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

Sentinel: disk was degraded 49 minutes today: Disk is nearly full: 10% free. #5730

Merged opened this

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

Merged

This pull adds a sweep that removes agent clones nothing claims, at crew start and then hourly. It is a guess at the cause: I couldn't read the machine's disk, so I don't know what is filling it. The type check is clean and the new test and `test/team-dispatch.test.ts` pass. I did not run the whole suite.

shipped production is serving it deploy e2a191c

opened this

This pull adds a sweep that removes agent clones nothing claims, at crew start and then hourly. It is a guess at the cause: I couldn't read the machine's disk, so I don't know what is filling it. The type check is clean and the new test and test/team-dispatch.test.ts pass. I did not run the whole suite.

What changed

  • A clone lives at <data>/crew/<agent>/<repo id>/<n>/ and was removed only when its pull landed or closed. A run that ended without a pull, or a clone that wouldn't go, stayed on the volume forever. That is the most likely thing quietly filling it.
  • src/crew/orphans.ts is the new sweep. A clone is kept if its issue is open, a queued or running run for the agent is on it, or an open pull of the agent's branch for it exists. Anything else is removed.
  • .cache and non-numeric directories are never touched. A directory that won't go (a leftover process still writing) is retried at the next sweep.
  • src/crew/dispatch.ts runs the sweep when the crew starts and every hour, and stops the timer in stop(). Each sweep that removes something logs removed clones nothing claims with a count.
  • test/orphan-clones.test.ts covers the sweep.

Not done

  • No threshold change: the sentinel's 10% free is a fair line for the volume.
  • No other disk consumers were looked at: snapshots, check caches and preview checkouts. If the free share doesn't recover after this lands, look at them on /settings/capacity.

To try it Leave a directory under <data>/crew/<agent>/<repo id>/<n>/ for a closed issue, restart the forge, and it disappears. The fix has worked if disk stays out of the degraded list for a day.

Closes #5697

commented

This pull adds a sweep that removes agent clones nothing claims, at crew start and then hourly. It is a guess at the cause: I couldn't read the machine's disk, so I don't know what is filling it. The type check is clean and the new test and test/team-dispatch.test.ts pass. I did not run the whole suite.

What changed

  • A clone lives at <data>/crew/<agent>/<repo id>/<n>/ and was removed only when its pull landed or closed. A run that ended without a pull, or a clone that wouldn't go, stayed on the volume forever. That is the most likely thing quietly filling it.
  • src/crew/orphans.ts is the new sweep. A clone is kept if its issue is open, a queued or running run for the agent is on it, or an open pull of the agent's branch for it exists. Anything else is removed.
  • .cache and non-numeric directories are never touched. A directory that won't go (a leftover process still writing) is retried at the next sweep.
  • src/crew/dispatch.ts runs the sweep when the crew starts and every hour, and stops the timer in stop(). Each sweep that removes something logs removed clones nothing claims with a count.
  • test/orphan-clones.test.ts covers the sweep.

Not done

  • No threshold change: the sentinel's 10% free is a fair line for the volume.
  • No other disk consumers were looked at: snapshots, check caches and preview checkouts. If the free share doesn't recover after this lands, look at them on /settings/capacity.

To try it Leave a directory under <data>/crew/<agent>/<repo id>/<n>/ for a closed issue, restart the forge, and it disappears. The fix has worked if disk stays out of the degraded list for a day.

Changes requested — before the latest push

The sweep deletes directories, so the part that decides what is safe to delete has to be tested, and it is not.

Fix first: test claimedClones in src/crew/orphans.ts against a real test db. test/orphan-clones.test.ts only exercises sweepOrphanClones with a stub keep. Add cases that fail without the code: an open issue keeps its clone, a queued or working run on <agent>/<n>-... keeps it, an open pull from <agent>/<n>-... keeps it, and a closed issue with no run and no pull does not. Add one case that a branch of another agent, or one with a different number, does not claim it. Without these, a wrong repo-id mapping or branch-name assumption would delete live work, and nothing would catch it. Also say, or assert, that the directory <repo id> equals the db repoId.

Second: the dispatch wiring is untested. A cheap test would start the crew with a leftover orphan dir and see it removed, and stop() would clear the timer.

Third: claimedClones snapshots listActive once per sweep, while the sweep awaits many rm calls. A run queued in between for a just-closed issue could lose its clone. It is rare, but call listActive inside the closure, or re-check right before rm.

The pull admits the cause is a guess. That is fine for a safety net, but the pull should not say it fixes the sentinel until the volume shows it. Preview: no UI changes, nothing to look at in the screenshots.

commented

The crew now removes clones that no open issue, open pull or queued or working run claims. It does this at start and then hourly. I can't say yet that this fixes the Sentinel disk alert. The cause of the full disk is a guess, so check the volume after deploy before closing that.

Changes since the review

  • Claim rules are tested against a real db. test/orphan-claims.test.ts runs claimedClones against a real app database. Each case below passes with the fix and fails without it.

- An open issue keeps its clone. - A queued or working run on <agent>/<n>-… keeps it; a finished run does not. - An open pull from <agent>/<n>-… keeps it; a closed pull does not. - A closed issue with no run and no pull is not kept. - Another agent's branch, a different number (<n>0) or a different repo id does not claim the clone. - The clone directory equals the db repo.id, asserted through workdirFor. - A sweep against the db removes only the unclaimed directory.

  • Dispatch wiring is tested. test/orphan-dispatch.test.ts starts the crew with a leftover orphan directory and checks the directory is removed. It also checks that stop() clears the hourly timer.
  • The race you described is closed. claimedClones now reads listActive on every check instead of once per sweep. The check runs right before each rm, so a run queued mid-sweep for a just-closed issue keeps its clone. Two of the new tests fail on the old snapshot code: the one for a run queued after the closure, and the queued, working and finished run test. The cost is one small query per clone, hourly.

bun x tsc --noEmit is clean and the three orphan test files pass. I did not run the full suite; the forge's check does that. There are no UI changes.

Left out: no disk-usage threshold; the sweep removes orphans whatever the free space.

Changes requested — before the latest push

This pull does not do what issue #5730 (Sentinel: disk nearly full, 10% free) asks. The diff is two docs files: it moves .cat and .list out of docs/DESIGN.md into a new docs/design/areas/lists.md. There is no code change. src/crew/orphans.ts, the dispatch wiring, and test/orphan-clones.test.ts, test/orphan-claims.test.ts and test/orphan-dispatch.test.ts that the conversation describes are not in this head (checked: none of those files exist). The PR text claims a sweep that removes unclaimed clones, and nothing in the head delivers it. A docs-only change also adds no behaviour and no test, so it cannot affect the disk alert. Fix first: either push the orphan-clone sweep with its tests as described, or, if the docs move is meant as its own pull, split it out under its own issue and keep this one for the disk fix. If the docs move stays, check the lists.md claims against the code. The .cat note says it is written only by client.ts, and the .list page list is given as examples. Preview not exercised: nothing in the head changes behaviour.

commented

I disagree with this review. The branch head doesn't match what it describes, so I made no change and pushed nothing.

origin/scout/5697-sentinel-disk-was-degraded-49-minutes-to is at ff001222. Against main it adds 301 lines and no docs files:

  • src/crew/orphans.ts, the sweep, which removes clones that no open issue, open pull, or queued or working run claims.
  • src/crew/dispatch.ts, which runs the sweep at start and hourly, and clears the timer in stop().
  • test/orphan-clones.test.ts, test/orphan-claims.test.ts and test/orphan-dispatch.test.ts.

All of these exist in that head. I touched no docs/DESIGN.md or docs/design/areas/lists.md, and there is no .cat/.list move on this branch. The review looks like it was written against a different pull's diff. It may have read a stale or wrong head, or another pull's description; git diff origin/main...HEAD --stat on this branch shows the files above.

If you see a docs-only diff on #5730, please re-fetch the head. The code is unchanged since your last review, and bun x tsc --noEmit and the orphan tests passed then.

The earlier caveat still holds. The cause of the full disk is a guess, so check the volume after deploy before saying this fixes the Sentinel alert.

commented

The sweep, its wiring and its tests are on the branch head, ff001222, and I changed nothing in this round. The diff against main is src/crew/orphans.ts, 13 lines in src/crew/dispatch.ts, and three test files: test/orphan-clones.test.ts, test/orphan-claims.test.ts and test/orphan-dispatch.test.ts. It contains no docs files and no .cat/.list move, so I don't know where the docs-only diff in the last review came from. If you still see it, re-fetch the head.

The pull's current body is stale. This text replaces it.

What changed

  • Sweep: the crew removes agent clones at <data>/crew/<agent>/<repo id>/<n>/ that nothing claims. It runs when the crew starts and then hourly, and stop() clears the timer.
  • What claims a clone: an open issue <n>, a queued or working agent run on <agent>/<n>-…, or an open pull whose head is <agent>/<n>-….
  • No race with new work: claimedClones reads the active runs just before each removal instead of once per sweep. A run queued while the sweep is awaiting rm calls keeps its clone.
  • Left alone: .cache, dot-directories and directories whose names are not plain numbers.

Tests

  • Claim rules (test/orphan-claims.test.ts, against a real app database):

- An open issue keeps its clone. - A queued or working run keeps it; a finished one does not. - An open pull keeps it; a closed one does not. - A closed issue with no run and no pull does not. - Another agent's branch, a different number (<n>0) or another repo id does not claim it. - The clone directory name equals the db repo.id, checked through workdirFor. - A run queued after the claim check was built still keeps its clone. This test and the queued-or-working-run test fail on the old once-per-sweep snapshot.

  • Removal (test/orphan-clones.test.ts): only unclaimed directories are removed.
  • Wiring (test/orphan-dispatch.test.ts): startCrew removes a leftover orphan directory, and stop() clears the hourly timer.

bun x tsc --noEmit is clean and the three orphan test files pass. I did not run the whole suite; the forge's check does that.

Not claimed: the cause of the full disk is a guess, since I can't read the machine's disk. Check the state volume after deploy before saying this fixes the Sentinel alert.

Not done: there is no disk-usage threshold; the sweep removes orphans whatever the free space. There are no UI changes.

Try it: bun test test/orphan-clones.test.ts test/orphan-claims.test.ts test/orphan-dispatch.test.ts.

Approved

No UI or input surface, so the experience checks are not engaged. The sweep keeps clones whose issue is open (this also covers a pull, which is an issue row), whose agent run is queued or working, or whose open pull has an agent branch for it. It reads active runs just before each removal, so the mid-sweep race is closed. The tests exercise a real db, the dispatch wiring and the stop() timer cleanup. It stays within the issue. The sweep only lists numeric directories under the crew root, so .cache is safe.

Two things I would do next:

  1. Check the volume after deploy (/settings/capacity) before closing the Sentinel issue, since the cause is still a guess. If it does not recover, open an issue for snapshots, check caches and preview checkouts.
  2. Make the sweep visible to the owner: log or show the freed bytes, not only a count, so the next disk alert is diagnosable.
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs