Conformance
Run the corpus against your implementation#
Fetch the index, fetch each fixture it names, and run each one: load the fixture's rules against the host described by input.capability, apply the input, and compare against expected. An implementation claiming conformance passes every fixture whose declared capability set it can adopt, and reports the ones it skipped. A skipped fixture is not a passed fixture, and the 139 fixtures the manifest marks baseline may not be skipped at all — their declared capability is one nothing conforming lacks.
curl https://openagentrules.org/spec/1.0/conformance/manifest.json
The runner algorithm#
The requirements below define the evaluation algorithm end to end. Each step is separately identified so a conformance fixture can cite it.
- [OAR-CONF-1] Load each rule document and validate it against the published OAR schema. An engine MUST reject a document that fails validation, naming the failing field. A rule set (
[OAR-DOC-31]) is not itself a schema-bearing document: an engine MUST validate each member against the rule schema individually, and no separate rule-set schema is published, because a collection carries no meaning of its own beyond the documents in it. - [OAR-CONF-2] An engine MUST check
oarbefore any other processing of a document, and reject an unsupported major or a greater minor ([OAR-DOC-4],[OAR-DOC-5]). - [OAR-CONF-3] An engine MUST resolve
anchor: a core anchor identifier through the anchor profile map, any other value against the declared host anchor catalogue ([OAR-PROF-5]). A value that is neither is a load rejection naming the value ([OAR-DOC-12]). - [OAR-CONF-4] An engine MUST reject a rule whose
requiresare not all provided by the host, and a rule referencing a non-core capability it does not declare inrequires([OAR-FACT-19],[OAR-FACT-20]). - [OAR-CONF-5] An engine MUST type-check
whenagainst the declared fact environment and MUST reject the rule on an unknown identifier or a type error. - [OAR-CONF-6] An engine MUST resolve
overridesandon_errorreferences, and reject an unresolvable one or a suppression cycle. - [OAR-CONF-7] An engine MUST apply configuration documents, rejecting one that names an unloaded rule or downgrades a mandatory rule.
- [OAR-CONF-8] At an anchor occurrence, an engine MUST select the rules whose resolved
anchormatches, whoseenforcementis notoff, and whose selector clauses all match. - [OAR-CONF-9] An engine MUST assemble the facts the selected rules reference, lazily where
[OAR-FACT-11]requires it. A fact provider failure MUST be handled per the rule'son_error. - [OAR-CONF-10] An engine MUST order evaluation as
[OAR-EVAL-1]requires — bykind, then by qualified identifier, amended by[OAR-EVAL-18]so each suppressor precedes the rules it names — and for each selected rule in that order MUST testflowbefore evaluatingwhen([OAR-EVAL-3]). - [OAR-CONF-11] An engine MUST record but not act on a rule whose
enforcementismonitor: no effect, no side-effect, no suppression, no short-circuit. - [OAR-CONF-12] An engine MUST apply suppression when a rule with
overridesfires, withdrawing the contribution of any already-evaluated rule it names. Suppression undoes what an earlier rule already contributed; it is not a short-circuit — evaluation continues (see[OAR-CONF-13]). The suppressed rule is still traced ([OAR-OPS-10]). - [OAR-CONF-13] The first enforced rule firing with
blockMUST short-circuit the occurrence; a rule firing withtransformMUST NOT. Short-circuit stops later rules from being evaluated at all; suppression ([OAR-CONF-12]) withdraws an already-evaluated contribution while evaluation continues. - [OAR-CONF-14] An engine MUST apply decision precedence:
block, thentransform, thennudge, thenwarn, otherwisenone. - [OAR-CONF-15] An engine MUST apply the
on_fireactions of every rule that fired and was enforced and was not suppressed. - [OAR-CONF-16] An engine MUST emit the applied-rules trace of
[OAR-OPS-9].
Fixtures (265)#
| Fixture | Covers | What it proves |
|---|---|---|
cfg-ambiguous-bare-reference-rejected | OAR-CFG-8 | A bare reference matching more than one rule is rejected, naming them (baseline) |
cfg-bare-reference-prefers-an-exact-qualified-match | OAR-CFG-8 | A bare reference names the unnamespaced rule exactly, even when a publisher ships the same id (baseline) |
cfg-bare-reference-resolves-across-namespaces | OAR-CFG-8, OAR-CFG-2 | An operator writes the bare id; it resolves against every loaded rule whatever its namespace (baseline) |
cfg-cannot-alter-what-a-rule-means | OAR-CFG-6 | A configuration changes whether and how loudly a rule runs, never what it means (baseline) |
cfg-disable-treats-a-rule-as-off | OAR-CFG-1, OAR-CFG-2, OAR-CONF-7 | A rule an operator disables behaves exactly as though its enforcement were off (baseline) |
cfg-enforcement-replaces-the-declared-value | OAR-CFG-3, OAR-CONF-7 | A configured enforcement replaces the rule's own (baseline) |
cfg-forward-minor-config-rejected | OAR-CFG-1 | A configuration written against a later minor is rejected, exactly as a document with one is (baseline) |
cfg-last-statement-about-a-rule-wins | OAR-CFG-7 | Configuration documents apply in order, and the last statement about a rule wins (baseline) |
cfg-mandatory-rule-cannot-be-disabled | OAR-CFG-5, OAR-OPS-7 | A configuration disabling a mandatory rule is rejected, naming the rule (baseline) |
cfg-mandatory-rule-cannot-be-downgraded | OAR-CFG-5, OAR-OPS-7 | A configuration downgrading a mandatory rule to monitor is rejected (baseline) |
cfg-qualified-reference-disambiguates | OAR-CFG-8, OAR-CFG-3 | The qualified form is required only when the bare one is actually ambiguous (baseline) |
cfg-unknown-rule-reference-rejected | OAR-CFG-4, OAR-CONF-7 | A configuration naming a rule that is not loaded is rejected, naming it (baseline) |
conf-core-anchor-fact-reports-the-core-spelling | OAR-CONF-29, OAR-PROF-1, OAR-FACT-15 | The core fact anchor reports the core identifier however the host spells the moment locally (baseline) |
conf-occurrence-anchor-is-host-local | OAR-CONF-29, OAR-PROF-4 | input.anchor is the right-hand side of anchors.core; the core identifier on the left does not select (baseline) |
conf-order-suppressor-precedes-only-the-rules-it-names | OAR-CONF-10, OAR-EVAL-18, OAR-EVAL-3 | A suppressor precedes only the rules it names; every other rule keeps its kind-then-identifier place |
conf-rule-set-members-validate-individually | OAR-CONF-1, OAR-DOC-31 | A rule set is not itself a schema-bearing document: each member is validated on its own terms (baseline) |
conf-selector-on-anchor-uses-the-core-spelling | OAR-CONF-29, OAR-SEL-7 | A selector clause on the core fact anchor matches the core identifier, not the host-local one (baseline) |
copy-canonical-double-integral | OAR-COPY-4, OAR-COPY-10 | copy canonical double integral |
copy-canonical-double-negative | OAR-COPY-4, OAR-COPY-10 | copy canonical double negative |
copy-canonical-double-negative-zero | OAR-COPY-4, OAR-COPY-10 | copy canonical double negative zero |
copy-canonical-double-small | OAR-COPY-4, OAR-COPY-10 | copy canonical double small |
copy-does-not-change-decision | OAR-COPY-6, OAR-DOC-24 | Rendered copy is presentation of the decision and does not change the effect or the winning rule |
copy-empty-members-remain-present | OAR-COPY-1, OAR-COPY-7 | copy empty members remain present (baseline) |
copy-if-else-and-not | OAR-COPY-3, OAR-COPY-7 | Copy conditionals take the if branch on a non-zero fact, the else branch otherwise, and not inverts the test |
copy-if-omits-zero | OAR-COPY-3, OAR-COPY-7, OAR-FACT-25 | A copy if-branch is omitted when the named fact is the zero value of its type |
copy-illegal-construct-rejected | OAR-COPY-3 | A copy member carrying a construct the binding grammar does not derive is a load error (baseline) |
copy-interpolates-facts | OAR-COPY-1, OAR-COPY-4, OAR-COPY-7, OAR-COPY-8 | After the decision, copy bindings substitute declared facts; list<string> joins with comma-space; whitespace in tags is insignificant |
copy-list-joins | OAR-COPY-4, OAR-COPY-7 | A list<string> binding interpolates as its members joined by comma-space |
copy-map-type-rejected | OAR-COPY-4 | A copy binding whose fact type cannot be interpolated is a load error |
copy-missing-endif-is-a-load-error | OAR-COPY-3 | copy missing endif is a load error (baseline) |
copy-nonempty-map-list-takes-if | OAR-COPY-3 | copy nonempty map list takes if |
copy-profile-fact-needs-requires | OAR-COPY-5, OAR-FACT-20 | A copy binding naming a non-core fact the rule does not reach through requires is a load error |
copy-unknown-fact-rejected | OAR-COPY-2, OAR-FACT-3 | A copy binding naming a fact the engine does not declare is a load error, never a runtime default (baseline) |
cs-content-length-threshold-is-in-the-rule | OAR-FACT-7, OAR-FACT-16 | The secrets profile publishes a length; the rule decides what is too long |
cs-jailbreak-score-below-threshold-passes | OAR-OPS-11, OAR-CONF-25 | A score below the rule's threshold does not fire; the detector never decided |
doc-bare-id-is-the-qualified-identifier | OAR-DOC-8, OAR-EVAL-8 | A rule with no namespace has the bare id as its qualified identifier — no separator, no host name (baseline) |
doc-copy-does-not-affect-the-decision | OAR-DOC-24, OAR-EVAL-19 | Two rules differing only in copy produce the same effect, and copy never reorders them (baseline) |
doc-copy-member-outside-the-closed-set-rejected | OAR-DOC-24 | copy carries a closed set of presentation strings (baseline) |
doc-current-minor-loads | OAR-DOC-5 | Every minor less than or equal to the engine's own is accepted (baseline) |
doc-detector-forbidden-for-other-kinds | OAR-DOC-23 | A detector object on any other kind is rejected (baseline) |
doc-detector-required-for-detector-kind | OAR-DOC-23 | kind: detector without a detector object is rejected (baseline) |
doc-duplicate-qualified-identifier-rejected | OAR-DOC-9 | Two rules with the same qualified identifier are a load-time rejection (baseline) |
doc-empty-flow-rejected | OAR-DOC-15, OAR-CONF-1 | A flow that is present must be non-empty; the empty list is rejected rather than assigned a meaning (baseline) |
doc-enforcement-defaults-to-enforce | OAR-DOC-16 | A document with no enforcement enforces (baseline) |
doc-forward-minor-rejected | OAR-DOC-5, OAR-CONF-2 | A minor greater than the engine's own is refused rather than partly honoured (baseline) |
doc-malformed-id-rejected | OAR-DOC-6, OAR-CONF-1 | id must match the published pattern (baseline) |
doc-mandatory-and-overrides-default | OAR-DOC-17, OAR-DOC-20 | mandatory defaults to false and overrides to the empty list, so an ordinary rule is suppressible (baseline) |
doc-minimal-rule-loads-and-fires | OAR-DOC-1, OAR-DOC-2, OAR-DOC-11, OAR-EVAL-3, OAR-CONF-1 | A document with only the five obligatory fields loads and fires (baseline) |
doc-missing-required-field-rejected | OAR-DOC-2, OAR-CONF-1, OAR-CONF-21 | A document without effect is rejected, naming the field (baseline) |
doc-on-error-defaults-to-fail-closed | OAR-DOC-18, OAR-OPS-3 | A rule that cannot be evaluated and declares no on_error blocks under its own identifiers (baseline) |
doc-on-fire-defaults-to-empty | OAR-DOC-19, OAR-FACT-10 | A rule with no on_fire changes no counter, and its condition changes none either (baseline) |
doc-qualified-identity-distinguishes-publishers | OAR-DOC-8, OAR-EVAL-8, OAR-EVAL-9, OAR-EVAL-19 | Two documents sharing an id under different namespaces are distinct rules and both load (baseline) |
doc-references-do-not-affect-the-decision | OAR-DOC-25 | Interoperability taxonomy tags never affect a decision (baseline) |
doc-related-target-need-not-be-loaded | OAR-DOC-30 | related records lineage, never affects a decision, and its target need not be loaded (baseline) |
doc-rule-set-member-must-be-a-document | OAR-DOC-31 | A rule set containing a member that is not a rule document is rejected (baseline) |
doc-rule-set-position-does-not-set-order | OAR-DOC-31, OAR-DOC-28, OAR-EVAL-1 | A member's position in the collection never affects identity, ordering, or precedence (baseline) |
doc-status-does-not-affect-the-decision | OAR-DOC-29 | status records the author's confidence and is inert (baseline) |
doc-transform-forbidden-for-other-effects | OAR-DOC-22 | A transform object on any other effect is rejected (baseline) |
doc-transform-required-for-transform-effect | OAR-DOC-22 | effect: transform without a transform object is rejected |
doc-undefined-field-emit-rejected | OAR-DOC-27 | A field this specification does not define is rejected, naming it (baseline) |
doc-undefined-severity-field-rejected | OAR-DOC-27 | severity was never a field of this format and is rejected (baseline) |
doc-undefined-top-level-copy-fields-rejected | OAR-DOC-27 | The pre-release top-level copy fields are gone and are rejected by name (baseline) |
doc-unknown-effect-rejected | OAR-DOC-11 | effect is a closed enumeration (baseline) |
doc-unknown-kind-rejected | OAR-DOC-10 | kind is a closed enumeration (baseline) |
doc-unsupported-major-rejected | OAR-DOC-4, OAR-CONF-2 | A major version this engine does not implement is refused, not coerced (baseline) |
doc-version-checked-before-undefined-field | OAR-CONF-2 | oar is checked before any other processing, so a bad version wins over a bad field (baseline) |
doc-version-leading-zero-rejected | OAR-DOC-3, OAR-CONF-1 | A version part with a leading zero is not a version; two engines free to equate 01.0 and 1.0 would disagree about what loads (baseline) |
doc-x-extension-is-ignored | OAR-DOC-26 | An x- extension the engine does not recognise is ignored, and never affects the decision (baseline) |
eval-advisories-accumulate-in-evaluation-order | OAR-EVAL-8, OAR-EVAL-19, OAR-EVAL-20, OAR-COPY-7, OAR-COPY-9, OAR-CONF-37 | Two nudges at one occurrence both appear, in evaluation order, neither discarding the other (baseline) |
eval-advisories-omit-a-monitor-rule | OAR-EVAL-20, OAR-EVAL-10 | A monitor nudge is recorded and does not appear on advisories (baseline) |
eval-advisories-omit-a-suppressed-rule | OAR-EVAL-20, OAR-EVAL-14 | A suppressed nudge does not appear on advisories (baseline) |
eval-advisories-warns-accumulate | OAR-EVAL-20, OAR-COPY-9, OAR-CONF-37 | Two warnings at one occurrence both appear, in evaluation order (baseline) |
eval-allow-contributes-no-decision | OAR-EVAL-7 | A rule firing with allow records an explicit pass and never overrides another rule (baseline) |
eval-block-short-circuits | OAR-EVAL-4, OAR-CONF-13, OAR-OPS-10 | The first enforced rule firing with block stops the occurrence; later rules are not evaluated (baseline) |
eval-decision-carries-both-identifiers | OAR-EVAL-8, OAR-EVAL-9 | A decision carries the effect, the bare id, and the qualified identifier (baseline) |
eval-flow-is-tested-before-when | OAR-EVAL-3 | when is not evaluated when flow did not match, so a rule the flow excluded cannot raise |
eval-flow-matched-then-when-is-evaluated | OAR-EVAL-3 | When flow does match, when is evaluated and may raise |
eval-kind-does-not-decide | OAR-EVAL-2, OAR-EVAL-6 | kind carries no meaning beyond order: a later-ordered rule's effect still wins on precedence (baseline) |
eval-mandatory-rule-cannot-be-overridden | OAR-EVAL-17, OAR-OPS-7 | An overrides entry naming a mandatory rule is a load-time rejection (baseline) |
eval-monitor-does-not-short-circuit-or-suppress | OAR-EVAL-10, OAR-CONF-11 | A monitored rule neither short-circuits the occurrence nor suppresses the rule it overrides (baseline) |
eval-monitor-records-without-acting | OAR-EVAL-10, OAR-OPS-1, OAR-CONF-11, OAR-FIRE-2 | A monitored rule is evaluated and recorded, contributes no decision and applies no side-effect (baseline) |
eval-monitor-rule-that-raises-does-not-block | OAR-EVAL-10, OAR-OPS-1 | A monitor rule that cannot be evaluated is recorded errored and its on_error is not applied (baseline) |
eval-no-rule-fires-is-none | OAR-EVAL-6 | An occurrence at which nothing fires resolves to none (baseline) |
eval-off-is-not-selected-or-recorded | OAR-EVAL-11, OAR-OPS-2 | A rule whose enforcement is off is not selected, not evaluated, and not in the trace (baseline) |
eval-off-still-loads-and-reports-load-errors | OAR-EVAL-11, OAR-OPS-2 | A rule whose enforcement is off remains loaded, so a load-time error in it is still reported (baseline) |
eval-order-is-kind-then-qualified-id | OAR-EVAL-1, OAR-CONF-10, OAR-OPS-10 | Evaluation runs schema, policy, invariant, detector, then ascending by qualified identifier (baseline) |
eval-overrides-cycle-rejected | OAR-EVAL-16, OAR-CONF-6 | A suppression cycle is a load-time rejection, naming the rules in it (baseline) |
eval-overrides-unresolvable-reference-rejected | OAR-EVAL-13, OAR-CONF-6 | An overrides entry that resolves to no loaded rule is a load-time rejection, naming it (baseline) |
eval-precedence-nudge-over-warn | OAR-EVAL-6, OAR-EVAL-20, OAR-CONF-14 | nudge outranks warn whatever order the two fire in (baseline) |
eval-precedence-transform-over-nudge-and-warn | OAR-EVAL-6, OAR-EVAL-20, OAR-CONF-14 | transform outranks nudge, and nudge outranks warn |
eval-side-effects-of-losing-rule-still-apply | OAR-EVAL-12, OAR-CONF-15 | on_fire applies to every rule that fired and was enforced, including one whose effect lost precedence (baseline) |
eval-side-effects-of-unreached-rule-do-not-apply | OAR-EVAL-12 | A rule never reached because of a short-circuit applies no side-effect (baseline) |
eval-suppression-does-not-transit | OAR-EVAL-15 | If A overrides B and B overrides C, A firing suppresses B but not C (baseline) |
eval-suppression-withdraws-side-effects-too | OAR-EVAL-14, OAR-CONF-12, OAR-EVAL-12 | A suppressed rule contributes no decision and applies no side-effect (baseline) |
eval-suppressor-is-evaluated-first | OAR-EVAL-18, OAR-EVAL-1 | A suppressor is evaluated before the rule it names, even when the base order puts the block first (baseline) |
eval-suppressor-ordering-disturbs-base-order-least | OAR-EVAL-18 | Only the constrained pair moves; every other rule keeps its kind-and-identifier place (baseline) |
eval-transform-does-not-short-circuit | OAR-EVAL-5, OAR-CONF-13 | A rule firing with transform lets later rules run |
expr-additional-builtin-rejected | OAR-EXPR-16 | A function the engine does not declare is an unknown identifier, not a built-in |
expr-aggregate-equality-rejected | OAR-EXPR-21 | Equality over two aggregate values is rejected at load rather than implemented element-wise |
expr-arithmetic-operand-pair-rejected | OAR-EXPR-9 | An arithmetic operand pair outside the typed set is refused at load (baseline) |
expr-chained-relation-rejected | OAR-EXPR-1, OAR-EXPR-4 | A relation admits at most one relational operator, whatever the precedence table suggests (baseline) |
expr-comment-rejected | OAR-EXPR-6 | A comment is not part of the language (baseline) |
expr-division-by-zero-raises | OAR-EXPR-14, OAR-OPS-3, OAR-OPS-4 | Division by zero raises, and the rule is handled per its on_error (baseline) |
expr-dotted-identifier-is-a-single-name | OAR-EXPR-1, OAR-FACT-3, OAR-EXPR-19 | A dotted identifier is one host-tier name, so tool_args.path is an unknown identifier rather than field selection |
expr-double-division-by-zero-raises | OAR-EXPR-14, OAR-OPS-3 | Division by a double zero raises rather than producing an IEEE infinity, and fail_closed then blocks with the rule's identifiers (baseline) |
expr-double-literal-overflow-rejected | OAR-EXPR-21 | A double literal whose nearest binary64 value is not finite is rejected at load (baseline) |
expr-double-overflow-raises | OAR-EXPR-14 | expr double overflow raises (baseline) |
expr-empty-affix-matches-every-string | OAR-EXPR-22 | An empty prefix, suffix, or substring matches every string |
expr-empty-list-literal-rejected | OAR-EXPR-21 | The empty list literal is rejected because its type cannot be inferred |
expr-field-selection-rejected | OAR-EXPR-1 | There is no field-selection operator: a "." after anything but a name is rejected, naming the construct and its offset |
expr-fifth-builtin-rejected | OAR-EXPR-16, OAR-EXPR-23 | A built-in this specification does not define is an unknown identifier |
expr-index-operand-pair-rejected | OAR-EXPR-13 | An index operand pair outside the typed set is refused at load |
expr-index-out-of-range-raises | OAR-EXPR-13, OAR-OPS-3 | Indexing a list out of range raises, and the rule is handled per its on_error |
expr-index-typed-list-of-maps | OAR-EXPR-13 | list<map> indexed by int yields map, which supports in and size only |
expr-int-double-comparison-promotes | OAR-EXPR-11, OAR-FACT-23 | One int and one double compare after promotion, and only for the comparison |
expr-int-overflow-raises | OAR-EXPR-15, OAR-FACT-23 | Integer arithmetic that overflows 64 bits raises rather than wrapping (baseline) |
expr-integer-division-truncates-toward-zero | OAR-EXPR-21 | Integer division truncates toward zero, and the remainder takes the sign of the dividend (baseline) |
expr-least-int-value-is-writable | OAR-EXPR-21, OAR-FACT-23 | The magnitude 9223372036854775808 is admitted as the immediate operand of unary minus (baseline) |
expr-list-literal-members-must-agree | OAR-EXPR-21 | A list literal takes the type of its members, which must all agree |
expr-list-of-ints-has-no-declarable-type | OAR-EXPR-21, OAR-FACT-22 | A list literal of agreeing members is still rejected when no list type of that member exists (baseline) |
expr-literal-newline-in-string-rejected | OAR-EXPR-1 | expr literal newline in string rejected (baseline) |
expr-map-literal-rejected | OAR-EXPR-1 | A map literal is outside the grammar (baseline) |
expr-map-string-string-is-a-map-for-in-and-size | OAR-EXPR-21, OAR-EXPR-12, OAR-EXPR-13 | A map<string,string> host fact answers in and size(), and indexes to a string |
expr-map-supports-in-and-size | OAR-EXPR-19 | in tests key presence on a map and size counts its members |
expr-minimum-integer-unary-node-count | OAR-EXPR-17, OAR-EXPR-20 | expr minimum integer unary node count (baseline) |
expr-modulo-by-zero-raises | OAR-EXPR-14 | Modulo by zero raises (baseline) |
expr-modulo-takes-two-ints | OAR-EXPR-9 | % takes two int operands (baseline) |
expr-negative-list-index-raises | OAR-EXPR-21, OAR-EXPR-13 | A negative list index raises, as an out-of-range one does |
expr-null-is-an-unknown-identifier | OAR-EXPR-7 | There is no null value: null is rejected as an unknown identifier |
expr-oversized-integer-literal-rejected | OAR-EXPR-21, OAR-EXPR-15 | An integer literal that does not fit 64 bits is rejected at load (baseline) |
expr-parse-tree-above-the-declared-limit-rejected | OAR-EXPR-17, OAR-EXPR-20 | A parse tree above the engine's declared ceiling is refused, and the ceiling is in the capability document (baseline) |
expr-parse-tree-of-256-nodes-accepted | OAR-EXPR-17, OAR-EXPR-20 | An engine accepts a condition whose parse tree holds 256 nodes, the published floor (baseline) |
expr-precedence-table-does-not-extend-the-grammar | OAR-EXPR-4 | a < b < c is not derivable, so it is rejected rather than grouped by the precedence table (baseline) |
expr-reserved-word-is-lexed-greedily | OAR-EXPR-24 | A name beginning with a reserved word is one identifier, not two tokens |
expr-short-circuit-avoids-a-raise | OAR-EXPR-5 | A false left operand of && stops the right one from raising (baseline) |
expr-short-circuit-guards-a-partial-subexpression | OAR-EXPR-5 | The right operand is not evaluated when the left decides the result, so the guard holds |
expr-single-quoted-words-are-not-references | OAR-EXPR-1, OAR-FACT-20 | expr single quoted words are not references (baseline) |
expr-size-is-the-only-builtin | OAR-EXPR-16 | size counts Unicode code points on a string, and no other built-in exists |
expr-string-builtins-do-not-fold-case | OAR-EXPR-22 | The string built-ins compare by code point and never fold case |
expr-string-builtins-match | OAR-EXPR-16 | The three string built-ins match a prefix, a suffix, and a substring |
expr-string-concatenation-accepted | OAR-EXPR-9 | + concatenates two strings |
expr-string-escapes-accepted | OAR-EXPR-3 | The closed escape set is accepted, including a four-digit \u escape |
expr-ternary-branches-must-share-a-type | OAR-EXPR-8 | The ternary condition is bool and its branches share a type |
expr-type-confused-comparison-rejected | OAR-EXPR-11 | A comparison between unrelated types is refused at load rather than silently never firing |
expr-typed-accessor-reaches-a-map-member | OAR-EXPR-19, OAR-FACT-9 | A declared observation function reaches a map member with a type known at load |
expr-unary-binds-tighter-than-multiplication | OAR-EXPR-4 | The precedence table governs how the grammar groups what it does derive (baseline) |
expr-unparameterised-map-cannot-be-indexed | OAR-EXPR-19 | A fact of the unparameterised type map may not be indexed; it supports only in and size |
expr-unsupported-escape-rejected | OAR-EXPR-3 | An escape outside the closed set is rejected |
fact-condition-outside-requires-rejected | OAR-FACT-20, OAR-CONF-4 | A condition reaching a profile fact the rule did not declare in requires is refused |
fact-condition-type-error-rejected | OAR-FACT-4, OAR-CONF-5 | A condition that is not type-correct against the declared environment is refused at load |
fact-content-provenance-distinguishes-untrusted-tool-data | OAR-FACT-16 | The content-provenance profile exposes host-attributed segment authority and trust without inspecting content text |
fact-copy-runtime-type-error-uses-on-error | OAR-FACT-26, OAR-COPY-5, OAR-COPY-11 | fact copy runtime type error uses on error |
fact-core-tier-needs-no-requires | OAR-FACT-15 | Every conforming engine provides the core facts, so a rule over them needs no requires at all (baseline) |
fact-detector-facts-are-assembled-lazily | OAR-FACT-11, OAR-CONF-9 | A detector is not run for a rule the selector did not select, so detector://error never fails |
fact-detector-observations-are-rule-local | OAR-FACT-11 | A detector finding produced for one rule is not visible to a later rule |
fact-detector-reports-observations-rule-owns-threshold | OAR-FACT-5, OAR-FACT-7, OAR-FACT-8, OAR-OPS-11, OAR-CONF-25 | The detector reports spans and scores; the rule sets the threshold, and two rules may disagree |
fact-flow-longer-than-window-rejected | OAR-FACT-13, OAR-PROF-3 | A flow longer than the host's declared activity window is refused at load |
fact-flow-matches-a-non-contiguous-subsequence | OAR-FACT-12 | flow matches when its steps appear in order in the activity window, contiguous or not |
fact-flow-out-of-order-does-not-match | OAR-FACT-12 | The steps must appear in the order flow gives them |
fact-flow-rejected-when-window-is-zero | OAR-PROF-3, OAR-FACT-13 | A host that tracks no recent activity declares zero and rejects every rule carrying flow (baseline) |
fact-host-fact-must-be-namespaced | OAR-FACT-14, OAR-FACT-18, OAR-FACT-24 | A host-tier fact published under a bare name belongs to no tier and is refused |
fact-host-fact-must-sit-under-the-host-namespace | OAR-FACT-18, OAR-FACT-24 | A host-tier fact under a namespace the host does not own is refused |
fact-host-fact-zero-at-unreported-occurrence | OAR-FACT-25 | fact host fact zero at unreported occurrence |
fact-host-tier-fact-loads-and-fires | OAR-FACT-18, OAR-FACT-21, OAR-CONF-23 | A rule reaching a host-tier fact through requires.facts loads and fires; the capability document says so |
fact-moderation-rule-owns-the-threshold | OAR-FACT-16 | The classifier reports a score per category and the rule sets the bar |
fact-name-of-an-unclaimed-profile-is-not-declared | OAR-FACT-17, OAR-FACT-19, OAR-CONF-20 | A host that does not claim a profile declares none of its names, so a rule reaching for one is refused (baseline) |
fact-non-boolean-condition-rejected | OAR-FACT-4 | A rejection for a non-boolean result names the type produced and the word bool |
fact-observation-function-supplied-by-fixture | OAR-FACT-9, OAR-CONF-26 | A value supplied under an observation function's name is that function's result for every argument |
fact-profile-is-provided-whole | OAR-FACT-16 | A host claiming a profile provides every member of it, not a convenient subset |
fact-requires-facts-reaches-one-name | OAR-FACT-20 | requires.facts reaches an individual name without claiming the whole profile |
fact-requires-unprovided-profile-rejected | OAR-FACT-19, OAR-CONF-4, OAR-CONF-20 | A rule naming a profile the host does not provide is refused at load, naming both (baseline) |
fact-root-must-be-boolean | OAR-FACT-4 | fact root must be boolean (baseline) |
fact-runtime-type-error-uses-on-error | OAR-FACT-26 | fact runtime type error uses on error |
fact-tool-fingerprint-canonical-arguments | OAR-FACT-28, OAR-CONF-40 | fact tool fingerprint canonical arguments |
fact-transform-target-is-assembled | OAR-FACT-11, OAR-CONF-9 | A transform target is a fact reference, so it is assembled even when the rule has no when |
fact-transform-target-needs-requires | OAR-FACT-20 | fact transform target needs requires |
fact-undeclarable-type-rejected | OAR-FACT-22, OAR-FACT-24 | A capability document declaring a fact type outside the published set is refused |
fact-unknown-identifier-rejected | OAR-FACT-3, OAR-FACT-1, OAR-CONF-5 | A condition naming something that is not a declared fact or function is refused at load (baseline) |
fact-unreported-fact-does-not-take-the-on-error-path | OAR-FACT-25, OAR-OPS-3 | An unreported fact is not a provider failure, so a fail_closed rule over one does not block |
fact-unreported-fact-takes-its-zero-value | OAR-FACT-25, OAR-CONF-9 | A declared fact the host has nothing to report for reads as the zero value of its type, never a failure |
fact-unreported-observation-function-takes-its-zero-value | OAR-FACT-25, OAR-CONF-26 | An observation function the fixture did not supply returns the zero value of its declared return type |
fact-window-is-ordered-oldest-first | OAR-FACT-12 | The activity window reads oldest step first, so flow reads in the order the steps happened |
fact-window-newest-first-would-not-match | OAR-FACT-12 | The same steps in the opposite order do not match, which is what fixes the window's direction |
fire-actions-apply-in-declaration-and-evaluation-order | OAR-FIRE-8 | The actions of one rule apply in the order listed, and rules apply in evaluation order (baseline) |
fire-actions-bind-to-their-core-facts | OAR-FIRE-3, OAR-CONF-15 | increment_counter writes fire_count and increment_breaker writes breaker_count (baseline) |
fire-count-counts-increments-not-firings | OAR-FIRE-3, OAR-FIRE-4, OAR-EVAL-19 | fire_count counts applications of increment_counter, so a rule that fires with no on_fire has zero (baseline) |
fire-count-of-escalates-across-occurrences | OAR-FIRE-11, OAR-CONF-31 | One rule counts and two read the count, so warn-then-block is expressible (baseline) |
fire-count-of-non-literal-argument-rejected | OAR-FIRE-11 | A counter read whose argument is not a string literal is refused at load |
fire-count-of-unresolvable-reference-rejected | OAR-FIRE-11 | A counter read naming no loaded rule is refused at load (baseline) |
fire-counter-scope-keys-the-counter | OAR-FIRE-10, OAR-FIRE-5, OAR-CONF-33 | A scoped counter counts each distinct scope value separately |
fire-counter-scope-non-string-fact-rejected | OAR-FIRE-10 | A counter scope naming a fact that is not a string is refused at load |
fire-counter-scope-undeclared-profile-fact-rejected | OAR-FIRE-10 | A counter scope naming a profile fact the rule does not require is refused at load |
fire-counter-scope-unknown-fact-rejected | OAR-FIRE-10 | A counter scope naming a fact the engine does not declare is refused at load (baseline) |
fire-counter-scope-with-an-empty-value-stays-scoped | OAR-FIRE-10, OAR-CONF-33 | A rule declaring counter_scope keeps a scoped counter even when the scope value is empty |
fire-counters-are-keyed-by-qualified-identifier | OAR-FIRE-5 | Two rules sharing a bare id under different namespaces keep separate counters (baseline) |
fire-every-condition-sees-the-same-counter-snapshot | OAR-FIRE-6 | A rule's own increment cannot change the value its own condition just read (baseline) |
fire-indirect-scope-requires-declaration | OAR-FIRE-11 | Counter readers declare the target scope dependency |
fire-own-count-reads-previous-occurrence | OAR-FIRE-3, OAR-FIRE-6 | fire own count reads previous occurrence (baseline) |
fire-publish-event-writes-no-fact | OAR-FIRE-3, OAR-FIRE-7 | publish_event emits a record and is not observable to any condition (baseline) |
fire-reset-sets-the-counter-to-zero | OAR-FIRE-3 | reset_counter and reset_breaker set their bound fact to zero (baseline) |
fire-scope-needs-declared-capability | OAR-FIRE-10, OAR-FACT-20 | fire scope needs declared capability |
fire-unknown-side-effect-rejected | OAR-FIRE-1 | on_fire draws from a closed vocabulary (baseline) |
mcp-bridged-call-facts | OAR-FACT-16, OAR-FACT-2 | The mcp profile's facts and its _for accessors are distinct names and both work |
mcp-error-code-is-a-machine-code | OAR-SEL-8 | A failed bridged call reports a machine error code, never free text, and the rule matches it exactly |
mcp-result-projection-accessors | OAR-FACT-9 | The mcp projection accessors carry declared return types, so a condition over them checks at load |
ops-annotate-then-redact-same-span | OAR-OPS-21, OAR-OPS-16 | Annotating and then redacting the same span yields the redaction followed by the annotation, not the redaction alone |
ops-annotation-inside-covering-rewrite | OAR-OPS-16, OAR-OPS-21, OAR-OPS-23, OAR-CONF-39 | ops annotation inside covering rewrite |
ops-bare-substitute-prefers-own-namespace | OAR-DOC-8, OAR-OPS-5 | ops bare substitute prefers own namespace (baseline) |
ops-block-discards-accumulated-transforms | OAR-OPS-17, OAR-EVAL-6 | A block at an occurrence discards every accumulated transform: nothing is delivered to mutate |
ops-content-anchor-evaluation-is-buffered | OAR-OPS-8 | A content anchor is evaluated once, over the fully assembled content |
ops-detector-produced-facts-reach-the-transform | OAR-CONF-25, OAR-FACT-11, OAR-OPS-15 | A span fact the detector produced at run time is the one the transform rewrites; content comes back changed, not merely reported changed |
ops-detector-transform-facts-are-rule-local | OAR-FACT-11, OAR-OPS-15 | Each accumulated transform uses the detector facts assembled for its own rule |
ops-error-short-circuit-retains-suppressed | OAR-OPS-10 | ops error short circuit retains suppressed (baseline) |
ops-fail-closed-blocks-and-stops | OAR-OPS-3, OAR-OPS-9, OAR-CONF-9, OAR-CONF-25 | A rule that cannot be evaluated with on_error fail_closed blocks and stops the occurrence (baseline) |
ops-fail-open-records-and-continues | OAR-OPS-4 | A rule that cannot be evaluated with on_error fail_open contributes nothing and evaluation continues (baseline) |
ops-load-errors-are-not-routed-through-on-error | OAR-OPS-3, OAR-CONF-5 | An unknown identifier is a load-time rejection even when on_error says fail_open (baseline) |
ops-monitor-outcome-says-which-way-it-went | OAR-OPS-9, OAR-EVAL-10 | Monitor mode records whether the rule would have fired, which is the only question it exists to answer (baseline) |
ops-on-error-bare-reference-stays-in-namespace | OAR-OPS-5 | A bare on_error reference does not resolve to the same id in another namespace (baseline) |
ops-on-error-naming-an-unloaded-rule-rejected | OAR-OPS-5, OAR-CONF-6 | An on_error naming a rule that is not loaded is a load-time rejection (baseline) |
ops-on-error-substitute-not-selected-at-its-anchor | OAR-OPS-5 | The substituted rule need not be selected at this anchor: substitution is a reference into the loaded set, not a second evaluation |
ops-on-error-substitutes-another-rules-identifiers | OAR-OPS-5 | on_error naming a rule blocks under that rule's identifiers, and the effect is still block (baseline) |
ops-overlapping-transforms-are-not-merged | OAR-OPS-16, OAR-EVAL-19 | Two transforms whose targets overlap apply in order rather than being merged or reordered |
ops-redact-then-annotate-same-span | OAR-OPS-21, OAR-OPS-16 | Redacting a span and then annotating it yields both, in that order: a zero-width annotation overlaps nothing |
ops-skipped-span-record | OAR-OPS-23, OAR-CONF-39 | ops skipped span record |
ops-suppressed-rule-is-traced-through-a-short-circuit | OAR-OPS-10, OAR-EVAL-14, OAR-EVAL-18 | A rule suppressed by a blocking suppressor is recorded suppressed, not omitted as never considered (baseline) |
ops-trace-records-every-outcome | OAR-OPS-9, OAR-OPS-10, OAR-CONF-16 | The trace records fired, passed, errored, monitored, and suppressed, in evaluation order (baseline) |
ops-transform-annotate-content-appends-at-the-end | OAR-OPS-21 | annotate on a content target inserts at the end of the content |
ops-transform-annotate-inserts-after-the-span | OAR-OPS-21 | annotate inserts its replacement immediately after the span end and removes nothing |
ops-transform-annotate-records-a-zero-width-rewrite | OAR-OPS-21, OAR-OPS-16 | An annotate does not consume the span it annotated, so a later transform over it still applies |
ops-transform-annotate-requires-replacement | OAR-OPS-13 | annotate must carry a replacement: an annotation with nothing to annotate with is not a transform |
ops-transform-block-discards-the-mutation | OAR-OPS-17 | A block at the occurrence leaves the content untouched |
ops-transform-offsets-are-original-coordinates | OAR-OPS-16, OAR-OPS-20 | A later transform’s offsets are read against the original content, not the earlier output |
ops-transform-overlapping-spans-merge | OAR-OPS-20 | Two overlapping spans in one transform are rewritten once, as a single covering span |
ops-transform-redact-may-omit-replacement | OAR-OPS-13 | redact may omit its replacement, and the engine substitutes its own placeholder |
ops-transform-redact-with-replacement-is-replace | OAR-OPS-21 | redact carrying a replacement and replace carrying the same one produce the same rewrite |
ops-transform-redact-without-replacement-uses-the-fixed-placeholder | OAR-OPS-13, OAR-OPS-21 | redact with no replacement substitutes exactly the code points [REDACTED] |
ops-transform-rejected-when-unimplemented | OAR-OPS-18 | An engine that does not implement content mutation refuses the rule rather than degrading it (baseline) |
ops-transform-replace-requires-replacement | OAR-OPS-13 | replace must carry a replacement |
ops-transform-span-out-of-range-is-ignored | OAR-OPS-19 | A span whose range falls outside the content is ignored rather than raising |
ops-transform-span-over-an-earlier-rewrite-is-skipped | OAR-OPS-16, OAR-OPS-20 | A span overlapping a range an earlier transform rewrote is not applied, and is not clamped |
ops-transform-span-without-start-and-end-rejected | OAR-OPS-19 | A span carrying neither start nor end cannot be applied |
ops-transform-spans-apply-highest-start-first | OAR-OPS-20, OAR-OPS-19, OAR-CONF-34 | Two spans in one transform are applied from the highest start, so the earlier offsets still land |
ops-transform-target-must-be-content-or-a-list-map-fact | OAR-OPS-14 | A target naming anything else is a load-time rejection |
ops-transform-whole-content-target | OAR-OPS-14, OAR-CONF-34 | A transform naming the whole content replaces all of it |
ops-transforms-accumulate-in-evaluation-order | OAR-OPS-15, OAR-OPS-16, OAR-EVAL-5, OAR-EVAL-8 | Two transforms at one occurrence both apply, in evaluation order, neither discarding the other |
ops-unresolvable-detector-reference-rejected | OAR-OPS-12 | A kind: detector rule whose reference the engine cannot resolve is refused at load (baseline) |
prof-anchor-map-declaring-one-twice-rejected | OAR-PROF-2, OAR-FACT-24 | A core anchor declared both supported and unsupported is a rejection (baseline) |
prof-anchor-map-omitting-a-core-anchor-rejected | OAR-PROF-2, OAR-FACT-24 | Every core anchor appears exactly once across core and unsupported (baseline) |
prof-core-anchor-maps-to-a-local-name | OAR-PROF-1, OAR-CONF-3, OAR-CONF-29 | A rule names the core anchor; the occurrence names the local one the host mapped it to (baseline) |
prof-history-records-admitted-tool-names | OAR-PROF-9, OAR-CONF-40 | prof history records admitted tool names |
prof-host-native-anchor-loads | OAR-PROF-5, OAR-PROF-8, OAR-CONF-3 | A host-native anchor is a valid document and loads; it is simply not portable, which is not a load failure (baseline) |
prof-secrets-claim-requires-a-detector | OAR-OPS-22, OAR-FACT-24 | A capability document claiming secrets with no registered detector is invalid: zero-valued scores are not the observation |
prof-uncatalogued-anchor-rejected | OAR-PROF-5, OAR-DOC-12, OAR-CONF-3 | An anchor that is neither core nor in the declared host catalogue is a load error, naming the value: a misspelled anchor must not silently never run (baseline) |
prof-unsupported-core-anchor-rejected | OAR-PROF-4, OAR-DOC-12, OAR-CONF-3, OAR-CONF-20 | A rule targeting a core anchor the host declares unsupported is refused, naming the anchor (baseline) |
sel-anchor-clause-is-core | OAR-SEL-7, OAR-FACT-15 | The core fact anchor may be named by a clause without any requires (baseline) |
sel-capability-host-string-is-selectable | OAR-SEL-3, OAR-FACT-27 | sel capability host string is selectable |
sel-clause-matches-by-membership | OAR-SEL-7, OAR-CONF-8 | A selector clause matches when the fact it names is a member of the clause list |
sel-clause-naming-untyped-fact-rejected | OAR-SEL-3 | A clause naming a fact that is neither string nor list<string> is a load error |
sel-clause-not-matching-deselects | OAR-SEL-7, OAR-CONF-8, OAR-OPS-9 | A rule whose clause does not match is not selected and does not appear in the trace |
sel-clause-outside-core-needs-requires | OAR-FACT-20, OAR-CONF-4 | A selector clause naming a profile fact the rule does not declare in requires is rejected |
sel-clauses-are-conjunctive | OAR-SEL-7 | Every clause present must match for the rule to be selected |
sel-empty-clause-loads-and-never-selects | OAR-SEL-6 | A clause whose value is the empty list matches nothing; the rule still loads |
sel-list-fact-matches-on-intersection | OAR-SEL-7 | A clause naming a list<string> fact matches on a non-empty intersection |
sel-matches-typed-facts-not-prose | OAR-SEL-8 | A clause matches a fact value exactly; it is never a substring or keyword search |
sel-unknown-fact-clause-rejected | OAR-SEL-3, OAR-FACT-1 | A clause naming a fact the engine does not declare is a load error, never a silent match (baseline) |