Repository navigation
Conversation
ASCS-eV/PufferDrive is consumed as a git submodule internally while feeding
features back to Emerge-Lab/PufferDrive. This commit carries everything that
exists only in the fork, and is the single place fork-only content lives.
Branch model:
3.0 verbatim, fast-forward-only mirror of upstream/3.0
integration/3.0 default branch; this commit plus a linear stack of
single-commit features; what internal consumers pin
feature/<slug> one feature, exactly one commit
mirror/<slug> cherry-picked onto pure upstream/3.0 for upstream PRs
integration/3.0 is the default branch because GitHub reads the PR template,
the contributing guidelines, the agent instructions and scheduled workflows
only from the default branch, and none of those files may exist on 3.0
without destroying the mirror. A clone checks out the default branch, so the
copy of the instructions here is the process as far as every agent and every
submodule consumer is concerned; a rule that lives only in an open PR has no
effect.
Nothing reaches integration/3.0 until three gates pass:
1. CI green on the final commit.
2. Adversarial review by someone other than the author, with the findings
written down -- including the probes that found nothing.
3. Upstream-readiness proven rather than asserted: the commit cherry-picks
onto a branch cut from pure upstream/3.0 and produces an upstream-clean
diff. We stack only commits we could contribute today.
chore(fork): commits are exempt from gate 3, since fork-only infrastructure
can never be upstream-ready. They carry two orthogonal markers: do-not-mirror
(must never reach upstream) and do-not-merge (the merge button is never
pressed -- merging would create a second chore(fork): commit and break the
single-commit invariant that every sync asserts). Such a PR is folded into
this commit by fixup and closed unmerged.
Contents:
- .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 gives 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.
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.
Gate 2 — adversarial reviewRun as a separate task with no authoring context (section 5: an agent may not review a change it Probes that found nothing (recorded so the next reader knows the coverage)
( Findings and disposition
Also corrected while in here: section 5 still said the two standing PRs "already exist, are |
a140448 to
b67c40f
Compare
|
Scope correction (maintainer direction): the human-approval gate is for upstream PRs only. Section 5 had over-reached to Amended: |
"What does this fork add that never goes upstream?" had no cheap answer. The content is a single `chore(fork):` commit on `integration/3.0`, but reading it meant resolving a SHA by hand, and the standing integration draft PR cannot show it in isolation because its diff necessarily carries the whole feature stack as well. Add `fork-only/3.0`: a derived branch holding exactly that one commit, republished on top of the `3.0` mirror, plus a standing draft PR into `3.0` whose "Files changed" tab is therefore precisely the fork-only content. It is a view, not storage. Fork-only content has to stay on the default branch: a clone checks out `integration/3.0`, GitHub runs scheduled workflows only from the default branch (so `sync-mirror.yml` parked elsewhere would stop firing), and the `pull_request` branch filter in `ci.yml` has to be there or feature PRs targeting `integration/3.0` get no checks at all -- which would make gate 1 unprovable. The view exists to be read, never to be the source of truth. `.github/workflows/fork-only-view.yml` rebuilds the branch on every push to `integration/3.0`, so it cannot drift. It refuses to publish a stack that violates the section 7 invariants -- not exactly one `chore(fork):` commit, or a base that is not parented on the mirror tip -- so a malformed stack surfaces as a failed run rather than as a misleading diff. Supporting changes: - the three contamination guards (4.5, gate 3, and section 6) now also match `fork-only-view`, which they would otherwise have let through into a mirror PR as an ordinary workflow file - section 5 allowed exactly one PR to target `3.0`; there are now two, both standing, both auto-maintained, neither ever merged - section 3.2 warns against `push:` triggers on `integration/3.0` for the test suites; note that this workflow uses one deliberately, so it is not "fixed" to match later - CONTRIBUTING.md still described the single-axis `[do-not-mirror]` marker scheme that was replaced by the two independent axes
b67c40f to
21ecfe5
Compare
d692385 to
fad5d95
Compare
Landed — closing unmerged (section 3.3)Gate 1: 12/12 green on 21ecfe5. Folded into the fork base commit by fixup, not merged:
Invariants verified before the force-push — all PASS:
GitHub logged Follow-up: this design turned out to be wrongThe first real run of the workflow it added, 39986186116, failed on the push: \ GitHub blocks Worth recording: this design cleared Gate 1 and Gate 2 and was still unworkable, because neither gate executes the workflow. |
What
Publish the fork-only
chore(fork):commit as a derived branchfork-only/3.0, so the fork-onlycontent can be read in isolation through a standing draft PR into
3.0.Why
"What does this fork add that never goes upstream?" had no cheap answer. The content is a single
chore(fork):commit onintegration/3.0, but reading it meant resolving a SHA by hand, and thestanding integration draft PR cannot show it in isolation — its diff necessarily carries the whole
feature stack too.
This is a view, not storage. Fork-only content must stay on the default branch, because:
integration/3.0, so that copy of the instructions is the process;sync-mirror.ymlparkedelsewhere would silently stop fast-forwarding the mirror;
pull_requestbranch filter inci.ymlmust be there or feature PRs targetingintegration/3.0get no checks at all, making Gate 1 unprovable.How tested
permissions: {contents: write, pull-requests: read}0
fixup!; exactly 1chore(fork):; base5efda076bis oldest, has exactly one parent,and
base^ == origin/3.0 == 74b44c2f3git diff --checkclean; LF-only, single trailing newline on all three filesgit rev-list --count origin/integration/3.0..HEAD-> 1actions/permissions/workflow->can_approve_pull_request_reviews: false;PR DO NOT MERGE - integration stack CI #1 labels ->
do-not-mergealoneNot run, and why:
pre-commitand themakesuites assume a POSIX shell and.venv/bin/python(section 4.3); this change was authored on Windows. The CI
pre-commitjob covers the former. No.c/.h, Python, notebook, dynamics, reward, observation or training-loop code is touched, somake rebuild,test-unit,test-eval,test-c,test-notebooks,test-docker-smokeand theperf target are not applicable.
New behaviour covered by a test: n/a — fork-only CI/doc infrastructure, no sim behaviour. The
workflow's own guards are its test; they are replayed above and were probed in Gate 2.
Stack hygiene
1)integration/3.0Merge gate
Verdict FAIL: 2 blockers, 6 should-fix. Both blockers were independently reproduced
against the live repository and fixed; see the review comment on this PR for the disposition
of every finding.
Gate 3 result: exempt: chore(fork) — fork-only infrastructure can never be upstream-ready.
Upstream disposition
chore(fork):change, Gate 3 exemptRisk / notes
GITHUB_TOKENis denied PR creation in thisrepository (
can_approve_pull_request_reviews: false), and section 5 reserves that decision for ahuman anyway. A human opens it once; the workflow thereafter only checks it — warning when it is
missing and failing loudly if one was ever merged, which would mean the mirror is
contaminated. This also removed the need for
pull-requests: writeand label self-creation.do-not-mergealone, neverdo-not-mirror. Both labels together are thein-flight-process-change signal that section 4.1 queries; a permanent PR wearing both would tell
every agent, forever, that the rules are mid-change. Generalised into a stated rule, and it is
already how standing PR DO NOT MERGE - integration stack CI #1 is labelled.
contents: writeand force-pushesfork-only/3.0. Its push has a SHA sourceand a literal destination, so it cannot write to
3.0orintegration/3.0.push:trigger onintegration/3.0, which section 3.2 warns against for the testsuites. That warning is about runner cost; this workflow runs a few git commands and must react
to the branch moving. Section 3.2 records the distinction so it is not "fixed" later.
3.0, so each refresh re-runs thepull_requestworkflows. Suppressing that would mean adding more fork-only hunks to
ci.yml,install.ymlandpre-commit.yml, and every extra hunk in a shared file is another contamination path for featurecommits. The fork base changes rarely. Documented rather than hidden.
diff lines for
fork:begin/fork:end, so an edit in the middle of the marker block inAGENTS.md/CLAUDE.mdcan produce a three-line-context diff containing neither marker and slippast the cheap preflight. Gate 3 still catches it. Fixing it means comparing extracted blocks
rather than diff lines — a separate reviewable idea (section 4.2).
3.0. There are now two, bothstanding, both never merged. Amended.
fork-only-view; without that, the new workflowwould have been treated as an ordinary file and could have ridden into a mirror PR.
CONTRIBUTING.mdstill described the superseded single-axis[do-not-mirror]marker scheme("four redundant markers"); corrected to the two independent axes, and its fork-only file list now
includes the new workflow.
after which the workflow fires for the first time and publishes
fork-only/3.0. A human thenopens the standing view PR once.