recallnest 3.0.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +101 -0
- package/README.md +222 -254
- package/README_CN.md +206 -243
- package/package.json +3 -2
- package/src/capture-engine.ts +26 -4
- package/src/context-composer-stable.ts +5 -1
- package/src/embedder.ts +24 -0
- package/src/env-config.ts +18 -0
- package/src/ingest.ts +225 -17
- package/src/kg-extractor.ts +17 -0
- package/src/memory-output.ts +35 -0
- package/src/pivot-apply.ts +52 -1
- package/src/pivot-evidence.ts +128 -0
- package/src/ppr-traversal.ts +25 -1
- package/src/runtime-config.ts +9 -0
- package/src/session-engine.ts +11 -4
- package/src/session-output.ts +9 -1
- package/src/session-store.ts +2 -3
- package/src/skill-promotion.ts +67 -1
- package/src/__tests__/access-tracker-novelty.test.ts +0 -324
- package/src/__tests__/activity-counter.test.ts +0 -125
- package/src/__tests__/adaptive-fidelity.test.ts +0 -102
- package/src/__tests__/admission-control.test.ts +0 -206
- package/src/__tests__/age-label.test.ts +0 -33
- package/src/__tests__/anchor-generator.test.ts +0 -67
- package/src/__tests__/api-server-security.test.ts +0 -102
- package/src/__tests__/auto-consolidation.test.ts +0 -168
- package/src/__tests__/auto-recall.test.ts +0 -131
- package/src/__tests__/babel-integration.test.ts +0 -144
- package/src/__tests__/batch-dedup.test.ts +0 -65
- package/src/__tests__/belief-history.test.ts +0 -220
- package/src/__tests__/canary-eval.test.ts +0 -114
- package/src/__tests__/capture-engine.test.ts +0 -1328
- package/src/__tests__/capture-heuristic.test.ts +0 -171
- package/src/__tests__/cascade-forget.test.ts +0 -210
- package/src/__tests__/category-min-scores.test.ts +0 -116
- package/src/__tests__/cc8-cc1-essential-context.test.ts +0 -298
- package/src/__tests__/circuit-breaker.test.ts +0 -99
- package/src/__tests__/cluster-consolidation.test.ts +0 -1236
- package/src/__tests__/confidence-metadata.test.ts +0 -125
- package/src/__tests__/confidence-tracker.test.ts +0 -261
- package/src/__tests__/conflict-advisor.test.ts +0 -206
- package/src/__tests__/conflict-escalation.test.ts +0 -149
- package/src/__tests__/conflict-lifecycle.test.ts +0 -83
- package/src/__tests__/conflict-output.test.ts +0 -85
- package/src/__tests__/conflict-store.test.ts +0 -418
- package/src/__tests__/connector-v1.test.ts +0 -181
- package/src/__tests__/consolidation-engine.test.ts +0 -520
- package/src/__tests__/constructive-retrieval.test.ts +0 -509
- package/src/__tests__/context-collapse-renderer.test.ts +0 -214
- package/src/__tests__/context-composer-pins.test.ts +0 -64
- package/src/__tests__/context-composer-task-selection.test.ts +0 -24
- package/src/__tests__/context-reconstructor.test.ts +0 -65
- package/src/__tests__/context-renderer.test.ts +0 -91
- package/src/__tests__/continuity-eval.test.ts +0 -275
- package/src/__tests__/continuity-schema.test.ts +0 -97
- package/src/__tests__/contracts.test.ts +0 -262
- package/src/__tests__/conversation-importer.test.ts +0 -692
- package/src/__tests__/core-recall-eval.test.ts +0 -235
- package/src/__tests__/core-summary.test.ts +0 -109
- package/src/__tests__/data-checkup.test.ts +0 -304
- package/src/__tests__/decay-exemption.test.ts +0 -129
- package/src/__tests__/dedup-actions.test.ts +0 -58
- package/src/__tests__/dedup-guard.test.ts +0 -39
- package/src/__tests__/deterministic-id.test.ts +0 -39
- package/src/__tests__/distill-lock.test.ts +0 -305
- package/src/__tests__/distill-session-argshape.test.ts +0 -79
- package/src/__tests__/doctor.test.ts +0 -319
- package/src/__tests__/dream-pipeline.test.ts +0 -820
- package/src/__tests__/dream-scope-isolation.test.ts +0 -386
- package/src/__tests__/dream-write-batching.test.ts +0 -211
- package/src/__tests__/drill-down.test.ts +0 -108
- package/src/__tests__/embedder.test.ts +0 -122
- package/src/__tests__/emotion-decay.test.ts +0 -46
- package/src/__tests__/emotion-detector.test.ts +0 -56
- package/src/__tests__/emotion-phase1-integration.test.ts +0 -153
- package/src/__tests__/emotion-retrieval.test.ts +0 -56
- package/src/__tests__/entity-resolver.test.ts +0 -58
- package/src/__tests__/env-config-invariant.test.ts +0 -80
- package/src/__tests__/env-config.test.ts +0 -211
- package/src/__tests__/error-signature-boost.test.ts +0 -87
- package/src/__tests__/error-signature.test.ts +0 -95
- package/src/__tests__/error-taxonomy.test.ts +0 -129
- package/src/__tests__/ethics-layer.test.ts +0 -476
- package/src/__tests__/event-segmenter.test.ts +0 -153
- package/src/__tests__/feature-flags-integration.test.ts +0 -54
- package/src/__tests__/frequency-tracker.test.ts +0 -113
- package/src/__tests__/freshness.test.ts +0 -186
- package/src/__tests__/graph-export.test.ts +0 -489
- package/src/__tests__/hotness-blend.test.ts +0 -283
- package/src/__tests__/ingest-chunking.test.ts +0 -44
- package/src/__tests__/ingest-scope-prefix.test.ts +0 -69
- package/src/__tests__/ingest.test.ts +0 -360
- package/src/__tests__/interference-detector.test.ts +0 -203
- package/src/__tests__/kg-extractor.test.ts +0 -192
- package/src/__tests__/kg-store.test.ts +0 -300
- package/src/__tests__/llm-client-pivot.test.ts +0 -628
- package/src/__tests__/llm-consolidation.test.ts +0 -226
- package/src/__tests__/maintenance-locks.test.ts +0 -197
- package/src/__tests__/mcp-efficiency.test.ts +0 -288
- package/src/__tests__/mcp-related-scopes.test.ts +0 -151
- package/src/__tests__/memory-boundaries.test.ts +0 -282
- package/src/__tests__/memory-evolution-b2-b3-e1.test.ts +0 -362
- package/src/__tests__/memory-evolution.test.ts +0 -271
- package/src/__tests__/memory-health-rebalance.test.ts +0 -144
- package/src/__tests__/memory-lint.test.ts +0 -421
- package/src/__tests__/memory-output.test.ts +0 -224
- package/src/__tests__/memory-promotion.test.ts +0 -315
- package/src/__tests__/memory-utility.test.ts +0 -256
- package/src/__tests__/migrate-dedup-ids.test.ts +0 -65
- package/src/__tests__/multi-vector.test.ts +0 -242
- package/src/__tests__/narrative-architecture.test.ts +0 -456
- package/src/__tests__/noise-filter.test.ts +0 -205
- package/src/__tests__/noise-prototype-bank.test.ts +0 -280
- package/src/__tests__/obsidian-connector.test.ts +0 -363
- package/src/__tests__/omitted-reporting.test.ts +0 -98
- package/src/__tests__/openai-contract.test.ts +0 -513
- package/src/__tests__/pending-review.test.ts +0 -77
- package/src/__tests__/pii-redact.test.ts +0 -333
- package/src/__tests__/pivot-apply.test.ts +0 -373
- package/src/__tests__/pivot-distill-supervisor.test.ts +0 -457
- package/src/__tests__/pivot-distill.test.ts +0 -1178
- package/src/__tests__/post-retrieval-filter.test.ts +0 -178
- package/src/__tests__/ppr-traversal.test.ts +0 -256
- package/src/__tests__/prediction-engine.test.ts +0 -349
- package/src/__tests__/predictive-prospective-memory.test.ts +0 -416
- package/src/__tests__/preference-guard-smoke.test.ts +0 -211
- package/src/__tests__/preference-matcher.test.ts +0 -282
- package/src/__tests__/preference-slots.test.ts +0 -205
- package/src/__tests__/promotion-distinct-sources.test.ts +0 -162
- package/src/__tests__/prospective-memory.test.ts +0 -283
- package/src/__tests__/pull-from-macbook-sync-only.test.ts +0 -679
- package/src/__tests__/query-entity-detector.test.ts +0 -171
- package/src/__tests__/query-expander-alias.test.ts +0 -146
- package/src/__tests__/query-expander.test.ts +0 -34
- package/src/__tests__/recall-gate.test.ts +0 -266
- package/src/__tests__/recall-governor.test.ts +0 -227
- package/src/__tests__/recall-mode.test.ts +0 -64
- package/src/__tests__/resolve-db-path.test.ts +0 -130
- package/src/__tests__/resolve-tier.test.ts +0 -64
- package/src/__tests__/result-synthesizer.test.ts +0 -198
- package/src/__tests__/resume-context.test.ts +0 -4898
- package/src/__tests__/retrieval-eval.test.ts +0 -163
- package/src/__tests__/retrieval-trace.test.ts +0 -213
- package/src/__tests__/retrieve-audit-revision.test.ts +0 -255
- package/src/__tests__/retriever-boundary-weight.test.ts +0 -136
- package/src/__tests__/retriever-lazy-init-dispatch.test.ts +0 -123
- package/src/__tests__/retroactive-boost.test.ts +0 -223
- package/src/__tests__/salience-scoring.test.ts +0 -106
- package/src/__tests__/scope-inventory.test.ts +0 -200
- package/src/__tests__/scope-policy.test.ts +0 -69
- package/src/__tests__/scope-suggester.test.ts +0 -80
- package/src/__tests__/session-checkpoint.test.ts +0 -291
- package/src/__tests__/session-distiller.test.ts +0 -640
- package/src/__tests__/session-gc.test.ts +0 -215
- package/src/__tests__/skill-engine.test.ts +0 -552
- package/src/__tests__/skill-promotion.test.ts +0 -654
- package/src/__tests__/skill-verifier.test.ts +0 -122
- package/src/__tests__/source-heartbeat.test.ts +0 -254
- package/src/__tests__/stable-context-length-contract.test.ts +0 -62
- package/src/__tests__/store-patch-metadata.test.ts +0 -235
- package/src/__tests__/store-read-consistency.test.ts +0 -122
- package/src/__tests__/store-schema-migration.test.ts +0 -87
- package/src/__tests__/store-scope-audit.test.ts +0 -81
- package/src/__tests__/store-upsert.test.ts +0 -201
- package/src/__tests__/supersede-chain.test.ts +0 -154
- package/src/__tests__/synthesis-contract.test.ts +0 -252
- package/src/__tests__/synthesis-promotion.test.ts +0 -369
- package/src/__tests__/temporal-parser.test.ts +0 -241
- package/src/__tests__/temporal-validity.test.ts +0 -160
- package/src/__tests__/term-registry-terminal-roster.test.ts +0 -127
- package/src/__tests__/term-registry.test.ts +0 -121
- package/src/__tests__/tool-error-surfacing.test.ts +0 -98
- package/src/__tests__/tool-output-compressor.test.ts +0 -160
- package/src/__tests__/topic-tag.test.ts +0 -113
- package/src/__tests__/trusted-memory.test.ts +0 -867
- package/src/__tests__/ui-server-security.test.ts +0 -93
- package/src/__tests__/usage-tracker.test.ts +0 -287
- package/src/__tests__/utility-weight.test.ts +0 -57
- package/src/__tests__/verbatim-self-recall.test.ts +0 -279
- package/src/__tests__/version-manager.test.ts +0 -248
- package/src/__tests__/workflow-observation-skill-outcome.test.ts +0 -352
- package/src/__tests__/workflow-observation.test.ts +0 -433
- package/src/__tests__/write-verifier.test.ts +0 -122
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "bun:test";
|
|
2
|
-
import { existsSync, mkdirSync, mkdtempSync, readdirSync, rmSync, utimesSync, writeFileSync } from "node:fs";
|
|
3
|
-
import { join } from "node:path";
|
|
4
|
-
import { tmpdir } from "node:os";
|
|
5
|
-
|
|
6
|
-
import { buildSessionCheckpointRecord } from "../session-engine.js";
|
|
7
|
-
import { SessionCheckpointStore, classifyCheckpointQuality } from "../session-store.js";
|
|
8
|
-
|
|
9
|
-
const FALLBACK_SUMMARY = "Checkpoint captured current task state without repo-state details.";
|
|
10
|
-
const NOW = new Date("2026-04-01T00:00:00.000Z");
|
|
11
|
-
|
|
12
|
-
function daysBeforeNow(days: number): string {
|
|
13
|
-
return new Date(NOW.getTime() - days * 86_400_000).toISOString();
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function makeRichCheckpoint(overrides: Record<string, unknown> = {}) {
|
|
17
|
-
return buildSessionCheckpointRecord({
|
|
18
|
-
sessionId: overrides.sessionId ?? crypto.randomUUID(),
|
|
19
|
-
scope: overrides.scope ?? "project:test",
|
|
20
|
-
summary: overrides.summary ?? "Rich checkpoint with real content about the project status.",
|
|
21
|
-
decisions: overrides.decisions ?? ["decision-a"],
|
|
22
|
-
openLoops: overrides.openLoops ?? ["loop-a"],
|
|
23
|
-
nextActions: overrides.nextActions ?? ["action-a"],
|
|
24
|
-
entities: [],
|
|
25
|
-
files: [],
|
|
26
|
-
updatedAt: overrides.updatedAt ?? daysBeforeNow(1),
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function makeMinimalCheckpoint(overrides: Record<string, unknown> = {}) {
|
|
31
|
-
return buildSessionCheckpointRecord({
|
|
32
|
-
sessionId: overrides.sessionId ?? crypto.randomUUID(),
|
|
33
|
-
scope: overrides.scope ?? "project:test",
|
|
34
|
-
summary: FALLBACK_SUMMARY,
|
|
35
|
-
decisions: [],
|
|
36
|
-
openLoops: [],
|
|
37
|
-
nextActions: [],
|
|
38
|
-
entities: [],
|
|
39
|
-
files: [],
|
|
40
|
-
updatedAt: overrides.updatedAt ?? daysBeforeNow(1),
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function createTempStore(): { store: SessionCheckpointStore; dir: string; cleanup: () => void } {
|
|
45
|
-
const dir = mkdtempSync(join(tmpdir(), "rn-gc-test-"));
|
|
46
|
-
const checkpointDir = join(dir, "session-checkpoints");
|
|
47
|
-
mkdirSync(checkpointDir, { recursive: true });
|
|
48
|
-
const store = new SessionCheckpointStore(checkpointDir);
|
|
49
|
-
return {
|
|
50
|
-
store,
|
|
51
|
-
dir,
|
|
52
|
-
cleanup: () => rmSync(dir, { recursive: true, force: true }),
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
describe("checkpoint gc - retention rules", () => {
|
|
57
|
-
it("keeps latest N rich checkpoints per scope and archives older ones", async () => {
|
|
58
|
-
const { store, cleanup } = createTempStore();
|
|
59
|
-
try {
|
|
60
|
-
// 7 rich checkpoints for same scope, spread across 5-50 days
|
|
61
|
-
const ages = [5, 10, 15, 25, 35, 42, 50];
|
|
62
|
-
for (const age of ages) {
|
|
63
|
-
await store.save(makeRichCheckpoint({ updatedAt: daysBeforeNow(age) }));
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const result = store.gc({ now: NOW, keepPerScope: 5, archiveAfterDays: 30 });
|
|
67
|
-
expect(result.kept).toBe(5);
|
|
68
|
-
expect(result.archived).toBe(2); // 42d and 50d
|
|
69
|
-
expect(result.deleted).toBe(0);
|
|
70
|
-
expect(result.errors).toHaveLength(0);
|
|
71
|
-
} finally {
|
|
72
|
-
cleanup();
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it("keeps latest checkpoint per session if within 48 hours", async () => {
|
|
77
|
-
const { store, cleanup } = createTempStore();
|
|
78
|
-
try {
|
|
79
|
-
const sessionA = crypto.randomUUID();
|
|
80
|
-
const sessionB = crypto.randomUUID();
|
|
81
|
-
|
|
82
|
-
// sessionA: 1 hour old minimal — should be protected by session TTL
|
|
83
|
-
await store.save(makeMinimalCheckpoint({ sessionId: sessionA, updatedAt: daysBeforeNow(0.04) }));
|
|
84
|
-
// sessionB: 10 days old minimal — no session TTL protection, >7 days → delete
|
|
85
|
-
await store.save(makeMinimalCheckpoint({ sessionId: sessionB, updatedAt: daysBeforeNow(10) }));
|
|
86
|
-
|
|
87
|
-
const result = store.gc({ now: NOW, sessionTtlHours: 48, minimalTtlDays: 7 });
|
|
88
|
-
expect(result.kept).toBe(1); // sessionA protected
|
|
89
|
-
expect(result.deleted).toBe(1); // sessionB expired minimal
|
|
90
|
-
} finally {
|
|
91
|
-
cleanup();
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it("deletes minimal checkpoints older than 7 days", async () => {
|
|
96
|
-
const { store, cleanup } = createTempStore();
|
|
97
|
-
try {
|
|
98
|
-
await store.save(makeMinimalCheckpoint({ updatedAt: daysBeforeNow(3) }));
|
|
99
|
-
await store.save(makeMinimalCheckpoint({ updatedAt: daysBeforeNow(8) }));
|
|
100
|
-
await store.save(makeMinimalCheckpoint({ updatedAt: daysBeforeNow(15) }));
|
|
101
|
-
|
|
102
|
-
const result = store.gc({ now: NOW, minimalTtlDays: 7 });
|
|
103
|
-
expect(result.kept).toBe(1); // 3d old
|
|
104
|
-
expect(result.deleted).toBe(2); // 8d and 15d old
|
|
105
|
-
} finally {
|
|
106
|
-
cleanup();
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
it("archives rich checkpoints older than 30 days not in latest-per-scope", async () => {
|
|
111
|
-
const { store, dir, cleanup } = createTempStore();
|
|
112
|
-
try {
|
|
113
|
-
const ages = [5, 10, 20, 35, 40, 50];
|
|
114
|
-
for (const age of ages) {
|
|
115
|
-
await store.save(makeRichCheckpoint({ updatedAt: daysBeforeNow(age) }));
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const result = store.gc({ now: NOW, keepPerScope: 3, archiveAfterDays: 30 });
|
|
119
|
-
expect(result.kept).toBe(3); // 5d, 10d, 20d
|
|
120
|
-
expect(result.archived).toBe(3); // 35d, 40d, 50d
|
|
121
|
-
|
|
122
|
-
// Verify files actually moved to archive
|
|
123
|
-
const archiveDir = join(dir, "archive", "session-checkpoints");
|
|
124
|
-
expect(existsSync(archiveDir)).toBe(true);
|
|
125
|
-
expect(readdirSync(archiveDir).filter((f) => f.endsWith(".json"))).toHaveLength(3);
|
|
126
|
-
} finally {
|
|
127
|
-
cleanup();
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
it("hard-deletes archived files older than 90 days", async () => {
|
|
132
|
-
const { store, dir, cleanup } = createTempStore();
|
|
133
|
-
try {
|
|
134
|
-
// Manually place 2 files in archive directory
|
|
135
|
-
const archiveDir = join(dir, "archive", "session-checkpoints");
|
|
136
|
-
mkdirSync(archiveDir, { recursive: true });
|
|
137
|
-
|
|
138
|
-
const file60d = join(archiveDir, "old-60d-file.json");
|
|
139
|
-
const file100d = join(archiveDir, "old-100d-file.json");
|
|
140
|
-
writeFileSync(file60d, "{}");
|
|
141
|
-
writeFileSync(file100d, "{}");
|
|
142
|
-
|
|
143
|
-
// Backdate mtimes
|
|
144
|
-
const mtime60 = new Date(NOW.getTime() - 60 * 86_400_000);
|
|
145
|
-
const mtime100 = new Date(NOW.getTime() - 100 * 86_400_000);
|
|
146
|
-
utimesSync(file60d, mtime60, mtime60);
|
|
147
|
-
utimesSync(file100d, mtime100, mtime100);
|
|
148
|
-
|
|
149
|
-
const result = store.gc({ now: NOW, archiveTtlDays: 90 });
|
|
150
|
-
expect(existsSync(file60d)).toBe(true); // 60d < 90d, survives
|
|
151
|
-
expect(existsSync(file100d)).toBe(false); // 100d > 90d, deleted
|
|
152
|
-
expect(result.deleted).toBe(1);
|
|
153
|
-
} finally {
|
|
154
|
-
cleanup();
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
describe("checkpoint gc - priority and edge cases", () => {
|
|
160
|
-
it("session TTL protection overrides minimal delete rule", async () => {
|
|
161
|
-
const { store, cleanup } = createTempStore();
|
|
162
|
-
try {
|
|
163
|
-
const sessionId = crypto.randomUUID();
|
|
164
|
-
// 2 hours old minimal — minimalTtlDays=0 would delete, but session TTL protects
|
|
165
|
-
await store.save(makeMinimalCheckpoint({ sessionId, updatedAt: daysBeforeNow(0.08) }));
|
|
166
|
-
|
|
167
|
-
const result = store.gc({ now: NOW, sessionTtlHours: 48, minimalTtlDays: 0 });
|
|
168
|
-
expect(result.kept).toBe(1);
|
|
169
|
-
expect(result.deleted).toBe(0);
|
|
170
|
-
|
|
171
|
-
const keepAction = result.actions.find((a) => a.action === "keep");
|
|
172
|
-
expect(keepAction?.reason).toContain("session");
|
|
173
|
-
} finally {
|
|
174
|
-
cleanup();
|
|
175
|
-
}
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
it("dry run does not modify any files", async () => {
|
|
179
|
-
const { store, dir, cleanup } = createTempStore();
|
|
180
|
-
try {
|
|
181
|
-
// 1 to delete (minimal, 10d), 1 to archive (rich, 35d), 1 to keep (rich, 2d)
|
|
182
|
-
await store.save(makeMinimalCheckpoint({ updatedAt: daysBeforeNow(10) }));
|
|
183
|
-
await store.save(makeRichCheckpoint({ updatedAt: daysBeforeNow(35) }));
|
|
184
|
-
await store.save(makeRichCheckpoint({ updatedAt: daysBeforeNow(2) }));
|
|
185
|
-
|
|
186
|
-
const checkpointDir = join(dir, "session-checkpoints");
|
|
187
|
-
const beforeCount = readdirSync(checkpointDir).filter((f) => f.endsWith(".json")).length;
|
|
188
|
-
|
|
189
|
-
const result = store.gc({ now: NOW, dryRun: true, keepPerScope: 1, archiveAfterDays: 30, minimalTtlDays: 7 });
|
|
190
|
-
expect(result.archived).toBeGreaterThan(0);
|
|
191
|
-
expect(result.deleted).toBeGreaterThan(0);
|
|
192
|
-
|
|
193
|
-
// Files are still there
|
|
194
|
-
const afterCount = readdirSync(checkpointDir).filter((f) => f.endsWith(".json")).length;
|
|
195
|
-
expect(afterCount).toBe(beforeCount);
|
|
196
|
-
} finally {
|
|
197
|
-
cleanup();
|
|
198
|
-
}
|
|
199
|
-
});
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
describe("checkpoint gc - structural", () => {
|
|
203
|
-
it("handles empty directory gracefully", () => {
|
|
204
|
-
const { store, cleanup } = createTempStore();
|
|
205
|
-
try {
|
|
206
|
-
const result = store.gc({ now: NOW });
|
|
207
|
-
expect(result.kept).toBe(0);
|
|
208
|
-
expect(result.archived).toBe(0);
|
|
209
|
-
expect(result.deleted).toBe(0);
|
|
210
|
-
expect(result.errors).toHaveLength(0);
|
|
211
|
-
} finally {
|
|
212
|
-
cleanup();
|
|
213
|
-
}
|
|
214
|
-
});
|
|
215
|
-
});
|