resolve all remaining open questions (OQ-03–OQ-29), add ADR-006

Resolve all 19 remaining open questions across the architecture. Every
question now has a documented resolution with rationale:

- OQ-004/OQ-029: edgeType is a universal required attribute on all edges,
  single graph per FlowGraph instance (ADR-006)
- OQ-011: No OR preconditions for v1; preconditionMode as v2 extension
- OQ-012: maxConcurrency enforced via reactive counting semaphore
- OQ-014: Unknown operationId creates node with pending status
- OQ-017: Expose common graphology traversal methods on FlowGraph (80/20)
- OQ-020: condition as Type.Unknown() with string/function documentation
- OQ-022: Identity imported from @alkdev/operations peer dep
- All other questions resolved with documented rationale

Fix three critical issues found by architecture review:
1. edgeType serialization/validation gap: document two-step validation
2. CallEdgeAttrs runtime discrimination: edgeType as runtime discriminant,
   depends_on edges clarified as observability-only (not execution)
3. ADR-005 signal mutation inconsistency: explicitly distinguish call-level
   statuses (event-log-driven) from workflow-derived statuses (signal-mutation)

Additional clarifications:
- dataFlow inference uses conservative strategy (defaults false)
- Conditional.test string resolution: operationName → status === completed
- Add negated field to TemplateEdgeAttrs for else-branch conditions
- Document edge key priority convention for composite keys
- Add maxConcurrency semaphore design to reactive-execution.md
This commit is contained in:
2026-05-21 09:25:55 +00:00
parent c76be7f689
commit f3e084d02f
9 changed files with 239 additions and 268 deletions

View File

@@ -1,6 +1,6 @@
---
status: draft
last_updated: 2026-05-21
last_updated: 2026-05-22
---
# Host Configs
@@ -453,7 +453,7 @@ The `Conditional.test` prop can be a function or a string. At the template level
1. ~~**Should structural containers create "virtual" nodes in the reactive engine?**~~ **Resolved (OQ-05)**: Containers stay transparent. Aggregate status for structural containers is computed as a projection from children's statuses, without requiring nodes in the event log or DAG. The `parentMap` and `siblingMap` in `ReactiveContext` provide the structural context for precondition computation.
2. **Should the GraphologyHostConfig produce a separate graph for edge types?** Currently all edge types (`sequential`, `conditional`, `typed`) share the same graph. An alternative is a separate graph per edge type, enabling type-specific queries without filtering.
2. ~~**Should the GraphologyHostConfig produce a separate graph for edge types?**~~ **Resolved (OQ-029)**: No — all edge types share a single graph, with `edgeType` as a universal required attribute on every edge. Separate graphs per edge type would add complexity (cross-graph traversal, cache coherence, multi-graph queries) for a marginal performance gain at current scale. Single-graph filtering by `edgeType` is O(n) on edges and negligible for expected graph sizes. If a concrete performance issue arises with very large template graphs, a `Map<EdgeType, DirectedGraph>` index can be added as an internal optimization without changing the API. See ADR-006 for the full decision on `edgeType` consistency.
3. ~~**How does the ReactiveHostConfig interact with the call protocol?**~~ **Resolved (ADR-005)**: The reactive layer bridges to the call protocol through the event log. The hub coordinator appends call protocol events; the reactive layer projects them into status and results. The `ReactiveHostConfig` reads from the `EventLogProjection` interface (via `getStatus()` and `getResult()`), not from direct signal mutations by the coordinator.