Docs Index
flow templates.md

Proof Card: Governed Flow Templates (FlowExecutor + DSL)

Status: production Last verified: 2026-05-20 against the PR #825 review head at the time of stamping. The card describes the implementation contract; specific commit SHAs are re-stamped on merge by the update-docs workflow rather than per R-round to avoid churn on intermediate review heads.

Claim

FlowExecutor (src/flows/templates/FlowExecutor.ts) is the single runtime that walks every governed flow template through transform → validate → governance scan → dispatch. When a template's payload contains high-risk PII or other policy violations, the executor short-circuits BEFORE the connector write — OutboundGovernanceService.validateConnectorWrite either approves the write (executor proceeds with the redacted payload), enqueues an ApprovalQueueService row and returns {status: 'pending_approval', approvalId, pollUrl}, or returns {status: 'blocked', reason: 'governance'} with the findings. This is the flow-layer counterpart to the route-layer catch helper (src/middleware/governance/approvalQueueErrorHandler.ts) and the connector-layer catch (BaseConnector.validateOutboundWrite); all three paths converge on the same ApprovalQueueService.enqueue contract that PR 3C's operator UI consumes. PR 14 narrowed ships single-row operations (create | update | delete) and one sample template; the merged remediation plan's bulk dispatch ships in PR 14b. LineageRecorder (PR 12) and OwnershipResolver (PR 13 / 13b) integration have since landedFlowExecutor now emits lineage events and enforces ownership via guardedWrite().

Source

Tests

Live vs Fixture

Known Gaps

Verification (60-second AI-reviewer recipe)

# Unit suite — 36 tests, ~60s on a warm Jest cache:
npm test -- tests/unit/flows/templates/FlowExecutor.test.ts

# Integration — 3 scenarios against in-memory sqlite + real governance services:
npx jest --config=jest.slow.config.cjs --testPathPatterns=tests/integration/FlowExecutor.test.ts --runInBand

# CI gate (registry/source consistency):
npm run audit-flow-templates

# CI gate regression suite (9 scenarios — A happy + B–I reject paths):
bash tests/scripts/check-flow-template-instrumentation.test.sh

# Confirm DI binding shape:
grep -n "TYPES.FlowExecutor" src/inversify/inversify.config.ts src/flows/templates/FlowExecutor.ts