@uniba-commons/persona-conformance
v0.1.0
Published
Cross-language conformance vectors for persona-protocol: frozen wire-format and claim-decision fixtures every implementation must pass. Data only — no runtime code.
Downloads
67
Readme
Conformance fixtures
Published as @uniba-commons/persona-conformance — the frozen, versioned
vectors every persona-protocol implementation must pass, so independent codecs
cannot drift from the wire contract. Data only; no runtime code.
Shared test vectors run against every language implementation (docs/spec/conformance.md). Runners live with each implementation's test suite:
- Ruby:
gems/persona/spec/conformance_spec.rb - TypeScript:
packages/server-core/test/conformance.test.ts
Files
wire-names.json— the fixed wire names. Runners assert their language's exported constants equal these values.claim-decision.json— the §6 claim decision table. Each case sets up a browser state and a holder state against an in-memory storage port, runs the implementation's claim logic, and asserts the outcome. Keys inexpectare optional — runners check only the keys present:personas_delta— net persona-count change (a confirmed merge is -1: none created, the source retired)result_user— who the browser resolves to afterwards ("new"/"current"/"holder")subject_holder— who holds the subject afterwards ("result"/"current"/"holder")result_has_agent_binding— the result user is bound togiven.agent_uidaccount_bindings_delta/agent_bindings_delta— binding-count changemerged/merge_preview— result flagsechoed_agent_uid— the credential-echo exception (string or null)current_retired— the acting persona no longer existsbrowser_binding_moved_to_holder—given.agent_uidnow resolves to the holder
claim-code.json— normalization, display formatting, and digest vectors for single-use claim codes (P-7).session-cookie.json— cookie-profile session verification vectors (C-1): a fixed secret plus tokens that must verify (returning the payload) or be rejected (tampered, expired, malformed).verify_atpins the clock in epoch seconds. Signing is covered by round-trip properties in each implementation, not by fixed bytes — token bytes depend on payload serialization order, which the protocol does not constrain. These vectors therefore pin verification within an implementation, not cross- implementation cookie interop: a cookie signed by one codec is not guaranteed to verify under another until a canonical serialization is frozen (see C-1 in the cookie-profile spec).
Which vectors bind you
Vectors bind by transport profile and capability level — you conform
against only the ones your implementation reaches. A header-profile, level-1
consumer needs wire-names.json and nothing else.
| | Level 1 — anonymous identity + join | Level 2 — + claims (account linking / claim codes) |
| ----------------------------------- | ---------------------------------------- | -------------------------------------------------- |
| Header profile (X-Agent-Id) | wire-names.json | + claim-decision.json, claim-code.json |
| Cookie profile (session cookie) | wire-names.json, session-cookie.json | + claim-decision.json, claim-code.json |
wire-names.jsonbinds every implementation — the wire names are shared by both profiles (NOT_JOINEDrides the cookie profile too, C-4/H-4).session-cookie.jsonbinds only the cookie profile (C-1).claim-code.jsonbinds implementations that issue single-use claim codes to restore or move a persona across browsers (P-7).claim-decision.jsonbinds implementations that graft a persona onto a verified account — the §6 account-link decision table.
Use (consumers)
Adopt these as tests against your own implementation — you need not depend on the reference libraries to conform. Pin a version; the vectors are what a release freezes.
import cases from '@uniba-commons/persona-conformance/claim-decision.json' with { type: 'json' }
// drive your account-link logic through each case and assert the expected outcomeAdding a vector
Fixtures are hand-written JSON (session tokens are generated by
session-cookie.gen.mjs next to this file). Keep them implementation-free:
a vector that only one implementation can satisfy is a spec bug — raise it
against the spec (docs/spec/) instead of special-casing a runner.
