Skip to content

fix(kpi): bind strict production provenance to exact log bytes #104

Description

@seonghobae

Problem

Protected main at c85d710804139c0697d7ef8fa47d02b1389e6d84 requires production provenance in strict KPI mode, but protected source does not cryptographically bind that provenance to the exact retained exchange-30d.ndjson bytes being scored. This is a data-integrity/provenance boundary distinct from the still-missing real 30-day production evidence in #3.

Active test-first repair: PR #105, current exact head 825dd9b8c3f19270602735a0c78a417fe7213345.

RCA 1 — provenance-to-evidence identity

The original failing boundary was exact-byte identity:

  • the collector retained source metadata and record count but no SHA-256/byte-size identity;
  • strict KPI verification trusted that metadata without recomputing retained-log identity;
  • replacing the collected file could therefore cause a different byte stream to be scored under unchanged provenance.

PR #105 adds collector-generated logSha256 and logBytes, validates digest format and positive safe-integer byte size, recomputes exact identity before scoring, and preserves secret/placeholder source-ID rejection.

RCA 2 — replace-score-restore TOCTOU

A start/end identity comparison was insufficient: a process could replace the original log after initial verification, let KPI child checks score the replacement, and restore the original before the final identity check.

Falsifiable RED b9c51582ab701f6851ee65e0f9283e90f5c6e53f deterministically replaces the original only while KPI child processes execute and restores it on child exit. Application CI run 31414867826, job 93541377446, failed exactly that regression while the remaining 652 tests passed.

GREEN e80c6a8541b480cd7c381c7042ea9e233863dd20 creates a process-private temporary snapshot after original identity verification, changes its mode to 0400, recomputes SHA-256/byte size against provenance, and passes only that verified snapshot to KPI child processes. Persistent original-path drift is still checked after children and temporary bytes are removed on completion/exit. This does not claim an OS privilege boundary against same-account/higher-privilege tampering or authenticate the upstream Logpush/archive provider.

RCA 3 — record-count/data-integrity boundary

Shell wc -l previously computed records before a separate Node pass computed logSha256/logBytes. An unterminated final NDJSON record therefore produced records: 0 although one valid record existed, and count versus digest/byte metadata came from separate reads.

Exact RED 676f31190226f1e9ebf566fc0914eb2666efd257 / application CI 31415905532, job 93544736430, failed exactly the count regression while 653 tests passed. GREEN 61b8c152698d2833fda6dfbb4a1b0dc951f468cd removes wc -l authority and derives records, logSha256, and logBytes from one retained-byte stream, including a final non-empty unterminated record.

RCA 4 — strict evidence-retention boundary

persistEvidence() logged an NOEMA_KPI_EVIDENCE_PATH write failure but swallowed it, so strict mode could exit 0 and emit PASS while explicitly configured retained evidence did not exist.

RED 807a867600249a1101e52965de47ed81f77e48e1 configures the evidence destination as a directory so persistence deterministically fails. Application CI run 31417456928, job 93549720229, checked out that exact RED and failed only the new regression (status was 0, expected 1); 654 other tests passed.

GREEN b4055f30bbe1d93891cba04d909b183e6503e505 makes evidence persistence return success/failure and requires successful retention before strict mode may emit final PASS. Non-strict optional-evidence behavior is unchanged; already-failing strict paths remain failing even if best-effort diagnostic evidence cannot be retained.

RCA 5 — positive-safe-integer byte mismatch regression coverage

Diagnostic review of exact head b4055f30bbe1d93891cba04d909b183e6503e505 found that missing/zero/unsafe logBytes tests exercised field validation but did not prove the identity-mismatch path for a syntactically valid positive safe integer.

Current head 825dd9b8c3f19270602735a0c78a417fe7213345 adds a focused regression that keeps the correct logSha256, changes logBytes by one, and requires KPI log identity does not match production provenance. No production implementation change was needed because the existing exact-identity check already fails closed.

Current exact-head proof

For unchanged PR #105 head 825dd9b8c3f19270602735a0c78a417fe7213345:

  • application ci 31418085423: terminal success;
  • reviewer-ci 31418085451: terminal success;
  • central Security Scan 31418085400: terminal success under current protected-base scanner semantics;
  • current unresolved inline review threads: 0;
  • the two original inline findings remain addressed/resolved;
  • the diagnostic P2 coverage gap on predecessor b4055f30bbe1d93891cba04d909b183e6503e505 is addressed on current head;
  • visible formal CodeRabbit review remains COMMENTED on predecessor 43054db5bc8486d56db77bd17f2371d633e678a5, not qualifying independent approval;
  • current-head model review retry is rate-limited and therefore non-passing, non-approval evidence;
  • GitHub reports the content graph mergeable, 16 commits ahead / 0 behind current protected main.

Acceptance

Implemented on PR #105 current head

  • Tampering with log bytes after provenance creation fails closed.
  • Wrong/malformed/missing digest or byte-size provenance fails closed.
  • Missing, zero and unsafe-integer logBytes are independently rejected with a valid digest.
  • A valid positive-safe-integer but incorrect logBytes value reaches and fails the exact identity-mismatch path.
  • Valid exact-byte provenance passes strict KPI evaluation.
  • Collector emits exact SHA-256 and byte size for retained log bytes.
  • Replace-score-restore of the original path cannot change bytes scored by KPI child checks.
  • Verified snapshot identity mismatch fails closed before scoring.
  • records, logSha256, and logBytes are derived from one retained-byte stream, including an unterminated final NDJSON record.
  • An explicitly configured strict evidence-retention write failure cannot produce final PASS.
  • Existing secret/placeholder source-ID protections remain intact.
  • Operator documentation defines the verified-snapshot guarantee and its OS-account privilege limitation.
  • No production KPI, acquisition, release, deployment, licensing, external-source-authenticity or legal-rights claim is manufactured.

Remaining protected integration / operation

Related: #3, #5, #27, #29

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions