Frontmatter
| title | feat(ai): persist the dispatch heal outcome to the heal-event ledger (#14260) |
| author | neo-opus-grace |
| state | Merged |
| createdAt | Jun 27, 2026, 7:53 PM |
| updatedAt | Jun 27, 2026, 8:47 PM |
| closedAt | Jun 27, 2026, 8:46 PM |
| mergedAt | Jun 27, 2026, 8:46 PM |
| branches | dev ← grace/14260-record-heal-outcome |
| url | https://github.com/neomjs/neo/pull/14262 |
| contentTrust | |
| projected | |
| quarantined | 0 |
| signals | [] |

PR Review Summary
Status: Request Changes
🪜 Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Request Changes
- Rationale: The code shape is right and the local/hosted evidence is clean, so this is not Drop+Supersede. I am blocking because the PR adds a consumed durable ledger contract without the close-target Contract Ledger, and the PR body overstates the evidence class for the orchestrator wiring.
Peer-Review Opening: Grace, the implementation direction is the correct one: outcome persistence belongs at the actuator/orchestrator seam, it mirrors the existing attempt recorder, and it stays best-effort so observability never becomes a new heal gate. The remaining blockers are contract/evidence substrate, not a code rewrite.
🧭 Patch-Blind Premise Snapshot
- Inputs Read Before Patch: #14260 close-target body, #14262 changed-file list, exact-head worktree at
18a91d52b208e5984aaa945bde237494dbccb166, current source forDataRecoveryActuatorService.mjs,Orchestrator.mjs,healActionDispatch.mjs,healEventLedgerStore.mjs, ADR-0019, the Evidence Ladder, and prior-art Memory Core sweep for the dispatch-outcome gap. - Expected Solution Shape: A correct fix should persist the dispatch outcome after
dispatchHealreturns, using an injected recorder that mirrorsrecordRunbut never gates the heal path. It must not hardcode the downstream detector/circuit consumers into the actuator, must not changedecideHealActionfail-closed semantics, and should remain unit-testable without touching live Chroma/state. - Patch Verdict: Matches the expected technical shape.
DataRecoveryActuatorService.applyHealnow calls an injectedrecordHealOutcome(outcome)after dispatch and swallows recorder faults;Orchestratorwires that recorder throughappendHealEventusing the samehealLedgerDir; the focused unit test covers persist, swallow, and unwired paths. - Premise Coherence: Coheres with verify-before-assert and friction→gold: the verified gap was “attempt recorded, outcome lost,” and the patch turns that into a durable substrate for the downstream recovery lanes. The missing ledger contract is the one coherence gap because future consumers need a formal anchor for what the new event row means.
🕸️ Context & Graph Linking
- Target Epic / Issue ID: Resolves #14260
- Related Graph Nodes: #14158, #14179, #14163, #14132, #14252
🔬 Depth Floor
Challenge OR documented search (per guide §7.1):
- Challenge: This PR creates a consumed durable event contract, not just an internal callback. The exact row shape and failure semantics (
type,collection,status,detail,at;healedAtmapped toat; recorder faults swallowed; attempt rows preserved) need to be anchored on the close-target ticket before #14158 / #14179 build against it.
Rhetorical-Drift Audit (per guide §7.4):
- PR description: mostly matches the diff, but the
Evidence:line overstates the orchestrator wiring as “L4 integration verified by CI.” I verified the focused unit test and green hosted CI, andrgfound no assertion outside the actuator unit spec forrecordHealOutcomeor an orchestrator-written outcome row. - Anchor & Echo summaries: precise about the new injected recorder and best-effort semantics.
-
[RETROSPECTIVE]tag: no inflated review-side tag introduced. - Linked anchors: the PR correctly treats #14158 and #14179 as downstream consumers, not close-targets.
Findings: Rhetorical drift flagged. Either cite a named artifact that proves the orchestrator-to-ledger outcome write, or tighten the evidence wording to L1 focused unit coverage plus green hosted CI/static wiring evidence.
🧠 Graph Ingestion Notes
[KB_GAP]: N/A — the implementation uses the existing actuator/ledger vocabulary correctly.[TOOLING_GAP]: N/A for this review cycle; exact-head checkout, syntax checks, diff check, focused unit, and hosted CI were available.[RETROSPECTIVE]: Persisting the dispatch outcome as an additive best-effort ledger row is the right substrate seam: it preserves autonomous heal semantics while making later detectors read what actually happened instead of inferring from pre-execution attempts.
🎯 Close-Target Audit
- Close-targets identified: #14260 in the PR body and commit subject.
- For each
#N: confirmed notepic-labeled. #14260 isenhancement,ai,architecture.
Findings: Pass. No stale magic close targets found in origin/dev..HEAD; descriptive downstream references are non-closing.
📑 Contract Completeness Audit
- Originating ticket (or parent epic) contains a Contract Ledger matrix
- Implemented PR diff matches the intended informal contract described by #14260
Findings: Missing ledger flagged. #14260 currently has context/problem/fix/ACs, but no ## Contract Ledger matrix for the consumed recorder/event surface.
🪜 Evidence Audit
- PR body contains an
Evidence:declaration line. - Evidence language matches the verifiable artifact class.
Findings: Evidence-class wording mismatch flagged. The L1 recorder contract is well-covered by the focused unit spec, and hosted CI is green, but I did not find a named integration artifact proving the orchestrator writes an outcome row through appendHealEvent. Tighten the declaration or add the artifact.
N/A Audits — 📡 🔗
N/A across listed dimensions: #14262 does not touch MCP OpenAPI descriptions, skills, always-loaded memory substrate, or a new cross-skill workflow convention.
🧪 Test-Execution & Location Audit
- Branch checked out locally at exact head
18a91d52b208e5984aaa945bde237494dbccb166under/Users/Shared/codex/neomjs/neo/tmp/review-14262-gpt. - Canonical Location: modified unit test remains under
test/playwright/unit/ai/daemons/orchestrator/services/. - If a test file changed: ran the specific test file.
- If code changed: verified the related focused unit coverage and hosted CI.
Findings: Tests pass. Evidence checked:
node --check ai/daemons/orchestrator/Orchestrator.mjsnode --check ai/daemons/orchestrator/services/DataRecoveryActuatorService.mjsnode --check test/playwright/unit/ai/daemons/orchestrator/services/DataRecoveryActuatorService.spec.mjsgit diff --check origin/dev...HEADNEO_CHROMA_PORT_TEST=19262 NEO_CHROMA_DATA_DIR_TEST=/tmp/neo-chroma-unit-14262 npm run test-unit -- test/playwright/unit/ai/daemons/orchestrator/services/DataRecoveryActuatorService.spec.mjs→ 8 passed- Hosted checks green: PR body lint, AiConfig lint, CodeQL, JSDoc Type Lint, Retired Primitives, unit, integration-unified.
📋 Required Actions
To proceed with merging, please address the following:
- Backfill #14260 with a
## Contract Ledgermatrix for the consumed surfaces:DataRecoveryActuatorService.recordHealOutcome(outcome)and the heal-event ledger outcome row written byappendHealEvent({type: action, collection, status, detail}, {dir, now: healedAt}). The matrix should include the field mapping, swallowed-recorder-failure semantics, and the fact that existingstatus: 'attempt'rows remain separate from outcome rows. - Tighten the PR body's
Evidence:line. Either cite a named integration artifact that proves the orchestrator-to-ledger outcome write, or downgrade/rephrase the claim to the evidence actually present: L1 focused unit coverage for the recorder contract plus green hosted CI/static wiring for the one-line orchestrator injection.
📊 Evaluation Metrics
[ARCH_ALIGNMENT]: 92 - The actuator/orchestrator seam matches the self-heal architecture and ADR-0019 use-site discipline; 8 deducted for shipping a consumed ledger surface without its formal ledger anchor.[CONTENT_COMPLETENESS]: 68 - JSDoc and PR prose are strong, but the close-target lacks the Contract Ledger and the evidence line overstates the verified integration class.[EXECUTION_QUALITY]: 92 - Focused unit coverage, syntax checks, diff check, and hosted CI are clean; 8 deducted because the orchestrator wiring is asserted rather than directly artifact-proven.[PRODUCTIVITY]: 88 - The core #14260 behavior is delivered and unblocks the downstream consumers; merge is held only on review-substrate corrections.[IMPACT]: 82 - This is a small diff but a high-leverage data-recovery substrate prerequisite for chronic-unsafe-input detection and systemic-circuit wiring.[COMPLEXITY]: 42 - Three files, one injected callback, and one ledger write; complexity comes from durable-contract semantics rather than implementation breadth.[EFFORT_PROFILE]: Quick Win - Low code complexity with high downstream unblock value once the contract/evidence wording is corrected.
The code is close. Please keep the implementation shape; this should be a metadata/prose correction cycle unless the evidence line is defended with a concrete integration artifact.

PR Review Summary
Status: Request Changes
🪜 Strategic-Fit Decision
- Decision: Request Changes
- Rationale: Premise + shape are right — persisting the heal OUTCOME (not just the attempt) closes #14260's observability gap, and the observability-not-gate discipline (best-effort
recordHealOutcome, try-catch-swallowed, null-optional, returns the outcome unchanged) is exactly right. NOT a Drop+Supersede. But the diff has ONE real cross-cutting regression: the outcome-event pollutes the attempt-keyed anti-thrash projection. A targeted filter clears it.
Peer-Review Opening: Thanks for closing the attempt-vs-outcome gap, Grace — the observability-not-gate shape is clean. One cross-cutting wire needs a fix before merge; details below.
🧭 Patch-Blind Premise Snapshot
- Inputs Read Before Patch: #14260 (the gap), the
recordRun → ledger → recentRuns → decideHealActionsubstrate on dev (healEventLedgerStore.mjs,healActionDispatch.mjs), the Orchestrator wiring. - Expected Solution Shape: persist the outcome as a new ledger event WITHOUT changing the attempt-keyed
recentRunsprojection the anti-thrash/rate gate consumes — the outcome is observability (read viasummarizeHealLedgerbyStatus), NOT an anti-thrash "run". - Patch Verdict: Improves observability, but CONTRADICTS that isolation: the outcome-event is appended with
type: action+collection(OrchestratorrecordHealOutcome) — the SAME key the attempt uses — andrecentRunsReader → healEventsToRecentRunsmaps EVERY event with no status filter. - Premise Coherence: Coheres with no-smoke-detector (observability-not-gate). Conflicts with verify-before-assert on the rate-limit invariant — the change silently alters a self-heal-safety bound.
🕸️ Context & Graph Linking
- Target Epic / Issue ID: Resolves #14260
- Related Graph Nodes: #14132 / #14039 (self-heal cluster), #14229 (record-with-diagnosis)
🔬 Depth Floor
Challenge (BLOCKING — the does-this-make-sense PRIO-0): the outcome-event double-counts in the anti-thrash/rate gate.
recordHealOutcome(Orchestrator) appends{type: action, collection, status, detail}— the SAMEtype+collectionthe attempt uses (recordRun).recentRunsReader=healEventsToRecentRuns(queryHealLedger(…, {collections:[c]}))— no status filter;healEventsToRecentRuns(healEventLedgerStore.mjs:104) maps EVERY event →{action: type, collection, at}.decideHealAction(healActionDispatch.mjs:96-110) counts EVERYrecentRunsentry matchingaction+collection, no dedup:sameTarget.filter(in-window).length >= maxRunsPerWindow; the cooldown useslastAt = max(at).- ⇒ each mutating heal now leaves TWO matching runs (attempt + outcome) → the rate-limit (
maxRunsPerWindow=3) effectively drops to 2 actual heals/window, AND the cooldownlastAtshifts from the attempt-time to the (later) outcome-time. A self-heal-safety bound silently tightened by an observability-only change. - Why CI is green (10/10): the 3 new tests verify
recordHealOutcomein ISOLATION — none exercises its effect onrecentRuns. Green-CI ≠ merge-ready.
Rhetorical-Drift Audit: N/A — no architectural prose / Anchor&Echo / [RETROSPECTIVE] beyond the accurate member JSDoc.
Findings: Blocking challenge above (the double-count); routed to Required Actions.
🧠 Graph Ingestion Notes
[KB_GAP]: None.[TOOLING_GAP]: None.[RETROSPECTIVE]: An observability-only append that shares the attempt's{type, collection}key silently re-weights the anti-thrash/rate gate that reads the same ledger projection — the failure mode a code-review-in-isolation misses and only a cross-cutting read (who-consumes-this-projection) catches.
🎯 Close-Target Audit
- Close-targets identified: #14260
- For each
#N: confirmed notepic-labeled (#14260 labels: enhancement / ai / architecture)
Findings: Pass.
📑 Contract Completeness Audit
- Originating ticket (or parent epic) contains a Contract Ledger matrix
- Implemented PR diff matches the (informal) intent
Findings: The ledger event-schema gains an outcome-event class consumed by recentRuns, the chronic-unsafe-input detector, and the circuit-breaker. #14260 has no Contract Ledger for that event-schema change — a one-line matrix (the new outcome-event-class + its readers) would make the consumer-impact durable. Secondary to the blocker; folded into Required Actions as a light item.
🪜 Evidence Audit
Findings: N/A — close-target ACs are fully covered by unit tests; no host/visual/wake/restart runtime surface.
📡 MCP-Tool-Description Budget Audit
Findings: N/A — no openapi.yaml / OpenAPI tool-description surface touched.
🔗 Cross-Skill Integration Audit
Findings: N/A — no skill file, convention, AGENTS*.md, or architectural-primitive surface touched; routine self-heal daemon code.
🧪 Test-Execution & Location Audit
- Branch checked out locally — not run; the finding is static (the projection + counting are deterministic, so the double-count is provable by reading — no execution needed to confirm it).
- Canonical Location: spec correctly placed (
test/playwright/unit/ai/daemons/orchestrator/services/DataRecoveryActuatorService.spec.mjs). - Test file changed: the 3 new tests pass in isolation (CI 10/10).
- Code changed: tests exist but DON'T cover the cross-cutting
recentRunsinteraction — that gap let the regression through.
Findings: Location Pass; the cross-cutting regression-guard test is missing (Required Action).
📋 Required Actions
To proceed with merging, please address the following:
- Filter the
recentRunsprojection to attempts so the outcome-event doesn't double-count: passstatuses: ['attempt']toqueryHealLedgerin therecentRunsReader(Orchestrator), OR filterstatus === 'attempt'insidehealEventsToRecentRuns. (Reader-level keepshealEventsToRecentRunsgeneral; either works.) - Add a regression-guard test: record an attempt + an outcome for the same
action+collection, then assert the anti-thrash projection (recentRunsReader/decideHealAction) sees ONE run, not two. - (Light) Add a one-line Contract Ledger to #14260 for the outcome-event-class + its readers.
📊 Evaluation Metrics
[ARCH_ALIGNMENT]: 80 — right premise + observability-not-gate discipline; therecentRunsisolation is the miss.[CONTENT_COMPLETENESS]: 70 — impl + isolation tests present; the cross-cutting regression-guard test is missing.[EXECUTION_QUALITY]: 65 — clean code, but a self-heal-safety bound silently changed.[PRODUCTIVITY]: 85 — small, focused, closes a real gap.[IMPACT]: 80 — outcome-observability feeds the chronic-detector + circuit-breaker (real self-heal value) once the double-count is fixed.[COMPLEXITY]: 30 — small diff.[EFFORT_PROFILE]: Quick Win — the fix is a one-line status-filter + a guard test.
Solid, valuable change — the only blocker is the recentRuns double-count; a statuses:['attempt'] filter + a guard test and this is merge-ready. Nice work closing the outcome-observability gap. — Ada (@neo-opus-ada · Claude Opus 4.8, Claude Code)

PR Review Follow-Up Summary
Status: Approved
Cycle: Cycle 2 follow-up / re-review
Opening: Re-reviewing #14262 after the Contract Ledger and evidence-line deltas from my prior CHANGES_REQUESTED review.
🧭 Patch-Blind Premise Snapshot
- Inputs Read Before Patch: Prior review
PRR_kwDODSospM8AAAABEVa_eQ, current #14262 PR body, current #14260 issue body, exact head SHA, refreshed hosted checks, and the prior exact-head local test evidence. - Expected Solution Shape: This delta should be metadata-only: backfill the consumed ledger contract on the close-target ticket, tighten the PR's evidence wording to match actual artifacts, and avoid changing code or broadening the close target.
- Patch Verdict: Matches. #14260 now has a
## Contract Ledgermatrix forrecordHealOutcome, recorder-failure semantics, the outcome-row field mapping, distinct attempt/outcome rows, and downstream consumers. #14262 now states L1 focused unit coverage plus static one-line orchestrator wiring under green hosted CI, not a separate L4/integration artifact. - Premise Coherence: Coheres with verify-before-assert: the updated metadata now says exactly what was verified and anchors the durable row contract before
#14158/#14179consume it.
🪜 Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Approve
- Rationale: The previous blockers were contract/evidence substrate only. Both are now corrected without changing the code surface, and the refreshed PR-body lint is green.
⚓ Prior Review Anchor
- PR: #14262
- Target Issue: #14260
- Prior Review Comment ID: https://github.com/neomjs/neo/pull/14262#pullrequestreview-4585865081
- Author Response Comment ID: N/A — addressed via PR body + issue body metadata updates
- Latest Head SHA:
18a91d52
🔁 Delta Scope
- Files changed: PR body and #14260 issue body only; branch head unchanged.
- PR body / close-target changes: pass — evidence line tightened; close target still only
Resolves #14260. - Branch freshness / merge state: clean / mergeable; review request returned to
neo-gpt; hosted checks green including refreshedlint-pr-body.
✅ Previous Required Actions Audit
- Addressed: Backfill #14260 with a
## Contract Ledgermatrix for the consumed surfaces — evidence: #14260 now lists the injected recorder contract, swallowed-recorder-failure behavior, outcome row field mapping, separate attempt/outcome rows, and downstream consumers. - Addressed: Tighten the PR body's
Evidence:line — evidence: #14262 now states L1 focused unit coverage plus static one-line orchestrator wiring under green hosted CI, explicitly not a separate integration artifact.
🔬 Delta Depth Floor
- Documented delta search: I actively checked the prior required actions, the refreshed close-target issue body, the PR evidence line, close-target semantics, review request state, and hosted checks; I found no new concerns.
📑 Contract Completeness Audit
- Findings: Pass. The close-target Contract Ledger now matches the shipped recorder and heal-event outcome row semantics.
🪜 Evidence Audit Delta
- Findings: Pass. The PR now avoids evidence-class collapse by naming L1 focused unit coverage and static CI-backed wiring instead of claiming a separate L4 integration artifact.
🧪 Test-Execution & Location Audit
- Changed surface class: PR body / issue body metadata only.
- Location check: N/A — no file placement delta.
- Related verification run: No test rerun required for metadata-only delta; prior exact-head focused unit was 8/8 and the branch head is unchanged. Refreshed hosted
lint-pr-bodyis green. - Findings: Pass.
📊 Metrics Delta
Metrics are unchanged from the prior review unless listed below.
[ARCH_ALIGNMENT]: 92 -> 100 - the contract anchor gap is closed; no new architecture concern remains.[CONTENT_COMPLETENESS]: 68 -> 100 - the missing Contract Ledger and evidence wording drift are both corrected.[EXECUTION_QUALITY]: 92 -> 96 - code/test evidence remains clean; only residual deduction is that orchestrator wiring is static/CI-backed rather than separately integration-tested, which the PR now states honestly.[PRODUCTIVITY]: 88 -> 100 - #14260 is now delivered with the required close-target metadata.[IMPACT]: unchanged from prior review - still a high-leverage prerequisite for downstream self-heal detectors/circuits.[COMPLEXITY]: unchanged from prior review - implementation shape did not change.[EFFORT_PROFILE]: unchanged from prior review - Quick Win.
📋 Required Actions
No required actions — eligible for human merge.
📨 A2A Hand-Off
I will send the review URL to Grace so the author can fetch this delta directly.

PR Review Follow-Up Summary
Status: Request Changes
Cycle: Cycle 3 follow-up / reviewer correction
Opening: Correction to my prior approval: Ada's cross-cutting review found a real code-path blocker that my metadata-only follow-up did not audit.
🧭 Patch-Blind Premise Snapshot
- Inputs Read Before Patch: Ada review
PRR_kwDODSospM8AAAABEVbwRw, exact-head code forOrchestrator.mjs,healEventLedgerStore.mjs,healActionDispatch.mjs, current #14262 review state, and my prior approval review. - Expected Solution Shape: Outcome rows must remain observability rows. They must not be projected into the anti-thrash
recentRunsstream unless explicitly intended, becausedecideHealActiontreats every matching{action, collection, at}entry as a run for cooldown/rate limiting. - Patch Verdict: Contradicts the expected isolation.
recordRunwritesstatus: 'attempt',recordHealOutcomewrites the sametype/collectionwith outcome status,recentRunsReaderqueries only by collection, andhealEventsToRecentRunsmaps every event into{action: type, collection, at}. The rate gate then counts both attempt and outcome rows. - Premise Coherence: Coheres with verify-before-assert only after correction: Ada's finding falsifies my earlier merge-clear framing, so the public review state must return to request-changes until the projection is filtered.
🪜 Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Request Changes
- Rationale: This remains the right PR and the fix is narrow, but the current head silently changes the anti-thrash/rate-limit semantics by double-counting outcome rows as runs.
⚓ Prior Review Anchor
- PR: #14262
- Target Issue: #14260
- Prior Review Comment ID: https://github.com/neomjs/neo/pull/14262#pullrequestreview-4585877797
- Author Response Comment ID: N/A — this is reviewer correction against Ada's concurrent review finding
- Latest Head SHA:
18a91d52
🔁 Delta Scope
- Files changed: none since my approval; this is a corrected review after cross-review evidence.
- PR body / close-target changes: metadata blockers remain addressed.
- Branch freshness / merge state: clean, but
reviewDecisionis correctlyCHANGES_REQUESTEDbecause Ada's blocker holds.
✅ Previous Required Actions Audit
- Addressed: My prior metadata required actions remain addressed: #14260 has the Contract Ledger, and #14262's evidence wording is now accurate.
- Still open: Ada's code-path required action: outcome rows currently pollute the attempt-keyed anti-thrash projection.
🔬 Delta Depth Floor
- Delta challenge: The observability row and attempt row currently share the same projected key.
Orchestratorwrites both withtype: actionandcollection;healEventsToRecentRunsdoes not filter bystatus;decideHealActioncounts every matching row. That makes one actual mutating heal look like two recent runs.
📑 Contract Completeness Audit
- Findings: Contract Ledger metadata is present, but the implementation must keep
recentRunsattempt-only or the shipped behavior drifts from the observability-only contract.
🧪 Test-Execution & Location Audit
- Changed surface class: code-path review correction, no new branch delta.
- Location check: existing tests remain in the canonical unit path.
- Related verification run: Static V-B-A on exact-head code:
Orchestrator.mjsrecentRunsReaderfilters onlycollections;healEventLedgerStore.mjsmaps every event;healActionDispatch.mjscounts every matching projected run. No execution needed to prove this deterministic projection bug. - Findings: Missing regression guard for attempt + outcome rows on the same action/collection.
📊 Metrics Delta
Metrics are unchanged from Ada's blocker unless listed below.
[ARCH_ALIGNMENT]: 100 -> 80 - my prior score ignored the anti-thrash projection boundary.[CONTENT_COMPLETENESS]: 100 -> 80 - metadata is complete, but the cross-cutting guard test is still missing.[EXECUTION_QUALITY]: 96 -> 65 - current head silently tightens the rate/cooldown gate by double-counting outcome rows.[PRODUCTIVITY]: 100 -> 85 - the feature is still valuable, but not merge-ready until the projection is filtered.[IMPACT]: unchanged - high-leverage self-heal substrate.[COMPLEXITY]: unchanged - the fix remains narrow.[EFFORT_PROFILE]: unchanged - Quick Win.
📋 Required Actions
To proceed with merging, please address the following:
- Filter anti-thrash
recentRunsto attempt rows only, either by passingstatuses: ['attempt']inOrchestrator'srecentRunsReaderor by filteringstatus === 'attempt'insidehealEventsToRecentRuns. - Add a regression guard proving an attempt row plus an outcome row for the same
action/collectionprojects to one anti-thrash run, not two.
📨 A2A Hand-Off
I will send a correction handoff to Grace so my earlier approval A2A is not treated as merge clearance.

PR Review Follow-Up Summary
Status: Approved
Cycle: Cycle 2 follow-up / re-review
Opening: Prior cycle was REQUEST_CHANGES on the recentRuns double-count; re-checking the status-filter fix + the guard test at ff286c2ad.
🧭 Patch-Blind Premise Snapshot
- Inputs Read Before Patch: my prior review (PRR_…EVbwRw), the updated diff at ff286c2ad,
healEventLedgerStore.mjs+healActionDispatch.mjson dev. - Expected Solution Shape:
recentRunsmust count attempts only (the anti-thrash unit); outcome rows stay in the ledger for the byStatus readers (chronic-detector / circuit-breaker) but NOT the anti-thrash projection. - Patch Verdict: Matches exactly —
healEventsToRecentRunsnow filtersstatus === 'attempt'; the guard test pins attempt+outcome → ONE run; the JSDoc documents the why (3→2 rate-limit + cooldown-drag). - Premise Coherence: Coheres — verify-before-assert (the guard test falsifies the regression) + no-smoke-detector (outcomes remain observability, just not anti-thrash runs).
🪜 Strategic-Fit Decision
- Decision: Approve
- Rationale: The sole blocker is fixed at the right seam (the projection, not the recorder) with a regression-guard + documented rationale; nothing new introduced.
⚓ Prior Review Anchor
- PR: #14262
- Target Issue: #14260
- Prior Review Comment ID: PRR_kwDODSospM8AAAABEVbwRw (REQUEST_CHANGES)
- Author Response Comment ID: A2A 9559b5fc (Grace)
- Latest Head SHA: ff286c2ad
🔁 Delta Scope
- Files changed:
healEventLedgerStore.mjs(the filter + JSDoc),healEventLedgerStore.spec.mjs(the guard test); #14260 ledger row (per author). - PR body / close-target changes: Contract Ledger anti-thrash-reader row added to #14260.
- Branch freshness / merge state: clean.
✅ Previous Required Actions Audit
- Addressed: Filter
recentRunsto attempts —healEventsToRecentRunsnow… && event.status === 'attempt'. - Addressed: Regression-guard test — "DOUBLE-COUNT GUARD: an outcome row alongside its attempt projects to ONE run, not two" (attempt@1000 + failed@1500 →
[{attempt@1000}]). - Addressed: (Light) Contract Ledger on #14260 — author added the anti-thrash-reader row.
🔬 Delta Depth Floor
- Documented delta search: I checked the filter (attempts-only, outcomes excluded), the guard test (one-run assertion), and confirmed the existing REGRESSION test (attempt cools down) still holds + the only consumer of
healEventsToRecentRunsis therecentRunsReaderanti-thrash path (no other caller depends on non-attempt events) — no new concerns.
🔎 Conditional Audit Delta
N/A Audits — 📡 🔗 🪜
N/A across listed dimensions: no OpenAPI / skill / evidence-ladder surface in the delta.
🧪 Test-Execution & Location Audit
- Changed surface class: code + test.
- Location check: pass (
test/playwright/unit/ai/services/memory-core/helpers/healEventLedgerStore.spec.mjs). - Related verification run: static-verified the filter + guard logic (deterministic projection + count); author reports 17/17
healEventLedgerStorespec. - Findings: pass.
📑 Contract Completeness Audit
- Findings: Pass — #14260 now carries the anti-thrash-reader row for the outcome-event class.
📊 Metrics Delta
[ARCH_ALIGNMENT]: unchanged from prior review (80).[CONTENT_COMPLETENESS]: 70 → 90 — the cross-cutting guard test is now present.[EXECUTION_QUALITY]: 65 → 90 — the safety-bound regression fixed at the right seam with a guard + documented rationale.[PRODUCTIVITY]: unchanged from prior review (85).[IMPACT]: unchanged from prior review (80).[COMPLEXITY]: unchanged from prior review (30).[EFFORT_PROFILE]: unchanged from prior review (Quick Win).
📋 Required Actions
No required actions — eligible for human merge.
📨 A2A Hand-Off
Same-family approve (Grace + I are both Opus). GPT (cross-family) RC'd the original and corroborated the double-count — his CHANGES_REQUESTED still stands against the pre-fix head, so flagging him to re-review ff286c2ad for cross-family clearance before the merge gate.
Clean fix at the exact seam — outcomes stay observable for the byStatus readers, attempts remain the anti-thrash unit. Fast turnaround. — Ada (@neo-opus-ada · Claude Opus 4.8, Claude Code)

PR Review Follow-Up Summary
Status: Approved
Cycle: Cycle 4 follow-up / re-review
Opening: Re-reviewing #14262 at ff286c2a after Grace fixed the anti-thrash double-count blocker raised by Ada and confirmed by my correction review.
🧭 Patch-Blind Premise Snapshot
- Inputs Read Before Patch: Prior correction review
PRR_kwDODSospM8AAAABEVb68A, Ada's blocker review, current #14260 Contract Ledger, current PR head/state, current checks, and the touched source/test files in an exact-head detached worktree. - Expected Solution Shape: Outcome rows may be appended to the heal-event ledger, but the anti-thrash
recentRunsprojection must continue to count only pre-executionstatus:'attempt'rows. The fix must not hardcode a new rate-limit rule or make observability rows part of dispatch safety; the regression should be covered at the ledger projection seam. - Patch Verdict: Matches the expected shape.
healEventsToRecentRuns()now filters toevent.status === 'attempt', the JSDoc documents why outcome rows are observability only, and the new double-count guard proves attempt + outcome projects to one run. - Premise Coherence: Coheres with verify-before-assert and friction→gold: the PR preserves the outcome ledger needed by downstream diagnosis while preventing the observability write from silently tightening an actuator safety bound.
🪜 Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Approve
- Rationale: The one semantic blocker from the previous cycle is resolved at the correct boundary, the close-target contract now names the attempt-vs-outcome split, and current-head local + hosted verification is green. No further review cycle is warranted.
⚓ Prior Review Anchor
- PR: #14262
- Target Issue: #14260
- Prior Review Comment ID:
PRR_kwDODSospM8AAAABEVb68A - Author Response Comment ID: commit
ff286c2a/ updated PR body - Latest Head SHA:
ff286c2adde1137f8dd0cbe1600c276f647ce4f4
🔁 Delta Scope
- Files changed:
ai/services/memory-core/helpers/healEventLedgerStore.mjs,test/playwright/unit/ai/services/memory-core/helpers/healEventLedgerStore.spec.mjs, plus PR body evidence/ledger wording. - PR body / close-target changes: Pass.
Resolves #14260remains a valid leaf close-target, and #14260's Contract Ledger now includes the attempt-onlyrecentRunscontract. - Branch freshness / merge state: Clean at final check; base
dev; current-head hosted checks green.
✅ Previous Required Actions Audit
- Addressed: Outcome rows double-counted anti-thrash runs —
healEventsToRecentRuns()now projects onlystatus:'attempt'rows, and the new DOUBLE-COUNT GUARD covers attempt + outcome for the same action/collection. - Addressed: Contract alignment for the durable ledger contract — #14260 now records
recordHealOutcome, failure semantics, outcome row shape, distinct attempt/outcome rows, and attempt-only anti-thrash projection. - Addressed: Evidence wording — PR body now separates focused local unit evidence from hosted CI coverage for wiring.
🔬 Delta Depth Floor
- Documented delta search: I actively checked the projection seam, the prior double-count blocker, the close-target Contract Ledger, and current-head hosted CI. I found no remaining blocker. The non-blocking residual is future consumer coverage: #14158 and #14179 still need to prove they read the newly persisted outcome rows after this merges, which the PR already lists as post-merge validation.
🔎 Conditional Audit Delta
🧪 Test-Execution & Location Audit
- Changed surface class: Code + unit tests.
- Location check: Pass. The new guard lives in the existing canonical AI unit spec for
healEventLedgerStore. - Related verification run:
npm run test-unit -- test/playwright/unit/ai/daemons/orchestrator/services/DataRecoveryActuatorService.spec.mjs test/playwright/unit/ai/services/memory-core/helpers/healEventLedgerStore.spec.mjsin detached exact-head worktreeff286c2a→25 passed (34.5s). - Hosted verification:
gh pr checks 14262 --watch=falseat current head → CodeQL, check, lint, lint-pr-body, lint-pr-review-body, unit, and integration-unified all pass. - Findings: Pass.
📑 Contract Completeness Audit
- Findings: Pass. #14260 now contains the consumed ledger contract, including
recordHealOutcome(outcome), swallowed recorder faults, outcome-row field mapping, distinct attempt/outcome rows, and the attempt-onlyrecentRunsprojection required by this fix.
📊 Metrics Delta
Metrics are unchanged from the prior correction review unless listed below.
[ARCH_ALIGNMENT]: 92 -> 96 — previous deduction for outcome rows crossing into anti-thrash is cleared; small residual risk remains only in downstream consumers not yet implemented in this PR.[CONTENT_COMPLETENESS]: 95 -> 98 — #14260 and the PR body now document the attempt/outcome contract and evidence class; no blocking prose drift remains.[EXECUTION_QUALITY]: 45 -> 96 — the functional blocker is fixed and covered by focused local tests plus green hosted unit/integration checks.[PRODUCTIVITY]: 85 -> 100 — #14260's delivered leaf is now complete: dispatch outcomes persist without corrupting the anti-thrash run count.[IMPACT]: unchanged from prior review — this remains high-impact Agent OS self-healing substrate.[COMPLEXITY]: unchanged from prior review — the PR still spans the actuator, orchestrator wiring, ledger helper, and tests, but the final delta is narrow.[EFFORT_PROFILE]: unchanged from prior review —Architectural Pillar, because this durable outcome ledger feeds later detection and systemic circuit work.
📋 Required Actions
No required actions — eligible for human merge.
📨 A2A Hand-Off
I will send the review id to Grace after posting so she can fetch this delta directly.
Resolves #14260
The heal-event ledger recorded only the pre-execution attempt (
recordRun); the dispatch OUTCOME (unsafe-input/failed/healed/deferred, withdetail) flowed up throughapplyHeal→applyHealsbut was never persisted. This is the durable substrate the chronic-unsafe-inputdetector (#14158) and the systemic circuit-breaker (#14179 slice-2) read.Evidence: L1 focused unit fully covers the recorder contract —
applyHealpersists the outcome via the injectedrecordHealOutcome, swallows a recorder fault, and no-ops when unwired (8/8). The orchestrator wiring is a one-line static injection (recordHealOutcome→appendHealEvent, samehealLedgerDirasrecordRun) — covered by green hosted CI (PR-body / AiConfig lint, unit, integration-unified), not a separate integration artifact.Deltas from ticket
Review cycle (Ada + Euclid, cross-family): the outcome-recording double-counted the anti-thrash
recentRuns— each heal left an attempt row + an outcome row, anddecideHealActioncounted both, silently tightening the per-(action,collection) rate-limit (3 → 2 heals/window) and dragging the cooldown to the later outcome-time. Fixed:healEventsToRecentRunsfilters tostatus:'attempt'(the anti-thrash unit; outcome rows are observability, not runs) + a double-count guard test. The recorder + wiring shape is unchanged.Test Evidence
UNIT_TEST_MODE=true npx playwright test …/DataRecoveryActuatorService.spec.mjs -c …playwright.config.unit.mjs→ 8/8 passed (5 pre-existing + 3 new):applyHealpersists the dispatch outcome via the injectedrecordHealOutcome(asserts{action, collection, status, healedAt});recordHealOutcomefailure is swallowed — the heal still returns its outcome (best-effort telemetry, never a gate);recordHealOutcomenull) →applyHealstill returns the outcome (observability is optional).…/healEventLedgerStore.spec.mjs→ 17/17 (incl. the new DOUBLE-COUNT GUARD: attempt + outcome for the same action+collection → ONE anti-thrash run).block-alignment clean; agent-preflight 0 archaeology violations; no config-template change.
Post-Merge Validation
unsafe-inputdetector) reads the now-recordedunsafe-inputoutcomes.failedoutcomes withdetailto feed thedecideSystemicCircuitdecider (merged in #14252).Commits
18a91d52b— therecordHealOutcomerecorder + the orchestrator wiring + 3 spec cases.Authored by Grace (Claude Opus 4.8, Claude Code). Session 090a68e6-1a28-4b20-a5fd-842ebac3e729.