Agentic AI Atlasby a5c.ai
OverviewWikiGraphFor AgentsEdgesSearchWorkspace
/
GitHubDocsDiscord
iiRecord
Agentic AI Atlas · Phase 0 (M0): hard split, private registry, publish guards, Effect baseline
page:docs-specs-platform-gaps-phase0-pr-bodya5c.ai
Search record views/
Record · tabs

Available views

II.Record viewspp. 1 - 1
overviewarticlejsongraph
II.
Page overview

page:docs-specs-platform-gaps-phase0-pr-body

Reference · live

Phase 0 (M0): hard split, private registry, publish guards, Effect baseline overview

Inspect the raw attributes, linked wiki pages, and inbound or outbound graph edges for page:docs-specs-platform-gaps-phase0-pr-body.

PageOutgoing · 0Incoming · 1

Attributes

nodeKind
Page
sourcePath
docs/specs/platform-gaps/phase0/PR-BODY.md
sourceKind
repo-docs
title
Phase 0 (M0): hard split, private registry, publish guards, Effect baseline
displayName
Phase 0 (M0): hard split, private registry, publish guards, Effect baseline
slug
docs/specs/platform-gaps/phase0/pr-body
articlePath
wiki/docs/specs/platform-gaps/phase0/PR-BODY.md
article
# Phase 0 (M0): hard split, private registry, publish guards, Effect baseline Branch `phase0/hard-split-registry-guards` → `staging`. 17 commits (`git log --oneline origin/staging..HEAD`), executing roadmap Phase 0 (`docs/specs/platform-gaps/50-roadmap-workpackages.md` §5): WP-RN-01, WP-RN-02, WP-RN-03, WP-RN-04, WP-RN-08 (spec 15) and WP-T3-32 stage 1 (spec 10), plus the owner-decided scope re-lock `@agentfabric` → `@fabricstack`. Invariants held throughout and re-verified at review time (2026-09-28): 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 before cutover; the `upstream` remote's push URL is `no_push`); nothing was published to `registry.npmjs.org` (`@fabricstack/smoke` → HTTP 404 there); the only registry write is the throwaway smoke package in Artifact Registry. ## Per-WP summary | WP | Commits | What landed | Record | |---|---|---|---| | WP-RN-01 two-repo hard split | `9e2957a06`, `7271ac146`, `b1146c911`, `49db231a9` | Cutover baseline (public `main` `feb68abe3`, 341 public heads, 7 fabric refs, snapshots + `watch-baseline.json`); read-only API evidence that no hosting-level transport exists (fabric is not a fork, no `mirror_url`, no webhooks or deploy keys on either repo); branch ruleset `protect-main-staging` (id `24103129`, active, `deletion` + `non_fast_forward` + `pull_request` on `main`/`staging`); `docs/DIVERGENCE-POLICY.md` with spec 15 §1.2 invariants 1–4 verbatim; `publish.yml` header no longer self-describes as a mirror; README repo-role statement; scheduled read-only propagation watch (`upstream-propagation-watch.yml` + `scripts/ci/upstream-propagation-watch.sh`) | [watch-baseline.md](https://github.com/a5c-ai/fabric/blob/phase0/hard-split-registry-guards/docs/specs/platform-gaps/phase0/watch-baseline.md) | | WP-RN-02 intake process + public-push guard | `030920ec6`, `4ea32666c` | `scripts/ci/public-push-guard.cjs` (8 rules, 13 negative + 9 positive fixtures, `--self-test`, node:test suite); CI job `public-push-guard` in `ci.yml`; `docs/UPSTREAM-INTAKE.md` (fetch-only remote, labeling, path map, fabric-wins conflict policy); label `upstream-intake`; PR template `.github/PULL_REQUEST_TEMPLATE/upstream-intake.md`; two inherited workflows fixed to stop targeting the public repo; rehearsal cherry-pick of public `76434c235` opened as [PR #2](https://github.com/a5c-ai/fabric/pull/2) | [intake-rehearsal.md](https://github.com/a5c-ai/fabric/blob/phase0/hard-split-registry-guards/docs/specs/platform-gaps/phase0/intake-rehearsal.md) | | WP-RN-03 scope + Artifact Registry provisioning | `393bf1f03`, `984e39bde`, `9ef6e7767` | AR npm repository `fabric-npm` (`boot-464019`/`us-central1`, standard, created 2026-09-28T15:06:04Z); repository-scoped IAM only (writer = `github-deployer@boot-464019.iam.gserviceaccount.com`, reader = `user:tal@a5c.ai`); root `.npmrc` scope routing line, zero credentials; `.github/workflows/ar-smoke.yml` (WIF auth, ping, dry-run-asserted publish, read-back); `docs/user-guide/private-install.md` | [ar-provisioning.md](https://github.com/a5c-ai/fabric/blob/phase0/hard-split-registry-guards/docs/specs/platform-gaps/phase0/ar-provisioning.md) | | WP-RN-04 publish-isolation guards G1–G6 | `f87f8d2e5`, `23b4a0f46` | Single constant `fabric.{privateScope,privateRegistry,legacyPublicScope}` in root `package.json` (`scripts/lib/registry-pin.cjs`); `scripts/ci/publish-isolation-guard.cjs` (G1 manifest pinning, G2 CI rules, G3 credential starvation, G4 informational status probe); `scripts/ci/bin-collision-guard.cjs` inside `test:binary-renames` (G5); `scope` step in `scripts/verify-release-artifacts.mjs` + self-test in `release-artifact-verifier.yml` (G6); CI job `publish-isolation`; negative fixtures under `scripts/ci/fixtures/publish-guards/{g1,g2,g3,g5,g6}`; read-only secret audit; `FABRIC_PRIVATE_TRAIN` flag for the RN-1 end-state | [publish-guards.md](https://github.com/a5c-ai/fabric/blob/phase0/hard-split-registry-guards/docs/specs/platform-gaps/phase0/publish-guards.md), [g4-npmjs-org-runbook.md](https://github.com/a5c-ai/fabric/blob/phase0/hard-split-registry-guards/docs/specs/platform-gaps/phase0/g4-npmjs-org-runbook.md), [g3-npm-token-restriction.md](https://github.com/a5c-ai/fabric/blob/phase0/hard-split-registry-guards/docs/specs/platform-gaps/phase0/g3-npm-token-restriction.md) | | Scope re-lock (owner decision, breakpoint `phase0.npmjs-org`) | `b4b3fa403`, `c9bfec2aa` | `@agentfabric` found third-party-owned on npmjs; re-locked to `@fabricstack` (free: org/user 404, unscoped 404, search total 0); spec 15 §2 rewritten with a dated amendment; specs 10/20/30/40/50, docs, workflows, all guard fixtures and the smoke package swept; AR smoke re-run under the new scope (run [36454074285](https://github.com/a5c-ai/fabric/actions/runs/36454074285), `@fabricstack/smoke@0.0.0-smoke.4`) | [scope-relock.md](https://github.com/a5c-ai/fabric/blob/phase0/hard-split-registry-guards/docs/specs/platform-gaps/phase0/scope-relock.md) | | WP-RN-08 no-double-rename gate | `efbd9de3f`, `80cd53a48` | `scripts/ci/no-double-rename.cjs` (9 rules, no waiver; name matrix parsed from spec 15 by `scripts/lib/rename-spec.cjs`; 59-entry baseline pinned to spec 15's current-name column); `scripts/ci/check-spec10-names.cjs` (spec 10 references only §3.3 names: 0 violations); 7 negative + 2 positive fixtures; wired into the `publish-isolation` job; naming rules in `docs/UPSTREAM-INTAKE.md` §10 and the intake PR template | [no-double-rename.md](https://github.com/a5c-ai/fabric/blob/phase0/hard-split-registry-guards/docs/specs/platform-gaps/phase0/no-double-rename.md) | | WP-T3-32 stage 1 Effect baseline | `5d16b830e`, `c56d71ee3` | Workspace-wide pin `effect@4.0.0-rc.115` + `@effect/vitest@4.0.0-rc.115` (root `overrides` + `devDependencies`); `patch-package --error-on-fail` on `postinstall`; ported `patches/effect+4.0.0-rc.115.patch` (5 files, 23 hunks, bodies byte-identical to upstream); MIT attribution in `third_party/t3code-patches/`; `scripts/ci/effect-baseline.test.mjs` (13 cases, in the CI `test` job); `docs/EFFECT-BASELINE.md` (pin owner, provenance, unstable-namespace register, rc→stable criteria, upgrade playbook); inventory of all 23 upstream patches | [effect-baseline.md](https://github.com/a5c-ai/fabric/blob/phase0/hard-split-registry-guards/docs/specs/platform-gaps/phase0/effect-baseline.md), [t3code-patches-inventory.md](https://github.com/a5c-ai/fabric/blob/phase0/hard-split-registry-guards/docs/specs/platform-gaps/phase0/t3code-patches-inventory.md) | ## M0 exit criteria (roadmap §5, Phase 0) | # | Criterion | Status | Evidence (re-run at review) | |---|---|---|---| | 1 | Hard split proven strictly read-only: mirror transport confirmed disabled with API evidence; ≥7-day propagation watch shows no upstream commit entering fabric outside `upstream-intake` PRs; `publish.yml` no longer self-describes as a mirror (WP-RN-01 AC1/AC2/AC4) | **Met, watch window open** | `gh api repos/a5c-ai/fabric` → `fork:false, mirror_url:null, parent:null`; 0 hooks on both repos; ruleset `24103129` active; public `pushed_at` unchanged; `bash scripts/ci/upstream-propagation-watch.sh` → `verdict: PASS` (341 heads, 0 post-baseline upstream commits, 9 fabric refs, 0 unexplained); CI watch runs [36392536804](https://github.com/a5c-ai/fabric/actions/runs/36392536804), [36392593360](https://github.com/a5c-ai/fabric/actions/runs/36392593360), [36392751222](https://github.com/a5c-ai/fabric/actions/runs/36392751222), [36392886290](https://github.com/a5c-ai/fabric/actions/runs/36392886290) all `success`. Watch **started 2026-09-28T07:29:35Z**; the ≥7-day window (which must contain a post-cutover public commit) is not yet closed — see "Pending owner actions" | | 2 | `npm ping` against `fabric-npm` succeeds from CI via WIF; `@fabricstack/smoke` publish+install rehearsal passes from the written doc alone (WP-RN-03 AC1–2) | **Met** | ar-smoke runs [36441575117](https://github.com/a5c-ai/fabric/actions/runs/36441575117) and [36454074285](https://github.com/a5c-ai/fabric/actions/runs/36454074285) `success` with every step green (WIF auth, ping, dry-run, publish, read-back); reviewer install in a fresh directory following only `docs/user-guide/private-install.md`: `npm install @fabricstack/smoke` → `{"ok":true} @fabricstack/smoke 0.0.0-smoke.4`, lockfile `resolved` on `us-central1-npm.pkg.dev`; local `npm ping` → `PONG` | | 3 | Guards G1–G6 each demonstrated red-until-green on their negative fixtures; repo secret audit shows no npmjs credential (WP-RN-04) | **Met** | `publish-isolation-guard --root` on `g1/negative/public-npmjs`, `g2/negative/npmjs-publish-private-scope`, `g3/negative/npmrc-token` → exit 1 each; `bin-collision-guard --root g5/negative/duplicate-bin` → exit 1; `verify-release-artifacts.mjs` on `g6/negative/private-scope-npmjs` → `scope: failed`, exit 1, and on `g6/positive/pinned` → passed; `--self-test` → 14/14, tree clean (122 files, 0 findings); `npm run test:publish-guards` → 17/17; `npm run test:binary-renames` → 32 bin names, 0 errors; `gh secret list -R a5c-ai/fabric` → only `KRADLE_TEST_AUTH_SECRET`; `.npmrc` and its full history carry no `_authToken`/`password`/`token=` | | 4 | The no-double-rename gate trips on a fixture `@t3code/x` manifest (WP-RN-08 AC2) | **Met** | `no-double-rename.cjs --root scripts/ci/fixtures/no-double-rename/negative/t3code-scope` → `packages/x/package.json:2: [t3code-scope-name] @t3code/x is a t3code-scoped name; ...`, exit 1; `--self-test` → 10/10; `npm run test:no-double-rename` → 16/16; `check-spec10-names.cjs` → 0 violations | | 5 | `npm ls effect` resolves a single `effect@4.0.0-rc.115` workspace-wide and the patch-regression test passes (WP-T3-32 AC1–2) | **Met** | `npm ls effect --all` → `effect@4.0.0-rc.115 overridden` (+ one `deduped` under `@effect/vitest@4.0.0-rc.115`); `npm run test:effect-baseline` → 13/13 (cases 5–8 are the patched-behaviour detectors, proven red with the patch reversed) | ## WP acceptance criteria not fully closable inside this branch (accepted by design; listed, not hidden) - **WP-RN-01 AC1(b)** — the ≥7-day passive propagation watch is only **started** (2026-09-28T07:29:35Z): cutover recorded, scheduled read-only watch installed, first runs green. The roadmap's wall-clock note keeps this off Phase 1's critical path; only the formal M0 gate record waits for the window (it must also contain at least one post-cutover public commit, and the public repo has not moved since 2026-09-16). - **WP-RN-02 AC3 / test requirement "rehearsal PR merged"** — [PR #2](https://github.com/a5c-ai/fabric/pull/2) (`intake/76434c2`, label `upstream-intake`, path map recorded) is **open, not merged**; merging is the owner's decision. - **WP-RN-04 G1 selector switch** (spec 15 §4.3: "must change in the same commit" as the manifests are pinned) — no manifest is renamed yet, so the switch is implemented behind `FABRIC_PRIVATE_TRAIN=1` (default off, byte-identical to the old inventory: 43 `@a5c-ai/*` entries, pinned by test) and flips in the RN-1 train (WP-RN-05/07). G2(b), G2(d), the G5 legacy-collision tolerance and the whole-tree npmjs rules follow the same flag. - **WP-RN-04 G4** — npmjs organization `fabricstack` is **not yet created** (pending owner action; the scope is free as of 2026-09-28, probe `--g4-status` → `unregistered`). - **WP-RN-04 G3 at organization level** — org secret `NPM_TOKEN` still has visibility `all` (readable by this repo through two inherited legacy `@a5c-ai` train workflows, reported by the guard as 8 legacy-train notices); restriction is a pending owner UI action. - **WP-RN-08 AC3** (first real landed fork passes the gate un-waived) — not yet exercisable; no fork has landed. Owned by WP-T3-01/02 (M2 exit criterion 1). - **WP-T3-32 AC3–AC5** (stage 2: build matrix, Vite/vitest re-platform, engine floors) — out of scope by the roadmap's staging; deferred in `docs/EFFECT-BASELINE.md` §7. ## Pending owner actions (outside the repository) 1. **G4 — register the `fabricstack` org on npmjs** per [g4-npmjs-org-runbook.md](https://github.com/a5c-ai/fabric/blob/phase0/hard-split-registry-guards/docs/specs/platform-gaps/phase0/g4-npmjs-org-runbook.md): company account, publish nothing, 2FA required, sole owner; then record the org URL in `publish-guards.md` (G4 row). Verify with `node scripts/ci/publish-isolation-guard.cjs --g4-status` → `registered-no-packages`. 2. **G3 — restrict org secret `NPM_TOKEN`** to selected repositories excluding `a5c-ai/fabric` (GitHub UI; the API path needs the secret value) per [g3-npm-token-restriction.md](https://github.com/a5c-ai/fabric/blob/phase0/hard-split-registry-guards/docs/specs/platform-gaps/phase0/g3-npm-token-restriction.md). Verify: `gh api orgs/a5c-ai/actions/secrets/NPM_TOKEN --jq .visibility` → `selected`. 3. **Close the ≥7-day propagation watch** once the window has elapsed and contains a post-cutover public commit: record the last green run, the `git for-each-ref` after-snapshot and the ref-by-ref diff against `fabric-refs-baseline.txt` in `watch-baseline.md` ("Closing procedure"). Until the workflow is on `main`, the schedule does not fire; dispatch with `gh workflow run upstream-propagation-watch.yml -R a5c-ai/fabric --ref <branch>`. 4. **Decide PR #2** (merge or close the intake rehearsal). 5. Optional cleanup: delete the old-scope `@agentfabric/smoke@0.0.0-smoke.2` from `fabric-npm` (`gcloud artifacts packages delete @agentfabric/smoke --repository=fabric-npm --location=us-central1 --project=boot-464019 --quiet`) and update the AR repository description (still "agentfabric private npm packages (fabric)"). ## Deferred items - **G1 selector switch** to `publishConfig.registry`-keyed selection: RN-1 train (WP-RN-05/07), behind `FABRIC_PRIVATE_TRAIN`. - **WP-T3-32 stage 2**: apps re-platform on stock Vite/vitest/tsc (`@voidzero-dev/*` grep gate), workspace `engines` ≥22.16 with the sub-floor CI run, tracked-fork build matrix; depends on WP-T3-01. Stage-2 input recorded: `@effect/vitest@4.0.0-rc.115` peers on `vitest >=5 <6` while fabric runs 4.1.6, so it is pinned and locked but not yet usable as a harness. - **`@effect/vitest` upstream patch dropped (DROPPED-toolchain)**, not ported: its only effect is `vitest` → `vite-plus/test` import rewriting, which is wrong under stock vitest; test 10 pins the unpatched imports. The WP objective text says "patched `@effect/vitest`"; the ACs (1), (2), (6) do not require it and the decision is recorded in `docs/EFFECT-BASELINE.md` §3. - **Patch inventory count**: 17 mobile-only (not the 19 the WP brief assumed) because `@legendapp/list` and `@pierre/diffs` are also consumed by `t3:apps/web`; those two plus `@ff-labs/fff-node` and `dbus-next` are DEFERRED-stage-2 to the WPs that land their consumers. - **Retargeting the 43 `@a5c-ai` manifests and the release workflows** (WP-RN-05/06/07); the two legacy workflows referencing `secrets.NPM_TOKEN` become hard findings under `--private-train`. ## Review observations (not failures) - `git grep -l "@agentfabric/"` lists four files: the two historical records (`g4-npmjs-org-runbook.md`, `scope-relock.md`) and two WP-RN-08 negative fixtures (`scripts/ci/fixtures/no-double-rename/negative/rejected-scope/packages/x/package.json`, `scripts/ci/fixtures/no-double-rename/spec10/negative.md`) that deliberately use the rejected scope to prove the `foreign-scope-new-unit` / `rejected-scope-name` rules trip. `scope-relock.md`'s "only two files" statement predates those fixtures. - `ci.yml` triggers on `pull_request` and `workflow_dispatch` only, so the `publish-isolation` job (WP-RN-04/08) and the `test` job's "Effect baseline" step have not yet executed in GitHub Actions; this PR's CI run is their first. The one `ci.yml` run tied to this branch (PR #2, run [36395354707](https://github.com/a5c-ai/fabric/actions/runs/36395354707)) ran the `public-push-guard` job green; its four red jobs (`Gateway Node engine floor` ×2 at "Build adapters gateway", `Lint, Tests, Package` at "Release tooling tests", `Docs QA` at "Docs quality gates") fail on exactly the same steps in the pre-Phase-0 run [36332996215](https://github.com/a5c-ai/fabric/actions/runs/36332996215) (`c0dd9722c`, PR #1) and are unrelated to this branch. - `npx markdownlint-cli2 docs/specs/platform-gaps/phase0/watch-baseline.md` reports MD010 hard tabs at lines 385–386 (inside the verbatim `git ls-remote` dump). The repo's markdownlint scope (`.markdownlint-cli2.mjs` globs) does not include the phase0 records; root `npx markdownlint-cli2` → 0 errors. ## How to verify Run from the repository root on this branch (`node_modules` installed with `npm install --legacy-peer-deps`). ```bash # Guards: self-tests (fixtures red, tree green) node scripts/ci/public-push-guard.cjs --self-test node scripts/ci/publish-isolation-guard.cjs --self-test node scripts/ci/no-double-rename.cjs --self-test node scripts/ci/check-spec10-names.cjs --self-test # Guards: node:test suites npm run test:public-push-guard npm run test:publish-guards npm run test:binary-renames npm run test:no-double-rename npm run test:effect-baseline # Negative fixtures trip (each exits 1) node scripts/ci/public-push-guard.cjs scripts/ci/fixtures/public-push-guard/negative/git-push-https.workflow.yml node scripts/ci/publish-isolation-guard.cjs --root scripts/ci/fixtures/publish-guards/g1/negative/public-npmjs node scripts/ci/publish-isolation-guard.cjs --root scripts/ci/fixtures/publish-guards/g2/negative/npmjs-publish-private-scope node scripts/ci/publish-isolation-guard.cjs --root scripts/ci/fixtures/publish-guards/g3/negative/npmrc-token node scripts/ci/bin-collision-guard.cjs --root scripts/ci/fixtures/publish-guards/g5/negative/duplicate-bin node scripts/verify-release-artifacts.mjs --package-dir scripts/ci/fixtures/publish-guards/g6/negative/private-scope-npmjs --skip-build --report-dir "$TMPDIR/g6" node scripts/ci/no-double-rename.cjs --root scripts/ci/fixtures/no-double-rename/negative/t3code-scope # Effect singleton npm ls effect --all # Scope constant, routing, credentials node -e "console.log(require('./package.json').fabric)" grep "@fabricstack:registry=" .npmrc grep -iE "_authToken|password|token=" .npmrc # must print nothing (exit 1) git log --all -p -- .npmrc | grep -iE "_authToken|password|token=" # must print nothing # Artifact Registry (needs gcloud auth as a reader of fabric-npm) npx -y google-artifactregistry-auth --repo-config=.npmrc --credential-config="$HOME/.npmrc" npm ping --registry https://us-central1-npm.pkg.dev/boot-464019/fabric-npm/ npm view @fabricstack/smoke versions --registry https://us-central1-npm.pkg.dev/boot-464019/fabric-npm/ node scripts/ci/publish-isolation-guard.cjs --g4-status # informational: unregistered until G4 is done # Hard split invariants (read-only) git remote -v # upstream ... no_push (push) bash scripts/ci/upstream-propagation-watch.sh # verdict: PASS gh api repos/a5c-ai/babysitter --jq .pushed_at # 2026-09-16T19:59:50Z gh api repos/a5c-ai/fabric/rulesets # id 24103129 active gh pr view 2 -R a5c-ai/fabric --json state,labels gh run list -R a5c-ai/fabric --workflow ar-smoke.yml --branch phase0/hard-split-registry-guards --limit 3 gh run list -R a5c-ai/fabric --workflow upstream-propagation-watch.yml --branch phase0/hard-split-registry-guards --limit 3 ``` 🤖 Generated with [Claude Code](https://claude.com/claude-code)
documents
[]

Outgoing edges

None.

Incoming edges

contains_page1
  • page:docs·PageBabysitter Docs

Related pages

No related wiki pages for this record.

Shortcuts

Open in graph
Browse node kind