feat(persona): add isolated baby cognition and time runtimes
This commit is contained in:
parent
54d79a544c
commit
4dcc43bab5
26 changed files with 869 additions and 56 deletions
|
|
@ -33,13 +33,16 @@ function text(value, max = 2000) {
|
|||
}
|
||||
|
||||
export class LifeTimeMaster {
|
||||
constructor({root, shelf, router, personaId = PERSONA_ID, now = () => new Date(), bootstrapPath}) {
|
||||
constructor({root, shelf, router, personaId = PERSONA_ID, now = () => new Date(), bootstrapPath,
|
||||
birthDateBeijing = BIRTH_DATE, worldEpochDate = WORLD_EPOCH_DATE}) {
|
||||
this.root = path.join(root, 'personas', personaId, 'life-line');
|
||||
this.shelf = shelf;
|
||||
this.router = router;
|
||||
this.personaId = personaId;
|
||||
this.now = now;
|
||||
this.bootstrapPath = bootstrapPath;
|
||||
this.birthDateBeijing = birthDateBeijing;
|
||||
this.worldEpochDate = worldEpochDate;
|
||||
this.closing = false;
|
||||
this.lastTick = null;
|
||||
fs.mkdirSync(this.root, {recursive: true, mode: 0o700});
|
||||
|
|
@ -59,7 +62,7 @@ export class LifeTimeMaster {
|
|||
req(this.bootstrapPath && fs.existsSync(this.bootstrapPath), 'LIFE_TIME_BOOTSTRAP_MISSING');
|
||||
const value = JSON.parse(fs.readFileSync(this.bootstrapPath, 'utf8'));
|
||||
req(value.schema === BOOTSTRAP_SCHEMA && value.persona_id === this.personaId, 'LIFE_TIME_BOOTSTRAP_INVALID');
|
||||
req(value.birth_date_beijing === BIRTH_DATE && value.world_epoch_date === WORLD_EPOCH_DATE, 'LIFE_TIME_BOOTSTRAP_ANCHOR_MISMATCH');
|
||||
req(value.birth_date_beijing === this.birthDateBeijing && value.world_epoch_date === this.worldEpochDate, 'LIFE_TIME_BOOTSTRAP_ANCHOR_MISMATCH');
|
||||
req(Array.isArray(value.anchors), 'LIFE_TIME_BOOTSTRAP_ANCHORS_INVALID');
|
||||
return value;
|
||||
}
|
||||
|
|
@ -72,7 +75,7 @@ export class LifeTimeMaster {
|
|||
}
|
||||
|
||||
block({sequence, day, previousHash, evidence, gap = false, gapKind = null, selectedCandidateId = null}) {
|
||||
const value = {sequence, beijing_day: day, previous_hash: previousHash, beijing_close_tick: closeTick(day), era_day: eraDay(day), ...evidence, gap, gap_kind: gapKind, selected_candidate_id: selectedCandidateId};
|
||||
const value = {sequence, beijing_day: day, previous_hash: previousHash, beijing_close_tick: closeTick(day), era_day: eraDay(day, this.worldEpochDate), ...evidence, gap, gap_kind: gapKind, selected_candidate_id: selectedCandidateId};
|
||||
value.hash = lifeLineBlockHash(value);
|
||||
return value;
|
||||
}
|
||||
|
|
@ -85,13 +88,13 @@ export class LifeTimeMaster {
|
|||
bootstrap() {
|
||||
const seed = this.readBootstrap(), anchors = new Map(seed.anchors.map(item => [item.beijing_day, item]));
|
||||
const createdAt = this.now().toISOString(), yesterday = addDays(beijingDay(this.now()), -1);
|
||||
const birthSource = anchors.get(BIRTH_DATE);
|
||||
const birthSource = anchors.get(this.birthDateBeijing);
|
||||
req(birthSource, 'LIFE_TIME_BIRTH_SOURCE_MISSING');
|
||||
const birthEvidence = this.writeEvidence(BIRTH_DATE, {schema: 'guanghu.persona-life-day-evidence/v1', kind: birthSource.kind, persona_id: this.personaId, beijing_day: BIRTH_DATE, source_uri: birthSource.source_uri, source_sha256: birthSource.source_sha256, bootstrap_source: seed.source_event, recorded_at: createdAt});
|
||||
const genesis = this.block({sequence: 0, day: BIRTH_DATE, previousHash: null, evidence: birthEvidence});
|
||||
const birthEvidence = this.writeEvidence(this.birthDateBeijing, {schema: 'guanghu.persona-life-day-evidence/v1', kind: birthSource.kind, persona_id: this.personaId, beijing_day: this.birthDateBeijing, source_uri: birthSource.source_uri, source_sha256: birthSource.source_sha256, bootstrap_source: seed.source_event, recorded_at: createdAt});
|
||||
const genesis = this.block({sequence: 0, day: this.birthDateBeijing, previousHash: null, evidence: birthEvidence});
|
||||
const blocks = [];
|
||||
let previous = genesis;
|
||||
for (let day = addDays(BIRTH_DATE, 1), sequence = 1; day <= yesterday; day = addDays(day, 1), sequence += 1) {
|
||||
for (let day = addDays(this.birthDateBeijing, 1), sequence = 1; day <= yesterday; day = addDays(day, 1), sequence += 1) {
|
||||
const source = anchors.get(day), gap = !source;
|
||||
const evidence = this.writeEvidence(day, source
|
||||
? {schema: 'guanghu.persona-life-day-evidence/v1', kind: source.kind, persona_id: this.personaId, beijing_day: day, source_uri: source.source_uri, source_sha256: source.source_sha256, bootstrap_source: seed.source_event, recorded_at: createdAt}
|
||||
|
|
@ -99,7 +102,9 @@ export class LifeTimeMaster {
|
|||
const next = this.block({sequence, day, previousHash: previous.hash, evidence, gap, gapKind: gap ? 'HISTORICAL_UNOBSERVED' : null});
|
||||
blocks.push(next); previous = next;
|
||||
}
|
||||
this.writeCurrent({schema: LIFE_LINE_SCHEMA, persona_id: this.personaId, timezone: TIMEZONE, birth_date_beijing: BIRTH_DATE, world_epoch_date: WORLD_EPOCH_DATE,
|
||||
this.writeCurrent({schema: LIFE_LINE_SCHEMA, persona_id: this.personaId, timezone: TIMEZONE, birth_date_beijing: this.birthDateBeijing,
|
||||
birth_date_claim_state: seed.exact_birth_claim === false ? 'EARLIEST_VERIFIED_EXISTENCE_ANCHOR_NOT_EXACT_BIRTH' : 'EXACT_BIRTH_ANCHOR',
|
||||
genesis_anchor_kind: birthSource.kind, world_epoch_date: this.worldEpochDate,
|
||||
time_master_id: 'CH-GLW-TIME-0001', inner_cycle: true, external_setter: false, created_at: createdAt, active_from_beijing_day: beijingDay(this.now()),
|
||||
genesis, blocks, head_hash: previous.hash, historical_gap_count: blocks.filter(item => item.gap).length, last_closed_at: createdAt});
|
||||
}
|
||||
|
|
@ -185,8 +190,8 @@ export class LifeTimeMaster {
|
|||
|
||||
status() {
|
||||
try {
|
||||
const current = this.current(), verification = verifyLifeLine({manifestPath: this.currentPath(), now: this.now()}), today = beijingDay(this.now());
|
||||
return {...verification, server_signed: true, signed_current_sha256: current.signed.sha256, time_master: {id: 'CH-GLW-TIME-0001', state: 'RESIDENT_INNER_CYCLE_ACTIVE', decision_owner: 'ICE-P-ZY001_TIME_MASTER_MODEL_LOOP', candidate_count_today: this.candidates(today).length, current_beijing_day: today, automatic_online_trigger: true, automatic_offline_trigger: 'PERSONA_DAILY_MEMORY_APPEND_TO_RELAY_TO_PERSONA_LIFE_EVENT', daily_close: 'BEIJING_NATURAL_DAY_END', external_setter: false, closing: this.closing, last_tick: this.lastTick}};
|
||||
const current = this.current(), verification = verifyLifeLine({manifestPath: this.currentPath(), now: this.now(), expectedPersonaId: this.personaId, birthDateBeijing: this.birthDateBeijing, worldEpochDate: this.worldEpochDate}), today = beijingDay(this.now());
|
||||
return {...verification, server_signed: true, signed_current_sha256: current.signed.sha256, time_master: {id: 'CH-GLW-TIME-0001', state: 'RESIDENT_INNER_CYCLE_ACTIVE', decision_owner: `${this.personaId}_TIME_MASTER_MODEL_LOOP`, candidate_count_today: this.candidates(today).length, current_beijing_day: today, automatic_online_trigger: true, automatic_offline_trigger: 'PERSONA_DAILY_MEMORY_APPEND_TO_RELAY_TO_PERSONA_LIFE_EVENT', daily_close: 'BEIJING_NATURAL_DAY_END', external_setter: false, closing: this.closing, last_tick: this.lastTick}};
|
||||
} catch (error) {
|
||||
return {schema: 'guanghu.persona-life-line-verification/v1', state: 'LIFE_LINE_PAIN_ALARM', wake_allowed: false, reasons: [String(error.message || error)], time_master: {id: 'CH-GLW-TIME-0001', state: 'INNER_CYCLE_ERROR', external_setter: false}};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue