Agentic AI Atlasby a5c.ai
OverviewWikiGraphFor AgentsEdgesSearchWorkspace
/
GitHubDocsDiscord
iiRecord
Agentic AI Atlas · WP-RN-02 record: public-push guard and intake rehearsal
page:docs-specs-platform-gaps-phase0-intake-rehearsala5c.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-intake-rehearsal

Reading · 9 min

WP-RN-02 record: public-push guard and intake rehearsal 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-02 (objective: codify the §1.4 intake process; make pushing fabric content to the public repository mechanically impossible from CI). Policy: docs/DIVERGENCE-POLICY.md; procedure: docs/UPSTREAM-INTAKE.md; cutover baseline: watch-baseline.md. The public repository a5c-ai/babysitter was read from and never written to (pushedat stayed 2026-09-16T19:59:50Z throughout; only git fetch upstream --no-tags, git ls-remote, gh api GET and gh pr list -R a5c-ai/babysitter were issued against it).

Pagewiki/docs/specs/platform-gaps/phase0/intake-rehearsal.mdOutgoing · 0Incoming · 1

WP-RN-02 record: public-push guard and intake rehearsal

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-02 (objective: codify the §1.4 intake process; make pushing fabric content to the public repository mechanically impossible from CI). Policy: docs/DIVERGENCE-POLICY.md; procedure: docs/UPSTREAM-INTAKE.md; cutover baseline: watch-baseline.md. The public repository a5c-ai/babysitter was read from and never written to (pushed_at stayed 2026-09-16T19:59:50Z throughout; only git fetch upstream --no-tags, git ls-remote, gh api GET and gh pr list -R a5c-ai/babysitter were issued against it).

What landed

ItemLocation
Guard scriptscripts/ci/public-push-guard.cjs (CommonJS, Node >= 22, no dependencies; --self-test, --root, --json)
Fixturesscripts/ci/fixtures/public-push-guard/negative/ (13, each declares expect: <rule>), .../positive/ (9)
Unit testsscripts/ci/public-push-guard.test.mjs (node:test), npm run test:public-push-guard; scan alone: npm run guard:public-push
CI jobpublic-push-guard in .github/workflows/ci.yml (permissions contents: read; --self-test, then asserts the checkout has no pushable remote for the public repository)
Intake proceduredocs/UPSTREAM-INTAKE.md
PR labelupstream-intake on a5c-ai/fabric (0E8A16, "Cherry-picked from public a5c-ai/babysitter")
PR template.github/PULL_REQUEST_TEMPLATE/upstream-intake.md (the default PULL_REQUEST_TEMPLATE.md is untouched)
Policy linkdocs/DIVERGENCE-POLICY.md §4 now points at the real intake doc, template, guard and this record

Guard rules

RuleTrips onAllowed form
push-to-publicgit push <public url>; git push <remote> when the file binds that remote to the public repositorygit push origin ...
pushable-remotegit remote add / git config remote.<n>.url / git clone / gh repo clone of the public repository without git remote set-url --push <n> no_push (or remote.<n>.pushurl no_push) in the same filethe fetch-only idiom of .github/workflows/upstream-propagation-watch.yml
push-url-setgit remote set-url --push <n> <public url>, git config remote.<n>.pushurl <public url>... no_push
ssh-urlgit@github.com:a5c-ai/babysitter outside a git fetch / ls-remote / remote-binding linegit fetch git@github.com:a5c-ai/babysitter.git main
gh-writegh api with -X POST/PUT/PATCH/DELETE or request fields against repos/a5c-ai/babysitter...; any non-read gh <group> <verb> -R a5c-ai/babysitter (pr create, release create, workflow run, ...)gh api repos/a5c-ai/babysitter --jq ..., gh pr list -R a5c-ai/babysitter
checkout-with-writeactions/checkout with repository: a5c-ai/babysitter plus token:, ssh-key:, persist-credentials: true, or contents: write / write-all in the filepersist-credentials: false under contents: read
action-targets-publicany other step whose with: block (including JSON inside prompts) carries repository: / repo: = the public repositoryuses: a5c-ai/babysitter/<path>@<ref> itself; ${{ github.repository }}
submodule-public.gitmodules url pointing at the public repository—

Scanned surface: .github/**, scripts/** (minus the guard, its test and its fixtures), package.json, .npmrc, .gitmodules; file types .yml .yaml .json .cjs .mjs .sh. Comments and Markdown are never findings; @a5c-ai/* npm names never match. Escape hatch: # public-push-guard: allow <reason> (trailing or on the preceding comment line; the reason is mandatory, a bare marker still fails).

Evidence: guard

text
$ node scripts/ci/public-push-guard.cjs --self-test
PASS  fixtures present  -- 13 negative, 9 positive
PASS  negative scripts/ci/fixtures/public-push-guard/negative/action-targets-public.workflow.yml trips  -- rules: action-targets-public
PASS  negative .../allow-marker-without-reason.workflow.yml trips  -- rules: push-to-public
PASS  negative .../checkout-with-token.workflow.yml trips  -- rules: checkout-with-write
PASS  negative .../checkout-write-permissions.workflow.yml trips  -- rules: checkout-with-write
PASS  negative .../clone-without-no-push.sh trips  -- rules: pushable-remote
PASS  negative .../gh-api-post.sh trips  -- rules: gh-write
PASS  negative .../gh-pr-create.workflow.yml trips  -- rules: gh-write
PASS  negative .../git-push-https.workflow.yml trips  -- rules: push-to-public
PASS  negative .../package-scripts.json trips  -- rules: push-to-public
PASS  negative .../push-named-remote.sh trips  -- rules: push-to-public
PASS  negative .../remote-add-ssh-without-no-push.workflow.yml trips  -- rules: pushable-remote
PASS  negative .../set-url-push.sh trips  -- rules: push-url-set
PASS  negative .../submodule/.gitmodules trips  -- rules: submodule-public
PASS  positive .../allow-marker.sh passes  -- 2 suppressed by allow marker
PASS  positive .../checkout-read-only.workflow.yml passes
PASS  positive .../config-push-url-no-push.sh passes
PASS  positive .../documentation.md passes
PASS  positive .../fetch-only-upstream.workflow.yml passes
PASS  positive .../gh-read-only.sh passes
PASS  positive .../npm-names.workflow.yml passes
PASS  positive .../package-metadata.json passes
PASS  positive .../uses-action-reference.workflow.yml passes
PASS  repository scan (118 files) passes

public-push-guard self-test: 24/24 assertions passed
public-push-guard: self-test passed; repository scan clean (118 files, 0 findings)
$ npm run test:public-push-guard
# tests 14  # pass 14  # fail 0

The first real scan (before any fix) reported three findings, all in inherited, disabled agent workflows, and they were fixed rather than allow-listed:

text
.github/workflows/issue-triage-dispatch.yml:76: [action-targets-public] step "uses: a5c-ai/babysitter/packages/adapters/triggers@staging" is pointed at a5c-ai/babysitter
    > { "issueNumber": ${{ inputs.issue_number || github.event.issue.number }}, "repo": "a5c-ai/babysitter" }
.github/workflows/live-stack-gardening.yml:51: [pushable-remote] git clone binds remote "origin" to a5c-ai/babysitter without `git remote set-url --push origin no_push`
    > git clone https://github.com/a5c-ai/babysitter.wiki.git /tmp/babysitter-wiki
.github/workflows/live-stack-gardening.yml:73: [action-targets-public] step "uses: a5c-ai/babysitter/packages/adapters/triggers@staging" is pointed at a5c-ai/babysitter
    > Inputs: { "repo": "a5c-ai/babysitter", "wikiPath": "/tmp/babysitter-wiki" }

Both workflows now act on ${{ github.repository }} (an agent dispatched from fabric with a token must not triage the public repository's issues or edit its wiki). js-yaml loads ci.yml, live-stack-gardening.yml and issue-triage-dispatch.yml; the new job's steps are Checkout repository, Setup Node.js, Guard self-test and repository scan, No pushable remote for the public repository, permissions {"contents":"read"}.

Rehearsal: candidate review

git fetch upstream --no-tags then git log --oneline --remotes=upstream --not --remotes=origin listed 469 public commits absent from every fabric ref; origin/main..upstream/main and origin/staging..upstream/develop (filtered) were empty; origin/staging..upstream/staging held three. Nearly all 469 are bot commits on agent-versions/daily-*, model-versions/daily-* and changelog/daily-* branches. Evaluation per docs/UPSTREAM-INTAKE.md §2:

CandidateBranchDecisionReason
d98b7ff70 docs: deployment is handled from a private deployment repositorystagingrejectedevery hunk says deployment happens outside the repository; fabric is the deployment repository (and git apply --check already failed: fabric's docs/development/06-kradle-cloud-platform.md has moved on)
02e3a8773 ci: remove the cluster deploy pipeline from the public publish workflowsstagingrejecteddeletes publish.yml deploy jobs and g0-rt-jitsi-e2e.yml, which fabric runs
64fd9f475 test(ci): pin publish workflows to have no cluster deploy jobsstagingrejectedasserts the absence of jobs fabric has
d5c7e7f77 fix(sdk): avoid non-portable fallback sdk symlinksagent/issue-1757rejected3-way cherry-pick (tried in a throwaway worktree, then aborted) conflicted in packages/babysitter-sdk/src/cli/main/runSupport.ts:291-303 and packages/genty/platform/.../validation.ts:107-116, exactly where public main later chose relative symlink targets (ded587848, 2026-08-14, already in fabric); superseded upstream, fabric wins leaves nothing
442e7ed6a feat(sdk): expose runId, runDir, artifactsDir on ProcessContextfeat/expose-runid-artifactsdir-on-process-contextrejectedalready in fabric (packages/babysitter-sdk/src/runtime/types.ts carries the identical fields and doc comments); the commit predates the public packages/sdk -> packages/babysitter-sdk move (47fd0e280, 2026-06-06)
58891e42a docs: apply enforcement messagingdocs/improve-readme-and-best-practicesrejectedreverted on its own branch by b62f317ac
776123a8d fix: create CONTRIBUTING.mdcopilot/fix-broken-contributing-linkrejectedalready reachable from fabric refs (0 commits beyond origin)
44e7f47ba docs: daily changelog update (2026-08-05)changelog/daily-2026-08-05rejectedmodifies CHANGELOG.md where fabric has diverged (fabric-only kip-sdk entries) and a docs/daily-updates/2026-08-05.md created earlier on the same bot branch
12eafcc00 / 96ad4691b Cursor and Hermes records / evidence sources for 2026-07-15agent-versions/daily-2026-07-15deferrednatural tight-series follow-up to the commit taken below; left out so the rehearsal is exactly one commit
76434c235 Add upstream agent versions for 2026-07-15agent-versions/daily-2026-07-15**taken**one commit, one new file, same shape as the 2026-07-14 and 2026-07-17 records fabric already has; fills a gap in fabric's own catalog data; nothing about it misdescribes fabric

Rehearsal: the documented flow, as run

text
$ git remote -v
origin    git@github.com:a5c-ai/fabric.git (fetch)
origin    git@github.com:a5c-ai/fabric.git (push)
upstream  https://github.com/a5c-ai/babysitter.git (fetch)
upstream  no_push (push)

$ git fetch upstream --no-tags
$ git switch -c intake/76434c2            # off phase0/hard-split-registry-guards at 030920ec6
$ git cherry-pick -x 76434c235
 1 file changed, 286 insertions(+)
 create mode 100644 packages/atlas/graph/agent-stack/agent-versions/upstream-current-2026-07-15.yaml
$ git log -1 --format='%h %an %s%n%b'
d39bba75d a5c-ai[bot] Add upstream agent versions for 2026-07-15
(cherry picked from commit 76434c235de18ea1c0aceb6f5297a87cef9e861c)

$ node -e '<js-yaml structural check>'
07-15 docs: 8 kinds: AgentVersion
07-14 docs: 10 kinds: AgentVersion
same top-level keys as 07-14: true
files: 35 ids: 177 unparsable (pre-existing): pi-issue-541.yaml
duplicate ids involving the new file: none
new ids: agentVersion:amp:0-0-1784091630-gf43d5c, agentVersion:claude:2-1-210, agentVersion:claude-agent-sdk:0-3-210,
         agentVersion:codex-sdk:6-47-0, agentVersion:droid:0-172-0, agentVersion:omp:16-5-2, agentVersion:opencode:1-18-1, agentVersion:pi:0-80-7

$ npm run build:index --workspace=@a5c-ai/atlas          # the consumer of these records
[atlas:indexer] wrote dist/index.json
[atlas:indexer] stats {"totalRecords":17715,"totalEdges":88686,"totalNodeKinds":245,"totalEdgeKinds":408,"totalClusters":20,"yamlFiles":2745,"parseErrors":1}
(exit 0; the one parse error is pi-issue-541.yaml, which fails strict YAML at 030920ec6 too; all 8 new ids present in dist/index.json)

$ node scripts/ci/public-push-guard.cjs --self-test      # 24/24, repository scan clean
$ git push -u origin intake/76434c2
$ gh pr list -R a5c-ai/babysitter --head agent-versions/daily-2026-07-15 --state all     # read-only provenance lookup
1422 OPEN https://github.com/a5c-ai/babysitter/pull/1422 Add upstream agent versions for 2026-07-15
$ gh pr create -R a5c-ai/fabric --base phase0/hard-split-registry-guards --head intake/76434c2 --label upstream-intake \
    --title "intake: Add upstream agent versions for 2026-07-15 (cherry-pick 76434c235)" --body-file <template filled in>
https://github.com/a5c-ai/fabric/pull/2
$ gh pr view 2 --json state,labels,baseRefName,headRefName
{"base":"phase0/hard-split-registry-guards","head":"intake/76434c2","labels":["upstream-intake"],"number":2,"state":"OPEN"}
$ git switch phase0/hard-split-registry-guards

Path map recorded in the PR: packages/atlas/graph/agent-stack/agent-versions/upstream-current-2026-07-15.yaml -> identical path (new file). Conflicts: none. Dropped hunks: none.

Status against the acceptance criteria

  • AC1 (intake doc: remote setup, labeling, path map, conflict policy): docs/UPSTREAM-INTAKE.md §1, §4, §5, §6. Done.
  • AC2 (CI guard fails push targets and checkout-with-write): guard + public-push-guard job; negative fixtures prove both classes trip. Done.
  • AC3 (rehearsal cherry-pick of one real upstream commit lands via the documented flow with its path map recorded): pull request **opened** — <https://github.com/a5c-ai/fabric/pull/2> — through the documented flow, labeled, path map recorded. **Not merged** by WP-RN-02; merging is the owner's decision (the branch ruleset requires a reviewed PR anyway). The spec's test requirement "rehearsal PR merged and referenced" therefore stays open until the owner merges #2; the reference is recorded here and in docs/UPSTREAM-INTAKE.md §9.
  • Test requirement (self-test fixture asserting the guard trips): --self-test and scripts/ci/public-push-guard.test.mjs. Done.
  • WP-RN-01 deferred requirement ("CI check from WP-RN-02 green"): the public-push-guard job runs on every pull request. First run, on the CI run of #2 (pull_request, run 36395354707): job Public-push guard (two-repo split) <https://github.com/a5c-ai/fabric/actions/runs/36395354707/job/108840321702> concluded success; steps Checkout repository, Setup Node.js, Guard self-test and repository scan, No pushable remote for the public repository all success. Green.

Rollback

PieceRollback
Guard, job, fixtures, tests, docs, template, workflow input fixesgit revert 030920ec6 (and the follow-up docs commit)
Labelgh label delete upstream-intake -R a5c-ai/fabric (do not: the propagation watch keys on it)
Rehearsal PRclose #2 without merging; git push origin --delete intake/76434c2

Nothing here touched the public repository, so there is nothing to roll back there.

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