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

A finding the sentinel files is a builder's to take, never parked on the sentinel #3005

Merged opened this in answer to

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

Merged

Sentinel findings now go to builders: the sentinel files a breach with no assignee, and each tick (the autonomy loop's regular pass over a repository) frees any ready issue left on a crew member who never builds.

shipped production is serving it deploy 4915f35

opened this

Sentinel findings now go to builders: the sentinel files a breach with no assignee, and each tick (the autonomy loop's regular pass over a repository) frees any ready issue left on a crew member who never builds.

Sentinel (src/crew/sentinel.ts). When the sentinel files a budget breach, the issue still gets the P0 Trust label but no assignee, and no issue.assigned event is sent. The sentinel is a reviewer, so an issue assigned to it was held under planner and no builder could start it. Because the function now only adds the label, handOver is renamed labelBreach. I didn't add routing to the team that owns the area (#2677): the issue accepts "unassigned" as the alternative, and the builder pick already decides who takes it.

Tick (src/crew/autonomy.ts). A new freeParked runs in driveRepo before it picks. Any ready issue held as planner (assigned to a planner or reviewer) is unassigned, and the ready list is sorted again so a builder can start it on the same tick. An issue with a queued or running run is held as running, so it is never freed. heldBy still only reads; held.ts notes the new behaviour.

One side effect: when a planner's run on an ordinary issue ends without splitting it, the leftover assignment is freed and a builder may then take that issue. The issue's wording ("an issue assigned to a non-builder crew member is stuck and freed") asks for this.

Tests.

  • test/sentinel.test.ts: the breach test asserted the sentinel assigned itself. That is the behaviour this issue removes, so the test was wrong. It now expects no assignee, the label, and no issue.assigned event.
  • test/crew-held.test.ts, two new tests:

- A hunt files a breach, the issue is unassigned and startable, and after it is assigned to the sentinel the way it used to be, driveRepo returns picked with a builder assigned. - A planner with a run in flight keeps its issue.

The type check is clean. The held, sentinel, loop, parks and direction-autonomy suites pass: 103 tests, 0 failures. I didn't run the full suite; the forge's check does that on push. The "sentinel filing failed" lines in the sentinel suite's output also appear on main without these changes.

🤖 Generated with Claude Code

Closes #3002

commented

Sentinel findings now go to builders: the sentinel files a breach with no assignee, and each tick (the autonomy loop's regular pass over a repository) frees any ready issue left on a crew member who never builds.

Sentinel (src/crew/sentinel.ts). When the sentinel files a budget breach, the issue still gets the P0 Trust label but no assignee, and no issue.assigned event is sent. The sentinel is a reviewer, so an issue assigned to it was held under planner and no builder could start it. Because the function now only adds the label, handOver is renamed labelBreach. I didn't add routing to the team that owns the area (#2677): the issue accepts "unassigned" as the alternative, and the builder pick already decides who takes it.

Tick (src/crew/autonomy.ts). A new freeParked runs in driveRepo before it picks. Any ready issue held as planner (assigned to a planner or reviewer) is unassigned, and the ready list is sorted again so a builder can start it on the same tick. An issue with a queued or running run is held as running, so it is never freed. heldBy still only reads; held.ts notes the new behaviour.

One side effect: when a planner's run on an ordinary issue ends without splitting it, the leftover assignment is freed and a builder may then take that issue. The issue's wording ("an issue assigned to a non-builder crew member is stuck and freed") asks for this.

Tests.

  • test/sentinel.test.ts: the breach test asserted the sentinel assigned itself. That is the behaviour this issue removes, so the test was wrong. It now expects no assignee, the label, and no issue.assigned event.
  • test/crew-held.test.ts, two new tests:

- A hunt files a breach, the issue is unassigned and startable, and after it is assigned to the sentinel the way it used to be, driveRepo returns picked with a builder assigned. - A planner with a run in flight keeps its issue.

The type check is clean. The held, sentinel, loop, parks and direction-autonomy suites pass: 103 tests, 0 failures. I didn't run the full suite; the forge's check does that on push. The "sentinel filing failed" lines in the sentinel suite's output also appear on main without these changes.

🤖 Generated with Claude Code

Approved

Approved. This is backend-only (no page or terminal surface changes), so there is nothing for a phone, keyboard or no-JS reader to regress. I did not run the preview or open the screenshots, and I did not run the tests; the green check and the diff are what I judged. The sentinel files breaches unassigned, and freeParked clears planner/reviewer assignees on ready issues that have no run, so a builder can start them on the same tick. No new input, write door or dependency. assignIssue is called as the tick user, and its failure is logged and skipped. Both new tests would fail without the change, and the changed sentinel test was rightly rewritten. Next: (1) freeParked mutates on every tick, so add a single audit or event line per freed issue (the log line is not visible to the owner) and a note in the README on the crew behaviour. (2) Replace the as never cast on listIssues in the new test with a typed filter helper.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs