3.7 KiB
Governed React Flow state and reference integrity
Trigger
Use this pattern when a documentation visualization combines Scope records with Kanban placement or renders canonical relationships as an interactive graph plus semantic fallback.
Canonical state separation
Keep these fields independent:
approval_gate: verified Scope decision evidence such asApproved for Solution; it is not a delivery status.delivery_status: the uppercase governed status for the item type.status_source:EXACTfor Task transitions and direct no-child decisions, orDERIVEDfor Idea/Epic/Feature required-child roll-up.blockedplusblocked_reason: orthogonal delivery impediment, never a status value.
The Board selector reads verified delivery_status and status_source. It must not map approval decisions to delivery, infer Task execution from documentation activity, or accept a parent aggregate computed from an incomplete child set. Show approval gate, canonical delivery status, and a separate plain-language Status basis (Exact item evidence or Required-child roll-up) in the fallback table so reviewers can detect contradictions without exposing internal source vocabulary.
Adapter-level fail-closed checks
Repository-wide YAML validation is necessary but not sufficient. The graph adapter should directly resolve before layout:
- every displayed Idea, Epic, Feature, and Task, including its canonical documentation route;
- every Idea's direct resulting-item roll-up set without ancestor/descendant double counting;
- every Epic's required Features and every Feature's required Tasks;
- every Feature dependency;
- every displayed question relationship and the question record's canonical route; and
- every delivery status against the item-type enum plus its exact/derived source.
Throw a clear error or return an explicit warning object before creating graph nodes. Never use .filter() to discard dangling relationships, convert an unresolved link to unlinked text, or construct a route from an ID naming convention.
Same-selector parity
Build graph nodes, graph edges, legends, and semantic rows from one deterministic selector. Rows should carry resolved link objects such as {id, url} rather than raw IDs so the table cannot drift from graph validation. Keep React Flow mutation disabled and retain the server-rendered semantic table outside client-only rendering.
RED-first tests
Add negative tests that prove the selector fails for:
- missing item documentation route;
- missing or duplicate Idea resulting-item relationship;
- missing parent Epic;
- incomplete required Feature or Task set;
- missing Feature dependency;
- missing question record or question route;
- missing/invalid delivery status or status source;
- a parent marked
TO_BE_RELEASEDwhile a required child is earlier thanTO_BE_RELEASED; - a parent marked
DONEwhile a required child is notDONE; and - a cancelled child silently counted as done or excluded without an explicit required-set decision.
These cases protect both authority separation and deterministic aggregation: approval remains independent, while delivery roll-up is fail-closed and reproducible.
Independent review sequence
A useful fail-closed reviewer prompt should explicitly ask whether:
- approval evidence is being used to infer delivery status;
- required-child roll-up follows the ordered
DONE→TO_BE_RELEASED→IN_DELIVERY→IN_DESIGN→IN_BACKLOGrules; - dangling references are silently omitted;
- fallback links are hard-coded or degraded to plain text; and
- negative tests exercise adapter behavior rather than relying only on global validation.
After any blocker fix, rerun the complete validation suite and obtain a fresh review over the complete final diff before pushing.