Repository navigation
Conversation
ASCS-eV/PufferDrive is consumed as a submodule internally while feeding features back to Emerge-Lab/PufferDrive. Document the model that keeps both possible: 3.0 as a verbatim upstream mirror and default branch, integration/3.0 as a linear stack of single-commit features, and mirror/<slug> branches cherry-picked onto pure 3.0 for upstream PRs. - .github/copilot-instructions.md: normative process for coding agents - CONTRIBUTING.md: human orientation, same rules - .github/pull_request_template.md: testing and stack-hygiene gates - .github/workflows/sync-mirror.yml: fast-forward-only mirror sync that refuses any non-fast-forward instead of rewriting the upstream base - AGENTS.md / CLAUDE.md: fenced pointer so agents find the fork process without colliding with upstream-owned content - ci.yml / install.yml: run CI for PRs targeting integration/3.0, which upstream's branch filters would otherwise skip A standing draft PR from integration/3.0 into 3.0 provides a continuous CI verdict on the combined stack; it must never be merged. Everything here is fork-only and must never be cherry-picked upstream.
35c9ef5 to
7661a01
Compare
Gate 2 — adversarial review recordReviewed in a fresh context by an agent that did not author the change (required by §5, since I wrote it). Verdict returned: do not stack it — 9 blockers + 6 should-fix, each with a demonstrated failure. All have now been resolved or explicitly deferred with a reason. Blockers — resolved
Should-fix — applied
B4 evidence — guards actually abortRun in a throwaway The first attempt at this test was itself invalid — the script omitted a clean-tree assertion, so with uncommitted edits present every Also added this round
Remaining blockerB1 only. This PR cannot go green until #3 lands. No further work here until then. |
7661a01 to
157adbe
Compare
Added §6.2 — After upstream respondsCloses a gap found while answering "does #3 need to be stacked and upstreamed?" (both: yes, independently). The post-acceptance lifecycle was previously one sentence in §7, plus a stray duplicate paragraph buried at the end of §6.1 — a section about the
Detection is by patch-identity, not the PR's merge badge — upstream may squash, rename or amend. Verified by execution, not assertion
The test found a defect in the section I had just written. My first draft documented only (My first attempt at the verification script was also wrong — it used the mirror commit as the fake upstream, making the range empty, so the Process noteBoth scripts ran in a throwaway StatusUnchanged: 1 commit, 3 markdown files, no code touched. Still red on Linux for the known |
157adbe to
c1c1a8f
Compare
Added §6.2 — While the mirror PR is open (former §6.2 → §6.3)Answers: how do feature PRs stack on The overlap needs no special handling — it is structural. But four real gaps existed around that period: 1. Deleting the mirror branch closes the upstream PR 🔴§6.2 case A (now §6.3) ended in a bare 2. The recorded SHA rots§6 rebuilt the mirror from "the 3. No refresh procedure while openTwo triggers, now both documented: 4. Nothing enumerated what is in flightOnce the fork PR closes, no link remains from a stacked commit to its open upstream PR. The slug is the only key; inventory commands added for both sides. Verified by execution
The staleness detector is patch-id based, so it needs no checkout and correctly ignores that the two commits have different parents. StatusUnchanged: 1 commit, 3 markdown files, no code. Still blocked on #3 per Gate 1. |
45354f0 to
c74ed71
Compare
The Linux CI jobs fail while installing the package:
[Errno 122] Disk quota exceeded
Errno 122 is EDQUOT, hit while unpacking the CUDA torch stack that
`pip install -e .` resolves by default. torch alone is 554.6 MB and the
accompanying nvidia-* wheels add another ~2.4 GB, which no longer fits
the runner's quota. The failure occurs during "Installing build
dependencies", i.e. the isolated PEP 517 build environment is already
enough to exceed it on its own.
The trigger is a runner image change, not a code change:
* upstream 11_bernhard_dev, 2026-10-20, Image: ubuntu-24.04 -> success
* same workflows, 2026-10-23, Image: ubuntu-26.04 -> failure
Both resolve an identical wheel set (torch 2.14.1, 554.6 MB). The
`ubuntu-latest` label began migrating to Ubuntu 26 on 2026-10-19
(actions/runner-images#14748), between those two runs. Both workflows
already carry "Free up disk space" steps, so these jobs were running
close to the limit before the migration.
Fix: install CPU-only torch from download.pytorch.org, then build with
--no-build-isolation so the build reuses it instead of resolving torch
a second time. --no-build-isolation needs the build dependencies present
up front, hence the explicit setuptools/wheel/numpy install; the
`setuptools<81` bound matches the pin already in install_requires.
This loses no coverage: BUILD_CUDA_EXT keys off CUDA_HOME/ROCM_HOME,
which is unset on these runners, so the CUDA sources were never compiled
here. tests/smoke_tests/Dockerfile already installs torch this way.
macOS keeps the plain `pip install -e .` unchanged: its PyPI wheels are
already CPU-only, and leaving it alone keeps the default PEP 517
build-isolation path under test somewhere in the matrix.
c74ed71 to
2881c22
Compare
`integration/3.0` is both what BMW pins and the base every later feature
rebases onto, so a defect merged there is multiplied across every consumer
and every subsequent PR. Opening a PR was previously enough to get a change
onto the stack; now it is not.
A feature may be stacked only after three gates:
1. CI green on the final commit.
2. An adversarial review by someone other than the author. Section 4.7
defines what that means concretely -- revert the fix and prove the new
test fails, hunt edge cases, determinism, trust boundaries, observation
and config layout, hot-path cost, scope creep, and likely upstream
objections -- and requires the findings to be written down, including
the probes that found nothing.
3. Upstream-readiness proven rather than asserted: the commit is
cherry-picked onto a branch cut from pure `upstream/3.0` *before*
merging, and must apply without conflict and produce an upstream-clean
diff. We stack only commits we could contribute today.
`chore(fork):` commits are exempt from gate 3 -- fork-only infrastructure
can never be upstream-ready -- and gain their own flow (section 3.3). Two
orthogonal axes must both be marked, because they fail in different
directions: `do-not-mirror` (must never reach upstream; marked four times
over -- title prefix, label, `chore(fork):` commit type, and the template's
"Never upstream" box) and `do-not-merge` (the merge button must never be
pressed on it; marked by title prefix and label). Merging such a PR would
put a *second* `chore(fork):` commit on the stack, and section 7 asserts
there is exactly one, so every future sync would abort until someone
unpicked it by hand. It is folded into the base commit by fixup instead, so
the stack keeps exactly one fork commit and the PR ends closed, not merged.
Also fixes a real ambiguity in the old text. Section 3 listed fork-only
*files* and fork-only *hunks inside shared files* as one flat list, and
section 4.5 then checked them with a file-name diff. That check cannot see
hunks, and it falsely flags any PR that legitimately edits a shared file --
which is exactly what the CI fix in #3 does to `ci.yml` and `install.yml`.
Split into 3.1 (whole files) and 3.2 (hunks in shared files), each with a
check that actually detects it.
Smaller changes:
- the default branch *is* the process. A clone checks out `integration/3.0`,
so a rule that lives only in an open PR has no effect on any agent or on
the BMW submodule consumers. Section 2 states this, 4.1 now opens by
listing in-flight process PRs (the two labels AND-ed, which excludes the
standing draft PR), and 3.3 requires the fold-in window to be kept short
and the output of agents that ran during it to be re-checked.
- document `chore/<slug>` branch naming, previously undefined
- agents may not review their own work, nor merge to `integration/3.0` on
their own initiative
- section 6 no longer rebuilds the mirror branch from scratch, since gate 3
already built and verified it, and now requires re-running the suites on
the mirror branch because it has a different base than CI tested
2881c22 to
b510f1e
Compare
7ae6c83 to
d692385
Compare
Applied by fixup — closed, not merged (§3.3)Folded into the base Merging would have created a second Resulting
|
| fork base | 5efda076b — chore(fork): define the ASCS-eV fork process |
| tip | d692385b2 — fix(ci): install CPU-only torch wheels in GitHub Actions |
| previous tip (lease target) | 7ae6c839f |
Gate 1 — CI green
12/12 on b510f1e7f, the exact SHA that was folded in — including the full install matrix
(3.11–3.14 on ubuntu-latest, 3.11/3.12 on macos-latest), which was red before #3 merged.
Gate 2 — adversarial review
Posted earlier in this thread: 9 blockers + 6 should-fix findings, each fixed or explicitly
accepted, including the probes that found nothing.
Gate 3 — exempt
Fork-only infrastructure can never be upstream-ready.
Post-fold verification
PASS: exactly 1 chore(fork) commit
PASS: no stray fixup!
PASS: oldest stack commit is the fork base
PASS: tip tree 62ceccd3… identical to the tree CI proved 12/12 green
PASS: ci-fix patch-id 1315dfd7… unchanged → upstream PR #602 linkage intact
The tree-equality check is deliberately stronger than re-running make test: the stacked
result is byte-for-byte the tree CI validated, so the verdict transfers exactly rather than
by inference.
Added in the final revision
The default branch is the process. A clone checks out integration/3.0, so a rule that
lives only in an open PR has no effect on any agent or on submodule consumers — this PR sat
open while the default branch served a 262-line version of a process that is now 930 lines.
- §2 states that the agent instructions, not just the PR template and scheduled workflows,
are read from the default branch. - §4.1 now opens by listing in-flight process PRs. The two labels AND-ed
(--label do-not-mirror --label do-not-merge) match fork-only process PRs and nothing else;
the standing draft PR DO NOT MERGE - integration stack CI #1 carriesdo-not-mergealone and is correctly excluded. Verified. - §3.3 requires the fold-in window to be kept short, and the output of agents that ran
during it to be re-checked rather than assumed compliant.
What
Hardens the fork process docs so that another agent can execute them unattended, and encodes the
merge gate: nothing is stacked on
integration/3.0without green CI, an adversarial review, andproven upstream-readiness.
Scope grew after two exercises were run against the docs (a reproducibility audit and an
adversarial review of #3). Both are folded in below.
Why
The process was readable but not executable. The audit found five blockers that would have
stopped or silently corrupted an agent run, two of which were repo-settings bugs rather than doc
bugs.
Blockers fixed
git rebase -i, which is a silent no-op headless — and the next command force-pushes the default branchgit commit --fixup+GIT_SEQUENCE_EDITOR=: git rebase -i --autosquash, plus a hard invariant check before the pushAGENTS.md"verbatim", which mandates adding anAGENTIC_PRFrench-poem file to every mirror PRgh pr checksupdate_goldens.sh, thegit add -ffor the gitignored rollout golden, and base-dependence across Gate 3Correctness fixes
git pull --rebasein §2 silently resurrects commits dropped during a rebase → replaced withfetch+reset --hard.reset --hardfirst, risking rewriting history on top of local drift.git branch -D mirror/<slug>fails when that branch is checked out → detach first.git diff upstream/3.0..HEAD→...HEADin Gate 3 and the template.grep -cexits non-zero on zero matches, aborting aset -escript →|| true.mirror/<slug>→ addedgit switch -.chore/branches (their whole job is to touchfork-only files) → explicit exemption.
make testwas described as "everything"; it istest-unit test-eval test-c test-notebooksandexcludes docker-smoke and perf → corrected in all three files.
upstreamremote andgh repo set-defaultwere documented nowhere, yet Gate 3 fails without thefirst and bare
gh prcan resolve to upstream without the second → §4.1 setup block.update-smoke-golden.ymlhazard: it ends ingit push origin HEAD:<ref>andtriggers on
3.0, so it can commit to the mirror. Added the detector and recovery.3.0" made explicit.How tested
GIT_EDITOR=false, so anyattempt to open an editor would hard-fail. Result: cherry-pick → fixup → autosquash rebase
completed, stack collapsed to exactly 1
chore(fork)commit, no strayfixup!, and thechange was confirmed present inside the base commit.
section N/§Ncross-references resolve to a heading that exists.git diff --checkclean.make testtarget read from the Makefile to confirm what it actually runs.update_goldens.shread to confirm the documentedgit add -fpath.Docs-only change; no code touched, so the suites are unaffected.
Stack hygiene
exempt: chore(fork) — this PR deliberately changes the files in §3.1.
Merge gate
chore(fork), can never be upstream-ready)Upstream disposition
chore(fork):change, Gate 3 exemptApplied by fixup into the base commit per §3.3, not with the merge button. This PR ends up
closed, not merged; the resulting
integration/3.0SHA gets posted here.Risk / notes
The one behavioural change outside the docs is the repo settings (rebase-merge enabled, squash and
merge-commit disabled, 12 required checks on
integration/3.0,do-not-mirrorlabel). Those arealready live.
Open follow-up:
#3is green and Gate 3 clean, but its body was rewritten after review found thestated root cause was wrong. It needs a human read before it goes upstream.