[discovered w/ the help of Claude]
Problem
fsck --ui=false always exits 0 even on corruption, discarding errors before they reach $?. In 2 of 3 failure modes, no diagnostic is printed, making --ui=false unusable as an automated CI/pipeline gate.
Impact Matrix (Fault Injection on Static-CT Log)
| Corruption Type |
Detected Internally |
Output Diagnostic |
Exit Code |
Bit flip (tile/0/042) |
Yes (hash mismatch) |
None |
0 |
Truncation (tile/data/042) |
Yes (bundle parse error) |
None |
0 |
Missing issuer (issuer/<hex>) |
Yes (fetch failure) |
WARN only |
0 |
Underlying detection logic in tessera/fsck is sound; only cmd/fsck error reporting fails.
Root Causes
- Early Return Bypasses
eg.Wait() (main.go:92–101):
f.Check completion invokes deferred cancel(), closing ctx.Done(). The non-TUI loop executes case <-ctx.Done(): return, exiting main directly and skipping eg.Wait(), os.Exit(1), and slog.Info("OK").
- Disconnected Issuer Status:
Successfully fsck'd log (tessera/fsck/fsck.go:167) reflects tree verification only, omitting concurrent checkIssuersTask status.
- LIFO Defer Prematurely Cancels Context (
main.go:76–81):
defer cancel() runs before defer lsc.Close(), canceling ctx while issuer workers may still be draining issuersToCheck, potentially truncating checks on large logs or causing spurious HTTP context canceled errors.
- Regression test: No test currently invokes the cmd/fsck binary — all existing fsck coverage calls Check() directly and inspects the returned error, which is why this went unnoticed. Add a test that execs the built binary against a corrupted fixture with --ui=false and asserts a non-zero exit.
Minimal Reproduction
go build -o /tmp/fsck-ct ./cmd/fsck
# Corrupt single byte in a mirrored log tile:
cp -r /path/to/log /tmp/broken
printf '\x01' | dd of=/tmp/broken/tile/0/042 bs=1 seek=100 conv=notrunc
# Run without TUI:
/tmp/fsck-ct --monitoring_url=file:///tmp/broken \
--origin=<origin> --public_key=<key> --ui=false
echo $? # Returns 0 with no error diagnostics (BUG)
[discovered w/ the help of Claude]
Problem
fsck --ui=falsealways exits 0 even on corruption, discarding errors before they reach$?. In 2 of 3 failure modes, no diagnostic is printed, making--ui=falseunusable as an automated CI/pipeline gate.Impact Matrix (Fault Injection on Static-CT Log)
tile/0/042)tile/data/042)issuer/<hex>)WARNonlyUnderlying detection logic in
tessera/fsckis sound; onlycmd/fsckerror reporting fails.Root Causes
eg.Wait()(main.go:92–101):f.Checkcompletion invokes deferredcancel(), closingctx.Done(). The non-TUI loop executescase <-ctx.Done(): return, exitingmaindirectly and skippingeg.Wait(),os.Exit(1), andslog.Info("OK").Successfully fsck'd log(tessera/fsck/fsck.go:167) reflects tree verification only, omitting concurrentcheckIssuersTaskstatus.main.go:76–81):defer cancel()runs beforedefer lsc.Close(), cancelingctxwhile issuer workers may still be drainingissuersToCheck, potentially truncating checks on large logs or causing spurious HTTPcontext cancelederrors.Minimal Reproduction