Skip to content

Architect run: thirdshift finds and implements a Strong deepening opportunity unattended - #241

Merged
JacobStephens2 merged 23 commits into
mainfrom
issue-27
Oct 1, 2026
Merged

JacobStephens2 merged 23 commits into
mainfrom
issue-27

Conversation

@JacobStephens2

@JacobStephens2 JacobStephens2 commented Oct 1, 2026 •

Copy link
Copy Markdown
Owner

Summary

thirdshift architect [<focus>] [--plan-only] starts an Architect run: an Architecture review of the Base branch publishes its top recommendation as a plan, and thirdshift marks the plan ready and dispatches it as thirdshift <plan URL> would.

thirdshift architect [<focus>] [--plan-only] [merge|no-merge] [email|no-email] [parallel <n>] [base-fix|no-base-fix]
  preflight, without an Issue URL        # origin on GitHub, git identity, HEAD attached, Base branch not ahead
  launch pull, if the User config asks
  worktree <repo>-architect, detached at origin/<base>
  Architecture review session            # Factory skills, headless; commits and pushes nothing
  remove the worktree, whatever the outcome
  read the final line
    "Architecture review plan: <url>"
      check: in this repository, open, created during this Architect run, no other unready label
      swap needs-triage for ready-for-agent
      --plan-only   -> print the plan's URL, exit 0
      otherwise     -> Spec run (sub-issues) or Run, with merge / parallel / base-fix
                       the Architect run ends as that run does
    "Architecture review idea: <url>"           -> print it, exit 0, no label changed
    "Architecture review already filed: <url>"  -> print it, exit 0, nothing filed
    no such line, failed or interrupted session, plan fails a check
                                                -> exit 1, cause and session log; plan stays needs-triage
  one Run notification, if asked; the dispatched run sends none
skills/
├── improve-codebase-architecture/   # headless: scan, take the top recommendation, publish plan or idea
├── to-spec/                         # headless: no seam check with a user
├── to-tickets/                      # headless: Tickets with "blocked by" links
└── codebase-design/                 # the architecture vocabulary
src/
├── architect.rs      # the review, the final line, the plan's checks, the label swap
├── args.rs           # Command::Architect; RunFlags reads the flags a Run shares
├── main.rs           # dispatch, exit code, help
├── notification.rs   # ArchitectNotification: the review's outcome, then the dispatched run's
├── worktree.rs       # ReviewWorktree: detached, always removed
├── prompt.rs         # the Architecture review prompt and its three final lines
└── spec_run.rs       # needs-triage and ready-for-agent, one home
prompts/architecture-review.md, site/prompts/   # generated
tests/architect_run.rs                          # 49 end-to-end cases on the fake claude and gh

The last commit addresses the review of the Spec as a whole: one RunFlags in place of two copies of the flag match, ready-for-agent beside needs-triage, a Sender on the prompts page in place of an empty list of units, the README's steps in the order the code takes them, and the README and help saying that a review that finds no deepening opportunity fails the Architect run.

Evidence

  • Before: main has no architect command, no Architecture review prompt and no tests/architect_run.rs.
    After: cargo test at fded284: all 28 test targets pass, with 0 failures. tests/architect_run.rs: 49 passed. Unit tests: 94 passed, including the parser tests for architect and the prompts page snapshot, which the label constants and Sender left unchanged. cargo fmt --check and cargo clippy --all-targets are clean.
architect --plan-only, review publishes a Ticket   -> label swapped, URL on stdout, exit 0
architect, plan with sub-issues                    -> Spec run; ends with the Spec PR's URL
architect, single Ticket                           -> Run; ends with its PR's URL
review files an idea / names the covering issue    -> URL on stdout, exit 0, no label changed
review fails, is interrupted, or names no issue    -> exit 1, plan left needs-triage
plan closed / older than the run / other unready label / other repository -> refused
merge, parallel, base-fix, User config defaults    -> reach the dispatched run
email                                              -> exactly one Run notification, for every outcome

Merge Danger

Door: two-way

A new command and new Factory skills; a Run and a Spec run keep their behaviour. Reverting removes the command. Issues an Architect run has already published stay on the tracker.

Blast Radius: contained

The shared code it touches is the argument parser (a Run's flags now go through RunFlags), run::run_to_end, the Run notification body and the worktree helpers. main has since defined in CONTEXT.md, for a later Spec (#250), that an Architect run is skipped while another is running and that plans carry an architect-plan label. This branch does neither: its README says nothing stops a second Architect run.

Unaddressed findings

Standards

  • (reviewed, dispatched) matched in both main.rs and notification.rs (Repeated Switches): the two matches make different things, the exit code and stdout in one and the email in the other, and a type for an ended Architect run would move both matches, not remove either.
  • DispatchArgs and RunArgs share goal, parallel, base_fix, and main resolves their defaults twice (Data Clump): the parsing is now shared through RunFlags, but a child Run resolves its defaults differently from an Architect run's dispatch, so the two sites are left apart.
  • architect::run and run::run repeat the launch steps (Duplicated Code): the shared steps are already functions (check_identity, check_base_branch, pull_base_branch); what is left is a line or two each, and differs on a detached HEAD and a given Base branch.
  • architect::Report and Outcome are near twins: one is what the review claimed and the other what thirdshift checked; PlanReady is only true after the label swap.
  • launch() returns a tuple and architect::repo() reads origin again for the notification: one extra git config read, before any work, so the notification can name the repository even when preflight later fails.
  • A failed review is failed on the Review: line and review failed in the subject: deliberate and documented in the README; the line's label already says it is the review.
  • Test helpers repeated from other test files (checks_on_head, the_one_notification, …): each test file in this repo carries its own, and moving them to tests/support is a change across every file, not this Spec's.
  • "parent issue" in skills/to-tickets, which CONTEXT.md lists under Avoid: the Factory skills are kept close to the originals so they can be re-synced, and they run in other repositories.

Spec

  • The skill takes the highest-ranked Strong candidate no issue covers, even when a non-Strong one ranks above it, where the Spec says "takes the top recommendation": what is implemented is still always Strong, and Headless Factory skills for the Architecture review #229 settled this wording in its own review. Worth a human decision: the stricter reading files an idea and implements nothing in that case.
  • With no uncovered Strong candidate, a covered top candidate ends as "already filed" rather than being skipped for the next uncovered idea: Stories 11 and 22 pull against each other here (a skipped candidate can never be "already filed"), and the skill's reading is the one that keeps Story 22 reachable.
  • A scan with no candidate at all fails the Architect run: the Spec has no outcome for it and says a missing line is a failed review. Now documented in the README and help; a success outcome for it would be a Spec change.
  • parallel <n> on a single-Ticket plan fails after the plan is marked ready: Architect run dispatches its plan as a Spec run or a Run #232 asked for it to be "rejected or reported as for thirdshift <Issue URL>"; it is tested and documented, and the plan is left ready to run without it.
  • The fixed <repo>-architect worktree path stops a second concurrent Architect run, and a worktree left by a killed one blocks the next: removing a stale worktree on start would delete a running review's. Documented in the README; the lock is out of scope here and is what Define Architect plan and when an Architect run is skipped #250 defines.
  • Dispatch flags rejected with --plan-only: not in the Spec, but Architect run dispatches its plan as a Spec run or a Run #232 and Pass Base fix through an Architect run to its dispatched run #234 asked for it.
  • The plan must be in the origin repository: not in the Spec's list of checks, kept so the wrong repository's issue is never relabelled or dispatched.
  • Unit tests of the private Report::read: the Spec's "don't test internals" is about the end-to-end seam; the repo unit-tests its parsers the same way.

Closes #27

Tickets

JacobStephens2 and others added 20 commits October 1, 2026 02:17
Copies of improve-codebase-architecture, to-spec, to-tickets and
codebase-design, with every human step replaced: the report is Markdown
with Mermaid in the issue, the review takes the top recommendation and
settles its design itself, and nothing is written to the repository.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…es a plan and thirdshift marks it ready

An Architect run starts from the Launch directory with no Issue URL. It
makes the Run preflight checks that need no issue, the opt-in launch pull,
and runs the Architecture review in a worktree detached at the Base
branch's head on origin. It reads the fixed-format last line of the
review's final message, checks the plan it names, swaps needs-triage for
ready-for-agent in one request, and prints the plan's URL.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Say where a single Ticket's Decisions and Architecture review sections
go, make the no-candidate case consistent with the final-line step, and
stop the publishing skills contradicting the throwaway-prototype rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Unready Ticket labels stay in the Spec run, which now answers for any
issue's labels. Marking the plan ready is split from reading the report and
checking the plan. Sessions::run_to_final_message says it runs a session,
and the three gh issue reads share one helper.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Headless Factory skills for the Architecture review
thirdshift architect --plan-only: the Architecture review publishes a plan and thirdshift marks it ready
…e issue that covers it

A review that reports the idea issue it filed, or the open issue that
already covers its top idea, no longer fails the Architect run. It swaps
no label and dispatches nothing, prints that issue's URL on stdout and
exits 0, with a last line on stderr saying which of the two it was.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Without --plan-only, once the plan is marked ready-for-agent, the
Architect run dispatches it as thirdshift <plan URL> would, and ends as
that run does. merge, no-merge and parallel <n> apply to the dispatched
run, and are rejected with --plan-only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the outcome

The already-filed line and the docs say top recommendation, as the
glossary does. The outcome keeps the Issue URL it was read as, the two
no-plan tests share their assertions, and two comments are rewrapped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ec plan coverage

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Architect run with no Strong candidate: idea issue or already filed
origin/issue-27 brings #231: an Architect run whose review found no Strong
candidate ends as a success on the idea issue or the issue that already
covers it. This branch dispatches the plan (#232).

Conflicts resolved by keeping both: architect::run returns #231's Outcome,
and the command dispatches only an Outcome::PlanReady without --plan-only.
An idea issue or an already-filed issue is printed and nothing is
dispatched, with or without --plan-only, as #231 specifies. The old
"published no plan" failures are gone with reported_plan. README and help
describe the dispatch and the No Strong candidate endings together; one
test covers a no-plan review given without --plan-only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Architect run dispatches its plan as a Spec run or a Run
architect takes email [address] and no-email, with the User config's
email.always as the default. Asked to, an Architect run sends one Run
notification however it ends: how the Architecture review ended, naming
the plan or idea issue, and how the dispatched Spec run or Run ended,
which sends none of its own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…o ask for a notification, two more outcomes tested

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One Run notification per Architect run
…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 and others added 2 commits October 1, 2026 00:13
Pass Base fix through an Architect run to its dispatched run
…run share, one home for the triage labels, the README's steps in order

A Run and an Architect run read merge, email, parallel and base-fix
through one RunFlags, in place of two copies of the same match.
ready-for-agent sits beside needs-triage, for the label swap, the Base
fix issue and the Architecture review prompt to share. The prompts page
names an Architect run as a prompt's sender, in place of an empty list
of units. The README removes the worktree where the code does, before
the plan is checked, and it and the help say that a review that finds no
deepening opportunity fails the Architect run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@JacobStephens2
JacobStephens2 marked this pull request as ready for review October 1, 2026 04:35
@JacobStephens2
JacobStephens2 merged commit fc8f3ee into main Oct 1, 2026
13 checks passed
@JacobStephens2
JacobStephens2 deleted the issue-27 branch October 1, 2026 04:42
@JacobStephens2 JacobStephens2 mentioned this pull request Oct 1, 2026
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.

Architect run: thirdshift finds and implements a Strong deepening opportunity unattended

1 participant