@event4u/agent-config 14.7.0 → 14.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (230) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +175 -390
  3. package/README.md +1 -1
  4. package/agents/templates/.ai-council.yml.example +34 -4
  5. package/dist/agent-src/commands/evals/git-pr-merge.json +13 -0
  6. package/dist/agent-src/commands/evals/roadmap.json +17 -1
  7. package/dist/agent-src/commands/pr/create.md +14 -2
  8. package/dist/agent-src/commands/pr/merge.md +383 -0
  9. package/dist/agent-src/commands/review/changes.md +95 -14
  10. package/dist/agent-src/commands/roadmap/process-full.md +157 -3
  11. package/dist/agent-src/commands/roadmap.md +1 -1
  12. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +46 -36
  13. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +37 -2
  14. package/dist/agent-src/contexts/execution/host-capability-manifest.md +77 -0
  15. package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +100 -2
  16. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +154 -2
  17. package/dist/agent-src/contexts/execution/subagent-response-contract.md +80 -0
  18. package/dist/agent-src/rules/artifact-drafting-protocol.md +5 -1
  19. package/dist/agent-src/rules/decision-revisit-gate.md +65 -33
  20. package/dist/agent-src/rules/recurring-criticism.md +1 -1
  21. package/dist/agent-src/rules/roadmap-progress-sync.md +19 -0
  22. package/dist/agent-src/rules/source-confidentiality.md +1 -1
  23. package/dist/agent-src/rules/untrusted-input-defense.md +9 -3
  24. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +7 -4
  25. package/dist/agent-src/scripts/dashboard_mode.ts +212 -0
  26. package/dist/agent-src/scripts/update_roadmap_progress.ts +47 -48
  27. package/dist/agent-src/skills/adr-create/SKILL.md +124 -5
  28. package/dist/agent-src/skills/code-review/evals/evals.json +87 -46
  29. package/dist/agent-src/skills/decision-record/SKILL.md +61 -3
  30. package/dist/agent-src/skills/decision-review/SKILL.md +65 -0
  31. package/dist/agent-src/skills/humanizer/SKILL.md +39 -0
  32. package/dist/agent-src/skills/humanizer/evals/strip_fixtures.json +57 -0
  33. package/dist/agent-src/skills/humanizer/references/fixtures.md +54 -0
  34. package/dist/agent-src/skills/judge-spec-compliance/SKILL.md +154 -0
  35. package/dist/agent-src/skills/judge-synthesis/SKILL.md +45 -0
  36. package/dist/agent-src/skills/merge-conflicts/SKILL.md +26 -0
  37. package/dist/agent-src/skills/roadmap-writing/SKILL.md +18 -18
  38. package/dist/agent-src/skills/security/SKILL.md +8 -0
  39. package/dist/agent-src/skills/security-audit/SKILL.md +12 -1
  40. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  41. package/dist/agent-src/templates/roadmaps.md +28 -2
  42. package/dist/cli/registry.js +3 -0
  43. package/dist/cli/registry.js.map +1 -1
  44. package/dist/cli-delegate/{chunk-FBKL6JWT.js → chunk-77GR3VD4.js} +68 -43
  45. package/dist/cli-delegate/{chunk-JZ4NR2TW.js → chunk-7PRE6ZV2.js} +1 -1
  46. package/dist/cli-delegate/{chunk-UEZ7D35A.js → chunk-CYH5SP6M.js} +4 -23
  47. package/dist/cli-delegate/{chunk-Q26HT4QT.js → chunk-E46KPN6K.js} +251 -150
  48. package/dist/cli-delegate/{chunk-74E3TKWV.js → chunk-H4VIVD4C.js} +5 -5
  49. package/dist/cli-delegate/chunk-I3EIN2YG.js +36 -0
  50. package/dist/cli-delegate/{chunk-4VR4ORQ6.js → chunk-LPPWO5CE.js} +4 -3
  51. package/dist/cli-delegate/{chunk-7F3VYSM2.js → chunk-PLSG6UL5.js} +14 -14
  52. package/dist/cli-delegate/cmd_adr_effective.js +1162 -0
  53. package/dist/cli-delegate/cmd_conformance.js +101 -25
  54. package/dist/cli-delegate/cmd_converge.js +3 -3
  55. package/dist/cli-delegate/cmd_doctor.js +7 -7
  56. package/dist/cli-delegate/cmd_export.js +6 -6
  57. package/dist/cli-delegate/cmd_handoff.js +7 -6
  58. package/dist/cli-delegate/cmd_memory_get.js +2 -1
  59. package/dist/cli-delegate/cmd_migrate.js +2 -2
  60. package/dist/cli-delegate/cmd_preflight.js +5 -5
  61. package/dist/cli-delegate/cmd_prune.js +6 -6
  62. package/dist/cli-delegate/cmd_route_audit.js +6 -5
  63. package/dist/cli-delegate/cmd_route_explain.js +3 -3
  64. package/dist/cli-delegate/cmd_session_recycle.js +3 -3
  65. package/dist/cli-delegate/cmd_settings_get.js +4 -4
  66. package/dist/cli-delegate/cmd_settings_migrate.js +6 -6
  67. package/dist/cli-delegate/cmd_settings_set.js +1 -1
  68. package/dist/cli-delegate/cmd_sync.js +6 -6
  69. package/dist/cli-delegate/cmd_uninstall.js +6 -6
  70. package/dist/cli-delegate/cmd_update.js +3 -3
  71. package/dist/cli-delegate/cmd_upgrade.js +3 -3
  72. package/dist/cli-delegate/cmd_validate.js +6 -6
  73. package/dist/cli-delegate/cmd_versions.js +3 -3
  74. package/dist/discovery/deprecation-report.md +1 -1
  75. package/dist/discovery/discovery-manifest.json +83 -30
  76. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  77. package/dist/discovery/discovery-manifest.summary.md +4 -4
  78. package/dist/discovery/dormancy-report.md +1 -1
  79. package/dist/discovery/orphan-report.md +1 -1
  80. package/dist/discovery/packs.json +11 -9
  81. package/dist/discovery/trust-report.md +2 -2
  82. package/dist/discovery/workspaces.json +9 -7
  83. package/dist/hooks/dispatch.js +1295 -812
  84. package/dist/install/globalRuleLayers.js +169 -0
  85. package/dist/install/globalRuleLayers.js.map +1 -0
  86. package/dist/install/partitionEligibility.js +156 -0
  87. package/dist/install/partitionEligibility.js.map +1 -1
  88. package/dist/install/ruleLayerPartition.js +157 -0
  89. package/dist/install/ruleLayerPartition.js.map +1 -0
  90. package/dist/mcp/registry-manifest.json +3 -3
  91. package/dist/mcp/server.json +2 -2
  92. package/dist/mcp/server.mjs +1358 -805
  93. package/dist/scripts/_lib/claude_plugin.js +162 -0
  94. package/dist/scripts/_lib/claude_plugin.js.map +1 -0
  95. package/dist/scripts/_lib/environment_detector.js +397 -0
  96. package/dist/scripts/_lib/environment_detector.js.map +1 -0
  97. package/dist/scripts/_lib/prune_empty_dirs.js +85 -0
  98. package/dist/scripts/_lib/prune_empty_dirs.js.map +1 -0
  99. package/dist/scripts/_lib/spawn_env.js +129 -0
  100. package/dist/scripts/_lib/spawn_env.js.map +1 -0
  101. package/dist/scripts/ai_council/modes.js +199 -0
  102. package/dist/scripts/ai_council/modes.js.map +1 -0
  103. package/dist/scripts/ai_council/transport_resolver.js +418 -0
  104. package/dist/scripts/ai_council/transport_resolver.js.map +1 -0
  105. package/dist/scripts/condense.js +52 -89
  106. package/dist/scripts/condense.js.map +1 -1
  107. package/dist/server/routes/wizard.js +3 -2
  108. package/dist/server/routes/wizard.js.map +1 -1
  109. package/dist/ui/assets/index-Cxgy63kz.js +26 -0
  110. package/dist/ui/assets/index-Cxgy63kz.js.map +1 -0
  111. package/dist/ui/index.html +1 -1
  112. package/docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +45 -1
  113. package/docs/guidelines/agent-infra/false-green.md +47 -1
  114. package/docs/guidelines/agent-infra/traceability-field-mechanics.md +50 -0
  115. package/docs/guidelines/agent-infra/untrusted-input-spotlighting.md +17 -0
  116. package/package.json +7 -3
  117. package/src/agent-src/scripts/archive_completed_roadmaps.ts +7 -4
  118. package/src/agent-src/scripts/dashboard_mode.ts +212 -0
  119. package/src/agent-src/scripts/update_roadmap_progress.ts +47 -48
  120. package/src/config/ci-local-parity.yml +21 -0
  121. package/src/config/estate-count-budget.json +13 -471
  122. package/src/config/evaluator-budgets.json +4 -4
  123. package/src/config/gate-coverage.yml +458 -12
  124. package/src/config/gate-violation-baselines.json +18 -8
  125. package/src/config/gitignore-block.txt +15 -2
  126. package/src/config/hook-latency-budget.json +5 -0
  127. package/src/config/publish-surface.json +60 -0
  128. package/src/config/requirements-trace-budget.json +32 -0
  129. package/src/config/rule-stub-ceilings.json +25 -4
  130. package/src/install/globalRuleLayers.ts +197 -0
  131. package/src/install/partitionEligibility.ts +177 -0
  132. package/src/install/ruleLayerPartition.ts +212 -0
  133. package/src/scripts/_cli/cmd_adr_effective.ts +484 -0
  134. package/src/scripts/_dispatch.bash +18 -0
  135. package/src/scripts/_lib/adr_frontmatter.test.ts +365 -0
  136. package/src/scripts/_lib/adr_frontmatter.ts +459 -0
  137. package/src/scripts/_lib/base_tree.ts +175 -0
  138. package/src/scripts/_lib/billing_grant.ts +165 -0
  139. package/src/scripts/_lib/billing_grant_cli.ts +123 -0
  140. package/src/scripts/_lib/council_fallback_posture.ts +53 -6
  141. package/src/scripts/_lib/council_fallback_wiring.ts +61 -1
  142. package/src/scripts/_lib/envelope_grounding.ts +11 -1
  143. package/src/scripts/_lib/host_capability.ts +59 -5
  144. package/src/scripts/_lib/layer_overlap_notice.ts +11 -2
  145. package/src/scripts/_lib/prune_empty_dirs.ts +80 -0
  146. package/src/scripts/_lib/quota_parked.ts +133 -0
  147. package/src/scripts/_lib/retrieval_sanitize.ts +62 -0
  148. package/src/scripts/_lib/review_telemetry.ts +196 -0
  149. package/src/scripts/_lib/subagent_response.ts +92 -0
  150. package/src/scripts/adr/evidence_census.ts +899 -0
  151. package/src/scripts/adr/regenerate_index.ts +25 -38
  152. package/src/scripts/adr_cite_check.ts +540 -39
  153. package/src/scripts/ai_council/clients.ts +12 -1
  154. package/src/scripts/ai_council/config.ts +72 -115
  155. package/src/scripts/ai_council/fallback_config.ts +19 -7
  156. package/src/scripts/ai_council/mid_flight_fallback.ts +88 -7
  157. package/src/scripts/ai_council/orchestrator.ts +2 -2
  158. package/src/scripts/ai_council/py_format.ts +124 -0
  159. package/src/scripts/ai_council/transport_resolver.ts +65 -2
  160. package/src/scripts/audit_adr_coverage.ts +134 -21
  161. package/src/scripts/bench_hook_latency.ts +204 -0
  162. package/src/scripts/build_archive_index.ts +34 -0
  163. package/src/scripts/check_adr_frontmatter.ts +574 -39
  164. package/src/scripts/check_council_pin_staleness.ts +300 -0
  165. package/src/scripts/check_estate_count.ts +420 -293
  166. package/src/scripts/check_gate_coverage.ts +91 -0
  167. package/src/scripts/check_hook_bundle_content.ts +219 -0
  168. package/src/scripts/check_new_adr_evidence.ts +529 -0
  169. package/src/scripts/check_no_stub_inventory_table.ts +292 -0
  170. package/src/scripts/check_pack_size.ts +234 -1
  171. package/src/scripts/check_publish_surface.ts +297 -0
  172. package/src/scripts/check_references.ts +18 -0
  173. package/src/scripts/check_requirements_trace.ts +378 -0
  174. package/src/scripts/check_rule_layer_partition.ts +531 -0
  175. package/src/scripts/check_secret_leak.ts +166 -12
  176. package/src/scripts/check_single_delivery.ts +137 -4
  177. package/src/scripts/check_standing_rule_delivery.ts +8 -2
  178. package/src/scripts/code_graph/cli.ts +44 -5
  179. package/src/scripts/code_graph/extract.ts +87 -0
  180. package/src/scripts/condense.ts +61 -91
  181. package/src/scripts/council_cli.ts +12 -16
  182. package/src/scripts/detect_ai_tells.ts +87 -0
  183. package/src/scripts/dispatch_r2_reviewer.ts +42 -0
  184. package/src/scripts/external_sources_denylist.json +4 -1
  185. package/src/scripts/generate_capabilities_index.ts +41 -0
  186. package/src/scripts/git_authorization_hook.ts +54 -4
  187. package/src/scripts/hooks/block_unauthorized_git.ts +41 -3
  188. package/src/scripts/hooks/dispatch_hook.ts +154 -187
  189. package/src/scripts/hooks/dispatch_issues.ts +38 -19
  190. package/src/scripts/hooks/fallback_yaml.ts +66 -0
  191. package/src/scripts/hooks/host_semantics.ts +21 -0
  192. package/src/scripts/hooks/injection_budget.ts +13 -3
  193. package/src/scripts/hooks/py_json_dumps.ts +103 -0
  194. package/src/scripts/hooks/run_continuation_hook.ts +3 -1
  195. package/src/scripts/hooks/state_io.ts +88 -1
  196. package/src/scripts/hooks/stdin_failure_policy.ts +96 -0
  197. package/src/scripts/hooks/subagent_ledger_hook.ts +76 -11
  198. package/src/scripts/injection_scan_hook.ts +257 -15
  199. package/src/scripts/lint_adr_sweep_routing.ts +365 -0
  200. package/src/scripts/lint_hook_manifest.ts +49 -0
  201. package/src/scripts/lint_provenance_vocabulary.ts +472 -4
  202. package/src/scripts/lint_workflow_security.ts +53 -10
  203. package/src/scripts/lint_workflow_security_allowlist.json +2 -18
  204. package/src/scripts/report_envelope_rate.ts +166 -0
  205. package/src/scripts/review_axis_report.ts +218 -0
  206. package/src/scripts/routing_doctor.ts +5 -1
  207. package/src/scripts/run_supervise.ts +46 -1
  208. package/src/scripts/schemas/evals.schema.json +5 -0
  209. package/src/scripts/sync_pr_branch.ts +170 -20
  210. package/dist/cli/commands/commands.candidates.test.js +0 -257
  211. package/dist/cli/commands/commands.candidates.test.js.map +0 -1
  212. package/dist/cli/commands/profiles.test.js +0 -88
  213. package/dist/cli/commands/profiles.test.js.map +0 -1
  214. package/dist/cli/commands/recordTriggerEval.test.js +0 -113
  215. package/dist/cli/commands/recordTriggerEval.test.js.map +0 -1
  216. package/dist/cli/configRoot.test.js +0 -97
  217. package/dist/cli/configRoot.test.js.map +0 -1
  218. package/dist/cli/mcp/content.test.js +0 -54
  219. package/dist/cli/mcp/content.test.js.map +0 -1
  220. package/dist/cli/mcp/dispatch.test.js +0 -108
  221. package/dist/cli/mcp/dispatch.test.js.map +0 -1
  222. package/dist/server/writeRoot.test.js +0 -91
  223. package/dist/server/writeRoot.test.js.map +0 -1
  224. package/dist/shared/capabilities.test.js +0 -39
  225. package/dist/shared/capabilities.test.js.map +0 -1
  226. package/dist/ui/assets/index-C1pBRm1f.js +0 -26
  227. package/dist/ui/assets/index-C1pBRm1f.js.map +0 -1
  228. package/dist/cli-delegate/{chunk-PPQO4NGR.js → chunk-6RJA2F5A.js} +3 -3
  229. package/dist/cli-delegate/{chunk-6EOCNQAM.js → chunk-E4XIZDIB.js} +0 -0
  230. package/dist/cli-delegate/{chunk-GJ5BVHXM.js → chunk-PMEKGDED.js} +3 -3
@@ -100,6 +100,83 @@ provenance before treating a `false` as a host limitation: on an unrecognized
100
100
  host every field is `default`, which is an absence of knowledge and not a
101
101
  measurement.
102
102
 
103
+ ## Observation protocol — what may be written into a registry row
104
+
105
+ **Added 2026-08-22** (`road-to-host-capability-observations` Phase 1). The
106
+ registry held **one** row while **eight** platform keys were declared, so on
107
+ seven hosts every field was the safe default — and `false` carried two meanings
108
+ at once. This protocol is what makes them distinguishable.
109
+
110
+ ```
111
+ A ROW IS WRITTEN FROM AN OBSERVATION IN A REAL SESSION, NEVER FROM THE HOST'S
112
+ DOCUMENTATION. A CAPABILITY THAT EXISTS ON PAPER AND NOT IN THE SESSION PRODUCES
113
+ A ROUTING DECISION THAT FAILS SILENTLY.
114
+ ```
115
+
116
+ **This is a written criterion a human applies, and deliberately not a script.**
117
+ A prober that decides for itself what counts as evidence is the inference
118
+ `host_capability.ts` already forbids, wearing an executable's authority.
119
+
120
+ ### Per-field criterion — each one transcript-observable
121
+
122
+ | Field | What counts as an observation |
123
+ |---|---|
124
+ | `subagent_spawn` | a dispatch record showing a **child leg with its own turn** — a start and a stop that pair, so the child's duration is measurable rather than inferred |
125
+ | `parallel_spawn` | **two child legs whose intervals overlap** — concurrently open children at one instant, not two children in sequence |
126
+ | `status_polling` | a **completed poll returning a state the parent did not already hold**. A poll that returns what the parent knew is not an observation of polling |
127
+ | `separate_quota_pool` | a **child leg continuing across a parent quota condition** — the parent constrained, the child proceeding |
128
+ | `worker_respawn` | **one task continuing across a killed and re-spawned worker, same task id.** Never inferred from the fact that spawning and killing both exist separately |
129
+
130
+ ### `agent_teams` is out of scope for a row, by construction
131
+
132
+ It is resolved **only** by the live environment probe and is never inferred from
133
+ a host id — `host_capability.ts` states that in the field's own doc comment, and
134
+ records that this repository has observed the flag's documented existence and
135
+ never its shape on any host. So: do not add it to a registry row. Observe it, if
136
+ at all, through the live probe.
137
+
138
+ ### Observed-absent is not the same row as never-looked
139
+
140
+ Both render as `false`, and collapsing them is the defect this protocol opens
141
+ against — a reader then cannot tell whether a capability was tested.
142
+
143
+ - **Never looked** — the field is **absent from the row**. It resolves to the
144
+ safe default, and `describeHostCapabilities` reports its source as `default`.
145
+ This is the state that needs no marker, because the absence *is* the record.
146
+ - **Observed absent** — the field is present and `false`, and carries a
147
+ `<field>_absent` citation in the same doc comment. Present-and-`false` is the
148
+ marker: it is only reachable by someone who wrote it deliberately, and the
149
+ provenance surface then reports `registry` rather than `default` — which is
150
+ exactly the distinction, readable from `routing:doctor` without opening the
151
+ file.
152
+
153
+ ### The four-part citation — a row without all four is not admissible
154
+
155
+ 1. **the host** — the platform key from `hook_manifest.yaml`;
156
+ 2. **the host version** at the time of observation;
157
+ 3. **the transcript or artefact reference** the observation is read from;
158
+ 4. **the date**.
159
+
160
+ Worked example, which a later row can be pattern-matched against:
161
+
162
+ ```
163
+ // subagent_spawn: OBSERVED — claude (Claude Code, Opus 5 1M session, 2026-08-22)
164
+ // agents/runtime/state/subagent-ledger/2026-08.jsonl: 445 `subagent_start`
165
+ // records and 420 stops carrying a measured `duration_ms`, i.e. 420 child legs
166
+ // whose start and stop pair. A measurable child duration is the criterion.
167
+ ```
168
+
169
+ ### Pre-state, pinned so the Phase 2 diff reads as an addition
170
+
171
+ At the commit this protocol landed on, the registry was exactly:
172
+
173
+ ```ts
174
+ const HOST_CAPABILITY_REGISTRY = { claude: { subagent_spawn: true, parallel_spawn: true } };
175
+ ```
176
+
177
+ One host, two fields. Six fields across seven other hosts resolved to the
178
+ all-`false` safe default.
179
+
103
180
  ## Related
104
181
 
105
182
  - [`subagent-configuration`](../subagent-configuration.md) — the `subagents.*`
@@ -4,8 +4,8 @@ Loaded by [`roadmap-process-loop § 3`](roadmap-process-loop.md) when the run's
4
4
  **derived** mode is `autonomous` or `phase-checkpoints`. The mode comes from the
5
5
  § 3a ladder — explicit invocation suffix, then frontmatter `execution.mode`,
6
6
  then the invocation form — so an ABSENT frontmatter field no longer keeps this
7
- context unloaded: under `process-full` / `/roadmap:next` it derives
8
- `autonomous`, under `process-phase` it derives `phase-checkpoints`. Only a
7
+ context unloaded: under `process-full` it derives `autonomous`, and under
8
+ `/roadmap:next` or `process-phase` it derives `phase-checkpoints`. Only a
9
9
  *derived* `interactive` (asked for explicitly, declared in frontmatter, or
10
10
  `process-step`) leaves this context unloaded and falls back to the legacy
11
11
  commit-step scan. Defines the run-start pre-scan,
@@ -78,6 +78,8 @@ Artifacts: <N> planned (skills/rules/commands/guidelines) —
78
78
  Open questions: <N> → decision sheet below (<M> rows); the rest via AI
79
79
  council (<members | "none configured — will halt on ambiguity">)
80
80
  Quality: <cadence> · Dashboard: <cadence>
81
+ Late artifacts: <halt | auto-research> (default halt; cap 3 then halt)
82
+ Deferred items: <wait | spawn-follow-up-draft | cancel-with-memo> (default wait)
81
83
 
82
84
  <decision sheet, per contract-decision-sheet — omitted entirely when M = 0>
83
85
 
@@ -97,6 +99,102 @@ re-ask inside the run. Adjust → apply, re-show once. The contract is
97
99
  re-derived on every invocation — it always reflects the roadmap's and
98
100
  repo's current state.
99
101
 
102
+ ### 2a. `late_artifacts` — what happens to an artifact the plan did not name
103
+
104
+ An artifact discovered **after** Accept was outside the batched overlap check,
105
+ so the research the contract summary reported does not cover it. Two policies,
106
+ and the field is on the screen because the choice changes what the run may do
107
+ without asking:
108
+
109
+ | Value | Behaviour |
110
+ |---|---|
111
+ | `halt` (**default**) | The run stops at the discovery with the scope-out-of-roadmap halt. The artifact is reported, not authored. |
112
+ | `auto-research` | The run re-runs Phase B (Research) and the overlap pass mid-run against the *current* artifact state — the identical procedure already accepted as non-interactive at contract time, only later. An **extend** verdict extends silently; a **create** verdict derives its understand-answers from the step text and the sheet answers; only a genuine overlap conflict halts. Capped at **three** late artifacts per run, then halt regardless. |
113
+
114
+ <!-- decision 2026-08-20: the shipped default is `halt`, not `auto-research`.
115
+ AI council 2/2 (anthropic + openai) on the `autonomy-defaults-sheet` fork
116
+ of road-to-user-out-of-the-loop, record
117
+ agents/evidence/council/drain-blocker-dispositions-a.md. Reasoning: the
118
+ roadmap's own Risk 7 is that auto-research drifts the run's scope, and its
119
+ stated mitigation is the cap — but a cap of three is a bound on how far the
120
+ drift goes, not a check on whether it should happen at all. `halt` is also
121
+ the behaviour the tree already had, so shipping it as the default means
122
+ this field is purely additive: nothing that worked before changes, and the
123
+ aggressive path becomes a thing a run declares rather than a thing it
124
+ inherits. Reversibility: flipping the default is one word in this table
125
+ plus one word in the mechanics guideline, with no dependent mechanism to
126
+ unwind, and the roadmap's own kill criterion (late-artifact revisit rate)
127
+ only becomes measurable once some runs declare `auto-research` — which an
128
+ opt-in still permits and a silent default would have made unattributable. -->
129
+
130
+ The cap is not negotiable by the field: a run that keeps discovering artifacts
131
+ has a planning problem, not an autonomy problem, and the third discovery is the
132
+ signal to say so.
133
+
134
+ ### 2b. `deferred_policy` — the two autonomous exits for a `[~]` item
135
+
136
+ [`roadmap-progress-sync`](../../rules/roadmap-progress-sync.md) Iron Law 3
137
+ forbids a silent archive with unresolved deferred items. That gate is
138
+ unchanged. What this field changes is which dispositions a run may reach
139
+ **without a synchronous prompt**, and there are exactly two, because the
140
+ preservation test in that rule already splits them the same way:
141
+
142
+ | Value | Behaviour |
143
+ |---|---|
144
+ | `wait` (**default**) | The synchronous halt stands. Every disposition stays conversational. |
145
+ | `spawn-follow-up-draft` | A roadmap closing with `[~]` items spawns the follow-up draft automatically, carrying each item **and** its blocker. The item stays alive in the active estate, which is what makes this council-decidable rather than owner-reserved. |
146
+ | `cancel-with-memo` | An item the run can show is no longer wanted is recorded `[-]` with a reasoning memo naming what changed. This is a **drop**, so it is owner-reserved by the preservation test: the run WRITES the memo and the recommendation, and the archive still waits for the user on that item. |
147
+
148
+ <!-- decision 2026-08-20: the policy offers BOTH exits — a follow-up draft and
149
+ an explicit cancellation with a reasoning memo — not the follow-up draft
150
+ alone. AI council 2/2 (anthropic + openai), same record as above.
151
+ Reasoning: follow-up-draft-only means every deferred item must be carried,
152
+ and a carried item nobody wants becomes the parking lot the roadmap's own
153
+ Risk 5 describes for memos. Offering cancellation makes "this is no longer
154
+ wanted" a statable outcome with a written reason instead of an indefinite
155
+ deferral wearing a follow-up roadmap. Reversibility, and it is the load-
156
+ bearing half: the cancellation exit does NOT lower the gate, because a
157
+ drop stays owner-reserved — the run produces the memo, the user still
158
+ decides. Removing the value later removes an option nobody was obliged to
159
+ use; the default stays `wait` either way. -->
160
+
161
+
162
+ ### 2c. `traceability` — requirement to acceptance to evidence, OPTIONAL
163
+
164
+ **Optional for every complexity, including `structural`.** Absent means *not
165
+ declared*, which is a different claim from "there is no requirement". Nothing
166
+ fails for omitting it, and no gate enforces it — the only consumer is a listing
167
+ inventory (`check_requirements_trace`) that exits 0 always. Requiredness is
168
+ deliberately **not** decided here (AI council 2/2, 2026-08-22): deciding it
169
+ before the listing phase has produced a count is deciding it on intuition.
170
+
171
+ A repeated **row**, not three flat fields:
172
+
173
+ ```yaml
174
+ traceability:
175
+ - requirement_id: pointer-reaches-the-worker
176
+ acceptance_id: pointer-under-line-cap
177
+ evidence_refs:
178
+ - src/scripts/dispatch_r2_reviewer.ts
179
+ ```
180
+
181
+ Three flat top-level fields would be **countable but not traceable**: with more
182
+ than one requirement and a shared pool of refs the relation is an ambiguous
183
+ many-to-many, so a gate could report a populated count while providing no
184
+ dependable trace. The row carries the relation.
185
+
186
+ Both grammars are reused, never invented — the claim-ledger kebab slug
187
+ (`docs/CLAIMS.md` § Entry schema) for the two ids, and the envelope ref-token
188
+ rule (`_lib/subagent_response.ts`) for `evidence_refs`: ref tokens, never
189
+ bodies.
190
+
191
+ Identity semantics, revision semantics, the three senses of "gate" and the
192
+ `[AC:<id>]` convention — including the verified fact that nothing parses
193
+ `verify:` lines structurally today — are in
194
+ [`guideline:agent-infra/traceability-field-mechanics`](../../../../docs/guidelines/agent-infra/traceability-field-mechanics.md).
195
+ They are not optional reading: a slug grammar does not imply a namespace, and
196
+ `evidence_refs` are syntactically safe tokens rather than verified evidence.
197
+
100
198
  ## 3. Grants activated by acceptance
101
199
 
102
200
  | Grant | Boundary |
@@ -112,7 +112,8 @@ Rung 3, by wrapper:
112
112
 
113
113
  | Wrapper | Derived mode | Contract |
114
114
  |---|---|---|
115
- | `/roadmap:process-full`, `/roadmap:next` | `autonomous`, **preselected** | offered |
115
+ | `/roadmap:process-full` | `autonomous`, **preselected** | offered |
116
+ | `/roadmap:next` | `phase-checkpoints`, **preselected** | offered |
116
117
  | `/roadmap:process-phase` | `phase-checkpoints` | offered |
117
118
  | `/roadmap:process-step` | — | none (one step needs no run contract) |
118
119
 
@@ -122,6 +123,25 @@ screen's `3. Run interactive instead` option
122
123
  ([`roadmap-execution-contract § 2`](roadmap-execution-contract.md)) stays on it
123
124
  in every case, so a derived mode is always one keystroke from being refused.
124
125
 
126
+ <!-- decision 2026-08-20: /roadmap:next preselects `phase-checkpoints`, not
127
+ `autonomous`. AI council 2/2 (anthropic + openai) on the
128
+ `autonomy-defaults-sheet` fork of road-to-user-out-of-the-loop, record
129
+ agents/evidence/council/drain-blocker-dispositions-a.md. Reasoning: the two
130
+ wrappers differ in what the user has actually seen at Accept time.
131
+ `process-full` names one roadmap the user chose, so `autonomous` is a
132
+ preselection over a scope they read. `/roadmap:next` SELECTS the roadmap
133
+ itself, so `autonomous` there preselects full autonomy over a target the
134
+ user has not seen — the one rung where the derivation picks the object and
135
+ the scope in the same keystroke. Reversibility: this is a preselected
136
+ option on a screen that still offers `1. Go — start processing
137
+ autonomously`, so the aggressive path costs one keystroke and no rebuild;
138
+ flipping the row back is a one-line edit with no dependent mechanism.
139
+ Deliberately scoped to `/roadmap:next` only — the blocker's question named
140
+ that wrapper, and Phase 1 Step 1 of the parent roadmap landed with
141
+ `process-full` → `autonomous` explicitly, so widening the change would
142
+ silently reverse an already-shipped step nobody asked to revisit. -->
143
+
144
+
125
145
  **Why the old fallback was a defect and not a conservative default.** Absent
126
146
  `execution.mode` used to mean the legacy commit-step scan, which derives no
127
147
  contract at all — no batched artifact drafting, no council auto-enable, no
@@ -132,6 +152,23 @@ path *under the wrapper built for the opposite*, and silently — the user saw a
132
152
  A default that contradicts the wrapper the user just typed is a wrong answer,
133
153
  not a safe one.
134
154
 
155
+ **Kill criteria — carried here, at the flip, not only in the roadmap that
156
+ made it.** A default flip whose reversal condition lives in a roadmap is a
157
+ flip nobody can reverse once that roadmap is archived, which is why both
158
+ conditions below sit next to the table they govern:
159
+
160
+ - **The ladder itself** (absent `execution.mode` derives a mode instead of
161
+ falling back to interactive): `3. Run interactive instead` chosen at the
162
+ contract screen in **more than 40 % of 20 runs** reverts rung 3, leaving
163
+ the ladder at explicit-suffix-then-frontmatter only. **No instrument
164
+ today** — nothing records which contract option was chosen, so the rate is
165
+ unmeasured rather than low. Stated so the gap is visible at the flip.
166
+ - **The `/roadmap:next` row** (`phase-checkpoints` rather than
167
+ `autonomous`): reverted if checkpoint-mode runs on that wrapper are
168
+ observed to stop at a phase boundary the user then waves through without
169
+ a change — that is a contact the preselection bought nothing for. Same
170
+ missing instrument, same honesty: this is a condition, not a reading.
171
+
135
172
  **What this does NOT change.** A derived mode grants nothing on its own:
136
173
  authorization is still the single Accept on the contract screen, per
137
174
  [`roadmap-execution-contract § Principle`](roadmap-execution-contract.md). The
@@ -260,6 +297,89 @@ run can simply outlast, or a cross-roadmap dependency the run can satisfy itself
260
297
  is work. The taxonomy still lacks the row; the mislabel now has a stated test
261
298
  instead of a default.
262
299
 
300
+ ### 3d. Set contract — one contract over an enumerated set
301
+
302
+ A **set contract** is the ordinary contract screen rendered over a closed,
303
+ ordered list of roadmaps instead of one. It grants
304
+ [`autonomy-mechanics § Task-scope`](autonomy-mechanics.md)'s **set-scoped**
305
+ shape, whose four conditions (enumerated before Accept · closed · ordered with
306
+ independence declared · one Accept) are the authorization contract — this
307
+ section is only the loop's side of it.
308
+
309
+ **What the screen must print, per member.** Roadmap path, derived branch name,
310
+ open-step count, artifact count from the pre-scan, and its dependency edges.
311
+ One decision sheet spans the whole set: a question that applies to several
312
+ members appears once, and its answer applies to all of them.
313
+
314
+ **Dependency edges come from two sources, unioned.**
315
+
316
+ | Source | Shape | Trust |
317
+ |---|---|---|
318
+ | Declared | `depends:` in the dependent roadmap's frontmatter — a list of roadmap slugs | authoritative; a declared edge is never overridden by the heuristic |
319
+ | Inferred | **file overlap**: the intersection of the owned-path sets the two pre-scans derived | advisory; an inferred edge orders the members and marks them non-parallelizable, and is printed as inferred so the user can see why |
320
+
321
+ The union feeds exactly two decisions and nothing else: **ordering** (a
322
+ dependent member runs after its parent) and **parallelizability** (only members
323
+ with no edge between them and disjoint owned paths are lane candidates). An
324
+ inferred edge is deliberately allowed to be wrong in the conservative
325
+ direction — a false edge costs serial execution, a missed edge costs a
326
+ collision, so overlap resolves toward *serial*.
327
+
328
+ #### Auto-continuity — the next member needs no new contact
329
+
330
+ Under an accepted set contract, when a member closes **green** the loop pulls
331
+ the next member whose dependencies are all satisfied and starts it without a
332
+ new contact. Green means: its own final report ran, its quality cadence passed,
333
+ and no halt class fired. Anything else is not green and does not continue —
334
+ see failure isolation below.
335
+
336
+ The default stays **this one only**: auto-continuity applies to
337
+ `/roadmap:next` and to any wrapper reaching this section **only when the set
338
+ option was chosen on the sheet**. A single-roadmap invocation is never widened
339
+ into a set because more roadmaps happened to be open, which is condition 4 of
340
+ the set-scoped shape read from the loop's side.
341
+
342
+ #### Failure isolation — a regression halts its own member, not the set
343
+
344
+ A quality regression, a failed verify probe, or a halt class firing inside one
345
+ member terminates **that member** and leaves the rest of the set running:
346
+
347
+ 1. Record the member's outcome as halted, with the halt class and the evidence.
348
+ 2. Skip every member that declares a dependency on it — transitively. A
349
+ dependent member of a halted parent is *blocked*, not failed, and is
350
+ reported as such.
351
+ 3. Continue with the next independent member.
352
+ 4. Report every member's outcome in one final report at the end of the set.
353
+
354
+ Two carve-outs, and they are the reason this is isolation rather than
355
+ tolerance. A **Hard-Floor** stop and a **locked decision class** stop the whole
356
+ set, not one member: both are about the user's authority rather than about the
357
+ member's code, and continuing past them under a set contract would be exactly
358
+ the "several authorizations from one Accept" failure the enumeration guards
359
+ against. Likewise the **N=3 validation budget** is per validation target and is
360
+ not reset by moving to the next member.
361
+
362
+ #### Parallel lanes — the shape, and why they are not on yet
363
+
364
+ Lanes are **staged**, not shipped: the gate is ten clean serial set runs, and
365
+ that gate has not been reached because no set run has happened. Recorded here
366
+ so the shape is settled before the runs rather than designed under pressure:
367
+
368
+ - **Cap: two lanes** in the first iteration — a recorded decision
369
+ (`decision 2026-08-20`, AI council 2/2 on the `autonomy-defaults-sheet`
370
+ fork), chosen over the configured `subagents.max_parallel` because a
371
+ collision at two lanes is diagnosable and one at N is not. Reversible: the
372
+ cap is one number in the set contract, and raising it after the first ten
373
+ clean parallel runs is strictly cheaper than recovering from a lost branch.
374
+ - **Candidate test:** no dependency edge in either direction, and disjoint
375
+ owned paths.
376
+ - **Isolation:** the existing worktree scope lock
377
+ ([`worktree-lifecycle`](../../skills/worktree-lifecycle/SKILL.md)).
378
+ - **Coordination:** session-register branch claims, so two sessions never share
379
+ a branch.
380
+ - **Delivery:** one branch and one PR per lane.
381
+ - **Immediate removal:** a single scope-lock collision with data loss.
382
+
263
383
  ## 4. Resolve cadences — read once, cache for the run
264
384
 
265
385
  Read both keys from `.agent-settings.yml` once and cache for the whole
@@ -414,7 +534,39 @@ For each open step in the working set (scope-bound — see wrapper):
414
534
  Empty output → Iron Law 2 was violated this iteration: the step
415
535
  landed work but no checkbox flipped. **Halt loudly**, surface
416
536
  "step <N> landed without checkbox flip — flip then resume", and
417
- stop the run. Do not auto-fix; the user resumes on the next turn.
537
+ stop the run. Outside an accepted contract: do not auto-fix; the user
538
+ resumes on the next turn. Inside one: exactly one self-fix attempt, under
539
+ the four preconditions below.
540
+
541
+ **One deterministic self-fix, contract mode only.** A forgotten flip is the
542
+ one halt class whose repair is mechanical — the work is on disk, the step is
543
+ named, and the glyph follows from the outcome. Halting a contract run on it
544
+ spends a user contact to retype something the run can derive. So inside an
545
+ accepted contract the run may attempt the flip **once**, and only when all
546
+ four hold:
547
+
548
+ 1. **The work is citable.** The step's landed change is identifiable in this
549
+ iteration's own output — a diff, a file path, a command result. No
550
+ evidence, no flip: that is a genuine halt, not a forgotten one.
551
+ 2. **The glyph is unambiguous.** `[x]` only for a step whose evidence is
552
+ present and, where the step carries a `verify:` field, whose fresh green
553
+ run is in this reply. Anything that would be `[~]` or `[-]` is a
554
+ *disposition*, never a repair — those halt exactly as before, because a
555
+ deferral and a cancellation are decisions.
556
+ 3. **Exactly one attempt, per run.** Not per step. A second forgotten flip
557
+ in the same run halts: one is a slip, two is a broken loop, and the
558
+ difference is the whole justification for allowing the first.
559
+ 4. **The attempt is verified, then re-guarded.** Re-run the
560
+ `git status --porcelain` probe above after the flip. Still empty → halt
561
+ loudly as before. A self-fix that cannot prove itself is
562
+ indistinguishable from the failure it was repairing.
563
+
564
+ The attempt is recorded as a decision memo (§ 4 handling), so an auto-flip is
565
+ reviewable after the fact rather than invisible. **Kill criterion, from the
566
+ originating roadmap and repeated here because a flip is a write to the source
567
+ of truth: one wrong auto-flip removes this allowance** and returns the guard
568
+ to halt-always. Reversibility is the deletion of this block — the guard
569
+ underneath it never changed.
418
570
 
419
571
  This guard is the deterministic counterpart to the rule's
420
572
  pre-send self-check — it catches a forgotten flip per step, not
@@ -31,6 +31,86 @@ orchestrator synthesises and re-verifies.
31
31
  chars (~3k tokens against a measured ~251k spawn floor). Constants + checks:
32
32
  `src/scripts/_lib/subagent_response.ts`.
33
33
 
34
+ ## The canonical shape, and the three-way divergence it resolves
35
+
36
+ **Reconciled 2026-08-22** (`road-to-subagent-envelope-adoption` Phase 0, AI
37
+ council 2/2 convergent). One contract existed in three mutually inconsistent
38
+ states, and the ledger's `0 valid envelopes of 1,845 stops` could not be cited
39
+ as evidence about any one of them, because a reader had to assume which.
40
+
41
+ ```
42
+ THE BODY SCHEMA IS `validateResponse`'S FIVE REQUIRED FIELDS. PRODUCERS CONVERGE
43
+ ON IT; THE VALIDATOR IS NOT WIDENED TO THE UNION OF WHAT PRODUCERS HAPPEN TO SEND.
44
+ ```
45
+
46
+ Direction chosen: **narrow the contract to what the validator already accepts**,
47
+ not widen the validator. Widening makes every future divergence legal by
48
+ construction, which is how one contract came to have three states.
49
+
50
+ ### Per-field divergence, one row per field
51
+
52
+ | Field | spawn-contract (f) | `team_dispatch` model JSON (`:297`) | `subagent_response.ts` validator | `dispatch_r2_reviewer` |
53
+ |---|---|---|---|---|
54
+ | `summary` | — (not a field clause) | present | **required** | silent |
55
+ | `handoff` | — | **absent** | **required** | silent |
56
+ | `confidence` | — | **absent** | **required** (`low\|medium\|high`) | silent |
57
+ | `findings` | — | present, `{severity, evidence, suggested_fix, location}` | **required**, `{title, evidence_refs?, mutating?}` | silent |
58
+ | `risks` | — | **absent** | **required** | silent |
59
+ | `artifact_paths` | — | absent | optional | silent |
60
+ | `assumptions` | — | absent | optional | silent |
61
+ | `status` | — | present, 3 model values | **not a body field** | silent |
62
+
63
+ An empty cell is a finding, not a pass. `dispatch_r2_reviewer` is silent on
64
+ every row — 1,292 lines with **0** hits for `envelope`, `DONE_WITH_CONCERNS`,
65
+ `response.contract` or `response_contract`.
66
+
67
+ ### Four boundaries, because "the contract" was conflating them
68
+
69
+ The council's sharpest correction: schema, lifecycle state, delivery and
70
+ classification were being treated as one thing.
71
+
72
+ 1. **Body schema** — the five required fields above, plus the two optional ones.
73
+ 2. **Lifecycle frame** — `DONE` / `DONE_WITH_CONCERNS` / `NEEDS_CONTEXT` from a
74
+ model, plus `BLOCKED` orchestrator-side only (`team_dispatch.ts:391`'s
75
+ `_MODEL_STATUSES` is the three-value set a model may send). **Not a body
76
+ field**, which is why narrowing the body does not delete it.
77
+ 3. **Delivery protocol** — serialize once, persist that exact serialization,
78
+ then emit the identical value as the final text-only message. This is
79
+ spawn-contract rule (f), and it **survives the narrowing**: its two clauses
80
+ are delivery invariants, not fields, so they were never candidates for the
81
+ validator's five.
82
+ 4. **Classification** — validate and record against an explicit contract and
83
+ classifier version.
84
+
85
+ ### Who owns the delivery protocol — and it is not the model
86
+
87
+ `team_dispatch.ts:280` asks a **read-only** model with no command or filesystem
88
+ access to return its review JSON. That model **cannot** satisfy "disk copy
89
+ written first", so rule (f) is an impossible prompt obligation for this
90
+ producer. The trusted dispatcher owns it: parse the producer's response, project
91
+ it into the canonical body, add the lifecycle frame, write the durable copy,
92
+ then emit the identical serialized value.
93
+
94
+ Recorded rather than implemented here — the projection adapter is a mechanism
95
+ this roadmap's Phase 1 does not ship, and saying so is cheaper than a contract
96
+ clause nobody can satisfy.
97
+
98
+ ### The validator is not the reason the rate is zero
99
+
100
+ Checked directly on 2026-08-22, because "zero valid envelopes over 1,845 stops"
101
+ has three possible causes and they need separating: a validator that rejects
102
+ valid input, producers that do not emit the fields, or a shape nobody can
103
+ produce.
104
+
105
+ `validateResponse` was run by hand against a minimal envelope
106
+ (`{summary, handoff, confidence, findings: [], risks: []}`) and a rich one
107
+ (with `findings[{title, evidence_refs, mutating}]` and `artifact_paths`).
108
+ **Both validate.** The `team_dispatch` model shape fails on four of five.
109
+
110
+ So the contract is implementable and the validator is correct; the rate is zero
111
+ because producers do not emit the shape. That removes the precondition one
112
+ council seat set before any narrowing.
113
+
34
114
  ## Durable copy — the envelope on disk before the message
35
115
 
36
116
  ```
@@ -55,8 +55,12 @@ Fires once per creation task, not once per edit.
55
55
  - At most two propose → reject cycles; then stop.
56
56
  - Commit only on approval.
57
57
  - Bypass is legitimate — *"just write it"* drops the protocol immediately.
58
+ - An artifact discovered **after** an accepted contract halts by default;
59
+ `late_artifacts: auto-research` is the only declared value that continues,
60
+ capped at three per run (mechanics guideline § Late artifacts).
58
61
 
59
- Body migrated to [`guideline:agent-infra/artifact-drafting-protocol-mechanics`](../docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md) (per P4 of `road-to-kernel-and-router.md`) — Phase A/B/C procedure detail + the roadmap-run batch-mode carve-out (Research-once-at-contract-time, batch scope, no `artifact_protocol: skip`).
62
+ Body migrated to [`guideline:agent-infra/artifact-drafting-protocol-mechanics`](../docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md) (per P4 of `road-to-kernel-and-router.md`) — Phase A/B/C procedure detail + the roadmap-run batch-mode carve-out (Research-once-at-contract-time, batch scope, no `artifact_protocol: skip`) + § Late artifacts (the `halt` default
63
+ and the five-step `auto-research` procedure).
60
64
  Trigger-set above activates this routing on demand, independent of the discipline profile (ADR-110).
61
65
 
62
66
  Extends (cross-link, don't restate): `ask-when-uncertain`,
@@ -39,25 +39,21 @@ THE USER IS REACHED FOR THE RESERVED SET — AND ALWAYS FOR IT.
39
39
  NEVER CITE A LOCK YOU HAVE NOT EVALUATED THIS TURN.
40
40
  ```
41
41
 
42
- An agent that finds a genuinely beneficial change blocked by a recorded
43
- past decision — an honest-null eval verdict, a "don't relitigate"
44
- memory or context note, a token-frugality/budget canon line, or an ADR —
45
- does not quietly comply and drop the change. It surfaces the conflict and
46
- re-evaluates the lock — **in the council by default**, reaching the user only
47
- for the reserved set below. Progress means adaptation: locks encode what was
48
- true when they were written, not a ceiling on what the package may ever become.
42
+ An agent that finds a beneficial change blocked by a recorded decision — an
43
+ honest-null verdict, a "don't relitigate" note, a budget-canon line, or an ADR —
44
+ does not quietly comply and drop it. It surfaces the conflict and re-evaluates
45
+ the lock **in the council by default**, reaching the user only for the reserved
46
+ set below. Locks encode what was true when they were written, not a ceiling on
47
+ what the package may ever become.
49
48
 
50
49
  **The default venue is the council, and this is a correction, not a new
51
- policy.** [`ai-council`](../skills/ai-council/SKILL.md) has said since its own
52
- Iron Law that *"a design decision the agent cannot settle from the tree goes to
53
- the council first, not to the user first"*, and its class table already lists
54
- "reopening a recorded decision". This rule used to say "offers the user a path",
55
- which contradicted that and made every lock an owner interrupt. The measured
56
- cost of the contradiction: across 26 days of transcripts, the agent reported a
57
- lock and waited, and the owner had to void the decision retroactively before the
58
- work resumed — in the two clearest cases the lock report is timestamped **before**
59
- the override demand. The ordering was the defect; the permission was never
60
- missing.
50
+ policy.** [`ai-council`](../skills/ai-council/SKILL.md)'s Iron Law already sends
51
+ a decision the agent cannot settle from the tree to the council first, and its
52
+ class table lists "reopening a recorded decision". The old "offers the user a
53
+ path" wording made every lock an owner interrupt; measured across 26 days of
54
+ transcripts, the agent reported a lock and waited while the owner voided the
55
+ decision retroactively — twice with the lock report timestamped **before** the
56
+ override demand. The ordering was the defect; the permission was never missing.
61
57
 
62
58
  **Mechanism-match check comes FIRST**: a verdict settles the *mechanism it
63
59
  tested*, not every future proposal that resembles it — if the blocked change
@@ -81,20 +77,54 @@ distinction.
81
77
  4. **Route it** — council by default (below), user only for the reserved set.
82
78
  5. **Record** the outcome with scope and `revisit-if`.
83
79
 
84
- These five are the obligation and they are stated here rather than only behind
85
- a route, because the route was measurably unreachable: `decision-revisit-gate`
86
- lives in the always-on `meta` pack while `decision-review` ships
87
- `install.default: false` in the non-default `analysis-workbench` pack, so a
88
- pack-legal install received the obligation and not the procedure. `routes_to`
89
- now names two always-on skills; the backward-audit depth in
90
- [`decision-review`](../skills/decision-review/SKILL.md) stays optional, which is
91
- the correct status for depth.
80
+ The five are stated here, not only behind a route, because the route was
81
+ measurably unreachable: `decision-review` ships `install.default: false` in the
82
+ non-default `analysis-workbench` pack, so a pack-legal install received the
83
+ obligation and not the procedure. `routes_to` now names two always-on skills;
84
+ the backward-audit depth in
85
+ [`decision-review`](../skills/decision-review/SKILL.md) stays optional.
92
86
 
93
87
  Full catalog (honest nulls, don't-relitigate notes, budget-canon lines, ADRs,
94
88
  hard structural caps), the per-step detail, when-NOT-to-fire and the failure
95
89
  modes remain in [`skill:decision-review` § Decision-revisit gate — mechanics](../skills/decision-review/SKILL.md).
96
90
  Trigger-set above activates this routing on demand, independent of the discipline profile (ADR-110).
97
91
 
92
+ ## Reading a lock — the two descriptive axes
93
+
94
+ Step 2 reads, in order: **effective state** (status · amendments · successors) →
95
+ **provenance** → **evidence strength** → **discovery** → **current evidence**
96
+ (does the basis still resolve in a clone?) → **reversibility of the proposed
97
+ transition** → **reserved dimensions**. `adr_cite_check` prints six of them —
98
+ read 6 is the agent's, because reversibility belongs to the proposed transition
99
+ and no tool reading one record supplies it. What each field means, and what a
100
+ `[found]` basis ref does NOT claim, is in that script's module docstring. The
101
+ evidence-priced burden table stays in
102
+ [`adr-layout § The reopen record`](../docs/contracts/adr-layout.md).
103
+
104
+ ```
105
+ A GRADE IS A MEASUREMENT, NOT A PERMISSION — IT GRANTS NOTHING.
106
+ CITING AN E0 LOCK AS A HARD BLOCKER WITHOUT SURFACING ITS GRADE IS A VIOLATION.
107
+ NO GRADE LETS AN AGENT SUPERSEDE A RECORD, SKIP A COUNCIL, OR TAKE ANY ACTION
108
+ IT COULD NOT TAKE YESTERDAY. THE COUNCIL-FIRST VENUE STAYS, AT EVERY GRADE.
109
+ AN ADR'S HISTORICAL DECISION-MAKER DOES NOT DETERMINE ITS REOPEN VENUE.
110
+ A LOW-EVIDENCE RECORD MAY STATE A DECISION; IT DOES NOT ESTABLISH THAT ITS
111
+ ALTERNATIVES REMAIN INVALID.
112
+ ```
113
+
114
+ Venue comes from the proposed transition, the trust boundaries it touches and
115
+ the reserved dimensions below — never from who decided originally, and never
116
+ from a grade. A weak grade changes how much a reopen must **do**, never who may
117
+ do it: `authority_basis: owner_intent` is surfaced with its accumulated cost and
118
+ never overruled, and council agreement never raises `evidence.strength` —
119
+ sources and measurements do.
120
+
121
+ **No E0/E1 agent path is enabled here, and no reading of this rule enables
122
+ one.** Whether an independently validated grade may ever reduce the
123
+ *authorization* burden is an owner-reserved open question — the
124
+ `authority-coupling-decision` blocker — left unanswered because the party
125
+ assigning a grade would be the party gaining authority from it, and would be
126
+ self-classifying the transition as reversible-internal on top.
127
+
98
128
  ## Who decides — the owner-reserved set
99
129
 
100
130
  The discriminator, in one question: **does the proposed transition weaken an
@@ -121,27 +151,24 @@ forever. Availability is `agent-config council:status`, never a project file
121
151
  ([`council-availability`](council-availability.md)).
122
152
 
123
153
  Field on the ADR: `reopen_policy: directional | owner | unclassified`, absent →
124
- **`unclassified`**, which permits council investigation and reversible
125
- experiments and gates only execution of a reserved transition. Absent is
154
+ **`unclassified`** — council investigation and reversible experiments are
155
+ permitted; only execution of a reserved transition is gated. Absent is
126
156
  deliberately not `owner`: with 146 accepted ADRs that default would encode
127
- today's blockage into the new schema. Full contract, the reopen record, and the
157
+ today's blockage into the new schema. Full contract, the reopen record and the
128
158
  precedent-creates-no-authority clause: [`adr-layout § Reopen authority`](../docs/contracts/adr-layout.md).
129
159
 
130
160
  ## See also
131
161
 
132
162
  - [`recurring-criticism`](recurring-criticism.md) — the **other entrance**: this
133
163
  rule fires when a lock blocks a change, that one when the same criticism arrives
134
- again. It reuses the five steps and the owner-reserved table below.
164
+ again. It reuses the five steps and the owner-reserved table above.
135
165
  - [`decision-review`](../skills/decision-review/SKILL.md) — the backward-audit
136
166
  procedure + the migrated gate mechanics.
137
167
  - [`ai-council`](../skills/ai-council/SKILL.md) — the re-evaluation mechanism;
138
168
  owns the convergence-summary scope + `revisit-if` contract.
139
169
  - [`decision-record`](../skills/decision-record/SKILL.md) — forward-flow decision
140
170
  locking; its **§ 4 Lock the choice + consequences** requires the `Revisit-if:`
141
- line that names the reopening condition up front. (This pointer used to cite an
142
- "escalation litmus" heading; `grep` over `src/` + `docs/` returns two hits and
143
- neither is in that file — the heading never existed, so the pointer led
144
- nowhere. Corrected to the section that carries the obligation.)
171
+ line that names the reopening condition up front.
145
172
  - [`token-budget-discipline`](token-budget-discipline.md) — the frugality-canon
146
173
  value-over-budget escalation this rule's budget-lock case defers to.
147
174
  - [`no-cheap-questions`](no-cheap-questions.md) — the question-quality floor a
@@ -164,3 +191,8 @@ plus the curated `dist/agent-src/scripts/` list and is deliberately out of this
164
191
  change. And `docs/decisions/` is projected into no agent-visible tree at all —
165
192
  the agent sees ADR *numbers* cited across rules and skills, almost never ADR
166
193
  *text*. Until that changes, "evaluate before citing" means opening the file.
194
+
195
+ `docs/contracts/` is unprojected on the same terms (`dist/agent-src/` carries no
196
+ `docs/`), so the burden table this rule points at is maintainer-reachable only.
197
+ That is why the reserved-set table above stays here rather than becoming a
198
+ pointer: a consumer install receives these lines and not the contract.