A malformed witness report reads as "no equivocation" to every consumer
- Dominant language
- Rust
- Stars
- 3
- Forks
- 0
- Avg merge
- 1d 42m
- Merged PRs (30d)
- 11
Description
Equivocation checking now returns a distinct verdict when a report fails to parse — deliberately, so that a malformed report can be told apart from an honest absence of conflict. **No consumer distinguishes it.** Every call site reduces the verdict to a proven-or-not test, so malformed lands in the same bucket as "these reports agree."
The distinction exists in the type and is discarded at all three consuming sites.
## Why it matters
A signer's goal in evading equivocation detection is simply that **no claim is raised**. Before the typed parse, that was achieved by presenting one logical value in two representations so the comparison saw two different states. The parse closes that — but if a malformed report also produces no claim, and nothing anywhere distinguishes the two outcomes, the evasion is relocated rather than closed. Making one report unparseable achieves what making it differently-encoded used to.
This is understood and is being closed from the other end: the witness sync path will refuse to ingest a report that fails to parse, so a malformed report never becomes a retained attestation in the first place. Until that lands, the distinct verdict is produced and thrown away.
## An interim regression worth stating plainly
A test previously asserted that a conflict between reports carrying atypical field types **must not** be dropped, and it passed — the system detected that equivocation. It now asserts that no claim is raised, because both reports are rejected as malformed before comparison.
On that input, the system detected an equivocation before this change and does not detect it now. The rejection is correct in itself; the consequence is that the detection is gone until the ingestion refusal lands.
Exposure is limited to development: the branch carrying this work reaches the release line only as a whole, with the ingestion refusal included.
## What resolving this involves
Either the consuming layer distinguishes the malformed verdict — surfacing it rather than folding it into no-conflict — or the ingestion refusal makes it unreachable and the verdict becomes a defensive assertion rather than a live path. The second is the planned route. This issue exists so the interim gap is visible rather than living in a comment, and so the deleted assertion is restored in whichever form ends up correct.
Related: #141, #146.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by tracing the three consuming sites that reduce the equivocation verdict to a proven-or-not result, then inspect the deleted regression assertion for atypical field types. Compare the two possible resolutions described in the issue: surface the malformed verdict, or make it unreachable through witness sync ingestion refusal; done means the malformed case is no longer silently treated as no conflict and the assertion is restored appropriately.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100