fix(memory-core): treat dreaming fence marker lines as inside-fence in promotion guard (#80613)#83718
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 4, 2026, 3:55 PM ET / 19:55 UTC. Summary PR surface: Source +6, Tests +118. Total +124 across 2 files. Reproducibility: yes. Current main’s source shows marker lines are skipped before range-bound checks, and the added tests give a direct marker-only range plus a record/rank/apply path that would fail before the patch. Review metrics: none identified. Stored data model Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land the narrow guard change after normal required checks finish, keeping the rehydrate-time fence-overlap boundary instead of adding a second sanitizer or new configuration surface. Do we have a high-confidence way to reproduce the issue? Yes. Current main’s source shows marker lines are skipped before range-bound checks, and the added tests give a direct marker-only range plus a record/rank/apply path that would fail before the patch. Is this the best way to solve the issue? Yes. The existing guard already owns rehydrate-time managed-fence rejection, so treating marker lines as managed content there is narrower and cleaner than changing chunking, adding a broad sanitizer, or introducing policy/config. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against d5badb9e3604. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +6, Tests +118. Total +124 across 2 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
Review history (1 earlier review cycle)
|
f9fcc43 to
cf8981c
Compare
|
Thanks @clawsweeper. Addressed both findings:
Full local test run on rebased @clawsweeper re-review please. |
|
Heads up: this PR needs to be updated against current |
cf8981c to
ae8d61c
Compare
|
Maintainer validation is complete.
No remaining proof gaps. |
…n promotion guard The lineRangeOverlapsDreamingFence guard tracked insideFence state from the marker lines but did not flag ranges that included the marker lines themselves. A relocated promotion range that ended on a start marker, began on an end marker, or covered only a marker line passed the guard, and the snippet built from those raw lines carried the marker text into MEMORY.md. Treat marker lines as inside-fence content for range overlap purposes and add unit + integration coverage. The integration test exercises the real applyShortTermPromotions path: pre-patch a recall whose stored snippet is the start-marker text produces a 'Promoted From Short-Term Memory' entry containing the literal marker; post-patch the same input yields applied=0 and no MEMORY.md write. Refs openclaw#80613.
c66c664 to
820e818
Compare
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Merged via squash.
|
…n promotion guard (openclaw#83718) The lineRangeOverlapsDreamingFence guard tracked insideFence state from the marker lines but did not flag ranges that included the marker lines themselves. A relocated promotion range that ended on a start marker, began on an end marker, or covered only a marker line passed the guard, and the snippet built from those raw lines carried the marker text into MEMORY.md. Treat marker lines as inside-fence content for range overlap purposes and add unit + integration coverage. The integration test exercises the real applyShortTermPromotions path: pre-patch a recall whose stored snippet is the start-marker text produces a 'Promoted From Short-Term Memory' entry containing the literal marker; post-patch the same input yields applied=0 and no MEMORY.md write. Refs openclaw#80613.
Summary
lineRangeOverlapsDreamingFenceinextensions/memory-core/src/short-term-promotion.tstrackedinsideFencestate from the fence marker lines but never flagged ranges that included the marker lines themselves. A relocated promotion range that ended on a<!-- openclaw:dreaming:*:start -->line, began on a<!-- openclaw:dreaming:*:end -->line, or covered only a marker line passed the guard, and the snippet built from those raw lines carried the marker text intoMEMORY.md.<!-- openclaw:dreaming:*:start/end -->text, and (when the window straddles content on either side of the marker) the adjacent line. This is the residual edge case noted by ClawSweeper on fix(memory-core): redact managed dreaming blocks during promotion rehydration (#80613) #80702 ("the managed-block leak half is related but should be handled by a focused memory-core promotion fix"), narrowed to the guard itself rather than a parallel sanitizer.extensions/memory-core/src/short-term-promotion.ts: marker lines are now checked against the range bounds; if a marker is inside the relocated range, the range is rejected. The pre-existing inside-fence tracking remains so interior lines between a start/end pair are still flagged. The contract elsewhere — the contamination predicate, the relocator, the apply path, theMEMORY.mdwriter — is untouched.relocateCandidateRange,isContaminatedDreamingSnippet,applyShortTermPromotions,buildDailySnippetChunks,stripManagedDailyDreamingLines, the CJK dedupe path (the second sub-bug of [Bug]: dreaming pipeline leaks raw candidate content into MEMORY.md and CJK dedup is ineffective in tokenizeSnippet #80613 is being addressed separately by fix(memory-core): use CJK-aware tokenizer for dreaming dedupe (#80613) #80620), or anyMEMORY.mdrendering. No new sanitizer is introduced — this is a narrowing of the existing guard.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
Real behavior proof (required for external PRs)
lineRangeOverlapsDreamingFencenow flags relocated promotion ranges that include a dreaming fence marker line, preventing the marker text (and any adjacent fenced content captured by the same raw-line window) from being promoted intoMEMORY.md.pnpm test extensions/memory-core/src/short-term-promotion.test.ts -t "lineRangeOverlapsDreamingFence"— targeted run of the affected describe block.pnpm test extensions/memory-core/src/short-term-promotion.test.ts— full file regression.pnpm test extensions/memory-core/src/dreaming-phases.test.ts— adjacent file regression.pnpm format:check extensions/memory-core/src/short-term-promotion.ts extensions/memory-core/src/short-term-promotion.test.ts— format on changed files.pnpm lint extensions/memory-core/src/short-term-promotion.ts extensions/memory-core/src/short-term-promotion.test.ts— lint on changed files.pnpm tsgo:extensionsandpnpm tsgo:extensions:test— typecheck.expected false to be true, confirming that the pre-patch guard returnsfalsefor a range that includes only a marker line.mainunrelated to this PR.)<!-- openclaw:dreaming:*:start -->or<!-- openclaw:dreaming:*:end -->marker line. No regressions in the existinglineRangeOverlapsDreamingFencedescribe block or the broader test files.applyShortTermPromotionsthat drivesrelocateCandidateRangeto organically pick a marker-line-bordering window. Probe attempts on currentmaincould not construct an organic trigger — the relocator's compare/quality scoring rarely prefers such windows when cleaner alternatives exist in the file — so the demonstration is at the unit level. The repo-wide format/lint/build/CI suite was not run locally; the changed files pass all relevant lanes individually.