fix: architecture review - address 5 critical issues, 6 warnings, 3 suggestions

Critical fixes:
- C1: Create standalone ADR-006 file (edge type consistency),
  extract from open-questions.md inline content
- C2: Convert CallResult from plain interface to TypeBox schema,
  aligning with 'TypeBox as single source of truth' constraint
- C3: Add fromJSON() cycle detection specification - enforce
  ADR-002 DAG invariant even on deserialized input
- C4: Rewrite consumer-integration.md Phase 4 to use ADR-005
  event-append pattern instead of direct signal mutation
- C5: Fix operator precedence bug in consumer-integration.md
  (missing parentheses around OR condition)

Warnings addressed:
- W1: Fix immutability claim - operation graph is 'conventionally
  immutable', not prevented by API
- W2: Add EventLogProjection to reactive exports map
- W3: Add CallResult/CallResultSchema to schema exports map
- W4: Fix reactive-execution.md Level 1 error handling to use
  event-append pattern instead of direct signal mutation
- W5: Remove duplicate dataFlow inference description in schema.md
- W6: Clarify ADR-006 project context (flowgraph vs taskgraph)

Suggestions implemented:
- S1: Add 'reviewed' document lifecycle status between draft/stable,
  update all docs to reviewed status
- S2: Add carve-out note for analysis result types in schema.md
  constraints (they are ephemeral, not serialized)
- S3: Add isComplete() and getAggregateStatus() convenience methods
  to WorkflowReactiveRoot specification
This commit is contained in:
2026-05-21 19:40:45 +00:00
parent f3e084d02f
commit 907c33650f
14 changed files with 189 additions and 85 deletions

View File

@@ -1,5 +1,5 @@
---
status: draft
status: reviewed
last_updated: 2026-05-22
---
@@ -303,34 +303,9 @@ Cross-cutting compilation of all unresolved questions across the flowgraph archi
---
## ADR-006: Edge Type Consistency and Single-Graph Architecture
### ADR-006: Edge Type Consistency and Single-Graph Architecture
**Status**: Accepted
**Context**: Two related questions (OQ-04, OQ-29) affect how edge types are represented in flowgraph:
- Should `edgeType` be a required attribute on all edges, or only on edges where it varies?
- Should `GraphologyHostConfig` produce separate graphs per edge type, or a single shared graph?
**Decision**:
1. `edgeType` is a required universal attribute on every edge, stored alongside (not inside) mode-specific attribute schemas.
2. All edge types share a single graphology `DirectedGraph` instance per `FlowGraph`.
3. Mode-specific attribute schemas (`OperationEdgeAttrs`, `TriggeredEdgeAttrs`, `DependencyEdgeAttrs`) do **not** include `edgeType` — it's stored separately at the graphology level.
4. `TemplateEdgeAttrs` includes `edgeType` as a constrained union (`"sequential" | "conditional"`) because template edges need to distinguish their type for rendering.
**Rationale**:
- Consistent serialization/deserialization (graphology native JSON format requires edge attributes)
- Uniform graphology queries and edge-type filtering across all graph modes
- The redundancy for operation graphs (`edgeType` is always `"typed"`) is a minor cost for significant consistency gains
- Separate graphs per edge type would add complexity (cross-graph traversal, cache coherence, multi-graph queries) without benefit at current scale
- Single-graph filtering by `edgeType` is O(n) on edges — negligible for expected graph sizes
**Consequences**:
- All `FlowGraph` instances store edges with `{ edgeType, ...modeSpecificAttrs }` at the graphology level
- Edge-type filtering is done via standard graphology attribute queries
- The `CallEdgeAttrs` union type is discriminated by `edgeType` at runtime (not by TypeBox schema validation, since both variants are empty objects)
- Serialization validation is a two-step process: (1) check that `edgeType` is present and matches the expected value for the graph mode, (2) validate remaining attributes against the mode-specific schema
- The `triggered` edge type gets the simple `${source}->${target}` key format; `depends_on` always gets the composite `${source}->${target}:depends_on` format (see schema.md Edge Key Convention)
- Future optimization (if needed) could add an internal `Map<EdgeType, Set<string>>` index without changing the public API
See [decisions/006-edge-type-consistency.md](decisions/006-edge-type-consistency.md) for the full decision record.
---