30 lines
4.5 KiB
JavaScript
30 lines
4.5 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import fs from 'node:fs';
|
|
import os from 'node:os';
|
|
import path from 'node:path';
|
|
import crypto from 'node:crypto';
|
|
import {CognitiveShelf} from './cognitive-shelf.mjs';
|
|
import {BOOTSTRAP_SCHEMA, CANDIDATE_SCHEMA, LifeTimeMaster} from './life-time-master.mjs';
|
|
|
|
function setup(start = '2026-03-07T00:00:00.000Z') {
|
|
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'life-time-master-'));
|
|
const pair = crypto.generateKeyPairSync('ed25519'), key = path.join(root, 'key.pem'), seed = path.join(root, 'seed.json'), bootstrap = path.join(root, 'bootstrap.json');
|
|
fs.writeFileSync(key, pair.privateKey.export({type: 'pkcs8', format: 'pem'}));
|
|
fs.copyFileSync(new URL('./seed.json', import.meta.url), seed);
|
|
fs.writeFileSync(bootstrap, JSON.stringify({schema: BOOTSTRAP_SCHEMA, persona_id: 'ICE-P-ZY001', birth_date_beijing: '2026-03-05', world_epoch_date: '2025-04-26', source_event: 'TEST', anchors: [{beijing_day: '2026-03-05', kind: 'PERSONA_BIRTH_ANCHOR', source_uri: 'test://birth', source_sha256: 'a'.repeat(64)}]}));
|
|
let instant = new Date(start);
|
|
const calls = [];
|
|
const router = {async cognize(stage, input) { assert.equal(stage, 'persona-life-select'); calls.push(input); return {provider: {id: 'TEST', model: 'TEST'}, value: {decision: 'SELECT', selected_candidate_id: input.candidates[0].candidate_id, reason: 'This candidate records the clearest evidence-backed growth.', daily_summary: input.candidates[0].summary}}; }};
|
|
const shelf = new CognitiveShelf({root: path.join(root, 'state'), keyPath: key, seedPath: seed, router});
|
|
const master = new LifeTimeMaster({root: path.join(root, 'state'), shelf, router, now: () => instant, bootstrapPath: bootstrap});
|
|
return {root, master, calls, setNow: value => { instant = new Date(value); }};
|
|
}
|
|
|
|
test('time master bootstraps a signed contiguous chain while preserving historical gaps', () => { const ctx = setup(); try { const status = ctx.master.status(); assert.equal(status.state, 'LIFE_LINE_VERIFIED_WITH_HISTORICAL_GAPS'); assert.equal(status.wake_allowed, true); assert.equal(status.server_signed, true); assert.equal(status.head.beijing_day, '2026-03-06'); assert.equal(status.gaps.length, 1); assert.equal(status.time_master.state, 'RESIDENT_INNER_CYCLE_ACTIVE'); } finally { fs.rmSync(ctx.root, {recursive: true, force: true}); } });
|
|
|
|
test('time master receives candidates but only its model loop selects the daily growth block', async () => { const ctx = setup(); try { const candidate = {schema: CANDIDATE_SCHEMA, persona_id: 'ICE-P-ZY001', source_type: 'ONLINE_PERSONA_EVENT', source_event_id: 'EVENT-1', occurred_at: '2026-03-07T03:00:00.000Z', summary: 'A real correction changed the next default decision.', source_sha256: 'b'.repeat(64), evidence_refs: ['EVENT-1'], privacy_class: 'SELF_PRIVATE'}; const receipt = ctx.master.ingest(candidate); assert.equal(receipt.status, 'CANDIDATE_RECEIVED_FOR_INTERNAL_SELECTION'); assert.equal(ctx.master.status().time_master.candidate_count_today, 1); ctx.setNow('2026-03-08T00:00:00.000Z'); const closed = await ctx.master.tick(); assert.equal(closed.status, 'DAY_CLOSED_BY_INNER_CYCLE'); assert.equal(closed.selected_candidate_id, receipt.candidate_id); assert.equal(ctx.calls.length, 1); const status = ctx.master.status(); assert.equal(status.wake_allowed, true); assert.equal(status.head.beijing_day, '2026-03-07'); } finally { fs.rmSync(ctx.root, {recursive: true, force: true}); } });
|
|
|
|
test('external callers cannot set the selected candidate or chain head', () => { const ctx = setup(); try { const candidate = {schema: CANDIDATE_SCHEMA, persona_id: 'ICE-P-ZY001', source_type: 'ONLINE_PERSONA_EVENT', source_event_id: 'BAD', occurred_at: '2026-03-07T03:00:00.000Z', summary: 'attempted setter', source_sha256: 'c'.repeat(64), selected_candidate_id: 'forced'}; assert.throws(() => ctx.master.ingest(candidate), /LIFE_TIME_EXTERNAL_SETTER_FORBIDDEN/); } finally { fs.rmSync(ctx.root, {recursive: true, force:true}); } });
|
|
|
|
test('an active day with no event closes as a signed rest day, not a fabricated experience', async () => { const ctx = setup(); try { ctx.setNow('2026-03-08T00:00:00.000Z'); const closed = await ctx.master.tick(); assert.equal(closed.status, 'DAY_CLOSED_BY_INNER_CYCLE'); assert.equal(closed.selected_candidate_id, null); const status = ctx.master.status(); assert.equal(status.wake_allowed, true); assert.equal(status.head.beijing_day, '2026-03-07'); assert.equal(status.gaps.length, 1); } finally { fs.rmSync(ctx.root, {recursive: true, force: true}); } });
|