Skip to content

Test the Ready issue rules in-process behind a seam for the search's reads - #371

Merged
JacobStephens2 merged 2 commits into
mainfrom
issue-370
Oct 4, 2026
Merged

JacobStephens2 merged 2 commits into
mainfrom
issue-370

Conversation

@JacobStephens2

Copy link
Copy Markdown
Owner

Summary

The Ready issue search now reads its outside facts through an internal seam. It takes the time of the pass as a value and hands each passed-over line to a sink. ready::first is unchanged, and so are its callers, the Pickup run and the Architect run.

 ready::first(launch, repo)
   open_issues_labelled(repo, ready-for-agent)
-  Search::new(launch, candidates).first_ready()
+  Search::new(&GitHubAndOrigin { launch }, candidates, Utc::now(), progress::step).first_ready()
     standing_of
-      github::candidate(issue)        # parent, sub-issues, blockers, last shaping
-      branch::started(launch, issue)  # Issue branch on origin, or a PR
-      Utc::now()                      # read once per candidate
+      reads.candidate(issue)
+      reads.started(issue)
+      now                             # read once per pass
-    progress::step(line)
+    (passed_over)(line)               # still printed as each issue is passed over
trait Reads            # private to src/ready.rs
├── GitHubAndOrigin    # production: github::candidate + branch::started
└── InMemory           # tests: records each read and line in one ordered log

There are 15 unit tests in src/ready.rs. They cover every rule and its line, the first-reason-that-applies order, and a Ticket whose Spec is or isn't ready, both above and below the Spec. They also cover the settle window at 9:59, 10:00 and 10:01 for each kind of shaping, a Spec whose Tickets are all closed (started and not started), and whether the Ready issue returned is a Spec. They assert the reads stay lazy: an issue passed over by its labels gets no read, and one passed over for its parent, base-fix or blockers gets no started check.

Nine end-to-end tests in tests/pickup_run.rs that only checked rule order or line wording are deleted, and the unready-label test is cut down to one label. At least one kept end-to-end test still reaches each read: the labels, the parent, the blockers, the timeline (label and link shaping), the sub-issues' states, the Issue branch on origin and the pull request.

Evidence

  • Before: src/ready.rs had no unit tests. Its rules were checked only through the binary, against a fake gh.
    After: cargo test --bin thirdshift ready:: gives 15 passed. The full cargo test, cargo clippy --all-targets and cargo fmt --check pass.

Merge Danger

Door: two-way

The change is internal to one module, and nothing a user sees changes.

Blast Radius: contained

A mistake in the refactor would change which issue a Pickup run takes, or whether an Architect run gives way. The kept end-to-end tests cover each production read.

Unaddressed findings

Standards

  • Tests assert the exact order of the reads. Kept on purpose. The issue asks that the search keep its reads lazy and in their current order, and that each line arrive as its issue is passed over. One ordered log of reads and lines is what shows both.
  • Facts repeats the fields of Candidate. Collapsing them would mean adding Clone or Default to github::Candidate only for tests. That widens a production type for no caller.

Spec

  • The "Ticket above a ready Spec" case only shows the Ticket is never reached. That is how the search behaves: it stops at the Spec, so no line could be held back.
  • There is no unit test for a Spec with all Tickets closed that was started through a PR. The wording for a PR start is covered by a_started_issue_says_what_shows_it_was_started, and the rule order doesn't depend on which kind of start it was.
  • The deleted end-to-end test that took an issue on a later pass, once it had settled, isn't replaced. The production clock read is still reached by the kept "less/more than ten minutes ago" tests. The window boundaries are now unit-tested against a fixed now.

Closes #370

🤖 Generated with Claude Code

JacobStephens2 and others added 2 commits October 4, 2026 16:44
…reads (#370)

The search reads each issue's candidate read and started check through
an internal Reads seam, takes the time of the pass as a value, and hands
each passed-over line to a caller-supplied sink. Unit tests drive the
rules against an in-memory adapter, and the Pickup run end-to-end tests
that only checked rule order or line wording are removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@JacobStephens2
JacobStephens2 merged commit e33aa7e into main Oct 4, 2026
13 checks passed
@JacobStephens2
JacobStephens2 deleted the issue-370 branch October 4, 2026 21:07
@JacobStephens2 JacobStephens2 mentioned this pull request Oct 5, 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.

Test the Ready issue rules in-process behind a seam for the search's reads

1 participant