Skip to content

Architect run dispatches its plan as a Spec run or a Run - #244

Merged
JacobStephens2 merged 3 commits into
issue-27from
issue-232
Oct 1, 2026
Merged

JacobStephens2 merged 3 commits into
issue-27from
issue-232

Conversation

@JacobStephens2

Copy link
Copy Markdown
Owner

Summary

Without --plan-only, an Architect run now goes on from the plan it marked ready to the Spec run or Run that thirdshift <plan URL> would start, and ends as that run does.

 thirdshift architect [<focus>] [merge | no-merge] [parallel <n>] [--plan-only]
   architect::run                  # Architecture review, checks, needs-triage -> ready-for-agent
-  print the plan's URL            # --plan-only was required
+  --plan-only?
+    print the plan's URL, exit 0  # merge, no-merge, parallel: argument error (exit 2)
+  else
+    "dispatching the plan <url>, as thirdshift <url> would"
+    run::run(plan, goal, parallel)  # the entry point thirdshift <Issue URL> uses
+      plan has sub-issues -> Spec run
+      otherwise           -> Run   # parallel <n> fails here, as for any non-Spec
+    exit code, PR URL on stdout, last stderr line: the dispatched run's
  • goal is merge/no-merge, else the User config's merge.always; parallel is parallel <n>, else spec.parallel (Parallel::new, now shared with the Run path).
  • The dispatched run sends no Run notification yet, whatever email.always says: that is One Run notification per Architect run #233. The README and help say so.
  • merge, no-merge and parallel are flags after architect, with or without dashes, so none of them can be the focus.

Seams tested: the thirdshift binary end to end through tests/support::Scenario with the fake claude and gh (tests/architect_run.rs, tests/command_surface.rs), and the argument parser, args::parse. The fake gh gains gh fake sub-issues <n> '<list>', so a fake Architecture review can publish a Spec.

Evidence

  • Before: thirdshift architect → exit 2, architect needs --plan-only: it can't yet implement the plan it publishes.
    After: new end-to-end tests in tests/architect_run.rs, all passing:
a_single_ticket_plan_starts_a_run_on_it_and_ends_as_that_run_does
a_plan_with_tickets_starts_a_spec_run_on_it_and_ends_as_that_spec_run_does
merge_merges_the_runs_pull_request_or_the_spec_pr
the_user_configs_merge_default_applies_unless_no_merge_is_given      # both plan shapes
parallel_passes_through_to_the_spec_run                              # #10 needs #9 landed first
parallel_on_a_single_ticket_plan_fails_as_it_does_for_an_issue_that_is_not_a_spec
a_dispatched_run_that_fails_fails_the_architect_run_as_a_failed_run_does
progress_lines_show_the_dispatch_after_the_label_swap_and_before_the_run
  • Dropping parallel from the dispatch makes both parallel tests fail (checked by hand, then restored).
  • Parser unit tests cover the flags in both spellings, contradictory, repeated and malformed ones, and each flag with --plan-only; tests/command_surface.rs covers the same rejections on the binary (exit 2, help on stderr, no review started).
  • Full suite: cargo test passes, every test binary (87 unit tests, 28 in architect_run, 61 in spec_run, and the rest); cargo clippy --all-targets and cargo fmt --check are clean.

Unaddressed findings

Reviewed with origin/issue-27 as the fixed point: the local issue-27 branch on this machine is behind it.

Standards

  • "Dispatch" is not in the CONTEXT.md glossary. The Architect run entry already describes the step, and the word comes from Architect run: thirdshift finds and implements a Strong deepening opportunity unattended #27 and Architect run dispatches its plan as a Spec run or a Run #232; a glossary term for a verb used in one place seemed more than it needs.
  • The Run notification glossary entry doesn't list the dispatched run among those that send none. That is the interim state until One Run notification per Architect run #233, which defines the one notification per Architect run and will rewrite the entry.
  • Data Clumps: DispatchArgs { goal, parallel } repeats two fields of RunArgs. Embedding it would change RunArgs and the Run's parsing, which Architect run: thirdshift finds and implements a Strong deepening opportunity unattended #27 says stays unchanged; the separate type is what makes "flags with --plan-only" unrepresentable.
  • Duplicated Code: the merge / no-merge / parallel match arms are in both parse and parse_architect. Three one-line arms over the shared ask_once and ask_parallel; a shared flag parser for two loops that otherwise differ would cost more than it saves.
  • Duplicated Code: pr_from and agent_opens_pr in tests/architect_run.rs resemble helpers in tests/spec_run.rs. Test files here keep their own small helpers and agent scripts; moving them into tests/support would mean rewriting spec_run.rs call sites in this PR.
  • Divergent Change: the Architect run is split between src/architect.rs (up to the plan) and architect() in src/main.rs (the dispatch). Deliberate: main.rs is where a Run's flags meet the User config's defaults, so dispatching from there is what keeps the plan's run identical to thirdshift <plan URL>.

Spec

  • The README's note that the dispatched run sends no Run notification covers ground that belongs to One Run notification per Architect run #233. Kept: it is what the code does today, and without it "exactly as thirdshift <plan URL> would" would be wrong for anyone with email.always set.

Merge Danger

Door: two-way

Revert the two commits and architect needs --plan-only again.

Blast Radius: architect

thirdshift architect without --plan-only used to be an argument error and now implements the plan unattended, opening a pull request, or merging it with merge or merge.always. A bare merge, no-merge or parallel after architect is now a flag, not a focus. The Run path changes only in how it builds Parallel.

Closes #232

🤖 Generated with Claude Code

JacobStephens2 and others added 3 commits October 1, 2026 02:56
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>
…ec plan coverage

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