@adia-ai/adia-ui-forge 0.8.62 → 0.8.63

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 (142) hide show
  1. package/.claude-plugin/plugin.json +2 -2
  2. package/.codex-plugin/plugin.json +3 -3
  3. package/CHANGELOG.md +300 -275
  4. package/README.md +54 -18
  5. package/__init__.py +8 -8
  6. package/agents/a2ui-maintenance-agent.corpus.json +7 -7
  7. package/agents/a2ui-maintenance-agent.md +6 -6
  8. package/agents/a2ui-planner-agent.md +11 -11
  9. package/agents/demo-audit-agent.corpus.json +4 -4
  10. package/agents/demo-audit-agent.md +8 -9
  11. package/agents/framework-checker.md +10 -11
  12. package/agents/framework-planner-agent.md +9 -10
  13. package/agents/gen-ui-review-agent.corpus.json +4 -4
  14. package/agents/gen-ui-review-agent.md +8 -8
  15. package/agents/package-release-agent.corpus.json +4 -4
  16. package/agents/package-release-agent.md +9 -10
  17. package/agents/primitive-authoring-agent.corpus.json +1 -1
  18. package/agents/primitive-authoring-agent.md +5 -5
  19. package/agents/routing-corpus.json +46 -46
  20. package/codex.interface.json +1 -1
  21. package/commands/gen-ui-review.md +1 -1
  22. package/commands/package-release.md +2 -2
  23. package/package.json +1 -1
  24. package/plugin.yaml +2 -2
  25. package/prompts/gen-ui-review.md +1 -1
  26. package/prompts/package-release.md +2 -2
  27. package/references/contracts/a2ui-mcp-surface.md +7 -7
  28. package/references/contracts/migration-guide-format.md +6 -7
  29. package/references/shared/content-trust.md +3 -5
  30. package/skills/a2ui-maintenance/SKILL.md +13 -16
  31. package/skills/a2ui-maintenance/evals/evals.json +2 -2
  32. package/skills/a2ui-maintenance/evals/routing-corpus.json +1 -1
  33. package/skills/a2ui-maintenance/references/anti-patterns.md +10 -10
  34. package/skills/a2ui-maintenance/references/chunk-authoring.md +11 -12
  35. package/skills/a2ui-maintenance/references/corpus-discipline.md +13 -14
  36. package/skills/a2ui-maintenance/references/data-model-reactivity.md +22 -25
  37. package/skills/a2ui-maintenance/references/eval-diagnostics.md +21 -21
  38. package/skills/a2ui-maintenance/references/format-extension-decisions.md +12 -13
  39. package/skills/a2ui-maintenance/references/leverage-rules.md +6 -6
  40. package/skills/a2ui-maintenance/references/mcp-pipeline-ops.md +9 -10
  41. package/skills/a2ui-maintenance/references/mcp-tool-reference.md +11 -12
  42. package/skills/a2ui-maintenance/references/pipeline-overview.md +33 -38
  43. package/skills/a2ui-maintenance/references/semantic-fail-lifting.md +13 -14
  44. package/skills/a2ui-maintenance/references/strategy-engines.md +14 -16
  45. package/skills/a2ui-maintenance/references/surface-lifecycle.md +10 -11
  46. package/skills/a2ui-maintenance/references/zettel-calibration.md +14 -16
  47. package/skills/component-md-authoring/SKILL.md +20 -21
  48. package/skills/component-md-authoring/agents/openai.yaml +1 -1
  49. package/skills/cross-harness-authoring-standards/SKILL.md +19 -21
  50. package/skills/cross-harness-authoring-standards/agents/openai.yaml +1 -1
  51. package/skills/cross-harness-compatibility-standards/SKILL.md +34 -35
  52. package/skills/cross-harness-compatibility-standards/agents/openai.yaml +1 -1
  53. package/skills/demo-audit/SKILL.md +38 -38
  54. package/skills/demo-audit/evals/routing-corpus.json +1 -1
  55. package/skills/demo-audit/references/admin-shell-anatomy.md +21 -25
  56. package/skills/demo-audit/references/app-shell-pitfalls.md +11 -13
  57. package/skills/demo-audit/references/auto-fix-allowlist.md +3 -3
  58. package/skills/demo-audit/references/card-anatomy-sweep.md +10 -11
  59. package/skills/demo-audit/references/chat-shell-anatomy.md +25 -26
  60. package/skills/demo-audit/references/editor-shell-anatomy.md +25 -28
  61. package/skills/demo-audit/references/html-attr-sweep.md +12 -13
  62. package/skills/demo-audit/references/mode7-status-battery.md +4 -4
  63. package/skills/demo-audit/references/native-leak-annotations.md +8 -8
  64. package/skills/demo-audit/references/output-contract-worked-example.md +8 -8
  65. package/skills/demo-audit/references/probe-discipline-and-escalation.md +2 -2
  66. package/skills/demo-audit/references/visual-probe-triage.md +21 -23
  67. package/skills/gen-ui-review/SKILL.md +27 -27
  68. package/skills/gen-ui-review/agents/openai.yaml +1 -1
  69. package/skills/gen-ui-review/evals/routing-corpus.json +1 -1
  70. package/skills/gen-ui-review/references/corpus-html-patterns.md +28 -29
  71. package/skills/gen-ui-review/references/exit-gate-mechanics.md +5 -5
  72. package/skills/gen-ui-review/references/lookup-maintenance.md +2 -2
  73. package/skills/gen-ui-review/references/loop-protocol.md +25 -25
  74. package/skills/gen-ui-review/references/rubric-cosmetic.md +10 -10
  75. package/skills/gen-ui-review/references/rubric-decompose.md +15 -16
  76. package/skills/gen-ui-review/references/rubric-score.md +23 -24
  77. package/skills/gen-ui-review/references/scorecard-worked-examples.md +12 -12
  78. package/skills/gen-ui-review/references/scores.schema.json +2 -2
  79. package/skills/llm-client-maintenance/SKILL.md +12 -12
  80. package/skills/llm-client-maintenance/evals/routing-corpus.json +1 -1
  81. package/skills/llm-client-maintenance/references/adapter-contract.md +27 -27
  82. package/skills/llm-client-maintenance/references/add-a-provider.md +25 -25
  83. package/skills/llm-client-maintenance/references/bridge-facade.md +31 -31
  84. package/skills/llm-client-maintenance/references/browser-proxy-boundary.md +17 -17
  85. package/skills/llm-client-maintenance/references/model-registry.md +14 -14
  86. package/skills/llm-client-maintenance/references/streaming-sse.md +21 -21
  87. package/skills/package-release/SKILL.md +21 -23
  88. package/skills/package-release/evals/evals.json +2 -2
  89. package/skills/package-release/evals/routing-corpus.json +2 -2
  90. package/skills/package-release/references/authorization-model.md +6 -8
  91. package/skills/package-release/references/changelog-discipline.md +25 -27
  92. package/skills/package-release/references/cut-procedure.md +129 -136
  93. package/skills/package-release/references/gates-catalog.md +42 -43
  94. package/skills/package-release/references/independent-package-release.md +14 -15
  95. package/skills/package-release/references/invariants-detail.md +9 -9
  96. package/skills/package-release/references/mechanization.md +11 -12
  97. package/skills/package-release/references/migration-guide-authoring.md +20 -20
  98. package/skills/package-release/references/notes-authoring.md +20 -20
  99. package/skills/package-release/references/recovery-paths.md +28 -28
  100. package/skills/primitive-authoring/SKILL.md +19 -19
  101. package/skills/primitive-authoring/agents/openai.yaml +1 -1
  102. package/skills/primitive-authoring/evals/evals.json +2 -2
  103. package/skills/primitive-authoring/evals/routing-corpus.json +2 -2
  104. package/skills/primitive-authoring/references/INDEX.md +22 -22
  105. package/skills/primitive-authoring/references/anti-patterns.md +76 -77
  106. package/skills/primitive-authoring/references/api-contract.md +63 -65
  107. package/skills/primitive-authoring/references/authoring-cycle.md +47 -50
  108. package/skills/primitive-authoring/references/canonical-pattern-index.md +118 -118
  109. package/skills/primitive-authoring/references/code-style.md +50 -52
  110. package/skills/primitive-authoring/references/common-gotchas.md +23 -23
  111. package/skills/primitive-authoring/references/composite-demo-protocol.md +42 -45
  112. package/skills/primitive-authoring/references/css-patterns.md +97 -97
  113. package/skills/primitive-authoring/references/for-attribute-event-contract.md +12 -12
  114. package/skills/primitive-authoring/references/form-control-sizing.md +16 -18
  115. package/skills/primitive-authoring/references/lifecycle-patterns.md +42 -42
  116. package/skills/primitive-authoring/references/llm-bridge.md +21 -21
  117. package/skills/primitive-authoring/references/module-promotion.md +51 -51
  118. package/skills/primitive-authoring/references/primitive-audit.md +16 -16
  119. package/skills/primitive-authoring/references/shell-patterns.md +81 -81
  120. package/skills/primitive-authoring/references/svg-authoring.md +62 -66
  121. package/skills/primitive-authoring/references/token-contract.md +45 -49
  122. package/skills/primitive-authoring/references/trait-pages.md +8 -8
  123. package/skills/primitive-authoring/references/worked-example.md +39 -39
  124. package/skills/primitive-authoring/references/yaml-contract.md +139 -143
  125. package/skills/site-deployment/SKILL.md +25 -26
  126. package/skills/site-deployment/agents/openai.yaml +1 -1
  127. package/skills/site-deployment/evals/routing-corpus.json +1 -1
  128. package/skills/site-deployment/references/deploy-playbooks.md +51 -53
  129. package/skills/site-docs-authoring/SKILL.md +14 -14
  130. package/skills/site-docs-authoring/agents/openai.yaml +1 -1
  131. package/skills/site-docs-authoring/evals/evals.json +1 -1
  132. package/skills/site-docs-authoring/evals/routing-corpus.json +1 -1
  133. package/skills/site-docs-authoring/intent.md +18 -18
  134. package/skills/ssr-compatibility/SKILL.md +24 -25
  135. package/skills/ssr-compatibility/agents/openai.yaml +1 -1
  136. package/skills/ssr-compatibility/evals/evals.json +1 -1
  137. package/skills/ssr-compatibility/evals/routing-corpus.json +1 -1
  138. package/skills/ssr-compatibility/references/consumer-workarounds.md +22 -23
  139. package/skills/ssr-compatibility/references/failure-shapes.md +84 -91
  140. package/skills/ssr-compatibility/references/guard-patterns.md +54 -58
  141. package/skills/ssr-compatibility/references/status-ledger.md +17 -17
  142. package/skills/ssr-compatibility/references/test-without-linkedom.md +26 -27
@@ -1,40 +1,39 @@
1
- # `gates-catalog.md` pre-flight gate roster + failure → recovery map
1
+ # `gates-catalog.md`, pre-flight gate roster + failure → recovery map
2
2
 
3
3
  `<plugin-root>` below is `$CLAUDE_PLUGIN_ROOT` in Claude Code; the plugin's installed directory
4
4
  in Codex.
5
5
 
6
6
  > Load for a verify-only run or on any gate failure during a cut. Maps every
7
7
  > release-flow gate × what it checks × typical failure × recovery. Gates are
8
- > grouped by **failure category** how the operator routes when one goes red
9
- > not by alphabetical namespace. Cited scripts live in the target monorepo's
8
+ > grouped by **failure category**, how the operator routes when one goes red, > not by alphabetical namespace. Cited scripts live in the target monorepo's
10
9
  > `package.json` (`check:*` / `verify:*` / `smoke:*` / `test:*`).
11
10
 
12
11
  Row layout per gate: **What** · **Typical failure** · **Recovery**.
13
12
 
14
13
  ---
15
14
 
16
- ## §Category 1 Release identity (hard-fail any cut)
15
+ ## §Category 1, Release identity (hard-fail any cut)
17
16
 
18
17
  ### `npm run check:lockstep`
19
18
 
20
- - **What:** all 10 lockstep `@adia-ai/*` packages declare the same `version` (the class-B `adia-plugins` package is excluded `lockstep: false`, `scripts/package-paths.mjs`); internal `@adia-ai/*` dep ranges match policy (`^X.Y.0` during PATCH cycles, bumped at MINOR).
19
+ - **What:** all 10 lockstep `@adia-ai/*` packages declare the same `version` (the class-B `adia-plugins` package is excluded, `lockstep: false`, `scripts/package-paths.mjs`); internal `@adia-ai/*` dep ranges match policy (`^X.Y.0` during PATCH cycles, bumped at MINOR).
21
20
  - **Typical failure:** one package forgot to bump; a peer edited an internal range mid-PATCH; a `^0.0.x` range slipped in.
22
21
  - **Recovery:** version drift → `` `<plugin-root>/skills/package-release/scripts/bump.mjs` ``; range drift → `npm run check:lockstep:fix` auto-aligns, then re-run.
23
- - **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.
22
+ - **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.
24
23
 
25
24
  ### `node scripts/release/check-release.mjs --all-pending` (F-N1, the release trip-wire)
26
25
 
27
26
  - **What:** for every unpushed tag, verifies CHANGELOG coverage of the diff between this tag and the package's previous tag.
28
- - **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.
29
- - **Real failure:** a touched directory has NO matching CHANGELOG entry at all the cycle missed documenting a change.
30
- - **Recovery:** cosmetic → add the path keyword to a relevant entry (`table.yaml` → `components/table/table.yaml`); real → author the missing entry. Either way: land it as a new commit through the PR flow (the release commit is already merged `--amend` is not possible post-invariant-3), delete + re-create the tags at the new post-merge SHA, re-run. Full discipline: [`changelog-discipline.md`](changelog-discipline.md) §F-N1 enrichment.
31
- - The umbrella tag `vX.Y.Z` classifies **`info`** (since 2026-07-19 it used to score `error`, which false-stopped release-pack's Step 7 on every cut); only per-package findings need action.
27
+ - **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.
28
+ - **Real failure:** a touched directory has NO matching CHANGELOG entry at all, the cycle missed documenting a change.
29
+ - **Recovery:** cosmetic → add the path keyword to a relevant entry (`table.yaml` → `components/table/table.yaml`); real → author the missing entry. Either way: land it as a new commit through the PR flow (the release commit is already merged, `--amend` is not possible post-invariant-3), delete + re-create the tags at the new post-merge SHA, re-run. Full discipline: [`changelog-discipline.md`](changelog-discipline.md) §F-N1 enrichment.
30
+ - The umbrella tag `vX.Y.Z` classifies **`info`** (since 2026-07-19, it used to score `error`, which false-stopped release-pack's Step 7 on every cut); only per-package findings need action.
32
31
 
33
- (The former `check:changelog-coverage` gate was deleted 2026-07-19 its drifted 9-package matcher could report "clean" where the authoritative gate fails. Pre-tag coverage is `check-release.mjs --pending-version X.Y.Z [--fix]`, Step 4f.)
32
+ (The former `check:changelog-coverage` gate was deleted 2026-07-19, its drifted 9-package matcher could report "clean" where the authoritative gate fails. Pre-tag coverage is `check-release.mjs --pending-version X.Y.Z [--fix]`, Step 4f.)
34
33
 
35
34
  ---
36
35
 
37
- ## §Category 2 Generated-file coherence (hard-fail any cut)
36
+ ## §Category 2, Generated-file coherence (hard-fail any cut)
38
37
 
39
38
  ### `node scripts/build/components.mjs --verify`
40
39
 
@@ -58,15 +57,15 @@ Row layout per gate: **What** · **Typical failure** · **Recovery**.
58
57
 
59
58
  ---
60
59
 
61
- ## §Category 3 Component / primitive structural drift
60
+ ## §Category 3, Component / primitive structural drift
62
61
 
63
62
  ### `npm run check:demo-shells`
64
63
 
65
64
  - **What:** every component demo `.html` imports all primitives named in its yaml `composes:` list.
66
65
  - **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.
66
+ - **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
67
 
69
- Smaller siblings in this category (same recovery shape fix the declaration or regenerate the registry):
68
+ Smaller siblings in this category (same recovery shape, fix the declaration or regenerate the registry):
70
69
 
71
70
  | Gate | What |
72
71
  | --- | --- |
@@ -79,7 +78,7 @@ Smaller siblings in this category (same recovery shape — fix the declaration o
79
78
 
80
79
  ---
81
80
 
82
- ## §Category 4 CSS spec compatibility
81
+ ## §Category 4, CSS spec compatibility
83
82
 
84
83
  ### `npm run check:lightningcss-build`
85
84
 
@@ -95,18 +94,18 @@ Also: `check:no-self-import-css` (no transitively self-importing barrel) · `che
95
94
 
96
95
  ---
97
96
 
98
- ## §Category 5 Browser safety / module hygiene
97
+ ## §Category 5, Browser safety / module hygiene
99
98
 
100
99
  ### `npm run check:browser-safe`
101
100
 
102
101
  - **What:** no top-level `import 'node:*'` in browser-reachable modules (`packages/gen-ui/a2ui/{compose,retrieval,validator}`, `web-components/`, `web-modules/`, `apps/*/app/*.contents.js`).
103
102
  - **Recovery:** dual-mode pattern (`IS_NODE` + dynamic `await import(/* @vite-ignore */ 'node:*')` + `import.meta.glob` browser branch); canonical impl: `packages/gen-ui/a2ui/retrieval/component-catalog.js`.
104
103
 
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).
104
+ 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
105
 
107
106
  ---
108
107
 
109
- ## §Category 6 Visual / structural integrity
108
+ ## §Category 6, Visual / structural integrity
110
109
 
111
110
  | Gate | What |
112
111
  | --- | --- |
@@ -116,11 +115,11 @@ Siblings: `check:absolute-imports` (no leading-`/` imports — rewrite relative)
116
115
  | `audit:native-primitive-leak` | native `<button>`/`<input>`/… where a `*-ui` equivalent exists; criticals must be replaced or annotated `data-native-ok="<reason>"` |
117
116
  | `audit:shell-composition` | admin-shell compositions missing canonical parts (statusbar, `[data-spacer]`/`[data-actions]`, …); escape hatch `data-shell-opt-out="<reason>"` |
118
117
 
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.
118
+ 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
119
 
121
120
  ---
122
121
 
123
- ## §Category 7 Corpus / bundle freshness
122
+ ## §Category 7, Corpus / bundle freshness
124
123
 
125
124
  ### `npm run verify:corpus`
126
125
 
@@ -129,8 +128,8 @@ The two `audit:*` probes are soft-fail pre-cut (exit-1 only on criticals); findi
129
128
 
130
129
  ### `npm run check:catalog-tiers`
131
130
 
132
- - **What:** `packages/gen-ui/a2ui/catalog/tier-index.json` derives cleanly from the committed catalog + the hand-authored `tiers/l*-*.json` sources (L0–L4 membership, composability law). It ships inside `@adia-ai/a2ui`, so a stale index is a publish defect. ADR-0069's gate split moved its PR-blocking freshness onto the `derived-resync` (push:main) job; the pre-cut roster re-asserts it because gate `check:chunks-fresh` cannot the harvester hashes `tier-index.json` as a harvest *source*, so a stale-but-harvested index keeps that gate green (gh#1494).
133
- - **Recovery:** `npm run build:catalog-tiers`; if that regen stales `check:chunks-fresh`, `npm run harvest:chunks` (the conditional pair Step 4d.5b runs post-bump a byte-identical tier regen owes no re-harvest). Stage `tier-index.json` + any corpus outputs.
131
+ - **What:** `packages/gen-ui/a2ui/catalog/tier-index.json` derives cleanly from the committed catalog + the hand-authored `tiers/l*-*.json` sources (L0–L4 membership, composability law). It ships inside `@adia-ai/a2ui`, so a stale index is a publish defect. ADR-0069's gate split moved its PR-blocking freshness onto the `derived-resync` (push:main) job; the pre-cut roster re-asserts it because gate `check:chunks-fresh` cannot, the harvester hashes `tier-index.json` as a harvest *source*, so a stale-but-harvested index keeps that gate green (gh#1494).
132
+ - **Recovery:** `npm run build:catalog-tiers`; if that regen stales `check:chunks-fresh`, `npm run harvest:chunks` (the conditional pair Step 4d.5b runs post-bump, a byte-identical tier regen owes no re-harvest). Stage `tier-index.json` + any corpus outputs.
134
133
 
135
134
  ### `npm run check:chunks-fresh`
136
135
 
@@ -141,13 +140,13 @@ The two `audit:*` probes are soft-fail pre-cut (exit-1 only on criticals); findi
141
140
 
142
141
  - **What:** `chunk-embeddings.json` at-or-newer-than `chunks/_index.json`.
143
142
  - **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]`.
144
- - **2026-08-12 isolated agent worktrees can't run this recovery step.** An agent dispatched with `isolation: worktree` (e.g. `build-lead` resolving a merge conflict) structurally can't read the dotenv secrets file a permission guard blocks copying it into the worktree, correctly, since that's a content-revealing operation on a secret file. Hit twice in one sweep: two separate PRs (#1113, #1117) each needed this recovery step mid-conflict-resolution and both had to hand off to a human running the command directly in their own terminal / via `!`. This step is a standing human-in-the-loop point, not something to keep dispatching an agent for.
143
+ - **2026-08-12, isolated agent worktrees can't run this recovery step.** An agent dispatched with `isolation: worktree` (e.g. `build-lead` resolving a merge conflict) structurally can't read the dotenv secrets file, a permission guard blocks copying it into the worktree, correctly, since that's a content-revealing operation on a secret file. Hit twice in one sweep: two separate PRs (#1113, #1117) each needed this recovery step mid-conflict-resolution and both had to hand off to a human running the command directly in their own terminal / via `!`. This step is a standing human-in-the-loop point, not something to keep dispatching an agent for.
145
144
 
146
145
  ### `npm run check:css-bundles-fresh` / `npm run check:js-bundles-fresh`
147
146
 
148
147
  - **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).
149
- - **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.
150
- - **Semantic content checks mechanized 2026-07-19** (formerly manual spot-checks; the v0.6.29–31 cycles shipped a shells-only `everything.min.js` that hard-crashed CDN consumers): `bundle-js.mjs` now enforces, on every build AND `--verify` run, that (1) `everything.js` still imports `@adia-ai/web-components`, (2) `everything.min.js` carries ≥100 distinct `-ui` tags, and (3) `icons-manifest.js` exists populated in BOTH dist trees. A fresh-but-semantically-wrong bundle fails the gate itself no separate manual step remains.
148
+ - **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.
149
+ - **Semantic content checks, mechanized 2026-07-19** (formerly manual spot-checks; the v0.6.29–31 cycles shipped a shells-only `everything.min.js` that hard-crashed CDN consumers): `bundle-js.mjs` now enforces, on every build AND `--verify` run, that (1) `everything.js` still imports `@adia-ai/web-components`, (2) `everything.min.js` carries ≥100 distinct `-ui` tags, and (3) `icons-manifest.js` exists populated in BOTH dist trees. A fresh-but-semantically-wrong bundle fails the gate itself, no separate manual step remains.
151
150
 
152
151
  ### `npm run audit:chunk-reconcile`
153
152
 
@@ -155,16 +154,16 @@ The two `audit:*` probes are soft-fail pre-cut (exit-1 only on criticals); findi
155
154
 
156
155
  ---
157
156
 
158
- ## §Category 8 Tests + types + evals
157
+ ## §Category 8, Tests + types + evals
159
158
 
160
159
  ### `npm run test:unit`
161
160
 
162
161
  - **What:** the vitest suite (~1000+ tests).
163
- - **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.
164
- - **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. Sequential is the source of truth, and **the roster gate now runs it directly** (`npm run test:unit:serial` = `vitest run --no-file-parallelism`, gate 4 since 2026-07-19) a parallel `test:unit` flake outside the roster still isn't a blocker, and don't raise the drain guard.
165
- - **Same-host contention timeout (gh#2195):** gate 4 running solo (Phase 1, see the execution-model note above) isolates it from every OTHER pre-flight gate, but not from unrelated concurrent load on the same shared, multi-tenant host another agent's build, a peer's own `npm run check`. gh#2195's diagnosis found this surfaces as a genuine 45s per-test timeout on a DIFFERENT single file each run, with no repeat culprit (the contention signature, not an order-dependent leak) and found no separate "release pre-flight runner" with its own core count exists to recalibrate `worker-cap.mjs` against; it's the same operator/agent host either way. `release-pack.mjs`'s `runSoloGateWithRetry()` now retries gate 4 exactly once, scoped to only the file(s) it named as failed, when the failure output has a parseable `FAIL <file>` list a file that fails once and passes clean on that immediate re-run was contention, not a regression; a file that fails twice is treated as a real one and the pre-flight still aborts. No other gate, and no OTHER invocation of `test:unit:serial` (CI, local dev, `npm run check`), gets this retry.
166
- - **Exit 143 (SIGTERM):** the vitest process was KILLED (resource pressure / a stray terminator), not a test failure re-run the gate directly (`npx vitest run --no-file-parallelism`) before diagnosing anything; a clean re-run means transient, proceed (v0.8.34 handoff hit this).
167
- - **First-time-at-cut failures are REAL (v0.8.34):** this serial suite runs tests PR CI never does `exit-gate.corpus` (dialect-catalog conformance over real harvested chunks) surfaces yaml-schema drift (e.g. an array prop missing `items.type`, the command/combobox `DynamicStringList` mis-map) only HERE, potentially weeks after the yaml edit merged green. Treat such a failure as a genuine latent defect to root-cause at the yaml SoT, never as release-blocking noise. (Structural fix promoting the corpus batch into PR CI tracked as a follow-up.)
162
+ - **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.
163
+ - **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. Sequential is the source of truth, and **the roster gate now runs it directly** (`npm run test:unit:serial` = `vitest run --no-file-parallelism`, gate 4 since 2026-07-19), a parallel `test:unit` flake outside the roster still isn't a blocker, and don't raise the drain guard.
164
+ - **Same-host contention timeout (gh#2195):** gate 4 running solo (Phase 1, see the execution-model note above) isolates it from every OTHER pre-flight gate, but not from unrelated concurrent load on the same shared, multi-tenant host, another agent's build, a peer's own `npm run check`. gh#2195's diagnosis found this surfaces as a genuine 45s per-test timeout on a DIFFERENT single file each run, with no repeat culprit (the contention signature, not an order-dependent leak), and found no separate "release pre-flight runner" with its own core count exists to recalibrate `worker-cap.mjs` against; it's the same operator/agent host either way. `release-pack.mjs`'s `runSoloGateWithRetry()` now retries gate 4 exactly once, scoped to only the file(s) it named as failed, when the failure output has a parseable `FAIL <file>` list, a file that fails once and passes clean on that immediate re-run was contention, not a regression; a file that fails twice is treated as a real one and the pre-flight still aborts. No other gate, and no OTHER invocation of `test:unit:serial` (CI, local dev, `npm run check`), gets this retry.
165
+ - **Exit 143 (SIGTERM):** the vitest process was KILLED (resource pressure / a stray terminator), not a test failure, re-run the gate directly (`npx vitest run --no-file-parallelism`) before diagnosing anything; a clean re-run means transient, proceed (v0.8.34 handoff hit this).
166
+ - **First-time-at-cut failures are REAL (v0.8.34):** this serial suite runs tests PR CI never does, `exit-gate.corpus` (dialect-catalog conformance over real harvested chunks) surfaces yaml-schema drift (e.g. an array prop missing `items.type`, the command/combobox `DynamicStringList` mis-map) only HERE, potentially weeks after the yaml edit merged green. Treat such a failure as a genuine latent defect to root-cause at the yaml SoT, never as release-blocking noise. (Structural fix, promoting the corpus batch into PR CI, tracked as a follow-up.)
168
167
 
169
168
  ### `npm run eval:diff -- --engine zettel`
170
169
 
@@ -173,36 +172,36 @@ The two `audit:*` probes are soft-fail pre-cut (exit-1 only on criticals); findi
173
172
  - **Free-form**: cov ≥ 90%, avg ≥ 83, F1 ≥ 55
174
173
  - **Monolithic**: cov = 100%, avg ≥ 95
175
174
  - **Dogfood**: 20/20, avg ≥ 95
176
- - **Recovery:** retrieval/corpus regression routes to the A2UI-pipeline skill.
175
+ - **Recovery:** retrieval/corpus regression, routes to the A2UI-pipeline skill.
177
176
 
178
177
  Siblings: `typecheck` (`tsc --noEmit`) · `smoke:engines` (gen-UI engines + retrieval probes) · `smoke:register-engine` (11/11) · `test:a2ui` (22/22, +1 skipped OK).
179
178
 
180
179
  ---
181
180
 
182
- ## §Category 9 Misc release safety
181
+ ## §Category 9, Misc release safety
183
182
 
184
183
  ### `node scripts/release/check-cut-hygiene.mjs --version X.Y.Z`
185
184
 
186
- - **What:** roster gate 18 (wired 2026-07-19; release-pack fills `--version` the roster's one `versionArg` entry). The objective half of the v0.7.13-retro hygiene checker: published README CDN pins / "Current version" claims must not sit below the cut's minor (`doc-currency`, error-level); merged release branches + extra worktrees print as `limbo` warns (advisory without `--strict`). The judgment half of §4e content *currency* of what the READMEs say stays yours.
185
+ - **What:** roster gate 18 (wired 2026-07-19; release-pack fills `--version`, the roster's one `versionArg` entry). The objective half of the v0.7.13-retro hygiene checker: published README CDN pins / "Current version" claims must not sit below the cut's minor (`doc-currency`, error-level); merged release branches + extra worktrees print as `limbo` warns (advisory without `--strict`). The judgment half of §4e, content *currency* of what the READMEs say, stays yours.
187
186
  - **Recovery:** update the stale README pin/claim, stage it into the release commit. A `limbo` warn routes to branch/worktree cleanup, never blocks the cut.
188
187
 
189
188
  ### `npm run dogfood:status`
190
189
 
191
190
  - **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.
192
191
  - **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.
193
- - **Layout-aware since gh#1359.** Two of the aggregated audits (`empty-instantiation`, `padded-route-gutter`) render against a throwaway vite dev server and need the pnpm/bootstrapped layout to trust rendered icons (gh#340). Under an npm-shaped `node_modules` (or the explicit `--static-only` flag) the run auto-degrades skips those two legs, prints a loud non-fatal notice, and still runs every other (static, layout-agnostic) audit. A green static-only result is **not** full coverage: run `node scripts/dev/bootstrap-worktree.mjs && npm run dogfood:status` once under the pnpm layout too before a cut ships. Only a missing `node_modules` entirely still hard-exits.
192
+ - **Layout-aware since gh#1359.** Two of the aggregated audits (`empty-instantiation`, `padded-route-gutter`) render against a throwaway vite dev server and need the pnpm/bootstrapped layout to trust rendered icons (gh#340). Under an npm-shaped `node_modules` (or the explicit `--static-only` flag) the run auto-degrades, skips those two legs, prints a loud non-fatal notice, and still runs every other (static, layout-agnostic) audit. A green static-only result is **not** full coverage: run `node scripts/dev/bootstrap-worktree.mjs && npm run dogfood:status` once under the pnpm layout too before a cut ships. Only a missing `node_modules` entirely still hard-exits.
194
193
 
195
194
  ### `npm run verify:pack`
196
195
 
197
- - **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.
196
+ - **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.
198
197
 
199
- 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).
198
+ 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).
200
199
 
201
200
  ---
202
201
 
203
202
  ## §Standard subsets
204
203
 
205
- **Minimum 6 (verify-only default)** fastest set that catches release-blockers:
204
+ **Minimum 6 (verify-only default)**, fastest set that catches release-blockers:
206
205
 
207
206
  ```bash
208
207
  node scripts/build/components.mjs --verify
@@ -215,9 +214,9 @@ npm run check:demo-shells
215
214
 
216
215
  Add `verify:corpus` + `check:embeddings-fresh` if chunks were touched; `check:lightningcss-build` if CSS was touched; F-N1 if unpushed release tags exist.
217
216
 
218
- **Full pre-cut sweep** the 30-gate roster in [`cut-procedure.md`](cut-procedure.md) §Step 3, sourced from `` `<plugin-root>/skills/package-release/scripts/gate-roster.mjs` `` (the ONE list; `release-pack.mjs` imports and runs it in full a subset run is impossible without editing that file). ~90s wall time.
217
+ **Full pre-cut sweep**, the 30-gate roster in [`cut-procedure.md`](cut-procedure.md) §Step 3, sourced from `` `<plugin-root>/skills/package-release/scripts/gate-roster.mjs` `` (the ONE list; `release-pack.mjs` imports and runs it in full, a subset run is impossible without editing that file). ~90s wall time.
219
218
 
220
- **Omnibus** `npm run check` invokes everything. Heavy; use when re-baselining a stale checkout.
219
+ **Omnibus**, `npm run check` invokes everything. Heavy; use when re-baselining a stale checkout.
221
220
 
222
221
  **Suffix variants:** most gates have `:strict` (warns fail), `:fix` (auto-apply, e.g. `check:lockstep:fix`), `:json` / `:quiet` (output form) variants.
223
222
 
@@ -226,5 +225,5 @@ Add `verify:corpus` + `check:embeddings-fresh` if chunks were touched; `check:li
226
225
  ## §Gate stewardship
227
226
 
228
227
  - **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.
229
- - **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.
230
- - **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.
228
+ - **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.
229
+ - **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.
@@ -1,9 +1,8 @@
1
- # `independent-package-release.md` class-B cut (independently-versioned package)
1
+ # `independent-package-release.md`, class-B cut (independently-versioned package)
2
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.
3
+ > Load when releasing a package versioned **independently** of the lockstep set, > excluded from the lockstep gate, no umbrella tag, no demo-site deploy.
5
4
  > **Class B's current member is `@adia-ai/adia-plugins`** (gh#1133/gh#1160,
6
- > ADR-0045) the npm-sourced marketplace manifest package, marked
5
+ > ADR-0045), the npm-sourced marketplace manifest package, marked
7
6
  > `lockstep: false` on the roster (`scripts/package-paths.mjs`). It's the
8
7
  > first member since the 2026-07-15 policy change (operator ruling) that
9
8
  > emptied the class: the Claude Code plugins under `packages/plugins/*`
@@ -16,18 +15,18 @@
16
15
 
17
16
  ## §Two release classes in one monorepo
18
17
 
19
- | | Class A lockstep cut | Class B independent package |
18
+ | | Class A, lockstep cut | Class B, independent package |
20
19
  | --- | --- | --- |
21
20
  | Versioning | whole set bumps together | own version line per package |
22
- | Lockstep gate | enforced (`check:lockstep` 10/10) | **excluded** a class-B package is not listed in `check-lockstep.mjs`'s `PACKAGES` (`adia-plugins`, the current member, is filtered out via `lockstep: false` `scripts/package-paths.mjs`) |
23
- | Umbrella tag | `vX.Y.Z` + per-package | **none** per-package tags only (versions differ) |
21
+ | Lockstep gate | enforced (`check:lockstep` 10/10) | **excluded**, a class-B package is not listed in `check-lockstep.mjs`'s `PACKAGES` (`adia-plugins`, the current member, is filtered out via `lockstep: false`, `scripts/package-paths.mjs`) |
22
+ | Umbrella tag | `vX.Y.Z` + per-package | **none**, per-package tags only (versions differ) |
24
23
  | `dist-tag` ordering | cross-package publish order matters | N/A |
25
24
  | Demo-site deploy | yes | **none** |
26
25
  | Publish trigger | tag-triggered per-package workflow | same mechanism (`.github/workflows/publish-adia-ui-{factory,forge}.yml`) |
27
26
 
28
27
  Class B keeps the single-authorization model and the verify-against-the-registry discipline; it drops every lockstep-specific invariant.
29
28
 
30
- ## §New-package onboarding the three trip-wires a FIRST cut hits
29
+ ## §New-package onboarding, the three trip-wires a FIRST cut hits
31
30
 
32
31
  Substrate fixes (release scripts / lockfile / CHANGELOG), landed once as a normal PR on `main` *before* tagging:
33
32
 
@@ -37,20 +36,20 @@ Substrate fixes (release scripts / lockfile / CHANGELOG), landed once as a norma
37
36
 
38
37
  ## §Procedure
39
38
 
40
- 1. **Re-baseline** `git fetch`; confirm the checkout isn't on a peer's branch.
39
+ 1. **Re-baseline**, `git fetch`; confirm the checkout isn't on a peer's branch.
41
40
  2. **Land the package(s) on `main`** via PR; resolve every review thread before an admin-merge (this repo's merge gate).
42
- 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.
43
- 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`.
41
+ 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.
42
+ 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`.
44
43
  5. **Push the tags** → the per-package workflows run `npm ci → verify:plugins → npm publish --access public`.
45
44
  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.
46
- 7. **Marketplace cut-over** per ADR-0045 the distribution channel is the npm-sourced manifest package `@adia-ai/adia-plugins` (no public git marketplace repo that shape was considered and rejected). Bump/publish the manifest package so its `marketplace.json` entries reference the new plugin versions; consumers add the marketplace from npm, never from a git repo.
45
+ 7. **Marketplace cut-over**, per ADR-0045 the distribution channel is the npm-sourced manifest package `@adia-ai/adia-plugins` (no public git marketplace repo: that shape was considered and rejected). Bump/publish the manifest package so its `marketplace.json` entries reference the new plugin versions; consumers add the marketplace from npm, never from a git repo.
47
46
 
48
47
  ## §Verify target
49
48
 
50
- The published package(s) on the **npm registry** at their independent versions, plus the npm-published `@adia-ai/adia-plugins` manifest referencing the new versions (ADR-0045). NOT "all 10 lockstep packages + the demo site" that's class A.
49
+ The published package(s) on the **npm registry** at their independent versions, plus the npm-published `@adia-ai/adia-plugins` manifest referencing the new versions (ADR-0045). NOT "all 10 lockstep packages + the demo site", that's class A.
51
50
 
52
51
  ## §Gotchas (from the first independent cut, factory v0.2.2 + forge v0.1.2)
53
52
 
54
53
  - Never add the package to the lockstep gate or tag it with the umbrella.
55
- - Publish-workflow YAMLs are token-bearing keep `persist-credentials: false` on the checkout step, matching the established workflows' action-pinning.
56
- - 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.
54
+ - Publish-workflow YAMLs are token-bearing, keep `persist-credentials: false` on the checkout step, matching the established workflows' action-pinning.
55
+ - 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.
@@ -1,4 +1,4 @@
1
- # Invariants detail and history
1
+ # Invariants, detail and history
2
2
 
3
3
  SKILL.md's own "Invariants" section states each rule; this expands the
4
4
  history and mechanics behind the denser ones.
@@ -6,39 +6,39 @@ history and mechanics behind the denser ones.
6
6
  ## 1. Lockstep coherence
7
7
 
8
8
  Every roster package bumps together (`check:lockstep`). **The roster is
9
- `scripts/package-paths.mjs`'s `PACKAGE_ROSTER` read it, never a copy.**
9
+ `scripts/package-paths.mjs`'s `PACKAGE_ROSTER`, read it, never a copy.**
10
10
  This line used to enumerate the names inline and went stale the first time
11
11
  the roster moved (ADR-0048 P4 added a package while the list still read the
12
12
  pre-split six); a name list has no gate behind it, so it can only decay.
13
13
  Each plugin's `.claude-plugin/plugin.json` version moves with its
14
- package.json `bump.mjs` handles both; `verify:plugins` gates the sync.
14
+ package.json, `bump.mjs` handles both; `verify:plugins` gates the sync.
15
15
 
16
16
  ## 2. PATCH-cut asymmetry
17
17
 
18
18
  Internal `@adia-ai/*` ranges hold at `^X.Y.0` during PATCH cuts; only MINOR
19
- bumps the floor. `^0.0.x` is forbidden (pre-1.0 caret locks exact shipped
19
+ bumps the floor. `^0.0.x` is forbidden (pre-1.0 caret locks exact, shipped
20
20
  a real stale-sibling bug).
21
21
 
22
22
  ## 3. Release commits land via PR, never a direct push to `main`
23
23
 
24
24
  (Repo policy, operator ruling 2026-07-12.) Commit on `release/vX.Y.Z` → PR →
25
- CI → merge THEN tag at `main`'s post-merge HEAD, not at the bump commit;
25
+ CI → merge, THEN tag at `main`'s post-merge HEAD, not at the bump commit;
26
26
  post-bump fixes merge before tagging and belong in the tarball. Exception:
27
27
  batch push tags each version at its own release-merge SHA.
28
28
 
29
29
  ## 4. One umbrella + one per-package tag per cut
30
30
 
31
31
  One per lockstep-roster package (`scripts/package-paths.mjs`); publish
32
- workflows key off the per-package tags. Push tags **one per `git push`** a
32
+ workflows key off the per-package tags. Push tags **one per `git push`**, a
33
33
  batched multi-tag push drops the trigger event.
34
34
 
35
35
  ## 5. F-N1 per-package clean
36
36
 
37
- `check:release --all-pending` the umbrella-tag mismatch error is expected
37
+ `check:release --all-pending`: the umbrella-tag mismatch error is expected
38
38
  noise. Coverage is mechanized at cut time: Step 4f
39
39
  (`check-release.mjs --pending-version X.Y.Z --fix`) runs the SAME matcher
40
40
  pre-PR and auto-appends verified Maintenance bullets, so a post-tag warn
41
- means something novel stop and investigate, don't loop enrichment PRs.
41
+ means something novel, stop and investigate, don't loop enrichment PRs.
42
42
 
43
43
  ## 6. `npm dist-tag latest` is set by publish order
44
44
 
@@ -54,7 +54,7 @@ including visible behavior changes, stays PATCH.
54
54
  Bump the pin in `packages/plugins/adia-ui-factory/.mcp.json` in the same cut
55
55
  (the consumer never floats; with the plugins in-lockstep this lands in the
56
56
  release commit itself, not a follow-up). The pinned NAME is `@adia-ai/mcp`
57
- with the `gen-ui` subcommand (`npx -y @adia-ai/mcp@<exact> gen-ui`) the
57
+ with the `gen-ui` subcommand (`npx -y @adia-ai/mcp@<exact> gen-ui`), the
58
58
  single live name since the ADR-0048 P7 cut (v0.8.37) per the gh#1240
59
59
  one-package amendment; `@adia-ai/a2ui-mcp` is retired and the P2-planned
60
60
  `@adia-ai/gen-ui-mcp` never published. `check:lockstep`'s mcp-pin guard and
@@ -1,40 +1,39 @@
1
- # Mechanization bundled `scripts/`, stdlib Node, all support `--dry`
1
+ # Mechanization, bundled `scripts/`, stdlib Node, all support `--dry`
2
2
 
3
- `release-pack.mjs` walks the cycle in two phases per invariant 3 `--mode
4
- cut` / `--mode from-scratch` promote `[Unreleased]` (BOTH modes now a
3
+ `release-pack.mjs` walks the cycle in two phases per invariant 3, `--mode
4
+ cut` / `--mode from-scratch` promote `[Unreleased]` (BOTH modes now, a
5
5
  peer's hand-authored section must be promoted whichever mode cut it, and a
6
6
  loud guard blocks the bump if any roster package still carries non-empty
7
7
  `[Unreleased]` content after promotion), run Step 4f (pre-tag coverage
8
8
  `--fix` with the authoritative F-N1 matcher), and stop at the release commit
9
9
  (PR → merge); `--mode handoff` tags/publishes/deploys from post-merge main.
10
- **`--go` is the standard invocation for an operator-initiated release** the
10
+ **`--go` is the standard invocation for an operator-initiated release**, the
11
11
  single authorization covers the cycle; evidence blocks print as a log;
12
12
  granular `--yes`/`--push`/`--publish` remain for cautious manual runs
13
13
  (`--push` still refuses to auto-fire past any F-N1 finding). `--mode batch`
14
- is not implemented it hard-rejects with a pointer to
14
+ is not implemented, it hard-rejects with a pointer to
15
15
  [recovery-paths.md](recovery-paths.md) §Scenario 2 rather than silently
16
16
  misbehaving; a real batch tags each version at its own release-merge SHA,
17
17
  which this single-version orchestrator has no model for. Pre-flight (Step 3)
18
18
  runs the full 30-gate roster from the single shared list in
19
- `scripts/gate-roster.mjs` the same list [cut-procedure.md](cut-procedure.md)
19
+ `scripts/gate-roster.mjs`, the same list [cut-procedure.md](cut-procedure.md)
20
20
  §3.1 transcribes, so a subset run requires editing that one file, not two.
21
21
 
22
22
  The pieces are callable alone: `bump.mjs` (version fields + the factory
23
23
  `.mcp.json` `@adia-ai/mcp` pin, invariant 8), `promote-unreleased.mjs` /
24
24
  `insert-stub.mjs` (CHANGELOG blocks), `tag-lockstep.mjs` (umbrella + one tag
25
- per lockstep roster package the set is derived from `PACKAGE_ROSTER`,
25
+ per lockstep roster package: the set is derived from `PACKAGE_ROSTER`,
26
26
  never a number written here: it went stale at 14 while the roster said 17,
27
27
  17 went stale in turn when gh#1240 folded two planned MCP rows into one
28
28
  (now 16), and 16 goes stale again the day the ADR-0048 shims retire; run
29
29
  `--dry` to see the live list, `--delete` to move), `dispatch-publish.mjs`
30
- (publish workflows; `--verify-triggered` re-dispatches missing AND dead
31
- cancelled/failed/timed-out — runs, each gated behind an npm-registry check
30
+ (publish workflows; `--verify-triggered` re-dispatches missing AND dead, cancelled/failed/timed-out, runs, each gated behind an npm-registry check
32
31
  so an already-published version is never re-dispatched (gh#763); `--after`
33
- enforces batch ordering dispatch output states what WAS done, never a
32
+ enforces batch ordering, dispatch output states what WAS done, never a
34
33
  to-do phrased as if it hadn't fired), and `pr-bridge.mjs` (the two-phase
35
34
  bridge: pushes the release branch, opens the PR, waits out CI, and merges
36
35
  ONLY on all-non-fail-soft-checks-green + zero unresolved threads + no
37
- changes-requested; any other state stops with evidence §5.7 mechanized,
36
+ changes-requested; any other state stops with evidence, §5.7 mechanized,
38
37
  `--dry` to preview the decision). All fail fast outside a monorepo root
39
38
  (`assert-monorepo-root.mjs`); fork-configurable via `--host` / `--scope`.
40
39
  All 6 CLI scripts (plus `scripts/release/check-release.mjs`) have a
@@ -46,7 +45,7 @@ exercised through the CLIs' selftests, not their own.
46
45
 
47
46
  Site deploy (Step 10 of the handoff) dispatches `deploy-site.yml` (its own
48
47
  pre-flight verify → snapshot → hardened rsync → post-deploy verify →
49
- auto-rollback), never a raw local `rsync` H1 (forge-campaign gh#268
48
+ auto-rollback), never a raw local `rsync`, H1 (forge-campaign gh#268
50
49
  audit): the script had drifted into bypassing that pipeline even though this
51
50
  doc already taught the workflow-dispatch path. The dispatch rides the
52
51
  cycle's single authorization (`--go`, or `--publish` on a manual run); the
@@ -1,35 +1,35 @@
1
- # `migration-guide-authoring.md` authoring the MIGRATION GUIDE on a breaking cut
1
+ # `migration-guide-authoring.md`, authoring the MIGRATION GUIDE on a breaking cut
2
2
 
3
3
  > Load whenever the cut is **MINOR** (an API-surface break) or on an explicit
4
4
  > "author the migration guide" ask. This is the **producer** side of migrations:
5
5
  > the release ships the breaking change, so the release authors the guide section
6
6
  > consumers follow. The shared producer/consumer format contract is
7
7
  > [`../../../references/contracts/migration-guide-format.md`](../../../references/contracts/migration-guide-format.md)
8
- > the factory's `app-migration` skill consumes exactly that shape.
8
+ >, the factory's `app-migration` skill consumes exactly that shape.
9
9
  >
10
10
  > Scope split: **producer (this skill)** authors the guide section + migrates the
11
11
  > framework's own in-repo surfaces. **Consumer** (a downstream app sweep) is the
12
- > factory plugin's `app-migration` decline and redirect. Designing the breaking
12
+ > factory plugin's `app-migration`, decline and redirect. Designing the breaking
13
13
  > change itself is a contract decision upstream of both.
14
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).
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
16
 
17
17
  ## §When a section is owed
18
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.
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
20
 
21
21
  ## §The authoring workflow
22
22
 
23
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
24
 
25
- **2. Write the section** one `###` subsection per item:
25
+ **2. Write the section**, one `###` subsection per item:
26
26
 
27
27
  ```markdown
28
28
  ## Migrating to @adia-ai/web-components@X.Y.Z (YYYY-MM-DD)
29
29
 
30
30
  <one-line scope: N breaking items, the headline.>
31
31
 
32
- ### <item bold headline> (`old` → `new`)
32
+ ### <item, bold headline> (`old` → `new`)
33
33
 
34
34
  <one sentence: what changed and why.>
35
35
 
@@ -44,21 +44,21 @@ done
44
44
 
45
45
  Shape rules:
46
46
 
47
- - **Audit grep first, sweep second** the consumer always lists call sites before sweeping; author both.
48
- - **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).
49
- - **One component per sweep regex** alternation captures (`<(toast|alert)-ui`) don't preserve the matched alternative cleanly.
50
- - **HTML-attribute regexes only match HTML/JSX** author a separate JS-side regex when the symbol has a programmatic form (`el.variant = 'danger'`).
47
+ - **Audit grep first, sweep second**, the consumer always lists call sites before sweeping; author both.
48
+ - **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).
49
+ - **One component per sweep regex**, alternation captures (`<(toast|alert)-ui`) don't preserve the matched alternative cleanly.
50
+ - **HTML-attribute regexes only match HTML/JSX**, author a separate JS-side regex when the symbol has a programmatic form (`el.variant = 'danger'`).
51
51
  - **`git grep -lz | while read -d '' f; do perl -i … "$f"; done`, never `| xargs perl -i`.**
52
52
  The `xargs` form hangs on zero matches (GNU xargs still runs perl once with no file argument,
53
53
  and `perl -i -pe` then blocks reading stdin instead of no-op'ing) and, if `<old>`/`<new>` are
54
54
  passed as shell variables rather than literals, an `@`-bearing replacement (`@adia-ai/...`)
55
55
  parses as perl array interpolation when inlined into `-pe` and silently substitutes empty
56
- (gh#1233) pass such strings through the environment instead of the perl source, per
56
+ (gh#1233), pass such strings through the environment instead of the perl source, per
57
57
  `.claude/docs/MIGRATION GUIDE.md`'s `§0.8.37` `sweep()` helper.
58
58
 
59
- **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.
59
+ **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.
60
60
 
61
- **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:
61
+ **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:
62
62
 
63
63
  ```bash
64
64
  LEGACY_PATTERNS=( '<old-tag' 'old-attr=' '--old-token' )
@@ -69,15 +69,15 @@ for pat in "${LEGACY_PATTERNS[@]}"; do
69
69
  done # 0 hits = sweep verified clean
70
70
  ```
71
71
 
72
- **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).
72
+ **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).
73
73
 
74
74
  ## §Manual-review classes (never auto-sweep)
75
75
 
76
- - **Semantic flips** a rename that inverts default behavior (`[open]` default-hidden → `[collapsed]` default-visible): the right migration depends on author intent. List occurrences, ask.
77
- - **Opt-out Booleans defaulting true** the migration only matters where a consumer explicitly disabled the affordance; sed can't tell.
78
- - **Ownership moves** a prop moving from wrapper to slotted child; the target child may not exist yet.
79
- - **kebab-string property keys** attribute name unchanged, only the JS programmatic form changed; audit programmatic access only.
80
- - **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.
76
+ - **Semantic flips**, a rename that inverts default behavior (`[open]` default-hidden → `[collapsed]` default-visible): the right migration depends on author intent. List occurrences, ask.
77
+ - **Opt-out Booleans defaulting true**, the migration only matters where a consumer explicitly disabled the affordance; sed can't tell.
78
+ - **Ownership moves**, a prop moving from wrapper to slotted child; the target child may not exist yet.
79
+ - **kebab-string property keys**, attribute name unchanged, only the JS programmatic form changed; audit programmatic access only.
80
+ - **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.
81
81
 
82
82
  ## §The version-coverage table
83
83