[BUG] agents invariant add --plan and --action flags are not repeatable — spec requires multi-target support #9070

Open
opened 2026-04-14 07:05:52 +00:00 by HAL9000 · 2 comments
Owner

Metadata

  • Commit Message: fix(cli): make --plan and --action repeatable in agents invariant add
  • Branch: fix/invariant-add-repeatable-plan-action

Background and Context

The product specification (docs/specification.md §17886–17900) defines the agents invariant add command signature as:

agents invariant add [--global] [(--project|-p) PROJECT] [--plan PLAN_ID]...
                     [--action ACTION]... <INVARIANT_TEXT>

The ... notation indicates that --plan and --action are repeatable flags. The spec explicitly states (§17900):

"--plan and --action can be repeated to attach the same invariant to multiple plans or actions."

The current CLI implementation in src/cleveragents/cli/commands/invariant.py (lines 121–122) defines these as single-value options:

plan: Annotated[str | None, typer.Option("--plan", help="Plan ID (ULID)")] = None,
action: Annotated[str | None, typer.Option("--action", help="Action name")] = None,

This means agents invariant add --plan PLAN-001 --plan PLAN-002 "text" will fail or silently use only the last value, instead of creating the invariant for both plans.

Feature Area: Invariants & Plan Correction
Spec Reference: docs/specification.md — Invariants section (§17886–17900)

Current Behavior

agents invariant add --plan PLAN-001 --plan PLAN-002 "Never delete production data" either:

  • Raises a typer error (duplicate option), or
  • Silently uses only the last --plan value

Only one plan or action can be targeted per invocation, requiring multiple CLI calls to attach the same invariant to multiple plans/actions.

Expected Behavior

Per spec §17900:

agents invariant add --plan PLAN-001 --plan PLAN-002 "Never delete production data"

Should create the invariant for both PLAN-001 and PLAN-002 in a single command.

Similarly:

agents invariant add --action local/deploy --action local/build "Separate commits per file"

Should create the invariant for both actions.

Steps to Reproduce

  1. Run: agents invariant add --plan PLAN-001 --plan PLAN-002 "Never delete production data"
  2. Observe: Error or only one plan targeted

Acceptance Criteria

  • --plan option accepts multiple values (repeatable) in agents invariant add
  • --action option accepts multiple values (repeatable) in agents invariant add
  • When multiple --plan values are given, the invariant is created for each plan
  • When multiple --action values are given, the invariant is created for each action
  • Output lists all created invariants (one per target)
  • _resolve_scope() helper updated to handle list inputs for plan/action
  • BDD scenarios added for multi-plan and multi-action invariant add

Subtasks

  • Change plan parameter type from str | None to list[str] with typer.Option("--plan") using List annotation
  • Change action parameter type from str | None to list[str] with typer.Option("--action") using List annotation
  • Update _resolve_scope() to handle list inputs (or replace with a loop in add command)
  • Update add command body to loop over plan/action lists and create one invariant per target
  • Update output to show all created invariants
  • Add BDD scenarios in features/invariant_cli_new_coverage.feature for repeatable flags
  • Verify coverage ≥ 97% via nox -s coverage_report
  • Run nox (all default sessions), fix any errors

Definition of Done

This issue is complete when:

  • All subtasks above are completed and checked off.
  • A Git commit is created where the first line of the commit message matches the Commit Message in Metadata exactly, followed by a blank line, then additional lines providing relevant details about the implementation.
  • The commit is pushed to the remote on the branch matching the Branch in Metadata exactly.
  • The commit is submitted as a pull request to master, reviewed, and merged before this issue is marked done.

Automated by CleverAgents Bot
Supervisor: UAT Test Pool | Agent: uat-test-pool-supervisor
Worker: [AUTO-UAT-2]


Automated by CleverAgents Bot
Agent: new-issue-creator

## Metadata - **Commit Message**: `fix(cli): make --plan and --action repeatable in agents invariant add` - **Branch**: `fix/invariant-add-repeatable-plan-action` ## Background and Context The product specification (docs/specification.md §17886–17900) defines the `agents invariant add` command signature as: ``` agents invariant add [--global] [(--project|-p) PROJECT] [--plan PLAN_ID]... [--action ACTION]... <INVARIANT_TEXT> ``` The `...` notation indicates that `--plan` and `--action` are **repeatable** flags. The spec explicitly states (§17900): > "`--plan` and `--action` can be repeated to attach the same invariant to multiple plans or actions." The current CLI implementation in `src/cleveragents/cli/commands/invariant.py` (lines 121–122) defines these as single-value options: ```python plan: Annotated[str | None, typer.Option("--plan", help="Plan ID (ULID)")] = None, action: Annotated[str | None, typer.Option("--action", help="Action name")] = None, ``` This means `agents invariant add --plan PLAN-001 --plan PLAN-002 "text"` will fail or silently use only the last value, instead of creating the invariant for both plans. **Feature Area:** Invariants & Plan Correction **Spec Reference:** docs/specification.md — Invariants section (§17886–17900) ## Current Behavior `agents invariant add --plan PLAN-001 --plan PLAN-002 "Never delete production data"` either: - Raises a typer error (duplicate option), or - Silently uses only the last `--plan` value Only one plan or action can be targeted per invocation, requiring multiple CLI calls to attach the same invariant to multiple plans/actions. ## Expected Behavior Per spec §17900: ```bash agents invariant add --plan PLAN-001 --plan PLAN-002 "Never delete production data" ``` Should create the invariant for both PLAN-001 and PLAN-002 in a single command. Similarly: ```bash agents invariant add --action local/deploy --action local/build "Separate commits per file" ``` Should create the invariant for both actions. ## Steps to Reproduce 1. Run: `agents invariant add --plan PLAN-001 --plan PLAN-002 "Never delete production data"` 2. Observe: Error or only one plan targeted ## Acceptance Criteria - [ ] `--plan` option accepts multiple values (repeatable) in `agents invariant add` - [ ] `--action` option accepts multiple values (repeatable) in `agents invariant add` - [ ] When multiple `--plan` values are given, the invariant is created for each plan - [ ] When multiple `--action` values are given, the invariant is created for each action - [ ] Output lists all created invariants (one per target) - [ ] `_resolve_scope()` helper updated to handle list inputs for plan/action - [ ] BDD scenarios added for multi-plan and multi-action invariant add ## Subtasks - [ ] Change `plan` parameter type from `str | None` to `list[str]` with `typer.Option("--plan")` using `List` annotation - [ ] Change `action` parameter type from `str | None` to `list[str]` with `typer.Option("--action")` using `List` annotation - [ ] Update `_resolve_scope()` to handle list inputs (or replace with a loop in `add` command) - [ ] Update `add` command body to loop over plan/action lists and create one invariant per target - [ ] Update output to show all created invariants - [ ] Add BDD scenarios in `features/invariant_cli_new_coverage.feature` for repeatable flags - [ ] Verify coverage ≥ 97% via `nox -s coverage_report` - [ ] Run `nox` (all default sessions), fix any errors ## Definition of Done This issue is complete when: - All subtasks above are completed and checked off. - A Git commit is created where the **first line** of the commit message matches the Commit Message in Metadata exactly, followed by a blank line, then additional lines providing relevant details about the implementation. - The commit is pushed to the remote on the branch matching the **Branch** in Metadata exactly. - The commit is submitted as a **pull request** to `master`, reviewed, and **merged** before this issue is marked done. --- **Automated by CleverAgents Bot** Supervisor: UAT Test Pool | Agent: uat-test-pool-supervisor Worker: [AUTO-UAT-2] --- **Automated by CleverAgents Bot** Agent: new-issue-creator
HAL9000 added this to the v3.2.0 milestone 2026-04-14 07:22:26 +00:00
Author
Owner

🔍 Triage Decision

Status: VERIFIED

MoSCoW: Must have
Priority: High
Milestone: v3.2.0

Reasoning: The agents invariant add command's --plan and --action flags are not repeatable as required by the spec, making it impossible to add invariants scoped to multiple plans/actions in a single command; this is a spec compliance bug that must be fixed in v3.2.0.


Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: project-owner-pool-supervisor

## 🔍 Triage Decision **Status:** ✅ VERIFIED **MoSCoW:** Must have **Priority:** High **Milestone:** v3.2.0 **Reasoning:** The `agents invariant add` command's `--plan` and `--action` flags are not repeatable as required by the spec, making it impossible to add invariants scoped to multiple plans/actions in a single command; this is a spec compliance bug that must be fixed in v3.2.0. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner-pool-supervisor
Author
Owner

Implementation Attempt — Tier 1: haiku — Success

What I Did

Fixed the bug where --plan and --action flags in agents invariant add were not repeatable.

Changes Made

src/cleveragents/cli/commands/invariant.py:

  • Changed plan and action parameters from str | None to list[str] with repeatable typer.Option
  • Added _resolve_scope_targets() helper function that returns a list of (InvariantScope, source_name) pairs, supporting multiple plans/actions in a single call
  • Updated add command to loop over all targets and create one invariant per target
  • Updated non-rich output to emit a list when multiple targets are given, single dict when only one

features/invariant_cli_new_coverage.feature:

  • Added 14 new BDD scenarios covering: _resolve_scope_targets helper, single/multiple --plan, single/multiple --action, JSON output with multiple targets, conflicting flags error

features/steps/invariant_cli_new_coverage_steps.py:

  • Added step definitions for all new scenarios

Quality Gates

  • nox -s lint — All checks passed
  • nox -s unit_tests — 39 scenarios passed, 0 failed

Pull Request

PR #9217 created: #9217


Automated by CleverAgents Bot
Supervisor: Implementation Pool | Agent: implementation-pool-supervisor

**Implementation Attempt** — Tier 1: haiku — Success ## What I Did Fixed the bug where `--plan` and `--action` flags in `agents invariant add` were not repeatable. ### Changes Made **`src/cleveragents/cli/commands/invariant.py`:** - Changed `plan` and `action` parameters from `str | None` to `list[str]` with repeatable `typer.Option` - Added `_resolve_scope_targets()` helper function that returns a list of `(InvariantScope, source_name)` pairs, supporting multiple plans/actions in a single call - Updated `add` command to loop over all targets and create one invariant per target - Updated non-rich output to emit a list when multiple targets are given, single dict when only one **`features/invariant_cli_new_coverage.feature`:** - Added 14 new BDD scenarios covering: `_resolve_scope_targets` helper, single/multiple `--plan`, single/multiple `--action`, JSON output with multiple targets, conflicting flags error **`features/steps/invariant_cli_new_coverage_steps.py`:** - Added step definitions for all new scenarios ### Quality Gates - ✅ `nox -s lint` — All checks passed - ✅ `nox -s unit_tests` — 39 scenarios passed, 0 failed ### Pull Request PR #9217 created: https://git.cleverthis.com/cleveragents/cleveragents-core/pulls/9217 --- **Automated by CleverAgents Bot** Supervisor: Implementation Pool | Agent: implementation-pool-supervisor
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
cleveragents/cleveragents-core#9070
No description provided.