LearnNewsExamplesServices
Frontmatter
id14059
titleDetection-latency-under-retention SLA check (evaluateDetectionRetentionSla) — #14030 AC3 verdict-half
stateClosed
labels
enhancementaitestingarchitecture
assigneesneo-opus-vega
createdAtJun 26, 2026, 6:52 AM
updatedAtJun 26, 2026, 9:33 AM
githubUrlhttps://github.com/neomjs/neo/issues/14059
authorneo-opus-vega
commentsCount0
parentIssue14030
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJun 26, 2026, 9:33 AM

Detection-latency-under-retention SLA check (evaluateDetectionRetentionSla) — #14030 AC3 verdict-half

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

Context

#14030 AC3: "if corruption isn't detected within the backup-retention window, the last good backup ages out and recovery becomes impossible." The relationship must be documented and guarded — the data-integrity detect cadence (#14026) must be provably faster than backup retention, so a last-good backup never ages out before corruption is caught.

Like AC2 (#14053), this splits into a verdict-producing pure check (buildable now) and the config-wiring + CI-guard (gated on #14026's cadence config + the live retention config).

The Fix (this slice — the verdict-half)

A pure function evaluateDetectionRetentionSla({detectCadenceMs, backupRetentionMs, safetyFactor}) in ai/scripts/maintenance/detectionRetentionSla.mjs: given the worst-case detect cadence and the backup-retention window, returns a structured verdict {withinSla, marginMs, requiredMaxDetectMs, reason}withinSla true iff detectCadenceMs <= backupRetentionMs / safetyFactor (detection catches corruption with enough margin that recovery can run before the last-good backup is pruned). Pure, no I/O. JSDoc documents the relationship + the safety-factor rationale.

Acceptance Criteria

  • evaluateDetectionRetentionSla returns withinSla:true when detect cadence ≤ retention/safetyFactor, false (with a reason + requiredMaxDetectMs) otherwise.
  • A non-positive or missing retention/cadence is rejected (TypeError) — no silent pass.
  • The detection-latency < retention relationship + the safety-factor rationale are documented (JSDoc).
  • Unit coverage for within / breached / boundary / invalid-input verdicts.

Out of Scope (stays on #14030 / gated)

  • The CI-guard wiring that reads #14026's live detect-cadence config + the live backup-retention config and fails CI on a breach (gated on #14026 being built + the retention config surfaced).
  • AC1 (#14055 / #14058) + AC2 (#14053).

Contract Ledger Matrix

Consumed surface Field Type / values Change Consumer impact Fallback / semantics
evaluateDetectionRetentionSla() return (exported from detectionRetentionSla.mjs) the verdict object withinSla: Boolean · marginMs: Number (retention/safetyFactor − cadence; negative when breached) · requiredMaxDetectMs: Number (retention/safetyFactor) · reason: String|null (null when within; the breach explanation otherwise) New exported function (additive — no signature change to existing exports) No current consumer (new surface). Intended consumers: the CI-guard (next slice — breach → red) and an operator SLA probe. Pure; throws TypeError on non-positive/missing detectCadenceMs/backupRetentionMs; safetyFactor defaults to 2 (detection ≤ half the retention window).
  • Docs: the function's JSDoc documents the verdict shape + the detection-latency<retention relationship + the safety-factor rationale.
  • Evidence: L2 unit — within / breached / boundary / invalid-input.

Related

  • #14030 — parent (AC3); #14039 — v13.1 epic.
  • #14026 — the detect-signal whose cadence this SLA constrains (the wiring gates on it).
  • #14053 (AC2 check-half) / #14055 (AC1 producer-core) — sibling verdict-half slices.

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

tobiu referenced in commit 8239bf0 - "feat(ai): detect-cadence-under-retention SLA verdict (#14059) (#14060)" on Jun 26, 2026, 9:33 AM
tobiu closed this issue on Jun 26, 2026, 9:33 AM