← All guided builds

Guided build · 16

Build an explainable policy graph

Combine typed graph structure, recursive policy, contested evidence, and dependency witnesses into one auditable release decision.

You will finish with: A release gate that answers not only yes or no, but which policy, facts, authorities, and graph edges produced the answer.

35 minAdvancedSource checked for Grid 0.61.0Reviewed 2026-08-25
Related canonical example19-release-governance.grid
Get Grid
Starter modelrelease-policy-starter.gridLocal policy, service facts, and dependency graph before evidence and explanation outputs.
Worked open-road routing caseopen-road-route.gridClose one road and verify the new cost, hops, and exact path edges without deleting its source row.

Watch it in Grid

See the workflow before you build it.

Follow the finished interaction, then use the written steps below to build and inspect it yourself.

Companion film

Policy with witnesses

Change one dependency, watch the releasability gate move while approval stays contested, and use WHY to retain its authorities and exact graph-edge witnesses.

39 secGrid 0.63.2
Open film page
On this page

What you will build

A release gate that combines service reviews, a dependency graph, reusable policy, and independent approval evidence. The final result stays useful when authorities disagree and retains the witnesses needed for an explanation.

1. Start with policy and model facts

Download the starter above. It declares a closed policy vocabulary:

predicate reviewed(by: symbol)
predicate blocked(reason: string)
predicate releasable means
  reviewed
  AND NOT blocked
  AND EVERY dependency IS :releasable
predicate dependency is transitive

Three model symbols carry reviewed facts and an ordinary reactive dependency chain:

database is :reviewed(:data) = 1
api is :reviewed(:platform) = database + 1
release is :reviewed(:change_board) = api + 1
release dependency api
api dependency database

Checkpoint: the reviewer attached to release is :change_board; transitivity makes release dependency database true.

The complete Release Governance example imports the same vocabulary from shared/governance.gs. Download its complete source bundle when you want policy reuse rather than a self-contained starter.

2. Keep operational structure as a graph

The starter also declares governance, a directed graph whose stable edge IDs name approval and dependency facts. Project its relation property into predicate knowledge:

KNOWLEDGE GRAPH governance VIA edge.relation

Add:

R5C2 = REACHABLE VIA dependency* FROM "release"
R1C7 = MUST("release" dependency "database")

Checkpoint: the reachable result contains release, api, and database; R1C7 = TRUE.

The graph remains resident. The predicate layer can reason over its relationships without copying every edge into separate facts.

3. Add attributable disagreement

Add two independent evidence statements:

EVIDENCE qa_approval SUPPORTS ("release" approved "deployment") BY qa
EVIDENCE security_hold REFUTES ("release" approved "deployment") BY security

Then publish the evidence and both modalities:

R1C2 = EVIDENCE("release" approved "deployment")
R1C3 = MUST("release" approved "deployment")
R1C4 = CANNOT("release" approved "deployment")

Checkpoint: R1C2 is both; R1C3 = TRUE; R1C4 = TRUE.

The evidence is contested, not erased. The model can ask for support, refutation, or the complete attributable state without allowing one authority to silently overwrite another.

4. Publish the release decision

Add:

R1C1 = MUST(release IS :releasable)
R1C6 = release.predicates.reviewed.by

Checkpoint: R1C1 = TRUE, R1C6 = :change_board, and the inferred database dependency remains true.

The releasability policy depends on reviewed state and the full transitive dependency cone. Approval evidence is reported separately, so a product can present the contested approval without falsifying the underlying readiness calculation.

5. Ask why

Inspect R1C7 with the Why action or the equivalent command for your deployment.

Checkpoint: the explanation names both release-api and api-database as witnesses for the inferred dependency.

Inspect R1C2.

Checkpoint: the explanation retains qa_approval by qa and security_hold by security rather than collapsing them to an unattributed boolean.

Avoid asserting an exact serialized explanation tree in application code. Test stable identities, facts, authorities, and witness edges; the presentation shape can evolve.

6. Connect typed graph analytics

Open Native Graph V2. It uses a closed road schema, a filtered view, and an immutable rewrite before asking for a bounded path:

path fastest = path in roads from "A" to "D"
  minimize sum(edge.minutes)
  limit 8 AS hops

Checkpoint: 3 roads are open, the normalized graph has 3 edges, and the fastest A→B→C→D route costs 14 minutes over 3 hops.

This is the same architectural split at a richer scale: Graph V2 owns typed structure and graph computation; predicates and WHY own policy truth and explanation.

7. Close a road and recompute the route

Open the Worked open-road routing case download. This separate worked model uses an editable, range-backed road table. The original Native Graph V2 example above binds its path to roads; this case deliberately binds it to the filtered open_roads view:

input RoadOpen = TRUE
F12 = RoadOpen

graph open_roads: Roads = roads {
  edge road where road.open = TRUE
}
path fastest = path in open_roads from "A" to "D"
  minimize sum(edge.minutes)
  limit 8 AS hops

The four stable road IDs are ab, bc, ac, and cd, with travel times 4, 7, 15, and 3 minutes respectively. All four begin open. The Route tab shows the computed cost, hops, open-road count, and exact selected edge IDs. Those edge values are read from fastest.edges, not reconstructed from a caption or an expected answer.

State Selected edge rows Minutes Hops Open roads Source roads
RoadOpen = TRUE ab, bc, cd 14 3 4 4
RoadOpen = FALSE ac, cd 18 2 3 4

In the Default tab, select I/O and set RoadOpen to FALSE. Return to Route to inspect the new result. The view excludes bc, while the source graph retains that road and its original seven-minute cost. A missing third edge displays as a dash. Reopen the road to restore the original route.

The important distinction is availability versus deletion: changing the view changes the admissible path without erasing the underlying road record.

Try it yourself

Add a blocked fact to the API symbol:

api is :blocked("critical vulnerability")

Checkpoint: MUST(api IS :releasable) becomes false, and the recursive release policy no longer proves the release releasable. The explanation should retain the blocked reason and the dependency path.

Remove the block after inspecting the result.

You are done when

  • Transitive dependency truth follows the graph without duplicated facts.
  • Conflicting approval evidence remains attributable to both authorities.
  • The release gate reports its policy result separately from contested approval.
  • WHY retains stable facts and graph-edge witnesses.
  • You can explain when to use Graph V2 computation, predicate policy, evidence, and presentation.
Build statusReached the expected checkpoint?