In detail
BB2G Elections System — Full Audit DOC-AUDIT
Governs: 1.1 · CONFIRMED
| version | note |
|---|
1.0 14,877 B 2026-08-27 | Findings C1–C5, H1–H13, M1–M7 against 23 repositories, 1,700 files. |
1.1 17,582 B 2026-09-09 | Adds the scope-corrections addendum after a second pass across all 415 repositories. |
Supersession: EXPLICIT — 1.1 contains 1.0 unchanged plus an addendum that corrects two of its own statements. Verified by diff: 1.1 is 1.0 with 14 lines appended, no deletions.
What changed:
- M3 said "ProofCore does not exist anywhere in the corpus." kristenslab/proofcore does exist. The substance of M3 survives (documentation only, no implementation); the name was wrong.
- The post-quantum work was never absent, only absent from elections. halo/lib/pqc.ts is a genuine hybrid KEM (QSF_ml_kem768_p256 over ML-KEM-768 + ECDH P-256, from @noble/post-quantum).
- sentinel-id already solves problems the audit raised: keyed one-way tokens, a reverse-map vault the minting service cannot reverse, 3-of-5 Shamir custody, 93 passing tests.
Action: Publish 1.1. Retain 1.0 in the archive only — it carries two statements its own successor withdraws.
Evidence: diff of the two files; addendum dated 9 September 2026
BB2G-Master-Specification-v3 DOC-SPEC
Governs: 3.1 · CONFIRMED
| version | note |
|---|
3.0 41,419 B 2026-08-27 | Nine sections. Resolves the 12 contradictions found across the scattered spec corpus. |
3.1 56,077 B 2026-09-09 | Adds §10 vote centers (VC-1…VC-10) and §11 post-quantum (PQ-1…PQ-9). §10 replaces the section 3.0 numbered 10. |
Supersession: EXPLICIT — 3.1 states "Change in 3.1" in its own header block.
What changed:
- TWO section numbers changed meaning, not one. §10 "One build" → "Vote centers"; §11 "Before anything binding" → "Post-quantum cryptography". One build moved to §12, Before anything binding to §13.
- §11 exists because the post-quantum work was real, was well done, and was not in the specification — it lived in quantum-safe, quantum-lab and halo.
Live defect — V-1 — v3.1 carries one stale internal cross-reference from v3.0.
Measured 2026-09-10, docs/source/spec-v3.1.md:69
| what | value | reading |
|---|
| §2 table, row 1 | 10 | cites "the bb2g-elections monorepo (§10)" — correct in v3.0, wrong in v3.1 |
| correct target | 12 | §12 is One build, where the monorepo is specified |
| §10 in v3.1 | — | is Vote centers — the reader is sent to polling places |
| other §10/§11 citations checked | 4 | L6, L513, L525 and the changelog all correctly reference the NEW meanings |
A renumbering silently invalidated a cross-reference. Nothing in the document is wrong on its own terms — the row is right, the section is right, only the pointer between them rotted. This is the exact failure a version register exists to catch, and it was found by checking every §N citation against the section titles in both versions rather than by reading the prose.
Action: Publish 3.1 with §10 corrected to §12 at line 69. A cross-reference to a renumbered section is a defect — the register gate checks all five citations.
Evidence: header "Change in 3.1"; section-heading diff of both versions; all §N citations enumerated
Election-Integrity-on-StrongRoom-SPEC.md SPEC-EI-SR
Governs: merged copy D (9,633 bytes) — created here; no pre-existing copy governs · CONFIRMED
| version | note |
|---|
A 9,405 B | Byte-identical pair. Singular "StrongRoom". Uses "anchored" and "Anchoring:" throughout. election-integrity/site/downloads + safe-elections-isolation/kit/docs |
B 9,447 B | Byte-identical pair, and the copy currently SERVED. Pluralised, but the correction is HALF-APPLIED. strongroom-elections/site/downloads + dist/downloads |
C 9,631 B | Unique. The complete correction: "witness-published" throughout, plus a two-line definition of "anchored to". safe-elections/site/downloads |
Supersession: DOCUMENTED HERE, NOT STATED IN THE ARTIFACTS. No copy declares itself a successor to any other. NO EXISTING COPY GOVERNS — see V-2. A merged copy D is created because C, the only copy with the complete anchor→witness correction, also carries a normative violation that B does not.
Live defect — The served copy (B) is half-corrected, and the defect is in production now.
Measured 2026-09-10, on kristenslab/strongroom-elections@HEAD site/downloads/Election-Integrity-on-StrongRoom-SPEC.md
| what | value | reading |
|---|
| anchored | 2 | withdrawn vocabulary, still in the tally-artifacts line |
| Anchor the tally | 1 | build step 5 never converted |
| Witness publishing | 1 | only the data-seam heading was converted |
| Anchored to | 0 | the two-line semantic clarification is absent |
| StrongRooms's | 1 | possessive typo, shipping |
Finding — V-2 — the "corrected" copy violates the specification that governs it. Newer is not better, and the direction of the regression is the dangerous one.
Measured 2026-09-10, line-by-line diff of all three copies against v3.1 LOG-7
| what | value | reading |
|---|
| C line 151 | 1 | "**Tamper-proof**, with a full report" |
| B line 149 | 1 | "**Tamper-evident**, with a full report" — B is the honest one HERE |
| v3.1 LOG-7 | — | "The word tamper-proof MUST NOT appear on any BB2G surface" |
| v3.1 §2 row 6 | — | "Tamper-evident, never immutable. The word tamper-proof is withdrawn from every BB2G surface." |
C is better than B on four of five differing passages: it completes the anchor→witness conversion, adds the two-line definition of "anchored to", and fixes the StrongRooms's possessive typo. On the fifth it strengthens a deliberately weak claim into a forbidden one. Publishing C — the obvious reading of "use the corrected version" — would have put a word onto a live BB2G surface that the governing specification forbids by name, on the exact subject (the audit log) that finding C1 proves the system does not achieve. The regression is small, one hyphenated word, and it points directly at the system's weakest claim.
Merged copy D — 9,633 bytes
Takes: C's 13 corrected lines — witness-published tally artifacts, the "Anchored to" definition, "Witness-publish the tally log" as build step 5, and the possessive fix.
Keeps: B's line 149, "Tamper-evident, with a full report".
0 occurrences of "tamper-proof"; 5 of "tamper-evident".
Action: Build the MERGED copy D over B in strongroom-elections — not C. Then one copy, one location, and every other repository references it rather than carrying its own.
Evidence: audit 01-spec-corpus.md §7 (SHA-256 of all three variants — the stated hash for C, 72bd79f048d161246b21b0e54239cd97745cd40d5da026073b3c291ade1c250e, was re-verified byte-for-byte on 2026-09-10 and matches); grep counts re-measured 2026-09-10
election-integrity ↔ safe-elections FORK-EI-SE
Governs: NEITHER — unresolved · CONFIRMED
| version | note |
|---|
| election-integrity | Holds coercion-resistant re-vote supersession (engine/election.mjs:238-250 + test/revote.test.mjs). Its own README marks it as the TARGET of the fork, not the deployment. Live: 401. |
| safe-elections | The deployed copy. Live: 200. Does NOT contain the re-vote supersession. |
Supersession: NONE. 22 of 38 shared paths are byte-identical; the other 16 diverged in BOTH directions. Neither is a successor to the other.
Why it matters: The best coercion defence in the corpus is in the copy that is not live. A merge in the obvious direction (deployed wins) would delete it.
Action: Resolve by decision, not by merge tool. Until then the register records both as governing different things, and no automated sync may run between them.
Evidence: audit M1 — 22 of 38 shared paths byte-identical, the rest diverged in both directions; re-vote supersession at election-integrity engine/election.mjs:238-250 plus test/revote.test.mjs; hunks in audit/work/election-integrity-copy-diff.txt
Merkle tree implementation CRYPTO-MERKLE
Governs: custody-layer/src/lib/merkle.mjs · CONFIRMED
| version | note |
|---|
| MBLTS-MERKLE-V1 | Duplicates the last node at odd widths. |
| RFC 6962 | Promotes the last node at odd widths. |
| 6 implementations total | Two mutually incompatible shapes, same domain separation. |
Supersession: NONE STATED. The two shapes produce different roots at every non-power-of-two size, so ballottrail and safe-elections cannot verify each other's roots. Only custody-layer/src/lib/merkle.mjs:6-28 handles both correctly — and it sits in a static explainer site.
Action: ADR-001 must fix one shape. Until it does, "the Merkle root" is not a well-defined term in this system and the register refuses to treat it as one.
Evidence: audit C2 — six implementations, two shapes; the only dual-shape-correct one is custody-layer/src/lib/merkle.mjs:6-28; detail in audit 02-crypto-tokens.md
strongroom-engine REPO-SR-ENGINE
Governs: n/a · RETIRED-PENDING-VERIFICATION
| version | note |
|---|
retired 2026-08-11 | Its own description says RETIRED — a duplicate of the strongroom engine. |
Supersession: SELF-REPORTED as retired. The retirement is NOT safe to complete.
Why it matters: It holds RecordingAnchor (auditlog.mjs:175-217) — the only external-anchor implementation that ever existed in the corpus. No surviving repository publishes a head to a witness. Everywhere else in the live corpus, "anchored" means "a root was computed locally."
Action: DO NOT ARCHIVE until RecordingAnchor is recovered into the surviving tree. This is precisely why the vocabulary is RETIRED-PENDING-VERIFICATION and not RETIRED.
Evidence: audit H10 — RecordingAnchor located at strongroom-engine auditlog.mjs:175-217; no surviving repository in the 23 publishes a head to a witness
Post-quantum primitives CRYPTO-PQ
Governs: halo/lib/pqc.ts · CONFIRMED
| version | note |
|---|
| hybrid KEM | QSF_ml_kem768_p256 — ML-KEM-768 + ECDH P-256, via @noble/post-quantum, not hand-rolled. The strongest single piece of cryptography in the portfolio. |
Supersession: n/a — this was never superseded, only invisible. It was filed under a different subject, so v3.0 specified a post-quantum posture from scratch while a working implementation sat in a sibling repository.
Action: PQ-5: one shared packages/pqc derived from halo/lib/pqc.ts. No elections component currently uses any post-quantum primitive — that remains true and must be stated, not glossed.
Evidence: audit 1.1 addendum, correction 2 — halo/lib/pqc.ts, QSF_ml_kem768_p256 over ML-KEM-768 and ECDH P-256, sourced from @noble/post-quantum rather than hand-rolled
sentinel-id protected-identity architecture CUSTODY-SENTINEL-ID
Governs: sentinel-id · CONFIRMED
| version | note |
|---|
| current | 93 passing tests. Keyed one-way tokens with per-context key derivation; reverse-map vault sealed to a public key so the minting service holds no reversal secret; 3-of-5 Shamir; break-glass requiring two distinct role classes; hash-chained audit on every operation; k-anonymity with OpenDP accounting. |
Supersession: n/a — adjacent system, wrongly outside the audited 23.
Action: Derive packages/keyvault FROM it rather than writing it fresh. Its docs/CRYPTO_REVIEW.md — which states plainly that a brief written by the code's authors is not the audit — is the template for GATE-1.
Evidence: audit 1.1 addendum, addition — 93 passing tests; docs/CRYPTO_REVIEW.md states that a brief written by the code's authors is not the audit
strongroom-elections.bornbetween2generals.com SITE-SR-ELECTIONS
Governs: dpl_3d5PNLPYAVPRa9ni3BTWEiNhK3AZ · CONFIRMED
| version | note |
|---|
production 2026-09-05 | Status Ready. Aliases list the custom domain. |
Supersession: n/a
Live defect — DOWN. 404 on every path, while the deployment itself is healthy.
Measured 2026-09-10
| what | value | reading |
|---|
| deployment URL | 302 | the passphrase gate, working correctly |
| strongroom-elections.vercel.app | 404 | |
| custom domain, every path | 404 | / /home /index.html /deck /pilot |
| DNS | 200 | correct CNAME to cname.vercel-dns.com — resolution is not the problem |
DNS resolves to Vercel and Vercel declines to route the hostname. That is the signature of the domain still being held by a different project. There is no "move" for a Vercel domain — it must be deleted from the project that holds it before it can be added to another, and adding it while it is held elsewhere fails quietly like this.
Action: Confirm which project holds the hostname, remove it there, re-add here. Outward-facing — not done without a decision.
Evidence: vercel inspect; dig; curl of every path — recorded 2026-09-10