Skip to content

One Run notification for a Pickup run that took an issue - #298

Merged
JacobStephens2 merged 4 commits into
issue-212from
issue-285
Oct 1, 2026
Merged

JacobStephens2 merged 4 commits into
issue-212from
issue-285

Conversation

@JacobStephens2

Copy link
Copy Markdown
Owner

Summary

A Pickup run asked for a Run notification now makes the notification's checks before any other work, and sends the one the Spec run or Run it dispatched would have sent by hand.

 pickup
   User config
+  Run notification's checks: an address and a Resend API key   # exit 1 on every pass, one that would be skipped included
   preflight checks, the lock                                   # skipped: no notification
   search for the lowest-numbered Ready issue                   # skipped: no notification
-  Run notification's checks, and the issue's title read from GitHub
+  whether the issue is a Spec, then "taking Ready issue #<n> ..."
+  the checked notification takes the issue and its title from the listing
   dispatch: a Spec run or a Run, which sends none of its own
   send the one notification, after the outcome is printed
src/
├── notification.rs   # Checked: the checks every notification shares; PickupNotification waits for the issue taken
├── pickup.rs         # Taken carries the issue's title; the Spec check comes before the "taking" line
└── main.rs           # pickup: checks first, a skip returns before anything is sent; help text
README.md             # "One Run notification for the issue taken" under Pickup runs; Run notifications points to it
CONTEXT.md            # Run notification: the dispatched run sends none of its own
tests/pickup_run.rs   # end-to-end cases with the Resend stand-in

Seam under test, the one the Spec names: the real thirdshift binary in a scenario against the fake gh, the fake claude and the Resend stand-in.

Evidence

  • Before: on issue-212, with the two tests written first:

    a_pass_that_would_be_skipped_for_having_no_ready_issue_still_stops_on_the_notifications_checks ... FAILED
      stderr: thirdshift: no Ready issue on acme/widgets      (exit 0, wanted 1)
    asked_for_a_notification_with_no_address_known_the_pass_stops_before_any_work ... FAILED
      gh calls before the check: issue list, pr list, api graphql   (wanted none)
    

    After: cargo test --test pickup_run: 43 passed; 0 failed. Full suite, cargo test: all 30 test binaries ok, 0 failed. cargo clippy --all-targets and cargo fmt --check clean.

  • Each acceptance criterion and the test that covers it:

    Criterion Test in tests/pickup_run.rs
    One notification for each ending the_notification_of_a_run_left_ready_for_review_is_that_runs, ..._of_a_merge_run_says_it_merged, ..._of_a_failed_run_has_its_pull_request_and_its_cause, ..._of_an_interrupted_run_says_it_was_interrupted
    A Run's subject and body, or a Spec run's with a line per Ticket the four above, the_notification_of_a_spec_run_is_that_spec_runs_with_a_line_per_ticket, the_notification_of_a_failed_spec_run_has_each_tickets_outcome
    email <address> over email.to; no-email over email.always a_pass_that_took_an_issue_sends_one_notification_when_the_command_or_the_user_config_asks
    The dispatched run sends none of its own the same table's email.always rows and the Spec run test: exactly one request
    A skipped pass sends none a_pass_skipped_for_having_no_ready_issue_sends_no_notification, a_pass_skipped_for_the_lock_sends_no_notification
    No address or no key exits 1 before any label change or session asked_for_a_notification_with_no_address_known_..., ..._with_no_resend_api_key_..., the two a_pass_that_would_be_skipped_..._still_stops_on_the_notifications_checks, the_notifications_checks_come_before_the_checks_on_the_clone
    A failed send is a warning: line a_notification_that_cant_be_sent_is_a_warning_that_changes_neither_the_exit_code_nor_stdout

Unaddressed findings

Standards

  • resend_env and the_one_notification are copies of the ones in tests/architect_run.rs and tests/spec_run.rs. Skipped: each test file keeps its own Resend helpers today (KEY and ACCEPTED too), and moving them to tests/support/resend.rs means editing two test files this Ticket doesn't otherwise touch.
  • The no-Ready-issue checks test re-spells assert_stopped_by_preflight. Skipped: that helper also asserts Numbered Issue branches after a merged or closed PR #7 is still ready-for-agent, and this scenario has no Numbered Issue branches after a merged or closed PR #7.
  • Issue and title travel together through ListedIssue, Taken and of_taken. Skipped: two fields, and passing Taken whole would make the notification depend on the Pickup run's module.
  • One rule is restated in the help, the README, CONTEXT.md and doc comments. Skipped: that is how this repo documents every command, and the help test pins the wording.
  • "Before any other work" comes after the User config is read and the interrupt handler is installed. Skipped: an Architect run has the same order and the same wording, and the Spec puts the User config first.
  • "As it would by hand" is loose: by hand the title can be missing, here it always comes from the listing. Skipped: the subject is the same whenever GitHub answers, and the listing saves a call that could fail.

Spec

Addressed from the review: one Checked core shared by the three notifications in place of a third copy of the checks; stale doc comments on RunNotification; Taken.title documented; the reused notification name in pickup; the lock tests' shared setup; a test that the notification's checks precede the clone's; and the Spec check moved ahead of the taking Ready issue line, so a pass that fails there has not said it took an issue.

Merge Danger

Door: two-way

Reverting restores the checks after the take. No stored state, label or config key changes.

Blast Radius: Pickup-runs

A scheduled thirdshift pickup with email.always set but no address or Resend key now exits 1 on every pass, where before it exited 0 on passes that were skipped. That is the Ticket's intent, and it shows in the cron log. Runs and Architect runs go through the refactored Checked core; their notification tests pass unchanged.

Closes #285

🤖 Generated with Claude Code

JacobStephens2 and others added 4 commits October 1, 2026 19:12
…made before any other work

A Pickup run asked for a Run notification now checks for an address and a
Resend API key before its preflight checks, the lock and any call to GitHub,
so a broken setup stops every pass with exit 1, one that would have been
skipped included. A pass that took an issue sends the notification the Spec
run or Run it dispatched would have sent by hand, titled from the listing the
issue was found in, and a skipped pass sends none.

Closes #285

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… Spec check before an issue is said to be taken, the notification's checks ahead of the clone's

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…un notification beside the whole Ready issue rule

The help states the whole Ready issue rule and the lines on issues passed
over, and leaves --email and --no-email out of the flags that apply to the
dispatched run: they ask for the Pickup run's own Run notification.

Whether the issue is a Spec comes from the candidate query, so the Tickets
query this branch had moved ahead of the taking line is gone: nothing can
fail between the search and the issue being said to be taken.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@JacobStephens2
JacobStephens2 merged commit be7b86f into issue-212 Oct 1, 2026
13 checks passed
@JacobStephens2
JacobStephens2 deleted the issue-285 branch October 1, 2026 19:57
JacobStephens2 added a commit that referenced this pull request Oct 1, 2026
…m limit beside a Pickup run's one Run notification

The notification's checks stay first, then the pass is run with pickup.limit.
A pass skipped for the Claim limit sends no notification: the case #298 left
for this branch is tested here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@JacobStephens2 JacobStephens2 mentioned this pull request Oct 2, 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.

1 participant