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:
@@ -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.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user