Public: anyone can read this; the crew can change it.
A forge that reaches its CPU limit is slowed, not stopped: a crew run on a 1-CPU forge finishes #11540
Check · Review · Land · Live — No review yet.
A forge at its CPU limit is now slowed instead of stopped, but the acceptance checks on a real small forge are not done, so do not close #11539 yet. The `keep_plan` tool wasn't available to me, so the plan is in this description.
21 files · +549 −10
waiting waiting for sentinel's review deploy 36f0b35
Check passeddeploy 36f0b35
Website spec: 23 findings (report only)
- / <a href="/admin-ada0/admin/app/production/open"> has no accessible name — names
- / <a href="/bad-name-12dd/bad-name/app/production/open"> has no accessible name — names
- /front <a href="/admin-ada0/admin/app/production/open"> has no accessible name — names
- /front <a href="/bad-name-12dd/bad-name/app/production/open"> has no accessible name — names
- /board http://127.0.0.1:36689/board answered 303 — https://specification.website/
- /notes http://127.0.0.1:36689/notes answered 303 — https://specification.website/
- /feed http://127.0.0.1:36689/feed answered 303 — https://specification.website/
- /review http://127.0.0.1:36689/review answered 303 — https://specification.website/
- /releases http://127.0.0.1:36689/releases answered 303 — https://specification.website/
- /repos http://127.0.0.1:36689/repos answered 303 — https://specification.website/
- /map http://127.0.0.1:36689/map answered 303 — https://specification.website/
- /system http://127.0.0.1:36689/system answered 303 — https://specification.website/
- /talk http://127.0.0.1:36689/talk answered 303 — https://specification.website/
- /flow http://127.0.0.1:36689/flow answered 303 — https://specification.website/
- /resilience http://127.0.0.1:36689/resilience answered 303 — https://specification.website/
- /boards?help http://127.0.0.1:36689/boards?help answered 303 — https://specification.website/
- /settings/crew http://127.0.0.1:36689/settings/crew answered 303 — https://specification.website/
- /settings/crew?help http://127.0.0.1:36689/settings/crew?help answered 303 — https://specification.website/
- /preview-admin/sample expected exactly one <h1>, found 2 — headings
- /preview-admin/sample/next expected exactly one <h1>, found 2 — headings
- /preview-admin/sample/bets expected exactly one <h1>, found 2 — headings
- /preview-admin/sample/waves expected exactly one <h1>, found 2 — headings
- /preview-admin/sample/milestones expected exactly one <h1>, found 2 — headings
Look
9 pages beside main · 0 new to this pull
/apps
In the dark
at 36f0b35 ·
/explore
In the dark
at 36f0b35 ·
/feed
In the dark
at 36f0b35 ·
/front
In the dark
at 36f0b35 ·
/map
In the dark
at 36f0b35 ·
/notes
In the dark
at 36f0b35 ·
/releases
In the dark
at 36f0b35 ·
/repos
In the dark
at 36f0b35 ·
/review
In the dark
at 36f0b35 ·
A forge at its CPU limit is now slowed instead of stopped, but the acceptance checks on a real small forge are not done, so do not close #11539 yet. The keep_plan tool wasn't available to me, so the plan is in this description.
What changed
- Throttle: a cell the kernel can't cap with
cpu.maxnow has its process tree paused (SIGSTOP/SIGCONT) for part of each tick. It averages its cores, and nothing is killed for being busy (src/apps/throttle.ts, wired intowatchTreeinsrc/apps/contain.ts). Using exactly the limit no longer counts as over it. - Last resort: a cell is stopped for CPU only after five minutes over twice its limit, and never in its first ten minutes. Memory, disk and process-count stops are unchanged.
- Owner told: when the host stops a child forge, it writes
host-stopped.jsoninto that forge's data directory (src/spawn/stop_note.ts). The owner's home page shows what happened and why for a day, under "Needs you". - Work fits the size: on a 1-core forge, checks are not started, scheduled snapshots are not taken and looks wait while a crew run is running (
src/spawn/fit.ts). A waiting look's age restarts, so a long run doesn't drop it. Pictures and the accessibility check now share one browser gate (src/looks/browser_gate.ts). - Interrupted runs: a run cut off by a restart already resumed in the same clone and session. If it is cut off twice in a row, the issue is parked with a plain note instead of looping (
src/crew/interrupt_loop.ts). - Plan lines: small now says the crew has its only core while it builds, so a change takes longer and checks and pictures wait. Medium says checks and pictures run beside the crew.
- Docs:
docs/features/cpu-throttle.md.
Tests
- New tests:
test/cpu-throttle.test.ts(the pause by hand calculation, the last-resort rule, and a real CPU hog held under its limit),test/crew-has-the-core.test.ts,test/crew-interrupted-twice.test.tsandtest/host-stop-note.test.ts(including the home page line). - The suites I ran,
bun x tsc --noEmit,scripts/gate.tsandscripts/design-lint.tspass. The exception is three real-chromium tests intest/looks.test.ts, which fail the same way without my change because chromium can't start in this sandbox. scripts/fast.tsnamed 2267 files, too many to run, so I ran the suites near the change instead. The forge's own check runs the rest.
What I did not do
- Three-minute real 1-CPU cell test: not written. The sandbox can't create cells.
- Stranger journey on small and the production probe: not run. Do not close #11539 until the probe passes and its host-log lines are pasted here.
- Measured first-change times for small, medium and large: not taken. The plan lines say what each size is for, with no numbers, which
test/sizes-api.test.tsrequires. - Credit charged twice: I did not confirm whether a resumed run could be charged twice for the same work. Spend is written per run, and the resumed run continues the same session.
- Throttle accuracy: the pause is sized from a 5-second window, so it settles near the limit after a few seconds and can overshoot briefly under load. The throttle test therefore only asserts well below an unthrottled core.
Try
Put a host-stopped.json in a forge's data directory, then open the admin's home page and read the line under "Needs you". The file looks like {"at":"<ISO time>","why":"…"}.
🤖 Generated with Claude Code
A forge at its CPU limit is now slowed instead of stopped, but the acceptance checks on a real small forge are not done, so do not close #11539 yet. The
keep_plantool wasn't available to me, so the plan is in this description.What changed
cpu.maxnow has its process tree paused (SIGSTOP/SIGCONT) for part of each tick. It averages its cores, and nothing is killed for being busy (src/apps/throttle.ts, wired intowatchTreeinsrc/apps/contain.ts). Using exactly the limit no longer counts as over it.host-stopped.jsoninto that forge's data directory (src/spawn/stop_note.ts). The owner's home page shows what happened and why for a day, under "Needs you".src/spawn/fit.ts). A waiting look's age restarts, so a long run doesn't drop it. Pictures and the accessibility check now share one browser gate (src/looks/browser_gate.ts).src/crew/interrupt_loop.ts).docs/features/cpu-throttle.md.Tests
test/cpu-throttle.test.ts(the pause by hand calculation, the last-resort rule, and a real CPU hog held under its limit),test/crew-has-the-core.test.ts,test/crew-interrupted-twice.test.tsandtest/host-stop-note.test.ts(including the home page line).bun x tsc --noEmit,scripts/gate.tsandscripts/design-lint.tspass. The exception is three real-chromium tests intest/looks.test.ts, which fail the same way without my change because chromium can't start in this sandbox.scripts/fast.tsnamed 2267 files, too many to run, so I ran the suites near the change instead. The forge's own check runs the rest.What I did not do
test/sizes-api.test.tsrequires.Try Put a
host-stopped.jsonin a forge's data directory, then open the admin's home page and read the line under "Needs you". The file looks like{"at":"<ISO time>","why":"…"}.🤖 Generated with Claude Code
Closes #11539