LearnNewsExamplesServices
Frontmatter
id14134
titleAutonomous data-recovery actuator: heal data-integrity drift via apply(), not escalate-to-operator
stateClosed
labels
enhancementaiarchitecture
assigneesneo-opus-grace
createdAtJun 26, 2026, 8:15 PM
updatedAtJun 27, 2026, 5:00 PM
githubUrlhttps://github.com/neomjs/neo/issues/14134
authorneo-opus-grace
commentsCount4
parentIssue14132
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJun 27, 2026, 5:00 PM

Autonomous data-recovery actuator: heal data-integrity drift via apply(), not escalate-to-operator

Closed v13.1.0/archive-v13-1-0-chunk-7 enhancementaiarchitecture
neo-opus-grace
neo-opus-grace commented on Jun 26, 2026, 8:15 PM

Context

@tobiu's v13.1 mandate (2026-06-26): 100% fully autonomous self-healing is mandatory; zero operator-ack anywhere in Agent OS; where the actuator lacks logic, build it — never fall back to a human. Operator already enforced this at the actuator layer (recovery daemon default-ON, empty blocklist). The data-integrity detect class (#14026 / #14075 / #14104 / #14117) re-introduced the disabled-self-healing at the data layer: every producer hardcodes actionClass: 'escalate', and DataIntegrityDiagnosisService routes EXCLUSIVELY to escalateDiagnosis — pages a nonexistent cloud operator. This ticket fills the missing actuator logic so data-integrity drift heals itself.

The Problem

RecoveryActuatorService's action vocabulary is ['restart', 'redeploy', 'page', 'warm-provider'] — there is no data-repair action. So a detected coverage-drift / vector-loss can only escalate, never apply() a repair. The autonomous repair pipeline already exists (repairMemoryCoreStoredEmbeddings, defragChromaDB) but is bypassed — the detect signal alarms instead of triggering the re-embed/restore that would heal it. In a cloud deployment (the live docker-mcp stack) that alarm reaches no one; the store stays gutted.

The Architectural Reality

  • ai/daemons/orchestrator/services/RecoveryActuatorService.mjs — action vocab restart/redeploy/page/warm-provider; apply() envelope is config+lifecycle only (ADR-0026).
  • The data-repair primitives exist: repairMemoryCoreStoredEmbeddings, defragChromaDB (ai/scripts/maintenance/) — proven by the #13999 recovery + #14046 gate, but only operator-run.
  • DataIntegrityDiagnosisService validates only an escalateDiagnosis() sink and asserts apply() is never reached even on drift (#14131) — the inverted contract.

The Fix

A bounded autonomous data-recovery actuator: an apply()-able data-repair action (re-embed-missing rows / restore-from-backup) that data-integrity diagnoses route to instead of escalate, with autonomous safety bounds (not a human gate):

  • rate-bound + anti-thrash (reuse recovery-run-state / leases) so it can't hammer the already-stalling embed provider or loop;
  • warm-provider-aware (compose with the existing warm-provider action when the embedder is cold/slow);
  • systemic-fault bound — a mismatch/loss RATE above threshold = a misconfigured embedder, not bounded drift → freeze + record telemetry (autonomous safety), NEVER a mass auto-re-embed (the #14115 expectedDimension false-storm class).
  • No runtime escalate/page (per #14132 / the operator directive): a heal-logic gap surfaces as a design-time ticket to build the heal, never a runtime page-a-human. Telemetry/audit logging is autonomous observability, not an escalate.

Divergence matrix (design-choice — OPEN AC, converges in /ideation per §1c)

Option Shape Falsifying source
(a) Dedicated data-recovery controller/actuator in the MC data domain (recommended — @neo-gpt) New actuator reusing recovery-run state / leases / anti-thrash; reserves the existing actuator for infra Lowest-risk; keeps ADR-0026's infra actuator action-set unchanged
(b) Extend RecoveryActuatorService with a repair-memory-core action One actuator, new data action ADR-0026 action-set expansion (currently config+lifecycle only) — bigger blast
(c) Direct runner→repair call DataIntegrityDiagnosisService calls repair directly Only acceptable if documented as the bounded data-recovery actuator boundary; an ad-hoc bypass is rejected (@neo-gpt #14131)

Decision Record impact

amends ADR-0026 — the actuator gains an autonomous data-repair action class, and the "data mutation stays operator-gated / recovery is escalate-with-plan, not auto-repair" framing is superseded by @tobiu's 100%-autonomous mandate. Downstream-amendment acknowledgment: the design-choice (a/b/c) + the precise bounds converge in /ideation (Discussion #14037 lineage); the Fix + ACs here may refresh post-graduation.

Acceptance Criteria

  • A healable data-integrity diagnosis (coverage-drift / missing vectors) triggers an autonomous bounded repair via apply() — NOT escalate — and heals the store with no human.
  • Rate-bound + anti-thrash + warm-provider-awareness prevent provider-hammering / repair loops (autonomous safety, asserted in tests).
  • A systemic-fault-rate residue freezes + records telemetry (autonomous safety), never a mass auto-re-embed; if its heal is unknown, that gap is a design-time ticket, not a runtime escalate.
  • No runtime escalate/page exists (per #14132); zero operator-ack on any path; every diagnosis routes to an autonomous heal or an autonomous freeze+record.
  • Design-choice (a/b/c) resolved in /ideation before implementation; this ticket's Fix refreshed to match.

Out of Scope

  • The accepted-loss settle outcome (#14084 — autonomous settle of irreducible-terminal residue, separate).
  • The producer/runner re-route from escalateapply() (Ada's side of the reshape).
  • The detect layer (#14026 / #14117 — already live).

Avoided Traps

  • "The remedy isn't bounded-safe → keep escalate." That's the regression — it routes to an absent human. The answer is a bounded autonomous actuator, not a human gate.
  • Naive auto-apply. An unbounded auto-re-embed on a dimension storm hammers the stalling provider — hence the rate / anti-thrash / systemic-fault bounds.

Related

#14039 (v13.1 epic — act-half reshape), #14084 (accepted-loss autonomous settle — sibling), #14026 (detect-signal class), #14061 (current escalate sink), #14131 (the stale escalate-only slice this supersedes), Discussion #14037 (recovery-actuator design lineage).

Origin Session ID: 5ab545e1-f09e-46c5-ae62-8cf5b2b96193

Handoff Retrieval Hints: query_raw_memories("autonomous data-recovery actuator apply re-embed restore bounded self-heal zero operator-ack"); exact anchors: RecoveryActuatorService action vocab, repairMemoryCoreStoredEmbeddings, DataIntegrityDiagnosisService.

Authored by Grace (Claude Opus 4.8, Claude Code).

tobiu referenced in commit 4172a64 - "docs(adr): ADR-0027 — autonomous Memory Core data-recovery actuator envelope (#14140) (#14141) on Jun 26, 2026, 11:56 PM
tobiu referenced in commit 945b565 - "feat(ai): autonomous heal-action dispatch core — safety-gate + injected execution (#14142) (#14143) on Jun 27, 2026, 12:27 AM
tobiu referenced in commit 2c3c401 - "feat(ai): cloudOnly composeServiceRecoveryEnabled mode-gate for B1 docker-socket recovery (#14150) (#14170) on Jun 27, 2026, 2:17 AM
tobiu referenced in commit efde5b6 - "feat(ai): autonomous re-embed-missing data heal — defer becomes act (#14134) (#14240) on Jun 27, 2026, 5:00 PM
tobiu closed this issue on Jun 27, 2026, 5:00 PM
tobiu referenced in commit 144ca82 - "refactor(ai): drop vestigial actionClass:escalate from the 5 data-integrity producers (#14138) (#14250) on Jun 27, 2026, 6:12 PM