page:docs-specs-platform-gaps-phase1-pr-body
feat(train): @fabricstack rename train 7.0.0 — packages, bins, exports, versioning, release → Artifact Registry (Phase 1 / M1) reference
Branch phase1/rename-train → staging. 46 reviewed commits (head 6c9f9eed9) + 2 docs-only commits (review-2 M8 fixes d62524d3e, and this body) over origin/staging (531975433); 3,625 files, +17,003/−8,028 at d62524d3e (gh api repos/a5c-ai/fabric/pulls/4). This is the one D10 break train of roadmap Phase 1 (docs/specs/platform-gaps/50-roadmap-workpackages.md, M1): WP-RN-05, WP-RN-06, WP-RN-07, WP-PKG-01 and WP-PKG-02 of spec 15 (docs/specs/platform-gaps/15-private-isolation-rename.md) land together, so that every consumer of the public @a5c-ai/ 6.0.x lineage sees exactly one breaking change: the scope, the bins, the exports surface and the version jump to 7.0.0 at once.
feat(train): @fabricstack rename train 7.0.0 — packages, bins, exports, versioning, release → Artifact Registry (Phase 1 / M1)
Branch phase1/rename-train → staging. 46 reviewed commits (head 6c9f9eed9) + 2 docs-only commits (review-2 M8 fixes d62524d3e, and this body) over origin/staging (531975433); 3,625 files, +17,003/−8,028 at d62524d3e (gh api repos/a5c-ai/fabric/pulls/4). This is the **one D10 break train** of roadmap Phase 1 (docs/specs/platform-gaps/50-roadmap-workpackages.md, M1): WP-RN-05, WP-RN-06, WP-RN-07, WP-PKG-01 and WP-PKG-02 of spec 15 (docs/specs/platform-gaps/15-private-isolation-rename.md) land together, so that every consumer of the public @a5c-ai/* 6.0.x lineage sees exactly one breaking change: the scope, the bins, the exports surface and the version jump to **7.0.0** at once.
What this train is
| Surface | Before (public @a5c-ai/* 6.0.x) | After (this PR) |
|---|---|---|
| Package names | 43 publishable @a5c-ai/* manifests + 8 private workspaces | **43 @fabricstack/* publishables** (spec 15 §3.1 new-name column, byte-exact; node scripts/lib/publishable-packages.cjs → 43 entries, 0 outside the scope) + 8 renamed private workspaces (@fabricstack/{memory,control-plane-sdk,control-plane-cli,admin-console,meeting-sidecar,catalog-webui,console-tui-plugins,ops-console}); the 8 @a5c-ai/genty-*-app retirement shells keep their names (§3.2). **Directories do not move** (RN-3 owns that). 4,399 import-specifier replacements in 3,193 files; lockfile regenerated, non-link nodes byte-identical to staging except the ink 6 / jsdom 30 closure (16 version changes / 27 added / 9 removed) |
| Bins | 26 names incl. duplicates and deprecation shims (babysitter, adapters, mock-harness, tasks-adapter, a5c-hooks-adapter, …) | **18 bins over 16 packages = spec 15 §3.1 set exactly**, duplicate-free (bin-collision-guard --json → 0 errors, 0 notices); 8 retired alias sources deleted; --version smoke on every bin that implements it (7.0.0 from PACKED tarballs for console-tui, orchestrator-sdk, catalog; harness-tasks now reads its manifest instead of a hard-coded 5.0.0) |
| Exports | 19 packages with maps, 24 without (bare main), one catalog/* wildcard | **Exact exports maps on all 43**, no pattern anywhere; ./package.json everywhere; bin-only packages (orchestrator, observer) carry a closed map; SDK publics ././cli/./config/./runtime/./testing deliberate and documented; generated docs/reference/package-publics.md with a drift gate; negative probes (real shipped non-exported files + synthetic dist/internal-anything) fail with ERR_PACKAGE_PATH_NOT_EXPORTED under require and import in the verifier for all 43 |
| Versioning | changesets (dead machinery: no workflow consumer), one ^0.0.180 internal range | **Lockstep 7.0.0, .changeset/ removed**, every internal edge exact-pinned, verify-manifests refuses wildcard/range/dist-tag/workspace: internal pins at file:line (fixture suite 8/8, on every PR); docs/VERSIONING.md |
| Release machinery | babysitter/<branch>/v* tags, registry.npmjs.org, NPM_TOKEN, legacy workflows | **Artifact Registry only** (https://us-central1-npm.pkg.dev/boot-464019/fabric-npm/, WIF, no stored credential): resolver TAG_PREFIX=fabric, every identity carries the registry; new publish-npm-private.yml (push main/staging/develop): resolve → packed-artifact verifier matrix (43/43, no tolerance) → WIF + google-artifactregistry-auth + npm ping → release plan → sync/verify-manifests/guards → derived wave build → 13 publish waves under candidate-<v> → published-consumer validation → single promotion → channel assertion → fabric/<branch>/v<version> tag on a5c-ai/fabric only. publish-packages-from-tag.yml (from-tag recovery), release-tags.yml, release-artifact-verifier.yml, live-stack-published.yml, fix-npm-tags.yml retargeted; G2(c)/G3 hard by default (grep -rln registry.npmjs.org .github/workflows → nothing); docs/RELEASE-RUNBOOK.md |
Invariants held throughout and re-verified at the time of this body (2026-10-04): the public repository a5c-ai/babysitter was never written to (gh api repos/a5c-ai/babysitter --jq .pushed_at → 2026-09-16T19:59:50Z, unchanged since cutover; upstream remote push URL no_push); **nothing was published** to any registry (npmjs probes of @fabricstack/{orchestrator,orchestrator-sdk,catalog,harness-sdk,smoke} → 404; the only object on AR is phase 0's @fabricstack/smoke@0.0.0-smoke.4); **no tag was created** (git ls-remote --tags origin → the 3 gke-cutover-* tags only, 0 fabric/ or babysitter/ refs); the org secret NPM_TOKEN is referenced by no workflow on this branch.
Per-WP summary
Records live under docs/specs/platform-gaps/phase1/ and are linked at the branch head.
| WP | Commits | What landed | Record |
|---|---|---|---|
| **WP-RN-05** phase-1 package renames (the full §3.1/§3.2 matrix) | 710473b8a manifests + lockfile + lockstep 7.0.0; d13367313 import-specifier sweep; 4247e4886 private-train selector/guards/tests/baseline on by default. Triage: 3ed7ac0a3, b76f636dd, f08f9365d, 99e69664f, 417a9af88, ed3fca229 (escaped-regex misses, report basenames, CLI banners, READMEs that gates assert on, prompt-template expectations) | 43 + 8 renamed in place from the spec-parsed matrix (scripts/lib/rename-spec.cjs); publishConfig = { registry: <AR> } with no access on every publishable; G1/G2(b)/G2(d)/G6 unconditional (the FABRIC_PRIVATE_TRAIN=0 opt-out would select zero packages, so it was not kept); check-package-renames rewritten against spec 15 (51 renames + 8 shells); no-double-rename baseline regenerated to the new-name column; residual @a5c-ai/ table (64 files, each justified: retirement shells, marketplace plugin ids → WP-RN-11, external @a5c-ai/compendium, guard fixtures, legacy-rejection tests) | rn-05-rename.md |
| **WP-RN-06** phase-1 binary renames + bin-collision resolution | 98f2c7f23 the §3.1 bin set, single-bin policy default; 027adc25e record. Review fixes: ed01994df runtime callers name the shipped bins; 17bd8a049 scenario-contract; fd7d3edf9 shipped SDK prompt templates invoke orchestrator; 3a057edcb console-tui from a clean install + --version, harness-tasks manifest version; a167b3631; 78df5013c | 18 bins / 16 packages, G5 end-state rules unconditional (duplicate-bin, public-train-bin, bin-not-in-spec, spec-bins-missing, drift 26=26 and 18=18); dropped bins listed per spec row; --version added to harness-mock, harness-triggers, catalog; operator's vacuous entry guard fixed; runtime bin resolution (SDK harness discovery, launch defaults, extensions sdkConfig, observer probe) moved to the shipped names; ~40 vitest suites moved to the end-state (none deleted/skipped) | rn-06-bins.md |
| **WP-PKG-02** lockstep versioning, changesets removed | 3beee69a6 (18 files, +638/−88) | git rm -r .changeset (4 tracked files); PR template / CONTRIBUTING / integrate-harness process + skill rewritten off npm run changeset; the single non-exact internal edge (library/specializations/meta/harnesses/pi/examples/package.json ^0.0.180) pinned; collectVersionDivergences rule unpinned-internal-dependency (wildcard / dist-tag / workspace: / caret / tilde / range / non-registry) with file:line output; scripts/__tests__/verify-manifests.test.mjs 8/8 and a new ci.yml publish-isolation step; docs/VERSIONING.md (D10 train-level major, why 7.0.0, rejected per-package semver) | pkg-02-versioning.md |
| **WP-PKG-01** exports exactness | 4f4d8152c exact maps on all 43, consumers off private dist paths (42 files); 0629bd780 verifier negative probes + in-repo resolver check + CI wiring; 19eb84f17 generated publics page + record. Triage/review: 1117e6993 packed gate resolves internal deps from checkout tarballs (also fixed a verifier defect: dependency tarballs deleted before dependents installed them); fb7c8b501, 8b4f959d7, 95274d2e2 strict exports-exactness on the built tree in the test job | scripts/lib/exports-map.cjs policy shared by the verifier and the PR check; verifier step exactness (default on) with data-driven probe manifests from the tarball inventory; scripts/ci/exports-exactness.cjs (dependency-free; --self-test 9/9 fixtures; tolerant scan in publish-isolation, --require-built strict scan after the last build in the test job: 43 publishable manifest(s), 6387 source file(s), 19020 specifier(s), 3305 workspace import(s) resolved, 0 finding(s)); docs/reference/package-publics.md via npm run docs:publics, drift = finding | pkg-01-exports.md |
| **CI shape** (review round 1) | f8224cae7 release-tooling tests in their own job so the test job executes its full 42-step shape; 7fdb9becd publish.yml builds the hooks leaves by their @fabricstack names + legacy-scope-template guard rule; 0efbe52fa release-tooling serialized (--test-concurrency=1), observer update probe off npmjs | The Lint, Tests, Package job had been dying at step 15 (Release tooling tests) on staging for months, so steps 16–42 had never run on any head; after the split it runs 47/47 green on every head of this branch | — |
| **WP-RN-07** release machinery retarget (versions, tags, waves, verifier → AR) | 57236a5f1 resolver + publish helpers → AR, fabric/ tags; 29722deac publish-npm-private.yml + retargeted recovery/verifier/tags/dist-tag workflows, G2(c)/G3 hard; 870b425ee RELEASE-RUNBOOK, release-pipeline, superseded banner; 5b5d33c6b, eaffe818c, d0c5e47b2, 7635c68e9 workflow-shape suites, new private-release-train suite, hard-default guard assertions, cross-platform fake-npm; 55036e19c record. Review fixes: 20ef45aa9 runbook in strict docs scope; a6c2d8bcc resolver rejection names both tag shapes, roadmap M1 literal amended; df7b195e1 --ref on every dispatch; 1159a5408 pre-merge whole-train dry-run rehearsal (--rehearsal, ci.yml job release-train-rehearsal); 1b9dd488b; 2a359be61 verify --write records the validated plan; b6fc8f4c4, 7b4cedd10 GITHUB_REF_NAME on pull_request; cb8ab8c54 helper resolves packages from the root workspaces globs (guard fixtures had shadowed 16 real names); 6c9f9eed9; d62524d3e review-2 M8 docs | TAG_PREFIX fabric, provenance fabric-release-*; RELEASE_MATRIX_SURFACES = [publish-npm-private.yml, publish-packages-from-tag.yml] (coverage gate live, 43 / 0 violations); 9 inherited FIX-010/FIX-011 workflow-shape failures rewritten to the AR train (equal or stricter); private-release-train.test.mjs 21/21; the rehearsal job found and forced the fix of **three defects the live train would have hit in wave 1** (verify --write ignored, GITHUB_REF_NAME, fixture shadowing) before anything could be published | rn-07-release.md, RELEASE-RUNBOOK.md, VERSIONING.md |
Adversarial reviews
Two independent review tracks, two rounds each, threshold 90 with every criterion ≥ 80. Both second rounds **PASS**; no blocking finding remains. The reviewers reproduced claims (packed tarballs in scratch consumers, CI job logs, comm of failing-test names against baselines, scope-normalised gateway diffs, lockfile node diffs) rather than reading records.
| Criterion | Weight | Rename train (RN-05/06, PKG-01/02): round 1 → **round 2** | Release machinery (RN-07): round 1 → **round 2** |
|---|---|---|---|
| spec-fidelity | 0.20 | → **88** | → **90** |
| build-and-test-evidence | 0.20 | → **92** | → **94** |
| exports-exactness | 0.15 | → **89** | → **93** |
| bin-safety | 0.10 | → **90** | → **92** |
| release-safety-and-isolation | 0.20 | → **92** | → **90** |
| rollback-realism | 0.15 | → **90** | → **88** |
| **Weighted** | **74 → 90** (head 78df5013c) | **87 → 91** (head 6c9f9eed9) |
Round-1 findings and their fixes, in one line each. Rename train: B1 the test job never ran past step 15 (job split, 47/47 now); M1 publish.yml built hooks leaves under the legacy template name (fixed + legacy-scope-template guard rule proven red on the old tree); M2 runtime callers spawned retired bins (0 hits now); M3 scenario-contract; M4 strict exports gate on the built tree (CI step 39, 0 findings); M5 shipped SDK prompt templates still said babysitter <cmd> (0 now, generator rewrites); M6 console-tui could not start from a clean install (ink 6 / react 19; --version → 7.0.0 from a packed install). Its one round-2 mustFix (M4b: the packed 43-package matrix had run nowhere because release-artifact-verifier.yml was disabled) was closed by WP-RN-07: the verifier is active and green on this PR (runs 37147720098, 37179946362, **37180964710**, each 43 passed / 0 failed, allowKnownFailures=false). Release machinery: M1 no pre-merge whole-train rehearsal possible (now release-train-rehearsal in ci.yml, credential-less, 13/13 waves, 43/43 dry-run publishes); M2 four workflows disabled (owner enabled them; see M8 below); M3 runbook dispatches without --ref; M4 roadmap literal fabric/staging/v7.0.0 rejected by the resolver (reconciled: staging publishes 7.0.1-staging.<sha>, fabric/main/v7.0.0 is the promotion train); M5 Docs QA misreported as inherited on two heads (corrected); M6/M7 owner actions (status below). Round-2 mustFix **M8** (docs-only): "Nothing can fire pre-merge" omitted the manual-dispatch path of the then-active legacy fix-npm-tags.yml copy — fixed in d62524d3e together with the mitigation (workflow re-disabled until Gate B).
CI evidence
**Final reviewed head 6c9f9eed9 — run 37180964707** (ci.yml, pull_request):
| Job | Result | Evidence |
|---|---|---|
| Release train rehearsal (dry-run, all packages) | **success** (job 111373287978) | proof step: waves completed: 13/13; packages dry-run-published: 43/43; publish commands: 43, 0 publish commands without --dry-run, no published line, no dist-tag add, no npmjs in any helper log; permissions: contents: read, no OIDC, no FABRIC_RELEASE_PUBLISH |
| Release tooling tests | **success** (job 111373288077) | # tests 184 / # pass 184 / # fail 0 |
| Lint, Tests, Package | **success** (job 111373288079) | 47/47 steps, incl. Binary rename guardrail (18 bins / 16 packages), Metapackage shim, Architecture boundary gate, SDK 2345 passed / 9 skipped, tasks 1085, hooks-core 431 + 13 leaf suites, harness-core PTY 985, extensions 87, genty-core 248, agent-runtime-platform 1700, console-tui / agent-comm / adapters-ui release verification, strict exports exactness 0 findings |
| Publish-isolation guards (G1-G6, no-double-rename) | **success** (job 111373288114) | guard self-test 16/16 + scan 0 findings; publish-guards 17/17; verify-manifests fixture 8/8; package-rename guardrail 51 + 8; exports-exactness self-test + tolerant scan + suite; no-double-rename 10/10 + 16/16 |
| Public-push guard, Observer Dashboard, Workspace Coverage | **success** | — |
| Docs QA, Gateway Node engine floor (22), (22.13.0) | failure — **inherited**, see below | — |
**Verifier — run 37180964710** (release-artifact-verifier.yml, pull_request, 6c9f9eed9): **success**; Verify packed artifacts with --exactness, allow_known_failures=false: 43 passed / 0 failed (every package packed, installed in a fresh consumer with its internal deps from checkout-packed tarballs, every declared subpath imported and type-checked, every negative probe ERR_PACKAGE_PATH_NOT_EXPORTED, every bin shebang checked and smoked).
**Docs-only head d62524d3e** (this body + review-2 M8 docs): CI run 37183179888 and verifier run 37183179892 were queued at the time of writing; the change touches two Markdown files and one node:test assertion (21/21 locally), nothing a CI job builds.
Inherited red jobs (identical on staging; not caused by this branch)
| Job | What fails | Proof it is inherited |
|---|---|---|
| Gateway Node engine floor (22) and (22.13.0) | Build adapters gateway: 62 ##[error] lines, the pre-existing TS2307 (Cannot find module '@fabricstack/catalog/catalog', 30×) + TS7006 (implicit any, 31×) set — the gateway is built before the catalog it imports; a build-order bug older than this branch | head jobs 111373288074 / 111373288031: 62 errors each; baseline run 36539167649 jobs 109310194332 / 109310194216: 62 errors each; scope-normalised (@a5c-ai/atlas → @fabricstack/catalog) sorted diff **empty** (rename-train review round 2); the staging oracle run 36638300466 (branch ci-oracle/staging-test-shape = staging + the ci.yml job split only) shows the same two red jobs |
| Docs QA | docs:lint, docs:snippets, docs:links pass ([SUCCESS] Generated static files ×2); docs:freshness fails on **7 stale generated docs**: docs/adapters/reference/04-agent-events.md, docs/harness-features-backlog/gaps/prompt-engineering/GAP-PROMPT-011.md, docs/reference-repos/README.md, docs/repo-with-babysitter-processes.md, docs/user-guide/reference/faq.md, docs/user-guide/reference/glossary.md, docs/user-guide/tutorials/advanced-multi-phase.md (76–116 days > 45) | head job 111373288051 vs baseline job 109310193973: the identical 7-entry list, only the day counts differ; the staging oracle run shows the same. (On two intermediate heads of this branch Docs QA failed earlier, in docs:links, on RELEASE-RUNBOOK cross-links — a real regression of 870b425ee, found by triage and fixed in 20ef45aa9; rn-07-release.md §5 records the correction) |
The Release tooling tests job was red on staging too (9 FIX-010/FIX-011 workflow-shape names + 1 hooks-leaf name, baseline job 109310194280 / oracle job 109644547816); WP-RN-07 rewrote those tests to the AR train, so the job is **green on this branch** (184/184) — the one inherited red this train fixes rather than carries.
M1 exit criteria (roadmap Phase 1) — status
| # | Criterion | Status |
|---|---|---|
| 1 | One staging train tagged fabric/staging/v7.0.1-staging.<sha> publishes all 43 @fabricstack/* packages to AR at that exact version in dependency waves, the staging dist-tag moves to it, and the public repo's tag namespace gains nothing | **pending publish** — this is what the merge does (below). Prepared and dry-run-proven: rehearsal 13/13 waves, 43/43 dry-run publishes on the real tree; verifier 43/43; resolver resolve --branch staging --sha <sha> → 7.0.1-staging.<sha> / staging / fabric/staging/v7.0.1-staging.<sha> / AR. The public-namespace half holds already (0 fabric/ tags anywhere, pushed_at unchanged) |
| 2 | Exports exactness: at least one non-exported deep-import probe fails per package in the verifier matrix; bin-key union duplicate-free; --version smokes pass | **met** (verifier runs 37147720098 / 37180964710: 43/43 with --exactness; bin-collision-guard 0 errors; --version → 7.0.0 from packed installs). WP-RN-06 AC2 (npm i -g of orchestrator + harness-cli from AR on a clean machine) is **pending publish**: wired as the §3.1 global-install smoke of live-stack-published.yml, runs after the first publication |
| 3 | verify-manifests fails on a wildcard internal dep fixture; .changeset/ is gone | **met** (npm run test:verify-manifests 8/8 incl. the literal "@fabricstack/catalog": "*" tripping at file:line; ls -d .changeset → No such file; CI publish-isolation step on every PR) |
What merging does
Merging to staging pushes the branch's .github/workflows/publish-npm-private.yml onto staging, and the push event starts it with dry_run=false — **the first real run of this workflow anywhere** (it cannot be dispatched before it exists on a branch, which is why the rehearsal is a ci.yml job). Sequence, each job gated on the previous:
1. resolve_release — release-version.cjs resolve --branch staging --sha <merge-sha> → version 7.0.1-staging.<12-char sha>, dist-tag staging, tag fabric/staging/v7.0.1-staging.<sha>, registry AR; verify-manifests; guard self-test. 2. verify_release_artifacts — release-artifact-verifier.yml, all 43 packages, allow_known_failures=false, --exactness. 3. publish_candidates — WIF (google-github-actions/auth@v2, vars.GCP_WORKLOAD_IDENTITY_PROVIDER / vars.GCP_SERVICE_ACCOUNT), npx google-artifactregistry-auth into $HOME/.npmrc (the committed .npmrc must stay byte-identical), npm ping; verify --write release-version.json + plan check; sync-workspace-versions + verify-manifests + guard; preflight channel assertion; derived-wave build; **13 publish waves** through scripts/publish-package-from-tag.mjs under candidate-7.0.1-staging.<sha> with FABRIC_RELEASE_PUBLISH=1 (the only place the opt-in is set); candidate dist-tag assertion over all 43. 4. published_consumer_validation — live-stack-published.yml: fresh project, .npmrc scope routing, install + import + bin smoke of all 43 at the exact version, the §3.1 global-install smoke (orchestrator + harness-cli → exactly orchestrator; then hooks CLI + harness SDK → exactly harness harness-hooks orchestrator, no EEXIST), live lanes at the exact version. 5. promote_release_channel — one release-promotion.cjs promote --evidence moves the **staging dist-tag** to 7.0.1-staging.<sha> on all 43 (latest never moves on a staging train). 6. assert_release_channel_tags --mode final. 7. create_release_tag — release-tags.yml pushes refs/tags/fabric/staging/v7.0.1-staging.<sha> to a5c-ai/fabric only.
Also on the push: publish.yml (the GKE deploy pipeline, unchanged in purpose) runs its build_all with the correct @fabricstack/harness-hooks-* names and validate_mux with the harness-cli suite the test job already proves green. No job on any path can reach registry.npmjs.org: the guard scans every workflow for the host and for npmjs credentials on every PR, the helper hard-fails npm output naming the public host, all 43 manifests pin publishConfig.registry to AR, and the repository has no npmjs secret.
**Merge method**: merge commit or squash — not rebase — so the train reverts as one git revert -m 1 (gh api repos/a5c-ai/fabric allows all three; the ruleset protect-main-staging requires one approving review and lists no required status checks, so the reds above do not block the button — read them as inherited, not as green).
Rollback and recovery
The procedure is docs/RELEASE-RUNBOOK.md (branch head) — §4 "Recovering a half-published train" (what a failed wave leaves behind: waves < N on AR under candidate-<v>, wave N partially published, no channel moved, no tag; first option gh run rerun <run-id> --failed, idempotent; then the from-tag recovery via publish-packages-from-tag.yml for a dead run), §5 "Repairing dist-tags" (fix-broken-latest-tags.mjs audit / --set <tag>=<version>, refuses a half-published inventory and the public host), §8 public-namespace checks after any release activity. Code side: a single git revert -m 1 of the merge restores staging's tree and lockfile exactly (reviewer node-level comparison); nothing outside git changed before the merge.
**First-train note (review-2 nice-to-have, now in the runbook):** on this train nothing earlier exists on AR, so before promotion there is nothing to roll back (orphaned candidates, no channel points at them), and **after promotion a channel rollback has no target** (--set staging=<previous> refuses a version any package lacks) — a post-promotion abort of the FIRST staging train is **fix-forward only**: new commit, new train. Consumers of the brand-new @fabricstack scope are unaffected either way; publication is immutable and nothing is ever unpublished.
Owner actions and their status (2026-10-04)
| Item | Status | Verification |
|---|---|---|
**M7 / G3** — restrict the org secret NPM_TOKEN away from fabric (GitHub UI) | **pending** (gh api orgs/a5c-ai/actions/secrets/NPM_TOKEN --jq .visibility → all). **Required before fix-npm-tags.yml is re-enabled / before anyone dispatches it** (moved forward from "before Gate B" by review-2 M8): the legacy copies on main and staging reference the secret | … --jq .visibility → selected; fabric absent from …/NPM_TOKEN/repositories |
**M6** — human reader binding on fabric-npm | **resolved** (orchestrator, fresh gcloud token): IAM policy shows roles/artifactregistry.reader for user:tal@a5c.ai; npx google-artifactregistry-auth + npm view @fabricstack/smoke --@fabricstack:registry=<AR> → 0.0.0-smoke.4; direct bearer GET → 200. The 2026-10-03 E403 was an expired token. Runbook: "re-authenticate first" kept, "CI-only" markers lifted | runbook §6 |
**M8 mitigation** — fix-npm-tags.yml re-enable | **re-DISABLED** 2026-10-04 (workflow 352401959 disabled_manually, 0 runs ever); the orchestrator re-enables it **immediately after PR #4 merges to staging, as part of Gate B, after M7 is verified**. Until then: do not dispatch fix-npm-tags.yml — without --ref, with --ref main, or with --ref staging before the merge it would run the legacy npmjs copy (identical blob 44112b847 on both branches, dry_run default false, --fix over the public @a5c-ai/* dist-tags). live-stack-published.yml, release-tags.yml, publish-packages-from-tag.yml, release-artifact-verifier.yml stay active | `gh api repos/a5c-ai/fabric/actions/workflows --paginate --jq '.workflows[] \ |
**G4** — register the fabricstack organization on public npmjs (publish nothing, 2FA, restricted membership) | **pending** (node scripts/ci/publish-isolation-guard.cjs --g4-status → unregistered; the scope is still free) | docs/specs/platform-gaps/phase0/g4-npmjs-org-runbook.md |
Required status checks on staging/main (ruleset 24103129 lists none) | pending, recommended before the first train (Lint, Tests, Package, Publish-isolation guards, Release tooling tests, Release train rehearsal) | gh api repos/a5c-ai/fabric/rulesets/24103129 |
Delete ci-oracle/staging-test-shape after reading the oracle run 36638300466 | pending, cosmetic (ci.yml-only delta; cannot start any publish/deploy) | — |
Deferred items (recorded, with owning WPs)
- **plugins/ + blueprints/ public bootstrap → WP-RN-11**: they still install the public
@a5c-ai/babysitter-sdkand callbabysitter …; they are not in any 7.0.0 tarball, and renaming the bins without retargeting the bootstrap would break them. WP-RN-11 moves bootstrap + bins together and must also install@fabricstack/harness-hooks-cliglobally (the SDK no longer re-exportsharness-hooks). The two marketplace sync workflows (sync-external-plugins.yml,sync-atlas-plugins.yml) are removed from the recovery path for the same reason; the channel-gateddocumented_installlane oflive-stack-published.ymlstays skipped pre-promotion. - **Docs / README / skills / process-library prose sweep → WP-RN-13** (counts in rn-06-bins.md: hyphenated old bin tokens 1,778 hits / 736 files;
babysitter <cmd>1,347 / 490;adapters <cmd>783 / 152;genty|atlas <cmd>50 / 27); the fivelibrary/processes/shared/*.jsJSDoc examples importing from the public@a5c-ai/babysitter-libraryride WP-RN-03/13 (library → process-library). - **Code-identifier renames and private dev bins → RN-4**: entry-file names and identifiers are unchanged (not user-visible); the private §3.2 dev bins (
kip,kip-mcp,kradle,kradle-serveroncontrol-plane-cli,kradle-jitsi-agent-*) keep their names (private: true, never published, duplicate-bin rule only). - **WP-T3-32 stage 2 (Effect)**: apps re-platform on stock Vite/vitest/tsc, engine floors, tracked-fork build matrix — unchanged from phase 0;
@effect/vitest@4.0.0-rc.115pinned, not usable as a harness until vitest 5. - **Done inside this train rather than deferred**:
RELEASE_MATRIX_SURFACESregistration (publish-npm-private.yml,publish-packages-from-tag.yml;verify:metadata43 / 0 violations); verifier coverage now **43/43** (the local matrix had stopped at 27/43 for memory; CI runs it on every PR). - **Nice-to-haves not taken** (follow-up list):
operator --version/orchestrator-mcp --versionprint a banner / start the stdio server instead of a version; the console-tui vitest suite runs in no CI job (itsverify:releasechecks pack contents only);docs/reference/package-publics.mdshould state the ESM-only posture ofconsole-tui,operator,model-gateway; pkg-02-versioning.md §5a lockfile numbers should read 16 / 27 / 9;ci.ymlre-cats all accumulated helper logs each rehearsal wave; the 16 real-named fixture manifests underscripts/ci/fixtures/publish-guards/g5/negative/duplicate-bin/remain a hazard for otherpackage.jsonwalkers; live-stack lanes gate promotion on three real-model runs (document the re-run path or consider a consumer-only first train).
How to verify
From the repository root on this branch, Node 22, npm ci (Linux/macOS; on Windows the vitest/lightningcss bindings are linux-only in the lockfile — the node:test suites and guards below run anywhere).
# Inventory, names, bins, manifests
node scripts/lib/publishable-packages.cjs | jq 'length' # 43
node scripts/lib/publishable-packages.cjs | jq -r '.[].name' | grep -vc '^@fabricstack/' # 0
node scripts/release-version.cjs verify-manifests --version 7.0.0 # All synchronized manifests are at release version 7.0.0.
npm run test:package-renames # 51 renamed packages (43 publishable + 8 private) and 8 retirement-listed shells
npm run test:binary-renames # 18 spec 15 §3.1 bins across 16 packages; G5 holds
node scripts/ci/bin-collision-guard.cjs --json | jq '.errors|length' # 0
npm run verify:metadata # Publishable inventory: 43; coverage gate over both AR workflows
npm run guard:packages # lockfile sync, native bindings, metadata, arch boundaries
# Guards (fixtures red, tree green)
node scripts/ci/publish-isolation-guard.cjs --self-test # 16/16; repository scan clean (0 findings, 0 legacy-train notices)
node scripts/ci/public-push-guard.cjs --self-test # 24/24; 0 findings
node scripts/ci/no-double-rename.cjs --self-test # 10/10
npm run test:publish-guards # 17/17 (incl. G2(d) over the real tree, no workflow names the public host)
npm run test:no-double-rename # 16/16
! grep -rln registry.npmjs.org .github/workflows # nothing
# Versioning (WP-PKG-02)
! test -d .changeset
npm run test:verify-manifests # 8/8 — the literal "@fabricstack/catalog": "*" trips at file:line
# Exports exactness (WP-PKG-01)
node scripts/ci/exports-exactness.cjs --self-test # 9/9 fixtures behaved
node scripts/ci/exports-exactness.cjs # 43 publishable manifest(s) … 0 finding(s) (tolerant: unbuilt targets deferred)
npm run test:exports-exactness
# after a full build: strict, no deferral
node scripts/ci/exports-exactness.cjs --require-built # 0 finding(s)
# packed negative probe for one package (what the verifier does for all 43)
node scripts/verify-release-artifacts.mjs --skip-build --exactness --package @fabricstack/orchestrator-sdk
# Release machinery (WP-RN-07)
node scripts/release-version.cjs resolve --branch staging --sha "$(git rev-parse --short=12 HEAD)" # 7.0.1-staging.<sha> / staging / fabric/staging/v… / AR
node scripts/release-version.cjs resolve --branch main --sha "$(git rev-parse --short=12 HEAD)" # 7.0.0 / latest / fabric/main/v7.0.0 / AR
node scripts/release-version.cjs from-tag --tag babysitter/main/v6.0.3 # exit 1: does not match fabric/<branch>/v<version>
node scripts/release-version.cjs from-tag --tag fabric/staging/v7.0.0 # exit 1: an exact version is never published from staging
node --test scripts/__tests__/private-release-train.test.mjs # 21/21
npm run test:release-tooling # 184/184 (CI) — the FIX-001/005/010/011 shape suites + WP-RN-07
# one-package rehearsal of the publish helper: npm publish --dry-run under the candidate tag, zero registry traffic
GITHUB_REF_NAME=staging node scripts/publish-package-from-tag.mjs --workspace=@fabricstack/catalog --release-version=7.0.0 --skip-build --rehearsal
# Isolation invariants (read-only)
gh api repos/a5c-ai/babysitter --jq .pushed_at # 2026-09-16T19:59:50Z
git ls-remote --tags origin | grep -cE 'refs/tags/(fabric|babysitter)/' # 0
gh api repos/a5c-ai/fabric/actions/secrets --jq '.secrets[].name' # KRADLE_TEST_AUTH_SECRET only
gh api repos/a5c-ai/fabric/actions/workflows --paginate --jq '.workflows[] | "\(.state) \(.path)"'
for p in orchestrator orchestrator-sdk catalog harness-sdk; do curl -s -o /dev/null -w "%{http_code} $p\n" "https://registry.npmjs.org/@fabricstack%2f$p"; done # 404 ×4
# CI runs to read
gh run view 37180964707 -R a5c-ai/fabric # ci.yml on 6c9f9eed9: rehearsal 13/13 + 43/43, release-tooling 184/184, test job 47/47; 3 inherited reds
gh run view 37180964710 -R a5c-ai/fabric # verifier on 6c9f9eed9: 43 passed / 0 failed
gh run view 36539167649 -R a5c-ai/fabric # pre-train baseline carrying the same Gateway ×2 + Docs QA reds🤖 Generated with Claude Code