Adds PipelineBranchKind (NONE/APPROVED/DECLINED) on stage definitions
so producers can tag the two routes downstream of a FORMAL-approval
stage. The engine then picks exactly one branch per decision:
• Approve → APPROVED-branch children auto-open, DECLINED-branch
siblings auto-SKIPPED (grayed out, unreachable)
• Request Changes → DECLINED-branch children auto-stamped APPROVED
(passive record of the decline), APPROVED-branch siblings auto-
SKIPPED, then the existing rework edge fires as before
Also fixes a quiet bug in pipeline-template-service.addStage where
approvalType was being dropped from new stages (whitelist didn't
include it).
UI: dropdown on the stage edit sheet + branch-kind badges on the
deliverable detail page. SKIPPED rendering already grays things out.
Smoke test extended: 65/65 passing including the user's split-on-
decision case, N-way split, regression assertion that untagged
pipelines still open all children, and an idempotency check.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
diamond, long chain) + rework reset for any pipeline graph
Expands the smoke test from one canonical shape to every pattern a
producer might build:
- linear A → B → C → D (4 stages, full cascade)
- fan-out A → {B, C, D} (all branches open simultaneously)
- fan-in {A, B, C} → D (D stays BLOCKED until *all* parents finish)
- diamond A → {B, C} → D (both legs must finish before convergence)
- long chain (10 stages, full cascade walk)
- rework D → A (full reset of intermediate stages, head spared)
- rework D → A with B SKIPPED (SKIPPED stays SKIPPED across rework)
- rework D → C single-step (only D resets)
- user's pipeline: rework Declined → Inputfile resets
Internal-Approval + Approved + Declined; Inputfile untouched
- state-machine: all 7 new shortcut edges + 2 rejection guards
Plus a pure `planReworkReset` helper that mirrors applyRework's
where-clause math, so any pipeline + rework target combination can
be asserted offline without a DB.
Run: npx tsx scripts/test-workflow-logic.ts
57/57 passing at HEAD.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Self-contained tsx script that exercises the pure state-machine +
dependency-engine logic against the user's exact 5-stage pipeline
shape (Inputfile → Internal Approval ⇉ Approved/Declined → Delivery)
— no DB needed.
Catches the regression from earlier today where `Cannot transition
from IN_PROGRESS to APPROVED` blocked the NONE-stage Mark Complete
shortcut, plus verifies:
- Order-based dependency fallback (when no V2 edges are drawn)
- Multi-branch unblock (approving Internal Approval opens BOTH
Approved and Declined simultaneously)
- Downstream-of-downstream stays correctly BLOCKED until its
specific parent completes (Delivery waits for Approved, not for
Internal Approval)
Run: npx tsx scripts/test-workflow-logic.ts
Non-zero exit on any failure. 19/19 assertions pass against current
HEAD.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>