@adia-ai/adia-ui-forge 0.8.62 → 0.8.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +2 -2
- package/.codex-plugin/plugin.json +3 -3
- package/CHANGELOG.md +317 -275
- package/README.md +54 -18
- package/__init__.py +8 -8
- package/agents/a2ui-maintenance-agent.corpus.json +7 -7
- package/agents/a2ui-maintenance-agent.md +6 -6
- package/agents/a2ui-planner-agent.md +11 -11
- package/agents/demo-audit-agent.corpus.json +4 -4
- package/agents/demo-audit-agent.md +8 -9
- package/agents/framework-checker.md +10 -11
- package/agents/framework-planner-agent.md +9 -10
- package/agents/gen-ui-review-agent.corpus.json +4 -4
- package/agents/gen-ui-review-agent.md +8 -8
- package/agents/package-release-agent.corpus.json +4 -4
- package/agents/package-release-agent.md +9 -10
- package/agents/primitive-authoring-agent.corpus.json +1 -1
- package/agents/primitive-authoring-agent.md +5 -5
- package/agents/routing-corpus.json +46 -46
- package/codex.interface.json +1 -1
- package/commands/gen-ui-review.md +1 -1
- package/commands/package-release.md +2 -2
- package/package.json +1 -1
- package/plugin.yaml +2 -2
- package/prompts/gen-ui-review.md +1 -1
- package/prompts/package-release.md +2 -2
- package/references/contracts/a2ui-mcp-surface.md +7 -7
- package/references/contracts/migration-guide-format.md +6 -7
- package/references/shared/content-trust.md +3 -5
- package/skills/a2ui-maintenance/SKILL.md +13 -16
- package/skills/a2ui-maintenance/evals/evals.json +2 -2
- package/skills/a2ui-maintenance/evals/routing-corpus.json +1 -1
- package/skills/a2ui-maintenance/references/anti-patterns.md +10 -10
- package/skills/a2ui-maintenance/references/chunk-authoring.md +11 -12
- package/skills/a2ui-maintenance/references/corpus-discipline.md +13 -14
- package/skills/a2ui-maintenance/references/data-model-reactivity.md +22 -25
- package/skills/a2ui-maintenance/references/eval-diagnostics.md +21 -21
- package/skills/a2ui-maintenance/references/format-extension-decisions.md +12 -13
- package/skills/a2ui-maintenance/references/leverage-rules.md +6 -6
- package/skills/a2ui-maintenance/references/mcp-pipeline-ops.md +9 -10
- package/skills/a2ui-maintenance/references/mcp-tool-reference.md +11 -12
- package/skills/a2ui-maintenance/references/pipeline-overview.md +33 -38
- package/skills/a2ui-maintenance/references/semantic-fail-lifting.md +13 -14
- package/skills/a2ui-maintenance/references/strategy-engines.md +14 -16
- package/skills/a2ui-maintenance/references/surface-lifecycle.md +10 -11
- package/skills/a2ui-maintenance/references/zettel-calibration.md +14 -16
- package/skills/component-md-authoring/SKILL.md +22 -22
- package/skills/component-md-authoring/agents/openai.yaml +1 -1
- package/skills/cross-harness-authoring-standards/SKILL.md +19 -21
- package/skills/cross-harness-authoring-standards/agents/openai.yaml +1 -1
- package/skills/cross-harness-compatibility-standards/SKILL.md +35 -34
- package/skills/cross-harness-compatibility-standards/agents/openai.yaml +1 -1
- package/skills/demo-audit/SKILL.md +38 -38
- package/skills/demo-audit/evals/routing-corpus.json +1 -1
- package/skills/demo-audit/references/admin-shell-anatomy.md +21 -25
- package/skills/demo-audit/references/app-shell-pitfalls.md +11 -13
- package/skills/demo-audit/references/auto-fix-allowlist.md +3 -3
- package/skills/demo-audit/references/card-anatomy-sweep.md +10 -11
- package/skills/demo-audit/references/chat-shell-anatomy.md +25 -26
- package/skills/demo-audit/references/editor-shell-anatomy.md +25 -28
- package/skills/demo-audit/references/html-attr-sweep.md +12 -13
- package/skills/demo-audit/references/mode7-status-battery.md +4 -4
- package/skills/demo-audit/references/native-leak-annotations.md +8 -8
- package/skills/demo-audit/references/output-contract-worked-example.md +8 -8
- package/skills/demo-audit/references/probe-discipline-and-escalation.md +2 -2
- package/skills/demo-audit/references/visual-probe-triage.md +21 -23
- package/skills/gen-ui-review/SKILL.md +28 -28
- package/skills/gen-ui-review/agents/openai.yaml +1 -1
- package/skills/gen-ui-review/evals/evals.json +1 -1
- package/skills/gen-ui-review/evals/routing-corpus.json +1 -1
- package/skills/gen-ui-review/references/corpus-html-patterns.md +28 -29
- package/skills/gen-ui-review/references/exit-gate-mechanics.md +5 -5
- package/skills/gen-ui-review/references/lookup-maintenance.md +2 -2
- package/skills/gen-ui-review/references/loop-protocol.md +25 -25
- package/skills/gen-ui-review/references/rubric-cosmetic.md +10 -10
- package/skills/gen-ui-review/references/rubric-decompose.md +15 -16
- package/skills/gen-ui-review/references/rubric-score.md +23 -24
- package/skills/gen-ui-review/references/scorecard-worked-examples.md +12 -12
- package/skills/gen-ui-review/references/scores.schema.json +2 -2
- package/skills/llm-client-maintenance/SKILL.md +12 -12
- package/skills/llm-client-maintenance/evals/routing-corpus.json +1 -1
- package/skills/llm-client-maintenance/references/adapter-contract.md +27 -27
- package/skills/llm-client-maintenance/references/add-a-provider.md +25 -25
- package/skills/llm-client-maintenance/references/bridge-facade.md +31 -31
- package/skills/llm-client-maintenance/references/browser-proxy-boundary.md +17 -17
- package/skills/llm-client-maintenance/references/model-registry.md +14 -14
- package/skills/llm-client-maintenance/references/streaming-sse.md +21 -21
- package/skills/package-release/SKILL.md +21 -23
- package/skills/package-release/evals/evals.json +2 -2
- package/skills/package-release/evals/routing-corpus.json +2 -2
- package/skills/package-release/references/authorization-model.md +6 -8
- package/skills/package-release/references/changelog-discipline.md +25 -27
- package/skills/package-release/references/cut-procedure.md +129 -136
- package/skills/package-release/references/gates-catalog.md +42 -43
- package/skills/package-release/references/independent-package-release.md +14 -15
- package/skills/package-release/references/invariants-detail.md +9 -9
- package/skills/package-release/references/mechanization.md +11 -12
- package/skills/package-release/references/migration-guide-authoring.md +20 -20
- package/skills/package-release/references/notes-authoring.md +20 -20
- package/skills/package-release/references/recovery-paths.md +28 -28
- package/skills/primitive-authoring/SKILL.md +19 -19
- package/skills/primitive-authoring/agents/openai.yaml +1 -1
- package/skills/primitive-authoring/evals/evals.json +2 -2
- package/skills/primitive-authoring/evals/routing-corpus.json +2 -2
- package/skills/primitive-authoring/references/INDEX.md +22 -22
- package/skills/primitive-authoring/references/anti-patterns.md +76 -77
- package/skills/primitive-authoring/references/api-contract.md +63 -65
- package/skills/primitive-authoring/references/authoring-cycle.md +47 -50
- package/skills/primitive-authoring/references/canonical-pattern-index.md +118 -118
- package/skills/primitive-authoring/references/code-style.md +50 -52
- package/skills/primitive-authoring/references/common-gotchas.md +23 -23
- package/skills/primitive-authoring/references/composite-demo-protocol.md +42 -45
- package/skills/primitive-authoring/references/css-patterns.md +97 -97
- package/skills/primitive-authoring/references/for-attribute-event-contract.md +12 -12
- package/skills/primitive-authoring/references/form-control-sizing.md +16 -18
- package/skills/primitive-authoring/references/lifecycle-patterns.md +42 -42
- package/skills/primitive-authoring/references/llm-bridge.md +21 -21
- package/skills/primitive-authoring/references/module-promotion.md +51 -51
- package/skills/primitive-authoring/references/primitive-audit.md +16 -16
- package/skills/primitive-authoring/references/shell-patterns.md +81 -81
- package/skills/primitive-authoring/references/svg-authoring.md +62 -66
- package/skills/primitive-authoring/references/token-contract.md +45 -49
- package/skills/primitive-authoring/references/trait-pages.md +8 -8
- package/skills/primitive-authoring/references/worked-example.md +39 -39
- package/skills/primitive-authoring/references/yaml-contract.md +139 -143
- package/skills/site-deployment/SKILL.md +25 -26
- package/skills/site-deployment/agents/openai.yaml +1 -1
- package/skills/site-deployment/evals/routing-corpus.json +1 -1
- package/skills/site-deployment/references/deploy-playbooks.md +51 -53
- package/skills/site-docs-authoring/SKILL.md +14 -14
- package/skills/site-docs-authoring/agents/openai.yaml +1 -1
- package/skills/site-docs-authoring/evals/evals.json +1 -1
- package/skills/site-docs-authoring/evals/routing-corpus.json +1 -1
- package/skills/site-docs-authoring/intent.md +18 -18
- package/skills/ssr-compatibility/SKILL.md +24 -25
- package/skills/ssr-compatibility/agents/openai.yaml +1 -1
- package/skills/ssr-compatibility/evals/evals.json +1 -1
- package/skills/ssr-compatibility/evals/routing-corpus.json +1 -1
- package/skills/ssr-compatibility/references/consumer-workarounds.md +22 -23
- package/skills/ssr-compatibility/references/failure-shapes.md +84 -91
- package/skills/ssr-compatibility/references/guard-patterns.md +54 -58
- package/skills/ssr-compatibility/references/status-ledger.md +17 -17
- package/skills/ssr-compatibility/references/test-without-linkedom.md +26 -27
|
@@ -1,40 +1,39 @@
|
|
|
1
|
-
# `gates-catalog.md
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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'"
|
|
29
|
-
- **Real failure:** a touched directory has NO matching CHANGELOG entry at all
|
|
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
|
|
31
|
-
- The umbrella tag `vX.Y.Z` classifies **`info`** (since 2026-07-19
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
150
|
-
- **Semantic content checks
|
|
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
|
|
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
|
|
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)
|
|
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
|
|
166
|
-
- **Exit 143 (SIGTERM):** the vitest process was KILLED (resource pressure / a stray terminator), not a test failure
|
|
167
|
-
- **First-time-at-cut failures are REAL (v0.8.34):** this serial suite runs tests PR CI never does
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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)
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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)
|
|
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
|
|
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
|
|
23
|
-
| Umbrella tag | `vX.Y.Z` + per-package | **none
|
|
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
|
|
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
|
|
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
|
|
43
|
-
4. **Tag at the published commit
|
|
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
|
|
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"
|
|
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
|
|
56
|
-
- A marketplace repo's org + visibility is an **operator call
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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`)
|
|
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
|
|
1
|
+
# Mechanization, bundled `scripts/`, stdlib Node, all support `--dry`
|
|
2
2
|
|
|
3
|
-
`release-pack.mjs` walks the cycle in two phases per invariant 3
|
|
4
|
-
cut` / `--mode from-scratch` promote `[Unreleased]` (BOTH modes now
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
48
|
-
- **Mechanical vs manual, explicitly labeled.** A pure rename ships a `perl -i -pe`; a semantic flip ships a "manual review
|
|
49
|
-
- **One component per sweep regex
|
|
50
|
-
- **HTML-attribute regexes only match HTML/JSX
|
|
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)
|
|
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
|
|
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
|
|
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
|
|
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
|
|
77
|
-
- **Opt-out Booleans defaulting true
|
|
78
|
-
- **Ownership moves
|
|
79
|
-
- **kebab-string property keys
|
|
80
|
-
- **Wide namespace renames (50+ symbols)
|
|
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
|
|