Conversation
… hold them equal The fifth slice of the Normative IR (V5 in docs/shaping/normative-ir-slices.md), stacked on V4, and the two spikes the shaping doc left open, executed as the slice: X1, the fact vocabulary, and X2, the predicate language and its compiler, designed by putting the twenty-four Requirements through a compiler rather than by inspection. ir/vocabulary/relations.yaml declares 44 relations over two scalar types, each tagged with where its tuples come from: the wire, ordinary code (hashes, JCS, signatures, schema validation), the Guardian's own records, deployment configuration, or the spec itself, whose fixed tables ship inside the program. The external-fact boundary (E7.1) is therefore derived per provision, not authored. A predicate is Datalog rules as strings in the record: atoms, not, the six comparators, assignment, cat and to_string, and count; a violation head plus helpers. The compiler types every variable against the vocabulary, infers helper types to a fixpoint, rejects unsafe rules, stratifies by SCC and refuses negation inside a cycle, and enforces N36: the violation head is exactly the declared subject then witness variables, both non-empty. A Requirement with neither a predicate nor a declared inexpressible reason does not compile. One authority, two targets: ir/dist/rules.dl, the published Soufflé program an auditor runs with stock Soufflé 2.5 over a directory of .facts, and ir/.build/rules.json for the semi-naive evaluator that is the laptop path. Both emit the unified violation(provision, subject, witness), which the differential oracle compares over shared fixtures and holds to each fixture's expected.tsv. Twenty-one predicates compiled; one alias, one permission, one non-testable; zero inexpressible on these specimens. Both engines derive identical sets on both fixtures (0 and 24 violations), and a deliberately weakened rule prints the four tuples only the evaluator derived. CI installs the pinned 2.5 .deb, hash-verified, in its own job. normalizeTrace() moves to V6 beside the external-fact computation, because the wire relations are only useful once the facts they join with exist. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BX56nQPAsqYihopWfWy1xm
Normative impact (ACS 0.1.2 at
|
The repository's .gitignore excludes every dist/ directory, so ir/dist/provision-index.md (and rules.dl from V5 on) never reached git even though `render --check` and `compile --check` require the committed copy. Re-include ir/dist/ and commit the files the checks compare against. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BX56nQPAsqYihopWfWy1xm
GitHub sets CI=true in every job, so the oracle-presence test failed in the plain test job, which has no Soufflé. The requirement is now opt-in through ACS_IR_REQUIRE_SOUFFLE, set by the differential job, which also runs the differential tests so the oracle half is exercised in CI. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BX56nQPAsqYihopWfWy1xm
afogel
added this pull request to stack #48
September 14, 2026 14:18
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.
Fifth slice of the Normative IR (
docs/shaping/normative-ir-slices.md§V5), stacked on #42. This is where the shaping doc's two open spikes, X1 (fact vocabulary) and X2 (predicate language and compiler), were executed as the slice.Demo:
bun run ir compileturns twenty-one IR predicates intoir/dist/rules.dl(published Soufflé program) andir/.build/rules.json(the evaluator's rule set).bun run ir differentialruns both engines over the same fixtures: identical violation sets, 0 on the conformant session and 24 on the violating one. A deliberately weakened rule turns the check red and prints the four tuples only one engine derived. Captured output and the design record are inir/slices/v5/README.md.What it delivers
ir/vocabulary/relations.yaml: 44 relations oversymbolandnumber, each tagged by source (wire, external, guardian-state, deployment, static). Static relations carry the spec's fixed tables (the §6 required-fields column, the DEFER reason enum, the trust ranking) and ship inside the program. The external-fact boundary (E7.1) is derived per provision from the relations a predicate touches, not authored.not, the six comparators,Var = expr,cat/to_string, andcount. Aviolation(subject..., witness...)head plus helpers. Nothing more, because every construct is emitted twice and held equivalent.inexpressiblereason does not compile (R3.1, R3.6).emitSouffleProgram()writes the.dlan auditor runs with stock Soufflé 2.5;rules.jsonfeeds the semi-naive evaluator, which runs with no Soufflé install (R3.9). Both produce the unifiedviolation(provision, subject, witness).ir/test/conformance/fixtures/{conformant,violating}, each held to the fixture'sexpected.tsvso two engines cannot agree on a wrong answer. CI installs the pinned 2.5.deb(SHA-256 verified) in its own job; locallySOUFFLE=/path bun run ir differential.Decisions
normalizeTrace()(N41) moves to V6 beside N42/N43, because wire relations are only useful once the external facts they join with exist; V5's fixtures are hand-authored.facts, which is what the differential needs regardless.invariants.tla(S15) is emitted and unread, per the shaping doc's non-goals.Verification
bun run typecheckpasses;bun test ir: 161 tests pass, with Soufflé present (differential tests ran against the real binary here).bun run ir compile --check,render --check,lint,differential: all green.🤖 Generated with Claude Code
https://claude.ai/code/session_01BX56nQPAsqYihopWfWy1xm