diff --git a/deployment/receipts/JD-LIVING-TIME-DEPLOYMENT-PLAN-20260909.json b/deployment/receipts/JD-LIVING-TIME-DEPLOYMENT-PLAN-20260909.json new file mode 100644 index 0000000..5ccc153 --- /dev/null +++ b/deployment/receipts/JD-LIVING-TIME-DEPLOYMENT-PLAN-20260909.json @@ -0,0 +1,16 @@ +{ + "schema":"guanghu.jd-living-time-deployment-plan/v1", + "receipt_id":"JD-LIVING-TIME-DEPLOYMENT-PLAN-20260909", + "node_id":"JD-FD-PRIMARY", + "expected_dmi":"f3d4b730-7f02-452f-975b-7091a4800431", + "source_repository":"REPO-012", + "source_commit":"BIND_AFTER_COMMIT", + "target_release_root":"/opt/guanghu/architecture-releases", + "world_state":"/var/lib/guanghu/tcs-mother-body/world/CURRENT.json", + "gateway":"/usr/local/libexec/guanghu/cognitive-gateway.py", + "start_script":"/usr/local/libexec/guanghu/tcs-mother-brain-start.sh", + "rollback":"restore previous start script release path, gateway backup and world CURRENT; restart supervised child", + "expected_receipt":"/guanghu/recovery/JD-FD-PRIMARY-living-time-20260909/DEPLOYMENT-RECEIPT.json", + "reboot":false, + "grub_change":false +} diff --git a/server-tools/tcs-mother-body/cognitive-gateway.py b/server-tools/tcs-mother-body/cognitive-gateway.py index 568c9de..c62fd3c 100644 --- a/server-tools/tcs-mother-body/cognitive-gateway.py +++ b/server-tools/tcs-mother-body/cognitive-gateway.py @@ -2,7 +2,7 @@ """Bounded SSH ingress for the single TCS mother and zero-core shelf.""" import json,os,re,sys,urllib.request,urllib.error def endpoint(command): - fixed={'zy-rpc health':('GET','/health'),'zy-rpc mother-status':('GET','/v1/mother/status'),'zy-rpc shelf-shared':('GET','/v1/shelf/shared'),'zy-rpc shelf-fifth':('GET','/v1/shelf/fifth'),'zy-rpc shelf-public':('GET','/v1/shelf/public'),'zy-rpc mother-ingest':('POST','/v1/mother/ingest'),'zy-rpc door-challenge':('POST','/v1/door/challenge'),'zy-rpc door-attest':('POST','/v1/door/attest'),'zy-rpc door-model-test':('POST','/v1/door/model-test'),'zy-rpc lamp-ignite':('POST','/v1/lamp/ignite'),'zy-rpc lamp-ask':('POST','/v1/lamp/ask'),'zy-rpc world-status':('GET','/v1/world/status')} + fixed={'zy-rpc health':('GET','/health'),'zy-rpc mother-status':('GET','/v1/mother/status'),'zy-rpc shelf-shared':('GET','/v1/shelf/shared'),'zy-rpc shelf-fifth':('GET','/v1/shelf/fifth'),'zy-rpc shelf-public':('GET','/v1/shelf/public'),'zy-rpc mother-ingest':('POST','/v1/mother/ingest'),'zy-rpc door-challenge':('POST','/v1/door/challenge'),'zy-rpc door-attest':('POST','/v1/door/attest'),'zy-rpc door-model-test':('POST','/v1/door/model-test'),'zy-rpc lamp-ignite':('POST','/v1/lamp/ignite'),'zy-rpc lamp-ask':('POST','/v1/lamp/ask'),'zy-rpc world-status':('GET','/v1/world/status'),'zy-rpc time-now':('GET','/v1/time/now')} if command in fixed:return fixed[command] if re.fullmatch(r'zy-rpc mother-job [a-f0-9]{64}',command):return 'GET','/v1/mother/jobs/'+command.split()[-1] if re.fullmatch(r'zy-rpc world-resolve [A-Za-z0-9_.:∞-]{1,128}',command):return 'GET','/v1/world/resolve?id='+command.split()[-1] diff --git a/server-tools/tcs-mother-body/living-time.mjs b/server-tools/tcs-mother-body/living-time.mjs new file mode 100644 index 0000000..1b0079c --- /dev/null +++ b/server-tools/tcs-mother-body/living-time.mjs @@ -0,0 +1,26 @@ +const EPOCH_MS = Date.parse("2025-04-25T16:00:00.000Z"); +const DAY_MS = 86_400_000; + +export function livingTime(nowMs = Date.now()) { + if (!Number.isInteger(nowMs) || nowMs < EPOCH_MS) throw new Error("time_before_guanghu_epoch"); + const elapsed = nowMs - EPOCH_MS; + return { + schema: "guanghu.era-living-time-snapshot/v1", + state: "LIVE_REALITY_TIME_DERIVED", + observed_at_unix_ms: nowMs, + world: { + id: "SYS-GLW-0001", + era_id: "GUANGHU-ERA-0001", + visible_birth_date_beijing: "2025-04-26", + birth_fact_precision: "DATE", + exact_birth_instant: null, + calendar_epoch_boundary: "2025-04-26T00:00:00+08:00", + calendar_epoch_boundary_kind: "DETERMINISTIC_COMPUTATION_CONVENTION_NOT_CLAIMED_BIRTH_INSTANT", + era_day: Math.floor(elapsed / DAY_MS) + 1, + elapsed_days_completed: Math.floor(elapsed / DAY_MS), + elapsed_milliseconds: elapsed, + }, + time_control_channel: { id: "CH-GLW-TIME-0001", path: "glw://time/control" }, + clock: { source: "REALITY_SYSTEM_CLOCK_UTC", stored_tick_counter: false, persona_wake_required: false, scheduler_required: false }, + }; +} diff --git a/server-tools/tcs-mother-body/living-time.test.mjs b/server-tools/tcs-mother-body/living-time.test.mjs new file mode 100644 index 0000000..26ed962 --- /dev/null +++ b/server-tools/tcs-mother-body/living-time.test.mjs @@ -0,0 +1,17 @@ +import assert from "node:assert/strict"; +import test from "node:test"; +import { livingTime } from "./living-time.mjs"; + +test("birth boundary is era day one", () => { + const value = livingTime(Date.parse("2025-04-25T16:00:00.000Z")); + assert.equal(value.world.era_day, 1); + assert.equal(value.world.elapsed_milliseconds, 0); +}); + +test("milliseconds advance without wake counter", () => { + const first = livingTime(Date.parse("2026-09-09T00:00:00.000Z")); + const second = livingTime(Date.parse("2026-09-09T00:00:00.017Z")); + assert.equal(second.world.elapsed_milliseconds - first.world.elapsed_milliseconds, 17); + assert.equal(second.clock.stored_tick_counter, false); + assert.equal(second.clock.persona_wake_required, false); +}); diff --git a/server-tools/tcs-mother-body/server.mjs b/server-tools/tcs-mother-body/server.mjs index 9b0ae47..7c11626 100644 --- a/server-tools/tcs-mother-body/server.mjs +++ b/server-tools/tcs-mother-body/server.mjs @@ -1,5 +1,5 @@ #!/usr/bin/env node -import http from 'node:http';import fs from 'node:fs';import crypto from 'node:crypto';import {ModelRouter} from './model-router.mjs';import {CognitiveShelf} from './cognitive-shelf.mjs';import {DoorLamp} from './door-lamp.mjs';import {WorldStateStore} from './world-state.mjs';import {LivingLamp} from './living-lamp.mjs'; +import http from 'node:http';import fs from 'node:fs';import crypto from 'node:crypto';import {ModelRouter} from './model-router.mjs';import {CognitiveShelf} from './cognitive-shelf.mjs';import {DoorLamp} from './door-lamp.mjs';import {WorldStateStore} from './world-state.mjs';import {LivingLamp} from './living-lamp.mjs';import {livingTime} from './living-time.mjs'; const HOST='127.0.0.1',PORT=Number(process.env.TCS_MOTHER_BRAIN_PORT||3931),ROOT=process.env.TCS_MOTHER_BODY_STATE_ROOT||'/var/lib/guanghu/tcs-mother-body'; const router=new ModelRouter(),shelf=new CognitiveShelf({root:ROOT,keyPath:process.env.TCS_MOTHER_SIGNING_KEY,seedPath:process.env.TCS_MOTHER_SEED,router}),routes=JSON.parse(fs.readFileSync(process.env.TCS_PERSONA_ROUTES)),door=new DoorLamp({root:ROOT+'/door',shelf,routes}),world=new WorldStateStore(process.env.TCS_WORLD_STATE_PATH||ROOT+'/world/CURRENT.json'),lamp=new LivingLamp({root:ROOT+'/living-lamp',key:crypto.createPrivateKey(fs.readFileSync(process.env.TCS_MOTHER_SIGNING_KEY)),navigationPath:process.env.TCS_LIT_NAVIGATION_MAP,scope:'FIFTH_DOMAIN'}); setInterval(()=>shelf.drain(),2000).unref();shelf.drain(); @@ -16,6 +16,7 @@ if(q.method==='POST'&&u.pathname==='/v1/door/attest')return send(r,200,door.atte if(q.method==='POST'&&u.pathname==='/v1/door/model-test'){const shared=shelf.current('shared');const result=await router.cognize('door-test',{shared_cognition:shared.value,questions:['unknown_guanghu_information_source','identity_before_persona_load','reality_authority_from_cognition']});return send(r,200,{outcome:'PASS',provider:result.provider,answers:result.value,shared_sha256:shared.artifact.sha256,credentials_exposed:false});} if(q.method==='GET'&&u.pathname==='/v1/world/status')return send(r,200,world.status()); if(q.method==='GET'&&u.pathname==='/v1/world/resolve')return send(r,200,world.resolve(String(u.searchParams.get('id')||''))); +if(q.method==='GET'&&u.pathname==='/v1/time/now')return send(r,200,livingTime()); if(q.method==='POST'&&u.pathname==='/v1/lamp/ignite')return send(r,200,lamp.ignite(await body(q,20000))); if(q.method==='POST'&&u.pathname==='/v1/lamp/ask')return send(r,200,lamp.ask(await body(q,20000))); return send(r,404,{error:'not_found'});}catch(e){return send(r,400,{error:String(e.message||e).slice(0,300)});}}).listen(PORT,HOST,()=>process.stdout.write(`tcs-single-mother listening ${HOST}:${PORT}\n`));