@remnic/core 9.3.629 → 9.3.631
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-cli.js +15 -13
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +5 -4
- package/dist/access-http.js +7 -6
- package/dist/access-mcp.d.ts +5 -4
- package/dist/access-mcp.js +6 -5
- package/dist/{access-service-BdThkfIE.d.ts → access-service-C9_EpVHd.d.ts} +2 -2
- package/dist/access-service.d.ts +5 -4
- package/dist/access-service.js +5 -4
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +1 -1
- package/dist/auto-sync-RFADEHIQ.js +75 -0
- package/dist/auto-sync-RFADEHIQ.js.map +1 -0
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +4 -3
- package/dist/briefing.d.ts +1 -1
- package/dist/briefing.js +3 -2
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer.d.ts +1 -1
- package/dist/calibration.d.ts +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +4 -3
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/{chunk-532VCWYW.js → chunk-242XFZ36.js} +2 -2
- package/dist/{chunk-XXO5TI3B.js → chunk-32U3N7H5.js} +3 -3
- package/dist/{chunk-KB4MFBF5.js → chunk-3RDYU3JS.js} +3 -3
- package/dist/{chunk-57QXN2CS.js → chunk-4S3N6HFG.js} +2 -2
- package/dist/{chunk-OLNNOHBC.js → chunk-5PT5I6JQ.js} +20 -14
- package/dist/{chunk-OLNNOHBC.js.map → chunk-5PT5I6JQ.js.map} +1 -1
- package/dist/{chunk-GE7Q7KXP.js → chunk-7A2QKUUA.js} +2 -2
- package/dist/{chunk-KKTXCFD7.js → chunk-7H5WCPBS.js} +95 -11
- package/dist/{chunk-KKTXCFD7.js.map → chunk-7H5WCPBS.js.map} +1 -1
- package/dist/{chunk-3MNBW7R7.js → chunk-C4KKM62E.js} +2 -2
- package/dist/{chunk-NKCW223V.js → chunk-CMN5AWAZ.js} +2 -2
- package/dist/{chunk-JXHMAQYT.js → chunk-DOBJH4I6.js} +4 -4
- package/dist/{chunk-TZDSNIRO.js → chunk-IFVFQRZ2.js} +5 -5
- package/dist/{chunk-LQYTQCXM.js → chunk-JCLECECB.js} +2 -2
- package/dist/chunk-KVDUDYEN.js +1164 -0
- package/dist/chunk-KVDUDYEN.js.map +1 -0
- package/dist/{chunk-QDV6VAD4.js → chunk-LEG7XWS2.js} +2 -2
- package/dist/chunk-M7XQSUBB.js +280 -0
- package/dist/chunk-M7XQSUBB.js.map +1 -0
- package/dist/{chunk-N5RGXWLQ.js → chunk-PUEAEQSN.js} +2 -2
- package/dist/{chunk-UGHUNQ74.js → chunk-QYGIQ5NM.js} +212 -417
- package/dist/chunk-QYGIQ5NM.js.map +1 -0
- package/dist/{chunk-JKCDQBDW.js → chunk-UXFOGILU.js} +2 -2
- package/dist/{chunk-MVQN73GT.js → chunk-VTR3MNYF.js} +2 -2
- package/dist/{chunk-KVFYTRMV.js → chunk-W25I7G6U.js} +2 -2
- package/dist/{chunk-3GLCUPXP.js → chunk-WLZBVYC6.js} +192 -889
- package/dist/chunk-WLZBVYC6.js.map +1 -0
- package/dist/{chunk-3R2UZV3U.js → chunk-X7EJF46S.js} +2 -2
- package/dist/{chunk-54KDA6UK.js → chunk-XG4NAWAV.js} +3 -3
- package/dist/{chunk-P2D2MM47.js → chunk-YROCXMCK.js} +2 -2
- package/dist/{cli-DAsHklrf.d.ts → cli-CuVEQWKr.d.ts} +3 -3
- package/dist/cli.d.ts +6 -5
- package/dist/cli.js +18 -17
- package/dist/compounding/engine.d.ts +1 -1
- package/dist/compounding/engine.js +3 -2
- package/dist/compounding/preference-consolidator.d.ts +1 -1
- package/dist/compression-optimizer.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +3 -2
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +3 -2
- package/dist/consolidation-provenance-check.d.ts +1 -1
- package/dist/consolidation-undo.d.ts +1 -1
- package/dist/contradiction/index.d.ts +1 -1
- package/dist/contradiction/index.js +4 -4
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/day-summary.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +3 -2
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +4 -3
- package/dist/extraction-judge-telemetry.d.ts +1 -1
- package/dist/extraction-judge-training.d.ts +1 -1
- package/dist/extraction-judge.d.ts +1 -1
- package/dist/extraction.d.ts +1 -1
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/identity-continuity.d.ts +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/index.d.ts +8 -8
- package/dist/index.js +49 -45
- package/dist/index.js.map +1 -1
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +3 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -2
- package/dist/maintenance/rebuild-memory-projection.js +4 -3
- package/dist/mcp-memory-inspector-app.d.ts +5 -4
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-worth-outcomes.d.ts +1 -1
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +1 -1
- package/dist/namespaces/migrate.js +4 -3
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/storage.d.ts +1 -1
- package/dist/namespaces/storage.js +3 -2
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +1 -1
- package/dist/operator-toolkit.js +7 -6
- package/dist/{orchestrator-BexeSJ2j.d.ts → orchestrator-CoqytbK_.d.ts} +102 -10
- package/dist/orchestrator.d.ts +4 -3
- package/dist/orchestrator.js +12 -10
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +1 -1
- package/dist/recall-disclosure-escalation.d.ts +1 -1
- package/dist/recall-explain-renderer.d.ts +1 -1
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray.d.ts +1 -1
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +2 -2
- package/dist/retrieval-agents.d.ts +1 -1
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/index.d.ts +1 -1
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-consolidation-PwkzNfdK.d.ts → semantic-consolidation-BPs6BURk.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +4 -3
- package/dist/semantic-rule-promotion.js +3 -2
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +3 -2
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/shared-context/manager.d.ts +1 -1
- package/dist/signal.d.ts +1 -1
- package/dist/storage.d.ts +38 -2
- package/dist/storage.js +6 -3
- package/dist/summarizer.d.ts +1 -1
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/temporal-supersession.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +1 -1
- package/dist/tier-routing.d.ts +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/{types-BCF2wqKa.d.ts → types-CpMPD8xl.d.ts} +59 -11
- package/dist/types.d.ts +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +3 -2
- package/package.json +1 -1
- package/src/orchestrator.ts +74 -0
- package/src/storage.ts +100 -0
- package/src/wearables/auto-sync.test.ts +181 -0
- package/src/wearables/auto-sync.ts +129 -0
- package/src/wearables/cli.ts +6 -0
- package/src/wearables/config.test.ts +90 -11
- package/src/wearables/config.ts +113 -11
- package/src/wearables/memory-gen.test.ts +416 -1
- package/src/wearables/memory-gen.ts +381 -23
- package/src/wearables/pipeline.test.ts +396 -5
- package/src/wearables/pipeline.ts +174 -22
- package/src/wearables/service.test.ts +172 -0
- package/src/wearables/service.ts +84 -3
- package/src/wearables/storage-io.test.ts +81 -0
- package/src/wearables/trust.test.ts +123 -0
- package/src/wearables/trust.ts +168 -0
- package/src/wearables/types.ts +57 -9
- package/dist/chunk-3GLCUPXP.js.map +0 -1
- package/dist/chunk-UGHUNQ74.js.map +0 -1
- /package/dist/{chunk-532VCWYW.js.map → chunk-242XFZ36.js.map} +0 -0
- /package/dist/{chunk-XXO5TI3B.js.map → chunk-32U3N7H5.js.map} +0 -0
- /package/dist/{chunk-KB4MFBF5.js.map → chunk-3RDYU3JS.js.map} +0 -0
- /package/dist/{chunk-57QXN2CS.js.map → chunk-4S3N6HFG.js.map} +0 -0
- /package/dist/{chunk-GE7Q7KXP.js.map → chunk-7A2QKUUA.js.map} +0 -0
- /package/dist/{chunk-3MNBW7R7.js.map → chunk-C4KKM62E.js.map} +0 -0
- /package/dist/{chunk-NKCW223V.js.map → chunk-CMN5AWAZ.js.map} +0 -0
- /package/dist/{chunk-JXHMAQYT.js.map → chunk-DOBJH4I6.js.map} +0 -0
- /package/dist/{chunk-TZDSNIRO.js.map → chunk-IFVFQRZ2.js.map} +0 -0
- /package/dist/{chunk-LQYTQCXM.js.map → chunk-JCLECECB.js.map} +0 -0
- /package/dist/{chunk-QDV6VAD4.js.map → chunk-LEG7XWS2.js.map} +0 -0
- /package/dist/{chunk-N5RGXWLQ.js.map → chunk-PUEAEQSN.js.map} +0 -0
- /package/dist/{chunk-JKCDQBDW.js.map → chunk-UXFOGILU.js.map} +0 -0
- /package/dist/{chunk-MVQN73GT.js.map → chunk-VTR3MNYF.js.map} +0 -0
- /package/dist/{chunk-KVFYTRMV.js.map → chunk-W25I7G6U.js.map} +0 -0
- /package/dist/{chunk-3R2UZV3U.js.map → chunk-X7EJF46S.js.map} +0 -0
- /package/dist/{chunk-54KDA6UK.js.map → chunk-XG4NAWAV.js.map} +0 -0
- /package/dist/{chunk-P2D2MM47.js.map → chunk-YROCXMCK.js.map} +0 -0
|
@@ -21,6 +21,9 @@ function settings(
|
|
|
21
21
|
return {
|
|
22
22
|
enabled: true,
|
|
23
23
|
memoryMode: "review",
|
|
24
|
+
sourceTrust: 0.8,
|
|
25
|
+
autoApproveTrust: 0.7,
|
|
26
|
+
reviewTrust: 0.45,
|
|
24
27
|
minConfidence: 0.6,
|
|
25
28
|
minImportance: "low",
|
|
26
29
|
maxMemoriesPerDay: 20,
|
|
@@ -318,6 +321,417 @@ test("daily digest writes one deterministic episode memory and dedups", async ()
|
|
|
318
321
|
assert.equal(writes2.length, 0);
|
|
319
322
|
});
|
|
320
323
|
|
|
324
|
+
function judgeReturning(
|
|
325
|
+
kinds: Array<"accept" | "reject" | "defer">,
|
|
326
|
+
): NonNullable<Parameters<typeof generateWearableMemories>[5]["judgeFacts"]> {
|
|
327
|
+
return async (candidates) => ({
|
|
328
|
+
verdicts: new Map(
|
|
329
|
+
candidates.map((_, index) => [
|
|
330
|
+
index,
|
|
331
|
+
{
|
|
332
|
+
kind: kinds[index] ?? "accept",
|
|
333
|
+
durable: (kinds[index] ?? "accept") === "accept",
|
|
334
|
+
reason: "test",
|
|
335
|
+
} as never,
|
|
336
|
+
]),
|
|
337
|
+
),
|
|
338
|
+
cached: 0,
|
|
339
|
+
judged: candidates.length,
|
|
340
|
+
elapsed: 1,
|
|
341
|
+
deferred: 0,
|
|
342
|
+
deferredCappedToReject: 0,
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
test("smart mode: judge verdicts gate active/review/drop with trust metadata", async () => {
|
|
347
|
+
const { writer, writes } = makeWriter();
|
|
348
|
+
const result = await generateWearableMemories(
|
|
349
|
+
"limitless",
|
|
350
|
+
"2026-06-10",
|
|
351
|
+
[LONG_CONVERSATION],
|
|
352
|
+
settings({ memoryMode: "smart" }),
|
|
353
|
+
REGISTRY,
|
|
354
|
+
{
|
|
355
|
+
extract: extractionReturning([
|
|
356
|
+
{ category: "decision", content: "Launch moved to September twelfth after the vendor call.", confidence: 0.9, tags: [] },
|
|
357
|
+
{ category: "fact", content: "Something the judge thinks is not durable at all.", confidence: 0.9, tags: [] },
|
|
358
|
+
{ category: "fact", content: "An ambiguous statement the judge wants to defer on.", confidence: 0.9, tags: [] },
|
|
359
|
+
]),
|
|
360
|
+
writer,
|
|
361
|
+
judgeFacts: judgeReturning(["accept", "reject", "defer"]),
|
|
362
|
+
},
|
|
363
|
+
);
|
|
364
|
+
// accept @ 0.9*0.8 + 0.15 = 0.87 -> active; reject -> drop; defer -> review.
|
|
365
|
+
assert.equal(result.created, 2);
|
|
366
|
+
assert.equal(result.skippedByReason["judge-rejected"], 1);
|
|
367
|
+
const byContent = new Map(writes.map((write) => [write.content, write]));
|
|
368
|
+
const active = byContent.get("Launch moved to September twelfth after the vendor call.");
|
|
369
|
+
assert.ok(active);
|
|
370
|
+
assert.equal(active.options.status, "active");
|
|
371
|
+
const attrs = active.options.structuredAttributes as Record<string, string>;
|
|
372
|
+
assert.equal(attrs.judgeVerdict, "accept");
|
|
373
|
+
assert.equal(attrs.trustDecision, "auto-approved");
|
|
374
|
+
assert.ok(Number(attrs.trustScore) > 0.8);
|
|
375
|
+
// trustScore persists rounded to 3 decimals; confidence carries the
|
|
376
|
+
// raw float — compare within rounding tolerance.
|
|
377
|
+
assert.ok(
|
|
378
|
+
Math.abs((active.options.confidence as number) - Number(attrs.trustScore)) < 0.001,
|
|
379
|
+
);
|
|
380
|
+
const deferred = byContent.get("An ambiguous statement the judge wants to defer on.");
|
|
381
|
+
assert.ok(deferred);
|
|
382
|
+
assert.equal(deferred.options.status, "pending_review");
|
|
383
|
+
assert.equal(
|
|
384
|
+
(deferred.options.structuredAttributes as Record<string, string>).trustDecision,
|
|
385
|
+
"judge-deferred",
|
|
386
|
+
);
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
test("smart mode without a judge degrades to confidence x sourceTrust banding", async () => {
|
|
390
|
+
const { writer, writes } = makeWriter();
|
|
391
|
+
const result = await generateWearableMemories(
|
|
392
|
+
"limitless",
|
|
393
|
+
"2026-06-10",
|
|
394
|
+
[LONG_CONVERSATION],
|
|
395
|
+
settings({ memoryMode: "smart", sourceTrust: 0.8 }),
|
|
396
|
+
REGISTRY,
|
|
397
|
+
{
|
|
398
|
+
extract: extractionReturning([
|
|
399
|
+
{ category: "fact", content: "The vendor contract renews every October first.", confidence: 0.95, tags: [] },
|
|
400
|
+
{ category: "fact", content: "Someone mentioned maybe moving the standup earlier.", confidence: 0.7, tags: [] },
|
|
401
|
+
{ category: "fact", content: "A mumbled aside that was barely transcribed correctly.", confidence: 0.4, tags: [] },
|
|
402
|
+
]),
|
|
403
|
+
writer,
|
|
404
|
+
},
|
|
405
|
+
);
|
|
406
|
+
// 0.95*0.8=0.76 active; 0.7*0.8=0.56 review; 0.4*0.8=0.32 dropped.
|
|
407
|
+
assert.equal(result.created, 2);
|
|
408
|
+
assert.equal(result.skippedByReason["below-trust"], 1);
|
|
409
|
+
const statuses = writes.map((write) => write.options.status).sort();
|
|
410
|
+
assert.deepEqual(statuses, ["active", "pending_review"]);
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
test("smart mode: cross-device corroboration lifts a borderline fact to active", async () => {
|
|
414
|
+
const { tokenizeDayBody } = await import("./trust.js");
|
|
415
|
+
const fact = {
|
|
416
|
+
category: "fact" as const,
|
|
417
|
+
content: "The launch moved to September twelfth after the vendor call.",
|
|
418
|
+
confidence: 0.75, // 0.75*0.8 = 0.6: review alone; +0.15 corroboration -> 0.75 active
|
|
419
|
+
tags: [],
|
|
420
|
+
};
|
|
421
|
+
const beeDayTokens = tokenizeDayBody(
|
|
422
|
+
"They said the launch moves to September twelfth right after that vendor call wrapped.",
|
|
423
|
+
);
|
|
424
|
+
|
|
425
|
+
const { writer: writerA, writes: writesA } = makeWriter();
|
|
426
|
+
await generateWearableMemories(
|
|
427
|
+
"limitless", "2026-06-10", [LONG_CONVERSATION],
|
|
428
|
+
settings({ memoryMode: "smart" }), REGISTRY,
|
|
429
|
+
{ extract: extractionReturning([fact]), writer: writerA },
|
|
430
|
+
);
|
|
431
|
+
const { writer: writerB, writes: writesB } = makeWriter();
|
|
432
|
+
await generateWearableMemories(
|
|
433
|
+
"limitless", "2026-06-10", [LONG_CONVERSATION],
|
|
434
|
+
settings({ memoryMode: "smart" }), REGISTRY,
|
|
435
|
+
{
|
|
436
|
+
extract: extractionReturning([fact]),
|
|
437
|
+
writer: writerB,
|
|
438
|
+
corroboration: {
|
|
439
|
+
otherSourceDayTokens: new Map([["bee", beeDayTokens]]),
|
|
440
|
+
existingMemories: [],
|
|
441
|
+
},
|
|
442
|
+
},
|
|
443
|
+
);
|
|
444
|
+
assert.equal(writesA[0].options.status, "pending_review", "uncorroborated stays in review");
|
|
445
|
+
assert.equal(writesB[0].options.status, "active", "corroborated crosses the auto threshold");
|
|
446
|
+
const attrs = writesB[0].options.structuredAttributes as Record<string, string>;
|
|
447
|
+
assert.equal(attrs.corroboratedBySources, "bee");
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
test("smart mode: a judge failure degrades with a warning instead of aborting", async () => {
|
|
451
|
+
const { writer, writes } = makeWriter();
|
|
452
|
+
const result = await generateWearableMemories(
|
|
453
|
+
"limitless",
|
|
454
|
+
"2026-06-10",
|
|
455
|
+
[LONG_CONVERSATION],
|
|
456
|
+
settings({ memoryMode: "smart" }),
|
|
457
|
+
REGISTRY,
|
|
458
|
+
{
|
|
459
|
+
extract: extractionReturning([
|
|
460
|
+
{ category: "fact", content: "The vendor contract renews every October first.", confidence: 0.95, tags: [] },
|
|
461
|
+
]),
|
|
462
|
+
writer,
|
|
463
|
+
judgeFacts: async () => {
|
|
464
|
+
throw new Error("judge backend down");
|
|
465
|
+
},
|
|
466
|
+
},
|
|
467
|
+
);
|
|
468
|
+
assert.equal(result.created, 1);
|
|
469
|
+
assert.equal(writes[0].options.status, "active");
|
|
470
|
+
assert.ok(result.warnings.some((warning) => warning.includes("judge unavailable")));
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
test("smart mode: dropped facts never consume day-cap slots", async () => {
|
|
474
|
+
const { writer, writes } = makeWriter();
|
|
475
|
+
const result = await generateWearableMemories(
|
|
476
|
+
"limitless",
|
|
477
|
+
"2026-06-10",
|
|
478
|
+
[LONG_CONVERSATION],
|
|
479
|
+
settings({ memoryMode: "smart", maxMemoriesPerDay: 1 }),
|
|
480
|
+
REGISTRY,
|
|
481
|
+
{
|
|
482
|
+
extract: extractionReturning([
|
|
483
|
+
// Highest trust but judge-rejected — must not occupy the only slot.
|
|
484
|
+
{ category: "fact", content: "A high-confidence fact the judge rejects as not durable.", confidence: 0.99, tags: [] },
|
|
485
|
+
{ category: "fact", content: "The vendor contract renews every October first as agreed.", confidence: 0.95, tags: [] },
|
|
486
|
+
]),
|
|
487
|
+
writer,
|
|
488
|
+
judgeFacts: judgeReturning(["reject", "accept"]),
|
|
489
|
+
},
|
|
490
|
+
);
|
|
491
|
+
assert.equal(result.created, 1, "the surviving fact gets the slot");
|
|
492
|
+
assert.equal(writes[0].content, "The vendor contract renews every October first as agreed.");
|
|
493
|
+
assert.equal(result.skippedByReason["judge-rejected"], 1);
|
|
494
|
+
assert.equal(result.skippedByReason["over-day-cap"], undefined, "no slot wasted on the drop");
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
test("a judge failure leaves the pass completed; extraction failure does not", async () => {
|
|
498
|
+
const { writer } = makeWriter();
|
|
499
|
+
const judgeDown = await generateWearableMemories(
|
|
500
|
+
"limitless",
|
|
501
|
+
"2026-06-10",
|
|
502
|
+
[LONG_CONVERSATION],
|
|
503
|
+
settings({ memoryMode: "smart" }),
|
|
504
|
+
REGISTRY,
|
|
505
|
+
{
|
|
506
|
+
extract: extractionReturning([
|
|
507
|
+
{ category: "fact", content: "The vendor contract renews every October first.", confidence: 0.95, tags: [] },
|
|
508
|
+
]),
|
|
509
|
+
writer,
|
|
510
|
+
judgeFacts: async () => {
|
|
511
|
+
throw new Error("judge backend down");
|
|
512
|
+
},
|
|
513
|
+
},
|
|
514
|
+
);
|
|
515
|
+
assert.equal(judgeDown.completed, true, "degraded pass is still complete");
|
|
516
|
+
assert.ok(judgeDown.warnings.length > 0);
|
|
517
|
+
|
|
518
|
+
const extractDown = await generateWearableMemories(
|
|
519
|
+
"limitless",
|
|
520
|
+
"2026-06-10",
|
|
521
|
+
[LONG_CONVERSATION],
|
|
522
|
+
settings({ memoryMode: "smart" }),
|
|
523
|
+
REGISTRY,
|
|
524
|
+
{
|
|
525
|
+
extract: async () => {
|
|
526
|
+
throw new Error("engine outage");
|
|
527
|
+
},
|
|
528
|
+
writer,
|
|
529
|
+
},
|
|
530
|
+
);
|
|
531
|
+
assert.equal(extractDown.completed, false, "aborted extraction must retry");
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
test("smart native import: judge gates writes; dropped ids re-score on later syncs", async () => {
|
|
535
|
+
const { writer, writes } = makeWriter();
|
|
536
|
+
const result = await importNativeMemories(
|
|
537
|
+
"omi",
|
|
538
|
+
[
|
|
539
|
+
{ id: "n1", content: "User volunteers at the food bank every month with the team." },
|
|
540
|
+
{ id: "n2", content: "Garbage provider extraction that should never persist." },
|
|
541
|
+
],
|
|
542
|
+
new Set(),
|
|
543
|
+
settings({ memoryMode: "smart", importNativeMemories: "smart" }),
|
|
544
|
+
{
|
|
545
|
+
extract: extractionReturning([]),
|
|
546
|
+
writer,
|
|
547
|
+
judgeFacts: judgeReturning(["accept", "reject"]),
|
|
548
|
+
},
|
|
549
|
+
);
|
|
550
|
+
// accept: 0.7 * (0.8*0.9) + 0.15 = 0.654 -> review band (no corroboration).
|
|
551
|
+
assert.equal(result.imported, 1);
|
|
552
|
+
assert.equal(writes.length, 1);
|
|
553
|
+
assert.equal(writes[0].options.status, "pending_review");
|
|
554
|
+
const attrs = writes[0].options.structuredAttributes as Record<string, string>;
|
|
555
|
+
assert.equal(attrs.judgeVerdict, "accept");
|
|
556
|
+
// Dropped facts are deliberately NOT tracked: later corpus or
|
|
557
|
+
// corroboration support must be able to admit them on a re-fetch
|
|
558
|
+
// (the judge verdict cache keeps repeated rejections cheap).
|
|
559
|
+
assert.ok(!result.importedIds.includes("n2"), "dropped ids re-fetch and re-score later");
|
|
560
|
+
assert.ok(result.importedIds.includes("n1"));
|
|
561
|
+
});
|
|
562
|
+
|
|
563
|
+
test("smart mode: new evidence promotes an earlier pending_review write in place", async () => {
|
|
564
|
+
const borderline = "The launch moved to September twelfth after the vendor call.";
|
|
565
|
+
const { writer, writes } = makeWriter([borderline]);
|
|
566
|
+
let promotedWith: Record<string, string> | undefined;
|
|
567
|
+
writer.findWearableMemoryByContent = async (content) =>
|
|
568
|
+
content.trim() === borderline ? { id: "mem-old", status: "pending_review" } : null;
|
|
569
|
+
writer.promoteWearableMemory = async (_id, attrs) => {
|
|
570
|
+
promotedWith = attrs;
|
|
571
|
+
return true;
|
|
572
|
+
};
|
|
573
|
+
const { tokenizeDayBody } = await import("./trust.js");
|
|
574
|
+
const result = await generateWearableMemories(
|
|
575
|
+
"limitless",
|
|
576
|
+
"2026-06-10",
|
|
577
|
+
[LONG_CONVERSATION],
|
|
578
|
+
settings({ memoryMode: "smart" }),
|
|
579
|
+
REGISTRY,
|
|
580
|
+
{
|
|
581
|
+
// 0.75*0.8 = 0.6 (review band) + 0.15 cross-source = 0.75 -> active.
|
|
582
|
+
extract: extractionReturning([
|
|
583
|
+
{ category: "fact", content: borderline, confidence: 0.75, tags: [] },
|
|
584
|
+
]),
|
|
585
|
+
writer,
|
|
586
|
+
corroboration: {
|
|
587
|
+
otherSourceDayTokens: new Map([
|
|
588
|
+
["bee", tokenizeDayBody("They said the launch moves to September twelfth right after that vendor call wrapped.")],
|
|
589
|
+
]),
|
|
590
|
+
existingMemories: [],
|
|
591
|
+
},
|
|
592
|
+
},
|
|
593
|
+
);
|
|
594
|
+
assert.equal(result.promoted, 1, "existing borderline write promoted");
|
|
595
|
+
assert.equal(result.created, 0);
|
|
596
|
+
assert.equal(writes.length, 0, "no duplicate write");
|
|
597
|
+
assert.ok(promotedWith);
|
|
598
|
+
assert.equal(promotedWith.trustDecision, "promoted-by-corroboration");
|
|
599
|
+
assert.equal(promotedWith.corroboratedBySources, "bee");
|
|
600
|
+
});
|
|
601
|
+
|
|
602
|
+
test("smart mode: duplicates without stronger evidence stay skipped, not promoted", async () => {
|
|
603
|
+
const borderline = "The launch moved to September twelfth after the vendor call.";
|
|
604
|
+
const { writer, writes } = makeWriter([borderline]);
|
|
605
|
+
let promoteCalls = 0;
|
|
606
|
+
writer.findWearableMemoryByContent = async () => ({ id: "mem-old", status: "pending_review" });
|
|
607
|
+
writer.promoteWearableMemory = async () => {
|
|
608
|
+
promoteCalls += 1;
|
|
609
|
+
return true;
|
|
610
|
+
};
|
|
611
|
+
const result = await generateWearableMemories(
|
|
612
|
+
"limitless",
|
|
613
|
+
"2026-06-10",
|
|
614
|
+
[LONG_CONVERSATION],
|
|
615
|
+
settings({ memoryMode: "smart" }),
|
|
616
|
+
REGISTRY,
|
|
617
|
+
{
|
|
618
|
+
// 0.75*0.8 = 0.6 — still review band without corroboration.
|
|
619
|
+
extract: extractionReturning([
|
|
620
|
+
{ category: "fact", content: borderline, confidence: 0.75, tags: [] },
|
|
621
|
+
]),
|
|
622
|
+
writer,
|
|
623
|
+
},
|
|
624
|
+
);
|
|
625
|
+
assert.equal(result.promoted, 0);
|
|
626
|
+
assert.equal(promoteCalls, 0, "no promotion without crossing the auto threshold");
|
|
627
|
+
assert.equal(result.skippedByReason["duplicate-existing"], 1);
|
|
628
|
+
assert.equal(writes.length, 0);
|
|
629
|
+
});
|
|
630
|
+
|
|
631
|
+
test("smart mode: a fresh judge-reject retires an earlier pending_review write", async () => {
|
|
632
|
+
const stale = "The launch moved to September twelfth after the vendor call.";
|
|
633
|
+
const { writer, writes } = makeWriter([stale]);
|
|
634
|
+
let demotedWith: Record<string, string> | undefined;
|
|
635
|
+
writer.findWearableMemoryByContent = async (content) =>
|
|
636
|
+
content.trim() === stale ? { id: "mem-old", status: "pending_review" } : null;
|
|
637
|
+
writer.promoteWearableMemory = async () => {
|
|
638
|
+
throw new Error("reject verdicts must never promote");
|
|
639
|
+
};
|
|
640
|
+
writer.demoteWearableMemory = async (_id, attrs) => {
|
|
641
|
+
demotedWith = attrs;
|
|
642
|
+
return true;
|
|
643
|
+
};
|
|
644
|
+
const result = await generateWearableMemories(
|
|
645
|
+
"limitless",
|
|
646
|
+
"2026-06-10",
|
|
647
|
+
[LONG_CONVERSATION],
|
|
648
|
+
settings({ memoryMode: "smart" }),
|
|
649
|
+
REGISTRY,
|
|
650
|
+
{
|
|
651
|
+
extract: extractionReturning([
|
|
652
|
+
{ category: "fact", content: stale, confidence: 0.9, tags: [] },
|
|
653
|
+
]),
|
|
654
|
+
writer,
|
|
655
|
+
judgeFacts: judgeReturning(["reject"]),
|
|
656
|
+
},
|
|
657
|
+
);
|
|
658
|
+
assert.equal(result.demoted, 1, "judge-reject retires the pending row");
|
|
659
|
+
assert.equal(result.promoted, 0);
|
|
660
|
+
assert.equal(writes.length, 0);
|
|
661
|
+
assert.equal(
|
|
662
|
+
result.skippedByReason["duplicate-existing"],
|
|
663
|
+
undefined,
|
|
664
|
+
"demotion is an action, not a skip",
|
|
665
|
+
);
|
|
666
|
+
assert.ok(demotedWith);
|
|
667
|
+
assert.equal(demotedWith.trustDecision, "demoted-by-rejection");
|
|
668
|
+
assert.equal(demotedWith.judgeVerdict, "reject");
|
|
669
|
+
});
|
|
670
|
+
|
|
671
|
+
test("smart mode: judge-reject never touches an active row", async () => {
|
|
672
|
+
const approved = "The launch moved to September twelfth after the vendor call.";
|
|
673
|
+
const { writer, writes } = makeWriter([approved]);
|
|
674
|
+
let demoteCalls = 0;
|
|
675
|
+
writer.findWearableMemoryByContent = async () => ({ id: "mem-old", status: "active" });
|
|
676
|
+
writer.promoteWearableMemory = async () => true;
|
|
677
|
+
writer.demoteWearableMemory = async () => {
|
|
678
|
+
demoteCalls += 1;
|
|
679
|
+
return true;
|
|
680
|
+
};
|
|
681
|
+
const result = await generateWearableMemories(
|
|
682
|
+
"limitless",
|
|
683
|
+
"2026-06-10",
|
|
684
|
+
[LONG_CONVERSATION],
|
|
685
|
+
settings({ memoryMode: "smart" }),
|
|
686
|
+
REGISTRY,
|
|
687
|
+
{
|
|
688
|
+
extract: extractionReturning([
|
|
689
|
+
{ category: "fact", content: approved, confidence: 0.9, tags: [] },
|
|
690
|
+
]),
|
|
691
|
+
writer,
|
|
692
|
+
judgeFacts: judgeReturning(["reject"]),
|
|
693
|
+
},
|
|
694
|
+
);
|
|
695
|
+
assert.equal(result.demoted, 0);
|
|
696
|
+
assert.equal(demoteCalls, 0, "operator-approved rows are not overturned by a re-verdict");
|
|
697
|
+
assert.equal(result.skippedByReason["duplicate-existing"], 1);
|
|
698
|
+
assert.equal(writes.length, 0);
|
|
699
|
+
});
|
|
700
|
+
|
|
701
|
+
test("smart mode: below-trust re-score without a reject verdict does not demote", async () => {
|
|
702
|
+
const borderline = "The launch moved to September twelfth after the vendor call.";
|
|
703
|
+
const { writer, writes } = makeWriter([borderline]);
|
|
704
|
+
let demoteCalls = 0;
|
|
705
|
+
writer.findWearableMemoryByContent = async () => ({ id: "mem-old", status: "pending_review" });
|
|
706
|
+
writer.promoteWearableMemory = async () => true;
|
|
707
|
+
writer.demoteWearableMemory = async () => {
|
|
708
|
+
demoteCalls += 1;
|
|
709
|
+
return true;
|
|
710
|
+
};
|
|
711
|
+
const result = await generateWearableMemories(
|
|
712
|
+
"limitless",
|
|
713
|
+
"2026-06-10",
|
|
714
|
+
[LONG_CONVERSATION],
|
|
715
|
+
// 0.62 * 0.5 = 0.31 < reviewTrust 0.45 -> drop band, verdict undefined.
|
|
716
|
+
settings({ memoryMode: "smart", sourceTrust: 0.5 }),
|
|
717
|
+
REGISTRY,
|
|
718
|
+
{
|
|
719
|
+
extract: extractionReturning([
|
|
720
|
+
{ category: "fact", content: borderline, confidence: 0.62, tags: [] },
|
|
721
|
+
]),
|
|
722
|
+
writer,
|
|
723
|
+
},
|
|
724
|
+
);
|
|
725
|
+
assert.equal(result.demoted, 0);
|
|
726
|
+
assert.equal(
|
|
727
|
+
demoteCalls,
|
|
728
|
+
0,
|
|
729
|
+
"a score-based drop is weaker evidence than an explicit reject — leave the row",
|
|
730
|
+
);
|
|
731
|
+
assert.equal(result.skippedByReason["duplicate-existing"], 1);
|
|
732
|
+
assert.equal(writes.length, 0);
|
|
733
|
+
});
|
|
734
|
+
|
|
321
735
|
test("native memories always import as pending_review and respect prior imports", async () => {
|
|
322
736
|
const { writer, writes } = makeWriter(["Provider fact already in Remnic."]);
|
|
323
737
|
const result = await importNativeMemories(
|
|
@@ -330,7 +744,8 @@ test("native memories always import as pending_review and respect prior imports"
|
|
|
330
744
|
{ id: "n5", content: "Previously imported." },
|
|
331
745
|
],
|
|
332
746
|
new Set(["n5"]),
|
|
333
|
-
|
|
747
|
+
settings({ importNativeMemories: "review" }),
|
|
748
|
+
{ extract: extractionReturning([]), writer },
|
|
334
749
|
);
|
|
335
750
|
// n1 imports; n2 dedups against existing storage; n3 dedups against
|
|
336
751
|
// n1 within the run; n4 is empty; n5 was imported on a prior sync.
|