The conformance claim
The specification states it as invariant 12: given the same deployment binding, the same exact specification bytes, and the same blocks on the active chain, independent implementations produce identical events, reason codes, state, counters, event roots, object-state roots, and chained roots at every height.
Everything else on this page follows from that sentence. Note how much it demands beyond agreeing on valid or invalid. Two implementations that reject the same transactions for different reasons are both nonconforming, because their event leaves differ, so their event roots differ, so every chained root after that block differs forever.
Nobody issues a Tandem conformance certificate, and this repository does not run a test service. Conformance is something you demonstrate with reproducible evidence against published artifacts, and that anyone else can re-run. That is the whole mechanism.
Requirements
| Requirement | Rules |
|---|---|
| Bind to exactly one network, one configured INIT txid, and one specification digest, selected by configuration and never by discovery | ID-1, ID-2 |
| Derive the namespace commitment and object keys by the exact preimages, using wire byte order for transaction identifiers and never reversing raw digests | ID-5, ID-6 |
| Detect marker candidates by the broad rule, so that malformed markers remain detectable and cannot evade multiple-marker counting | REC-1, REC-2 |
| Remove foreign INIT candidates before counting markers | REC-3 |
| Enforce the exact script and payload lengths, minimal push encoding, and absence of trailing bytes | REC-4, REC-5, REC-6 |
| Enforce every fixed payload field, including reserved bytes, flags, defined kinds, and defined reasons | REC-7, REC-8, REC-9 |
| Enforce the key pair rules: valid points, distinct, sorted, and bound to their required roles | PAIR-1, PAIR-4 |
| Enforce the exact 71-byte witness script and the four-element carrier witness stack in order | PAIR-2, PAIR-3 |
| Enforce sequence continuity, carrier continuity, and equal terminal payouts | PAIR-5, PAIR-6, PAIR-7 |
| Enforce the exact fee arithmetic, including the ceiling and floor split that gives the odd satoshi to side A | PAIR-3.3 |
| Enforce every operation template exactly, with exact input and output counts, roles, and sequences | OP-1 to OP-6 |
| Require confirmation in a strictly earlier block for every required prevout | OP-6 note |
| Apply the exact state machine, including terminating an object on any confirmed carrier spend that does not validate | ST-1, ST-2, ST-3 |
| Maintain the three post-block counters exactly | ST-6 |
| Apply the dispatch order, including its precedence over numeric reason order | INV-1, INV-2 |
| Return the lowest failing reason code within a single-marker operation | INV-3, INV-4 |
| Use the stable reason registry with its permanent names and numeric values | INV-5 |
| Compute event leaves, object-state leaves, both Merkle roots with odd-leaf duplication, and the chained root, for every block including empty ones | ROOT-1 to ROOT-4 |
| Reverse block application exactly on disconnection, before applying any replacement branch | ROOT-4 |
| Exclude mempool observations from state, counters, and roots entirely | ST-6 |
Evidence you can produce today
These are reproducible now, against published artifacts, with no network and no permission required.
| Evidence | Covers | Does not cover |
|---|---|---|
| Specification digest and byte contract | That you are reading the same protocol as everyone else | Anything about your parser |
| The five published marker encodings | Payload field layout, exact lengths, push minimality boundaries | Transaction-level rules, signatures, state |
| Identity derivations | Namespace and object key preimages, and byte-order handling | Everything downstream of identity |
| The carrier derivation | Key sorting, witness script bytes, P2WSH construction | Signature verification |
| The 31 validation cases | All 26 reason codes, and the event type and class each produces | Fee arithmetic against real amounts, real signatures, multi-block behaviour |
| The published preimages and Merkle levels | Leaf field order, domain tags, odd-leaf duplication, both roots | Root computation over a real chain |
| The chained root reconstruction | The chaining formula and counter encoding | Chaining across many blocks and across a reorganization |
Read the right-hand column carefully. The published corpus is a necessary conformance gate, not a sufficient one. It contains no raw transactions, no signatures, no block data, and no reorganization scenarios. An implementation that passes every published vector has demonstrated that its encodings and hashing are right. It has not yet demonstrated that its transaction validation or its rollback is.
The accurate statement is that your implementation reproduces every published Tandem vector. That is a real and checkable claim. Claiming full protocol conformance requires evidence for the parts the corpus does not reach, which you would have to produce and publish yourself.
Implementation checklist
Build in this order. Each stage is checkable before the next one is written, which is the only realistic way to find a hashing or ordering mistake before it is buried.
Stage 1: bytes
- Hash tandem.md as raw bytes. Compare the digest, byte count, and line count against release/spec.json. Do not normalize whitespace or line endings before hashing.
- Hash golden.json and compare it against the fixture digest in the vector manifest.
- Derive the vector root from the fixture digest and confirm it equals the published root. Derive it, do not copy it.
- Implement the primitive encodings: unsigned little-endian integers, the wire and display hash orders, and the rule that a raw digest is never reversed.
Stage 2: identity
- Implement the namespace commitment. Confirm it reproduces the published namespace for the published binding.
- Implement the object key. Confirm it reproduces the published object key.
- Implement the protocol identifier and object display identifier strings, and use binary keys everywhere internally.
Stage 3: markers
- Implement candidate detection by the broad rule, including partial payloads and non-minimal pushes.
- Implement foreign INIT removal, keyed on payload byte 6 and the configured txid.
- Implement strict parsing: complete prefix, length bounds, declared length equal to present length, no trailing bytes, minimal push, exact per-opcode length.
- Implement all five payload grammars, with every fixed field, reserved byte, and defined-value set enforced.
- Confirm all five published marker scripts parse to their published operation, payload size, and script size.
Stage 4: transactions
- Implement P2WPKH and carrier witness shape checks, including the leading empty element and signature order.
- Implement key validation: on-curve, distinct, sorted, HASH160-bound to the correct role.
- Implement signature verification with strict DER, low-S,
SIGHASH_ALL, SegWit v0 hashing, and the exact prevout amount. - Implement each operation template exactly, with exact counts, roles, and sequences.
- Implement checked fee arithmetic that cannot wrap, then the exact splits including the ceiling and floor tie-break.
- Implement confirmation provenance as a strictly-earlier-block test.
- Implement REFUND recognition, including the exact sequence value and consensus maturity.
Stage 5: classification and state
- Implement the top-level dispatch in its exact step order.
- Implement single-marker validation in ascending reason-code order, returning the lowest failing code, and deferring state-dependent checks that cannot be made.
- Implement the state machine and every state delta, including terminal transitions.
- Implement the three counters as post-block values.
- Confirm all 31 published validation cases produce the published reason, class, and event type.
Stage 6: roots
- Implement the event leaf preimage. Confirm each published preimage hashes to its published leaf, and confirm its length is 371 bytes, not 374.
- Implement the object-state leaf preimage. Confirm the published preimages and the 204-byte length.
- Implement both Merkle trees with odd-leaf duplication and the single-leaf shortcut. Confirm every published intermediate level.
- Implement the empty-set roots for both trees.
- Implement the chained root, and confirm it for the published block including its counters.
- Emit a root for every block from the INIT confirmation block onward, including blocks with no events.
Stage 7: chain handling
- Implement block connection as an atomic unit: events, deltas, both roots, counters, chained root.
- Implement block disconnection as an exact reversal, completing before any replacement branch is applied.
- Confirm that a disconnect and reconnect of the same block returns you to an identical chained root.
- Keep mempool observations in storage with no path into state, counters, or roots.
Stage 8: publishing your view
- Emit agreement tuples matching the published schema, with counters and heights as decimal strings.
- Normalize the tuple with RFC 8785 JCS and sign only the tuple.
- Record your own release provenance per height, and do not rewrite historical provenance on a later release.
- Compare only the nine semantic fields against another pipeline, never the four release fields.
- Fail closed on disagreement, on any missing dependency, and on a stale tip.
Where implementations go wrong
Each of these is a real hazard that the rules single out, and each produces silent divergence rather than an obvious error.
| Mistake | Symptom |
|---|---|
| Reversing a raw digest as though it were a txid | Namespace and object keys differ from everyone else's, and nothing else works |
| Accepting a same-block prevout | Occasional extra valid events that another implementation rejects |
| Returning a true but not lowest reason code | Verdicts agree, event roots do not |
| Padding the event preimage to 374 bytes | Every event leaf differs, so every root differs from the first event onward |
| Skipping blocks with no Tandem events | Chained roots diverge permanently from the first skipped block |
| Giving the odd fee satoshi to side B | Valid transactions rejected, or invalid ones accepted, on odd fees only |
| Ignoring an invalid carrier spend instead of terminating the object | Objects that should be dead stay active, so object-state roots diverge |
| Emitting one event for a multiple-carrier spend | Event count and ordering differ, so the event root differs |
| Parsing agreement counters as numbers and re-serializing | Signatures stop verifying at large values or on round trips |
| Letting a mempool sighting satisfy a predecessor requirement | Constructed transactions fail confirmation provenance once mined |
| Sorting object leaves by display identifier rather than binary key | Object-state root differs whenever ordering differs between the two |
Treating key_id as authenticated | An unsigned envelope field is trusted to select trust |
If you are building a product
Parser conformance is one concern. Shipping something to people who hold keys is another, and the second one has its own rules.
- Label the network and the verification status wherever state is shown. Never present state from a height where authorized pipelines disagree.
- Keep mainnet construction and broadcast unavailable. Mainnet is not active, and no repository, website, or funded address changes that.
- Fail closed for state-changing actions during any indexer disagreement or unreadiness.
- Complete, export, checksum, and restore-test every recovery transaction before its parent is broadcast. The exit is prepared before the move, not after.
- Reconstruct and display inputs, outputs, amounts, scripts, fees, sequences, locktime, key order, and commitments before requesting a signature. Blind signing defeats the pairing property entirely.
- Never request a seed phrase or a raw private key, and never accept one if offered.
- Treat all retrieved content as untrusted. Enforce your own size and type limits, render safely, and never execute retrieved content as application code.
- Explain permanence and correlation before a user commits personal, legal, location, or relationship data to a public chain.
The Bitcoin Universe capability snapshot lists 38 protocols, 29 of them with a marketplace entry. Tandem has no entry at all, so no Universe surface implements a buy, sell, list, or transfer action for a Tandem object. If your product needs a trade path, Tandem does not provide one and this repository does not describe one.