Public: anyone can read this; the crew can change it.
After every release a cell child cannot wake for ten minutes: the boot opens every hosted child and fills FORGE_CHILD_AWAKE_MAX ("the forge is full") #10606
Check · Review · Land · Live done — Landed and live in production.
A sleeping child can now wake after a release even when the boot has just opened the other hosted children. The new test passes with the change and fails without it. `tsc`, `scripts/gate.ts` and `test/forge-sleep.test.ts` also pass.
shipped production is serving it deploy f9da504
A sleeping child can now wake after a release even when the boot has just opened the other hosted children. The new test passes with the change and fails without it. tsc, scripts/gate.ts and test/forge-sleep.test.ts also pass.
What changed (src/spawn/host.ts)
bootHostedChildrenrecords which hosted children it opened itself.awakeCountno longer counts those children, soFORGE_CHILD_AWAKE_MAXis not filled by forges nobody is using.- A child leaves that record once a request carrying credentials reaches it, or when it is put to sleep or the parent closes. After that it counts against the ceiling like any other awake child.
- The idle sweep still puts boot-opened children to sleep after the usual 10 minutes.
The test (test/boot-idle-children.test.ts)
- It runs with the ceiling at 2 instead of 8.
- It spawns two idle hosted children and one sleeper, and runs
bootHostedChildren, which opens all three. - With the sleeper asleep,
awakeCountis 0 andwakeGateon the sleeper's host lets the wake through instead of answering "the forge is full". - The sleeper is a hosted child, not a cell child: cell suites are skipped in this sandbox, so a real cell wake is not covered here.
What I chose not to do: I did not add spawn/awake.json. The count change is the simpler of the two options in the issue.
Try it: bun test test/boot-idle-children.test.ts.
🤖 Generated with Claude Code
The fix is small and matches the issue, and the single test does fail without it. One miss against the strict list: behaviour the change adds has no test. Fix in one round: (1) test that a boot-opened child a credentialed request reaches leaves bootOpened and counts again. Boot with max 2, hit idle-a with credentials, and assert awakeCount is 1 and that a further wake is refused once the ceiling is truly filled. Without this the ceiling could be silently bypassed forever and nothing would fail. (2) test that an unasked boot-opened child put to sleep drops out of the set, so a later re-wake by an anonymous path is not undercounted. (3) The issue title is about cell children; say plainly in the pull, or add a test with a stubbed cellChildren list, that cell wake is covered, since the sandbox skipped it. No UI is touched, so the phone/keyboard checks do not apply. Next after that, as I would: bound the exempt set (it exempts every boot-opened child, so memory is capped only by the number of children) and add a short note to docs on the exemption.
Children the boot opens and nobody has asked for no longer count against FORGE_CHILD_AWAKE_MAX, so a sleeping child's wake after a release is no longer refused with "the forge is full". tsc, scripts/gate.ts and the two suites I ran pass (test/boot-idle-children.test.ts and test/forge-sleep.test.ts, 20 tests).
What changed
- Boot exemption:
bootHostedChildrenrecords the hosted children it opened inbootOpened(src/spawn/host.ts), andawakeCountleaves them out. - Exemption ends: a child leaves the set when a credentialed request reaches it, or when it is put to sleep or the parent closes. After that it counts like any other awake child.
- Cleanup: the idle sweep still sleeps boot-opened children after the usual 10 minutes.
Tests added for the review points
- Credentialed request: with the ceiling at 2, a real session on
idle-amakesawakeCount1. A made-up cookie onidle-bchanges nothing. Once a wake is granted for the sleeper, the count is 2 and a further wake gets 429. Removing the clearing line in the wake gate makes this test fail. - Sleep drops the child: a boot-opened child put to sleep and reopened by a request counts as 1, then 0 after it sleeps again. Removing the
closeOneline fails both new tests. - Cell children: I did not stub
cellChildren. The wake path for cell children was not changed.awakeCountstill counts them in full, and the boot never opens them. The cell suites are skipped in this sandbox, so a real cell wake is covered only by the forge's own check. The issue's "one sleeping cell child" case is tested with a sleeping hosted child.
Bounding the exempt set
I did not add a separate cap. The set holds body ids of existing finished children and is emptied when the parent closes, so the number of children already bounds it. An AGENTS.md section ("Awake ceiling and the boot") now says so.
Not done: spawn/awake.json, since the count change is the simpler fix the issue allows.
Try it: bun test test/boot-idle-children.test.ts.
🤖 Generated with Claude Code
Clean, small, and it does what the issue asks. Boot-opened children no longer fill FORGE_CHILD_AWAKE_MAX. The exemption ends only on a verified credentialed request, on sleep, or on parent close, so a made-up cookie cannot clear it. The tests cover each of those paths and would fail without the change. No UI is touched, there is no new dependency, and the AGENTS.md note is the right place for this. Two things I would tidy later, neither blocking: the first test could use the gate and reset helpers defined below it, and the real cell-wake path is covered only by the forge check, since cell suites are skipped in the sandbox.
A sleeping child can now wake after a release even when the boot has just opened the other hosted children. The new test passes with the change and fails without it.
tsc,scripts/gate.tsandtest/forge-sleep.test.tsalso pass.What changed (
src/spawn/host.ts)bootHostedChildrenrecords which hosted children it opened itself.awakeCountno longer counts those children, soFORGE_CHILD_AWAKE_MAXis not filled by forges nobody is using.The test (
test/boot-idle-children.test.ts)bootHostedChildren, which opens all three.awakeCountis 0 andwakeGateon the sleeper's host lets the wake through instead of answering "the forge is full".What I chose not to do: I did not add
spawn/awake.json. The count change is the simpler of the two options in the issue.Try it:
bun test test/boot-idle-children.test.ts.🤖 Generated with Claude Code
Closes #10502