Skip to content

Security guarantees and conformance coverage

This is an informative map of the normative requirements to the repository's executable tests. It is not a new profile, a certification, a claim that every input has been tested, or evidence that a particular deployment passed. A test result applies to the exact implementation, inputs, policy, verification time and tool version recorded in that run.

The verification checklist, canonicalization profile and admission profile remain authoritative. A reference implementation and the test kit can both contain defects. Resolve discrepancies against the specification and a reproducible case; agreement between implementations does not decide correctness.

What the guarantees mean

Layer What its checks establish What they do not establish
Schema The input has the permitted structure and field values Valid signatures, honest claims, principal identity or authorization
Cryptographic verification The checked signatures, hashes and relationships satisfy the applicable rules for the supplied keys, policy and time That the named principal is trusted, that a recorded event occurred, or that a tool may run
Principal trust Verified principal signature components match the operator's out-of-band trust set Identity beyond that trust source or permission to perform an action
strict-v1 admission Verification, principal trust, signed audience/session constraints and sufficiently fresh revocation status satisfy the profile Single use, revocation newer than the snapshot, or action authorization
Adapter enforcement The integration applies the operator's admission decision before its protected handler A property supplied by the core protocol or established by the external conformance kit

action_authorized remains false. A verified or admitted record of a blocked or escalated action is evidence of that recorded decision, not permission to execute it. Session binding prevents splicing of inconsistent sessions; it does not consume a bundle or make it single-use.

Reading the evidence

The kit README defines the commands, contracts, report fields and exit codes. Its surfaces are different:

  • Reference: tools/conformance.js calls reference helpers and lib/verify.js; the latter schema-validates V2 input and delegates cryptographic verification to TypeScript.
  • External primitives: contract /1 exercises canonicalization and digests through a supplied implementation.
  • External evidence: contract /2 exercises Merkle roots, composite signatures and V2 bundle verification. The repository supplies TypeScript, Python, Go, Rust and WASM wrappers.
  • External admission: contract /3 exercises combined admission and configuration loading. The repository supplies TypeScript, Python, Go and Rust wrappers; WASM has no admission API.
  • SDK and adapter suites: separate tests, with their own entry points and scopes. An item in the kit's inventory is not a test executed by that kit.

The numbered contracts are runner interfaces, not versions of the DCP protocol. Wrapper identity is self-declared. Five wrappers are not five independent external adopters: WASM shares Rust code, and all these wrappers belong to this repository.

A negative result is useful only with a working positive control. Altering signed content without updating its signature can make a test fail for several reasons. A spec_step label or a matching error message alone does not prove that one particular check caused rejection. Cases with an isolated valid/invalid pair provide stronger evidence than separately built rejected bundles with only a suite-level positive control.

V2 verification map

The case names below refer to bundle vectors. M, R and A mean must_reject, must_reject_bundles and must_accept_bundles; the external IDs have the prefix external.v2.bundle_vectors. followed by must_reject, must_reject_bundles or must_accept, respectively, then the case name. signed_bundle is the base positive. These are selected traceable samples, not an exhaustive list or a completeness rating.

Normative rule Selected existing cases or suite Scope and remaining limits
V2-1: select the version M dcp_bundle_version_1_0, dcp_bundle_version_3_0 V2 entry-point rejection; does not exercise all V1 requirements
V2-2: validate envelope and artifact schemas Reference v2.signed_bundle.schema_invalid_payload_rejected; schema suites; the opt-in schema-validation catalog (57 cases) The SDK verifiers on main run V2-2 themselves; published SDK versions do not. See the boundary below
V2-3: manifest, payload hashes and audit binding M intent_payload_hash_wrong, audit_entries_truncated; R manifest_intent_hash_mismatch, audit_chain_hash_wrong; A empty_audit_trail Samples of hash/chain binding; not isolated coverage of every field and malformed shape
V2-4: session, time and unsigned metadata consistency R intent_session_nonce_differs, session_expired_with_offset, session_longer_than_policy_max_with_late_created_at; M signature_signer_id_other; A session_duration_at_millisecond_precision Fixed-time tests; requested policy and effective mode must be distinguished
V2-5: signature structure and canonical encoding M bundle_classical_sig_b64_with_trailing_bits, intent_classical_sig_b64_unpadded; R classical_only_bundle_signature_without_pq Encoding samples do not cover every signature location and defect combination
V2-6: principal signs the manifest R bundle_signed_by_agent_keys; reference v2.signed_bundle.forged_classical_signature_rejected Role binding and signature samples; does not establish trust in a self-declared principal
V2-7: verify present PQ signatures M bundle_pq_signature_invalid, bundle_pq_slot_holds_ed25519 The legacy evidence catalog exercises these under its selected policy; claiming all effective modes requires corresponding controls
V2-8: verify each artifact with its context and signer role M rpr_classical_signature_invalid, intent_signed_by_principal, policy_decision_signed_under_intent_context Samples of artifacts and roles; not every combination of component, context and key
V2-9: derive tier without allowing a declaration to lower it R classical_only_intent_action_type_constructor, classical_only_intent_security_tier_constructor Verdict samples; the external bundle operation does not assess the reported resolved tier
V2-10: enforce effective mode and algorithm policy R classical_only_payment_from_low_risk_passport; classical_only_routine in four modes Mode samples; the legacy evidence catalog has no dedicated algorithm allowlist/advisory matrix
V2-11: verify secondary fields when present external.v2.secondary_sha3, from secondary vectors Positive controls and malformed/mismatching fields; absent links are optional, so acceptance does not imply a complete secondary chain
V2-12: bind and verify checkpoints A pq_checkpoint_over_the_trail; R pq_checkpoint_listed_but_missing, pq_checkpoint_event_range_count_wrong, pq_checkpoint_pq_signature_invalid Samples of membership, range and signatures; not every malformed range or component combination
V2-13: derive key IDs and enforce key validity R passport_key_kid_not_derived, passport_key_public_key_with_trailing_bits, rpr_binding_key_revoked Key/encoding/status samples; not exhaustive key-policy coverage
V2-14: cross-artifact consistency R passport_principal_binding_reference_other, audit_entry_policy_decision_other; A blocked_action_recorded, escalated_action_recorded Evidence consistency is distinct from permission to act

The corpus's expectations must be interpreted with its declared policy, per-case overrides and verification time. A positive hybrid bundle can verify under pq_only; the presence of classical bytes needed for binding does not make it a negative control. A requested classical_only policy can resolve to a stricter effective mode because of the action's tier.

Schema and cryptographic API boundary

V2-2 requires schema validation. On main, the V2 verifiers of the TypeScript, Python, Go, Rust and WASM SDKs run it themselves: verifySignedBundleV2 and its counterparts, the combined admission API, which verifies first, and the experimental candidate verifier; evaluating admission from an earlier verification result does not run it again. Published SDK versions do not include it. The gate validates the signed bundle envelope and the four payloads (responsible_principal_record, agent_passport, intent, policy_decision) against schemas/v2. It runs after the verifier's policy and clock checks, and before the verifier checks the manifest, payload hashes, keys and signatures. Every SDK interprets the same representation generated from schemas/v2 (tools/schema-ir/); CI regenerates it and compares the copies.

  • Closed and open objects. An unknown member of a closed object (additionalProperties: false, for example the envelope, SignedPayload, composite_sig, audit entries and checkpoints) is rejected even when hashes and signatures stay valid. In an open object, such as the intent target or the audit evidence, the declared members keep their constraints (target.channel, for instance, is required and enumerated); only the additional members the schema does not describe are not inspected at this layer, and those under a commitment can reach canonicalization. An additional member of the bundle object itself is accepted: the schema leaves bundle open, the member is under no commitment (unlike the signed artifacts and manifest the bundle contains), and no later check reads it.
  • Missing and null. A missing required member and a null where the schema expects another type are both rejected, with different diagnostics (required, type). The manifest's session_issued_at and session_expires_at must be strings when present: null is rejected.
  • Diagnostics. A schema failure returns verified: false with errors of the form schema: <JSON pointer> <keyword>[ <member>], at most 16 followed by schema: further errors not listed, never with input values and without cryptographic details. A rejection that a deeper check used to report can now carry a schema diagnostic instead; a schema failure does not show that the deeper check ran.
  • Candidate overlay. On the experimental dcp-jcs-v2 path, which a caller selects explicitly, the only difference is the manifest's canonicalization_profile, which must be dcp-jcs-v2. The default profile and the signed bytes are unchanged.
  • date-time. The format check is the one the reference verifier applies, ajv-formats 3.0.1 in full mode, quirks included: any ECMAScript white space or t as the separator, +hh and +hhmm offsets, a second 60 when the time moved by its offset is 23:59. It is a compatibility boundary of the schema layer, not strict RFC 3339. The temporal parsers of V2-4, V2-13 and V2-14 remain a separate, later layer and can still reject a time the schema accepts.
  • Parsers come first. What a JSON parser refuses never reaches V2-2. Go reports a root that is not an object as its historical parse error; the Rust API takes a parsed serde_json::Value, so serde_json's refusals (a lone surrogate, 1e400) belong to the caller; the WASM binding keeps its policy parse error, JSON parse error and version dispatch before V2-2.
  • Acceptance change. Schema-invalid bundles that the SDK verifiers accepted before now return verified: false. No schema-only API is added, and no schema or profile changes.

An implementer claiming the full V2 checklist must account for V2-2 as well as the cryptographic checks. Do not weaken the schema or describe a partial API as a complete gate to make a test pass. The kit reports these layers separately.

Unknown members are not universally forbidden. Some schema objects are open. Schema acceptance of an extension in a signed object does not preserve its old signature: hashes and signatures must be recomputed when signed content changes. No new required-extension mechanism is defined here.

The opt-in schema-validation catalog runs 57 signed cases through an implementation: 13 positives, and 44 negatives that each count only when the base case verifies in the same run. CI runs it through the five SDK wrappers. The opt-in schema diagnostic catalog keeps 15 closure cases: its base and permitted extensions are positive controls; closed-object extensions and invalid enumeration values retain the normative rejection. A failing SDK case remains a failure, and a pass of either catalog covers its cases only. The separate tools/conformance/schema-boundary.js report distinguishes schema validation, integrity of the finite corpus, and schema-plus-SDK composition at the corpus time. That composition is not evidence that the SDK alone implements V2-2, and the integrity helper is not a general normative verifier.

Verifier policy samples

The opt-in policy catalog adds 74 cases under the existing /2 contract: 10 positive controls, 24 invalid-present-PQ cases, 14 algorithm-list/advisory cases and 26 committed tier cases. Each request carries its exact policy and verification time. The default evidence catalog remains unchanged.

The new routine hybrid control exercises effective classical_only, as well as the other three modes. The standard hybrid control raises a requested classical_only to hybrid_preferred. The corpus records this derivation; /2 assesses the verdict, not the implementation's reported tier or effective mode.

The PQ negatives alter only the PQ signature at the bundle, passport or checkpoint; the classical component remains valid. Algorithm-list cases keep the same bundle and change only policy. Tier cases reuse separately signed committed bundles and a routine control under the same requested mode: they are not single-change twins. Every negative requires its positive control to pass in the same run.

Classical algorithm exclusions under pq_only remain omitted pending clarification, without an expected verdict. Deferred cases and interpretation questions are recorded in the corpus; an untested combination does not by itself demonstrate a contradiction in the specification. These samples do not close the schema gap or establish complete V2 conformance.

Structural samples

The opt-in structural catalog adds 16 cases through /2: two positive controls and 14 negatives covering signature encoding, checkpoint components and ranges, manifest commitments, a fractional payload, session order and a bundle classical signature invalidated while its PQ signature is recomputed correctly. The effective mode is hybrid_preferred; these classical negatives make no claim about pq_only.

The four encoding cases preserve the decoded signature bytes. Checkpoint ranges use actual trail positions, with deliberately unsorted identifiers. Manifest mutations are signed again. A reversed session has a separate positive twin within the allowed clock skew. Every negative requires its controls to pass in the same run.

Isolation has explicit limits: a fraction has no dcp-jcs-v1 representation, so its old hashes and signatures remain stale; a backwards range has no valid root for that range. Component checks document the intended defects but do not identify which SDK check caused rejection. These samples do not close the schema gap or prove complete conformance.

Admission map

The shared admission vectors and external admission catalog exercise the following groups through the combined admission API and configuration loaders. Read the exact rule, inputs and expected fields in each case; the group name is not a proof of exhaustive coverage.

Requirement Exercised surface Limit
T1–T2: principal and component keys anchored in operator trust external.admission.outcomes Trust is supplied out of band; the kit does not establish a real-world identity
P1–P4: V2, signed audience, signed session window and hybrid principal signatures Outcomes and composed cases Structural and verified checks are different; malformed-value combinations are not all enumerated
R1–R5: snapshot availability, shape, age and subject status Outcomes A fresh snapshot is not proof of revocation events after its checked_at
Configuration: reject unknown fields, malformed trust and profile weakening external.admission.config Multiple-defect cases may allow more than one normative error; incidental message wording is not the rule
Combined procedure and result Outcomes and composed cases action_authorized:false, recorded decisions and trust/profile results are assessed; complete signer_keys output is not directly compared
A1–A3: protected handler, operator configuration, sources, tenant and cache Separate adapter tests Outside this external kit; an SDK result does not prove integration enforcement

An evaluator that accepts a precomputed verification result trusts its caller to supply the result for the same bundle, policy and time. The external admission operation uses the combined API. A passing combined test does not make an arbitrary caller-supplied verification object safe.

Claims for core and profiles

Surface What can be reported from the kit What must remain separate
Core data representation Exact tested dcp-jcs-v1 canonical bytes and digests Untested inputs and the experimental candidate
V2 evidence verification Results for selected bundle, Merkle and signature cases Full V2 compliance, especially schema coverage, unless separately established
Crypto primitives Tested domain separation, component verification and binding Verifier policy, principal trust and admission
strict-v1 admission Results for the selected admission/configuration cases Deployment enforcement and action authorization
V1 Reference schema and integrity checks on committed fixtures Independent third-party V1 conformance
A2A and governance Only the specific rules actually exercised by a named suite Complete functional conformance of either profile
DCP-05 to DCP-09 The internal schema/wire suites' stated checks Complete lifecycle, rights or delegation semantics
Experimental dcp-jcs-v2 Its separately selected experimental tests Normative/default status; dcp-jcs-v1 remains unchanged

A subset result must name the subset and its limits. Do not turn unsupported, a missing case, a crash, a timeout or a skipped matrix into a passing case. A reserved SDK test that returns without running its matrix is not evidence that the matrix ran.

Further validation

The implementer guide describes how to reproduce and report results independently. External implementation and independent security review are additional milestones; this repository's tests do not substitute for them.

Performance measurements use their own documented harness. End-to-end timing does not attribute cost to a cryptographic primitive or prove the absence of early exits. Optimize only after measuring a specific cost and preserving verification decisions and compatibility.