# 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 as `Approved for Solution`; it is not a delivery status. - `delivery_status`: the uppercase governed status for the item type. - `status_source`: `EXACT` for Task transitions and direct no-child decisions, or `DERIVED` for Idea/Epic/Feature required-child roll-up. - `blocked` plus `blocked_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: 1. every displayed Idea, Epic, Feature, and Task, including its canonical documentation route; 2. every Idea's direct resulting-item roll-up set without ancestor/descendant double counting; 3. every Epic's required Features and every Feature's required Tasks; 4. every Feature dependency; 5. every displayed question relationship and the question record's canonical route; and 6. 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_RELEASED` while a required child is earlier than `TO_BE_RELEASED`; - a parent marked `DONE` while a required child is not `DONE`; 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_BACKLOG` rules; - 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.