Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions assistant/src/config/schemas/__tests__/memory-v2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,11 @@ describe("MemoryV3ConfigSchema", () => {
denseQuota: { activeDomain: 30, offDomain: 8 },
lanes: { hot: true, sparse: true, dense: true, tree: true, edges: true },
ks: [5, 10, 25, 50],
write: {
enabled: false,
consolidateIntervalMs: 3600000,
coactivation: false,
},
});
});

Expand Down Expand Up @@ -287,6 +292,30 @@ describe("MemoryV3ConfigSchema", () => {
test("rejects non-number ks entries", () => {
expect(() => MemoryV3ConfigSchema.parse({ ks: ["a"] })).toThrow();
});

test("parses the write subtree to safe off defaults when omitted", () => {
const parsed = MemoryV3ConfigSchema.parse({});
expect(parsed.write).toEqual({
enabled: false,
consolidateIntervalMs: 3600000,
coactivation: false,
});
});

test("accepts a partial write override and defaults the rest", () => {
const parsed = MemoryV3ConfigSchema.parse({ write: { enabled: true } });
expect(parsed.write).toEqual({
enabled: true,
consolidateIntervalMs: 3600000,
coactivation: false,
});
});

test("rejects a non-integer write.consolidateIntervalMs", () => {
expect(() =>
MemoryV3ConfigSchema.parse({ write: { consolidateIntervalMs: 1.5 } }),
).toThrow();
});
});

describe("MemoryConfigSchema integration with v3 block", () => {
Expand All @@ -298,6 +327,11 @@ describe("MemoryConfigSchema integration with v3 block", () => {
expect(parsed.v3.passCap).toBe(3);
expect(parsed.v3.lanes.dense).toBe(true);
expect(parsed.v3.ks).toEqual([5, 10, 25, 50]);
expect(parsed.v3.write).toEqual({
enabled: false,
consolidateIntervalMs: 3600000,
coactivation: false,
});
});

test("leaves pre-existing configs (no v3 key) otherwise unchanged", () => {
Expand Down
37 changes: 37 additions & 0 deletions assistant/src/config/schemas/memory-v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,38 @@ export const MemoryV3ConfigSchema = z
.describe(
"Evaluation top-K cutoffs the v3 loop reports metrics at (e.g. recall@K).",
),
write: z
.object({
enabled: z
.boolean({ error: "memory.v3.write.enabled must be a boolean" })
.default(false)
.describe(
"Whether v3 consolidation owns the shared-buffer drain + tree build. Off by default — v2 consolidation stays the sole buffer-drainer. Does NOT introduce a separate buffer.",
),
consolidateIntervalMs: z
.number({
error: "memory.v3.write.consolidateIntervalMs must be a number",
})
.int("memory.v3.write.consolidateIntervalMs must be an integer")
.default(3600000)
.describe(
"Interval, in milliseconds, between scheduled v3 consolidation runs once the v3 write path owns the drain. Default 1 hour.",
),
coactivation: z
.boolean({ error: "memory.v3.write.coactivation must be a boolean" })
.default(false)
.describe(
"Whether v3 consolidation learns co-activation edges during the tree build. Off by default; consumed by a later PR.",
),
})
.default({
enabled: false,
consolidateIntervalMs: 3600000,
coactivation: false,
})
.describe(
"Memory v3 write-path configuration. All default-off scaffolding — controls whether v3 consolidation owns the shared-buffer drain + tree build. Consumed by later PRs.",
),
})
.default({
enabled: false,
Expand All @@ -501,6 +533,11 @@ export const MemoryV3ConfigSchema = z
denseQuota: { activeDomain: 30, offDomain: 8 },
lanes: { hot: true, sparse: true, dense: true, tree: true, edges: true },
ks: [5, 10, 25, 50],
write: {
enabled: false,
consolidateIntervalMs: 3600000,
coactivation: false,
},
})
.describe(
"Memory v3 — multi-lane bounded-descent retrieval. Additive scaffolding, disabled by default.",
Expand Down
20 changes: 19 additions & 1 deletion assistant/src/memory/__tests__/jobs-store-job-classes.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
import { describe, expect, test } from "bun:test";

import { EMBED_JOB_TYPES, SLOW_LLM_JOB_TYPES } from "../jobs-store.js";
import {
EMBED_JOB_TYPES,
type MemoryJobType,
SLOW_LLM_JOB_TYPES,
} from "../jobs-store.js";

describe("memory v3 job types", () => {
test("the v3 job-type literals are members of MemoryJobType", () => {
// Compile-time assignability is enforced by `tsc --noEmit`; the runtime
// assertion keeps the literals visible to the test runner. These types are
// inert scaffolding until their handlers land in later PRs.
const v3JobTypes: MemoryJobType[] = [
"memory_v3_consolidate",
"memory_v3_index_maintenance",
"memory_v3_edge_learning",
];
expect(new Set(v3JobTypes).size).toBe(3);
});
});

describe("memory job classes", () => {
test("EMBED_JOB_TYPES and SLOW_LLM_JOB_TYPES are disjoint", () => {
Expand Down
3 changes: 3 additions & 0 deletions assistant/src/memory/jobs-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ export type MemoryJobType =
| "memory_v2_migrate"
| "memory_v2_reembed"
| "memory_v2_activation_recompute"
| "memory_v3_consolidate"
| "memory_v3_index_maintenance"
| "memory_v3_edge_learning"
| "memory_retrospective";

export const EMBED_JOB_TYPES: MemoryJobType[] = [
Expand Down
Loading