Skip to content

Test the Architect run's and Pickup run's skip rules in-process behind a Pass seam - #375

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

JacobStephens2 merged 2 commits into
mainfrom
issue-374

Conversation

@JacobStephens2

Copy link
Copy Markdown
Owner

Summary

Both Passes now run their gates through one Pass seam. Each run's gates are a single function that returns a decision. The unit tests drive that function against an in-memory adapter.

 architect::run
   launch::start                     # the lock skip goes through skip() too
-  github::open_issues_labelled(architect-plan)
-  github::open_issues_labelled(architect-idea)
-  ready::first
+  gates(&mut OnGitHub)  -> Decision::{Skip, GoAhead}
+    open plans → waiting ideas → Ready issue
   skip() / logs::started

 pickup::run
   launch::start
-  claim::sweep
-  claim::open_count
-  ready::first
+  gates(&mut OnGitHub, repo, limit) -> Decision::{Skip, Take}
+    sweep → Claim-limit count → Ready issue
   skip() / "taking Ready issue" / logs::started
src/pass.rs
  trait Outside
    open_issues      # list a label's open issues
    closed_issues    # list a label's closed issues
    apply            # make one label Edit
    ready_issue      # the Ready issue search's answer
    step             # hand on a progress line
  OnGitHub           # production adapter: github::*, Edit::apply, ready::first, progress::step
  InMemory, Call     # cfg(test): issues filed by label, open or closed; records every call in order

claim.rs no longer has sweep or open_count. It keeps in-progress and the Claim's own making and ending. CONTEXT.md gains the term Pass.

Evidence

  • Before: gate order and skip lines were checked only by end-to-end tests that run the binary against a fake gh.
    After: 20 new in-process gate tests in architect::tests and pickup::tests, for example:

    InMemory: open plan #5, waiting idea #7, Ready issue #8
    gates()  -> Skip(OpenPlans[#5]); calls == [Open(architect-plan)]   # no later read
    InMemory: closed #4 [in-progress], 2 open in-progress, limit 2
    gates()  -> Skip(AtClaimLimit); calls == [Closed, Step, Edit #4, Open]   # no Ready issue search
    

    15 end-to-end tests were deleted because they only checked gate order or a skip line's wording: 8 in architect_run, 7 in pickup_run. Every lock, notification and preflight test is kept. So is each end-to-end test the issue lists. cargo test passes all 32 suites with 0 failures, and cargo clippy --all-targets and cargo fmt --check are clean.

Merge Danger

Door: two-way

It is an internal refactor: no skip line, exit code or GitHub read or write changes.

Blast Radius: Passes

A mistake would show up as an Architect run or a Pickup run skipping, or not skipping, wrongly. The kept end-to-end tests still cover each skip reason through the real binary.

Unaddressed findings

Standards

  • cfg(test) accessors on Edit (issue, changes, labels_after): kept. The issue asks the in-memory adapter to record which issue an Edit is for and what it takes off and puts on, and Edit doesn't expose that otherwise. They are test-only.
  • The Sweep moved out of claim.rs (Feature Envy on claim::IN_PROGRESS): kept. The issue explicitly decides that the Sweep moves into the Pickup run's gates.
  • Decision enum, adapter construction and the decide helper duplicated across the two runs: kept. The variants differ (GoAhead vs Take(ReadyIssue)), and a generic Decision<T> would add abstraction for very little gain.
  • A bare bool for "is a Spec" and tuple returns in the test helpers: kept. This is test-only, and it mirrors ReadyIssue::is_spec and the existing helpers in ready.rs.
  • acme/widgets hardcoded in several test fixtures: kept. This follows the existing tests in ready.rs.

Spec

  • InMemory has a closed-listing failure and a filed(...) builder beyond the listed holdings: kept. The issue's own required tests need them: both kinds of Sweep warning, and an Edit that would take nothing off.
  • Clone derived on ListedIssue and Repo, and Edit gains test-only accessors: kept. These are internal, so no public interface of either run changes. Clone lets the in-memory adapter return listings, and lets the lock skip use the one skip step.

Closes #374

🤖 Generated with Claude Code

JacobStephens2 and others added 2 commits October 4, 2026 18:13
…d a Pass seam (#374)

A new Pass module holds the one seam both runs' gates read and change
GitHub through: the open and closed listings by label, one label Edit,
the Ready issue search's answer and a progress line. Each run's gates
become one function returning its decision, tested against a shared
in-memory adapter that records every call. The Sweep and the Claim-limit
count leave the Claim module for the Pickup run's gates. Both entry
points record each skip, the lock's included, through one step. The
end-to-end tests that only checked gate order or a skip line go, and
CONTEXT.md defines the Pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@JacobStephens2
JacobStephens2 merged commit a66e8c8 into main Oct 4, 2026
13 checks passed
@JacobStephens2
JacobStephens2 deleted the issue-374 branch October 4, 2026 22:27
@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 Architect run's and Pickup run's skip rules in-process behind a Pass seam

1 participant