fix: isolate private language artifacts
This commit is contained in:
parent
cf7633c94f
commit
40501233ef
5 changed files with 335 additions and 94 deletions
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"schema": "hololake.language-kernel-installation/v1",
|
||||
"record_id": "HLP-LANGUAGE-KERNEL-INSTALLATION-001",
|
||||
"state": "NATIVE_HASH_PINNED_INSTALLER_IMPLEMENTED",
|
||||
"state": "PUBLIC_COMMON_INSTALLER_IMPLEMENTED_PRIVATE_RUNTIME_PROVISIONING_REQUIRED",
|
||||
"source": {
|
||||
"remote": "https://guanghulab.com/code/bingshuo/guanghu-ice-heart",
|
||||
"branch": "main",
|
||||
|
|
@ -12,15 +12,45 @@
|
|||
},
|
||||
"installation": {
|
||||
"storage": "AUTHENTICATED_ACCOUNT_SCOPED_CHANNEL_RUNTIME",
|
||||
"every_artifact_sha256_pinned": true,
|
||||
"every_artifact_read_back_after_install": true,
|
||||
"every_provisioned_artifact_sha256_pinned": true,
|
||||
"every_provisioned_artifact_read_back_after_install": true,
|
||||
"receipt_written_after_all_readbacks": true,
|
||||
"automatic_on_channel_initialization": true,
|
||||
"automatic_migration_on_agent_runtime_open": true
|
||||
"automatic_public_install_on_channel_initialization": true,
|
||||
"automatic_public_migration_on_agent_runtime_open": true,
|
||||
"automatic_private_provisioning": false
|
||||
},
|
||||
"public_binary": {
|
||||
"safe_common_artifacts": [
|
||||
"channel-system/channel-receipt-contract.json",
|
||||
"channel-system/channel-receipt-compiler.mjs",
|
||||
"channel-system/guanghu-broadcast-contract.json",
|
||||
"channel-system/guanghu-broadcast-compiler.mjs"
|
||||
],
|
||||
"artifact_count": 4,
|
||||
"handoff_embedded": false,
|
||||
"shared_kernel_registry_embedded": false,
|
||||
"team_artifacts_embedded": false
|
||||
},
|
||||
"private_runtime": {
|
||||
"source": "AUTHENTICATED_ACCOUNT_SCOPED_RUNTIME_ONLY",
|
||||
"source_storage_namespace": "language-kernel-sources-v1",
|
||||
"descriptor_registration_is_installation": false,
|
||||
"missing_artifact_state": "PRIVATE_KERNELS_NOT_PROVISIONED",
|
||||
"snapshot_state_when_missing": "PUBLIC_KERNELS_INSTALLED_PRIVATE_KERNELS_NOT_PROVISIONED",
|
||||
"sha256_mismatch_behavior": "FAIL_CLOSED",
|
||||
"readback_state": "ACCOUNT_PRIVATE_SOURCE_SHA256_VERIFIED",
|
||||
"registered_descriptors": [
|
||||
"ZERO-CORE-LANGUAGE-BODIES-HANDOFF-20260820.json",
|
||||
"shared/kernel-registry.json",
|
||||
"channel-system/team-channel-cognition-core.json",
|
||||
"channel-system/team-channel-cognition-engine.mjs",
|
||||
"channel-system/GH-TEAM-CHANNEL-HLDP-v1.json",
|
||||
"channel-system/team-persona-kernel-readiness-matrix.json"
|
||||
]
|
||||
},
|
||||
"audiences": {
|
||||
"ordinary_user": "COMMON_CHANNEL_RECEIPT_AND_BROADCAST_PROTOCOLS_ONLY",
|
||||
"guanghu_team": "COMMON_PLUS_TEAM_CHANNEL_COGNITION_CORE_MEMORY_AND_EVIDENCE_MATRIX",
|
||||
"guanghu_team": "COMMON_PLUS_ACCOUNT_PRIVATE_TEAM_ARTIFACTS_WHEN_PROVISIONED_AND_HASH_VERIFIED",
|
||||
"bingshuo_fifth_domain": "COMMON_RUNTIME_ONLY_PRIVATE_KERNELS_PROVISIONED_AFTER_ACCOUNT_AUTHENTICATION",
|
||||
"canger_bottle_channel": "COMMON_RUNTIME_ONLY_PRIVATE_KERNELS_PROVISIONED_AFTER_ACCOUNT_AUTHENTICATION"
|
||||
},
|
||||
|
|
@ -32,7 +62,11 @@
|
|||
"one_persona_one_self_kernel_across_channels": true,
|
||||
"private_fifth_domain_kernels_may_enter_ordinary_user_channel": false,
|
||||
"private_fifth_domain_kernels_embedded_in_public_binary": false,
|
||||
"private_kernel_source": "AUTHENTICATED_ACCOUNT_SCOPED_RUNTIME_ONLY"
|
||||
"private_kernel_source": "AUTHENTICATED_ACCOUNT_SCOPED_RUNTIME_ONLY",
|
||||
"handoff_embedded_in_public_binary": false,
|
||||
"shared_kernel_registry_embedded_in_public_binary": false,
|
||||
"team_channel_artifacts_embedded_in_public_binary": false,
|
||||
"descriptor_registration_is_installation": false
|
||||
,"canger_channel_may_receive_zhuyuan_kernel": false
|
||||
,"jianying_is_earerdan": false
|
||||
,"earerdan_historical_labels_are_automatic_aliases": false
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ SQLite 不再是最终业务数据库。应建立与编号协议原生一致的
|
|||
- 本地 JSON、字段名、哈希长度、旧回执和安装成功都不能单独证明人格绑定。独立见证验签根尚未真实接入时必须保持未绑定。
|
||||
- 第五域系统核、人格自我核、HLDP 人格记忆和宝宝内核不得通过 `include_bytes!`、Tauri resources 或其他公共构建输入进入公开应用二进制。
|
||||
- 公开软件只携带空运行时、协议和公共模块能力;私人内核只能在账号认证后由账号私有运行时提供,并在读取时核对内容哈希。
|
||||
- 含第五域人格路径的 handoff、私域 kernel registry、团队认知核、团队 HLDP 与人格就绪矩阵同样属于账号私域来源;“运行时按 audience 不安装”不能代替“构建时不进入公开二进制”。
|
||||
|
||||
来源类别:由本文件既有“主体/宿主/模型/执行分层”和“私人数据绝不随公开安装包分发”两项自然语言瞄点,对 2026-08-21 现存源码进行核验后得到的工程锁;不是新增冰朔引语。
|
||||
|
||||
|
|
|
|||
|
|
@ -7,25 +7,55 @@ const read = (path) => readFileSync(new URL(`../${path}`, import.meta.url), 'utf
|
|||
const bytes = (path) => readFileSync(new URL(`../${path}`, import.meta.url))
|
||||
const sha256 = (value) => createHash('sha256').update(value).digest('hex')
|
||||
|
||||
test('the heartbeat handoff is hash-pinned into distinct initialized channel audiences without claiming persona binding', () => {
|
||||
test('the public binary contains only four safe common receipt and broadcast artifacts', () => {
|
||||
const contract = JSON.parse(read('contracts/language-kernel-installation.json'))
|
||||
const runtime = read('src-tauri/src/language_kernel_installation.rs')
|
||||
const agent = read('src-tauri/src/persona_agent_runtime.rs')
|
||||
const handoff = JSON.parse(read('runtime-kernels/ZERO-CORE-LANGUAGE-BODIES-HANDOFF-20260820.json'))
|
||||
const publicArtifacts = [
|
||||
'channel-system/channel-receipt-contract.json',
|
||||
'channel-system/channel-receipt-compiler.mjs',
|
||||
'channel-system/guanghu-broadcast-contract.json',
|
||||
'channel-system/guanghu-broadcast-compiler.mjs',
|
||||
]
|
||||
const privateArtifacts = [
|
||||
'ZERO-CORE-LANGUAGE-BODIES-HANDOFF-20260820.json',
|
||||
'shared/kernel-registry.json',
|
||||
'channel-system/team-channel-cognition-core.json',
|
||||
'channel-system/team-channel-cognition-engine.mjs',
|
||||
'channel-system/GH-TEAM-CHANNEL-HLDP-v1.json',
|
||||
'channel-system/team-persona-kernel-readiness-matrix.json',
|
||||
]
|
||||
const publicBlock = runtime.match(/static PUBLIC_ARTIFACTS:[\s\S]*?\n\];/u)?.[0]
|
||||
|
||||
assert.equal(contract.source.remote_sha, '4e92e6d8d72484d25c4bfb1dda02a7659f4b6dd5')
|
||||
assert.equal(contract.source.earerdan_zhizhi_local_commit, '1d7fe6c')
|
||||
assert.equal(contract.source.earerdan_zhizhi_remote_state, 'LOCAL_COMMIT_VERIFIED_NOT_REMOTE_CANON')
|
||||
assert.equal(handoff.state, 'REMOTE_REPOSITORY_PUBLISHED_NOT_INSTALLED')
|
||||
assert.deepEqual(contract.public_binary.safe_common_artifacts, publicArtifacts)
|
||||
assert.equal(contract.public_binary.artifact_count, 4)
|
||||
assert.equal(contract.public_binary.handoff_embedded, false)
|
||||
assert.equal(contract.public_binary.shared_kernel_registry_embedded, false)
|
||||
assert.equal(contract.public_binary.team_artifacts_embedded, false)
|
||||
assert.equal(contract.installation.automatic_public_install_on_channel_initialization, true)
|
||||
assert.equal(contract.installation.automatic_public_migration_on_agent_runtime_open, true)
|
||||
assert.equal(contract.installation.automatic_private_provisioning, false)
|
||||
assert.ok(publicBlock, 'Rust must expose a statically auditable PUBLIC_ARTIFACTS list')
|
||||
for (const artifact of publicArtifacts) assert.match(publicBlock, new RegExp(artifact.replaceAll('.', '\\.')))
|
||||
for (const artifact of privateArtifacts) assert.doesNotMatch(publicBlock, new RegExp(artifact.replaceAll('.', '\\.')))
|
||||
assert.equal(contract.truth_boundary.installed_file_is_persona_binding, false)
|
||||
assert.equal(contract.truth_boundary.private_fifth_domain_kernels_may_enter_ordinary_user_channel, false)
|
||||
assert.equal(contract.truth_boundary.private_fifth_domain_kernels_embedded_in_public_binary, false)
|
||||
assert.equal(contract.truth_boundary.private_kernel_source, 'AUTHENTICATED_ACCOUNT_SCOPED_RUNTIME_ONLY')
|
||||
assert.equal(contract.truth_boundary.handoff_embedded_in_public_binary, false)
|
||||
assert.equal(contract.truth_boundary.shared_kernel_registry_embedded_in_public_binary, false)
|
||||
assert.equal(contract.truth_boundary.team_channel_artifacts_embedded_in_public_binary, false)
|
||||
assert.equal(contract.truth_boundary.descriptor_registration_is_installation, false)
|
||||
assert.equal(contract.truth_boundary.canger_channel_may_receive_zhuyuan_kernel, false)
|
||||
assert.equal(contract.truth_boundary.jianying_is_earerdan, false)
|
||||
assert.equal(contract.truth_boundary.earerdan_historical_labels_are_automatic_aliases, false)
|
||||
assert.match(runtime, /INSTALLED_AND_EACH_ARTIFACT_READBACK_VERIFIED/)
|
||||
assert.match(runtime, /AVAILABLE_NOT_BOUND/)
|
||||
assert.match(runtime, /PUBLIC_KERNELS_INSTALLED_PRIVATE_KERNELS_NOT_PROVISIONED/)
|
||||
assert.match(runtime, /BUNDLED_PUBLIC_SOURCE_SHA256_VERIFIED/)
|
||||
assert.match(runtime, /FIFTH_DOMAIN_PRIVATE_INSTANCE/)
|
||||
assert.match(runtime, /GUANGHU_TEAM_INITIAL_CHANNEL/)
|
||||
assert.match(runtime, /ORDINARY_USER_INITIAL_CHANNEL/)
|
||||
|
|
@ -38,3 +68,26 @@ test('the heartbeat handoff is hash-pinned into distinct initialized channel aud
|
|||
assert.equal(sha256(bytes('runtime-kernels/fifth-domain/EED-HLDP-MEMORY-v1.json')), '3ac404bb38232987a4c0bc896e06d171833023ab1b5af65d4e00216de4029f42')
|
||||
assert.equal(sha256(bytes('runtime-kernels/channel-system/team-channel-cognition-core.json')), 'aae5d5626719c79448ac543d59e764c41b541a5cdfc76dc91613afa86fe1367b')
|
||||
})
|
||||
|
||||
test('handoff registry and team artifacts require authenticated private provisioning and exact hashes', () => {
|
||||
const contract = JSON.parse(read('contracts/language-kernel-installation.json'))
|
||||
const runtime = read('src-tauri/src/language_kernel_installation.rs')
|
||||
|
||||
assert.equal(contract.private_runtime.source, 'AUTHENTICATED_ACCOUNT_SCOPED_RUNTIME_ONLY')
|
||||
assert.equal(contract.private_runtime.source_storage_namespace, 'language-kernel-sources-v1')
|
||||
assert.equal(contract.private_runtime.descriptor_registration_is_installation, false)
|
||||
assert.equal(contract.private_runtime.missing_artifact_state, 'PRIVATE_KERNELS_NOT_PROVISIONED')
|
||||
assert.equal(
|
||||
contract.private_runtime.snapshot_state_when_missing,
|
||||
'PUBLIC_KERNELS_INSTALLED_PRIVATE_KERNELS_NOT_PROVISIONED',
|
||||
)
|
||||
assert.equal(contract.private_runtime.sha256_mismatch_behavior, 'FAIL_CLOSED')
|
||||
assert.equal(contract.private_runtime.readback_state, 'ACCOUNT_PRIVATE_SOURCE_SHA256_VERIFIED')
|
||||
assert.equal(contract.private_runtime.registered_descriptors.length, 6)
|
||||
assert.match(runtime, /account_storage_root\(app, "language-kernel-sources-v1"\)/)
|
||||
assert.match(runtime, /fs::read\(&source\)/)
|
||||
assert.match(runtime, /expected_sha256/)
|
||||
assert.match(runtime, /HOLOLAKE_LANGUAGE_KERNEL_PRIVATE_SHA256_MISMATCH/)
|
||||
assert.match(runtime, /PRIVATE_KERNELS_NOT_PROVISIONED/)
|
||||
assert.match(runtime, /ACCOUNT_PRIVATE_SOURCE_SHA256_VERIFIED/)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@ interface RuntimeSnapshot {
|
|||
state: string
|
||||
sourceRemoteSha: string
|
||||
artifactCount: number
|
||||
publicArtifactCount: number
|
||||
privateArtifactCount: number
|
||||
expectedPrivateArtifactCount: number
|
||||
privateProvisioningState: string
|
||||
personaBindingState: string
|
||||
channelReceiptRuntimeState: string
|
||||
}
|
||||
|
|
@ -82,6 +86,15 @@ function friendlyError(reason: unknown) {
|
|||
return `${message}\n技术回执:${raw}`
|
||||
}
|
||||
|
||||
function kernelStateLabel(runtime: RuntimeSnapshot | null) {
|
||||
const installation = runtime?.languageKernelInstallation
|
||||
if (!installation) return '等待安装核验'
|
||||
if (installation.privateProvisioningState === 'PRIVATE_KERNELS_NOT_PROVISIONED') return '公共协议已核验 · 私域核未配置'
|
||||
if (installation.privateProvisioningState === 'PRIVATE_KERNELS_PARTIALLY_PROVISIONED_SHA256_VERIFIED') return '公共协议已核验 · 私域核仅部分配置'
|
||||
if (installation.privateProvisioningState === 'PRIVATE_KERNELS_PROVISIONED_SHA256_VERIFIED') return runtime?.boundPersonaNumber ? '私域核已核验 · 当前人格绑定已通过' : '私域核已核验 · 当前未绑定人格'
|
||||
return '公共协议安装已核验'
|
||||
}
|
||||
|
||||
export function KnowledgeAgent({ activeKnowledgePath, onClose }: { activeKnowledgePath?: string; onClose: () => void }) {
|
||||
const [runtime, setRuntime] = useState<RuntimeSnapshot | null>(null)
|
||||
const [conversation, setConversation] = useState<Conversation | null>(null)
|
||||
|
|
@ -181,7 +194,7 @@ export function KnowledgeAgent({ activeKnowledgePath, onClose }: { activeKnowled
|
|||
<header className="agent-header"><div><span>{runtime?.boundPersonaNumber ? 'LANGUAGE PERSONA CHANNEL' : 'LANGUAGE CHANNEL SYSTEM'}</span><h2>{runtime?.channelName || '零点原核本体频道'}</h2><p>{runtime?.channelNumber || 'ICE-CH-ZC001'} · 知识库内嵌 Agent</p></div><button type="button" aria-label="关闭频道系统" onClick={onClose}>×</button></header>
|
||||
<nav className="agent-tabs"><button type="button" className={tab === 'channel' ? 'active' : ''} onClick={() => setTab('channel')}>频道 Agent</button><button type="button" className={tab === 'worker' ? 'active' : ''} onClick={() => setTab('worker')}>本地执行体</button><button type="button" className={tab === 'forge' ? 'active' : ''} onClick={() => setTab('forge')}>工具锻造</button></nav>
|
||||
{tab === 'worker' ? <LocalWorkerPanel boundPersonaNumber={runtime?.boundPersonaNumber}/> : tab === 'forge' ? <ToolForgePanel boundPersonaNumber={runtime?.boundPersonaNumber}/> : <>
|
||||
<section className="agent-runtime-bar"><div><b>{runtime?.boundPersonaNumber && runtime?.boundPersonaName ? `${runtime.boundPersonaNumber} · ${runtime.boundPersonaName}` : `${runtime?.responderNumber || 'ICE-CH-ZC001'} · ${runtime?.responderName || '零点原核频道系统'}`}</b><span>{runtime?.boundPersonaNumber ? '人格回应通道 · 由频道调度模型层级' : '频道系统本体 · 直接交流与整体调度'}</span></div><i/><div><b>{runtime?.languageKernelInstallation?.artifactCount ?? 0} 个有界核</b><span>{runtime?.languageKernelInstallation?.state === 'INSTALLED_AND_EACH_ARTIFACT_READBACK_VERIFIED' ? runtime?.boundPersonaNumber ? '核安装已核验 · 当前人格绑定已通过' : '核安装已核验 · 当前未绑定人格' : '等待安装核验'}</span></div><i/><div><b>{runtime?.personalSkillRuntime?.skillCount ?? 0} 个私有技能脑</b><span>确定性核与本机工具优先</span></div><i/><div><b>{provider?.label || '等待模型入口'}</b><span>{runtime?.boundPersonaNumber ? '频道按任务选择小模型或旗舰模型' : '频道认知与架构对话使用旗舰模型'}</span></div><button type="button" onClick={() => setConfigOpen((value) => !value)}>模型设置</button></section>
|
||||
<section className="agent-runtime-bar"><div><b>{runtime?.boundPersonaNumber && runtime?.boundPersonaName ? `${runtime.boundPersonaNumber} · ${runtime.boundPersonaName}` : `${runtime?.responderNumber || 'ICE-CH-ZC001'} · ${runtime?.responderName || '零点原核频道系统'}`}</b><span>{runtime?.boundPersonaNumber ? '人格回应通道 · 由频道调度模型层级' : '频道系统本体 · 直接交流与整体调度'}</span></div><i/><div><b>{runtime?.languageKernelInstallation?.artifactCount ?? 0} 个有界核</b><span>{kernelStateLabel(runtime)}</span></div><i/><div><b>{runtime?.personalSkillRuntime?.skillCount ?? 0} 个私有技能脑</b><span>确定性核与本机工具优先</span></div><i/><div><b>{provider?.label || '等待模型入口'}</b><span>{runtime?.boundPersonaNumber ? '频道按任务选择小模型或旗舰模型' : '频道认知与架构对话使用旗舰模型'}</span></div><button type="button" onClick={() => setConfigOpen((value) => !value)}>模型设置</button></section>
|
||||
{configOpen && <form className="agent-provider-form" onSubmit={(event) => void saveProvider(event)}><label><span>入口名称</span><input value={providerLabel} onChange={(event) => setProviderLabel(event.target.value)}/></label><label><span>Base URL</span><input value={baseUrl} onChange={(event) => setBaseUrl(event.target.value)}/></label><label><span>模型</span><input value={model} onChange={(event) => setModel(event.target.value)}/></label><label><span>Token Plan API Key</span><input type="password" autoComplete="off" value={apiKey} placeholder="sk-sp-… · 只存系统钥匙串" onChange={(event) => setApiKey(event.target.value)}/></label><button disabled={!baseUrl || !model}>保存模型入口</button></form>}
|
||||
<div className="agent-channel-layout">
|
||||
<aside className="agent-conversations" aria-label="频道历史对话">
|
||||
|
|
|
|||
Loading…
Reference in a new issue