feat(flows): NF-6 Phase 7 — pr-opened/synchronize/closed flows + delete final inline calls #390

Merged
charles merged 1 commit from feat/flows-phase-7-pr-open-close into main 2026-04-26 16:23:35 +00:00
Collaborator

Summary

Final NF-6 phase. Wraps the last 2 legacy webhook helpers (handlePullRequestOpened + handlePullRequestClosed) into baked-in flows, then deletes the inline calls from webhook.ts. Webhook becomes pure normalize → dispatchToFlows.

Ships

3 new baked-in flows + 2 new node types:

Flow Trigger Wraps
pr-opened pull_request.opened handlePullRequestOpened (review-fallback timer + no-workflows shortcut)
pr-synchronize pull_request.synchronize same handler — legacy code shared one helper
pr-closed pull_request.closed handlePullRequestClosed (worktree cleanup + post-merge rebase probe)

Two new node types:

  • forge.handle_pr_opened — async; awaits the legacy handler so the timer arming + decidePostCiAction launch happens before the run records ok.
  • forge.handle_pr_closed — sync void; same MUST-stay-sync-void contract as forge.handle_issue_closed_cleanup (an async wrapper would silently flip the fire-and-forget semantics into await-completion).

Cutover

config/agents.json::node_flows.suppress_legacy adds the 3 new trigger kinds. webhook.ts drops the inline handlePullRequestOpened / handlePullRequestClosed calls + their imports.

Final dispatcher is ~30 lines:

  • signature verify
  • parse + multi-repo gate
  • normalize → ForgeEvent
  • dispatchToFlows

Migration totals (Phases 1-7)

  • 12 baked-in flows shipped
  • 19 flow node types
  • ~1900 lines of legacy code deleted across the migration
  • Webhook dispatcher: ~30 LOC (was ~200 LOC of switch + plumbing)

Test plan

  • 16 new e2e tests across 2 files (pr-opened-graph + pr-closed-graph)
  • Full suite: 1946 pass / 4 pre-existing fail (session pruning + foreman + 1 flaky PATCH /agents)
  • Server typecheck clean
  • AGENT_NODE_COUNT bumped from 17 to 19
  • Removed 2 stale tests for the deleted inline pull_request.closed arm — coverage in pr-closed-graph.test.ts

🤖 Generated with Claude Code

## Summary **Final NF-6 phase.** Wraps the last 2 legacy webhook helpers (`handlePullRequestOpened` + `handlePullRequestClosed`) into baked-in flows, then deletes the inline calls from webhook.ts. Webhook becomes pure `normalize → dispatchToFlows`. ## Ships 3 new baked-in flows + 2 new node types: | Flow | Trigger | Wraps | |---|---|---| | `pr-opened` | `pull_request.opened` | `handlePullRequestOpened` (review-fallback timer + no-workflows shortcut) | | `pr-synchronize` | `pull_request.synchronize` | same handler — legacy code shared one helper | | `pr-closed` | `pull_request.closed` | `handlePullRequestClosed` (worktree cleanup + post-merge rebase probe) | Two new node types: - `forge.handle_pr_opened` — async; awaits the legacy handler so the timer arming + decidePostCiAction launch happens before the run records `ok`. - `forge.handle_pr_closed` — sync void; same MUST-stay-sync-void contract as `forge.handle_issue_closed_cleanup` (an `async` wrapper would silently flip the fire-and-forget semantics into await-completion). ## Cutover `config/agents.json::node_flows.suppress_legacy` adds the 3 new trigger kinds. `webhook.ts` drops the inline `handlePullRequestOpened` / `handlePullRequestClosed` calls + their imports. Final dispatcher is ~30 lines: - signature verify - parse + multi-repo gate - normalize → ForgeEvent - `dispatchToFlows` ## Migration totals (Phases 1-7) - **12 baked-in flows** shipped - **19 flow node types** - **~1900 lines** of legacy code deleted across the migration - Webhook dispatcher: ~30 LOC (was ~200 LOC of switch + plumbing) ## Test plan - [x] 16 new e2e tests across 2 files (pr-opened-graph + pr-closed-graph) - [x] Full suite: 1946 pass / 4 pre-existing fail (session pruning + foreman + 1 flaky PATCH /agents) - [x] Server typecheck clean - [x] AGENT_NODE_COUNT bumped from 17 to 19 - [x] Removed 2 stale tests for the deleted inline `pull_request.closed` arm — coverage in `pr-closed-graph.test.ts` 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(flows): NF-6 Phase 7 — pr-opened/synchronize/closed flows + delete final inline calls
All checks were successful
qa / qa (pull_request) Successful in 6m39s
qa / dockerfile (pull_request) Successful in 12s
45edc419c6
Final NF-6 phase. Wraps the last 2 legacy webhook helpers
(`handlePullRequestOpened` + `handlePullRequestClosed`) into baked-in
flows, then deletes the inline calls from webhook.ts. Webhook becomes
pure normalize → `dispatchToFlows`.

## Ships

3 new baked-in flows + 2 new node types:

| Flow | Trigger | Wraps |
|---|---|---|
| `pr-opened` | `pull_request.opened` | `handlePullRequestOpened` (review-fallback timer + no-workflows shortcut) |
| `pr-synchronize` | `pull_request.synchronize` | same handler — legacy code shared one helper |
| `pr-closed` | `pull_request.closed` | `handlePullRequestClosed` (worktree cleanup + post-merge rebase probe) |

Two new node types:
- `forge.handle_pr_opened` — async; awaits the legacy handler so the
  fire-and-forget timer arming + decidePostCiAction launch happen
  before the run records `ok`.
- `forge.handle_pr_closed` — sync void; same MUST-stay-sync-void
  contract as `forge.handle_issue_closed_cleanup` (an `async` wrapper
  would silently flip the fire-and-forget semantics into
  await-completion).

## Cutover

`config/agents.json::node_flows.suppress_legacy` adds the 3 new
trigger kinds (`pull_request.opened`, `pull_request.synchronize`,
`pull_request.closed`).

`webhook.ts` drops the inline `handlePullRequestOpened` /
`handlePullRequestClosed` calls plus their imports. Final dispatcher
is ~30 lines:
  - signature verify
  - parse + multi-repo gate
  - normalize → ForgeEvent
  - `dispatchToFlows`

## Test plan

- [x] 16 new e2e tests across 2 files
- [x] Full suite: 1946 pass / 4 pre-existing fail
- [x] Server typecheck clean
- [x] AGENT_NODE_COUNT bumped from 17 to 19
- [x] Removed 2 stale tests in `webhook.test.ts` for the deleted
      inline `pull_request.closed` arm — coverage in
      `pr-closed-graph.test.ts`

## Migration totals (Phases 1-7)

- 12 baked-in flows shipped
- 19 flow node types
- ~1900 lines of legacy code deleted across the migration
- Webhook dispatcher: ~30 LOC (was ~200 LOC of switch + plumbing)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
charles deleted branch feat/flows-phase-7-pr-open-close 2026-04-26 16:23:35 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/claude-hooks!390
No description provided.