From 99f575f6cf52bfa35f1974ee5bc5b4fc07e74cf7 Mon Sep 17 00:00:00 2001 From: CleverThis Date: Fri, 10 Apr 2026 21:39:07 +0000 Subject: [PATCH] =?UTF-8?q?docs(spec):=20clarify=20invariant=20CLI=20?= =?UTF-8?q?=E2=80=94=20add=20--non-overridable=20flag=20and=20--effective?= =?UTF-8?q?=20--action=20support?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- docs/specification.md | 55 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/docs/specification.md b/docs/specification.md index dbe7bd381..094995923 100644 --- a/docs/specification.md +++ b/docs/specification.md @@ -361,7 +361,7 @@ The following standards are integrated into the architecture: agents config list [--filter-values <REGEX>] [<REGEX>] agents invariant add [--global] [(--project|-p) PROJECT] [--plan PLAN_ID]... - [--action ACTION]... <INVARIANT_TEXT> + [--action ACTION]... [--non-overridable] <INVARIANT_TEXT> agents invariant list [--global] [(--project|-p) PROJECT] [--plan PLAN_ID] [--action ACTION] [--effective] [<REGEX>] agents invariant remove [--yes|-y] <INVARIANT_ID> @@ -17884,7 +17884,7 @@ None. ##### agents invariant add
agents invariant add [--global] [(--project|-p) PROJECT] [--plan PLAN_ID]...
-                     [--action ACTION]... <INVARIANT_TEXT>
+ [--action ACTION]... [--non-overridable] <INVARIANT_TEXT> **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 ╰────────────────────────────────────────────────────────────────────────╯ ✓ 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) === "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 [--effective] [<REGEX>] **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" │ ✓ 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) === "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: or self.get_global_invariant_actor() ) - # 3. Reconcile: apply precedence (plan > project > global), resolve conflicts - effective = reconciler.reconcile(raw, precedence=['plan', 'project', 'global']) + # 3. Reconcile: apply precedence (plan > action > project > global), resolve conflicts + effective = reconciler.reconcile(raw, precedence=['plan', 'action', 'project', 'global']) return effective def collect_all_invariants(self, plan): -- 2.52.0