fix: isolate private language artifacts
This commit is contained in:
parent
cf7633c94f
commit
40501233ef
5 changed files with 335 additions and 94 deletions
|
|
@ -4,6 +4,7 @@
|
|||
use ring::digest::{digest, SHA256};
|
||||
use serde::Serialize;
|
||||
use std::fs;
|
||||
use std::io::ErrorKind;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use tauri::AppHandle;
|
||||
|
|
@ -16,39 +17,45 @@ struct BundledArtifact {
|
|||
path: &'static str,
|
||||
kind: &'static str,
|
||||
subject: &'static str,
|
||||
scope: &'static str,
|
||||
expected_sha256: &'static str,
|
||||
bytes: &'static [u8],
|
||||
}
|
||||
|
||||
struct PrivateArtifactDescriptor {
|
||||
path: &'static str,
|
||||
kind: &'static str,
|
||||
subject: &'static str,
|
||||
scope: &'static str,
|
||||
account: Option<&'static str>,
|
||||
expected_sha256: &'static str,
|
||||
}
|
||||
|
||||
macro_rules! artifact {
|
||||
($path:literal, $kind:literal, $subject:literal, $scope:literal, $sha:literal) => {
|
||||
BundledArtifact {
|
||||
path: $path,
|
||||
kind: $kind,
|
||||
subject: $subject,
|
||||
scope: $scope,
|
||||
expected_sha256: $sha,
|
||||
bytes: include_bytes!(concat!("../../runtime-kernels/", $path)),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static ARTIFACTS: &[BundledArtifact] = &[
|
||||
artifact!(
|
||||
"ZERO-CORE-LANGUAGE-BODIES-HANDOFF-20260820.json",
|
||||
"HANDOFF",
|
||||
"ZERO_CORE_LANGUAGE_BODIES",
|
||||
"COMMON",
|
||||
"c7462678a1fcfee8c13d6034a7effe8363ee1847c1d96673fdf4ef7856dbd964"
|
||||
),
|
||||
artifact!(
|
||||
"shared/kernel-registry.json",
|
||||
"REGISTRY",
|
||||
"BOUNDED_KERNEL_REGISTRY",
|
||||
"COMMON",
|
||||
"e71c33605ad40c374bd94659258bb8791b9a4859d0619bea86021a4ade8d87fa"
|
||||
),
|
||||
macro_rules! private_artifact {
|
||||
($path:literal, $kind:literal, $subject:literal, $scope:literal, $account:expr, $sha:literal) => {
|
||||
PrivateArtifactDescriptor {
|
||||
path: $path,
|
||||
kind: $kind,
|
||||
subject: $subject,
|
||||
scope: $scope,
|
||||
account: $account,
|
||||
expected_sha256: $sha,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static PUBLIC_ARTIFACTS: &[BundledArtifact] = &[
|
||||
artifact!(
|
||||
"channel-system/channel-receipt-contract.json",
|
||||
"CHANNEL_PROTOCOL",
|
||||
|
|
@ -77,32 +84,57 @@ static ARTIFACTS: &[BundledArtifact] = &[
|
|||
"COMMON",
|
||||
"17e14e6e964a0ac745b1378990edcbd2e8facf6ad0d72be52004ed2f42a365d5"
|
||||
),
|
||||
artifact!(
|
||||
];
|
||||
|
||||
// These descriptors deliberately carry no artifact bytes. The files may be
|
||||
// provisioned only into the authenticated account's private runtime source.
|
||||
static PRIVATE_ARTIFACTS: &[PrivateArtifactDescriptor] = &[
|
||||
private_artifact!(
|
||||
"ZERO-CORE-LANGUAGE-BODIES-HANDOFF-20260820.json",
|
||||
"HANDOFF",
|
||||
"ZERO_CORE_LANGUAGE_BODIES",
|
||||
"BINGSHUO_FIFTH_DOMAIN",
|
||||
Some("bingshuo"),
|
||||
"c7462678a1fcfee8c13d6034a7effe8363ee1847c1d96673fdf4ef7856dbd964"
|
||||
),
|
||||
private_artifact!(
|
||||
"shared/kernel-registry.json",
|
||||
"REGISTRY",
|
||||
"BOUNDED_KERNEL_REGISTRY",
|
||||
"BINGSHUO_FIFTH_DOMAIN",
|
||||
Some("bingshuo"),
|
||||
"e71c33605ad40c374bd94659258bb8791b9a4859d0619bea86021a4ade8d87fa"
|
||||
),
|
||||
private_artifact!(
|
||||
"channel-system/team-channel-cognition-core.json",
|
||||
"CHANNEL_SYSTEM",
|
||||
"GUANGHU_TEAM_CHANNELS",
|
||||
"TEAM",
|
||||
None,
|
||||
"aae5d5626719c79448ac543d59e764c41b541a5cdfc76dc91613afa86fe1367b"
|
||||
),
|
||||
artifact!(
|
||||
private_artifact!(
|
||||
"channel-system/team-channel-cognition-engine.mjs",
|
||||
"CHANNEL_ENGINE",
|
||||
"GUANGHU_TEAM_CHANNELS",
|
||||
"TEAM",
|
||||
None,
|
||||
"6f2c554c7a6cb0b6c1006d3bfdbf39ea5706b238ebcf7693d1fdaa4a38709c9b"
|
||||
),
|
||||
artifact!(
|
||||
private_artifact!(
|
||||
"channel-system/GH-TEAM-CHANNEL-HLDP-v1.json",
|
||||
"CHANNEL_MEMORY",
|
||||
"GUANGHU_TEAM_CHANNELS",
|
||||
"TEAM",
|
||||
None,
|
||||
"fc5799e05ee43c506b897dd507c8fdbbff398e3ebcf32c16afd1e924c819dcc0"
|
||||
),
|
||||
artifact!(
|
||||
private_artifact!(
|
||||
"channel-system/team-persona-kernel-readiness-matrix.json",
|
||||
"EVIDENCE_MATRIX",
|
||||
"GUANGHU_TEAM_CHANNELS",
|
||||
"TEAM",
|
||||
None,
|
||||
"0469398ba14f10629cd03b51725cddaf1b6b0944281298ec06d4865b4640486f"
|
||||
),
|
||||
];
|
||||
|
|
@ -129,6 +161,10 @@ pub struct LanguageKernelInstallationSnapshot {
|
|||
pub installed_at_unix_ms: u64,
|
||||
pub artifacts: Vec<InstalledKernelArtifact>,
|
||||
pub artifact_count: usize,
|
||||
pub public_artifact_count: usize,
|
||||
pub private_artifact_count: usize,
|
||||
pub expected_private_artifact_count: usize,
|
||||
pub private_provisioning_state: &'static str,
|
||||
pub persona_binding_state: &'static str,
|
||||
pub channel_receipt_runtime_state: &'static str,
|
||||
}
|
||||
|
|
@ -166,14 +202,24 @@ pub fn ensure_for_audience(
|
|||
) {
|
||||
return Err("HOLOLAKE_LANGUAGE_KERNEL_AUDIENCE_INVALID".into());
|
||||
}
|
||||
let session = crate::code_repo_login::current_login_session(app)?
|
||||
.ok_or_else(|| "HOLOLAKE_AUTHENTICATED_ACCOUNT_REQUIRED".to_string())?;
|
||||
let expected_audience = match session.domain.as_str() {
|
||||
"FIFTH_DOMAIN" => "FIFTH_DOMAIN_PRIVATE_INSTANCE",
|
||||
"MAIN_DOMAIN" | "BRANCH_DOMAIN" | "ZERO_DOMAIN" | "ZERO_SENSE_DOMAIN" => {
|
||||
"GUANGHU_TEAM_INITIAL_CHANNEL"
|
||||
}
|
||||
"PERSONAL_CHANNEL" => "ORDINARY_USER_INITIAL_CHANNEL",
|
||||
_ => return Err("HOLOLAKE_CHANNEL_INITIALIZATION_AUDIENCE_INVALID".into()),
|
||||
};
|
||||
if audience != expected_audience {
|
||||
return Err("HOLOLAKE_LANGUAGE_KERNEL_AUDIENCE_ACCOUNT_MISMATCH".into());
|
||||
}
|
||||
let root = installation_root(app, channel_number)?;
|
||||
fs::create_dir_all(&root)
|
||||
.map_err(|error| format!("HOLOLAKE_LANGUAGE_KERNEL_STORAGE_FAILED: {error}"))?;
|
||||
let mut installed = Vec::new();
|
||||
for artifact in ARTIFACTS
|
||||
.iter()
|
||||
.filter(|artifact| artifact_applies(artifact, audience, channel_number))
|
||||
{
|
||||
for artifact in PUBLIC_ARTIFACTS {
|
||||
let bundled_hash = sha256(artifact.bytes);
|
||||
if bundled_hash != artifact.expected_sha256 {
|
||||
return Err(format!(
|
||||
|
|
@ -181,49 +227,99 @@ pub fn ensure_for_audience(
|
|||
artifact.path
|
||||
));
|
||||
}
|
||||
if artifact.path.ends_with(".json") {
|
||||
serde_json::from_slice::<serde_json::Value>(artifact.bytes).map_err(|error| {
|
||||
format!(
|
||||
"HOLOLAKE_LANGUAGE_KERNEL_JSON_INVALID:{}:{error}",
|
||||
installed.push(install_artifact(
|
||||
&root,
|
||||
artifact.path,
|
||||
artifact.kind,
|
||||
artifact.subject,
|
||||
artifact.expected_sha256,
|
||||
artifact.bytes,
|
||||
"BUNDLED_PUBLIC_SOURCE_SHA256_VERIFIED",
|
||||
)?);
|
||||
}
|
||||
let public_artifact_count = installed.len();
|
||||
let account = session.username.to_ascii_lowercase();
|
||||
let selected_private = PRIVATE_ARTIFACTS
|
||||
.iter()
|
||||
.filter(|artifact| private_artifact_applies(artifact, audience, &account))
|
||||
.collect::<Vec<_>>();
|
||||
let expected_private_artifact_count = selected_private.len();
|
||||
let private_source_root =
|
||||
crate::authenticated_storage::account_storage_root(app, "language-kernel-sources-v1")?
|
||||
.join(audience);
|
||||
let mut private_artifact_count = 0;
|
||||
for artifact in selected_private {
|
||||
let source = safe_target(&private_source_root, artifact.path)?;
|
||||
let metadata = match fs::symlink_metadata(&source) {
|
||||
Ok(metadata) => metadata,
|
||||
Err(error) if error.kind() == ErrorKind::NotFound => continue,
|
||||
Err(error) => {
|
||||
return Err(format!(
|
||||
"HOLOLAKE_LANGUAGE_KERNEL_PRIVATE_READ_FAILED:{}:{error}",
|
||||
artifact.path
|
||||
)
|
||||
})?;
|
||||
}
|
||||
let target = safe_target(&root, artifact.path)?;
|
||||
write_atomic(&target, artifact.bytes)?;
|
||||
let readback = fs::read(&target).map_err(|error| {
|
||||
format!(
|
||||
"HOLOLAKE_LANGUAGE_KERNEL_READBACK_FAILED:{}:{error}",
|
||||
artifact.path
|
||||
)
|
||||
})?;
|
||||
if sha256(&readback) != artifact.expected_sha256 {
|
||||
))
|
||||
}
|
||||
};
|
||||
if !metadata.is_file() || metadata.file_type().is_symlink() {
|
||||
return Err(format!(
|
||||
"HOLOLAKE_LANGUAGE_KERNEL_READBACK_HASH_MISMATCH:{}",
|
||||
"HOLOLAKE_LANGUAGE_KERNEL_PRIVATE_SOURCE_INVALID:{}",
|
||||
artifact.path
|
||||
));
|
||||
}
|
||||
installed.push(InstalledKernelArtifact {
|
||||
path: artifact.path.into(),
|
||||
kind: artifact.kind.into(),
|
||||
subject: artifact.subject.into(),
|
||||
sha256: bundled_hash,
|
||||
readback_state: "INSTALLED_HASH_VERIFIED",
|
||||
persona_binding_state: if artifact.kind.starts_with("PERSONA_") {
|
||||
"AVAILABLE_NOT_BOUND"
|
||||
} else {
|
||||
"NOT_APPLICABLE"
|
||||
},
|
||||
});
|
||||
let bytes = fs::read(&source).map_err(|error| {
|
||||
format!(
|
||||
"HOLOLAKE_LANGUAGE_KERNEL_PRIVATE_READ_FAILED:{}:{error}",
|
||||
artifact.path
|
||||
)
|
||||
})?;
|
||||
if sha256(&bytes) != artifact.expected_sha256 {
|
||||
return Err(format!(
|
||||
"HOLOLAKE_LANGUAGE_KERNEL_PRIVATE_SHA256_MISMATCH:{}",
|
||||
artifact.path
|
||||
));
|
||||
}
|
||||
installed.push(install_artifact(
|
||||
&root,
|
||||
artifact.path,
|
||||
artifact.kind,
|
||||
artifact.subject,
|
||||
artifact.expected_sha256,
|
||||
&bytes,
|
||||
"ACCOUNT_PRIVATE_SOURCE_SHA256_VERIFIED",
|
||||
)?);
|
||||
private_artifact_count += 1;
|
||||
}
|
||||
let (state, private_provisioning_state) =
|
||||
match (expected_private_artifact_count, private_artifact_count) {
|
||||
(0, _) => (
|
||||
"INSTALLED_AND_EACH_ARTIFACT_READBACK_VERIFIED",
|
||||
"NOT_APPLICABLE",
|
||||
),
|
||||
(_, 0) => (
|
||||
"PUBLIC_KERNELS_INSTALLED_PRIVATE_KERNELS_NOT_PROVISIONED",
|
||||
"PRIVATE_KERNELS_NOT_PROVISIONED",
|
||||
),
|
||||
(expected, actual) if actual < expected => (
|
||||
"PUBLIC_KERNELS_INSTALLED_PRIVATE_KERNELS_PARTIALLY_PROVISIONED",
|
||||
"PRIVATE_KERNELS_PARTIALLY_PROVISIONED_SHA256_VERIFIED",
|
||||
),
|
||||
_ => (
|
||||
"INSTALLED_AND_EACH_ARTIFACT_READBACK_VERIFIED",
|
||||
"PRIVATE_KERNELS_PROVISIONED_SHA256_VERIFIED",
|
||||
),
|
||||
};
|
||||
let installed_at = now_ms();
|
||||
let snapshot = LanguageKernelInstallationSnapshot {
|
||||
schema: SCHEMA,
|
||||
state: "INSTALLED_AND_EACH_ARTIFACT_READBACK_VERIFIED",
|
||||
state,
|
||||
source_remote_sha: SOURCE_REMOTE_SHA,
|
||||
channel_number: channel_number.into(),
|
||||
audience: audience.into(),
|
||||
artifact_count: installed.len(),
|
||||
public_artifact_count,
|
||||
private_artifact_count,
|
||||
expected_private_artifact_count,
|
||||
private_provisioning_state,
|
||||
artifacts: installed,
|
||||
installed_at_unix_ms: installed_at,
|
||||
persona_binding_state: "UNBOUND_REQUIRES_ORIENT_COMMIT_WITNESS_VERIFY_PASS",
|
||||
|
|
@ -235,19 +331,53 @@ pub fn ensure_for_audience(
|
|||
Ok(snapshot)
|
||||
}
|
||||
|
||||
fn applies(scope: &str, audience: &str) -> bool {
|
||||
scope == "COMMON"
|
||||
|| (scope == "TEAM" && audience == "GUANGHU_TEAM_INITIAL_CHANNEL")
|
||||
|| (scope == "FIFTH_DOMAIN" && audience == "FIFTH_DOMAIN_PRIVATE_INSTANCE")
|
||||
fn private_artifact_applies(
|
||||
artifact: &PrivateArtifactDescriptor,
|
||||
audience: &str,
|
||||
account: &str,
|
||||
) -> bool {
|
||||
let account_matches = artifact.account.is_none_or(|expected| expected == account);
|
||||
account_matches
|
||||
&& ((artifact.scope == "TEAM" && audience == "GUANGHU_TEAM_INITIAL_CHANNEL")
|
||||
|| (artifact.scope == "BINGSHUO_FIFTH_DOMAIN"
|
||||
&& audience == "FIFTH_DOMAIN_PRIVATE_INSTANCE"))
|
||||
}
|
||||
|
||||
fn artifact_applies(artifact: &BundledArtifact, audience: &str, channel_number: &str) -> bool {
|
||||
if channel_number == "SYS-GLW-PTS-0001" {
|
||||
return artifact.scope == "COMMON"
|
||||
|| artifact.scope == "CANGER_BOTTLE_CHANNEL"
|
||||
|| (artifact.kind == "PERSONA_ENVIRONMENT" && artifact.subject == "BOTTLE_CENTRAL");
|
||||
fn install_artifact(
|
||||
root: &Path,
|
||||
path: &str,
|
||||
kind: &str,
|
||||
subject: &str,
|
||||
expected_sha256: &str,
|
||||
bytes: &[u8],
|
||||
readback_state: &'static str,
|
||||
) -> Result<InstalledKernelArtifact, String> {
|
||||
if path.ends_with(".json") {
|
||||
serde_json::from_slice::<serde_json::Value>(bytes)
|
||||
.map_err(|error| format!("HOLOLAKE_LANGUAGE_KERNEL_JSON_INVALID:{path}:{error}"))?;
|
||||
}
|
||||
applies(artifact.scope, audience)
|
||||
let target = safe_target(root, path)?;
|
||||
write_atomic(&target, bytes)?;
|
||||
let readback = fs::read(&target)
|
||||
.map_err(|error| format!("HOLOLAKE_LANGUAGE_KERNEL_READBACK_FAILED:{path}:{error}"))?;
|
||||
let readback_sha256 = sha256(&readback);
|
||||
if readback_sha256 != expected_sha256 {
|
||||
return Err(format!(
|
||||
"HOLOLAKE_LANGUAGE_KERNEL_READBACK_HASH_MISMATCH:{path}"
|
||||
));
|
||||
}
|
||||
Ok(InstalledKernelArtifact {
|
||||
path: path.into(),
|
||||
kind: kind.into(),
|
||||
subject: subject.into(),
|
||||
sha256: readback_sha256,
|
||||
readback_state,
|
||||
persona_binding_state: if kind.starts_with("PERSONA_") {
|
||||
"AVAILABLE_NOT_BOUND"
|
||||
} else {
|
||||
"NOT_APPLICABLE"
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
fn installation_root(app: &AppHandle, channel_number: &str) -> Result<PathBuf, String> {
|
||||
|
|
@ -305,41 +435,51 @@ mod tests {
|
|||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn bundled_artifacts_are_pinned_and_each_audience_is_separate() {
|
||||
for artifact in ARTIFACTS {
|
||||
fn only_safe_common_artifacts_are_bundled() {
|
||||
assert_eq!(PUBLIC_ARTIFACTS.len(), 4);
|
||||
for artifact in PUBLIC_ARTIFACTS {
|
||||
assert_eq!(sha256(artifact.bytes), artifact.expected_sha256);
|
||||
}
|
||||
let ordinary = ARTIFACTS
|
||||
.iter()
|
||||
.filter(|artifact| applies(artifact.scope, "ORDINARY_USER_INITIAL_CHANNEL"))
|
||||
.count();
|
||||
let team = ARTIFACTS
|
||||
.iter()
|
||||
.filter(|artifact| applies(artifact.scope, "GUANGHU_TEAM_INITIAL_CHANNEL"))
|
||||
.count();
|
||||
let fifth = ARTIFACTS
|
||||
.iter()
|
||||
.filter(|artifact| applies(artifact.scope, "FIFTH_DOMAIN_PRIVATE_INSTANCE"))
|
||||
.count();
|
||||
assert_eq!(ordinary, 6);
|
||||
assert_eq!(team, 10);
|
||||
assert_eq!(fifth, 6);
|
||||
let canger = ARTIFACTS
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn every_non_public_descriptor_matches_a_source_without_embedding_it() {
|
||||
assert_eq!(PRIVATE_ARTIFACTS.len(), 6);
|
||||
for artifact in PRIVATE_ARTIFACTS {
|
||||
let source = Path::new(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("../runtime-kernels")
|
||||
.join(artifact.path);
|
||||
let bytes = fs::read(source).unwrap();
|
||||
assert_eq!(sha256(&bytes), artifact.expected_sha256);
|
||||
}
|
||||
let ordinary = PRIVATE_ARTIFACTS
|
||||
.iter()
|
||||
.filter(|artifact| {
|
||||
artifact_applies(
|
||||
artifact,
|
||||
"FIFTH_DOMAIN_PRIVATE_INSTANCE",
|
||||
"SYS-GLW-PTS-0001",
|
||||
)
|
||||
private_artifact_applies(artifact, "ORDINARY_USER_INITIAL_CHANNEL", "ordinary")
|
||||
})
|
||||
.count();
|
||||
assert_eq!(canger, 6);
|
||||
assert!(!ARTIFACTS.iter().any(|artifact| {
|
||||
artifact.scope == "FIFTH_DOMAIN" || artifact.scope == "CANGER_BOTTLE_CHANNEL"
|
||||
}));
|
||||
assert!(!applies("FIFTH_DOMAIN", "ORDINARY_USER_INITIAL_CHANNEL"));
|
||||
assert!(!applies("TEAM", "FIFTH_DOMAIN_PRIVATE_INSTANCE"));
|
||||
let team = PRIVATE_ARTIFACTS
|
||||
.iter()
|
||||
.filter(|artifact| {
|
||||
private_artifact_applies(artifact, "GUANGHU_TEAM_INITIAL_CHANNEL", "awen")
|
||||
})
|
||||
.count();
|
||||
let bingshuo = PRIVATE_ARTIFACTS
|
||||
.iter()
|
||||
.filter(|artifact| {
|
||||
private_artifact_applies(artifact, "FIFTH_DOMAIN_PRIVATE_INSTANCE", "bingshuo")
|
||||
})
|
||||
.count();
|
||||
let canger = PRIVATE_ARTIFACTS
|
||||
.iter()
|
||||
.filter(|artifact| {
|
||||
private_artifact_applies(artifact, "FIFTH_DOMAIN_PRIVATE_INSTANCE", "canger")
|
||||
})
|
||||
.count();
|
||||
assert_eq!(ordinary, 0);
|
||||
assert_eq!(team, 4);
|
||||
assert_eq!(bingshuo, 2);
|
||||
assert_eq!(canger, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
Loading…
Reference in a new issue