Agentic AI Atlasby a5c.ai
OverviewWikiGraphFor AgentsEdgesSearchWorkspace
/
GitHubDocsDiscord
iiRecord
Agentic AI Atlas · WP-RN-03 record: `@fabricstack` scope + Artifact Registry npm provisioning
page:docs-specs-platform-gaps-phase0-ar-provisioninga5c.ai
Search record views/
Record · tabs

Available views

II.Record viewspp. 1 - 1
overviewarticlejsongraph
III.Related pagespp. 1 - 1
II.
Page reference

page:docs-specs-platform-gaps-phase0-ar-provisioning

Reading · 7 min

WP-RN-03 record: `@fabricstack` scope + Artifact Registry npm provisioning reference

Executed 2026-09-28 on branch phase0/hard-split-registry-guards of a5c-ai/fabric. Spec: docs/specs/platform-gaps/15-private-isolation-rename.md WP-RN-03 (§2 scope decision, §4.1 registry provisioning). Owner approval for the GCP changes was given at the phase0.gcp-provision breakpoint ("Approve (gcloud re-authed) — create fabric-npm + the two IAM bindings, run the WIF smoke publish and the local install"). Developer/CI instructions: docs/user-guide/private-install.md. The public repository a5c-ai/babysitter was never written to (pushedat stayed 2026-09-16T19:59:50Z throughout; only gh api GET calls were issued against it) and nothing was published to registry.npmjs.org.

Pagewiki/docs/specs/platform-gaps/phase0/ar-provisioning.mdOutgoing · 0Incoming · 1

WP-RN-03 record: `@fabricstack` scope + Artifact Registry npm provisioning

**Scope re-locked to @fabricstack on 2026-09-28, see scope-relock.md.** This record was produced under the previous private scope @agentfabric; its scope strings were rewritten mechanically at the re-lock (the quoted run logs and transcripts below therefore originally showed the old name, and the smoke package they refer to is the old-scope 0.0.0-smoke.2, now a cleanup candidate in AR). The re-run under the new scope is recorded in scope-relock.md. The Artifact Registry repository, IAM policy and WIF principal are scope-agnostic and unchanged.

Executed 2026-09-28 on branch phase0/hard-split-registry-guards of a5c-ai/fabric. Spec: docs/specs/platform-gaps/15-private-isolation-rename.md WP-RN-03 (§2 scope decision, §4.1 registry provisioning). Owner approval for the GCP changes was given at the phase0.gcp-provision breakpoint ("Approve (gcloud re-authed) — create fabric-npm + the two IAM bindings, run the WIF smoke publish and the local install"). Developer/CI instructions: docs/user-guide/private-install.md. The public repository a5c-ai/babysitter was never written to (pushed_at stayed 2026-09-16T19:59:50Z throughout; only gh api GET calls were issued against it) and nothing was published to registry.npmjs.org.

What was created

ItemValue
Scope@fabricstack (spec 15 §2; final lock at Gate B)
GCP project / regionboot-464019 / us-central1
Artifact Registry repositoryprojects/boot-464019/locations/us-central1/repositories/fabric-npm, format NPM, mode STANDARD_REPOSITORY, description "agentfabric private npm packages (fabric)", created 2026-09-28T15:06:04Z, Google-managed encryption, vulnerability scanning disabled (containerscanning.googleapis.com not enabled)
Registry URLhttps://us-central1-npm.pkg.dev/boot-464019/fabric-npm/
Committed root .npmrc@fabricstack:registry=https://us-central1-npm.pkg.dev/boot-464019/fabric-npm/ plus a comment line; the pre-existing workspace lines (link-workspace-packages, prefer-workspace-packages, from commit 1f3ea8ad8) were kept; zero credentials
Smoke fixturescripts/ci/fixtures/ar-smoke/package/ (@fabricstack/smoke, publishConfig.registry = registry URL, index.js exports { ok: true })
Smoke workflow.github/workflows/ar-smoke.yml (id 369233665), workflow_dispatch; a push trigger scoped to its own file only registers it on feature branches, the job is gated on github.event_name == 'workflow_dispatch'
Developer/CI docdocs/user-guide/private-install.md

Creation detail: gcloud artifacts repositories create fabric-npm --repository-format=npm ... failed twice with INVALID_ARGUMENT: Maven config is not supported for format "NPM" (a gcloud client defect, also with --mode=standard-repository), so the repository was created with the same parameters through the REST API (POST https://artifactregistry.googleapis.com/v1/projects/boot-464019/locations/us-central1/repositories?repositoryId=fabric-npm, body {"format":"NPM","mode":"STANDARD_REPOSITORY","description":"agentfabric private npm packages (fabric)"}, operation d629ee5e-5f29-49bb-8122-db614d5b2ac8). gcloud artifacts repositories describe fabric-npm --location=us-central1 --project=boot-464019 confirms the values in the table.

The spec's second .npmrc line (//us-central1-npm.pkg.dev/boot-464019/fabric-npm/:always-auth=true) was not added: always-auth is not an npm >= 9 option (npm 10 ignores it with a warning), and the brief for this work package asked for the scope-routing line only. Artifact Registry npm requires a bearer token on every request regardless, which the helper provides.

IAM (repository-scoped only; nothing granted at project level)

The CI identity is the existing WIF pair from the a5c-ai organization variables (visibility ALL, so no environment: is needed in workflows): GCP_SERVICE_ACCOUNT=github-deployer@boot-464019.iam.gserviceaccount.com, GCP_WORKLOAD_IDENTITY_PROVIDER=projects/1024539647872/locations/global/workloadIdentityPools/github/providers/a5c-ai, GCP_PROJECT_ID=boot-464019. No new service account or WIF pool was created.

Commands run:

bash
gcloud artifacts repositories add-iam-policy-binding fabric-npm --location=us-central1 --project=boot-464019 \
  --member=serviceAccount:github-deployer@boot-464019.iam.gserviceaccount.com --role=roles/artifactregistry.writer
gcloud artifacts repositories add-iam-policy-binding fabric-npm --location=us-central1 --project=boot-464019 \
  --member=user:tal@a5c.ai --role=roles/artifactregistry.reader
gcloud artifacts repositories get-iam-policy fabric-npm --location=us-central1 --project=boot-464019 --format=json

Final policy, verbatim:

json
{
  "bindings": [
    {
      "members": [
        "user:tal@a5c.ai"
      ],
      "role": "roles/artifactregistry.reader"
    },
    {
      "members": [
        "serviceAccount:github-deployer@boot-464019.iam.gserviceaccount.com"
      ],
      "role": "roles/artifactregistry.writer"
    }
  ],
  "etag": "BwZcjGj6Uio=",
  "version": 1
}

Human principal set: user:tal@a5c.ai (reader). Additional developers get roles/artifactregistry.reader on the repository with the first command above; writer stays reserved for the CI service account (spec 15 §4.1: "humans reader-by-default, writer only for release owners").

WIF principal (pre-existing, unchanged)

gcloud iam service-accounts get-iam-policy github-deployer@boot-464019.iam.gserviceaccount.com shows roles/iam.workloadIdentityUser for principalSet://iam.googleapis.com/projects/1024539647872/locations/global/workloadIdentityPools/github/attribute.repository/a5c-ai/fabric (alongside a5c-ai/babysitter, a5c-ai/company, a5c-ai/osb). The pool provider github/providers/a5c-ai has attribute condition assertion.repository_owner == "a5c-ai" and maps attribute.repository. No WIF change was needed or made.

Smoke run (AC1, AC2 publish half)

  • Registration: the first gh workflow run ar-smoke.yml --ref phase0/hard-split-registry-guards returned HTTP 404: workflow ar-smoke.yml not found on the default branch, the same behavior WP-RN-01 hit; the push trigger + job gate fixed it (push run 36441528697, conclusion skipped, published nothing).
  • Dispatch: gh workflow run ar-smoke.yml -R a5c-ai/fabric --ref phase0/hard-split-registry-guards → run https://github.com/a5c-ai/fabric/actions/runs/36441575117 (run number 2, attempt 1, head 984e39bde), conclusion **success**, all steps green.
  • Log excerpts (job 108993127550):
text
Retrieving credentials from gcloud...
Success!
npm notice PING https://us-central1-npm.pkg.dev/boot-464019/fabric-npm/
npm notice PONG 215ms
npm notice Publishing to https://us-central1-npm.pkg.dev/boot-464019/fabric-npm/ with tag latest and default access (dry-run)
+ @fabricstack/smoke@0.0.0-smoke.2
npm notice Publishing to https://us-central1-npm.pkg.dev/boot-464019/fabric-npm/ with tag latest and default access
+ @fabricstack/smoke@0.0.0-smoke.2
name = '@fabricstack/smoke'
version = '0.0.0-smoke.2'
dist.tarball = 'https://us-central1-npm.pkg.dev/boot-464019/fabric-npm/@fabricstack/smoke/-/@fabricstack/smoke-0.0.0-smoke.2.tgz'
  • Registry state afterwards: gcloud artifacts packages list --repository=fabric-npm --location=us-central1 → @fabricstack/smoke (2026-09-28T18:11:04); versions → 0.0.0-smoke.2 only.

Local install transcript (AC2 install half; this machine, following only `docs/user-guide/private-install.md`)

Fresh directory outside the repository (gcloud auth login had already been done for tal@a5c.ai; gcloud auth list → tal@a5c.ai *):

text
$ printf '@fabricstack:registry=https://us-central1-npm.pkg.dev/boot-464019/fabric-npm/\n' > .npmrc
$ npx -y google-artifactregistry-auth --repo-config=.npmrc --credential-config="$HOME/.npmrc"
Retrieving application default credentials...
Retrieving credentials from gcloud...
Success!
$ npm init -y >/dev/null
$ npm view @fabricstack/smoke version --registry https://us-central1-npm.pkg.dev/boot-464019/fabric-npm/
0.0.0-smoke.2
$ npm install @fabricstack/smoke@0.0.0-smoke.2
added 1 package, and audited 2 packages in 2s
found 0 vulnerabilities
$ node -e "console.log(require('@fabricstack/smoke'))"
{ ok: true }
$ node -e "const p=require('@fabricstack/smoke/package.json');console.log(p.name, p.version, p.publishConfig.registry)"
@fabricstack/smoke 0.0.0-smoke.2 https://us-central1-npm.pkg.dev/boot-464019/fabric-npm/
$ grep resolved package-lock.json
"resolved": "https://us-central1-npm.pkg.dev/boot-464019/fabric-npm/@fabricstack/smoke/-/@fabricstack/smoke-0.0.0-smoke.2.tgz"
$ grep -iE "_authToken|password|token=" .npmrc ; echo $?
1

The helper wrote //us-central1-npm.pkg.dev/boot-464019/fabric-npm/:_authToken=... into the user ~/.npmrc and left both project .npmrc files untouched.

AC3: committed `.npmrc` has zero credentials

  • grep -iE "_authToken|password|token=" .npmrc → no match (exit 1), before and after the helper and the workflow run.
  • History secret scan: git log --all -p -- .npmrc | grep -iE "_authToken|password|token=" → no match across all three historical commits touching the file (836d2677e, d2fd97ff0, 1f3ea8ad8).
  • Other .npmrc files in the tree: packages/observer-dashboard/.npmrc (engine-strict, install-strategy only). No package sets a conflicting publishConfig.registry; the 43 @a5c-ai/* packages keep publishConfig.access: public untouched (their retarget is WP-RN-04/RN-1).
  • The workflow's credential step asserts the same grep and git diff --exit-code -- .npmrc after the helper runs.
  • Gate command (run from the repository root after everything else): npx -y google-artifactregistry-auth --repo-config=.npmrc >/dev/null 2>&1; npm ping --registry https://us-central1-npm.pkg.dev/boot-464019/fabric-npm/ && ! grep -iE "_authToken|password|token=" .npmrc && echo AR-PING-PASS → PONG 332ms, AR-PING-PASS.

Isolation checks

  • curl -s -o /dev/null -w "%{http_code}" https://registry.npmjs.org/@fabricstack%2fsmoke → 404.
  • npm view @fabricstack/smoke --registry https://registry.npmjs.org/ from a directory **without** scope routing → E404 '@fabricstack/smoke@*' is not in this registry.
  • Caveat for anyone repeating that check: run it from inside the repository and npm answers from Artifact Registry, because a scoped @fabricstack:registry line takes precedence over --registry for scoped names. That precedence is why the committed .npmrc alone already steers every @fabricstack/* request away from npmjs; it is not a substitute for the G1–G6 guards of WP-RN-04.
  • node scripts/ci/public-push-guard.cjs → scanned 120 files, 0 finding(s), 0 suppressed; --self-test → 24/24 assertions passed. The new workflow and fixture add no public-repo reference.
  • gh api repos/a5c-ai/babysitter --jq .pushed_at → 2026-09-16T19:59:50Z at start and end; git remote -v → upstream no_push (push) throughout.

Commits

  • 393bf1f03 feat(registry): provision Artifact Registry npm + @fabricstack scope routing (WP-RN-03)
  • 984e39bde ci(registry): register ar-smoke from feature branches via a gated push trigger
  • this record: see git log -- docs/specs/platform-gaps/phase0/ar-provisioning.md

Rollback

bash
# remove the smoke package (keeps the repository)
gcloud artifacts packages delete @fabricstack/smoke --repository=fabric-npm --location=us-central1 --project=boot-464019 --quiet
# remove the IAM bindings
gcloud artifacts repositories remove-iam-policy-binding fabric-npm --location=us-central1 --project=boot-464019 \
  --member=user:tal@a5c.ai --role=roles/artifactregistry.reader
gcloud artifacts repositories remove-iam-policy-binding fabric-npm --location=us-central1 --project=boot-464019 \
  --member=serviceAccount:github-deployer@boot-464019.iam.gserviceaccount.com --role=roles/artifactregistry.writer
# delete the repository (irreversible; deletes every package in it)
gcloud artifacts repositories delete fabric-npm --location=us-central1 --project=boot-464019 --quiet
# fabric side
git revert 984e39bde 393bf1f03
# developer machines: drop the token line from ~/.npmrc (tokens expire after about an hour anyway)

Article source

The article body is owned directly by this record.

Related pages

No related wiki pages for this record.

Shortcuts

Open overview
Open JSON
Open graph