Skip to content

thirdshift architect base <branch>: an Architect run names its Base branch - #256

Merged
JacobStephens2 merged 3 commits into
issue-237from
issue-246
Oct 1, 2026
Merged

JacobStephens2 merged 3 commits into
issue-237from
issue-246

Conversation

@JacobStephens2

Copy link
Copy Markdown
Owner

Summary

thirdshift architect base <branch> (or --base <branch>) names the Base branch of an Architect run, so the branch checked out in the Launch directory stops mattering.

 architect(args)
-  architect::run(focus)
-    base = checked-out branch, else "HEAD is detached"
+  architect::run(focus, args.base)
+    base = args.base, else checked-out branch, else "HEAD is detached"
     preflight::check_base_branch(base)          # on origin, local copy not ahead
-    launch pull of base
+    launch pull, only if base is the branch checked out
     ReviewWorktree at origin/<base>
-    -> PlanReady(plan)
+    -> PlanReady { plan, base }
-  run::run_to_end(plan, child: None)             # Base branch = checked-out branch
+  run::run_to_end(plan, StartedBy::ArchitectRun { base })
+    Issue branch / Spec branch off origin/<base>, pull request / Spec PR into <base>

run_to_end now takes what started the Run in place of child: Option<&Kind>:

pub enum StartedBy<'a> {
    Command,                      // thirdshift <Issue URL>: the checked-out branch
    ArchitectRun { base: &'a str }, // dispatching its plan: the Architect run's Base branch
    Child(&'a Kind),              // a Ticket's Run or a Base fix: the branch it was given
}

base is parsed for architect only. thirdshift <Issue URL> doesn't take it, and no hidden argument was added: the dispatch is in-process.

Seams tested: the argument parser (args::parse, unit tests) and the thirdshift binary end to end (tests/architect_run.rs, tests/command_surface.rs, with the fake claude and gh).

Evidence

  • Before: the review ran at the checked-out branch's head, and the dispatched Run targeted it.
    base_starts_the_review_at_the_named_branchs_origin_head_whatever_is_checked_out
      left:  a11bb52… (origin/main)   right: 82b9c33… (origin/develop)
    base_carries_the_named_branch_to_the_dispatched_spec_run_whatever_is_checked_out
      left: "main"   right: "develop"          # the Spec PR's base
    
    After: cargo test passes: 28 test binaries, 0 failed; cargo clippy --all-targets and cargo fmt --check are clean.
    architect base develop [--plan-only], from main and from a detached HEAD, with an uncommitted change
      review worktree HEAD == origin/develop
      dispatched Run:      issue-8 off develop, PR base develop
      dispatched Spec run: Spec branch off develop, Spec PR base develop, Tickets merged into issue-8
    architect base nowhere            -> "base branch nowhere does not exist on origin; push it first"
    architect base develop (local +1) -> "local develop is 1 commit(s) ahead of origin/develop; push them first"
    launch.pull = true                -> checkout updated only when develop is checked out
    architect base | base --plan-only | base x base y -> exit 2
    
  • One full run, on a machine other sessions were loading (load average 7.5 on 4 cores), failed base_carries_the_named_branch_to_the_dispatched_spec_run_whatever_is_checked_out on its exit code. I didn't capture its stderr. It passed in the next full run and in 12 further runs of that test, so I couldn't find a cause.

Unaddressed findings

Standards

  • Possible Duplicated Code: the Base branch is resolved in both architect.rs and run.rs (symbolic-ref, given-or-checked-out, check_base_branch, launch pull). Skipped: a Run's resolution goes through Issue branch selection, where a Continuation's open pull request decides, and an Architect run's doesn't, so the shared part is two git calls.
  • Outcome::PlanReady carries the Base branch back to main.rs. Skipped: only a ready plan is dispatched, and it is the one outcome that needs the branch, so the variant is where it belongs; returning it beside every outcome would give idea outcomes a branch they don't use.
  • ask_base repeats ask_parallel's shape. Skipped: the reviewer judged it acceptable, and it follows the existing pattern.
  • Test setup: develop_on_origin(detached: bool) is a flag argument, and the develop setup is repeated in the Spec run and launch pull tests. Skipped: those tests build their scenario another way first (spec_plan, a checked-out develop), so the helper doesn't fit them without a second one.

Spec

  • The detached-HEAD message without base gained ", or name it with base ", against "thirdshift architect without base behaves as before". Skipped: the run is rejected as before, and the hint names the way out this Ticket adds. The duplicate test the reviewer pointed at was folded into the existing one.
  • base followed by an argument starting with a dash, or a blank one, is an argument error too, where the Ticket only lists "nothing after it, or given twice". Skipped: no branch name starts with a dash, so architect base --plan-only is a typo, which story 18 says must not silently pick a branch.
  • Tests the Ticket didn't list (merge into the named branch, base rejected on a Run). Skipped: they pin "It is not added to thirdshift <Issue URL>" and cost little.

Merge Danger

Door: two-way

Reverting removes the flag; nothing is stored or migrated.

Blast Radius: Runs

Every Run now goes through StartedBy, and a Ticket's Run or a Base fix reads the real checked-out branch where it used to read the branch it was given, which only feeds launch pull, off for child Runs. The detached-HEAD message of thirdshift architect and the progress line of a Continuation whose pull request's base replaces a given branch (not the given <branch>) changed wording.

Closes #246

🤖 Generated with Claude Code

JacobStephens2 and others added 3 commits October 1, 2026 09:08
…ranch

base <branch> (or --base <branch>) on architect names the Base branch,
whatever the Launch directory has checked out: the Architecture review's
worktree starts at its origin head, and the Spec run or Run the plan is
dispatched as takes it as its Base branch, as an internal parameter of the
dispatch. The detached-HEAD check is skipped when it is given, and launch
pull only updates the checkout when the named branch is the one checked out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…h its PR replaces was given or checked out, exact errors for base on a Run, the test module's doc in order

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The plan an Architecture review marked ready carries the Architect run's
Base branch inside the Reviewed outcome, next to the skipped one, and a
run that names its Base branch takes the repository's lock once the
checks on that branch pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant