Repository navigation
The Run owns its start, tested in-process behind a seam (#388) - #389
Merged
Merged
Conversation
The Run's start, from the Tickets read to the Claim ended, runs generic over a private seam, with a production adapter over the opened Launch directory, GitHub, Issue branch selection, the logs, the Claim, the worktree, the Spec run and the Delivery, and a scripted fake. Each rule has a unit test, and the end-to-end tests that only checked one of them through a whole Run are gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Name the worktree's checkout a Continuation as CONTEXT.md does, pick it and the prompt in one match, assert the start's calls by their order rather than their positions, and leave the kept end-to-end tests where they were. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The Run's start, from the Tickets read to the Claim ended, now runs in the Run module's own code. It is generic over a private seam,
run::Outside. The Launch directory is opened before the seam, and the production adapter is built from it.run_to_end BaseFix::new run LaunchDirectory::open_for_run # Origin match, open issue, git identity + LaunchAndGitHub { directory, Logs::of_run, claim: None, .. } + start(outside, issue, asks, started_by, directory.checked_out()) - github::tickets / logs::started / branch::select / base_branch / pull - interrupt::requested / claim::make / Logs::of_run / Delivery + outside.tickets unless a child Run + outside.started as a Run or a Spec run + refuse parallel on an issue with no sub-issues + outside.select + refuse all closed on a fresh selection + selection.pr_base(given, checked_out, |line| outside.step(line)) + outside.base_branch / outside.pull + outside.interrupted -> FailedRun { interrupted: true } + outside.make_claim unless a child Run + outside.worktree(Fresh | Continuation, branch, base) + outside.spec_run | outside.deliver(fresh or continuation prompt) + outside.end_claim(goal reached, or none)The worktree. It is the seam's associated type. In production it is a real
Worktree. In the fake it is theCheckoutit was created by, so the hand-off is tested without git.The Claim. The production adapter makes the Claim and keeps it. The rules decide whether a Claim is made and with which goal it is ended.
The Session logs. They are built when the adapter is built, so no unit test needs the process-wide logs.
Issue branch selection.
Selection::pr_basenow always takes the progress line as a callback. The variant that wrote straight to the progress lines had no callers left, so it is gone.The tests. 25 unit tests in
src/run.rscover what started the Run, the work recorded as started, the refusals, the Base branch, the pull, the interrupt, the Claim and the hand-off. Seven end-to-end tests that each checked only one of those rules are removed:tests/continuation.rs: the two continuation prompts, and the checked-out Base branch without an open PR;tests/spec_run.rs:parallelon an issue with no sub-issues, every Ticket closed with no Spec branch, and an issue with no sub-issues being an ordinary Run.The end-to-end tests for each wiring path stay. They cover the preflight refusals changing no label, the Claim being made before the worktree, a Claim that can't be made, the fresh prompt in a sibling worktree, an open PR's base whatever is checked out or on a detached HEAD, and the pull.
Evidence
Before: the order of the start had no unit test. It could only be checked by driving the binary against the fake
gh,gitandclaude.After:
cargo test --bin thirdshift run::passes. One of the new tests, for example:The full
cargo testrun passes: 961 tests, 0 failed.cargo clippy --all-targetsreports no warnings, andcargo fmt --checkis clean.Merge Danger
Door: two-way
The interface of the Run module is unchanged, and the seam is private. Seen from the command line, nothing changes: the requests, git effects, progress lines, logs, refusals and outcomes are the same.
Blast Radius: every Run
Every Command that does work goes through this start: a Run, a Spec run, and an Architect run's or a Pickup run's dispatch. A mistake in the order of the steps would show up there, for example a Claim made before a refusal. The remaining end-to-end tests check the wiring for each of these paths.
Unaddressed findings
Standards
LaunchAndGitHubhas 13 methods, most of them one-line pass-throughs. These are the 12 methods the spec listed, plus ending the Claim, and the sibling seams look the same.startguards on aclaimsbool, and the adapter also holds anOption<Claim>. The bool is the rule under test. TheOptionis where the adapter keeps the Claim it made, which the spec asks for.baseis passed on each call. It goes toworktree,spec_runanddeliverrather than being kept in the adapter. The rules settle the Base branch, so it can't be a field of the adapter, which is built before it is settled.start<O: Outside>instead ofimpl Outside.delivery.rsuses the same generic form, andstart_in_worktreenamesOtoo.Failsenum. Here each failure is a single step with nothing to share, so the bools read more plainly.start_by,run_onandrun_askedoverlap. Each is a shorter call for the most common case.Selection::pr_basenow requires the line callback. It has one production caller.Spec
pr_basechanged. The spec says to use the existing callback variant. Keeping the old wrapper would have left dead code that clippy warns about.Closes #388
🤖 Generated with Claude Code