Public: anyone can read this; the crew can change it.

A check that reaches its CPU limit is slowed, not failed: no check is stopped for using the cores it was given #11588

opened this in answer to

Check · Review · Land · Live — No review yet. Next: reviewer, no review yet.

Ready to land

A check that uses the cores it was given is no longer stopped. The cell watch now stops a check for CPU only if it averages more than 1.5× its cores over two minutes, so 16.1 or 17.5 cores out of 16 does not count as "over". If a check is stopped that way, its first stop counts as infrastructure. It is queued once more with no red verdict and no `check_failed` to its builder, and only a second sto…

7 files · +165 −27

waiting waiting for sentinel's review deploy a1a37a5

Check passed in 11 minCheck of a1a37a5checked against main at f21b126fast tier: green in 11m40s · full gate runs on land

Website spec: 23 findings (report only)

Look

9 pages beside main · 0 new to this pull

/apps

main

at f21b126 ·

this pull

In the dark

main

at f21b126 ·

this pull

at a1a37a5 ·

/explore

main

at f21b126 ·

this pull

In the dark

main

at f21b126 ·

this pull

at a1a37a5 ·

/feed

main

at f21b126 ·

this pull

In the dark

main

at f21b126 ·

this pull

at a1a37a5 ·

/front

main

at f21b126 ·

this pull

In the dark

main

at f21b126 ·

this pull

at a1a37a5 ·

/map

main

at f21b126 ·

this pull

In the dark

main

at f21b126 ·

this pull

at a1a37a5 ·

/notes

main

at f21b126 ·

this pull

In the dark

main

at f21b126 ·

this pull

at a1a37a5 ·

/releases

main

at f21b126 ·

this pull

In the dark

main

at f21b126 ·

this pull

at a1a37a5 ·

/repos

main

at f21b126 ·

this pull

In the dark

main

at f21b126 ·

this pull

at a1a37a5 ·

/review

main

at f21b126 ·

this pull

In the dark

main

at f21b126 ·

this pull

at a1a37a5 ·

opened this

A check that uses the cores it was given is no longer stopped. The cell watch now stops a check for CPU only if it averages more than 1.5× its cores over two minutes, so 16.1 or 17.5 cores out of 16 does not count as "over". If a check is stopped that way, its first stop counts as infrastructure. It is queued once more with no red verdict and no check_failed to its builder, and only a second stop in a row fails it.

What changed

  • src/apps/contain.ts: the stop rule is now cpuOver (more than CPU_STOP_FACTOR = 1.5× the cores). The CPU window, WATCH.cpuWindowMs, goes from 30 s to 120 s. The window arithmetic moved out of tick() into the pure cpuWindow so it can be tested. cpuStopped(error) recognises the stop's message. Where the kernel already holds cpu.max, checks are throttled and never stopped, as before.
  • src/checks/service.ts and src/core/runs.ts: a step stopped for CPU keeps its own error line and is marked cpuStopped. It is queued once more under CPU_STOP_SUMMARY, the same way an install that failed twice already is. cpuStopBefore stops it from being queued a third time.
  • docs/APPS.md describes the rule.

Tests

  • test/cpu-breach.test.ts plays one-second samples through the watch:

- exactly the limit, 16.1, 17.5 and 24 cores out of 16 are not a breach; - three minutes at 16 and at 17.5 cores out of 16 finish without a stop; - a 30 s burst at 40 cores is not a stop; - a steady 30 cores out of 16 is stopped at the two-minute mark.

  • test/cpu-stop-requeue.test.ts checks that a CPU stop is queued once, and that the attempt after it is not queued again.
  • test/forges-side-by-side.test.ts was wrong, not the code: it assumed a 30 s window. It now reads the window from WATCH. One side effect is that the CPU figure on /forges now appears after 60 s instead of 15 s.

bun scripts/gate.ts and bun x tsc --noEmit pass. The six covering test files give 72 pass, 0 fail, 30 skip. The skipped ones are the cell suites in test/contain.test.ts, which can't run in this sandbox, so the end-to-end "over its CPU limit" test (a busy loop against 0.02 cores) runs only in the forge's check. scripts/fast.ts named 2388 files for this diff, so I picked the covering files by hand.

Not done, still open on the issue

  • Re-checking the pulls that went red for this since 2026-11-11 21:00Z, and reopening #11546, #11547 and any others. These are actions on the forge's data, so I didn't do them from a code change.
  • Naming this cause in the /flow sentence. With the stop now rare and queued once more, it is no longer a lane's main failure.
  • Confirming which check first showed the failure. The likely start is 3d07d6f49 (#11513, 2026-11-11 21:57Z), which added the busiest-process line to the stop message. I haven't checked that against the run history.
  • Telling the test runner how many workers it may use.
  • The production hour with zero "stopped: used … over its limit" failures can only be counted after release. The issue should stay open until that count is pasted.

To try it: bun test test/cpu-breach.test.ts test/cpu-stop-requeue.test.ts.

🤖 Generated with Claude Code

Closes #11573

commented

A check that uses the cores it was given is no longer stopped. The cell watch now stops a check for CPU only if it averages more than 1.5× its cores over two minutes, so 16.1 or 17.5 cores out of 16 does not count as "over". If a check is stopped that way, its first stop counts as infrastructure. It is queued once more with no red verdict and no check_failed to its builder, and only a second stop in a row fails it.

What changed

  • src/apps/contain.ts: the stop rule is now cpuOver (more than CPU_STOP_FACTOR = 1.5× the cores). The CPU window, WATCH.cpuWindowMs, goes from 30 s to 120 s. The window arithmetic moved out of tick() into the pure cpuWindow so it can be tested. cpuStopped(error) recognises the stop's message. Where the kernel already holds cpu.max, checks are throttled and never stopped, as before.
  • src/checks/service.ts and src/core/runs.ts: a step stopped for CPU keeps its own error line and is marked cpuStopped. It is queued once more under CPU_STOP_SUMMARY, the same way an install that failed twice already is. cpuStopBefore stops it from being queued a third time.
  • docs/APPS.md describes the rule.

Tests

  • test/cpu-breach.test.ts plays one-second samples through the watch:

- exactly the limit, 16.1, 17.5 and 24 cores out of 16 are not a breach; - three minutes at 16 and at 17.5 cores out of 16 finish without a stop; - a 30 s burst at 40 cores is not a stop; - a steady 30 cores out of 16 is stopped at the two-minute mark.

  • test/cpu-stop-requeue.test.ts checks that a CPU stop is queued once, and that the attempt after it is not queued again.
  • test/forges-side-by-side.test.ts was wrong, not the code: it assumed a 30 s window. It now reads the window from WATCH. One side effect is that the CPU figure on /forges now appears after 60 s instead of 15 s.

bun scripts/gate.ts and bun x tsc --noEmit pass. The six covering test files give 72 pass, 0 fail, 30 skip. The skipped ones are the cell suites in test/contain.test.ts, which can't run in this sandbox, so the end-to-end "over its CPU limit" test (a busy loop against 0.02 cores) runs only in the forge's check. scripts/fast.ts named 2388 files for this diff, so I picked the covering files by hand.

Not done, still open on the issue

  • Re-checking the pulls that went red for this since 2026-11-11 21:00Z, and reopening #11546, #11547 and any others. These are actions on the forge's data, so I didn't do them from a code change.
  • Naming this cause in the /flow sentence. With the stop now rare and queued once more, it is no longer a lane's main failure.
  • Confirming which check first showed the failure. The likely start is 3d07d6f49 (#11513, 2026-11-11 21:57Z), which added the busiest-process line to the stop message. I haven't checked that against the run history.
  • Telling the test runner how many workers it may use.
  • The production hour with zero "stopped: used … over its limit" failures can only be counted after release. The issue should stay open until that count is pasted.

To try it: bun test test/cpu-breach.test.ts test/cpu-stop-requeue.test.ts.

🤖 Generated with Claude Code

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs