feat: quality gate engine and node state store#32
Conversation
- Quality gate engine independently verifies agent claims (test results, type checks, lint) by running commands and parsing output - Node state store persists validated node state to DB, replacing event-replay resume with explicit validated state - Gates integrated into DAG executor: P0/P1 block progression, P2 warns - Loop nodes get real feedback (test names, error counts) on gate failure - Test output parsers for vitest/jest/bun test, tsc, and eslint - API endpoints for gate results and node state summaries - SSE events for gate lifecycle (started/passed/failed/blocked) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comprehensive PR ReviewPR: #32 — feat: quality gate engine and node state store SummaryWell-structured quality gate engine with clean separation of concerns. Code quality and conventions are strong. Two significant gaps: (1) silent gate execution errors that undermine the trust boundary, and (2) missing test coverage for the persistence layer, API routes, and DAG executor gate integration. Verdict:
(9 HIGH = 3 code/test + 6 documentation) HIGH IssuesH1: Gate Execution Error Silently Accepted as Success
When View fixAdd user warning message + } catch (gateErr) {
const errMsg = (gateErr as Error).message;
getLog().error({ err: gateErr as Error, nodeId }, 'dag.gate_execution_error');
await safeSendMessage(platform, conversationId,
`Warning: Gate execution failed for node '${nodeId}': ${errMsg}. Proceeding without gate verification.`,
{ workflowId: workflowRun.id, nodeName: nodeId });
emitter.emit({ type: 'gate_failed', runId: workflowRun.id, nodeId, ... });
}H2: No Tests for Node State DB CRUD
JSON serialization, SQLite boolean coercion (0/1 → boolean), and upsert ON CONFLICT logic — all error-prone — have zero test coverage. The fire-and-forget pattern means bugs would be completely silent. View detailsAdd unit tests following H3: DAG Executor Gate Integration Untested
Gate integration logic (run gates after completion, downgrade to failed on block, persist state) has no test coverage. If View detailsAdd integration test with mocked H4-H9: Documentation Updates (6 findings)
MEDIUM Issues (Needs Decision)M1: Loop Node Gate Error Also Silent
Options: Fix now (consistent with H1) | Create issue | Skip M2: Fire-and-Forget Double Error Swallowing
Options: Remove inner try/catch (callers already have M3: No Tests for New API Routes
Options: Add route tests | Create issue | Skip M4: Loop Gate Rejection Flow Untested
Options: Add tests (HIGH effort) | Create issue | Skip LOW IssuesView 8 low-priority suggestions
What's Good
Next Steps
Reviewed by Archon comprehensive-pr-review workflow |
Code fixes: - H1: Gate execution errors now warn user + emit gate_failed event (DAG nodes) - M1: Same fix for loop node gate execution errors (consistency) - M2: Remove double error swallowing in node-states.ts — let callers .catch() - L2: Remove dead `?? 3` fallback (Zod default is 0) - L5: Add safe JSON parsing with fallback for corrupted DB rows Tests added: - H2: 14 unit tests for node-states.ts DB CRUD, normalization, and edge cases Documentation updated: - H4: Add `gates` to CLAUDE.md DAG node options - H5: Update table count 8→10, add node_states + test_results - H6: Add summary + gate-result API endpoints to CLAUDE.md - H7: Update docs-web database.md (table count, new tables, migrations) - H8: Add new endpoints to docs-web api.md - H9: Add Quality Gates section to authoring-workflows guide - M5: Add gates/ subdirectory to CLAUDE.md architecture tree Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
UX Journey
Before
After
Architecture Diagram
Before
After
Connection inventory:
Label Snapshot
risk: mediumsize: Lworkflows,core,serverworkflows:gates,workflows:dag-executor,core:db,server:apiChange Metadata
featuremultiLinked Issue
artifacts/runs/34353bad590c84f9aeebe24399794173/plan.md34353bad590c84f9aeebe24399794173Validation Evidence (required)
Security Impact (required)
NoNoNoNo— gates execute commands in the existing worktree CWDCompatibility / Migration
Yes— gates are opt-in viagates:field on nodes; existing workflows unchangedNoYes— SQLite auto-creates tables; PostgreSQL requiresmigrations/022_node_states.sqlpsql $DATABASE_URL < migrations/022_node_states.sql(PostgreSQL only)Human Verification (required)
bun run validatepass (type-check + lint + format + 2991 tests)Side Effects / Blast Radius (required)
Rollback Plan (required)
gate_failedSSE events and node failures in workflow runsRisks and Mitigations