Skip to content

One Run notification per Architect run - #245

Merged
JacobStephens2 merged 2 commits into
issue-27from
issue-233
Oct 1, 2026
Merged

JacobStephens2 merged 2 commits into
issue-27from
issue-233

Conversation

@JacobStephens2

Copy link
Copy Markdown
Owner

Summary

An Architect run asked for a Run notification, by email [address] or by email.always without no-email, now sends exactly one, however it ends. The Spec run or Run it dispatches still sends none.

 architect(args)
   user_config
   interrupt::install
+  ArchitectNotification::new        # address and Resend key checked before any work
   architect::run                    # the Architecture review, the plan marked ready
   run::run                          # only for a ready plan without --plan-only; sends nothing
   print the outcome, pick the exit code
+  notification.send(reviewed, dispatched)   # a failed send is only a warning
Subject: [thirdshift] acme/widgets Architect run: <outcome>
  dispatched:  ready for review | merged | failed | interrupted
  otherwise:   plan published | idea filed | idea already filed | review failed | interrupted

Review:       plan published: https://github.com/acme/widgets/issues/8
Dispatched:   merged
Pull request: https://github.com/acme/widgets/pull/3
Host:         droplet-1
Took:         12m 4s

Tickets:
#9 landed with https://github.com/acme/widgets/pull/1
#10 landed with https://github.com/acme/widgets/pull/2
  • architect takes email [address] and no-email, with or without --plan-only. The word after email is the address only if it has an @, so a focus is not taken for it.
  • Help, the README (a new "One Run notification" section) and the Run notification glossary entry say so.

Seams tested: the thirdshift binary through tests/support::Scenario with the fake claude and gh and the Resend stand-in (tests/architect_run.rs, tests/command_surface.rs); the argument parser, args::parse; the notification's subject and body text, in notification's unit tests.

Evidence

  • Before: thirdshift architect --plan-only --email me@example.com exits 2 with unexpected argument after architect: --email, and plan_only_sends_one_notification_naming_the_plan fails on it.
    After: cargo test passes, all suites. tests/architect_run.rs has 44 tests, 13 of them new, one notification each for: --plan-only, idea filed, already filed, review failed, review interrupted, a plan that fails its checks, a dispatched Run that succeeds or fails, and a dispatched Spec run that succeeds or fails, with its Ticket lines. Also no-email over email.always, no notification unasked, no address stopping before any work, and a failed send leaving the exit code and stdout alone. cargo clippy --all-targets -- -D warnings and cargo fmt --check are clean.

Unaddressed findings

Standards

  • (reviewed, dispatched) is matched in both main::architect and ArchitectNotification::send; one "how the Architect run ended" type would hold it once. Skipped: the two matches serve different readers, the exit code and the email, as run_outcome and the Run's notification do for a Run. One type would mean moving the dispatch out of main into the architect module, which reworks Architect run dispatches its plan as a Spec run or a Run #232 rather than this Ticket.
  • The email and no-email arms in parse_architect copy those in parse. Skipped: they follow the merge and no-merge arms beside them, which are copied the same way. The shared part is already in ask_once and is_address.
  • KEY, ACCEPTED, EMAIL_ALWAYS and the_one_notification copy tests/run_notification.rs and tests/spec_run.rs. Skipped: those two files already each keep their own copies. Moving them to tests/support/resend.rs would touch test files this Ticket doesn't otherwise change. The inline copy of the environment inside this file was removed.
  • architect::launch() returns an unnamed tuple, and a notified Architect run reads origin twice. Skipped: the tuple has one private caller besides repo(), and the second read is one git config.

Spec

  • A review that fails after publishing a plan sends a notification that doesn't name the plan. Skipped: thirdshift learns the plan's URL only from the review's final line, which a failed session never wrote. The session log is named instead.
  • interrupted is a review outcome the issue doesn't list. Kept: it is how a Run's notification already tells an interrupt from a failure.
  • A preflight failure, such as a detached HEAD, is reported as review failed. Skipped: the cause line says what failed, and a Run's notification likewise says failed for its preflight failures.
  • The subject says review failed where the body says Review: failed. Kept: the subject has to tell a failed review from a failed dispatched run, whose outcome is failed. The body has the Review: and Dispatched: labels for that.
  • A focus with an @ right after email is taken for the address. Skipped: it is the rule a Run uses for the word after email, and the README says so. Putting the focus before email avoids it.

Merge Danger

Door: two-way

Reverting restores architect rejecting the email flags and sending nothing.

Blast Radius: Architect runs

With email.always = true, an Architect run now sends an email where it sent none, and stops before any work if no address or Resend API key is found, as a Run does. Runs and Spec runs started on an Issue URL are unchanged, apart from a refactor of how their notification is built that their tests still pass.

Closes #233

🤖 Generated with Claude Code

JacobStephens2 and others added 2 commits October 1, 2026 03:29
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>
@JacobStephens2
JacobStephens2 merged commit 1c6b990 into issue-27 Oct 1, 2026
13 checks passed
@JacobStephens2
JacobStephens2 deleted the issue-233 branch October 1, 2026 03:39
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