feat(memory): add outcome normalization to dreaming events#97705
feat(memory): add outcome normalization to dreaming events#97705lg320531124 wants to merge 5 commits into
Conversation
Add MemoryDreamOutcome type (completed|partial|failed|timed_out) and optional outcome/error fields to MemoryHostDreamCompletedEvent so downstream consumers can distinguish failed from successful dreaming runs without parsing log text. - src/memory-host-sdk/events.ts: add type + event fields - extensions/memory-core/src/dreaming-markdown.ts: pass through outcome/error to event emissions - extensions/memory-core/src/dreaming.ts: emit failed event in deep-dreaming catch block Backward compatible: outcome is optional; missing treated as completed. Closes openclaw#97690
|
Codex review: needs real behavior proof before merge. Reviewed June 29, 2026, 4:09 AM ET / 08:09 UTC. Summary PR surface: Source +40, Tests +68. Total +108 across 4 files. Reproducibility: yes. at source level: current main and v2026.6.10 lack outcome/error fields on dream completion events, and the deep failure path only logs. I did not run a live dreaming timeout or failed-run scenario in this read-only review. Review metrics: 2 noteworthy metrics.
Stored data model Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Risk before merge
Maintainer options:
Next step before merge
Security Review findings
Review detailsBest possible solution: Land an additive, maintainer-approved dreaming outcome contract that preserves existing readers, classifies completed/partial/failed/timed_out correctly, and includes redacted real failed-run event-log proof. Do we have a high-confidence way to reproduce the issue? Yes, at source level: current main and v2026.6.10 lack outcome/error fields on dream completion events, and the deep failure path only logs. I did not run a live dreaming timeout or failed-run scenario in this read-only review. Is this the best way to solve the issue? No, not yet: the additive event direction is plausible, but the latest head still conflates partial side effects with failed completion and needs maintainer-approved taxonomy plus real behavior proof. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 96c8338d5bfa. Label changesLabel justifications:
Evidence reviewedPR surface: Source +40, Tests +68. Total +108 across 4 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
sweepNowMs is declared inside the try block, so the catch block cannot reference it. Use Date.now() instead — precise timestamp alignment is not important for failure events.
ClawSweeper P2: appendMemoryHostEvent in the catch block can itself throw (mkdir/appendRegularFile), which would reject the whole dreaming trigger and skip later workspaces. Wrap in try/catch so diagnostic logging is best-effort.
|
Addressed the P2 finding in 367fbea. The This follows the codebase's existing best-effort convention for diagnostic writes — a failed event append should never turn a caught workspace failure into a trigger rejection that skips later workspaces. |
Tests for: - Successful dream events omit outcome (backward compatible) - Failed dream events record outcome and error fields - Partial outcome on deep dreaming events
|
@vincentkoc 👋 This PR adds outcome normalization ( |
|
Closing in favor of #97723, which was merged and covers the same ground — Thanks @vincentkoc / @steipete — happy to see this land. Keeping an eye on #97692 (crash-recovery design) for the |
What Problem This Solves
Dreaming phase events (
memory.dream.completed) currently have no structured way to indicate whether a run succeeded or failed. When a deep-dreaming workspace fails, the error is only logged to console — not recorded in the JSONL event log. Downstream consumers (monitoring, dashboards, alerting) cannot distinguish successful from failed dreaming runs without parsing log text.Issue: #97690
Why This Change Was Made
Agent runs have normalized terminal outcomes via
agent-run-terminal-outcome.ts(7 reasons: completed, hard_timeout, timed_out, cancelled, aborted, blocked, failed). Dreaming events lack an equivalent — this is a gap in observability.The
MemoryDreamOutcometype follows the same normalization pattern with 4 states relevant to dreaming:completed,partial,failed,timed_out.User Impact
outcome: "failed"and anerrorfieldmemory.dream.completedevents and filter by outcome without parsing logsEvidence
Type-check
Unit tests (6/6 passed)
Dreaming markdown tests (9/9 passed)
Backward compatibility
The
outcomefield is optional onMemoryHostDreamCompletedEvent. Existing event consumers that don't check for it continue to work unchanged. The JSDoc comment documents the backward-compatible default: "treat missing as completed".ClawSweeper P2 fix
The failure-event append in the catch block (
dreaming.ts:705) is wrapped in its own try/catch so diagnostic event-log writes cannot turn a caught workspace failure into a rejected trigger that skips later workspaces.Files changed
src/memory-host-sdk/events.ts— AddedMemoryDreamOutcometype andoutcome/errorfields to event typeextensions/memory-core/src/dreaming-markdown.ts— Pass throughoutcome/errorparams to event emissionsextensions/memory-core/src/dreaming.ts— Emitmemory.dream.completedwithoutcome: "failed"in the deep-dreaming catch block (guarded)extensions/memory-core/src/memory-events.test.ts— Added 3 tests for outcome normalization (implicit success, failed with error, partial)