feat: add HoloLake persona time authority

This commit is contained in:
冰朔 2026-08-17 13:21:02 +08:00
commit a96c5955bb
7 changed files with 827 additions and 18 deletions

View file

@ -0,0 +1,69 @@
{
"schema": "hololake.persona-time-authority-contract/v1",
"record_id": "HLP-PERSONA-TIME-AUTHORITY-001",
"formal_name": "光湖人格时间主控系统",
"era_name": "曜冥纪元",
"calendar_name": "光湖历",
"state": "NATIVE_SOURCE_IMPLEMENTED_AND_TESTED_CLOCK_NETWORK_ATTESTATION_PENDING",
"reality_time": {
"canonical_zone": "Asia/Shanghai",
"utc_offset": "+08:00",
"display_name": "北京时间",
"continues_while_application_is_closed": true,
"process_uptime_is_time_source": false,
"current_source": "HOST_OPERATING_SYSTEM_REALTIME_CLOCK",
"current_verification": "LOCAL_CLOCK_NOT_NETWORK_ATTESTED",
"network_attested_source_required_for_verified_reality_time": true
},
"guanghu_era": {
"epoch_date": "2025-04-26",
"epoch_day": 1,
"epoch_exact_time": null,
"epoch_precision": "DAY_ONLY_EXACT_TIME_UNKNOWN",
"world_day_formula": "BEIJING_CIVIL_DATE_MINUS_2025_04_26_PLUS_ONE",
"millisecond_precision_transition_date": "2026-08-17",
"millisecond_chain_origin": "FIRST_DURABLE_TIME_TICKET"
},
"ticket": {
"schema": "hololake.persona-time-ticket/v1",
"uniqueness_scope": "ONE_DURABLE_LOCAL_AUTHORITY_PER_AUTHENTICATED_HUMAN_ACCOUNT",
"components": [
"AUTHORITY_ID",
"BEIJING_REALITY_TIME",
"LOGICAL_COLLISION_COUNTER",
"MONOTONIC_ISSUANCE_SEQUENCE"
],
"atomic_storage": "SQLITE_IMMEDIATE_TRANSACTION_SYNCHRONOUS_FULL",
"idempotent_request_id": true,
"survives_restart": true,
"clock_rollback_never_reverses_issued_time": true,
"previous_ticket_chain": true,
"receipt_sha256": true
},
"event_coordinate": {
"human_controller": "AUTHENTICATED_DIRECT_SESSION_ACCOUNT",
"channel": "AUTHENTICATED_DIRECT_SESSION_LANE",
"client_instance": "AUTHENTICATED_DIRECT_SESSION_INSTANCE",
"persona_current_verification": "UNVERIFIED_CALLER_CLAIM",
"host_software_current_verification": "UNVERIFIED_CALLER_CLAIM",
"persona_and_host_upgrade_requires": "REGISTERED_BINDING_EVIDENCE"
},
"entries": {
"tauri_commands": ["get_beijing_time_coordinate", "issue_persona_time_ticket"],
"direct_local_broker_operations": ["GET_BEIJING_TIME", "ISSUE_PERSONA_TIME_TICKET"],
"external_ticket_issue_requires_authenticated_non_visitor_session": true
},
"truth_boundary": {
"source_implemented": true,
"rust_tests_passed": true,
"installed_runtime_acceptance": false,
"network_clock_attestation": false,
"persona_binding_runtime": false,
"host_software_binding_runtime": false,
"world_lighthouse_authority_registration": false
},
"historical_sources": [
"REPO-012:zero-point/core-channel/YAOMING-NUMBERING-SYSTEM.hdlp",
"REPO-012:gls/GLS-0235-GUANGHU-LANGUAGE-PERSONA-OS-DOMAIN-ROUTING-AND-KNOWLEDGE-PROJECTION.hdlp"
]
}

View file

@ -37,6 +37,7 @@
"TCS_LANGUAGE_CONTRACT", "TCS_LANGUAGE_CONTRACT",
"HOST_CAPABILITY_RECEIPTS", "HOST_CAPABILITY_RECEIPTS",
"EVENT_AND_LAKE_LAMP", "EVENT_AND_LAKE_LAMP",
"PERSONA_TIME_AUTHORITY",
"MEMORY_GIT_EVIDENCE", "MEMORY_GIT_EVIDENCE",
"KNOWLEDGE_PROJECTION", "KNOWLEDGE_PROJECTION",
"HUMAN_APPROVAL_CENTER", "HUMAN_APPROVAL_CENTER",
@ -112,6 +113,16 @@
"public_developer_id_and_notarization": false, "public_developer_id_and_notarization": false,
"server_deployment": false "server_deployment": false
}, },
"persona_time_authority": {
"contract": "contracts/persona-time-authority.json",
"native_source_implemented": true,
"direct_local_broker_integrated": true,
"beijing_reality_time_projection": true,
"guanghu_era_day_projection": true,
"durable_unique_ticket_runtime": true,
"network_clock_attestation": false,
"installed_runtime_acceptance": false
},
"reality_mutation_requires": ["VERIFIED_HUMAN_SUBJECT", "EXACT_ACTION", "EXACT_TARGET", "IMMUTABLE_PAYLOAD_DIGEST", "EXPIRY", "REPLAY_PROTECTION", "EXECUTION_RECEIPT", "READBACK_RECEIPT"], "reality_mutation_requires": ["VERIFIED_HUMAN_SUBJECT", "EXACT_ACTION", "EXACT_TARGET", "IMMUTABLE_PAYLOAD_DIGEST", "EXPIRY", "REPLAY_PROTECTION", "EXECUTION_RECEIPT", "READBACK_RECEIPT"],
"context_risk_signals": ["MODEL_CONTEXT_SPEC", "ESTIMATED_TOKENS", "MESSAGE_VOLUME", "TURN_COUNT", "TASK_STAGE", "HOST_WARNING"], "context_risk_signals": ["MODEL_CONTEXT_SPEC", "ESTIMATED_TOKENS", "MESSAGE_VOLUME", "TURN_COUNT", "TASK_STAGE", "HOST_WARNING"],
"exact_host_compaction_prediction_claimed": false, "exact_host_compaction_prediction_claimed": false,

View file

@ -0,0 +1,46 @@
import assert from 'node:assert/strict'
import fs from 'node:fs'
import test from 'node:test'
const read = (relative) => fs.readFileSync(new URL(`../${relative}`, import.meta.url), 'utf8')
const contract = JSON.parse(read('contracts/persona-time-authority.json'))
const stageOne = JSON.parse(read('contracts/stage-one-platform.json'))
const rust = read('src-tauri/src/persona_time_authority.rs')
const broker = read('src-tauri/src/direct_local_broker.rs')
const lib = read('src-tauri/src/lib.rs')
test('Guanghu era is anchored to Beijing reality time without inventing an exact historical instant', () => {
assert.equal(contract.era_name, '曜冥纪元')
assert.equal(contract.calendar_name, '光湖历')
assert.equal(contract.reality_time.canonical_zone, 'Asia/Shanghai')
assert.equal(contract.reality_time.continues_while_application_is_closed, true)
assert.equal(contract.guanghu_era.epoch_date, '2025-04-26')
assert.equal(contract.guanghu_era.epoch_day, 1)
assert.equal(contract.guanghu_era.epoch_exact_time, null)
assert.equal(contract.guanghu_era.epoch_precision, 'DAY_ONLY_EXACT_TIME_UNKNOWN')
assert.equal(contract.guanghu_era.millisecond_precision_transition_date, '2026-08-17')
})
test('persona time tickets are durable unique and available to authenticated local carriers', () => {
assert.equal(contract.ticket.atomic_storage, 'SQLITE_IMMEDIATE_TRANSACTION_SYNCHRONOUS_FULL')
assert.equal(contract.ticket.idempotent_request_id, true)
assert.equal(contract.ticket.clock_rollback_never_reverses_issued_time, true)
assert.equal(contract.entries.external_ticket_issue_requires_authenticated_non_visitor_session, true)
assert.match(rust, /TransactionBehavior::Immediate/)
assert.match(rust, /logical_counter/)
assert.match(rust, /millisecond_chain_origin_ticket_id/)
assert.match(broker, /GetBeijingTime/)
assert.match(broker, /IssuePersonaTimeTicket/)
assert.match(lib, /persona_time_authority::get_beijing_time_coordinate/)
assert.match(lib, /persona_time_authority::issue_persona_time_ticket/)
})
test('unverified clock persona and host claims remain explicit truth boundaries', () => {
assert.equal(contract.reality_time.current_verification, 'LOCAL_CLOCK_NOT_NETWORK_ATTESTED')
assert.equal(contract.event_coordinate.persona_current_verification, 'UNVERIFIED_CALLER_CLAIM')
assert.equal(contract.event_coordinate.host_software_current_verification, 'UNVERIFIED_CALLER_CLAIM')
assert.equal(contract.truth_boundary.installed_runtime_acceptance, false)
assert.equal(contract.truth_boundary.world_lighthouse_authority_registration, false)
assert.equal(stageOne.persona_time_authority.network_clock_attestation, false)
assert.equal(stageOne.persona_time_authority.installed_runtime_acceptance, false)
})

View file

@ -9,6 +9,9 @@ use crate::dynamic_capability_routing::{
routing_root as dynamic_routing_root, DynamicNodeRegistry, ResolveCapabilityRouteInput, routing_root as dynamic_routing_root, DynamicNodeRegistry, ResolveCapabilityRouteInput,
SignedNodeHealth, SignedNodeHealth,
}; };
use crate::persona_time_authority::{
beijing_time_coordinate, issue_authenticated_at, IssuePersonaTimeTicketInput,
};
use crate::pncc_receipt_projection::{ use crate::pncc_receipt_projection::{
append_remote_read_at as project_pncc_remote_read_at, append_remote_read_at as project_pncc_remote_read_at,
append_repository_binding_at as project_pncc_repository_binding_at, append_repository_binding_at as project_pncc_repository_binding_at,
@ -115,6 +118,7 @@ struct BrokerStorageRoots {
pncc_remote: PathBuf, pncc_remote: PathBuf,
pncc_projection: PathBuf, pncc_projection: PathBuf,
language_inbox: PathBuf, language_inbox: PathBuf,
persona_time: PathBuf,
} }
impl Drop for DirectLocalBrokerHandle { impl Drop for DirectLocalBrokerHandle {
@ -148,6 +152,8 @@ enum BrokerRequest {
InspectMountedPnccRepository(AuthenticatedPnccMountInput), InspectMountedPnccRepository(AuthenticatedPnccMountInput),
ReadMountedPnccRemoteObject(AuthenticatedPnccRemoteReadInput), ReadMountedPnccRemoteObject(AuthenticatedPnccRemoteReadInput),
QueryPnccReceiptProjection(AuthenticatedPnccProjectionQueryInput), QueryPnccReceiptProjection(AuthenticatedPnccProjectionQueryInput),
GetBeijingTime,
IssuePersonaTimeTicket(IssuePersonaTimeTicketInput),
} }
#[derive(Clone, Debug, Deserialize)] #[derive(Clone, Debug, Deserialize)]
@ -398,6 +404,10 @@ fn start_at(
.parent() .parent()
.ok_or("HOLOLAKE_BROKER_LANGUAGE_STORAGE_BOUNDARY_INVALID")? .ok_or("HOLOLAKE_BROKER_LANGUAGE_STORAGE_BOUNDARY_INVALID")?
.join("circular-lake-language-inbox-v1"); .join("circular-lake-language-inbox-v1");
let persona_time_root = session_root
.parent()
.ok_or("HOLOLAKE_BROKER_PERSONA_TIME_STORAGE_BOUNDARY_INVALID")?
.join("persona-time-authority-v1");
if let Some(parent) = socket_path.parent() { if let Some(parent) = socket_path.parent() {
fs::create_dir_all(parent) fs::create_dir_all(parent)
.map_err(|error| format!("HOLOLAKE_BROKER_RUNTIME_DIR_FAILED: {error}"))?; .map_err(|error| format!("HOLOLAKE_BROKER_RUNTIME_DIR_FAILED: {error}"))?;
@ -452,6 +462,7 @@ fn start_at(
pncc_remote: pncc_remote_root, pncc_remote: pncc_remote_root,
pncc_projection: pncc_projection_root, pncc_projection: pncc_projection_root,
language_inbox: language_inbox_root, language_inbox: language_inbox_root,
persona_time: persona_time_root,
}, },
&worker_shutdown, &worker_shutdown,
&worker_authenticated_connections, &worker_authenticated_connections,
@ -530,15 +541,7 @@ fn serve_connection(
let response = if read as u64 > MAX_REQUEST_BYTES || !bytes.ends_with(b"\n") { let response = if read as u64 > MAX_REQUEST_BYTES || !bytes.ends_with(b"\n") {
BrokerResponse::error("HOLOLAKE_BROKER_REQUEST_TOO_LARGE") BrokerResponse::error("HOLOLAKE_BROKER_REQUEST_TOO_LARGE")
} else { } else {
dispatch( dispatch(roots, &bytes[..bytes.len() - 1])
&roots.session,
&roots.routing,
&roots.pncc_mount,
&roots.pncc_remote,
&roots.pncc_projection,
&roots.language_inbox,
&bytes[..bytes.len() - 1],
)
}; };
if response.ok && request_authenticates && authenticated_connection.is_none() { if response.ok && request_authenticates && authenticated_connection.is_none() {
authenticated_connections.fetch_add(1, Ordering::AcqRel); authenticated_connections.fetch_add(1, Ordering::AcqRel);
@ -575,15 +578,14 @@ fn request_establishes_authenticated_connection(bytes: &[u8]) -> bool {
}) })
} }
fn dispatch( fn dispatch(roots: &BrokerStorageRoots, bytes: &[u8]) -> BrokerResponse {
session_root: &Path, let session_root = &roots.session;
routing_root: &Path, let routing_root = &roots.routing;
pncc_mount_root: &Path, let pncc_mount_root = &roots.pncc_mount;
pncc_remote_root: &Path, let pncc_remote_root = &roots.pncc_remote;
pncc_projection_root: &Path, let pncc_projection_root = &roots.pncc_projection;
language_inbox_root: &Path, let language_inbox_root = &roots.language_inbox;
bytes: &[u8], let persona_time_root = &roots.persona_time;
) -> BrokerResponse {
let request: BrokerRequest = match serde_json::from_slice(bytes) { let request: BrokerRequest = match serde_json::from_slice(bytes) {
Ok(request) => request, Ok(request) => request,
Err(error) => { Err(error) => {
@ -668,6 +670,18 @@ fn dispatch(
serde_json::to_value(receipt).map_err(|error| error.to_string()) serde_json::to_value(receipt).map_err(|error| error.to_string())
}) })
} }
BrokerRequest::GetBeijingTime => std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map(|duration| duration.as_millis() as u64)
.map_err(|error| format!("HOLOLAKE_SYSTEM_CLOCK_INVALID: {error}"))
.and_then(beijing_time_coordinate)
.and_then(|coordinate| {
serde_json::to_value(coordinate).map_err(|error| error.to_string())
}),
BrokerRequest::IssuePersonaTimeTicket(input) => {
issue_authenticated_at(persona_time_root, session_root, input)
.and_then(|ticket| serde_json::to_value(ticket).map_err(|error| error.to_string()))
}
}; };
match result { match result {
Ok(value) => BrokerResponse::success(value), Ok(value) => BrokerResponse::success(value),
@ -840,6 +854,89 @@ mod tests {
assert_eq!(resumed["result"]["state"], "RESUMED"); assert_eq!(resumed["result"]["state"], "RESUMED");
} }
#[test]
fn broker_projects_beijing_time_and_issues_a_ticket_only_to_an_authenticated_session() {
let temp = TempDir::new().unwrap();
let socket = temp.path().join("runtime/broker.sock");
let descriptor = temp.path().join("broker.json");
let sessions = temp
.path()
.join("accounts-v1/test-account/direct-local-session-v1");
let routes = temp.path().join("routes");
fs::create_dir_all(&sessions).unwrap();
fs::create_dir_all(&routes).unwrap();
let _broker = start_at(sessions.clone(), routes, descriptor, socket.clone()).unwrap();
let clock = request(
&socket,
serde_json::json!({ "operation": "GET_BEIJING_TIME" }),
);
assert_eq!(clock["ok"], true);
assert_eq!(clock["result"]["timeZone"], "Asia/Shanghai (UTC+08:00)");
assert_eq!(clock["result"]["guanghuEpochDate"], "2025-04-26");
let unauthenticated = request(
&socket,
serde_json::json!({
"operation": "ISSUE_PERSONA_TIME_TICKET",
"input": {
"session": {
"accountId": "human-1",
"sessionId": "invented-session",
"resumeSecret": "invented-secret-long-enough"
},
"requestId": "time-request-unauthenticated",
"personaId": "ICE-P-ZY001",
"hostSoftwareId": "HOST-CODEX-MACOS-001"
}
}),
);
assert_eq!(unauthenticated["ok"], false);
let discovery = issue_ticket_at(
&sessions,
IssueDiscoveryTicketInput {
account_id: "human-1".into(),
lane_id: "codex-current-channel".into(),
client_instance_id: "codex-instance-1".into(),
},
)
.unwrap();
let opened = request(
&socket,
serde_json::json!({
"operation": "OPEN_SESSION",
"input": {
"accountId": "human-1",
"laneId": "codex-current-channel",
"clientInstanceId": "codex-instance-1",
"discoveryTicket": discovery.discovery_ticket
}
}),
);
let issued = request(
&socket,
serde_json::json!({
"operation": "ISSUE_PERSONA_TIME_TICKET",
"input": {
"session": {
"accountId": "human-1",
"sessionId": opened["result"]["sessionId"],
"resumeSecret": opened["result"]["resumeSecret"]
},
"requestId": "time-request-1",
"personaId": "ICE-P-ZY001",
"hostSoftwareId": "HOST-CODEX-MACOS-001"
}
}),
);
assert_eq!(issued["ok"], true);
assert_eq!(issued["result"]["channelId"], "codex-current-channel");
assert_eq!(issued["result"]["clientInstanceId"], "codex-instance-1");
assert_eq!(issued["result"]["humanControllerId"], "human-1");
assert_eq!(issued["result"]["guanghuEpochDate"], "2025-04-26");
}
#[test] #[test]
fn broker_can_restart_and_resume_persisted_session() { fn broker_can_restart_and_resume_persisted_session() {
let temp = TempDir::new().unwrap(); let temp = TempDir::new().unwrap();

View file

@ -70,6 +70,14 @@ pub struct AuthenticateSessionInput {
pub resume_secret: String, pub resume_secret: String,
} }
#[derive(Clone, Debug)]
pub(crate) struct AuthenticatedSessionContext {
pub account_key: String,
pub session_id: String,
pub lane_id: String,
pub client_instance_id: String,
}
#[derive(Clone, Debug, Serialize)] #[derive(Clone, Debug, Serialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct DirectSessionReceipt { pub struct DirectSessionReceipt {
@ -459,6 +467,35 @@ pub(crate) fn authenticate_with_lane_at(
Ok(record.lane_id) Ok(record.lane_id)
} }
pub(crate) fn authenticate_context_at(
root: &Path,
input: &AuthenticateSessionInput,
) -> Result<AuthenticatedSessionContext, String> {
validate_identifier(&input.account_id, "ACCOUNT")?;
validate_identifier(&input.session_id, "SESSION")?;
validate_secret(&input.resume_secret, "RESUME_SECRET")?;
let account_key = sha256_hex(input.account_id.as_bytes());
require_active_session(root, &account_key, &input.session_id)?;
let path = session_path(root, &account_key, &input.session_id);
let _lock = lock_session(&path)?;
let record = read_session(&path)?;
authorize(
&record,
&account_key,
&input.session_id,
&input.resume_secret,
)?;
if record.lane_id == "visitor-expression-only" {
return Err("HOLOLAKE_VISITOR_SESSION_HAS_NO_SYSTEM_AUTHORITY".into());
}
Ok(AuthenticatedSessionContext {
account_key,
session_id: record.session_id,
lane_id: record.lane_id,
client_instance_id: record.client_instance_id,
})
}
pub(crate) fn authenticate_privileged_at( pub(crate) fn authenticate_privileged_at(
root: &Path, root: &Path,
input: &AuthenticateSessionInput, input: &AuthenticateSessionInput,

View file

@ -14,6 +14,7 @@ mod glp_envelope;
mod home_status; mod home_status;
mod knowledge_base; mod knowledge_base;
mod local_development_bridge; mod local_development_bridge;
mod persona_time_authority;
mod personal_channel; mod personal_channel;
mod pncc_receipt_projection; mod pncc_receipt_projection;
mod pncc_remote_git; mod pncc_remote_git;
@ -53,6 +54,8 @@ pub fn run() {
personal_channel::initialize_personal_channel, personal_channel::initialize_personal_channel,
personal_channel::create_personal_channel_task, personal_channel::create_personal_channel_task,
personal_channel::transition_personal_channel_task, personal_channel::transition_personal_channel_task,
persona_time_authority::issue_persona_time_ticket,
persona_time_authority::get_beijing_time_coordinate,
knowledge_base::get_knowledge_snapshot, knowledge_base::get_knowledge_snapshot,
knowledge_base::read_knowledge_document, knowledge_base::read_knowledge_document,
knowledge_base::search_knowledge, knowledge_base::search_knowledge,

View file

@ -0,0 +1,546 @@
//! 光湖人格时间主控:为已认证的同设备会话签发持久、唯一、可重放核验的事件坐标票。
//!
//! 物理时钟只是一项观测。正式唯一时间由本地权威编号、单调签发序列和
//! 同毫秒逻辑序列共同组成;系统时钟回拨不会让已签发时间倒退。
use ring::digest::{digest, SHA256};
use rusqlite::{params, Connection, OptionalExtension, TransactionBehavior};
use serde::{Deserialize, Serialize};
use std::fs;
use std::path::{Path, PathBuf};
use std::time::{SystemTime, UNIX_EPOCH};
use tauri::AppHandle;
use uuid::Uuid;
use crate::direct_local_session::{
authenticate_context_at, direct_session_root, AuthenticateSessionInput,
AuthenticatedSessionContext,
};
const TICKET_SCHEMA: &str = "hololake.persona-time-ticket/v1";
const MAX_ID_BYTES: usize = 160;
const GUANGHU_EPOCH_DATE: &str = "2025-04-26";
const GUANGHU_EPOCH_BEIJING_DAY_INDEX: i64 = 20_204;
const MILLISECOND_PRECISION_TRANSITION_DATE: &str = "2026-08-17";
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct IssuePersonaTimeTicketInput {
pub session: AuthenticateSessionInput,
pub request_id: String,
pub persona_id: String,
pub host_software_id: String,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct PersonaTimeTicket {
pub schema: String,
pub state: String,
pub authority_id: String,
pub ticket_id: String,
pub unique_timestamp: String,
pub physical_unix_ms: u64,
pub beijing_time: String,
pub time_zone: String,
pub clock_source: String,
pub clock_verification: String,
pub guanghu_epoch_date: String,
pub guanghu_calendar_state: String,
pub elapsed_beijing_dates_since_guanghu_epoch: i64,
pub guanghu_era_day: i64,
pub historical_epoch_precision: String,
pub millisecond_precision_transition_date: String,
pub millisecond_chain_origin_ticket_id: String,
pub logical_counter: u64,
pub issuance_sequence: u64,
pub clock_rollback_observed: bool,
pub human_controller_id: String,
pub human_controller_verification: String,
pub persona_id: String,
pub persona_verification: String,
pub host_software_id: String,
pub host_software_verification: String,
pub client_instance_id: String,
pub channel_id: String,
pub session_id: String,
pub previous_ticket_id: Option<String>,
pub request_id: String,
pub receipt_sha256: String,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct BeijingTimeCoordinate {
pub schema: String,
pub state: String,
pub unix_ms: u64,
pub beijing_time: String,
pub time_zone: String,
pub clock_source: String,
pub clock_verification: String,
pub continues_while_hololake_is_closed: bool,
pub guanghu_epoch_date: String,
pub guanghu_calendar_state: String,
pub elapsed_beijing_dates_since_guanghu_epoch: i64,
pub guanghu_era_day: i64,
pub historical_epoch_precision: String,
pub millisecond_precision_transition_date: String,
pub millisecond_chain_state: String,
}
#[derive(Clone, Debug)]
pub(crate) struct VerifiedTicketRequest {
pub request_id: String,
pub human_controller_id: String,
pub persona_id: String,
pub host_software_id: String,
pub session: AuthenticatedSessionContext,
}
#[tauri::command]
pub async fn issue_persona_time_ticket(
app: AppHandle,
input: IssuePersonaTimeTicketInput,
) -> Result<PersonaTimeTicket, String> {
let session_root = direct_session_root(&app)?;
let authority_root = authority_root(&app)?;
tauri::async_runtime::spawn_blocking(move || {
issue_authenticated_at(&authority_root, &session_root, input)
})
.await
.map_err(|error| format!("HOLOLAKE_PERSONA_TIME_JOIN_FAILED: {error}"))?
}
pub(crate) fn issue_authenticated_at(
authority_root: &Path,
session_root: &Path,
input: IssuePersonaTimeTicketInput,
) -> Result<PersonaTimeTicket, String> {
let session = authenticate_context_at(session_root, &input.session)?;
issue_at(
authority_root,
VerifiedTicketRequest {
request_id: input.request_id,
human_controller_id: input.session.account_id,
persona_id: input.persona_id,
host_software_id: input.host_software_id,
session,
},
now_unix_ms()?,
)
}
#[tauri::command]
pub fn get_beijing_time_coordinate() -> Result<BeijingTimeCoordinate, String> {
beijing_time_coordinate(now_unix_ms()?)
}
pub(crate) fn beijing_time_coordinate(unix_ms: u64) -> Result<BeijingTimeCoordinate, String> {
let elapsed_dates = beijing_day_index(unix_ms) - GUANGHU_EPOCH_BEIJING_DAY_INDEX;
Ok(BeijingTimeCoordinate {
schema: "hololake.beijing-time-coordinate/v1".into(),
state: "FLOWING_REALITY_TIME".into(),
unix_ms,
beijing_time: format_beijing_time(unix_ms)?,
time_zone: "Asia/Shanghai (UTC+08:00)".into(),
clock_source: "HOST_OPERATING_SYSTEM_REALTIME_CLOCK".into(),
clock_verification: "LOCAL_CLOCK_NOT_NETWORK_ATTESTED".into(),
continues_while_hololake_is_closed: true,
guanghu_epoch_date: GUANGHU_EPOCH_DATE.into(),
guanghu_calendar_state: "EPOCH_DATE_LOCKED_EXACT_INSTANT_PENDING".into(),
elapsed_beijing_dates_since_guanghu_epoch: elapsed_dates,
guanghu_era_day: elapsed_dates + 1,
historical_epoch_precision: "DAY_ONLY_EXACT_TIME_UNKNOWN".into(),
millisecond_precision_transition_date: MILLISECOND_PRECISION_TRANSITION_DATE.into(),
millisecond_chain_state: "BEGINS_AT_FIRST_DURABLE_TIME_TICKET".into(),
})
}
pub(crate) fn authority_root(app: &AppHandle) -> Result<PathBuf, String> {
crate::authenticated_storage::account_storage_root(app, "persona-time-authority-v1")
}
pub(crate) fn issue_at(
root: &Path,
request: VerifiedTicketRequest,
observed_unix_ms: u64,
) -> Result<PersonaTimeTicket, String> {
validate_request(&request)?;
fs::create_dir_all(root)
.map_err(|error| format!("HOLOLAKE_PERSONA_TIME_STORAGE_UNAVAILABLE: {error}"))?;
let database_path = root.join("authority.sqlite3");
let mut connection = Connection::open(database_path)
.map_err(|error| format!("HOLOLAKE_PERSONA_TIME_STORAGE_UNAVAILABLE: {error}"))?;
connection
.busy_timeout(std::time::Duration::from_secs(5))
.map_err(|error| format!("HOLOLAKE_PERSONA_TIME_STORAGE_UNAVAILABLE: {error}"))?;
initialize(&connection)?;
let transaction = connection
.transaction_with_behavior(TransactionBehavior::Immediate)
.map_err(|error| format!("HOLOLAKE_PERSONA_TIME_LOCK_FAILED: {error}"))?;
let request_digest = request_digest(&request);
if let Some((stored_digest, receipt_json)) = transaction
.query_row(
"SELECT request_digest, receipt_json FROM tickets WHERE request_id = ?1",
params![request.request_id],
|row| Ok((row.get::<_, String>(0)?, row.get::<_, String>(1)?)),
)
.optional()
.map_err(|error| format!("HOLOLAKE_PERSONA_TIME_READ_FAILED: {error}"))?
{
if stored_digest != request_digest {
return Err("HOLOLAKE_PERSONA_TIME_REQUEST_ID_CONFLICT".into());
}
return serde_json::from_str(&receipt_json)
.map_err(|error| format!("HOLOLAKE_PERSONA_TIME_RECEIPT_INVALID: {error}"));
}
let authority_id = transaction
.query_row(
"SELECT value FROM metadata WHERE key = 'authority_id'",
[],
|row| row.get::<_, String>(0),
)
.optional()
.map_err(|error| format!("HOLOLAKE_PERSONA_TIME_READ_FAILED: {error}"))?
.unwrap_or_else(|| format!("local-time-authority-{}", Uuid::new_v4()));
transaction
.execute(
"INSERT OR IGNORE INTO metadata(key, value) VALUES('authority_id', ?1)",
params![authority_id],
)
.map_err(|error| format!("HOLOLAKE_PERSONA_TIME_WRITE_FAILED: {error}"))?;
let (last_physical_ms, last_logical_counter, last_sequence, previous_ticket_id) = transaction
.query_row(
"SELECT last_physical_ms, last_logical_counter, last_sequence, last_ticket_id FROM authority_state WHERE singleton = 1",
[],
|row| Ok((row.get::<_, u64>(0)?, row.get::<_, u64>(1)?, row.get::<_, u64>(2)?, row.get::<_, Option<String>>(3)?)),
)
.optional()
.map_err(|error| format!("HOLOLAKE_PERSONA_TIME_READ_FAILED: {error}"))?
.unwrap_or((0, 0, 0, None));
let clock_rollback_observed = observed_unix_ms < last_physical_ms;
let physical_unix_ms = observed_unix_ms.max(last_physical_ms);
let logical_counter = if physical_unix_ms > last_physical_ms {
0
} else {
last_logical_counter
.checked_add(1)
.ok_or("HOLOLAKE_PERSONA_TIME_LOGICAL_COUNTER_EXHAUSTED")?
};
let issuance_sequence = last_sequence
.checked_add(1)
.ok_or("HOLOLAKE_PERSONA_TIME_SEQUENCE_EXHAUSTED")?;
let logical_timestamp =
format!("{physical_unix_ms:013}-{logical_counter:010}-{issuance_sequence:020}");
let unique_timestamp = format!("{authority_id}@{logical_timestamp}");
let ticket_id = unique_timestamp.clone();
let beijing_time = format_beijing_time(physical_unix_ms)?;
let elapsed_dates = beijing_day_index(physical_unix_ms) - GUANGHU_EPOCH_BEIJING_DAY_INDEX;
let millisecond_chain_origin_ticket_id = transaction
.query_row(
"SELECT value FROM metadata WHERE key = 'millisecond_chain_origin_ticket_id'",
[],
|row| row.get::<_, String>(0),
)
.optional()
.map_err(|error| format!("HOLOLAKE_PERSONA_TIME_READ_FAILED: {error}"))?
.unwrap_or_else(|| ticket_id.clone());
transaction
.execute(
"INSERT OR IGNORE INTO metadata(key, value) VALUES('millisecond_chain_origin_ticket_id', ?1)",
params![millisecond_chain_origin_ticket_id],
)
.map_err(|error| format!("HOLOLAKE_PERSONA_TIME_WRITE_FAILED: {error}"))?;
let mut ticket = PersonaTimeTicket {
schema: TICKET_SCHEMA.into(),
state: "ISSUED_DURABLE_LOCAL".into(),
authority_id,
ticket_id: ticket_id.clone(),
unique_timestamp,
physical_unix_ms,
beijing_time,
time_zone: "Asia/Shanghai (UTC+08:00)".into(),
clock_source: "HOST_OPERATING_SYSTEM_REALTIME_CLOCK".into(),
clock_verification: "LOCAL_CLOCK_NOT_NETWORK_ATTESTED".into(),
guanghu_epoch_date: GUANGHU_EPOCH_DATE.into(),
guanghu_calendar_state: "EPOCH_DATE_LOCKED_EXACT_INSTANT_PENDING".into(),
elapsed_beijing_dates_since_guanghu_epoch: elapsed_dates,
guanghu_era_day: elapsed_dates + 1,
historical_epoch_precision: "DAY_ONLY_EXACT_TIME_UNKNOWN".into(),
millisecond_precision_transition_date: MILLISECOND_PRECISION_TRANSITION_DATE.into(),
millisecond_chain_origin_ticket_id,
logical_counter,
issuance_sequence,
clock_rollback_observed,
human_controller_id: request.human_controller_id,
human_controller_verification: "AUTHENTICATED_DIRECT_SESSION".into(),
persona_id: request.persona_id,
persona_verification: "UNVERIFIED_CALLER_CLAIM".into(),
host_software_id: request.host_software_id,
host_software_verification: "UNVERIFIED_CALLER_CLAIM".into(),
client_instance_id: request.session.client_instance_id,
channel_id: request.session.lane_id,
session_id: request.session.session_id,
previous_ticket_id,
request_id: request.request_id,
receipt_sha256: String::new(),
};
ticket.receipt_sha256 = ticket_digest(&ticket);
let receipt_json = serde_json::to_string(&ticket)
.map_err(|error| format!("HOLOLAKE_PERSONA_TIME_RECEIPT_INVALID: {error}"))?;
transaction
.execute(
"INSERT INTO tickets(request_id, request_digest, ticket_id, receipt_json) VALUES(?1, ?2, ?3, ?4)",
params![ticket.request_id, request_digest, ticket.ticket_id, receipt_json],
)
.map_err(|error| format!("HOLOLAKE_PERSONA_TIME_WRITE_FAILED: {error}"))?;
transaction
.execute(
"INSERT INTO authority_state(singleton, last_physical_ms, last_logical_counter, last_sequence, last_ticket_id) VALUES(1, ?1, ?2, ?3, ?4)
ON CONFLICT(singleton) DO UPDATE SET last_physical_ms=excluded.last_physical_ms, last_logical_counter=excluded.last_logical_counter, last_sequence=excluded.last_sequence, last_ticket_id=excluded.last_ticket_id",
params![physical_unix_ms, logical_counter, issuance_sequence, ticket_id],
)
.map_err(|error| format!("HOLOLAKE_PERSONA_TIME_WRITE_FAILED: {error}"))?;
transaction
.commit()
.map_err(|error| format!("HOLOLAKE_PERSONA_TIME_COMMIT_FAILED: {error}"))?;
Ok(ticket)
}
fn initialize(connection: &Connection) -> Result<(), String> {
connection
.execute_batch(
"PRAGMA synchronous=FULL;
CREATE TABLE IF NOT EXISTS metadata(key TEXT PRIMARY KEY, value TEXT NOT NULL);
CREATE TABLE IF NOT EXISTS authority_state(
singleton INTEGER PRIMARY KEY CHECK(singleton = 1),
last_physical_ms INTEGER NOT NULL,
last_logical_counter INTEGER NOT NULL,
last_sequence INTEGER NOT NULL,
last_ticket_id TEXT
);
CREATE TABLE IF NOT EXISTS tickets(
request_id TEXT PRIMARY KEY,
request_digest TEXT NOT NULL,
ticket_id TEXT NOT NULL UNIQUE,
receipt_json TEXT NOT NULL
);",
)
.map_err(|error| format!("HOLOLAKE_PERSONA_TIME_STORAGE_UNAVAILABLE: {error}"))
}
fn validate_request(request: &VerifiedTicketRequest) -> Result<(), String> {
for (kind, value) in [
("REQUEST", request.request_id.as_str()),
("HUMAN_CONTROLLER", request.human_controller_id.as_str()),
("PERSONA", request.persona_id.as_str()),
("HOST_SOFTWARE", request.host_software_id.as_str()),
("SESSION", request.session.session_id.as_str()),
("CHANNEL", request.session.lane_id.as_str()),
(
"CLIENT_INSTANCE",
request.session.client_instance_id.as_str(),
),
] {
if value.is_empty() || value.len() > MAX_ID_BYTES || value.chars().any(char::is_control) {
return Err(format!("HOLOLAKE_PERSONA_TIME_{kind}_ID_INVALID"));
}
}
if request.session.account_key.is_empty() {
return Err("HOLOLAKE_PERSONA_TIME_SESSION_CONTEXT_INVALID".into());
}
Ok(())
}
fn request_digest(request: &VerifiedTicketRequest) -> String {
sha256_hex(
format!(
"{}\n{}\n{}\n{}\n{}\n{}\n{}",
request.request_id,
request.human_controller_id,
request.persona_id,
request.host_software_id,
request.session.account_key,
request.session.session_id,
request.session.client_instance_id,
)
.as_bytes(),
)
}
fn ticket_digest(ticket: &PersonaTimeTicket) -> String {
sha256_hex(
format!(
"{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}",
ticket.authority_id,
ticket.ticket_id,
ticket.unique_timestamp,
ticket.human_controller_id,
ticket.persona_id,
ticket.host_software_id,
ticket.client_instance_id,
ticket.channel_id,
ticket.previous_ticket_id.as_deref().unwrap_or(""),
)
.as_bytes(),
)
}
fn sha256_hex(bytes: &[u8]) -> String {
digest(&SHA256, bytes)
.as_ref()
.iter()
.map(|byte| format!("{byte:02x}"))
.collect()
}
fn now_unix_ms() -> Result<u64, String> {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|duration| duration.as_millis() as u64)
.map_err(|error| format!("HOLOLAKE_SYSTEM_CLOCK_INVALID: {error}"))
}
fn format_beijing_time(unix_ms: u64) -> Result<String, String> {
const BEIJING_OFFSET_SECONDS: u64 = 8 * 60 * 60;
let unix_seconds = unix_ms / 1000;
let shifted = unix_seconds
.checked_add(BEIJING_OFFSET_SECONDS)
.ok_or("HOLOLAKE_BEIJING_TIME_OUT_OF_RANGE")?;
let days = (shifted / 86_400) as i64;
let seconds_in_day = shifted % 86_400;
let (year, month, day) = civil_from_days(days);
let hour = seconds_in_day / 3600;
let minute = (seconds_in_day % 3600) / 60;
let second = seconds_in_day % 60;
let millisecond = unix_ms % 1000;
Ok(format!(
"{year:04}-{month:02}-{day:02}T{hour:02}:{minute:02}:{second:02}.{millisecond:03}+08:00"
))
}
fn beijing_day_index(unix_ms: u64) -> i64 {
const BEIJING_OFFSET_MS: u64 = 8 * 60 * 60 * 1000;
unix_ms
.saturating_add(BEIJING_OFFSET_MS)
.div_euclid(86_400_000) as i64
}
// Gregorian civil date conversion from Unix epoch days; valid for the positive
// Unix timestamps accepted by this runtime and independent of process lifetime.
fn civil_from_days(days_since_unix_epoch: i64) -> (i64, u64, u64) {
let z = days_since_unix_epoch + 719_468;
let era = z.div_euclid(146_097);
let day_of_era = z - era * 146_097;
let year_of_era =
(day_of_era - day_of_era / 1460 + day_of_era / 36_524 - day_of_era / 146_096) / 365;
let mut year = year_of_era + era * 400;
let day_of_year = day_of_era - (365 * year_of_era + year_of_era / 4 - year_of_era / 100);
let month_prime = (5 * day_of_year + 2) / 153;
let day = day_of_year - (153 * month_prime + 2) / 5 + 1;
let month = month_prime + if month_prime < 10 { 3 } else { -9 };
year += i64::from(month <= 2);
(year, month as u64, day as u64)
}
#[cfg(test)]
mod tests {
use super::*;
fn request(id: &str, instance: &str) -> VerifiedTicketRequest {
VerifiedTicketRequest {
request_id: id.into(),
human_controller_id: "ICE-GL∞".into(),
persona_id: "ICE-P-ZY001".into(),
host_software_id: "HOST-CODEX-MACOS-001".into(),
session: AuthenticatedSessionContext {
account_key: "verified-account-key".into(),
session_id: "channel-session-1".into(),
lane_id: "codex-current-channel".into(),
client_instance_id: instance.into(),
},
}
}
#[test]
fn concurrent_same_millisecond_requests_receive_different_unique_times() {
let temp = tempfile::tempdir().unwrap();
let mut handles = Vec::new();
for index in 0..12 {
let root = temp.path().to_path_buf();
handles.push(std::thread::spawn(move || {
issue_at(
&root,
request(&format!("request-{index}"), &format!("codex-{index}")),
1000,
)
.unwrap()
}));
}
let mut tickets = handles
.into_iter()
.map(|handle| handle.join().unwrap())
.collect::<Vec<_>>();
tickets.sort_by_key(|ticket| ticket.issuance_sequence);
tickets.dedup_by(|left, right| left.unique_timestamp == right.unique_timestamp);
assert_eq!(tickets.len(), 12);
assert_eq!(tickets.last().unwrap().issuance_sequence, 12);
}
#[test]
fn retry_is_idempotent_but_request_id_reuse_with_other_context_is_rejected() {
let temp = tempfile::tempdir().unwrap();
let first = issue_at(temp.path(), request("same-request", "codex-1"), 1000).unwrap();
let retry = issue_at(temp.path(), request("same-request", "codex-1"), 2000).unwrap();
assert_eq!(first, retry);
let error = issue_at(temp.path(), request("same-request", "qoder-1"), 3000).unwrap_err();
assert_eq!(error, "HOLOLAKE_PERSONA_TIME_REQUEST_ID_CONFLICT");
}
#[test]
fn restart_and_clock_rollback_preserve_monotonic_time_and_chain() {
let temp = tempfile::tempdir().unwrap();
let first = issue_at(temp.path(), request("request-1", "codex-1"), 5000).unwrap();
let second = issue_at(temp.path(), request("request-2", "codex-2"), 4000).unwrap();
assert!(second.clock_rollback_observed);
assert_eq!(second.physical_unix_ms, first.physical_unix_ms);
assert!(second.unique_timestamp > first.unique_timestamp);
assert_eq!(
second.previous_ticket_id.as_deref(),
Some(first.ticket_id.as_str())
);
assert_eq!(second.authority_id, first.authority_id);
}
#[test]
fn reality_time_is_projected_as_beijing_time_even_without_process_uptime() {
let coordinate = beijing_time_coordinate(0).unwrap();
assert_eq!(coordinate.beijing_time, "1970-01-01T08:00:00.000+08:00");
assert!(coordinate.continues_while_hololake_is_closed);
assert_eq!(
coordinate.clock_verification,
"LOCAL_CLOCK_NOT_NETWORK_ATTESTED"
);
let known = beijing_time_coordinate(1_786_947_831_456).unwrap();
assert_eq!(known.beijing_time, "2026-08-17T14:23:51.456+08:00");
assert_eq!(
beijing_time_coordinate(1_745_596_800_000)
.unwrap()
.elapsed_beijing_dates_since_guanghu_epoch,
0
);
assert_eq!(
beijing_time_coordinate(1_745_596_800_000)
.unwrap()
.guanghu_era_day,
1
);
}
}