@event4u/agent-config 14.6.0 → 14.8.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 (258) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +255 -145
  3. package/README.md +1 -1
  4. package/dist/agent-src/commands/analyze/inbox.md +264 -10
  5. package/dist/agent-src/commands/analyze.md +1 -1
  6. package/dist/agent-src/commands/evals/git-pr-merge.json +13 -0
  7. package/dist/agent-src/commands/evals/roadmap.json +17 -1
  8. package/dist/agent-src/commands/pr/create.md +14 -2
  9. package/dist/agent-src/commands/pr/merge.md +379 -0
  10. package/dist/agent-src/commands/roadmap/process-full.md +272 -32
  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/roadmap-execution-contract.md +95 -2
  15. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +289 -106
  16. package/dist/agent-src/rules/artifact-drafting-protocol.md +5 -1
  17. package/dist/agent-src/rules/context-hygiene.md +2 -0
  18. package/dist/agent-src/rules/decision-revisit-gate.md +67 -32
  19. package/dist/agent-src/rules/fix-what-you-see.md +108 -0
  20. package/dist/agent-src/rules/no-roadmap-references.md +0 -5
  21. package/dist/agent-src/rules/recurring-criticism.md +110 -0
  22. package/dist/agent-src/rules/roadmap-progress-sync.md +20 -1
  23. package/dist/agent-src/rules/rule-type-governance.md +0 -2
  24. package/dist/agent-src/rules/self-repair-loop.md +17 -0
  25. package/dist/agent-src/rules/skill-quality.md +0 -2
  26. package/dist/agent-src/rules/source-confidentiality.md +37 -7
  27. package/dist/agent-src/scripts/archival_sweep.ts +117 -0
  28. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +26 -7
  29. package/dist/agent-src/scripts/dashboard_mode.ts +212 -0
  30. package/dist/agent-src/scripts/gate_budget.ts +282 -0
  31. package/dist/agent-src/scripts/gate_execute.ts +72 -31
  32. package/dist/agent-src/scripts/roadmap_gates.ts +74 -3
  33. package/dist/agent-src/scripts/update_roadmap_progress.ts +296 -53
  34. package/dist/agent-src/skills/adr-create/SKILL.md +124 -5
  35. package/dist/agent-src/skills/ai-council/SKILL.md +48 -807
  36. package/dist/agent-src/skills/ai-council/references/advanced-modes.md +320 -0
  37. package/dist/agent-src/skills/ai-council/references/cost-and-redaction.md +99 -0
  38. package/dist/agent-src/skills/ai-council/references/execution-modes.md +162 -0
  39. package/dist/agent-src/skills/ai-council/references/output-and-synthesis.md +125 -0
  40. package/dist/agent-src/skills/ai-council/references/procedure.md +143 -0
  41. package/dist/agent-src/skills/decision-record/SKILL.md +61 -3
  42. package/dist/agent-src/skills/decision-review/SKILL.md +65 -0
  43. package/dist/agent-src/skills/merge-conflicts/SKILL.md +26 -0
  44. package/dist/agent-src/skills/quality-tools/SKILL.md +34 -326
  45. package/dist/agent-src/skills/quality-tools/references/js-ts-tools.md +113 -0
  46. package/dist/agent-src/skills/quality-tools/references/php-tools.md +222 -0
  47. package/dist/agent-src/skills/roadmap-management/SKILL.md +15 -409
  48. package/dist/agent-src/skills/roadmap-management/references/archival.md +226 -0
  49. package/dist/agent-src/skills/roadmap-management/references/authoring.md +107 -0
  50. package/dist/agent-src/skills/roadmap-management/references/dashboard.md +47 -0
  51. package/dist/agent-src/skills/roadmap-management/references/lifecycle.md +58 -0
  52. package/dist/agent-src/skills/security/SKILL.md +8 -0
  53. package/dist/agent-src/skills/security-audit/SKILL.md +12 -1
  54. package/dist/agent-src/skills/skill-writing/SKILL.md +34 -570
  55. package/dist/agent-src/skills/skill-writing/references/procedure.md +275 -0
  56. package/dist/agent-src/skills/skill-writing/references/read-only-scripts.md +18 -0
  57. package/dist/agent-src/skills/skill-writing/references/section-patterns.md +298 -0
  58. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  59. package/dist/agent-src/templates/roadmaps.md +65 -4
  60. package/dist/agent-src/templates/scripts/telemetry/flush_sender.mjs +163 -0
  61. package/dist/agent-src/templates/scripts/telemetry/remote.ts +160 -7
  62. package/dist/agent-src/templates/scripts/telemetry/transport.ts +169 -0
  63. package/dist/cli/registry.js +2 -1
  64. package/dist/cli/registry.js.map +1 -1
  65. package/dist/cli-delegate/chunk-2GNWGMAL.js +172 -0
  66. package/dist/cli-delegate/{chunk-P6LQDIWK.js → chunk-7PRE6ZV2.js} +338 -0
  67. package/dist/cli-delegate/{chunk-BKO2AZ7Z.js → chunk-B2ERU2VA.js} +1 -1
  68. package/dist/cli-delegate/chunk-E4XIZDIB.js +402 -0
  69. package/dist/cli-delegate/{chunk-3UCJWMMP.js → chunk-EEJUMCDZ.js} +16 -16
  70. package/dist/cli-delegate/{chunk-NXFWFAYV.js → chunk-G23AT6GD.js} +1 -0
  71. package/dist/cli-delegate/{chunk-XURJ4AQC.js → chunk-H4VIVD4C.js} +385 -284
  72. package/dist/cli-delegate/chunk-I3EIN2YG.js +36 -0
  73. package/dist/cli-delegate/{chunk-RLN73PR5.js → chunk-LPPWO5CE.js} +12 -8
  74. package/dist/cli-delegate/chunk-MWRD5YOH.js +100 -0
  75. package/dist/cli-delegate/{chunk-UEZ7D35A.js → chunk-N7CDDGI3.js} +4 -23
  76. package/dist/cli-delegate/{chunk-63WSP6YZ.js → chunk-PMEKGDED.js} +74 -167
  77. package/dist/cli-delegate/{chunk-GRRPEPRN.js → chunk-T7L2QK3K.js} +24 -5
  78. package/dist/cli-delegate/{chunk-EVTY7ISR.js → chunk-YM4GZDJG.js} +9 -1
  79. package/dist/cli-delegate/cmd_adr_effective.js +1162 -0
  80. package/dist/cli-delegate/cmd_conformance.js +466 -716
  81. package/dist/cli-delegate/cmd_converge.js +3 -3
  82. package/dist/cli-delegate/cmd_doctor.js +10 -10
  83. package/dist/cli-delegate/cmd_explain.js +1 -1
  84. package/dist/cli-delegate/cmd_export.js +10 -9
  85. package/dist/cli-delegate/cmd_handoff.js +10 -9
  86. package/dist/cli-delegate/cmd_memory_get.js +2 -1
  87. package/dist/cli-delegate/cmd_migrate.js +2 -2
  88. package/dist/cli-delegate/cmd_packs_active.js +1 -1
  89. package/dist/cli-delegate/cmd_preflight.js +5 -5
  90. package/dist/cli-delegate/cmd_prune.js +11 -10
  91. package/dist/cli-delegate/cmd_route_audit.js +6 -5
  92. package/dist/cli-delegate/cmd_route_explain.js +3 -3
  93. package/dist/cli-delegate/cmd_session_recycle.js +840 -30
  94. package/dist/cli-delegate/cmd_settings_get.js +3 -3
  95. package/dist/cli-delegate/cmd_settings_migrate.js +10 -9
  96. package/dist/cli-delegate/cmd_settings_set.js +1 -1
  97. package/dist/cli-delegate/cmd_sync.js +11 -10
  98. package/dist/cli-delegate/cmd_uninstall.js +13 -11
  99. package/dist/cli-delegate/cmd_update.js +4 -4
  100. package/dist/cli-delegate/cmd_upgrade.js +4 -4
  101. package/dist/cli-delegate/cmd_validate.js +11 -10
  102. package/dist/cli-delegate/cmd_versions.js +3 -3
  103. package/dist/discovery/deprecation-report.md +1 -1
  104. package/dist/discovery/discovery-manifest.json +111 -37
  105. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  106. package/dist/discovery/discovery-manifest.summary.md +5 -5
  107. package/dist/discovery/dormancy-report.md +1 -1
  108. package/dist/discovery/orphan-report.md +1 -1
  109. package/dist/discovery/packs.json +15 -12
  110. package/dist/discovery/trust-report.md +3 -3
  111. package/dist/discovery/workspaces.json +11 -8
  112. package/dist/hooks/dispatch.js +3165 -2192
  113. package/dist/install/claudePathsPlan.js +187 -0
  114. package/dist/install/claudePathsPlan.js.map +1 -0
  115. package/dist/install/globalRuleLayers.js +169 -0
  116. package/dist/install/globalRuleLayers.js.map +1 -0
  117. package/dist/install/hostLayerFingerprint.js +136 -0
  118. package/dist/install/hostLayerFingerprint.js.map +1 -0
  119. package/dist/install/install.mjs +553 -425
  120. package/dist/install/partitionEligibility.js +432 -0
  121. package/dist/install/partitionEligibility.js.map +1 -0
  122. package/dist/install/ruleLayerPartition.js +157 -0
  123. package/dist/install/ruleLayerPartition.js.map +1 -0
  124. package/dist/mcp/registry-manifest.json +3 -3
  125. package/dist/mcp/server.json +2 -2
  126. package/dist/mcp/server.mjs +1863 -1234
  127. package/dist/router.json +1 -1
  128. package/dist/scripts/_lib/agent_src.js +41 -0
  129. package/dist/scripts/_lib/agent_src.js.map +1 -1
  130. package/dist/scripts/_lib/install_layout.js +83 -0
  131. package/dist/scripts/_lib/install_layout.js.map +1 -0
  132. package/dist/scripts/_lib/installed_lock.js +444 -0
  133. package/dist/scripts/_lib/installed_lock.js.map +1 -0
  134. package/dist/scripts/_lib/prune_empty_dirs.js +85 -0
  135. package/dist/scripts/_lib/prune_empty_dirs.js.map +1 -0
  136. package/dist/scripts/condense.js +63 -251
  137. package/dist/scripts/condense.js.map +1 -1
  138. package/dist/server/schemas/settings.js +4 -0
  139. package/dist/server/schemas/settings.js.map +1 -1
  140. package/docs/contracts/settings-classes.md +12 -6
  141. package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +8 -3
  142. package/docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +45 -1
  143. package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +26 -0
  144. package/docs/guidelines/agent-infra/false-green.md +47 -1
  145. package/docs/guidelines/agent-infra/memory-access.md +17 -0
  146. package/docs/guidelines/agent-infra/recurring-criticism-mechanics.md +96 -0
  147. package/package.json +1 -1
  148. package/src/agent-src/scripts/archival_sweep.ts +117 -0
  149. package/src/agent-src/scripts/archive_completed_roadmaps.ts +26 -7
  150. package/src/agent-src/scripts/dashboard_mode.ts +212 -0
  151. package/src/agent-src/scripts/gate_budget.ts +282 -0
  152. package/src/agent-src/scripts/gate_execute.ts +72 -31
  153. package/src/agent-src/scripts/roadmap_gates.ts +74 -3
  154. package/src/agent-src/scripts/update_roadmap_progress.ts +296 -53
  155. package/src/agent-src/templates/scripts/telemetry/flush_sender.mjs +163 -0
  156. package/src/agent-src/templates/scripts/telemetry/remote.ts +160 -7
  157. package/src/agent-src/templates/scripts/telemetry/transport.ts +169 -0
  158. package/src/config/agent-settings.template.yml +27 -2
  159. package/src/config/ci-local-parity.yml +39 -0
  160. package/src/config/estate-count-budget.json +612 -3
  161. package/src/config/evaluator-budgets.json +3 -3
  162. package/src/config/gate-coverage.yml +220 -12
  163. package/src/config/gate-violation-baselines.json +73 -63
  164. package/src/config/gitignore-block.txt +15 -2
  165. package/src/config/hook-latency-budget.json +5 -0
  166. package/src/config/rule-activation-census.json +14 -6
  167. package/src/config/rule-stub-ceilings.json +34 -7
  168. package/src/install/claudePathsPlan.ts +196 -0
  169. package/src/install/globalRuleLayers.ts +197 -0
  170. package/src/install/hostLayerFingerprint.ts +145 -0
  171. package/src/install/partitionEligibility.ts +502 -0
  172. package/src/install/ruleLayerPartition.ts +212 -0
  173. package/src/scripts/_cli/cmd_adr_effective.ts +484 -0
  174. package/src/scripts/_cli/cmd_session_recycle.ts +9 -1
  175. package/src/scripts/_dispatch.bash +17 -1
  176. package/src/scripts/_lib/ac_heading.ts +30 -0
  177. package/src/scripts/_lib/adr_frontmatter.test.ts +365 -0
  178. package/src/scripts/_lib/adr_frontmatter.ts +459 -0
  179. package/src/scripts/_lib/agent_src.ts +42 -0
  180. package/src/scripts/_lib/bench_ab_pinned_repo.ts +162 -0
  181. package/src/scripts/_lib/bench_ab_workspace.ts +10 -1
  182. package/src/scripts/_lib/envelope_grounding.ts +49 -9
  183. package/src/scripts/_lib/installed_lock.ts +50 -5
  184. package/src/scripts/_lib/layer_overlap_notice.ts +11 -2
  185. package/src/scripts/_lib/md_section.ts +129 -0
  186. package/src/scripts/_lib/prune_empty_dirs.ts +80 -0
  187. package/src/scripts/_lib/scope_guard.sh +26 -3
  188. package/src/scripts/_lib/self_repair.ts +19 -0
  189. package/src/scripts/_lib/self_repair_class_b.ts +171 -0
  190. package/src/scripts/adr/evidence_census.ts +899 -0
  191. package/src/scripts/adr/regenerate_index.ts +12 -32
  192. package/src/scripts/adr_cite_check.ts +540 -39
  193. package/src/scripts/ai_council/cli_help.ts +55 -0
  194. package/src/scripts/audit_adr_coverage.ts +103 -17
  195. package/src/scripts/before_complete_hook.ts +153 -28
  196. package/src/scripts/bench_ab_v2_complexity.ts +27 -7
  197. package/src/scripts/bench_hook_latency.ts +204 -0
  198. package/src/scripts/build_archive_index.ts +34 -0
  199. package/src/scripts/check_adr_frontmatter.ts +574 -39
  200. package/src/scripts/check_hook_bundle_content.ts +219 -0
  201. package/src/scripts/check_new_adr_evidence.ts +529 -0
  202. package/src/scripts/check_references.ts +78 -0
  203. package/src/scripts/check_release_published.ts +32 -11
  204. package/src/scripts/check_rule_layer_partition.ts +531 -0
  205. package/src/scripts/check_single_delivery.ts +194 -17
  206. package/src/scripts/check_standing_rule_delivery.ts +8 -2
  207. package/src/scripts/ci_settle.ts +170 -0
  208. package/src/scripts/condense.ts +79 -259
  209. package/src/scripts/council_cli.ts +3 -3
  210. package/src/scripts/dispatch_r2_reviewer.ts +6 -14
  211. package/src/scripts/external_sources_denylist.json +4 -1
  212. package/src/scripts/hook_manifest.json +1 -1
  213. package/src/scripts/hook_manifest.yaml +77 -14
  214. package/src/scripts/hooks/block_no_verify.ts +61 -10
  215. package/src/scripts/hooks/block_unauthorized_git.ts +21 -1
  216. package/src/scripts/hooks/concern_registry.ts +4 -0
  217. package/src/scripts/hooks/dispatch_hook.ts +154 -187
  218. package/src/scripts/hooks/dispatch_issues.ts +38 -19
  219. package/src/scripts/hooks/fallback_yaml.ts +66 -0
  220. package/src/scripts/hooks/host_semantics.ts +21 -0
  221. package/src/scripts/hooks/injection_budget.ts +13 -3
  222. package/src/scripts/hooks/py_json_dumps.ts +103 -0
  223. package/src/scripts/hooks/rtk_wrap_hook.ts +8 -3
  224. package/src/scripts/hooks/run_continuation_hook.ts +8 -5
  225. package/src/scripts/hooks/ship_diff_volume_hook.ts +81 -15
  226. package/src/scripts/hooks/source_first_gate_hook.ts +464 -0
  227. package/src/scripts/hooks/state_io.ts +870 -21
  228. package/src/scripts/hooks/stdin_failure_policy.ts +96 -0
  229. package/src/scripts/hooks/subagent_ledger_hook.ts +44 -15
  230. package/src/scripts/hooks/telemetry_flush_hook.ts +139 -0
  231. package/src/scripts/hooks/telemetry_self_repair.ts +128 -0
  232. package/src/scripts/hooks/telemetry_usage_hook.ts +22 -4
  233. package/src/scripts/hooks/turn_end_gate_hook.ts +81 -15
  234. package/src/scripts/injection_scan_hook.ts +137 -5
  235. package/src/scripts/install.ts +16 -11
  236. package/src/scripts/language_mirror_hook.ts +561 -25
  237. package/src/scripts/lint_framework_leakage_allowlist.json +2 -2
  238. package/src/scripts/lint_hook_manifest.ts +49 -0
  239. package/src/scripts/lint_plan_risk_register.ts +4 -3
  240. package/src/scripts/lint_provenance_vocabulary.ts +472 -4
  241. package/src/scripts/lint_skill_router_head.ts +4 -4
  242. package/src/scripts/mcp_server/tools.ts +2 -2
  243. package/src/scripts/new_roadmap.ts +136 -0
  244. package/src/scripts/pack_mcp_content.ts +20 -5
  245. package/src/scripts/release.ts +37 -38
  246. package/src/scripts/report_layer_overlap.ts +6 -0
  247. package/src/scripts/routing_doctor.ts +5 -1
  248. package/src/scripts/self_repair_hook.ts +37 -5
  249. package/src/scripts/session_register_hook.ts +11 -0
  250. package/src/scripts/skill_usage_collect.ts +11 -1
  251. package/src/scripts/skill_usage_report.ts +278 -8
  252. package/src/scripts/sync_pr_branch.ts +170 -20
  253. package/src/server/schemas/settings.ts +8 -0
  254. package/dist/cli-delegate/chunk-EJITJBJX.js +0 -172
  255. package/dist/cli-delegate/chunk-PZWRPRWP.js +0 -38
  256. package/dist/cli-delegate/{chunk-PPQO4NGR.js → chunk-6RJA2F5A.js} +3 -3
  257. package/dist/cli-delegate/{chunk-RYNADUFG.js → chunk-LWTYTX6F.js} +0 -0
  258. package/dist/cli-delegate/{chunk-FBKL6JWT.js → chunk-MMSGVZKV.js} +3 -3
@@ -87,10 +87,54 @@ those artifacts:
87
87
  to obtain.
88
88
  - **Scope is the batch, nothing more.** An artifact NOT declared in the
89
89
  roadmap (discovered mid-run) triggers the full interactive protocol —
90
- or, under the contract, the scope-out-of-roadmap halt.
90
+ or, under the contract, the scope-out-of-roadmap halt. That halt is the
91
+ **default** and stays the default; see § Late artifacts below for the one
92
+ declared value that changes it.
91
93
  - Batch mode never skips the Research pass itself — it relocates and
92
94
  batches it. `artifact_protocol: skip` does not exist.
93
95
 
96
+ ### Late artifacts — `halt` by default, `auto-research` only when declared
97
+
98
+ The bullet above is the whole rule when the contract says nothing. A contract
99
+ may instead declare `late_artifacts: auto-research`
100
+ ([`roadmap-execution-contract § 2a`](../../../src/agent-src/contexts/execution/roadmap-execution-contract.md)),
101
+ and then a mid-run discovery runs **this** procedure rather than halting:
102
+
103
+ 1. **Re-run Phase B against current state** — the same overlap scan the batch
104
+ ran at contract time, now over the artifact the run just found. Nothing new
105
+ is invented: this is the accepted-as-non-interactive procedure, later.
106
+ 2. **Extend verdict → extend silently.** The nearest match is edited. This is
107
+ the outcome the overlap scan exists to produce and it needs no approval it
108
+ did not already have.
109
+ 3. **Create verdict → derive Phase A from what is already on the record.** The
110
+ understand-answers come from the roadmap step text plus the decision-sheet
111
+ answers the user accepted. No new question is opened.
112
+ 4. **Genuine overlap conflict → halt.** Two plausible extend targets, or a
113
+ match whose scope contradicts the step, is a real decision and stops the
114
+ run.
115
+ 5. **Cap: three per run, then halt regardless of verdict.**
116
+
117
+ `halt` remains the shipped default (`decision 2026-08-20`, AI council 2/2 on
118
+ the `autonomy-defaults-sheet` fork; record
119
+ `agents/evidence/council/drain-blocker-dispositions-a.md`). The reasoning is
120
+ short: the cap bounds how far an unplanned artifact can drift the run, but it
121
+ does not decide whether the drift is wanted, and the conservative side of that
122
+ fork is the behaviour the tree already had. Making `auto-research` a declared
123
+ value rather than an inherited one is also what makes its own kill criterion —
124
+ the late-artifact revisit rate — attributable to the runs that chose it.
125
+ Reverting is one word in each of the two tables; no mechanism depends on the
126
+ default's direction.
127
+
128
+ **Kill criterion for `auto-research`, at the site rather than in a roadmap:**
129
+ a late-artifact revisit rate above 20 % — an auto-authored or auto-extended
130
+ artifact later reworked or reverted — removes the value and returns every
131
+ late discovery to `halt`. **No instrument today:** nothing counts late
132
+ artifacts or their revisits, so the rate is unmeasured rather than low, and
133
+ the cap of three is the only live bound. Recorded here because a criterion
134
+ that lives only in the roadmap that flipped the default becomes unreachable
135
+ the moment that roadmap is archived.
136
+
137
+
94
138
  ## Complexity budget — the six questions before a new artefact
95
139
 
96
140
  Folded here from the 9.4.0 review (Prio 5), which named the failure mode:
@@ -88,3 +88,29 @@ Exit code is always 0 — hooks must never block the agent loop.
88
88
 
89
89
  - `context-hygiene` (rule) — thresholds, 3-failure rule, tool-loop cap, read-loop Iron Law.
90
90
  - `systematic-debugging` § Debug micro-loop — the one-test-one-fix-one-rerun procedure.
91
+
92
+ ## The CI waiter — use the helper, never the hand-written loop
93
+
94
+ `./scripts-run src/scripts/ci_settle <pr> [--timeout-min N] [--interval-sec N]`
95
+
96
+ Exit codes: **0** settled green · **1** settled red, with the failing checks
97
+ named · **2** did not settle, or the API could not be read — never a verdict.
98
+
99
+ Four states classify as *not settled*, and each one is a way the hand-written
100
+ form goes wrong: an API error, a non-zero `gh` exit, unparseable output, and
101
+ **zero registered checks** (a run that has not registered its checks yet looks
102
+ exactly like a finished one with nothing to report).
103
+
104
+ **Why it exists.** Measured 2026-08-20:
105
+
106
+ ```bash
107
+ until ! gh pr checks 1459 | grep -q "pending"; do sleep 60; done
108
+ ```
109
+
110
+ The API then failed. Its error text — `error connecting to api.github.com` —
111
+ contains no `pending`, so the loop exited, the session reported a settle that
112
+ had not happened, and the claim had to be retracted to the user in the next
113
+ reply. The bug is not the sleep or the grep: **absence of the word `pending`
114
+ was treated as evidence of completion**, and an error is neither settled nor
115
+ pending. The exit condition is the part that is easy to get wrong, so it lives
116
+ in one place rather than in every agent's head.
@@ -1,6 +1,6 @@
1
1
  # False Green — the ways a passing result can be wrong here
2
2
 
3
- > Nine failure modes, each with the detection command that distinguishes "found nothing" from "looked at nothing". Every one is drawn from this repository's own history, not from a generic checklist.
3
+ > Eleven failure modes, each with the detection command that distinguishes "found nothing" from "looked at nothing". Every one is drawn from this repository's own history, not from a generic checklist.
4
4
 
5
5
  _Origin: `road-to-skill-ecosystem-gate-integrity` Phase 3. The recurring shape is not that a gate reports a wrong finding — it is that a gate reports **no** finding for a reason unrelated to the property it guards, and no output distinguishes the two cases._
6
6
 
@@ -128,6 +128,52 @@ empty rendered template equals an absent target file. The gate reports
128
128
  comparing. Two absences are the absence of a comparison, not the presence of a
129
129
  match. The estate-wide audit is below.
130
130
 
131
+ ### 10. Hook-bypass override
132
+
133
+ The gate never ran because the hook that runs it was disabled for that
134
+ invocation. `git commit --no-verify` (and its short `-n` form) skips every
135
+ pre-commit hook; `core.hooksPath` repointed at an empty directory skips them
136
+ permanently and silently. Both produce a commit that looks exactly like a
137
+ commit whose hooks passed. The same shape reaches the runtime hook layer: a
138
+ concern bound in the manifest is still inert on a host that does not honour a
139
+ deny, so "the guard is registered" is not "the guard fired".
140
+
141
+ <!-- example-fence-allow: git-no-verify -- the fence teaches how to DETECT the core.hooksPath bypass; the forbidden form has to appear for the diagnostic to be readable, and every line here is a read-only query -->
142
+ ```bash
143
+ git config --get core.hooksPath # empty = repo default, good
144
+ ./scripts-run src/scripts/hooks/block_no_verify --help # the tool-call guard
145
+ agent-config hooks:status # per-host bindings, not the manifest
146
+ ```
147
+
148
+ **Structural fix:** the bypass is blocked at tool-call time by
149
+ `block-no-verify` on the one host that honours a deny, and the authoritative
150
+ gate is remote CI, which no local override can skip. Never read a local green
151
+ as evidence when the hook path was overridden — re-run in CI, or run the gate
152
+ directly rather than through the hook.
153
+
154
+ ### 11. Cached-green reuse
155
+
156
+ The green belongs to a different input than the one being judged. Three real
157
+ shapes here. A gate that reads `dist/agent-src/` passes against a **stale
158
+ projection** while the `src/` change it was meant to judge is not in the tree it
159
+ scanned — the recorded trap is a worktree whose stale `dist` faked generator
160
+ drift, and its mirror, a golden capture reading `dist` where the assertion was
161
+ about `src`. A count ratchet sits inside its limit for so long that "within
162
+ budget" stops meaning anything, which is why a baseline carries an expiry at
163
+ all. And the conversational form: trusting a verification run earlier in the
164
+ same session, after the tree has moved underneath it.
165
+
166
+ ```bash
167
+ bash src/scripts/condense.sh --changed # dist != rewrite(src) => the scan root is stale
168
+ ./scripts-run src/scripts/check_condensation --summary # byte-exactness dist vs rewrite(src)
169
+ ```
170
+
171
+ **Structural fix:** regenerate before judging (`task sync` then
172
+ `task generate-tools`, in that order), and treat a baseline unchanged past
173
+ `STALE_AFTER_DAYS` (56, `_lib/gate_baseline.ts:39`) as suppression rather than
174
+ as headroom. A completion claim rests on a run made **after** the last edit, not
175
+ on the freshest run you happen to remember.
176
+
131
177
  ## The audited sync/parity gates
132
178
 
133
179
  Comparison-shaped gates carry entry #9's failure mode by default: `diff a b`
@@ -8,6 +8,23 @@ abstraction backed by `scripts/memory_lookup.ts` (TypeScript, run via
8
8
  tsx). It reads curated YAML under `agents/memory/<type>/` and the
9
9
  agent-written `agents/memory/intake/*.jsonl` signal log.
10
10
 
11
+ ## Index by the moment, not only by the topic
12
+
13
+ Every entry answers **"what was I about to do when this would have helped"** — a
14
+ verb and its object (`author a roadmap`, `wait on CI`, `push a branch`, `edit a
15
+ markdown section with a script`) — and the index carries a trigger-moment
16
+ section keyed on those verbs beside the topic grouping.
17
+
18
+ A store indexed only by subject is an index for *browsing*, and browsing is not
19
+ the failure mode: an agent does not go looking for a trap it does not know
20
+ exists. Measured 2026-08-20 on one instrumented session — of eleven error
21
+ classes, **nine already had an entry** and all nine were read *after* the
22
+ failure. The deficit was delivery, not knowledge.
23
+
24
+ Writing the trigger key is part of writing the entry. A second index maintained
25
+ separately from the entries rots, and a rotted index is worse than none because
26
+ it still looks authoritative.
27
+
11
28
  ## The contract
12
29
 
13
30
  Consumers reach it via the CLI (`agent-config memory:lookup`) or the
@@ -0,0 +1,96 @@
1
+ # Recurring-criticism mechanics
2
+
3
+ > Depth for the `recurring-criticism` rule — the past-disposition store list, the mechanism-is-the-defect classification, the hardening floor, and the failure-mode catalog.
4
+
5
+ _No YAML frontmatter, deliberately: every other guideline under `docs/guidelines/`
6
+ is frontmatter-less, and a `name:` key here makes the two MCP resource loaders
7
+ derive different URIs for the same file — one from the key
8
+ (`guideline://recurring-criticism-mechanics`), one from the path
9
+ (`guideline://agent-infra/recurring-criticism-mechanics`). That is a
10
+ `mcp_parity_smoke` drift, and it only surfaces once `dist/cli/agent-config.js`
11
+ is built, so the local suite passes and CI does not._
12
+
13
+ Depth for [`recurring-criticism`](../../../src/rules/recurring-criticism.md). The
14
+ rule carries the obligation; this carries the lookup addresses and the reasoning
15
+ that would otherwise be paid in every session — that rule is phrase-triggered, and
16
+ a phrase-triggered rule is unconditionally loaded on Claude (the emitter writes no
17
+ `paths:` when any non-path trigger is present), so every line in it is a line every
18
+ session pays for. This file is read on demand.
19
+
20
+ ## Look it up before re-deriving it
21
+
22
+ Without a mechanism that forces a reference to the earlier disposition, every
23
+ recurrence becomes a fresh investigation even where the answer already exists
24
+ <!-- harvest:forced-lookup-of-past-root-causes -->. The stores are fragmented and
25
+ only partly queryable, so **name which one you checked**:
26
+
27
+ | Store | Path | Queryable? |
28
+ |---|---|---|
29
+ | ADRs + index | `docs/decisions/` + `INDEX.md`, via `adr_cite_check <ADR-NNN>` | yes — status, `review_trigger` state, successors |
30
+ | Estate / activation / low-impact dispositions | `agents/decisions/*.yml`, `agents/decisions/low-impact-decisions.md` | yes, closed vocabularies |
31
+ | Roadmap dispositions | `agents/roadmaps/{archive,skipped,later}/` | `later/` only; `skipped/` carries its reason as header prose |
32
+ | Curated memory | `agents/memory/*.yml` | yes |
33
+ | Analysis documents | `agents/evidence/analysis/` | grep only |
34
+ | Harvest / borrow ledgers | `provenance/*.jsonl` | yes, but `adopt`/`adapt` only |
35
+
36
+ **Rejections are the weak spot, and by design.** `provenance/README.md` states that
37
+ a `reject` verdict lives in the analysis document rather than a ledger, because
38
+ nothing in the tree cites it. So "I found nothing" here means *unstructured prose
39
+ was grepped*, never *nothing was decided*. Say which of the two you mean — the
40
+ difference decides whether the recurrence is new information or a lookup failure.
41
+
42
+ ## The mechanism is the candidate defect, not the item
43
+
44
+ Classify what was missing before choosing an artefact — the taxonomy in
45
+ [`skill-improvement-pipeline`](../../../src/skills/skill-improvement-pipeline/SKILL.md)
46
+ § Classify the missing component (instruction · source-of-truth · tool · validator ·
47
+ permission · sandbox · evaluation · recovery-path) is the one to use, because "add
48
+ another rule" is the answer that feels right and is usually wrong.
49
+
50
+ Then land the learning where it **constrains** the next run, per
51
+ [`learning-to-rule-or-skill`](../../../src/skills/learning-to-rule-or-skill/SKILL.md).
52
+ A lesson that does not narrow the next attempt produces thrashing rather than
53
+ convergence <!-- harvest:unconstraining-lesson-thrashes -->; a learning that lives
54
+ only in a reply is not a learning, it is a note.
55
+
56
+ **Third recurrence of the same class escalates to structure** —
57
+ [`decision-review`](../../../src/skills/decision-review/SKILL.md) § Escalation owns
58
+ the threshold, and its point is worth restating: a louder restatement of a rule the
59
+ agent keeps missing is the one response already known not to work. At that point
60
+ the choice is a deterministic gate or deletion, not more prose.
61
+
62
+ ## The hardening floor
63
+
64
+ Self-improvement loops can regress the artefact they improve
65
+ <!-- harvest:self-improvement-can-self-regress -->. Two consequences:
66
+
67
+ - A hardening change carries the **same evidence bar** as any other change. "We
68
+ learned something" is not a licence, and a mechanism proposed in response to a
69
+ recurrence still needs a measured false-positive rate before it becomes CI.
70
+ - It never arrives as a **weakened** gate, a widened allowlist, a lifted Hard
71
+ Floor, or a loosened ratchet. If the only available hardening lowers a floor, the
72
+ recurrence escalates to the owner instead — that transition is owner-reserved per
73
+ [`decision-revisit-gate`](../../../src/rules/decision-revisit-gate.md) § Who
74
+ decides.
75
+
76
+ ## Failure modes
77
+
78
+ - **Resolving on the count.** "You have said it three times, so you are right" is
79
+ the sycophancy failure with a procedure attached. The count opens the question.
80
+ - **Resolving on the count, inverted.** "It is only the second time, so the old
81
+ call stands" — the repetition still shifted the burden of proof.
82
+ - **Naming no outcome.** A resolution that does not say which of the three applies
83
+ (decision wrong · never recorded · unreachable) has not resolved anything.
84
+ - **Grepping prose and reporting absence.** See the rejection note above.
85
+ - **Treating a resemblance as a recurrence.** Mechanism-match runs first; a new
86
+ complaint that tests a different mechanism is a new finding.
87
+ - **Hardening the item instead of the mechanism.** Fixing the one instance leaves
88
+ the surface that dismissed it intact, which is what produces the fourth
89
+ recurrence.
90
+ - **Writing the learning into the reply.** It has to land in an artefact.
91
+
92
+ ## See also
93
+
94
+ - [`recurring-criticism`](../../../src/rules/recurring-criticism.md) — the obligation.
95
+ - [`decision-revisit-gate`](../../../src/rules/decision-revisit-gate.md) — the other entrance (a lock blocking a change), the five steps, the owner-reserved table.
96
+ - [`self-repair-loop`](../../../src/rules/self-repair-loop.md) — the single-occurrence intake and the `occurrences` counter this rule consumes.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@event4u/agent-config",
3
3
  "mcpName": "io.github.event4u-app/agent-config",
4
- "version": "14.6.0",
4
+ "version": "14.8.0",
5
5
  "description": "Governed skills, rules and commands for AI coding tools (Claude Code, Cursor, Windsurf, Copilot) — every claim machine-checked, including \"zero runtime daemon\".",
6
6
  "license": "MIT",
7
7
  "private": false,
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Archival-sweep spawner for the roadmap dashboard.
3
+ *
4
+ * Split out of `update_roadmap_progress.ts` rather than authored there: that
5
+ * file sits at the 1500-line source ceiling `check_source_size_budget`
6
+ * ratchets, and the sweep plus its contract is the newest and most separable
7
+ * thing in it. The contract below is that text, moved intact.
8
+ *
9
+ * `--archive` (opt-in; wired into `task roadmap-progress` and
10
+ * `agent-config roadmap:progress`) runs the archival sweep before rendering
11
+ * instead of printing "Completed roadmaps not yet archived" and leaving the
12
+ * work to a human who has been ignoring the line for weeks. It is a flag rather
13
+ * than the default because the PostToolUse hook re-runs the WRITE path once per
14
+ * turn on every roadmap edit, and a hook that silently `git mv`s files mid-work
15
+ * is a bigger problem than the warning it would remove. `--check` never
16
+ * archives — see `run_archival_sweep`.
17
+ *
18
+ * WHY the warning existed at all, since this is the one place a reader of the
19
+ * flag will look: the sweep's own default is `--changed-only`, so a PR archives
20
+ * exactly the roadmaps it completed. A roadmap completed by a PR whose sweep did
21
+ * not run is then complete, on the trunk, and OUTSIDE every later branch's
22
+ * history — no `--changed-only` sweep finds it again. Measured 2026-08-20: six
23
+ * such roadmaps, with every regen reprinting the warning at whoever ran it.
24
+ * `/create-pr` § 1c keeps `--changed-only`; repo-wide reconciliation is this
25
+ * flag's job and nothing else's.
26
+ *
27
+ * This layout is deliberate rather than convenient: the prose homes for it are
28
+ * both at their ceilings (`roadmap-progress-mechanics.md` sits 122 chars under
29
+ * the 16,000-char depth ceiling, and `roadmap-management/SKILL.md` tips
30
+ * `skill_too_large` on any prose block), so the contract lives with the code it
31
+ * governs. Moving it out means making room first.
32
+ *
33
+ * AI council 2026-08-20 (anthropic + openai, blind peer review): both seats
34
+ * converged on explicit opt-in + `--all` scope + hook archival-free, and both
35
+ * independently required the `--check` exclusion, the archive-before-render
36
+ * order, and that a failed sweep must not render. RECORDED DISSENT: one seat
37
+ * argued for flipping the sweep's own default to `--all` instead. Rejected —
38
+ * that makes every PR a potential estate-wide cleanup, which is exactly what
39
+ * `--changed-only` exists to prevent.
40
+ */
41
+
42
+ import { spawnSync } from 'node:child_process';
43
+ import * as fs from 'node:fs';
44
+ import * as path from 'node:path';
45
+ import { fileURLToPath } from 'node:url';
46
+
47
+ // Same directory as `update_roadmap_progress.ts`, so the `path.dirname` below
48
+ // resolves the sweep script exactly as it did before the split.
49
+ const _HERE = fileURLToPath(import.meta.url);
50
+
51
+ function _isFile(p: string): boolean {
52
+ try {
53
+ return fs.statSync(p).isFile();
54
+ } catch {
55
+ return false;
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Run the archival sweep for every complete roadmap, in-place.
61
+ *
62
+ * Spawned rather than imported: `archive_completed_roadmaps.ts` imports
63
+ * `collect` from `update_roadmap_progress.ts`, so a static import back would close a cycle, and
64
+ * `main()` is synchronous so a dynamic `await import()` is not available either.
65
+ * The sweep is the same twin `_regen_dashboard` already spawns in the other
66
+ * direction, so the spawn shape is the established one in this pair.
67
+ *
68
+ * No recursion: the sweep re-runs this script with NO flags, so its inner
69
+ * dashboard pass has archival off and terminates at depth 2.
70
+ *
71
+ * `--all`, not the sweep's `--changed-only` default. The default exists so a PR
72
+ * archives exactly the roadmaps it completed; here the caller asked the
73
+ * repo-wide dashboard to reconcile the estate, and the roadmaps that leak are
74
+ * by construction the ones NOT in this branch's history — six had accumulated
75
+ * on the trunk while the warning printed every regen. A roadmap the sweep
76
+ * refuses (open blockers) stays put and is still reported below.
77
+ */
78
+ export function run_archival_sweep(root: string): SweepResult {
79
+ const script = path.join(path.dirname(_HERE), 'archive_completed_roadmaps.ts');
80
+ if (!_isFile(script)) {
81
+ // A consumer install without the sweep script: nothing to run, and that
82
+ // is a normal state — the warning below still reports the roadmaps.
83
+ return { ran: false, ok: true, stdout: '', stderr: '' };
84
+ }
85
+ const argv = [script, '--all', '--repo-root', root];
86
+ const binName = process.platform === 'win32' ? 'tsx.cmd' : 'tsx';
87
+ let dir = path.dirname(_HERE);
88
+ for (;;) {
89
+ const candidate = path.join(dir, 'node_modules', '.bin', binName);
90
+ if (fs.existsSync(candidate)) {
91
+ return _sweepResult(spawnSync(candidate, argv, { cwd: root, encoding: 'utf-8' }));
92
+ }
93
+ const parent = path.dirname(dir);
94
+ if (parent === dir) {
95
+ break;
96
+ }
97
+ dir = parent;
98
+ }
99
+ return _sweepResult(spawnSync('npx', ['tsx', ...argv], { cwd: root, encoding: 'utf-8' }));
100
+ }
101
+
102
+ export interface SweepResult {
103
+ ran: boolean;
104
+ ok: boolean;
105
+ stdout: string;
106
+ stderr: string;
107
+ }
108
+
109
+ function _sweepResult(r: ReturnType<typeof spawnSync>): SweepResult {
110
+ return {
111
+ ran: true,
112
+ ok: r.status === 0,
113
+ stdout: String(r.stdout ?? ''),
114
+ stderr: String(r.stderr ?? ''),
115
+ };
116
+ }
117
+
@@ -31,6 +31,7 @@
31
31
  * ./scripts-run src/scripts/archive_completed_roadmaps # --changed-only (default)
32
32
  * ./scripts-run src/scripts/archive_completed_roadmaps --all
33
33
  * ./scripts-run src/scripts/archive_completed_roadmaps --base origin/main --dry-run
34
+ * ./scripts-run src/scripts/archive_completed_roadmaps --repo-root /path/to/proj
34
35
  *
35
36
  * --- Parity notes (ADR-200) ---
36
37
  *
@@ -397,10 +398,13 @@ function _regen_dashboard(root: string, dry_run: boolean): void {
397
398
  // Python: `_run([sys.executable, str(script)], root)`; the twin spawns the
398
399
  // dashboard generator twin through the same `tsx` runtime, cwd=root.
399
400
  _runTwin(root, script);
400
- const dash = path.join(root, 'agents', 'roadmaps-progress.md');
401
- if (_isFile(dash)) {
402
- _run(['git', 'add', '--', 'agents/roadmaps-progress.md'], root);
403
- }
401
+ // The dashboard is NOT staged. It is gitignored in this repository, and
402
+ // `git add -- <ignored-path>` exits 1 with "The following paths are ignored"
403
+ // -- a code `_run` returns and this call site discarded, so the previous
404
+ // `git add` here was a silent no-op from the moment the file was untracked
405
+ // (2026-08-21) and nothing objected. Regenerating it is still correct; the
406
+ // developer reads it on disk, and `task roadmap-progress-check` compares a
407
+ // present copy against a fresh render.
404
408
  }
405
409
 
406
410
  /**
@@ -462,19 +466,21 @@ function _runTwin(root: string, script: string): void {
462
466
  const _PROG = 'archive_completed_roadmaps.py';
463
467
 
464
468
  function _usage(): string {
465
- return `usage: ${_PROG} [-h] [--all] [--base BASE] [--dry-run]\n`;
469
+ return `usage: ${_PROG} [-h] [--all] [--base BASE] [--dry-run] [--repo-root REPO_ROOT]\n`;
466
470
  }
467
471
 
468
472
  interface Args {
469
473
  all: boolean;
470
474
  base: string;
471
475
  dry_run: boolean;
476
+ repo_root: string | null;
472
477
  }
473
478
 
474
479
  function _parseArgs(argv: readonly string[]): Args {
475
480
  let all = false;
476
481
  let base = 'origin/main';
477
482
  let dry_run = false;
483
+ let repo_root: string | null = null;
478
484
  const emitError = (msg: string): never => {
479
485
  process.stderr.write(_usage());
480
486
  process.stderr.write(`${_PROG}: error: ${msg}\n`);
@@ -502,17 +508,30 @@ function _parseArgs(argv: readonly string[]): Args {
502
508
  } else if (tok.startsWith('--base=')) {
503
509
  base = tok.slice('--base='.length);
504
510
  i += 1;
511
+ } else if (tok === '--repo-root') {
512
+ const val = argv[i + 1];
513
+ if (val === undefined) {
514
+ emitError('argument --repo-root: expected one argument');
515
+ }
516
+ repo_root = val as string;
517
+ i += 2;
518
+ } else if (tok.startsWith('--repo-root=')) {
519
+ repo_root = tok.slice('--repo-root='.length);
520
+ i += 1;
505
521
  } else {
506
522
  emitError(`unrecognized arguments: ${tok}`);
507
523
  }
508
524
  }
509
- return { all, base, dry_run };
525
+ return { all, base, dry_run, repo_root };
510
526
  }
511
527
 
512
528
  function main(argv?: readonly string[]): number {
513
529
  const ns = _parseArgs(argv ?? process.argv.slice(2));
514
530
 
515
- const root = _repo_root();
531
+ // An explicit `--repo-root` wins over the `git rev-parse` resolution. The
532
+ // dashboard generator passes it so a monorepo sub-project sweep cannot walk
533
+ // up to the enclosing repo and archive the PARENT's roadmaps.
534
+ const root = ns.repo_root ?? _repo_root();
516
535
  const archived = archive_completed(root, {
517
536
  changed_only: !ns.all,
518
537
  base: ns.base,