Skip to Content
Test Vectors

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)

Download JCS Vectors (JSON) 

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 statement content shapes diverge.

Browse Core Pairwise Vectors 

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.

Browse AI-Eval Vectors 

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 with canonical_hash(frames[N]) — that is, SHA-256(JCS(frames[N])) emitted as sha256:<hex>.
  • "<BRIDGE_HASH:N>" is replaced with canonical_hash(supplied_bridges[N]) — the hash is taken from the supplied_bridges array, not from bridges. Use it in bridge_refs entries inside metadata.apl so 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.

Last updated on