@adia-ai/adia-ui-forge 0.1.2 → 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.
Files changed (196) hide show
  1. package/.claude-plugin/plugin.json +3 -6
  2. package/CHANGELOG.md +27 -26
  3. package/README.md +35 -40
  4. package/agents/a2ui-engineer.md +26 -0
  5. package/agents/component-author.md +29 -0
  6. package/agents/framework-verifier.md +26 -0
  7. package/agents/release-engineer.md +25 -0
  8. package/agents/routing-corpus.json +318 -0
  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 -5
  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 +22 -40
  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-deploy/references/deploy-playbooks.md +276 -0
  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 +27 -2
  90. package/skills/{adia-ui-release → adia-release}/scripts/dispatch-publish.mjs +72 -6
  91. package/skills/{adia-ui-release → adia-release}/scripts/insert-stub.mjs +6 -4
  92. package/skills/adia-release/scripts/package-paths.mjs +50 -0
  93. package/skills/{adia-ui-release → adia-release}/scripts/promote-unreleased.mjs +4 -3
  94. package/skills/{adia-ui-release → adia-release}/scripts/release-pack.mjs +48 -27
  95. package/skills/{adia-ui-release → adia-release}/scripts/tag-lockstep.mjs +15 -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/bin/lib/audit-axes.mjs +0 -555
  101. package/bin/lib/dry-run-irreversible.mjs +0 -236
  102. package/bin/lib/run-skill-evals.mjs +0 -487
  103. package/bin/lib/teach-router.mjs +0 -250
  104. package/commands/adia-forge-a2ui.md +0 -10
  105. package/commands/adia-forge-author.md +0 -10
  106. package/commands/adia-forge-dogfood.md +0 -8
  107. package/commands/adia-forge-llm.md +0 -8
  108. package/commands/adia-forge-orient.md +0 -10
  109. package/commands/adia-forge-release.md +0 -8
  110. package/commands/adia-forge-review.md +0 -10
  111. package/references/shared/pev-rationale.md +0 -64
  112. package/references/shared/skill-conventions.md +0 -133
  113. package/skills/adia-ui-a2ui/CHANGELOG.md +0 -32
  114. package/skills/adia-ui-a2ui/SKILL.md +0 -243
  115. package/skills/adia-ui-a2ui/evals/adversarial-corpus.json +0 -75
  116. package/skills/adia-ui-a2ui/evals/teach-routing-cases.json +0 -100
  117. package/skills/adia-ui-a2ui/references/anti-patterns.md +0 -24
  118. package/skills/adia-ui-a2ui/references/chunk-authoring.md +0 -88
  119. package/skills/adia-ui-a2ui/references/corpus-discipline.md +0 -56
  120. package/skills/adia-ui-a2ui/references/eval-diagnostics.md +0 -127
  121. package/skills/adia-ui-a2ui/references/fragment-graph.md +0 -91
  122. package/skills/adia-ui-a2ui/references/mcp-pipeline-ops.md +0 -106
  123. package/skills/adia-ui-a2ui/references/mcp-tool-reference.md +0 -398
  124. package/skills/adia-ui-a2ui/references/pipeline-overview.md +0 -175
  125. package/skills/adia-ui-a2ui/references/semantic-fail-lifting.md +0 -120
  126. package/skills/adia-ui-a2ui/references/strategy-engines.md +0 -111
  127. package/skills/adia-ui-a2ui/references/teach-protocol.md +0 -220
  128. package/skills/adia-ui-a2ui/references/zettel-calibration.md +0 -93
  129. package/skills/adia-ui-a2ui/scripts/audit-a2ui-roster.mjs +0 -96
  130. package/skills/adia-ui-a2ui/scripts/teach-route.mjs +0 -157
  131. package/skills/adia-ui-a2ui/skill.json +0 -38
  132. package/skills/adia-ui-authoring/CHANGELOG.md +0 -32
  133. package/skills/adia-ui-authoring/SKILL.md +0 -256
  134. package/skills/adia-ui-authoring/assets/case-studies/admin-shell-decomposition.md +0 -101
  135. package/skills/adia-ui-authoring/assets/case-studies/maxtokens-32768-discovery.md +0 -109
  136. package/skills/adia-ui-authoring/assets/case-studies/theme-panel-promotion.md +0 -113
  137. package/skills/adia-ui-authoring/evals/adversarial-design-plan-gates.json +0 -138
  138. package/skills/adia-ui-authoring/evals/routing-corpus.json +0 -245
  139. package/skills/adia-ui-authoring/references/canonical-pattern-index.md +0 -179
  140. package/skills/adia-ui-authoring/references/common-gotchas.md +0 -93
  141. package/skills/adia-ui-authoring/references/composite-demo-protocol.md +0 -1084
  142. package/skills/adia-ui-authoring/references/teach-protocol.md +0 -428
  143. package/skills/adia-ui-authoring/scripts/audit-authoring-roster.mjs +0 -148
  144. package/skills/adia-ui-authoring/skill.json +0 -45
  145. package/skills/adia-ui-dogfood/CHANGELOG.md +0 -17
  146. package/skills/adia-ui-dogfood/README.md +0 -62
  147. package/skills/adia-ui-dogfood/SKILL.md +0 -866
  148. package/skills/adia-ui-dogfood/skill.json +0 -40
  149. package/skills/adia-ui-forge/SKILL.md +0 -88
  150. package/skills/adia-ui-forge/evals/routing-corpus.json +0 -30
  151. package/skills/adia-ui-gen-review/CHANGELOG.md +0 -108
  152. package/skills/adia-ui-gen-review/SKILL.md +0 -266
  153. package/skills/adia-ui-gen-review/references/loop-protocol.md +0 -712
  154. package/skills/adia-ui-gen-review/references/rubric-cosmetic.md +0 -144
  155. package/skills/adia-ui-gen-review/references/rubric-decompose.md +0 -117
  156. package/skills/adia-ui-gen-review/references/rubric-score.md +0 -249
  157. package/skills/adia-ui-gen-review/references/teach-protocol.md +0 -214
  158. package/skills/adia-ui-gen-review/skill.json +0 -22
  159. package/skills/adia-ui-llm/CHANGELOG.md +0 -25
  160. package/skills/adia-ui-llm/SKILL.md +0 -165
  161. package/skills/adia-ui-llm/evals/adversarial-corpus.json +0 -75
  162. package/skills/adia-ui-llm/evals/routing-corpus.json +0 -30
  163. package/skills/adia-ui-llm/evals/teach-routing-cases.json +0 -73
  164. package/skills/adia-ui-llm/references/teach-protocol.md +0 -78
  165. package/skills/adia-ui-llm/scripts/audit-llm-roster.mjs +0 -93
  166. package/skills/adia-ui-llm/scripts/teach-route.mjs +0 -119
  167. package/skills/adia-ui-llm/skill.json +0 -33
  168. package/skills/adia-ui-release/CHANGELOG.md +0 -23
  169. package/skills/adia-ui-release/SKILL.md +0 -295
  170. package/skills/adia-ui-release/assets/case-studies/2026-05-20-batch-push-v0.6.14-v0.6.15.md +0 -144
  171. package/skills/adia-ui-release/assets/case-studies/2026-05-20-corpus-drift-remediation-v0.6.15.md +0 -155
  172. package/skills/adia-ui-release/assets/case-studies/2026-05-20-version-skip-correction-v0.6.12.md +0 -114
  173. package/skills/adia-ui-release/assets/case-studies/2026-05-21-author-from-scratch-v0.6.18.md +0 -139
  174. package/skills/adia-ui-release/assets/case-studies/2026-05-21-feedback37-retraction-v0.6.21.md +0 -124
  175. package/skills/adia-ui-release/assets/case-studies/2026-05-21-fn1-enrichment-pass-v0.6.19.md +0 -125
  176. package/skills/adia-ui-release/assets/case-studies/2026-05-21-stale-test-detection-v0.6.20.md +0 -142
  177. package/skills/adia-ui-release/assets/case-studies/2026-05-23-freshness-gate-recovery-v0.6.32.md +0 -97
  178. package/skills/adia-ui-release/assets/case-studies/2026-05-26-catalog-drift-recurring-v0.6.40.md +0 -147
  179. package/skills/adia-ui-release/assets/templates/stub-changelog.template.md +0 -22
  180. package/skills/adia-ui-release/evals/evals.json +0 -164
  181. package/skills/adia-ui-release/references/changelog-discipline.md +0 -250
  182. package/skills/adia-ui-release/references/cycle-happy-path.md +0 -520
  183. package/skills/adia-ui-release/references/exe-deploy.md +0 -149
  184. package/skills/adia-ui-release/references/gates-catalog.md +0 -778
  185. package/skills/adia-ui-release/references/ledger-discipline.md +0 -232
  186. package/skills/adia-ui-release/references/migration-guide-authoring.md +0 -174
  187. package/skills/adia-ui-release/references/multi-agent-baseline.md +0 -207
  188. package/skills/adia-ui-release/references/notes-authoring.md +0 -212
  189. package/skills/adia-ui-release/references/recovery-paths.md +0 -215
  190. package/skills/adia-ui-release/references/rollup-notes.md +0 -208
  191. package/skills/adia-ui-release/references/teach-protocol.md +0 -468
  192. package/skills/adia-ui-release/scripts/audit-gate-roster.mjs +0 -196
  193. package/skills/adia-ui-release/scripts/make-ledger.mjs +0 -179
  194. package/skills/adia-ui-release/skill.json +0 -75
  195. /package/skills/{adia-ui-authoring → adia-author}/references/api-contract.md +0 -0
  196. /package/skills/{adia-ui-release → adia-release}/scripts/assert-monorepo-root.mjs +0 -0
@@ -0,0 +1,247 @@
1
+ # `cut-procedure.md` — the standard lockstep cut
2
+
3
+ > Load for any class-A lockstep cut (cut & ship · author from scratch · deploy
4
+ > handoff). Companions: [`gates-catalog.md`](gates-catalog.md) (gate roster +
5
+ > failure routing), [`changelog-discipline.md`](changelog-discipline.md) (promotion
6
+ > + F-N1 enrichment), [`recovery-paths.md`](recovery-paths.md) (when it goes wrong).
7
+ > The concrete gate names, 9 package paths, and `ui-kit.exe.xyz` deploy are the
8
+ > @adia-ai monorepo's worked example of the portable discipline. `$REPO` = repo root.
9
+
10
+ Two entry variants, converging at Step 5:
11
+
12
+ - **Variant A — deploy handoff:** a peer pre-cut the release commit + CHANGELOG + bump + lockfile. Re-baseline, verify, then resume at Step 6 (tag).
13
+ - **Variant B — author from scratch:** source landed under `## [Unreleased]` with no bump. Do Step 4 (promotion + bump + lockfile), then the full tail.
14
+
15
+ `scripts/release-pack.mjs` (bundled) mechanizes the whole sequence with the three operator checkpoints preserved; the steps below are the manual/diagnostic form.
16
+
17
+ | Step | Action | Mutates? |
18
+ | --- | --- | --- |
19
+ | 1 | Re-baseline (branch check + status + log + fetch) | No |
20
+ | 2 | Classify uncommitted files; stash strays | Stash only |
21
+ | 3 | Pre-flight gates (+ harvest preamble if source content changed) | No |
22
+ | 4 | (Variant B) Promote `[Unreleased]`; bump; lockfile | Yes |
23
+ | 5 | Stage the release allowlist; commit on `release/vX.Y.Z` | Yes |
24
+ | 5.5 | Pre-commit freshness trip-wire | No |
25
+ | 5.7 | Release PR: push branch → CI → merge → re-baseline on `main` | PR + merge |
26
+ | 6 | Tag umbrella + per-package at post-merge HEAD — **checkpoint 1 first** | Yes |
27
+ | 7 | F-N1 release trip-wire; enrich CHANGELOGs on warns | If warns |
28
+ | 8 | Push tags (one per push; `main` already merged) — **checkpoint 2 first** | Push |
29
+ | 9 | Dispatch publish workflows; wait; verify registry — **checkpoint 3 first** | Publish |
30
+ | 10 | GH releases + site deploy | Deploy |
31
+ | 11 | Author release notes (default, not optional) | No |
32
+
33
+ ---
34
+
35
+ ## §Step 1 — Re-baseline
36
+
37
+ Context is stale at the start of every turn; run unconditionally:
38
+
39
+ ```bash
40
+ git -C "$REPO" branch --show-current # MUST print: main
41
+ git -C "$REPO" status --short
42
+ git -C "$REPO" log --oneline -8
43
+ git -C "$REPO" fetch && git -C "$REPO" log HEAD..origin/main --oneline # must be empty
44
+ git -C "$REPO" tag --list 'vX.Y.Z' '*-vX.Y.Z' # must NOT exist yet
45
+ ```
46
+
47
+ `branch --show-current` ≠ `main` → stop; cutting on a feature branch pushes a stale `main` ref while the tags point at the feature tip. Recovery: [`recovery-paths.md`](recovery-paths.md) §Scenario 8. If multiple unpushed `release(*):` commits exist → this is a batch push, [`recovery-paths.md`](recovery-paths.md) §Scenario 2.
48
+
49
+ ## §Step 2 — Classify uncommitted files; stash strays
50
+
51
+ Modified/untracked files you didn't author are classification decisions — diff each one. A **stray** = uncommitted + undocumented (no CHANGELOG entry or commit explains it) + behavior-visible + contradicting a release artifact. Stash strays; never revert (revert destroys the work):
52
+
53
+ ```bash
54
+ git -C "$REPO" stash push <file1> <file2> -m "vX.Y.Z-cycle: <reason> — parked"
55
+ ```
56
+
57
+ Keep the stash held through the site deploy (Step 10) — the tarball builds from the **tag** but the site builds from the **working tree**; an uncommitted stray leaks into the deployed site and not the packages, silently. Pop after the cycle; if pop reports "kept the stash", see [`recovery-paths.md`](recovery-paths.md) §Scenario 6. Record any exclusion in the release-commit message (`Excluded — in-flight: <file> (<reason>)`).
58
+
59
+ ## §Step 3 — Pre-flight gates
60
+
61
+ ### 3.0 Harvest preamble (only when source content changed in the window)
62
+
63
+ If `git diff <prev-tag>..HEAD --name-only` touches component yaml / `.a2ui.json` sources, `*.contents.html`, catalog/site pages with `data-chunk-*` annotations — regenerate downstream artifacts proactively (otherwise the freshness gates force a tag-move recovery later):
64
+
65
+ ```bash
66
+ node scripts/build/components.mjs # catalog + per-component sidecars
67
+ npm run harvest:chunks # chunk corpus from site/apps/playgrounds/catalog
68
+ npm run build:embeddings:chunks # embedding index (needs OPENAI_API_KEY)
69
+ npm run build -w @adia-ai/llm # tsc artifact build:bundle-js resolves
70
+ npm run build:bundles # dist CSS+JS bundles
71
+ ```
72
+
73
+ **Regen output supersedes working-tree state.** These outputs land in the release commit unconditionally, even when the same paths are also dirty from a peer — the fresh regen is authoritative; divergent uncommitted work rebases on top afterwards.
74
+
75
+ ### 3.1 The full roster — every gate runs; a subset = pre-flight failure
76
+
77
+ ```bash
78
+ node scripts/build/components.mjs --verify # 1 yaml ↔ sidecar ↔ .d.ts
79
+ npm run verify:traits # 2 trait coverage
80
+ npm run check:lockstep # 3 version coherence
81
+ npm run test:unit # 4 vitest
82
+ npm run typecheck # 5 tsc --noEmit
83
+ npm run check:demo-shells # 6 demo imports cover composes:
84
+ npm run check:lightningcss-build # 7 CSS minifies
85
+ npm run check:css-bundles-fresh # 8 dist CSS matches source
86
+ npm run check:js-bundles-fresh # 9 dist JS matches source
87
+ npm run smoke:engines # 10 gen-UI engines
88
+ npm run smoke:register-engine # 11 register-engine 11/11
89
+ npm run verify:corpus # 12 corpus 0 errors
90
+ npm run check:chunks-fresh # 13 chunk index vs sources
91
+ npm run check:embeddings-fresh # 14 embeddings vs chunk index
92
+ npm run check:links # 15 intra-repo links
93
+ npm run eval:diff -- --engine zettel # 16 eval floors
94
+ npm run dogfood:status # 17 P0/P1 dogfood floor
95
+ ```
96
+
97
+ Any red → route via [`gates-catalog.md`](gates-catalog.md); fix at the source, re-run the narrowest gate, then re-run the full sequence. The canonical miss: a cut that ran 7 of the gates shipped a stale-embeddings defect that surfaced a day later and cost a tag-move recovery.
98
+
99
+ ## §Step 4 — (Variant B) Promote, bump, lockfile
100
+
101
+ **4a. Promote** `## [Unreleased]` → `## [vX.Y.Z] — YYYY-MM-DD` per package (`scripts/promote-unreleased.mjs`); author fresh blocks for changed-but-unlogged packages; stub the pure ride-alongs (`scripts/insert-stub.mjs`). Classification recipe + shapes: [`changelog-discipline.md`](changelog-discipline.md).
102
+
103
+ **4b. Bump.** PATCH vs MINOR: **MINOR is reserved for API-surface breaks only** (removed/renamed prop, attribute, slot, event, token, or tag). Visible behavior changes, re-scalings, and opt-in features stay PATCH; a CHANGELOG bullet saying "(MINOR behavior change)" is prose, not a semver directive. Unqualified "bump version" = PATCH; don't round-trip to ask. `node "${CLAUDE_PLUGIN_ROOT}/skills/adia-release/scripts/bump.mjs" --from X.Y.Z-1 --to X.Y.Z`. On a MINOR cut, also bump the internal `@adia-ai/*` `^ranges` separately (bump.mjs touches `"version"` fields only) — and a MINOR cut owes a MIGRATION GUIDE section ([`migration-guide-authoring.md`](migration-guide-authoring.md)).
104
+
105
+ **4c. Lockfile.** `npm install --package-lock-only --no-audit --no-fund` — must land in the release commit. The publish workflows open with `npm ci`, which hard-fails on a version/lockfile mismatch: a bump without the regenerated lockfile passes locally and breaks **every** publish at clean-install.
106
+
107
+ **4d.** `npm run check:lockstep` → `OK — all packages at X.Y.Z, all internal ranges at ^X.Y.0`.
108
+
109
+ ## §Step 5 — Stage and commit (on a release branch)
110
+
111
+ The release commit lands via PR, never a direct push to `main` (repo
112
+ policy, operator ruling 2026-07-12 — everything ships PR-first). Branch
113
+ FIRST, then stage. Defensively clear the index, then stage by explicit
114
+ allowlist (never `git add -A`; if peers may have pre-staged files,
115
+ `git commit -o <paths>` also bypasses a polluted index):
116
+
117
+ ```bash
118
+ git -C "$REPO" checkout -b "release/vX.Y.Z"
119
+ git -C "$REPO" reset HEAD >/dev/null 2>&1
120
+ git -C "$REPO" add package-lock.json packages/*/package.json packages/*/CHANGELOG.md \
121
+ packages/a2ui/*/package.json packages/a2ui/*/CHANGELOG.md # + in-scope source + Step-3.0 regen outputs
122
+ git -C "$REPO" diff --cached --stat | tail -3 # count must match the allowlist
123
+ ```
124
+
125
+ Commit shape: `chore(release): vX.Y.Z lockstep — <summary>` with substantive scope per package, ride-along stub list, any `Excluded — in-flight:` lines, and the pasted gate summary.
126
+
127
+ ## §Step 5.5 — Pre-commit freshness trip-wire
128
+
129
+ After `git add`, before `git commit`, re-run the three freshness gates against staged state:
130
+
131
+ ```bash
132
+ node scripts/build/components.mjs --verify && npm run check:chunks-fresh && npm run check:embeddings-fresh
133
+ ```
134
+
135
+ Drift here means a regen output was left out of the allowlist — stage it and re-run. <2s now vs ~5min of tag-move recovery after CI catches it. Do not proceed to tag with drift.
136
+
137
+ ## §Step 5.7 — Release PR: push the branch, merge, re-baseline
138
+
139
+ The release commit reaches `main` through the standard PR flow:
140
+
141
+ ```bash
142
+ git -C "$REPO" push -u origin "release/vX.Y.Z"
143
+ gh pr create --title "release: vX.Y.Z lockstep" --body "<scope + gate summary>"
144
+ # wait for required checks (fail-soft jobs excluded); then merge per house flow:
145
+ gh pr merge <N> --admin --merge --delete-branch
146
+ git -C "$REPO" checkout main && git -C "$REPO" pull
147
+ ```
148
+
149
+ Post-merge fixes land as follow-up commits to the SAME release PR (or a
150
+ second PR merged before tagging) — the tag point below is always `main`'s
151
+ post-merge HEAD, so anything merged before tagging ships in the tarball.
152
+ If unrelated PRs merged between yours and the tag step, that is fine: tag
153
+ at HEAD is the invariant, and the window closes at the tag.
154
+
155
+ ## §Step 6 — Tag ← operator checkpoint 1 (before tagging)
156
+
157
+ Show the operator the planned tag list + the F-N1 preview; proceed only on their go. Then tag **at `main`'s post-merge HEAD** (post-bump fixes belong in the tarball; the window's last merge is the tag point — exception: batch push tags each version at its own release-merge SHA):
158
+
159
+ ```bash
160
+ node "${CLAUDE_PLUGIN_ROOT}/skills/adia-release/scripts/tag-lockstep.mjs" \
161
+ --version X.Y.Z # umbrella vX.Y.Z + 11 <pkg>-vX.Y.Z (incl. the 2 plugins, 2026-07-15 policy)
162
+ ```
163
+
164
+ ## §Step 7 — F-N1 release trip-wire
165
+
166
+ ```bash
167
+ node scripts/release/check-release.mjs --all-pending
168
+ ```
169
+
170
+ Per-package tags must be `✓ clean`; the umbrella-tag error is expected noise. On warns, run the enrichment pass ([`changelog-discipline.md`](changelog-discipline.md) §F-N1): fix the entry, land it as a follow-up commit through the PR flow (`--amend` is no longer possible — the release commit is already merged), delete + re-create the tags at the new post-merge SHA, re-run.
171
+
172
+ ## §Step 8 — Push tags ← operator checkpoint 2 (before pushing tags)
173
+
174
+ `main` is already on the remote (the release PR merged in Step 5.7) —
175
+ only the tags push here. Show the tag list + confirm
176
+ `git rev-list --count origin/main..HEAD` is 0 (a non-zero count means
177
+ local commits bypassed the PR flow — stop and route them through a PR
178
+ first); on go:
179
+
180
+ ```bash
181
+ for t in web-components-vX.Y.Z web-modules-vX.Y.Z llm-vX.Y.Z a2ui-runtime-vX.Y.Z \
182
+ a2ui-compose-vX.Y.Z a2ui-corpus-vX.Y.Z a2ui-mcp-vX.Y.Z \
183
+ a2ui-retrieval-vX.Y.Z a2ui-validator-vX.Y.Z \
184
+ adia-ui-factory-vX.Y.Z adia-ui-forge-vX.Y.Z; do
185
+ git -C "$REPO" push origin "$t" # ONE tag per push — batched multi-tag
186
+ done # pushes drop the create event (Scenario 7)
187
+ git -C "$REPO" push origin vX.Y.Z # umbrella last; triggers nothing
188
+ ```
189
+
190
+ ## §Step 9 — Publish ← operator checkpoint 3 (before publishing)
191
+
192
+ For batch pushes, confirm ordering with the operator: **oldest version publishes and settles first** — `npm dist-tag latest` is set by publish order. Then:
193
+
194
+ ```bash
195
+ node "${CLAUDE_PLUGIN_ROOT}/skills/adia-release/scripts/dispatch-publish.mjs" \
196
+ --version X.Y.Z --verify-triggered # re-dispatches only missing runs
197
+ ```
198
+
199
+ Wait for the workflows to settle, then verify against the **registry**, never the workflow's green check:
200
+
201
+ ```bash
202
+ for pkg in web-components web-modules llm a2ui-runtime a2ui-compose a2ui-corpus \
203
+ a2ui-mcp a2ui-retrieval a2ui-validator adia-ui-factory adia-ui-forge; do
204
+ echo -n "$pkg: "; npm view "@adia-ai/$pkg" version
205
+ done
206
+ npm view @adia-ai/web-components dist-tags.latest # must equal X.Y.Z
207
+ ```
208
+
209
+ Zero workflows fired after a tag push → [`recovery-paths.md`](recovery-paths.md) §Scenario 7.
210
+
211
+ ## §Step 10 — GH releases + site deploy
212
+
213
+ ```bash
214
+ for pkg in <the 9>; do
215
+ gh release create "$pkg-vX.Y.Z" --title "@adia-ai/$pkg vX.Y.Z" --notes-file <body>.md
216
+ done
217
+ # Site deploy goes through the pipeline, never a raw rsync (operator go required — deploy is checkpoint-class):
218
+ gh workflow run "Deploy site (ui-kit.exe.xyz)" --repo adiahealth/gen-ui-kit --ref main
219
+ ```
220
+
221
+ Deploy discipline (the release tenant of the demo-site host; VM/service ops belong to the deploy skill, `adia-deploy`):
222
+
223
+ - `deploy-site.yml` owns build → pre-flight verify → snapshot → rsync → post-deploy verify → auto-rollback; it builds from `main`, so the release commit must already be merged (§Step 5.7 guarantees this). A raw local rsync bypasses every one of those gates.
224
+ - **Verify deployed FILES, never SPA routes.** The docs site returns HTTP 200 + the same ~5 KB shell for *every* path; an unmatched route renders blank with no error. Curl a content file and grep for real bytes:
225
+
226
+ ```bash
227
+ curl -s -o /dev/null -w "%{http_code}\n" https://ui-kit.exe.xyz/packages/web-components/styles/host.css # 200
228
+ curl -s https://ui-kit.exe.xyz/<this-cycle's-content-file> | grep -q "<unique string>" && echo OK
229
+ ```
230
+
231
+ - Any docs **route** cited to the operator or in notes must exist in `site/sitemap.json` (`grep '"path":'`) — a plausible-looking route that isn't in the sitemap renders blank.
232
+
233
+ Any Step-2 stashes: `git stash pop`; flag conflicts to the operator.
234
+
235
+ ## §Step 11 — Author release notes (default)
236
+
237
+ Always author notes at end-of-cycle without being asked — context is freshest now. Single version → [`notes-authoring.md`](notes-authoring.md); ≥2 versions since the last broadcast → its §Rollup section. Surface the draft inline for copy-paste; the operator owns posting. Skip only on an explicit "no notes".
238
+
239
+ ---
240
+
241
+ ## §Variant A shortcut
242
+
243
+ Peer pre-cut the release commit: Step 1 (confirm HEAD is the `release(*): vX.Y.Z` commit) → Step 2 → Step 3 → skip 4–5 → resume at Step 6.
244
+
245
+ ## §When to abort
246
+
247
+ Stop and surface to the operator when: a gate fails outside the documented recoveries; F-N1 reports >1 warn per package tag or any non-umbrella error; the release-commit candidate fails `check:demo-shells` / `check:lockstep` / `check:embeddings-fresh` (→ [`recovery-paths.md`](recovery-paths.md) §Scenario 4); uncommitted files stay unclassifiable after diffing; or a publish workflow fails E404/E401 (npm-token rotation — operator-owned).
@@ -0,0 +1,222 @@
1
+ # `gates-catalog.md` — pre-flight gate roster + failure → recovery map
2
+
3
+ > Load for a verify-only run or on any gate failure during a cut. Maps every
4
+ > release-flow gate × what it checks × typical failure × recovery. Gates are
5
+ > grouped by **failure category** — how the operator routes when one goes red —
6
+ > not by alphabetical namespace. Cited scripts live in the target monorepo's
7
+ > `package.json` (`check:*` / `verify:*` / `smoke:*` / `test:*`).
8
+
9
+ Row layout per gate: **What** · **Typical failure** · **Recovery**.
10
+
11
+ ---
12
+
13
+ ## §Category 1 — Release identity (hard-fail any cut)
14
+
15
+ ### `npm run check:lockstep`
16
+
17
+ - **What:** all 9 `@adia-ai/*` packages declare the same `version`; internal `@adia-ai/*` dep ranges match policy (`^X.Y.0` during PATCH cycles, bumped at MINOR).
18
+ - **Typical failure:** one package forgot to bump; a peer edited an internal range mid-PATCH; a `^0.0.x` range slipped in.
19
+ - **Recovery:** version drift → `scripts/bump.mjs` (bundled with this skill); range drift → `npm run check:lockstep:fix` auto-aligns, then re-run.
20
+ - **Why `^0.0.x` is forbidden:** npm pre-1.0 semver only widens the caret when major+minor aren't both zero — `^0.0.6` resolves to `>=0.0.6 <0.0.7`, locked to exactly 0.0.6. An internal dep pinned that way silently installs a *stale* sibling on every fresh `npm i` (this shipped a real ~4-day-latent bug before the lockstep policy). The `^X.Y.0` floor (Y≥1) widens correctly across patches; trust the gate, don't reason about caret semantics by hand. Moot at 1.0.0.
21
+
22
+ ### `node scripts/release/check-release.mjs --all-pending` (F-N1, the release trip-wire)
23
+
24
+ - **What:** for every unpushed tag, verifies CHANGELOG coverage of the diff between this tag and the package's previous tag.
25
+ - **Cosmetic failure:** "diff `packages/<pkg>/components/` touched but CHANGELOG `[X.Y.Z]` doesn't mention 'components'" — the entry names the component (`table-ui`) but not the literal path keyword. Regex miss, change IS documented.
26
+ - **Real failure:** a touched directory has NO matching CHANGELOG entry at all — the cycle missed documenting a change.
27
+ - **Recovery:** cosmetic → add the path keyword to a relevant entry (`table.yaml` → `components/table/table.yaml`); real → author the missing entry. Either way: amend the release commit, delete + re-create the tags at the new SHA, re-run. Full discipline: [`changelog-discipline.md`](changelog-discipline.md) §F-N1 enrichment.
28
+ - The umbrella tag's "doesn't match `<pkg>-v<version>`" **error is expected — ignore it**; only per-package warns need action.
29
+
30
+ ### `npm run check:changelog-coverage`
31
+
32
+ - **What:** every published package has a `[vX.Y.Z]` CHANGELOG block for the current `package.json` version.
33
+ - **Recovery:** add the block (stub if genuinely no source change — but classify by the diff first, see [`changelog-discipline.md`](changelog-discipline.md) §Detecting source-changing packages).
34
+
35
+ ---
36
+
37
+ ## §Category 2 — Generated-file coherence (hard-fail any cut)
38
+
39
+ ### `node scripts/build/components.mjs --verify`
40
+
41
+ - **What:** every component yaml has an up-to-date `.a2ui.json` sidecar; `.d.ts` codegen current. (Generated files are also hook-guarded against hand edits.)
42
+ - **Recovery:** `node scripts/build/components.mjs` (no `--verify`) regenerates; stage the sidecars.
43
+
44
+ ### `npm run verify:traits`
45
+
46
+ - **What:** `traits/_catalog.json` reflects every `defineTrait()` call; 100% coverage.
47
+ - **Recovery:** `npm run build:traits`; stage.
48
+
49
+ ### `npm run verify:a2ui-schema`
50
+
51
+ - **What:** the A2UI JSON Schema is in sync with the `@adia-ai/a2ui-runtime` TS types.
52
+ - **Recovery:** `node scripts/build/a2ui-schema-types.mjs`; stage.
53
+
54
+ ### `npm run verify:tsconfig-strictness`
55
+
56
+ - **What:** per-package `tsconfig.json` doesn't silently relax flags set strict in `tsconfig.base.json` (ADR-0029). A relaxation needs a `// TS-MIG-NNN` tracking comment.
57
+ - **Recovery:** remove the override, or add the tracking comment.
58
+
59
+ ---
60
+
61
+ ## §Category 3 — Component / primitive structural drift
62
+
63
+ ### `npm run check:demo-shells`
64
+
65
+ - **What:** every component demo `.html` imports all primitives named in its yaml `composes:` list.
66
+ - **Typical failure:** a yaml gained a `composes:` entry but the demo shell didn't get the matching `<script>` import.
67
+ - **Recovery:** add `<script type="module" src="../<tag>/<tag>.js">` to the demo shell. **Release-blocking: HIGH** — a commit failing this gate ships broken demo pages in its tarball. If the fix already landed later but entangled with `[Unreleased]` work → [`recovery-paths.md`](recovery-paths.md) §Scenario 4.
68
+
69
+ Smaller siblings in this category (same recovery shape — fix the declaration or regenerate the registry):
70
+
71
+ | Gate | What |
72
+ | --- | --- |
73
+ | `check:composes` | every yaml `composes:` entry resolves to a real primitive |
74
+ | `check:dts-sibling-presence` | every component `.js` has a sibling `.d.ts` |
75
+ | `check:registry-catalog-coherence` | runtime registry ↔ A2UI catalog parity (both directions) |
76
+ | `check:required-icons` | every referenced `<icon-ui>` name is registered |
77
+ | `check:standalone-html-phosphor` | standalone demos using Phosphor icons include the loader |
78
+ | `check:substitutable-set-drift` | substitutable-element registry in sync |
79
+
80
+ ---
81
+
82
+ ## §Category 4 — CSS spec compatibility
83
+
84
+ ### `npm run check:lightningcss-build`
85
+
86
+ - **What:** every CSS file under `packages/web-{components,modules}/` minifies cleanly under LightningCSS + current Vite default targets.
87
+ - **Recovery:** fix the offending CSS. Most common sub-case ↓
88
+
89
+ ### `npm run check:scope-bare-descendants`
90
+
91
+ - **What:** no `@scope { > X {} }` bare-combinator descendants (LightningCSS rejects as "Invalid empty selector").
92
+ - **Recovery:** `node scripts/build/codemod-scope-bare-descendants.mjs` rewrites `> X` → `& > X`.
93
+
94
+ Also: `check:no-self-import-css` (no transitively self-importing barrel) · `check:rolldown-glob` (`import.meta.glob` works under Rolldown).
95
+
96
+ ---
97
+
98
+ ## §Category 5 — Browser safety / module hygiene
99
+
100
+ ### `npm run check:browser-safe`
101
+
102
+ - **What:** no top-level `import 'node:*'` in browser-reachable modules (`packages/a2ui/{compose,retrieval,validator}`, `web-components/`, `web-modules/`, `apps/*/app/*.contents.js`).
103
+ - **Recovery:** dual-mode pattern (`IS_NODE` + dynamic `await import(/* @vite-ignore */ 'node:*')` + `import.meta.glob` browser branch); canonical impl: `packages/a2ui/retrieval/component-catalog.js`.
104
+
105
+ Siblings: `check:absolute-imports` (no leading-`/` imports — rewrite relative) · `check:template-interp` (template `${expr}` contract) · `check:yaml-events` (yaml `events:` match runtime `dispatchEvent` calls) · `check:yaml-impl-coverage` (every yaml prop implemented in the JS class).
106
+
107
+ ---
108
+
109
+ ## §Category 6 — Visual / structural integrity
110
+
111
+ | Gate | What |
112
+ | --- | --- |
113
+ | `check:card-structure` / `check:drawer-structure` | card/drawer body wraps in `<section>` (strict variants of the `audit:*` twins) |
114
+ | `check:with-css-pairing` | every shell with paired `.js` + `.css` has a `/with-css` companion + exports-map entry |
115
+ | `verify:no-legacy-shell-shapes` | no legacy `<main>` / `[data-content-*]` shapes under `<admin-shell>` (ADR-0032) |
116
+ | `audit:native-primitive-leak` | native `<button>`/`<input>`/… where a `*-ui` equivalent exists; criticals must be replaced or annotated `data-native-ok="<reason>"` |
117
+ | `audit:shell-composition` | admin-shell compositions missing canonical parts (statusbar, `[data-spacer]`/`[data-actions]`, …); escape hatch `data-shell-opt-out="<reason>"` |
118
+
119
+ The two `audit:*` probes are soft-fail pre-cut (exit-1 only on criticals); findings get folded into release notes if non-zero. Recovery for both is manual — slot/attr semantics need a human eyeball, never auto-fix.
120
+
121
+ ---
122
+
123
+ ## §Category 7 — Corpus / bundle freshness
124
+
125
+ ### `npm run verify:corpus`
126
+
127
+ - **What:** every chunk in `packages/a2ui/corpus/chunks/*.json` is reachable and well-formed.
128
+ - **Recovery:** corpus remediation routes to the A2UI-pipeline skill, not this one.
129
+
130
+ ### `npm run check:chunks-fresh`
131
+
132
+ - **What:** `chunks/_index.json` matches on-disk chunks and source fragments.
133
+ - **Recovery:** `npm run harvest:chunks`; stage the corpus outputs.
134
+
135
+ ### `npm run check:embeddings-fresh`
136
+
137
+ - **What:** `chunk-embeddings.json` at-or-newer-than `chunks/_index.json`.
138
+ - **Recovery:** `npm run build:embeddings:chunks` (needs `OPENAI_API_KEY`; ~6s). Stage `chunk-embeddings.json` + note the regen in the a2ui-corpus CHANGELOG `[vX.Y.Z]`.
139
+
140
+ ### `npm run check:css-bundles-fresh` / `npm run check:js-bundles-fresh`
141
+
142
+ - **What:** the `dist/` CDN bundles (`web-components.min.{css,js}`, `everything.min.js`, per-shell `*.min.js`, `icons-manifest.js`) match source. Stale bundles mean jsdelivr/unpkg serve yesterday's build. **Blocking in CI** (2026-06-08).
143
+ - **Recovery:** `npm run build -w @adia-ai/llm` **FIRST** (its `index.js` is a gitignored tsc artifact `build:bundle-js` resolves — a fresh worktree can't bundle without it), then `npm run build:bundles` (or `build:bundle-css` / `build:bundle-js` individually). Stage both `dist/` trees.
144
+ - **Manual spot-checks** (complement the gate; the v0.6.29–31 cycles shipped a shells-only `everything.min.js` that hard-crashed CDN consumers):
145
+
146
+ ```bash
147
+ grep "import '@adia-ai/web-components'" packages/web-modules/everything.js # must be present
148
+ grep -oE '"[a-z][a-z-]*-ui"' packages/web-modules/dist/everything.min.js | sort -u | wc -l # ≥100
149
+ node -e "const m=require('./packages/web-components/dist/icons-manifest.js'); \
150
+ console.log('regular:', m.default.regular.length, '| cdn:', m.default.cdn)" # non-empty + cdn key
151
+ ```
152
+
153
+ ### `npm run audit:chunk-reconcile`
154
+
155
+ - **What:** duplicate-reconciliation report for the chunk corpus (fingerprint collisions, near-duplicates, structural twins). Advisory, not blocking.
156
+
157
+ ---
158
+
159
+ ## §Category 8 — Tests + types + evals
160
+
161
+ ### `npm run test:unit`
162
+
163
+ - **What:** the vitest suite (~1000+ tests).
164
+ - **Stale-test failure:** the test asserts a behavior a peer deliberately changed (CHANGELOG-documented) without updating the assertion. Tell it apart by reading assertion vs CHANGELOG vs source: if the code matches the CHANGELOG's described behavior, the test is stale — update the assertion (see [`recovery-paths.md`](recovery-paths.md) §Scenario 5). Real regression → fix the regression.
165
+ - **Parallel-contention flake:** heavy web-modules composite suites can fail under full parallelism on a loaded machine (`signals: drain loop exceeded 100 iterations`). Load-dependent, not a code defect. **Gate on `npx vitest run --no-file-parallelism`** (sequential is the source of truth); don't treat a one-off parallel flake as a blocker, and don't raise the drain guard.
166
+
167
+ ### `npm run eval:diff -- --engine zettel`
168
+
169
+ - **What:** end-to-end gen-UI eval. Floors (preserve-not-regress):
170
+ - **Zettel**: cov ≥ 87%, avg ≥ 85, MRR ≥ 0.94
171
+ - **Free-form**: cov ≥ 90%, avg ≥ 83, F1 ≥ 55
172
+ - **Monolithic**: cov = 100%, avg ≥ 95
173
+ - **Dogfood**: 20/20, avg ≥ 95
174
+ - **Recovery:** retrieval/corpus regression — routes to the A2UI-pipeline skill.
175
+
176
+ Siblings: `typecheck` (`tsc --noEmit`) · `smoke:engines` (gen-UI engines + retrieval probes) · `smoke:register-engine` (11/11) · `test:a2ui` (22/22, +1 skipped OK).
177
+
178
+ ---
179
+
180
+ ## §Category 9 — Misc release safety
181
+
182
+ ### `npm run dogfood:status`
183
+
184
+ - **What:** aggregator over the component dogfood audits; classifies findings P0–P3 and regenerates the tracker at `qa/findings/dogfood-tracker.md`. Exit-1 when P0+P1 > 0; P2/P3 are advisory.
185
+ - **Pre-cut policy: must pass before tag.** Any P0/P1 means a paid-down bug class was re-introduced; open the tracker, apply the canonical fix template at the cited file:line, re-run. ~5s.
186
+
187
+ ### `npm run verify:pack`
188
+
189
+ - **What:** `npm pack --dry-run` succeeds per package — catches malformed `files`/`exports`. Note: the npm `files:` array supports negation (`!components/**/*.html`); verify tarball contents with `--dry-run` after touching it.
190
+
191
+ Siblings: `check:links` (intra-repo markdown links resolve) · `check:cdn-pins` (docs' CDN `@0.X` pins match the current minor — catches a stale `@0.6` after a `0.7` cut) · `verify:contrast` / `verify:palette` (WCAG pairs / OKLCH ramps).
192
+
193
+ ---
194
+
195
+ ## §Standard subsets
196
+
197
+ **Minimum 6 (verify-only default)** — fastest set that catches release-blockers:
198
+
199
+ ```bash
200
+ node scripts/build/components.mjs --verify
201
+ npm run check:lockstep
202
+ npm run verify:traits
203
+ npm run test:unit
204
+ npm run typecheck
205
+ npm run check:demo-shells
206
+ ```
207
+
208
+ Add `verify:corpus` + `check:embeddings-fresh` if chunks were touched; `check:lightningcss-build` if CSS was touched; F-N1 if unpushed release tags exist.
209
+
210
+ **Full pre-cut sweep** — the 17-gate roster in [`cut-procedure.md`](cut-procedure.md) §Step 3. ~90s wall time.
211
+
212
+ **Omnibus** — `npm run check` invokes everything. Heavy; use when re-baselining a stale checkout.
213
+
214
+ **Suffix variants:** most gates have `:strict` (warns fail), `:fix` (auto-apply, e.g. `check:lockstep:fix`), `:json` / `:quiet` (output form) variants.
215
+
216
+ ---
217
+
218
+ ## §Gate stewardship
219
+
220
+ - **This catalog must stay in sync with `package.json` `scripts`.** When a cycle meets a release-flow gate not listed here, add its row in the same change.
221
+ - **New CI gates ship advisory first** (`continue-on-error: true`), promoted to blocking after 5+ green runs. Two freshness-gate traps: mtime checks are permanently red on fresh `actions/checkout` (clone-time mtimes — need `fetch-depth: 0` + git-restore-mtime); a dir-watching gate needs its own workflow whose `pull_request: paths:` covers the watched dirs.
222
+ - **New/extended `scripts/release/check-*.mjs` slots run against `main` immediately**; close every finding same-cycle. Before adding a slot, grep the existing ones — the gap is often a regex limit in a current slot, not a missing slot.
@@ -0,0 +1,52 @@
1
+ # `independent-package-release.md` — class-B cut (independently-versioned package)
2
+
3
+ > Load when releasing a package versioned **independently** of the lockstep set —
4
+ > excluded from the lockstep gate, no umbrella tag, no demo-site deploy.
5
+ > **Class B currently has NO members** (2026-07-15 policy change, operator
6
+ > ruling): the Claude Code plugins under `packages/plugins/*` joined the
7
+ > lockstep after class-B independence let npm drift a full harness-reset
8
+ > behind the repo (npm served forge 0.1.3/factory 0.2.4 pre-reset content
9
+ > while the rewritten estate sat unpublished at a regressed 0.1.0). This
10
+ > procedure is retained for future genuinely-independent packages. The
11
+ > lockstep cut is [`cut-procedure.md`](cut-procedure.md).
12
+
13
+ ## §Two release classes in one monorepo
14
+
15
+ | | Class A — lockstep cut | Class B — independent package |
16
+ | --- | --- | --- |
17
+ | Versioning | whole set bumps together | own version line per package |
18
+ | Lockstep gate | enforced (`check:lockstep` 9/9) | **excluded** — the gate skips `packages/plugins/*` by design |
19
+ | Umbrella tag | `vX.Y.Z` + per-package | **none** — per-package tags only (versions differ) |
20
+ | `dist-tag` ordering | cross-package publish order matters | N/A |
21
+ | Demo-site deploy | yes | **none** |
22
+ | Publish trigger | tag-triggered per-package workflow | same mechanism (`.github/workflows/publish-adia-ui-{factory,forge}.yml`) |
23
+
24
+ Class B keeps the operator checkpoints and the verify-against-the-registry discipline; it drops every lockstep-specific invariant.
25
+
26
+ ## §New-package onboarding — the three trip-wires a FIRST cut hits
27
+
28
+ Substrate fixes (release scripts / lockfile / CHANGELOG), landed once as a normal PR on `main` *before* tagging:
29
+
30
+ 1. **Lockfile.** A new workspace package absent from the lockfile blocks the pre-commit hook and fails the workflow's `npm ci`. Fix: `npm install --package-lock-only && git add package-lock.json`.
31
+ 2. **Release-trip-wire package registry.** F-N1 validates each pushed tag against `scripts/release/check-release.mjs`'s hardcoded `PACKAGES` array; an unregistered tag fails the pre-push hook with `unknown package`. Fix: add `{ tagPrefix: '<name>', path: 'packages/plugins/<name>' }`.
32
+ 3. **CHANGELOG bracket form.** The trip-wire requires Keep-a-Changelog `## [<version>]` headings; bare `## <version>` fails with "no `## [<version>]` entry".
33
+
34
+ ## §Procedure
35
+
36
+ 1. **Re-baseline** — `git fetch`; confirm the checkout isn't on a peer's branch.
37
+ 2. **Land the package(s) on `main`** via PR; resolve every review thread before an admin-merge (this repo's merge gate).
38
+ 3. **Pre-publish gate.** `npm run verify:plugins` (package.json ↔ plugin-manifest versions synced). Plugin-specific structural gates: `npm run audit:plugin-coupling` + `npm run check:factory-bare-repo` (ADR-0040 — the plugin must work in a bare consumer repo, no monorepo coupling). The lockstep gate still passes for the lockstep set. First publish of a name: `npm view @adia-ai/<pkg> version` → `E404` means the name is free.
39
+ 4. **Tag at the published commit** — `git tag <pkg>-vX.Y.Z` per package; versions differ; no umbrella. Dry-run the trip-wire over the tags (`node scripts/release/check-release.mjs <tags>`) before pushing. If the shared working tree is on a peer's branch, push tags from a throwaway worktree on `origin/main`.
40
+ 5. **Push the tags** → the per-package workflows run `npm ci → verify:plugins → npm publish --access public`.
41
+ 6. **Verify against npm, not the workflow:** `npm view @adia-ai/<pkg> version` returns the new independent version for each package. Watch runs (`gh run watch <id> --exit-status`), but the registry is the source of truth.
42
+ 7. **Marketplace cut-over** (if a plugin marketplace repo exists): point the manifest's per-plugin `source` at npm (`{ "source": "npm", "package": "@adia-ai/<pkg>" }`), `git rm -r` vendored copies, validate the JSON, commit, push. Consumers then `/plugin marketplace add <org>/<repo>` → `/plugin install <pkg>@<repo>`.
43
+
44
+ ## §Verify target
45
+
46
+ The published package(s) on the **npm registry** at their independent versions, plus (if a marketplace exists) its manifest referencing npm. NOT "all 9 + the demo site" — that's class A.
47
+
48
+ ## §Gotchas (from the first independent cut, factory v0.2.2 + forge v0.1.2)
49
+
50
+ - Never add the package to the lockstep gate or tag it with the umbrella.
51
+ - Publish-workflow YAMLs are token-bearing — keep `persist-credentials: false` on the checkout step, matching the established workflows' action-pinning.
52
+ - A marketplace repo's org + visibility is an **operator call** — a public `gh repo create` is outward-facing; confirm first, and run a secret-scan of full history before pushing any repo public.
@@ -0,0 +1,86 @@
1
+ # `migration-guide-authoring.md` — authoring the MIGRATION GUIDE on a breaking cut
2
+
3
+ > Load whenever the cut is **MINOR** (an API-surface break) or on an explicit
4
+ > "author the migration guide" ask. This is the **producer** side of migrations:
5
+ > the release ships the breaking change, so the release authors the guide section
6
+ > consumers follow. The shared producer/consumer format contract is
7
+ > [`../../../references/contracts/migration-guide-format.md`](../../../references/contracts/migration-guide-format.md)
8
+ > — the factory's `adia-migrate` skill consumes exactly that shape.
9
+ >
10
+ > Scope split: **producer (this skill)** authors the guide section + migrates the
11
+ > framework's own in-repo surfaces. **Consumer** (a downstream app sweep) is the
12
+ > factory plugin's `adia-migrate` — decline and redirect. Designing the breaking
13
+ > change itself is a contract decision upstream of both.
14
+
15
+ The guide lives at **`.claude/docs/MIGRATION GUIDE.md`** (the space in the filename is intentional; it's a first-class consumer artifact). One section per breaking release, newest at top; a consumer jumping versions reads the merged span. Every cut — breaking or not — gets a version-scope bullet in the top index (see the format contract).
16
+
17
+ ## §When a section is owed
18
+
19
+ Author (or extend) a section when the cut removes or renames a **public API symbol**: a prop/attribute (`variant="danger"` → `color="danger"`), a slot or slot-semantics flip, an event name, a token (`--n-*` → `--a-*`), a tag, a Boolean → enum migration, or a default-value change wide enough that consumers must act. Same line as the PATCH-vs-MINOR rule: cutting MINOR almost certainly owes a section. Additive cuts need none — note "additive; no consumer sweep" in the version-coverage table and move on.
20
+
21
+ ## §The authoring workflow
22
+
23
+ **1. Enumerate the breaking surface** from the cut's diff + CHANGELOG `### Removed`/`### Changed` entries. Per item capture: the symbol · before → after · the kind (pure rename / semantic flip / Boolean→enum / removal) · the audit grep · the sweep (or "manual review").
24
+
25
+ **2. Write the section** — one `###` subsection per item:
26
+
27
+ ```markdown
28
+ ## Migrating to @adia-ai/web-components@X.Y.Z (YYYY-MM-DD)
29
+
30
+ <one-line scope: N breaking items, the headline.>
31
+
32
+ ### <item — bold headline> (`old` → `new`)
33
+
34
+ <one sentence: what changed and why.>
35
+
36
+ **Audit:**
37
+ git grep -nE '<pattern that surfaces call sites>'
38
+
39
+ **Sweep:**
40
+ git grep -nlE '<pattern>' | xargs perl -i -pe 's/<old>/<new>/g'
41
+ ```
42
+
43
+ Shape rules:
44
+
45
+ - **Audit grep first, sweep second** — the consumer always lists call sites before sweeping; author both.
46
+ - **Mechanical vs manual, explicitly labeled.** A pure rename ships a `perl -i -pe`; a semantic flip ships a "manual review — here's why" note (sed can't tell author intent).
47
+ - **One component per sweep regex** — alternation captures (`<(toast|alert)-ui`) don't preserve the matched alternative cleanly.
48
+ - **HTML-attribute regexes only match HTML/JSX** — author a separate JS-side regex when the symbol has a programmatic form (`el.variant = 'danger'`).
49
+
50
+ **3. Migrate the in-repo surfaces FIRST.** Before the cut ships, run the audit + sweep against `apps/`, `playgrounds/`, `catalog/`, `packages/web-components/components/*/*.html` — the release must not ship broken examples of the thing it changed, and dogfooding the recipe here is what proves it works for consumers.
51
+
52
+ **4. Verify.** Run the cut's normal gate roster; the structural/demo gates catch missed in-repo surfaces. Then the **sweep-verification grep** across ALL extensions — the trap is a vocabulary migration that touched markup but not the CSS selectors or JS comments referencing it:
53
+
54
+ ```bash
55
+ LEGACY_PATTERNS=( '<old-tag' 'old-attr=' '--old-token' )
56
+ for pat in "${LEGACY_PATTERNS[@]}"; do
57
+ echo "=== $pat ==="
58
+ grep -rln -E "$pat" apps playgrounds catalog \
59
+ --include='*.css' --include='*.html' --include='*.js' --include='*.yaml'
60
+ done # 0 hits = sweep verified clean
61
+ ```
62
+
63
+ **5. Cross-reference.** The breaking package's CHANGELOG entry names the symbol AND points at the guide section; the release notes carry a `⚠️` heads-up linking it. Anchors are stable — never retitle an existing section (release notes and consumer tooling link them).
64
+
65
+ ## §Manual-review classes (never auto-sweep)
66
+
67
+ - **Semantic flips** — a rename that inverts default behavior (`[open]` default-hidden → `[collapsed]` default-visible): the right migration depends on author intent. List occurrences, ask.
68
+ - **Opt-out Booleans defaulting true** — the migration only matters where a consumer explicitly disabled the affordance; sed can't tell.
69
+ - **Ownership moves** — a prop moving from wrapper to slotted child; the target child may not exist yet.
70
+ - **kebab-string property keys** — attribute name unchanged, only the JS programmatic form changed; audit programmatic access only.
71
+ - **Wide namespace renames (50+ symbols)** — tag/token/class rename waves: list by table, require human approval per cluster; blind sweeps hit false positives on shared prefixes.
72
+
73
+ ## §The version-coverage table
74
+
75
+ Maintained at the top of the guide; classifies every release so a gap-jumping consumer knows which sections apply: `additive` (bump and go) · `BREAKING (N items)` (has a section) · `structural` (import retargeting) · `rename` (wide namespace rename, manual-review by cluster). Note forward-looking volatile surfaces at the bottom of the guide so the next breaking-release author knows where churn concentrates.
76
+
77
+ ## §Anti-patterns
78
+
79
+ Authoring the guide after the cut ships (it's part of the release scope) · a `perl -i -pe` for a semantic flip · merged alternation sweeps · skipping the in-repo sweep · a CHANGELOG bullet with no guide section for a real break (the CHANGELOG says *what*, the guide says *how*) · doing the consumer sweep from here.
80
+
81
+ ## §Done when
82
+
83
+ 1. Every breaking item in the cut's CHANGELOG has a matching subsection (audit + sweep, or a labeled manual-review note).
84
+ 2. In-repo surfaces swept; the sweep-verification grep reports 0 legacy hits.
85
+ 3. The cut's structural/demo gates pass.
86
+ 4. The release notes carry the `⚠️` heads-up linking the section.