Skip to content

Pass Base fix through an Architect run to its dispatched run - #251

Merged
JacobStephens2 merged 20 commits into
issue-27from
issue-234
Oct 1, 2026
Merged

JacobStephens2 merged 20 commits into
issue-27from
issue-234

Conversation

@JacobStephens2

Copy link
Copy Markdown
Owner

Summary

thirdshift architect now takes base-fix / no-base-fix (and their -- forms) and hands them, or the User config's base.fix, to the Spec run or Run its plan is dispatched as. The Architecture review watches no CI, so a Base fix can only start there.

 thirdshift architect [<focus>] [flags]
   Architecture review  ->  plan marked ready-for-agent
   dispatch the plan, as thirdshift <plan URL> would
     goal      = merge | no-merge      else merge.always
     parallel  = parallel <n>          else spec.parallel
+    base fix  = base-fix | no-base-fix else base.fix
+  last lines and the one Run notification carry "Base fix: <issue URL> merged"

 thirdshift architect --plan-only
-  rejects merge, no-merge, parallel
+  rejects merge, no-merge, parallel, base-fix, no-base-fix   (nothing is dispatched)

A Run and an Architect run's dispatched run now end through one place, so "as thirdshift <plan URL> would" isn't kept true by hand twice:

 main / architect
-  BaseFix::new -> run::run(.., &mut base_fix) -> base_fix.report()   # in both
-  run_outcome(&ended, base_fix) ; notification.send(&ended, base_fix)
+  run::run_to_end(.., child, BaseFixAsk) -> run::Ended { outcome, base_fix }
+  run_outcome(&ended) ; notification.send(&ended)

This PR also merges main into the Spec branch's line. The ticket is blocked by #221 (the Base fix), which merged to main but was not on issue-27. The first commit, 85c7939, merges origin/main in; that is most of the diff (the 17 commits of #226). The ticket's own work is the two commits after it:

85c7939  Merge origin/main into issue-234          # #221's Base fix; 5 files conflicted
f12e473  Pass Base fix through an Architect run    # the ticket
f2ac7a1  Address review                            # run::Ended, run_to_end, Spec run test

Merge resolutions worth a look:

  • tests/fakes/gh.rs: both sides added gh issue create. Kept main's, which refuses a label the repository lacks, as gh does, and added this branch's createdAt. The Architect run tests now give their repository needs-triage, ready-for-agent and architecture through a scenario() helper.
  • src/notification.rs: this branch's Ending gained main's base_fix, so an Architect run's notification has the Base fix: line a Run's has.
  • src/args.rs: kept this branch's ask_parallel helper for both parsers, with main's base-fix arms and child Run kinds.

Seams tested: the argument parser (unit tests in src/args.rs), and the thirdshift binary through tests/support::Scenario with the fake claude and gh (tests/architect_run.rs, tests/command_surface.rs).

Evidence

  • Before: architect base-fix, with the plan's Run meeting an Inherited failure (base_fix_lets_the_dispatched_run_start_a_base_fix, written first):
    thirdshift: dispatching the plan .../issues/8, as thirdshift .../issues/8 would
    thirdshift: CI failed on 0bc7f8e: test
    thirdshift: Inherited failures (also failing on main at ba3813f): test
    thirdshift: CI red on test, which also fails on main at ba3813f; fix main first
    test result: FAILED. 0 passed; 1 failed
    
    After: the dispatched Run starts Base fix CI watching, CI-fix Repair and the Repair cap #9 into main, merges the fixed main in and ends ready for review.
    cargo test --test architect_run base_fix
    test the_one_notification_says_what_became_of_the_dispatched_runs_base_fix ... ok
    test without_base_fix_the_dispatched_run_fails_on_an_inherited_failure ... ok
    test the_user_configs_base_fix_applies_to_the_dispatched_run_unless_no_base_fix_is_given ... ok
    test base_fix_lets_the_dispatched_run_start_a_base_fix ... ok
    test base_fix_or_the_user_configs_reaches_each_tickets_run_of_the_dispatched_spec_run ... ok
    test result: ok. 5 passed; 0 failed
    
  • Before: architect --plan-only base-fix took base-fix as the focus.
    After: exit 2: merge, no-merge, parallel, base-fix and no-base-fix can't be used with --plan-only: it dispatches no run for them to apply to. architect base-fix --no-base-fix: base-fix and no-base-fix can't be used together.
  • Full suite after the last commit: cargo test, 572 passed, 0 failed, across 28 test binaries. cargo clippy --all-targets and cargo fmt --check are clean.

Acceptance criteria:

  • base-fix and no-base-fix are accepted by architect and rejected together.
  • The flag, or the User config's base.fix, reaches the dispatched Spec run or Run.
  • base-fix or no-base-fix with --plan-only is rejected.
  • The README mentions it, as does thirdshift help.

Unaddressed findings

Reviewed with /thirdshift:code-review against issue-27. Addressed: the dispatch sequence duplicated between main and architect, the outcome-and-Base-fix pair travelling as a tuple, the Spec-publishing script re-inlined in a test, two unwrapped doc comments, and the User config default not being tested on a dispatched Spec run.

Standards

  • The base-fix / no-base-fix arms are repeated in parse and parse_architect. Skipped: the file already does this for merge and email, with ask_once as the shared part; the two arms differ only in where they store the ask, and a helper for them alone would break that pattern.
  • RED, GREEN, checks_on_head, checks_on_origin and inherited_failure copy helpers in tests/spec_run.rs. Skipped: each test file keeping its own small script helpers is the repository's habit (checks_on_head was already in three files), and moving them to tests/support is a change across test files this ticket doesn't own.
  • without_base_fix_the_dispatched_run_fails_on_an_inherited_failure repeats the assertions of the no-base-fix loop. Skipped: they pin different behaviors, the default with nothing set and the flag overriding base.fix = true; either could break without the other.

Spec

  • A Base fix for the dispatched Spec run's own Spec PR, into the Base branch, isn't tested through architect. Skipped: it takes the same BaseFixAsk through the same run::run_to_end as the Ticket case that is tested, and the Spec PR's Base fix itself is covered in tests/spec_run.rs.
  • The Base fix: line in the Architect run's last lines and notification goes beyond the ticket's literal criteria. Kept, and the reviewer didn't call it scope creep: Architect run: thirdshift finds and implements a Strong deepening opportunity unattended #27 has base-fix applied "as if given to thirdshift <plan URL>" and the dispatched run's notification suppressed, so without it the report would be lost.

Merge Danger

Door: two-way

Reverting the last two commits removes the flags. The merge of main is the part that is awkward to undo, but issue-27 has to take main in before #241 can merge anyway.

Blast Radius: Architect-runs

architect with neither flag and no base.fix behaves as before. With base.fix = true in the User config, an Architect run's dispatched run may now start a Base fix where it couldn't before, which is what the setting says. A word base-fix given to architect is no longer read as the focus.

Closes #234

🤖 Generated with Claude Code

JacobStephens2 and others added 20 commits October 1, 2026 01:28
A failed check that also failed, under the same name, on the Base branch
commit the head last merged in is an Inherited failure (ADR 0008). The CI
watcher now splits the failed checks into the branch's own and Inherited
ones. A CI-fix Repair is given only the branch's own, with the Inherited
ones listed as not to fix. When only Inherited failures are left, the Run
merges the Base branch again if it moved, and otherwise fails naming the
checks, the Base branch and its commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tively, test a still-red moved Base branch

A check is an Inherited failure only if every check of its name on the Base
branch commit failed. Commit statuses and a Base branch that moved but is
still red are now covered through the binary.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Inherited failures fail the Run without a Repair
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ks, name the child Run's kind

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A Base fix, when the base-fix flag is given
base.fix in the User config lets every Run start a Base fix with no flag;
no-base-fix forbids it for one Run, and contradicts base-fix. Setup asks
about Base fixes only with every Run a Merge run, and always writes the
setting.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… writes base.fix at its default with merging off, share the Spec run test setup

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Base fix in the User config and Setup
…ch directory at a time

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… left open, share the Launch directory lock

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
README.md: keep issue-221's wording that base-fix, no-base-fix or the User
config's base.fix holds for each Ticket's Run, with issue-224's shared Base
fix and its "One Base fix per Base branch" section.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…list and Run notification, share the check list and the Inherited failure cause

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Inherited failures: fail fast on a red Base branch, or fix it with a Base fix
…itect run passes on

An Architect run's dispatched run starts no Base fix yet. The fake gh's
issue create is main's, which refuses a label the repository lacks, now
also recording when the issue was created; the Architect run tests give
their repository the labels the fake agent publishes with.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
architect takes base-fix and no-base-fix, with their -- forms, rejects
the two together, and rejects either with --plan-only, which dispatches
nothing. Without either, the User config's base.fix decides. The run the
plan is dispatched as may then start a Base fix, and the Architect run's
last lines and its one Run notification say what became of it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…to its end, the User config default tested on a Spec run

run::Ended pairs a Run's or Spec run's outcome with what became of its
Base fix, and run::run_to_end is the one place that makes it, for a Run
and for the run an Architect run dispatches. The Spec run pass-through
test reuses spec_plan and also covers base.fix from the User config.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@JacobStephens2
JacobStephens2 merged commit 5bfb19d into issue-27 Oct 1, 2026
13 checks passed
@JacobStephens2
JacobStephens2 deleted the issue-234 branch October 1, 2026 04:13
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