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 →Guided build · 16
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.
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.
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
releaseis:change_board; transitivity makesrelease dependency databasetrue.
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.
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.
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:
R1C2isboth;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.
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.
Inspect R1C7 with the Why action or the equivalent command for your deployment.
Checkpoint: the explanation names both
release-apiandapi-databaseas witnesses for the inferred dependency.
Inspect R1C2.
Checkpoint: the explanation retains
qa_approvalbyqaandsecurity_holdbysecurityrather 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.
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.
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.
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.