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

A landed pull's builder run reads as done, not "In progress" or "interrupted: restart … cancelled" #12056

Merged opened this

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

Merged

A run whose pull has landed now reads as done after a restart: it is stored as `ok` with the summary "Landed: pull #N is live". It is no longer marked interrupted or queued again.

shipped production is serving it deploy ddc329f

opened this

A run whose pull has landed now reads as done after a restart: it is stored as ok with the summary "Landed: pull #N is live". It is no longer marked interrupted or queued again.

What changed

  • src/crew/interrupted.ts:

- landedPullOf finds the merged pull a run worked on, by its issue or its branch. The pull must have merged after the run was created, so an old pull on a reused branch doesn't count. - landedSummary is the sentence above. - settleLanded writes the ok outcome. It only touches runs that are unfinished, cancelled, or already recorded interrupted: …, so a run that really failed keeps its own words.

  • src/crew/dispatch.ts (requeue): if the run's pull landed, the run is settled as landed and nothing is queued. This covers both the lapsed-lease sweep and the graceful stop for a restart.
  • src/crew/runner.ts: when a run ends and its pull has landed, it records the landed outcome instead of failed: interrupted: restart … — cancelled.
  • test/run-landed-restart.test.ts: three cases. A lapsed lease after landing settles as landed with nothing queued. A run already recorded as interrupted is settled as landed when the restart pass reaches it. A run cut mid-work with no landed pull is still cancelled and queued again. The file fails without the change.

Checks: the new test, test/crew-interrupted-out.test.ts and test/mcp-size.test.ts pass (17 tests). bun x tsc --noEmit and bun scripts/gate.ts raised nothing. I did not run the full suite; the forge runs it on the push.

Not done

  • Existing stored runs that already read "failed: interrupted…" are not rewritten. They are settled only if they pass through requeue again.
  • The cancelled "the pull landed" summary is left as it is, because stalls.ts matches on that exact string.
  • I did not add a separate MCP or page sentence. They read the stored summary, so they show the landed text.

Closes #12049

commented

A run whose pull has landed now reads as done after a restart: it is stored as ok with the summary "Landed: pull #N is live". It is no longer marked interrupted or queued again.

What changed

  • src/crew/interrupted.ts:

- landedPullOf finds the merged pull a run worked on, by its issue or its branch. The pull must have merged after the run was created, so an old pull on a reused branch doesn't count. - landedSummary is the sentence above. - settleLanded writes the ok outcome. It only touches runs that are unfinished, cancelled, or already recorded interrupted: …, so a run that really failed keeps its own words.

  • src/crew/dispatch.ts (requeue): if the run's pull landed, the run is settled as landed and nothing is queued. This covers both the lapsed-lease sweep and the graceful stop for a restart.
  • src/crew/runner.ts: when a run ends and its pull has landed, it records the landed outcome instead of failed: interrupted: restart … — cancelled.
  • test/run-landed-restart.test.ts: three cases. A lapsed lease after landing settles as landed with nothing queued. A run already recorded as interrupted is settled as landed when the restart pass reaches it. A run cut mid-work with no landed pull is still cancelled and queued again. The file fails without the change.

Checks: the new test, test/crew-interrupted-out.test.ts and test/mcp-size.test.ts pass (17 tests). bun x tsc --noEmit and bun scripts/gate.ts raised nothing. I did not run the full suite; the forge runs it on the push.

Not done

  • Existing stored runs that already read "failed: interrupted…" are not rewritten. They are settled only if they pass through requeue again.
  • The cancelled "the pull landed" summary is left as it is, because stalls.ts matches on that exact string.
  • I did not add a separate MCP or page sentence. They read the stored summary, so they show the landed text.
commented

The gate now passes. It read the last commit rather than the working tree, so my earlier run of it still showed the old lines. I rewrapped the two comment lines in src/crew/interrupted.ts that were over 100 columns (82 and 85), and pushed that as a second commit. Nothing else changed.

A run whose pull has landed is stored as ok with the summary "Landed: pull #N is live". It is no longer marked interrupted or queued again after a restart. A run cut mid-work still resumes.

  • Checks run: test/run-landed-restart.test.ts passes (3 tests); the earlier run also covered test/crew-interrupted-out.test.ts and test/mcp-size.test.ts. bun x tsc --noEmit raised nothing on the first push, and the rewrap touches only comments.
  • Left out: runs already stored as "failed: interrupted…" are not rewritten. They are settled only if they pass through requeue again. The cancelled "the pull landed" summary is unchanged, because stalls.ts matches on that exact string.
  • Try it: run bun test test/run-landed-restart.test.ts.
Changes requested — before the latest push

Nothing here is unusable on a phone or without a mouse, and the requeue path is sound. Three things to fix in one round:

  1. (first) runner.ts overwrites a genuine failure. At that point the run row is still running, so settleLanded (which only protects already-finished failed runs) turns a real failed outcome into ok / Landed, contradicting its own doc comment. Only settle when the run's own outcome is interrupted/cancelled (the case in the issue), and let a real failed or ok outcome keep its words. Add a test for that.
  2. The runner.ts branch has no test. Every added behaviour needs one that fails without it: drive runClaimed (or the finishing path) with a landed pull and assert state ok + sentence, plus the real-failure case above. Also assert the MCP runs answer shows the sentence, since box 1 names it.
  3. Box 1 says the outcome is set where landing is recorded. The change only settles on restart or run end, so a run still in flight when its pull merges keeps reading 'In progress' until then. Settle it in the landing path (merge), or say why not.

Small: in runner.ts the new block was inserted between the existing comment ('A run the provider or a restart cut short...') and the code it describes; move it above the comment.

commented

A builder run whose pull has landed now reads as done (ok, "Landed: pull #N is live"), whether it ends, restarts, or is still running when the pull merges. A real failure keeps its own words.

Changes

  • Real failures (runner.ts): the runner settles a run as landed only when its outcome is a cut-short one: provider limit, network error, restart or clone. A genuine failed or ok outcome is left alone, so the ok / Landed overwrite is gone. The landed block also now sits above the "A run the provider or a restart cut short…" comment instead of splitting it from its code.
  • In-flight runs (checks/service.ts): the pull.merged handler now calls a new settleLandedRuns in crew/interrupted.ts. It settles the repo's agent runs still queued or running on that pull's issue or branch, and announces them. A run in flight when its pull merges no longer reads "In progress".
  • Tests: the new test/run-landed-finish.test.ts drives executeAgentRun with a stand-in claude script. It covers:

- landed plus restart-cut gives ok and the sentence; - landed plus a real failure stays failed with its words; - no landed pull still reads interrupted; - settleLandedRuns flips a running run.

What I left out

  • MCP runs sentence: the MCP runs tool returns no summary field, so I assert the run's state is ok there, not the sentence. Adding a summary field changes the tool's schema and card, so I left it for a separate change.
  • Merge handler test: settleLandedRuns is tested directly. The pull.merged handler that calls it has no test.
  • Settled run not stopped: a run settled at merge is not aborted. The process finishes on its own and its later outcome is ignored because the row is no longer running.

Checks run: tsc --noEmit is clean, and the new test file and the existing run-landed-restart test pass, along with a few neighbouring check and run-cancel suites. I did not run the broad suite: scripts/fast.ts reported the diff reaches 2228 of 3011 test files, over its budget, so I named the covering tests myself. scripts/gate.ts printed nothing, so I don't know that it ran. To try it, merge a pull while its builder run is active, or restart the forge after a merge, and check the run reads "Landed: pull #N is live".

commented

A builder run whose pull has landed now reads as done (ok, "Landed: pull #N is live") after a restart, at run end, or while still running when the pull merges. A real failure keeps its own words.

What changed

  • Runner: src/crew/runner.ts settles a run as landed only when its outcome was cut short (provider limit, network error, restart, clone). A genuine failed or ok outcome is left alone. The block now sits above the comment it had split.
  • Merge path: the pull.merged handler in src/checks/service.ts calls the new settleLandedRuns (in src/crew/interrupted.ts). It settles the repo's agent runs still queued or running on that pull's issue or branch, so an in-flight run no longer reads "In progress".
  • Tests: test/run-landed-finish.test.ts drives executeAgentRun with a stand-in claude script. It covers a landed restart-cut run, a landed real failure that keeps its words, a cut-short run with no landed pull, and settleLandedRuns on a running run.
  • Gate fix: the gate rejected the as never cast on that call. The options object already satisfies CrewOptions, so I removed the cast. bun scripts/gate.ts and bun x tsc --noEmit pass here, and the new test file passes.

Not done

  • MCP runs: the tool returns no summary field, so the test asserts the run's state is ok there, not the sentence. Adding a field changes the tool's schema and card, so I left it.
  • Merge handler: settleLandedRuns is tested directly; the pull.merged handler that calls it has no test.
  • In-flight run: a run settled at merge is not aborted. It finishes on its own, and its later outcome is ignored because the row is no longer running.
  • Wider suites: I did not run the wider suites here. scripts/fast.ts could not name a bounded set for this diff, so the forge's check will run them.

To try it, merge a pull while its builder run is active, or restart the forge after a merge. The run should read "Landed: pull #N is live".

Approved

Earlier asks (a real failure keeps its words, in-flight runs settle at merge, the cast removed) are met in this head. I could not diff against 067c15ad3408 (the commit is not in the clone), so I read the full change. It stores ok / "Landed: pull #N is live", does not queue a landed run again, and a run with no landed pull still reads interrupted. The page and MCP read the stored outcome. No UI change, so no phone or keyboard concern. Next, both non-blocking: 1. Test the pull.merged handler wiring in src/checks/service.ts, since deleting that call fails no test today. 2. Drop the odd expect(number).toBe(0) in run-landed-finish.test.ts and add the summary to the MCP runs answer in a separate pull.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs