@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.
- package/.claude-plugin/plugin.json +2 -2
- package/.codex-plugin/plugin.json +3 -3
- package/CHANGELOG.md +300 -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 +20 -21
- 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 +34 -35
- 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 +27 -27
- package/skills/gen-ui-review/agents/openai.yaml +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,4 +1,4 @@
|
|
|
1
|
-
# `cut-procedure.md
|
|
1
|
+
# `cut-procedure.md`, the standard lockstep cut
|
|
2
2
|
|
|
3
3
|
`<plugin-root>` below is `$CLAUDE_PLUGIN_ROOT` in Claude Code; the plugin's installed directory
|
|
4
4
|
in Codex.
|
|
@@ -13,10 +13,10 @@ in Codex.
|
|
|
13
13
|
|
|
14
14
|
Two entry variants, converging at Step 5:
|
|
15
15
|
|
|
16
|
-
- **Variant A
|
|
17
|
-
- **Variant B
|
|
16
|
+
- **Variant A, deploy handoff:** a peer pre-cut the release commit + CHANGELOG + bump + lockfile. Re-baseline, verify, run **Step 4e** (release docs + team notes, the peer's cut may not have generated them, and the pretag gate blocks Step 6 without them), then resume at Step 6 (tag).
|
|
17
|
+
- **Variant B, author from scratch:** source landed under `## [Unreleased]` with no bump. Do Step 4 (promotion + bump + lockfile), then the full tail.
|
|
18
18
|
|
|
19
|
-
`` `<plugin-root>/skills/package-release/scripts/release-pack.mjs` `` (bundled) mechanizes the sequence in two phases per invariant 3
|
|
19
|
+
`` `<plugin-root>/skills/package-release/scripts/release-pack.mjs` `` (bundled) mechanizes the sequence in two phases per invariant 3, the cut modes stop at the release commit (PR → CI → merge happens between), `--mode handoff` runs tag→publish→deploy from post-merge main. **Run with `--go` for an operator-initiated release** (single authorization, §below); the steps below are the manual/diagnostic form and run straight through on the same one-go model.
|
|
20
20
|
|
|
21
21
|
| Step | Action | Mutates? |
|
|
22
22
|
| --- | --- | --- |
|
|
@@ -25,12 +25,12 @@ Two entry variants, converging at Step 5:
|
|
|
25
25
|
| 3 | Pre-flight gates (+ harvest preamble if source content changed) | No |
|
|
26
26
|
| 4a-pre | Assemble `changes/<pr>.md` fragments into the right `[Unreleased]` (REQ-W11-06) | Yes |
|
|
27
27
|
| 4 | (Variant B) Promote `[Unreleased]`; bump; lockfile | Yes |
|
|
28
|
-
| 4f | Pre-tag coverage `--fix
|
|
28
|
+
| 4f | Pre-tag coverage `--fix`, authoritative F-N1 matcher, pre-PR | CHANGELOGs |
|
|
29
29
|
| 5 | Stage the release allowlist; commit on `release/vX.Y.Z` | Yes |
|
|
30
30
|
| 5.5 | Pre-commit freshness trip-wire | No |
|
|
31
31
|
| 5.7 | Release PR: push branch → CI → merge → re-baseline on `main` | PR + merge |
|
|
32
32
|
| 6 | Tag umbrella + per-package at post-merge HEAD | Yes |
|
|
33
|
-
| 7 | F-N1 release trip-wire (expected clean
|
|
33
|
+
| 7 | F-N1 release trip-wire (expected clean, 4f already ran) | No |
|
|
34
34
|
| 8 | Push tags (one per push; `main` already merged) | Push |
|
|
35
35
|
| 9 | Dispatch publish workflows; wait; verify registry | Publish |
|
|
36
36
|
| 10 | GH releases + site deploy dispatch | Deploy |
|
|
@@ -39,7 +39,7 @@ Two entry variants, converging at Step 5:
|
|
|
39
39
|
|
|
40
40
|
---
|
|
41
41
|
|
|
42
|
-
## §Step 1
|
|
42
|
+
## §Step 1, Re-baseline
|
|
43
43
|
|
|
44
44
|
Context is stale at the start of every turn; run unconditionally:
|
|
45
45
|
|
|
@@ -49,35 +49,35 @@ git -C "$REPO" status --short
|
|
|
49
49
|
git -C "$REPO" log --oneline -8
|
|
50
50
|
git -C "$REPO" fetch && git -C "$REPO" log HEAD..origin/main --oneline # must be empty
|
|
51
51
|
git -C "$REPO" tag --list 'vX.Y.Z' '*-vX.Y.Z' # must NOT exist yet
|
|
52
|
-
[ -d "$REPO/node_modules/.pnpm" ] && echo "STOP: pnpm-shaped node_modules
|
|
52
|
+
[ -d "$REPO/node_modules/.pnpm" ] && echo "STOP: pnpm-shaped node_modules, run npm ci first" # gate 9 precondition, see §3.1 layout note
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
**Check the `node_modules` layout here, not at gate 9.** The §3.1 layout note (gh#1359)
|
|
56
56
|
already says gate 9 (`check:js-bundles-fresh`) needs the npm-ci layout, but it sits AFTER
|
|
57
|
-
the gate roster and is easy to read past
|
|
57
|
+
the gate roster and is easy to read past, the v0.8.55 cut (2026-08-28) ran the full
|
|
58
58
|
33-gate pre-flight under a pnpm-shaped tree, lost ~12 minutes to gates 1-8 and 10-33
|
|
59
59
|
passing, then failed gate 9 with phantom bundle drift (1.24 MB on disk vs 1.52 MB fresh
|
|
60
|
-
on every JS entry
|
|
60
|
+
on every JS entry, the Phosphor icon glob resolving differently, not a real source
|
|
61
61
|
change). The one-line check above fails in under a second instead. `npm ci` to recover;
|
|
62
62
|
`npm install` alone does NOT reshape an existing pnpm tree.
|
|
63
63
|
|
|
64
64
|
`branch --show-current` ≠ `main` → stop; cutting on a feature branch pushes a stale `main` ref while the tags point at the feature tip. Recovery: [`recovery-paths.md`](recovery-paths.md) §Scenario 8. If multiple unpushed `release(*):` commits exist → this is a batch push, [`recovery-paths.md`](recovery-paths.md) §Scenario 2.
|
|
65
65
|
|
|
66
|
-
## §Step 2
|
|
66
|
+
## §Step 2, Classify uncommitted files; stash strays
|
|
67
67
|
|
|
68
|
-
Modified/untracked files you didn't author are classification decisions
|
|
68
|
+
Modified/untracked files you didn't author are classification decisions, diff each one. A **stray** = uncommitted + undocumented (no CHANGELOG entry or commit explains it) + behavior-visible + contradicting a release artifact. Stash strays; never revert (revert destroys the work):
|
|
69
69
|
|
|
70
70
|
```bash
|
|
71
|
-
git -C "$REPO" stash push <file1> <file2> -m "vX.Y.Z-cycle: <reason
|
|
71
|
+
git -C "$REPO" stash push <file1> <file2> -m "vX.Y.Z-cycle: <reason>, parked"
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
-
Keep the stash held through the site deploy (Step 10)
|
|
74
|
+
Keep the stash held through the site deploy (Step 10), the tarball builds from the **tag** but the site builds from the **working tree**; an uncommitted stray leaks into the deployed site and not the packages, silently. Pop after the cycle; if pop reports "kept the stash", see [`recovery-paths.md`](recovery-paths.md) §Scenario 6. Record any exclusion in the release-commit message (`Excluded, in-flight: <file> (<reason>)`).
|
|
75
75
|
|
|
76
|
-
## §Step 3
|
|
76
|
+
## §Step 3, Pre-flight gates
|
|
77
77
|
|
|
78
78
|
### 3.0 Harvest preamble (only when source content changed in the window)
|
|
79
79
|
|
|
80
|
-
If `git diff <prev-tag>..HEAD --name-only` touches component yaml / `.a2ui.json` sources, **`*.examples.html`**, `*.contents.html`, **any file under `site/`, `apps/`, `playgrounds/`, or `catalog
|
|
80
|
+
If `git diff <prev-tag>..HEAD --name-only` touches component yaml / `.a2ui.json` sources, **`*.examples.html`**, `*.contents.html`, **any file under `site/`, `apps/`, `playgrounds/`, or `catalog/`**, annotated with `data-chunk-*` or not, or any `styles/colors/*` token source, regenerate downstream artifacts proactively (otherwise the freshness gates force a tag-move recovery later):
|
|
81
81
|
|
|
82
82
|
```bash
|
|
83
83
|
node scripts/build/components.mjs # catalog + per-component sidecars
|
|
@@ -92,20 +92,20 @@ npm run build:bundles # dist CSS+JS bundles
|
|
|
92
92
|
|
|
93
93
|
**The `data-chunk-*` qualifier was the trap** (gh#421). Two separate cuts lost a CI round-trip to it:
|
|
94
94
|
|
|
95
|
-
- **v0.8.14** edited two components' `*.examples.html
|
|
96
|
-
- **The 0.8.16 cycle** then added a brand-new `site/pages/guides/theming.html` with *no* annotations, ran `check:links`, `verify:llms`, and `verify:patterns-index
|
|
95
|
+
- **v0.8.14** edited two components' `*.examples.html`, not yaml, not `.contents.html`, no annotation, so it read as out of scope. It isn't: `.examples.html` feeds **two** generators (`.examples.md` and the chunk harvest's source hashes; a third, the retired site-a2ui converted rows, applied historically). Every freshness gate this doc named came back clean, and CI still failed on `🔴 stale /site/components/{menu,popover}` plus `2 source file(s) changed since harvest`.
|
|
96
|
+
- **The 0.8.16 cycle** then added a brand-new `site/pages/guides/theming.html` with *no* annotations, ran `check:links`, `verify:llms`, and `verify:patterns-index`, all clean, and CI failed anyway: `1 source file(s) NEW since harvest`.
|
|
97
97
|
|
|
98
98
|
Root cause of both: `check-chunks-fresh` hashes **every** source file under the harvest globs and compares the set against the corpus record, so a new or changed file trips it whether or not the harvester extracts a chunk from it. The annotation governs what gets *harvested*, never what gets *hashed*. Hence the trigger list above names the directories, not the annotation.
|
|
99
99
|
|
|
100
|
-
When only source *hashes* move and chunk content does not, `check:embeddings-fresh` stays green on its content hash
|
|
100
|
+
When only source *hashes* move and chunk content does not, `check:embeddings-fresh` stays green on its content hash, no embedding rebuild, no `OPENAI_API_KEY` needed. Both incidents above were that case, which is why the block above runs that check *before* `build:embeddings:chunks` and skips the rebuild when it passes: an unconditional rebuild makes an ordinary `.examples.html` or new-page edit fail pre-flight on any machine without the key, for no reason. Only a change that alters chunk **content** needs the rebuild.
|
|
101
101
|
|
|
102
|
-
**Regen output supersedes working-tree state.** These outputs land in the release commit unconditionally, even when the same paths are also dirty from a peer
|
|
102
|
+
**Regen output supersedes working-tree state.** These outputs land in the release commit unconditionally, even when the same paths are also dirty from a peer: the fresh regen is authoritative; divergent uncommitted work rebases on top afterwards.
|
|
103
103
|
|
|
104
|
-
**Staging a read-only report without cutting** (gh#3063): `node scripts/release/preflight-dry-run.mjs --version X.Y.Z` runs this same roster (`gate-roster.mjs` SoT) inside a throwaway `npm ci` clone and prints per-gate PASS/FAIL plus a tail-of-log on failure
|
|
104
|
+
**Staging a read-only report without cutting** (gh#3063): `node scripts/release/preflight-dry-run.mjs --version X.Y.Z` runs this same roster (`gate-roster.mjs` SoT) inside a throwaway `npm ci` clone and prints per-gate PASS/FAIL plus a tail-of-log on failure, no bump, no tag, no CHANGELOG promotion, nothing lands on the real repo. This mechanizes the ad-hoc procedure the 0.8.59 staging pre-flight hand-drove (gh#2870 comments 5526330460 + addendum); use it whenever a "how healthy is main right now" report is wanted ahead of an actual cut. `--dry-run` lists the roster with no clone/npm ci; `--keep` preserves the throwaway clone for inspection.
|
|
105
105
|
|
|
106
|
-
### 3.1 The full roster
|
|
106
|
+
### 3.1 The full roster, every gate runs; a subset = pre-flight failure
|
|
107
107
|
|
|
108
|
-
**Precondition
|
|
108
|
+
**Precondition, tsc build for llm, agent, persona (gh#3342).** Gate 4
|
|
109
109
|
(`test:unit:serial`) runs each package's root `*.test.js` files against its
|
|
110
110
|
BUILT output, not its `src/*.ts`: `persona.test.js` imports `./index.js`
|
|
111
111
|
directly, `agent.test.js`'s own docstring says "run against the BUILT
|
|
@@ -113,23 +113,23 @@ output ... `npm run build -w @adia-ai/agent` first", and `llm/core` carries
|
|
|
113
113
|
a dedicated `dist-check.test.js` that asserts the emitted artifacts exist
|
|
114
114
|
and explicitly does not build them itself. All three packages' emitted
|
|
115
115
|
`.js`/`.d.ts` are gitignored, so a fresh cut clone has none of them until
|
|
116
|
-
something builds them
|
|
116
|
+
something builds them, unlike §3.0's regen outputs, this is a plain build
|
|
117
117
|
artifact, not a content-conditional regen, so `release-pack.mjs`'s
|
|
118
118
|
`step3PreFlight()` now runs `npm run build -w @adia-ai/llm -w @adia-ai/agent
|
|
119
119
|
-w @adia-ai/persona` unconditionally, every cut, immediately before gate 4
|
|
120
|
-
(mechanized fix
|
|
120
|
+
(mechanized fix, a manual cut should run the same command first). The
|
|
121
121
|
v0.8.59 cut hit this: §3.0's `npm run build -w @adia-ai/llm` line only
|
|
122
122
|
fires when its source-content trigger list matches, and never named
|
|
123
123
|
agent/persona at all, so a cut with no matching trigger reached gate 4 with
|
|
124
124
|
stale or absent dist and failed on it.
|
|
125
125
|
|
|
126
|
-
**Execution model (gh#2006): three phases, not one serial walk.** `step3PreFlight()` runs gate 4 solo first (see its own note below), then gates 16 → 27 → 28 strictly in order (the eval-health write-then-read dependency
|
|
126
|
+
**Execution model (gh#2006): three phases, not one serial walk.** `step3PreFlight()` runs gate 4 solo first (see its own note below), then gates 16 → 27 → 28 strictly in order (the eval-health write-then-read dependency, gate 28 reads whichever `evals/mcp/runs/` directory sorts lexically LAST, so nothing else may write there between 27 and 28), concurrently with a bounded pool running every other gate at once (`PREFLIGHT_CONCURRENCY`, default 4, override for a dedicated/idle host). Every gate still resolves the same command, still fails the whole pre-flight on a red result, and still reports its own number, only the WALL-CLOCK schedule changed, never the roster below or its numbering. `--dry` previews stay the original flat serial walk unchanged.
|
|
127
127
|
|
|
128
128
|
```bash
|
|
129
129
|
node scripts/build/components.mjs --verify # 1 yaml ↔ sidecar ↔ .d.ts
|
|
130
130
|
npm run verify:traits # 2 trait coverage
|
|
131
131
|
npm run check:lockstep # 3 version coherence (+ factory .mcp.json @adia-ai/mcp pin, invariant 8)
|
|
132
|
-
npm run test:unit:serial # 4 vitest, serial
|
|
132
|
+
npm run test:unit:serial # 4 vitest, serial, the source of truth (§Cat 8; parallel flakes under load)
|
|
133
133
|
npm run typecheck # 5 tsc --noEmit
|
|
134
134
|
npm run check:demo-shells # 6 demo imports cover composes:
|
|
135
135
|
npm run check:lightningcss-build # 7 CSS minifies
|
|
@@ -144,48 +144,47 @@ npm run check:links # 15 intra-repo links
|
|
|
144
144
|
npm run eval:diff -- --engine zettel # 16 eval floors
|
|
145
145
|
npm run dogfood:status # 17 P0/P1 dogfood floor (static-only under npm-ci; run once more under bootstrap layout for full coverage, gh#1359)
|
|
146
146
|
npm run check:examples-md-fresh # 18 .examples.md vs .examples.html
|
|
147
|
-
# gate 19 (verify:site-a2ui) retired with the site-a2ui mechanism
|
|
148
|
-
npm run verify:contrast # 20 WCAG AA
|
|
147
|
+
# gate 19 (verify:site-a2ui) retired with the site-a2ui mechanism, ADR-0072 Decision 2 / gh#2410
|
|
148
|
+
npm run verify:contrast # 20 WCAG AA, canvas-text AND text-on-fill
|
|
149
149
|
npm run check:token-semantics-sync # 21 token-selection generated refs vs token sources
|
|
150
150
|
npm run check:demo-routes # 22 demo surfaces routed + patterns indexed
|
|
151
151
|
npm run check:brand-assets # 23 brand mark token-driven, not baked raster
|
|
152
|
-
node scripts/release/check-cut-hygiene.mjs --version <mode-dependent> # 24 README CDN-pin + version currency
|
|
152
|
+
node scripts/release/check-cut-hygiene.mjs --version <mode-dependent> # 24 README CDN-pin + version currency, CUT modes pre-flight at the PREVIOUS version (the README claim is exact-match and only moves at the Step-4 bump; Step 4g re-proves at the cut version), HANDOFF pre-flights at the CUT version (post-merge, the claim already moved)
|
|
153
153
|
python3 packages/plugins/adia-ui-factory/scripts/adia-scaffold selftest # 25 scaffold specifiers resolve in packed @adia-ai/web-components + @adia-ai/web-modules tarballs (gh#1132)
|
|
154
|
-
node scripts/release/check-dx-sweep-freshness.mjs # 26 DX sweep fresh + not regression-RED (gh#1137 REQ-05
|
|
154
|
+
node scripts/release/check-dx-sweep-freshness.mjs # 26 DX sweep fresh + not regression-RED (gh#1137 REQ-05, FLAGGED, needs package-release confirmation; see the script's own header)
|
|
155
155
|
npm run eval:diff -- --engine free-form # 27 fresh free-form eval run (evals/health input, gh#1135)
|
|
156
156
|
node scripts/release/write-eval-health.mjs --version <cut> # 28 evals/health/<version>.json committed, AC-01/AC-02 run for real (gh#1135, WS-4 SPEC REQ-06)
|
|
157
|
-
node scripts/release/check-estate-split-latch.mjs # 29 no lockstep cut mid estate-split (ADR-0048 / gh#1192)
|
|
158
|
-
npm run check:catalog-tiers # 30 tier-index.json vs committed catalog (gh#1494
|
|
157
|
+
node scripts/release/check-estate-split-latch.mjs # 29 no lockstep cut mid estate-split (ADR-0048 / gh#1192), see the note below
|
|
158
|
+
npm run check:catalog-tiers # 30 tier-index.json vs committed catalog (gh#1494, ADR-0069 moved its PR-blocking half to derived-resync; the pre-cut roster re-asserts Class-R freshness before a tag. Gate 13 can't catch this: the harvester hashes tier-index.json as a SOURCE)
|
|
159
159
|
npm run check:codex-manifests-fresh # 31 Codex plugin.json + openai.yaml vs .claude-plugin/plugin.json SoT (gh#1888)
|
|
160
160
|
npm run check:harness-manifests-fresh # 32 Hermes/Pi plugin.yaml + __init__.py + prompts vs .claude-plugin/plugin.json + commands SoT (gh#1954)
|
|
161
161
|
npm run verify:patterns-index # 33 pattern-index.md (mcp + adia-ui-factory) vs corpus source
|
|
162
|
-
node scripts/release/check-yaml-events-vs-runtime.mjs --strict --strict-details # 34 yaml events: blocks vs runtime dispatch
|
|
162
|
+
node scripts/release/check-yaml-events-vs-runtime.mjs --strict --strict-details # 34 yaml events: blocks vs runtime dispatch, no phantom/missing events (gh#2829)
|
|
163
163
|
node scripts/release/check-yaml-impl-coverage.mjs --strict # 35 yaml schema fields vs implementation coverage (gh#2829)
|
|
164
|
-
npm run check:treeshake # 36 single-import build matrix (esbuild+rollup)
|
|
165
|
-
npm run check:lint-efficacy # 37 lint rule bank: seeded catch rate 100% + golden-set 0 error FPs + mutation hardening (gh#2911
|
|
164
|
+
npm run check:treeshake # 36 single-import build matrix (esbuild+rollup), byte budgets + marker-leak + CSS purity + whole-lib delta + docs grep-gate (gh#2912)
|
|
165
|
+
npm run check:lint-efficacy # 37 lint rule bank: seeded catch rate 100% + golden-set 0 error FPs + mutation hardening (gh#2911, not in `npm run check`, ~100s over the <60s bar)
|
|
166
166
|
```
|
|
167
167
|
|
|
168
|
-
**Gate 29 was the ADR-0048 latch; since P5 it is a permanent invariant.** Between P1 and P5 the repo was correct in-repo but deliberately **not publishable** (old-name stubs marked `private: true` that the roster still mapped, plus dependency edges onto workspace packages no cut published), and a cut in that window would have shipped broken packages that npm cannot unpublish. **P5 cleared it by landing the real thing
|
|
168
|
+
**Gate 29 was the ADR-0048 latch; since P5 it is a permanent invariant.** Between P1 and P5 the repo was correct in-repo but deliberately **not publishable** (old-name stubs marked `private: true` that the roster still mapped, plus dependency edges onto workspace packages no cut published), and a cut in that window would have shipped broken packages that npm cannot unpublish. **P5 cleared it by landing the real thing**, the six stubs became publishable shims and `PACKAGE_ROSTER` gained the three remaining new names, at which point all 9 offending edges resolved and the gate went green on its own. No gate logic was changed.
|
|
169
169
|
|
|
170
|
-
It asserts three tree properties over the lockstep roster
|
|
170
|
+
It asserts three tree properties over the lockstep roster, no roster dir is `private: true`, and no roster package depends on a workspace package that is either private or absent from the roster: which is why it self-cleared rather than needing a removal. Never bypass it by flipping `private` or hand-editing the roster; that is the exact failure it exists to prevent. Self-check: `node scripts/release/check-estate-split-latch.mjs selftest`. It stays in the roster permanently: it now costs nothing and catches any FUTURE unpublishable dependency edge.
|
|
171
171
|
|
|
172
172
|
**Layout note (gh#1359): the roster does not run under one uniform `node_modules` shape.** Every gate above is layout-agnostic except two, which pull in opposite directions:
|
|
173
173
|
|
|
174
|
-
- **Gate 9** (`check:js-bundles-fresh`) needs the **npm-ci layout
|
|
175
|
-
- **Gate 17** (`npm run dogfood:status`) needs the **pnpm/bootstrapped layout** for its two live-probe legs (`empty-instantiation`, `padded-route-gutter`) to render icons correctly (gh#340)
|
|
174
|
+
- **Gate 9** (`check:js-bundles-fresh`) needs the **npm-ci layout**: the committed `dist/` bundles are npm-shaped (an entry-relative Phosphor icon glob resolves differently under pnpm's non-hoisted layout, producing a materially larger fresh build that fails the diff). Run pre-flight under `npm ci`.
|
|
175
|
+
- **Gate 17** (`npm run dogfood:status`) needs the **pnpm/bootstrapped layout** for its two live-probe legs (`empty-instantiation`, `padded-route-gutter`) to render icons correctly (gh#340), but auto-degrades to a static-only run (every other audit it aggregates has no dev-server dependency) rather than hard-failing when it detects an npm-shaped layout, so it no longer blocks a straight npm-ci roster pass. **A static-only pass is not full coverage.** Run `node scripts/dev/bootstrap-worktree.mjs && npm run dogfood:status` once under that layout, before or after the main npm-ci roster pass, to actually exercise the two live-probe legs before tagging.
|
|
176
176
|
|
|
177
177
|
No other gate in the roster cares which layout produced `node_modules`.
|
|
178
178
|
|
|
179
179
|
Any red → route via [`gates-catalog.md`](gates-catalog.md); fix at the source, re-run the narrowest gate, then re-run the full sequence. The canonical miss: a cut that ran 7 of the gates shipped a stale-embeddings defect that surfaced a day later and cost a tag-move recovery.
|
|
180
180
|
|
|
181
|
-
## §Step 4
|
|
181
|
+
## §Step 4, (Variant B, or ANY variant with uncommitted `[Unreleased]` content) Promote, bump, lockfile
|
|
182
182
|
|
|
183
183
|
**4a-pre. Assemble `changes/<pr>.md` fragments (REQ-W11-06, gh#2931), BEFORE promotion.** This
|
|
184
|
-
repo's PRs land a `changes/<pr>.md` fragment instead of hand-editing a CHANGELOG directly
|
|
185
|
-
`check-changelog-pr-gate.mjs`'s own PR-time gate now REQUIRES a fragment for a roster-package
|
|
184
|
+
repo's PRs land a `changes/<pr>.md` fragment instead of hand-editing a CHANGELOG directly, `check-changelog-pr-gate.mjs`'s own PR-time gate now REQUIRES a fragment for a roster-package
|
|
186
185
|
change and refuses the direct edit outright (gh#3123; the root `CHANGELOG.md` was already
|
|
187
186
|
fragment-only in practice before that ticket). Those fragments accumulate
|
|
188
|
-
unreleased until something folds them into the right CHANGELOG's `[Unreleased]` section
|
|
187
|
+
unreleased until something folds them into the right CHANGELOG's `[Unreleased]` section, that's
|
|
189
188
|
this step, and it must run before 4a promotes `[Unreleased]` to a versioned heading, or a
|
|
190
189
|
fragment folded in afterward would land under the WRONG (already-promoted) heading.
|
|
191
190
|
|
|
@@ -203,44 +202,43 @@ Routing rule (`scripts/release/assemble-changelog-fragments.mjs`'s own header, f
|
|
|
203
202
|
there): a fragment's first line is `- <kind>: <sentence>` (kind in fix|feature|chore|docs,
|
|
204
203
|
unchanged from `changelog_fragments.py`'s schema) or, this repo's own addition, `- <kind>
|
|
205
204
|
(<package>): <sentence>` naming a `PACKAGE_ROSTER` (`package-paths.mjs`) entry. The
|
|
206
|
-
parenthetical-package form routes to that package's own `packages/<dir>/CHANGELOG.md
|
|
205
|
+
parenthetical-package form routes to that package's own `packages/<dir>/CHANGELOG.md`, the
|
|
207
206
|
norm for package-scoped fragments as of gh#3123, not a hypothetical; the plain form routes to
|
|
208
207
|
the repo-root `CHANGELOG.md`, whose own header scopes
|
|
209
208
|
it to exactly that shape of change ("tooling, CI, build scripts, cross-package work, docs").
|
|
210
209
|
`kind` maps to a Keep-a-Changelog subsection: `feature`→Added, `fix`→Fixed, `chore`→Changed,
|
|
211
|
-
`docs`→Docs
|
|
210
|
+
`docs`→Docs, created under `## [Unreleased]` in that canonical order if the subsection doesn't
|
|
212
211
|
already exist, otherwise appended to the existing one.
|
|
213
212
|
|
|
214
213
|
**Deliberately NOT a pre-flight roster gate (§3.1).** Pending fragments are a NORMAL state
|
|
215
|
-
between PRs, not a defect
|
|
214
|
+
between PRs, not a defect, a `--verify`-shaped freshness gate added to the pre-cut roster (which
|
|
216
215
|
runs before this step, in Step 3) would fail on every cut that has any recent chore/fix/feature
|
|
217
216
|
PR queued, which is the common case. The `--verify` invocation above is a post-assembly
|
|
218
217
|
self-check (proves the assemble actually consumed everything it found), not a standing gate;
|
|
219
218
|
`gate-roster.mjs`'s count is unchanged by this ticket.
|
|
220
219
|
|
|
221
|
-
**Run 4a whenever a hand-authored `## [Unreleased]` section is still sitting uncommitted, not only on a strict Variant B.** `release-pack.mjs --mode cut` (a peer's pre-staged content, not yet promoted) needs it exactly as much as `--mode from-scratch` does
|
|
220
|
+
**Run 4a whenever a hand-authored `## [Unreleased]` section is still sitting uncommitted, not only on a strict Variant B.** `release-pack.mjs --mode cut` (a peer's pre-staged content, not yet promoted) needs it exactly as much as `--mode from-scratch` does: the v0.8.4 near-miss was `--mode cut` skipping this step entirely because the doc (and the script) only associated promotion with "from scratch". Both modes now run it and both hard-fail before the bump if any roster package still carries non-empty `[Unreleased]` content afterward.
|
|
222
221
|
|
|
223
|
-
**4a. Promote** `## [Unreleased]` → `## [vX.Y.Z]
|
|
222
|
+
**4a. Promote** `## [Unreleased]` → `## [vX.Y.Z], YYYY-MM-DD` per package (`` `<plugin-root>/skills/package-release/scripts/promote-unreleased.mjs` ``); author fresh blocks for changed-but-unlogged packages; stub the pure ride-alongs (`` `<plugin-root>/skills/package-release/scripts/insert-stub.mjs` ``). Classification recipe + shapes: [`changelog-discipline.md`](changelog-discipline.md).
|
|
224
223
|
|
|
225
|
-
`release-pack.mjs` (both `--mode cut` and `--mode from-scratch`) now rejects any `--substantive-packages`/`--stub-packages` name whose entry in `scripts/package-paths.mjs`'s `PACKAGE_ROSTER` is unknown or `lockstep: false`, at parse time, before Step 1 runs (gh#2894)
|
|
224
|
+
`release-pack.mjs` (both `--mode cut` and `--mode from-scratch`) now rejects any `--substantive-packages`/`--stub-packages` name whose entry in `scripts/package-paths.mjs`'s `PACKAGE_ROSTER` is unknown or `lockstep: false`, at parse time, before Step 1 runs (gh#2894), the 0.8.58 cut passed `adia-plugins` (lockstep:false) in `--substantive-packages` and let `promote-unreleased.mjs` rewrite its `[Unreleased]` header to a version that package never ships, caught only at Step 5.6 after the full pre-flight had already run.
|
|
226
225
|
|
|
227
|
-
**4b. Bump.** PATCH vs MINOR: **MINOR is reserved for API-surface breaks only** (removed/renamed prop, attribute, slot, event, token, or tag). Visible behavior changes, re-scalings, and opt-in features stay PATCH; a CHANGELOG bullet saying "(MINOR behavior change)" is prose, not a semver directive. Unqualified "bump version" = PATCH; don't round-trip to ask. `node "<plugin-root>/skills/package-release/scripts/bump.mjs" --from X.Y.Z-1 --to X.Y.Z`. On a MINOR cut, also bump the internal `@adia-ai/*` `^ranges` separately (bump.mjs touches `"version"` fields only)
|
|
226
|
+
**4b. Bump.** PATCH vs MINOR: **MINOR is reserved for API-surface breaks only** (removed/renamed prop, attribute, slot, event, token, or tag). Visible behavior changes, re-scalings, and opt-in features stay PATCH; a CHANGELOG bullet saying "(MINOR behavior change)" is prose, not a semver directive. Unqualified "bump version" = PATCH; don't round-trip to ask. `node "<plugin-root>/skills/package-release/scripts/bump.mjs" --from X.Y.Z-1 --to X.Y.Z`. On a MINOR cut, also bump the internal `@adia-ai/*` `^ranges` separately (bump.mjs touches `"version"` fields only), and a MINOR cut owes a MIGRATION GUIDE section ([`migration-guide-authoring.md`](migration-guide-authoring.md)).
|
|
228
227
|
|
|
229
|
-
**4c. Lockfile.** `npm install --package-lock-only --no-audit --no-fund
|
|
228
|
+
**4c. Lockfile.** `npm install --package-lock-only --no-audit --no-fund`, must land in the release commit. The publish workflows open with `npm ci`, which hard-fails on a version/lockfile mismatch: a bump without the regenerated lockfile passes locally and breaks **every** publish at clean-install.
|
|
230
229
|
|
|
231
|
-
**4d.** `npm run check:lockstep` → `OK
|
|
230
|
+
**4d.** `npm run check:lockstep` → `OK, all packages at X.Y.Z, all internal ranges at ^X.Y.0`.
|
|
232
231
|
|
|
233
|
-
**4d.5. Regenerate the derived genui catalog** (gh#617): `node scripts/build/derive-genui-catalog.mjs`. Its `catalogId` embeds the lockstep version (`adia.base@X.Y.Z`), so the 4b bump just invalidated `packages/genui/adia-catalog/{base,adia-pack}.json
|
|
232
|
+
**4d.5. Regenerate the derived genui catalog** (gh#617): `node scripts/build/derive-genui-catalog.mjs`. Its `catalogId` embeds the lockstep version (`adia.base@X.Y.Z`), so the 4b bump just invalidated `packages/genui/adia-catalog/{base,adia-pack}.json`, regenerated pre-bump (§3.0) or not. The v0.8.26 cut skipped this and `check:genui-catalog` failed in CI one push later. Both files ride the release commit (Step 5 stages them).
|
|
234
233
|
|
|
235
|
-
**4d.5b. Regenerate catalog tiers + re-harvest the chunk corpus if it goes stale** (gh#1361, automated
|
|
234
|
+
**4d.5b. Regenerate catalog tiers + re-harvest the chunk corpus if it goes stale** (gh#1361, automated: this was a recurring manual rider before): `npm run build:catalog-tiers`, then `npm run check:chunks-fresh`; if that probe goes stale, `npm run harvest:chunks`. `tier-index.json` derives from the same post-bump catalog 4d.5 just refreshed, and the chunk harvester hashes `tier-index.json` as a harvest SOURCE, regenerating tiers without re-harvesting left `check:chunks-fresh` red on the next run, needing a manual rider commit both cuts it happened live: v0.8.39 (`72417beff`) and v0.8.40/CUT-0840-B (`d9ca8b323`, "Ran `npm run build:catalog-tiers` ... That regen staled `check:chunks-fresh` ... so re-harvested"). The re-harvest is CONDITIONAL on the freshness probe, not unconditional, a tier regen that produces a byte-identical index owes no re-harvest. `tier-index.json`, `packages/gen-ui/engine/corpus/manifest.json`, and `packages/gen-ui/engine/corpus/chunks/` all ride the release commit (Step 5 stages them).
|
|
236
235
|
|
|
237
|
-
**4d.6. Regenerate the Codex plugin manifests** (gh#1888, gh#1899): `node scripts/build/codex-manifests.mjs`, then `npm run check:codex-manifests-fresh` to confirm. Both plugins' `.codex-plugin/plugin.json` embed `version` from `.claude-plugin/plugin.json`, which the 4b bump just moved
|
|
236
|
+
**4d.6. Regenerate the Codex plugin manifests** (gh#1888, gh#1899): `node scripts/build/codex-manifests.mjs`, then `npm run check:codex-manifests-fresh` to confirm. Both plugins' `.codex-plugin/plugin.json` embed `version` from `.claude-plugin/plugin.json`, which the 4b bump just moved, same "derived artifact carries the lockstep version" class as 4d.5's genui catalog. Gate 31 runs pre-bump in Step 3 and only proves freshness against the PREVIOUS version; nothing re-ran the generator post-bump before this line existed, the v0.8.48 release PR (#1897) shipped stale manifests as a result, caught by `check:codex-manifests-fresh` in CI and fixed by hand on the release branch. `packages/plugins/*/.codex-plugin/plugin.json` and `packages/plugins/*/skills/*/agents/openai.yaml` ride the release commit (Step 5 stages them).
|
|
238
237
|
|
|
239
|
-
**4d.7. Regenerate the Hermes/Pi plugin manifests** (gh#1954): `node scripts/build/harness-manifests.mjs`, then `npm run check:harness-manifests-fresh` to confirm. Same hazard as 4d.6, same fix
|
|
238
|
+
**4d.7. Regenerate the Hermes/Pi plugin manifests** (gh#1954): `node scripts/build/harness-manifests.mjs`, then `npm run check:harness-manifests-fresh` to confirm. Same hazard as 4d.6, same fix, both plugins' `plugin.yaml` embed `version` from `.claude-plugin/plugin.json`. Gate 32 runs pre-bump in Step 3 and only proves freshness against the PREVIOUS version; run this post-bump every cut, not just when a skill/command changed. `packages/plugins/*/plugin.yaml`, `packages/plugins/*/__init__.py`, `packages/plugins/*/hermes-mcp.yaml` (factory only), and `packages/plugins/*/prompts/*.md` ride the release commit (Step 5 stages them).
|
|
240
239
|
|
|
241
240
|
**4e. Release docs + team notes** (gated, not optional): review the entry
|
|
242
|
-
files the release touches (root README/CHANGELOG, per-package READMEs
|
|
243
|
-
content currency is YOUR judgment; the gate only proves presence), then
|
|
241
|
+
files the release touches (root README/CHANGELOG, per-package READMEs, content currency is YOUR judgment; the gate only proves presence), then
|
|
244
242
|
generate the team notes and land them IN the release commit:
|
|
245
243
|
|
|
246
244
|
```bash
|
|
@@ -248,7 +246,7 @@ node scripts/release/generate-release-notes.mjs --version X.Y.Z --write # →
|
|
|
248
246
|
node scripts/release/check-release-docs.mjs --version X.Y.Z # must print OK
|
|
249
247
|
```
|
|
250
248
|
|
|
251
|
-
`check-release-docs` is enforced twice downstream
|
|
249
|
+
`check-release-docs` is enforced twice downstream, the
|
|
252
250
|
`release-pretag-docs-gate` Claude Code hook (adia-forge plugin) denies
|
|
253
251
|
tag-creation/tag-push/publish-dispatch commands until it passes, and
|
|
254
252
|
`.githooks/pre-push` blocks release-tag pushes the same way (v0.8.4
|
|
@@ -256,27 +254,27 @@ shipped tarballs with unpromoted `[Unreleased]` CHANGELOG headers because
|
|
|
256
254
|
this class of check ran only after tagging).
|
|
257
255
|
|
|
258
256
|
**4-resume. Resuming a cut that died mid-Step-4** (v0.8.10 and v0.8.29 hit
|
|
259
|
-
this live). Two shapes, told apart by the lockstep versions
|
|
257
|
+
this live). Two shapes, told apart by the lockstep versions, `release-pack.mjs`
|
|
260
258
|
checks them itself at startup (gh#765):
|
|
261
259
|
|
|
262
260
|
- **Complete bump (all 13 `package.json` versions at the cut version):**
|
|
263
261
|
just RE-RUN the same `release-pack.mjs` command. It detects the half-cut
|
|
264
262
|
tree before the pre-flight, prints a `[resume]` banner, validates the
|
|
265
263
|
hygiene gates at the CUT version (no more gate-24 false-fail at the
|
|
266
|
-
previous version), and skips promote/stub/bump in Step 4
|
|
264
|
+
previous version), and skips promote/stub/bump in Step 4, re-running only
|
|
267
265
|
the idempotent substeps (lockfile, catalog, 4e notes, 4f coverage, 4g
|
|
268
266
|
hygiene) and continuing to Step 5. The `promote-unreleased.mjs`
|
|
269
267
|
"already has ## [X.Y.Z]" hard-error can no longer be reached on this path.
|
|
270
|
-
Do NOT hand-edit CHANGELOGs back to `[Unreleased]` first
|
|
268
|
+
Do NOT hand-edit CHANGELOGs back to `[Unreleased]` first, the resumed run
|
|
271
269
|
expects the promoted state and re-proves it with the
|
|
272
270
|
unpromoted-`[Unreleased]` guard.
|
|
273
|
-
- **Mixed versions (some packages bumped, some not
|
|
271
|
+
- **Mixed versions (some packages bumped, some not, a mid-bump abort):**
|
|
274
272
|
the orchestrator hard-stops listing the stragglers and will neither resume
|
|
275
273
|
nor roll back. Recover by hand: restore the tree (`git status` /
|
|
276
274
|
`git checkout -- <files>`, or finish the bump with `bump.mjs` directly),
|
|
277
275
|
then re-run. To verify the promotion state along the way, the
|
|
278
276
|
authoritative gate is `node scripts/release/check-release-docs.mjs
|
|
279
|
-
--version X.Y.Z
|
|
277
|
+
--version X.Y.Z`, it covers every lockstep package (including the nested
|
|
280
278
|
`a2ui/*` and `plugins/*` paths a shallow `packages/*` glob misses) and
|
|
281
279
|
fails on any leftover `[Unreleased]` content or missing `[X.Y.Z]` heading;
|
|
282
280
|
it will still flag the not-yet-generated `docs/ops/releases/vX.Y.Z.md`, which
|
|
@@ -285,36 +283,35 @@ checks them itself at startup (gh#765):
|
|
|
285
283
|
The fully manual fallback (both shapes, if the orchestrator itself is
|
|
286
284
|
suspect) remains the standalone pieces the Mechanization section names, in
|
|
287
285
|
this order. **Stubs complete BEFORE 4f** (the v0.8.32 resume proved the
|
|
288
|
-
ordering): the bump-complete marker cannot see whether insert-stub ran
|
|
286
|
+
ordering): the bump-complete marker cannot see whether insert-stub ran, a
|
|
289
287
|
stub package's `[Unreleased]` is empty, so every guard passes with its
|
|
290
288
|
`[X.Y.Z]` section entirely absent; running the coverage `--fix` before the
|
|
291
289
|
stub sections exist leaves it nothing to append to, and the gap resurfaces
|
|
292
290
|
as F-N1 warns at the push boundary, costing a tag move:
|
|
293
291
|
|
|
294
292
|
```bash
|
|
295
|
-
node scripts/release/assemble-changelog-fragments.mjs # 4a-pre (idempotent
|
|
293
|
+
node scripts/release/assemble-changelog-fragments.mjs # 4a-pre (idempotent, safe to re-run; no-op if already assembled)
|
|
296
294
|
node "<plugin-root>/skills/package-release/scripts/insert-stub.mjs" \
|
|
297
295
|
--version X.Y.Z --date YYYY-MM-DD --previous-version X.Y.Z-1 \
|
|
298
|
-
--substantive "<one-line>" --xref "<anchor>" --packages <missing-stubs> # 4a-stub
|
|
296
|
+
--substantive "<one-line>" --xref "<anchor>" --packages <missing-stubs> # 4a-stub, FIRST, only the missing ones (hard-errors on existing sections)
|
|
299
297
|
node "<plugin-root>/skills/package-release/scripts/bump.mjs" --from X.Y.Z-1 --to X.Y.Z # 4b (skip if versions already moved)
|
|
300
298
|
npm install --package-lock-only --no-audit --no-fund # 4c
|
|
301
299
|
npm run check:lockstep # 4d
|
|
302
|
-
node scripts/build/derive-genui-catalog.mjs # 4d.5
|
|
303
|
-
node scripts/build/codex-manifests.mjs # 4d.6
|
|
304
|
-
node scripts/build/harness-manifests.mjs # 4d.7
|
|
305
|
-
node scripts/release/check-release.mjs --pending-version X.Y.Z --fix # 4f
|
|
300
|
+
node scripts/build/derive-genui-catalog.mjs # 4d.5, catalogId carries the bumped version (gh#617)
|
|
301
|
+
node scripts/build/codex-manifests.mjs # 4d.6, Codex manifest version carries the bumped version (gh#1899)
|
|
302
|
+
node scripts/build/harness-manifests.mjs # 4d.7, Hermes/Pi manifest version carries the bumped version (gh#1954)
|
|
303
|
+
node scripts/release/check-release.mjs --pending-version X.Y.Z --fix # 4f, AFTER the stubs exist
|
|
306
304
|
node scripts/release/generate-release-notes.mjs --version X.Y.Z --write # 4e
|
|
307
305
|
node scripts/release/check-release-docs.mjs --version X.Y.Z # 4e gate
|
|
308
|
-
node scripts/release/check-cut-hygiene.mjs --version X.Y.Z # 4g
|
|
309
|
-
# then Step 5 by hand (branch, stage, commit)
|
|
310
|
-
# trip-wire runs on the staged set exactly as on a normal cut, don't skip it
|
|
311
|
-
# and Step 5.7 via pr-bridge.mjs
|
|
306
|
+
node scripts/release/check-cut-hygiene.mjs --version X.Y.Z # 4g, post-bump proof
|
|
307
|
+
# then Step 5 by hand (branch, stage, commit), Step 5.5's freshness
|
|
308
|
+
# trip-wire runs on the staged set exactly as on a normal cut, don't skip it, # and Step 5.7 via pr-bridge.mjs
|
|
312
309
|
```
|
|
313
310
|
|
|
314
|
-
## §Step 5
|
|
311
|
+
## §Step 5, Stage and commit (on a release branch)
|
|
315
312
|
|
|
316
313
|
The release commit lands via PR, never a direct push to `main` (repo
|
|
317
|
-
policy, operator ruling 2026-07-12
|
|
314
|
+
policy, operator ruling 2026-07-12, everything ships PR-first). Branch
|
|
318
315
|
FIRST, then stage. Defensively clear the index, then stage by explicit
|
|
319
316
|
allowlist (never `git add -A`; if peers may have pre-staged files,
|
|
320
317
|
`git commit -o <paths>` also bypasses a polluted index):
|
|
@@ -331,9 +328,9 @@ git -C "$REPO" add package-lock.json packages/*/package.json packages/*/CHANGELO
|
|
|
331
328
|
git -C "$REPO" diff --cached --stat | tail -3 # count must match the allowlist
|
|
332
329
|
```
|
|
333
330
|
|
|
334
|
-
Commit shape: `chore(release): vX.Y.Z lockstep
|
|
331
|
+
Commit shape: `chore(release): vX.Y.Z lockstep, <summary>` with substantive scope per package, ride-along stub list, any `Excluded, in-flight:` lines, and the pasted gate summary.
|
|
335
332
|
|
|
336
|
-
## §Step 5.5
|
|
333
|
+
## §Step 5.5, Pre-commit freshness trip-wire
|
|
337
334
|
|
|
338
335
|
After `git add`, before `git commit`, re-run the three freshness gates against staged state:
|
|
339
336
|
|
|
@@ -341,23 +338,22 @@ After `git add`, before `git commit`, re-run the three freshness gates against s
|
|
|
341
338
|
node scripts/build/components.mjs --verify && npm run check:chunks-fresh && npm run check:embeddings-fresh
|
|
342
339
|
```
|
|
343
340
|
|
|
344
|
-
Drift here means a regen output was left out of the allowlist
|
|
341
|
+
Drift here means a regen output was left out of the allowlist, stage it and re-run. <2s now vs ~5min of tag-move recovery after CI catches it. Do not proceed to tag with drift.
|
|
345
342
|
|
|
346
|
-
## §Step 5.6
|
|
343
|
+
## §Step 5.6, Unstaged-tracked-files guard (`release-pack.mjs`, gh#2473)
|
|
347
344
|
|
|
348
345
|
`release-pack.mjs`'s Step 5 mechanizes this: right after its own `git add`
|
|
349
346
|
(the allowlist above, as automated), it runs `git status --porcelain` and
|
|
350
|
-
fails the cut if any tracked file is still modified-in-the-worktree
|
|
351
|
-
proof the allowlist covered everything bump.mjs / cut-hygiene touched this
|
|
347
|
+
fails the cut if any tracked file is still modified-in-the-worktree, proof the allowlist covered everything bump.mjs / cut-hygiene touched this
|
|
352
348
|
cut, not just what §Step 5.5's three named freshness gates happen to check.
|
|
353
349
|
The allowlist itself went stale five times (gh#1198, gh#1899, gh#1954,
|
|
354
|
-
gh#2473, gh#3342
|
|
355
|
-
this guard is generic rather than another named file
|
|
350
|
+
gh#2473, gh#3342, most recently `icons-cdn.js`'s PACKAGE_VERSION pin), so
|
|
351
|
+
this guard is generic rather than another named file, it stays the
|
|
356
352
|
fallback for anything below. **The PINNED_REFS-covered subset of the
|
|
357
353
|
allowlist can no longer drift this way at all** (gh#3361): `release-pack.mjs`
|
|
358
354
|
now derives those specific entries straight from `bump.mjs`'s own
|
|
359
355
|
`PINNED_REFS`/`REPO_PINNED_REFS` tables (`pinnedRefFiles()`) instead of
|
|
360
|
-
hand-listing the same paths a second time
|
|
356
|
+
hand-listing the same paths a second time, a new pinned file in `bump.mjs`
|
|
361
357
|
is automatically a new allowlist entry, no second edit needed. Everything
|
|
362
358
|
NOT PINNED_REFS-covered (roster `package.json`/`CHANGELOG.md`, and the Step
|
|
363
359
|
4d.5-4d.8 derived catalog/manifest/dist outputs) is still hand-listed and
|
|
@@ -365,10 +361,10 @@ still relies on this guard as the safety net. A manual cut should run the
|
|
|
365
361
|
equivalent check by hand: `git status --porcelain` after staging must be
|
|
366
362
|
empty of `M`/`D` lines.
|
|
367
363
|
|
|
368
|
-
## §Step 5.7
|
|
364
|
+
## §Step 5.7, Release PR: push the branch, merge, re-baseline
|
|
369
365
|
|
|
370
366
|
The release commit reaches `main` through the standard PR flow. Mechanized
|
|
371
|
-
form (preferred
|
|
367
|
+
form (preferred, `pr-bridge.mjs` pushes, opens the PR, polls, merges ONLY
|
|
372
368
|
when every non-fail-soft check is green AND zero review threads are
|
|
373
369
|
unresolved AND no review requests changes; any other state stops with the
|
|
374
370
|
evidence, never force-merges):
|
|
@@ -389,78 +385,77 @@ git -C "$REPO" checkout main && git -C "$REPO" pull
|
|
|
389
385
|
```
|
|
390
386
|
|
|
391
387
|
Post-merge fixes land as follow-up commits to the SAME release PR (or a
|
|
392
|
-
second PR merged before tagging)
|
|
388
|
+
second PR merged before tagging): the tag point below is always `main`'s
|
|
393
389
|
post-merge HEAD, so anything merged before tagging ships in the tarball.
|
|
394
390
|
If unrelated PRs merged between yours and the tag step, that is fine: tag
|
|
395
391
|
at HEAD is the invariant, and the window closes at the tag.
|
|
396
392
|
|
|
397
393
|
## §Single authorization + evidence log (operator ruling 2026-07-17)
|
|
398
394
|
|
|
399
|
-
The operator's initiating instruction covers the whole cycle
|
|
395
|
+
The operator's initiating instruction covers the whole cycle, no per-step re-confirmation (this replaced the 4-checkpoint sign-off model after the v0.8.5 cut spent ~40 minutes on approval relays while every real protection fired deterministically). The evidence blocks the checkpoints used to gate on still PRINT, as a running log: the audit trail is unchanged; only the waiting is gone:
|
|
400
396
|
|
|
401
397
|
| Evidence logged before | Content | Why it's still printed |
|
|
402
398
|
| --- | --- | --- |
|
|
403
399
|
| Tagging (Step 6) | The planned tag list (umbrella + 10 per-package) | The log line a recovery diagnoses from |
|
|
404
|
-
| Pushing (Step 8) | The Step 7 F-N1 output + tag list + `origin/main..HEAD` count | F-N1's first real evidence
|
|
400
|
+
| Pushing (Step 8) | The Step 7 F-N1 output + tag list + `origin/main..HEAD` count | F-N1's first real evidence, and its ERROR path still hard-stops unconditionally |
|
|
405
401
|
| Publishing (Step 9) | The current registry snapshot (versions + `dist-tags.latest`) | Ordering is verified against what's LIVE, mechanically |
|
|
406
402
|
| Deploying (Step 10) | The `deploy-site.yml` dispatch (never a raw rsync) | The workflow carries its own GitHub-environment human gate |
|
|
407
403
|
|
|
408
|
-
`release-pack.mjs --go` auto-confirms all of these; the granular `--yes` / `--push` / `--publish` flags remain for cautious manual runs and prompt interactively when absent. **Two rules no flag or instruction wording skips:** an F-N1 *error* hard-stops before the push step exists at all, and a cosmetic F-N1 *warn* refuses auto-confirmation at the push boundary (with Step 4f mechanized, a warn appearing at Step 7 means something novel
|
|
404
|
+
`release-pack.mjs --go` auto-confirms all of these; the granular `--yes` / `--push` / `--publish` flags remain for cautious manual runs and prompt interactively when absent. **Two rules no flag or instruction wording skips:** an F-N1 *error* hard-stops before the push step exists at all, and a cosmetic F-N1 *warn* refuses auto-confirmation at the push boundary (with Step 4f mechanized, a warn appearing at Step 7 means something novel, investigate, don't loop enrichment PRs).
|
|
409
405
|
|
|
410
|
-
## §Step 4f
|
|
406
|
+
## §Step 4f, Pre-tag coverage `--fix` (the retag-loop killer)
|
|
411
407
|
|
|
412
|
-
After the bump + lockfile, run the AUTHORITATIVE F-N1 matcher against the working tree
|
|
408
|
+
After the bump + lockfile, run the AUTHORITATIVE F-N1 matcher against the working tree, same code, same `changelogMentions` patterns, every roster package, and let it append verified Maintenance bullets for any changed-but-unmentioned directory:
|
|
413
409
|
|
|
414
410
|
```bash
|
|
415
411
|
node scripts/release/check-release.mjs --pending-version X.Y.Z --fix
|
|
416
412
|
```
|
|
417
413
|
|
|
418
|
-
Stage its CHANGELOG edits into the release commit (the Step-5 allowlist already covers `CHANGELOG.md`). It re-verifies its own output with the same matcher before writing
|
|
414
|
+
Stage its CHANGELOG edits into the release commit (the Step-5 allowlist already covers `CHANGELOG.md`). It re-verifies its own output with the same matcher before writing, a `--fix` that doesn't satisfy the checker is a hard error, not a silent pass. (The former `check:changelog-coverage` gate, a different matcher and a 9-package roster missing the 2 plugins, cost the v0.8.5 cut 3 enrichment PRs and 3 tag rewrites after "coverage clean" at cut time; it was deleted 2026-07-19, so `check-release.mjs --pending-version` is now the only pre-tag coverage check.)
|
|
419
415
|
|
|
420
|
-
## §Step 6
|
|
416
|
+
## §Step 6, Tag
|
|
421
417
|
|
|
422
|
-
Log the planned tag list (evidence table above), then tag **at `main`'s post-merge HEAD** (post-bump fixes belong in the tarball; the window's last merge is the tag point
|
|
418
|
+
Log the planned tag list (evidence table above), then tag **at `main`'s post-merge HEAD** (post-bump fixes belong in the tarball; the window's last merge is the tag point, exception: batch push tags each version at its own release-merge SHA):
|
|
423
419
|
|
|
424
420
|
```bash
|
|
425
421
|
node "<plugin-root>/skills/package-release/scripts/tag-lockstep.mjs" \
|
|
426
422
|
--version X.Y.Z # umbrella vX.Y.Z + 10 <pkg>-vX.Y.Z (8 npm + 2 plugins)
|
|
427
423
|
```
|
|
428
424
|
|
|
429
|
-
## §Step 7
|
|
425
|
+
## §Step 7, F-N1 release trip-wire
|
|
430
426
|
|
|
431
427
|
```bash
|
|
432
428
|
node scripts/release/check-release.mjs --all-pending
|
|
433
429
|
```
|
|
434
430
|
|
|
435
|
-
Per-package tags must be `✓ clean`; the umbrella-tag error is expected noise. **Expected outcome: clean
|
|
431
|
+
Per-package tags must be `✓ clean`; the umbrella-tag error is expected noise. **Expected outcome: clean, Step 4f already ran the same matcher pre-PR.** A warn here means something changed between 4f and the tag (an interleaved merge, a 4f skip), investigate the cause, then recover via [`changelog-discipline.md`](changelog-discipline.md) §F-N1: fix the entry, land it as a follow-up commit through the PR flow (`--amend` is not possible: the release commit is already merged), delete + re-create the tags at the new post-merge SHA, re-run.
|
|
436
432
|
|
|
437
|
-
## §Step 8
|
|
433
|
+
## §Step 8, Push tags
|
|
438
434
|
|
|
439
|
-
`main` is already on the remote (the release PR merged in Step 5.7)
|
|
440
|
-
only the tags push here. Log the Step 7 F-N1 results + the tag list
|
|
435
|
+
`main` is already on the remote (the release PR merged in Step 5.7), only the tags push here. Log the Step 7 F-N1 results + the tag list
|
|
441
436
|
(evidence table above) + confirm `git rev-list --count origin/main..HEAD`
|
|
442
|
-
is 0 (a non-zero count means local commits bypassed the PR flow
|
|
437
|
+
is 0 (a non-zero count means local commits bypassed the PR flow, stop
|
|
443
438
|
and route them through a PR first); then:
|
|
444
439
|
|
|
445
440
|
The package list comes from the roster, never a hand list. This block used to
|
|
446
|
-
enumerate the names inline and silently went stale
|
|
441
|
+
enumerate the names inline and silently went stale, it pushed 11 tags against
|
|
447
442
|
a 14-package roster (`agent`, `persona` and `a2ui-protocol-mcp` missing), which
|
|
448
443
|
is three packages that would simply never publish.
|
|
449
444
|
|
|
450
445
|
```bash
|
|
451
446
|
PKGS=$(node -e "import('<plugin-root>/skills/package-release/scripts/package-paths.mjs')
|
|
452
447
|
.then(m => console.log(m.PACKAGE_ROSTER.filter(p => p.lockstep !== false).map(p => p.name).join(' ')))")
|
|
453
|
-
echo "$PKGS" # log it
|
|
448
|
+
echo "$PKGS" # log it: this IS the tag list evidence
|
|
454
449
|
|
|
455
450
|
for p in $PKGS; do
|
|
456
|
-
git -C "$REPO" push origin "${p}-vX.Y.Z" # ONE tag per push
|
|
451
|
+
git -C "$REPO" push origin "${p}-vX.Y.Z" # ONE tag per push, batched multi-tag
|
|
457
452
|
done # pushes drop the create event (Scenario 7)
|
|
458
453
|
git -C "$REPO" push origin vX.Y.Z # umbrella last; triggers nothing
|
|
459
454
|
```
|
|
460
455
|
|
|
461
|
-
## §Step 9
|
|
456
|
+
## §Step 9, Publish
|
|
462
457
|
|
|
463
|
-
Log the current registry snapshot (per-package versions + `dist-tags.latest`) before dispatching. For batch pushes, verify ordering against that snapshot: **oldest version publishes and settles first
|
|
458
|
+
Log the current registry snapshot (per-package versions + `dist-tags.latest`) before dispatching. For batch pushes, verify ordering against that snapshot: **oldest version publishes and settles first**, `npm dist-tag latest` is set by publish order. Then:
|
|
464
459
|
|
|
465
460
|
```bash
|
|
466
461
|
node "<plugin-root>/skills/package-release/scripts/dispatch-publish.mjs" \
|
|
@@ -470,7 +465,7 @@ node "<plugin-root>/skills/package-release/scripts/dispatch-publish.mjs" \
|
|
|
470
465
|
Wait for the workflows to settle, then verify against the **registry**, never the workflow's green check:
|
|
471
466
|
|
|
472
467
|
```bash
|
|
473
|
-
# The name list comes from PACKAGE_ROSTER, never a hand-typed loop
|
|
468
|
+
# The name list comes from PACKAGE_ROSTER, never a hand-typed loop: this loop
|
|
474
469
|
# WAS hand-typed and went stale the moment ADR-0048 changed the roster (it still
|
|
475
470
|
# named the six pre-split a2ui packages and omitted a2ui-protocol-mcp, so a
|
|
476
471
|
# "verified" cut would have skipped checking the package most likely to be
|
|
@@ -487,18 +482,17 @@ npm view @adia-ai/web-components dist-tags.latest # must equal X.Y.Z
|
|
|
487
482
|
Zero workflows fired after a tag push → [`recovery-paths.md`](recovery-paths.md) §Scenario 7.
|
|
488
483
|
|
|
489
484
|
**npm's async staged-publish path (gh#3342):** a large tarball can take up to
|
|
490
|
-
~25 minutes to become visible on `npm view` after npm accepts it
|
|
491
|
-
`release-pack.mjs`'s own Step 9 poll accounts for this (`REGISTRY_POLL_MINUTES`,
|
|
485
|
+
~25 minutes to become visible on `npm view` after npm accepts it, `release-pack.mjs`'s own Step 9 poll accounts for this (`REGISTRY_POLL_MINUTES`,
|
|
492
486
|
default 30, up from the 10-minute window the v0.8.59 cut exceeded with every
|
|
493
487
|
publish run green). A re-dispatch attempted while a package is in that state
|
|
494
488
|
fails its `npm publish` step with `npm error code E409` ("Cannot publish over
|
|
495
|
-
previously staged version")
|
|
489
|
+
previously staged version"): that is the staged-not-lost signal, never a real
|
|
496
490
|
failure; release-pack's Step 9 detects it (the failing run's own log) and polls
|
|
497
491
|
longer instead of hard-failing. See [`recovery-paths.md`](recovery-paths.md)
|
|
498
492
|
§Scenario 9 for manual recovery, including resuming at Step 10 only
|
|
499
493
|
(`--from-step10`) without re-running the pre-flight or re-tagging.
|
|
500
494
|
|
|
501
|
-
## §Step 10
|
|
495
|
+
## §Step 10, GH releases + site deploy dispatch
|
|
502
496
|
|
|
503
497
|
```bash
|
|
504
498
|
for pkg in $(node -e '
|
|
@@ -515,7 +509,7 @@ gh workflow run "Deploy site (ui-kit.exe.xyz)" --repo adiahealth/gen-ui-kit --re
|
|
|
515
509
|
|
|
516
510
|
Deploy discipline (the release tenant of the demo-site host; VM/service ops belong to the deploy skill, `site-deployment`):
|
|
517
511
|
|
|
518
|
-
- `deploy-site.yml` owns build → pre-flight verify → snapshot → rsync → post-deploy verify → auto-rollback; it builds from `main`, so the release commit must already be merged (§Step 5.7 guarantees this). A raw local rsync bypasses every one of those gates
|
|
512
|
+
- `deploy-site.yml` owns build → pre-flight verify → snapshot → rsync → post-deploy verify → auto-rollback; it builds from `main`, so the release commit must already be merged (§Step 5.7 guarantees this). A raw local rsync bypasses every one of those gates, `release-pack.mjs` dispatches the workflow (never rsyncs directly) behind its own confirm (H1, forge-campaign gh#268 audit: the script had drifted from this already-documented procedure).
|
|
519
513
|
- **Verify deployed FILES, never SPA routes.** The docs site returns HTTP 200 + the same ~5 KB shell for *every* path; an unmatched route renders blank with no error. Curl a content file and grep for real bytes:
|
|
520
514
|
|
|
521
515
|
```bash
|
|
@@ -523,7 +517,7 @@ Deploy discipline (the release tenant of the demo-site host; VM/service ops belo
|
|
|
523
517
|
curl -s https://ui-kit.exe.xyz/<this-cycle's-content-file> | grep -q "<unique string>" && echo OK
|
|
524
518
|
```
|
|
525
519
|
|
|
526
|
-
- Any docs **route** cited to the operator or in notes must exist in `site/sitemap.json` (`grep '"path":'`)
|
|
520
|
+
- Any docs **route** cited to the operator or in notes must exist in `site/sitemap.json` (`grep '"path":'`), a plausible-looking route that isn't in the sitemap renders blank.
|
|
527
521
|
|
|
528
522
|
**Milestone close (ADR-0103, gh#2729, dated addendum 2026-09-01).** Every
|
|
529
523
|
lockstep cut has an open GitHub Milestone named `vX.Y.Z` (one per cut,
|
|
@@ -537,7 +531,7 @@ gh api -X PATCH "repos/adiahealth/gen-ui-kit/milestones/$number" -f state=closed
|
|
|
537
531
|
```
|
|
538
532
|
|
|
539
533
|
Any issue still open in that milestone at close time either ships anyway
|
|
540
|
-
(re-tag it into the milestone that actually shipped it
|
|
534
|
+
(re-tag it into the milestone that actually shipped it, never leave an
|
|
541
535
|
already-shipped issue's milestone wrong) or slips to the next milestone
|
|
542
536
|
(re-tag now, don't leave the closed milestone showing open issues). Create
|
|
543
537
|
the NEXT cut's milestone here too, so scheduling work for it doesn't wait on
|
|
@@ -549,11 +543,11 @@ gh api repos/adiahealth/gen-ui-kit/milestones -f title="vNEXT.Y.Z" -f state=open
|
|
|
549
543
|
|
|
550
544
|
Any Step-2 stashes: `git stash pop`; flag conflicts to the operator.
|
|
551
545
|
|
|
552
|
-
## §Step 11
|
|
546
|
+
## §Step 11, Author release notes (default)
|
|
553
547
|
|
|
554
|
-
Always author notes at end-of-cycle without being asked
|
|
548
|
+
Always author notes at end-of-cycle without being asked, context is freshest now. Single version → [`notes-authoring.md`](notes-authoring.md); ≥2 versions since the last broadcast → its §Rollup section. Surface the draft inline for copy-paste; the operator owns posting. Skip only on an explicit "no notes".
|
|
555
549
|
|
|
556
|
-
## §Step 12
|
|
550
|
+
## §Step 12, Restore the dev layout
|
|
557
551
|
|
|
558
552
|
The cut runs under `npm ci` (Step 1's layout check, gate 9), and that leaves
|
|
559
553
|
`node_modules` npm-shaped. The dev server refuses to start on that tree:
|
|
@@ -572,18 +566,17 @@ gitignored). Live cost of skipping this: the v0.8.55 cut (2026-08-28) left the
|
|
|
572
566
|
operator's primary checkout unable to run `npm run dev` until the layout was
|
|
573
567
|
restored by hand.
|
|
574
568
|
|
|
575
|
-
## §The 0.8.38 cut (the clean-world cut
|
|
569
|
+
## §The 0.8.38 cut (the clean-world cut, delete this section after it lands)
|
|
576
570
|
|
|
577
571
|
The first cut AFTER the estate-split bridge. Pre-conditions, all verifiable
|
|
578
572
|
before Step 1:
|
|
579
573
|
|
|
580
|
-
1. **The shim-deletion follow-up PR has MERGED** (the §0.8.37 follow-up
|
|
574
|
+
1. **The shim-deletion follow-up PR has MERGED** (the §0.8.37 follow-up, that
|
|
581
575
|
section deleted itself with the same PR, as designed:
|
|
582
576
|
`packages/shims/` gone, roster shim rows gone, the six `publish-a2ui-*.yml`
|
|
583
577
|
workflows gone, `check:shims`/`check-shim-bridges` retired). The roster file
|
|
584
|
-
is the member count
|
|
585
|
-
2. **Deprecation pointers have been live for the full inter-cut window
|
|
586
|
-
`npm info <old-name> deprecated` returns the pointer text for all six names.
|
|
578
|
+
is the member count, never transcribe it.
|
|
579
|
+
2. **Deprecation pointers have been live for the full inter-cut window**, `npm info <old-name> deprecated` returns the pointer text for all six names.
|
|
587
580
|
This is the stated policy for the one-cycle bridge: caret-floating consumers
|
|
588
581
|
landed on the shims at 0.8.37, were pointed at the successors the entire
|
|
589
582
|
window, and hard-stop only now. If the window was shorter than ~a week of
|
|
@@ -591,37 +584,37 @@ before Step 1:
|
|
|
591
584
|
deleting the bridge out from under them.
|
|
592
585
|
3. **`fix-old-names` has swept the known consumer repos** against the shim
|
|
593
586
|
names (the closeout half of the rename wave + split).
|
|
594
|
-
4. Whatever landed between cuts rides along normally
|
|
587
|
+
4. Whatever landed between cuts rides along normally, as of authoring, the
|
|
595
588
|
queued candidates are the directory wave (gh#1244, npm-invisible), the
|
|
596
589
|
catalog tiers (gh#1243, new `@adia-ai/a2ui` subpath `./catalog`), and the
|
|
597
|
-
factory MCP server (gh#1241, a third `adia-mcp` subcommand
|
|
590
|
+
factory MCP server (gh#1241, a third `adia-mcp` subcommand, NOT a new
|
|
598
591
|
package). None changes the roster; if one does by then, the roster file
|
|
599
592
|
already reflects it and the gates enforce it.
|
|
600
593
|
|
|
601
|
-
**In the release commit:** nothing estate-split-specific remains
|
|
594
|
+
**In the release commit:** nothing estate-split-specific remains: this is a
|
|
602
595
|
normal cut. If gh#1241 landed, the factory `.mcp.json` MAY additionally
|
|
603
|
-
register `adia-factory` (`["-y", "@adia-ai/mcp@0.8.38", "factory"]`)
|
|
596
|
+
register `adia-factory` (`["-y", "@adia-ai/mcp@0.8.38", "factory"]`), an
|
|
604
597
|
addition, not a flip.
|
|
605
598
|
|
|
606
599
|
**After publish:** the standard registry verify, plus one split-closure check:
|
|
607
600
|
`npm view @adia-ai/a2ui-compose versions` should END at 0.8.37 (the shim's one
|
|
608
|
-
and only publish)
|
|
601
|
+
and only publish), a 0.8.38 appearing under any retired name means a workflow
|
|
609
602
|
survived the follow-up PR; kill the tag and investigate before anything else.
|
|
610
603
|
|
|
611
604
|
Delete this section in the same PR that closes the split's tracking record.
|
|
612
605
|
|
|
613
606
|
## §Variant A shortcut
|
|
614
607
|
|
|
615
|
-
Peer pre-cut the release commit: Step 1 (confirm HEAD is the `release(*): vX.Y.Z` commit) → Step 2 → Step 3 → skip 4–5 → resume at Step 6. The peer's release commit must already be MERGED to `main` via its PR before tagging (invariant 3
|
|
608
|
+
Peer pre-cut the release commit: Step 1 (confirm HEAD is the `release(*): vX.Y.Z` commit) → Step 2 → Step 3 → skip 4–5 → resume at Step 6. The peer's release commit must already be MERGED to `main` via its PR before tagging (invariant 3, tag at post-merge HEAD, never at an unpushed local commit); an unmerged pre-cut commit goes through Step 5.7 first, it doesn't shortcut past it.
|
|
616
609
|
|
|
617
|
-
## §Plugin cache
|
|
610
|
+
## §Plugin cache, content between cuts is invisible until the next bump
|
|
618
611
|
|
|
619
|
-
The installed Claude Code plugin cache is keyed by the version string in `.claude-plugin/plugin.json
|
|
612
|
+
The installed Claude Code plugin cache is keyed by the version string in `.claude-plugin/plugin.json`, `/reload-plugins` only refreshes when that string CHANGES. Lockstep forbids a solo plugin bump, so any skill/agent/doc content merged to `main` between cuts does NOT reach the installed plugin until the next lockstep cut (or a deliberate manual `rsync` of the plugin dir over `~/.claude/plugins/cache/<marketplace>/<plugin>/<version>/`). Consequences:
|
|
620
613
|
|
|
621
|
-
- Shipping plugin-content changes mid-cycle is fine
|
|
614
|
+
- Shipping plugin-content changes mid-cycle is fine, just know they're repo-only until the next cut; don't report them as "live in the harness".
|
|
622
615
|
- The v0.8.5 case (PR #304): a full release-process rewrite merged with no bump, and the installed plugin silently kept executing the RETIRED procedure until a manual cache sync. If the merged content changes operational behavior an active session depends on, do the manual sync immediately and say so.
|
|
623
|
-
- At cut time nothing extra is needed
|
|
616
|
+
- At cut time nothing extra is needed: the lockstep bump itself is what invalidates the cache.
|
|
624
617
|
|
|
625
618
|
## §When to abort
|
|
626
619
|
|
|
627
|
-
Stop and surface to the operator when: a gate fails outside the documented recoveries; F-N1 reports >1 warn per package tag or any non-umbrella error; the release-commit candidate fails `check:demo-shells` / `check:lockstep` / `check:embeddings-fresh` (→ [`recovery-paths.md`](recovery-paths.md) §Scenario 4); uncommitted files stay unclassifiable after diffing; or a publish workflow fails E404/E401 (npm-token rotation
|
|
620
|
+
Stop and surface to the operator when: a gate fails outside the documented recoveries; F-N1 reports >1 warn per package tag or any non-umbrella error; the release-commit candidate fails `check:demo-shells` / `check:lockstep` / `check:embeddings-fresh` (→ [`recovery-paths.md`](recovery-paths.md) §Scenario 4); uncommitted files stay unclassifiable after diffing; or a publish workflow fails E404/E401 (npm-token rotation, operator-owned).
|