@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,91 +0,0 @@
1
- # Spec dating sweep (git-mtime batch)
2
-
3
- **Added:** 2026-05-02 after F-A7 finding identified ~25 spec files
4
- lacking date markers.
5
-
6
- ## The drift class
7
-
8
- Files in `docs/specs/` (or the project's spec dir) should have a
9
- `date:` frontmatter or `_Last reviewed: YYYY-MM-DD_` line. Without
10
- this, future readers can't tell if the spec is current, when it was
11
- last reviewed, or whether to cross-check against more recent
12
- journal entries.
13
-
14
- The standard fix is "add a `_Last reviewed: <date>_` line." But
15
- hard-coding today's date is wrong — it asserts a review that didn't
16
- happen for files you haven't read.
17
-
18
- ## Detection
19
-
20
- ```bash
21
- for f in docs/specs/*.md; do
22
- if ! grep -qE "^date:|Last reviewed|_Date:_" "$f"; then
23
- echo " $(basename "$f")"
24
- fi
25
- done
26
- ```
27
-
28
- ## Fix recipe (mechanical Python batch using git-mtime)
29
-
30
- Use git's last-modification date as the proxy for content freshness:
31
-
32
- ```python
33
- import pathlib, re, subprocess
34
-
35
- ROOT = pathlib.Path("/path/to/repo")
36
- SPECS = ROOT / "docs/specs"
37
-
38
- def has_date_marker(text):
39
- head = text[:1500]
40
- return bool(re.search(r"^date:\s*\d{4}-\d{2}-\d{2}", head, re.MULTILINE)) or \
41
- "Last reviewed:" in head or "_Date:_" in head
42
-
43
- def git_mtime(p):
44
- try:
45
- out = subprocess.check_output(
46
- ["git", "log", "-1", "--format=%cs", "--", str(p)],
47
- cwd=ROOT, text=True, stderr=subprocess.DEVNULL
48
- ).strip()
49
- return out if out else "TODAY"
50
- except subprocess.CalledProcessError:
51
- return "TODAY"
52
-
53
- count = 0
54
- for p in sorted(SPECS.glob("*.md")):
55
- if p.name == "INDEX.md":
56
- continue
57
- text = p.read_text()
58
- if has_date_marker(text):
59
- continue
60
- mtime = git_mtime(p)
61
- lines = text.splitlines()
62
- h1_idx = next((i for i, l in enumerate(lines) if l.startswith("# ")), None)
63
- if h1_idx is None:
64
- continue
65
- new_lines = lines[:h1_idx+1] + [""] + [f"_Last reviewed: {mtime}_"] + lines[h1_idx+1:]
66
- p.write_text("\n".join(new_lines) + "\n")
67
- count += 1
68
- print(f" {p.name} → _Last reviewed: {mtime}_")
69
-
70
- print(f"\nDated {count} files")
71
- ```
72
-
73
- ## Why git-mtime, not today's date
74
-
75
- - **Accurate:** the file genuinely was reviewed when it was last
76
- edited; using that date doesn't lie.
77
- - **Stable:** running the script idempotently doesn't push every
78
- spec's "Last reviewed" forward to today.
79
- - **Surface-able:** `find docs/specs -name '*.md' -mtime +180` plus
80
- the dated content tells you which specs need an actual review.
81
-
82
- ## Prevention
83
-
84
- The `format-hygiene` audit category catches new undated files. The
85
- batch sweep runs once on a backlog; ongoing prevention is via the
86
- audit's per-PR check.
87
-
88
- ## Related
89
-
90
- - `format-hygiene` audit pattern (sibling).
91
- - `stale-audit` skill check #5.
@@ -1,182 +0,0 @@
1
- ---
2
- date: 2026-04-27
3
- coverage: canonical
4
- peers:
5
- - staleness-tooling.md
6
- - pointer-validation.md
7
- - orphan-detection.md
8
- - redundancy-detection.md
9
- - ../recipes/self-healing-hooks.md
10
- - ../recipes/continuous-learning-loop.md
11
- primary_sources:
12
- - https://djw.fyi/portfolio/preventing-drift/ — Daryl White, "Avoiding the Silent Stale Doc Problem"
13
- - https://git-scm.com/docs/git-log — git log committer-date semantics
14
- - https://github.blog/ai-and-ml/github-copilot/how-to-write-a-great-agents-md-lessons-from-over-2500-repositories/
15
- status: research-verified
16
- ---
17
-
18
- # Stale-content detection (delivers Promise 3, "less-prone-to-staleness")
19
-
20
- > **The premise.** A doc can have intact links, no orphans, and a clean structure — and still be wrong. *Stale content* is the case where the prose, examples, or commands no longer match the code they describe. This is the hardest staleness class to detect because there's no broken pointer to grep for; the rot is semantic. Three heuristics catch most of it cheaply. The rest needs LLM-on-diff (covered in `staleness-tooling.md`).
21
-
22
- ## Where this fits
23
-
24
- `staleness-tooling.md` covers the *tools* (lychee, Vale, markdownlint, LLM-on-diff). This file covers the *patterns* — the heuristic checks the audit runs against the repo. Pair them: the tool tells you *what to run*, the pattern tells you *what to look for*.
25
-
26
- ## Three heuristics
27
-
28
- | # | Heuristic | What it catches | Cost |
29
- |---|---|---|---|
30
- | 1 | **Git-mtime + missing dated frontmatter** | Docs nobody has touched in 6+ months that also nobody has explicitly re-affirmed | Cheap (one `find` + one `grep`) |
31
- | 2 | **Symbol/path references in prose vs `git ls-files`** | Docs that mention class/function/file names that no longer exist in the codebase | Cheap (grep + set diff) |
32
- | 3 | **Commands in docs vs current package manifest** | AGENTS.md says `npm install` but `pnpm-lock.yaml` is the only lockfile; or `python setup.py` but the project moved to `uv` | Medium (a few `jq` / file-existence checks) |
33
-
34
- These three together catch the bulk of stale content. The long tail (semantic rot in prose) needs LLM-on-diff per `staleness-tooling.md`.
35
-
36
- ## Heuristic 1 — git-mtime + missing dated frontmatter
37
-
38
- A doc unmodified for >6 months *and* without a `_Last reviewed: YYYY-MM-DD_` line is probably stale. The "AND" is critical: a 4-year-old `docs/architecture.md` re-reviewed quarterly is not stale.
39
-
40
- ```bash
41
- #!/usr/bin/env bash
42
- # scripts/find-stale-by-age.sh
43
- set -euo pipefail
44
- threshold_days=180
45
- now=$(date +%s)
46
- find .brain docs -type f -name '*.md' \
47
- -not -path '.brain/archive/*' -not -path '.brain/adrs/*' -not -path '.brain/postmortems/*' \
48
- -not -path 'docs/archive/*' -not -path 'docs/adrs/*' -not -path 'docs/postmortems/*' \
49
- | while read -r f; do
50
- last=$(git log -1 --format=%ct -- "$f" 2>/dev/null || echo 0)
51
- [ "$last" -eq 0 ] && continue
52
- age=$(( (now - last) / 86400 ))
53
- [ "$age" -le "$threshold_days" ] && continue
54
- if rev=$(grep -oE '_Last reviewed:[[:space:]]*[0-9]{4}-[0-9]{2}-[0-9]{2}' "$f" \
55
- | grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2}' | head -1); then
56
- ru=$(date -j -f '%Y-%m-%d' "$rev" +%s 2>/dev/null \
57
- || date -d "$rev" +%s 2>/dev/null || echo 0)
58
- [ $(( (now - ru) / 86400 )) -le "$threshold_days" ] && continue
59
- echo "STALE-AGE: $f (commit ${age}d ago; review $(( (now - ru) / 86400 ))d ago)"
60
- else
61
- echo "STALE-AGE: $f (commit ${age}d ago; no _Last reviewed:_ line)"
62
- fi
63
- done
64
- ```
65
-
66
- Excluded folders: ADRs (immutable — see `../doc-types/adr-pattern.md`) and post-mortems (describe a fixed past event). Use `git log` committer-date, not filesystem mtime — `clone`/`rebase`/`worktree` clobber filesystem mtime.
67
-
68
- ## Heuristic 2 — symbol/path references vs `git ls-files`
69
-
70
- A doc *names* something (class, function, file path) that the code no longer contains. Catches the canonical class-renamed-doc-not-updated case.
71
-
72
- ```bash
73
- #!/usr/bin/env bash
74
- # scripts/find-stale-symbols.sh
75
- set -euo pipefail
76
- all_paths=$(git ls-files | sort -u)
77
- find .brain docs -type f -name '*.md' \
78
- -not -path '.brain/archive/*' -not -path '.brain/adrs/*' -not -path '.brain/postmortems/*' \
79
- -not -path 'docs/archive/*' -not -path 'docs/adrs/*' -not -path 'docs/postmortems/*' \
80
- | while read -r f; do
81
- # Backticked file paths.
82
- grep -oE '`[a-zA-Z0-9_./-]+\.(ts|tsx|js|jsx|py|go|rs|java|rb|json|toml|yaml|yml)`' "$f" \
83
- | tr -d '`' | sort -u | while read -r ref; do
84
- grep -qxF "$ref" <<<"$all_paths" || echo "STALE-PATH: $f -> $ref"
85
- done
86
- # Backticked PascalCase identifiers (cheap class-name proxy).
87
- grep -oE '`[A-Z][a-zA-Z0-9_]{3,}`' "$f" \
88
- | tr -d '`' | sort -u | while read -r sym; do
89
- git grep -q -wF "$sym" -- ':!*.md' ':!.brain/**' ':!docs/**' 2>/dev/null \
90
- || echo "STALE-SYMBOL: $f -> $sym"
91
- done
92
- done
93
- ```
94
-
95
- False-positive sources: symbols inside before/after code blocks; aliased symbols (`Foo = Bar`); test-only definitions. Emit as **advisory** — human reviews before acting.
96
-
97
- ## Heuristic 3 — commands vs package manifest
98
-
99
- AGENTS.md says `npm install` but only `pnpm-lock.yaml` exists; the agent runs npm and pollutes the repo with `package-lock.json`. Precise enough to gate as a pre-commit check.
100
-
101
- ```bash
102
- #!/usr/bin/env bash
103
- # scripts/check-commands-vs-manifest.sh
104
- set -euo pipefail
105
- fail=0
106
- pm=""
107
- if [ -f pnpm-lock.yaml ]; then pm=pnpm
108
- elif [ -f yarn.lock ]; then pm=yarn
109
- elif [ -f bun.lockb ] || [ -f bun.lock ]; then pm=bun
110
- elif [ -f package-lock.json ]; then pm=npm
111
- fi
112
- for f in AGENTS.md CLAUDE.md README.md CONTRIBUTING.md; do
113
- [ -f "$f" ] && [ ! -L "$f" ] || continue
114
- if [ -n "$pm" ]; then
115
- awk '/^```(bash|sh|shell|console)/,/^```$/' "$f" \
116
- | grep -oE '\b(npm|pnpm|yarn|bun)\b' | sort -u | while read -r p; do
117
- [ "$p" != "$pm" ] && { echo "STALE-CMD: $f uses '$p'; lockfile is '$pm'"; fail=1; }
118
- done
119
- fi
120
- if [ -f uv.lock ]; then
121
- awk '/^```(bash|sh|shell|console)/,/^```$/' "$f" \
122
- | grep -qE '\b(pip install|python setup\.py)\b' \
123
- && { echo "STALE-CMD: $f uses pip/setup.py; uv.lock present"; fail=1; }
124
- fi
125
- done
126
- exit $fail
127
- ```
128
-
129
- Extend per ecosystem: Cargo, Go modules, Bundler. Same pattern — canonical manifest vs command-block PM/runner mismatch.
130
-
131
- ## Putting the three together
132
-
133
- The full stale-content pass:
134
-
135
- ```bash
136
- echo "=== Heuristic 1: age ==="
137
- bash scripts/find-stale-by-age.sh
138
-
139
- echo "=== Heuristic 2: symbols ==="
140
- bash scripts/find-stale-symbols.sh
141
-
142
- echo "=== Heuristic 3: commands ==="
143
- bash scripts/check-commands-vs-manifest.sh
144
- ```
145
-
146
- Run weekly per `../recipes/self-healing-hooks.md`'s scheduled cron. Findings are filed as a single weekly issue, not as commit-blocking errors — these heuristics produce false positives and shouldn't gate merges.
147
-
148
- The exception: heuristic 3 is precise enough to gate. If `pnpm-lock.yaml` exists and AGENTS.md says `npm install`, that's an unambiguous bug — wire it as a pre-commit check.
149
-
150
- ## Severity rubric
151
-
152
- | Finding | Severity | Why |
153
- |---|---|---|
154
- | Heuristic 3 — command mismatch (AGENTS.md says `npm` + `pnpm-lock.yaml`) | High | Agent will run wrong PM and pollute repo |
155
- | Heuristic 2 — symbol referenced in AGENTS.md no longer exists | High | Canonical doc misleads agent on every session |
156
- | Heuristic 2 — symbol referenced in `.brain/**` or `docs/**` no longer exists | Medium | Lower visibility but still wrong |
157
- | Heuristic 1 — doc >6mo old, no review line | Medium | Likely-but-not-certainly stale; advisory |
158
- | Heuristic 1 — doc >12mo old, no review line | High | Almost certainly stale |
159
-
160
- ## What this pattern is NOT for
161
-
162
- - **Broken intra-repo links** — that's `pointer-validation.md`. Stale content is about *correct prose about wrong code*, not about links.
163
- - **External link rot** — `staleness-tooling.md`'s lychee.
164
- - **Live external links pointing at outdated content** — that's a separate concern. `lychee` confirms the URL responds; it doesn't check whether the *fetched content still matches what the doc claims*. For that, see `../recipes/external-reference-verification.md` (WebFetch-powered, autoresearch-DNA).
165
- - **Outdated dependency versions in lockfiles** — out of doc-audit scope; that's a Dependabot / Renovate problem.
166
- - **Generic "the doc is too short / shallow"** — quality issues, not staleness; covered by `../guidance/llm-doc-writing.md`.
167
-
168
- ## Companion: when these heuristics aren't enough
169
-
170
- For semantic rot the heuristics miss ("the doc says we use Postgres but actually we migrated to PlanetScale six months ago" — no symbol-name overlap, no command-block giveaway), the answer is **LLM-on-diff** per `staleness-tooling.md`. On every PR, an LLM compares the code diff against `AGENTS.md` and `.brain/**` + `docs/**` and flags doc sections that should have changed. It's the most expensive layer (API calls per PR) and it's gated on `vars.LLM_DOC_DRIFT_ENABLED` per `../recipes/self-healing-hooks.md`.
171
-
172
- The three heuristics in this file are the cheap baseline; LLM-on-diff is the deeper-but-pricier complement.
173
-
174
- ## Cross-references
175
-
176
- - Tooling for staleness (lychee, Vale, markdownlint, LLM-on-diff): `staleness-tooling.md`
177
- - Pointer validation (link-level rot): `pointer-validation.md`
178
- - Orphan detection (unreachable docs): `orphan-detection.md`
179
- - Redundancy detection (drift between fat files): `redundancy-detection.md`
180
- - Self-healing hooks (where the cron runs): `../recipes/self-healing-hooks.md`
181
- - Continuous-learning loop (how AGENTS.md *stops* going stale): `../recipes/continuous-learning-loop.md`
182
- - External-reference verification (WebFetch-powered; catches the gap above): `../recipes/external-reference-verification.md`
@@ -1,156 +0,0 @@
1
- ---
2
- date: 2026-04-27
3
- coverage: extended
4
- peers:
5
- - stale-content.md
6
- - pointer-validation.md
7
- - ../guidance/llm-doc-writing.md
8
- primary_sources:
9
- - https://github.com/lycheeverse/lychee — fast Markdown/HTML link checker (Rust)
10
- - https://github.com/lycheeverse/lychee-action — GitHub Action
11
- - https://vale.sh/ — markup-aware prose linter
12
- - https://github.com/DavidAnson/markdownlint — Markdown structure linter
13
- - https://djw.fyi/portfolio/preventing-drift/ — Daryl White, "Avoiding the Silent Stale Doc Problem"
14
- - https://docuwriter.ai/ — commercial code-doc-drift product
15
- status: research-verified
16
- ---
17
-
18
- # Tooling for staleness detection
19
-
20
- > **What to actually run** when the audit needs help finding stale links, broken references, prose smells, and code/doc drift. The skill itself implements the simplest checks (existence, last-modified, broken pointers); for deeper coverage, reach for these tools.
21
-
22
- ## Link checking — `lychee`
23
-
24
- **`lychee`** ([lycheeverse/lychee](https://github.com/lycheeverse/lychee)) is a fast Markdown/HTML/RST/text link checker written in Rust. It's the de-facto standard.
25
-
26
- Run locally:
27
-
28
- ```bash
29
- lychee --offline --no-progress '.brain/**/*.md' 'docs/**/*.md' '*.md' '*.MD'
30
- # --offline skips network; useful for fast intra-repo link audit
31
- # drop --offline to also check external URLs
32
- ```
33
-
34
- GitHub Actions:
35
-
36
- ```yaml
37
- # .github/workflows/links.yml
38
- name: Links
39
- on:
40
- pull_request: { paths: ['**.md'] }
41
- schedule: [{ cron: '0 0 * * 1' }] # Mondays
42
- jobs:
43
- links:
44
- runs-on: ubuntu-latest
45
- steps:
46
- - uses: actions/checkout@v4
47
- - uses: lycheeverse/lychee-action@v2
48
- with:
49
- args: --cache --max-cache-age=1d --no-progress '.brain/**/*.md' 'docs/**/*.md' '*.md'
50
- fail: true
51
- ```
52
-
53
- The cache is essential — without it, GitHub rate-limits external link checks quickly.
54
-
55
- Older alternative: `markdown-link-check` (Node). Slower; lychee is preferred.
56
-
57
- ## Prose linting — `Vale`
58
-
59
- **`Vale`** ([vale.sh](https://vale.sh/)) is a markup-aware prose linter — used by Datadog, Grafana, Elastic, Microsoft, and others. Custom rule packs let you enforce a style guide (sentence length, weasel words, branding terms, Markdown conventions).
60
-
61
- Useful for the audit only when the project has a content style guide. If not, skip.
62
-
63
- ```bash
64
- vale .brain/ docs/
65
- ```
66
-
67
- ## Markdown structure linting — `markdownlint`
68
-
69
- **`markdownlint`** ([DavidAnson/markdownlint](https://github.com/DavidAnson/markdownlint)) checks Markdown structure (heading levels, list indentation, blank lines, etc.). Doesn't check freshness; complements lychee.
70
-
71
- ```bash
72
- markdownlint .brain/ docs/ *.md
73
- ```
74
-
75
- ## Code/doc drift detection — the genuinely hard one
76
-
77
- There's no canonical OSS tool for "this code change should have updated this doc." Two pragmatic approaches in 2026:
78
-
79
- ### LLM-on-diff (the popular DIY)
80
-
81
- Per [Daryl White's "Avoiding the Silent Stale Doc Problem"](https://djw.fyi/portfolio/preventing-drift/): a GitHub Action that, on each PR, asks an LLM whether the code diff requires doc updates and which docs.
82
-
83
- Sketch:
84
-
85
- ```yaml
86
- # .github/workflows/doc-drift.yml
87
- name: Doc drift
88
- on: pull_request
89
- jobs:
90
- drift:
91
- runs-on: ubuntu-latest
92
- steps:
93
- - uses: actions/checkout@v4
94
- with: { fetch-depth: 0 }
95
- - run: |
96
- git diff origin/${{ github.base_ref }}...HEAD --stat > /tmp/diff.txt
97
- # Pipe /tmp/diff.txt + AGENTS.md + .brain/ + docs/ index into an LLM that
98
- # returns "no doc changes needed" or "consider updating: <list>".
99
- # Post as a PR comment.
100
- ```
101
-
102
- This is bespoke per project but cheap to maintain.
103
-
104
- ### DocuWriter.ai (commercial)
105
-
106
- [docuwriter.ai](https://docuwriter.ai/) — uses git diff webhooks + LLM analysis to flag doc-relevant code changes. Useful for large repos where the DIY pattern is too noisy.
107
-
108
- ## Git-heuristic staleness (DIY, baseline)
109
-
110
- The simplest staleness signal: file last-modified date. The skill itself can implement this directly:
111
-
112
- ```bash
113
- # Files in .brain/ + docs/ older than 6 months without a "Last reviewed" line:
114
- find .brain docs -name '*.md' -mtime +180 | while read f; do
115
- if ! grep -q '_Last reviewed:' "$f"; then
116
- echo "STALE: $f (last modified: $(git log -1 --format=%cs -- "$f"))"
117
- fi
118
- done
119
- ```
120
-
121
- Use `git log` mtime rather than filesystem mtime — filesystem mtime can be misleading after `git clone` or rebase.
122
-
123
- ## Composing the staleness pass
124
-
125
- Recommended order:
126
-
127
- 1. **Existence + entry-file pointers** (skill internal) — what does the entry say, what's actually there
128
- 2. **lychee** — flag broken intra-repo and external links
129
- 3. **markdownlint** — flag structural issues
130
- 4. **Git-heuristic mtime check** — flag undated docs older than threshold
131
- 5. **Vale** (if project has style guide) — flag prose smells
132
- 6. **LLM-on-diff** (in CI, ongoing) — flag PRs that should have updated docs
133
-
134
- The first four are fast; run them on every audit. The last two are slower / more bespoke; run them in CI.
135
-
136
- ## What to put in the audit report
137
-
138
- For each stale finding:
139
-
140
- ```markdown
141
- - **STALE — `docs/architecture.md`** (severity: medium)
142
- - Last modified: 2024-09-12 (583 days ago).
143
- - No `_Last reviewed:_` line.
144
- - References `class FooHandler` which was renamed to `RequestHandler` in commit `abc123` (2025-03-15).
145
- - **Tools that flagged this:**
146
- - mtime-heuristic (older than 6mo, undated)
147
- - intra-repo grep (referenced symbol no longer exists)
148
- - **Recommendation:** review and re-date, OR archive to `.brain/archive/architecture-2024.md`.
149
- ```
150
-
151
- ## Cross-references
152
-
153
- - General staleness audit pattern: `stale-content.md`
154
- - Pointer validation: `pointer-validation.md`
155
- - LLM-doc-writing guidance: `../guidance/llm-doc-writing.md`
156
- - Full audit recipe: `../recipes/audit-existing-repo.md`
@@ -1,196 +0,0 @@
1
- ---
2
- date: 2026-04-27
3
- coverage: canonical
4
- peers:
5
- - redundancy-detection.md
6
- - ../guidance/context-budget.md
7
- - ../guidance/llm-doc-writing.md
8
- - ../recipes/self-healing-hooks.md
9
- primary_sources:
10
- - https://code.claude.com/docs/en/best-practices
11
- - https://github.blog/ai-and-ml/github-copilot/how-to-write-a-great-agents-md-lessons-from-over-2500-repositories/
12
- status: research-verified
13
- ---
14
-
15
- # Token-waste detection (delivers Promise 2, "token-and-context-optimized")
16
-
17
- > **The premise.** A token loaded into context is a token not available for the work being done. Every byte of AGENTS.md / CLAUDE.md / loaded docs has to *earn its place* — by changing agent behavior in a way no other doc does. This audit catches the bytes that aren't earning.
18
-
19
- ## The five token-waste smells
20
-
21
- | # | Smell | What it looks like | Severity |
22
- |---|---|---|---|
23
- | 1 | **Bloated entry file** | AGENTS.md or CLAUDE.md > 200 lines | High |
24
- | 2 | **Bloated subfolder doc** | `docs/<not-adrs-or-postmortems>/<file>.md` > 500 lines | Medium |
25
- | 3 | **Verbose prose** | Long paragraphs where bullets / tables work | Low |
26
- | 4 | **Cross-doc repetition** | Same content in 3+ files | Medium (handled in `redundancy-detection.md`) |
27
- | 5 | **Redundant frontmatter / boilerplate** | Long YAML frontmatter, license headers, generated tables of contents in every file | Low |
28
-
29
- ## Smell 1 — bloated entry files (the critical one)
30
-
31
- **The check:** `wc -l AGENTS.md CLAUDE.md`. Anthropic's published guidance is `<200 lines`; we warn at 150 and fail at 200.
32
-
33
- **Why it matters:** entry files are loaded *every session*. A 400-line AGENTS.md costs ~5K tokens *every time the agent starts work*. Across a hundred sessions in a year, that's 500K tokens spent on metadata — a meaningful chunk of any per-developer LLM budget, before doing any work.
34
-
35
- **Auto-detection:**
36
-
37
- ```bash
38
- # Pre-commit hook (also in self-healing-hooks.md)
39
- for f in AGENTS.md CLAUDE.md; do
40
- [ -f "$f" ] && [ ! -L "$f" ] || continue
41
- n=$(wc -l < "$f")
42
- if [ "$n" -gt 200 ]; then
43
- echo "ERROR: $f is $n lines (>200). See guidance/context-budget.md."
44
- exit 1
45
- elif [ "$n" -gt 150 ]; then
46
- echo "WARN: $f is $n lines (>150). Consider compression."
47
- fi
48
- done
49
- ```
50
-
51
- **Fix recipe:** see `../guidance/context-budget.md` "How to reduce a bloated AGENTS.md (the recipe)" — the 8-step compression pass typically takes a 600-line entry file to 150 without losing instructional value.
52
-
53
- ## Smell 2 — bloated subfolder docs
54
-
55
- **The check:** `find .brain docs -name '*.md' -not -path '.brain/adrs/*' -not -path '.brain/postmortems/*' -not -path '.brain/architecture/*'` and any file with `wc -l > 500`.
56
-
57
- **Why it matters:** unlike entry files, subfolder docs aren't loaded every session — but a bloated `docs/setup.md` (1200 lines) is a sign the doc has become a dumping ground rather than a focused unit. Split into a folder.
58
-
59
- **Exceptions:**
60
-
61
- - `.brain/adrs/<one>.md` can be any length — one ADR captures one decision in full.
62
- - `.brain/postmortems/<one>.md` can be any length — incidents need depth.
63
- - `.brain/architecture/<one>.md` may be long; consider splitting into multiple files in the folder if so.
64
- - `CHANGELOG.md` is append-only; it grows without bound.
65
-
66
- **Auto-detection:**
67
-
68
- ```bash
69
- find .brain docs -name '*.md' -type f \
70
- -not -path '.brain/adrs/*' \
71
- -not -path '.brain/postmortems/*' \
72
- -not -path '.brain/architecture/*' \
73
- -not -path '.brain/archive/*' \
74
- | while read f; do
75
- n=$(wc -l < "$f")
76
- if [ "$n" -gt 500 ]; then
77
- echo "$f: $n lines (consider splitting into a folder)"
78
- fi
79
- done
80
- ```
81
-
82
- **Fix recipe:** if `docs/setup.md` is 1200 lines covering "first-time setup", "deployment", "troubleshooting", "FAQ" — split:
83
-
84
- ```
85
- docs/setup/
86
- ├── README.md (~30 lines: index)
87
- ├── first-time.md (~150)
88
- ├── deployment.md (~200)
89
- ├── troubleshooting.md (~300)
90
- └── faq.md (~150)
91
- ```
92
-
93
- Update entry-file pointers from `docs/setup.md` → `docs/setup/`.
94
-
95
- ## Smell 3 — verbose prose
96
-
97
- **The check:** prose-vs-bullet ratio. A heuristic: paragraphs longer than 4 sentences, especially in the `Conventions` or `Build` sections of AGENTS.md, are usually compressible.
98
-
99
- **Why it matters:** the agent doesn't need narrative — it needs constraints. "We use TypeScript with strict mode enabled because we value type safety and prefer to catch errors at compile time rather than runtime" is twice the tokens of "TypeScript: strict" and worse for the agent.
100
-
101
- **Auto-detection:** hard to automate cleanly. Practical approach: a script that flags any AGENTS.md / CLAUDE.md paragraph >300 characters as a review candidate.
102
-
103
- ```bash
104
- # Find long paragraphs (>300 chars between blank lines) in AGENTS.md
105
- awk -v RS='' -v ORS='\n\n' '{ if (length($0) > 300 && !/^#/) print NR": "$0 }' AGENTS.md
106
- ```
107
-
108
- **Fix recipe:** convert prose to bullets or tables. Test: can you read it as instructions to follow? If yes, bullets. If no (it's actually motivation/context), move to a different file.
109
-
110
- ## Smell 4 — cross-doc repetition
111
-
112
- Detailed in `redundancy-detection.md`. Token cost is 2× / 3× / Nx of the same content loaded N times.
113
-
114
- ## Smell 5 — redundant frontmatter / boilerplate
115
-
116
- **The check:** YAML frontmatter that's longer than 5-10 lines per file, or boilerplate (license headers, "this file is auto-generated", boilerplate ToCs) that adds bytes without information.
117
-
118
- **Why it matters:** small per-file but it adds up. A 50-line license header in every doc, across 80 docs, is 4000 lines of pure tax.
119
-
120
- **Auto-detection:**
121
-
122
- ```bash
123
- # Find files with YAML frontmatter >10 lines
124
- for f in .brain/**/*.md docs/**/*.md *.md; do
125
- [ -f "$f" ] || continue
126
- if head -1 "$f" | grep -q '^---'; then
127
- end=$(awk '/^---/{i++; if(i==2) print NR}' "$f")
128
- [ -n "$end" ] && [ "$end" -gt 12 ] && echo "$f: frontmatter is $end lines"
129
- fi
130
- done
131
- ```
132
-
133
- **Fix recipe:**
134
- - Trim YAML frontmatter to: `date`, `coverage`, `peers`, `primary_sources`, `status`. That's it.
135
- - Move license headers into a single `LICENSE` file at the root (which is the convention anyway).
136
- - Generate ToCs at render time, not commit time. (For GitHub-rendered docs, the GitHub UI renders the ToC; don't commit one.)
137
-
138
- ## What does NOT count as token waste
139
-
140
- - **Long ADRs** — one architectural decision captured in full is the right shape; don't compress for its own sake.
141
- - **Long post-mortems** — incidents with complex root causes need depth.
142
- - **Long CHANGELOG.md** — append-only history.
143
- - **Long ARCHITECTURE.md (within reason)** — under ~1500 lines, the depth is earning its tokens. Past that, split.
144
- - **Code examples** — if an example illustrates a non-obvious pattern, it's earning its place. If it's restating something obvious, cut it.
145
-
146
- ## The full audit pass
147
-
148
- ```bash
149
- # 1. Entry file length
150
- for f in AGENTS.md CLAUDE.md; do
151
- [ -f "$f" ] && [ ! -L "$f" ] || continue
152
- n=$(wc -l < "$f")
153
- [ "$n" -gt 150 ] && echo "ENTRY-FILE-LENGTH: $f = $n lines"
154
- done
155
-
156
- # 2. Subfolder bloat
157
- find .brain docs -name '*.md' -type f \
158
- -not -path '.brain/adrs/*' \
159
- -not -path '.brain/postmortems/*' \
160
- -not -path '.brain/architecture/*' \
161
- -not -path '.brain/archive/*' \
162
- | while read f; do
163
- n=$(wc -l < "$f")
164
- [ "$n" -gt 500 ] && echo "SUBFOLDER-BLOAT: $f = $n lines"
165
- done
166
-
167
- # 3. Verbose prose in entry files
168
- for f in AGENTS.md CLAUDE.md; do
169
- [ -f "$f" ] && [ ! -L "$f" ] || continue
170
- awk -v f="$f" -v RS='' '{ if (length($0) > 300 && !/^#/) print "VERBOSE-PARA: "f": "substr($0,1,80)"..." }' "$f"
171
- done
172
-
173
- # 4. Frontmatter bloat
174
- for f in $(find . -name '*.md' -type f -not -path '*/node_modules/*'); do
175
- head -1 "$f" 2>/dev/null | grep -q '^---' || continue
176
- end=$(awk '/^---/{i++; if(i==2){ print NR; exit }}' "$f")
177
- [ -n "$end" ] && [ "$end" -gt 12 ] && echo "FRONTMATTER-BLOAT: $f = $end lines"
178
- done
179
- ```
180
-
181
- ## Severity rubric
182
-
183
- | Finding | Severity | Why |
184
- |---|---|---|
185
- | Entry file >200 lines | High | Loaded every session; per-session waste |
186
- | Entry file 150-200 | Medium | Approaching ceiling |
187
- | Subfolder doc >500 (non-ADR/postmortem) | Medium | One-off cost when loaded; structural smell |
188
- | Verbose prose in entry file | Low | Per-session waste, individually small |
189
- | Frontmatter bloat | Low | Per-file waste, individually small |
190
-
191
- ## Cross-references
192
-
193
- - Context budget (the math behind these limits): `../guidance/context-budget.md`
194
- - Redundancy detection (cross-doc repetition): `redundancy-detection.md`
195
- - LLM-doc-writing (content-quality companion): `../guidance/llm-doc-writing.md`
196
- - Self-healing hooks (where these checks run automatically): `../recipes/self-healing-hooks.md`