Context
#16780 needs a bounded observation of repeated batch-embedding work. Provider activity says which stage consumes inference and WAL drain says how much work remains; neither records content identity. This ticket adds that identity dimension without storing corpus text or turning the observation into an alarm.
Architectural Reality
Knowledge Base and Memory Core run in separate processes, so a TextEmbeddingService-local window cannot be read by the Memory Core metrics observer. Both recorder services already open the same plane-anchored graph SQLite. The identity observation therefore belongs in that shared artifact.
The producer is TextEmbeddingService.embedTexts(), not interactive embedText(). It records logical batch-input admissions only after provider and abort validation and before provider settlement. Pre-aborted, unsupported, empty, yielded-before-next-chunk, and locally invalid work records nothing; work that fails after admission remains observable. Transport retry attempts are not multiplied into new logical submissions.
Fix
- Replace the process-local window with shared
embedding_identity_log and embedding_identity_state tables.
- Store only a recorder-owned source, timestamp, opaque id, and 128-bit SHA-256 fingerprint; never raw input.
- Bound retention to 2,048 rows and preserve durable
coverage_started_at and evicted_through boundaries.
- Read watermark, retained boundary, and counts in one SQLite snapshot so concurrent eviction cannot create a partial-as-total result.
- Query the exact
get_memory_core_tool_metrics().sinceMs interval; old repeats cannot contaminate a current interval.
- Publish
status, reason, coverageStartedAt, oldestRetainedAt, distinct, ratio, submissions, and truncated on every response arm.
- Keep the ratio observational:
submissions / distinct, and null for an observed interval with no batch submissions. A value above 1 may be legitimate and neither proves a loop nor disproves convergence.
Contract Ledger
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback / Edge Case |
Evidence |
TextEmbeddingService.embedTexts() |
#16866 / #16780 AC-3 |
After validation and immediately before admitted provider work, pass batch inputs to the recorder owned by that process. |
Invalid, pre-aborted, empty, or yielded-before-next-chunk work records nothing; telemetry failure is behavior-neutral. |
Provider admission and negative controls in TextEmbeddingService.spec.mjs |
| Shared identity ledger |
#16866; plane-anchored graph DB |
KB and MC contribute to one row-bounded population; source is recorder-owned; raw text becomes a 128-bit fingerprint. |
Retention writes an eviction watermark; reads use one snapshot; unknown source normalizes to unknown. |
Two-connection, interleaving, lookback, coverage, eviction, and raw-absence tests |
get_memory_core_tool_metrics().reembedRatio |
Existing metrics observer |
Read the shared ledger over the same effective sinceMs and return the complete field set. |
Disabled/unavailable arms are null-valued; writer/read gaps are partial or unavailable; coverage gaps set truncated. |
KB-to-MC visibility, exact lookback, empty interval, combined-partial, and status-arm tests |
OpenAPI ReembedRatioResponse |
Runtime response above |
Require all eight fields and describe observational admitted-batch values scoped to sinceMs. |
Nullable observation fields on unavailable arms; ratio above 1 carries no verdict. |
OpenAPI service-parity and response-key tests |
VectorService.embedChunks({chunksToProcess: []}) |
#16780 AC-1 |
Return zero work without invoking the embedding provider or writing vectors. |
N/A |
Provider-boundary spy in VectorService.batchFailureIsolation.spec.mjs |
Acceptance Criteria
Out of Scope
Automated alarm thresholds, loop adjudication or remediation, interactive single-text embedding calls, and raw-content retention.
Related
#16780, #16835, #16861.
Origin Session ID: 87f453f9-aa80-4487-9ed1-b5d91e052c43
Authored by Ada (Claude Opus 5, Claude Code); cross-process repair by @neo-gpt.
Context
#16780 needs a bounded observation of repeated batch-embedding work. Provider activity says which stage consumes inference and WAL drain says how much work remains; neither records content identity. This ticket adds that identity dimension without storing corpus text or turning the observation into an alarm.
Architectural Reality
Knowledge Base and Memory Core run in separate processes, so a
TextEmbeddingService-local window cannot be read by the Memory Core metrics observer. Both recorder services already open the same plane-anchored graph SQLite. The identity observation therefore belongs in that shared artifact.The producer is
TextEmbeddingService.embedTexts(), not interactiveembedText(). It records logical batch-input admissions only after provider and abort validation and before provider settlement. Pre-aborted, unsupported, empty, yielded-before-next-chunk, and locally invalid work records nothing; work that fails after admission remains observable. Transport retry attempts are not multiplied into new logical submissions.Fix
embedding_identity_logandembedding_identity_statetables.coverage_started_atandevicted_throughboundaries.get_memory_core_tool_metrics().sinceMsinterval; old repeats cannot contaminate a current interval.status,reason,coverageStartedAt,oldestRetainedAt,distinct,ratio,submissions, andtruncatedon every response arm.submissions / distinct, andnullfor an observed interval with no batch submissions. A value above 1 may be legitimate and neither proves a loop nor disproves convergence.Contract Ledger
TextEmbeddingService.embedTexts()TextEmbeddingService.spec.mjsunknown.get_memory_core_tool_metrics().reembedRatiosinceMsand return the complete field set.truncated.ReembedRatioResponsesinceMs.VectorService.embedChunks({chunksToProcess: []})VectorService.batchFailureIsolation.spec.mjsAcceptance Criteria
1; this is a no-repeat control, not a convergence verdict.1.ratio: null, never a synthetic clean value.truncated: true, with complete controls for later intervals.sinceMs, with the complete required shape on every status arm.Out of Scope
Automated alarm thresholds, loop adjudication or remediation, interactive single-text embedding calls, and raw-content retention.
Related
#16780, #16835, #16861.
Origin Session ID: 87f453f9-aa80-4487-9ed1-b5d91e052c43
Authored by Ada (Claude Opus 5, Claude Code); cross-process repair by @neo-gpt.