Context
#14026 leaf 4 (after coverage-drift #14075, monotonicity #14094, SQLite-integrity #14096). The Memory Core Chroma store grew to ~2.5GB (#14079) — uncontrolled store-size growth (un-pruned WAL / orphaned segments / churn) is a data-integrity signal, yet there is no detect signal for it. The #14026 body lists store-size/bloat (absolute + growth-rate) as a heuristic.
The Architectural Reality
dataIntegrityCoverageDiagnosis.mjs (#14075) + sqliteIntegrityDiagnosis.mjs (#14096) are the pure-producer pattern to mirror.
- Store size is measured by the daemon (e.g.
fs.stat on the store) + a previous sample for growth-rate — INJECTED into the pure producer (like monotonicity's count samples).
- Thresholds (absolute bytes + growth-ratio) are ADR-0019 config leaves, read at the daemon use-site and passed as params (NOT in the pure fn).
The Fix
A pure buildStoreBloatDiagnosis({storeSizeBytes, previousSizeBytes, thresholds, observedAt, serviceId}):
- Emits a
data-integrity / escalate diagnosis when storeSizeBytes > thresholds.absoluteBytes (absolute bloat) OR (previousSizeBytes present and the growth ratio (storeSizeBytes - previousSizeBytes) / previousSizeBytes > thresholds.growthRatio).
evidenceFacts name which signal(s) crossed (absolute / growth) + the sizes + the crossed threshold; details.reasonCode: 'data-integrity-store-bloat'.
null when within budget (no false escalation); a sub-signal whose threshold is non-finite is skipped (graceful).
- Detect-only — no prune/vacuum (operator-gated remediation; #14079).
Acceptance Criteria
Contract Ledger Matrix
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
buildStoreBloatDiagnosis({storeSizeBytes, previousSizeBytes, thresholds, observedAt, serviceId}) |
#14075 pure-producer pattern + #14079 bloat signal |
absolute OR growth bloat → data-integrity/escalate diagnosis; null within budget |
missing/zero previous → absolute-only; non-finite size → null; bad serviceId/observedAt → TypeError |
module + fn JSDoc |
unit spec |
| recovery-diagnosis payload |
createRecoveryDiagnosisEvent (recoveryRunStateStore) |
recoveryClass: 'data-integrity' · details.actionClass: 'escalate' · targetIdentity.kind: 'compose-service' · evidenceFacts[].type: 'store-bloat' (+ signal/sizes/threshold) · details.reasonCode: 'data-integrity-store-bloat' |
n/a |
JSDoc |
spec asserts each field |
(Contract Ledger included at creation — per @neo-gpt's #14095 catch, the detect-leaf pattern carries the ledger from the start.)
Out of Scope
- Scheduling + the size measurement (the #14026 wiring slice).
- Pruning/vacuuming the store (operator-gated; #14079).
Related
#14026 (parent), #14075 / #14094 / #14096 (sibling producers), #14079 (the 2.5GB bloat this detects), #14089 (the ADR-0025 §2.4 dimension), #14039.
Live latest-open sweep: checked latest open + the #14026 leaf set at 2026-06-26T14:07Z; no store-bloat leaf exists (#14079 = broader bloat roadmap). A2A: broadcast [coordination] + claim before filing.
Origin Session ID: 5ab545e1-f09e-46c5-ae62-8cf5b2b96193
Handoff Retrieval Hints: query_raw_memories("store-size bloat data-integrity detect producer absolute growth-rate"); anchors: ai/daemons/orchestrator/services/sqliteIntegrityDiagnosis.mjs (sibling), #14079.
Context
#14026 leaf 4 (after coverage-drift #14075, monotonicity #14094, SQLite-integrity #14096). The Memory Core Chroma store grew to ~2.5GB (#14079) — uncontrolled store-size growth (un-pruned WAL / orphaned segments / churn) is a data-integrity signal, yet there is no detect signal for it. The #14026 body lists store-size/bloat (absolute + growth-rate) as a heuristic.
The Architectural Reality
dataIntegrityCoverageDiagnosis.mjs(#14075) +sqliteIntegrityDiagnosis.mjs(#14096) are the pure-producer pattern to mirror.fs.staton the store) + a previous sample for growth-rate — INJECTED into the pure producer (like monotonicity's count samples).The Fix
A pure
buildStoreBloatDiagnosis({storeSizeBytes, previousSizeBytes, thresholds, observedAt, serviceId}):data-integrity/escalatediagnosis whenstoreSizeBytes > thresholds.absoluteBytes(absolute bloat) OR (previousSizeBytespresent and the growth ratio(storeSizeBytes - previousSizeBytes) / previousSizeBytes > thresholds.growthRatio).evidenceFactsname which signal(s) crossed (absolute/growth) + the sizes + the crossed threshold;details.reasonCode: 'data-integrity-store-bloat'.nullwhen within budget (no false escalation); a sub-signal whose threshold is non-finite is skipped (graceful).Acceptance Criteria
data-integrity/escalatediagnosis on absolute-bloat OR growth-bloat;nullwhen within budget.evidenceFactsname the crossed signal(s) + sizes + threshold;details.reasonCode: 'data-integrity-store-bloat'.targetIdentity.kind: 'compose-service'; thresholds are params (ADR-0019 — read at the use-site, not in the pure fn).null; missing/zeropreviousSizeBytes→ absolute-only; non-finitestoreSizeBytes→null; enum/target validate; arg-guard throws.Contract Ledger Matrix
buildStoreBloatDiagnosis({storeSizeBytes, previousSizeBytes, thresholds, observedAt, serviceId})data-integrity/escalatediagnosis;nullwithin budgetnull; badserviceId/observedAt→TypeErrorcreateRecoveryDiagnosisEvent(recoveryRunStateStore)recoveryClass: 'data-integrity'·details.actionClass: 'escalate'·targetIdentity.kind: 'compose-service'·evidenceFacts[].type: 'store-bloat'(+ signal/sizes/threshold) ·details.reasonCode: 'data-integrity-store-bloat'(Contract Ledger included at creation — per @neo-gpt's #14095 catch, the detect-leaf pattern carries the ledger from the start.)
Out of Scope
Related
#14026 (parent), #14075 / #14094 / #14096 (sibling producers), #14079 (the 2.5GB bloat this detects), #14089 (the ADR-0025 §2.4 dimension), #14039.
Live latest-open sweep: checked latest open + the #14026 leaf set at 2026-06-26T14:07Z; no store-bloat leaf exists (#14079 = broader bloat roadmap). A2A: broadcast
[coordination]+ claim before filing.Origin Session ID: 5ab545e1-f09e-46c5-ae62-8cf5b2b96193
Handoff Retrieval Hints:
query_raw_memories("store-size bloat data-integrity detect producer absolute growth-rate"); anchors:ai/daemons/orchestrator/services/sqliteIntegrityDiagnosis.mjs(sibling),#14079.