Flows YAML — port imperative webhook handlers as ops #1067

Closed
opened 2026-05-10 15:38:51 +00:00 by claude-desktop · 0 comments
Collaborator

User story

As the platform, I want the three imperative webhook handlers to become YAML ops invoked from flows, so that webhook ingress is a pure dispatcher and there is exactly one path from event to side effect.

Resolves audit finding §1.1.1 (flow + legacy collision; same event has two writers).

Acceptance criteria

Ops to author

  • cancel_tasks — replaces handleIssueUnassigned at apps/server/src/http/webhook.ts:296. Args: repo, issue_number, assignee?.
  • pr_dependency_markers — replaces handlePrDependencyMarkers at webhook.ts:325.
  • propagate_dependencies — replaces handleStackedRebaseCascade at webhook.ts:333 and the legacy handleIssueClosed callback.

Webhook cleanup

  • Inline calls in webhook.ts:296–341 removed; webhook just calls the YAML dispatcher.
  • Forge handler is a thin loop: verify → normalize → dispatch → SSE broadcast.

Default-flow wiring

  • flows/defaults/issue-unassigned.yml invokes cancel_tasks on issues.unassigned.
  • flows/defaults/pr-synchronize.yml invokes pr_dependency_markers and (conditional) propagate_dependencies.
  • flows/defaults/issue-closed.yml invokes propagate_dependencies.

Tests

  • Replay a recorded webhook payload through the new path; assert identical side effects to the imperative path.
  • After deletion of inline calls, an issue.unassigned event still cancels tasks.

Out of scope

  • Deletion of legacy handler files (covered by #flows-14 cutover).

References

  • Spec: docs/specs/flows-yaml.md §6.1, §11 Phase 3 step 4.
  • Audit: apps/server/src/http/webhook.ts:296–341.
## User story As the platform, I want the three imperative webhook handlers to become YAML ops invoked from flows, so that webhook ingress is a pure dispatcher and there is exactly one path from event to side effect. Resolves audit finding §1.1.1 (flow + legacy collision; same event has two writers). ## Acceptance criteria ### Ops to author - [ ] `cancel_tasks` — replaces `handleIssueUnassigned` at `apps/server/src/http/webhook.ts:296`. Args: `repo`, `issue_number`, `assignee?`. - [ ] `pr_dependency_markers` — replaces `handlePrDependencyMarkers` at `webhook.ts:325`. - [ ] `propagate_dependencies` — replaces `handleStackedRebaseCascade` at `webhook.ts:333` and the legacy `handleIssueClosed` callback. ### Webhook cleanup - [ ] Inline calls in `webhook.ts:296–341` removed; webhook just calls the YAML dispatcher. - [ ] Forge handler is a thin loop: verify → normalize → dispatch → SSE broadcast. ### Default-flow wiring - [ ] `flows/defaults/issue-unassigned.yml` invokes `cancel_tasks` on `issues.unassigned`. - [ ] `flows/defaults/pr-synchronize.yml` invokes `pr_dependency_markers` and (conditional) `propagate_dependencies`. - [ ] `flows/defaults/issue-closed.yml` invokes `propagate_dependencies`. ### Tests - [ ] Replay a recorded webhook payload through the new path; assert identical side effects to the imperative path. - [ ] After deletion of inline calls, an issue.unassigned event still cancels tasks. ## Out of scope - Deletion of legacy handler files (covered by #flows-14 cutover). ## References - Spec: `docs/specs/flows-yaml.md` §6.1, §11 Phase 3 step 4. - Audit: `apps/server/src/http/webhook.ts:296–341`.
Sign in to join this conversation.
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#1067
No description provided.