linkedin-studio/scripts/brain/tests/consolidate.test.ts
Kjell Tore Guttormsen ff39d14206 feat(linkedin-studio): SB-S2 consolidation engine — proposeDiff/applyDiff [skip-docs]
Pure deterministic engine over the two-layer profile: add / reject-ai-draft /
evidence-bump / promote-at-N(3) / conflict-keep-both / decay-flag(90d). No-duplicate-id
guarantee: primary id = mintEntityId(observed,key), conflict-alt id =
mintContentId(observed-alt🔑:value::date) — byte-distinct. Folded profile-field
seeds immutable (different kind); static facts decay-exempt; no supersede (S3).
applyDiff produces the next ProfileDoc that round-trips through parse/serialize;
re-running is idempotent (bump, not duplicate). + consolidation-state.json sidecar IO.
12 engine tests (SC1a–g, SC2, SC3, SC4). brain 63→75, tsc clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RigJBiRFNtFZKCz21qNbQ4
2026-06-23 17:00:56 +02:00

160 lines
7.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { describe, test } from "node:test";
import assert from "node:assert/strict";
import { proposeDiff, applyDiff, type Candidate } from "../src/consolidate.js";
import { mintEntityId } from "../src/id.js";
import { parseProfile, serializeProfile } from "../src/profile.js";
import type { ProfileDoc, ProfileFact } from "../src/types.js";
const TODAY = "2026-06-23";
const observedId = (key: string) => mintEntityId({ kind: "observed", key });
const fact = (over: Partial<ProfileFact>): ProfileFact => ({
id: "000000000000",
value: "v",
first_seen: "2026-01-01",
last_seen: TODAY,
evidence_count: 1,
provenance: "published",
status: "active",
...over,
});
const doc = (staticF: ProfileFact[], dynamicF: ProfileFact[]): ProfileDoc => ({
schemaVersion: 1,
static: staticF,
dynamic: dynamicF,
});
const cand = (over: Partial<Candidate>): Candidate => ({
key: "k",
value: "v",
provenance: "published",
source: "manual",
observed_date: TODAY,
...over,
});
describe("proposeDiff classification (SC1ag)", () => {
test("SC1a — add: a published candidate with no match becomes a new dynamic fact", () => {
const diff = proposeDiff({ current: doc([], []), candidates: [cand({ key: "topic", value: "AI safety" })], today: TODAY });
assert.equal(diff.additions.length, 1);
assert.equal(diff.additions[0].value, "AI safety");
assert.equal(diff.additions[0].id, observedId("topic"));
assert.equal(diff.additions[0].evidence_count, 1);
assert.equal(diff.additions[0].status, "active");
});
test("SC1b — reject: an ai-draft candidate produces an empty diff", () => {
const diff = proposeDiff({ current: doc([], []), candidates: [cand({ provenance: "ai-draft" })], today: TODAY });
assert.deepEqual(diff.additions, []);
assert.deepEqual(diff.evidenceBumps, []);
assert.deepEqual(diff.promotions, []);
assert.deepEqual(diff.conflicts, []);
});
test("SC1c — evidence-bump: same key+value bumps the existing fact, no addition", () => {
const id = observedId("topic");
const cur = doc([], [fact({ id, value: "AI safety", evidence_count: 1 })]);
const diff = proposeDiff({ current: cur, candidates: [cand({ key: "topic", value: "AI safety" })], today: TODAY });
assert.equal(diff.additions.length, 0);
assert.equal(diff.evidenceBumps.length, 1);
assert.deepEqual(diff.evidenceBumps[0], { id, newCount: 2, last_seen: TODAY });
});
test("SC1d — promote: a dynamic fact reaching N=3 is promoted", () => {
const id = observedId("topic");
const cur = doc([], [fact({ id, value: "AI safety", evidence_count: 2 })]);
const diff = proposeDiff({ current: cur, candidates: [cand({ key: "topic", value: "AI safety" })], today: TODAY });
assert.equal(diff.evidenceBumps[0].newCount, 3);
assert.deepEqual(diff.promotions, [{ id }]);
});
test("SC1d — no promote below N", () => {
const id = observedId("topic");
const cur = doc([], [fact({ id, value: "x", evidence_count: 1 })]);
const diff = proposeDiff({ current: cur, candidates: [cand({ key: "topic", value: "x" })], today: TODAY });
assert.deepEqual(diff.promotions, []);
});
test("SC1e — conflict: different value keeps BOTH with DISTINCT ids, old fact untouched", () => {
const primaryId = observedId("role");
const cur = doc([], [fact({ id: primaryId, value: "advisor", evidence_count: 2 })]);
const diff = proposeDiff({ current: cur, candidates: [cand({ key: "role", value: "architect" })], today: TODAY });
assert.equal(diff.conflicts.length, 1);
assert.equal(diff.conflicts[0].primaryId, primaryId);
assert.equal(diff.conflicts[0].primaryValue, "advisor");
assert.notEqual(diff.conflicts[0].altId, primaryId, "alt id must differ from primary id (no duplicate-id corruption)");
// the alt fact is added; the old fact is NOT bumped
assert.equal(diff.additions.length, 1);
assert.equal(diff.additions[0].value, "architect");
assert.equal(diff.additions[0].id, diff.conflicts[0].altId);
assert.deepEqual(diff.evidenceBumps, []);
});
test("SC1f — decay: a dynamic fact older than 90d is flagged; a static fact is decay-exempt", () => {
const old = "2026-03-01"; // ~114 days before TODAY
const dyn = fact({ id: observedId("stale-topic"), value: "old", last_seen: old });
const stat = fact({ id: observedId("settled"), value: "stable", last_seen: old });
const cur = doc([stat], [dyn]);
const diff = proposeDiff({ current: cur, candidates: [], today: TODAY });
assert.equal(diff.staleFlags.length, 1, "only the dynamic stale fact is flagged");
assert.equal(diff.staleFlags[0].id, dyn.id);
assert.ok(diff.staleFlags[0].daysStale > 90);
});
test("SC1f — a fresh dynamic fact is not flagged", () => {
const cur = doc([], [fact({ id: observedId("fresh"), last_seen: "2026-06-20" })]);
const diff = proposeDiff({ current: cur, candidates: [], today: TODAY });
assert.deepEqual(diff.staleFlags, []);
});
test("SC1g — folded immutable: a candidate overlapping a profile-field seed adds a new observed fact, seed untouched", () => {
const foldedId = mintEntityId({ kind: "profile-field", key: "role" });
const folded = fact({ id: foldedId, value: "advisor", provenance: "human" });
const cur = doc([folded], []);
const before = serializeProfile(cur);
const diff = proposeDiff({ current: cur, candidates: [cand({ key: "role", value: "architect" })], today: TODAY });
// candidate keys to observed:role (≠ profile-field:role) → no match → ADD, no conflict on the folded seed
assert.equal(diff.additions.length, 1);
assert.equal(diff.additions[0].id, observedId("role"));
assert.equal(diff.conflicts.length, 0);
assert.equal(serializeProfile(cur), before, "input doc not mutated; folded seed untouched");
});
});
describe("proposeDiff purity + applyDiff round-trip (SC2, SC3, SC4)", () => {
test("SC2 — proposeDiff does not mutate its inputs", () => {
const cur = doc([], [fact({ id: observedId("topic"), value: "x" })]);
const candidates = [cand({ key: "topic", value: "x" }), cand({ key: "new", value: "y" })];
const snapCur = JSON.stringify(cur);
const snapCand = JSON.stringify(candidates);
proposeDiff({ current: cur, candidates, today: TODAY });
assert.equal(JSON.stringify(cur), snapCur, "current unchanged");
assert.equal(JSON.stringify(candidates), snapCand, "candidates unchanged");
});
test("SC3 — applyDiff(current, proposeDiff(...)) round-trips through parse/serialize", () => {
const cur = doc([fact({ id: mintEntityId({ kind: "profile-field", key: "name" }), value: "KTG", provenance: "human" })], [fact({ id: observedId("topic"), value: "AI safety", evidence_count: 2 })]);
const candidates = [
cand({ key: "topic", value: "AI safety" }), // bump→promote
cand({ key: "new-topic", value: "governance" }), // add
cand({ key: "topic", value: "alignment" }), // conflict on topic → alt
];
const diff = proposeDiff({ current: cur, candidates, today: TODAY });
const next = applyDiff(cur, diff);
const round = parseProfile(serializeProfile(next));
assert.deepEqual(round, next, "applied doc round-trips exactly");
// every fact id is unique (no duplicate-id corruption)
const ids = [...round.static, ...round.dynamic].map((f) => f.id);
assert.equal(new Set(ids).size, ids.length, "all fact ids unique");
});
test("SC4 — idempotent: re-running propose→apply with the same candidates adds no duplicate facts", () => {
const cur = doc([], []);
const candidates = [cand({ key: "topic", value: "AI safety" })];
const once = applyDiff(cur, proposeDiff({ current: cur, candidates, today: TODAY }));
const twice = applyDiff(once, proposeDiff({ current: once, candidates, today: TODAY }));
const factsOnce = [...once.static, ...once.dynamic].length;
const factsTwice = [...twice.static, ...twice.dynamic].length;
assert.equal(factsTwice, factsOnce, "no duplicate fact on re-run (bump only)");
});
});