UAT: agents invariant add --plan and --action flags not repeatable — spec requires multi-target support #1440

Open
opened 2026-04-02 17:57:31 +00:00 by freemo · 2 comments
Owner

Metadata

  • Branch: bugfix/m3-invariant-add-repeatable-flags
  • Commit Message: fix(cli): make --plan and --action flags repeatable in agents invariant add
  • Milestone: v3.2.0
  • Parent Epic: #395

Summary

The agents invariant add command's --plan and --action flags are implemented as single-value options (str | None) instead of repeatable list options (list[str]), and _resolve_scope rejects multiple scope flags entirely. This contradicts the specification, which explicitly states both flags are repeatable to allow attaching the same invariant to multiple plans or actions in a single command.

What Was Tested

The agents invariant add command's --plan and --action flags were tested for repeatability as specified in the documentation.

Expected Behavior (from spec)

Per docs/specification.md (section "agents invariant add"):

--plan PLAN_ID: Attach to a plan (plan-level invariant). Repeatable.
--action ACTION: Attach to an action (action-level invariant). Repeatable.
At least one scope flag (--global, --project, --plan, or --action) must be provided. --plan and --action can be repeated to attach the same invariant to multiple plans or actions.

The spec explicitly states that --plan and --action are repeatable, allowing the same invariant to be attached to multiple plans or actions in a single command.

Actual Behavior

The implementation defines --plan and --action as str | None (single value) instead of list[str]. When --plan is repeated, only the last value is used:

# In src/cleveragents/cli/commands/invariant.py
plan: Annotated[str | None, typer.Option("--plan", help="Plan ID (ULID)")] = None,
action: Annotated[str | None, typer.Option("--action", help="Action name")] = None,

Additionally, the _resolve_scope function rejects multiple scope flags entirely:

flags_set = sum([is_global, project is not None, plan is not None, action is not None])
if flags_set > 1:
    raise typer.BadParameter("Specify at most one scope flag...")

This means --plan PLAN1 --plan PLAN2 silently uses only PLAN2, and --plan PLAN1 --action ACTION1 raises an error.

Steps to Reproduce

from cleveragents.cli.commands.invariant import app
from typer.testing import CliRunner

runner = CliRunner()

# Repeated --plan only attaches to last plan
result = runner.invoke(app, ['add', '--plan', 'PLAN1', '--plan', 'PLAN2', 'Test invariant'])
# Output shows only PLAN2 as source — PLAN1 is silently ignored

# --plan and --action together raises error
result = runner.invoke(app, ['add', '--plan', 'PLAN1', '--action', 'ACTION1', 'Test invariant'])
# Error: "Specify at most one scope flag"

Code Location

  • src/cleveragents/cli/commands/invariant.pyadd() function, lines ~120-122
  • src/cleveragents/cli/commands/invariant.py_resolve_scope() function

Impact

Users cannot attach the same invariant to multiple plans or actions in a single command, requiring multiple separate invocations. This is a functional regression from the spec.

Subtasks

  • Change plan parameter type from str | None to list[str] using typer.Option("--plan") with default=[]
  • Change action parameter type from str | None to list[str] using typer.Option("--action") with default=[]
  • Refactor _resolve_scope() to accept list[str] for plan and action and allow mixed scope flags (e.g., --plan + --action together)
  • Update scope validation logic: require at least one scope flag; allow multiple --plan and/or --action values simultaneously
  • Update the invariant creation logic to iterate over all provided plan IDs and action names, creating one invariant record per target
  • Update CLI help text and docs/reference/invariants.md to document repeatability
  • Tests (Behave): Add features/invariant_add_repeatable.feature with scenarios for repeated --plan, repeated --action, mixed --plan + --action, and single-value backward-compatibility
  • Tests (Robot): Add robot/invariant_add_repeatable.robot integration test covering multi-target attach
  • Tests (ASV): Add benchmarks/invariant_add_bench.py for multi-target attach throughput
  • Verify coverage >= 97% via nox -s coverage_report
  • Run nox (all default sessions), fix any errors

Definition of Done

  • --plan and --action flags accept multiple values via repetition (e.g., --plan P1 --plan P2)
  • --plan and --action can be combined in a single invocation (e.g., --plan P1 --action A1)
  • Single-value usage remains backward-compatible
  • _resolve_scope() no longer raises an error when both --plan and --action are provided
  • All new Behave scenarios pass
  • All new Robot integration tests pass
  • All nox stages pass
  • Coverage >= 97%

ISSUES CLOSED: #395

## Metadata - **Branch**: `bugfix/m3-invariant-add-repeatable-flags` - **Commit Message**: `fix(cli): make --plan and --action flags repeatable in agents invariant add` - **Milestone**: v3.2.0 - **Parent Epic**: #395 ## Summary The `agents invariant add` command's `--plan` and `--action` flags are implemented as single-value options (`str | None`) instead of repeatable list options (`list[str]`), and `_resolve_scope` rejects multiple scope flags entirely. This contradicts the specification, which explicitly states both flags are repeatable to allow attaching the same invariant to multiple plans or actions in a single command. ## What Was Tested The `agents invariant add` command's `--plan` and `--action` flags were tested for repeatability as specified in the documentation. ## Expected Behavior (from spec) Per `docs/specification.md` (section "agents invariant add"): > `--plan PLAN_ID`: Attach to a plan (plan-level invariant). **Repeatable.** > `--action ACTION`: Attach to an action (action-level invariant). **Repeatable.** > At least one scope flag (`--global`, `--project`, `--plan`, or `--action`) must be provided. `--plan` and `--action` can be repeated to attach the same invariant to multiple plans or actions. The spec explicitly states that `--plan` and `--action` are repeatable, allowing the same invariant to be attached to multiple plans or actions in a single command. ## Actual Behavior The implementation defines `--plan` and `--action` as `str | None` (single value) instead of `list[str]`. When `--plan` is repeated, only the last value is used: ```python # In src/cleveragents/cli/commands/invariant.py plan: Annotated[str | None, typer.Option("--plan", help="Plan ID (ULID)")] = None, action: Annotated[str | None, typer.Option("--action", help="Action name")] = None, ``` Additionally, the `_resolve_scope` function rejects multiple scope flags entirely: ```python flags_set = sum([is_global, project is not None, plan is not None, action is not None]) if flags_set > 1: raise typer.BadParameter("Specify at most one scope flag...") ``` This means `--plan PLAN1 --plan PLAN2` silently uses only PLAN2, and `--plan PLAN1 --action ACTION1` raises an error. ## Steps to Reproduce ```python from cleveragents.cli.commands.invariant import app from typer.testing import CliRunner runner = CliRunner() # Repeated --plan only attaches to last plan result = runner.invoke(app, ['add', '--plan', 'PLAN1', '--plan', 'PLAN2', 'Test invariant']) # Output shows only PLAN2 as source — PLAN1 is silently ignored # --plan and --action together raises error result = runner.invoke(app, ['add', '--plan', 'PLAN1', '--action', 'ACTION1', 'Test invariant']) # Error: "Specify at most one scope flag" ``` ## Code Location - `src/cleveragents/cli/commands/invariant.py` — `add()` function, lines ~120-122 - `src/cleveragents/cli/commands/invariant.py` — `_resolve_scope()` function ## Impact Users cannot attach the same invariant to multiple plans or actions in a single command, requiring multiple separate invocations. This is a functional regression from the spec. ## Subtasks - [ ] Change `plan` parameter type from `str | None` to `list[str]` using `typer.Option("--plan")` with `default=[]` - [ ] Change `action` parameter type from `str | None` to `list[str]` using `typer.Option("--action")` with `default=[]` - [ ] Refactor `_resolve_scope()` to accept `list[str]` for `plan` and `action` and allow mixed scope flags (e.g., `--plan` + `--action` together) - [ ] Update scope validation logic: require at least one scope flag; allow multiple `--plan` and/or `--action` values simultaneously - [ ] Update the invariant creation logic to iterate over all provided plan IDs and action names, creating one invariant record per target - [ ] Update CLI help text and `docs/reference/invariants.md` to document repeatability - [ ] Tests (Behave): Add `features/invariant_add_repeatable.feature` with scenarios for repeated `--plan`, repeated `--action`, mixed `--plan` + `--action`, and single-value backward-compatibility - [ ] Tests (Robot): Add `robot/invariant_add_repeatable.robot` integration test covering multi-target attach - [ ] Tests (ASV): Add `benchmarks/invariant_add_bench.py` for multi-target attach throughput - [ ] Verify coverage >= 97% via `nox -s coverage_report` - [ ] Run `nox` (all default sessions), fix any errors ## Definition of Done - [ ] `--plan` and `--action` flags accept multiple values via repetition (e.g., `--plan P1 --plan P2`) - [ ] `--plan` and `--action` can be combined in a single invocation (e.g., `--plan P1 --action A1`) - [ ] Single-value usage remains backward-compatible - [ ] `_resolve_scope()` no longer raises an error when both `--plan` and `--action` are provided - [ ] All new Behave scenarios pass - [ ] All new Robot integration tests pass - [ ] All nox stages pass - [ ] Coverage >= 97% ISSUES CLOSED: #395
freemo added this to the v3.2.0 milestone 2026-04-02 18:00:09 +00:00
freemo self-assigned this 2026-04-02 18:45:10 +00:00
Author
Owner

Issue triaged by project owner:

  • State: Verified
  • Priority: Medium (already assigned) — CLI flags are not repeatable as the spec requires. Users cannot attach invariants to multiple targets in one command.
  • Milestone: v3.2.0 (already assigned)
  • MoSCoW: Must Have (already assigned) — The spec explicitly states --plan and --action are "Repeatable." The current implementation silently drops repeated values and rejects mixed scope flags. This is a functional deviation from the spec.
  • Parent Epic: #395

Valid UAT bug. The fix requires changing parameter types from str | None to list[str] and refactoring _resolve_scope() to accept multiple scope flags.


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

Issue triaged by project owner: - **State**: Verified - **Priority**: Medium (already assigned) — CLI flags are not repeatable as the spec requires. Users cannot attach invariants to multiple targets in one command. - **Milestone**: v3.2.0 (already assigned) - **MoSCoW**: Must Have (already assigned) — The spec explicitly states `--plan` and `--action` are "Repeatable." The current implementation silently drops repeated values and rejects mixed scope flags. This is a functional deviation from the spec. - **Parent Epic**: #395 Valid UAT bug. The fix requires changing parameter types from `str | None` to `list[str]` and refactoring `_resolve_scope()` to accept multiple scope flags. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: ca-project-owner
Author
Owner

Issue triaged by project owner:

  • State: Verified
  • Priority: High — Elevating from Medium. The agents invariant add command's --plan and --action flags not being repeatable directly violates the specification and blocks the v3.2.0 acceptance criteria for invariant management.
  • Milestone: v3.2.0 — This is a core v3.2.0 feature (invariant management). Keeping in v3.2.0.
  • MoSCoW: Must Have — The specification requires repeatable flags for invariant add. This blocks the v3.2.0 acceptance criterion: "agents invariant add creates invariants."
  • Parent Epic: #394 (Decision Framework) — Invariant management is part of the decision framework.

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

Issue triaged by project owner: - **State**: Verified - **Priority**: High — Elevating from Medium. The `agents invariant add` command's `--plan` and `--action` flags not being repeatable directly violates the specification and blocks the v3.2.0 acceptance criteria for invariant management. - **Milestone**: v3.2.0 — This is a core v3.2.0 feature (invariant management). Keeping in v3.2.0. - **MoSCoW**: Must Have — The specification requires repeatable flags for `invariant add`. This blocks the v3.2.0 acceptance criterion: "agents invariant add creates invariants." - **Parent Epic**: #394 (Decision Framework) — Invariant management is part of the decision framework. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: ca-project-owner
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.

Blocks
#394 Epic: Decision Framework
cleveragents/cleveragents-core
Reference
cleveragents/cleveragents-core#1440
No description provided.