Skip to content

Name the torn tail, and reach full agreement between both verifiers - #38

Merged
repsecure merged 1 commit into
mainfrom
agent/2.7-torn-tail
Aug 5, 2026
Merged

Name the torn tail, and reach full agreement between both verifiers#38
repsecure merged 1 commit into
mainfrom
agent/2.7-torn-tail

Conversation

@repsecure

Copy link
Copy Markdown
Owner

Names a torn final line as what it is, and closes the last case where the two verifiers disagreed.

Before: line 7: not valid JSON, chained FAIL.
After: line 7: torn-tail, the final line has no terminator and does not parse, which is what a hard kill mid-append leaves; the records before it are complete, chained PASS.

Both verifiers already rejected this case, so this is not a security hole. It is a diagnosis defect, and those are expensive: an operator who reads "broken chain" on a torn tail concludes the audit log was tampered with, when a process died mid-write. Recovery already handled the case correctly; only the report was wrong.

The boundary is exact. Torn-tail fires only when the line is last, the file has no trailing newline, and the line fails to parse. A truncated line anywhere else stays corruption. The falsifier widening that branch fails both boundary tests.

With this, conformance reads 26 cases, 26 agreed, 0 declared divergences, 0 failures. The "where the two verifiers disagree" section is retired, and the limits row now states only what is true: agreement is bounded by the corpus and is not a proof of general equivalence, and the harness fails if they ever stop agreeing.

Worth recording one near miss. The limits row did not produce a merge conflict, so git silently kept this branch's "three cases" over main's "four". A grep for stale counts caught it. Two correct branches, no conflict, wrong number in a security doc.

A process killed mid-append leaves exactly one partial line, always the
last and always without its terminator. The chain walk reported that as
an invalid line and failed the chained layer, which tells an operator
their audit log was tampered with when in fact a process died mid-write.
A security tool that raises tampering on every hard kill costs real
investigation time and gets its alerts ignored.

verifyChainFile now reads the terminator off the raw bytes, which a
filtered split destroys, and reports an unparseable unterminated final
line as a torn tail on a separate notes channel. Notes are printed on
the chained layer without deciding its verdict, mirroring the fatal flag
the Go verifier carries. An unparseable line anywhere else, or one that
carries its terminator, was not produced by an interrupted append and
stays fatal.

b11 was the last declared divergence, so the harness now reports 26
cases, 26 agreed, 0 declared divergences, 0 failures. DIVERGENCES keeps
its const and comment with the object emptied: empty is the assertion
that the two implementations disagree about nothing in this corpus, and
the harness enforces it in both directions. The disagreement section is
retired from both READMEs rather than left describing an empty list, the
limits table now claims only what is true, that agreement is bounded by
the corpus and is not a proof of equivalence, and the changelog reads as
one change to verification rather than two.
@repsecure
repsecure merged commit 28bb4b3 into main Aug 5, 2026
10 checks passed
@repsecure
repsecure deleted the agent/2.7-torn-tail branch August 5, 2026 16:14
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