page:docs-specs-platform-gaps-phase1-rn-06-bins
WP-RN-06 record: Phase-1 binary renames + bin-collision resolution reference
Executed 2026-09-29 on branch phase1/rename-train of a5c-ai/fabric (base 4247e4886 = the WP-RN-05 head). Spec: docs/specs/platform-gaps/15-private-isolation-rename.md §3 "Single-bin policy", §3.1 "Bin(s)" column (rows 1–43), §3.3 (incoming units' bins — none landed yet, none created), §4.3 G5 and "WP-RN-06"; intent 00-intent.md D10 (break freely, no shims), D17 (the public repo keeps the old bins for old users), D18 (neutral names), D19/D20/D21. Builds on phase1/rn-05-rename.md (packages renamed in place, bins deliberately carried over as G5 notices until this WP).
WP-RN-06 record: Phase-1 binary renames + bin-collision resolution
Executed 2026-09-29 on branch phase1/rename-train of a5c-ai/fabric (base 4247e4886 = the WP-RN-05 head). Spec: docs/specs/platform-gaps/15-private-isolation-rename.md §3 "Single-bin policy", §3.1 "Bin(s)" column (rows 1–43), §3.3 (incoming units' bins — none landed yet, none created), §4.3 G5 and "WP-RN-06"; intent 00-intent.md D10 (break freely, no shims), D17 (the public repo keeps the old bins for old users), D18 (neutral names), D19/D20/D21. Builds on phase1/rn-05-rename.md (packages renamed in place, bins deliberately carried over as G5 notices until this WP).
The public repository a5c-ai/babysitter was never written to: gh api repos/a5c-ai/babysitter --jq .pushed_at → 2026-09-16T19:59:50Z at start and end (only GET calls were issued); git remote -v → upstream no_push (push). Nothing was published to any registry, no tag was created, no PR was opened (the orchestrator opens the draft PR after this WP).
Final bin table (spec 15 §3.1 bin column, shipped)
Entry **files** keep their RN-1 spelling (file identifiers are RN-4's surface, WP-RN-11); only the bin keys changed, and each key points at the entry the build already emits. scripts/check-binary-renames.cjs (npm run test:binary-renames) pins this table row by row against the spec text parsed by scripts/lib/rename-spec.cjs (newBins column) and against each package's tsconfig rootDir → outDir derivation.
| # (§3.1) | Package (dir) | Bins → entry | Dropped (public-train name, reason) |
|---|---|---|---|
| 1 | @fabricstack/orchestrator (packages/babysitter) | orchestrator → bin/babysitter.js | babysitter — renamed; the metapackage shim now exposes the SDK CLI as orchestrator |
| 2 | @fabricstack/orchestrator-sdk (packages/babysitter-sdk) | orchestrator-sdk → dist/cli/main.js; orchestrator-mcp → dist/cli/mcpServeEntry.js | babysitter-sdk, babysitter-mcp-server — renamed; babysitter (duplicate of row 1), adapters (duplicate of row 4), adapters-hooks (duplicate of row 21) — "three duplicate/colliding bins dropped" (§3.1 row 2); their re-export shim sources src/cli/adaptersBin.ts, src/cli/adaptersHooksBin.ts deleted |
| 3 | @fabricstack/observer (packages/observer-dashboard) | observer → ./dist/cli.js | babysitter-observer-dashboard — renamed |
| 4 | @fabricstack/harness-sdk (packages/adapters/sdk) | harness → ./dist/bin/adapters.js | adapters — renamed (resolves the adapters collision with row 2) |
| 5 | @fabricstack/harness-cli (packages/adapters/cli) | — (delegates to row 4, as today) | — |
| 8 | @fabricstack/harness-mock (packages/adapters/harness-mock) | harness-mock → ./dist/bin/adapters-harness-mock.js | adapters-harness-mock — renamed; mock-harness — legacy alias dropped, src/bin/mock-harness.ts deleted |
| 14 | @fabricstack/harness-tasks (packages/adapters/tasks) | harness-tasks → ./dist/cli/index.js | adapters-tasks — renamed; tasks-adapter — alias dropped, src/cli/tasks-adapter.ts deleted |
| 16 | @fabricstack/harness-triggers (packages/adapters/triggers) | harness-triggers → ./dist/cli.js | adapters-triggers — renamed; triggers-adapter — alias dropped, src/triggers-adapter.ts deleted |
| 17 | @fabricstack/harness-channels (packages/adapters/channels) | harness-channels → ./dist/cli.js | adapters-channels — renamed; mcp-channels — alias dropped (same target, no source to delete) |
| 18 | @fabricstack/harness-extensions (packages/adapters/extensions) | harness-extensions → ./dist/cli.js | adapters-extensions — renamed; extensions-adapter — FIX-004 compat shim dropped, src/extension-adapter.ts deleted |
| 19 | @fabricstack/model-gateway (packages/adapters/transport) | model-gateway → ./dist/bin/adapters-transport-proxy.js | adapters-transport-proxy — renamed; adapters-proxy — alias dropped, src/bin/adapters-proxy.ts deleted |
| 21 | @fabricstack/harness-hooks-cli (packages/adapters/hooks/cli) | harness-hooks → dist/cli/main.js | adapters-hooks — renamed (resolves the collision with row 2); a5c-hooks-adapter — alias dropped, src/cli/a5c-hooks-adapter.ts deleted |
| 34 | @fabricstack/agent-runtime-cli (packages/genty/cli) | agent-runtime → ./dist/cli/main.js | genty — renamed |
| 38 | @fabricstack/console-tui (packages/genty/tui) | console-tui → ./dist/bin/adapters-tui.js | adapters-tui — renamed |
| 40 | @fabricstack/catalog (packages/atlas) | catalog → dist/cli.js | atlas — renamed; a5c-atlas — alias dropped (same target) |
| 42 | @fabricstack/control-plane (packages/kradle/core) | control-plane-server → ./bin/kradle-server.mjs; control-plane-demo → ./bin/kradle-demo.mjs | kradle-server, kradle-demo — renamed (also resolves the kradle-server collision with the private @fabricstack/control-plane-cli dev bin) |
| 43 | @fabricstack/operator (packages/kradle/installer) | operator → ./dist/cli.js | kradle-install — renamed |
Union of bin keys across the 43 publishables = exactly the 18 §3.1 bins, duplicate-free (AC1; proof under "Gates"). The private §3.2 workspaces keep their dev-only bins (kip, kip-mcp on @fabricstack/memory; kradle, kradle-server on @fabricstack/control-plane-cli; the three kradle-jitsi-agent-* on @fabricstack/meeting-sidecar): they are private: true, never reach a registry, and G5 subjects them to duplicate-bin only (unchanged RN-05 decision; the RN-4 identifier phase renames them). §3.3 bins (environment-server) are allowed by the guard but not created (D21: they land with their units).
What changed besides the manifests
| Surface | Change |
|---|---|
| Entry sources | 8 dead alias/shim sources deleted (table above). No entry file renamed: none of the names is user-visible, the bin keys are. |
| Usage/help strings that print the bin name | orchestrator SDK CORE_PROGRAM.commandName babysitter → orchestrator (drives formatUsage, --help, error hints), usage.ts harness-install hints, cost:stats/tokens:stats usage, compression command doc-comments; packages/babysitter/bin/babysitter.js repair hints; harness CLI (packages/adapters/cli/src, 232 tokens) Usage: adapters … / adapters <cmd> → harness (the adapters *subcommand* of harness adapters list kept); hooks CLI yargs scriptName('harness-hooks'); agent-runtime AGENT_PROGRAM.commandName genty → agent-runtime (type widened), print.ts/tui.ts/ui.ts/dispatch.ts hints; console-tui Usage: console-tui, stderr prefixes; model-gateway Usage: model-gateway, [model-gateway] log prefixes, TRANSPORT_MUX_RUNTIME.executable; harness-mock, harness-channels (alias line removed), harness-triggers, harness-extensions usage banners; harness-tasks commander .name("harness-tasks") and harness-tasks auth … hints; catalog Usage: catalog (+ --help/--version now exit 0 on stdout, AC3); observer banner/version line; control-plane-server/-demo usage; operator usage (cloud … → operator …) |
| Runtime bin resolution (breaks if left) | SDK harness/unified/discovery.ts cli and subprocess.ts default spawn a5c-hooks-adapter → harness-hooks; packages/adapters/launch/src/bridge-hooks.ts defaults babysitter/a5c-hooks-adapter → orchestrator/harness-hooks (BABYSITTER_BIN/HOOKS_MUX_BIN overrides unchanged); extensions compiler sdkConfig.ts defaults cli: 'orchestrator', proxyBinary: 'harness-hooks' (generated plugin hooks now invoke harness-hooks invoke …); agent-runtime-platform operatorCommands.ts templates orchestrator run:status … etc.; observer version-info.ts probes orchestrator --version and the copyable resume command is orchestrator run:iterate <id>; SDK CLI-setup prompt snippets (prompts/contextShared.ts) use orchestrator, fall back to npm exec … @fabricstack/orchestrator-sdk@$SDK_VERSION -- orchestrator-sdk, repair with npm i -g @fabricstack/orchestrator; SDK hook prompts (harness/hooks/utils.ts) tell the agent to call orchestrator run:iterate/run:status; prompts/parts/runCreation.ts orchestrator session:whoami |
Shipped CI templates (packages/adapters/triggers) | action.yml, azure-pipelines.yml, circleci-config.yml, bitbucket-pipelines.yml, .gitlab-ci.yml: adapters-triggers/`triggers-adapter enrich |
| CI lanes | .github/workflows/live-stack.yml PATH shim map: harness, agent-runtime, orchestrator, harness-hooks (the agent-platform alias is not a package bin and stays); live-stack runner/contract (packages/adapters/cli/tests/live-stack) invoke harness …, agent-runtime call, orchestrator harness:install-plugin, and install the hooks CLI globally **without --force** (the RC-1 two-provider reconciliation existed only because of the adapters-hooks collision this WP removes) |
| Release gates | scripts/lib/package-surface.cjs BIN_SMOKE_ARGS keyed on @fabricstack/catalog catalog (stats); .github/workflows/release-artifact-verifier.yml header documents the §3.1 bin smoke set; package-level verify:release gates of @fabricstack/harness-extensions (single bin, retired shim source/target must be absent), @fabricstack/console-tui (console-tui, exactly one bin), @fabricstack/operator (operator, exactly one bin), @fabricstack/observer (help banner observer — CLI …) |
| Docs that tests assert on | docs/adapters/terminology-and-structure-gaps/binary-renames.md rewritten as the superseded-plan note + the §3.1 table (tool input of check-binary-renames.cjs); packages/adapters/tasks/README.md + docs/setup-guide.md (single harness-tasks bin; FIX-012 documented-surface test); packages/adapters/hooks/{README,cli/README,docs/**}.md bin tokens a5c-hooks-adapter/adapters-hooks → harness-hooks (Codex docs-parity test) |
G5 becomes the default (`scripts/ci/bin-collision-guard.cjs`)
LEGACY_COLLISIONSand the RN-05 carry-over tolerance (carryOverBinsByPackage, per-row legacy-bin notices) are deleted. Rules, all unconditional:duplicate-bin(any two owners),public-train-binandbin-not-in-spec(publishable private-scope owners),spec-bins-missing(every §3.1 bin shipped by a publishable),public-train-bins-drift(pinnedPUBLIC_TRAIN_BINS== spec §3.1 "Current package — bins" union, 26 = 26) and the newspec-bins-drift(pinnedSPEC_BINS_31== spec §3.1 "Bin(s)" union, 18 = 18).noticesis always empty.--private-train/FABRIC_PRIVATE_TRAIN=1are accepted as no-op aliases (checkBinCollisions(root, { privateTrain })ignores the option and reportsprivateTrain: true), so the orchestrator'snode scripts/ci/bin-collision-guard.cjs --private-trainkeeps working;scripts/lib/registry-pin.cjsnow documents the flag as selecting only the G2(c)/G3 workflow rules (WP-RN-07).- Fixtures (
scripts/ci/fixtures/publish-guards/g5/, regenerated from the spec parse — 16 fixture packages each): positivedistinct-bins= the exact §3.1 end-state; negativesduplicate-bin(orchestratoron two packages),public-train-bin(atlason row 1 →public-train-bin+bin-not-in-spec), **legacy-carry-over** (row 1 keepsbabysitter, row 21 keepsadapters-hooks— tolerated before this WP, an error now),spec-bin-missing(operatorabsent →spec-bins-missing),off-spec-bin(catalog-extra→bin-not-in-spec). Each negative trips **exactly** its declared rule set (the test compares the whole set now, not a subset) with and without--private-train. scripts/ci/publish-guards.test.mjsG5 tests rewritten: repository test asserts zero duplicates, publishable bin union ==SPEC_BINS_31(AC1 mechanically), no public-train name reused, no notices,LEGACY_COLLISIONSabsent, flag-independence.scripts/check-binary-renames.cjsrewritten from the 8-row alias table (canonical+legacy per package, deprecation-warning check) to the §3.1BIN_TABLE(16 packages / 18 bins): exact bin map per manifest, spec cross-check (rows and directories), entry source exists, emitted path derivation (rootDir → outDir; plain-JS bins compared directly;@fabricstack/observer's esbuild CLI markedderived: false— its tsconfig carries no rootDir/outDir; the packed-artifact verifier proves itsdist/cli.js), **retired alias sources must be absent**, doc table cells present, then G5.
Tests adjusted, and why
- SDK:
regressions/marketplace-owner-and-sdk-bin.test.ts(was: SDK must shipadapters-hooks/adaptersshims) now pins the SDK bin map to exactly{orchestrator-sdk, orchestrator-mcp}and asserts every retired/renamed shim name absent;cli/__tests__/resolveDependencyBin.test.tsresolvesharness-hooks/harness(the helper stays as a library function, its doc-comment updated);cliMain/cliRuns/instructions/contextSharedtests expectorchestrator …;harness/unifiede2e comment. - Harness family:
packages/adapters/cli/tests(bridge-hooks token checks acceptharness-hooks/orchestrator,Usage: harness mcp|plugin, describe titles); live-stackscenario-contract.test.tsRC-1 block (was: prove both packages declareadapters-hooksand the hooks install uses--force) now proves the collision is gone and **no--force** is emitted;primary-live-runner.test.tsRC-1 block likewise;harness-mock/tests/mock-harness-cli.test.tsimports the surviving entry and expectsharness-mockin--help;taskscli-program.test.ts(harness-tasksprogram name/argv) andmcp-documented-surface.test.ts(was: "both published bins are documented" incl. the shim's deprecation text → single bin, retired source absent, docs name no retired bin as a command);triggers/tests/cli.test.tsUsage: harness-triggers;channelscli-bin-smoke.test.tsUsage: harness-channels;transport/tests/bin-smoke.test.tsUsage: model-gateway; hooks CLIcli.test.ts$0: 'harness-hooks'(24 argv mocks);adapter-codexdocs-parity expectsharness-hooks exec …; extensionspackaged-surface-parity.test.ts(was: both bins run, compat bin warns and delegates status → single bin, no deprecation text, retired names not linked; report basenamefabricstack__harness-extensions.json— thea5c-ai__extensions-adapter.jsonit read was already stale since RN-05). - Agent-runtime / console:
genty/clilive-integration test spawnsagent-runtime;genty/tuirelease-verification.test.tsfixture binconsole-tui,mcp-view.test.tsxexpectsharness mcp install. - Control plane:
kradle/core/tests/{bin-smoke,kradle}.test.jsreadcontrol-plane-server/control-plane-demo;kradle/installer/tests/release-verification.test.tsfixture binoperator. - Observer:
version-info,kanban-*,breakpoint-approval,pagetests and the two Playwright specs expectorchestrator run:iterate …/orchestrator --version. - Scripts:
scripts/__tests__/hooks-atlas-ownership.test.mjsexpects the verifier to smoke['harness-hooks'];scripts/ci/publish-guards.test.mjsG5 (above). - No test file was deleted or skipped. Test *cases* whose subject no longer exists (the compat bin's deprecation-warning/delegated-status assertions in the extensions gates, the tasks shim-forwarding case, the RC-1
--forceproofs) were rewritten into their end-state counterparts (single bin / no--force/ retired sources absent), so each file still fails if the retired behaviour comes back.
Deliberately NOT swept here (tracked for WP-RN-11 / WP-RN-13)
The sweep boundary is "everything that executes": manifests, entry sources, usage strings, runtime bin resolution, generated hook commands, CI lanes/templates, tests and the docs those tests assert on. Left, with the same rationale as RN-05's Markdown deferral:
plugins/babysitter-unified/**andblueprints/**(marketplace plugin surface, WP-RN-11): their bootstrap still installs the **public** SDK (npm exec --yes --package @a5c-ai/babysitter-sdk@… -- babysitter,plugins/babysitter-unified/bin/install-shared-sdk.js) and their hooks callbabysitter hook:run …. Renaming those invocations without retargeting the bootstrap to AR/@fabricstack/orchestratorwould break them; RN-11 must move both together. Consequently the SDK command templates synced fromplugins/babysitter-unified/commands/*.md(scripts/sync-sdk-command-templates.cjs, whose builder text also saysbabysitter process-library:active) are unchanged andcheck:sdk-command-templates/check:plugin-commandsstay "synchronized" by construction.- Agent-facing prompt text in Markdown/skills/process-library JS (
packages/babysitter-sdk/src/prompts/templates/**,packages/*/skills/**,library/**prompt strings such asbabysitter plugin:update-registry), READMEs,docs/**,packages/atlas/graph/**catalogue records of the public ecosystem: WP-RN-13 (Markdown) / WP-RN-11 (catalogue). Counts at the end of this WP (rg -P, excludingnode_modules,dist, lockfile): hyphenated old bin tokens(?<![@/\w.-])(babysitter-sdk|…|kradle-install)(?![\w-])→ 1,778 hits in 736 files (top:library/specializations313 md,packages/atlas274 code — catalogue data,docs/**~500 md);babysitter <command>invocations → 1,347 hits in 490 files (top:docs/user-guide226,blueprints/a5c220,plugins/babysitter-unified162,docs/assimilation82, SDK prompt templates 62,library/**120);adapters <command>→ 783 hits in 152 files (docs/adapters352,docs/user-guide109,docs/testing63,packages/adapters/meta52 — archived docs,packages/adapters/launch41 — model-provider config idsadapters-proxy, not the bin);genty|atlas <command>→ 50 hits in 27 files (all docs/README). Script: WP output scratchdeferred-counts.cjs. - Known follow-ups surfaced here, not this WP's:
packages/observer-dashboard/src/cli.ts:217still checks for updates againsthttps://registry.npmjs.org/@fabricstack/observer/latest(a private package on the public registry — WP-RN-07 registry retarget); the verifier's clean-consumer install resolves@fabricstack/*dependencies from npmjs (E404 until the first AR publication, M1 exit criterion 1 — WP-RN-07 routes the consumer at AR); the plugin bootstrap (WP-RN-11) must install@fabricstack/harness-hooks-cliglobally in addition to the orchestrator because npm links only a package's own bins and the SDK no longer re-exportsharness-hooks.
AC2 — global install from Artifact Registry (pending publish; for the M1 verifier)
Nothing is published yet (WP-RN-07 publishes the train), so AC2 is proven after the first AR publication. Exact commands, on a clean machine (or an empty prefix), with gcloud ADC and the google-artifactregistry-auth helper having refreshed the user ~/.npmrc (docs/user-guide private-install page from WP-RN-03):
export AR=https://us-central1-npm.pkg.dev/boot-464019/fabric-npm/
export PREFIX=$(mktemp -d) # empty global prefix: no pre-existing bins
npm config set @fabricstack:registry "$AR" --location=user # or rely on the committed scope routing
npm i -g --prefix "$PREFIX" @fabricstack/orchestrator@7.0.0 @fabricstack/harness-cli@7.0.0 --registry "$AR" 2>&1 | tee ac2-install.log
! grep -q EEXIST ac2-install.log # AC2: no EEXIST bin conflict
ls "$PREFIX/bin" # expected: orchestrator (harness-cli declares no bin, §3.1 row 5)
"$PREFIX/bin/orchestrator" --version && "$PREFIX/bin/orchestrator" --help
# the hooks CLI is a separate global install (npm links only a package's own bins):
npm i -g --prefix "$PREFIX" @fabricstack/harness-hooks-cli@7.0.0 @fabricstack/harness-sdk@7.0.0 --registry "$AR" 2>&1 | tee -a ac2-install.log
! grep -q EEXIST ac2-install.log
ls "$PREFIX/bin" # expected: orchestrator harness harness-hooks — no duplicate, no legacy nameExpected bin set after the two installs: orchestrator, harness, harness-hooks (plus nothing else); npm i -g of every other bin-bearing §3.1 package adds exactly its row's bins (orchestrator-sdk+orchestrator-mcp, observer, harness-mock, harness-tasks, harness-triggers, harness-channels, harness-extensions, model-gateway, agent-runtime, console-tui, catalog, control-plane-server+control-plane-demo, operator) with no EEXIST, because the union is duplicate-free (AC1) and disjoint from the public train's 26 names (G5 public-train-bin) — so a machine that also has @a5c-ai/* installed globally cannot collide either.
AC3 — local `--version` / `--help` smoke transcript
Run after the builds (build:sdk, build:adapters, build:hooks-adapter, build:adapters-extensions, per-workspace builds of harness-mock/model-gateway/harness-channels/harness-triggers/operator/console-tui/agent-runtime-cli/catalog/orchestrator-sdk, and build:cli of observer — all exit 0 on this machine; build:app of observer cannot run here, see "Environment"). Each §3.1 bin entry was executed as node <package dir>/<bin target> <args> (the WP scratch smoke.cjs; the catalog line also runs its verifier smoke argument stats). ok = exit 0; the first output line follows.
ok orchestrator --version exit=0 | 7.0.0
ok orchestrator --help exit=0 | Usage:
ok orchestrator-sdk --version exit=0 | 7.0.0
ok orchestrator-sdk --help exit=0 | Usage:
ok orchestrator-mcp --version exit=0 | Babysitter MCP server running on stdio
ok orchestrator-mcp --help exit=0 | Babysitter MCP server running on stdio
ok observer --version exit=0 | observer v7.0.0
ok observer --help exit=0 | observer — CLI for the observer dashboard
ok harness --version exit=0 | harness v7.0.0
ok harness --help exit=0 | harness - Agent Multiplexer CLI (v7.0.0)
ok harness-mock --version exit=0 | 7.0.0
ok harness-mock --help exit=0 | harness-mock — replay a mock agent scenario.
ok harness-tasks --version exit=0 | 5.0.0
ok harness-tasks --help exit=0 | Usage: harness-tasks [options] [command]
ok harness-triggers --version exit=0 | 7.0.0
ok harness-triggers --help exit=0 | Usage: harness-triggers <evaluate|enrich> [flags]
ok harness-channels --version exit=0 | 7.0.0
ok harness-channels --help exit=0 | Usage: harness-channels <config.yml>
ok harness-extensions --version exit=0 | harness-extensions - Cross-harness plugin compiler for AI coding agents
ok harness-extensions --help exit=0 | harness-extensions - Cross-harness plugin compiler for AI coding agents
ok model-gateway --version exit=0 | 7.0.0
ok model-gateway --help exit=0 | Usage: model-gateway [--help] [--version]
ok harness-hooks --version exit=0 | 7.0.0
ok harness-hooks --help exit=0 | harness-hooks <command> [options]
ok agent-runtime --version exit=0 | 7.0.0
ok agent-runtime --help exit=0 | agent-runtime create-run [--prompt <text>] [--harness <name>] …
FAIL console-tui --version exit=1 | C:\work\fabric\node_modules\react-reconciler\cjs\react-reconciler.development.js:491
FAIL console-tui --help exit=1 | C:\work\fabric\node_modules\react-reconciler\cjs\react-reconciler.development.js:491
ok catalog --version exit=0 | 7.0.0
ok catalog --help exit=0 | Usage: catalog <command>
ok catalog stats exit=0 | {
ok control-plane-server --version exit=0 | 7.0.0
ok control-plane-server --help exit=0 | Usage: control-plane-server [--port=<port>]
ok control-plane-demo --version exit=0 | Kradle 7.0.0 — Kubernetes-native forge runtime with Argo CD and Kradle-managed repository hosting
ok control-plane-demo --help exit=0 | Usage: control-plane-demo [--json]
ok operator --version exit=0 | operator - deployment CLI for the control-plane Kubernetes environments
ok operator --help exit=0 | operator - deployment CLI for the control-plane Kubernetes environments
35/37 smoke invocations exit 0 across 18 binsEntry-script fixes the smoke forced (all in the bin entry files this WP owns): harness-mock and harness-triggers never handled --version (unknown flag / unknown command — the FIX-011 verifier only smokes --help), both now print the package version; catalog answered --help with usage on stderr and exit 1 and had no --version — both now exit 0 on stdout (invalid invocations still exit 1); operator's executedDirectly guard compared process.argv[1] against a hard-coded cloud/cloud.js suffix that no installed shim ever matched, so kradle-install --help printed nothing and exited 0 (a vacuous pass in CI) — it now compares resolved paths like the extensions CLI does; the harness --version banner said adapters v…. Pre-existing oddities left as-is and noted: orchestrator-mcp ignores --help/--version (it is a stdio MCP server: it starts, sees stdin closed and exits 0); harness-tasks --version prints a hard-coded 5.0.0 (commander .version() literal, not the manifest version — a WP-RN-07 lockstep item); control-plane-demo --version prints the demo banner (the demo has no version flag; control-plane-server has); prose still says "Babysitter"/"Kradle" (RN-4 identifiers, WP-RN-11).
console-tui (2/37): fails identically on --version and --help **on this machine only** — TypeError: Cannot read properties of undefined (reading 'ReactCurrentOwner') from node_modules/react-reconciler@0.29.2 resolving the root react@19.2.6 while packages/genty/tui pins react@^18.3.1 (nested 18.3.1 present) and ink is not hoisted (require('ink') from the root fails) — the same incremental-install skew RN-05 documented (no npm ci on this machine, memory-reaped twice). The bin was not changed beyond its stderr prefix and usage line; its own verify:release, tests/adapters-tui-bin.test.ts and the FIX-011 verifier bin smoke run in CI (ubuntu) on the pushed commits. Not smoked locally: nothing else — every other §3.1 bin ran here.
Release-artifact verifier over the bin-bearing packages
node scripts/verify-release-artifacts.mjs --skip-build --report-dir <scratch> --package <each of the 16 bin-bearing publishables> (reports kept with the WP output). Per-step status (p passed, f failed, s skipped after a failure):
@fabricstack/catalog pack:p scope:p surfaces:p shebangs:p install:p imports:p typecheck:p bins:f — bins: spawnSync …\consumer\node_modules\.bin\catalog ENOENT
@fabricstack/harness-tasks pack:p scope:p surfaces:p shebangs:p install:p imports:p typecheck:p bins:f — bins: spawnSync …\.bin\harness-tasks ENOENT
@fabricstack/harness-triggers pack:p scope:p surfaces:p shebangs:p install:p imports:p typecheck:p bins:f — bins: spawnSync …\.bin\harness-triggers ENOENT
@fabricstack/control-plane pack:p scope:p surfaces:p shebangs:p install:p imports:p typecheck:s bins:f — bins: spawnSync …\.bin\control-plane-demo ENOENT
@fabricstack/operator pack:p scope:p surfaces:p shebangs:p install:p imports:p typecheck:p bins:f — bins: spawnSync …\.bin\operator ENOENT
@fabricstack/orchestrator, orchestrator-sdk, observer, harness-sdk, harness-mock, harness-channels, harness-extensions, model-gateway, harness-hooks-cli, agent-runtime-cli, console-tui
pack:p scope:p surfaces:p shebangs:p install:f — install: npm error code E404 (`@fabricstack/<dep>@7.0.0` is not in registry.npmjs.org)Reading: for every package the exact tarball packs, passes the G6 scope gate, declares surfaces that exist and bins with shebangs (surfaces/shebangs walk the **new** bin keys — a renamed key pointing at a missing file would have failed there). The five packages without internal @fabricstack/* dependencies install into the clean consumer, import and typecheck, and npm links the **new** bin names into node_modules/.bin (the step's own bin … was not linked check passed; the failure is spawnSync … ENOENT on the Windows .cmd shim — the known pre-existing Windows failure of the bins step named in the WP brief; RN-05 hit the same class). The other eleven stop at install because the temporary consumer resolves their @fabricstack/* dependencies from npmjs, where nothing is published (M1 exit criterion 1; the consumer's registry routing at AR is WP-RN-07's). No package failed a rename-caused step. The verifier's bin configuration change of this WP (BIN_SMOKE_ARGS key @fabricstack/catalog catalog, workflow header) is therefore proven locally as far as this machine allows; .github/workflows/release-artifact-verifier.yml (ubuntu, workflow_dispatch) runs the full matrix after the first AR publication.
Review round 1 (adversarial review 2026-09-29, score 74): what the first full CI test-job runs revealed
The review's central point stands: until commit f8224cae7 the CI test job had never executed past its eighth step on this branch (the inherited FIX-010/FIX-011 workflow-shape failures in test:release-tooling stopped it), so none of the vitest rewrites recorded above had run anywhere. The step now runs as its own required, visibly-red release-tooling job; the test job runs its full shape. The suites were also run locally for the first time (the rolldown win32 binding was dropped into node_modules for the session — not committed, nothing in the lockfile changed for it). A staging **oracle run** (branch ci-oracle/staging-test-shape = origin/staging + the same job split, run 36638300466) gives every step a staging baseline: steps 1–30 of the test job pass on staging and "Realtime flow tests" (step 31) fails there with Cannot find package 'jsdom'.
Findings fixed, by commit:
| Finding | Where | Fix |
|---|---|---|
M2 runtime default spawns the retired mock-harness | packages/adapters/cli/src/commands/run.ts:372 | harness-mock (AGENT_MUX_MOCK_HARNESS_BIN override unchanged); doc-comment updated (ed01994df) |
M2-class: remote adapter spawns the retired adapters bin | packages/adapters/codecs/src/adapters-remote-adapter.ts (cliCommand default, --version probes, sessions list) | harness (via this.cliCommand); guidance strings; test adapters-remote-adapter.test.ts pins harness and refuses adapters run |
M2-class: agent prompts name the retired babysitter bin | packages/adapters/launch/src/launch.ts:548 (bridge-interactive follow-up), packages/adapters/codecs/src/babysitter-adapter.ts plugin commands | orchestrator …; launch-bridge-interactive.test.ts pins it |
| M2-class: split-token legacy package paths | packages/babysitter-sdk/src/cli/main/runSupport.ts:266, packages/genty/platform/src/harness/internal/createRun/planProcess/validation.ts:55 (path.join("@a5c-ai", "babysitter-sdk")) | the process-local SDK fallback link now sits under the package's own name, where require("@fabricstack/orchestrator-sdk") looks; 3 SDK tests that were red locally for exactly this reason ("Cannot find package '@fabricstack/orchestrator-sdk'") pass; fixtures in cliRuns, localSdkDependencySymlink, externalTaskValidation, the metapackage shim test, the PTY packaged consumer and the bridge-hooks Windows shim moved to the new names |
| M3 stale expectation | packages/adapters/cli/tests/live-stack/scenario-contract.test.ts:25-34 | expects no --force and orchestrator harness:install-plugin (17bd8a049); 19/19 |
| B1 cycle 1: architecture gate red | docs/v6-spec-and-roadmap/decisions/ADR-001-agent-platform-seam-contract.md said @a5c-ai/genty-platform ×7; seams/contract.test.ts asserts the new name | swept (a doc a test asserts on, b76f636dd); geminiCli.test.ts / contextShared.test.ts expected babysitter / npm i -g @fabricstack/orchestrator-sdk in the CLI setup snippet — now pin orchestrator, the SDK's own orchestrator-sdk fallback bin and the metapackage repair |
| B1 cycle 2: tasks packaged-surface parity red | packages/adapters/tasks/src/__tests__/packaged-surface-parity.test.ts:50 read the verifier report as a5c-ai__tasks-adapter.json | fabricstack__harness-tasks.json (same stale-basename class RN-06 fixed for extensions) |
B1 cycle 2: harness CLI --version banner | packages/adapters/cli/tests/built-cli.test.ts expected adapters v… | expects harness v… and refuses the retired banner |
M5 shipped prompt templates instruct babysitter … | packages/babysitter-sdk/src/prompts/templates/** (38 lines + 11 more in user-profile.md, process-creation.md:40, process-guidelines.md:49) | every CLI invocation (babysitter <ns>:<cmd>, npx babysitter <ns>:<cmd>) → orchestrator <ns>:<cmd> (bare: npx orchestrator would resolve an unrelated npmjs package). The commands/*.md templates are **generated** from plugins/babysitter-unified/commands/*.md by scripts/sync-sdk-command-templates.cjs; the plugin sources stay on the public train (their bootstrap installs the public SDK — WP-RN-11 moves both together), so the sync script now rewrites CLI invocations to the shipped bin while generating (toShippedBinNames, invocations only: never prose, slash commands or package names) and its builder text names orchestrator. check:sdk-command-templates / check:plugin-commands stay "synchronized" with the regenerated templates — not weakened: the check is still byte-equality against the generator. Zero retired-bin invocations remain in the shipped template set |
M6 harness-tasks --version printed a hard-coded 5.0.0 | packages/adapters/tasks/src/cli/{program,index}.ts | readCliVersion() reads the manifest (CLI_VERSION re-exported); local: harness-tasks --version → 7.0.0 |
M6 console-tui crashed on --version/--help from a clean install | packages/genty/tui/package.json declared react ^18.3.1 under a root resolving React 19; --legacy-peer-deps hoisted ink 5's react-reconciler@0.29 next to react@19 (ReactCurrentOwner TypeError). A dependency-declaration problem, present on staging's lockfile too | @fabricstack/console-tui, @fabricstack/console-tui-plugins, @fabricstack/harness-cli declare ink ^6.0.0 (React 19) + react ^19.2.4; root devDependencies declares ink (the root vitest.setup.ts imports it, previously by hoisting accident); lockfile regenerated minimally (see pkg-02-versioning.md §5a). console-tui also never implemented --version (it answered "Unknown flag") — src/bin/runtime.ts now prints the manifest version (-v/--version), help lists it, adapters-tui-bin.test.ts pins the output |
staging-inherited: "Realtime flow tests" (Cannot find package 'jsdom') | packages/genty/ui SessionDetailScreen.test.tsx declares @vitest-environment jsdom; jsdom was never a dependency (fails identically on the staging oracle) | jsdom devDependency on @fabricstack/console-ui, so the test job can run past step 31 for the first time |
Local evidence after the changes (vitest): see the commit messages; CI evidence: "CI evidence (review round 1)" below.
Two more casualties the later cycles surfaced, same class (tests pinning pre-rename text that only a run past step 8 could reveal): packages/adapters/core/tests/release-verification.test.ts expected the gate error to match comm-adapter/automation (417a9af88); packages/genty/platform/.../__tests__/prompts.test.ts pinned babysitter profile:read --user --json from the pre-M5 template (ed3fca229). Package READMEs that package gates assert on (harness-core, console-ui, harness-extensions) were swept with the spec matrix in 99e69664f (README sweeps otherwise stay WP-RN-13's).
CI evidence (review round 1)
Every push ran ci.yml on the draft PR; the test job's reach grew with each triage cycle (step numbers as GitHub reports them; "release-tooling" became its own job in cycle 1):
| Cycle | Run | test job reach | Cause of the stop | Fixed in |
|---|---|---|---|---|
| baseline (review) | 36634324150 | step 9 of 42 | inherited FIX-010/FIX-011 names in test:release-tooling | job split f8224cae7 |
| 1 | 36638104867 | step 11 (architecture gate) | ADR said @a5c-ai/genty-platform | b76f636dd |
| 2 | 37135984897 | step 17 (tasks packaged-surface parity); steps 14–16 (SDK unit tests 2345/2345, tasks 1085/1085) green for the first time | stale report basename a5c-ai__tasks-adapter.json | f08f9365d |
| 3 | 37137648327 | step 16 | cli-program.test.ts pinned the literal 5.0.0 the M6 fix removed | a167b3631 |
| 4 | 37138136179 | step 28 (harness-core verify:release); steps 18–27 (hooks 431, triggers, console-tui verify:release) green | harness-core README still @a5c-ai/comm-adapter (gate-asserted) | 99e69664f |
| 5 | 37139013302 | step 29 (harness-core suite; PTY contract 984/993 incl. the renamed packaged consumer) | stale regex comm-adapter/automation | 417a9af88 |
| 6 | 37139713168 | step 41 (agent-runtime-platform suite, 1699/1700); steps 29–40 green: realtime-flow 7/7 (jsdom), Playwright e2e, extensions 87/87, **strict exports gate on the CI-built tree: 43 manifests, 3305 imports, 0 findings**, agent-runtime-core 248/248 | prompts.test.ts pinned the pre-M5 template text | ed3fca229 |
| 7 | 37140849717 | **all 42 steps green** (job 111254803136, 15 min 25 s): SDK 2345/2354 (9 skipped), tasks 1085, hooks 431/431, triggers unit/e2e/coverage, console-tui + harness-core + console-ui verify:release, PTY contract, realtime-flow 7/7, Playwright e2e, extensions 87, strict exports gate 0 findings, agent-runtime-core 248, agent-runtime-platform 1700/1700, unified plugin bundles | — | — |
Staging oracle (branch ci-oracle/staging-test-shape, run 36638300466): test job reaches step 31 and fails on Cannot find package 'jsdom'; this branch passes that step since 3a057edcb (jsdom declared). Jobs red on every run and proven inherited: **Release tooling tests** — with --test-concurrency=1 exactly the 9 FIX-010/FIX-011 names of the baseline (cycle 3 onward: # pass 154 / # fail 9; the catalog-build race name of cycle 2 is gone); **Gateway Node engine floor (22 / 22.13.0)** — 62 ##[error] lines, identical count to the baseline job; **Docs QA** — the 7 pre-existing stale generated docs (docs:freshness, same list as staging). Green on every run: public-push guard, publish-isolation (now also running test:package-renames), workspace coverage, observer dashboard (1297 tests).
Push cycles: the brief allowed four for B1; seven were used (cycles 5–7 each removed one more stale pin that only the previous cycle's reach could expose). Reported, not hidden.
Commits
On phase1/rename-train: 98f2c7f23 feat(bins): ship the spec 15 §3.1 bin set; single-bin policy default (WP-RN-06) — manifests, entry sources, usage strings, runtime bin resolution, CI lanes/templates, G5 default, check-binary-renames.cjs, fixtures, tests, binary-renames.md; followed by the docs commit adding this record. No PR opened (the orchestrator opens the draft PR), no tag created, nothing published.
Gates (from `C:/work/fabric`)
Orchestrator gate, verbatim, final run after every change: npm run test:binary-renames && node scripts/ci/bin-collision-guard.cjs --private-train && echo RN06-PASS →
Binary rename guardrail passed for 18 spec 15 §3.1 bins across 16 packages (entry targets verified, 8 retired alias sources absent); single-bin policy (G5) holds over 25 workspace bin names.
bin-collision-guard: 25 bin name(s) across the workspace, 0 error(s) (single-bin end-state: spec 15 §3.1 set of 18 bins)
RN06-PASSAC1 proof (node scripts/ci/bin-collision-guard.cjs --json): 25 workspace bin names, 0 with more than one owner; the 18 owned by publishables are exactly SPEC_BINS_31 (agent-runtime catalog console-tui control-plane-demo control-plane-server harness harness-channels harness-extensions harness-hooks harness-mock harness-tasks harness-triggers model-gateway observer operator orchestrator orchestrator-mcp orchestrator-sdk); the other 7 are the private-workspace dev bins listed above. publish-guards.test.mjs "G5 (repository)" asserts the same set mechanically.
Kept green (same run): node scripts/ci/publish-isolation-guard.cjs --self-test → "self-test passed; repository scan clean (101 files, 0 findings, 8 legacy-train notice(s))"; npm run test:publish-guards → 17/17 (G5 fixtures + repository end-state + test:binary-renames wiring, G6 real tarballs); node scripts/ci/no-double-rename.cjs --self-test → 10/10; node scripts/ci/public-push-guard.cjs → "scanned 312 files, 0 finding(s)"; npm run guard:packages → "package-integrity guard passed"; 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 … 112 allowed legacy reference file(s)"; npm run verify:metadata → "Publishable inventory: 43 public packages"; npm run check:sdk-command-templates / check:plugin-commands → "synchronized". node --test scripts/__tests__/hooks-atlas-ownership.test.mjs → 4/6: the two failures are the RN-05 environmental pair (packed install of a hooks leaf resolves @fabricstack/catalog@7.0.0 from npmjs → E404 until the first AR publication), reproduced verbatim from the test output; the test's bin expectation is now ['harness-hooks'].
Environment (Windows, this machine; CI verifies)
Same machine and install state as RN-05 (node_modules restored with npm install --legacy-peer-deps; npm ci deliberately not run): build:app of @fabricstack/observer fails with Cannot find module '../lightningcss.win32-x64-msvc.node' (its build:cli, the bin, builds and smokes fine); vitest cannot load (rolldown-binding.win32-x64-msvc.node), so **none of the package-level vitest suites edited here were executed locally** — SDK (cliMain, cliRuns, instructions, contextShared, resolveDependencyBin, marketplace-owner-and-sdk-bin), harness CLI (bridge-hooks, integration, commands/*, live-stack contract/runner), harness-mock, tasks (cli-program, mcp-documented-surface), triggers, channels, transport, hooks CLI, adapter-codex docs-parity, extensions (packaged-surface-parity via tsx also needs the E404-blocked clean install), agent-runtime cli, console-tui, observer, control-plane (node --test, runnable: tests/bin-smoke.test.js and kradle.test.js pass locally), operator. Every edited assertion was changed by reading the source it pins and cross-checked against the local smoke output above; the CI test / observer-dashboard / workspace-coverage / live-stack jobs (ubuntu) verify them on the pushed commits. The test:release-tooling Windows-impossible list of RN-05 is unchanged. Nothing was deleted or skipped to make a gate pass.