UAT: agents invariant add CLI missing --non-overridable flag — non_overridable global invariants cannot be set via CLI #6253

Open
opened 2026-04-09 18:17:19 +00:00 by HAL9000 · 0 comments
Owner

Background and Context

The specification (§19749) states:

Non-overridable invariants are set via agents invariant add --global --non-overridable "<constraint>".

The non_overridable flag on GLOBAL-scoped invariants is a key safety mechanism — it enables system-wide constraints that cannot be overridden by any lower-scope invariant (not even plan-level). This is critical for constraints such as "Never commit secrets to version control."

Current Behavior

The agents invariant add CLI command (src/cleveragents/cli/commands/invariant.py) has no --non-overridable flag:

@app.command()
def add(
    text: Annotated[str, typer.Argument(help="The invariant constraint text")],
    is_global: Annotated[bool, typer.Option("--global", ...)] = False,
    project: Annotated[str | None, typer.Option("--project", ...)] = None,
    plan: Annotated[str | None, typer.Option("--plan", ...)] = None,
    action: Annotated[str | None, typer.Option("--action", ...)] = None,
    fmt: ...
) -> None:

Additionally, InvariantService.add_invariant() (src/cleveragents/application/services/invariant_service.py) does not accept a non_overridable parameter:

def add_invariant(
    self,
    text: str,
    scope: InvariantScope,
    source_name: str,
) -> Invariant:

The Invariant domain model does have a non_overridable field (defaults to False), and InvariantReconciliationActor correctly uses it during reconciliation. However, there is no way to set non_overridable=True via the CLI or the service's add_invariant method.

Expected Behavior

The CLI command should accept --non-overridable as an option on agents invariant add:

agents invariant add --global --non-overridable "Never commit secrets to version control"

The InvariantService.add_invariant() method should accept a non_overridable: bool = False parameter and pass it to the Invariant constructor.

Acceptance Criteria

  • agents invariant add CLI accepts --non-overridable flag
  • Flag is only meaningful with --global; CLI should warn/ignore if set with other scopes (per spec)
  • InvariantService.add_invariant() accepts non_overridable: bool = False parameter
  • The created Invariant has non_overridable=True when flag is passed
  • InvariantReconciliationActor continues to correctly give non-overridable globals priority
  • agents invariant list output shows whether an invariant is non-overridable
  • Unit tests (Behave) cover the new CLI flag and service parameter
  • nox (all default sessions) passes

Supporting Information

  • Spec reference: docs/specification.md §19749: "Non-overridable invariants are set via agents invariant add --global --non-overridable "<constraint>""
  • CLI file: src/cleveragents/cli/commands/invariant.pyadd() function
  • Service file: src/cleveragents/application/services/invariant_service.pyInvariantService.add_invariant()
  • Domain model: src/cleveragents/domain/models/core/invariant.pyInvariant.non_overridable field exists but is only settable programmatically
  • Reconciliation actor: src/cleveragents/actor/reconciliation.py — correctly implements the non-overridable priority check, but can never be triggered since non_overridable is always False

Automated by CleverAgents Bot
Supervisor: UAT Testing | Agent: uat-tester

## Background and Context The specification (§19749) states: > Non-overridable invariants are set via `agents invariant add --global --non-overridable "<constraint>"`. The `non_overridable` flag on `GLOBAL`-scoped invariants is a key safety mechanism — it enables system-wide constraints that cannot be overridden by any lower-scope invariant (not even plan-level). This is critical for constraints such as "Never commit secrets to version control." ## Current Behavior The `agents invariant add` CLI command (`src/cleveragents/cli/commands/invariant.py`) has no `--non-overridable` flag: ```python @app.command() def add( text: Annotated[str, typer.Argument(help="The invariant constraint text")], is_global: Annotated[bool, typer.Option("--global", ...)] = False, project: Annotated[str | None, typer.Option("--project", ...)] = None, plan: Annotated[str | None, typer.Option("--plan", ...)] = None, action: Annotated[str | None, typer.Option("--action", ...)] = None, fmt: ... ) -> None: ``` Additionally, `InvariantService.add_invariant()` (`src/cleveragents/application/services/invariant_service.py`) does not accept a `non_overridable` parameter: ```python def add_invariant( self, text: str, scope: InvariantScope, source_name: str, ) -> Invariant: ``` The `Invariant` domain model does have a `non_overridable` field (defaults to `False`), and `InvariantReconciliationActor` correctly uses it during reconciliation. However, there is no way to set `non_overridable=True` via the CLI or the service's `add_invariant` method. ## Expected Behavior The CLI command should accept `--non-overridable` as an option on `agents invariant add`: ```bash agents invariant add --global --non-overridable "Never commit secrets to version control" ``` The `InvariantService.add_invariant()` method should accept a `non_overridable: bool = False` parameter and pass it to the `Invariant` constructor. ## Acceptance Criteria - [ ] `agents invariant add` CLI accepts `--non-overridable` flag - [ ] Flag is only meaningful with `--global`; CLI should warn/ignore if set with other scopes (per spec) - [ ] `InvariantService.add_invariant()` accepts `non_overridable: bool = False` parameter - [ ] The created `Invariant` has `non_overridable=True` when flag is passed - [ ] `InvariantReconciliationActor` continues to correctly give non-overridable globals priority - [ ] `agents invariant list` output shows whether an invariant is non-overridable - [ ] Unit tests (Behave) cover the new CLI flag and service parameter - [ ] `nox` (all default sessions) passes ## Supporting Information - **Spec reference**: `docs/specification.md` §19749: "Non-overridable invariants are set via `agents invariant add --global --non-overridable "<constraint>"`" - **CLI file**: `src/cleveragents/cli/commands/invariant.py` — `add()` function - **Service file**: `src/cleveragents/application/services/invariant_service.py` — `InvariantService.add_invariant()` - **Domain model**: `src/cleveragents/domain/models/core/invariant.py` — `Invariant.non_overridable` field exists but is only settable programmatically - **Reconciliation actor**: `src/cleveragents/actor/reconciliation.py` — correctly implements the non-overridable priority check, but can never be triggered since `non_overridable` is always `False` --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: uat-tester
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.

Dependencies

No dependencies set.

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