Judgment Pack Core 0.3.0
On this page
Status
This document is a draft. It may change incompatibly and MUST NOT be represented as an industry standard or as suitable, by conformance alone, for consequential decisions.
0.3.0 defines four conformance classes: carrier, structural, and semantic document
conformance, and evaluator conformance (§3.4). Sections 7 and 8 are normative for an implementation
that claims the evaluator class and informative for every other consumer; a document-conformance
claim does not depend on them. This release adds document profiles and routed escalations and
tightens carrier admission to require pairing for Unicode escapes in the UTF-16 surrogate range.
Migration from 0.2.0-draft requires revalidation; changing only the version selector is sufficient
only for documents that already meet the current carrier, structural and semantic requirements.
Re-declaration opts the pack into this release's exact evaluator semantics and corpus and confers no
conformance on any implementation (§11).
The key words MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT, and MAY are to be interpreted as described by BCP 14 when, and only when, they appear in all capitals. Normative references are listed in §12.
1. Purpose
Judgment Pack Core defines a portable JSON document for representing:
- a decision intent and question;
- possible outcomes;
- evidence requirements;
- sources and claim-level citations;
- applicability conditions;
- rules and typed exceptions;
- explicit behavior for unknown information;
- escalation requirements; and
- basic authorship and review metadata.
The core defines representation and document conformance. For an implementation that claims evaluator conformance (§3.4) it also defines portable evaluation semantics (§§7–8) and one portable result, the disposition of §8.3. It does not establish truth, authority, safety, or fitness for a deployment, and a disposition is not made true, authorized, or safe by being portable.
1.1 Normative artifacts and precedence
The artifacts in this repository have distinct roles:
- this document is the normative prose for carrier and semantic document conformance, for evaluator conformance, and for the interpretation of schema-defined fields;
schema/judgment-pack-core.schema.jsonis the normative machine-readable projection of structural document constraints;spec/checkpoint-witness.md, a companion document, is the normative prose for the witness-statement reader conformance class it defines, and for nothing else;spec/dialect.md, a companion document, is the normative prose for the preparation-verifier reader conformance class it defines, and for nothing else;- selected retained columns is accepted at draft maturity as normative prose for the exact RC2 selected leaf support scope only; it establishes no implicit ordinary support or generic preparation-verifier claim, and publication requires the immutable RC2 release;
- the evaluation corpus — the manifest and case fixtures under
conformance/evaluation/, not its README — is normative for evaluator conformance (§3.4) and for nothing else. This is the normative status the bullet below reserves for a later specification, granted here to those files only; and - examples, the document-conformance corpus, READMEs, design notes, RFCs, the roadmap, and implementation behavior are informative unless a later specification explicitly gives an artifact normative status.
A conformance claim MUST satisfy all applicable normative requirements. If the schema or the evaluation corpus disagrees with this document, this document controls and the mismatch is a specification defect that SHOULD be reported. An example, test fixture, validator, or product behavior cannot override any normative artifact.
2. Normative representation
2.1 JSON carrier
The normative carrier is a JSON text as defined by RFC 8259. In addition:
- object member names MUST be unique;
- a
\uUnicode escape sequence that falls in the UTF-16 surrogate range (U+D800–U+DFFF) MUST form a valid UTF-16 surrogate pair; an unpaired surrogate escape is malformed input; and - implementations MUST reject malformed or incomplete input and data exceeding their documented resource limits rather than process only a silent prefix.
Root type, recognized members, and field-value constraints belong to structural or semantic document conformance rather than carrier conformance.
2.2 Decimal grammar
JSON numbers SHOULD NOT be used for business quantities whose exact decimal identity matters. The
comparison operand of a fact condition using greater-than, greater-than-or-equal, less-than,
or less-than-or-equal MUST be a string matching:
decimal = [ "-" ] ( "0" / non-zero-digit *DIGIT ) [ "." 1*DIGIT ]
Exponent notation, leading plus signs, leading zeroes, NaN, and infinities are not admitted.
This grammar does not classify every numeric-looking string as a decimal and does not apply to
identifiers, versions, paths, locators, citations, equality operands, or other textual values merely
because they contain digits. Core 0.3.0 has no general decimal type marker; exact decimal
quantities outside ordered fact-condition operands require a future profile or declared extension.
This section defines decimal lexical syntax only. It has no decimal type marker and does not define
decimal equality, scale, units, or cross-unit conversion. §7.4 defines ordered comparison of two
strings satisfying this grammar for evaluator conformance (§3.4) and nothing else; it defines no
decimal-aware equality, so equals compares two such strings as strings. Outside that class,
satisfying this grammar does not imply executable comparison support.
3. Conformance classes
This draft defines three document conformance classes and one evaluator conformance class. The
document classes are unchanged in substance from 0.1.0-draft and do not depend on the evaluator
class. It defines no execution conformance: applying an outcome remains outside Core.
3.1 Carrier-conforming document
A serialized document is carrier conforming when it satisfies §2.1, including valid and complete
RFC 8259 JSON, unique object member names, well-formed UTF-16 surrogate pairing for all \u escape
sequences, and explicit failure rather than silent partial processing when a documented resource
limit is exceeded.
3.2 Structurally conforming document
A carrier-conforming document is structurally conforming when it satisfies the normative JSON Schema and all schema-adjacent requirements in this document.
The format keywords in the schema are assertions for JPS conformance, regardless of whether a
JSON Schema implementation treats format as annotation by default. A structural validator MUST
enable the Draft 2020-12 Format-Assertion vocabulary or perform equivalent checks. In particular:
idMUST be an absolute URI conforming to RFC 3986;source.publishedAtMUST be an RFC 3339full-date; andmetadata.createdAtand everymetadata.reviews[].reviewedAtvalue MUST be an RFC 3339date-time.
Accepting these fields without asserting their formats is insufficient for structural conformance.
3.3 Semantically conforming document
A structurally conforming document is semantically conforming when:
- every local reference resolves exactly once;
- referenced object kinds are correct;
- outcome, rule, evidence-requirement, source, and exception identifiers are unique within their collections;
- every rule outcome and fallback outcome names a declared outcome;
- every rule evidence reference names a declared evidence requirement;
- every rule source reference names a declared source;
- every
evidence-presentcondition names a declared evidence requirement; - every exception target names a declared rule when a target is present;
- every exception outcome names a declared outcome when an outcome is present;
- every exception source reference names a declared source;
- required extension capabilities are declared;
- field meanings and cross-field constraints follow the normative prose in §§4–6 and §9.
Condition or resolution results are not part of semantic document conformance.
3.3.1 Recommended rule-overlap check
This subsection is non-normative. A validator is recommended to compare every pair of rules that
name different outcomes and report JPS-RULES-OVERLAP when their conditions can both be true for
one facts document. This check is not a conformance requirement: a pack with an overlap remains
conforming, and evaluation in the overlap continues unchanged. Core §8 step 8 records conflict,
and the disposition is unresolved.
For conditions composed of fact nodes on one path and literal, all, any, and not, the
check is exact. Track the sets of values for which each condition is true and false; values in
neither set produce unknown. For equals, the true set is the singleton containing its operand;
for in, it is the set of its operands; and not-equals swaps the equality true and false sets,
all under the type-preserving equality of §7.4. Each ordered comparison's true and false sets are
intervals of decimal-string values under §7.4's mathematical ordering, with an open or closed
endpoint according to the operator; other values remain unknown. all intersects true sets and
unites false sets, any unites true sets and intersects false sets, and not swaps the two sets. A
literal supplies the corresponding full and empty sets. Two rules overlap exactly when the
intersection of their true sets is non-empty. Thus ranges that meet only at an endpoint excluded by
either range do not overlap. Equality and membership retain JSON type and spelling, including
§7.4's distinction between decimal ordering and string equality.
When the two conditions use different fact paths and neither condition excludes the other, the result is overlap not excluded, rather than an exact overlap. Core conditions do not relate the values at two paths, so a validator must not invent such a relationship. An implementation may use Core's collection and nesting bounds to keep this pairwise analysis bounded.
The diagnostic has these members:
- code
JPS-RULES-OVERLAP; - certainty
exactornot-excluded; - severity;
- a JSON Pointer to the first rule in the reported pair;
- the ids and outcomes of both rules;
- for an exact result, either a witness facts input or the overlapping region: its fact
pathandfromand/ortoendpoints with inclusivity, or its shared values; - the effect sentence: "Core §8 records
conflict; the disposition isunresolved."; and - a suggested exclusive rewrite, identifying the rule to rewrite and giving its replacement
whencondition.
The two rule ids in one diagnostic must differ. The manifest schema requires two unique rule
identity objects, but Draft 2020-12 cannot compare only their id member across array items, so a
manifest reader also enforces this id-level invariant.
For the common ascending numeric bands, the suggestion bounds the lower rule using Core's existing
two-comparison form. For example, replace score >= 40 with an all of
greater-than-or-equal 40 and less-than 70 when the higher rule is score >= 70. No new operator
is needed. For a cross-path pair, the suggestion may instead conjoin the lower rule with not of
the higher rule's condition. Because not preserves unknown (§7.3), a missing higher-rule fact
makes that lower rule unknown too; with onUnknown: escalate, the record is not silently banded
lower than its known facts justify.
Plain validation reports every instance as a warning. Strict mode, including
test-conformance --strict, reports an exact, non-empty overlap as an error, and a review interface
blocks publication for that exact case. not-excluded remains a warning in every mode and does not
block publication. After the project can count published packs that trigger the exact case, a Core
minor may promote it to §3.3 semantic conformance; it is not promoted in this draft.
3.4 Evaluator conformance
An implementation is evaluator conforming when, given
- a semantically conforming pack (§3.3);
- one JSON facts document;
- at most one evidence-availability document, whose absence §8.2 defines; and
- its own supported-extension set,
it produces the portable disposition of §8.3 under the semantics of §§7–8, reports every condition
that prevents completing an evaluation as an evaluation error rather than as a disposition (§8.4),
defines the limits §10 requires of this class, and passes the evaluation corpus published for the
exact specVersion it names.
The claim is scoped by the contract, not by the corpus: it asserts that the implementation satisfies every requirement of §§7–10 — the semantics, the disposition, the error classes, and the documented limits — for every input it admits. It says nothing about the pack, the facts, the evidence, or the consequences of acting on a disposition (§3.5). Corpus results are required evidence for that claim and are not exhaustive evidence of it (§3.4.1).
Every row of the corpus published for the claimed specVersion MUST pass, and a failed row blocks the
claim. A failed row does not by itself decide who is wrong: a divergence is as likely to be a defect
in the row as in the implementation, and §1.1 makes this document control over the corpus. What a
claimant MUST NOT do is decide that question for itself. A row is defective for a released corpus
version only when the project has said so in a versioned erratum, published beside the corpus as
conformance/evaluation/errata.md: one entry naming the suiteVersion it applies to, the case id, the
date of issue, and the defect. An erratum edits nothing — the manifest of a released version is never
changed (§3.4.1), so the frozen rows stay exactly as published — and it has one effect: a claim against
that suiteVersion may exclude the row the erratum names, provided the claim names the row and cites
the erratum. Until such an erratum exists, a failing row is a blocked claim and a specification-defect
report, in that order.
Carrier, structural, and semantic document conformance are untouched by this class. A document is conforming or not without reference to any evaluator, and an implementation MAY claim document conformance alone.
3.4.1 Evaluator-conformance claims
Exactly one form of evaluator-conformance claim is definable: a claim against this class and against
the evaluation corpus for one exact specVersion, naming that
version, the corpus version, the results obtained, and — in the claim's own words, not as an inference
a reader must draw — that every row of that corpus version passed. If a project-issued erratum marks a
row defective for that corpus version (§3.4), the claim MUST name that row and cite the erratum;
otherwise "every row" means every row. Everything else remains forbidden. An implementation MUST NOT:
- claim partial or qualified evaluator conformance — a subset of §§7–8, a subset of the corpus, or conformance "except for" any requirement;
- claim evaluator conformance on the strength of prototyping, of an experimental surface, or of agreement with another implementation, in place of corpus results;
- claim evaluator conformance without having run the evaluation corpus for the exact
specVersionclaimed; - claim evaluator conformance under
0.1.0-draft, which defines no such class, or under anyspecVersionwhose corpus it has not run; - claim evaluator conformance while a row of the named corpus version fails, unless a project-issued
erratum for that
suiteVersionmarks that row defective and the claim names and cites it (§3.4); or - describe an evaluator-conformance claim as establishing anything §3.5 excludes.
A claim is made against one exact specVersion and is not inherited by any other version (§11).
The evaluation corpus is a seed corpus: it is version-pinned, it is not exhaustive, and it grows by
RFC. Passing it is necessary for the claim and is not evidence that the implementation is correct on
inputs the corpus does not contain.
The corpus is frozen at the release of a specVersion and grows only into the next one: rows are
added, changed, or corrected on the way to a later specVersion, never inside a released one, so two
identically worded claims against the same specVersion require the same rows. "The corpus version"
a claim must name is the suiteVersion member of the evaluation manifest, which for a released
version equals the specVersion the corpus was published for. An erratum (§3.4) is the only
post-release statement about a released corpus, and it changes no row.
Two optional case members of the corpus carrier are defined and unused by every row of this version's
corpus, so that a later row can carry them without a carrier change. workBudget is a positive integer
of evaluation-work units, in the accounting units a future work-accounting model will define; when it is
absent, the case sets no budget and the implementation's own documented limit (§10) applies.
expectedErrorPhase is preflight or evaluation and says which phase an expected error class was
reached in — while admitting the inputs (§8.2) or while evaluating them (§8) — so it accompanies
expectedErrorClass and never an expected disposition.
3.5 Non-claims
Conformance MUST NOT be described as proof that:
- a claim is true;
- evidence is authentic or sufficient;
- an author or reviewer had authority;
- an outcome is legally or ethically permissible;
- a particular runtime applied the pack correctly; or
- use of the pack is safe.
The runtime-correctness bullet has exactly one narrow exception. An evaluator-conformance claim (§3.4) asserts that the claimed implementation complies with the complete evaluator contract of §§7–10 — the semantics of §§7–8, the §8.3 disposition, the §8.4 error classes, and the limits §10 requires of the class — for every input it admits, not merely for the inputs it happened to run. Its corpus results are required evidence of that compliance and are not exhaustive evidence of it: the corpus is a seed corpus, and passing every row of it demonstrates nothing directly about an input no row contains (§3.4.1). The claim asserts nothing about any deployment, any particular run in production, the facts and evidence a caller supplied, or the permissibility of acting on a disposition. Every other bullet above applies to the evaluator class unchanged.
4. Root object
| Member | Required | Meaning |
|---|---|---|
profile |
no | Ceiling profile: base (default) or extended (§4.1) |
specVersion |
yes | Exact value 0.3.0 |
id |
yes | Stable absolute URI identifying the pack series |
version |
yes | Three-component MAJOR.MINOR.PATCH revision string |
title |
yes | Non-empty human-readable title |
description |
no | Human-readable overview |
decision |
yes | Decision intent and question |
applicability |
no | Optional condition delimiting the pack's scope |
evidenceRequirements |
no | Declared inputs or proof obligations |
sources |
no | Located source material |
outcomes |
yes | At least two possible outcomes |
rules |
yes | One or more rules |
exceptions |
no | Typed exceptions to rules or normal resolution |
fallbackOutcome |
no | Candidate outcome when normal rules yield no candidate |
escalation |
no | Optional handoff configuration, not a decision outcome |
metadata |
no | Authorship, license, creation, and review information |
extensions |
no | Namespaced extension values |
Collection order is preserved for authoring and display but MUST NOT determine rule priority.
The root MUST be an object. The schema defines the recognized members of each Core object; a member
not defined for that Core object MUST NOT appear. The names and arbitrary JSON values inside an
extensions object are governed separately by §9.
4.1 Document ceiling profiles
A document may declare profile, exactly base or extended; absence means base.
A profile is a named set of ceilings, versioned with this specification. It changes no
members, minima, grammar, numeric domain, uniqueness requirement or evaluation semantics.
It never lowers a ceiling below base. An installation setting MUST NOT raise a ceiling
that the document does not declare. Core packs, Workflow documents and Dialect documents carry this member at their root.
Policy and governing-adoption documents adopt it from the next companion version;
the released 1.0.0 draft does not carry profile. Dialect source
and connection profiles are separate objects, not this ceiling declaration.
A reader MUST admit a document only under a profile it supports. Profile negotiation is
the first admission step: after the bounded root scan needed to identify the declaration,
and before other documents' byte-bound checks, schema interpretation, reference loading,
acquisition or evaluation, it checks that declaration. A supporting reader then applies
the selected profile's ceilings. An unknown name, non-string, empty
string or null is a structural refusal using the format's existing structural diagnostic.
For input declaring a known but unsupported profile, it returns exactly one diagnostic
profile-unsupported, naming that profile: {"code":"profile-unsupported","profile":"extended"}
for an unsupported extended declaration. A format's refusal envelope may wrap these two
members (Dialect uses refusal for the code); it MUST NOT append another diagnostic or
input-derived message. The same rule applies to implicit base. Only the parsing needed to identify the declaration precedes
this check; malformed JSON retains its syntax refusal. Resource-safe parsing may reject
unreadable input, but MUST NOT silently process a prefix or fall back to base.
profile is part of the document's bytes, so it is part of its digest and every exact-identity
rule. Readers MUST NOT insert the default or remove an explicit declaration before hashing.
An extended document has the same identity everywhere, including at readers refusing it.
For the proposed exact selected retained-column/1 contract only,
the retained-column companion specifies scoped Dialect artifact ceilings
after its own selection and independent role admission. Absence of that selection uses this
table. It does not raise Core pack, global transport, canonical parser, target-count or independent
work ceilings. This is an RC2 adoption candidate, not a support claim for an existing release.
The following is the ceiling table for these formats. Numbers elsewhere in the companions
state base; except for the exactly selected retained-column companion above, their
corresponding extended ceilings are exclusively those below. Units
and counting conventions remain those of the owning companion. No Core outcome, rule or
reference maximum is defined, so none is introduced here. Fixed semantic cardinalities
(such as exactly one coverage record per selected section), numeric domains and index ranges
are not resource ceilings and do not change.
| Format and resource | base |
extended |
|---|---|---|
| Core escalation routes (and their resulting handoff routes) | 8 | 16 |
| Policy (from the next companion version): informationalSources, sourceProvenance, sourceRefs per section, governingPolicies | 16 | 32 |
| Policy (from the next companion version): sections, scope sectionIds, coverage records per policy, consumerElements per section | 64 | 128 |
| Policy (from the next companion version): artifact version characters | 256 | 512 |
| Policy (from the next companion version): URI characters | 2048 | 4096 |
| Policy (from the next companion version): local ID and media type characters | 128 | 256 |
| Policy (from the next companion version): readable text characters | 4096 | 8192 |
| Policy (from the next companion version): parsed document bytes | 262144 | 524288 |
| Policy (from the next companion version): document nesting | 32 | 64 |
| Policy (from the next companion version): number literal characters | 128 | 256 |
| Policy (from the next companion version): exponent magnitude | 308 | 616 |
| Policy (from the next companion version): narrative, review basis and informational material bytes | 1048576 | 2097152 |
| Policy (from the next companion version): original material / registration bytes | 4194304 | 8388608 |
| Policy (from the next companion version): distinct retained bytes | 16777216 | 33554432 |
| Policy (from the next companion version): material registrations | 16 | 32 |
| Workflow limits.maxStages | 32 | 64 |
| Workflow limits.maxRecords, limits.maxInstances | 4096 | 8192 |
| Workflow limits.maxAttempts | 16 | 32 |
| Workflow limits.maxBytes | 1073741824 | 2147483648 |
| Dialect document bytes | 131072 | 262144 |
| Dialect combined dialect, case and acquisitions bytes | 2097152 | 4194304 |
| Dialect profiles / binding document bytes | 65536 | 131072 |
| Dialect preparation / record bytes | 8388608 | 16777216 |
| Dialect sources | 16 | 32 |
| Dialect retained responses, parameters per scope, clauses per rule, conditions per all/any | 64 | 128 |
| Dialect unwrap pointers | 4 | 8 |
| Dialect unwrapped string bytes | 200000 | 400000 |
| Dialect fact targets | 256 | 512 |
| Dialect evidence targets | 128 | 256 |
| Dialect value nesting / document nesting | 32 / 64 | 64 / 128 |
| Dialect number literal characters / exponent magnitude | 128 / 308 | 256 / 616 |
| Dialect declared fields, answer entries, text-list items, observations, citation indices | 64 | 128 |
| Dialect field name bytes | 64 | 128 |
| Dialect description bytes | 2048 | 4096 |
| Dialect model name bytes | 256 | 512 |
| Dialect evidence instruction bytes | 4096 | 8192 |
| Dialect text value bytes | 8192 | 16384 |
| Dialect text-list item bytes | 1024 | 2048 |
| Dialect decimal string characters | 128 | 256 |
| Dialect capabilities per source or connection profile | 3 | 6 |
| Dialect web assignments per source | 2 | 4 |
| Dialect earlier reconciliation sources | 15 | 30 |
| Dialect endpoint scope entries | 32 | 64 |
| Dialect endpoint scope entry / endpoint URL bytes | 2048 | 4096 |
| Dialect artifact ID bytes | 1024 | 2048 |
Workflow's document-declared limits remains required; only its ceilings above change.
Other Workflow carrier bounds remain unchanged. Raising a Dialect list ceiling does not
invent capability names or waive distinctness; a closed vocabulary can still constrain it.
Policy's canonical integer magnitude stays 9007199254740991: it is a numeric domain, not
a resource ceiling. Core implementation-defined limits (§10) are not rows of this table.
The published structural schemas retain base maxima and declare the profile enum with
base as an annotation default. A reader supporting extended MUST validate with the
corresponding ceilings above, preserving every other schema constraint; applying an unchanged
base schema alone does not validate an extended document. Schema validation alone does not
negotiate capabilities. Reader capability records list profiles, the supported names;
listing extended commits the reader to every extended ceiling of its format.
5. Identity and references
The pack id MUST be an absolute URI. Local object identifiers are non-empty ASCII strings matching
^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$.
Local identifiers are scoped to the pack version. They MUST NOT be interpreted as globally unique. Meaning MUST NOT be inferred from the spelling of an identifier.
Core 0.3.0 has no imports or remote-reference resolution. All rule, outcome, source,
evidence-requirement, and exception references resolve within one document.
6. Core objects
6.1 Decision
decision.intent explains the organizational purpose. decision.question states the question the
pack is intended to resolve. Both are required human-readable strings.
The decision object MAY include namespaced extensions. It MUST NOT embed prompts or executable host-language code.
6.2 Evidence requirement
An evidence requirement declares:
id— local identity;description— what must be provided;required— whether absence prevents normal resolution; and- optional
kind—document,fact,measurement, orattestation.
The kind is descriptive in this draft. Products may acquire or authenticate evidence differently.
6.3 Source
A source contains:
idandtitle;- a typed
locatorwithkindandvalue; - optional publisher and publication date;
- optional
citationcontaining a location and excerpt; and - optional rights information.
A source record represents provenance supplied by the author. Core conformance does not verify that the source exists, that the excerpt is accurate, or that its license permits a proposed use.
6.4 Outcome
An outcome has a local id, human-readable label, and optional description.
An outcome is a declared result, not an authorization to perform an external action. Execution of an outcome is outside Core.
6.5 Rule
A rule declares:
idanddescription;when, a condition;outcome, a declared outcome id;onUnknown, eitherignoreorescalate;- optional evidence-requirement references;
- optional source references; and
- optional rationale.
The representation has no rule-priority field, and array order carries no priority meaning. Handling
of conflicts and onUnknown appears in §8, which is normative for evaluator conformance (§3.4) and
informative for a document-conformance consumer.
6.6 Exception
An exception declares a condition and one effect:
suppress-rule, withtargetRule;force-outcome, withoutcome; orescalate.
For suppress-rule, targetRule is required and outcome is absent. For force-outcome, outcome
is required and targetRule is absent. For escalate, both are absent. Every exception also has a
required onUnknown policy of ignore or escalate. Evaluation order and effect compatibility
appear in §8, which is normative for evaluator conformance (§3.4) and informative for a
document-conformance consumer.
6.7 Escalation
An escalation object describes configured handoff intent. triggers is a non-empty set chosen
from:
not-applicable;missing-required-evidence;unknown;conflict; andno-match.
An escalation MUST declare exactly one of target and routes; declaring both is not
conformant. target retains its existing {kind, name} shape, with kind one of human-role,
queue, or system, and name a non-empty display name. routes is an ordered array of 1 to 8
entries, each a closed object containing target and optionally triggers. Each route target
has that same shape. If present, route triggers MUST be a non-empty, duplicate-free subset of
this escalation's triggers. An omitted route trigger list means unconditional selection once
a handoff is requested, not a request by itself. Duplicate targets remain distinct routes.
The maximum of 8 is the base schema bound; §4.1 raises it to 16 under extended.
It is not an installation setting.
For example, "routes": [{"target": {"kind": "queue", "name": "Review"},
"triggers": ["unknown"]}, {"target": {"kind": "human-role", "name": "Oversight"}}]
selects Review only for a retained unknown reason and Oversight for every requested handoff,
provided unknown is declared among the escalation's triggers.
The target identifies a human role, queue, or external system by a display name. The object configures handoff intent; it does not itself make a pack applicable, turn a condition into an outcome, or prove that a handoff occurred. When the object is omitted, Core supplies no default triggers or target. Core does not define delivery, identity resolution, authorization, or service-level objectives.
6.8 Metadata
Metadata MAY carry authors, creation time, license expression, and review records. These are author assertions. Signature and organizational-authority profiles may strengthen them later.
7. Condition interpretation
This section is normative for evaluator conformance (§3.4) and informative for every other
consumer. In 0.1.0-draft the results described here were informative in every direction; that note
is amended, and amended only for the evaluator class. The allowed JSON shapes for conditions remain
normative through the schema for all classes, and a carrier, structural, or semantic document
conformance claim is unaffected by anything in this section: no result below can make a document
conforming or non-conforming.
A condition produces true, false, or unknown:
literalreturns its Boolean value;alluses strong three-valued conjunction;anyuses strong three-valued disjunction;notnegates while preservingunknown;factcompares a value selected from runtime-supplied facts; andevidence-presenttests whether evidence was supplied for a named requirement.
7.1 all
falseif any child is false;trueif every child is true;unknownotherwise.
7.2 any
trueif any child is true;falseif every child is false;unknownotherwise.
7.3 not
true becomes false, false becomes true, and unknown remains unknown.
7.4 Fact conditions
A fact.path is interpreted as RFC 6901 JSON Pointer syntax against one runtime-supplied JSON facts
document. The empty string selects the document root. A syntactically valid pointer that does not
resolve, including an invalid array traversal at runtime, produces unknown.
The admitted operators are:
equals;not-equals;greater-than;greater-than-or-equal;less-than;less-than-or-equal; andin.
equals uses type-preserving JSON equality: null equals null; Booleans and
strings compare by value; JSON numbers compare by their mathematical value without lossy
conversion; arrays compare recursively in order; and objects compare recursively by member name
and value without regard to member order. There is no coercion between JSON types. not-equals is
the Boolean inverse of equals when equality can be determined.
For in, the schema requires the condition value to be a non-empty array. The selected fact value
is compared for equality with each array item. A match produces true; no match produces false.
The schema requires operands of greater-than, greater-than-or-equal, less-than, and
less-than-or-equal to satisfy the decimal grammar in §2.2. An ordered comparison is defined if
and only if both the selected fact value and the operand are JSON strings satisfying that grammar;
the two are then compared by mathematical value. Any other selected value — including a JSON number,
a Boolean, null, an array, an object, or a string that does not satisfy the grammar — makes the
comparison undefined and produces unknown. A JSON number is deliberately not coerced: the grammar
exists because a number's decimal identity is not preserved, and silently accepting one would make
two implementations disagree.
Equality of decimal strings is string equality and is deliberately not decimal-aware. "1.0" and
"1.00" are therefore not equal under equals, and not-equals is correspondingly true, while
neither is greater than the other under an ordered comparison, which reads both by mathematical value.
The two families of operator answer different questions and Core defines no reconciliation between
them; a pack that needs decimal-aware equality must normalize scale in the pack, in the operand and in
the facts it is compared against.
Units, quantities carrying units, and date or time values have no ordered comparison here. Such an
operand does not satisfy §2.2, so an ordered comparison over one is not expressible rather than
merely unknown-by-accident; equals, not-equals, and in still compare those values as ordinary
JSON. Outside evaluator conformance, structural acceptance of an ordered condition still implies no
executable support.
An implementation claiming evaluator conformance (§3.4) MUST implement every operator listed above.
"Unsupported operator" is not an available result for that class, and answering unknown where this
section defines true or false is a failure to implement §7.4 rather than a conforming result —
§3.4.1 forbids claiming a subset of §§7–8, whether or not a corpus row happens to exercise the
operator. Within that class unknown is produced by exactly three things: a path that is absent or
does not resolve; a selected value or operand whose shape the operator does not admit, which includes a
value carrying units, since this section does not admit one in an ordered comparison at all; and a value
the implementation cannot compare exactly. That last case is confined to JSON numbers outside an
implementation's exact range, it is the one open question of §13 that §8.3 names as the single seam in
its byte-agreement requirement, and it is not permission to return unknown for anything else.
7.5 Evidence presence
evidence-present is true when the evaluation input records the named requirement as available,
false when it records the requirement as absent, and unknown when the input cannot say. For
evaluator conformance those three states are supplied by the evidence-availability document of §8.2:
present is true, absent is false, and unknown — including an omitted key — is unknown.
That tri-state input replaces 0.1.0-draft's appeal to a "complete evidence manifest", which was
undefined and was the one recorded semantic divergence between careful readings of that draft. This
draft still defines no evidence-manifest interchange format beyond the tri-state of §8.2.
8. Resolution model
This section is normative for evaluator conformance (§3.4) and informative for every other consumer, on the same terms as §7. The step order below is contractual only where it changes the disposition; it mandates no implementation algorithm, and an implementation may compute in any order that yields the specified disposition. §8.2 defines the inputs, §8.3 the one portable result, and §8.4 the errors that replace a result.
Resolution produces one of three result kinds:
- an
outcomeresult naming exactly one declared outcome; - a
not-applicableresult carrying reasonnot-applicable, which is not an outcome; and - an
unresolvedresult carrying one or more reasons.
The generated reason vocabulary is not-applicable, missing-required-evidence, unknown,
conflict, and no-match, matching escalation.triggers. A true exception with effect escalate
adds the separate reason exception-escalation; that reason is a direct request rather than a
trigger-selected request. A result may retain multiple reasons. Reasons are a de-duplicated set;
their order carries no priority. Implementations may additionally record contributing rule,
exception, or evidence-requirement ids, outside the disposition (§8.3).
The algorithm is:
- Treat omitted
applicabilityas the literal valuetrue. If applicability is false, produce a terminalnot-applicableresult carrying reasonnot-applicableand do not evaluate exceptions or rules. If it is unknown, produce anunresolvedresult with reasonunknownand stop. - Inspect every required evidence requirement, using the presence values of §7.5. Record
missing-required-evidenceif and only if at least one required requirement's presence isfalse. Recordunknownif and only if at least one required requirement's presence isunknownand none isfalse. Retain the ids of the requirements that produced either reason for diagnostics. This restates0.1.0-draft's binary "any required evidence is absent" test in the three-valued terms of §7.5, and is the resolution of that draft's one recorded semantic divergence. - Evaluate every exception condition and collect its effects. An unknown exception with
onUnknown: ignorecontributes no effect but remains unknown in a trace. An unknown exception withonUnknown: escalaterecords reasonunknown. - Combine true exception effects as follows:
- all
suppress-ruleeffects are compatible and suppress the union of their target rules; force-outcomeeffects are compatible when they all name the same outcome and conflict when they name different outcomes;- suppression is compatible with a forced outcome; and
- one or more
escalateeffects are mutually compatible, record reasonexception-escalation, and form a direct escalation request that takes precedence over suppression and forced outcomes.
- Record reason
conflictfor incompatible forced outcomes. If step 2 recorded either of its reasons, an exception is unknown withonUnknown: escalate, exception effects conflict, or a true exception directly requests escalation, produceunresolvedafter all exception effects have been inspected, and do not evaluate normal rules. Retain every reason discovered at this stage. A direct exception escalation is also retained as such in diagnostics. - If one compatible forced outcome remains and no blocking state from step 5 exists, produce that outcome without evaluating normal rules. Otherwise, remove every suppressed rule and evaluate all remaining rules.
- A true rule contributes its outcome as a candidate. A false rule contributes none. An unknown
rule with
onUnknown: ignorecontributes no candidate and does not block resolution; an unknown rule withonUnknown: escalaterecords reasonunknownand blocks both a candidate outcome and the fallback. - Record reason
conflictwhen true rules name more than one distinct outcome. If both an escalate-on-unknown rule and conflicting true rules are present, retain bothunknownandconflict; neither is discarded because the other also blocks resolution. Produceunresolvedwhenever either reason is present. - If no blocking reason exists and true rules name one distinct outcome, produce it. Multiple true rules naming that same outcome are compatible.
- If no true rule contributes an outcome, use
fallbackOutcomewhen present. False rules and unknown rules withonUnknown: ignoredo not prevent this fallback. If no fallback is present, produceunresolvedwith reasonno-match.
Thus, onUnknown: escalate has blocking precedence over otherwise compatible outcomes at the same
resolution stage, while onUnknown: ignore never changes an unknown condition to false and does
not erase that unknown from a trace. Array order, lexical id order, and implementation-defined
priority MUST NOT select among rule outcomes, and a conflict MUST NOT be tie-broken: it is an
unresolved result.
8.1 Handoff configuration
Evaluation state and handoff configuration are distinct. An unresolved or not-applicable result
exists independently of the optional escalation object; escalation is not itself an outcome.
For an escalation declaring target, the configured target is requested when at least one retained
reason appears in escalation.triggers. When several reasons match, resolution
creates exactly one handoff request to the configured target and includes the complete retained
reason set. That complete set is carried in the disposition's reasons; handoff.triggeredBy names
the subset of it that triggered the request, which is smaller whenever escalation.triggers does not
name every retained reason (§8.3). A true exception with effect escalate is a direct request and
uses the configured target regardless of the trigger list.
For an escalation declaring routes, first determine whether a request is made by at least one
retained reason in escalation.triggers or by a direct exception escalation. Only when a request
is made, select every route whose triggers intersects the complete disposition reasons, and
every route that omits triggers. Make exactly one request per selected route, in declaration
order. This is fan-out, not alternatives or fallback; identical target objects are not deduplicated.
A direct exception bypasses the escalation trigger gate, but does not bypass route filters.
If no route is selected, handoff.state is none, handoff.routes is empty, and triggeredBy
is absent. Routing never changes kind, outcomeId, or the complete retained reasons.
A review-named outcome alone requests nothing, including from unconditional routes.
When escalation is omitted, there are no default triggers and no default target. When it is
present but no generated reason matches its triggers, there is likewise no configured handoff for
that reason. In either case, an unresolved result remains unresolved and must not be converted into
a fallback or other outcome. A direct exception escalation without an escalation object remains
an unresolved direct request with no Core-defined destination; the disposition records it as a
requested handoff whose destination the pack does not supply (§8.3).
8.2 Evaluation inputs
An evaluation takes four inputs. Three are documents — the pack and the facts document are always supplied, and the evidence-availability document is optional, with the meaning of its absence defined below — and the fourth is a property of the implementation. Two documents are therefore the minimum and three the maximum.
- Pack — one semantically conforming document (§3.3). A pack that is not semantically conforming is an evaluation error (§8.4), not a disposition.
- Facts — one JSON document. Every
fact.pathis an RFC 6901 JSON Pointer evaluated against it (§7.4). There is exactly one facts document per evaluation; Core defines no fact namespace, merging, or acquisition. - Evidence availability — one JSON object whose member names are declared
evidenceRequirements[].idvalues and whose values are exactly one of the stringspresent,absent, orunknown. An omitted key meansunknown. An omitted document as a whole is the implicit empty object, which by that rule makes every declared requirementunknown; it is the only form absence takes, and it is not an error. A value that is not a JSON object at all, a member name that is not a declared requirement id, or a value outside those three strings is an evaluation error (§8.4) — an undeclared key is far more likely to be a caller's mistake than a statement about the pack. Duplicate member names are already rejected by §2.1. - Supported extensions — the set of
metadata.requiredExtensionscapabilities the implementation supports. A required capability outside that set is an evaluation error (§8.4), never a disposition (§9).
Input preflight. The inputs are admitted before evaluation begins. An implementation claiming
evaluator conformance MUST validate them in this order — the pack, then the facts document, then the
evidence-availability document, then the pack's metadata.requiredExtensions against its own
supported-extension set — and MUST complete that validation before step 1 of §8 runs. That order is the
error precedence of §8.4, so the first failure encountered is also the class §8.4 requires be reported.
Any violation of this section's shape requirements is the malformed-input evaluation error of §8.4: an
evidence-availability input that is not a JSON object, an undeclared member name, a value outside
present, absent, and unknown, and a facts or evidence-availability input that is not a
carrier-conforming JSON text (§2.1) are all that error. So is reaching a documented document or carrier
limit while admitting an input, because §2.1 requires refusing such a document rather than processing
part of it, so the input is never admitted (§8.4, §10).
Because preflight completes before step 1, no result can outrace an input error: a pack whose
applicability is false, presented with an evidence-availability document carrying an undeclared key, is
the malformed-input error and never the not-applicable disposition, and the same holds for every
other terminal step of §8 and for every preflight failure. Two conforming implementations therefore
agree on which inputs are admitted at all, not only on what an admitted input produces.
Core defines no transport, file layout, or command-line surface for these inputs. It defines what they mean.
8.3 The portable disposition
An implementation claiming evaluator conformance MUST produce, for each evaluation, exactly one disposition or exactly one evaluation error (§8.4) and no disposition. The disposition is a JSON object with these members and no others:
| Member | Present | Value |
|---|---|---|
kind |
always | outcome, not-applicable, or unresolved |
outcomeId |
iff kind is outcome |
the id of exactly one declared outcome |
reasons |
always | the retained reason set, serialized as a sorted array |
handoff |
always | an object carrying the handoff state, and its trigger |
kind is the result kind produced by §8. not-applicable and unresolved are not outcomes and MUST
NOT be mapped onto one, defaulted to one, or flattened into the same field as outcomeId.
outcomeId MUST be present when kind is outcome and MUST be absent otherwise — absent, not
null and not an empty string. It MUST name a declared outcome of the pack evaluated.
reasons is a set: unordered and duplicate-free. Its members are drawn from
not-applicable, missing-required-evidence, unknown, conflict, no-match, and
exception-escalation; no other value is admitted. It is empty if and only if kind is outcome.
When kind is not-applicable its one member is not-applicable. Two dispositions have the same
reasons when the sets are equal; serialized order is never a difference in the disposition.
handoff is an object with:
state—requestedwhen §8.1 makes a handoff request, whether trigger-selected or a direct exception request, and including a direct exception request made when the pack carries noescalationobject, in which case the request has no Core-defined destination (§8.1).noneotherwise. Present always.triggeredBy— present if and only ifstateisrequested. A non-empty set of reason identifiers: every retained reason that appears inescalation.triggers, plusexception-escalationwhen a true exception with effectescalatemade a direct request (§8.1). It is always a subset ofreasons; route filtering does not narrow it.routes— present if and only if the pack declaresescalation.routes. An ordered array of the selected routes'targetobjects, one per selected route in declaration order, including duplicate targets. It is empty when no request is made or no route is selected. A non-empty array accompaniesstate: "requested"; an empty array accompaniesstate: "none".
For a pack declaring target alone, the disposition does not echo the configured target and its
canonical bytes remain unchanged from 0.2.0-draft. A consumer reads that target from the pack.
For a pack declaring routes, handoff.routes carries exactly the targets selected from the pack.
Targets are display names, not addresses (§6.7). A requested handoff is a request, not evidence
that a handoff occurred.
Nothing else belongs in the disposition object. An implementation MAY report a trace, contributing rule, exception, or evidence-requirement ids, timings, or any other diagnostic outside the disposition, and their presence or absence MUST NOT change any member above.
Serialization. So that two conforming implementations can be compared:
- both sets —
reasonsandhandoff.triggeredBy— are serialized as JSON arrays whose elements are sorted ascending by Unicode code point, with no duplicates; - an absent member is omitted, never serialized as
null; - member order carries no meaning; and
- where a byte comparison is required, each disposition is first canonicalized as described by RFC 8785, which orders object members by name. A disposition contains no numbers, so that specification's number rules never engage.
Two conforming implementations given the same pack, facts document, evidence-availability document, and supported-extension set MUST produce byte-identical canonicalized dispositions. That is the whole of the portability claim, and §3.5 applies to every part of it.
That requirement has exactly one seam, and this is the whole of it: whether equality involving a JSON
number an implementation cannot represent exactly is unknown or an explicit input error is an open
question (§7.4, §13). Until §13 closes it, two implementations with different arithmetic ranges may
answer differently on such a value, and an input carrying one is outside the portable claim. No other
input, operator, or member is outside it, and no other implementation-relative escape exists in §§7–8:
an implementation MUST NOT read this seam as permission to answer unknown anywhere else.
Two illustrative canonicalized dispositions, informative:
{"handoff":{"state":"none"},"kind":"outcome","outcomeId":"proceed","reasons":[]}
{"handoff":{"state":"requested","triggeredBy":["missing-required-evidence"]},"kind":"unresolved","reasons":["missing-required-evidence"]}
8.4 Evaluation errors
An evaluation error is not a disposition. When an implementation claiming evaluator conformance
cannot complete an evaluation, it MUST report an evaluation error, MUST NOT emit a disposition for
that evaluation, and MUST NOT substitute unresolved, not-applicable, or a fallback outcome for
the error. Evaluation terminates wherever §8 had reached, and partial state MUST NOT be reported as a
result. This is the §3.1 rule applied one layer up: a documented limit or a malformed input produces
explicit failure, never a silent partial processing that a caller could mistake for a result. A
truncated evaluation reported as a disposition is a forged disposition.
An implementation MUST report the class of every evaluation error, and every evaluation error is identified by exactly one class: exactly one of the four Core classes below, or — for a condition no Core class covers — exactly one documented implementation-defined class in the form this section requires of one. A Core class always takes precedence: an implementation-defined class is reported only when no Core class applies, never in place of one that does.
The Core classes are:
pack-not-conformant— the pack input is not a semantically conforming document (§3.3), failing at any of the carrier, structural, or semantic layer.unsupported-required-extension— the pack declares a capability inmetadata.requiredExtensionsthat the implementation does not support. §9's "structurally readable but not fully interpretable" report is this error for the evaluator class: the unsupported part may be the part that decides, so no disposition may be produced.malformed-input— an input failed the preflight of §8.2. The facts document or the evidence-availability document is not a carrier-conforming JSON text (§2.1); or the evidence-availability input violates §8.2 by not being a JSON object, by carrying an undeclared member name, or by carrying a value outsidepresent,absent, andunknown; or a documented document or carrier limit — bytes, nesting depth, or string size — was reached while admitting an input, which §2.1 requires be refused rather than partly processed, so the input never became one.resource-exhaustion— a limit documented under §10 was reached during evaluation: a collection-size limit or the evaluation-work limit. This class is about work an admitted input turned out to require, never about admitting the input in the first place.
More than one class can apply to the same inputs: a pack that fails semantic conformance presented with
an evidence document carrying an undeclared key is both pack-not-conformant and malformed-input. The
classes are therefore evaluated in one fixed order — pack-not-conformant, then malformed-input, then
unsupported-required-extension, then resource-exhaustion — and the first that applies is the class
reported, so that two conforming implementations report the same class for the same inputs. That order is
the preflight order of §8.2, and the phase split between malformed-input and resource-exhaustion is
what keeps it from contradicting §10: a limit reached while admitting an input is malformed-input
because the input was refused, and resource-exhaustion is reserved for a limit reached while evaluating
an input that was admitted. An implementation MAY name the other classes it also considered as message
detail.
As stated above, an implementation MAY define an additional class for a condition none of the four Core
classes covers — and only for such a condition — and MAY attach any message detail it likes. An
implementation-defined class MUST be documented and MUST be named in the reverse-domain form of
§9 — for example com.example.timeout — which cannot collide with a Core class identifier, since
those are bare kebab-case names, nor with a class another implementation defines. The transport, exit
status, and wire format of an evaluation error are not defined here; the class identifier is. A
machine-readable diagnostic contract remains open (§13).
9. Extensions
extensions is an object whose keys use reverse-domain naming, for example
com.example.review-policy. Values may be any JSON value.
An optional extension MUST NOT change Core semantics. Consumers preserve optional extensions when round-tripping but may otherwise ignore them.
Required extension semantics are declared in metadata.requiredExtensions. A consumer that does
not support every required extension MUST report the document as structurally readable but not
fully interpretable. It MUST NOT silently ignore a required extension. For an implementation claiming
evaluator conformance, that report is the unsupported-required-extension evaluation error of §8.4
and no disposition is produced.
Every name in metadata.requiredExtensions MUST appear as a key in at least one extensions
object in the document. A required-extension declaration without a corresponding value is
semantically invalid. An extension key omitted from metadata.requiredExtensions is optional.
Names beginning with org.judgmentpack. are reserved for future specification-defined extensions.
10. Security and privacy considerations
Implementations must treat packs, sources, citations, extensions, and runtime facts as untrusted input. They SHOULD define limits for document bytes, nesting depth, collection sizes, string sizes, and evaluation work.
An implementation claiming evaluator conformance (§3.4) MUST define and document at least its
collection-size and evaluation-work limits, and reaching one of those during an evaluation MUST produce
the resource-exhaustion evaluation error of §8.4 rather than a disposition. A documented document or
carrier limit — bytes, nesting depth, or string size — reached while admitting an input instead produces
malformed-input: §2.1 refuses such a document rather than processing part of it, and §8.2's preflight
therefore never admits it (§8.4). Either way the evaluation yields an explicit error and never a
disposition; the two classes differ only in which phase the limit belongs to. Defining a limit is not
portability: two conforming implementations may define different limits, so an input above either
one is outside the portable claim. The evaluation corpus therefore keeps its cases well inside any
plausible limit instead of probing one.
Implementations MUST NOT:
- execute code found in strings or extensions;
- fetch source locators during ordinary validation unless explicitly requested;
- treat a URL or publisher name as proof of authenticity;
- expose sensitive evidence merely because a pack references it;
- convert conformance into authorization; or
- continue after silently dropping malformed or unsupported required content.
11. Versioning
specVersion identifies this specification draft. version identifies the pack revision. They are
independent.
During 0.x, any specification release may be breaking. A future stable specification must define
reader, writer, and semantic compatibility separately and supply machine-readable migration cases.
A published pack version SHOULD be immutable. Changed content SHOULD receive a new version.
Compatibility from 0.2.0-draft is explicit rather than inferred from a shared 0.x prefix:
- Reader and writer: an older reader does not acquire
0.3.0support by ignoring or replacing the exact selector.0.3.0adds the optionalprofilemember and escalationroutes; these newer-only shapes are not accepted by the historical structural schema. Writers targeting an older selector must satisfy that older version's requirements and cannot emit these members under it. Readers implementing multiple versions dispatch on the complete selector and preserve the older contract; supporting the current version does not reinterpret historical documents. - Carrier: §2.1 now requires Unicode escapes in the UTF-16 surrogate range to form well-formed pairs. A lone
\uD800escape in a title was accepted by the published0.2.0-draftcarrier and structural schema but is refused as malformed input here. Replacing onlyspecVersioncannot repair it; the author must supply an intended Unicode scalar value or a valid surrogate pair, not silently substitute a replacement character. - Structural and semantic migration: revalidate the document under §§3.1–3.3, including its selected document profile, supported ceilings and escalation form. Selector-only migration is sufficient only when the document already satisfies those requirements. Otherwise deliberate content changes and review are needed; there is no automatic transformation or unchanged-verdict promise for every historical document.
- Evaluation: re-declaration opts into this release's exact §§7–8 evaluator semantics and evaluation corpus, including the selected escalation behavior. It is not semantically inert and creates, transfers or strengthens no implementation-conformance claim.
An unedited 0.2.0-draft pack is not structurally conforming to 0.3.0 because its selector is
exact (§4). The 0.1.0-draft and 0.2.0-draft schemas remain published for documents retaining
those selectors, with historical rules and identities preserved.
An evaluator-conformance claim (§3.4) attaches to one exact specVersion and to the evaluation
corpus published with it. It is not inherited by a later or an earlier version, and re-declaring a
pack acquires nothing for the implementations that read it.
12. Normative references
- BCP 14, including RFC 2119 and RFC 8174, defines the requirement keywords used by this document.
- RFC 8259 defines JSON.
- RFC 3986 defines URI syntax.
- RFC 3339 defines the date and date-time forms used by schema format assertions.
- RFC 6901 defines the JSON Pointer syntax admitted by
fact.path. - RFC 8785 defines the JSON canonicalization used by §8.3 when two dispositions are compared byte for byte.
- JSON Schema Core, Draft 2020-12 and JSON Schema Validation, Draft 2020-12 define the schema dialect and validation keywords used by the normative schema.
13. Open questions
Whether portable rule evaluation belongs in Core or in a separate profile is closed: §3.4 places the class in Core, so the error contract and the disposition shape live in one place that a later evaluation profile can build on rather than restate. Before a candidate stable core, the project must still resolve:
- exact unit, date/time, and normalization semantics beyond the decimal-string ordering of §7.4;
- a
betweenfact operator with an inclusive lower bound and exclusive upper bound; it could make the two-comparison band of §3.3.1 one line and exact by construction, but adding anopis a schema change that older evaluators would refuse, so evidence should first count use of the two-comparison rewrite; - whether equality between syntactically valid but arithmetically unrepresentable JSON numbers is
unknown, as §7.4's incomparable-value rule implies, or an explicit input error. This is the single seam §8.3 excludes from its byte-agreement requirement, and the evaluation corpus carries no row for it because a row cannot state an expected result until the question is closed; - an interchange form for evidence beyond §8.2's tri-state, and whether §8.2 grows into it;
- the minimum a trace must surface, including whether it must surface a true rule that a forced outcome skipped;
- a machine-readable diagnostic contract, for document validation and for the §8.4 error classes;
- the minimum provenance and lineage model;
- whether authority bindings belong in optional profiles;
- content identity, canonicalization, and signatures;
- imports and content-addressed dependencies; and
- negotiation beyond the document ceiling profiles in §4.1.