Skip to content

Name what a Pickup run or Security run dispatched, and when, in its stage - #923

Merged
JacobStephens2 merged 3 commits into
mainfrom
issue-889
Oct 21, 2026
Merged

JacobStephens2 merged 3 commits into
mainfrom
issue-889

Conversation

@JacobStephens2

@JacobStephens2 JacobStephens2 commented Oct 21, 2026 •

Copy link
Copy Markdown
Owner

Summary

A Pickup run or Security run now enters a stage naming what it dispatched, timed from the dispatch. A Pickup run's Command record keeps the title its Ready issue was listed with.

 Pickup run (Command record)
-  issue.title: null                        → "(title unavailable)"
-  stages: []                               → "starting", for its whole life
+  issue.title: from the Ready issue listing
+  stages: [dispatched Spec run @ dispatch] → "dispatched Spec run · 19 hr 46 min"
   dispatched: [Spec run, stages: Tickets, …]   (unchanged)

 Security run
   stages: Security audit, Security reproduction, Security fix publishing
+          dispatched Run | dispatched Spec run   (while its fix runs)
Record::dispatching(work)          # src/logs/recording.rs
  if pass is Pickup or Security
    stage(dispatched <kind>)       # still the pass's own record, so began_at = dispatch
  push dispatched record
Record::started(dispatched work)   # launch checks may find a Spec
  rename the pass's dispatch stage to match

health::observe                    # src/logs/reading/health.rs
  a dispatch stage: no Usual range, never Silent or Slow; the dispatched Command carries health
  • A Pickup run that died after dispatching reads died at dispatched Run.
  • Older records, with no stages and a null title, still read starting, died before first stage or their outcome, with (title unavailable).
  • Older binaries skip the new stage names, as they skip any unknown stage.
  • The Console's Inbox uses the same stage_text, so it shows the same words.
  • An Architect run keeps its Architecture review stage while its plan runs, because the issue asks for this only for Pickup runs and Security runs.
  • docs/guide.md lists the new stages and their health rule.

Evidence

  • Before: with the recording change removed, a_pickup_or_security_run_enters_a_stage_naming_what_it_dispatched_and_when and a_dispatch_found_to_be_a_spec_by_its_launch_checks_renames_the_pass_stage fail. With the health change removed, a_dispatch_stage_is_never_slow_or_silent_since_its_dispatched_command_carries_health fails: the pass reads "state":"silent" and has a "dispatched Run" Usual range.
    After: they pass, along with these new or extended tests:
    status: live Pickup run on #7 holding in its Run
      row  starts "Pickup run acme/widgets#7 Make widgets · " and contains " · dispatched Run · "
      json stage.name == "dispatched Run", began_at is RFC 3339, issue.title == "Make widgets"
      show starts "Pickup run pickup-<stamp> · dispatched Run · ", with a "Make widgets" line
    spec_run: live Pickup run on a Spec → " · dispatched Spec run · ", health ok
    security_run: fix in flight → Security run row " · dispatched Run · "; stages end with "dispatched Run"
    status: died after dispatch → " · died at dispatched Run"
    status: pre-change record (no stages, null title) → "(title unavailable)", outcome / "died before first stage"
    
    Full cargo test: exit 0, 55 of 55 test binaries ok. cargo clippy --all-targets is clean.

Merge Danger

Door: two-way

The change adds stage names and fills in a title that was already a field. Older readers skip unknown stage names, so a rollback leaves new records readable.

Blast Radius: status

status, show and the Console read the new stages. A Security run's Security fix publishing stage now ends at the dispatch rather than at the Command's end, so its Usual range will narrow as new records arrive.

Review

Both reviewers read every changed file. There were no generated-output exclusions and no changed file was left unread. Fixed after review: Work::issue_url is now the one place that reads a Work's issue, StageName::dispatched is exhaustive, and the comments say what is_dispatch checks and why an Architect run is left out.

Unaddressed findings

Standards

  • 4. A StageName::parse to replace the string lists in known and is_dispatch: declined. is_dispatch follows the existing StageName::known shape over persisted, tolerant stage names (src/logs/command_record.rs, StageName::known), and rewriting both goes beyond this issue. Its doc comment was fixed.
  • 6. The dispatch stage is set in dispatching and renamed in started: declined. The rename exists because the launch checks can change the dispatched kind after the dispatch is kept (see the existing comment in Record::started, "The launch checks have now established whether the issue is a Spec"). It is pinned by a_dispatch_found_to_be_a_spec_by_its_launch_checks_renames_the_pass_stage.
  • 7. A shared test helper for finding a status row: declined. The same inline .lines().find(|line| line.starts_with(…)) idiom is already used in the existing status tests (tests/status.rs, status_shows_each_idle_pass_until_its_own_kind_starts_work).

Spec

  • (b)1. The Usual range for Security fix publishing shrinks: declined. The new end time is when the publishing session actually ended. The old one also counted the whole dispatched Run, which belongs to that Run's own stages, and the issue asks that a pass's dispatch be timed from the dispatch.
  • (c). After its fix ends, a Security run reads dispatched Run until it ends: declined. src/security.rs fix dispatches one fix, then calls only record_security_fix_ending before the Security run ends, so there is no "between fixes" state inside one Security run.

Security

  • None. The new Pickup title comes from the same GitHub issue title that Runs already record, and the Console's Askama templates escape it. The new stage names are fixed strings.

Closes #889

🤖 Generated with Claude Code

Built with claude · claude-opus-5-5 · medium

Security review outcome

No unaddressed introduced findings.

JacobStephens2 and others added 2 commits October 20, 2026 21:43
…tage

A Pickup run or Security run now enters a `dispatched Run` or
`dispatched Spec run` stage when it dispatches, so status reads
`dispatched Spec run · 19 hr 46 min` instead of `starting`, and
`died at dispatched Spec run` if its process goes. A dispatch stage has no
Usual range and is never Silent or Slow: the dispatched Command carries
its own health. A Pickup run's record carries the title its Ready issue
was listed with.

Closes #889

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@JacobStephens2
JacobStephens2 merged commit 239cf54 into main Oct 21, 2026
19 checks passed
@JacobStephens2
JacobStephens2 deleted the issue-889 branch October 21, 2026 03:00
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.

A Pickup run reads "starting" and "(title unavailable)" for its whole life

1 participant