@adia-ai/adia-ui-forge 0.1.3 → 0.8.1

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 (259) hide show
  1. package/.claude-plugin/plugin.json +4 -7
  2. package/CHANGELOG.md +35 -34
  3. package/README.md +35 -40
  4. package/agents/a2ui-engineer.md +22 -53
  5. package/agents/component-author.md +29 -0
  6. package/agents/framework-verifier.md +26 -0
  7. package/agents/release-engineer.md +21 -81
  8. package/agents/routing-corpus.json +293 -64
  9. package/bin/demo-postwrite-pattern-gate +94 -0
  10. package/bin/forge-lint +17 -2
  11. package/bin/sidecar-prewrite-guard +104 -0
  12. package/commands/deploy.md +9 -0
  13. package/commands/dogfood.md +10 -0
  14. package/commands/gen-review.md +9 -0
  15. package/commands/release.md +10 -0
  16. package/hooks/hooks.json +15 -0
  17. package/package.json +3 -6
  18. package/references/contracts/a2ui-mcp-surface.md +35 -0
  19. package/references/contracts/migration-guide-format.md +34 -0
  20. package/references/shared/content-trust.md +19 -74
  21. package/skills/adia-a2ui/SKILL.md +99 -0
  22. package/skills/{adia-ui-a2ui → adia-a2ui}/evals/routing-corpus.json +10 -10
  23. package/skills/adia-a2ui/references/anti-patterns.md +27 -0
  24. package/skills/adia-a2ui/references/chunk-authoring.md +71 -0
  25. package/skills/adia-a2ui/references/corpus-discipline.md +68 -0
  26. package/skills/adia-a2ui/references/eval-diagnostics.md +86 -0
  27. package/skills/adia-a2ui/references/format-extension-decisions.md +66 -0
  28. package/skills/adia-a2ui/references/leverage-rules.md +52 -0
  29. package/skills/adia-a2ui/references/mcp-pipeline-ops.md +83 -0
  30. package/skills/adia-a2ui/references/mcp-tool-reference.md +59 -0
  31. package/skills/adia-a2ui/references/pipeline-overview.md +115 -0
  32. package/skills/adia-a2ui/references/semantic-fail-lifting.md +74 -0
  33. package/skills/adia-a2ui/references/strategy-engines.md +109 -0
  34. package/skills/adia-a2ui/references/zettel-calibration.md +104 -0
  35. package/skills/adia-author/SKILL.md +112 -0
  36. package/skills/adia-author/evals/routing-corpus.json +222 -0
  37. package/skills/{adia-ui-authoring → adia-author}/references/anti-patterns.md +33 -4
  38. package/skills/{adia-ui-authoring → adia-author}/references/authoring-cycle.md +9 -11
  39. package/skills/adia-author/references/canonical-pattern-index.md +243 -0
  40. package/skills/{adia-ui-authoring → adia-author}/references/code-style.md +19 -21
  41. package/skills/adia-author/references/common-gotchas.md +129 -0
  42. package/skills/adia-author/references/composite-demo-protocol.md +271 -0
  43. package/skills/{adia-ui-authoring → adia-author}/references/css-patterns.md +19 -6
  44. package/skills/{adia-ui-authoring → adia-author}/references/lifecycle-patterns.md +1 -0
  45. package/skills/{adia-ui-authoring → adia-author}/references/llm-bridge.md +3 -5
  46. package/skills/{adia-ui-authoring → adia-author}/references/module-promotion.md +20 -38
  47. package/skills/{adia-ui-authoring → adia-author}/references/primitive-audit.md +2 -4
  48. package/skills/{adia-ui-authoring → adia-author}/references/shell-patterns.md +12 -18
  49. package/skills/{adia-ui-authoring → adia-author}/references/token-contract.md +5 -7
  50. package/skills/{adia-ui-authoring → adia-author}/references/worked-example.md +3 -3
  51. package/skills/{adia-ui-authoring → adia-author}/references/yaml-contract.md +3 -3
  52. package/skills/{adia-ui-authoring → adia-author}/scripts/build-canonical-pattern-index.mjs +3 -3
  53. package/skills/adia-deploy/SKILL.md +128 -0
  54. package/skills/{adia-ui-ops → adia-deploy}/references/deploy-playbooks.md +47 -30
  55. package/skills/adia-dogfood/SKILL.md +124 -0
  56. package/skills/adia-dogfood/references/admin-shell-anatomy.md +77 -0
  57. package/skills/adia-dogfood/references/app-shell-pitfalls.md +66 -0
  58. package/skills/adia-dogfood/references/card-anatomy-sweep.md +66 -0
  59. package/skills/adia-dogfood/references/html-attr-sweep.md +63 -0
  60. package/skills/adia-dogfood/references/native-leak-annotations.md +73 -0
  61. package/skills/adia-dogfood/references/visual-probe-triage.md +80 -0
  62. package/skills/{adia-ui-dogfood → adia-dogfood}/scripts/analyze.mjs +30 -14
  63. package/skills/adia-gen-review/SKILL.md +127 -0
  64. package/skills/adia-gen-review/references/corpus-html-patterns.md +279 -0
  65. package/skills/adia-gen-review/references/loop-protocol.md +216 -0
  66. package/skills/adia-gen-review/references/rubric-cosmetic.md +100 -0
  67. package/skills/adia-gen-review/references/rubric-decompose.md +101 -0
  68. package/skills/adia-gen-review/references/rubric-score.md +214 -0
  69. package/skills/{adia-ui-gen-review → adia-gen-review}/references/scores.schema.json +2 -2
  70. package/skills/{adia-ui-gen-review → adia-gen-review}/scripts/gen-review-coverage-audit.mjs +4 -4
  71. package/skills/{adia-ui-gen-review → adia-gen-review}/scripts/gen-review-decompose.mjs +10 -6
  72. package/skills/{adia-ui-gen-review → adia-gen-review}/scripts/gen-review-status.mjs +5 -5
  73. package/skills/{adia-ui-gen-review → adia-gen-review}/scripts/validate-cycle-scores.mjs +5 -5
  74. package/skills/adia-llm-internals/SKILL.md +77 -0
  75. package/skills/{adia-ui-llm → adia-llm-internals}/references/adapter-contract.md +4 -2
  76. package/skills/{adia-ui-llm → adia-llm-internals}/references/add-a-provider.md +4 -5
  77. package/skills/{adia-ui-llm → adia-llm-internals}/references/bridge-facade.md +10 -3
  78. package/skills/{adia-ui-llm → adia-llm-internals}/references/browser-proxy-boundary.md +1 -1
  79. package/skills/{adia-ui-llm → adia-llm-internals}/references/model-registry.md +5 -3
  80. package/skills/{adia-ui-llm → adia-llm-internals}/references/streaming-sse.md +2 -2
  81. package/skills/adia-release/SKILL.md +72 -0
  82. package/skills/adia-release/references/changelog-discipline.md +119 -0
  83. package/skills/adia-release/references/cut-procedure.md +247 -0
  84. package/skills/adia-release/references/gates-catalog.md +222 -0
  85. package/skills/adia-release/references/independent-package-release.md +52 -0
  86. package/skills/adia-release/references/migration-guide-authoring.md +86 -0
  87. package/skills/adia-release/references/notes-authoring.md +90 -0
  88. package/skills/adia-release/references/recovery-paths.md +106 -0
  89. package/skills/{adia-ui-release → adia-release}/scripts/bump.mjs +28 -3
  90. package/skills/{adia-ui-release → adia-release}/scripts/dispatch-publish.mjs +10 -7
  91. package/skills/{adia-ui-release → adia-release}/scripts/insert-stub.mjs +1 -1
  92. package/skills/{adia-ui-release → adia-release}/scripts/package-paths.mjs +6 -0
  93. package/skills/{adia-ui-release → adia-release}/scripts/promote-unreleased.mjs +1 -1
  94. package/skills/{adia-ui-release → adia-release}/scripts/release-pack.mjs +38 -31
  95. package/skills/{adia-ui-release → adia-release}/scripts/tag-lockstep.mjs +7 -3
  96. package/skills/adia-site-docs/SKILL.md +68 -0
  97. package/skills/adia-site-docs/evals/audit-report.md +30 -0
  98. package/skills/adia-site-docs/evals/routing-corpus.json +176 -0
  99. package/skills/adia-site-docs/intent.md +72 -0
  100. package/agents/README.md +0 -209
  101. package/agents/author.md +0 -56
  102. package/agents/repo-steward.md +0 -56
  103. package/agents/spec-architect.md +0 -53
  104. package/agents/tech-lead.md +0 -57
  105. package/agents/verifier.md +0 -55
  106. package/bin/lib/audit-axes.mjs +0 -555
  107. package/bin/lib/dry-run-irreversible.mjs +0 -236
  108. package/bin/lib/run-skill-evals.mjs +0 -487
  109. package/bin/lib/teach-router.mjs +0 -250
  110. package/commands/adia-forge-a2ui.md +0 -10
  111. package/commands/adia-forge-author.md +0 -10
  112. package/commands/adia-forge-dogfood.md +0 -8
  113. package/commands/adia-forge-llm.md +0 -8
  114. package/commands/adia-forge-orient.md +0 -10
  115. package/commands/adia-forge-release.md +0 -8
  116. package/commands/adia-forge-review.md +0 -10
  117. package/references/shared/pev-rationale.md +0 -64
  118. package/references/shared/skill-conventions.md +0 -133
  119. package/skills/adia-ui-a2ui/CHANGELOG.md +0 -32
  120. package/skills/adia-ui-a2ui/SKILL.md +0 -243
  121. package/skills/adia-ui-a2ui/evals/adversarial-corpus.json +0 -75
  122. package/skills/adia-ui-a2ui/evals/teach-routing-cases.json +0 -100
  123. package/skills/adia-ui-a2ui/references/anti-patterns.md +0 -24
  124. package/skills/adia-ui-a2ui/references/chunk-authoring.md +0 -88
  125. package/skills/adia-ui-a2ui/references/corpus-discipline.md +0 -56
  126. package/skills/adia-ui-a2ui/references/eval-diagnostics.md +0 -127
  127. package/skills/adia-ui-a2ui/references/fragment-graph.md +0 -91
  128. package/skills/adia-ui-a2ui/references/mcp-pipeline-ops.md +0 -106
  129. package/skills/adia-ui-a2ui/references/mcp-tool-reference.md +0 -398
  130. package/skills/adia-ui-a2ui/references/pipeline-overview.md +0 -175
  131. package/skills/adia-ui-a2ui/references/semantic-fail-lifting.md +0 -120
  132. package/skills/adia-ui-a2ui/references/strategy-engines.md +0 -111
  133. package/skills/adia-ui-a2ui/references/teach-protocol.md +0 -220
  134. package/skills/adia-ui-a2ui/references/zettel-calibration.md +0 -93
  135. package/skills/adia-ui-a2ui/scripts/audit-a2ui-roster.mjs +0 -96
  136. package/skills/adia-ui-a2ui/scripts/teach-route.mjs +0 -157
  137. package/skills/adia-ui-a2ui/skill.json +0 -38
  138. package/skills/adia-ui-authoring/CHANGELOG.md +0 -32
  139. package/skills/adia-ui-authoring/SKILL.md +0 -256
  140. package/skills/adia-ui-authoring/assets/case-studies/admin-shell-decomposition.md +0 -101
  141. package/skills/adia-ui-authoring/assets/case-studies/maxtokens-32768-discovery.md +0 -109
  142. package/skills/adia-ui-authoring/assets/case-studies/theme-panel-promotion.md +0 -113
  143. package/skills/adia-ui-authoring/evals/adversarial-design-plan-gates.json +0 -138
  144. package/skills/adia-ui-authoring/evals/routing-corpus.json +0 -245
  145. package/skills/adia-ui-authoring/references/canonical-pattern-index.md +0 -179
  146. package/skills/adia-ui-authoring/references/common-gotchas.md +0 -93
  147. package/skills/adia-ui-authoring/references/composite-demo-protocol.md +0 -1084
  148. package/skills/adia-ui-authoring/references/teach-protocol.md +0 -428
  149. package/skills/adia-ui-authoring/scripts/audit-authoring-roster.mjs +0 -148
  150. package/skills/adia-ui-authoring/skill.json +0 -45
  151. package/skills/adia-ui-dogfood/CHANGELOG.md +0 -17
  152. package/skills/adia-ui-dogfood/README.md +0 -62
  153. package/skills/adia-ui-dogfood/SKILL.md +0 -866
  154. package/skills/adia-ui-dogfood/skill.json +0 -40
  155. package/skills/adia-ui-forge/SKILL.md +0 -88
  156. package/skills/adia-ui-forge/evals/routing-corpus.json +0 -30
  157. package/skills/adia-ui-gen-review/CHANGELOG.md +0 -108
  158. package/skills/adia-ui-gen-review/SKILL.md +0 -266
  159. package/skills/adia-ui-gen-review/references/loop-protocol.md +0 -712
  160. package/skills/adia-ui-gen-review/references/rubric-cosmetic.md +0 -144
  161. package/skills/adia-ui-gen-review/references/rubric-decompose.md +0 -117
  162. package/skills/adia-ui-gen-review/references/rubric-score.md +0 -249
  163. package/skills/adia-ui-gen-review/references/teach-protocol.md +0 -214
  164. package/skills/adia-ui-gen-review/skill.json +0 -23
  165. package/skills/adia-ui-llm/CHANGELOG.md +0 -25
  166. package/skills/adia-ui-llm/SKILL.md +0 -165
  167. package/skills/adia-ui-llm/evals/adversarial-corpus.json +0 -75
  168. package/skills/adia-ui-llm/evals/routing-corpus.json +0 -30
  169. package/skills/adia-ui-llm/evals/teach-routing-cases.json +0 -73
  170. package/skills/adia-ui-llm/references/teach-protocol.md +0 -78
  171. package/skills/adia-ui-llm/scripts/audit-llm-roster.mjs +0 -93
  172. package/skills/adia-ui-llm/scripts/teach-route.mjs +0 -119
  173. package/skills/adia-ui-llm/skill.json +0 -33
  174. package/skills/adia-ui-ops/CHANGELOG.md +0 -291
  175. package/skills/adia-ui-ops/SKILL.md +0 -401
  176. package/skills/adia-ui-ops/references/INDEX.md +0 -158
  177. package/skills/adia-ui-ops/references/audit-cadence.md +0 -263
  178. package/skills/adia-ui-ops/references/audit-patterns/archive-link-sweep.md +0 -96
  179. package/skills/adia-ui-ops/references/audit-patterns/audit-history-ledger.md +0 -162
  180. package/skills/adia-ui-ops/references/audit-patterns/browser-bundle-node-imports.md +0 -154
  181. package/skills/adia-ui-ops/references/audit-patterns/changelog-unreleased-bloat.md +0 -75
  182. package/skills/adia-ui-ops/references/audit-patterns/coverage-gaps.md +0 -187
  183. package/skills/adia-ui-ops/references/audit-patterns/entry-file-coverage.md +0 -122
  184. package/skills/adia-ui-ops/references/audit-patterns/format-hygiene.md +0 -217
  185. package/skills/adia-ui-ops/references/audit-patterns/lockstep-versioning.md +0 -113
  186. package/skills/adia-ui-ops/references/audit-patterns/memory-fragmentation.md +0 -180
  187. package/skills/adia-ui-ops/references/audit-patterns/orphan-detection.md +0 -202
  188. package/skills/adia-ui-ops/references/audit-patterns/pointer-validation.md +0 -180
  189. package/skills/adia-ui-ops/references/audit-patterns/redundancy-detection.md +0 -210
  190. package/skills/adia-ui-ops/references/audit-patterns/spec-dating-sweep.md +0 -91
  191. package/skills/adia-ui-ops/references/audit-patterns/stale-content.md +0 -182
  192. package/skills/adia-ui-ops/references/audit-patterns/staleness-tooling.md +0 -156
  193. package/skills/adia-ui-ops/references/audit-patterns/token-waste-detection.md +0 -196
  194. package/skills/adia-ui-ops/references/doc-types/adr-pattern.md +0 -210
  195. package/skills/adia-ui-ops/references/doc-types/architecture-md.md +0 -190
  196. package/skills/adia-ui-ops/references/doc-types/changelog.md +0 -183
  197. package/skills/adia-ui-ops/references/doc-types/decisions-log.md +0 -146
  198. package/skills/adia-ui-ops/references/doc-types/plan-roadmap.md +0 -182
  199. package/skills/adia-ui-ops/references/doc-types/postmortem-pattern.md +0 -206
  200. package/skills/adia-ui-ops/references/genres/prose-and-writing.md +0 -149
  201. package/skills/adia-ui-ops/references/guidance/context-budget.md +0 -137
  202. package/skills/adia-ui-ops/references/guidance/llm-doc-writing.md +0 -116
  203. package/skills/adia-ui-ops/references/guidance/reliability-dial.md +0 -186
  204. package/skills/adia-ui-ops/references/recipes/adr-introduction.md +0 -211
  205. package/skills/adia-ui-ops/references/recipes/audit-existing-repo.md +0 -234
  206. package/skills/adia-ui-ops/references/recipes/cold-start-harvest.md +0 -263
  207. package/skills/adia-ui-ops/references/recipes/concurrent-learnings-merge.md +0 -158
  208. package/skills/adia-ui-ops/references/recipes/continuous-learning-loop.md +0 -169
  209. package/skills/adia-ui-ops/references/recipes/external-reference-verification.md +0 -158
  210. package/skills/adia-ui-ops/references/recipes/findings-index-readout.md +0 -126
  211. package/skills/adia-ui-ops/references/recipes/greenfield-setup.md +0 -252
  212. package/skills/adia-ui-ops/references/recipes/harvest-repo-brain.md +0 -169
  213. package/skills/adia-ui-ops/references/recipes/import-repo-brain-harvest.md +0 -153
  214. package/skills/adia-ui-ops/references/recipes/memory-organization.md +0 -182
  215. package/skills/adia-ui-ops/references/recipes/recommend-then-validate.md +0 -199
  216. package/skills/adia-ui-ops/references/recipes/self-healing-hooks.md +0 -366
  217. package/skills/adia-ui-ops/references/recipes/skill-stewardship-loop.md +0 -113
  218. package/skills/adia-ui-ops/references/standards/agents-md-spec.md +0 -138
  219. package/skills/adia-ui-ops/references/standards/claude-md-convention.md +0 -123
  220. package/skills/adia-ui-ops/references/standards/cross-tool-matrix.md +0 -85
  221. package/skills/adia-ui-ops/references/standards/readme-conventions.md +0 -232
  222. package/skills/adia-ui-ops/references/teach-protocol.md +0 -215
  223. package/skills/adia-ui-ops/scripts/audit-ops-roster.mjs +0 -104
  224. package/skills/adia-ui-ops/skill.json +0 -65
  225. package/skills/adia-ui-release/CHANGELOG.md +0 -66
  226. package/skills/adia-ui-release/SKILL.md +0 -323
  227. package/skills/adia-ui-release/assets/case-studies/2026-05-20-batch-push-v0.6.14-v0.6.15.md +0 -144
  228. package/skills/adia-ui-release/assets/case-studies/2026-05-20-corpus-drift-remediation-v0.6.15.md +0 -155
  229. package/skills/adia-ui-release/assets/case-studies/2026-05-20-version-skip-correction-v0.6.12.md +0 -114
  230. package/skills/adia-ui-release/assets/case-studies/2026-05-21-author-from-scratch-v0.6.18.md +0 -139
  231. package/skills/adia-ui-release/assets/case-studies/2026-05-21-feedback37-retraction-v0.6.21.md +0 -124
  232. package/skills/adia-ui-release/assets/case-studies/2026-05-21-fn1-enrichment-pass-v0.6.19.md +0 -125
  233. package/skills/adia-ui-release/assets/case-studies/2026-05-21-stale-test-detection-v0.6.20.md +0 -142
  234. package/skills/adia-ui-release/assets/case-studies/2026-05-23-freshness-gate-recovery-v0.6.32.md +0 -97
  235. package/skills/adia-ui-release/assets/case-studies/2026-05-26-catalog-drift-recurring-v0.6.40.md +0 -147
  236. package/skills/adia-ui-release/assets/templates/stub-changelog.template.md +0 -22
  237. package/skills/adia-ui-release/evals/evals.json +0 -164
  238. package/skills/adia-ui-release/references/changelog-discipline.md +0 -250
  239. package/skills/adia-ui-release/references/cycle-happy-path.md +0 -520
  240. package/skills/adia-ui-release/references/exe-deploy.md +0 -149
  241. package/skills/adia-ui-release/references/gates-catalog.md +0 -778
  242. package/skills/adia-ui-release/references/independent-package-release.md +0 -129
  243. package/skills/adia-ui-release/references/ledger-discipline.md +0 -232
  244. package/skills/adia-ui-release/references/migration-guide-authoring.md +0 -174
  245. package/skills/adia-ui-release/references/multi-agent-baseline.md +0 -207
  246. package/skills/adia-ui-release/references/notes-authoring.md +0 -212
  247. package/skills/adia-ui-release/references/recovery-paths.md +0 -262
  248. package/skills/adia-ui-release/references/rollup-notes.md +0 -208
  249. package/skills/adia-ui-release/references/teach-protocol.md +0 -468
  250. package/skills/adia-ui-release/scripts/audit-gate-roster.mjs +0 -196
  251. package/skills/adia-ui-release/scripts/make-ledger.mjs +0 -200
  252. package/skills/adia-ui-release/skill.json +0 -77
  253. package/skills/dogfood-sweep/CHANGELOG.md +0 -37
  254. package/skills/dogfood-sweep/README.md +0 -105
  255. package/skills/dogfood-sweep/SKILL.md +0 -1000
  256. package/skills/dogfood-sweep/analyze.mjs +0 -600
  257. package/skills/dogfood-sweep/skill.json +0 -31
  258. /package/skills/{adia-ui-authoring → adia-author}/references/api-contract.md +0 -0
  259. /package/skills/{adia-ui-release → adia-release}/scripts/assert-monorepo-root.mjs +0 -0
@@ -1,199 +0,0 @@
1
- ---
2
- date: 2026-04-27
3
- coverage: canonical
4
- peers:
5
- - self-healing-hooks.md
6
- - audit-existing-repo.md
7
- - ../guidance/reliability-dial.md
8
- - ../audit-patterns/audit-history-ledger.md
9
- primary_sources:
10
- - Steve Yegge, "Welcome to Gas City" — multi-agent consensus pattern
11
- - https://docs.anthropic.com/en/docs/claude-code/sub-agents — Claude Code subagent pattern
12
- status: research-verified
13
- ---
14
-
15
- # Recommend-then-validate (the two-agent fix pattern)
16
-
17
- > _"You should never just have one coding agent managing infrastructure… you should always have at least two or three working together on a little crew. Any agent can go temporarily insane, at any time, and make a bad call."_
18
- > — Steve Yegge, "Welcome to Gas City"
19
-
20
- ## What this delivers
21
-
22
- A single agent's apply-mode pass is **one source of truth, no consensus**. If that agent hallucinates a fix, the bad fix lands. The recommend-then-validate pattern splits the work:
23
-
24
- 1. **Recommender** — reads the audit; proposes specific fixes; produces a structured fix plan.
25
- 2. **Validator** — receives the fix plan; dry-runs each fix against the trip-wires; vetoes any fix that would break an invariant; opens the PR with only the surviving fixes.
26
-
27
- The validator is *not* a critic. It's an execution gate that runs the same trip-wires after a hypothetical fix and confirms they still pass. A fix that introduces a new violation gets rejected.
28
-
29
- This pattern is **required for `strict` strictness** (per `../guidance/reliability-dial.md`) and **optional but recommended for `normal`** for any apply-mode pass touching >5 files.
30
-
31
- ## The fix-plan contract
32
-
33
- The recommender emits a structured plan; the validator consumes it.
34
-
35
- ```yaml
36
- # .brain/fix-plan-2026-04-27.yaml (transient; consumed then discarded)
37
- strictness: normal
38
- findings_addressed:
39
- - id: DRIFT-CLAUDE-AGENTS
40
- severity: critical
41
- fixes:
42
- - kind: symlink
43
- target: CLAUDE.md
44
- points_to: AGENTS.md
45
- reason: "Eliminates drift; satisfies Promise 1."
46
- - kind: edit
47
- file: AGENTS.md
48
- description: "Compress 'Conventions' from 80 to 30 lines (Promise 2)."
49
- diff_preview: |
50
- [diff body]
51
- - kind: archive
52
- file: docs/old-plan.md
53
- move_to: .brain/archive/old-plan-2026-04-27.md
54
- reason: "Orphan, last modified 2024-08-15."
55
- ```
56
-
57
- Each fix is *typed* (`symlink | edit | archive | create | delete`). The validator knows how to dry-run each kind.
58
-
59
- ## The validator's veto rules
60
-
61
- After a hypothetical fix, the validator re-runs the relevant trip-wires:
62
-
63
- | Fix kind | Validator checks |
64
- |---|---|
65
- | `symlink` | Symlink target exists; ownership/permissions correct |
66
- | `edit` | Resulting file still <200 lines (entry files); frontmatter still valid; no new broken links introduced |
67
- | `archive` | File is genuinely orphaned (per `../audit-patterns/orphan-detection.md`); not within active grace window |
68
- | `create` | Path valid; doesn't conflict with existing file; YAML frontmatter present |
69
- | `delete` | **Always vetoed.** Move to `.brain/archive/` instead. Hard rule, no overrides. |
70
-
71
- If any veto fires, the fix is dropped from the plan and a finding is emitted: `VETO — <fix> rejected because <rule>`. The PR opens with the surviving fixes only.
72
-
73
- ## Implementation paths
74
-
75
- ### Path A — Sequential within Claude Code (simplest)
76
-
77
- Use the Claude Code subagent pattern. Main agent acts as recommender; spawns a validator subagent via the Agent tool with a fresh context.
78
-
79
- ```
80
- 1. Main agent runs the audit, builds fix plan, writes .brain/fix-plan-*.yaml
81
- 2. Main agent spawns validator subagent: "Read .brain/fix-plan-*.yaml;
82
- dry-run each fix; emit veto report."
83
- 3. Validator subagent returns veto list (fresh context — can't share rationalization)
84
- 4. Main agent removes vetoed fixes from plan; opens PR with remainder
85
- ```
86
-
87
- The validator runs in fresh context, so it can't accidentally rationalize the recommender's earlier reasoning. Independent re-evaluation is the load-bearing property.
88
-
89
- ### Path B — Distributed via GitHub Actions
90
-
91
- Two-job CI workflow. Job 1 (recommender) emits the fix plan as a workflow artifact. Job 2 (validator) downloads the artifact, dry-runs, opens the PR.
92
-
93
- ```yaml
94
- # .github/workflows/repo-fixer-apply.yml
95
- jobs:
96
- recommend:
97
- runs-on: ubuntu-latest
98
- steps:
99
- - uses: actions/checkout@v4
100
- - run: bash scripts/audit.sh > /tmp/audit.json
101
- - run: bash scripts/build-fix-plan.sh /tmp/audit.json > /tmp/fix-plan.yaml
102
- - uses: actions/upload-artifact@v4
103
- with: { name: fix-plan, path: /tmp/fix-plan.yaml }
104
-
105
- validate:
106
- needs: recommend
107
- runs-on: ubuntu-latest
108
- steps:
109
- - uses: actions/checkout@v4
110
- - uses: actions/download-artifact@v4
111
- with: { name: fix-plan }
112
- - run: bash scripts/validate-fix-plan.sh fix-plan.yaml > /tmp/vetoes.txt
113
- - run: bash scripts/apply-survivors.sh fix-plan.yaml /tmp/vetoes.txt
114
- - uses: peter-evans/create-pull-request@v6
115
- with:
116
- title: '[repo-fixer] Apply audited fixes'
117
- body-path: /tmp/pr-body.md
118
- ```
119
-
120
- Job isolation ensures the validator can't share state with the recommender — Yegge's insight in cleanest form.
121
-
122
- ## Iterating within a budget (autoresearch DNA)
123
-
124
- > Inspired by Karpathy's [autoresearch](https://github.com/karpathy/autoresearch) — autonomous propose-evaluate-iterate within a fixed budget. Repo-fixer scopes the spirit, not the overnight unattended shape: bounded rounds, deterministic eval, every iteration logged to the audit history ledger.
125
-
126
- The base pattern above is one round. For high-finding-count audits or `strict` strictness, that single round may leave fixes on the table — vetoed because of a *fixable* issue (e.g., a proposed AGENTS.md compression would still exceed 200 lines, but a tighter version wouldn't).
127
-
128
- The iterate-within-budget extension: when the validator vetoes fixes, feed the veto reasons back to the recommender and let it re-propose. Bounded by an explicit budget.
129
-
130
- ### Configuration
131
-
132
- `.brain/config.toml`:
133
-
134
- ```toml
135
- [ops-repo.iteration]
136
- enabled = false # default: false (opt-in)
137
- max_rounds = 3 # hard cap; loop exits early if no new fixes survive
138
- wall_clock_seconds = 300 # 5 minutes total across all rounds
139
- ```
140
-
141
- Each round, the recommender receives:
142
-
143
- 1. The original audit findings (unchanged)
144
- 2. The previous round's veto report (new — the agent reads "your symlink fix was vetoed because the target wasn't valid; here's why")
145
- 3. The set of already-applied fixes from prior rounds (so it doesn't re-propose them)
146
-
147
- Each round logs to the audit history ledger as a separate entry within the run.
148
-
149
- ### When iteration helps
150
-
151
- | Scenario | Outcome with 1 round | Outcome with 3 rounds |
152
- |---|---|---|
153
- | Recommender proposes 200-line AGENTS.md compression that would exceed the budget | Vetoed; user gets a TODO | Round 2 produces a 150-line version that passes |
154
- | Recommender suggests archiving a doc still in the 30-day grace window | Vetoed | Round 2 skips that doc; archives others |
155
- | All fixes pass first-round validation | PR with N fixes | Same PR — loop exits early |
156
-
157
- ### When iteration doesn't help
158
-
159
- - Single-finding fixes (no benefit beyond round 1)
160
- - Vetoes that are fundamentally un-fixable (e.g., `delete-always-vetoed` — the rule will never let it through)
161
- - `lax` strictness (over-engineered for the use case)
162
-
163
- ### Stop conditions
164
-
165
- The loop terminates when ANY of:
166
-
167
- 1. All proposed fixes pass validation (early success)
168
- 2. Two consecutive rounds produce zero new survivors (convergence)
169
- 3. `max_rounds` reached
170
- 4. `wall_clock_seconds` exhausted
171
-
172
- The PR opens with the union of surviving fixes across rounds, plus a final veto report listing what didn't survive.
173
-
174
- ### How autoresearch DNA maps in (and where it stops)
175
-
176
- Autoresearch runs overnight, fully unattended, hill-climbing on a single file with a single metric. This loop runs in a single CI invocation, budgeted in minutes, human-reviewed via PR. We take *bounded propose-evaluate-iterate with a deterministic eval function* — we don't take overnight autonomy. Yegge alignment ("shepherds, not auto-pilots") stays intact.
177
-
178
- ## When NOT to use this pattern
179
-
180
- - **Single-file fixes.** Symlinking CLAUDE.md once doesn't need two agents; the trip-wire itself is the validation.
181
- - **`lax` strictness on prototypes.** Friction unjustified.
182
- - **Repos with no production cost of doc breakage.** Solo side projects.
183
-
184
- The pattern earns its keep on multi-file passes where one bad fix can cascade.
185
-
186
- ## Anti-patterns
187
-
188
- - **Recommender and validator share context.** Defeats the purpose. Validator must run in fresh context (subagent or separate CI job).
189
- - **Validator can edit the plan.** No. Validator only vetoes; the recommender's fixes are immutable inputs. Editing happens in the next round.
190
- - **Skipping the veto report.** The PR body should include the full veto list — humans need to see what *wasn't* applied and why.
191
- - **Auto-merging the PR.** No. The validator gate is necessary but not sufficient; humans still review and merge.
192
- - **Three or more agents in parallel for the same plan.** Diminishing returns; coordination cost dominates after two. Yegge says "two or three" for *different problems*, not redundant validators on one problem.
193
-
194
- ## Cross-references
195
-
196
- - Reliability dial (which `strictness` levels require this pattern): `../guidance/reliability-dial.md`
197
- - Self-healing hooks (the trip-wires the validator runs): `self-healing-hooks.md`
198
- - Audit recipe (the input to the recommender): `audit-existing-repo.md`
199
- - Audit history (vetoes get recorded): `../audit-patterns/audit-history-ledger.md`
@@ -1,366 +0,0 @@
1
- ---
2
- date: 2026-04-27
3
- coverage: canonical
4
- peers:
5
- - continuous-learning-loop.md
6
- - audit-existing-repo.md
7
- - ../audit-patterns/staleness-tooling.md
8
- - ../audit-patterns/redundancy-detection.md
9
- primary_sources:
10
- - https://github.com/lycheeverse/lychee-action
11
- - https://github.com/typicode/husky
12
- - https://pre-commit.com/
13
- - https://docs.github.com/actions/using-workflows/triggering-a-workflow
14
- - https://djw.fyi/portfolio/preventing-drift/
15
- status: research-verified
16
- ---
17
-
18
- # Self-healing hooks (delivers Promise 4)
19
-
20
- > **The premise.** A repo without trip-wires can't honor the "self-healing" promise — it can only be clean today and rotten tomorrow. This recipe installs the hooks that catch breakage before it lands and the workflows that keep watch on a schedule.
21
-
22
- ## What "self-healing" means concretely
23
-
24
- A self-healing repo:
25
-
26
- 1. **Refuses to merge PRs** that introduce drift between CLAUDE.md and AGENTS.md.
27
- 2. **Refuses to merge PRs** with broken intra-repo or external links in `.brain/` or `docs/`.
28
- 3. **Refuses commits** that bloat AGENTS.md / CLAUDE.md past the 200-line ceiling.
29
- 4. **Auto-archives** orphaned docs after a 30-day grace period.
30
- 5. **Surfaces stale content** weekly (scheduled CI), not on a someone-remembered-to-look basis.
31
- 6. **Captures decisions** at the moment of decision (ADR-on-architectural-change), not retroactively.
32
-
33
- The first three are pre-commit / PR-time gates. The fourth is a scheduled workflow. The fifth is a scheduled audit. The sixth is a `continuous-learning-loop.md` flow.
34
-
35
- ## The hook stack
36
-
37
- ### Layer 1 — pre-commit hooks (local; catch problems before they leave the machine)
38
-
39
- Use `pre-commit` (Python) or `husky` (Node). The skill recommends `pre-commit` for cross-language repos and `husky` for Node-monoculture.
40
-
41
- #### pre-commit (`.pre-commit-config.yaml`)
42
-
43
- ```yaml
44
- # .pre-commit-config.yaml
45
- repos:
46
- # Lint Markdown structure
47
- - repo: https://github.com/igorshubovych/markdownlint-cli
48
- rev: v0.42.0
49
- hooks:
50
- - id: markdownlint
51
- files: '\.(md|MD)$'
52
-
53
- # Repo-brain trip-wires (custom, local hooks)
54
- - repo: local
55
- hooks:
56
- # Trip-wire 1: AGENTS.md / CLAUDE.md must not drift
57
- - id: agents-claude-drift
58
- name: AGENTS.md / CLAUDE.md must not have drifted prose
59
- entry: bash -c 'bash scripts/check-agents-claude-drift.sh'
60
- language: system
61
- files: '^(AGENTS\.md|CLAUDE\.md)$'
62
- pass_filenames: false
63
-
64
- # Trip-wire 2: AGENTS.md / CLAUDE.md must stay <200 lines
65
- - id: entry-file-length
66
- name: Entry files <200 lines (warn at 150)
67
- entry: bash -c 'for f in AGENTS.md CLAUDE.md; do if [ -f "$f" ] && [ ! -L "$f" ]; then n=$(wc -l <"$f"); if [ "$n" -gt 200 ]; then echo "ERROR: $f is $n lines (>200)"; exit 1; elif [ "$n" -gt 150 ]; then echo "WARN: $f is $n lines (>150)"; fi; fi; done'
68
- language: system
69
- pass_filenames: false
70
-
71
- # Trip-wire 3: docs in .brain/ or docs/ must have a date
72
- - id: doc-frontmatter-date
73
- name: .brain/*.md and docs/*.md must have date frontmatter or "Last reviewed:" line
74
- entry: bash -c 'bash scripts/check-doc-dates.sh'
75
- language: system
76
- files: '^(\.brain|docs)/.*\.md$'
77
- pass_filenames: true
78
- ```
79
-
80
- #### `scripts/check-agents-claude-drift.sh`
81
-
82
- ```bash
83
- #!/usr/bin/env bash
84
- # Trip-wire: AGENTS.md and CLAUDE.md must not have drifted prose.
85
- # Pass cases:
86
- # (a) CLAUDE.md is a symlink to AGENTS.md → identical content.
87
- # (b) CLAUDE.md is a thin pointer (≤15 lines) referencing AGENTS.md.
88
- # (c) AGENTS.md exists, CLAUDE.md does not.
89
- # Fail: both exist as fat (>15 lines) divergent files.
90
-
91
- set -euo pipefail
92
-
93
- if [ ! -f AGENTS.md ] && [ ! -f CLAUDE.md ]; then
94
- exit 0 # Neither exists; not this hook's problem
95
- fi
96
-
97
- if [ ! -f AGENTS.md ]; then
98
- echo "ERROR: CLAUDE.md exists but AGENTS.md does not. Promote CLAUDE.md → AGENTS.md."
99
- exit 1
100
- fi
101
-
102
- if [ ! -f CLAUDE.md ]; then
103
- exit 0 # AGENTS.md only; fine
104
- fi
105
-
106
- # CLAUDE.md is a symlink? (clean)
107
- if [ -L CLAUDE.md ]; then
108
- target="$(readlink CLAUDE.md)"
109
- if [ "$target" = "AGENTS.md" ]; then
110
- exit 0
111
- else
112
- echo "ERROR: CLAUDE.md is a symlink to '$target', not AGENTS.md."
113
- exit 1
114
- fi
115
- fi
116
-
117
- # CLAUDE.md is thin? (clean)
118
- claude_lines=$(wc -l < CLAUDE.md)
119
- if [ "$claude_lines" -le 15 ]; then
120
- if grep -q -i "AGENTS\.md" CLAUDE.md; then
121
- exit 0
122
- else
123
- echo "ERROR: CLAUDE.md is short but doesn't reference AGENTS.md."
124
- exit 1
125
- fi
126
- fi
127
-
128
- # Both fat → drift risk.
129
- echo "ERROR: Both AGENTS.md ($(wc -l <AGENTS.md) lines) and CLAUDE.md ($claude_lines lines) are fat."
130
- echo " Demote one to a thin pointer or symlink. See ops-repo/standards/claude-md-convention.md."
131
- exit 1
132
- ```
133
-
134
- #### `scripts/check-doc-dates.sh`
135
-
136
- ```bash
137
- #!/usr/bin/env bash
138
- # Trip-wire: every .brain/*.md and docs/*.md must have a date.
139
- set -euo pipefail
140
- fail=0
141
- for f in "$@"; do
142
- if grep -qE '^date:[[:space:]]*[0-9]{4}-[0-9]{2}-[0-9]{2}' "$f"; then
143
- continue # YAML frontmatter date OK
144
- fi
145
- if grep -qE '_Last reviewed:[[:space:]]*[0-9]{4}-[0-9]{2}-[0-9]{2}' "$f"; then
146
- continue # Inline "Last reviewed:" line OK
147
- fi
148
- echo "ERROR: $f has no date frontmatter or 'Last reviewed:' line."
149
- fail=1
150
- done
151
- exit $fail
152
- ```
153
-
154
- ### Layer 2 — PR-time CI (catch problems before merge)
155
-
156
- #### `.github/workflows/repo-brain-pr.yml`
157
-
158
- ```yaml
159
- name: Repo-brain (PR)
160
-
161
- on:
162
- pull_request:
163
- paths: ['**.md', '.brain/**', 'docs/**', 'AGENTS.md', 'CLAUDE.md', '.cursor/**', '.windsurfrules', '.github/copilot-instructions.md']
164
-
165
- jobs:
166
- links:
167
- runs-on: ubuntu-latest
168
- steps:
169
- - uses: actions/checkout@v4
170
- - name: Lychee link check
171
- uses: lycheeverse/lychee-action@v2
172
- with:
173
- args: --cache --max-cache-age=1d --no-progress '.brain/**/*.md' 'docs/**/*.md' '*.md'
174
- fail: true
175
-
176
- drift-and-length:
177
- runs-on: ubuntu-latest
178
- steps:
179
- - uses: actions/checkout@v4
180
- - run: bash scripts/check-agents-claude-drift.sh
181
- - run: bash scripts/check-entry-file-length.sh
182
-
183
- doc-dates:
184
- runs-on: ubuntu-latest
185
- steps:
186
- - uses: actions/checkout@v4
187
- with: { fetch-depth: 0 }
188
- - run: |
189
- changed=$(git diff --name-only origin/${{ github.base_ref }}...HEAD -- '.brain/**/*.md' 'docs/**/*.md' || true)
190
- if [ -n "$changed" ]; then
191
- bash scripts/check-doc-dates.sh $changed
192
- fi
193
-
194
- llm-doc-drift:
195
- if: ${{ vars.LLM_DOC_DRIFT_ENABLED == 'true' }}
196
- runs-on: ubuntu-latest
197
- steps:
198
- - uses: actions/checkout@v4
199
- with: { fetch-depth: 0 }
200
- - name: Ask LLM if code diff requires doc updates
201
- env:
202
- ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
203
- run: bash scripts/llm-doc-drift-check.sh
204
- ```
205
-
206
- The `llm-doc-drift` job is opt-in (gated on `vars.LLM_DOC_DRIFT_ENABLED`) — costs API calls per PR. Worth it for high-traffic repos; overkill for hobby projects.
207
-
208
- ### Layer 3 — scheduled CI (find problems no commit triggered)
209
-
210
- #### `.github/workflows/repo-brain-weekly.yml`
211
-
212
- ```yaml
213
- name: Repo-brain (weekly audit)
214
-
215
- on:
216
- schedule:
217
- - cron: '0 13 * * 1' # Mondays 13:00 UTC
218
- workflow_dispatch:
219
-
220
- jobs:
221
- full-audit:
222
- runs-on: ubuntu-latest
223
- steps:
224
- - uses: actions/checkout@v4
225
- with: { fetch-depth: 0 }
226
-
227
- - name: External link check (full)
228
- uses: lycheeverse/lychee-action@v2
229
- with:
230
- args: --no-progress '.brain/**/*.md' 'docs/**/*.md' '*.md'
231
- fail: false # Don't fail; report
232
-
233
- - name: Stale-doc detection (mtime + frontmatter)
234
- run: bash scripts/find-stale-docs.sh > stale-report.md
235
-
236
- - name: Orphan detection
237
- run: bash scripts/find-orphan-docs.sh > orphan-report.md
238
-
239
- - name: Open issue if findings
240
- if: always()
241
- uses: actions/github-script@v7
242
- with:
243
- script: |
244
- const fs = require('fs');
245
- const stale = fs.readFileSync('stale-report.md', 'utf8');
246
- const orphans = fs.readFileSync('orphan-report.md', 'utf8');
247
- if (stale.trim() || orphans.trim()) {
248
- await github.rest.issues.create({
249
- owner: context.repo.owner,
250
- repo: context.repo.repo,
251
- title: `[ops-repo] Weekly audit findings — ${new Date().toISOString().slice(0,10)}`,
252
- body: `## Stale docs\n\n${stale}\n\n## Orphans\n\n${orphans}`,
253
- labels: ['docs', 'ops-repo']
254
- });
255
- }
256
- ```
257
-
258
- ### Layer 4 — auto-archive (the orphan grace-period flow)
259
-
260
- #### `scripts/find-orphan-docs.sh`
261
-
262
- ```bash
263
- #!/usr/bin/env bash
264
- # Find docs in .brain/ or docs/ not referenced by any entry file or other doc.
265
- set -euo pipefail
266
- all_docs=$(find .brain docs -type f -name '*.md' 2>/dev/null)
267
- referenced=$(
268
- cat AGENTS.md CLAUDE.md README.md .brain/**/*.md docs/**/*.md 2>/dev/null \
269
- | grep -oE '\[[^]]+\]\(([^)]+)\)' \
270
- | grep -oE '\(([^)]+)\)' \
271
- | tr -d '()' \
272
- | sort -u
273
- )
274
- for f in $all_docs; do
275
- base=$(basename "$f")
276
- if ! echo "$referenced" | grep -q -F "$base"; then
277
- # Orphan candidate.
278
- last_modified=$(git log -1 --format=%cs -- "$f")
279
- echo "- $f (last modified: $last_modified)"
280
- fi
281
- done
282
- ```
283
-
284
- #### `.github/workflows/repo-brain-auto-archive.yml`
285
-
286
- ```yaml
287
- name: Repo-brain (auto-archive orphans after 30-day grace)
288
- on:
289
- schedule:
290
- - cron: '0 13 * * 1' # Mondays
291
- workflow_dispatch:
292
-
293
- jobs:
294
- archive:
295
- runs-on: ubuntu-latest
296
- steps:
297
- - uses: actions/checkout@v4
298
- with: { fetch-depth: 0 }
299
- - name: Move stale orphans to .brain/archive/
300
- run: |
301
- # An orphan unmodified for 30+ days AND not in /archive/ → archive it.
302
- while IFS= read -r line; do
303
- [[ -z "$line" ]] && continue
304
- f=$(echo "$line" | cut -d' ' -f2)
305
- [[ "$f" == .brain/archive/* ]] && continue
306
- [[ "$f" == docs/archive/* ]] && continue
307
- mtime=$(git log -1 --format=%ct -- "$f")
308
- now=$(date +%s)
309
- age_days=$(( (now - mtime) / 86400 ))
310
- if [ "$age_days" -gt 30 ]; then
311
- mkdir -p .brain/archive
312
- git mv "$f" ".brain/archive/$(basename "$f")"
313
- echo "Archived: $f (orphan for ${age_days}d)"
314
- fi
315
- done < <(bash scripts/find-orphan-docs.sh)
316
- - name: Open PR
317
- uses: peter-evans/create-pull-request@v6
318
- with:
319
- base: main # see the gotcha below — required for tag-push triggers
320
- title: '[ops-repo] Auto-archive stale orphan docs'
321
- body: 'Auto-archived orphan docs untouched for 30+ days. Review and merge or revert.'
322
- branch: ops-repo/auto-archive
323
- ```
324
-
325
- The PR step is critical — **never silently delete or move docs**. Always open a PR so a human can review.
326
-
327
- ### Gotcha — `peter-evans/create-pull-request` needs `base: main` on tag-push
328
-
329
- If your workflow also triggers on tag pushes (e.g., a build-log harvest that fires on every release tag), the GitHub Actions runner checks out the *tag* — which is a detached HEAD, not a branch. Without an explicit `base` input, `create-pull-request` exits with:
330
-
331
- ```
332
- ##[error]When the repository is checked out on a commit instead of a branch,
333
- the 'base' input must be supplied.
334
- ```
335
-
336
- **Symptom**: every tag-push run of the workflow fails at the PR-opening step. Cron and `workflow_dispatch` runs (which check out the branch) succeed; tag-push runs fail. The audit ledger drops entries silently — the harvester writes the JSON, but the PR never opens, so the entry never lands on `main`.
337
-
338
- **Fix**: always set `base: main` (or your default branch). It's a no-op on cron / dispatch runs (the action would auto-detect `main` anyway) and load-bearing on tag-push runs.
339
-
340
- Observed in the wild on 2026-04-28 — a build-log workflow at `adiahealth/gen-ui-kit` failed for 8 consecutive tag-push runs because the action wouldn't open the PR. The cron path worked but the entry sat in an unmerged PR (`ops-repo/build-log` branch) for 2 days, so the ledger appeared frozen at the last manually-merged entry. The fix is one line.
341
-
342
- ## What the audit verifies
343
-
344
- When `ops-repo` audits a repo, the self-healing check looks for:
345
-
346
- 1. ✅ `.pre-commit-config.yaml` exists OR `.husky/` has equivalent hooks.
347
- 2. ✅ The `agents-claude-drift`, `entry-file-length`, `doc-frontmatter-date` hooks are wired.
348
- 3. ✅ `.github/workflows/repo-brain-pr.yml` (or equivalent) exists and includes lychee.
349
- 4. ✅ `.github/workflows/repo-brain-weekly.yml` (or equivalent scheduled audit) exists.
350
- 5. ✅ `scripts/check-agents-claude-drift.sh` and the other helper scripts exist.
351
-
352
- If any are missing, the audit emits a `MISSING TRIP-WIRE` finding with severity = high (because the promise of self-healing isn't being delivered).
353
-
354
- ## Common anti-patterns
355
-
356
- - **Hooks defined but not installed** — `.pre-commit-config.yaml` exists but no one ran `pre-commit install`. The audit cannot detect installation; this is a `setup` step in `recipes/greenfield-setup.md`.
357
- - **Auto-archive without PR step** — silently moving files breaks links. Always go through PR.
358
- - **Lychee with `fail: false` everywhere** — defeats the gate. Use `fail: true` on PR; `fail: false` only on scheduled audits where issue-opening is the action.
359
- - **No grace period on orphans** — files get archived on the first scan after they go orphaned. 30 days is the recommended floor.
360
-
361
- ## Cross-references
362
-
363
- - Continuous-learning loop (Promise 5): `continuous-learning-loop.md`
364
- - Staleness tooling deep dive: `../audit-patterns/staleness-tooling.md`
365
- - Redundancy detection: `../audit-patterns/redundancy-detection.md`
366
- - Full audit recipe: `audit-existing-repo.md`
@@ -1,113 +0,0 @@
1
- # Skill stewardship loop
2
-
3
- The continuously-learning loop for procedural memory (skills) — the
4
- analog of `harvest ops-repo` for the doc surface.
5
-
6
- **Authored:** 2026-05-02 — implements Step 2 of the ops-repo v2.0
7
- skill-stewardship evolution. Pairs with `scripts/skills/audit-skills.mjs`
8
- + `scripts/skills/draft-skill.mjs` + `scripts/skills/check-skill-frontmatter.mjs`.
9
-
10
- ## The cadence
11
-
12
- Run `npm run audit:skills` at three triggers:
13
-
14
- 1. **Session-end** of any major work (release cut, multi-day arc,
15
- postmortem). Surfaces candidates from procedures the session walked.
16
- 2. **Quarterly** as part of the `/ops-repo` audit. Catches accumulated
17
- drift — stale refs, redundancy, low-utility skills.
18
- 3. **On-demand** when the user asks "is anything stale?" or "what
19
- skills should we have?".
20
-
21
- Each run produces 0–N findings. Triage by severity:
22
-
23
- - **Errors** (currently none from `audit:skills`; `check:skills` produces
24
- errors for missing frontmatter).
25
- - **Warns** — stale refs, description redundancy. Fix immediately or
26
- document as deferred.
27
- - **Info** — procedure-recurrence candidates, graduation gaps,
28
- description-divergence hints. Review; promote to drafts via
29
- `npm run draft:skill <name>` when appropriate.
30
-
31
- ## The 6 detection signals (recap)
32
-
33
- | # | Signal | Threshold | What it surfaces |
34
- |---|---|---|---|
35
- | 1 | Pattern recurrence in journals | ≥ 2 sessions | Procedures walked enough to deserve a skill |
36
- | 2 | Graduations without skills | row mentions script but no skill | Permanent infrastructure that lacks procedural skill capture |
37
- | 3 | Memory citation count | ≥ 3 citations | Memory entries hot enough to warrant skill promotion |
38
- | 4 | Stale path/tag refs in SKILL.md | path doesn't resolve | Skills referencing renamed code |
39
- | 5 | Description-vs-body divergence | body churn ≥ 100 lines | Skills whose body has evolved beyond the description |
40
- | 6 | Pairwise description similarity | Jaccard ≥ 0.6 | Likely-redundant skill pairs |
41
-
42
- Thresholds tunable via `.brain/config.toml` (when implemented; today
43
- they're hardcoded in `audit-skills.mjs`).
44
-
45
- ## The triage flow
46
-
47
- ```
48
- audit-skills (read-only)
49
-
50
-
51
- finding cluster
52
-
53
- ├─→ stale-skill-ref ──────→ iterate skill --update (fix paths)
54
- │ (or: just edit SKILL.md directly)
55
-
56
- ├─→ description-similarity ──→ iterate skill --merge OR
57
- │ edit descriptions to differentiate
58
-
59
- ├─→ procedure-recurrence ──→ draft-skill <name> --journal-section ...
60
- │ (operator reviews + commits)
61
-
62
- ├─→ graduation-without-skill → draft-skill <name> --audit-finding ...
63
- │ (or: skip if mechanical infra is enough)
64
-
65
- └─→ description-divergence-hint ──→ review SKILL.md description vs body;
66
- edit description if stale
67
- ```
68
-
69
- ## Anti-patterns
70
-
71
- - **Acting on every info finding.** Info-level signals are advisory.
72
- Procedure-recurrence in journals doesn't *always* mean a skill is
73
- warranted — sometimes the recurring section is "Verification" which
74
- is just session-end discipline, not a procedure. Triage before
75
- promoting.
76
-
77
- - **Auto-archiving stale skills.** `audit-skills` doesn't have an
78
- `archive` mode for the same reason `ops-repo` doesn't auto-delete
79
- orphan docs: a stale skill might just need an `iterate skill --update`
80
- pass, not deletion. Archive only after explicit superseded-by
81
- designation.
82
-
83
- - **Filling out the skeleton in one pass.** `draft-skill` produces a
84
- TODO-heavy SKILL.md. The skeleton lays the canvas; **synthesis is a
85
- separate pass**, ideally invoking `meta-skill` /
86
- `meta-expert-author` against the skeleton. Don't ship a draft as
87
- if it were a finished skill — `check:skills` catches the
88
- description-too-short and trigger-phrases-thin cases, but only after
89
- you ask CI to validate.
90
-
91
- - **Treating user-level skills as in scope.** This audit walks
92
- `.agents/skills/` (project-local) only. User-level skills at
93
- `~/.claude/skills/` (or `~/.pi/agent/skills/` for Pi) are managed by a separate cadence — they travel
94
- across projects and shouldn't be governed by any single project's
95
- audit. Run a separate user-level audit quarterly if needed.
96
-
97
- ## Pairs with
98
-
99
- - `lockstep-release` — every coordinated cut graduates infrastructure;
100
- the post-publish admin should include `audit:skills` to capture any
101
- procedures the cut walked.
102
- - `stale-audit` — sibling sweep for the doc surface.
103
- - `ops-postmortem` — postmortems often surface graduation
104
- candidates that map to skills.
105
- - `ops-memory` — when memory entries are superseded by
106
- skills, the entry's description should flag the supersession.
107
-
108
- ## Future evolution
109
-
110
- - **Telemetry-based utility detection.** When the harness logs `Skill({skill: X})` invocations, low-utility skills (zero invocations across N sessions despite matching prompts) become detectable. Today only the heuristic divergence-hint exists.
111
- - **Description-vs-body diff.** Today's body-churn-since-description-edit is approximate. A real diff would track which lines of the description haven't been touched since the body changes.
112
- - **Cross-skill pairs-with graph audit.** When skill A says "pairs with B" but B doesn't say "pairs with A", the graph is asymmetric. An audit signal could flag.
113
- - **Skill lifecycle states in frontmatter.** Adding `status: candidate | draft | active | stale | superseded | archived` would let the audit transition skills explicitly through the graph.