feat(spec): OperationalDAG + GovernedLoop — loops-vs-graphs governance - #253
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
Adds normative schemas + fixtures + a validator to mechanically enforce the “loops vs graphs” governance split: OperationalDAG must remain acyclic with semantically grounded nodes, while GovernedLoop is the only admissible cycle shape (bounded + convergent + fail-closed + admitted).
Changes:
- Introduces new JSON Schemas:
OperationalDAGandGovernedLoop, plus positive examples and negative conformance fixtures. - Adds
tools/validate_dag_loop.pyto enforce schema conformance and extra invariants (edge resolution + DAG acyclicity + loop governance). - Documents the doctrine and adds a
make validate-dag-looptarget (but currently not included inmake validate).
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/validate_dag_loop.py | New validator: schema conformance + DAG edge/cycle checks + loop governance checks + negative vectors. |
| specs/operational-dag-governed-loop.md | New spec note describing OperationalDAG vs GovernedLoop semantics and validation entrypoint. |
| schemas/OperationalDAG.json | New schema defining OperationalDAG nodes/edges and semantic grounding requirements. |
| schemas/GovernedLoop.json | New schema defining governed loops (bound, convergence, fail-closed handler, admission). |
| Makefile | Adds validate-dag-loop target (needs wiring into aggregate validate). |
| fixtures/dag-loop/conformance.json | Adds negative vectors with expected failing JSON-Schema keywords. |
| examples/operational_dag.promotion.json | Adds a conforming OperationalDAG example. |
| examples/governed_loop.vocab_currency.json | Adds a conforming GovernedLoop example. |
| CHANGELOG.md | Documents addition of OperationalDAG/GovernedLoop and validator wiring. |
Comment on lines
+14
to
+16
| validate-dag-loop: | ||
| python3 -m pip install --user jsonschema >/dev/null | ||
| python3 tools/validate_dag_loop.py |
Comment on lines
+49
to
+52
| for name, dag in dags.items(): | ||
| node_ids = {n["id"] for n in dag["nodes"]} | ||
| adj: dict[str, list[str]] = {n: [] for n in node_ids} | ||
| ok_edges = True |
mdheller
added a commit
that referenced
this pull request
Aug 2, 2026
…Y (Copilot #253) The prior wiring used a string match that didn't hit this repo's long 'validate:' line, so the target was DEFINED but unreachable — 'make validate' silently skipped the new enforcement (the exact 'declared but not live' gap this contract exists to refuse; RC=0 was false comfort). Now appended to both the 'validate:' prerequisites and .PHONY; 'make -n validate' confirms it runs. Copilot's second comment (duplicate node ids collapsing in the set) was already remediated in the preceding commit (validator refuses duplicate node ids, teeth-verified).
mdheller
added a commit
that referenced
this pull request
Aug 2, 2026
…Y (Copilot #253) The prior wiring used a string match that didn't hit this repo's long 'validate:' line, so the target was DEFINED but unreachable — 'make validate' silently skipped the new enforcement (the exact 'declared but not live' gap this contract exists to refuse; RC=0 was false comfort). Now appended to both the 'validate:' prerequisites and .PHONY; 'make -n validate' confirms it runs. Copilot's second comment (duplicate node ids collapsing in the set) was already remediated in the preceding commit (validator refuses duplicate node ids, teeth-verified).
mdheller
force-pushed
the
feat/operational-dag-governed-loop
branch
from
August 2, 2026 21:27
138f09a to
56e2e0c
Compare
DAG carries identity/dependency/causality → MUST be acyclic; validate_dag_loop.py REFUSES a cycle (a loop where a DAG belongs is unsatisfiable) and grounds every node in the vocab/DataClass/service substrate (semanticRef) with field-calculus placement. GovernedLoop is the only legitimate cycle, and only when governed: BOUNDED (maxIterations) + CONVERGENT (a measure) + FAIL-CLOSED (onNonConvergence refuse| escalate-human, never continue) + ADMITTED by the superconscious (loops don't self-authorize). 5 negative vectors; teeth-verified (cycle refused, self-authorizing loop refused). Wired into make validate.
A DAG is identity; two nodes sharing an id collapse into one in the node-id set and silently mask edge/cycle errors. Schema minItems cannot catch it, so validate_dag_loop.py now refuses duplicate node ids. Teeth-verified.
mdheller
force-pushed
the
feat/operational-dag-governed-loop
branch
from
August 2, 2026 21:31
56e2e0c to
dae2571
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Where loops vs graphs win — made mechanical
Closes the enforcement owed by the loops-vs-graphs doctrine.
OperationalDAGcarries identity / dependency / causality → MUST be acyclic.validate_dag_loop.pyrefuses a cycle (a loop where a DAG belongs is unsatisfiable), resolves every edge to a real node, and requires every node to be semantically grounded (semanticRef→ GlossaryTerm / DataClass / service). Placement is a field-calculus reference (placementRef→ PlacementFact / phase-field), not ad-hoc.GovernedLoopis the only legitimate cycle, admissible only when governed:bound.maxIterations ≥ 1(termination)convergence.measure∈ {fixpoint, monotone-decrease, error-below-tolerance}onNonConvergence∈ {refuse, escalate-human}, nevercontinueadmission.superconsciousRef(the superconscious holds refusal authority + convergence budget; loops don't self-authorize)Teeth (verified)
has a CYCLE)don't self-authorize)failValidator(node missing semanticRef, edge missing endpoint, onNonConvergence=continue, loop missing admission, loop missing bound)Wired into
make validate(RC=0; 347 unique $id).Ties: SP-GATE fail-closed pattern, vocabulary-as-governance-substrate, field calculus (MeshRush phase-field), superconscious governor.