Compare commits

...

1 Commits

Author SHA1 Message Date
HAL9000 99f575f6cf docs(spec): clarify invariant CLI — add --non-overridable flag and --effective --action support
CI / lint (pull_request) Successful in 29s
CI / helm (pull_request) Successful in 25s
CI / push-validation (pull_request) Successful in 26s
CI / build (pull_request) Successful in 32s
CI / typecheck (pull_request) Successful in 53s
CI / security (pull_request) Successful in 1m1s
CI / quality (pull_request) Successful in 1m6s
CI / e2e_tests (pull_request) Successful in 4m3s
CI / integration_tests (pull_request) Successful in 7m50s
CI / unit_tests (pull_request) Successful in 8m40s
CI / docker (pull_request) Successful in 21s
CI / coverage (pull_request) Successful in 11m57s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 58m11s
Two spec gaps were causing UAT failures (#7461, #7462):

1. agents invariant add: Add --non-overridable flag to CLI synopsis and
   argument list. The flag was documented in the conceptual section
   (Layer 3: Invariant Enforcement) but absent from the CLI command
   definition, causing implementers to omit it entirely.

2. agents invariant list: Clarify that --effective is valid with both
   --plan and --action (not only --plan). The synopsis already showed
   --effective without restriction, but the argument description said
   'Only with --plan', causing the implementation to reject
   --effective --action. Add example output for the --action --effective
   combination.

3. InvariantEnforcer code snippet: Fix precedence list to include
   'action' tier (plan > action > project > global), matching the
   four-tier precedence defined in the Invariant glossary entry.

Fixes: #7461, #7462 (spec gaps — implementation work tracked separately)
2026-04-10 21:39:07 +00:00
+49 -6
View File
@@ -361,7 +361,7 @@ The following standards are integrated into the architecture:
<span style="color: cyan; font-weight: 600;">agents</span> config list [<span style="color: cyan;">--filter-values</span> <span style="color: #66cc66;">&lt;REGEX&gt;</span>] [<span style="color: #66cc66;">&lt;REGEX&gt;</span>]
<span style="color: cyan; font-weight: 600;">agents</span> invariant add [<span style="color: cyan;">--global</span>] [(<span style="color: cyan;">--project</span>|<span style="color: yellow;">-p</span>) PROJECT] [<span style="color: cyan;">--plan</span> PLAN_ID]...
[<span style="color: cyan;">--action</span> ACTION]... <span style="color: #66cc66;">&lt;INVARIANT_TEXT&gt;</span>
[<span style="color: cyan;">--action</span> ACTION]... [<span style="color: cyan;">--non-overridable</span>] <span style="color: #66cc66;">&lt;INVARIANT_TEXT&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> invariant list [<span style="color: cyan;">--global</span>] [(<span style="color: cyan;">--project</span>|<span style="color: yellow;">-p</span>) PROJECT] [<span style="color: cyan;">--plan</span> PLAN_ID] [<span style="color: cyan;">--action</span> ACTION]
[<span style="color: cyan;">--effective</span>] [<span style="color: #66cc66;">&lt;REGEX&gt;</span>]
<span style="color: cyan; font-weight: 600;">agents</span> invariant remove [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;INVARIANT_ID&gt;</span>
@@ -17884,7 +17884,7 @@ None.
##### agents invariant add
<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> invariant add [<span style="color: cyan;">--global</span>] [(<span style="color: cyan;">--project</span>|<span style="color: yellow;">-p</span>) PROJECT] [<span style="color: cyan;">--plan</span> PLAN_ID]...
[<span style="color: cyan;">--action</span> ACTION]... <span style="color: #66cc66;">&lt;INVARIANT_TEXT&gt;</span></code></pre></div>
[<span style="color: cyan;">--action</span> ACTION]... [<span style="color: cyan;">--non-overridable</span>] <span style="color: #66cc66;">&lt;INVARIANT_TEXT&gt;</span></code></pre></div>
**Purpose**
Add an invariant at the specified scope.
@@ -17896,6 +17896,7 @@ Add an invariant at the specified scope.
- `--project/-p PROJECT`: Attach to a project (applies to all plans targeting this project).
- `--plan PLAN_ID`: Attach to a plan (plan-level invariant). Repeatable.
- `--action ACTION`: Attach to an action (action-level invariant). Repeatable.
- `--non-overridable`: Mark this invariant as non-overridable. **Only valid with `--global`.** When set, this global invariant takes absolute precedence over all other scopes — even plan-level invariants cannot override it. Intended for system-wide safety constraints that must never be relaxed (e.g., "Never commit secrets to version control"). Silently ignored if used with any non-global scope flag.
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.
@@ -17946,6 +17947,17 @@ At least one scope flag (`--global`, `--project`, `--plan`, or `--action`) must
╰────────────────────────────────────────────────────────────────────────╯
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Invariant added
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> invariant add <span style="color: cyan;">--global</span> <span style="color: cyan;">--non-overridable</span> <span style="color: #66cc66;">&quot;Never commit secrets to version control&quot;</span>
╭─ Invariant Added ──────────────────────────────────────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Invariant:</span> Never commit secrets to version control │
│ <span style="color: #5599ff; font-weight: 600;">Scope:</span> global │
│ <span style="color: yellow; font-weight: 600;">Non-overridable:</span> true │
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> inv_01HXM9J5C │
╰────────────────────────────────────────────────────────────────────────────╯
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Invariant added (non-overridable — takes absolute precedence over all scopes)
</code></pre></div>
=== "Plain"
@@ -17989,6 +18001,16 @@ At least one scope flag (`--global`, `--project`, `--plan`, or `--action`) must
ID: inv_01HXM9H4B
[OK] Invariant added
$ agents invariant add --global --non-overridable "Never commit secrets to version control"
Invariant Added
Invariant: Never commit secrets to version control
Scope: global
Non-overridable: true
ID: inv_01HXM9J5C
[OK] Invariant added (non-overridable — takes absolute precedence over all scopes)
```
=== "JSON"
@@ -18063,7 +18085,7 @@ At least one scope flag (`--global`, `--project`, `--plan`, or `--action`) must
[<span style="color: cyan;">--effective</span>] [<span style="color: #66cc66;">&lt;REGEX&gt;</span>]</code></pre></div>
**Purpose**
List invariants at a given scope. Use `--effective` with `--plan` to show the final reconciled view of invariants (after precedence resolution) rather than just the invariants directly attached at that scope.
List invariants at a given scope. Use `--effective` with `--plan` or `--action` to show the final reconciled view of invariants (after precedence resolution) rather than just the invariants directly attached at that scope.
**Arguments**
@@ -18071,7 +18093,7 @@ List invariants at a given scope. Use `--effective` with `--plan` to show the fi
- `--project/-p PROJECT`: List invariants attached to a project.
- `--plan PLAN_ID`: List invariants attached to a plan.
- `--action ACTION`: List invariants attached to an action.
- `--effective`: (Only with `--plan`) Show the reconciled invariant view after precedence resolution across all scopes.
- `--effective`: Show the reconciled invariant view after precedence resolution across all scopes. Valid with `--plan` or `--action`. When used with `--plan`, shows the fully resolved effective invariant set for that plan (merging global, project, action, and plan scopes). When used with `--action`, shows the effective invariant set that would apply to any plan instantiated from that action (merging global and action scopes). Not valid with `--global` or `--project` alone (those scopes have no higher-priority overrides to merge).
**Examples**
@@ -18104,6 +18126,17 @@ List invariants at a given scope. Use `--effective` with `--plan` to show the fi
│ parameterized statements"</span> │
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 3 effective invariants (1 global, 1 project, 1 plan; 1 conflict resolved)
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> invariant list <span style="color: cyan;">--action</span> local/deploy <span style="color: cyan;">--effective</span>
╭─ Effective Invariants (Action local/deploy) ───────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID</span> <span style="color: cyan; font-weight: 600;">Source</span> <span style="color: cyan; font-weight: 600;">Text</span> │
│ <span style="opacity: 0.7;">────────────── ─────── ──────────────────────────────────────────────────────</span> │
│ inv_01HXM9A1B global All public APIs must maintain backward compatibility │
│ inv_01HXM9H4B action Action requires approval before execution │
╰───────────────────────────────────────────────────────────────────────────────────────╯
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 2 effective invariants (1 global, 1 action)
</code></pre></div>
=== "Plain"
@@ -18133,6 +18166,16 @@ List invariants at a given scope. Use `--effective` with `--plan` to show the fi
parameterized statements"
[OK] 3 effective invariants (1 global, 1 project, 1 plan; 1 conflict resolved)
$ agents invariant list --action local/deploy --effective
Effective Invariants (Action local/deploy)
ID Source Text
-------------- ------- --------------------------------------------------
inv_01HXM9A1B global All public APIs must maintain backward compatibility
inv_01HXM9H4B action Action requires approval before execution
[OK] 2 effective invariants (1 global, 1 action)
```
=== "JSON"
@@ -19798,8 +19841,8 @@ The system collects, reconciles, and checks invariants:
<span style="color: magenta; font-weight: 600;">or</span> self.get_global_invariant_actor()
)
<span style="opacity: 0.7;"># 3. Reconcile: apply precedence (plan &gt; project &gt; global), resolve conflicts</span>
effective = reconciler.reconcile(raw, precedence=[<span style="color: #66cc66;">&#x27;plan&#x27;</span>, <span style="color: #66cc66;">&#x27;project&#x27;</span>, <span style="color: #66cc66;">&#x27;global&#x27;</span>])
<span style="opacity: 0.7;"># 3. Reconcile: apply precedence (plan &gt; action &gt; project &gt; global), resolve conflicts</span>
effective = reconciler.reconcile(raw, precedence=[<span style="color: #66cc66;">&#x27;plan&#x27;</span>, <span style="color: #66cc66;">&#x27;action&#x27;</span>, <span style="color: #66cc66;">&#x27;project&#x27;</span>, <span style="color: #66cc66;">&#x27;global&#x27;</span>])
<span style="color: magenta; font-weight: 600;">return</span> effective
<span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">collect_all_invariants</span>(self, plan):