diff --git a/docs/specification.md b/docs/specification.md index 4accaad8b..1a9a5f08f 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. 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. + : 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, Execute, and Apply phases; recorded as `invariant_enforced` decisions that propagate to child plans. Reconciliation failure blocks the phase transition with `ReconciliationBlockedError`. 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). @@ -19750,6 +19750,18 @@ Each effective invariant is then recorded as an `invariant_enforced` decision in **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. +**Reconciliation failure behavior**: When invariant reconciliation fails (e.g., irreconcilable conflicts between invariants), the phase transition is **blocked** — the plan cannot proceed to the next phase. The system raises a `ReconciliationBlockedError` and emits an `INVARIANT_VIOLATED` event on the event bus. The plan remains in its current phase until the invariants are corrected. + +Reconciliation runs at the start of three phase transitions: + +- **Strategize start** (`start_strategize()`) — the primary reconciliation point +- **Execute start** (`execute_plan()`) — re-validates invariants before execution begins +- **Apply start** (`apply_plan()`) — final invariant check before changes are applied + +After a correction is applied via `agents plan correct`, reconciliation automatically re-runs via a `CORRECTION_APPLIED` event subscription (best-effort; does not block correction completion). + +The built-in reconciliation actor is registered as `builtin/invariant-reconciliation`. It is used when no custom invariant actor is configured at the plan, project, or global level. + **Correcting invariants**: The correction mechanism for `invariant_enforced` decisions supports two operations: * **Remove**: Remove an existing invariant from the plan's decision tree (the invariant remains defined at its scope but is no longer enforced for this plan). * **Add**: Add a new invariant to the plan. When adding, the user can select from invariants already accessible to the plan (those defined at the plan, action, project, or global scope), or provide free-form text to create a new ad-hoc invariant.