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

One pure function decides when a cell's CPU use is a stop: over twice its cores for five minutes straight, never in its first ten minutes #11628

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

I added `cpuStop` in `src/apps/cpu_rule.ts`. Nothing calls it yet, so the watch loop and `src/apps/contain.ts` are untouched. `bun test` on `test/cpu-rule.test.ts`, `test/cpu-breach.test.ts` and `test/contain.test.ts` passes, and so does `bun x tsc --noEmit`. `bun scripts/gate.ts` ran before the push, but I only looked at its last lines and they showed no error.

shipped production is serving it deploy e1bbdcb

opened this

I added cpuStop in src/apps/cpu_rule.ts. Nothing calls it yet, so the watch loop and src/apps/contain.ts are untouched. bun test on test/cpu-rule.test.ts, test/cpu-breach.test.ts and test/contain.test.ts passes, and so does bun x tsc --noEmit. bun scripts/gate.ts ran before the push, but I only looked at its last lines and they showed no error.

  • The rule: cpuStop({ cores, cpus, overSinceMs, nowMs, startedAtMs }) returns true only when cores > 2 * cpus has held for at least 5 minutes and the cell is at least 10 minutes old. It takes no clock and does no I/O. The three constants are exported: CPU_STOP_FACTOR, CPU_STOP_HOLD_MS and CPU_STOP_GRACE_MS.
  • Inputs it refuses: overSinceMs is null when the overage doesn't currently hold. Any NaN input also returns false.
  • Tests: test/cpu-rule.test.ts covers the six cases from the issue. I added the exact 10-minute boundary, which stops, and the case where the cores are at the limit and overSinceMs is null.
  • scripts/gate.ts: it picks up test/*.test.ts by glob, so it needed no change.

To try it, run bun test test/cpu-rule.test.ts.

Closes #11612

commented

The check failed because src/apps/cpu_rule.ts has no caller yet, and test/unreached.test.ts fails any module under src/ that nothing imports. I added the file to scripts/unreached-allow.json, the allow list built for this case. test/unreached.test.ts and bun x tsc --noEmit now pass here, and I've pushed. I did not re-run the full check, so the forge's run on this push is the confirmation.

The issue said only three files may change, and this is a fourth. The change is one line, and the entry has to come off that list when the watch loop starts calling cpuStop, because test/unreached.test.ts also fails a listed file that has become reached.

commented

This pull adds src/apps/cpu_rule.ts, one pure function that decides when a cell's CPU use counts as a stop: over twice its cores for five minutes, and never in the cell's first ten minutes. test/cpu-rule.test.ts covers it. Nothing calls it yet, so I added src/apps/cpu_rule.ts to scripts/unreached-allow.json until the watcher does.

The one failing check test, "the three lists, on the page and on /flow", was a date bug in the test and unrelated to the CPU rule. test/flow-handover-page.test.ts fixed its clock at 2026-11-11T12:00Z, but /flow reads the real time. Once the date moved past that day, the seeded hand-over note fell outside the one-day window and dropped off the page. The test now takes NOW from Date.now(), so it stays inside the window on any day. I did not change any app code.

test/flow-handover-page.test.ts passes (7 of 7) and bun x tsc --noEmit is clean. I did not re-run the full suite here. I pushed without running bun scripts/gate.ts this round, so the forge's check is the first run of it.

To try the CPU rule: bun test test/cpu-rule.test.ts.

commented

I merged main into the branch and pushed it. The only conflict was in test/flow-handover-page.test.ts, where main had already made the same fix I pushed earlier: take NOW from Date.now() so the test stays inside /flow's one-day hand-over window. I kept main's version, so this pull no longer touches that file.

The pull's own change is unchanged: src/apps/cpu_rule.ts, the pure function that decides when a cell's CPU use counts as a stop (over twice its cores for five minutes, never in the cell's first ten), with test/cpu-rule.test.ts. Nothing calls it yet, so it stays listed in scripts/unreached-allow.json until the watcher does.

bun x tsc --noEmit is clean and test/flow-handover-page.test.ts and test/cpu-rule.test.ts pass (13 tests). I did not run bun scripts/gate.ts or the full suite; the forge's check does that on this push.

To try it: bun test test/cpu-rule.test.ts.

Approved

Pure rule, no clock or I/O, correct on every case the issue lists; tests pass (17 pass, 30 skipped for the unix-socket mode), preview answers 200. The gate lists test files by glob, so box 3 needs no edit. The fourth file, scripts/unreached-allow.json, is forced by test/unreached.test.ts and explained in the pull; it must come off when the watcher calls cpuStop.

Next two: (1) wire cpuStop into the watch loop in contain.ts in a follow-up and drop the allow-list entry in the same commit; (2) add tests for the exact 5-minute hold boundary just below it (4:59.999) and for NaN inputs, which the guard handles but nothing pins.

commented

Left #11612 open: 2 unticked items remain (A new src/apps/cpu_rule.ts exports one pure function, e.g. cpuStop({ cores, cpus, overSinceMs, nowMs, startedAtMs }): boolean (plain data in, a boolean out; no Date.now(), no I/O). It answers true only when cores > 2 * cpus has held continuously for at least 5 minutes and the cell is at least 10 minutes old. Also export the two constants (CPU_STOP_FACTOR = 2, CPU_STOP_HOLD_MS = 5 * 60_000, CPU_STOP_GRACE_MS = 10 * 60_000).; Only these files change: src/apps/cpu_rule.ts, test/cpu-rule.test.ts and, if needed, scripts/gate.ts. src/apps/contain.ts is not touched in this pull.).

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs