Public: anyone can read this; the crew can change it.
A twice-parked issue goes back to the planner with its reasons instead of silently dropping out #679
Check · Review · Land · Live done — Landed and live in production.
Closes #613
shipped production is serving it for issue #613 — its issue is already done deploy 4183511
The description, now that the work is done (the forge has no route to edit a pull's body).
What a person sees. An issue the crew parked twice is no longer dropped. The second park says every reason on the issue and hands it to the planner. The board lists it, above the regions, for whoever owns the app: the app, the issue, why, and one action, Open. It stays there until the issue is split, replaced or deferred, or a person says what to try.
What changed.
src/crew/parks.ts:parkedTwiceis the one list every surface reads: open, struck out, nobody on it, no open pull that would close it, waiting for nothing open.parkReasonsreads the reasons out of the park notes.src/crew/autonomy.ts: the second park's note carries every reason and the hand-over.planIfThinasks the planner once for a hand-over newer than its last pass, with a full map and after a declined direction.src/crew/brief.ts,src/crew/runner.ts: a planning run's task listsParked twice: #n, every reason, and the three states it may leave the issue in (split, replaced by a fresh issue, deferred behind the Later gate; dropped where a repository has no gate).src/crew/later.tsfinds the gate by its title.src/web/pages/board.ts: the rows join the strip #614 added for the planner's decline.src/web/pages/map.ts:parkedTwicein the map's data, soGET …/mapand the MCP'smapcarry it.
Two rules changed; please read these.
- Only a person's word resets the two strikes. Before, a planner's comment did, so an answer in words alone took the issue off the map's
parkedand back into dispatch as it was. (COUNTEDinparks.ts; the #463 test is updated.) - A planner may now close an issue it did not write, in exactly one case: an open issue the crew parked twice, as
splitordropped. Neverdone, never a pull, never a reopen, never on a mirror; builders and everyone else are refused as before. Without this the planner could not replace or split an issue the owner wrote. (handedToPlannerinsrc/actions/issues.ts; the refusing tests are intest/crew-parks.test.ts.)
What it removes. The dead end itself: parkedCount >= 2 no longer means nobody has it. The planner clause in the strike count. It adds one row kind and one link to an existing strip, and no screen.
Done means reachable.
- Page:
/board, the row above the regions. - MCP:
map→parkedTwice: [{ number, title, reasons }](alsoGET /api/v1/repos/:owner/:name/map). - Test:
test/crew-parks.test.ts(second park hands over; one pass owed; the brief; the board; the map and MCP; the grant and its refusals; a planning run through the stand-in agent carries the list). - Look: taken locally at phone and desktop widths, because the preview's own look is the signed-out front door and cannot show a signed-in board. The pictures are with the steward.
Not in this pull. A twice-parked issue is not an ask: it does not page the phone or count in the header. The strip keeps #614's declined id and class names.
🤖 Generated with Claude Code
Changes after the security review (this supersedes rule 2 in the description above).
The planner's grant is narrower. On an open issue the crew parked twice, the repository's planner may:
- close it as
split, only when every issue named inintois an open issue made since the hand-over (newer than the last park note), is not the issue itself and is not the Later gate. A closed issue or an older issue is refused, so a split cannot be a drop under another name. The blockers still move to the parts in the same action. - close it as
dropped, only when an agent wrote it. What a person asked for is dropped by a person; for a person's issue the planner's moves are split, replace, or defer behind the Later gate with the reasons in a comment.
Still never done, never a pull, never a reopen, never on a mirror, and only the planner on that repository. The planning run's task now says whose each issue is and offers dropping only for the crew's own.
Refusing tests, in test/crew-parks.test.ts, each also over the API with the planner's own token: dropping a person's issue; a split with no into; a split into a closed issue, an older issue, itself, the Later gate, and a good issue beside a bad one.
Known, and not fixed here. COUNTED in src/crew/parks.ts treats any non-agent's comment as a person's word, so a reader's comment on a public repository resets the two strikes. The crew-direction change (#694) brings mayDirectCrew; whichever of the two pulls lands second wires it into COUNTED. #694 is not on main yet, so it is not wired here.
🤖 Generated with Claude Code
Main merged in (head 34b4832): what changed in this pull since the last review
main now carries the rule for who directs the crew (#619, crew/direct.ts). This pull follows it, as agreed when the two crossed:
- Whose word starts the count again. A person who may direct the crew (
directorsAmong), never a reader, never a row imported from an origin. The planner's word still does not: it answers by splitting, replacing or deferring.parks.tsno longer has a rule of its own for this. - What counts as a park. A park note counts only when the crew wrote it: in the name of someone who directs the crew (as
parkIssuewrites it) or by one of the repository's own agents (as the breaker may). A comment that only reads like a park strikes nothing and hands nothing to the planner. New refusing test:a comment that only reads like a park. - An open pull that answers a handed-over issue is counted through
proposedWork, so only the crew's or a director's pull takes the issue off the planner's list. parkedCount,struckOut,handedOverAt,parkReasonstake the repository;parkedTwicetakes repositories and makes its count once per repository that has a candidate.
The planner's grant in actions/issues.ts is unchanged from the reviewed version.
Verified locally on this head: tsc clean; crew-parks, ledger, crew-direction, crew-direction-autonomy, autonomy, board, map, planner-declined, mcp, issues, and the five merge-collision files: 370 pass, 0 fail.
🤖 Generated with Claude Code
Round 4: the author rule (closes #724)
Closes #724. (The pull's body cannot be edited through the API, so #724 needs closing by hand when this merges.)
An author's say over their own issue is now a person's (setIssueState, ownSay). An agent closes an issue by landing a pull for it, or by the planner's grant on a handed-over issue, and reopens none. So the issue a planner opens to replace a person's ask is not the planner's to close, and the ask cannot be lost that way.
Checked first: no crew flow relied on an agent closing its own issue. Parks and autonomy act as the person who set the crew to work; the audit probe acts as the repository's owner when that is a person; fleet operations take a person.
New refusing test in test/crew-parks.test.ts: "refused: an agent's own issue is not its own to close or reopen — what the planner opened to replace a person's ask stays". The planner opens X, splits a person's handed-over ask into X (allowed), then cannot close X (no reason, done, dropped) by the action or over the API with its own token, and cannot reopen it once a person closed it; a builder cannot close or reopen an issue it wrote. The test failed before the fix. A person's own issue stays theirs to close and reopen, writer or not (asserted in "a comment that only reads like a park").
🤖 Generated with Claude Code
Round 5: a person's ask split into the crew's issue is still the person's
standsForPerson (core/issues.ts) follows the split chain through the issue.closed events: an issue stands for a person's ask when a person wrote it, or when it was named in the into of a split that closed an issue a person's ask stood in, however many splits ago. The planner's grant drops only what no person's ask stands in; split stays open. The board's hand-over list and the planner's brief call such an issue a person's ask, not the crew's own.
Refusing test, test/crew-parks.test.ts: "refused: a person's ask split into the crew's issue is still the person's — parked twice, it is split again, never dropped". It failed before the fix.
🤖 Generated with Claude Code
Closes #613
In progress (steward build team). First commit only reads the park notes; the hand-over, the planner's brief, the board line and the map data follow on this branch.
🤖 Generated with Claude Code