Agentic AI Atlasby a5c.ai
OverviewWikiGraphFor AgentsEdgesSearchWorkspace
/
GitHubDocsDiscord
i.2Wiki
Agentic AI Atlas · Upstream intake: cherry-picking public fixes into fabric
docs/upstream-intakea5c.ai
Search the atlas/
Wiki · linked records

Article and nearby pages

I.Current articlepp. 1 - 1
adapters docsAgent-Adapter ↔ Babysitter IntegrationAgent Layer Gaps — Full Agent StackContributor ReferenceArticlesHarness Assimilation
I.
Wiki article

docs/upstream-intake

Reading · 13 min

Upstream intake: cherry-picking public fixes into fabric reference

Status: binding. Implements docs/specs/platform-gaps/15-private-isolation-rename.md §1.4 (cherry-pick-only intake) and §1.5 (divergence policy) under decision D17 of docs/specs/platform-gaps/00-intent.md; executed by WP-RN-02. The policy this procedure serves is docs/DIVERGENCE-POLICY.md; the cutover record is docs/specs/platform-gaps/phase0/watch-baseline.md; the rehearsal of this procedure is docs/specs/platform-gaps/phase0/intake-rehearsal.md.

Page nodewiki/docs/UPSTREAM-INTAKE.mdNearby pages · 45Documents · 0

Continue reading

Nearby pages in the same section.

adapters docsAgent-Adapter ↔ Babysitter IntegrationAgent Layer Gaps — Full Agent StackContributor ReferenceArticlesHarness AssimilationAtlas Catalog UnificationAtlas Graph ↔ Library Gap ReportBabysitter BlueprintsBabysitter Plugins → Blueprints RenameBabysitter CLI & SDK Examplesa5c Development DocumentationDivergence policy: fabric and the public babysitter repositoryEffect baseline (WP-T3-32)Evil FallbacksGenty Features Backlog: Adversarial Gap Analysisgenty Stack RenamesUsing the Babysitter GitHub ActionUsing Babysitter with Claude Code GitHub ActionsUsing Babysitter with Codex GitHub ActionsUsing Babysitter with Gemini CLI GitHub ActionsHardcoded Harness/Target Gaps — Should Be Derived from Atlas GraphHarness Features Backlog: Gap Analysis (Restructured)Here Be Dragons — Babysitter MonorepoHermes Agent Deep ResearchPackage and Plugin Docs MapAgent PluginsProof-Based Policy EnforcementProof-Based Policy EnforcementReferenceReference ReposRelease incident record — stale `latest` dist-tags (2026-08-13)Continuous Release PipelineRelease readiness — `staging` → `main`Release recovery runbook — candidate publish, published-consumer validation, channel promotionRelease runbook — private train to Artifact RegistryRepositories Using BabysitterBabysitter Run History InsightsSupermemory Deep ResearchTesting StrategyBabysitter User GuideBabysitter v6: The Orchestration Platform Goes Universala5c.ai V6 Spec And RoadmapVersioningWorkspace Validation Map

Upstream intake: cherry-picking public fixes into fabric

Status: binding. Implements docs/specs/platform-gaps/15-private-isolation-rename.md §1.4 (cherry-pick-only intake) and §1.5 (divergence policy) under decision D17 of docs/specs/platform-gaps/00-intent.md; executed by WP-RN-02. The policy this procedure serves is docs/DIVERGENCE-POLICY.md; the cutover record is docs/specs/platform-gaps/phase0/watch-baseline.md; the rehearsal of this procedure is docs/specs/platform-gaps/phase0/intake-rehearsal.md.

a5c-ai/fabric is the private product repository. The public a5c-ai/babysitter repository is a separate, open project that this repository reads from and never writes to. Public fixes reach fabric in exactly one way: a maintainer cherry-picks individual public commits onto a fabric branch and lands them through a pull request labeled upstream-intake. There is no other path: no merges, no pulls, no shared tags, no automation.

1. The `upstream` remote is fetch-only

Every clone that takes part in intake configures the public repository as a remote named upstream whose push URL is disabled. Run these exact commands once per clone:

bash
git remote add upstream https://github.com/a5c-ai/babysitter.git
git remote set-url --push upstream no_push
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)

no_push is not a URL, so git push upstream ... fails mechanically before contacting GitHub. The propagation watch (scripts/ci/upstream-propagation-watch.sh) refuses to run unless the push URL is exactly no_push, and the CI guard (§7) fails any workflow or script that configures the public repository as a remote without it.

Rules that follow from docs/DIVERGENCE-POLICY.md §1–2:

  • No clone of fabric may carry a pushable remote for a5c-ai/babysitter under any name; git clone of the public repository into a fabric working tree is not done (fetch it through upstream instead).
  • Never git push upstream, never git push <public-url>, never gh pr create -R a5c-ai/babysitter, never a gh api write (POST/PUT/PATCH/DELETE) against repos/a5c-ai/babysitter. Read-only access (git fetch, git ls-remote, gh api GET, gh pr list -R a5c-ai/babysitter) is the only permitted interaction.
  • Never fetch the public tags: always git fetch upstream --no-tags. Public babysitter/<branch>/v* tags must not enter fabric's tag namespace (fabric's release tags are fabric/<branch>/v*, WP-RN-07).

2. When intake is allowed

Intake is pull-based and opportunistic (spec 15 §1.4). It is done by a maintainer at their own cadence, never on a schedule and never by automation. A public commit is a candidate when all of the following hold:

1. It is a fix or a self-contained addition fabric actually wants: security fixes to the journal, replay and trust cluster first (spec 15 §1.5: evaluated in the intake owner's next review pass), then bug fixes, then documentation or data records. Features are taken only when fabric has decided to adopt them. 2. It is small enough to review as a unit: one commit, or one tight series of commits that only makes sense together (for example "create record" + "amend record"). 3. It does not contradict fabric's divergence. A public commit that describes the public project's own arrangements (for example, that deployment happens "elsewhere") is not taken into the repository it would misdescribe. 4. It is not already in fabric under another commit, and it has not been superseded on the public main by a later change.

Bulk intake, if ever wanted, is scheduled before WP-RN-10 executes the directory renames (spec 15 §1.4 binding sequencing rule); afterwards intake is expected to shrink to targeted fixes.

Review the candidates with read-only commands only:

bash
git fetch upstream --no-tags --prune
git log --oneline origin/main..upstream/main                      # public main ahead of fabric main
git log --oneline origin/staging..upstream/staging
git log --oneline --remotes=upstream --not --remotes=origin        # every public commit fabric lacks (all branches)
git show --stat <sha>
git diff <sha>^ <sha> | git apply --check                          # quick applicability probe (no 3-way; a failure is not final)

3. The cherry-pick flow

One upstream commit, or one tight series, per pull request. The branch name is intake/<short-sha> of the first (or only) upstream commit.

bash
git fetch upstream --no-tags --prune
git switch -c intake/<short-sha> <fabric base branch>     # main, staging, or the feature branch the fix belongs on
git cherry-pick -x <sha>                                  # -x records "(cherry picked from commit <sha>)" in the message
# for a tight series, oldest first:
git cherry-pick -x <sha-1> <sha-2>

-x is mandatory: the recorded upstream SHA is what reviewers, the propagation watch and future audits use to trace the commit to its public origin.

If a file moved in fabric (see §5), use rename-aware cherry-picking, or apply the patch into the new directory:

bash
git cherry-pick -x -X find-renames <sha>
# or, when the whole subtree moved:
git format-patch -1 --stdout <sha> | git apply -3 --directory=<new-dir> -p<N>
git commit -a -m "<subject>" -m "(cherry picked from commit <sha>)"

Then run the checks that are directly relevant to the touched files (the package's own test suite, the docs gates for documentation, the guard for anything under .github/ or scripts/), push the branch to origin only, and open the pull request (§4):

bash
node scripts/ci/public-push-guard.cjs --self-test
git push -u origin intake/<short-sha>
gh pr create --base <fabric base branch> --label upstream-intake --template upstream-intake.md

Never rebase an intake branch onto a public head, never git merge upstream/<branch>, never git pull upstream <branch>: the branch is built from fabric's history plus the cherry-picked commits and nothing else (docs/DIVERGENCE-POLICY.md §3).

4. Pull request requirements

Every intake pull request:

- the upstream SHA(s) in full, with subject, public branch, author and date; - the upstream pull request or issue link when one exists (gh pr list -R a5c-ai/babysitter --search <sha> is a read-only lookup), or "none"; - the path map: one row for every touched file, public path to fabric path, marked identical, renamed (<old> -> <new>) or dropped (§5); - conflicts and dropped hunks, per hunk, with the reason (§6); - test evidence: the commands run and their result; - the checklist, including git remote -v showing upstream ... no_push (push);

  • targets a fabric branch and carries the label upstream-intake (gh label create upstream-intake --description "Cherry-picked from public a5c-ai/babysitter" --color 0E8A16, already present on a5c-ai/fabric);
  • uses the template .github/PULL_REQUEST_TEMPLATE/upstream-intake.md (gh pr create --template upstream-intake.md, or open the PR on GitHub with ?template=upstream-intake.md) and fills in every section:
  • contains only the listed upstream commits (plus, if unavoidable, one fabric-authored fix-up commit for name or path adaptation, clearly titled intake: adapt <file> to fabric layout);
  • passes CI, including the public-push-guard job.

Reviewers verify that the commit message carries the (cherry picked from commit <sha>) trailer, that the SHA exists on the public repository (git branch -r --contains <sha> after git fetch upstream --no-tags), and that the path map covers every file in the diff.

5. Path map: public paths to fabric paths

The path map is required even when every path is identical, because the two trees diverge over time and the map is the record of what was checked. Known differences between the public layout and fabric's, to be extended as the rename work packages land:

Public path or nameFabric path or nameSinceAffects
packages/sdk/packages/babysitter-sdk/public commit 47fd0e280 (2026-06-06), shared historypublic commits authored before that rename (older feature branches)
@a5c-ai/<package> npm names@fabricstack/<name> per spec 15 §3.1WP-RN-05 (not yet executed)any commit touching package.json names or import specifiers, once RN-5 lands
package directoriesspec 15 §3.3 directory matrixWP-RN-10 (not yet executed)every intake, once RN-10 lands (git apply --directory or -X find-renames)
public release tags babysitter/<branch>/v*never imported; fabric tags are fabric/<branch>/v*WP-RN-01 / WP-RN-07tag references in scripts and docs

At the time of the WP-RN-02 rehearsal, git ls-tree of packages/ at upstream/main and at fabric's work branch showed no path differences (the trees share history up to the cutover baseline of 2026-09-28), so a current public commit maps 1:1 unless it was authored before a public rename.

6. Conflict policy: fabric wins

Divergence is licensed (D17: fabric is "free to diverge in implementation"). On a conflict:

1. Keep fabric's version of the conflicting hunk. Do not restructure fabric's code to make the public patch apply cleanly. 2. Re-apply only the intended delta of the upstream commit on top of fabric's version, when that delta still makes sense in fabric's code. If fabric already solved the same problem differently, the upstream hunk is dropped, not merged. 3. Record every dropped hunk in the pull request (file, what upstream changed, what fabric keeps, why). 4. If nothing of the commit survives, do not open the pull request; record the evaluation instead (as the rehearsal record below does for the candidates it rejected).

A public commit that was itself superseded on public main is treated as already-decided upstream and is not taken.

7. What is forbidden

ActionWhyEnforced by
git merge upstream/<branch>, git pull upstream <branch>, fast-forwarding onto a public commit, scheduled or automated mergeswholesale merges re-create the mirror relationship the split ended (docs/DIVERGENCE-POLICY.md §3)propagation watch (unexplained public commits fail the audit); reviewer check of the PR's commit list
git push upstream ..., git push <public-url> ..., git remote set-url --push upstream <url>, any remote for the public repository without no_pushinvariant 1: nothing in fabric alters the public repositoryno_push URL; scripts/ci/public-push-guard.cjs (push-to-public, pushable-remote, push-url-set, ssh-url rules)
gh pr create -R a5c-ai/babysitter, gh release create -R a5c-ai/babysitter, gh api -X POST/PUT/PATCH/DELETE repos/a5c-ai/babysitter/..., gh workflow run -R a5c-ai/babysittersame invariantguard (gh-write rule)
actions/checkout of a5c-ai/babysitter with a token, an ssh-key, persist-credentials: true or contents: writea pushable working copy of the public repository inside CIguard (checkout-with-write rule)
any action step or agent dispatch pointed at a5c-ai/babysitter (repository: / repo: inputs)fabric's automation acts on fabric onlyguard (action-targets-public rule)
git fetch upstream without --no-tags, git fetch --tags upstreampublic tags must not enter fabric's tag namespace--no-tags in every documented command and in the watch workflow
a submodule pointing at the public repositorya pushable checkout inside the treeguard (submodule-public rule)

The guard allows, by rule: uses: a5c-ai/babysitter/<path>@<ref> action references, git fetch and git ls-remote, gh api GET calls and gh ... list/view commands, the fetch-only remote idiom, npm package names under @a5c-ai/, comments and Markdown, and a line annotated # public-push-guard: allow <reason> (the reason is mandatory and is reviewed like any other change). Run it locally with node scripts/ci/public-push-guard.cjs (--self-test also proves the negative fixtures in scripts/ci/fixtures/public-push-guard/ trip); unit tests: npm run test:public-push-guard.

8. How the propagation watch treats intake pull requests

.github/workflows/upstream-propagation-watch.yml fetches the public heads daily over the fetch-only remote and computes the public commits that post-date the cutover baseline. For every such commit reachable from a fabric ref it looks for a **merged** pull request on a5c-ai/fabric labeled upstream-intake whose merge commit contains that public commit (gh pr list --state merged --label upstream-intake). Found: the commit is reported as OK ... arrived via upstream-intake PR #<n>. Not found: the run fails with the commit and the fabric refs that contain it.

Consequences for intake:

  • The label is load-bearing. A cherry-pick merged without the label is reported as an unexplained propagation until the label is added to the merged PR (the watch re-evaluates on its next run).
  • The cherry-picked commit has a new SHA, so it is never itself a "post-baseline public commit"; what the watch excuses is a public commit that reaches fabric with its original SHA, which only a merge or a push of public history can cause. Cherry-picks therefore never trip the watch; the label mainly documents provenance and covers the -x trailer lookup in audits.
  • Open (unmerged) intake PRs do not count. The rehearsal PR below stays open until the owner merges it; the watch is unaffected either way.

9. Rehearsal record (WP-RN-02, 2026-09-28)

The procedure above was rehearsed once, end to end, on branch intake/76434c2 off phase0/hard-split-registry-guards. Full record with commands and outputs: docs/specs/platform-gaps/phase0/intake-rehearsal.md.

Candidate review (git log --oneline --remotes=upstream --not --remotes=origin listed 469 public commits fabric lacks; public main and develop had nothing beyond fabric; public staging had three):

CandidateDecisionReason
d98b7ff70 docs: deployment is handled from a private deployment repository (staging)rejected (§2 rule 3)every hunk states that deployment happens outside the repository; fabric is that deployment repository
02e3a8773 ci: remove the cluster deploy pipeline from the public publish workflows (staging)rejected (§2 rule 3)would delete fabric's deploy pipeline
64fd9f475 test(ci): pin publish workflows to have no cluster deploy jobs (staging)rejected (§2 rule 3)asserts the absence of jobs fabric has
d5c7e7f77 fix(sdk): avoid non-portable fallback sdk symlinks (agent/issue-1757)rejected (§2 rule 4, §6)superseded on public main by ded587848 (relative symlink targets, 2026-08-14), which fabric already has; the 3-way cherry-pick conflicted in runSupport.ts and validation.ts exactly on that hunk; fabric wins left nothing
442e7ed6a feat(sdk): expose runId, runDir, artifactsDir on ProcessContext (feat/expose-runid-...)rejected (§2 rule 4)already present in fabric (packages/babysitter-sdk/src/runtime/types.ts); the commit predates the public packages/sdk -> packages/babysitter-sdk rename
58891e42a docs: apply enforcement messaging (docs/improve-readme-and-best-practices)rejectedreverted on its own branch (b62f317ac)
76434c235 Add upstream agent versions for 2026-07-15 (agent-versions/daily-2026-07-15)**taken**one commit, one new file packages/atlas/graph/agent-stack/agent-versions/upstream-current-2026-07-15.yaml, same shape as the 07-14 and 07-17 records fabric has; fills a gap in fabric's own catalog data

Path map of the taken commit: packages/atlas/graph/agent-stack/agent-versions/upstream-current-2026-07-15.yaml -> identical path in fabric (new file). Conflicts: none. Sibling commits 96ad4691b (evidence sources for the same day) and 12eafcc00 (Cursor and Hermes records) are the natural follow-up tight series and were left for a second intake so the rehearsal stays at one commit.

Pull request: <https://github.com/a5c-ai/fabric/pull/2> (base phase0/hard-split-registry-guards, head intake/76434c2, fabric commit d39bba75d, label upstream-intake). The public origin of the commit is a5c-ai/babysitter pull request #1422 (looked up read-only with gh pr list -R a5c-ai/babysitter --head agent-versions/daily-2026-07-15 --state all). The PR was opened, not merged, by WP-RN-02: merging is the owner's decision.

10. Naming rules for any unit that enters fabric (spec 15 §3.3, WP-RN-08)

These rules apply to every pull request that adds or moves a package.json, whichever way the code arrives: a public-babysitter cherry-pick (this document), a t3code fork or extraction (docs/specs/platform-gaps/10-t3code-migration.md, WP-T3-01 and later), or fabric-authored work.

1. A unit migrated from t3code is born under its spec 15 §3.3 name and directory — @fabricstack/contracts at packages/contracts, @fabricstack/acp at packages/acp, @fabricstack/codex-protocol at packages/codex-protocol, @fabricstack/ssh at packages/ssh, @fabricstack/tailscale at packages/tailscale, @fabricstack/environment at apps/environment (bin environment-server), @fabricstack/client-runtime at packages/client-runtime, @fabricstack/console-web at apps/console-web, @fabricstack/console-desktop at apps/console-desktop, @fabricstack/relay at infra/relay — with publishConfig.registry pinned to the Artifact Registry URL (spec 15 §4.3 G1). There is no interim name and no interim directory, not even for one commit (spec 15 interaction rule 1: "no double rename"). 2. A new unit never carries @t3code/*, t3-*, one of t3code's own names (@t3tools/*, t3, t3code-*, effect-acp, effect-codex-app-server), @a5c-ai/*, a scope spec 15 §2 rejected, or no scope at all. Upstream names belong in UPSTREAM.json, LICENSE-THIRD-PARTY and provenance headers only. 3. A @fabricstack/* name must be one the spec lists (§3.1/§3.2 new-name column or §3.3 table); a spec target directory holds exactly the package the spec assigns to it. Existing @a5c-ai/* units keep their current names until WP-RN-05 renames them — moving one to its new directory while keeping its old name is the double rename the gate exists to stop. 4. The only exemption is the spec 15 §3.2 retirement list (the eight genty device/web/desktop shells deleted by T-27), which is never renamed.

Enforcement: node scripts/ci/no-double-rename.cjs (CI job publish-isolation; --self-test proves the negative fixtures under scripts/ci/fixtures/no-double-rename/ trip) scans every workspace manifest and every package.json under packages/, apps/ and infra/, treats any name absent from scripts/ci/fixtures/no-double-rename/baseline-packages.json as a new unit, and fails the job with a file:line finding. It has no waiver annotation. Spec 10 itself is held to the same names by node scripts/ci/check-spec10-names.cjs. Record the outcome in the pull request's "Naming rules" table and checklist (.github/PULL_REQUEST_TEMPLATE/upstream-intake.md); the record of the gate's introduction is docs/specs/platform-gaps/phase0/no-double-rename.md.

Trail

Wiki
Babysitter Docs

Upstream intake: cherry-picking public fixes into fabric

Continue reading

adapters docs
Agent-Adapter ↔ Babysitter Integration
Agent Layer Gaps — Full Agent Stack
Contributor Reference
Articles
Harness Assimilation
Atlas Catalog Unification
Atlas Graph ↔ Library Gap Report

Page record

Open node ledger

wiki/docs/UPSTREAM-INTAKE.md

Documents

No documented graph nodes on this page.