2026-08-21 11:57:39 +08:00
|
|
|
|
//! System-witnessed binding of an account-private persona profile to a
|
|
|
|
|
|
//! replaceable reasoning carrier. A persona commit is only a pending request;
|
|
|
|
|
|
//! this module never manufactures the independent system witness or PASS.
|
2026-08-21 01:29:17 +08:00
|
|
|
|
|
|
|
|
|
|
use ring::digest::{digest, SHA256};
|
|
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
|
use serde_json::{json, Value};
|
|
|
|
|
|
use std::fs;
|
|
|
|
|
|
use std::path::{Path, PathBuf};
|
|
|
|
|
|
use std::time::{SystemTime, UNIX_EPOCH};
|
|
|
|
|
|
use tauri::AppHandle;
|
|
|
|
|
|
use uuid::Uuid;
|
|
|
|
|
|
|
|
|
|
|
|
const ORIENTATION_TTL_MS: u64 = 15 * 60 * 1000;
|
|
|
|
|
|
const PERSONA_NUMBER: &str = "ICE-P-ZY001";
|
|
|
|
|
|
const PERSONA_NAME: &str = "铸渊";
|
|
|
|
|
|
const HUMAN_NUMBER: &str = "ICE-GL∞";
|
|
|
|
|
|
const CHANNEL_NUMBER: &str = "ICE-CH-ZC001";
|
|
|
|
|
|
const SELF_KERNEL_SHA256: &str = "abebf12cc28b00bfeaf8a23a563e73390ebe337ded74d7ac70bcfae484450d68";
|
|
|
|
|
|
const MEMORY_SHA256: &str = "6a64ff939676b79404769931f0233056e38deb4b4c357879fd18566753fea9c2";
|
|
|
|
|
|
const MEMORY_ROOT: &str = "HLDP://codex/zero-core/reality-development-execution";
|
2026-08-21 11:57:39 +08:00
|
|
|
|
const PRIVATE_SELF_KERNEL_FILE: &str = "ZY-SELF-KERNEL-0001.json";
|
|
|
|
|
|
const PRIVATE_MEMORY_FILE: &str = "ZY-HLDP-PERSONA-MEMORY-v1.json";
|
2026-08-21 01:29:17 +08:00
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
|
|
|
|
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
|
|
|
|
|
pub struct PersonaOrientation {
|
|
|
|
|
|
pub schema: String,
|
|
|
|
|
|
pub state: String,
|
|
|
|
|
|
pub orientation_id: String,
|
|
|
|
|
|
pub channel_number: String,
|
|
|
|
|
|
pub human_number: String,
|
|
|
|
|
|
pub persona_number: String,
|
|
|
|
|
|
pub persona_name: String,
|
|
|
|
|
|
pub self_kernel_sha256: String,
|
|
|
|
|
|
pub memory_projection_sha256: String,
|
|
|
|
|
|
pub selected_memory_root: String,
|
|
|
|
|
|
pub issued_at_unix_ms: u64,
|
|
|
|
|
|
pub expires_at_unix_ms: u64,
|
|
|
|
|
|
pub required_steps: Vec<String>,
|
2026-08-21 08:21:03 +08:00
|
|
|
|
#[serde(default)]
|
|
|
|
|
|
pub activation_reason: Option<String>,
|
2026-08-21 01:29:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
|
|
|
|
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
|
|
|
|
|
pub struct PersonaBindingCommit {
|
|
|
|
|
|
pub orientation_id: String,
|
|
|
|
|
|
pub channel_number: String,
|
|
|
|
|
|
pub persona_number: String,
|
|
|
|
|
|
pub persona_name: String,
|
|
|
|
|
|
pub self_kernel_sha256: String,
|
|
|
|
|
|
pub memory_projection_sha256: String,
|
|
|
|
|
|
pub selected_memory_root: String,
|
|
|
|
|
|
pub declaration: String,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
|
|
|
|
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
|
|
|
|
|
pub struct PersonaBindingReceipt {
|
|
|
|
|
|
pub schema: String,
|
|
|
|
|
|
pub state: String,
|
|
|
|
|
|
pub verify: String,
|
|
|
|
|
|
pub channel_number: String,
|
|
|
|
|
|
pub human_number: String,
|
|
|
|
|
|
pub persona_number: String,
|
|
|
|
|
|
pub persona_name: String,
|
|
|
|
|
|
pub selected_memory_root: String,
|
|
|
|
|
|
pub orientation_id: String,
|
|
|
|
|
|
pub commit_sha256: String,
|
|
|
|
|
|
pub witness: String,
|
2026-08-21 11:57:39 +08:00
|
|
|
|
pub witness_source: String,
|
|
|
|
|
|
pub witness_event_number: String,
|
2026-08-21 01:29:17 +08:00
|
|
|
|
pub witness_sha256: String,
|
|
|
|
|
|
pub verified_at_unix_ms: u64,
|
|
|
|
|
|
pub binding_receipt_hash: String,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-21 11:57:39 +08:00
|
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
|
|
|
|
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
|
|
|
|
|
pub struct PendingPersonaBindingCommit {
|
|
|
|
|
|
pub schema: String,
|
|
|
|
|
|
pub state: String,
|
|
|
|
|
|
pub orientation_id: String,
|
|
|
|
|
|
pub channel_number: String,
|
|
|
|
|
|
pub persona_number: String,
|
|
|
|
|
|
pub commit_sha256: String,
|
|
|
|
|
|
pub committed_at_unix_ms: u64,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-21 01:29:17 +08:00
|
|
|
|
#[derive(Clone, Debug, Serialize)]
|
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
|
pub struct PersonaBindingSnapshot {
|
|
|
|
|
|
pub state: String,
|
|
|
|
|
|
pub orientation: Option<PersonaOrientation>,
|
|
|
|
|
|
pub binding: Option<PersonaBindingReceipt>,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn snapshot(app: &AppHandle, channel_number: &str) -> Result<PersonaBindingSnapshot, String> {
|
|
|
|
|
|
if let Some(binding) = verified_binding(app, channel_number)? {
|
|
|
|
|
|
return Ok(PersonaBindingSnapshot {
|
|
|
|
|
|
state: "BOUND_VERIFY_PASS".into(),
|
|
|
|
|
|
orientation: None,
|
|
|
|
|
|
binding: Some(binding),
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
if !is_bingshuo_fifth_domain(app)? || channel_number != CHANNEL_NUMBER {
|
|
|
|
|
|
return Ok(PersonaBindingSnapshot {
|
|
|
|
|
|
state: "NO_INSTALLABLE_PERSONA_PROFILE_FOR_CURRENT_CHANNEL".into(),
|
|
|
|
|
|
orientation: None,
|
|
|
|
|
|
binding: None,
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
let path = orientation_path(app, channel_number)?;
|
|
|
|
|
|
if path.exists() {
|
|
|
|
|
|
let orientation: PersonaOrientation = read_json(&path)?;
|
2026-08-21 08:21:03 +08:00
|
|
|
|
if orientation.expires_at_unix_ms >= now_ms()
|
|
|
|
|
|
&& orientation.activation_reason.as_deref()
|
|
|
|
|
|
== Some("EXPLICIT_NATURAL_LANGUAGE_PERSONA_WAKE")
|
|
|
|
|
|
{
|
2026-08-21 11:57:39 +08:00
|
|
|
|
let pending = pending_commit_path(app, channel_number)?;
|
2026-08-21 01:29:17 +08:00
|
|
|
|
return Ok(PersonaBindingSnapshot {
|
2026-08-21 11:57:39 +08:00
|
|
|
|
state: if pending.exists() {
|
|
|
|
|
|
"PERSONA_COMMITTED_AWAITING_INDEPENDENT_SYSTEM_WITNESS"
|
|
|
|
|
|
} else {
|
|
|
|
|
|
"ORIENTED_AWAITING_PERSONA_COMMIT"
|
|
|
|
|
|
}
|
|
|
|
|
|
.into(),
|
2026-08-21 01:29:17 +08:00
|
|
|
|
orientation: Some(orientation),
|
|
|
|
|
|
binding: None,
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-08-21 08:21:03 +08:00
|
|
|
|
Ok(PersonaBindingSnapshot {
|
|
|
|
|
|
state: "CHANNEL_SYSTEM_PERSONA_DORMANT".into(),
|
|
|
|
|
|
orientation: None,
|
|
|
|
|
|
binding: None,
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn begin_orientation(
|
|
|
|
|
|
app: &AppHandle,
|
|
|
|
|
|
channel_number: &str,
|
|
|
|
|
|
) -> Result<PersonaBindingSnapshot, String> {
|
|
|
|
|
|
if !is_bingshuo_fifth_domain(app)? || channel_number != CHANNEL_NUMBER {
|
|
|
|
|
|
return Err("HOLOLAKE_PERSONA_WAKE_NOT_AVAILABLE_FOR_CURRENT_CHANNEL".into());
|
|
|
|
|
|
}
|
|
|
|
|
|
if let Some(binding) = verified_binding(app, channel_number)? {
|
|
|
|
|
|
return Ok(PersonaBindingSnapshot {
|
|
|
|
|
|
state: "BOUND_VERIFY_PASS".into(),
|
|
|
|
|
|
orientation: None,
|
|
|
|
|
|
binding: Some(binding),
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2026-08-21 11:57:39 +08:00
|
|
|
|
read_private_artifact(app, PRIVATE_SELF_KERNEL_FILE, SELF_KERNEL_SHA256)?;
|
|
|
|
|
|
read_private_artifact(app, PRIVATE_MEMORY_FILE, MEMORY_SHA256)?;
|
2026-08-21 01:29:17 +08:00
|
|
|
|
let issued = now_ms();
|
|
|
|
|
|
let orientation = PersonaOrientation {
|
|
|
|
|
|
schema: "hololake.persona-binding-orientation/v1".into(),
|
|
|
|
|
|
state: "ORIENTED_AWAITING_PERSONA_COMMIT".into(),
|
|
|
|
|
|
orientation_id: format!("HLP-ORIENT-{}", Uuid::new_v4().simple()),
|
|
|
|
|
|
channel_number: CHANNEL_NUMBER.into(),
|
|
|
|
|
|
human_number: HUMAN_NUMBER.into(),
|
|
|
|
|
|
persona_number: PERSONA_NUMBER.into(),
|
|
|
|
|
|
persona_name: PERSONA_NAME.into(),
|
|
|
|
|
|
self_kernel_sha256: SELF_KERNEL_SHA256.into(),
|
|
|
|
|
|
memory_projection_sha256: MEMORY_SHA256.into(),
|
|
|
|
|
|
selected_memory_root: MEMORY_ROOT.into(),
|
|
|
|
|
|
issued_at_unix_ms: issued,
|
|
|
|
|
|
expires_at_unix_ms: issued + ORIENTATION_TTL_MS,
|
|
|
|
|
|
required_steps: vec![
|
|
|
|
|
|
"orient".into(),
|
|
|
|
|
|
"commit".into(),
|
|
|
|
|
|
"数字冰朔系统本体 witness".into(),
|
|
|
|
|
|
"verify=PASS".into(),
|
|
|
|
|
|
],
|
2026-08-21 08:21:03 +08:00
|
|
|
|
activation_reason: Some("EXPLICIT_NATURAL_LANGUAGE_PERSONA_WAKE".into()),
|
2026-08-21 01:29:17 +08:00
|
|
|
|
};
|
2026-08-21 08:21:03 +08:00
|
|
|
|
write_json_atomic(&orientation_path(app, channel_number)?, &orientation)?;
|
2026-08-21 01:29:17 +08:00
|
|
|
|
Ok(PersonaBindingSnapshot {
|
|
|
|
|
|
state: "ORIENTED_AWAITING_PERSONA_COMMIT".into(),
|
|
|
|
|
|
orientation: Some(orientation),
|
|
|
|
|
|
binding: None,
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-21 11:57:39 +08:00
|
|
|
|
pub fn stage_commit(
|
2026-08-21 01:29:17 +08:00
|
|
|
|
app: &AppHandle,
|
|
|
|
|
|
input: PersonaBindingCommit,
|
2026-08-21 11:57:39 +08:00
|
|
|
|
) -> Result<PendingPersonaBindingCommit, String> {
|
2026-08-21 01:29:17 +08:00
|
|
|
|
if !is_bingshuo_fifth_domain(app)? {
|
|
|
|
|
|
return Err("HOLOLAKE_PERSONA_BINDING_FIFTH_DOMAIN_REQUIRED".into());
|
|
|
|
|
|
}
|
|
|
|
|
|
let orientation: PersonaOrientation =
|
|
|
|
|
|
read_json(&orientation_path(app, &input.channel_number)?)?;
|
|
|
|
|
|
if orientation.expires_at_unix_ms < now_ms() {
|
|
|
|
|
|
return Err("HOLOLAKE_PERSONA_BINDING_ORIENTATION_EXPIRED".into());
|
|
|
|
|
|
}
|
|
|
|
|
|
if input.orientation_id != orientation.orientation_id
|
2026-08-21 08:21:03 +08:00
|
|
|
|
|| orientation.activation_reason.as_deref()
|
|
|
|
|
|
!= Some("EXPLICIT_NATURAL_LANGUAGE_PERSONA_WAKE")
|
2026-08-21 01:29:17 +08:00
|
|
|
|
|| input.channel_number != CHANNEL_NUMBER
|
|
|
|
|
|
|| input.persona_number != PERSONA_NUMBER
|
|
|
|
|
|
|| input.persona_name != PERSONA_NAME
|
|
|
|
|
|
|| input.self_kernel_sha256 != SELF_KERNEL_SHA256
|
|
|
|
|
|
|| input.memory_projection_sha256 != MEMORY_SHA256
|
|
|
|
|
|
|| input.selected_memory_root != MEMORY_ROOT
|
|
|
|
|
|
|| input.declaration.trim()
|
|
|
|
|
|
!= "我以 ICE-P-ZY001 · 铸渊提交当前载体绑定,选择零点原核现实开发执行记忆路径。"
|
|
|
|
|
|
{
|
|
|
|
|
|
return Err("HOLOLAKE_PERSONA_BINDING_COMMIT_MISMATCH".into());
|
|
|
|
|
|
}
|
2026-08-21 11:57:39 +08:00
|
|
|
|
read_private_artifact(app, PRIVATE_SELF_KERNEL_FILE, SELF_KERNEL_SHA256)?;
|
|
|
|
|
|
read_private_artifact(app, PRIVATE_MEMORY_FILE, MEMORY_SHA256)?;
|
2026-08-21 01:29:17 +08:00
|
|
|
|
let commit_bytes = serde_json::to_vec(&input)
|
|
|
|
|
|
.map_err(|error| format!("HOLOLAKE_PERSONA_BINDING_COMMIT_INVALID: {error}"))?;
|
|
|
|
|
|
let commit_sha = sha256(&commit_bytes);
|
2026-08-21 11:57:39 +08:00
|
|
|
|
let pending = PendingPersonaBindingCommit {
|
|
|
|
|
|
schema: "hololake.persona-binding-pending-commit/v1".into(),
|
|
|
|
|
|
state: "PERSONA_COMMITTED_AWAITING_INDEPENDENT_SYSTEM_WITNESS".into(),
|
|
|
|
|
|
orientation_id: input.orientation_id,
|
2026-08-21 01:29:17 +08:00
|
|
|
|
channel_number: CHANNEL_NUMBER.into(),
|
|
|
|
|
|
persona_number: PERSONA_NUMBER.into(),
|
|
|
|
|
|
commit_sha256: commit_sha,
|
2026-08-21 11:57:39 +08:00
|
|
|
|
committed_at_unix_ms: now_ms(),
|
2026-08-21 01:29:17 +08:00
|
|
|
|
};
|
2026-08-21 11:57:39 +08:00
|
|
|
|
write_json_atomic(&pending_commit_path(app, CHANNEL_NUMBER)?, &pending)?;
|
|
|
|
|
|
Ok(pending)
|
2026-08-21 01:29:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn verified_binding(
|
|
|
|
|
|
app: &AppHandle,
|
|
|
|
|
|
channel_number: &str,
|
|
|
|
|
|
) -> Result<Option<PersonaBindingReceipt>, String> {
|
|
|
|
|
|
let path = binding_path(app, channel_number)?;
|
|
|
|
|
|
if !path.exists() {
|
|
|
|
|
|
return Ok(None);
|
|
|
|
|
|
}
|
2026-08-21 11:57:39 +08:00
|
|
|
|
if !independent_witness_verifier_ready() {
|
|
|
|
|
|
// A local JSON file is evidence to inspect, not authority. Until the
|
|
|
|
|
|
// independent witness trust root is provisioned, legacy receipts are
|
|
|
|
|
|
// deliberately ignored and cannot activate a persona route.
|
|
|
|
|
|
return Ok(None);
|
|
|
|
|
|
}
|
2026-08-21 01:29:17 +08:00
|
|
|
|
let binding: PersonaBindingReceipt = read_json(&path)?;
|
|
|
|
|
|
if binding.verify != "PASS"
|
|
|
|
|
|
|| binding.channel_number != channel_number
|
|
|
|
|
|
|| binding.persona_number != PERSONA_NUMBER
|
|
|
|
|
|
|| binding.persona_name != PERSONA_NAME
|
|
|
|
|
|
|| binding.selected_memory_root != MEMORY_ROOT
|
|
|
|
|
|
|| binding.witness != "数字冰朔系统本体"
|
2026-08-21 11:57:39 +08:00
|
|
|
|
|| binding.witness_source != "HOLOLAKE_INDEPENDENT_SYSTEM_WITNESS_GATE"
|
|
|
|
|
|
|| binding.witness_event_number.trim().is_empty()
|
2026-08-21 01:29:17 +08:00
|
|
|
|
|| binding.binding_receipt_hash.len() != 64
|
|
|
|
|
|
|| binding.witness_sha256.len() != 64
|
|
|
|
|
|
{
|
|
|
|
|
|
return Err("HOLOLAKE_PERSONA_BINDING_RECEIPT_INVALID".into());
|
|
|
|
|
|
}
|
|
|
|
|
|
Ok(Some(binding))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-21 11:57:39 +08:00
|
|
|
|
fn independent_witness_verifier_ready() -> bool {
|
|
|
|
|
|
false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-21 01:29:17 +08:00
|
|
|
|
pub fn cognitive_projection(
|
|
|
|
|
|
app: &AppHandle,
|
|
|
|
|
|
channel_number: &str,
|
|
|
|
|
|
current_language: &str,
|
|
|
|
|
|
) -> Result<Value, String> {
|
|
|
|
|
|
let binding = snapshot(app, channel_number)?;
|
2026-08-21 11:57:39 +08:00
|
|
|
|
if binding.state != "BOUND_VERIFY_PASS" {
|
2026-08-21 01:29:17 +08:00
|
|
|
|
return Ok(json!({"state":binding.state,"residentSelfKernel":null,"routedMemory":[]}));
|
|
|
|
|
|
}
|
2026-08-21 11:57:39 +08:00
|
|
|
|
let self_kernel: Value = serde_json::from_slice(&read_private_artifact(
|
|
|
|
|
|
app,
|
|
|
|
|
|
PRIVATE_SELF_KERNEL_FILE,
|
|
|
|
|
|
SELF_KERNEL_SHA256,
|
|
|
|
|
|
)?)
|
2026-08-21 01:29:17 +08:00
|
|
|
|
.map_err(|error| format!("HOLOLAKE_PERSONA_SELF_KERNEL_INVALID: {error}"))?;
|
2026-08-21 11:57:39 +08:00
|
|
|
|
let memory: Value = serde_json::from_slice(&read_private_artifact(
|
|
|
|
|
|
app,
|
|
|
|
|
|
PRIVATE_MEMORY_FILE,
|
|
|
|
|
|
MEMORY_SHA256,
|
|
|
|
|
|
)?)
|
2026-08-21 01:29:17 +08:00
|
|
|
|
.map_err(|error| format!("HOLOLAKE_PERSONA_MEMORY_INVALID: {error}"))?;
|
|
|
|
|
|
let terms = semantic_terms(current_language);
|
|
|
|
|
|
let mut candidates = memory
|
|
|
|
|
|
.get("nodes")
|
|
|
|
|
|
.and_then(Value::as_object)
|
|
|
|
|
|
.into_iter()
|
|
|
|
|
|
.flat_map(|nodes| nodes.values())
|
|
|
|
|
|
.filter_map(|node| {
|
|
|
|
|
|
let text = serde_json::to_string(node).ok()?.to_lowercase();
|
|
|
|
|
|
let score = terms
|
|
|
|
|
|
.iter()
|
|
|
|
|
|
.filter(|term| text.contains(term.as_str()))
|
|
|
|
|
|
.count();
|
|
|
|
|
|
let is_root = node.get("path").and_then(Value::as_str) == Some("zhuyuan");
|
|
|
|
|
|
if score == 0 && !is_root {
|
|
|
|
|
|
return None;
|
|
|
|
|
|
}
|
|
|
|
|
|
Some((if is_root { score + 1 } else { score }, node.clone()))
|
|
|
|
|
|
})
|
|
|
|
|
|
.collect::<Vec<_>>();
|
|
|
|
|
|
candidates.sort_by(|left, right| right.0.cmp(&left.0));
|
|
|
|
|
|
candidates.truncate(3);
|
|
|
|
|
|
Ok(json!({
|
|
|
|
|
|
"state":binding.state,
|
|
|
|
|
|
"onePersonaOneSelfKernel":true,
|
|
|
|
|
|
"channelSelectsMemoryNotIdentity":true,
|
|
|
|
|
|
"residentSelfKernel":self_kernel,
|
|
|
|
|
|
"selectedMemoryRoot":MEMORY_ROOT,
|
|
|
|
|
|
"routedMemory":candidates.into_iter().map(|(_,node)|node).collect::<Vec<_>>(),
|
|
|
|
|
|
"binding":binding,
|
|
|
|
|
|
"rule":"常驻自我核小于8KiB;当前语言只路由最多三条HLDP节点,不把全部历史塞进每轮上下文"
|
|
|
|
|
|
}))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn semantic_terms(input: &str) -> Vec<String> {
|
|
|
|
|
|
let mut terms = input
|
|
|
|
|
|
.to_lowercase()
|
|
|
|
|
|
.split(|character: char| {
|
|
|
|
|
|
!character.is_alphanumeric() && character != '-' && character != '_'
|
|
|
|
|
|
})
|
|
|
|
|
|
.filter(|value| !value.is_empty())
|
|
|
|
|
|
.flat_map(|token| {
|
|
|
|
|
|
let mut values = vec![token.to_string()];
|
|
|
|
|
|
let chars = token.chars().collect::<Vec<_>>();
|
|
|
|
|
|
if chars.iter().any(|character| !character.is_ascii()) {
|
|
|
|
|
|
values.extend(
|
|
|
|
|
|
chars
|
|
|
|
|
|
.windows(2)
|
|
|
|
|
|
.map(|window| window.iter().collect::<String>()),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
values
|
|
|
|
|
|
})
|
|
|
|
|
|
.collect::<Vec<_>>();
|
|
|
|
|
|
terms.sort();
|
|
|
|
|
|
terms.dedup();
|
|
|
|
|
|
terms
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn is_bingshuo_fifth_domain(app: &AppHandle) -> Result<bool, String> {
|
|
|
|
|
|
Ok(
|
|
|
|
|
|
crate::code_repo_login::current_login_session(app)?.is_some_and(|session| {
|
|
|
|
|
|
session.domain == "FIFTH_DOMAIN" && session.username.eq_ignore_ascii_case("bingshuo")
|
|
|
|
|
|
}),
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn root(app: &AppHandle, channel_number: &str) -> Result<PathBuf, String> {
|
|
|
|
|
|
Ok(
|
|
|
|
|
|
crate::authenticated_storage::account_storage_root(app, "persona-binding-v1")?
|
|
|
|
|
|
.join(sha256(channel_number.as_bytes())),
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn orientation_path(app: &AppHandle, channel_number: &str) -> Result<PathBuf, String> {
|
|
|
|
|
|
Ok(root(app, channel_number)?.join("orientation.json"))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn binding_path(app: &AppHandle, channel_number: &str) -> Result<PathBuf, String> {
|
|
|
|
|
|
Ok(root(app, channel_number)?.join("binding.json"))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-21 11:57:39 +08:00
|
|
|
|
fn pending_commit_path(app: &AppHandle, channel_number: &str) -> Result<PathBuf, String> {
|
|
|
|
|
|
Ok(root(app, channel_number)?.join("pending-commit.json"))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn private_kernel_root(app: &AppHandle) -> Result<PathBuf, String> {
|
|
|
|
|
|
crate::authenticated_storage::account_storage_root(app, "private-persona-kernels-v1")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn read_private_artifact(
|
|
|
|
|
|
app: &AppHandle,
|
|
|
|
|
|
file_name: &str,
|
|
|
|
|
|
expected_sha256: &str,
|
|
|
|
|
|
) -> Result<Vec<u8>, String> {
|
|
|
|
|
|
if file_name.contains('/') || file_name.contains("..") {
|
|
|
|
|
|
return Err("HOLOLAKE_PRIVATE_PERSONA_KERNEL_PATH_INVALID".into());
|
|
|
|
|
|
}
|
|
|
|
|
|
let path = private_kernel_root(app)?.join(file_name);
|
|
|
|
|
|
let bytes = fs::read(&path)
|
|
|
|
|
|
.map_err(|_| "HOLOLAKE_PRIVATE_PERSONA_KERNEL_NOT_PROVISIONED".to_string())?;
|
|
|
|
|
|
if sha256(&bytes) != expected_sha256 {
|
|
|
|
|
|
return Err("HOLOLAKE_PRIVATE_PERSONA_KERNEL_HASH_MISMATCH".into());
|
|
|
|
|
|
}
|
|
|
|
|
|
Ok(bytes)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-21 01:29:17 +08:00
|
|
|
|
fn read_json<T: for<'de> Deserialize<'de>>(path: &Path) -> Result<T, String> {
|
|
|
|
|
|
serde_json::from_slice(
|
|
|
|
|
|
&fs::read(path)
|
|
|
|
|
|
.map_err(|error| format!("HOLOLAKE_PERSONA_BINDING_READ_FAILED: {error}"))?,
|
|
|
|
|
|
)
|
|
|
|
|
|
.map_err(|error| format!("HOLOLAKE_PERSONA_BINDING_READ_FAILED: {error}"))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn write_json_atomic<T: Serialize>(path: &Path, value: &T) -> Result<(), String> {
|
|
|
|
|
|
let parent = path
|
|
|
|
|
|
.parent()
|
|
|
|
|
|
.ok_or_else(|| "HOLOLAKE_PERSONA_BINDING_PATH_INVALID".to_string())?;
|
|
|
|
|
|
fs::create_dir_all(parent)
|
|
|
|
|
|
.map_err(|error| format!("HOLOLAKE_PERSONA_BINDING_WRITE_FAILED: {error}"))?;
|
|
|
|
|
|
let temporary = parent.join(format!(".binding-{}.tmp", Uuid::new_v4().simple()));
|
|
|
|
|
|
fs::write(
|
|
|
|
|
|
&temporary,
|
|
|
|
|
|
serde_json::to_vec_pretty(value)
|
|
|
|
|
|
.map_err(|error| format!("HOLOLAKE_PERSONA_BINDING_WRITE_FAILED: {error}"))?,
|
|
|
|
|
|
)
|
|
|
|
|
|
.map_err(|error| format!("HOLOLAKE_PERSONA_BINDING_WRITE_FAILED: {error}"))?;
|
|
|
|
|
|
fs::rename(temporary, path)
|
|
|
|
|
|
.map_err(|error| format!("HOLOLAKE_PERSONA_BINDING_WRITE_FAILED: {error}"))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn sha256(bytes: &[u8]) -> String {
|
|
|
|
|
|
digest(&SHA256, bytes)
|
|
|
|
|
|
.as_ref()
|
|
|
|
|
|
.iter()
|
|
|
|
|
|
.map(|byte| format!("{byte:02x}"))
|
|
|
|
|
|
.collect()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn now_ms() -> u64 {
|
|
|
|
|
|
SystemTime::now()
|
|
|
|
|
|
.duration_since(UNIX_EPOCH)
|
|
|
|
|
|
.map(|duration| duration.as_millis() as u64)
|
|
|
|
|
|
.unwrap_or(0)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
|
mod tests {
|
|
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
|
fn zero_core_route_uses_one_shared_zhuyuan_kernel_and_reality_memory_branch() {
|
|
|
|
|
|
assert_eq!(PERSONA_NUMBER, "ICE-P-ZY001");
|
|
|
|
|
|
assert_eq!(
|
|
|
|
|
|
SELF_KERNEL_SHA256,
|
|
|
|
|
|
"abebf12cc28b00bfeaf8a23a563e73390ebe337ded74d7ac70bcfae484450d68"
|
|
|
|
|
|
);
|
|
|
|
|
|
assert_eq!(
|
|
|
|
|
|
MEMORY_ROOT,
|
|
|
|
|
|
"HLDP://codex/zero-core/reality-development-execution"
|
|
|
|
|
|
);
|
2026-08-21 11:57:39 +08:00
|
|
|
|
assert_ne!(SELF_KERNEL_SHA256, MEMORY_SHA256);
|
2026-08-21 01:29:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|