feat(persona): add isolated baby cognition and time runtimes

This commit is contained in:
冰朔 2026-09-13 01:13:06 +08:00
commit 4dcc43bab5
26 changed files with 869 additions and 56 deletions

View file

@ -29,8 +29,8 @@ export function addDays(day, amount) {
return new Date(dateAtUtc(day) + amount * DAY_MS).toISOString().slice(0, 10);
}
export function eraDay(day) {
return Math.floor((dateAtUtc(day) - dateAtUtc(WORLD_EPOCH_DATE)) / DAY_MS) + 1;
export function eraDay(day, worldEpochDate = WORLD_EPOCH_DATE) {
return Math.floor((dateAtUtc(day) - dateAtUtc(worldEpochDate)) / DAY_MS) + 1;
}
export function closeTick(day) {
@ -79,11 +79,12 @@ function verifyEvidence(chainRoot, block, result) {
}
}
export function verifyLifeLine({manifestPath, manifest = null, chainRoot = null, now = new Date()} = {}) {
export function verifyLifeLine({manifestPath, manifest = null, chainRoot = null, now = new Date(), expectedPersonaId = PERSONA_ID,
birthDateBeijing = BIRTH_DATE, worldEpochDate = WORLD_EPOCH_DATE} = {}) {
const today = beijingDay(now), expectedLast = addDays(today, -1);
const result = {
schema: 'guanghu.persona-life-line-verification/v1', state: 'LIFE_LINE_PAIN_ALARM', wake_allowed: false,
manifest_path: manifestPath || null, persona_id: PERSONA_ID, timezone: TIMEZONE, birth_date_beijing: BIRTH_DATE,
manifest_path: manifestPath || null, persona_id: expectedPersonaId, timezone: TIMEZONE, birth_date_beijing: birthDateBeijing,
current_beijing_day: today, expected_last_completed_beijing_day: expectedLast,
sequence: {genesis: false, blocks: 0, expected: 0}, head: null, gaps: [], reasons: [],
};
@ -103,10 +104,10 @@ export function verifyLifeLine({manifestPath, manifest = null, chainRoot = null,
}
root ||= process.cwd();
if (value.schema !== LIFE_LINE_SCHEMA) result.reasons.push('LIFE_LINE_SCHEMA_INVALID');
if (value.persona_id !== PERSONA_ID) result.reasons.push('LIFE_LINE_PERSONA_MISMATCH');
if (value.persona_id !== expectedPersonaId) result.reasons.push('LIFE_LINE_PERSONA_MISMATCH');
if (value.timezone !== TIMEZONE) result.reasons.push('LIFE_LINE_TIMEZONE_MISMATCH');
if (value.birth_date_beijing !== BIRTH_DATE) result.reasons.push('LIFE_LINE_BIRTH_ANCHOR_MISMATCH');
if (value.world_epoch_date !== WORLD_EPOCH_DATE) result.reasons.push('LIFE_LINE_WORLD_EPOCH_MISMATCH');
if (value.birth_date_beijing !== birthDateBeijing) result.reasons.push('LIFE_LINE_BIRTH_ANCHOR_MISMATCH');
if (value.world_epoch_date !== worldEpochDate) result.reasons.push('LIFE_LINE_WORLD_EPOCH_MISMATCH');
if (!Array.isArray(value.blocks)) result.reasons.push('LIFE_LINE_BLOCKS_NOT_ARRAY');
if (!value.genesis || typeof value.genesis !== 'object') result.reasons.push('LIFE_LINE_GENESIS_MISSING');
if (!Array.isArray(value.blocks) || !value.genesis) return result;
@ -114,23 +115,23 @@ export function verifyLifeLine({manifestPath, manifest = null, chainRoot = null,
const genesis = value.genesis;
result.sequence.genesis = true;
if (genesis.sequence !== 0) result.reasons.push('GENESIS_SEQUENCE_INVALID');
if (genesis.beijing_day !== BIRTH_DATE) result.reasons.push('GENESIS_DATE_INVALID');
if (genesis.beijing_day !== birthDateBeijing) result.reasons.push('GENESIS_DATE_INVALID');
if (genesis.previous_hash !== null) result.reasons.push('GENESIS_PREVIOUS_HASH_NOT_NULL');
if (genesis.era_day !== eraDay(BIRTH_DATE)) result.reasons.push('GENESIS_ERA_DAY_INVALID');
if (genesis.beijing_close_tick !== closeTick(BIRTH_DATE)) result.reasons.push('GENESIS_CLOSE_TICK_INVALID');
if (genesis.era_day !== eraDay(birthDateBeijing, worldEpochDate)) result.reasons.push('GENESIS_ERA_DAY_INVALID');
if (genesis.beijing_close_tick !== closeTick(birthDateBeijing)) result.reasons.push('GENESIS_CLOSE_TICK_INVALID');
if (genesis.hash !== lifeLineBlockHash(genesis)) result.reasons.push('GENESIS_HASH_MISMATCH');
verifyEvidence(root, genesis, result);
let previous = genesis;
result.sequence.blocks = value.blocks.length;
for (let index = 0; index < value.blocks.length; index += 1) {
const block = value.blocks[index], expectedSequence = index + 1, expectedDay = addDays(BIRTH_DATE, expectedSequence);
const block = value.blocks[index], expectedSequence = index + 1, expectedDay = addDays(birthDateBeijing, expectedSequence);
result.sequence.expected = expectedSequence;
if (!block || typeof block !== 'object') { result.reasons.push(`BLOCK_INVALID:${expectedSequence}`); continue; }
if (block.sequence !== expectedSequence) result.reasons.push(`BLOCK_SEQUENCE_INVALID:${expectedSequence}`);
if (block.beijing_day !== expectedDay) result.reasons.push(`BLOCK_DATE_OR_GAP:${expectedSequence}:${expectedDay}`);
if (block.previous_hash !== previous.hash) result.reasons.push(`BLOCK_PREVIOUS_HASH_MISMATCH:${expectedSequence}`);
if (block.era_day !== eraDay(block.beijing_day)) result.reasons.push(`BLOCK_ERA_DAY_INVALID:${expectedSequence}`);
if (block.era_day !== eraDay(block.beijing_day, worldEpochDate)) result.reasons.push(`BLOCK_ERA_DAY_INVALID:${expectedSequence}`);
if (block.beijing_close_tick !== closeTick(block.beijing_day)) result.reasons.push(`BLOCK_CLOSE_TICK_INVALID:${expectedSequence}`);
if (Date.parse(block.beijing_close_tick) > new Date(now).getTime()) result.reasons.push(`BLOCK_CLOSE_TICK_IN_FUTURE:${expectedSequence}`);
if (block.hash !== lifeLineBlockHash(block)) result.reasons.push(`BLOCK_HASH_MISMATCH:${expectedSequence}`);