Test Vectors
To ensure interoperability between different implementations of the APL Protocol, we provide a suite of test vectors covering content-addressed identity, single-receipt verification, pairwise relation evaluation, and the reference AI-Eval vertical profile.
1. JSON Canonicalization (JCS)
APL uses the same JCS (RFC 8785) canonicalization as ATL for all content-addressed artifacts (frames, bridges, transformations). The JCS test suite published by ATL is normatively sufficient for APL implementations:
- Key ordering (UTF-16 code point order)
- Number formatting (no trailing zeros)
- Unicode handling (no escaping of non-control characters)
2. Core Single-Receipt Verification
End-to-end vectors for the 14-step single-receipt verification algorithm (The Protocol § 5). Each vector carries a metadata.apl payload, the frames (and, where relevant, bridges) needed to resolve references, and the expected VerifierOutput.
- Valid cases: canonical AI-Eval observation, photojournalism raw capture, scientific-measurement spectrometer.
- Invalid cases:
carrier-failure,invalid-claim-structure,invalid-frame-reference,invalid-frame-kernel,semantic-linkage-failure.
Browse Core Single-Receipt Vectors
3. Core Pairwise Relation Evaluation
Vectors for the pairwise algorithm (The Protocol § 5.8). Each case supplies two receipts plus a top-level query and asserts the expected relation_outcome.
same-frame-comparable— identical frame, identical aspect sets, compatible statements.bridged-comparable— different frames, applicable content-addressed bridge resolves and passes Core checks.incomparable-no-bridge— different frames, no applicable bridge.statement-shape-mismatch— same frame but statementcontentshapes diverge.
4. APL/AI-Eval Profile Vectors
Vectors for the reference vertical profile APL/AI-Eval v1.0, exercising profile-specific claim rules, predicate constraints, allowed relation_type values, and bridge-kind applicability.
- Single-receipt:
ai-eval-mmlu-valid,ai-eval-invalid-profile. - Pairwise:
bridged-runner-equivalence,incomparable-no-bridge,incomparable-adversarial-bridge,ai-eval-same-frame-disallowed-predicate,ai-eval-same-frame-disallowed-relation-type.
Vector Format
Each vector is a self-contained JSON file. The harness is defined in apl-core/tests/vectors_core.rs and apl-core/apl-ai-eval/tests/vectors_ai_eval.rs; both crates use the same shape.
Single-receipt vector
{
"name": <string>, // required — short identifier
"description": <string>, // optional — human-readable summary
"source": <string>, // optional — normative reference or "fabricated"
"metadata_apl": <object>, // required — the APL payload under test
"frames": [<frame>, ...], // optional — frames resolvable during verification
"bridges": [<bridge>, ...], // optional — bridge documents (present but not consumed on the single-receipt path)
"carrier": null | "invalid", // optional — swaps the mock carrier; "invalid" exercises carrier-failure
"profile": null | <string>, // optional — profile id (apl-core harness only accepts null)
"expected": <SingleExpected> // required — see below
}expected for single-receipt vectors is a matcher, not a full equality check:
{
"core_outcome": "apl-valid" | "apl-invalid",
"relation_outcome": "relation-not-evaluated",
"failure_classes_contains": [<failure-class>, ...], // optional
"diagnostics_contains": [<diagnostic-code>, ...], // optional
"diagnostics_absent": [<diagnostic-code>, ...] // optional
}Pairwise vector
{
"name": <string>,
"description": <string>, // optional
"source": <string>, // optional
"left": { "metadata_apl": <object> }, // required
"right": { "metadata_apl": <object> }, // required
"frames": [<frame>, ...], // optional
"bridges": [<bridge>, ...], // optional
"supplied_bridges": [<bridge>, ...], // optional — the set passed via PairwiseInput.supplied_bridges
"query": <relation_query>, // required — NOT "relation_query"
"profile": null | <string>, // optional — profile id
"expected": <PairwiseExpected>
}expected for pairwise vectors:
{
"left_core": "apl-valid" | "apl-invalid",
"right_core": "apl-valid" | "apl-invalid",
"relation_outcome": "same-frame-comparable" | "bridged-comparable" | "incomparable" | "relation-not-evaluated",
"diagnostics_contains": [<diagnostic-code>, ...], // optional
"diagnostics_absent": [<diagnostic-code>, ...] // optional
}Pairwise expected has no failure_classes_contains field — per-side failure classes are reported in the single-receipt output and are covered by single-receipt vectors; the pairwise shape asserts only the relation outcome and diagnostics.
Hash-placeholder substitution
Vectors use two placeholder forms inside string values; the harness substitutes them before calling the verifier:
"<FRAME_HASH:N>"is replaced withcanonical_hash(frames[N])— that is,SHA-256(JCS(frames[N]))emitted assha256:<hex>."<BRIDGE_HASH:N>"is replaced withcanonical_hash(supplied_bridges[N])— the hash is taken from thesupplied_bridgesarray, not frombridges. Use it inbridge_refsentries insidemetadata.aplso that the content-addressed check in the pairwise algorithm accepts the corresponding supplied bridge.
The harness resolves <FRAME_HASH:N> placeholders inside supplied_bridges first, then substitutes <FRAME_HASH:N> and <BRIDGE_HASH:N> placeholders in the claim metadata against the already-resolved supplied bridges. This ordering keeps the vectors readable while preserving the content-addressed identity contract.