A log can verify and still be missing records.
An evidence export covering a two-hour outage, during which the logging path discarded every record, is byte-for-byte indistinguishable from one covering a quiet afternoon. Both verify. Both look complete. One is worthless, and nothing in it says so.
VLC-1 is an open specification and a conformance checker for the missing property: whether a reader holding the delivered log can establish that it is all of it. It runs on any audit log, offline, with no install step.
The arithmetic
The central check is a ledger identity. Every record the producer made is either in the file or declared lost, and the two have to add up to what the producer says it made.
delivered + declared lost = produced
A quiet afternoon
60 + 0 = 60
Balances.
An outage, declared
40 + 20 = 60
Balances, and says why.
An outage, hidden
40 + 0 ≠ 60
Twenty records unaccounted for.
Without the identity, the first and third logs are the same file. With it, the third cannot pass for the first.
That is one of six levels, L0–L5. Each adds a property the one below cannot establish, and each is defined by the attack it refuses.
The levels
- RecordedNothing is established. The baseline.
- Tamper-evidentRefuses editing, reordering and truncation of what was delivered.
- Loss-accountedRefuses the silent drop. The ledger above.
- Coverage-declaredRefuses the unhooked source: the log states what it was watching.
- Policy-boundRefuses the after-the-fact rule swap: verdicts are bound to the rules that produced them.
- Independently witnessedRefuses the forged self-report: the record was not written by the thing it describes.
A machine-checked proof establishes that the levels are strictly ordered and each one necessary. The checker is bound to that proof by an exhaustive differential test, and a self-test fails in both directions.
Two numbers, not one
Some requirements the checker recomputes from the file. Others it can only relay from what the producer says alongside it. Every report gives both, separately: a structural level from the log alone, and an attested level that adds the producer’s claims. Independence is a fact about who holds the pen, not a property of the bytes, so the highest level is attested by construction.
The structural number is meant to be one an adapter cannot inflate. A review on 21 September found a requirement classed as structural that could still be moved by the adapter alone. The structural level itself held, but only because the highest level is capped at attested. It is fixed, and a test now rewrites the adapter on every example and requires every structural result to come out the same.
Corrected in public
Everything this project scored before 13 September was produced by its author, which by its own rules establishes nothing. The only repair is other people reading it. These are the defects they found, newest first. Fixes to two of them have since been checked against the code by the person who reported them.
A second contribution, and the witness held to its own standard
Reported on 21 and 22 September 2026 as EXT-015 to EXT-017, by pipavlo82 and babyblueviper1. Fixed.
The reconciler accepted a witness whose chain held but whose own level was too low to corroborate anything, and described some tools as excluded when they were not. And a rewritten log could only be caught against a value the checker was never given; babyblueviper1’s second pull request added the means to supply one. The reference journals were then re-recorded by the corrected sensor on a machine the author does not control.
Three more, found by testing what nothing tested
Found by the maintainer on 21 September 2026 as EXT-012 to EXT-014, following the same report. Fixed.
The verification workflow built for outsiders could not fail, and showed a green tick over a crashed self-test. One chain format did not link records to each other, so a deleted record verified. And one way of counting records could not see loss at the start or end of a sequence. Corrigendum 4.
The first fix written by someone else
Reported and fixed by babyblueviper1 (invinoveritas) on 21 September 2026 as EXT-009 to EXT-011. Merged.
A reader outside the project filed a defect report with reproductions and a tested patch, then sent the fix as a pull request. Sequence-numbered logs could hide silent loss, a duplicated field name could change what a record said with every hash still valid, and one malformed line crashed the checker. It is the first change to VLC-1 its author did not write. Corrigendum 4.
Four more, from the same review
Reported by pipavlo82 on 21 September 2026 as EXT-005 to EXT-008. Fixed.
Reconciliation reported agreement from empty or unverified inputs, and matched executables by name so a different binary could corroborate a claim. Seven obligations were checked for presence rather than type, and each could reach the top structural level while violated. An evidence citation could be malformed and still count. And the lowest level was described as resisting a complete rewrite, which on a log alone it cannot. Corrigendum 3. Every fix is held in place by a test that fails against the code it replaced.
A structural requirement read the adapter
Reported by pipavlo82 on 21 September 2026 as EXT-004. Fixed.
The witnessing requirement scored the witness on every requirement, attested ones included, so pointing one adapter field at any non-empty value flipped a structural result with the log unchanged. The report described the structural level moving; reproduced, it held, and the number that moved was attested. The leak underneath was real.
A deleted event could be masked by a framing record
Reported by pipavlo82 on 21 September 2026 as EXT-003. Fixed.
The identity counted coverage and loss declarations as delivered events. A producer could delete an event, add one framing record, and the totals still balanced. Corrigendum 2.
Loss accounting assumed the producer survived its own outage
Reported by Shahab K. on 13 September 2026 as EXT-002. Fixed.
A log truncated and renumbered closed the identity. The headline example held for transport loss only. The repair is a witnessed-interval qualifier, L3i, scored separately. Corrigendum 1.
A false coverage declaration raised the structural level
Reported by Shahab K. on 13 September 2026 as EXT-001. Fixed.
The checker tested that a declaration was present, not that it was true. Corrigendum 1.
What it does not claim
- It is not a certification, an audit, or a security review.
- Eight log formats have been scored: six from public documentation, one (NVIDIA OpenShell) from a single live capture, and one by its own operator. That is not a survey of the market.
- The reference implementation’s journals were re-recorded after EXT-003 on a GitHub-hosted machine, not its author’s. The originals fail the corrected check and are kept unedited, because the count sits inside a hash chain and correcting it would break the binding.
- On a log alone, the lowest level establishes that the chain is consistent. Detecting a complete rewrite needs a root or head held independently of the log.
- Beyond its author’s own captures, it has been run against one live log from a system its author did not write: a single NVIDIA OpenShell sandbox run on a GitHub-hosted runner, 2026-09-29. It has not yet been run against a production deployment.
Run it
Python 3, standard library only. Nothing leaves your machine.
git clone https://github.com/MattyIceMatrix/vlc-1
cd vlc-1
python3 conformance.py --log your-log.jsonl \
--adapter adapters/plain-jsonl.json
If it scores your log lower than you expected, that is the result most worth reporting.
- Source, specification and examples
- Citable release, DOI 10.5281/zenodo.22728393 — always the newest version
- Version 1.4.2-draft, DOI 10.5281/zenodo.23028240 — to pin exactly what you read
- Every external finding, with its reporter