Repository navigation
[Data Integrity Gap] Reject non-finite KPI snapshot evidence #329
Description
Buyer/operator outcome
Keep persisted/exported KPI evidence numerically well-defined. A corrupt or tampered append-only analytics ledger must fail closed instead of replaying NaN, infinity, negative rates, or negative latency values into buyer-facing evidence.
Fresh protected-main evidence — 2026-08-10
Protected main is 83ec6f7fe2b04bdcd28bf98ec350e41e55730a18.
KpiSnapshotLedger.rate(...) currently delegates directly to Double.parseDouble(field). Java accepts the lexical values NaN, Infinity, and -Infinity, so those values are currently replayable from the file-backed ledger. nullableLong(...) also accepts negative p95 latency values. These are structurally parseable but impossible/undefined KPI evidence and can later break JSON/export semantics or mislead diligence/operator analysis.
This is distinct from active PR #328, which corrects the denominator semantics of conversionSuccessRate. This issue owns persisted-evidence numeric validity and must not change the terminal-outcome formula.
Required contract
- persisted
conversionSuccessRatemust be finite and within[0.0, 1.0]; - persisted
p95TimeToPreviewMs, when present, must be non-negative; - malformed numeric evidence fails closed while loading the ledger using the existing controlled invalid-line failure contract;
- no raw persisted line or tenant/subject content is emitted in the public failure message;
- valid historical finite snapshots remain reloadable;
- do not silently clamp, coerce, or discard invalid evidence;
- keep this bounded slice independent of chore: superseded by current-base KPI PR #338 #328's denominator semantics and [Security Gap] Push analytics tenant isolation into repository queries #326's tenant-scoped repository-query successor work.
Test-first acceptance
- Add RED ledger-replay cases for
NaN,Infinity,-Infinity, a negative rate, a rate greater than one, and negative p95 latency. - Observe exact failures before changing production parsing.
- Implement the smallest validation at the ledger parse boundary.
- Preserve current invalid-line error shape and valid round-trip tests.
- Run exact-head CI, Security Scan, SAST, fuzz and current review gates with zero required skips/failures/errors.
- Preserve exact owned production coverage and public Javadocs.
Documentation boundary
PR #305 remains the canonical cross-cutting documentation writer. This bounded integrity slice should update code/tests only; canonical data-integrity/test/traceability semantics can be reconciled through the canonical documentation line after integration.
Activity