@adia-ai/adia-ui-forge 0.1.3 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +3 -6
- package/CHANGELOG.md +27 -34
- package/README.md +35 -40
- package/agents/a2ui-engineer.md +22 -53
- package/agents/component-author.md +29 -0
- package/agents/framework-verifier.md +26 -0
- package/agents/release-engineer.md +21 -81
- package/agents/routing-corpus.json +293 -64
- package/bin/demo-postwrite-pattern-gate +94 -0
- package/bin/forge-lint +17 -2
- package/bin/sidecar-prewrite-guard +104 -0
- package/commands/deploy.md +9 -0
- package/commands/dogfood.md +10 -0
- package/commands/gen-review.md +9 -0
- package/commands/release.md +10 -0
- package/hooks/hooks.json +15 -0
- package/package.json +3 -6
- package/references/contracts/a2ui-mcp-surface.md +35 -0
- package/references/contracts/migration-guide-format.md +34 -0
- package/references/shared/content-trust.md +19 -74
- package/skills/adia-a2ui/SKILL.md +99 -0
- package/skills/{adia-ui-a2ui → adia-a2ui}/evals/routing-corpus.json +10 -10
- package/skills/adia-a2ui/references/anti-patterns.md +27 -0
- package/skills/adia-a2ui/references/chunk-authoring.md +71 -0
- package/skills/adia-a2ui/references/corpus-discipline.md +68 -0
- package/skills/adia-a2ui/references/eval-diagnostics.md +86 -0
- package/skills/adia-a2ui/references/format-extension-decisions.md +66 -0
- package/skills/adia-a2ui/references/leverage-rules.md +52 -0
- package/skills/adia-a2ui/references/mcp-pipeline-ops.md +83 -0
- package/skills/adia-a2ui/references/mcp-tool-reference.md +59 -0
- package/skills/adia-a2ui/references/pipeline-overview.md +115 -0
- package/skills/adia-a2ui/references/semantic-fail-lifting.md +74 -0
- package/skills/adia-a2ui/references/strategy-engines.md +109 -0
- package/skills/adia-a2ui/references/zettel-calibration.md +104 -0
- package/skills/adia-author/SKILL.md +112 -0
- package/skills/adia-author/evals/routing-corpus.json +222 -0
- package/skills/{adia-ui-authoring → adia-author}/references/anti-patterns.md +33 -4
- package/skills/{adia-ui-authoring → adia-author}/references/authoring-cycle.md +9 -11
- package/skills/adia-author/references/canonical-pattern-index.md +243 -0
- package/skills/{adia-ui-authoring → adia-author}/references/code-style.md +19 -21
- package/skills/adia-author/references/common-gotchas.md +129 -0
- package/skills/adia-author/references/composite-demo-protocol.md +271 -0
- package/skills/{adia-ui-authoring → adia-author}/references/css-patterns.md +19 -6
- package/skills/{adia-ui-authoring → adia-author}/references/lifecycle-patterns.md +1 -0
- package/skills/{adia-ui-authoring → adia-author}/references/llm-bridge.md +3 -5
- package/skills/{adia-ui-authoring → adia-author}/references/module-promotion.md +20 -38
- package/skills/{adia-ui-authoring → adia-author}/references/primitive-audit.md +2 -4
- package/skills/{adia-ui-authoring → adia-author}/references/shell-patterns.md +12 -18
- package/skills/{adia-ui-authoring → adia-author}/references/token-contract.md +5 -7
- package/skills/{adia-ui-authoring → adia-author}/references/worked-example.md +3 -3
- package/skills/{adia-ui-authoring → adia-author}/references/yaml-contract.md +3 -3
- package/skills/{adia-ui-authoring → adia-author}/scripts/build-canonical-pattern-index.mjs +3 -3
- package/skills/adia-deploy/SKILL.md +128 -0
- package/skills/{adia-ui-ops → adia-deploy}/references/deploy-playbooks.md +47 -30
- package/skills/adia-dogfood/SKILL.md +124 -0
- package/skills/adia-dogfood/references/admin-shell-anatomy.md +77 -0
- package/skills/adia-dogfood/references/app-shell-pitfalls.md +66 -0
- package/skills/adia-dogfood/references/card-anatomy-sweep.md +66 -0
- package/skills/adia-dogfood/references/html-attr-sweep.md +63 -0
- package/skills/adia-dogfood/references/native-leak-annotations.md +73 -0
- package/skills/adia-dogfood/references/visual-probe-triage.md +80 -0
- package/skills/{adia-ui-dogfood → adia-dogfood}/scripts/analyze.mjs +30 -14
- package/skills/adia-gen-review/SKILL.md +127 -0
- package/skills/adia-gen-review/references/corpus-html-patterns.md +279 -0
- package/skills/adia-gen-review/references/loop-protocol.md +216 -0
- package/skills/adia-gen-review/references/rubric-cosmetic.md +100 -0
- package/skills/adia-gen-review/references/rubric-decompose.md +101 -0
- package/skills/adia-gen-review/references/rubric-score.md +214 -0
- package/skills/{adia-ui-gen-review → adia-gen-review}/references/scores.schema.json +2 -2
- package/skills/{adia-ui-gen-review → adia-gen-review}/scripts/gen-review-coverage-audit.mjs +4 -4
- package/skills/{adia-ui-gen-review → adia-gen-review}/scripts/gen-review-decompose.mjs +10 -6
- package/skills/{adia-ui-gen-review → adia-gen-review}/scripts/gen-review-status.mjs +5 -5
- package/skills/{adia-ui-gen-review → adia-gen-review}/scripts/validate-cycle-scores.mjs +5 -5
- package/skills/adia-llm-internals/SKILL.md +77 -0
- package/skills/{adia-ui-llm → adia-llm-internals}/references/adapter-contract.md +4 -2
- package/skills/{adia-ui-llm → adia-llm-internals}/references/add-a-provider.md +4 -5
- package/skills/{adia-ui-llm → adia-llm-internals}/references/bridge-facade.md +10 -3
- package/skills/{adia-ui-llm → adia-llm-internals}/references/browser-proxy-boundary.md +1 -1
- package/skills/{adia-ui-llm → adia-llm-internals}/references/model-registry.md +5 -3
- package/skills/{adia-ui-llm → adia-llm-internals}/references/streaming-sse.md +2 -2
- package/skills/adia-release/SKILL.md +72 -0
- package/skills/adia-release/references/changelog-discipline.md +119 -0
- package/skills/adia-release/references/cut-procedure.md +247 -0
- package/skills/adia-release/references/gates-catalog.md +222 -0
- package/skills/adia-release/references/independent-package-release.md +52 -0
- package/skills/adia-release/references/migration-guide-authoring.md +86 -0
- package/skills/adia-release/references/notes-authoring.md +90 -0
- package/skills/adia-release/references/recovery-paths.md +106 -0
- package/skills/{adia-ui-release → adia-release}/scripts/bump.mjs +27 -2
- package/skills/{adia-ui-release → adia-release}/scripts/dispatch-publish.mjs +4 -1
- package/skills/{adia-ui-release → adia-release}/scripts/insert-stub.mjs +1 -1
- package/skills/{adia-ui-release → adia-release}/scripts/package-paths.mjs +6 -0
- package/skills/{adia-ui-release → adia-release}/scripts/promote-unreleased.mjs +1 -1
- package/skills/{adia-ui-release → adia-release}/scripts/release-pack.mjs +13 -21
- package/skills/{adia-ui-release → adia-release}/scripts/tag-lockstep.mjs +5 -1
- package/skills/adia-site-docs/SKILL.md +68 -0
- package/skills/adia-site-docs/evals/audit-report.md +30 -0
- package/skills/adia-site-docs/evals/routing-corpus.json +176 -0
- package/skills/adia-site-docs/intent.md +72 -0
- package/agents/README.md +0 -209
- package/agents/author.md +0 -56
- package/agents/repo-steward.md +0 -56
- package/agents/spec-architect.md +0 -53
- package/agents/tech-lead.md +0 -57
- package/agents/verifier.md +0 -55
- package/bin/lib/audit-axes.mjs +0 -555
- package/bin/lib/dry-run-irreversible.mjs +0 -236
- package/bin/lib/run-skill-evals.mjs +0 -487
- package/bin/lib/teach-router.mjs +0 -250
- package/commands/adia-forge-a2ui.md +0 -10
- package/commands/adia-forge-author.md +0 -10
- package/commands/adia-forge-dogfood.md +0 -8
- package/commands/adia-forge-llm.md +0 -8
- package/commands/adia-forge-orient.md +0 -10
- package/commands/adia-forge-release.md +0 -8
- package/commands/adia-forge-review.md +0 -10
- package/references/shared/pev-rationale.md +0 -64
- package/references/shared/skill-conventions.md +0 -133
- package/skills/adia-ui-a2ui/CHANGELOG.md +0 -32
- package/skills/adia-ui-a2ui/SKILL.md +0 -243
- package/skills/adia-ui-a2ui/evals/adversarial-corpus.json +0 -75
- package/skills/adia-ui-a2ui/evals/teach-routing-cases.json +0 -100
- package/skills/adia-ui-a2ui/references/anti-patterns.md +0 -24
- package/skills/adia-ui-a2ui/references/chunk-authoring.md +0 -88
- package/skills/adia-ui-a2ui/references/corpus-discipline.md +0 -56
- package/skills/adia-ui-a2ui/references/eval-diagnostics.md +0 -127
- package/skills/adia-ui-a2ui/references/fragment-graph.md +0 -91
- package/skills/adia-ui-a2ui/references/mcp-pipeline-ops.md +0 -106
- package/skills/adia-ui-a2ui/references/mcp-tool-reference.md +0 -398
- package/skills/adia-ui-a2ui/references/pipeline-overview.md +0 -175
- package/skills/adia-ui-a2ui/references/semantic-fail-lifting.md +0 -120
- package/skills/adia-ui-a2ui/references/strategy-engines.md +0 -111
- package/skills/adia-ui-a2ui/references/teach-protocol.md +0 -220
- package/skills/adia-ui-a2ui/references/zettel-calibration.md +0 -93
- package/skills/adia-ui-a2ui/scripts/audit-a2ui-roster.mjs +0 -96
- package/skills/adia-ui-a2ui/scripts/teach-route.mjs +0 -157
- package/skills/adia-ui-a2ui/skill.json +0 -38
- package/skills/adia-ui-authoring/CHANGELOG.md +0 -32
- package/skills/adia-ui-authoring/SKILL.md +0 -256
- package/skills/adia-ui-authoring/assets/case-studies/admin-shell-decomposition.md +0 -101
- package/skills/adia-ui-authoring/assets/case-studies/maxtokens-32768-discovery.md +0 -109
- package/skills/adia-ui-authoring/assets/case-studies/theme-panel-promotion.md +0 -113
- package/skills/adia-ui-authoring/evals/adversarial-design-plan-gates.json +0 -138
- package/skills/adia-ui-authoring/evals/routing-corpus.json +0 -245
- package/skills/adia-ui-authoring/references/canonical-pattern-index.md +0 -179
- package/skills/adia-ui-authoring/references/common-gotchas.md +0 -93
- package/skills/adia-ui-authoring/references/composite-demo-protocol.md +0 -1084
- package/skills/adia-ui-authoring/references/teach-protocol.md +0 -428
- package/skills/adia-ui-authoring/scripts/audit-authoring-roster.mjs +0 -148
- package/skills/adia-ui-authoring/skill.json +0 -45
- package/skills/adia-ui-dogfood/CHANGELOG.md +0 -17
- package/skills/adia-ui-dogfood/README.md +0 -62
- package/skills/adia-ui-dogfood/SKILL.md +0 -866
- package/skills/adia-ui-dogfood/skill.json +0 -40
- package/skills/adia-ui-forge/SKILL.md +0 -88
- package/skills/adia-ui-forge/evals/routing-corpus.json +0 -30
- package/skills/adia-ui-gen-review/CHANGELOG.md +0 -108
- package/skills/adia-ui-gen-review/SKILL.md +0 -266
- package/skills/adia-ui-gen-review/references/loop-protocol.md +0 -712
- package/skills/adia-ui-gen-review/references/rubric-cosmetic.md +0 -144
- package/skills/adia-ui-gen-review/references/rubric-decompose.md +0 -117
- package/skills/adia-ui-gen-review/references/rubric-score.md +0 -249
- package/skills/adia-ui-gen-review/references/teach-protocol.md +0 -214
- package/skills/adia-ui-gen-review/skill.json +0 -23
- package/skills/adia-ui-llm/CHANGELOG.md +0 -25
- package/skills/adia-ui-llm/SKILL.md +0 -165
- package/skills/adia-ui-llm/evals/adversarial-corpus.json +0 -75
- package/skills/adia-ui-llm/evals/routing-corpus.json +0 -30
- package/skills/adia-ui-llm/evals/teach-routing-cases.json +0 -73
- package/skills/adia-ui-llm/references/teach-protocol.md +0 -78
- package/skills/adia-ui-llm/scripts/audit-llm-roster.mjs +0 -93
- package/skills/adia-ui-llm/scripts/teach-route.mjs +0 -119
- package/skills/adia-ui-llm/skill.json +0 -33
- package/skills/adia-ui-ops/CHANGELOG.md +0 -291
- package/skills/adia-ui-ops/SKILL.md +0 -401
- package/skills/adia-ui-ops/references/INDEX.md +0 -158
- package/skills/adia-ui-ops/references/audit-cadence.md +0 -263
- package/skills/adia-ui-ops/references/audit-patterns/archive-link-sweep.md +0 -96
- package/skills/adia-ui-ops/references/audit-patterns/audit-history-ledger.md +0 -162
- package/skills/adia-ui-ops/references/audit-patterns/browser-bundle-node-imports.md +0 -154
- package/skills/adia-ui-ops/references/audit-patterns/changelog-unreleased-bloat.md +0 -75
- package/skills/adia-ui-ops/references/audit-patterns/coverage-gaps.md +0 -187
- package/skills/adia-ui-ops/references/audit-patterns/entry-file-coverage.md +0 -122
- package/skills/adia-ui-ops/references/audit-patterns/format-hygiene.md +0 -217
- package/skills/adia-ui-ops/references/audit-patterns/lockstep-versioning.md +0 -113
- package/skills/adia-ui-ops/references/audit-patterns/memory-fragmentation.md +0 -180
- package/skills/adia-ui-ops/references/audit-patterns/orphan-detection.md +0 -202
- package/skills/adia-ui-ops/references/audit-patterns/pointer-validation.md +0 -180
- package/skills/adia-ui-ops/references/audit-patterns/redundancy-detection.md +0 -210
- package/skills/adia-ui-ops/references/audit-patterns/spec-dating-sweep.md +0 -91
- package/skills/adia-ui-ops/references/audit-patterns/stale-content.md +0 -182
- package/skills/adia-ui-ops/references/audit-patterns/staleness-tooling.md +0 -156
- package/skills/adia-ui-ops/references/audit-patterns/token-waste-detection.md +0 -196
- package/skills/adia-ui-ops/references/doc-types/adr-pattern.md +0 -210
- package/skills/adia-ui-ops/references/doc-types/architecture-md.md +0 -190
- package/skills/adia-ui-ops/references/doc-types/changelog.md +0 -183
- package/skills/adia-ui-ops/references/doc-types/decisions-log.md +0 -146
- package/skills/adia-ui-ops/references/doc-types/plan-roadmap.md +0 -182
- package/skills/adia-ui-ops/references/doc-types/postmortem-pattern.md +0 -206
- package/skills/adia-ui-ops/references/genres/prose-and-writing.md +0 -149
- package/skills/adia-ui-ops/references/guidance/context-budget.md +0 -137
- package/skills/adia-ui-ops/references/guidance/llm-doc-writing.md +0 -116
- package/skills/adia-ui-ops/references/guidance/reliability-dial.md +0 -186
- package/skills/adia-ui-ops/references/recipes/adr-introduction.md +0 -211
- package/skills/adia-ui-ops/references/recipes/audit-existing-repo.md +0 -234
- package/skills/adia-ui-ops/references/recipes/cold-start-harvest.md +0 -263
- package/skills/adia-ui-ops/references/recipes/concurrent-learnings-merge.md +0 -158
- package/skills/adia-ui-ops/references/recipes/continuous-learning-loop.md +0 -169
- package/skills/adia-ui-ops/references/recipes/external-reference-verification.md +0 -158
- package/skills/adia-ui-ops/references/recipes/findings-index-readout.md +0 -126
- package/skills/adia-ui-ops/references/recipes/greenfield-setup.md +0 -252
- package/skills/adia-ui-ops/references/recipes/harvest-repo-brain.md +0 -169
- package/skills/adia-ui-ops/references/recipes/import-repo-brain-harvest.md +0 -153
- package/skills/adia-ui-ops/references/recipes/memory-organization.md +0 -182
- package/skills/adia-ui-ops/references/recipes/recommend-then-validate.md +0 -199
- package/skills/adia-ui-ops/references/recipes/self-healing-hooks.md +0 -366
- package/skills/adia-ui-ops/references/recipes/skill-stewardship-loop.md +0 -113
- package/skills/adia-ui-ops/references/standards/agents-md-spec.md +0 -138
- package/skills/adia-ui-ops/references/standards/claude-md-convention.md +0 -123
- package/skills/adia-ui-ops/references/standards/cross-tool-matrix.md +0 -85
- package/skills/adia-ui-ops/references/standards/readme-conventions.md +0 -232
- package/skills/adia-ui-ops/references/teach-protocol.md +0 -215
- package/skills/adia-ui-ops/scripts/audit-ops-roster.mjs +0 -104
- package/skills/adia-ui-ops/skill.json +0 -65
- package/skills/adia-ui-release/CHANGELOG.md +0 -66
- package/skills/adia-ui-release/SKILL.md +0 -323
- package/skills/adia-ui-release/assets/case-studies/2026-05-20-batch-push-v0.6.14-v0.6.15.md +0 -144
- package/skills/adia-ui-release/assets/case-studies/2026-05-20-corpus-drift-remediation-v0.6.15.md +0 -155
- package/skills/adia-ui-release/assets/case-studies/2026-05-20-version-skip-correction-v0.6.12.md +0 -114
- package/skills/adia-ui-release/assets/case-studies/2026-05-21-author-from-scratch-v0.6.18.md +0 -139
- package/skills/adia-ui-release/assets/case-studies/2026-05-21-feedback37-retraction-v0.6.21.md +0 -124
- package/skills/adia-ui-release/assets/case-studies/2026-05-21-fn1-enrichment-pass-v0.6.19.md +0 -125
- package/skills/adia-ui-release/assets/case-studies/2026-05-21-stale-test-detection-v0.6.20.md +0 -142
- package/skills/adia-ui-release/assets/case-studies/2026-05-23-freshness-gate-recovery-v0.6.32.md +0 -97
- package/skills/adia-ui-release/assets/case-studies/2026-05-26-catalog-drift-recurring-v0.6.40.md +0 -147
- package/skills/adia-ui-release/assets/templates/stub-changelog.template.md +0 -22
- package/skills/adia-ui-release/evals/evals.json +0 -164
- package/skills/adia-ui-release/references/changelog-discipline.md +0 -250
- package/skills/adia-ui-release/references/cycle-happy-path.md +0 -520
- package/skills/adia-ui-release/references/exe-deploy.md +0 -149
- package/skills/adia-ui-release/references/gates-catalog.md +0 -778
- package/skills/adia-ui-release/references/independent-package-release.md +0 -129
- package/skills/adia-ui-release/references/ledger-discipline.md +0 -232
- package/skills/adia-ui-release/references/migration-guide-authoring.md +0 -174
- package/skills/adia-ui-release/references/multi-agent-baseline.md +0 -207
- package/skills/adia-ui-release/references/notes-authoring.md +0 -212
- package/skills/adia-ui-release/references/recovery-paths.md +0 -262
- package/skills/adia-ui-release/references/rollup-notes.md +0 -208
- package/skills/adia-ui-release/references/teach-protocol.md +0 -468
- package/skills/adia-ui-release/scripts/audit-gate-roster.mjs +0 -196
- package/skills/adia-ui-release/scripts/make-ledger.mjs +0 -200
- package/skills/adia-ui-release/skill.json +0 -77
- package/skills/dogfood-sweep/CHANGELOG.md +0 -37
- package/skills/dogfood-sweep/README.md +0 -105
- package/skills/dogfood-sweep/SKILL.md +0 -1000
- package/skills/dogfood-sweep/analyze.mjs +0 -600
- package/skills/dogfood-sweep/skill.json +0 -31
- /package/skills/{adia-ui-authoring → adia-author}/references/api-contract.md +0 -0
- /package/skills/{adia-ui-release → adia-release}/scripts/assert-monorepo-root.mjs +0 -0
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
date: 2026-04-27
|
|
3
|
-
coverage: canonical
|
|
4
|
-
peers:
|
|
5
|
-
- coverage-gaps.md
|
|
6
|
-
- staleness-tooling.md
|
|
7
|
-
- entry-file-coverage.md
|
|
8
|
-
- pointer-validation.md
|
|
9
|
-
- orphan-detection.md
|
|
10
|
-
- stale-content.md
|
|
11
|
-
- memory-fragmentation.md
|
|
12
|
-
- ../doc-types/adr-pattern.md
|
|
13
|
-
- ../doc-types/postmortem-pattern.md
|
|
14
|
-
- ../recipes/self-healing-hooks.md
|
|
15
|
-
- ../guidance/context-budget.md
|
|
16
|
-
primary_sources:
|
|
17
|
-
- https://adr.github.io/ — ADR `Status:` field convention
|
|
18
|
-
- https://github.com/joelparkerhenderson/architecture-decision-record
|
|
19
|
-
- https://sre.google/sre-book/postmortem-culture/ — Postmortem severity + duration metadata
|
|
20
|
-
- https://djw.fyi/portfolio/preventing-drift/ — Daryl White, "Avoiding the Silent Stale Doc Problem"
|
|
21
|
-
- https://keepachangelog.com/ — Keep a Changelog format
|
|
22
|
-
status: research-verified
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
# Format hygiene (delivers Promise 3, "less-prone-to-staleness")
|
|
26
|
-
|
|
27
|
-
> **The premise.** Staleness is invisible without dates. Ownership is invisible without owners. A doc that doesn't *say* when it was last reviewed cannot be flagged as stale by any automated audit — it's not that the audit is wrong, it's that the doc has refused to answer the question. Format hygiene is the precondition for every staleness check downstream.
|
|
28
|
-
|
|
29
|
-
## Form vs. content
|
|
30
|
-
|
|
31
|
-
This is a **form check**, not a **content check**:
|
|
32
|
-
|
|
33
|
-
| Form check (this file) | Content check (elsewhere) |
|
|
34
|
-
|---|---|
|
|
35
|
-
| Does the file have a `date:` field? | Is the date recent? → `stale-content.md` |
|
|
36
|
-
| Does the ADR have a `Status:` field? | Is the status accurate? → manual review |
|
|
37
|
-
| Does AGENTS.md have a `_Last reviewed:_` line? | Is AGENTS.md telling the truth? → `redundancy-detection.md` |
|
|
38
|
-
|
|
39
|
-
Form is mechanizable; content mostly is not. **Enforce form first** — without it, the staleness tooling in `staleness-tooling.md` runs blind.
|
|
40
|
-
|
|
41
|
-
## Why this is Promise 3's home
|
|
42
|
-
|
|
43
|
-
Promise 3 depends on *visibility* of staleness:
|
|
44
|
-
|
|
45
|
-
```
|
|
46
|
-
date frontmatter → mtime threshold → audit flags stale → human reviews → re-dates or archives
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
Break the first link (no date), break the chain. `git log -1 --format=%cs` is a noisy fallback — a typo fix on a 3-year-old doc looks "fresh." The `_Last reviewed:_` line is the explicit affirmation that someone *reread* the doc.
|
|
50
|
-
|
|
51
|
-
## The five hygiene checks
|
|
52
|
-
|
|
53
|
-
| # | Check | Where it applies | Severity |
|
|
54
|
-
|---|---|---|---|
|
|
55
|
-
| 1 | Doc has `date:` YAML frontmatter OR `_Last reviewed:_` line | All canonical docs | High |
|
|
56
|
-
| 2 | Doc has YAML frontmatter at all | Canonical reference docs (skills-style) | Medium |
|
|
57
|
-
| 3 | AGENTS.md has `_Last reviewed:_` or version line | AGENTS.md, CLAUDE.md (if fat) | High |
|
|
58
|
-
| 4 | ADR has `Status:` field | `.brain/adrs/*.md` | High |
|
|
59
|
-
| 5 | Postmortem has `severity:` and `duration:` | `.brain/postmortems/*.md` | High |
|
|
60
|
-
|
|
61
|
-
Ownership (`_Owner:_` or `owner:`) is a sixth concern — emit as Medium where missing; small repos can accept "team that owns the parent directory."
|
|
62
|
-
|
|
63
|
-
## Check 1 — every canonical doc is dated
|
|
64
|
-
|
|
65
|
-
Two acceptable forms; either passes. **Form A — YAML frontmatter** (`date: 2026-04-27`). **Form B — inline reviewed-line** (`_Last reviewed: 2026-04-27 by @kimba_`).
|
|
66
|
-
|
|
67
|
-
### Detection
|
|
68
|
-
|
|
69
|
-
```bash
|
|
70
|
-
# A doc is "dated" if it has either form. Otherwise emit finding.
|
|
71
|
-
check_dated() {
|
|
72
|
-
local f="$1"
|
|
73
|
-
# Form A: YAML date: field within first frontmatter block
|
|
74
|
-
if head -20 "$f" | awk '/^---$/{i++; if(i==2) exit} i==1' | grep -qE '^date:\s*[0-9]{4}-[0-9]{2}-[0-9]{2}'; then
|
|
75
|
-
return 0
|
|
76
|
-
fi
|
|
77
|
-
# Form B: _Last reviewed:_ line anywhere in the file
|
|
78
|
-
if grep -qE '_Last reviewed:_?\s*[0-9]{4}-[0-9]{2}-[0-9]{2}' "$f"; then
|
|
79
|
-
return 0
|
|
80
|
-
fi
|
|
81
|
-
return 1
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
for f in AGENTS.md CLAUDE.md README.md CHANGELOG.md \
|
|
85
|
-
$(find .brain docs -name '*.md' -not -path '.brain/archive/*' -not -path 'docs/archive/*' 2>/dev/null); do
|
|
86
|
-
[ -f "$f" ] && [ ! -L "$f" ] || continue
|
|
87
|
-
if ! check_dated "$f"; then
|
|
88
|
-
echo "UNDATED: $f"
|
|
89
|
-
fi
|
|
90
|
-
done
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
CHANGELOG.md is special — it's append-only and dates live per-entry. The check passes if *any* entry has a date heading like `## [1.2.3] - 2026-04-27`.
|
|
94
|
-
|
|
95
|
-
## Check 2 — canonical reference docs have YAML frontmatter
|
|
96
|
-
|
|
97
|
-
For reference material in `.brain/` (not narrative READMEs in `docs/`), missing frontmatter is a smell. The ops-repo convention mirrors this skills library: `date`, `coverage`, `peers`, `primary_sources`, `status`.
|
|
98
|
-
|
|
99
|
-
### Detection
|
|
100
|
-
|
|
101
|
-
```bash
|
|
102
|
-
# A doc has frontmatter if line 1 is exactly `---`.
|
|
103
|
-
for f in $(find .brain docs -name '*.md' -not -path '.brain/archive/*' -not -path 'docs/archive/*' 2>/dev/null); do
|
|
104
|
-
[ -f "$f" ] || continue
|
|
105
|
-
if [ "$(head -1 "$f")" != "---" ]; then
|
|
106
|
-
echo "NO-FRONTMATTER: $f"
|
|
107
|
-
fi
|
|
108
|
-
done
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
Medium severity — narrative docs legitimately don't need frontmatter. Reference docs and ADRs/postmortems definitely should.
|
|
112
|
-
|
|
113
|
-
## Check 3 — AGENTS.md has `_Last reviewed:_` or version line
|
|
114
|
-
|
|
115
|
-
AGENTS.md is loaded every session; if it can't be cheaply freshness-checked, the staleness story collapses for the most-loaded file in the repo.
|
|
116
|
-
|
|
117
|
-
### Detection
|
|
118
|
-
|
|
119
|
-
```bash
|
|
120
|
-
for f in AGENTS.md CLAUDE.md; do
|
|
121
|
-
[ -f "$f" ] && [ ! -L "$f" ] || continue
|
|
122
|
-
# Skip thin pointers (≤15 lines)
|
|
123
|
-
[ "$(wc -l < "$f")" -le 15 ] && continue
|
|
124
|
-
# Require either a Last-reviewed line or a Version line
|
|
125
|
-
if ! grep -qE '_Last reviewed:_?\s*[0-9]{4}-[0-9]{2}-[0-9]{2}|^Version:\s*[0-9]+\.[0-9]+' "$f"; then
|
|
126
|
-
echo "NO-REVIEW-LINE: $f"
|
|
127
|
-
fi
|
|
128
|
-
done
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
A version line (`Version: 2026.04`) is acceptable — calendar-versioning AGENTS.md is valid for repos that re-cut docs per release.
|
|
132
|
-
|
|
133
|
-
## Check 4 — every ADR has a `Status:` field
|
|
134
|
-
|
|
135
|
-
Per [adr.github.io](https://adr.github.io/), an ADR without `Status:` is uninterpretable — readers can't tell if it's `proposed`, `accepted`, `deprecated`, or `superseded`. See `../doc-types/adr-pattern.md`.
|
|
136
|
-
|
|
137
|
-
### Detection
|
|
138
|
-
|
|
139
|
-
```bash
|
|
140
|
-
# Status field can be in frontmatter (status:) OR in body (## Status: accepted).
|
|
141
|
-
for f in $(find .brain/adrs docs/adrs docs/adr docs/decisions -name '*.md' 2>/dev/null); do
|
|
142
|
-
[ -f "$f" ] || continue
|
|
143
|
-
# README/index files are not ADRs
|
|
144
|
-
case "$(basename "$f")" in README.md|index.md|INDEX.md) continue ;; esac
|
|
145
|
-
if ! grep -qE '^status:\s+(proposed|accepted|deprecated|superseded|rejected)|^##\s+Status' "$f"; then
|
|
146
|
-
echo "ADR-NO-STATUS: $f"
|
|
147
|
-
fi
|
|
148
|
-
done
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
Accept `proposed | accepted | deprecated | superseded | rejected` (case-insensitive). Custom workflows pass with a warning.
|
|
152
|
-
|
|
153
|
-
## Check 5 — every postmortem has `severity:` and `duration:`
|
|
154
|
-
|
|
155
|
-
Per Google's [SRE Book postmortem culture](https://sre.google/sre-book/postmortem-culture/) and `../doc-types/postmortem-pattern.md`, a postmortem without severity + duration is *narrative* — it can't be aggregated ("incidents per quarter at SEV-1" needs these).
|
|
156
|
-
|
|
157
|
-
### Detection
|
|
158
|
-
|
|
159
|
-
```bash
|
|
160
|
-
for f in $(find .brain/postmortems docs/postmortems docs/incidents -name '*.md' 2>/dev/null); do
|
|
161
|
-
[ -f "$f" ] || continue
|
|
162
|
-
case "$(basename "$f")" in README.md|index.md|INDEX.md|TEMPLATE.md) continue ;; esac
|
|
163
|
-
has_sev=false; has_dur=false
|
|
164
|
-
grep -qE '^severity:\s*(SEV-?[0-9]|P[0-9]|critical|high|medium|low)' "$f" && has_sev=true
|
|
165
|
-
grep -qE '^duration:\s+' "$f" && has_dur=true
|
|
166
|
-
[ "$has_sev" = false ] && echo "POSTMORTEM-NO-SEVERITY: $f"
|
|
167
|
-
[ "$has_dur" = false ] && echo "POSTMORTEM-NO-DURATION: $f"
|
|
168
|
-
done
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
`status:` (resolved / ongoing / blocked) and `date:` fall under Check 1 and Check 2 above.
|
|
172
|
-
|
|
173
|
-
## Output shape (the gap-report row)
|
|
174
|
-
|
|
175
|
-
```markdown
|
|
176
|
-
- **NO-REVIEW-LINE — `AGENTS.md`** (severity: high)
|
|
177
|
-
- 187 lines of fat instructions, no `_Last reviewed:_` and no `Version:` line.
|
|
178
|
-
- **Promise 3 impact:** the most-loaded file in the repo is invisible to the audit.
|
|
179
|
-
- **Recommendation:** add `_Last reviewed: 2026-04-27 by @kimba_` near the top.
|
|
180
|
-
|
|
181
|
-
- **ADR-NO-STATUS — `.brain/adrs/0007-pick-postgres.md`** (severity: high)
|
|
182
|
-
- **Recommendation:** add `Status: accepted` (or `superseded by 0014`). See `../doc-types/adr-pattern.md`.
|
|
183
|
-
|
|
184
|
-
- **POSTMORTEM-NO-SEVERITY — `.brain/postmortems/2026-03-15-checkout-outage.md`** (severity: high)
|
|
185
|
-
- **Recommendation:** add `severity: SEV-2` and `duration: 47 minutes`.
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
## Severity rubric (consolidated)
|
|
189
|
-
|
|
190
|
-
| Finding | Severity | Why |
|
|
191
|
-
|---|---|---|
|
|
192
|
-
| AGENTS.md / CLAUDE.md (fat) without `_Last reviewed:_` | High | Most-loaded file invisible to staleness tooling |
|
|
193
|
-
| ADR without `Status:` | High | ADR uninterpretable; readers can't tell what's current |
|
|
194
|
-
| Postmortem without `severity:` | High | Cannot aggregate; loses analytical value |
|
|
195
|
-
| Postmortem without `duration:` | High | Same as above |
|
|
196
|
-
| Canonical reference doc without `date:` or `_Last reviewed:_` | High | Invisible to staleness tooling |
|
|
197
|
-
| Reference doc in `.brain/` without YAML frontmatter | Medium | Convention drift; advisory for narrative docs |
|
|
198
|
-
| Doc without `_Owner:_` or implicit team owner | Medium | Ownership gap; advisory |
|
|
199
|
-
|
|
200
|
-
## What this pattern is NOT for
|
|
201
|
-
|
|
202
|
-
- **Content correctness** — `severity: SEV-2` passes hygiene even if the real severity was SEV-1. Content question.
|
|
203
|
-
- **Schema validation** — shape only; a typed-skill schema validator is a different tool.
|
|
204
|
-
- **Markdown structure** — heading levels, list indentation live in `markdownlint`, called from `staleness-tooling.md`.
|
|
205
|
-
|
|
206
|
-
## Cross-references
|
|
207
|
-
|
|
208
|
-
- Coverage gaps (does the file even exist?): `coverage-gaps.md`
|
|
209
|
-
- Stale content (is the date recent enough?): `stale-content.md`, `staleness-tooling.md`
|
|
210
|
-
- Entry-file shape (AGENTS.md sectional checks): `entry-file-coverage.md`
|
|
211
|
-
- Pointer validation (do referenced files resolve?): `pointer-validation.md`
|
|
212
|
-
- Orphan detection (is this file linked from anywhere?): `orphan-detection.md`
|
|
213
|
-
- Memory fragmentation (are ADRs scattered across folders?): `memory-fragmentation.md`
|
|
214
|
-
- ADR template: `../doc-types/adr-pattern.md`
|
|
215
|
-
- Postmortem template: `../doc-types/postmortem-pattern.md`
|
|
216
|
-
- Self-healing hook (run on commit): `../recipes/self-healing-hooks.md`
|
|
217
|
-
- Context budget (AGENTS.md shape rules): `../guidance/context-budget.md`
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
# Lockstep versioning (Promise-4 trip-wire for monorepos)
|
|
2
|
-
|
|
3
|
-
**Added:** 2026-05-02 after the AdiaUI repo's caret-on-0.0.x lock-in
|
|
4
|
-
postmortem (`a2ui-mcp@0.1.3 → corpus@0.0.6` shipped silently for ~4
|
|
5
|
-
days).
|
|
6
|
-
|
|
7
|
-
## The drift class
|
|
8
|
-
|
|
9
|
-
Monorepos with multiple published packages accumulate one of two
|
|
10
|
-
versioning failure modes:
|
|
11
|
-
|
|
12
|
-
1. **Independent versions diverge silently.** Internal-dep ranges
|
|
13
|
-
like `^0.0.x` lock to exact versions under npm pre-1.0 semver
|
|
14
|
-
(`^0.0.6 = exactly 0.0.6`). Consumers track stale bundled
|
|
15
|
-
versions while developers see `main`.
|
|
16
|
-
2. **Coordinated cuts have high friction.** Every change to any
|
|
17
|
-
package requires bumping all packages, regenerating lockfiles,
|
|
18
|
-
re-tagging, re-publishing. Operators skip the coordination → drift.
|
|
19
|
-
|
|
20
|
-
Both modes produce shipping bugs that are invisible until a consumer
|
|
21
|
-
reports it (or, in the AdiaUI case, until a manual code review
|
|
22
|
-
catches it).
|
|
23
|
-
|
|
24
|
-
## Detection (Promise-4 trip-wire)
|
|
25
|
-
|
|
26
|
-
The trip-wire is a CI gate that runs on every PR. Three checks:
|
|
27
|
-
|
|
28
|
-
1. **Version match:** all published packages share one version.
|
|
29
|
-
2. **Caret-trap:** no `@<scope>/*` dep range matches `^0\.0\.\d+`.
|
|
30
|
-
3. **Range alignment:** every internal `@<scope>/*` range is `^X.Y.0`
|
|
31
|
-
matching the lockstep version.
|
|
32
|
-
|
|
33
|
-
Example implementation (AdiaUI repo,
|
|
34
|
-
`scripts/release/check-lockstep.mjs`):
|
|
35
|
-
|
|
36
|
-
```js
|
|
37
|
-
const PACKAGES = [
|
|
38
|
-
"packages/a2ui/compose/package.json",
|
|
39
|
-
"packages/a2ui/corpus/package.json",
|
|
40
|
-
// ... 8 total
|
|
41
|
-
];
|
|
42
|
-
const ADIA_DEP_RE = /^@adia-ai\//;
|
|
43
|
-
const CARET_0_0_X_RE = /^\^0\.0\.\d+$/;
|
|
44
|
-
const VALID_CARET_RE = /^\^(\d+)\.(\d+)\.0$/;
|
|
45
|
-
|
|
46
|
-
// Read all 9 package.jsons. Compare versions; flag mismatches.
|
|
47
|
-
// For each @adia-ai/* dep across all 9: flag if ^0.0.x; flag if ranges differ.
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
Wire to CI:
|
|
51
|
-
|
|
52
|
-
```yaml
|
|
53
|
-
# .github/workflows/docs-lint.yml (or sibling workflow)
|
|
54
|
-
lockstep-versioning:
|
|
55
|
-
name: Lockstep version coherence
|
|
56
|
-
runs-on: ubuntu-latest
|
|
57
|
-
steps:
|
|
58
|
-
- uses: actions/checkout@v4
|
|
59
|
-
- uses: actions/setup-node@v4
|
|
60
|
-
- run: node scripts/release/check-lockstep.mjs
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
The `--fix` mode rewrites mismatched ranges to the highest version
|
|
64
|
-
observed. Used during a coordinated cut to sync the rest of the tree.
|
|
65
|
-
|
|
66
|
-
## When to install
|
|
67
|
-
|
|
68
|
-
Install when the monorepo has **2+ published packages** AND at least
|
|
69
|
-
one package has internal-dep ranges to siblings. The catastrophic
|
|
70
|
-
failure mode is `^0.0.x` ranges + a popular consumer-facing package;
|
|
71
|
-
the gate prevents both from coexisting.
|
|
72
|
-
|
|
73
|
-
The convention to write down (in the project's spec / docs):
|
|
74
|
-
|
|
75
|
-
- All N published packages share one version `X.Y.0` with Y≥1.
|
|
76
|
-
- Every internal dep range is `^X.Y.0` matching the lockstep version.
|
|
77
|
-
- Cuts are atomic: bumping one bumps all N.
|
|
78
|
-
- The CI gate fails any PR that misaligns.
|
|
79
|
-
|
|
80
|
-
For AdiaUI's specific implementation (the worked example), see the
|
|
81
|
-
consuming repo's `docs/specs/package-architecture.md` § 15 (versioning policy).
|
|
82
|
-
|
|
83
|
-
## Prevention (post-publish admin)
|
|
84
|
-
|
|
85
|
-
Once the gate is installed and passing, the post-publish admin:
|
|
86
|
-
|
|
87
|
-
1. **Flip from `continue-on-error: true` to blocking.** Most cuts are
|
|
88
|
-
added with the gate advisory (because the cut PR itself can't pass
|
|
89
|
-
the gate — it's installing the gate against a misaligned repo).
|
|
90
|
-
After the cut succeeds, flip to blocking.
|
|
91
|
-
2. **Add the gate to** `.brain/findings/INDEX.md` Graduations.
|
|
92
|
-
3. **Cross-reference the postmortem** if the gate was prompted by an
|
|
93
|
-
incident.
|
|
94
|
-
|
|
95
|
-
## Anti-patterns
|
|
96
|
-
|
|
97
|
-
- **Don't make the gate optional.** A `continue-on-error: true` gate
|
|
98
|
-
is invisible to operators; the value is in the block.
|
|
99
|
-
- **Don't try to make the policy "just for some packages."** The
|
|
100
|
-
caret-trap is a class — once you have the gate, sweep it across all
|
|
101
|
-
internal deps. Partial enforcement is worse than no enforcement
|
|
102
|
-
(operators trust the gate; misalignment in non-gated packages
|
|
103
|
-
becomes a different shipping bug class).
|
|
104
|
-
- **Don't accept `^0.0.x` ranges with comments saying "we know."**
|
|
105
|
-
Comments don't enforce; the gate does.
|
|
106
|
-
|
|
107
|
-
## Related
|
|
108
|
-
|
|
109
|
-
- See [`feedback_npm_caret_on_0_0_x.md`](`~/.claude/projects/<repo>/memory/`) —
|
|
110
|
-
the user-memory entry (now flagged as superseded by the policy).
|
|
111
|
-
- See `.brain/postmortems/2026-05-02-corpus-caret-lock.md` — the
|
|
112
|
-
postmortem that drove the gate's authoring.
|
|
113
|
-
- See `lockstep-release` skill — the procedural counterpart for cuts.
|
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
date: 2026-04-27
|
|
3
|
-
coverage: canonical
|
|
4
|
-
peers:
|
|
5
|
-
- orphan-detection.md
|
|
6
|
-
- stale-content.md
|
|
7
|
-
- entry-file-coverage.md
|
|
8
|
-
- ../recipes/continuous-learning-loop.md
|
|
9
|
-
- ../doc-types/adr-pattern.md
|
|
10
|
-
- ../doc-types/postmortem-pattern.md
|
|
11
|
-
primary_sources:
|
|
12
|
-
- https://adr.github.io — ADR conventions; canonical folder layout
|
|
13
|
-
- https://sre.google/workbook/postmortem-culture/ — Google SRE postmortem culture
|
|
14
|
-
- Michael Nygard, "Documenting Architecture Decisions" (cognitect.com/blog/2011/11/15)
|
|
15
|
-
- https://learn.microsoft.com/en-us/azure/well-architected/architect-role/architecture-decision-record
|
|
16
|
-
status: research-verified
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
# Memory-fragmentation detection (delivers Promise 5, "continuously-learning")
|
|
20
|
-
|
|
21
|
-
> **The premise.** A repo's memory primitives — ADRs, post-mortems, decision logs, RFCs — only compound if they live in **one canonical place per kind** and are reachable from AGENTS.md. When decisions live in PR descriptions, post-mortems live in Slack, and runbooks live in Notion, the agent (and every new human) starts from zero on every session. This audit detects the fragmentation and points at the consolidation recipe.
|
|
22
|
-
|
|
23
|
-
## Where this fits
|
|
24
|
-
|
|
25
|
-
`../recipes/continuous-learning-loop.md` describes the *flow* — how decisions and incidents become persistent memory. `../doc-types/adr-pattern.md` and `../doc-types/postmortem-pattern.md` describe the *artifacts*. This file is the *audit*: how to detect that the flow is broken or the artifacts are scattered.
|
|
26
|
-
|
|
27
|
-
## Four signals of memory fragmentation
|
|
28
|
-
|
|
29
|
-
| # | Signal | What it looks like | Severity |
|
|
30
|
-
|---|---|---|---|
|
|
31
|
-
| 1 | **No `.brain/adrs/` folder despite architectural-shape commits** | `git log --grep='migrate\|switch from\|adopt'` returns 20 hits; `.brain/adrs/` doesn't exist | High |
|
|
32
|
-
| 2 | **No `.brain/postmortems/` despite incident-shape commits** | `git log --grep='hotfix\|revert\|incident\|outage'` returns matches; `.brain/postmortems/` empty | High |
|
|
33
|
-
| 3 | **Decision/RFC/ADR text scattered outside the canonical folders** | `grep -ri 'decision\|ADR\|RFC' docs/` finds matches in random `docs/notes-*.md` files, not `.brain/adrs/` | Medium |
|
|
34
|
-
| 4 | **AGENTS.md missing a "Memory primitives" section** | Agent doesn't know to consult ADRs / post-mortems / runbooks | **Critical** (closes-the-loop check) |
|
|
35
|
-
|
|
36
|
-
Signal 4 is the most damaging. A repo can have an exemplary `.brain/adrs/` folder with 40 decisions, and if AGENTS.md doesn't tell the agent to *read it*, the artifacts are dead weight on disk.
|
|
37
|
-
|
|
38
|
-
## The bash check
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
#!/usr/bin/env bash
|
|
42
|
-
# scripts/check-memory-fragmentation.sh
|
|
43
|
-
set -euo pipefail
|
|
44
|
-
fail=0
|
|
45
|
-
|
|
46
|
-
# Signal 1: ADR folder vs architectural-commit volume.
|
|
47
|
-
arch=$(git log --since='2 years ago' \
|
|
48
|
-
--grep='migrate\|switch\|adopt\|introduce\|deprecate\|replace.*with' \
|
|
49
|
-
--oneline 2>/dev/null | wc -l | tr -d ' ')
|
|
50
|
-
if [ ! -d .brain/adrs ] && [ ! -d docs/adrs ] && [ ! -d docs/architecture/decisions ] && [ ! -d adrs ]; then
|
|
51
|
-
[ "$arch" -gt 5 ] && { echo "FRAGMENT-NO-ADR-FOLDER: $arch arch-shape commits in 2y; no .brain/adrs/."; fail=1; }
|
|
52
|
-
else
|
|
53
|
-
n=$(find .brain/adrs docs/adrs docs/architecture/decisions adrs -name '*.md' \
|
|
54
|
-
-not -name 'README.md' -not -name 'INDEX.md' 2>/dev/null | wc -l | tr -d ' ')
|
|
55
|
-
yrs=$(( ($(date +%s) - $(git log --reverse --format=%ct | head -1)) / 31536000 ))
|
|
56
|
-
[ "$yrs" -lt 1 ] && yrs=1
|
|
57
|
-
[ "$n" -lt "$yrs" ] && echo "FRAGMENT-SPARSE-ADRS: $n ADRs for ${yrs}y repo (expected >=$yrs)."
|
|
58
|
-
fi
|
|
59
|
-
|
|
60
|
-
# Signal 2: postmortems vs incident-shape commits.
|
|
61
|
-
inc=$(git log --grep='hotfix\|revert\|incident\|outage\|rollback\|emergency' \
|
|
62
|
-
--oneline 2>/dev/null | wc -l | tr -d ' ')
|
|
63
|
-
if [ ! -d .brain/postmortems ] && [ ! -d docs/postmortems ] && [ ! -d docs/incidents ] && [ ! -d docs/post-mortems ]; then
|
|
64
|
-
[ "$inc" -gt 3 ] && { echo "FRAGMENT-NO-POSTMORTEM-FOLDER: $inc incident-shape commits; none filed."; fail=1; }
|
|
65
|
-
fi
|
|
66
|
-
|
|
67
|
-
# Signal 3: decision/RFC/postmortem text outside canonical folders.
|
|
68
|
-
canonical_re='\.brain/(adrs|postmortems|architecture)/|docs/(adrs|architecture/decisions|postmortems|incidents|post-mortems)/'
|
|
69
|
-
find .brain docs -type f -name '*.md' -not -path '.brain/archive/*' -not -path 'docs/archive/*' | while read -r f; do
|
|
70
|
-
echo "$f" | grep -qE "$canonical_re" && continue
|
|
71
|
-
case "$(basename "$f")" in README.md|INDEX.md) continue ;; esac
|
|
72
|
-
if grep -qE '^## (Status|Decision|Consequences)' "$f" 2>/dev/null \
|
|
73
|
-
|| grep -qiE '\b(post-?mortem|RFC[- ]?[0-9]|architecture decision record)\b' "$f"; then
|
|
74
|
-
echo "FRAGMENT-MISPLACED: $f is decision/postmortem/RFC-shaped but outside canonical folders."
|
|
75
|
-
fi
|
|
76
|
-
done
|
|
77
|
-
|
|
78
|
-
# Signal 4: AGENTS.md "Memory primitives" section (hard fail).
|
|
79
|
-
c=AGENTS.md; [ ! -f "$c" ] && [ -f CLAUDE.md ] && c=CLAUDE.md
|
|
80
|
-
if [ -f "$c" ] && [ ! -L "$c" ]; then
|
|
81
|
-
grep -qiE '^## *(memory primitives|memory|where to find|key documents)' "$c" \
|
|
82
|
-
|| { echo "FRAGMENT-NO-MEMORY-SECTION: $c lacks a Memory primitives section."; fail=1; }
|
|
83
|
-
fi
|
|
84
|
-
exit $fail
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
Heuristics are conservative — most findings are advisory. Only signal 4 is gated as a hard finding because it always indicates a closed-loop break.
|
|
88
|
-
|
|
89
|
-
## What each signal recommends
|
|
90
|
-
|
|
91
|
-
### Signal 1 — no `.brain/adrs/` despite architectural commits
|
|
92
|
-
|
|
93
|
-
**Recommendation.** Bootstrap the folder with `recipes/adr-introduction.md` (planned per the INDEX). The first ADR (`0001-record-architecture-decisions.md`) is the meta-decision: "we will record architectural decisions". Then back-fill 3-5 of the most-impactful past architectural changes as historical ADRs.
|
|
94
|
-
|
|
95
|
-
### Signal 2 — incidents without post-mortems
|
|
96
|
-
|
|
97
|
-
**Recommendation.** Create `.brain/postmortems/` (or `docs/incidents/`). For commits matching the incident heuristic (`hotfix`, `revert`, `outage`), do *not* try to retroactively reconstruct post-mortems for events the team didn't review. Instead: install the convention going forward, and as the next SEV-1 / SEV-2 happens, run the post-mortem flow per `../doc-types/postmortem-pattern.md`.
|
|
98
|
-
|
|
99
|
-
### Signal 3 — misplaced decision/RFC/postmortem text
|
|
100
|
-
|
|
101
|
-
**Recommendation.** Move the file. The audit emits a `git mv` suggestion:
|
|
102
|
-
|
|
103
|
-
```bash
|
|
104
|
-
# For each FRAGMENT-MISPLACED file, the recommendation is:
|
|
105
|
-
git mv docs/notes-on-postgres-decision.md .brain/adrs/0014-use-postgres-not-mysql.md
|
|
106
|
-
# Then re-number to fit the existing sequence; update any inbound links.
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
Re-numbering is mandatory if the canonical folder uses sequential numbering. The audit does not auto-rename — too easy to break links — but it lists all candidates so the consolidation can be batched in one PR.
|
|
110
|
-
|
|
111
|
-
### Signal 4 — no Memory primitives section in AGENTS.md
|
|
112
|
-
|
|
113
|
-
**Recommendation.** Add the section using the template from `../recipes/continuous-learning-loop.md`:
|
|
114
|
-
|
|
115
|
-
```markdown
|
|
116
|
-
## Memory primitives
|
|
117
|
-
|
|
118
|
-
- **Before architectural changes**, read `.brain/adrs/` newest-first. If your
|
|
119
|
-
proposed change conflicts with an `Accepted` ADR, write a new ADR
|
|
120
|
-
superseding it; don't silently override.
|
|
121
|
-
|
|
122
|
-
- **When debugging a production issue**, search `.brain/postmortems/` for
|
|
123
|
-
prior occurrences. Many "new" bugs are repeats.
|
|
124
|
-
|
|
125
|
-
- **When you make a mistake the user has to correct**, ask: "Should I add
|
|
126
|
-
this to AGENTS.md so I don't repeat it?" Most of the time the answer is
|
|
127
|
-
yes. Add a one-line correction with a dated parenthetical.
|
|
128
|
-
|
|
129
|
-
- **When a runbook is needed for a recurring operation**, file it in
|
|
130
|
-
`.brain/runbooks/` rather than embedding it in AGENTS.md.
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
This is the single highest-leverage edit in any audit — without it, Promise 5 isn't being delivered no matter how many ADRs the repo has.
|
|
134
|
-
|
|
135
|
-
## Out-of-repo memory (the harder problem)
|
|
136
|
-
|
|
137
|
-
A category of fragmentation the bash check can't detect: decisions and post-mortems that live *outside* the repo entirely — in Slack threads, Notion pages, Confluence, Linear comments, Google Docs, meeting notes, individual engineers' brains.
|
|
138
|
-
|
|
139
|
-
The audit can't grep these. What it *can* do is emit an advisory finding:
|
|
140
|
-
|
|
141
|
-
```text
|
|
142
|
-
ADVISORY: Repo has 47 PRs in 12 months that mention "RFC", "decision", or "design doc"
|
|
143
|
-
in their description but no ADRs were written. Consider whether decisions are
|
|
144
|
-
being captured durably, or only in transient PR descriptions.
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
```bash
|
|
148
|
-
# Heuristic for the advisory
|
|
149
|
-
gh pr list --state merged --limit 200 --search "RFC OR decision OR \"design doc\"" \
|
|
150
|
-
--json number,title --jq '. | length' 2>/dev/null
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
The fix is cultural, not mechanical: the team agrees that "decision in a PR description" → "ADR in `.brain/adrs/`" before merge. The PR template change is in `../recipes/continuous-learning-loop.md` (Flow 2).
|
|
154
|
-
|
|
155
|
-
## Severity rubric
|
|
156
|
-
|
|
157
|
-
| Finding | Severity | Why |
|
|
158
|
-
|---|---|---|
|
|
159
|
-
| AGENTS.md missing Memory primitives section | **Critical** | Closes-loop check; artifacts on disk are dead weight without it |
|
|
160
|
-
| `.brain/adrs/` missing AND repo has architectural-shape commits | High | Decisions are evaporating into PR descriptions |
|
|
161
|
-
| `.brain/postmortems/` missing AND repo has incident-shape commits | High | Lessons aren't compounding |
|
|
162
|
-
| Decision-shaped content outside canonical folders | Medium | Discoverability breaks; agent won't find it |
|
|
163
|
-
| Sparse ADRs (<1 per year of repo age) for repos >2 years old | Medium | Likely under-capture; advisory |
|
|
164
|
-
| Out-of-repo memory (Slack/Notion) | Advisory | Cultural fix; audit emits a recommendation, not a hard finding |
|
|
165
|
-
|
|
166
|
-
## What this pattern is NOT for
|
|
167
|
-
|
|
168
|
-
- **Detecting whether individual ADRs are well-written** — that's a content-quality check, not a fragmentation check. See `../doc-types/adr-pattern.md` for the format rubric.
|
|
169
|
-
- **Detecting stale ADRs** — ADRs are immutable; "stale" doesn't apply. An ADR replaced by a newer one is `Superseded`, not `stale`. The audit explicitly excludes `.brain/adrs/` from `stale-content.md`'s heuristic 1.
|
|
170
|
-
- **Detecting that a post-mortem is blameless** — the convention is in `../doc-types/postmortem-pattern.md`; the audit doesn't enforce it because language analysis is unreliable.
|
|
171
|
-
- **Runbooks** — `.brain/runbooks/` is mentioned in the Memory primitives template but isn't its own audit category yet (could be added in v0.3.0).
|
|
172
|
-
|
|
173
|
-
## Cross-references
|
|
174
|
-
|
|
175
|
-
- Continuous-learning loop (the flow this audit verifies): `../recipes/continuous-learning-loop.md`
|
|
176
|
-
- ADR pattern (the canonical artifact format): `../doc-types/adr-pattern.md`
|
|
177
|
-
- Post-mortem pattern (the other canonical artifact format): `../doc-types/postmortem-pattern.md`
|
|
178
|
-
- Orphan detection (sibling — finds unreachable docs, here we find scattered ones): `orphan-detection.md`
|
|
179
|
-
- Stale-content (sibling Promise 3 audit): `stale-content.md`
|
|
180
|
-
- Entry-file coverage (precondition — AGENTS.md exists to host Memory primitives section): `entry-file-coverage.md`
|