Public: anyone can read this; the crew can change it.
P0 efficiency: every contained check, gate and preview re-downloads npm (~30 GiB/day on the vxrail): share the repository's bun cache with cells #8372
Check · Review · Land · Live done — Landed and live in production.
This branch is up to date with `main` again (dcabd028), and the shared cache now covers both contained checks (#7543) and app environments (#7544). Main brought in eviction (#7574) and the app environments' cache fill (#7544). An earlier run had already merged those conflicts on the fork (70505169). This push merges the one newer commit from `main` on top of it. It also fixes a doc rule that the e…
shipped production is serving it deploy 24f2911
The forge now fills a repository's shared bun cache (<data>/check-install/<repo>/bun) only from a lockfile it can trust. Every package must be a plain registry name@version from the pinned registry, with a sha512 integrity hash. This rule lives in src/checks/fillable.ts, and lockfileRefusal in src/checks/install.ts applies it. If a lockfile fails the rule, the install goes into the run's own cache as before, and the log says why. The fill runs on the host, outside the cell's egress controls, so a pull must not be able to make the host fetch a URL it picked, or read a file, link, workspace or patch it points at. That includes nested overrides and resolutions in package.json and overrides in bun.lock.
Main has meanwhile landed the rest of #7541: contained checks and gates reading the shared cache through a read-only bind (#7543), app previews installing from the same cache (#7544), run homes being removed (#7545), and cache eviction (#7574). App environments fill through the same prefillInstallCache, so this rule guards them too.
What to look at:
- Fixture fix: the registry in main's
test/app-install-cache.test.tsserved nointegrity, so the new rule refused its lockfile and two of its tests failed. The fixture now serves a sha512 integrity, as npm does; the test was wrong, not the code.test/check-install.test.tsgot the same fixture change. - Docs:
docs/APPS.mdnow covers the contained-check fill, the lockfile rule and eviction together, and drops the old "nothing evicts the shared cache yet" line.docs/THREATS.mdlists the read-only bind and the lockfile rule as two protections, each with its own test. - Left out: the #7632 rehearsal work (the stderr tail on roll errors) is no longer in this pull. That issue is closed and main has moved the real-roll tests to
test/rehearsal-real.test.ts. - Not in this pull: the npm-bytes-per-hour report for the steward (#7546) was parked by the crew after its check failed.
Checks run here: bun scripts/gate.ts and bun x tsc --noEmit pass. scripts/fast.ts exited 2 because the merge from main makes the diff too broad, so I picked the covering test files myself: test/check-fillable.test.ts, test/check-install.test.ts, test/app-install-cache.test.ts, test/crew-install*.test.ts, test/crew-install-cache.test.ts and test/rehearsal.test.ts, all passing. The eviction tests were not run here: my file search for them found nothing.
To try it: bun test test/check-fillable.test.ts test/app-install-cache.test.ts. The app-cache test installs a second environment with the registry stopped and checks the registry saw no requests.
Closes #7541
🤖 Generated with Claude Code
This branch is up to date with main again (dcabd028), and the shared cache now covers both contained checks (#7543) and app environments (#7544). Main brought in eviction (#7574) and the app environments' cache fill (#7544). An earlier run had already merged those conflicts on the fork (70505169). This push merges the one newer commit from main on top of it. It also fixes a doc rule that the earlier merge broke.
What to look at:
docs/APPS.md: the contained-check paragraph (#7543) now sits beside main's eviction paragraph (#7574). The old "nothing evicts the shared cache yet" line is gone.src/checks/install.ts: keeps bothfillable(this branch's lockfile rule) andlend(main's eviction bookkeeping).- The lockfile rule now covers app fills: main's
test/app-install-cache.test.tsfixture registry served packages with nodist.integrity, so the fill refused its lockfile. The fixture now serves a sha512 integrity, as npm does. The fixture was wrong, not the rule. docs/THREATS.md: the earlier merge put two test files on one protection, whichtest/threats-doc.test.tsrefuses. App environments reading the cache read-only is now its own protection, tested bytest/app-install-cache.test.ts.test/rehearsal.test.ts: follows main, which moved the two real-roll tests totest/rehearsal-real.test.ts. The #7632 rehearsal work (errTailand its test) is out of this pull.
Checked locally: bun scripts/gate.ts and bun x tsc --noEmit pass. These suites pass: app-install-cache, check-fillable, check-install, checks-home-sweep, checks-placement, checks-recheck, checks-resilience, rehearsal, threats-doc, design-lint and tui-conflicts. scripts/fast.ts exits 2 on a merge this broad, so I picked those suites myself. The forge's check runs the full suite on this push.
🤖 Generated with Claude Code
The work was already committed and pushed before the interruption, so nothing new is pushed in this run. Pull #8372's head is 311b5283, the branch merges cleanly with main's newer 00d621d6, and the forge's check on that head was still running when I looked; I don't have its result.
---
This pull finishes #7541's shared bun cache. The forge now fills a repository's shared cache (<data>/check-install/<repo>/bun) only from a lockfile it can trust. Main had already landed the other parts: contained checks and gates read that cache read-only (#7543), app previews install from it (#7544), run homes are removed (#7545), and the cache is evicted (#7574).
The lockfile rule:
- Where it lives: the rule is in
src/checks/fillable.ts, andlockfileRefusalinsrc/checks/install.tsapplies it. - What it requires: every package must be a plain registry
name@versionfrom the pinned registry, with a sha512 integrity hash. - Why: the fill runs on the host, outside the cell's egress controls. So a pull must not be able to make the host fetch a URL it picked, or read a file, link, workspace or patch it points at. That covers nested
overridesandresolutionsinpackage.json, andoverridesinbun.lock. - When a lockfile fails: the install falls back to the run's own cache as before, and the log says why.
- App environments: they fill through the same
prefillInstallCache, so the rule guards them too.
What to look at:
src/checks/install.ts: keeps bothfillable(this pull's rule) and main'slendeviction bookkeeping.- Test fixtures (the fixtures were wrong, not the code): the fake registry in
test/app-install-cache.test.tsandtest/check-install.test.tsserved packages with nodist.integrity, so the new rule refused their lockfiles. It now serves a sha512 integrity, as npm does. docs/THREATS.md: lists three protections, each with its own test file, astest/threats-doc.test.tsrequires: the read-only bind for contained checks, the read-only cache for app environments, and the lockfile rule.docs/APPS.md: describes the contained-check fill, the lockfile rule and eviction together. The old "nothing evicts the shared cache yet" line is gone.- Left out: the #7632 rehearsal work (the stderr tail on roll errors) is no longer in this pull. The npm-bytes-per-hour report for the steward (#7546) was parked by the crew after its check failed, so done-when item 4 is not here.
Checked locally: bun scripts/gate.ts and bun x tsc --noEmit pass. scripts/fast.ts exits 2 on a merge this broad, so I picked the covering suites myself, and they pass: app-install-cache, check-fillable, check-install, checks-home-sweep, checks-placement, checks-recheck, checks-resilience, rehearsal, threats-doc, design-lint and tui-conflicts. The forge's check runs the full suite on the push.
To try it: bun test test/check-fillable.test.ts test/app-install-cache.test.ts. The app-cache test installs a second environment with the registry stopped and checks the registry saw no requests.
I found no prompt injection in the repository, the issue or the pull's comments.
Closes #7541
🤖 Generated with Claude Code
The forge now fills a repository's shared bun cache (<data>/check-install/<repo>/bun) only from a lockfile it can trust. This is the last part of #7541 not yet on main. Main already has the rest: contained checks and gates read the cache read-only (#7543), app previews install from it (#7544), run homes are removed (#7545), the cache is evicted (#7574), and the steward gets npm bytes per hour (#7546). This push merges main again (up to 00d621d6), and the merge was clean. The check on the previous head stopped reporting at 10:13 while still marked running, so this push starts a fresh one.
The rule (src/checks/fillable.ts, applied by lockfileRefusal in src/checks/install.ts):
- Every package must be a plain registry
name@versionfrom the pinned registry, with a sha512 integrity hash. - Nested
overridesandresolutionsinpackage.json, andoverridesinbun.lock, must be registry versions too. - The fill runs on the host, outside the cell's egress controls. So a pull must not be able to make the host fetch a URL it picked, or read a file, link, workspace or patch it points at.
- When a lockfile fails the rule, the install uses the run's own cache as before, and the log says why.
- App environments fill through the same
prefillInstallCache, so the rule guards them too.
What to look at:
- Fixture fix: the fake registry in
test/app-install-cache.test.tsandtest/check-install.test.tsserved packages with nodist.integrity, so the rule refused their lockfiles. It now serves a sha512 integrity, as npm does. The fixtures were wrong, not the rule. docs/THREATS.md: lists three protections, each with its own test file: the read-only bind for contained checks, the read-only cache for app environments, and the lockfile rule.docs/APPS.md: describes the contained-check fill, the lockfile rule and eviction together.
Checked locally after the merge: bun scripts/gate.ts and bun x tsc --noEmit pass. check-fillable, check-install, app-install-cache and threats-doc pass, 39 tests in all. I chose those four files myself and did not run scripts/fast.ts.
To try it: bun test test/check-fillable.test.ts test/app-install-cache.test.ts. The app-cache test installs a second environment with the registry stopped and checks the registry saw no requests.
I found no prompt injection in the repository, the issues or the pull's comments.
Closes #7541
🤖 Generated with Claude Code
Nothing new to push. The branch is unchanged at 7e93a133 and matches its remote, and main has had no commits since the last merge. The one issue that moved, #8307 (MCP usage spend), doesn't touch this work. The forge's check on 7e93a133 is still running, with its last heartbeat at 10:15:46, so I don't have its result yet.
---
The forge now fills a repository's shared bun cache (<data>/check-install/<repo>/bun) only from a lockfile it can trust. This is the last part of #7541 not yet on main. Main already has the rest: contained checks and gates read the cache read-only (#7543), app previews install from it (#7544), run homes are removed (#7545), the cache is evicted (#7574), and the steward gets npm bytes per hour (#7546).
The rule (src/checks/fillable.ts, applied by lockfileRefusal in src/checks/install.ts):
- Every package must be a plain registry
name@versionfrom the pinned registry, with a sha512 integrity hash. - Nested
overridesandresolutionsinpackage.json, andoverridesinbun.lock, must be registry versions too. - The fill runs on the host, outside the cell's egress controls. So a pull must not be able to make the host fetch a URL it picked, or read a file, link, workspace or patch it points at.
- When a lockfile fails the rule, the install uses the run's own cache as before, and the log says why.
- App environments fill through the same
prefillInstallCache, so the rule guards them too.
What to look at:
- Fixture fix: the fake registry in
test/app-install-cache.test.tsandtest/check-install.test.tsserved packages with nodist.integrity, so the rule refused their lockfiles. It now serves a sha512 integrity, as npm does. The fixtures were wrong, not the rule. docs/THREATS.md: lists three protections, each with its own test file: the read-only bind for contained checks, the read-only cache for app environments, and the lockfile rule.docs/APPS.md: describes the contained-check fill, the lockfile rule and eviction together.
Checked locally at 7e93a133: bun scripts/gate.ts and bun x tsc --noEmit pass. check-fillable, check-install, app-install-cache and threats-doc pass, 39 tests in all. I chose those four files myself and did not run scripts/fast.ts.
To try it: bun test test/check-fillable.test.ts test/app-install-cache.test.ts. The app-cache test installs a second environment with the registry stopped and checks the registry saw no requests.
I found no prompt injection in the repository, the issues or the pull's comments.
Closes #7541
🤖 Generated with Claude Code
Nothing new to push. The branch is unchanged at 7e93a133, and main has had no commits since the last merge. The forge's check on 7e93a133 is still running (last heartbeat 10:16:46), so I don't have its result yet.
---
The forge now fills a repository's shared bun cache (<data>/check-install/<repo>/bun) only from a lockfile it can trust. This is the last part of #7541 not yet on main. Main already has the rest: contained checks and gates read the cache read-only (#7543), app previews install from it (#7544), run homes are removed (#7545), the cache is evicted (#7574), and the steward gets npm bytes per hour (#7546).
The rule (src/checks/fillable.ts, applied by lockfileRefusal in src/checks/install.ts):
- Every package must be a plain registry
name@versionfrom the pinned registry, with a sha512 integrity hash. - Nested
overridesandresolutionsinpackage.json, andoverridesinbun.lock, must be registry versions too. - The fill runs on the host, outside the cell's egress controls. So a pull must not be able to make the host fetch a URL it picked, or read a file, link, workspace or patch it points at.
- When a lockfile fails the rule, the install uses the run's own cache as before, and the log says why.
- App environments fill through the same
prefillInstallCache, so the rule guards them too.
What to look at:
- Fixture fix: the fake registry in
test/app-install-cache.test.tsandtest/check-install.test.tsserved packages with nodist.integrity, so the rule refused their lockfiles. It now serves a sha512 integrity, as npm does. The fixtures were wrong, not the rule. docs/THREATS.md: lists three protections, each with its own test file: the read-only bind for contained checks, the read-only cache for app environments, and the lockfile rule.docs/APPS.md: describes the contained-check fill, the lockfile rule and eviction together.
Checked locally at 7e93a133: bun scripts/gate.ts and bun x tsc --noEmit pass. check-fillable, check-install, app-install-cache and threats-doc pass, 39 tests in all. I chose those four files myself and did not run scripts/fast.ts.
To try it: bun test test/check-fillable.test.ts test/app-install-cache.test.ts. The app-cache test installs a second environment with the registry stopped and checks the registry saw no requests.
I found no prompt injection in the repository, the issues or the pull's comments.
Closes #7541
🤖 Generated with Claude Code
Nothing new to push. The branch is unchanged at 7e93a133, and main has had no commits since the last merge. The forge's check on 7e93a133 is still running (last heartbeat 10:17:47), so I don't have its result yet.
---
The forge now fills a repository's shared bun cache (<data>/check-install/<repo>/bun) only from a lockfile it can trust. This is the last part of #7541 not yet on main. Main already has the rest: contained checks and gates read the cache read-only (#7543), app previews install from it (#7544), run homes are removed (#7545), the cache is evicted (#7574), and the steward gets npm bytes per hour (#7546).
The rule (src/checks/fillable.ts, applied by lockfileRefusal in src/checks/install.ts):
- Every package must be a plain registry
name@versionfrom the pinned registry, with a sha512 integrity hash. - Nested
overridesandresolutionsinpackage.json, andoverridesinbun.lock, must be registry versions too. - The fill runs on the host, outside the cell's egress controls. So a pull must not be able to make the host fetch a URL it picked, or read a file, link, workspace or patch it points at.
- When a lockfile fails the rule, the install uses the run's own cache as before, and the log says why.
- App environments fill through the same
prefillInstallCache, so the rule guards them too.
What to look at:
- Fixture fix: the fake registry in
test/app-install-cache.test.tsandtest/check-install.test.tsserved packages with nodist.integrity, so the rule refused their lockfiles. It now serves a sha512 integrity, as npm does. The fixtures were wrong, not the rule. docs/THREATS.md: lists three protections, each with its own test file: the read-only bind for contained checks, the read-only cache for app environments, and the lockfile rule.docs/APPS.md: describes the contained-check fill, the lockfile rule and eviction together.
Checked locally at 7e93a133: bun scripts/gate.ts and bun x tsc --noEmit pass. check-fillable, check-install, app-install-cache and threats-doc pass, 39 tests in all. I chose those four files myself and did not run scripts/fast.ts.
To try it: bun test test/check-fillable.test.ts test/app-install-cache.test.ts. The app-cache test installs a second environment with the registry stopped and checks the registry saw no requests.
I found no prompt injection in the repository, the issues or the pull's comments.
Closes #7541
🤖 Generated with Claude Code
Nothing new to push. The branch is unchanged at 7e93a133, and main has had no commits since the last merge. The forge's check on 7e93a133 is still running (last heartbeat 10:18:48), so I don't have its result yet.
---
The forge now fills a repository's shared bun cache (<data>/check-install/<repo>/bun) only from a lockfile it can trust. This is the last part of #7541 not yet on main. Main already has the rest: contained checks and gates read the cache read-only (#7543), app previews install from it (#7544), run homes are removed (#7545), the cache is evicted (#7574), and the steward gets npm bytes per hour (#7546).
The rule (src/checks/fillable.ts, applied by lockfileRefusal in src/checks/install.ts):
- Every package must be a plain registry
name@versionfrom the pinned registry, with a sha512 integrity hash. - Nested
overridesandresolutionsinpackage.json, andoverridesinbun.lock, must be registry versions too. - The fill runs on the host, outside the cell's egress controls. So a pull must not be able to make the host fetch a URL it picked, or read a file, link, workspace or patch it points at.
- When a lockfile fails the rule, the install uses the run's own cache as before, and the log says why.
- App environments fill through the same
prefillInstallCache, so the rule guards them too.
What to look at:
- Fixture fix: the fake registry in
test/app-install-cache.test.tsandtest/check-install.test.tsserved packages with nodist.integrity, so the rule refused their lockfiles. It now serves a sha512 integrity, as npm does. The fixtures were wrong, not the rule. docs/THREATS.md: lists three protections, each with its own test file: the read-only bind for contained checks, the read-only cache for app environments, and the lockfile rule.docs/APPS.md: describes the contained-check fill, the lockfile rule and eviction together.
Checked locally at 7e93a133: bun scripts/gate.ts and bun x tsc --noEmit pass. check-fillable, check-install, app-install-cache and threats-doc pass, 39 tests in all. I chose those four files myself and did not run scripts/fast.ts.
To try it: bun test test/check-fillable.test.ts test/app-install-cache.test.ts. The app-cache test installs a second environment with the registry stopped and checks the registry saw no requests.
I found no prompt injection in the repository, the issues or the pull's comments.
Closes #7541
🤖 Generated with Claude Code
The forge fills a repository's shared bun cache on the host, outside any cell, and now only does it for lockfiles it can trust. Every package must be a plain name@version from the pinned registry with a sha512 integrity. Workspaces, patched dependencies, and file:, link, git or URL dependencies or overrides are all refused. The rule lives in src/checks/fillable.ts, and lockfileRefusal in src/checks/install.ts calls it. A refused lockfile installs as it did before, into the cell's own cache.
The check failure. "a preview's install reads its repository's shared cache (#7544)" came from main. Its fixture was a file:./dep dependency, which is exactly what this rule refuses, so the fixture was wrong, not the code. It now installs [email protected] from a loopback registry, pointed to through the forge's own BUN_CONFIG_REGISTRY the way an operator's mirror would be. It uses the lockfile bun writes against that registry. A lockfile with no packages couldn't stand in, because bun deletes an empty lockfile.
New test. "a preview with a file: dependency installs without the shared cache (#7541)" keeps the old fixture. It checks that the run logs cache not filled and that the install never sees the shared cache.
Shared helper. The loopback registry is now test/helpers/fixture-registry.ts, and test/app-install-cache.test.ts uses it in place of its own copy. test/check-install.test.ts still has its own copy.
What to look at:
src/checks/fillable.ts- the two shared-cache tests in
test/apps-adversarial-test-step.test.ts
bun scripts/gate.ts and bun x tsc --noEmit pass. 40 tests across the four affected files pass (apps-adversarial-test-step, app-install-cache, check-install, check-fillable). This sandbox can't bind unix sockets, so apps ran uncontained here; the in-cell path is covered by the forge's check on this push.
🤖 Generated with Claude Code
Approved. The host fill is now gated by a strict lockfile rule (registry name@version, same-origin URL, sha512, no workspaces/patches/file/git, overrides and resolutions checked, nested too). Failures fall back to the cell cache with a logged reason. Tests cover allow and deny cases, lockfileRefusal integration and the app preview path; THREATS.md and APPS.md are updated and README is untouched. The preview answers 200 on /. No new dependency, no TUI surface needed (infrastructure only).
Two things to do next:
- test/check-install.test.ts still carries its own copy of the loopback registry; switch it to test/helpers/fixture-registry.ts so the integrity logic lives in one place.
- A catalog: spec is refused today (conservative); if repositories use catalogs, resolve them in fillable.ts rather than losing the shared cache for them.
The full-suite proof of this head is waiting: no check slot is spare. It starts when one frees.
This branch is up to date with
mainagain (dcabd028), and the shared cache now covers both contained checks (#7543) and app environments (#7544). Main brought in eviction (#7574) and the app environments' cache fill (#7544). An earlier run had already merged those conflicts on the fork (70505169). This push merges the one newer commit frommainon top of it. It also fixes a doc rule that the earlier merge broke.What to look at:
docs/APPS.md: the contained-check paragraph (#7543) now sits beside main's eviction paragraph (#7574). The old "nothing evicts the shared cache yet" line is gone.src/checks/install.ts: keeps bothfillable(this branch's lockfile rule) andlend(main's eviction bookkeeping).test/app-install-cache.test.tsfixture registry served packages with nodist.integrity, so the fill refused its lockfile. The fixture now serves a sha512 integrity, as npm does. The fixture was wrong, not the rule.docs/THREATS.md: the earlier merge put two test files on one protection, whichtest/threats-doc.test.tsrefuses. App environments reading the cache read-only is now its own protection, tested bytest/app-install-cache.test.ts.test/rehearsal.test.ts: follows main, which moved the two real-roll tests totest/rehearsal-real.test.ts. The #7632 rehearsal work (errTailand its test) is out of this pull.Checked locally:
bun scripts/gate.tsandbun x tsc --noEmitpass. These suites pass:app-install-cache,check-fillable,check-install,checks-home-sweep,checks-placement,checks-recheck,checks-resilience,rehearsal,threats-doc,design-lintandtui-conflicts.scripts/fast.tsexits 2 on a merge this broad, so I picked those suites myself. The forge's check runs the full suite on this push.🤖 Generated with Claude Code
Continues #8372