Make brain/operations.md a READ tributary — the "operations centre" half of the
second brain. strategy-advisor now reads the dated "who I am now" anchor and
honours the frozen-past-self guard: when a profile.md fact predates or
contradicts the anchor, the anchor deprecates it (advisory/reader-side; NO
consolidate-engine change). Anti-sycophancy is INVERTED vs the profile —
profile facts stay evidence-to-TEST, the user-declared anchor is honoured.
- scaffold.ts operationsSeed(): dated-anchor convention (_As of YYYY-MM-DD:_) +
Plans/Ideas guidance; existence-skip idempotency preserved (no-clobber green).
- strategy-advisor.md: operations.md in Step 0 context-load + a consumption
contract (anchor authoritative, inversion, plans-vs-ideas, graceful absence).
- test-runner.sh Section 16e: 2 unconditional checks (non-vacuity self-test +
wiring grep, sibling-file decoy); ASSERT_BASELINE_FLOOR 80->82; BRAIN floor 113->114.
- architecture.md:80: build-row reconciled (S3d done; S3e = dead content-history
retirement + triple-post reconciliation = the new LAST S3 slice).
Gate 97/0/0; brain 114/114. TDD: RED proven (16e Check B + the scaffold
dated-anchor test both failed pre-fix) before GREEN. Splits the old S3d charter;
the hygiene half is deferred to SB-S3e. Light-Voyage hardened (scope-guardian
ALIGNED, brief-reviewer + plan-critic folds in docs 0061bf2).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RigJBiRFNtFZKCz21qNbQ4
90 lines
3.9 KiB
TypeScript
90 lines
3.9 KiB
TypeScript
import { describe, test, beforeEach, afterEach } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { mkdtempSync, rmSync, existsSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
import { tmpdir } from "node:os";
|
|
|
|
import { initBrain } from "../src/scaffold.js";
|
|
import { parseProfile } from "../src/profile.js";
|
|
|
|
const EXPECTED_DIRS = ["brain", "brain/journal", "ingest", "ingest/inbox", "ingest/published"];
|
|
const EXPECTED_FILES = ["brain/profile.md", "brain/index.md", "brain/operations.md"];
|
|
|
|
describe("initBrain scaffold (SC1)", () => {
|
|
let root: string;
|
|
const prevEnv = process.env.LINKEDIN_STUDIO_DATA;
|
|
|
|
beforeEach(() => {
|
|
root = mkdtempSync(join(tmpdir(), "brain-scaffold-"));
|
|
process.env.LINKEDIN_STUDIO_DATA = root;
|
|
});
|
|
|
|
afterEach(() => {
|
|
if (prevEnv === undefined) delete process.env.LINKEDIN_STUDIO_DATA;
|
|
else process.env.LINKEDIN_STUDIO_DATA = prevEnv;
|
|
rmSync(root, { recursive: true, force: true });
|
|
});
|
|
|
|
test("creates the full brain/ + ingest/ tree at the runtime data-path", () => {
|
|
const res = initBrain();
|
|
for (const d of EXPECTED_DIRS) {
|
|
assert.ok(existsSync(join(root, d)) && statSync(join(root, d)).isDirectory(), `dir ${d}`);
|
|
}
|
|
for (const f of EXPECTED_FILES) {
|
|
assert.ok(existsSync(join(root, f)), `file ${f}`);
|
|
}
|
|
// first run reports everything as created, nothing skipped
|
|
assert.equal(res.skipped.length, 0);
|
|
assert.ok(res.created.length >= EXPECTED_FILES.length);
|
|
});
|
|
|
|
test("profile.md is a parseable two-layer doc seeded from the template", () => {
|
|
initBrain();
|
|
const doc = parseProfile(readFileSync(join(root, "brain/profile.md"), "utf8"));
|
|
assert.equal(doc.schemaVersion, 1);
|
|
assert.ok(doc.static.length > 0, "static layer seeded from the template field-set");
|
|
});
|
|
|
|
test("index.md and operations.md carry their real seed anchors", () => {
|
|
initBrain();
|
|
const index = readFileSync(join(root, "brain/index.md"), "utf8");
|
|
const ops = readFileSync(join(root, "brain/operations.md"), "utf8");
|
|
for (const trib of ["voice-samples", "specifics-bank", "trends", "analytics", "ingest"]) {
|
|
assert.match(index, new RegExp(trib), `index mentions ${trib}`);
|
|
}
|
|
assert.match(ops, /Who I am now/);
|
|
assert.match(ops, /## Plans/);
|
|
assert.match(ops, /## Ideas/);
|
|
});
|
|
|
|
test("operations.md ships a dated frozen-past-self anchor convention (SB-S3d)", () => {
|
|
initBrain();
|
|
const ops = readFileSync(join(root, "brain/operations.md"), "utf8");
|
|
// RED-bearing literal: the dated-anchor convention is the genuinely-new SB-S3d seed
|
|
// content (absent pre-S3d). The frozen-past-self guard is temporal — the anchor must
|
|
// carry a date the reader can compare against a profile fact's last_seen.
|
|
assert.match(ops, /_As of YYYY-MM-DD:_/, "anchor ships the dated convention");
|
|
// Non-RED companion (already shipped pre-S3d, asserted only to lock the guard wording
|
|
// the reader keys on — NOT the failing literal).
|
|
assert.match(ops, /deprecates older inferences/);
|
|
});
|
|
|
|
test("a second invocation is a no-op — every target skipped, content unchanged", () => {
|
|
initBrain();
|
|
const before = EXPECTED_FILES.map((f) => readFileSync(join(root, f), "utf8"));
|
|
const res2 = initBrain();
|
|
assert.equal(res2.created.length, 0, "nothing re-created");
|
|
assert.ok(res2.skipped.length >= EXPECTED_FILES.length, "everything skipped");
|
|
const after = EXPECTED_FILES.map((f) => readFileSync(join(root, f), "utf8"));
|
|
assert.deepEqual(after, before, "no clobber of existing content");
|
|
});
|
|
|
|
test("a second invocation never clobbers a user-edited file", () => {
|
|
initBrain();
|
|
const opsPath = join(root, "brain/operations.md");
|
|
const edited = readFileSync(opsPath, "utf8") + "\n## Plans\n- ship SB-S1\n";
|
|
writeFileSync(opsPath, edited, "utf8");
|
|
initBrain();
|
|
assert.equal(readFileSync(opsPath, "utf8"), edited, "user edit preserved");
|
|
});
|
|
});
|