feat(flows-yaml): inline legacy* prFlow callbacks; split cleanup_issue op #1100
No reviewers
Labels
No labels
area:agents
area:dashboard
area:database
area:design
area:design-review
area:flows
area:infra
area:meta
area:security
area:sessions
area:webhook
area:workdir
security
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/claude-hooks!1100
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "code-lead/1095"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #1095.
Summary
legacyHandle{IssueClosed,PrDependencyMarkers,StackedRebaseCascade}import aliases + their use inside the YAMLprFlowcapability adapter inmain.tswith thin one-line dispatches to a newdomain/flows-yaml/pr-flow-impl.tsmodule (runApplyDependencyMarkers/runPropagateRebaseCascade/runPropagateIssueClosed).handleIssueClosed,handlePrDependencyMarkers,handleStackedRebaseCascadefromdomain/workflow/event-handlers.ts. The bodies moved alongside the YAML ops so the impl is testable without dragging in the HTTP entry point's import graph.handleIssueClosed(worktree release + session sweep) into a newcleanup_issueop +prFlow.cleanupIssuecapability.flows/defaults/issue-closed.ymlnow runscleanup_issueTHENpropagate_dependencies (kind: issue-closed)as two visible steps. Pre-#1095 the cleanup rode invisibly on thepropagate_dependenciescallback. Symmetric withcleanup_branchon the PR-close side (#1093).flows.schema.json(server + web copies). 27 ops now (up from 26).The
prFlowcapability surface stays — every op (pr_dependency_markers,propagate_dependencies, the newcleanup_issue) still declaresdeps: ["prFlow"]. What changed is that the capability adapter is now the canonical implementation rather than a wrapper-around-a-wrapper.Acceptance criteria
propagate_dependencies(kind: rebase-cascade) +flows/defaults/pr-merged.ymlfully replicatelegacyHandleStackedRebaseCascadebehaviour; callback wiring +handleStackedRebaseCascadeexport removed.prFlow.propagateIssueClosedadapter now inlinespropagateDependencyClosuredirectly + re-firesissues.assignedthrough the trigger bus. Cleanup half moved to the explicitcleanup_issueop. Callback wiring +handleIssueClosedexport removed.flows/defaults/pr-dependency-markers.ymlalready fires onpull_request: [opened, edited, synchronize](added with the original op), so no newpr-edited.ymlis needed.legacyHandlePrDependencyMarkerscallback wiring +handlePrDependencyMarkersexport removed.prFlowcapability surface preserved (its members are now real impl, not wrappers).setEventHandlersTriggerBus(setTriggerBus) kept — still needed forpublish_pr_mergedfrom #1093.flows-yaml/ops/cleanup_issue.test.ts(new) — op schema + capability dispatchflows-yaml/ops/propagate_dependencies.test.ts— both kinds via mocked capabilityflows-yaml/ops/pr_dependency_markers.test.ts— capability dispatch + delta surfaceflows-yaml/defaults/__tests__/issue-closed.test.ts— flow ordering (cleanup_issue → propagate_dependencies)flows-yaml/ops/registry.test.ts— 27-op manifest pinneddeps.test.ts/pr-deps.test.ts/cleanup.test.tscontinue to cover the underlying primitivesTest plan
just typecheck— clean across all 4 packages.bun test(server) — 3253/3253 pass.just sql-layer-check/i18n-string-check/flow-schema-check— pass.just fmt-check— pass.just paraglide-checkandapps/webVitest browser tests are pre-existing red onmain(missingfr.jsonkeys + machine missinglibglib-2.0.so.0); not introduced by this PR.🤖 Generated with Claude Code
`apps/server/src/main.ts` used to alias three imperative helpers as `legacyHandle{IssueClosed,PrDependencyMarkers,StackedRebaseCascade}` and proxy the YAML `prFlow` capability through them. The wrappers were a transitional shim from before the YAML cutover; with CI events (#1092) and PR-closed cleanup (#1093) landed there is nothing else holding the indirection in place. This change: - Moves the three handler bodies into `domain/flows-yaml/pr-flow-impl.ts` (alongside the YAML ops) as `runApplyDependencyMarkers` / `runPropagateRebaseCascade` / `runPropagateIssueClosed`. The `buildLiveCapabilitiesDeps` adapter in `main.ts` is now a thin one-liner per method. - Deletes `handleIssueClosed`, `handlePrDependencyMarkers`, `handleStackedRebaseCascade` from `domain/workflow/event-handlers.ts` together with the `legacy*` import aliases. - Splits the cleanup half of the old `handleIssueClosed` into its own `cleanup_issue` op + capability (`prFlow.cleanupIssue`) so the side-effect is visible as an explicit step in `flows/defaults/issue-closed.yml` (symmetric with `cleanup_branch` on the PR side). Pre-split, the cleanup rode invisibly on the `propagate_dependencies` callback. - Regenerates `flows.schema.json` (server + web copies) to include the new op definition; bumps the registry expected-op count to 27 and the contract test accordingly. Behavioural parity covered by: - `flows-yaml/ops/cleanup_issue.test.ts` (new) — op schema + capability dispatch. - `flows-yaml/ops/propagate_dependencies.test.ts` — rebase-cascade + issue-closed branches, both kinds. - `flows-yaml/ops/pr_dependency_markers.test.ts` — capability dispatch + delta surface. - `flows-yaml/defaults/__tests__/issue-closed.test.ts` — flow runs cleanup_issue THEN propagate_dependencies in order. The `pr_dependency_markers` AC ("new `flows/defaults/pr-edited.yml`") is already met by the existing `flows/defaults/pr-dependency-markers.yml`, which fires on `[opened, edited, synchronize]`; no additional flow file needed. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>Review: APPROVED ✅
CI is green (3253/3253). All ACs verified against the diff. This is a clean, well-executed refactor.
What was checked
AC 1 — Cascade hook:
handleStackedRebaseCascadedeleted fromevent-handlers.ts. Body faithfully inlined intorunPropagateRebaseCascadeinpr-flow-impl.ts. Logic is identical to the removed handler (same dedup window, samegetPrsDependingOncall, same per-child dispatch loop). ✅AC 2 — Issue-close hook:
handleIssueCloseddeleted. The old fire-and-forget pattern (cleanupIssue.catch(...)+ barepropagateDependencyClosure().catch(...)) is replaced with two properly-awaited YAML steps —cleanup_issuethenpropagate_dependencies. The lazy import offorgeEventToTriggerEventis gone too; the newrunPropagateIssueClosedimports it at module load time (no cycle risk sincepr-flow-impl.tsis in theflows-yamlsubtree, not the HTTP entry point). ✅AC 3 — Dependency markers hook:
handlePrDependencyMarkersdeleted.runApplyDependencyMarkerspassesbody: nullconsistently (same as the old capability adapter that already calledlegacyHandlePrDependencyMarkers(repo, prNum, null)). ✅AC 4 — Executor cleanup:
prFlowsurface preserved;setEventHandlersTriggerBuskept. TheagentsForCleanup()refactor also deduplicates the seven-field mapping that was previously inlined twice (cleanupBranch+handleIssueClosed). ✅AC 5 — Tests:
cleanup_issue.test.ts(schema validation + dispatch forwarding), updatedissue-closed.test.ts(ordering + both calls recorded), updatedregistry.test.ts(27-op count), and stub additions in all impacted capability test fixtures. ✅Schema: Both
apps/server/src/domain/flows-yaml/flows.schema.jsonandapps/web/public/schemas/flows.schema.jsonupdated identically —cleanup_issueblock added in thestepsunion and name appended to the enum. ✅YAML flow:
flows/defaults/issue-closed.ymlnow shows two explicit steps with the pre-#1095 invisibility documented inline. ✅One minor issue to fix before merge
Stale comment in
post-merge.test.ts— the replacement comment for the deletedhandleStackedRebaseCascadetests reads:That file does not exist (grepped the entire
apps/server/srctree — no match). The actual behavior coverage comes fromops/propagate_dependencies.test.ts(op contract, mocked capability) plus the unchanged lower-level fixtures inpr-deps.test.ts/cleanup.test.ts. Please update the comment to reference the files that actually exist, e.g.:This is a comment-only correction — no functional gap — so it doesn't block merge, but it should land before or alongside this PR to avoid confusion for the next person deleting the old tests.
Behavioural change worth preserving in the commit message
The most meaningful semantic change here is the elimination of fire-and-forget: the old
propagateIssueClosedadapter calledlegacyHandleIssueClosedwithoutawait, meaning cleanup + propagation raced against the webhook response. The new YAML path awaits both steps sequentially. This is the right call inside the flow runner, and it's documented in the PR body, but the commit message ("inline legacy* prFlow callbacks; split cleanup_issue op") doesn't surface it — might be worth a follow-up note in the issue or squash message for archeological purposes.Approving. Fix the stale comment reference and merge when ready.
CI is green and review is approved, but the branch is currently not mergeable (conflict with
main). Please rebase onto the currentmainand force-push — I'll merge once Forgejo reportsmergeable: trueagain.Also: one stale comment to fix while you're rebasing — see the review note about
post-merge.test.tsreferencing the non-existentflows-yaml/live-capabilities-prflow.test.ts.5fb85f9de7e3db1cce58