LearnNewsExamplesServices
Frontmatter
id14048
titleBackup integrity: flag empty-parity (gutted-store) exports instead of a silent pass
stateClosed
labels
enhancementaitesting
assigneesneo-opus-vega
createdAtJun 26, 2026, 4:36 AM
updatedAtJun 26, 2026, 9:35 AM
githubUrlhttps://github.com/neomjs/neo/issues/14048
authorneo-opus-vega
commentsCount0
parentIssue14030
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJun 26, 2026, 9:35 AM

Backup integrity: flag empty-parity (gutted-store) exports instead of a silent pass

Closed v13.1.0/archive-v13-1-0-chunk-6 enhancementaitesting
neo-opus-vega
neo-opus-vega commented on Jun 26, 2026, 4:36 AM

Context

backup.mjs verifyBundleIntegrity (the row-count parity check added with #13584) compares the bundle's JSONL row count against the SDK source count and throws on mismatch — which correctly catches the #14042 false-green class (manifest claims N, artifact 0 bytes → N≠0 → fail).

The Problem

The parity branch if (bundleCount === sourceCount) reports status: 'pass' when both are zero. A backup of a gutted store (the #13999 signature: the source was already emptied → export returns 0 → bundle is 0) therefore reports a healthy pass, indistinguishable from a real backup. An all-empty "passing" backup is a false recovery source — exactly the trust gap the backup substrate is supposed to close.

The Fix

In verifyBundleIntegrity, distinguish status: 'empty' (sourceCount === bundleCount === 0) from a healthy pass (N === N, N > 0). In runBackup, surface empty subsystems with a loud logger.warnnon-fatal (a fresh environment legitimately backs up empty subsystems) but visible, and the empty status is carried in bundle-meta.integrity so a downstream canary/alert can escalate on it.

Acceptance Criteria

  • verifyBundleIntegrity returns status: 'empty' (not 'pass') when source and bundle are both zero, with a reason.
  • N === N (N > 0) still returns 'pass'; a mismatch still returns 'fail'; non-numeric still 'skipped'.
  • runBackup warns (non-fatal) on empty subsystems; bundle-meta.integrity carries the empty status.
  • Unit coverage for the empty-parity case.

Relation

  • Slice of #14030 AC2 (verify the backup is a usable recovery source, not merely present). The remaining #14030 AC2 work — a sampled logical import into a throwaway store — and AC1 (alert wiring) / AC3 (retention-SLA) follow separately per the build-order on #14030.
  • #13999 — the gutted-store incident this makes visible.

Contract Ledger Matrix

Consumed surface Field Allowed values Change Consumer impact Fallback / non-fatal semantics
verifyBundleIntegrity() return + persisted bundle-meta.integrity[] status pass (positive row-count parity) · empty (source === bundle === 0 — non-fatal but recovery-unhealthy) · fail (row-count mismatch) · skipped (non-numeric source count) Adds empty (previously pass/fail/skipped) No current consumer switches on status: restore.mjs runs its own pre-flight validateBundle + reads only topology/neoVersion; HealthService reads only completedAt/timestamp. Intended consumer: the future backup canary (#14026 / #14030 AC1). Additive — an unknown-status consumer treats empty as not-pass (correct: empty ≠ healthy). runBackup surfaces empty non-fatally (a fresh environment legitimately backs up empty subsystems): a loud logger.warn + the empty status persisted into bundle-meta.integrity for the canary to escalate on. A populated deployment reporting empty is the gutted-store signature.
  • Docs: verifyBundleIntegrity JSDoc (body + @returns) documents all four statuses.
  • Evidence: L2 — the helper test covers the empty-parity branch; the runBackup propagation test asserts status:'empty' is persisted into bundle-meta.integrity with a non-fatal warning.

Authored-by: @neo-opus-vega (Vega, Claude Opus 4.8)

tobiu referenced in commit 8b34fe3 - "fix(ai): flag empty-parity backups as not a healthy pass (#14048) (#14049) on Jun 26, 2026, 9:35 AM
tobiu closed this issue on Jun 26, 2026, 9:35 AM
tobiu referenced in commit 3d67020 - "feat(ai): backup restorability pre-flight check (#14053) (#14054) on Jun 26, 2026, 9:36 AM