Represent RFC 2119 strength as facts and derive verdicts in Datalog - #49
Open
afogel wants to merge 2 commits into
Open
Represent RFC 2119 strength as facts and derive verdicts in Datalog#49afogel wants to merge 2 commits into
afogel wants to merge 2 commits into
Conversation
The judgement moves from TypeScript into the rule program. Each compiled provision's keyword becomes facts (strength, polarity), with the profiles that activate it, the non-wire relations it reads, and whether it is conditional on a permission; the run supplies negotiated(session, profile) and available(relation); nine rules derive fail, deviates, pass, unevaluated, not_activated and not_exercised per session. The published Soufflé program outputs the verdicts and the differential oracle compares them between engines and against expected-verdicts.tsv. A breached SHOULD is now a deviation, counted apart from a failure; 13 of the 69 compiled rules are SHOULDs and were reported as failures before. The keyword is the marked span's first RFC 2119 word. A record states its own, with keyword_basis, where the span has none (nine table cells and list items) or a misleading one: hooks.md's "MAY NOT return DENY", which RFC 2119 does not define, and two tables whose first keyword is a RECOMMENDED beside the MUST the rule checks. The join refuses a permission judged by anything but MAY and an obligation judged by MAY. A conditional provision is exercised when the positive atoms of its rule matched in the session. The old check read the Guardian-state relations a provision uses and treated an empty list as never exercised, so ACS-REQ-0102, which reads wire relations only, could never fail. The rule checker is its own module, shared by the provision compiler and the verdict layer. Fixture envelope.facts now list every seq, which is how a violation keyed by seq is attributed to its session. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BX56nQPAsqYihopWfWy1xm
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
|
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.
Stacked on #47. The RFC 2119 keyword a provision binds is now data the rule program reads, and the verdict a provision gets is derived by rules in both engines rather than decided in TypeScript.
What changed
strength(P, must|should|may)andpolarity(P, obligation|prohibition), besiderequires_profile,needs(the non-wire relations it reads),conditional,compiledandprovision. The run supplies two new vocabulary relations:negotiated(session, profile)from the ServerHello, andavailable(relation), every guardian-state, deployment and external relation the verifier was given. An empty relation and an absent one differ, and only the latter makes a provision unevaluated.fail,deviates,pass,unevaluated,not_activatedandnot_exercisedper session. Each compiled provision gets a projection rule attributing its violations to a session through a session column, or a seq column joined toenvelope; a provision with neither does not compile. A conditional provision is exercised when the positive atoms of its rule matched in the session. The published.dloutputs the six verdict relations, and the differential oracle compares them between engines and against a newexpected-verdicts.tsvper fixture. TypeScript only folds the per-session verdicts into the one the report shows.failbefore. The report now has adeviatesverdict, a deviating column in the per-profile table, and shows the keyword each provision is judged by.level). A record states its own, with a requiredkeyword_basis, where the span has none or a misleading one. Eleven records do: nine table cells and list items with no keyword (schema constraints, lowercase "required", "always"),hooks.md's "MAY NOT return DENY", which RFC 2119 does not define, and two tables whose first keyword is a RECOMMENDED beside the MUST the rule checks. The join refuses a permission judged by anything but MAY, an obligation judged by MAY, and a Requirement with no keyword at all.not_activatedis derived over every Requirement, compiled or not, so the report's precedence is unchanged: a permission in a profile the session never negotiated is still reported as not activated.What building it found
envelope.factswere empty. Attribution by seq needs a row per seq, so both fixtures now list every seq the other relations mention.MAY NOTand the nine keyword-free obligations, for upstream.Checks
tsc,bun test ir(189 pass), every--check(census, markers apply, extract, render, compile, both marker patches),lint: all clean.expected-verdicts.tsv.Not in this PR: "never" and "always" as census candidates for unmarked normative statements. The normative sources carry 15 such lines; each would need a binding or an exclusion, which is census work of its own.
🤖 Generated with Claude Code
https://claude.ai/code/session_01BX56nQPAsqYihopWfWy1xm
Generated by Claude Code