Skip to content

feat: add post-PR lifecycle phases and ship method#1153

Merged
stack72 merged 3 commits intomainfrom
post-pr-lifecycle-phases
Apr 9, 2026
Merged

feat: add post-PR lifecycle phases and ship method#1153
stack72 merged 3 commits intomainfrom
post-pr-lifecycle-phases

Conversation

@stack72
Copy link
Copy Markdown
Contributor

@stack72 stack72 commented Apr 9, 2026

Summary

  • Adds two new phases (pr_failed, releasing) between pr_open and done for visibility into CI failures and release builds
  • Adds three new methods: pr_merged (pr_open → releasing), pr_failed (pr_open → pr_failed), ship (releasing → done)
  • Adds pr-cooldown check enforcing a 3-minute wait after link_pr before checking PR status, giving CI time to run
  • Enables recovery from pr_failed via link_pr (re-link) or implement (major rework)
  • Adds skill guidance requiring human confirmation before opening PRs

Test Plan

  • deno check — type checking passes
  • deno lint — no lint errors
  • deno fmt — all files formatted
  • deno run test — all 4260 tests pass (26 in lifecycle + schema tests)
  • deno run compile — binary compiles successfully
  • Manual: create an issue-lifecycle instance, walk through link_pr → pr_merged → ship flow
  • Manual: verify pr_failed → link_pr recovery loop works

🤖 Generated with Claude Code

…thod

Extends the issue-lifecycle model with intermediate states between PR open
and done, giving visibility into CI failures and release builds.

New methods: pr_merged (pr_open → releasing), pr_failed (pr_open → pr_failed),
ship (releasing → done). Adds pr-cooldown check enforcing 3-minute wait after
link_pr before checking PR status. Recovery paths allow link_pr and implement
from pr_failed. Skill guidance updated to require human confirmation before
opening PRs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

Blocking Issues

  1. plan-approved check blocks the pr_failed → implement recovery path (extensions/models/issue_lifecycle.ts:270)
    The TRANSITIONS table now allows implement from pr_failed, but the plan-approved check hard-codes state.phase !== "approved" — so calling implement from pr_failed will always be rejected by the check, even though the valid-transition check passes. The recovery path documented in the skill and implementation reference is broken at runtime.

    Fix: update the plan-approved check to also allow pr_failed as a valid phase, e.g.:

    if (state.phase !== "approved" && state.phase !== "pr_failed") {

Suggestions

  1. No tests for the pr-cooldown check — The cooldown check has non-trivial time-based logic (reading linkedAt, computing elapsed time, formatting remaining seconds). A test with a recently-linked PR and a test with an old-enough linkedAt would give confidence this works. The check can be tested via the model's check infrastructure or by calling its execute directly.

  2. No test for link_pr from pr_failed recovery pathlink_pr now accepts pr_failed as a source phase, and the PullRequestSchema documents that failedAt/failureReason are "cleared on next link_pr." Adding a test that calls link_pr after seeding a pullRequest-main resource with failure fields would verify the recovery path and that those fields are indeed absent in the overwritten resource.

  3. link_pr description is stale (issue_lifecycle.ts:1170) — The description says "Transitions the phase to pr_open if currently implementing" but it now also handles recovery from pr_failed. Consider updating to mention both source phases.

  4. start transition test doesn't cover new phases (schemas_test.ts:44-47) — The test only asserts pr_open is included in start's allowed phases. The two new phases (pr_failed, releasing) are also in the list. A minor gap — the Phase ordering test catches their existence, but an explicit assertion on start would document the intent.

stack72 and others added 2 commits April 9, 2026 14:21
- Fix plan-approved check to allow implement from pr_failed (recovery path
  was broken at runtime because the check hard-coded phase !== "approved")
- Add pr-cooldown check tests (recently linked, old enough, no PR linked)
- Add test for link_pr from pr_failed verifying failure fields are cleared
- Update start transition test to cover pr_failed and releasing phases
- Update link_pr description to mention pr_failed source phase

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds an `attempt` counter to the pullRequest resource that starts at 1
on the first link_pr call and increments on each subsequent call. The
attempt number is carried through pr_failed and pr_merged lifecycle
entries so swamp-club shows numbered steps like plan iterations do:
"PR linked (attempt 1)", "PR failed (attempt 1)", "PR linked (attempt 2)",
"PR merged (attempt 2)".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

Well-structured PR that adds post-PR lifecycle phases with clean state machine design.

Blocking Issues

None.

Suggestions

  1. as PullRequestData cast in pr-cooldown check (schemas.ts:310-312): The raw JSON.parse + type assertion bypasses Zod validation. If the stored data is malformed (e.g., linkedAt missing), new Date(pr.linkedAt).getTime() would silently produce NaN, and the cooldown check would always pass. Consider parsing through PullRequestSchema.parse() for defense-in-depth — though this follows the existing pattern in the codebase, so not blocking.

  2. Context type duplication across methods: The context type for pr_merged, pr_failed, link_pr, and ship is repeated inline. A shared type alias (e.g., MethodContext) could reduce the surface area for drift. Low priority — the current approach is explicit and works.

DDD Assessment

Good domain modeling:

  • State transitions via explicit domain methods (pr_merged, pr_failed, ship) rather than generic setters — proper ubiquitous language.
  • The pr-cooldown check encapsulates a domain policy as a named concept.
  • Recovery paths (pr_failed → link_pr, pr_failed → implement) model real-world scenarios explicitly.
  • Attempt tracking on PullRequestData gives the aggregate history awareness without separate event sourcing.

Checklist

  • No any types
  • All promises awaited (no fire-and-forget)
  • License headers present on all .ts files
  • No imports from internal libswamp paths
  • Test coverage for all new methods and the cooldown check
  • Schema tests updated for new phases and transitions
  • Upgrade entry added for version bump
  • Skill docs updated to reflect new phases and human-confirmation rule

@stack72 stack72 merged commit fe91dbe into main Apr 9, 2026
10 checks passed
@stack72 stack72 deleted the post-pr-lifecycle-phases branch April 9, 2026 13:33
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