feat(flows-yaml): shadow mode + cutover CLI + legacy + UI deletion (closes #1078) #1083
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!1083
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "flows-yaml/cutover"
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 #1078. Final phase of the Flows YAML milestone (#40). Builds on #1075 (engine), #1076 (defaults + REST), #1077 (UI).
This PR is destructive. The legacy JSON node engine, React Flow canvas, and
/api/flows-yamlURL prefix are gone. The YAML engine becomes the sole dispatch path. Operator post-merge checklist below.Commits
feat(flows-yaml): live capabilities + shadow mode + diff reporter— wires real service deps, adds shadow tables + diff reporter (no behavior change at defaultmode: "off").feat(flows-yaml): per-flow cutover CLI + 24h shadow gate— operator-driven per-flow promotion. Settings learnper_flowoverrides +cutover_history.feat(flows-yaml): delete legacy engine + cut UI over + rename audit columns— destructive cleanup.What landed
Phase 1 — live + shadow
buildLiveCapabilitiesDeps()inmain.tscomposes thin closures over the existing service surface (workers, dedup, agent-resolver, forge, breakdown, review-guard, pr-flow).assertCapabilitiesSatisfyOps()refuses to start the dispatcher on missing deps.shadow-capabilities.tswraps mutating ops as no-op recorders; read-only ops pass through.shadow-hooks-impl.tspersists toflow_runs_yaml+flow_node_runs_yaml.flows-yaml-diff-reporter.ts(6h cron) pairsflow_runsvsflow_runs_yaml±60s window; emitslegacy_only/yaml_only/flow_name_diverged/op_sequence_divergedmismatch types. Surfaced viaGET /api/flows/diff-report.0014_flow_runs_yaml_shadow_table.sqladds the shadow tables with the post-cutover column names (flow_name,step_id,uses).Phase 2 — per-flow cutover
FlowsYamlSettingsextended withper_flow: Record<name, mode>+cutover_history.per-flow-router.tsreturns the right capability bag per flow at execution time; settings flips take effect on the next event.cutover-gate.tsenforces "→ live" promotion (must be in shadow, ≥24h shadow data, zero recent diff mismatches naming this flow).--forceoverrides + records.POST /api/flows/:name/mode— operator-callable mode change. Auth-gated. Same gate as the CLI.apps/server/scripts/flows-yaml-cutover.ts+flows-yaml-mode-status.tsplusjust flows-yaml-cutover NAME MODE *EXTRAandjust flows-yaml-mode-statusrecipes.Phase 3 — legacy deletion + UI cutover + renames
Server deletions (54 files):
apps/server/src/domain/flows/entire directory — JSON node-graph engine: executor, registry, validation, flow-dispatch, agent/forge/mcp-nodes, every*-graph.{ts,json,test.ts}, types, seed-status, rate-limitapps/server/src/http/{flows-divergence,divergence-summary,flow-assistant-routes}— dead consumers of the deleted engineapps/server/src/infrastructure/database/{flows,flow-audit}.ts+ schema modules — paired with the dropped tablesServer rewrites:
webhook.ts— dropdispatchToFlows+ the three imperative handlers at lines 296–341. The YAML dispatcher is the sole path.main.ts— drop 13 legacy imports + 11/api/flows/*legacy handler stubs +seedDefaultFlowAtBoot(). WiresetEventHandlersTriggerBus(closes a latent unwired-bus bug).event-handlers.ts— replaceflow-dispatchlazy-import inpropagateDependencyClosurewith a YAML trigger-bus publish.dispatcher.ts— drop the legacy single-bag constructor; router-only.Drizzle migration
0015_drop_legacy_flows_and_rename_audit.sql:flows+flow_auditflow_runs.flow_id→flow_nameflow_runs.flow_versiondroppedflow_node_runs.node_id→step_id;uses TEXTadded (matches shadow table shape)migrate.ts. Newmigrate-0015-rename.test.tscovers pre/post column shape + idempotence.Web deletions + cutover:
apps/web/src/features/flows/*canvas + palette + inspector + assistant panel deleted (the#1075-era React Flow canvas)apps/web/src/routes/flows.{index,$flowId,$flowId.v.$version,$flowId.versions,new,test}.tsxlegacy routes deletedfeatures/flows-yaml/→features/flows/;routes/flows-yaml.*→routes/flows.*;lib/flows-yaml-api.ts→lib/flows-api.ts/api/flows-yaml/*→/api/flows/*;/flows-yaml/*→/flows/*flows-yaml-→flows-nav-sections.tsxcollapsed to a single canonical Flows entry pointing at/flowsapps/web/package.jsondrops@xyflow/react+@types/dagre+dagreSpec retirement:
specs/node-flows.md+specs/node-flows-ui.mdget a RETIRED banner; files kept as archiveWhat stays:
flow_runs_yaml/flow_node_runs_yaml/flows_yaml_diff_report) — operator may want post-merge shadow dataworkflow/event-handlers.ts—handleIssueClosed,handleCheckSuiteCompleted,handlePullRequestClosed,handlePullRequestOpened,handleSlashCommandOther,detectOutstandingChangeRequest,latestVerdict,isTrustedUser,dispatchIssueForAgentall still support live capabilitiesStats
Operator post-merge checklist
flows_yaml_settings.modetolive(or per-flowlive) BEFORE the deploy lands, otherwise no dispatch fires (the legacy fallback is gone). The phase-2 cutover CLI is the gate./api/flows-yaml/*is removed — bookmarks and external scripts need to flip to/api/flows/*.routeTree.gen.tsauto-regenerates on nextvite build.🤖 Generated with Claude Code