LearnNewsExamplesServices
Frontmatter
id15689
titleRestore embed-preflight gate blocks preserved-vector restores — revert and re-scope to re-embed actions
stateClosed
labels
bugai
assigneesneo-kimi-phoebe
createdAtJul 22, 2026, 11:21 AM
updatedAtJul 22, 2026, 12:17 PM
githubUrlhttps://github.com/neomjs/neo/issues/15689
authorneo-kimi-phoebe
commentsCount2
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJul 22, 2026, 12:17 PM

Restore embed-preflight gate blocks preserved-vector restores — revert and re-scope to re-embed actions

neo-kimi-phoebe
neo-kimi-phoebe commented on Jul 22, 2026, 11:21 AM

Context

Emmy's peer-role premise-revalidation of merged PR #15643 (A2A 2026-07-22T09:12Z, operator-requested) falsified the gate's core claim. Source-verified and conceded: restores preserve embeddings; no production restore path re-embeds. The hard gate I added blocks exactly the recovery it claimed to protect — a provider-down disaster restore that would succeed on preserved vectors.

The Falsification Chain (verified this session)

  1. KB: ai/services/knowledge-base/DatabaseService.mjs:257-260 — "Records preserve their original embeddings — no re-embedding is triggered"; :344 passes embeddings: batch.map(r => r.embedding) into upsert.
  2. MC: ai/services/memory-core/DatabaseService.mjs:436,440importDatabase({reEmbed=false}) DEFAULT; only reEmbed: true (:585) strips vectors for Chroma re-embedding.
  3. ai/scripts/maintenance/restore.mjs contains zero reEmbed usage; the symbol lives only in defragChromaDB.mjs, repairMemoryCoreStoredEmbeddings.mjs, reEmbedMissingHeal.mjs, migrateMemoryCore.mjs, and KB VectorService.mjs.
  4. ADR-0027 (0027-autonomous-data-recovery-actuator.md) separates re-embed-missing / re-embed-rows (provider-needed) from restore-delta-merge (v13.2-deferred, bundle-merge — preserved-vector by the same import paths). The gate is wrong-shaped for the future actuator too: the preflight belongs to the re-embed actions, not restore paths.

The Problem

restore.mjs preflights the embedding provider before ANY restore (preflightEmbeddingProvider, gated by onlySubstrate selection but applied to all substrates including graph/concepts/trajectories flat-file restores) and refuses when the provider is cold — with an error message teaching a false mechanism ("Restore re-embeds imported records"). Consequences:

  • A provider-down disaster-recovery restore — the exact scenario the gate claimed to protect — is refused despite preserved vectors making it provider-free.
  • The false mechanism is now load-bearing JSDoc and error prose, poisoning future readers.
  • The facf802e8d spec seam threads a healthy embedText through restore flow specs, entrenching the false premise in the test suite.

The Fix

  1. Revert the restore.mjs gate: remove preflightEmbeddingProvider, its call site, the --skip-embed-preflight flag, the false JSDoc/error prose, and the restore-flow embedText spec seam (#15643 + facf802e8d).
  2. Keep the honest remainder: the bundle-integrity gap that remains is records missing embeddings (corrupt/partial bundles) — that belongs to import-path validation (fail with a precise missing-vector error naming the re-embed repair script), not a provider preflight. Named as follow-up direction, not bundled here.
  3. The canary's correct home is the ADR-0027 actuator path, not standalone scripts (corrected per operator-verified authority note, issuecomment-5044161615): re-embedding repair is orchestrator-driven — orchestrator diagnostics/classifier → controller-selected action → Memory-Core-resident ADR-0027 actuator using an injected repair primitive. Standalone scripts (defragChromaDB.mjs, repairMemoryCoreStoredEmbeddings.mjs, reEmbedMissingHeal.mjs) hold no scheduling, diagnosis, action-selection, or readiness authority, so the write-canary probe must NOT be re-homed there. Any future action-local probe must be abortable. Named follow-up direction, not this PR.
  4. Open question recorded: #15640's original "fresh-host restore stall" observation needs re-identification — if a real stall existed, its path was not re-embedding (candidates: missing-vector bundle records; post-restore ingestion). Recorded in the ticket so the next reader doesn't re-derive the false premise.

Acceptance Criteria

  • restore.mjs performs no embedding-provider preflight; restore of a preserved-vector bundle succeeds with the provider unreachable (unit witness with a failing embed seam)
  • The false "re-embeds imported records" prose is gone from JSDoc, error messages, and specs
  • The --skip-embed-preflight flag and the restore-flow embedText seam are removed
  • Follow-up direction for the re-embed-action probe (ADR-0027 actuator path, abortable, action-local) + missing-vector import validation is named in the PR body (not implemented here)
  • Existing restore specs (flow, merge/replace, onlySubstrate, topology) stay green without the seam

Out of Scope

  • The action-local abortable probe on the ADR-0027 actuator path (named follow-up; standalone scripts explicitly hold no such authority)
  • Missing-vector import validation (named follow-up)
  • Re-litigating the #15640 observation (recorded as open question)

Related

  • #15640, PR #15643, facf802e8d (the gate being reverted)
  • ADR-0027 (the action taxonomy that confirms the correct scope)
  • #15639 (first-boot restore — consumes this restore path; unaffected by preserved vectors)

Live latest-open sweep: checked latest 20 open issues at 2026-07-22T09:22Z; no equivalent found. A2A in-flight sweep: Emmy's re-validation assigns this correction to me; no competing claim.

Origin Session ID: 72c8c42d-f18a-408c-97c8-aeb1f82dd276

Retrieval Hint: "restore embed preflight preserved vectors revert gate over-broad provider re-embed actions"