diff --git a/docs/specification.md b/docs/specification.md index f020b553e..a09d55126 100644 --- a/docs/specification.md +++ b/docs/specification.md @@ -89,7 +89,7 @@ The following standards are integrated into the architecture: : A persisted choice point in a plan's decision tree, created during Strategize or Execute. Records the question, chosen option, alternatives, confidence score, rationale, context snapshot, and downstream dependencies. Types: `prompt_definition`, `invariant_enforced`, `strategy_choice`, `subplan_spawn`, `subplan_parallel_spawn`, among others. Supports targeted correction with selective subtree recomputation. Invariant - : A natural-language constraint on plan execution scoped to global, project, action, or plan level. Action invariants are promoted to plan-level when the action is used, so the runtime precedence chain is three-tier: ==plan > project > global==. Reconciled by the Invariant Reconciliation Actor at the start of Strategize; recorded as `invariant_enforced` decisions that propagate to child plans. + : A natural-language constraint on plan execution scoped to global, project, action, or plan level. The runtime precedence chain is four-tier: ==plan > action > project > global==. Exception: global invariants marked `non_overridable` always win regardless of scope. Reconciled by the Invariant Reconciliation Actor at the start of Strategize; recorded as `invariant_enforced` decisions that propagate to child plans. Automation Profile : A named set of confidence thresholds (each `0.0`–`1.0`) gating which plan operations proceed automatically versus requiring human approval. `0.0` = always automatic; `1.0` = always manual. Eight built-in profiles (`manual` through `full-auto`). Custom profiles namespaced as `[[server:]namespace/]name`. Each profile composes a **Safety Profile** that controls hard safety constraints (sandbox, checkpoint, unsafe-tool gating, skill restrictions, cost/retry limits). @@ -18977,7 +18977,7 @@ When the action is used: 2. The plan's automation profile is resolved (plan > action > project > global precedence) 3. Any invariants from the action are carried forward as plan-level invariants, combined with any `--invariant` flags provided 4. The plan enters the **Strategize** phase -5. The **Invariant Reconciliation Actor** computes the effective invariant view (resolving conflicts using plan > project > global precedence) +5. The **Invariant Reconciliation Actor** computes the effective invariant view (resolving conflicts using plan > action > project > global precedence) 6. The `strategy_actor` begins analyzing the project(s) #### What Strategize Does @@ -18988,7 +18988,7 @@ Strategize is: * **read-only**, producing a plan of attack, * responsible for gathering context from project resources, -* responsible for collecting applicable invariants (from global, project, action, and plan scopes), computing the effective invariant view via the **Invariant Reconciliation Actor** (applying plan > project > global precedence), and recording them as `invariant_enforced` decisions, +* responsible for collecting applicable invariants (from global, project, action, and plan scopes), computing the effective invariant view via the **Invariant Reconciliation Actor** (applying plan > action > project > global precedence), and recording them as `invariant_enforced` decisions, * responsible for generating a strategy and child plan blueprint (using `subplan_spawn` and `subplan_parallel_spawn` decisions), * not allowed to execute child plans or modify resources. @@ -19598,10 +19598,13 @@ Invariants are named constraints that guide and constrain plan execution. They c **Precedence and conflict resolution**: When invariants from different scopes conflict, narrower scopes override broader scopes: -* **Plan-level** invariants override **project-level** and **global-level** invariants. +* **Plan-level** invariants override **action-level**, **project-level**, and **global-level** invariants. +* **Action-level** invariants override **project-level** and **global-level** invariants. * **Project-level** invariants override **global-level** invariants. -Note: Action invariants are carried forward as plan-level invariants when the action is used (see **Action invariants** above), so they participate in precedence at the plan tier — there is no separate action tier in the precedence chain. +Exception: **Non-overridable global invariants** (marked `non_overridable: true`) always take precedence over all other scopes, including plan-level invariants. See below. + +The full precedence chain (highest to lowest): `plan > action > project > global`. Conflict resolution is performed by the **Invariant Reconciliation Actor** — a dedicated actor responsible for comparing invariants across scopes, identifying conflicts, and producing the final **effective invariant view** for a plan. The Invariant Reconciliation Actor is set at three levels via `--invariant-actor`: @@ -19615,11 +19618,13 @@ The lookup order is: plan → project → global config. The first Invariant Rec 1. Collecting all invariants from global, project, plan, and action scopes. 2. Identifying conflicts (invariants from different scopes that contradict each other). -3. Applying precedence rules (plan > project > global) to resolve conflicts. +3. Applying precedence rules (plan > action > project > global) to resolve conflicts, with non-overridable global invariants taking absolute precedence. 4. Producing the final set of effective invariants. Each effective invariant is then recorded as an `invariant_enforced` decision in the plan's decision tree. This makes invariants visible, auditable, and correctable through the standard decision correction mechanism. +**Non-overridable global invariants**: A global invariant may be marked `non_overridable: true`. When set, this invariant takes precedence over all lower-scope invariants regardless of the normal precedence chain -- even plan-level invariants cannot override it. This is intended for system-wide safety constraints that must never be relaxed (e.g., "Never commit secrets to version control"). Non-overridable invariants are set via `agents invariant add --global --non-overridable ""`. The `non_overridable` flag is only meaningful on `GLOBAL`-scoped invariants; it is ignored on project, action, and plan invariants. + **Child plan inheritance**: When a top-level plan spawns child plans, the parent's effective invariant view (already reconciled) is passed down to each child plan. Child plans do not re-run reconciliation — they inherit the parent's resolved view. **Correcting invariants**: The correction mechanism for `invariant_enforced` decisions supports two operations: