Skip to content

Commit 0766319

Browse files
test(memory-core): exercise fuzzy-window straddle path for #80613
Address ClawSweeper P3 on PR #80702: the existing integration test recorded the recall snippet at the exact human bullet line, so relocateCandidateRange always took the exact-match path and never exercised the fuzzy window search that originally latched onto the managed-block straddle window in #80613. Add a regression that records a clean-leading multi-line straddle snippet at a stale 20..30 range, forcing rehydration through the fuzzy window search. Verified the new test FAILS without redactManagedDreaming Lines (MEMORY.md receives '- - Plan switches use exRule, not abConfig ## Light Sleep <!-- openclaw:dreaming:light:start --> - Candidate: ... - status: staged <!-- openclaw:dreaming:light:end -->' verbatim) and PASSES with the sanitizer in place. All 88 tests across short-term-promotion and dreaming-phases pass. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 9325311 commit 0766319

1 file changed

Lines changed: 80 additions & 0 deletions

File tree

extensions/memory-core/src/short-term-promotion.test.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,6 +1301,86 @@ describe("short-term promotion", () => {
13011301
});
13021302
});
13031303

1304+
it("blocks fuzzy-window straddle leaks when the recorded range no longer matches the daily note (#80613)", async () => {
1305+
await withTempWorkspace(async (workspaceDir) => {
1306+
// Daily note: human bullet, then a managed Light Sleep dreaming block that follows it
1307+
// directly. Lines 1-11 below; the dreaming block is lines 4-11 (heading + start..end markers
1308+
// + four staged scaffolding lines).
1309+
await writeDailyMemoryNote(workspaceDir, "2026-04-13", [
1310+
"## Plan toggle field",
1311+
"- Plan switches use exRule, not abConfig",
1312+
"",
1313+
"## Light Sleep",
1314+
"<!-- openclaw:dreaming:light:start -->",
1315+
"- Candidate: Plan toggle field summary",
1316+
" - confidence: 0.00",
1317+
" - evidence: memory/.dreams/session-corpus/2026-04-13.txt:1-3",
1318+
" - recalls: 0",
1319+
" - status: staged",
1320+
"<!-- openclaw:dreaming:light:end -->",
1321+
]);
1322+
1323+
// Stored snippet captures the same multi-line straddle a stale recall would have held
1324+
// (human bullet immediately followed by the managed-block heading and dreaming bullets).
1325+
// It starts with the human bullet, so isContaminatedDreamingSnippet does not flag it
1326+
// (no leading `Candidate:` after the leading-prefix consumer), and we deliberately point
1327+
// startLine/endLine at a stale range past the file's tail so relocateCandidateRange must
1328+
// skip the exact-match path and fall through to the fuzzy window search that originally
1329+
// latched onto the straddle window in #80613.
1330+
const straddleSnippet = [
1331+
"- Plan switches use exRule, not abConfig",
1332+
"## Light Sleep",
1333+
"<!-- openclaw:dreaming:light:start -->",
1334+
"- Candidate: Plan toggle field summary",
1335+
" - confidence: 0.00",
1336+
" - evidence: memory/.dreams/session-corpus/2026-04-13.txt:1-3",
1337+
" - recalls: 0",
1338+
" - status: staged",
1339+
"<!-- openclaw:dreaming:light:end -->",
1340+
].join("\n");
1341+
1342+
await recordShortTermRecalls({
1343+
workspaceDir,
1344+
query: "plan toggle field straddle",
1345+
results: [
1346+
{
1347+
path: "memory/2026-04-13.md",
1348+
startLine: 20,
1349+
endLine: 30,
1350+
score: 0.94,
1351+
snippet: straddleSnippet,
1352+
source: "memory",
1353+
},
1354+
],
1355+
});
1356+
1357+
const ranked = await rankShortTermPromotionCandidates({
1358+
workspaceDir,
1359+
minScore: 0,
1360+
minRecallCount: 0,
1361+
minUniqueQueries: 0,
1362+
});
1363+
await applyShortTermPromotions({
1364+
workspaceDir,
1365+
candidates: ranked,
1366+
minScore: 0,
1367+
minRecallCount: 0,
1368+
minUniqueQueries: 0,
1369+
});
1370+
1371+
const memoryText = await fs
1372+
.readFile(path.join(workspaceDir, "MEMORY.md"), "utf-8")
1373+
.catch(() => "");
1374+
// The fuzzy window must never relocate to a snippet that re-introduces managed
1375+
// dreaming markers, candidate scaffolding, or status: staged from the straddle window.
1376+
expect(memoryText).not.toMatch(/Candidate:/i);
1377+
expect(memoryText).not.toMatch(/confidence:\s*0\.00/i);
1378+
expect(memoryText).not.toMatch(/status:\s*staged/i);
1379+
expect(memoryText).not.toMatch(/openclaw:dreaming:light/i);
1380+
expect(memoryText).not.toMatch(/<!--\s*openclaw:dreaming/i);
1381+
});
1382+
});
1383+
13041384
it("applies promotion candidates to MEMORY.md and marks them promoted", async () => {
13051385
await withTempWorkspace(async (workspaceDir) => {
13061386
await writeDailyMemoryNote(workspaceDir, "2026-04-01", [

0 commit comments

Comments
 (0)