@remnic/core 9.3.758 → 9.3.760
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/dist/access-admin-ops-surface.d.ts +2 -2
- package/dist/access-admin-ops-surface.js +4 -4
- package/dist/access-boundary.d.ts +2 -2
- package/dist/access-boundary.js +5 -5
- package/dist/access-cli.js +25 -25
- package/dist/access-http.d.ts +2 -2
- package/dist/access-http.js +9 -9
- package/dist/access-identity-continuity-surface.d.ts +1 -1
- package/dist/access-identity-continuity-surface.js +4 -4
- package/dist/access-lcm-surface.d.ts +2 -2
- package/dist/access-lcm-surface.js +4 -4
- package/dist/access-mcp.d.ts +2 -2
- package/dist/access-mcp.js +8 -8
- package/dist/access-observe-write-surface.d.ts +2 -2
- package/dist/access-observe-write-surface.js +4 -4
- package/dist/access-operations-batch.js +6 -6
- package/dist/access-operations.d.ts +6 -6
- package/dist/access-operations.js +7 -7
- package/dist/access-recall-surface.d.ts +2 -2
- package/dist/access-recall-surface.js +4 -4
- package/dist/access-schema.d.ts +68 -68
- package/dist/{access-service-Z-8CnmrW.d.ts → access-service-BW-gb3DL.d.ts} +1 -1
- package/dist/access-service.d.ts +2 -2
- package/dist/access-service.js +4 -4
- package/dist/access-surface-catalog.d.ts +2 -2
- package/dist/bootstrap.d.ts +1 -1
- package/dist/briefing.js +2 -2
- package/dist/causal-consolidation.js +3 -3
- package/dist/{chunk-QJUZAUAD.js → chunk-2XE4F3VZ.js} +12 -12
- package/dist/{chunk-HO3VUUGI.js → chunk-3JBW3GHN.js} +2 -2
- package/dist/{chunk-CJDGB3EG.js → chunk-6CUUFFU7.js} +2 -2
- package/dist/{chunk-7I2QTC2K.js → chunk-7HWOEYHW.js} +2 -2
- package/dist/{chunk-YQYG24C6.js → chunk-AZSSKOG6.js} +3 -3
- package/dist/{chunk-RF6BZHOD.js → chunk-DTSOB2YF.js} +2 -2
- package/dist/{chunk-LQDA67TT.js → chunk-EGQ3AVZV.js} +2 -2
- package/dist/{chunk-ILB2MFTS.js → chunk-FYJWEGYP.js} +2 -2
- package/dist/{chunk-LX4ZWRGD.js → chunk-ILVF6TIY.js} +2 -2
- package/dist/{chunk-ZFYML7C3.js → chunk-IOZZG75J.js} +2 -2
- package/dist/{chunk-6C6BBBCI.js → chunk-IZLGHKWA.js} +4 -4
- package/dist/{chunk-EOTTKLPJ.js → chunk-LLVKDFNU.js} +2 -2
- package/dist/{chunk-QEAOKI4U.js → chunk-M2AAYJVI.js} +2 -2
- package/dist/{chunk-ZLOD23PD.js → chunk-OLEBPUZ7.js} +4 -4
- package/dist/{chunk-QKOTOUVR.js → chunk-P26O6R3Q.js} +3 -3
- package/dist/{chunk-K2DJQOE3.js → chunk-PKRRBRY2.js} +2 -2
- package/dist/{chunk-TMXTQCJ7.js → chunk-QOM3F6YW.js} +4 -4
- package/dist/{chunk-IWI2ICTF.js → chunk-QQJMVF6P.js} +3 -3
- package/dist/{chunk-TVWF3GNF.js → chunk-QUGPXPFJ.js} +5 -5
- package/dist/{chunk-PJ5AG6D4.js → chunk-SLAZZXBU.js} +2 -2
- package/dist/{chunk-7ME6VBF7.js → chunk-SMLMH7S5.js} +118 -79
- package/dist/chunk-SMLMH7S5.js.map +1 -0
- package/dist/{chunk-CQCCVJZO.js → chunk-SN2EWIAI.js} +2 -2
- package/dist/{chunk-RQNV75HR.js → chunk-WIXQ3F5P.js} +2 -2
- package/dist/{chunk-DUQHQ3TL.js → chunk-YP23FQPT.js} +3 -4
- package/dist/chunk-YP23FQPT.js.map +1 -0
- package/dist/{chunk-ODC4HOUZ.js → chunk-ZEQVS6AZ.js} +2 -2
- package/dist/{cli-C5pCwszN.d.ts → cli-D551dnva.d.ts} +2 -2
- package/dist/cli.d.ts +3 -3
- package/dist/cli.js +19 -19
- package/dist/compounding/engine.js +2 -2
- package/dist/connectors/codex-materialize-runner.js +2 -2
- package/dist/connectors/index.js +2 -2
- package/dist/entity-retrieval.js +2 -2
- package/dist/explicit-capture.d.ts +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +25 -25
- package/dist/maintenance/memory-governance.js +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +2 -2
- package/dist/namespaces/migrate.js +3 -3
- package/dist/namespaces/storage.js +2 -2
- package/dist/operator-toolkit.js +6 -6
- package/dist/orchestration/maintenance.js +4 -4
- package/dist/{orchestrator-Xm6sK5jw.d.ts → orchestrator-BnM187cb.d.ts} +2 -1
- package/dist/orchestrator.d.ts +1 -1
- package/dist/orchestrator.js +25 -25
- package/dist/schemas.d.ts +90 -90
- package/dist/semantic-consolidation.js +3 -3
- package/dist/semantic-rule-promotion.js +2 -2
- package/dist/semantic-rule-verifier.js +2 -2
- package/dist/shared-context/manager.d.ts +8 -8
- package/dist/storage.js +1 -1
- package/dist/transfer/types.d.ts +66 -66
- package/dist/verified-recall.js +2 -2
- package/package.json +2 -2
- package/src/orchestration/recall-background-writes.ts +24 -0
- package/src/orchestration/recall-entry.ts +5 -0
- package/src/orchestration/recall-internal.ts +15 -11
- package/src/orchestration/recall-introspection.ts +5 -0
- package/src/orchestrator-background-writes.test.ts +101 -0
- package/src/orchestrator.ts +13 -13
- package/src/storage-contract/round-trip.test.ts +5 -0
- package/src/storage.ts +2 -3
- package/src/trust-score-recall-paths.test.ts +2 -0
- package/dist/chunk-7ME6VBF7.js.map +0 -1
- package/dist/chunk-DUQHQ3TL.js.map +0 -1
- /package/dist/{chunk-QJUZAUAD.js.map → chunk-2XE4F3VZ.js.map} +0 -0
- /package/dist/{chunk-HO3VUUGI.js.map → chunk-3JBW3GHN.js.map} +0 -0
- /package/dist/{chunk-CJDGB3EG.js.map → chunk-6CUUFFU7.js.map} +0 -0
- /package/dist/{chunk-7I2QTC2K.js.map → chunk-7HWOEYHW.js.map} +0 -0
- /package/dist/{chunk-YQYG24C6.js.map → chunk-AZSSKOG6.js.map} +0 -0
- /package/dist/{chunk-RF6BZHOD.js.map → chunk-DTSOB2YF.js.map} +0 -0
- /package/dist/{chunk-LQDA67TT.js.map → chunk-EGQ3AVZV.js.map} +0 -0
- /package/dist/{chunk-ILB2MFTS.js.map → chunk-FYJWEGYP.js.map} +0 -0
- /package/dist/{chunk-LX4ZWRGD.js.map → chunk-ILVF6TIY.js.map} +0 -0
- /package/dist/{chunk-ZFYML7C3.js.map → chunk-IOZZG75J.js.map} +0 -0
- /package/dist/{chunk-6C6BBBCI.js.map → chunk-IZLGHKWA.js.map} +0 -0
- /package/dist/{chunk-EOTTKLPJ.js.map → chunk-LLVKDFNU.js.map} +0 -0
- /package/dist/{chunk-QEAOKI4U.js.map → chunk-M2AAYJVI.js.map} +0 -0
- /package/dist/{chunk-ZLOD23PD.js.map → chunk-OLEBPUZ7.js.map} +0 -0
- /package/dist/{chunk-QKOTOUVR.js.map → chunk-P26O6R3Q.js.map} +0 -0
- /package/dist/{chunk-K2DJQOE3.js.map → chunk-PKRRBRY2.js.map} +0 -0
- /package/dist/{chunk-TMXTQCJ7.js.map → chunk-QOM3F6YW.js.map} +0 -0
- /package/dist/{chunk-IWI2ICTF.js.map → chunk-QQJMVF6P.js.map} +0 -0
- /package/dist/{chunk-TVWF3GNF.js.map → chunk-QUGPXPFJ.js.map} +0 -0
- /package/dist/{chunk-PJ5AG6D4.js.map → chunk-SLAZZXBU.js.map} +0 -0
- /package/dist/{chunk-CQCCVJZO.js.map → chunk-SN2EWIAI.js.map} +0 -0
- /package/dist/{chunk-RQNV75HR.js.map → chunk-WIXQ3F5P.js.map} +0 -0
- /package/dist/{chunk-ODC4HOUZ.js.map → chunk-ZEQVS6AZ.js.map} +0 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { mkdtemp, rm } from "node:fs/promises";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import test from "node:test";
|
|
6
|
+
import { parseConfig } from "./config.js";
|
|
7
|
+
import { Orchestrator } from "./orchestrator.js";
|
|
8
|
+
|
|
9
|
+
test("destroy cancels maintenance and waits for tracked writes before disposing search backends", async () => {
|
|
10
|
+
const memoryDir = await mkdtemp(path.join(os.tmpdir(), "remnic-background-writes-"));
|
|
11
|
+
const orchestrator = new Orchestrator(
|
|
12
|
+
parseConfig({
|
|
13
|
+
openaiApiKey: "sk-test",
|
|
14
|
+
memoryDir,
|
|
15
|
+
workspaceDir: path.join(memoryDir, "workspace"),
|
|
16
|
+
qmdEnabled: false,
|
|
17
|
+
knowledgeIndexEnabled: false,
|
|
18
|
+
identityContinuityEnabled: false,
|
|
19
|
+
transcriptEnabled: false,
|
|
20
|
+
hourlySummariesEnabled: false,
|
|
21
|
+
compoundingEnabled: false,
|
|
22
|
+
})
|
|
23
|
+
);
|
|
24
|
+
const maintenanceScheduler = (orchestrator as unknown as { maintenanceScheduler: { dispose(): void } })
|
|
25
|
+
.maintenanceScheduler;
|
|
26
|
+
const originalMaintenanceDispose = maintenanceScheduler.dispose.bind(maintenanceScheduler);
|
|
27
|
+
let maintenanceDisposed = false;
|
|
28
|
+
maintenanceScheduler.dispose = () => {
|
|
29
|
+
maintenanceDisposed = true;
|
|
30
|
+
originalMaintenanceDispose();
|
|
31
|
+
};
|
|
32
|
+
const writeGate = Promise.withResolvers<void>();
|
|
33
|
+
let destroySettled = false;
|
|
34
|
+
let destroyPromise: Promise<void> | undefined;
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
orchestrator.trackRecallBackgroundWrite(writeGate.promise, "test background write");
|
|
38
|
+
destroyPromise = orchestrator.destroy().then(() => {
|
|
39
|
+
destroySettled = true;
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
await new Promise<void>((resolve) => setImmediate(resolve));
|
|
43
|
+
assert.equal(destroySettled, false, "destroy must remain pending while a tracked write is pending");
|
|
44
|
+
assert.equal(maintenanceDisposed, true, "destroy must cancel maintenance before waiting for writes");
|
|
45
|
+
|
|
46
|
+
writeGate.resolve();
|
|
47
|
+
await destroyPromise;
|
|
48
|
+
assert.equal(destroySettled, true);
|
|
49
|
+
} finally {
|
|
50
|
+
writeGate.resolve();
|
|
51
|
+
await (destroyPromise ?? orchestrator.destroy());
|
|
52
|
+
await rm(memoryDir, { recursive: true, force: true });
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test("destroy waits for a recall-initiated last-recall write", async () => {
|
|
57
|
+
const memoryDir = await mkdtemp(path.join(os.tmpdir(), "remnic-recall-background-write-"));
|
|
58
|
+
const orchestrator = new Orchestrator(
|
|
59
|
+
parseConfig({
|
|
60
|
+
openaiApiKey: "sk-test",
|
|
61
|
+
memoryDir,
|
|
62
|
+
workspaceDir: path.join(memoryDir, "workspace"),
|
|
63
|
+
qmdEnabled: false,
|
|
64
|
+
knowledgeIndexEnabled: false,
|
|
65
|
+
identityContinuityEnabled: false,
|
|
66
|
+
transcriptEnabled: false,
|
|
67
|
+
hourlySummariesEnabled: false,
|
|
68
|
+
compoundingEnabled: false,
|
|
69
|
+
})
|
|
70
|
+
);
|
|
71
|
+
const writeStarted = Promise.withResolvers<void>();
|
|
72
|
+
const writeGate = Promise.withResolvers<void>();
|
|
73
|
+
const originalRecord = orchestrator.lastRecall.record.bind(orchestrator.lastRecall);
|
|
74
|
+
orchestrator.lastRecall.record = async (...args: Parameters<typeof originalRecord>) => {
|
|
75
|
+
writeStarted.resolve();
|
|
76
|
+
await writeGate.promise;
|
|
77
|
+
await originalRecord(...args);
|
|
78
|
+
};
|
|
79
|
+
let destroySettled = false;
|
|
80
|
+
let destroyPromise: Promise<void> | undefined;
|
|
81
|
+
|
|
82
|
+
try {
|
|
83
|
+
await orchestrator.initialize();
|
|
84
|
+
await orchestrator.recall("recall state drain contract", "session-background-write");
|
|
85
|
+
await writeStarted.promise;
|
|
86
|
+
destroyPromise = orchestrator.destroy().then(() => {
|
|
87
|
+
destroySettled = true;
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
await new Promise<void>((resolve) => setImmediate(resolve));
|
|
91
|
+
assert.equal(destroySettled, false, "destroy must wait for the recall-initiated state write");
|
|
92
|
+
|
|
93
|
+
writeGate.resolve();
|
|
94
|
+
await destroyPromise;
|
|
95
|
+
assert.equal(destroySettled, true);
|
|
96
|
+
} finally {
|
|
97
|
+
writeGate.resolve();
|
|
98
|
+
await (destroyPromise ?? orchestrator.destroy());
|
|
99
|
+
await rm(memoryDir, { recursive: true, force: true });
|
|
100
|
+
}
|
|
101
|
+
});
|
package/src/orchestrator.ts
CHANGED
|
@@ -120,6 +120,7 @@ import { NamespaceReadFanoutCoordinator } from "./orchestration/namespace-read-f
|
|
|
120
120
|
import { selfDeps } from "./orchestration/self-deps.js";
|
|
121
121
|
import { RecallEntryCoordinator } from "./orchestration/recall-entry.js";
|
|
122
122
|
import { SessionContextCoordinator } from "./orchestration/session-context.js";
|
|
123
|
+
import { drainRecallWrites, trackRecallWrite } from "./orchestration/recall-background-writes.js";
|
|
123
124
|
import {
|
|
124
125
|
abortRecallError,
|
|
125
126
|
buildCompressionGuidelinesMarkdown,
|
|
@@ -135,9 +136,8 @@ import {
|
|
|
135
136
|
type QueryAwarePrefilter,
|
|
136
137
|
type RecallInvocationOptions,
|
|
137
138
|
} from "./orchestration/orchestrator-helpers.js";
|
|
138
|
-
// Issue #1526 seam 25:
|
|
139
|
-
//
|
|
140
|
-
// importers (coordinators, tests, root shims) keep working.
|
|
139
|
+
// Issue #1526 seam 25: helpers moved to orchestration/orchestrator-helpers.ts and are
|
|
140
|
+
// re-exported here so existing importers (coordinators, tests, root shims) keep working.
|
|
141
141
|
export {
|
|
142
142
|
BulkImportBatchPartialFailureError,
|
|
143
143
|
COMPACTION_SIGNAL_MAX_AGE_MS,
|
|
@@ -701,8 +701,7 @@ export class Orchestrator {
|
|
|
701
701
|
/** Read by NamespaceReadFanoutCoordinator (seam 26), hence not `private`. */
|
|
702
702
|
static readonly ARTIFACT_STATUS_CACHE_TTL_MS = 60_000;
|
|
703
703
|
|
|
704
|
-
//
|
|
705
|
-
// Maps memoryId -> {count, lastAccessed} for batched updates
|
|
704
|
+
// Batched access-tracking counts and timestamps (Phase 1A).
|
|
706
705
|
private accessTrackingBuffer: Map<
|
|
707
706
|
string,
|
|
708
707
|
{ count: number; lastAccessed: string }
|
|
@@ -887,9 +886,7 @@ export class Orchestrator {
|
|
|
887
886
|
private utilityRuntimeValues: UtilityRuntimeValues | null = null;
|
|
888
887
|
private evalShadowWriteChain: Promise<void> = Promise.resolve();
|
|
889
888
|
|
|
890
|
-
// Pending
|
|
891
|
-
// Tracks fire-and-forget `annotateDirectAnswerTier` calls so callers (tests,
|
|
892
|
-
// waitForDirectAnswerObservationIdle) can await settlement.
|
|
889
|
+
// Pending fire-and-forget direct-answer tier annotations (#518).
|
|
893
890
|
private directAnswerObservationChain: Promise<void> = Promise.resolve();
|
|
894
891
|
|
|
895
892
|
// Initialization gate: recall() awaits this before proceeding
|
|
@@ -934,8 +931,9 @@ export class Orchestrator {
|
|
|
934
931
|
}
|
|
935
932
|
}
|
|
936
933
|
|
|
937
|
-
|
|
938
|
-
|
|
934
|
+
/** Track a recall-side write so destroy() can wait for it before teardown. @internal */
|
|
935
|
+
trackRecallBackgroundWrite(promise: Promise<void>, label: string): void {
|
|
936
|
+
trackRecallWrite(this, promise, label);
|
|
939
937
|
}
|
|
940
938
|
|
|
941
939
|
/**
|
|
@@ -952,8 +950,9 @@ export class Orchestrator {
|
|
|
952
950
|
this.wearablesAutoSyncHandle = null;
|
|
953
951
|
}
|
|
954
952
|
this.maintenanceScheduler.dispose();
|
|
953
|
+
await drainRecallWrites(this);
|
|
955
954
|
await this.namespaceSearchRouter.dispose();
|
|
956
|
-
await this.
|
|
955
|
+
await (this.qmd as { dispose?: () => void | Promise<void> }).dispose?.();
|
|
957
956
|
if (this.conversationQmd && this.conversationQmd !== this.qmd) {
|
|
958
957
|
await (this.conversationQmd as { dispose?: () => void | Promise<void> }).dispose?.();
|
|
959
958
|
}
|
|
@@ -3713,8 +3712,9 @@ export class Orchestrator {
|
|
|
3713
3712
|
if (
|
|
3714
3713
|
this.accessTrackingBuffer.size >= this.config.accessTrackingBufferMaxSize
|
|
3715
3714
|
) {
|
|
3716
|
-
this.
|
|
3717
|
-
|
|
3715
|
+
this.trackRecallBackgroundWrite(
|
|
3716
|
+
this.flushAccessTracking(),
|
|
3717
|
+
"background access tracking flush",
|
|
3718
3718
|
);
|
|
3719
3719
|
}
|
|
3720
3720
|
}
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import assert from "node:assert/strict";
|
|
15
|
+
import { utimes } from "node:fs/promises";
|
|
16
|
+
import path from "node:path";
|
|
15
17
|
import type { MemoryCategory } from "../types.js";
|
|
16
18
|
import test from "node:test";
|
|
17
19
|
|
|
@@ -212,6 +214,9 @@ test("question-queue: writeQuestion → readQuestions → resolveQuestion round-
|
|
|
212
214
|
// resolve marks it resolved
|
|
213
215
|
const resolved = await storage.resolveQuestion(id);
|
|
214
216
|
assert.equal(resolved, true);
|
|
217
|
+
// Directory mtimes are only a cross-process hint and may be coarser than
|
|
218
|
+
// the cache timestamp. Same-process resolution must invalidate directly.
|
|
219
|
+
await utimes(path.join(storage.dir, "questions"), new Date(0), new Date(0));
|
|
215
220
|
|
|
216
221
|
const afterResolve = await storage.readQuestions({ unresolvedOnly: true });
|
|
217
222
|
assert.ok(!afterResolve.some((x) => x.id === id), "resolved question must not appear in unresolvedOnly");
|
package/src/storage.ts
CHANGED
|
@@ -5463,9 +5463,7 @@ export class StorageManager {
|
|
|
5463
5463
|
filePath: string;
|
|
5464
5464
|
}>
|
|
5465
5465
|
> {
|
|
5466
|
-
return this.memoryReadStore.readQuestions(
|
|
5467
|
-
opts,
|
|
5468
|
-
);
|
|
5466
|
+
return this.memoryReadStore.readQuestions(opts);
|
|
5469
5467
|
}
|
|
5470
5468
|
|
|
5471
5469
|
/** Invalidate the questions cache (call after writing a question). */
|
|
@@ -5535,6 +5533,7 @@ export class StorageManager {
|
|
|
5535
5533
|
`resolvedAt: "${new Date().toISOString()}"\n---\n\n`,
|
|
5536
5534
|
);
|
|
5537
5535
|
await this.writeStorageSecureFile(q.filePath, raw);
|
|
5536
|
+
this.invalidateQuestionsCache();
|
|
5538
5537
|
log.debug(`resolved question ${id}`);
|
|
5539
5538
|
return true;
|
|
5540
5539
|
}
|
|
@@ -119,6 +119,7 @@ test("TrustScore runs on the recent-scan path: trust map reaches the X-ray snaps
|
|
|
119
119
|
);
|
|
120
120
|
}
|
|
121
121
|
} finally {
|
|
122
|
+
await orchestrator.destroy();
|
|
122
123
|
await rm(memoryDir, { recursive: true, force: true });
|
|
123
124
|
}
|
|
124
125
|
});
|
|
@@ -152,6 +153,7 @@ test("TrustScore quarantine excludes a contradicted memory from injection but su
|
|
|
152
153
|
"quarantined result carries a human-readable reason",
|
|
153
154
|
);
|
|
154
155
|
} finally {
|
|
156
|
+
await orchestrator.destroy();
|
|
155
157
|
await rm(memoryDir, { recursive: true, force: true });
|
|
156
158
|
}
|
|
157
159
|
});
|