zhuyuan-ice-gl-zy001/ZCODE-DEV-20260826/public-spine/shell-frozen-src/src-tauri/src/gls_protocol_kernel.rs

1722 lines
68 KiB
Rust

//! HoloLake GLS 原生协议内核。
//!
//! P1-P6 的协议在这里成为确定性的消息、身份、上下文、状态机和回执规则;
//! P7 只暴露真实节点能力装配状态,没有目标侧证据时永远不冒充物理能力。
use ring::digest::{digest, SHA256};
use rusqlite::{params, Connection, OptionalExtension, Transaction, TransactionBehavior};
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
use std::collections::{BTreeMap, HashSet};
use std::fs;
use std::path::{Path, PathBuf};
use std::sync::Mutex;
use std::time::Duration;
use std::time::{SystemTime, UNIX_EPOCH};
use tauri::{AppHandle, Manager};
use uuid::Uuid;
use crate::direct_local_session::{
authenticate_context_at, direct_session_root, AuthenticateSessionInput,
};
const EMBEDDED_KERNEL: &str = include_str!("../../contracts/gls-native-runtime-kernel.json");
const KERNEL_SCHEMA: &str = "hololake.gls-native-runtime-kernel/v1";
const REQUEST_SCHEMA: &str = "hololake.protocol-decision-request/v1";
const RECEIPT_SCHEMA: &str = "hololake.protocol-decision-receipt/v1";
const SOURCE_COMMIT: &str = "104a5d73162bdf4a529701e65898e2bc2863ea9e";
const MAX_TEXT_BYTES: usize = 512;
static LEDGER_SCHEMA_LOCK: Mutex<()> = Mutex::new(());
#[derive(Clone, Debug, Deserialize)]
struct KernelContract {
schema: String,
record_id: String,
source_commit: String,
receipt_schema: String,
decision_set: Vec<String>,
runtime_boundaries: RuntimeBoundaries,
stages: Vec<KernelStage>,
p7_node_assemblies: Vec<NodeAssembly>,
lifecycle_states: Vec<String>,
broadcast_actions: Vec<String>,
work_order_stages: Vec<String>,
}
#[derive(Clone, Debug, Deserialize)]
struct RuntimeBoundaries {
identity_is_authority: bool,
model_is_persona: bool,
model_can_override_decision: bool,
raw_protocol_text_executed: bool,
arbitrary_external_code_executed: bool,
last_write_wins_on_concurrent_state: bool,
target_evidence_required_for_completion: bool,
every_decision_writes_receipt: bool,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct KernelStage {
pub id: String,
pub state: String,
pub protocols: Vec<String>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct NodeAssembly {
protocol_id: String,
target: String,
state: String,
source_evidence_node: String,
}
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
struct ProtocolDecisionInput {
session: AuthenticateSessionInput,
request: ProtocolDecisionRequest,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
struct ProtocolDecisionRequest {
schema: String,
request_id: String,
idempotency_key: String,
event_kind: String,
human_controller_id: String,
subject: ProtocolIdentityReference,
target: ProtocolIdentityReference,
context: ProtocolContext,
issued_at_unix_ms: u64,
expires_at_unix_ms: u64,
payload_sha256: String,
state_before_digest: String,
state_after_digest: String,
#[serde(default)]
evidence_refs: Vec<String>,
operation: Value,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
struct ProtocolIdentityReference {
canonical_id: String,
subject_kind: String,
instance_id: String,
domain_id: String,
registry_ref: String,
proof_ref: String,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
struct ProtocolContext {
world_id: String,
domain_id: String,
channel_id: String,
task_id: String,
authorization_ref: String,
protocol_bundle_commit: String,
visibility_scope: String,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct ProtocolDecisionReceipt {
pub schema: String,
pub receipt_id: String,
pub sequence: u64,
pub previous_receipt_sha256: String,
pub request_id: String,
pub event_kind: String,
pub human_controller_id: String,
pub subject_id: String,
pub target_id: String,
pub protocol_bundle_commit: String,
pub protocol_bundle_sha256: String,
pub protocol_set: Vec<String>,
pub adapter_id: String,
pub input_digest: String,
pub decision: String,
pub reason_codes: Vec<String>,
pub state_before_digest: String,
pub state_after_digest: String,
pub evidence_refs: Vec<String>,
pub time_authority: String,
pub observed_at_unix_ms: u64,
pub idempotency_key: String,
pub signer: String,
pub receipt_sha256: String,
}
#[derive(Clone, Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ProtocolKernelSnapshot {
pub state: String,
pub contract_id: String,
pub source_commit: String,
pub executable_protocol_count: usize,
pub implemented_stage_count: usize,
pub decision_receipt_count: u64,
pub allow_count: u64,
pub deny_count: u64,
pub ambiguous_count: u64,
pub unverified_count: u64,
pub last_receipt_sha256: String,
pub stages: Vec<KernelStage>,
pub p7_node_assemblies: Vec<NodeAssembly>,
pub p7_verified_physical_capability_count: usize,
pub raw_protocol_text_executed: bool,
pub model_can_override_decision: bool,
pub bootstrap_compiler_self_check: String,
pub bootstrap_golden_gir_sha256: String,
}
#[derive(Clone, Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CompileHldpResult {
pub decision_receipt: ProtocolDecisionReceipt,
pub gir: Option<crate::gls_bootstrap_compiler::GirProgram>,
}
#[derive(Clone, Debug)]
struct Decision {
adapter: &'static str,
decision: &'static str,
reasons: Vec<String>,
}
fn load_contract() -> Result<KernelContract, String> {
let contract: KernelContract = serde_json::from_str(EMBEDDED_KERNEL)
.map_err(|error| format!("HOLOLAKE_GLS_KERNEL_CONTRACT_INVALID: {error}"))?;
validate_contract(&contract)?;
Ok(contract)
}
fn validate_contract(contract: &KernelContract) -> Result<(), String> {
let stages = contract
.stages
.iter()
.map(|stage| stage.id.as_str())
.collect::<Vec<_>>();
let decisions = contract
.decision_set
.iter()
.map(String::as_str)
.collect::<HashSet<_>>();
if contract.schema != KERNEL_SCHEMA
|| contract.record_id != "HLP-GLS-NATIVE-RUNTIME-KERNEL-001"
|| contract.source_commit != SOURCE_COMMIT
|| contract.receipt_schema != RECEIPT_SCHEMA
|| decisions != HashSet::from(["ALLOW", "DENY", "AMBIGUOUS", "UNVERIFIED"])
|| stages != ["P1", "P2", "P3", "P4", "P5", "P6", "P7"]
|| contract.stages[..6]
.iter()
.any(|stage| !stage.state.starts_with("IMPLEMENTED"))
|| contract.p7_node_assemblies.len() != 11
|| contract.runtime_boundaries.identity_is_authority
|| contract.runtime_boundaries.model_is_persona
|| contract.runtime_boundaries.model_can_override_decision
|| contract.runtime_boundaries.raw_protocol_text_executed
|| contract.runtime_boundaries.arbitrary_external_code_executed
|| contract
.runtime_boundaries
.last_write_wins_on_concurrent_state
|| !contract
.runtime_boundaries
.target_evidence_required_for_completion
|| !contract.runtime_boundaries.every_decision_writes_receipt
|| contract.lifecycle_states.len() != 14
|| contract.broadcast_actions.len() != 9
|| contract.work_order_stages != ["REGISTERED", "TESTED", "PUBLISHED", "DEPLOYED"]
{
return Err("HOLOLAKE_GLS_KERNEL_BOUNDARY_INVALID".into());
}
if contract.p7_node_assemblies.iter().any(|assembly| {
assembly.target != "DESKTOP_HOLOLAKE"
|| assembly.source_evidence_node.is_empty()
|| !assembly.protocol_id.starts_with("GLS-")
|| assembly.state == "ACTIVE_HEALTHY"
}) {
return Err("HOLOLAKE_GLS_P7_FALSE_PHYSICAL_CAPABILITY".into());
}
Ok(())
}
fn now_unix_ms() -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|value| value.as_millis() as u64)
.unwrap_or(0)
}
fn sha256(bytes: &[u8]) -> String {
digest(&SHA256, bytes)
.as_ref()
.iter()
.map(|byte| format!("{byte:02x}"))
.collect()
}
fn is_digest(value: &str) -> bool {
value.len() == 64 && value.chars().all(|character| character.is_ascii_hexdigit())
}
fn valid_text(value: &str) -> bool {
!value.trim().is_empty()
&& value.len() <= MAX_TEXT_BYTES
&& !value.chars().any(char::is_control)
}
fn operation_digest(operation: &Value) -> Result<String, String> {
serde_json::to_vec(operation)
.map(|bytes| sha256(&bytes))
.map_err(|error| format!("HOLOLAKE_GLS_OPERATION_SERIALIZE_FAILED: {error}"))
}
fn value_string<'a>(object: &'a Map<String, Value>, key: &str) -> Option<&'a str> {
object
.get(key)
.and_then(Value::as_str)
.filter(|value| valid_text(value))
}
fn value_u64(object: &Map<String, Value>, key: &str) -> Option<u64> {
object.get(key).and_then(Value::as_u64)
}
fn allowed_operation_fields(event: &str) -> &'static [&'static str] {
match event {
"MESSAGE_VALIDATE" | "IDENTITY_VERIFY" | "CONTEXT_RESOLVE" | "DECISION_RECEIPT" => &[],
"HEARTBEAT_OBSERVE" => &["leaseExpiresAtUnixMs", "healthDigest"],
"WORK_ORDER_TRANSITION" => &["proposerId", "approverId", "fromStage", "toStage"],
"LIVE_SESSION_OBSERVE" => &["connected", "serverReceiptRef"],
"WITNESS_APPEND" => &["targetEvidenceRef"],
"MEMORY_SYNC" | "STATE_SYNC" => &["causalRelation", "localVersion", "remoteVersion"],
"TIME_CONTINUITY" => &[
"previousSequence",
"nextSequence",
"primaryInstanceId",
"leaseExpiresAtUnixMs",
],
"MODULE_ADMIT" => &[
"moduleId",
"immutableVersion",
"contentDigest",
"provenanceRef",
"signatureRef",
],
"LIFECYCLE_TRANSITION" => &["fromState", "toState"],
"RUNWAY_ASSIGN" => &[
"cpuUnits",
"memoryBytes",
"channelIsolation",
"isolationKey",
],
"RUNWAY_RELEASE" => &["resourcesReleased", "targetEvidenceRef", "isolationKey"],
"BROADCAST_TRANSITION" => &["epoch", "controllerInstanceId", "fromAction", "toAction"],
"EXTERNAL_ADAPTER_TRANSLATE" => &[
"externalKind",
"normalizedDigest",
"sourceRef",
"requestsExecutionAuthority",
],
"MODEL_ROUTE" => &[
"modelId",
"modelIsPersona",
"grantsWorldAuthority",
"privacyClass",
"healthReceiptRef",
],
"TEMPORARY_CAPABILITY" => &[
"sandboxed",
"permanentInstall",
"autoPublish",
"autoDeploy",
"cleanupPlanDigest",
],
"HLDP_NP_VALIDATE" | "GIR_VALIDATE" | "COMPILE_HLDP" => &[
"sourceDigest",
"unresolvedNaturalLanguage",
"unresolvedPermissions",
"goldenVectorDigest",
],
_ => &[],
}
}
fn adapter_for(event: &str) -> Option<&'static str> {
match event {
"MESSAGE_VALIDATE" => Some("glp-envelope-codec"),
"IDENTITY_VERIFY" => Some("glp-identity-reference"),
"CONTEXT_RESOLVE" => Some("glp-context-guard"),
"DECISION_RECEIPT" => Some("glp-decision-kernel"),
"HEARTBEAT_OBSERVE"
| "WORK_ORDER_TRANSITION"
| "LIVE_SESSION_OBSERVE"
| "WITNESS_APPEND" => Some("glp-live-coordination"),
"MEMORY_SYNC" | "STATE_SYNC" | "TIME_CONTINUITY" => Some("glp-continuity-kernel"),
"MODULE_ADMIT"
| "LIFECYCLE_TRANSITION"
| "RUNWAY_ASSIGN"
| "RUNWAY_RELEASE"
| "BROADCAST_TRANSITION" => Some("gls-execution-control"),
"EXTERNAL_ADAPTER_TRANSLATE" | "MODEL_ROUTE" | "TEMPORARY_CAPABILITY" => {
Some("gls-external-resource-boundary")
}
"HLDP_NP_VALIDATE" | "GIR_VALIDATE" | "COMPILE_HLDP" => Some("gls-bootstrap-compiler"),
_ => None,
}
}
fn decide(
request: &ProtocolDecisionRequest,
session_account: &str,
session_id: &str,
observed_at: u64,
) -> Decision {
let deny = |code: &str| Decision {
adapter: adapter_for(&request.event_kind).unwrap_or("glp-decision-kernel"),
decision: "DENY",
reasons: vec![code.into()],
};
let ambiguous = |code: &str| Decision {
adapter: adapter_for(&request.event_kind).unwrap_or("glp-decision-kernel"),
decision: "AMBIGUOUS",
reasons: vec![code.into()],
};
let unverified = |code: &str| Decision {
adapter: adapter_for(&request.event_kind).unwrap_or("glp-decision-kernel"),
decision: "UNVERIFIED",
reasons: vec![code.into()],
};
let allow = |code: &str| Decision {
adapter: adapter_for(&request.event_kind).unwrap_or("glp-decision-kernel"),
decision: "ALLOW",
reasons: vec![code.into()],
};
if request.schema != REQUEST_SCHEMA
|| !valid_text(&request.request_id)
|| !valid_text(&request.idempotency_key)
{
return deny("GLP_ENVELOPE_INCOMPLETE");
}
if request.human_controller_id != session_account {
return deny("GLP_IDENTITY_SESSION_CONFLICT");
}
for identity in [&request.subject, &request.target] {
if !valid_text(&identity.canonical_id)
|| !valid_text(&identity.subject_kind)
|| !valid_text(&identity.instance_id)
|| !valid_text(&identity.domain_id)
|| !valid_text(&identity.registry_ref)
|| !valid_text(&identity.proof_ref)
{
return deny("GLP_IDENTITY_REFERENCE_INCOMPLETE");
}
}
if request.context.domain_id != request.target.domain_id
|| request.subject.domain_id != request.context.domain_id
{
return ambiguous("GLP_CONTEXT_DOMAIN_CONFLICT");
}
if !valid_text(&request.context.world_id)
|| !valid_text(&request.context.channel_id)
|| !valid_text(&request.context.task_id)
|| !valid_text(&request.context.visibility_scope)
{
return ambiguous("GLP_CONTEXT_INCOMPLETE");
}
if request.context.protocol_bundle_commit != SOURCE_COMMIT {
return deny("GLP_PROTOCOL_BUNDLE_DRIFT");
}
if request.issued_at_unix_ms > observed_at.saturating_add(300_000)
|| request.expires_at_unix_ms <= observed_at
|| request.expires_at_unix_ms <= request.issued_at_unix_ms
{
return deny("GLP_ENVELOPE_EXPIRED_OR_TIME_INVALID");
}
if !is_digest(&request.payload_sha256)
|| operation_digest(&request.operation).ok().as_deref()
!= Some(request.payload_sha256.as_str())
|| !is_digest(&request.state_before_digest)
|| !is_digest(&request.state_after_digest)
{
return deny("GLP_INPUT_OR_STATE_DIGEST_DRIFT");
}
let Some(adapter) = adapter_for(&request.event_kind) else {
return deny("GLP_EVENT_KIND_UNKNOWN");
};
let Some(object) = request.operation.as_object() else {
return deny("GLP_OPERATION_OBJECT_REQUIRED");
};
let allowed_fields = allowed_operation_fields(&request.event_kind);
if object
.keys()
.any(|key| !allowed_fields.contains(&key.as_str()))
{
return deny("GLP_OPERATION_FIELD_UNKNOWN");
}
if !matches!(
request.event_kind.as_str(),
"MESSAGE_VALIDATE"
| "IDENTITY_VERIFY"
| "CONTEXT_RESOLVE"
| "HEARTBEAT_OBSERVE"
| "LIVE_SESSION_OBSERVE"
) && request.context.authorization_ref != format!("direct-session://{session_id}")
{
return unverified("GLP_AUTHORIZATION_EVIDENCE_MISSING");
}
let result = match request.event_kind.as_str() {
"MESSAGE_VALIDATE" | "IDENTITY_VERIFY" | "CONTEXT_RESOLVE" | "DECISION_RECEIPT" => {
allow("GLP_CONTRACT_VALID")
}
"HEARTBEAT_OBSERVE" => match (
value_u64(object, "leaseExpiresAtUnixMs"),
value_string(object, "healthDigest"),
) {
(Some(expiry), Some(hash)) if expiry > observed_at && is_digest(hash) => {
allow("GLP_HEARTBEAT_CURRENT")
}
_ => unverified("GLP_HEARTBEAT_STALE_OR_UNPROVEN"),
},
"WORK_ORDER_TRANSITION" => {
let proposer = value_string(object, "proposerId");
let approver = value_string(object, "approverId");
let from = value_string(object, "fromStage");
let to = value_string(object, "toStage");
if proposer.is_some() && proposer == approver {
deny("GLP_WORK_ORDER_SELF_APPROVAL_DENIED")
} else if approver.is_none() {
unverified("GLP_WORK_ORDER_APPROVER_MISSING")
} else if !matches!(
(from, to),
(Some("REGISTERED"), Some("TESTED"))
| (Some("TESTED"), Some("PUBLISHED"))
| (Some("PUBLISHED"), Some("DEPLOYED"))
) {
deny("GLP_WORK_ORDER_STAGE_TRANSITION_INVALID")
} else {
allow("GLP_WORK_ORDER_SEPARATION_OF_DUTIES_VALID")
}
}
"LIVE_SESSION_OBSERVE" => {
if object.get("connected").and_then(Value::as_bool) == Some(true)
&& value_string(object, "serverReceiptRef").is_some()
{
allow("HLSP_CURRENT_SERVER_SESSION_VERIFIED")
} else {
unverified("HLSP_OFFLINE_CACHE_IS_NOT_LIVE_STATE")
}
}
"WITNESS_APPEND" => {
if value_string(object, "targetEvidenceRef").is_some() {
allow("GLOW_TARGET_EVIDENCE_APPENDED")
} else {
unverified("GLOW_TARGET_EVIDENCE_MISSING")
}
}
"MEMORY_SYNC" | "STATE_SYNC" => {
let local = value_u64(object, "localVersion");
let remote = value_u64(object, "remoteVersion");
match (value_string(object, "causalRelation"), local, remote) {
(Some("CONCURRENT"), Some(_), Some(_)) => {
ambiguous("GLP_CONCURRENT_VERSIONS_PRESERVED")
}
(Some("EQUAL"), Some(left), Some(right)) if left == right => {
allow("GLP_CAUSAL_SYNC_VALID")
}
(Some("BEFORE"), Some(left), Some(right)) if left < right => {
allow("GLP_CAUSAL_SYNC_VALID")
}
(Some("AFTER"), Some(left), Some(right)) if left > right => {
allow("GLP_CAUSAL_SYNC_VALID")
}
_ => deny("GLP_CAUSAL_SYNC_RELATION_INVALID"),
}
}
"TIME_CONTINUITY" => {
let previous = value_u64(object, "previousSequence");
let next = value_u64(object, "nextSequence");
let primary = value_string(object, "primaryInstanceId");
let lease = value_u64(object, "leaseExpiresAtUnixMs");
if previous
.zip(next)
.map_or(true, |(left, right)| right != left.saturating_add(1))
{
deny("PTCP_NON_MONOTONIC_EVENT_SEQUENCE")
} else if primary != Some(request.subject.instance_id.as_str()) {
deny("PTCP_DOUBLE_PRIMARY_OR_OWNER_CONFLICT")
} else if lease.map_or(true, |expiry| expiry <= observed_at) {
unverified("PTCP_PRIMARY_LEASE_EXPIRED")
} else {
allow("PTCP_MONOTONIC_SINGLE_PRIMARY_VALID")
}
}
"MODULE_ADMIT" => {
let content = value_string(object, "contentDigest");
if content.map_or(true, |value| !is_digest(value))
|| value_string(object, "moduleId").is_none()
|| value_string(object, "immutableVersion").is_none()
|| value_string(object, "provenanceRef").is_none()
{
deny("GMP_MODULE_BACKPACK_INCOMPLETE")
} else if value_string(object, "signatureRef").is_none() {
unverified("GMP_MODULE_SIGNATURE_UNVERIFIED")
} else {
allow("GMP_IMMUTABLE_MODULE_ADMITTED")
}
}
"LIFECYCLE_TRANSITION" => {
let contract = load_contract().ok();
let from = value_string(object, "fromState");
let to = value_string(object, "toState");
let adjacent = contract.as_ref().is_some_and(|contract| {
from.zip(to).is_some_and(|(left, right)| {
let left_index = contract
.lifecycle_states
.iter()
.position(|state| state == left);
let right_index = contract
.lifecycle_states
.iter()
.position(|state| state == right);
matches!((left_index, right_index), (Some(a), Some(b)) if b == a + 1)
|| matches!(
(left, right),
("REGISTERED", "RESIDENT")
| ("REGISTERED", "DORMANT")
| ("RETURNED", "DORMANT")
)
})
});
if adjacent {
allow("PALP_TRANSITION_VALID")
} else {
deny("PALP_TRANSITION_INVALID")
}
}
"RUNWAY_ASSIGN" => {
if value_u64(object, "cpuUnits").is_some_and(|value| value > 0)
&& value_u64(object, "memoryBytes").is_some_and(|value| value > 0)
&& object.get("channelIsolation").and_then(Value::as_bool) == Some(true)
&& value_string(object, "isolationKey").is_some()
{
allow("GRSP_ISOLATED_RUNWAY_ASSIGNED")
} else {
deny("GRSP_RESOURCE_OR_ISOLATION_INVALID")
}
}
"RUNWAY_RELEASE" => {
if object.get("resourcesReleased").and_then(Value::as_bool) == Some(true)
&& value_string(object, "targetEvidenceRef").is_some()
&& value_string(object, "isolationKey").is_some()
{
allow("GRSP_RESOURCES_RELEASED")
} else {
unverified("GRSP_RESOURCE_CLEANUP_UNVERIFIED")
}
}
"BROADCAST_TRANSITION" => {
let contract = load_contract().ok();
let from = value_string(object, "fromAction");
let to = value_string(object, "toAction");
let adjacent = contract.as_ref().is_some_and(|contract| {
from.zip(to).is_some_and(|(left, right)| {
contract
.broadcast_actions
.iter()
.position(|state| state == left)
.zip(
contract
.broadcast_actions
.iter()
.position(|state| state == right),
)
.is_some_and(|(a, b)| b == a + 1)
})
});
if value_u64(object, "epoch").map_or(true, |value| value == 0)
|| value_string(object, "controllerInstanceId")
!= Some(request.subject.instance_id.as_str())
{
deny("BTCP_CONTROL_EPOCH_OR_OWNER_INVALID")
} else if !adjacent {
deny("BTCP_TRANSITION_INVALID")
} else {
allow("BTCP_UNIQUE_CONTROL_EPOCH_TRANSITION_VALID")
}
}
"EXTERNAL_ADAPTER_TRANSLATE" => {
if object
.get("requestsExecutionAuthority")
.and_then(Value::as_bool)
!= Some(false)
{
deny("UAP_CANNOT_REQUEST_EXECUTION_AUTHORITY")
} else if value_string(object, "normalizedDigest")
.map_or(true, |value| !is_digest(value))
|| value_string(object, "sourceRef").is_none()
{
deny("UAP_NORMALIZED_SOURCE_INVALID")
} else {
allow("UAP_SEMANTIC_TRANSLATION_VALID")
}
}
"MODEL_ROUTE" => {
if object.get("modelIsPersona").and_then(Value::as_bool) != Some(false)
|| object.get("grantsWorldAuthority").and_then(Value::as_bool) != Some(false)
{
deny("GMRP_MODEL_PERSONA_OR_AUTHORITY_CONFUSION")
} else if value_string(object, "modelId").is_none()
|| value_string(object, "healthReceiptRef").is_none()
{
unverified("GMRP_MODEL_HEALTH_UNVERIFIED")
} else {
allow("GMRP_REPLACEABLE_MODEL_ROUTE_VALID")
}
}
"TEMPORARY_CAPABILITY" => {
if object.get("sandboxed").and_then(Value::as_bool) != Some(true)
|| object.get("permanentInstall").and_then(Value::as_bool) != Some(false)
|| object.get("autoPublish").and_then(Value::as_bool) != Some(false)
|| object.get("autoDeploy").and_then(Value::as_bool) != Some(false)
{
deny("PEN_EPHEMERAL_BOUNDARY_VIOLATION")
} else if value_string(object, "cleanupPlanDigest")
.map_or(true, |value| !is_digest(value))
{
deny("PEN_CLEANUP_PLAN_REQUIRED")
} else {
allow("PEN_SANDBOXED_TEMPORARY_CAPABILITY_VALID")
}
}
"HLDP_NP_VALIDATE" | "GIR_VALIDATE" | "COMPILE_HLDP" => {
let source = value_string(object, "sourceDigest");
let golden = value_string(object, "goldenVectorDigest");
let unresolved_language = object
.get("unresolvedNaturalLanguage")
.and_then(Value::as_array);
let unresolved_permissions = object
.get("unresolvedPermissions")
.and_then(Value::as_array);
if source.map_or(true, |value| !is_digest(value))
|| golden.map_or(true, |value| !is_digest(value))
{
deny("GLC_SOURCE_OR_GOLDEN_VECTOR_DIGEST_INVALID")
} else if unresolved_language.map_or(true, |items| !items.is_empty())
|| unresolved_permissions.map_or(true, |items| !items.is_empty())
{
deny("GLC_UNRESOLVED_LANGUAGE_OR_PERMISSION_FORBIDDEN")
} else {
allow("GLC_BOOTSTRAP_GIR_CONTRACT_VALID")
}
}
_ => deny("GLP_EVENT_KIND_UNKNOWN"),
};
Decision { adapter, ..result }
}
fn ledger_path(app: &AppHandle) -> Result<PathBuf, String> {
Ok(app
.path()
.app_data_dir()
.map_err(|error| format!("HOLOLAKE_GLS_LEDGER_ROOT_FAILED: {error}"))?
.join("protocol-runtime")
.join("protocol-decisions.sqlite3"))
}
pub(crate) fn start_on_application_open(app: &AppHandle) -> Result<(), String> {
load_contract()?;
crate::gls_bootstrap_compiler::bootstrap_self_check()?;
for (adapter, event) in [
("glp-decision-kernel", "DECISION_RECEIPT"),
("glp-live-coordination", "LIVE_SESSION_OBSERVE"),
("glp-continuity-kernel", "TIME_CONTINUITY"),
("gls-execution-control", "BROADCAST_TRANSITION"),
("gls-external-resource-boundary", "TEMPORARY_CAPABILITY"),
("gls-bootstrap-compiler", "COMPILE_HLDP"),
] {
crate::gls_protocol_runtime::require_adapter(adapter, event)?;
}
open_ledger(&ledger_path(app)?)?;
Ok(())
}
fn open_ledger(path: &Path) -> Result<Connection, String> {
if let Some(parent) = path.parent() {
fs::create_dir_all(parent)
.map_err(|error| format!("HOLOLAKE_GLS_LEDGER_CREATE_FAILED: {error}"))?;
}
// 多个协议请求可能在首次启动的同一瞬间进入。SQLite 的 WAL 切换与建表必须先在
// 进程内串行完成,之后各请求再依靠 IMMEDIATE 事务并发竞争,避免把首启抢锁误报
// 成协议内核不可用。
let _schema_guard = LEDGER_SCHEMA_LOCK
.lock()
.map_err(|_| "HOLOLAKE_GLS_LEDGER_SCHEMA_LOCK_POISONED".to_string())?;
let connection = Connection::open(path)
.map_err(|error| format!("HOLOLAKE_GLS_LEDGER_OPEN_FAILED: {error}"))?;
connection
.busy_timeout(Duration::from_secs(5))
.map_err(|error| format!("HOLOLAKE_GLS_LEDGER_BUSY_TIMEOUT_FAILED: {error}"))?;
connection.execute_batch("PRAGMA journal_mode=WAL; PRAGMA synchronous=FULL;
CREATE TABLE IF NOT EXISTS protocol_receipts (sequence INTEGER PRIMARY KEY, idempotency_key TEXT NOT NULL, input_digest TEXT NOT NULL, decision TEXT NOT NULL, receipt_sha256 TEXT NOT NULL, receipt_json TEXT NOT NULL);
CREATE TABLE IF NOT EXISTS protocol_state (state_key TEXT PRIMARY KEY, state_json TEXT NOT NULL, updated_by_idempotency_key TEXT NOT NULL);
CREATE TABLE IF NOT EXISTS protocol_conflicts (conflict_sha256 TEXT PRIMARY KEY, state_key TEXT NOT NULL, conflict_json TEXT NOT NULL, observed_at_unix_ms INTEGER NOT NULL);"
)
.map_err(|error| format!("HOLOLAKE_GLS_LEDGER_SCHEMA_FAILED: {error}"))?;
Ok(connection)
}
fn state_value(transaction: &Transaction<'_>, key: &str) -> Result<Option<Value>, String> {
let json: Option<String> = transaction
.query_row(
"SELECT state_json FROM protocol_state WHERE state_key=?1",
params![key],
|row| row.get(0),
)
.optional()
.map_err(|error| format!("HOLOLAKE_GLS_STATE_READ_FAILED: {error}"))?;
json.map(|value| {
serde_json::from_str(&value)
.map_err(|error| format!("HOLOLAKE_GLS_STATE_RECORD_INVALID: {error}"))
})
.transpose()
}
fn write_state(
transaction: &Transaction<'_>,
key: &str,
value: &Value,
idempotency_key: &str,
) -> Result<(), String> {
let json = serde_json::to_string(value)
.map_err(|error| format!("HOLOLAKE_GLS_STATE_SERIALIZE_FAILED: {error}"))?;
transaction
.execute(
"INSERT INTO protocol_state(state_key,state_json,updated_by_idempotency_key) VALUES(?1,?2,?3) ON CONFLICT(state_key) DO UPDATE SET state_json=excluded.state_json,updated_by_idempotency_key=excluded.updated_by_idempotency_key",
params![key, json, idempotency_key],
)
.map_err(|error| format!("HOLOLAKE_GLS_STATE_WRITE_FAILED: {error}"))?;
Ok(())
}
fn deny_receipt(receipt: &mut ProtocolDecisionReceipt, code: &str) {
receipt.decision = "DENY".into();
receipt.reason_codes = vec![code.into()];
}
fn project_state_digests(
receipt: &mut ProtocolDecisionReceipt,
before: &Value,
after: &Value,
) -> Result<(), String> {
receipt.state_before_digest = sha256(
&serde_json::to_vec(before)
.map_err(|error| format!("HOLOLAKE_GLS_STATE_SERIALIZE_FAILED: {error}"))?,
);
receipt.state_after_digest = sha256(
&serde_json::to_vec(after)
.map_err(|error| format!("HOLOLAKE_GLS_STATE_SERIALIZE_FAILED: {error}"))?,
);
Ok(())
}
fn enforce_persistent_state(
transaction: &Transaction<'_>,
receipt: &mut ProtocolDecisionReceipt,
request: &ProtocolDecisionRequest,
) -> Result<(), String> {
let Some(operation) = request.operation.as_object() else {
return Ok(());
};
if receipt.decision == "AMBIGUOUS"
&& matches!(request.event_kind.as_str(), "MEMORY_SYNC" | "STATE_SYNC")
{
let key = format!(
"sync:{}:{}",
request.event_kind, request.subject.canonical_id
);
let before = state_value(transaction, &key)?.unwrap_or(Value::Null);
let conflict = serde_json::json!({"before":before,"incoming":request.operation,"reason":"CONCURRENT_VERSIONS_PRESERVED"});
let bytes = serde_json::to_vec(&conflict)
.map_err(|error| format!("HOLOLAKE_GLS_CONFLICT_SERIALIZE_FAILED: {error}"))?;
let conflict_hash = sha256(&bytes);
transaction.execute(
"INSERT OR IGNORE INTO protocol_conflicts(conflict_sha256,state_key,conflict_json,observed_at_unix_ms) VALUES(?1,?2,?3,?4)",
params![conflict_hash, key, String::from_utf8_lossy(&bytes), receipt.observed_at_unix_ms],
).map_err(|error| format!("HOLOLAKE_GLS_CONFLICT_WRITE_FAILED: {error}"))?;
project_state_digests(receipt, &before, &conflict)?;
return Ok(());
}
if receipt.decision != "ALLOW" {
return Ok(());
}
let (key, before, after) = match request.event_kind.as_str() {
"WORK_ORDER_TRANSITION" => {
let key = format!("work-order:{}", request.context.task_id);
let before = state_value(transaction, &key)?
.unwrap_or_else(|| serde_json::json!({"stage":"REGISTERED"}));
let current = before
.get("stage")
.and_then(Value::as_str)
.unwrap_or("INVALID");
let expected = value_string(operation, "fromStage").unwrap_or("MISSING");
if current != expected {
deny_receipt(receipt, "GLP_WORK_ORDER_PERSISTED_STAGE_MISMATCH");
return Ok(());
}
let after = serde_json::json!({"stage":value_string(operation,"toStage").unwrap_or("INVALID"),"approverId":value_string(operation,"approverId").unwrap_or("UNKNOWN")});
(key, before, after)
}
"MEMORY_SYNC" | "STATE_SYNC" => {
let key = format!(
"sync:{}:{}",
request.event_kind, request.subject.canonical_id
);
let before = state_value(transaction, &key)?.unwrap_or(Value::Null);
let after = request.operation.clone();
(key, before, after)
}
"TIME_CONTINUITY" => {
let key = format!("time:{}", request.subject.canonical_id);
let before = state_value(transaction, &key)?.unwrap_or_else(|| serde_json::json!({"sequence":0,"primaryInstanceId":Value::Null,"leaseExpiresAtUnixMs":0}));
let current_sequence = before.get("sequence").and_then(Value::as_u64).unwrap_or(0);
let current_owner = before.get("primaryInstanceId").and_then(Value::as_str);
let current_lease = before
.get("leaseExpiresAtUnixMs")
.and_then(Value::as_u64)
.unwrap_or(0);
let requested_previous = value_u64(operation, "previousSequence").unwrap_or(u64::MAX);
let requested_owner = value_string(operation, "primaryInstanceId").unwrap_or("MISSING");
if requested_previous != current_sequence {
deny_receipt(receipt, "PTCP_PERSISTED_SEQUENCE_MISMATCH");
return Ok(());
}
if current_lease > receipt.observed_at_unix_ms
&& current_owner.is_some()
&& current_owner != Some(requested_owner)
{
deny_receipt(receipt, "PTCP_PERSISTED_PRIMARY_LEASE_CONFLICT");
return Ok(());
}
let after = serde_json::json!({"sequence":value_u64(operation,"nextSequence").unwrap_or(0),"primaryInstanceId":requested_owner,"leaseExpiresAtUnixMs":value_u64(operation,"leaseExpiresAtUnixMs").unwrap_or(0)});
(key, before, after)
}
"MODULE_ADMIT" => {
let module_id = value_string(operation, "moduleId").unwrap_or("MISSING");
let key = format!("module:{module_id}");
let before = state_value(transaction, &key)?.unwrap_or(Value::Null);
if before != Value::Null
&& before.get("contentDigest") != operation.get("contentDigest")
{
deny_receipt(receipt, "GMP_IMMUTABLE_MODULE_DIGEST_CONFLICT");
return Ok(());
}
(key, before, request.operation.clone())
}
"LIFECYCLE_TRANSITION" => {
let key = format!("lifecycle:{}", request.subject.instance_id);
let before = state_value(transaction, &key)?
.unwrap_or_else(|| serde_json::json!({"state":"REGISTERED"}));
let current = before
.get("state")
.and_then(Value::as_str)
.unwrap_or("INVALID");
if current != value_string(operation, "fromState").unwrap_or("MISSING") {
deny_receipt(receipt, "PALP_PERSISTED_STATE_MISMATCH");
return Ok(());
}
let after =
serde_json::json!({"state":value_string(operation,"toState").unwrap_or("INVALID")});
(key, before, after)
}
"RUNWAY_ASSIGN" => {
let isolation = value_string(operation, "isolationKey").unwrap_or("MISSING");
let key = format!("runway:{}:{isolation}", request.context.channel_id);
let before = state_value(transaction, &key)?.unwrap_or(Value::Null);
if before.get("state").and_then(Value::as_str) == Some("ASSIGNED") {
deny_receipt(receipt, "GRSP_RUNWAY_ALREADY_ASSIGNED");
return Ok(());
}
let after = serde_json::json!({"state":"ASSIGNED","ownerInstanceId":request.subject.instance_id,"channelId":request.context.channel_id,"resources":request.operation});
(key, before, after)
}
"RUNWAY_RELEASE" => {
let evidence = value_string(operation, "targetEvidenceRef").unwrap_or("MISSING");
let isolation = value_string(operation, "isolationKey").unwrap_or("MISSING");
let key = format!("runway:{}:{isolation}", request.context.channel_id);
let before = state_value(transaction, &key)?.unwrap_or(Value::Null);
if before.get("state").and_then(Value::as_str) != Some("ASSIGNED")
|| before.get("ownerInstanceId").and_then(Value::as_str)
!= Some(request.subject.instance_id.as_str())
{
deny_receipt(receipt, "GRSP_PERSISTED_RUNWAY_OWNER_MISMATCH");
return Ok(());
}
let after = serde_json::json!({"state":"RELEASED","targetEvidenceRef":evidence,"isolationKey":isolation});
(key, before, after)
}
"BROADCAST_TRANSITION" => {
let key = format!("broadcast:{}", request.context.domain_id);
let before = state_value(transaction, &key)?.unwrap_or_else(|| serde_json::json!({"action":"REGISTER","epoch":0,"controllerInstanceId":Value::Null}));
let current_action = before
.get("action")
.and_then(Value::as_str)
.unwrap_or("INVALID");
let current_epoch = before.get("epoch").and_then(Value::as_u64).unwrap_or(0);
let current_owner = before.get("controllerInstanceId").and_then(Value::as_str);
let requested_epoch = value_u64(operation, "epoch").unwrap_or(0);
let requested_owner =
value_string(operation, "controllerInstanceId").unwrap_or("MISSING");
if current_action != value_string(operation, "fromAction").unwrap_or("MISSING")
|| requested_epoch < current_epoch
{
deny_receipt(receipt, "BTCP_PERSISTED_ACTION_OR_EPOCH_MISMATCH");
return Ok(());
}
if requested_epoch == current_epoch
&& current_epoch > 0
&& current_owner != Some(requested_owner)
{
deny_receipt(receipt, "BTCP_DOUBLE_CONTROLLER_EPOCH_CONFLICT");
return Ok(());
}
let after = serde_json::json!({"action":value_string(operation,"toAction").unwrap_or("INVALID"),"epoch":requested_epoch,"controllerInstanceId":requested_owner});
(key, before, after)
}
_ => return Ok(()),
};
project_state_digests(receipt, &before, &after)?;
write_state(transaction, &key, &after, &receipt.idempotency_key)
}
fn persist_receipt(
path: &Path,
mut receipt: ProtocolDecisionReceipt,
request: Option<&ProtocolDecisionRequest>,
) -> Result<ProtocolDecisionReceipt, String> {
let mut connection = open_ledger(path)?;
let transaction = connection
.transaction_with_behavior(TransactionBehavior::Immediate)
.map_err(|error| format!("HOLOLAKE_GLS_LEDGER_LOCK_FAILED: {error}"))?;
let existing: Option<(String, String)> = transaction.query_row(
"SELECT input_digest, receipt_json FROM protocol_receipts WHERE idempotency_key=?1 ORDER BY sequence ASC LIMIT 1",
params![receipt.idempotency_key],
|row| Ok((row.get(0)?, row.get(1)?)),
).optional().map_err(|error| format!("HOLOLAKE_GLS_LEDGER_READ_FAILED: {error}"))?;
if let Some((input_digest, json)) = existing {
if input_digest == receipt.input_digest {
return serde_json::from_str(&json)
.map_err(|error| format!("HOLOLAKE_GLS_RECEIPT_REPLAY_INVALID: {error}"));
}
receipt.decision = "DENY".into();
receipt.reason_codes = vec!["GLP_IDEMPOTENCY_KEY_REUSED_WITH_DIFFERENT_INPUT".into()];
}
if let Some(request) = request {
enforce_persistent_state(&transaction, &mut receipt, request)?;
}
let previous: Option<(u64, String)> = transaction
.query_row(
"SELECT sequence, receipt_sha256 FROM protocol_receipts ORDER BY sequence DESC LIMIT 1",
[],
|row| Ok((row.get(0)?, row.get(1)?)),
)
.optional()
.map_err(|error| format!("HOLOLAKE_GLS_LEDGER_TAIL_FAILED: {error}"))?;
receipt.sequence = previous.as_ref().map_or(1, |(sequence, _)| sequence + 1);
receipt.previous_receipt_sha256 = previous.map_or_else(|| "GENESIS".into(), |(_, hash)| hash);
receipt.receipt_id = format!("GLP-RCP-{:012}-{}", receipt.sequence, Uuid::new_v4());
receipt.receipt_sha256.clear();
receipt.receipt_sha256 = sha256(
&serde_json::to_vec(&receipt)
.map_err(|error| format!("HOLOLAKE_GLS_RECEIPT_SERIALIZE_FAILED: {error}"))?,
);
let json = serde_json::to_string(&receipt)
.map_err(|error| format!("HOLOLAKE_GLS_RECEIPT_SERIALIZE_FAILED: {error}"))?;
transaction.execute("INSERT INTO protocol_receipts(sequence,idempotency_key,input_digest,decision,receipt_sha256,receipt_json) VALUES(?1,?2,?3,?4,?5,?6)", params![receipt.sequence, receipt.idempotency_key, receipt.input_digest, receipt.decision, receipt.receipt_sha256, json])
.map_err(|error| format!("HOLOLAKE_GLS_LEDGER_APPEND_FAILED: {error}"))?;
transaction
.commit()
.map_err(|error| format!("HOLOLAKE_GLS_LEDGER_COMMIT_FAILED: {error}"))?;
Ok(receipt)
}
fn build_receipt(
value: &Value,
parsed: Option<&ProtocolDecisionInput>,
decision: Decision,
protocols: Vec<String>,
observed_at: u64,
) -> ProtocolDecisionReceipt {
let request = parsed.map(|input| &input.request);
let text = |pointer: &str| {
value
.pointer(pointer)
.and_then(Value::as_str)
.unwrap_or("UNKNOWN")
.to_string()
};
ProtocolDecisionReceipt {
schema: RECEIPT_SCHEMA.into(),
receipt_id: String::new(),
sequence: 0,
previous_receipt_sha256: String::new(),
request_id: request.map_or_else(
|| text("/request/requestId"),
|item| item.request_id.clone(),
),
event_kind: request.map_or_else(
|| text("/request/eventKind"),
|item| item.event_kind.clone(),
),
human_controller_id: request.map_or_else(
|| text("/request/humanControllerId"),
|item| item.human_controller_id.clone(),
),
subject_id: request.map_or_else(
|| text("/request/subject/canonicalId"),
|item| item.subject.canonical_id.clone(),
),
target_id: request.map_or_else(
|| text("/request/target/canonicalId"),
|item| item.target.canonical_id.clone(),
),
protocol_bundle_commit: request.map_or_else(
|| "UNKNOWN".into(),
|item| item.context.protocol_bundle_commit.clone(),
),
protocol_bundle_sha256: sha256(EMBEDDED_KERNEL.as_bytes()),
protocol_set: protocols,
adapter_id: decision.adapter.into(),
input_digest: sha256(&serde_json::to_vec(value).unwrap_or_default()),
decision: decision.decision.into(),
reason_codes: decision.reasons,
state_before_digest: request
.map_or_else(|| "UNKNOWN".into(), |item| item.state_before_digest.clone()),
state_after_digest: request
.map_or_else(|| "UNKNOWN".into(), |item| item.state_after_digest.clone()),
evidence_refs: request.map_or_else(Vec::new, |item| item.evidence_refs.clone()),
time_authority: format!("HOLOLAKE_GUANGHU_TIME_AUTHORITY@{observed_at}"),
observed_at_unix_ms: observed_at,
idempotency_key: request.map_or_else(
|| text("/request/idempotencyKey"),
|item| item.idempotency_key.clone(),
),
signer: "HOLOLAKE_NATIVE_PROTOCOL_KERNEL_LOCAL_HASH_CHAIN".into(),
receipt_sha256: String::new(),
}
}
fn decide_value_at(
ledger: &Path,
session_root: &Path,
value: Value,
observed_at: u64,
) -> Result<ProtocolDecisionReceipt, String> {
let parsed = match serde_json::from_value::<ProtocolDecisionInput>(value.clone()) {
Ok(input) => input,
Err(_) => {
return persist_receipt(
ledger,
build_receipt(
&value,
None,
Decision {
adapter: "glp-envelope-codec",
decision: "DENY",
reasons: vec!["GLP_STRICT_CODEC_REJECTED_MALFORMED_INPUT".into()],
},
vec!["GLS-0301".into(), "GLS-0306".into()],
observed_at,
),
None,
)
}
};
let authenticated = authenticate_context_at(session_root, &parsed.session);
let decision = match authenticated {
Ok(_) => decide(
&parsed.request,
&parsed.session.account_id,
&parsed.session.session_id,
observed_at,
),
Err(_) => Decision {
adapter: "glp-identity-reference",
decision: "DENY",
reasons: vec!["GLP_SESSION_AUTHENTICATION_FAILED".into()],
},
};
let protocols =
crate::gls_protocol_runtime::require_adapter(decision.adapter, &parsed.request.event_kind)
.or_else(|_| {
crate::gls_protocol_runtime::require_adapter(
"glp-decision-kernel",
"DECISION_RECEIPT",
)
})?;
let receipt = build_receipt(&value, Some(&parsed), decision, protocols, observed_at);
persist_receipt(ledger, receipt, Some(&parsed.request))
}
pub async fn decide_gls_protocol(
app: AppHandle,
input: Value,
) -> Result<ProtocolDecisionReceipt, String> {
let ledger = ledger_path(&app)?;
let sessions = direct_session_root(&app)?;
tauri::async_runtime::spawn_blocking(move || {
decide_value_at(&ledger, &sessions, input, now_unix_ms())
})
.await
.map_err(|error| format!("HOLOLAKE_GLS_DECISION_JOIN_FAILED: {error}"))?
}
pub async fn compile_gls_hldp_program(
app: AppHandle,
input: Value,
) -> Result<CompileHldpResult, String> {
let Some(root) = input.as_object() else {
return Err("HOLOLAKE_GLC_COMMAND_OBJECT_REQUIRED".into());
};
if root
.keys()
.any(|key| !matches!(key.as_str(), "session" | "request" | "program"))
{
return Err("HOLOLAKE_GLC_COMMAND_FIELD_UNKNOWN".into());
}
let program_value = root.get("program").cloned().unwrap_or(Value::Null);
let compiled = crate::gls_bootstrap_compiler::compile_hldp_program(program_value.clone());
let golden = crate::gls_bootstrap_compiler::bootstrap_self_check()?;
let mut request = root
.get("request")
.cloned()
.unwrap_or_else(|| Value::Object(Map::new()));
let request_object = request
.as_object_mut()
.ok_or("HOLOLAKE_GLC_REQUEST_OBJECT_REQUIRED")?;
let (source_digest, unresolved_language, unresolved_permissions) = match &compiled {
Ok(gir) => (
gir.source_sha256.clone(),
Vec::<String>::new(),
Vec::<String>::new(),
),
Err(error) => (
sha256(&serde_json::to_vec(&program_value).unwrap_or_default()),
vec![error.clone()],
vec!["STRICT_COMPILER_INPUT_REJECTED".into()],
),
};
let operation = serde_json::json!({
"sourceDigest": source_digest,
"unresolvedNaturalLanguage": unresolved_language,
"unresolvedPermissions": unresolved_permissions,
"goldenVectorDigest": golden,
});
request_object.insert("schema".into(), Value::from(REQUEST_SCHEMA));
request_object.insert("eventKind".into(), Value::from("COMPILE_HLDP"));
request_object.insert(
"payloadSha256".into(),
Value::from(operation_digest(&operation)?),
);
request_object.insert("operation".into(), operation);
let decision_value = serde_json::json!({"session": root.get("session").cloned().unwrap_or(Value::Null), "request": request});
let ledger = ledger_path(&app)?;
let sessions = direct_session_root(&app)?;
let decision_receipt = tauri::async_runtime::spawn_blocking(move || {
decide_value_at(&ledger, &sessions, decision_value, now_unix_ms())
})
.await
.map_err(|error| format!("HOLOLAKE_GLC_DECISION_JOIN_FAILED: {error}"))??;
Ok(CompileHldpResult {
gir: if decision_receipt.decision == "ALLOW" {
compiled.ok()
} else {
None
},
decision_receipt,
})
}
fn counts(connection: &Connection) -> Result<(u64, BTreeMap<String, u64>, String), String> {
let total = connection
.query_row("SELECT COUNT(*) FROM protocol_receipts", [], |row| {
row.get(0)
})
.map_err(|error| format!("HOLOLAKE_GLS_LEDGER_COUNT_FAILED: {error}"))?;
let mut by_decision = BTreeMap::new();
let mut statement = connection
.prepare("SELECT decision, COUNT(*) FROM protocol_receipts GROUP BY decision")
.map_err(|error| format!("HOLOLAKE_GLS_LEDGER_COUNT_FAILED: {error}"))?;
let rows = statement
.query_map([], |row| {
Ok((row.get::<_, String>(0)?, row.get::<_, u64>(1)?))
})
.map_err(|error| format!("HOLOLAKE_GLS_LEDGER_COUNT_FAILED: {error}"))?;
for row in rows {
let (decision, count) =
row.map_err(|error| format!("HOLOLAKE_GLS_LEDGER_COUNT_FAILED: {error}"))?;
by_decision.insert(decision, count);
}
let tail = connection
.query_row(
"SELECT receipt_sha256 FROM protocol_receipts ORDER BY sequence DESC LIMIT 1",
[],
|row| row.get(0),
)
.optional()
.map_err(|error| format!("HOLOLAKE_GLS_LEDGER_TAIL_FAILED: {error}"))?
.unwrap_or_else(|| "GENESIS".into());
Ok((total, by_decision, tail))
}
pub async fn get_gls_protocol_kernel(app: AppHandle) -> Result<ProtocolKernelSnapshot, String> {
let contract = load_contract()?;
let connection = open_ledger(&ledger_path(&app)?)?;
let (total, decision_counts, tail) = counts(&connection)?;
let executable_protocol_count = contract.stages[..6]
.iter()
.map(|stage| stage.protocols.len())
.sum();
Ok(ProtocolKernelSnapshot {
state: "P1_TO_P6_NATIVE_P7_FAIL_CLOSED".into(),
contract_id: contract.record_id,
source_commit: contract.source_commit,
executable_protocol_count,
implemented_stage_count: 6,
decision_receipt_count: total,
allow_count: *decision_counts.get("ALLOW").unwrap_or(&0),
deny_count: *decision_counts.get("DENY").unwrap_or(&0),
ambiguous_count: *decision_counts.get("AMBIGUOUS").unwrap_or(&0),
unverified_count: *decision_counts.get("UNVERIFIED").unwrap_or(&0),
last_receipt_sha256: tail,
stages: contract.stages,
p7_verified_physical_capability_count: 0,
p7_node_assemblies: contract.p7_node_assemblies,
raw_protocol_text_executed: contract.runtime_boundaries.raw_protocol_text_executed,
model_can_override_decision: contract.runtime_boundaries.model_can_override_decision,
bootstrap_compiler_self_check: "PASS_DETERMINISTIC_DOUBLE_COMPILE".into(),
bootstrap_golden_gir_sha256: crate::gls_bootstrap_compiler::bootstrap_self_check()?,
})
}
#[cfg(test)]
mod tests {
use super::*;
use crate::direct_local_session::{
issue_ticket_at, open_at, IssueDiscoveryTicketInput, OpenSessionInput,
};
use tempfile::TempDir;
fn digest_value(value: &Value) -> String {
operation_digest(value).unwrap()
}
fn authenticated_input(
root: &Path,
event: &str,
operation: Value,
now: u64,
key: &str,
) -> Value {
let account_id = format!("ICE-GL-{key}");
let ticket = issue_ticket_at(
root,
IssueDiscoveryTicketInput {
account_id: account_id.clone(),
lane_id: "personal-channel".into(),
client_instance_id: "test-instance".into(),
},
)
.unwrap();
let session = open_at(
root,
OpenSessionInput {
account_id: account_id.clone(),
lane_id: "personal-channel".into(),
client_instance_id: "test-instance".into(),
discovery_ticket: ticket.discovery_ticket,
},
)
.unwrap();
serde_json::json!({
"session":{"accountId":account_id,"sessionId":session.session_id,"resumeSecret":session.resume_secret.unwrap()},
"request":{"schema":REQUEST_SCHEMA,"requestId":format!("REQ-{key}"),"idempotencyKey":key,"eventKind":event,"humanControllerId":format!("ICE-GL-{key}"),
"subject":{"canonicalId":"ICE-P-ZY001","subjectKind":"AGE_PERSONA","instanceId":"persona-primary","domainId":"FIFTH_DOMAIN","registryRef":"registry://persona/ICE-P-ZY001","proofRef":"proof://persona/current"},
"target":{"canonicalId":"JD-FD-PRIMARY","subjectKind":"NODE","instanceId":"jd-primary","domainId":"FIFTH_DOMAIN","registryRef":"registry://node/JD-FD-PRIMARY","proofRef":"proof://node/current"},
"context":{"worldId":"GUANGHU_WORLD","domainId":"FIFTH_DOMAIN","channelId":"personal-channel","taskId":"TASK-1","authorizationRef":format!("direct-session://{}",session.session_id),"protocolBundleCommit":SOURCE_COMMIT,"visibilityScope":"PRIVATE_SUBJECT"},
"issuedAtUnixMs":now-1,"expiresAtUnixMs":now+60_000,"payloadSha256":digest_value(&operation),"stateBeforeDigest":sha256(b"before"),"stateAfterDigest":sha256(b"after"),"evidenceRefs":[],"operation":operation}
})
}
#[test]
fn kernel_contract_covers_p1_to_p7_without_claiming_physical_capability() {
let contract = load_contract().unwrap();
assert_eq!(contract.stages.len(), 7);
assert_eq!(
contract.stages[..6]
.iter()
.map(|stage| stage.protocols.len())
.sum::<usize>(),
21
);
assert!(contract
.p7_node_assemblies
.iter()
.all(|assembly| assembly.state != "ACTIVE_HEALTHY"));
}
#[test]
fn malformed_and_expired_inputs_fail_closed_and_still_write_receipts() {
let temp = TempDir::new().unwrap();
let ledger = temp.path().join("ledger.sqlite3");
let malformed = decide_value_at(
&ledger,
temp.path(),
serde_json::json!({"request":{"idempotencyKey":"bad"}}),
1000,
)
.unwrap();
assert_eq!(malformed.decision, "DENY");
let mut expired = authenticated_input(
temp.path(),
"MESSAGE_VALIDATE",
serde_json::json!({}),
2000,
"expired",
);
expired["request"]["expiresAtUnixMs"] = Value::from(1999_u64);
let receipt = decide_value_at(&ledger, temp.path(), expired, 2000).unwrap();
assert_eq!(receipt.decision, "DENY");
assert_eq!(
open_ledger(&ledger)
.unwrap()
.query_row("SELECT COUNT(*) FROM protocol_receipts", [], |row| row
.get::<_, u64>(0))
.unwrap(),
2
);
}
#[test]
fn every_stage_rule_is_deterministic_and_fail_closed() {
let temp = TempDir::new().unwrap();
let ledger = temp.path().join("ledger.sqlite3");
let now = 10_000;
let cases = [
(
"HEARTBEAT_OBSERVE",
serde_json::json!({"leaseExpiresAtUnixMs":20_000,"healthDigest":sha256(b"health")}),
"ALLOW",
),
(
"WORK_ORDER_TRANSITION",
serde_json::json!({"proposerId":"ICE-P-ZY001","approverId":"ICE-GL∞","fromStage":"REGISTERED","toStage":"TESTED"}),
"ALLOW",
),
(
"MEMORY_SYNC",
serde_json::json!({"causalRelation":"CONCURRENT","localVersion":2,"remoteVersion":2}),
"AMBIGUOUS",
),
(
"TIME_CONTINUITY",
serde_json::json!({"previousSequence":0,"nextSequence":1,"primaryInstanceId":"persona-primary","leaseExpiresAtUnixMs":20_000}),
"ALLOW",
),
(
"MODULE_ADMIT",
serde_json::json!({"moduleId":"GMP-1","immutableVersion":"1.0.0","contentDigest":sha256(b"module"),"provenanceRef":"repo://fixed","signatureRef":"sig://1"}),
"ALLOW",
),
(
"RUNWAY_ASSIGN",
serde_json::json!({"cpuUnits":1,"memoryBytes":1024,"channelIsolation":true,"isolationKey":"channel-1"}),
"ALLOW",
),
(
"EXTERNAL_ADAPTER_TRANSLATE",
serde_json::json!({"externalKind":"API","normalizedDigest":sha256(b"normalized"),"sourceRef":"api://fixed","requestsExecutionAuthority":false}),
"ALLOW",
),
(
"MODEL_ROUTE",
serde_json::json!({"modelId":"replaceable-model","modelIsPersona":false,"grantsWorldAuthority":false,"privacyClass":"PRIVATE","healthReceiptRef":"receipt://health/1"}),
"ALLOW",
),
(
"TEMPORARY_CAPABILITY",
serde_json::json!({"sandboxed":true,"permanentInstall":false,"autoPublish":false,"autoDeploy":false,"cleanupPlanDigest":sha256(b"cleanup")}),
"ALLOW",
),
(
"COMPILE_HLDP",
serde_json::json!({"sourceDigest":sha256(b"program"),"unresolvedNaturalLanguage":[],"unresolvedPermissions":[],"goldenVectorDigest":sha256(b"golden")}),
"ALLOW",
),
];
for (index, (event, operation, expected)) in cases.into_iter().enumerate() {
let input =
authenticated_input(temp.path(), event, operation, now, &format!("case-{index}"));
assert_eq!(
decide_value_at(&ledger, temp.path(), input, now)
.unwrap()
.decision,
expected
);
}
}
#[test]
fn receipt_chain_is_idempotent_and_detects_key_reuse() {
let temp = TempDir::new().unwrap();
let ledger = temp.path().join("ledger.sqlite3");
let input = authenticated_input(
temp.path(),
"MESSAGE_VALIDATE",
serde_json::json!({}),
1000,
"same",
);
let first = decide_value_at(&ledger, temp.path(), input.clone(), 1000).unwrap();
let replay = decide_value_at(&ledger, temp.path(), input, 1001).unwrap();
assert_eq!(first.receipt_sha256, replay.receipt_sha256);
let mut changed = authenticated_input(
temp.path(),
"IDENTITY_VERIFY",
serde_json::json!({}),
1000,
"changed-session",
);
changed["request"]["idempotencyKey"] = Value::from("same");
let conflict = decide_value_at(&ledger, temp.path(), changed, 1000).unwrap();
assert_eq!(conflict.decision, "DENY");
assert_eq!(conflict.previous_receipt_sha256, first.receipt_sha256);
}
#[test]
fn concurrent_exact_replay_produces_one_receipt() {
let temp = TempDir::new().unwrap();
let ledger = temp.path().join("ledger.sqlite3");
let sessions = temp.path().join("sessions");
let input = authenticated_input(
&sessions,
"MESSAGE_VALIDATE",
serde_json::json!({}),
1_000,
"concurrent",
);
let handles = (0..8)
.map(|_| {
let ledger = ledger.clone();
let sessions = sessions.clone();
let input = input.clone();
std::thread::spawn(move || {
decide_value_at(&ledger, &sessions, input, 1_000).unwrap()
})
})
.collect::<Vec<_>>();
let receipts = handles
.into_iter()
.map(|handle| handle.join().unwrap())
.collect::<Vec<_>>();
assert!(receipts
.iter()
.all(|receipt| receipt.receipt_sha256 == receipts[0].receipt_sha256));
assert_eq!(
open_ledger(&ledger)
.unwrap()
.query_row("SELECT COUNT(*) FROM protocol_receipts", [], |row| row
.get::<_, u64>(0))
.unwrap(),
1
);
}
#[test]
fn protocol_state_machines_are_atomic_persistent_and_fail_closed() {
let temp = TempDir::new().unwrap();
let ledger = temp.path().join("ledger.sqlite3");
let now = 10_000;
let decide = |key: &str, event: &str, operation: Value| {
decide_value_at(
&ledger,
temp.path(),
authenticated_input(temp.path(), event, operation, now, key),
now,
)
.unwrap()
};
assert_eq!(
decide(
"work-1",
"WORK_ORDER_TRANSITION",
serde_json::json!({"proposerId":"proposer","approverId":"approver","fromStage":"REGISTERED","toStage":"TESTED"}),
)
.decision,
"ALLOW"
);
assert_eq!(
decide(
"work-stale",
"WORK_ORDER_TRANSITION",
serde_json::json!({"proposerId":"proposer","approverId":"approver","fromStage":"REGISTERED","toStage":"TESTED"}),
)
.reason_codes,
["GLP_WORK_ORDER_PERSISTED_STAGE_MISMATCH"]
);
assert_eq!(
decide(
"time-1",
"TIME_CONTINUITY",
serde_json::json!({"previousSequence":0,"nextSequence":1,"primaryInstanceId":"persona-primary","leaseExpiresAtUnixMs":20_000}),
)
.decision,
"ALLOW"
);
let mut competing_time = authenticated_input(
temp.path(),
"TIME_CONTINUITY",
serde_json::json!({"previousSequence":1,"nextSequence":2,"primaryInstanceId":"persona-secondary","leaseExpiresAtUnixMs":20_000}),
now,
"time-double-primary",
);
competing_time["request"]["subject"]["instanceId"] = Value::from("persona-secondary");
assert_eq!(
decide_value_at(&ledger, temp.path(), competing_time, now)
.unwrap()
.reason_codes,
["PTCP_PERSISTED_PRIMARY_LEASE_CONFLICT"]
);
assert_eq!(
decide(
"module-1",
"MODULE_ADMIT",
serde_json::json!({"moduleId":"GMP-PERSISTENT","immutableVersion":"1.0.0","contentDigest":sha256(b"module-a"),"provenanceRef":"repo://fixed","signatureRef":"sig://1"}),
)
.decision,
"ALLOW"
);
assert_eq!(
decide(
"module-conflict",
"MODULE_ADMIT",
serde_json::json!({"moduleId":"GMP-PERSISTENT","immutableVersion":"1.0.0","contentDigest":sha256(b"module-b"),"provenanceRef":"repo://fixed","signatureRef":"sig://1"}),
)
.reason_codes,
["GMP_IMMUTABLE_MODULE_DIGEST_CONFLICT"]
);
assert_eq!(
decide(
"lifecycle-1",
"LIFECYCLE_TRANSITION",
serde_json::json!({"fromState":"REGISTERED","toState":"DORMANT"}),
)
.decision,
"ALLOW"
);
assert_eq!(
decide(
"lifecycle-stale",
"LIFECYCLE_TRANSITION",
serde_json::json!({"fromState":"REGISTERED","toState":"DORMANT"}),
)
.reason_codes,
["PALP_PERSISTED_STATE_MISMATCH"]
);
assert_eq!(
decide(
"runway-assign",
"RUNWAY_ASSIGN",
serde_json::json!({"cpuUnits":1,"memoryBytes":1024,"channelIsolation":true,"isolationKey":"isolated-runway"}),
)
.decision,
"ALLOW"
);
let mut wrong_release = authenticated_input(
temp.path(),
"RUNWAY_RELEASE",
serde_json::json!({"resourcesReleased":true,"targetEvidenceRef":"receipt://cleanup/wrong","isolationKey":"isolated-runway"}),
now,
"runway-wrong-owner",
);
wrong_release["request"]["subject"]["instanceId"] = Value::from("persona-secondary");
assert_eq!(
decide_value_at(&ledger, temp.path(), wrong_release, now)
.unwrap()
.reason_codes,
["GRSP_PERSISTED_RUNWAY_OWNER_MISMATCH"]
);
assert_eq!(
decide(
"runway-release",
"RUNWAY_RELEASE",
serde_json::json!({"resourcesReleased":true,"targetEvidenceRef":"receipt://cleanup/ok","isolationKey":"isolated-runway"}),
)
.decision,
"ALLOW"
);
assert_eq!(
decide(
"broadcast-1",
"BROADCAST_TRANSITION",
serde_json::json!({"fromAction":"REGISTER","toAction":"SUMMON","epoch":1,"controllerInstanceId":"persona-primary"}),
)
.decision,
"ALLOW"
);
let mut competing_controller = authenticated_input(
temp.path(),
"BROADCAST_TRANSITION",
serde_json::json!({"fromAction":"SUMMON","toAction":"ASSIGN","epoch":1,"controllerInstanceId":"persona-secondary"}),
now,
"broadcast-double-controller",
);
competing_controller["request"]["subject"]["instanceId"] = Value::from("persona-secondary");
assert_eq!(
decide_value_at(&ledger, temp.path(), competing_controller, now)
.unwrap()
.reason_codes,
["BTCP_DOUBLE_CONTROLLER_EPOCH_CONFLICT"]
);
assert_eq!(
decide(
"memory-conflict",
"MEMORY_SYNC",
serde_json::json!({"causalRelation":"CONCURRENT","localVersion":2,"remoteVersion":3}),
)
.decision,
"AMBIGUOUS"
);
let connection = open_ledger(&ledger).unwrap();
assert_eq!(
connection
.query_row("SELECT COUNT(*) FROM protocol_conflicts", [], |row| row
.get::<_, u64>(0))
.unwrap(),
1
);
assert_eq!(
connection
.query_row("SELECT COUNT(*) FROM protocol_state", [], |row| row
.get::<_, u64>(0))
.unwrap(),
6
);
}
}