Files
corp-v1-channel-scope/references/react-flow-governed-state.md
T

63 lines
3.7 KiB
Markdown

# 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.