Integrity Criteria

tx-rails

Criteria for the Integrity of Transaction Processing

The written definition of what “behaving correctly” means, against which
an independent practitioner can perform procedures and report findings.
Short title Integrity Criteria
Subject matter tx-rails transaction processing, peer discovery, deployment boundary and origination
Criteria groups 6 worked · 34 criteria · 10 exclusions
Version 0.4 — draft
Status not yet adopted
How to use this document

§4 to §10 are worked in full with real entries. Every check ID, registration, status and gap
in them was verified against the code, not illustrated. §1, §2, §11 and §12 remain
sample content, marked as such, and are meant to be rewritten by whoever adopts this.
Appendix A is a blank section to copy for each further criteria group.
The six criteria groups are drawn from different places, and the difference matters when reading a
finding:
  • §4 Initialisation and §5 Evidence integrity come from the live check set and from
    defects already found and fixed on this estate.
  • §6 Peer discovery, §7 Integration mode and data visibility,
    §8 Federation boundary and settlement regime and §9 Machine origination come from the
    four parts of the platform’s own architecture material — peer discovery and minimal DNS;
    integration modes and the data-visibility ladder; the federation trust model, deployment shapes and
    the three transaction regimes; and machine-originated transactions. Each claim there was read back
    against the code before it was written as a criterion, which is what §10.4 records.
  • Keep the five-column shape. It is what makes a criterion testable rather than merely stated.
  • Cite check IDs; never paraphrase what a check does. The code is the definition. A criterion
    that restates it will drift from it, and nothing will be comparing the two.
  • Anything not covered goes in §10. A criteria list with no exclusions section silently asserts it is complete.
  • A pitch is not a source. Four criteria groups here were extracted from material written to
    persuade. Every sentence of it was checked against the code first, and one claim did not survive
    that check (§10.4). Extracting criteria from architecture material is a good way to find out what
    the system does; it is not a way to find out what is true.

1 · Purpose and intended users

Sample content — rewrite

This document states the criteria against which the integrity of transaction processing in
tx-rails is to be evaluated. It exists so that a party outside the operator can form a view
of whether the platform behaved correctly without relying on the operator’s assurance
that it did.
The intended users are the engaging party (ITOTCCA), an independent practitioner engaged to
perform procedures against these criteria, and any counterparty to whom the resulting report
is provided. It is not written for the general public and is not a marketing document.
Within the engaging party the officer responsible for this subject matter is the
executive director of cyber-security. That role owns this document — it is the approver
named in §12 — and owns custody of the key material the criteria depend on, including the
validator signing keys held alongside snapshots.
What the role cannot be

The executive director of cyber-security is an officer of the engaging party. That is
the role’s usefulness here and equally its limit. It can own the criteria, hold the keys,
and answer for the estate’s response to a finding. It cannot supply the independence the
report depends on, because independence under the framework is independence from the
responsible party, and this role is part of it.
Personnel do not cross. The arm’s-length party operating the auditor tiers
holds no role inside ITOTCCA — decided 2026-09-03 on risk-exposure grounds, and recorded here
because it is the kind of arrangement that is easy to concede quietly later. It is also the
load-bearing one: under IAS 24 a person who is key management personnel of both entities makes
them related parties by definition, so a single shared officer would make the words
arm’s length false as a description rather than merely weak as a safeguard.
The same boundary decides a question that will be asked: whether the auditor tiers could sit
under this role. They could, and the criteria in §4 to §9 would be unaffected — but
their findings would remain operator-produced, which is precisely the property EVID-06
exists to name. That is not a defect and it is not a substitute. It means the independence has
to come from the engaged practitioner and from a reader’s ability to reproduce a result
without asking the operator for anything — never from the org chart.

Nothing here is an opinion about the platform. Each criterion is a statement that is either
met or not met on a given date, and the document is written so that the difference is
decidable by someone who did not build the system.

Why this section matters

Under an assurance framework the criteria must be relevant to the intended users’
decision
. Naming those users here is what makes relevance assessable rather than assumed —
and it is the section that stops the criteria drifting into things that are merely easy to measure.

2 · Subject matter and scope boundary

Sample content — rewrite

In scope. The processing of transactions by the tx-rails validator mesh: their
admission, ordering, commitment to the ledger, and the trace records written as a
consequence. The criteria address whether the mesh’s replicas agree, whether records
are complete, and whether what was recorded can be shown not to have been altered.
Out of scope, deliberately. The correctness of the data supplied to the platform.
tx-rails records what it is given; it cannot establish that a submitted valuation, hazard
report or payment instruction is truthful. A criterion that appeared to cover this would be
the most damaging kind of error in this document, because it would offer a reader assurance
that no mechanism here can support.
Also out of scope. Availability, latency and throughput; the security of participants’
own systems and client devices; and the conduct of the parties whose transactions are recorded.
Scope varies by integration mode, and this is the trap worth naming. The platform accepts
transactions under four integration modes carrying different evidence. Under the hash-only mode
the customer computes a hash of a transaction that already executed in their own system and sends
only that hash; the platform never sees the content. That customer’s executed / committed /
aborted lifecycle is therefore not merely unrecorded but structurally unknowable, and no
criterion below reaches it.
The specific misreading to guard against: trace.tx_outcome does hold a
committed-or-aborted row for such a transaction. That row records whether our attestation
committed on our chain — not the customer transaction it attests. Reading the first as an
answer to the second would let a criterion appear to cover ground that no mechanism reaches.

Subject matter added in version 0.2 — and the boundary that came with it

Version 0.1 scoped this document to the validator mesh. §6 to §9 extend it outward in three
directions the mesh does not reach: who a node talks to before consensus applies (§6),
which deployment boundary a transaction crosses and what agreement it rests on when it
crosses a border (§8), and what may originate a transaction without a person (§9). §7 sits
across all of them, because what any criterion can reach depends on how the transaction arrived.
These are in scope because a reader forming a view on transaction integrity cannot stop at the
mesh: a transaction admitted by an unverified peer, coordinated across a boundary it should not
have crossed, or originated by a compromised device is not made sound by replicas agreeing about
it afterwards. Every criterion in §4 and §5 assumes those questions were already answered.
What did not come into scope with them. Nothing here evaluates the commercial or
jurisdictional argument the deployment shapes are sold on — that hardware separation satisfies a
given regulator, or that a given topology discharges a transfer obligation. FED-06 states only
that pyramids share no validator, which is a fact about a validator set. Whether that fact
satisfies a data-protection regime is a legal question, and a criterion that appeared to answer it
would be the same error §2 already names, wearing different clothes.

Drafting rule

Scope boundaries cannot be tabulated — a table of criteria implies its own completeness, and
only prose can say what was left out and why. Write the exclusions before the criteria,
while it is still obvious what you decided not to attempt.

3 · How to read a criterion

Every criterion is one row. The columns are a contract, and each exists to
prevent a specific failure in the document itself.
Column What goes in it The failure it prevents
ID A stable identifier, e.g. INIT-01. Never reused, never renumbered. A practitioner must be able to report “criterion 14: performed, no exception”.
Renumbering silently invalidates every report already issued.
Criterion One sentence stating what must be true. No justification, no argument. Prose invites advocacy, and advocacy is what disqualifies criteria as neutral.
How it is tested The check ID that tests it, or the named manual procedure if there is none. A criterion with no test is an aspiration. Naming the test makes the difference visible.
Evidence produced The artefact a practitioner can inspect and retain. A test whose result is not retained cannot be reported on after the fact.
What a failure looks like The concrete observable state when the criterion is not met. The column that does the real work. It is what stops a criterion being written that
cannot fail — “the system maintains the integrity of records” passes every year and means nothing.
Two rules that keep this honest

  • Cite, don’t paraphrase. The How it is tested cell names a check ID; the check’s own
    source comment remains the definition of what it does. Every citation carries the claim it makes —
    data-claim="registered", "unregistered" or "vacuous" — and
    TestCriteriaCitationsMatchTheRegistry in cmd/chubbychecker-joint
    verifies each against the live registry on every build.
    It checks both directions. A test asserting only that cited checks exist would pass happily
    while §10 told a reader something was uncovered long after it was implemented — an understated gap
    is still a false statement to the practitioner relying on it.
  • A registered check is not a working check. Coverage counts are taken from registries, and a
    check that returns success unconditionally is counted the same as one that tests something.
    §10.2 records where that is currently true, by name — thirteen of the one hundred and thirty.
  • An unmarked citation is a citation the guard cannot check. Some mechanisms this document
    relies on live outside the registry the guard composes — a check in another checker’s set, a
    constructor, a build gate. Those are cited in <code> rather than as a claimed
    check ID, on purpose. Marking them would assert a verification that never runs, which is worse
    than not marking them at all. FED-01 is the case where this matters most, and it says so in place.

4 · Criteria — Initialisation

The state that must hold before the mesh processes any transaction: that nodes are
who they claim to be, that they are running the same schema, that no single party controls
admission to the mesh, and that the machinery which makes later comparison possible was switched
on before there was anything to compare.
Failures here are distinctive because they are silent and retrospective: nothing
alerts, and the consequence only becomes visible much later, when a question is asked that the
records can no longer answer.
ID Criterion How it is tested Evidence produced What a failure looks like
INIT-01 A transaction is processed by the node its metadata names, and by no other. cc012 “Node Identities”, a per-transaction check,
registered in checks-joint.
implemented
Check verdict stream; the signed finding attestation covering the block-height window. A committed transaction whose declared node ID differs from the node that processed it.
Raised as a check failure naming both.
INIT-02 Every node in the mesh carries an identical database schema. cc085 “Schema Drift” per block; cc120
“Schema Evolution” in the integrity set.
implemented
Check verdict; the per-node schema comparison the check performs. Two nodes report different schemas — characteristically after a migration that succeeded
on some nodes and not others, which does not otherwise announce itself.
INIT-03 Admission to the mesh does not depend on too few bootstrap peers. cc010 “Overcentralization”, a block check in the
integrity set.
implemented
Check verdict, including the count of distinct bootstrap peers observed. The distinct peer count falls below the configured threshold, leaving one party able to
determine who joins the mesh.
INIT-04 The commitment key is provisioned on every replica before the first trace row is written. No check. Deployment-time evidence only: TRACE_COMMIT_KEY_FILE set on each
replica, and a non-zero row count in trace.org_trace_commitment on each.
manual procedure — no automated test
Pod environment as deployed; per-replica commitment row counts, captured together in one pass. The variable is unset, the committer is absent, and commitments are simply not written.
This does not error at start-up by design — unset means off. The only observable is a
zero count, so absence must be looked for; it will never announce itself.
INIT-05 Bootstrap peers are addressed by IP literal, not by name. cc001 “DNS Reliance”, a per-block
check.
implemented 2026-08-31 — previously registered and
returning success unconditionally.
Check verdict, naming each peer addressed by name and the total examined. Any bootstrap peer given as a hostname. A peer address is the first thing a joining node
trusts — it decides who tells that node what the chain is — and DNS is unauthenticated here,
so whoever answers the name chooses that peer before consensus has any say. An unparseable
address counts as a finding, not a skip: the one address whose resolution path is unknown
must not be the one the check ignores.
Note on INIT-04

It is deliberately included even though nothing tests it automatically. A criterion that matters
and has no test belongs in the register with that stated, not omitted until someone builds the
test — omitting it would make the gap invisible, which is the opposite of what the register is for.
The How it is tested cell is where that distinction lives.

5 · Criteria — Evidence integrity

Whether a result means anything. These criteria are drawn from defects already found
and fixed on this estate, and they share one shape: status was treated as evidence. A service
was running, a unit was active, a charm said ok — and none of those things had been
earned.
They belong in a criteria document rather than a defect log because each describes a
property a practitioner can test, and because the failures were invisible precisely to the kind of
inspection a reader would otherwise rely on. A chain sat halted for roughly a day with every pod
Running and every unit active. An audit tier streamed zero blocks since the day it was deployed
while reporting BFT mesh active (ok). Nothing was broken in any way that
looking would reveal.
ID Criterion How it is tested Evidence produced What a failure looks like
EVID-01 A checking cycle that could not run its checks does not report a pass. RunContinuousChecksSummary, which separates ran / failed / could-not-run /
not-applicable. Used by chubbychecker-governance, chubbychecker-registry
and — since 2026-08-31 — chubbychecker-joint.
implemented on every checker
The cycle’s own summary line, stating how many of how many checks actually ran. A tier logs checks passed in the same cycle in which checks failed on missing
schemas. The corrected form states it outright: NOT A PASS — 3 of 3 continuous checks
could not run
, against checks passed (4/4 ran) elsewhere. Same binary, opposite
verdicts, both true.
EVID-02 Liveness is established by movement, not by reported status. audit-liveness-probe.sh — samples every chain and every auditor twice and
requires the position to have advanced.
operator script, not in the repository
Two sampled positions per node with their timestamps, retained together. The position is unchanged between samples, or the node is unreachable. Unreachable is
a failure, never a skip
— the original defect was that an unanswered node was simply
omitted, and a liveness result over the nodes that answered always looks alive.
EVID-03 Every ABCI application reports its true applied height at handshake. k3d/ops/abci-info-guard.sh — fails the build if any served ABCI application
does not override Info().
implemented as a build gate
The build gate’s own result, per release. An application embeds types.BaseApplication and inherits its answer of
“height 0”, so consensus replays every committed block on every restart —
measured at ~172,900 blocks and about 3.3 hours for a single node — while the service is
active, nothing is logged, and the charm reports healthy. The node is simply not
committing.
EVID-04 An applied-height watermark never moves backwards. No automated test. The write uses SQL GREATEST so a replay cannot lower it.
construction only — no test
The recorded watermark, sampled before and after any restart. A replay re-applies old blocks and overwrites the watermark with its own lower position.
Observed: a node seeded at height 66599 was sent back to the start by its own replay.
EVID-05 Independent recorders hold a fingerprint of a submission, never its content. No automated test — a property of what the interceptor transmits.
design property — no test
The recorder’s stored rows, inspected for payload fields. A recorder holds the actual business payload. This discloses nothing new to the customer,
whose content the platform already holds — the harm is that it places a second copy in a
different party’s custody, carrying every disclosure obligation the original carries and
worth more to an attacker than the ledger. Detection is unaffected: any change to a field,
including renaming or reordering, changes the fingerprint.
EVID-06 What was submitted is attested alongside what the validators recorded. cc131 “Baseline Commitment
Anchored”, a per-block check.
registered 2026-08-31
The gateway tier’s signed commitment for the slab covering each height, verified
against a key resolved by agreement across replicas.
A transaction reached consensus with no baseline at all — meaning something was
executed that the gateway tier never saw. Or the commitment’s signature does not verify,
or it is bound to a different slab than the one it was stored against, which is a replay of
a genuine signature onto the wrong range. Absence of any commitment is not a failure: two
tiers are paired with a baseline recorder — the national gateway tier (gw0–3 with
bi0–3) and the overseer tier (overseer0–3 with ovbi0–3, paired
2026-09-01). Elsewhere a missing commitment is recorded as commitment-weak by design, so
this criterion bites only where a recorder existed to have seen the submission.
EVID-07 A tier’s application state is bound into the block its validators sign. The tier’s app-hash function, evaluated in FinalizeBlock and returned as
the block’s AppHash: get_current_aggregator_app_hash,
get_current_registry_app_hash, get_current_governor_app_hash,
get_current_overseer_app_hash. Enforced by consensus itself rather than by a
check — a validator computing a different digest cannot commit the block.
four tiers; overseer tier from height 130,000
block_app_hash read from every validator in the mesh at one common height.
The values must be non-empty and identical. A digest that is constant across many
heights is not a fault: it changes only when the state it covers changes, so an idle tier
legitimately repeats one value.
Two validators hold different application state while agreeing on every block — the
divergence every other criterion in §5 assumes it would see, silently absent. The
introduction of an app hash is itself the hazard it must survive: adding one changes the
digest of an already-running chain, so it is height-gated — every node is given the
same future height, rolled inert, and switches together. Whatever the application returns it must also record: an overseer node returned the digest correctly for a day while never persisting it, which left the whole tier unable to restart — the handshake compared the state’s real digest against a hash of nothing and panicked. A tier that runs perfectly and cannot be restarted is one power-cycle from an outage. And a hash that cannot be
computed is never returned empty: the node halts instead, because an empty
AppHash from one node while its peers send the real one is a fork produced by the safety
mechanism itself.
Why EVID-06 is the load-bearing one

Every other anchoring criterion verifies the validators’ own account of what happened — block
hashes, trace roots, slab anchors, all produced by the nodes being audited. The baseline is
captured before any validator sees the transaction, and is the only record in the system not
produced by the party it polices
.
Its key resolution is quorum-based for a specific reason: the check verifies a signature against
whatever key it is given, so a single replica able to answer alone could supply an attacker’s
key and make an attacker-signed commitment verify — handing that replica the power to forge the
very attestation the check exists to police. Replicas that disagree about a registered key are
refused rather than resolved to a majority, because the disagreement is itself the finding.

Why these are criteria and not merely history

Each was found by asking a question and following it into the code, not by a check firing. That is
the argument for writing criteria down: the failures a running system reports are, by construction,
the ones it was built to notice. A criterion is a claim someone outside can test, including
claims the system has no opinion about.

6 · Criteria — Peer discovery and name resolution

Whether a node or a client is talking to who it believes it is, before consensus has
any say in the matter
. A peer address is the first thing a joining node trusts; a bootstrap
resolver is the first thing that decides what a peer address is. Everything in §4 and §5 assumes
these questions were already answered correctly.
Three of the five criteria below have no automated check, and the reason is worth
stating rather than working around: these gates are conditional, and their off state is silent.
A verifier that was never installed and a mesh in which every peer is legitimate produce the same
observable — no rejections. That is INIT-04’s shape again, one layer further out.
ID Criterion How it is tested Evidence produced What a failure looks like
NAME-01 Every peer admitted to a routing interaction has passed enterprise-CA identity verification. No check. Construction: applyEnforce in cmd/h3-rpc-gw/dht.go
closes the connection to any peer peerverify has not verified.
manual procedure — and the gate is conditional
The verification layer’s enablement as deployed, captured in the same pass as the gate’s
rejection log for that window.
NewPeerVerifier returns (nil, nil) when disabled, so
PeerVerifierActive() is nil and the gate is skipped for every peer.
Nothing errors and nothing is logged. The only observable is an absence of rejections,
which is precisely what a correctly-gated healthy mesh also looks like.
NAME-02 The bootstrap resolver is authenticated by a pinned key, not by the public CA set. No check. Construction: dohclient.makePinVerifier compares the leaf
certificate’s SPKI SHA-256 against a configured set.
manual procedure — and the empty set disables it
The pinned fingerprint set as deployed, recorded beside the endpoint it applies to. The pinned set is empty, so the verify callback returns nil and any certificate the system
roots accept is accepted. The source names this state “only safe for tests”;
nothing enforces that. This is the one DNS dependency the design deliberately keeps, and
whoever answers it chooses the bootstrap peers — the same reasoning as INIT-05, one layer down.
NAME-03 A federation’s published settlement identity is signed by the key it announces, and is
refused unless the peer serving it is itself verified.
No check in the audit set. Construction: the announcement is self-signed with the
key it publishes as its counter-signing key, and cmd/h3-rpc-gw/regimec_discovery.go
refuses one served by an unverified peer.
construction, unit-tested — no continuous check
The discovery result, retained together with the identity of the peer that served it. An announcement whose signature does not verify under its own announced key, or one
accepted from an unverified peer. The second is the load-bearing half. A self-signature
proves only that the publisher holds the key it named — never that the publisher is the
federation it claims to be. Without the peer gate, self-signing proves nothing an attacker
cannot equally produce.
NAME-04 Discovering a counterparty does not register it. No check — a property of the call graph. Discovery returns a result to an operator;
registering the agreement is a separate, separately-authorised call.
design property — no test
The discovery output and the registration call, retained as two records under two
authorisations.
Any path that registers a discovered announcement as a live trust anchor without a human
decision. Finding a legitimate first-time counterparty and registering a fraudulent one
would then be one step rather than two — and only the first of those two is
cryptographically rigorous.
NAME-05 Node churn is measured, and a node whose churn cannot be measured is not counted as stable. cc006 “Node Churn”, a per-block
check.
registered — but returns a pass when its provider is absent
Check verdict, with the per-node reconnect counts it actually read. The metrics provider is not configured and the check returns success rather than
could-not-run. This is EVID-01’s failure moved inside a single check instead of across a
cycle: the value that reports a stable mesh and the value that reports nothing at all are
the same value.
What is not repeated here

INIT-05 (cc001) already covers bootstrap peers
being addressed by IP literal rather than by name, and it is not restated. Together with NAME-02 it
is the whole of what this document claims about the bootstrap edge: one criterion on how the
address is written, one on who is trusted to resolve it. Neither reaches the question of whether
the resolved peer is the right one — that is NAME-01, and NAME-01 has no test.

7 · Criteria — Integration mode and data visibility

What a criterion can reach depends on which integration mode delivered the
transaction
, and on who can read the field it asserts something about. These are two
independent axes, and a criterion that names neither is being asserted for all combinations at once —
and will be wrong for at least one of them.
This is the group most exposed to the misreading §2 warns about, so each row below is
written to be false under conditions a reader can check, rather than true under conditions a reader
has to assume.
ID Criterion How it is tested Evidence produced What a failure looks like
MODE-01 A transaction’s integration mode is determined from positive evidence, never from an absent field. No check. checks.ModeOfParameters classifies on the atom name or a
non-empty process id and returns unknown otherwise. One classifier serves both the
checkers and the baseline interceptor.
construction, unit-tested
The classifier’s verdict per transaction, and the fact that a single implementation
produced both consumers’ answers.
A malformed content-mode transaction — also missing a process id — read as hash-only, which
excuses every mode-aware check from examining it. A positive identification cannot be
produced by omission
; treating absence as hash-only converts a malformation into a
licence to skip. A second classifier appearing anywhere is the same failure in slower motion.
MODE-02 A hash-only transaction is not retained carrying business content. No check. The baseline interceptor drops every parameter outside
checks.ModeAParameterAllowlist before storage and logs what it dropped.
implemented — but the only record is a log line
The interceptor’s log for the window, captured before it rotates. A hash-only submission arrives carrying business parameters. The promise itself holds —
they are dropped — but the fact that a customer’s system transmitted content it believed was
never sent survives only in a log. The mechanism is sound and the evidence is not,
which is a different defect from the mechanism being absent, and needs reporting as such.
MODE-03 A check that cannot apply to a transaction reports not-applicable, not a pass. checks.SkipIfHashOnly returns a not-applicable verdict for hash-only
transactions.
written, and called by nothing — the two
checks whose own doc comments prescribe it are both stubs (§10).
The cycle summary’s not-applicable count — once there is a caller capable of producing one. A mode-aware check runs against a hash-only transaction, finds no customer-side process
state because none was ever sent, and returns success. The verdict is indistinguishable from
a real pass and the coverage count includes it. Today every consumer of this guard is a
comment.
MODE-04 What was submitted is compared against what the validators recorded. cc118 “Transaction Parameter
Tampering” — compares committed metadata and request type against the pre-registered
baseline trace.
implemented
Check verdict; the pre-registered trace the provider returned for that transaction. Metadata or request type differs between baseline and commit. Note the shape of a defect
this check has already carried and had corrected: it compared the legacy, never-populated
amount fields rather than the ones the gateway actually fills, so that comparison was a
silent no-op on every real transaction. A check can be implemented, registered, running,
and still comparing nothing.
MODE-05 A quantitative field is unchanged between submission and persistence, and the comparison
survives that field being encrypted.
cc-bpd-038 “Amounts Constancy
Verification” — decrypts both sides and compares plaintext positionally across every
configured replica.
implemented
The per-replica comparison the check performs, and the quorum-resolved key it used. A persisted amount differs from the consensus-agreed submitted amount. The instructive
failure is the one this design forecloses: comparing ciphertext instead. A fresh nonce per
encryption means an unchanged value never re-encrypts to the same bytes, so a ciphertext
comparison reports tampering on every honest transaction — and would have to be switched off
to be usable, which is how a check becomes decorative.
MODE-06 Independent replicas agree on the commitment they recorded, without any of them holding a
key to the data.
cc-bpd-039 “Commitment
Cross-Replica”, a per-transaction check.
implemented
The replicas’ commitments for the transaction, retained together. Four distinct states, each refused explicitly rather than allowed to read as agreement: a
replica disagrees; a replica cannot be read (a failure, never a skip — a comparison
over one replica always agrees with itself); a field present on some replicas and absent on
others (a disagreement, because suppression presents as absence); or zero commitments
anywhere (could-not-run, not a pass).
MODE-07 Every replica re-derives byte-identical state from the same transaction stream. TestNoWallClockInActions (orgnodes-core/abci) rejects wall-clock
use in atom code at build time; cc054
“Clock Skew” per block.
implemented as a build gate
The gate’s result per release; the check’s verdict per block. An atom reads a wall clock. Replicas then diverge for benign reasons, and
every divergence finding in this document becomes ambiguous — a state mismatch can no
longer be read as a fault. This is the property the whole of §5 rests on, and it is held by a
test rather than by review.
What this group deliberately does not assert

Nothing above claims the customer’s transaction executed, committed, or was aborted. Under
the hash-only mode that is structurally unknowable, and trace.tx_outcome — which does
hold a committed-or-aborted row — answers a different question. §2 states the misreading; these
rows are worded so that none of them can be taken as reaching it.
Nor does any row assert a visibility rung. Only the platform-key rung is wired, and only for one
field; the rungs at which the platform genuinely cannot decrypt are undesigned for every field the
platform validates. MODE-06 is the one criterion here that would survive that change, because it
does not read values at all.

8 · Criteria — Federation boundary and settlement regime

Where a transaction is coordinated, and what agreement it rests on: atomic commitment
within one pyramid, a compensating orchestration within one sovereign, and neither of those across a
border.
The evidence here divides sharply, and the division is the useful part. The
cross-border settlement engine is the best-evidenced mechanism in this document — a predicate
that is a pure function of anchored evidence, a compare-and-swap that model checking found was
missing, a structural refusal to run against a test anchor. The deployment claim sitting above it —
that enterprise data does not cross a pyramid — is the least evidenced, and it is the one the
commercial argument leads with. Both are below, marked.
ID Criterion How it is tested Evidence produced What a failure looks like
FED-01 A cross-border settlement outcome is a function of anchored evidence alone, and evaluates
identically for both parties and any auditor.
cg04 “Regime C Predicate Divergence Detection”, registered in
chubbychecker-governance‘s own check set.
implemented — citation deliberately unmarked: this check
is in a different binary’s registry, which the §3 guard does not read (see the note below).
The intents and commitments the check read, and its verdict. An intent recorded as settled whose anchored evidence does not satisfy the predicate —
catastrophic, because settled is terminal and there is no race window that could explain it.
Or an intent that has satisfied the predicate for more than five minutes without settling —
transient, and may still resolve.
FED-02 Evidence attributed to a counterparty verifies against the key in the registered bilateral
agreement.
No check. regimec.verifyCounterpartyAuthorship rejects counterparty-claimed
evidence unless its signature verifies against the agreement’s counter-signing key; a missing
key, a missing signature and a bad signature are all hard rejections, not silent skips.
construction, unit-tested — no continuous check
The agreement as registered and the evidence as accepted, retained together. Forged evidence accepted. And note what is not reached: rejection today is an error
returned to the caller, not a state transition. There is no disputed status and no escalation
path, so a genuine forgery attempt leaves no durable record that this criterion was ever
exercised — the mechanism works and produces no evidence of having worked.
FED-03 A compensated settlement is never returned to settled. No check. The status write is a compare-and-swap on the from- and to-status.
construction only — no test in the audit set
The intent’s status transitions, retained in order. A late but genuinely valid commitment overwrites an already-compensated intent back to
settled, erasing the record of a real fund reversal. Not hypothetical: the write was
unconditional until a model check of the engine’s own concurrency found it.
FED-04 Production settlement cannot run against a test anchor. No check — a structural property. regimec.NewProductionEngine takes no
anchor argument at all; its anchor comes only from the live-credential constructor, which
errors rather than falling back.
construction — structural, not a convention to remember
The constructor’s signature, per release. A signature change reintroducing an anchor parameter. There is presently no call site at
which a test anchor could be supplied, because there is nothing to supply it through — the
same shape of guarantee as a signature check, rather than a rule someone must remember.
This says nothing about whether the anchor itself is sound. That it never forks,
reorders or equivocates is the external ledger’s property, not this platform’s; it is
permanent residual trust, not an untested item, and a criterion asserting it would be the
most damaging error this document could contain.
FED-05 Both legs of a cross-border settlement are judged against one deadline. No check. The agreement’s timeout is a single value fixed and validated at
registration, and a commitment carries no deadline of its own.
construction only
The registered agreement, and the intent and commitment judged under it. A commitment free to state an independent deadline. A short-deadline intent times out and
compensates, while a later commitment carrying a longer, self-chosen deadline still looks
satisfiable and settles — one side settled and the other compensated, for the same
transaction. The single deadline is what makes the predicate a function of shared evidence
rather than of whose clock was asked.
FED-06 Federations carried by different pyramids share no validator. No check. Deployment-time evidence only: each pyramid’s validator set, compared for
overlap.
manual procedure — no automated test
Each pyramid’s validator set, captured in a single pass so the sets are comparable. A validator appearing in two pyramids’ sets. Read the boundary of this claim carefully.
It reaches hardware separation across pyramids only. Federations grouped
within one pyramid — the shape most full-scale deployments are expected to land on —
share validators by design, and their separation is software: tenant scoping inside one state
machine. No criterion in this document tests that software half, and it is the half most
deployments will actually rely on.
Why FED-01’s citation carries no claim attribute

Every other check cited in this document is marked with the claim it makes and verified against the
live registry on each build. cg04 cannot be: it is registered in a different binary’s
check set, which the guard does not compose. Marking it anyway would be worse than leaving it
unmarked — the attribute would assert a verification that never runs.
So FED-01 is the one criterion here resting on inspection rather than on a build gate, and that is
a gap in the guard, not a property of the check. Extending the guard to read the governance
registry as well is the fix; until it does, a practitioner should treat FED-01’s citation as they
would any uncited claim.

9 · Criteria — Machine origination

Sensor fleets and authored contract processes originate transactions without a human in
the loop. The first question a reviewer asks is whether a compromised device can move value across a
border. There is a real answer, it is enforced fail-closed at the point of origination, and it is
narrower than the surrounding documentation states — which is exactly why it belongs here as a
criterion rather than as a quotation.
ID Criterion How it is tested Evidence produced What a failure looks like
ORIG-01 A device-originated event cannot originate a transaction outside its own pyramid. No check. origin.Kind.allowedRegime permits only the atomic
intra-pyramid regime for a device-kind event, and Originate returns a
restriction error before doing any other work.
construction, unit-tested — no continuous check
The origination record, carrying the kind claimed and the regime reached. A device-originated event accepted into the orchestrated or cross-border regime.
Read the restriction precisely: it attaches to the device kind alone. An authored
contract atom is not restricted this way — see §10 — so “machine-originated” and
“device-originated” are different sets, and only the second is covered by this
criterion.
ORIG-02 An origination event is authenticated before anything acts on it. No check. Originate requires a kind, a regime, an identity and a
non-empty signature, verifies the signature against the per-pyramid trust list, and errors on
any failure — nothing partial proceeds.
construction, fail-closed, unit-tested
The verified identity recorded against the origination. An unsigned or unverifiable event accepted. One state to look for specifically: the package
ships a no-op verifier that accepts any non-empty signature, documented as test-only.
Nothing structurally prevents it being wired to a real trust list, so this criterion is met
only if the deployed verifier is the real one — a deployment fact, not a code fact,
and therefore one that must be captured per deployment rather than per release.
ORIG-03 A device-originated event carries the consensused block time, not a wall clock. No check. Originate rejects a device-kind event whose block time is
unset.
implemented for the device kind only
The block time recorded on the origination, per event. For every other origination kind, an unset block time is silently filled from the
local wall clock — in the one package whose stated purpose is to make all three origination
sources produce the same shape. Contract atoms are not device-kind and may originate into the
orchestrated and cross-border regimes, so this fallback is reachable on exactly the paths
where two parties must agree about time
. It does not error; the value is simply wrong in
a way nothing downstream can distinguish.
ORIG-04 A contract atom originating a domestic orchestrated transaction is subject to a standing
veto before it executes.
No check. Kind.minimumMode raises such an origination to at least
semi-automatic, which the coordination gate turns into a vote a regulator can use to block
it. The floor escalates a weaker request and leaves a stronger one alone.
construction, unit-tested
The coordination mode recorded on the origination, against the mode the caller requested. A contract atom originates a compensating transaction fully automatically, with no veto
point before compensation would be needed. There is no equivalent floor for the
cross-border regime
— the coordination gate does not apply there at all — so this
criterion covers the domestic case only, and the cross-border case is uncovered by design
rather than by oversight.
Why this group is worth having despite four “no check” cells

Every criterion above is enforced by construction and none by a running check, which normally
argues for §10 rather than a criteria table. They are here because construction of this kind
is testable by an outsider — the restriction, the fail-closed ordering, the floor and the
missing floor are all readable in one function each, and a practitioner can be handed those
functions and a release tag.
What that cannot establish is whether the restriction is reached in a live deployment. The
origination claim travels on the wire and must be populated by whatever produced the event
upstream; a caller that never sets it leaves the whole seam inert while every function above
remains correct. That is recorded in §10, not softened here.

10 · Exclusions and known gaps

Matters that belong to the groups above on their merits but are not claimed as
criteria, because nothing currently establishes them. Each was verified against the code rather than
assumed, and each is stated at the strength the code supports rather than the strength the
surrounding documentation claims.

10.1 · Matters with no mechanism

Ref The matter Why it is not a criterion What would be needed
INIT-X1 The initial trust anchor is protected. cc002 is not implemented and
registered nowhere. Since 2026-08-31 it refuses rather than returning success, so
registering it can no longer produce silent passes.
not covered
A provider giving each node’s genesis hash, plus the value recorded at chain creation.
Agreement between nodes is not sufficient: a rewrite applied to every node leaves them
agreeing perfectly and disagreeing with history — a defect of exactly that shape has already
occurred here, a charm rewriting genesis.json mesh-wide.
FED-X1 Enterprise data does not commingle between federations sharing a pyramid. FED-06 reaches hardware separation across pyramids only. Within a pyramid the boundary is
software — tenant scoping in one state machine — and no check tests it.
cc061 “State Bleed” sounds like
the check for this and is not: it is a hygiene watchdog for a transient store whose only
caller was retired, and it is deliberately left unwired, returning a transient failure
on every invocation rather than a false green.
not covered
A check comparing state reachable under one federation’s scope against the rows another
federation owns, in a pyramid actually carrying both. This is the separation most full-scale
deployments will rely on, and it is the one the sovereignty argument does not rest on —
worth resolving before those two facts are read as one.
FED-X2 Data that must agree across shards does agree. cc073 “Cross Shard Drift” is
registered and runs, but compares a single hard-coded key described in its own source as
hypothetical, returns success when fewer than two shards are reported, and
continues past a shard it cannot read — the omission EVID-02 exists to forbid.
registered; not evidence
A real set of cross-shard invariants, and an unreadable shard treated as a finding rather
than skipped. Until then this check’s pass carries no information, and it is counted in
coverage as though it did.
EVID-X1 Application state is bound into consensus on every tier. Three tiers compute no app hash at all: member-classes (org-server-abci),
the tophats tier, and the auditor tier (auditor-abci). All three return an
empty AppHash and leave last_app_hash NULL. They are outside
consensus for two different reasons, and the difference decides what can be done about it.
On member-classes it is a dependency: domain columns are sealed with AES-GCM, whose
random nonce makes the ciphertext differ on every replica, so a digest taken over those
columns would diverge consensus on every row. On the auditor tier it is a deferred
choice
: every attestation it commits is already self-authenticating, signed under a
did:key derived from the signing key, so tampering with a stored row is detected by
re-verifying the signature rather than by a chain digest. That tier also began at height
zero, which is the one moment an app hash can be adopted without height-gating.
three tiers outside consensus
For member-classes and tophats: a digest computed over a canonical projection that
excludes randomised ciphertext — the shape the overseer tier’s function already uses
to strip wall-clock columns before hashing. For the auditor tier the work is smaller,
because nothing has to be excluded: a digest over the committed attestations, adopted at a
chosen height. Until then these three tiers’ application state is agreed by nobody,
and a replica that drifts goes on committing blocks alongside its peers. The auditor tier
is the least exposed of the three — a drifted attestation still fails signature
verification — but least exposed is not the same as covered.
ORIG-X1 Machine origination is restricted end to end, from the device to the settlement gate. The restriction is enforced where the origination claim is evaluated. Whether it is
populated is the upstream caller’s responsibility, and a caller that leaves the
claim unset leaves the seam inert while every function remains correct.
not covered end to end
Evidence that the services which actually emit device and contract events populate the
origination kind on the wire. Absent that, ORIG-01 is a property of a function rather than of
the platform, and the difference is invisible from either side.
ORIG-X2 A contract atom cannot originate a cross-boundary transaction without a human. This is asserted in the pitch material and is not what the code does.
allowedRegime restricts the device kind to the intra-pyramid regime and
leaves contract atoms unrestricted across all three; the only brake on a contract atom is
ORIG-04’s coordination floor, which applies to the domestic regime and not to the
cross-border one. claim not supported
Either the restriction the documentation describes, or documentation matching the
restriction that exists. The two must not be handed to a reviewer together — see the note
below.
EVID-X2 A replica’s own failure cannot become a consensus outcome. Nothing checks this. Each ABCI application decides for itself which errors are
deterministic — the same on every replica, and therefore safe to return as a result
code — and which describe only local conditions and must halt the node instead. That
decision is a hand-written classifier per application, with no test coverage required of it
and nothing comparing one application’s judgement against another’s.
not covered anywhere
A shared classifier, and a check that fails when any application returns a result code
derived from a condition that is local to one replica. This is not theoretical, and it has
now happened twice. The agg mesh halted unrecoverably on 2026-08-22 that way. On 2026-09-04
a routine credential rotation left one auditor node without database privileges for about
twelve seconds; every block executed in that window returned a result code its peers did
not; Block.Header.LastResultsHash diverged, and that node panicked on every
subsequent block until its chain state was rebuilt from its peers. The classifier is fixed
and rolled — privilege and authentication failures now halt the node — but the
fix is one application’s, and the property is asserted by nobody.
EVID-X3 A sequence of attestations shows that auditing continued. Nothing checks this. Empty windows are signed deliberately, so that a gap in the
sequence is visible rather than hidden by a silent skip — but nothing asserts that
consecutive attestations are distinguishable. Where they are not, the record
cannot separate an auditor that examined every window and found nothing from one that
made a single claim and never spoke again.
not covered anywhere
A check that fails when a mesh’s attestations stop advancing, or when consecutive
attestations from one identity are identical. Observed on 2026-09-05: gov1,
commercial-gov and the registry auditors each held exactly four attestations — one
per replica — unchanged across a sampling interval, while the workload tiers
climbed into the hundreds. The obvious reading was that they had stopped attesting. They
had not. Those three checkers are DB-only, follow no chain, and so observed no heights;
every window was 0–0, the signed claim was byte-identical each period, and because
auditor.attestations is keyed by signature every republish collided into the
row already there. The database was correctly refusing to store the same claim twice.
The registry auditor was, at that moment, detecting six referential-integrity gaps and
three completeness violations every thirty seconds. The window is now anchored to the
height of the chain the attestation is published to, and the counts advance — but
the property is asserted by nobody, and the same shape returns for any future auditor
that watches something other than a chain.
NAME-X1 A validator that is partitioned from its peers is detectable. Nothing on this estate reads peer count. Not a check, not a charm status, not a roll gate.
A node with no peers keeps committing its own view, answers RPC, reports its true height and
passes every check registered here — and its unit status stays green.
not covered anywhere
A check comparing each validator’s peer count against the size of its own validator
set, failing when any node sees fewer peers than it should. This is not theoretical: on
2026-09-04 a charm refresh rewrote peer addresses into an unresolvable form, all four nodes
of a mesh dropped to zero peers, and the chain halted for about 25 minutes while every
existing signal — heights, unit status, service state, image tags — read healthy
throughout. Height is not a proxy: a partitioned node keeps committing until consensus
stalls, so by the time heights stop advancing the chain has already stopped.
MODE-X1 A field the platform cannot decrypt is still cross-checked. Only the platform-key rung is wired, and only for one field. The rungs at which the platform
genuinely cannot decrypt are undesigned for every field the platform validates.
designed for one field; undesigned generally
Per-field classification and a customer-held key path. MODE-06 is the one criterion already
written that survives the change, because it compares commitments rather than values — which
is the argument for building outward from it rather than around it.

10.2 · Registered checks that cannot fail

Coverage counts are taken from registries, and a check that returns success
unconditionally is counted exactly like one that tests something. Thirteen of the one hundred and
thirty registered checks have bodies that discard their arguments and return success
, all emptied
in the same 2026-05-23 metadata collapse and each carrying a comment saying so. They are named here
individually so that a coverage figure taken from the registry can be corrected by subtraction, and
so that implementing any one of them breaks the build until this section is updated.
Check What it would test Note
cc004 Sybil attack / routing vulnerability Depended on a per-transaction nonce removed in the collapse. Named in §6’s subject matter; not covered by any criterion there.
cc047 Phantom write Needs an action to report its own real table reference; the field carries a literal placeholder today.
cc048 Lost rollback Same root gap as cc047. Its own comment prescribes the MODE-03 guard for the revived version — one of the two callers that do not exist.
cc049 Out-of-order commit —
cc053 Transaction gap —
cc087 Transaction id reordering —
cc091 Inverted causality via metadata —
cc107 Context-detached execution Its comment argues the check is now redundant against gateway-layer verification — which is a decision to record, not a stub to revive.
cc108 Unconsumed compensation logic The second of MODE-03’s two prescribed-but-absent callers. Compensation is the mechanism FED-03 and ORIG-04 both depend on.
cc113 Immutable field overwrite Also registered as a prevention gate. The gate runs on every member-class transaction and rejects nothing.
cc-bpd-006 Draft-version execution prevention Also a prevention gate.
cc-bpd-007 Illegal transition detection Also a prevention gate.
cc-bpd-009 Step entry/exit policy enforcement Also a prevention gate.

Four of the thirteen are prevention gates

A prevention gate is not a check that reports afterwards — it is a synchronous rejection in the
commit path, registered precisely because the invariant it holds is worth refusing a transaction
over. Four of them (cc113,
cc-bpd-006,
cc-bpd-007,
cc-bpd-009) call functions that return success
unconditionally.
The consequence is worse than a missing check, and worth stating plainly rather than folding into
the count above. A gate that rejects nothing is indistinguishable, from every angle available to
an operator, from a gate whose invariant has never been violated.
It appears in the gate list,
it executes on every transaction, it adds latency, and it produces exactly the observable a
correctly-functioning gate produces on well-formed traffic. Nothing about running the system
reveals the difference; only reading the four functions does.
This is the same class as the two never-registered checks recorded in 10.3 below, arriving from the
opposite direction: there, a check that could not run; here, a gate that runs and decides nothing.
Both are counted as coverage.

10.3 · Defects this document found, all now closed

A check that had never run. cc-bpd-039, the
cross-replica commitment comparison and the check MODE-06 now rests on, was referenced
only inside its own source file and appeared in no registry. It had never executed once.
registered — together with the provider behind it, which was
declared but constructed nowhere, so registering the check alone would have produced
“provider not configured” on every transaction and looked like coverage.
A coverage count that disagreed with itself. The integrity registry’s comment said it
adds twelve checks, listed thirteen IDs beneath that sentence, and registered fourteen —
cc111 registered but undocumented.
corrected, and guarded: the comment is now checked against the
function that follows it, because correcting the number once would leave the next edit free to
desynchronise it again.
A second check that had never run. cc131
— the only check verifying what was submitted rather than the validators’ own account —
was likewise registered nowhere. Its two providers existed only in org-server-abci,
which passes its registry to the ABCI application rather than to a check registry, so nothing
could reach them. registered, with both providers built auditor-side.
Two checks written, built, tested and never called is a class, not an accident.
Earned passes on two checkers out of three.
chubbychecker-joint still called RunContinuousChecks, which returns
success unless a catastrophic fault also exceeds the threshold — so on the eight auditor units
running it, a check that could not execute was invisible and the cycle read as a pass. Governance
and registry had been switched to the summary form when it was written; this one had not.
switched.
None was discoverable by reading the code normally. All four surfaced the moment a criterion had
to name the mechanism supporting it — which is the argument for the document, and the reason the
conformance guard described in §3 is not optional. It has already earned its place: registering
cc131 broke the build, because this section still said it was uncovered.

10.4 · Open, found while writing §6 – §9

The documentation and the code disagree about who may cross a boundary

ORIG-X2 above is the sharpest of the new findings and the one with a reader on the other end of
it. The pitch material states that a contract atom, like a device, may originate only into the
intra-pyramid regime, and that reaching a domestic or cross-border regime requires a human. The
code says otherwise, deliberately and with its reasoning written down: the device restriction is
permanent, and the contract-atom restriction was lifted because an authored process carries its own
declared compensation. Inside the same source file, the constant’s own comment still says
restricted to Regime A, contradicting the package comment eighty lines above it.
Both positions are defensible. What is not defensible is handing a reviewer the document and the
system together, because the security answer to “can a machine move money across a
border”
differs between them. A criteria document is the wrong place to resolve which
is right
— that is an architectural decision — so it is recorded here as a divergence with both
sides named, and ORIG-01 is worded to claim only what the code enforces.

Mechanisms whose evidence expires

MODE-02 and NAME-01 share a shape that none of §4 or §5’s entries had. The mechanism is
correct — content is dropped, unverified peers are disconnected — and the only record that it
acted is a log line. A practitioner asked whether a hash-only customer ever transmitted content, or
whether an unverified peer ever attempted to join, has nothing to read once the window has rotated.
This is distinct from an absent mechanism and should not be reported as one. It is also distinct
from INIT-04, where the mechanism may be absent and the absence is silent. Here the mechanism is
present, working, and unable to produce evidence of having worked — which is the one failure
mode a criteria document is most likely to mark as satisfied.

Two gates that are off unless switched on, and silent when off

NAME-01 and NAME-02 are conditional in the same way and for the same reason: an empty pin set
disables certificate pinning, and an uninstalled verifier disables peer-identity gating. Neither
errors. Neither logs. The pinning path documents its permissive state as
“only safe for tests” and nothing enforces that sentence.
This is INIT-04’s pattern — unset means off — appearing twice more, in the layer that decides
who a node talks to at all. It is recorded here rather than only in the criteria because the
pattern, not the two instances, is the finding: three independent security-relevant mechanisms
on this estate default to off and say nothing about it
, and there is no sweep that would find
the fourth.

11 · Evidence, retention and the practitioner’s tooling

Sample content — rewrite

Findings are attested at intervals by each checker, signed with a key held by that checker, and
identified by a did:key that is derived from the signing key itself. A practitioner can
therefore verify an attestation using only the attestation: no registry lookup, no key
distribution, and no reliance on any service the operator runs.
Those attestations are now committed to the auditor tier’s own BFT meshes rather than
written to a log file. That distinction is the whole point: an attestation living only in a log the
audited party controls demonstrates integrity but not independence, because the party being audited
can remove it. Every one of the seven auditor meshes commits them, and each mesh carries four
distinct did:key identities — one per replica, each key generated on its own unit and never
transmitted — so the four auditors are separately attributable rather than averaged into one voice.
An empty window is signed and committed like any other, which is what stops silence being mistaken
for agreement.
committing on all seven meshes
Retention: attestations are retained for [period — to be set], which
must be at least the period the practitioner is asked to report on. The store now exists
(auditor.attestations, keyed by signature), so this is a policy decision rather than a
missing mechanism — but it is unanswered, and an unbounded store is not a retention policy.

State this plainly, and do not soften it

The verification tool is written by the operator. Under an assurance engagement the practitioner
must satisfy themselves it is fit — by reviewing it, having an expert review it, or using their
own. Reproducible builds and published source narrow this; they do not close it. A criteria
document that omits this limitation misrepresents the strength of everything above it.

12 · Change control

Sample content — rewrite

Criteria are versioned as a set. A report cites the version it was performed against. IDs are
never reused and never renumbered; a withdrawn criterion is marked withdrawn and kept, so that
an older report remains readable against the document it referenced.
Adding a criterion, changing what a criterion requires, or moving one to §10 are all changes
requiring the approval of the executive director of cyber-security
approver settled 2026-09-03. Correcting a typographical error
is not.
The approver is settled even though the versioning policy around it is still sample content.
An unnamed approver is the failure this section exists to prevent: it makes every change to the
criteria deniable after the fact, which is worse than a policy that has not been written yet.

Appendix A · Blank section to copy

One of these per criteria group. Suggested groups, following the shape of the existing
check set rather than inventing a taxonomy. Six are worked above — Initialisation (§4),
Evidence integrity (§5), Peer discovery and name resolution (§6),
Integration mode and data visibility (§7), Federation boundary and settlement regime
(§8) and Machine origination (§9). Groups still to write:
Admission & ordering, Replica agreement, Record completeness,
Anchoring & immutability, Authorisation & separation of duties,
Recovery.
ID Criterion How it is tested Evidence produced What a failure looks like
XXX-01 One sentence. What must be true, with no argument for why. Check ID, or the named manual procedure. State plainly if there is none. The artefact retained, named specifically enough to ask for. The observable state when this is not met. If you cannot write this cell, the criterion is not yet testable.
Follow each table with an exclusions table in the shape of §10 — even where it is empty,
in which case say so explicitly rather than omitting it.

Appendix B · Drafting checklist

Check Why
Can this criterion fail? Write the failure cell first. If nothing goes in it, the criterion is unfalsifiable and will pass forever.
Does the cited check exist and run? Existing, registered and non-vacuous are three different things. cc002, cc001 and cc-bpd-039 each fail a different one.
Is it stated without argument? Justification belongs in the surrounding prose. In the cell it reads as advocacy and undermines neutrality.
Is the evidence retained? A verdict that scrolls out of a log window cannot be reported on later. Decide from state that does not expire.
Is there an exclusions table? Its absence is a claim of completeness, made silently and almost always wrongly.
Would a reader over-read this? The test is whether someone could take a criterion as covering data truthfulness. If so, rewrite it.
tx-rails — Criteria for the Integrity of Transaction Processing ·
§4 to §10 contain real entries verified against the code; §10 records what is not covered, including
thirteen registered checks that cannot fail and one claim the code does not support.
§1, §2, §11 and §12 are sample content to be rewritten. Check IDs carrying a claim attribute are
literals resolvable in the source tree and are verified on every build; mechanisms cited without one
are outside the guard’s reach and say so in place.

Tx-Rails — Built by IT/OT Chain & Cloud Australia (ITOTCCA). Sydney · London.