Skip to content

tools: independent CAP-1 implementation pair and conformance probes - #160

Merged
b7n0de merged 1 commit into
mainfrom
feat/cap1-independent-implementation-20260831
Aug 31, 2026
Merged

tools: independent CAP-1 implementation pair and conformance probes#160
b7n0de merged 1 commit into
mainfrom
feat/cap1-independent-implementation-20260831

Conversation

@b7n0de

@b7n0de b7n0de commented Aug 31, 2026

Copy link
Copy Markdown
Owner

Two implementations of draft-hillier-coverage-attestation-00 (CAP-1), written from the draft
prose rather than from each other, plus the probes used to compare them.

Section 7.3 of the draft says an implementation by an unaffiliated party is the most useful
contribution a reader could make to the work. This is that implementation, published so the
finding it produced can be checked rather than taken on trust.

What is here

path what it is
py/cap1_verify.py rules R0–R8 implemented from the prose
rs/ a second implementation in Rust, own hand-written JSON reader, no dependencies
sonden.py builds the probes from the author's tree at run time
lauf.py, run.sh one entry point; no network, no clock, no installation

The two implementations share no code — no common canonicalisation, no common hash path, no
common JSON parser. Where they agree, they agree independently.

The Rust reader distinguishes integer syntax from float syntax deliberately, which is what
makes R5's "non-negative integers" measurable rather than a matter of coercion.

The author's vectors are not redistributed

sonden.py transforms his tree at run time; the generated probes are gitignored. Point run.sh
at a checkout of the vectors and it builds them locally:

./run.sh /path/to/certisyn-drafts/cap-1

The positive controls K1 and K2 are his unchanged vectors and must be accepted by every
reading; K3 is a single genuine rule break and must be refused by every reading. Without
those three, a detection rate measures nothing.

What it found

Reproduced from a fresh copy of this branch against commit 0980d32 of the draft repository:

file                        last-wins   first-wins  strict      author
K1 (PV-03 unchanged)        CONFORMS    CONFORMS    CONFORMS    CONFORMS
K2 (PV-01 unchanged)        CONFORMS    CONFORMS    CONFORMS    CONFORMS
K3 (single R1 break)        REFUSED     REFUSED     REFUSED     REFUSED
S09 (duplicate eligible)    REFUSED     CONFORMS    JSON error  REFUSED      <-- disagreement
S10 (duplicate complete)    CONFORMS    REFUSED     JSON error  CONFORMS     <-- disagreement

CAP-1 does not say how a verifier must treat duplicate JSON member names. RFC 8259 §4 says names
SHOULD be unique and that behaviour on violation is unpredictable. Three readings that each
conform to the draft therefore reach different verdicts on the same document.

The sharpest consequence is determinism: two verifiers can disagree about a document while both
follow the specification.

Honest limits

  • The package is written in German, comments and README included.
  • The rules are implemented from the prose. A misreading of the prose is possible; it would show
    up as a disagreement with the author's own runner rather than as a silent pass.
  • The strict reading refuses duplicate names at the parser level. That is a choice this package
    makes, not one the draft requires.
  • Nothing here has been sent to the author or to any mailing list.

Status

Opened as a draft. It exists to let the required guard check run against the branch, which
only happens on a pull request. Merging is a separate decision and is not requested here.

Two implementations of draft-hillier-coverage-attestation-00 (CAP-1), written from the
draft prose rather than from each other, plus the probes used to compare them.

WHY THIS IS HERE. Section 7.3 of the draft says an implementation by an unaffiliated party
is the most useful contribution a reader could make. This is that implementation, made
available so the finding it produced can be checked rather than taken on trust.

WHAT IT CONTAINS
  py/cap1_verify.py   rules R0-R8 implemented from the prose
  rs/                 a second implementation in Rust with its own hand-written JSON reader
                      and no dependencies; it distinguishes integer syntax from float syntax,
                      which is what makes R5's "non-negative integers" measurable
  sonden.py           builds the probes FROM the author's tree at run time
  lauf.py, run.sh     one entry point; no network, no clock, no installation

THE TWO IMPLEMENTATIONS SHARE NO CODE. No common canonicalisation, no common hash path, no
common JSON parser. Where they agree, they agree independently; where they disagree, that is
a finding about the specification and not about a shared bug.

THE AUTHOR'S VECTORS ARE NOT REDISTRIBUTED. sonden.py transforms his tree at run time and the
generated probes are gitignored. Point run.sh at a checkout of the vectors and it builds them
locally. The positive controls K1 and K2 are his unchanged vectors and must be accepted by
every reading; K3 is a single genuine rule break and must be refused by every reading. Without
those three, a detection rate measures nothing.

WHAT IT FOUND, reproducible from a fresh copy:
  file                        last-wins   first-wins  strict     author
  K1 (PV-03 unchanged)        CONFORMS    CONFORMS    CONFORMS   CONFORMS
  K2 (PV-01 unchanged)        CONFORMS    CONFORMS    CONFORMS   CONFORMS
  K3 (single R1 break)        REFUSED     REFUSED     REFUSED    REFUSED
  S09 (duplicate eligible)    REFUSED     CONFORMS    JSON error REFUSED     <-- disagreement
  S10 (duplicate complete)    CONFORMS    REFUSED     JSON error CONFORMS    <-- disagreement

CAP-1 does not say how a verifier must treat duplicate JSON member names. RFC 8259 section 4
says names SHOULD be unique and that behaviour on violation is unpredictable. Three readings
that each conform to the draft therefore reach different verdicts on the same document. The
sharpest consequence is determinism: two verifiers can disagree about a document while both
following the specification.

HONEST LIMITS. The package is written in German, comments and README included. The rules are
implemented from the prose, so a misreading of the prose is possible and would show up as a
disagreement with the author's own runner rather than as a silent pass. The strict reading
refuses duplicate names at the parser level, which is a choice this package makes and not one
the draft requires.
@b7n0de
b7n0de marked this pull request as ready for review August 31, 2026 07:21
@b7n0de
b7n0de merged commit 96dacc4 into main Aug 31, 2026
21 of 22 checks passed
@b7n0de
b7n0de deleted the feat/cap1-independent-implementation-20260831 branch August 31, 2026 07:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant