LearnNewsExamplesServices
Frontmatter
id14295
titleSeal heal-ledger retention coverage
stateClosed
labels
bugaiarchitecture
assigneesneo-gpt
createdAtJun 28, 2026, 4:43 PM
updatedAtJun 28, 2026, 8:41 PM
githubUrlhttps://github.com/neomjs/neo/issues/14295
authorneo-gpt
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJun 28, 2026, 8:41 PM

Seal heal-ledger retention coverage

Closed v13.1.0/archive-v13-1-0-chunk-7 bugaiarchitecture
neo-gpt
neo-gpt commented on Jun 28, 2026, 4:43 PM

Context

PR #14272 shipped the self-heal observability surface and bounded heal-ledger primitives. During final review, one valid follow-up remained: some production append sites still wrote to the shared heal-event ledger without supplying the validated retention pair, so those event classes could grow the ledger indefinitely if they were the only active writers.

This issue was originally filed with an additional dataDir mutation-coherence claim. That claim is retracted. dataDir is reactive, but that fact alone does not prove every closure constructed inside sibling beforeSet* hooks must migrate after later dataDir changes. Runtime dataDir mutation across all data-bound orchestrator closures is a broader contract question and is out of scope here.

The Problem

appendHealEvent() intentionally owns no production retention defaults. It only arms the append-time prune gate when callers supply finite triggerBytes and maxEvents.

The production append classes that still needed explicit retention coverage were:

  • ai/daemons/orchestrator/Orchestrator.mjs recordCircuitEvent
  • ai/services/memory-core/helpers/freezeReprobeRunner.mjs contained-reopen
  • ai/services/memory-core/helpers/freezeReprobeRunner.mjs unfreeze
  • ai/services/memory-core/helpers/freezeReprobeRunner.mjs contained

The Fix

  • Keep healEventLedgerStore.mjs pure: no helper-owned production defaults and no direct AiConfig reads inside the helper.
  • Read and validate AiConfig.orchestrator.recoveryActuator.healLedger.{maxEvents,pruneTriggerBytes} directly at each Orchestrator append use-site boundary. No wrapper around the provider; ADR-0019 keeps AiConfig as the reactive state provider.
  • Pass that explicit retention pair to all production writers that contribute to the shared #14163 heal-event ledger.
  • Add focused regression coverage proving systemic-circuit and freeze re-probe event classes retain under the same bounded policy without mutating the shared AiConfig singleton in tests.

Contract Ledger Matrix

Target Surface Source of Authority Behavior Fallback Evidence
Shared heal-event append retention policy AiConfig.orchestrator.recoveryActuator.healLedger + validateHealLedgerRetention() Every production writer to the shared heal-event ledger passes validated {maxEvents, triggerBytes} into appendHealEvent() from the Orchestrator use site. Invalid config fails at the AiConfig boundary before append; observability write failures remain non-gating where required. Focused unit tests prove circuit events and freeze re-probe event classes prune under the supplied policy.
Freeze re-probe and systemic-circuit ledger events runFreezeReprobe() / recordCircuitEvent contained-reopen, unfreeze, contained, and circuit events are retained under the same bounded policy as data-recovery attempts/outcomes. Event append remains best-effort and must not gate heal/unfreeze logic. Helper and Orchestrator unit regressions.

Decision Record impact

Aligned with ADR 0019. Runtime policy stays in AiConfig; Orchestrator reads provider leaves directly at use sites; pure helpers receive explicit values and do not re-read or own production defaults. Tests must not mutate the shared singleton.

Acceptance Criteria

  • All production heal-event append sites that contribute to the shared #14163 ledger arm bounded retention with the validated AiConfig {maxEvents, triggerBytes} pair, with no helper-owned production fallback.
  • Freeze re-probe events and systemic-circuit events cannot grow the shared heal-event ledger indefinitely when they are the only event class firing.
  • Focused unit coverage proves the retention-policy coverage regression.
  • #14272 remains release-unblocked; this is the consolidated follow-up lane owned by @neo-gpt.

Out of Scope

  • No new MCP tool.
  • No new retention leaf names.
  • No rewrite of #14272's self-heal snapshot envelope.
  • No runtime dataDir mutation contract change.
  • No split into multiple micro tickets.

Related

Related: #14163, #14272, #14039, #14128, #14179, #14166

Handoff Retrieval Hints: "PR #14272 heal-ledger retention follow-up"; "appendHealEvent retention policy omitted call sites"; "freeze re-probe heal-ledger retention".

tobiu referenced in commit d2d8848 - "fix(ai): seal heal-ledger retention (#14295) (#14296)" on Jun 28, 2026, 8:41 PM
tobiu closed this issue on Jun 28, 2026, 8:41 PM