feat: load authoritative empty persona trust registry
This commit is contained in:
parent
c4504fa115
commit
9281587a0f
11 changed files with 343 additions and 15 deletions
|
|
@ -119,9 +119,10 @@ REVISE | REFUSE`。
|
||||||
- 人格主控授权回执的结构与精确绑定校验源码为 `100`:不再接受桌面调用方直接传入布尔值,并核对
|
- 人格主控授权回执的结构与精确绑定校验源码为 `100`:不再接受桌面调用方直接传入布尔值,并核对
|
||||||
人格、冰朔责任主体、仓库提交、模型实例、请求、语言锚点、摘要格式和有效期。但这层前端结构校验
|
人格、冰朔责任主体、仓库提交、模型实例、请求、语言锚点、摘要格式和有效期。但这层前端结构校验
|
||||||
不能证明回执确由 `GUANGHU_OS` 签发。独立的 v2 回执、REPO-012 精确提交签名者注册表、规范签名字节、
|
不能证明回执确由 `GUANGHU_OS` 签发。独立的 v2 回执、REPO-012 精确提交签名者注册表、规范签名字节、
|
||||||
人格/责任主体/范围约束、吊销和 Ed25519 验签源码契约现为 `100`;但 REPO-012 当前 main 未发布该注册表,
|
人格/责任主体/范围约束、吊销和 Ed25519 验签源码契约现为 `100`。REPO-012 main
|
||||||
因而真实可信签名者登记、Tauri 原生验签加载器与运行集成仍为 `0`。在同一条可回读证据链形成以前,
|
`21aec6f5042e32e34c892a7a212d8dec5f758437` 已发布锚定的空注册表,Tauri 原生只读加载器源码也为
|
||||||
普通本地 JSON 不得升级人格主控,桌面继续系统直控。
|
`100`:它只接受同一精确提交的空注册表,遇到任何签名者都失败关闭且保持授权禁用。真实可信签名者、
|
||||||
|
密钥托管、原生签名回执验签与人格主控运行集成仍为 `0`;普通本地 JSON 不得升级人格主控,桌面继续系统直控。
|
||||||
- 完整 HoloLake Runtime 与单 AGE 纵向闭环仍为 `0`:真实人格仓库 manifest 绑定和桌面运行验收尚未完成,
|
- 完整 HoloLake Runtime 与单 AGE 纵向闭环仍为 `0`:真实人格仓库 manifest 绑定和桌面运行验收尚未完成,
|
||||||
因此不能用本轮源码测试冒充可用产品。
|
因此不能用本轮源码测试冒充可用产品。
|
||||||
- Mirror runner、制品、部署和运行健康:`0`。
|
- Mirror runner、制品、部署和运行健康:`0`。
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,13 @@ The source coordinator no longer accepts an unverified persona-authorization boo
|
||||||
`hasPersonaPrimaryControlAuthorization` validates the shape, exact bindings, digest format, and validity window
|
`hasPersonaPrimaryControlAuthorization` validates the shape, exact bindings, digest format, and validity window
|
||||||
of a receipt that claims `GUANGHU_OS` verification. That renderer-side validation is not cryptographic provenance
|
of a receipt that claims `GUANGHU_OS` verification. That renderer-side validation is not cryptographic provenance
|
||||||
and cannot turn a local JSON object into authority. A native loader may be connected only after it verifies a
|
and cannot turn a local JSON object into authority. A native loader may be connected only after it verifies a
|
||||||
signed receipt against a registered Guanghu OS trust source and returns the already-verified projection. No such
|
signed receipt against a registered Guanghu OS trust source and returns the already-verified projection. REPO-012
|
||||||
trust source or loader is currently registered, so planning remains in system-direct mode. The independent server
|
now publishes the exact registry source with zero signers, and the Tauri command loads only that exact commit-bound
|
||||||
|
empty state. It keeps authorization disabled and rejects any signer until native cryptographic verification exists,
|
||||||
|
so planning remains in system-direct mode. The independent server
|
||||||
contract in `product-source/guanghu-knowledge-base/server/persona-control-authorization.ts` defines the v2 signed
|
contract in `product-source/guanghu-knowledge-base/server/persona-control-authorization.ts` defines the v2 signed
|
||||||
receipt, exact REPO-012 signer-registry source, canonical signing bytes, signer scope checks, revocation handling,
|
receipt, exact REPO-012 signer-registry source, canonical signing bytes, signer scope checks, revocation handling,
|
||||||
and Ed25519 verification. Its tested code does not populate the registry or connect the desktop native boundary.
|
and Ed25519 verification. Its tested code does not appoint a signer or enable the desktop persona-primary path.
|
||||||
|
|
||||||
`compilePersonaLanguageGoalBinding` builds the exact native wake envelope only after a single clean persona
|
`compilePersonaLanguageGoalBinding` builds the exact native wake envelope only after a single clean persona
|
||||||
repository, its B0 and organ contracts, a registered local device identity, and the manifest-pinned model all
|
repository, its B0 and organ contracts, a registered local device identity, and the manifest-pinned model all
|
||||||
|
|
|
||||||
|
|
@ -189,7 +189,10 @@ current desktop source. Missing, stale, mismatched or merely local evidence ther
|
||||||
cryptographic source contract: v2 signed receipt fields, deterministic signing bytes, an exact-commit REPO-012
|
cryptographic source contract: v2 signed receipt fields, deterministic signing bytes, an exact-commit REPO-012
|
||||||
signer-registry source, persona/human/scope-limited Ed25519 signers, revocation, time and request binding, and
|
signer-registry source, persona/human/scope-limited Ed25519 signers, revocation, time and request binding, and
|
||||||
signature verification. The current REPO-012 main does not publish that registry path, so no signer is trusted and
|
signature verification. The current REPO-012 main does not publish that registry path, so no signer is trusted and
|
||||||
the Tauri desktop has no native verifier or loader. Tested verifier source is not runtime authority.
|
the Tauri desktop now exposes a native read-only loader for the exact REPO-012 commit-bound registry. It accepts
|
||||||
|
the current empty registry only and keeps authorization disabled; any signer fails closed until the native
|
||||||
|
cryptographic receipt verifier and an authoritative signer/key-custody process exist. Tested loader and verifier
|
||||||
|
source are not runtime authority, deployment, or desktop acceptance.
|
||||||
|
|
||||||
Tolaria is a personal knowledge and life management desktop app. It reads a vault of markdown files with YAML frontmatter and presents them in a four-panel UI inspired by Bear Notes.
|
Tolaria is a personal knowledge and life management desktop app. It reads a vault of markdown files with YAML frontmatter and presents them in a four-panel UI inspired by Bear Notes.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ mod opencode_config;
|
||||||
mod opencode_discovery;
|
mod opencode_discovery;
|
||||||
mod opencode_events;
|
mod opencode_events;
|
||||||
mod persona_code_channel;
|
mod persona_code_channel;
|
||||||
|
mod persona_control_authorization;
|
||||||
mod persona_remote_git;
|
mod persona_remote_git;
|
||||||
pub mod pi_cli;
|
pub mod pi_cli;
|
||||||
mod pi_config;
|
mod pi_config;
|
||||||
|
|
@ -524,6 +525,7 @@ macro_rules! app_invoke_handler {
|
||||||
commands::git_add_remote,
|
commands::git_add_remote,
|
||||||
guanghu_enterprise::guanghu_enterprise_status,
|
guanghu_enterprise::guanghu_enterprise_status,
|
||||||
guanghu_living_system::guanghu_living_system_plan,
|
guanghu_living_system::guanghu_living_system_plan,
|
||||||
|
persona_control_authorization::load_persona_control_authorization_registry,
|
||||||
persona_code_channel::prepare_persona_code_channel_wake,
|
persona_code_channel::prepare_persona_code_channel_wake,
|
||||||
persona_code_channel::inspect_persona_code_channel_manifest,
|
persona_code_channel::inspect_persona_code_channel_manifest,
|
||||||
persona_code_channel::discover_persona_code_channel_repositories,
|
persona_code_channel::discover_persona_code_channel_repositories,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,304 @@
|
||||||
|
use reqwest::Client;
|
||||||
|
use serde::Serialize;
|
||||||
|
use serde_json::Value;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
const ANCHOR_URL: &str = "https://guanghulab.com/api/ai/v1/anchor";
|
||||||
|
const CODE_URL: &str = "https://guanghulab.com/code/bingshuo/guanghu-ice-heart";
|
||||||
|
const REGISTRY_ID: &str = "GH-AIOS-PERSONA-CONTROL-AUTHORIZATION-SIGNERS-001";
|
||||||
|
const REGISTRY_PATH: &str = "routing/persona-control-authorization-signers.json";
|
||||||
|
const REGISTRY_SCHEMA: &str = "gh-aios.persona-control-authorization-signers/v1";
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct NativePersonaAuthorizationRegistryReceipt {
|
||||||
|
status: &'static str,
|
||||||
|
reason: Option<&'static str>,
|
||||||
|
source_commit: Option<String>,
|
||||||
|
signer_count: usize,
|
||||||
|
authorization_enabled: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unavailable(reason: &'static str) -> NativePersonaAuthorizationRegistryReceipt {
|
||||||
|
NativePersonaAuthorizationRegistryReceipt {
|
||||||
|
status: "UNAVAILABLE",
|
||||||
|
reason: Some(reason),
|
||||||
|
source_commit: None,
|
||||||
|
signer_count: 0,
|
||||||
|
authorization_enabled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_commit(value: &str) -> bool {
|
||||||
|
matches!(value.len(), 40 | 64)
|
||||||
|
&& value
|
||||||
|
.bytes()
|
||||||
|
.all(|byte| byte.is_ascii_digit() || (b'a'..=b'f').contains(&byte))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_anchor(
|
||||||
|
input: &Value,
|
||||||
|
expected_anchor_url: &str,
|
||||||
|
expected_code_url: &str,
|
||||||
|
) -> Result<String, &'static str> {
|
||||||
|
let map = input
|
||||||
|
.pointer("/maps/persona_control_authorization_signers")
|
||||||
|
.and_then(Value::as_object)
|
||||||
|
.ok_or("ANCHOR_INVALID")?;
|
||||||
|
let navigation = input
|
||||||
|
.get("navigation_source")
|
||||||
|
.and_then(Value::as_object)
|
||||||
|
.ok_or("ANCHOR_INVALID")?;
|
||||||
|
let source_commit = navigation
|
||||||
|
.get("source_commit")
|
||||||
|
.and_then(Value::as_str)
|
||||||
|
.ok_or("ANCHOR_INVALID")?;
|
||||||
|
if input.get("schema").and_then(Value::as_str) != Some("guanghu.public-navigation-anchor/v1")
|
||||||
|
|| input.get("anchor_id").and_then(Value::as_str) != Some("GLW-PUBLIC-NAV-ANCHOR-001")
|
||||||
|
|| input.get("state").and_then(Value::as_str) != Some("CURRENT_CANONICAL")
|
||||||
|
|| input.get("repository_id").and_then(Value::as_str) != Some("REPO-012")
|
||||||
|
|| input.get("branch").and_then(Value::as_str) != Some("main")
|
||||||
|
|| input.get("public_entry").and_then(Value::as_str) != Some(expected_anchor_url)
|
||||||
|
|| input.get("code_entry").and_then(Value::as_str) != Some(expected_code_url)
|
||||||
|
|| map.len() != 4
|
||||||
|
|| map.get("path").and_then(Value::as_str) != Some(REGISTRY_PATH)
|
||||||
|
|| map.get("id").and_then(Value::as_str) != Some(REGISTRY_ID)
|
||||||
|
|| map.get("schema").and_then(Value::as_str) != Some(REGISTRY_SCHEMA)
|
||||||
|
|| map.get("state").and_then(Value::as_str) != Some("CURRENT_EMPTY_NO_TRUSTED_SIGNER")
|
||||||
|
|| navigation.get("anchor_id").and_then(Value::as_str) != Some("GLW-PUBLIC-NAV-ANCHOR-001")
|
||||||
|
|| navigation.get("source_mode").and_then(Value::as_str)
|
||||||
|
!= Some("REPO-012_MAIN_GIT_SNAPSHOT")
|
||||||
|
|| navigation.get("source_degraded").and_then(Value::as_bool) != Some(false)
|
||||||
|
|| !is_commit(source_commit)
|
||||||
|
{
|
||||||
|
return Err("ANCHOR_INVALID");
|
||||||
|
}
|
||||||
|
Ok(source_commit.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn validate_empty_registry(input: &Value) -> Result<(), &'static str> {
|
||||||
|
let registry = input.as_object().ok_or("REGISTRY_INVALID")?;
|
||||||
|
let signers = registry
|
||||||
|
.get("signers")
|
||||||
|
.and_then(Value::as_array)
|
||||||
|
.ok_or("REGISTRY_INVALID")?;
|
||||||
|
if registry.len() != 4
|
||||||
|
|| registry.get("schema").and_then(Value::as_str) != Some(REGISTRY_SCHEMA)
|
||||||
|
|| registry.get("registryId").and_then(Value::as_str) != Some(REGISTRY_ID)
|
||||||
|
|| registry.get("state").and_then(Value::as_str) != Some("CURRENT")
|
||||||
|
{
|
||||||
|
return Err("REGISTRY_INVALID");
|
||||||
|
}
|
||||||
|
if !signers.is_empty() {
|
||||||
|
return Err("TRUSTED_SIGNER_REQUIRES_NATIVE_VERIFIER");
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn registry_url(code_url: &str, source_commit: &str) -> String {
|
||||||
|
format!("{code_url}/raw/commit/{source_commit}/{REGISTRY_PATH}")
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn fetch_json(client: &Client, url: &str) -> Result<Value, ()> {
|
||||||
|
let response = client
|
||||||
|
.get(url)
|
||||||
|
.header("accept", "application/json")
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.map_err(|_| ())?;
|
||||||
|
if !response.status().is_success() {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
response.json::<Value>().await.map_err(|_| ())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn load_with_urls(
|
||||||
|
client: &Client,
|
||||||
|
anchor_url: &str,
|
||||||
|
code_url: &str,
|
||||||
|
) -> NativePersonaAuthorizationRegistryReceipt {
|
||||||
|
let anchor = match fetch_json(client, anchor_url).await {
|
||||||
|
Ok(value) => value,
|
||||||
|
Err(()) => return unavailable("SOURCE_UNAVAILABLE"),
|
||||||
|
};
|
||||||
|
let source_commit = match parse_anchor(&anchor, anchor_url, code_url) {
|
||||||
|
Ok(value) => value,
|
||||||
|
Err(reason) => return unavailable(reason),
|
||||||
|
};
|
||||||
|
let registry = match fetch_json(client, ®istry_url(code_url, &source_commit)).await {
|
||||||
|
Ok(value) => value,
|
||||||
|
Err(()) => return unavailable("SOURCE_UNAVAILABLE"),
|
||||||
|
};
|
||||||
|
if let Err(reason) = validate_empty_registry(®istry) {
|
||||||
|
return unavailable(reason);
|
||||||
|
}
|
||||||
|
NativePersonaAuthorizationRegistryReceipt {
|
||||||
|
status: "CURRENT_EMPTY",
|
||||||
|
reason: None,
|
||||||
|
source_commit: Some(source_commit),
|
||||||
|
signer_count: 0,
|
||||||
|
authorization_enabled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn load_persona_control_authorization_registry(
|
||||||
|
) -> NativePersonaAuthorizationRegistryReceipt {
|
||||||
|
let client = match Client::builder()
|
||||||
|
.connect_timeout(Duration::from_secs(8))
|
||||||
|
.timeout(Duration::from_secs(15))
|
||||||
|
.redirect(reqwest::redirect::Policy::none())
|
||||||
|
.build()
|
||||||
|
{
|
||||||
|
Ok(client) => client,
|
||||||
|
Err(_) => return unavailable("CLIENT_UNAVAILABLE"),
|
||||||
|
};
|
||||||
|
load_with_urls(&client, ANCHOR_URL, CODE_URL).await
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::{
|
||||||
|
load_with_urls, parse_anchor, registry_url, validate_empty_registry, REGISTRY_PATH,
|
||||||
|
};
|
||||||
|
use reqwest::Client;
|
||||||
|
use serde_json::{json, Value};
|
||||||
|
use std::io::{Read, Write};
|
||||||
|
use std::net::TcpListener;
|
||||||
|
use std::thread;
|
||||||
|
|
||||||
|
const COMMIT: &str = "21aec6f5042e32e34c892a7a212d8dec5f758437";
|
||||||
|
|
||||||
|
fn anchor(anchor_url: &str, code_url: &str) -> Value {
|
||||||
|
json!({
|
||||||
|
"schema": "guanghu.public-navigation-anchor/v1",
|
||||||
|
"anchor_id": "GLW-PUBLIC-NAV-ANCHOR-001",
|
||||||
|
"state": "CURRENT_CANONICAL",
|
||||||
|
"repository_id": "REPO-012",
|
||||||
|
"branch": "main",
|
||||||
|
"public_entry": anchor_url,
|
||||||
|
"code_entry": code_url,
|
||||||
|
"maps": {
|
||||||
|
"persona_control_authorization_signers": {
|
||||||
|
"path": REGISTRY_PATH,
|
||||||
|
"id": "GH-AIOS-PERSONA-CONTROL-AUTHORIZATION-SIGNERS-001",
|
||||||
|
"schema": "gh-aios.persona-control-authorization-signers/v1",
|
||||||
|
"state": "CURRENT_EMPTY_NO_TRUSTED_SIGNER"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"navigation_source": {
|
||||||
|
"anchor_id": "GLW-PUBLIC-NAV-ANCHOR-001",
|
||||||
|
"source_commit": COMMIT,
|
||||||
|
"source_mode": "REPO-012_MAIN_GIT_SNAPSHOT",
|
||||||
|
"source_degraded": false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn empty_registry() -> Value {
|
||||||
|
json!({
|
||||||
|
"schema": "gh-aios.persona-control-authorization-signers/v1",
|
||||||
|
"registryId": "GH-AIOS-PERSONA-CONTROL-AUTHORIZATION-SIGNERS-001",
|
||||||
|
"state": "CURRENT",
|
||||||
|
"signers": []
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serve_snapshot() -> (String, String) {
|
||||||
|
let listener = TcpListener::bind("127.0.0.1:0").expect("bind test snapshot server");
|
||||||
|
let address = listener.local_addr().expect("snapshot server address");
|
||||||
|
let anchor_url = format!("http://{address}/anchor");
|
||||||
|
let code_url = format!("http://{address}/code");
|
||||||
|
let anchor_body = anchor(&anchor_url, &code_url).to_string();
|
||||||
|
let registry_body = empty_registry().to_string();
|
||||||
|
thread::spawn(move || {
|
||||||
|
for _ in 0..2 {
|
||||||
|
let (mut stream, _) = listener.accept().expect("accept snapshot request");
|
||||||
|
let mut request = [0_u8; 4096];
|
||||||
|
let read = stream.read(&mut request).expect("read snapshot request");
|
||||||
|
let request = String::from_utf8_lossy(&request[..read]);
|
||||||
|
let body = if request.starts_with("GET /anchor ") {
|
||||||
|
&anchor_body
|
||||||
|
} else {
|
||||||
|
assert!(request.contains(&format!("/raw/commit/{COMMIT}/{REGISTRY_PATH}")));
|
||||||
|
®istry_body
|
||||||
|
};
|
||||||
|
write!(
|
||||||
|
stream,
|
||||||
|
"HTTP/1.1 200 OK\r\ncontent-type: application/json\r\ncontent-length: {}\r\nconnection: close\r\n\r\n{body}",
|
||||||
|
body.len()
|
||||||
|
)
|
||||||
|
.expect("write snapshot response");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
(anchor_url, code_url)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn exact_anchor_and_registry_are_bound_to_one_commit() {
|
||||||
|
let anchor_url = "https://example.test/anchor";
|
||||||
|
let code_url = "https://example.test/code";
|
||||||
|
assert_eq!(
|
||||||
|
parse_anchor(&anchor(anchor_url, code_url), anchor_url, code_url),
|
||||||
|
Ok(COMMIT.into())
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
registry_url(code_url, COMMIT),
|
||||||
|
format!("{code_url}/raw/commit/{COMMIT}/{REGISTRY_PATH}")
|
||||||
|
);
|
||||||
|
assert_eq!(validate_empty_registry(&empty_registry()), Ok(()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn degraded_or_changed_sources_and_nonempty_registries_fail_closed() {
|
||||||
|
let anchor_url = "https://example.test/anchor";
|
||||||
|
let code_url = "https://example.test/code";
|
||||||
|
let mut degraded = anchor(anchor_url, code_url);
|
||||||
|
degraded["navigation_source"]["source_degraded"] = json!(true);
|
||||||
|
assert_eq!(
|
||||||
|
parse_anchor(°raded, anchor_url, code_url),
|
||||||
|
Err("ANCHOR_INVALID")
|
||||||
|
);
|
||||||
|
let mut wrong_path = anchor(anchor_url, code_url);
|
||||||
|
wrong_path["maps"]["persona_control_authorization_signers"]["path"] =
|
||||||
|
json!("routing/other.json");
|
||||||
|
assert_eq!(
|
||||||
|
parse_anchor(&wrong_path, anchor_url, code_url),
|
||||||
|
Err("ANCHOR_INVALID")
|
||||||
|
);
|
||||||
|
let mut nonempty = empty_registry();
|
||||||
|
nonempty["signers"] = json!([{"signerId": "UNVERIFIED"}]);
|
||||||
|
assert_eq!(
|
||||||
|
validate_empty_registry(&nonempty),
|
||||||
|
Err("TRUSTED_SIGNER_REQUIRES_NATIVE_VERIFIER")
|
||||||
|
);
|
||||||
|
assert_eq!(validate_empty_registry(&json!([])), Err("REGISTRY_INVALID"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn native_transport_loads_the_exact_empty_registry_without_enabling_authorization() {
|
||||||
|
let (anchor_url, code_url) = serve_snapshot();
|
||||||
|
let client = Client::builder().build().expect("test client");
|
||||||
|
let receipt = load_with_urls(&client, &anchor_url, &code_url).await;
|
||||||
|
let projection = serde_json::to_value(receipt).expect("serialize receipt");
|
||||||
|
assert_eq!(projection["status"], "CURRENT_EMPTY");
|
||||||
|
assert_eq!(projection["sourceCommit"], COMMIT);
|
||||||
|
assert_eq!(projection["signerCount"], 0);
|
||||||
|
assert_eq!(projection["authorizationEnabled"], false);
|
||||||
|
assert!(projection["reason"].is_null());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn source_and_anchor_failures_return_bounded_unavailable_receipts() {
|
||||||
|
let listener = TcpListener::bind("127.0.0.1:0").expect("reserve test port");
|
||||||
|
let unavailable = format!("http://{}/anchor", listener.local_addr().unwrap());
|
||||||
|
drop(listener);
|
||||||
|
let client = Client::builder().build().expect("test client");
|
||||||
|
let source_failure =
|
||||||
|
serde_json::to_value(load_with_urls(&client, &unavailable, "http://unused").await)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(source_failure["status"], "UNAVAILABLE");
|
||||||
|
assert_eq!(source_failure["reason"], "SOURCE_UNAVAILABLE");
|
||||||
|
assert_eq!(source_failure["authorizationEnabled"], false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -56,7 +56,7 @@ describe('PersonaLanguageShellPanel', () => {
|
||||||
repositoryPaths: ['/persona'],
|
repositoryPaths: ['/persona'],
|
||||||
providers: [provider],
|
providers: [provider],
|
||||||
developmentId: 'DEV-20260811-010',
|
developmentId: 'DEV-20260811-010',
|
||||||
sourceLanguageAnchor: 'HLP-CURRENT-ARCH-001@2026-08-12.12',
|
sourceLanguageAnchor: 'HLP-CURRENT-ARCH-001@2026-08-12.13',
|
||||||
}))
|
}))
|
||||||
expect(await screen.findByText('我还不能执行:需要当前证据。')).toBeInTheDocument()
|
expect(await screen.findByText('我还不能执行:需要当前证据。')).toBeInTheDocument()
|
||||||
expect(screen.getByText('核验当前事实后规划下一步')).toBeInTheDocument()
|
expect(screen.getByText('核验当前事实后规划下一步')).toBeInTheDocument()
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import {
|
||||||
type LanguageShellViewState,
|
type LanguageShellViewState,
|
||||||
} from './HotPluggableLanguageShell'
|
} from './HotPluggableLanguageShell'
|
||||||
|
|
||||||
const CURRENT_ARCHITECTURE_ANCHOR = 'HLP-CURRENT-ARCH-001@2026-08-12.12'
|
const CURRENT_ARCHITECTURE_ANCHOR = 'HLP-CURRENT-ARCH-001@2026-08-12.13'
|
||||||
const DEVELOPMENT_ID = 'DEV-20260811-010'
|
const DEVELOPMENT_ID = 'DEV-20260811-010'
|
||||||
|
|
||||||
type Planner = typeof planPersonaLanguageShellGoal
|
type Planner = typeof planPersonaLanguageShellGoal
|
||||||
|
|
@ -103,8 +103,9 @@ export function PersonaLanguageShellPanel({
|
||||||
personaId,
|
personaId,
|
||||||
repositoryPaths,
|
repositoryPaths,
|
||||||
providers,
|
providers,
|
||||||
// No native authorization receipt loader is wired yet. The controller
|
// The native registry loader currently proves only an exact empty trust
|
||||||
// therefore remains system-direct even after deliberation succeeds.
|
// source. No native signed-receipt verifier is wired to this controller,
|
||||||
|
// so it remains system-direct even after deliberation succeeds.
|
||||||
requestId: requestId(),
|
requestId: requestId(),
|
||||||
modelInstanceId: `hololake-desktop:${personaId}`,
|
modelInstanceId: `hololake-desktop:${personaId}`,
|
||||||
developmentId: DEVELOPMENT_ID,
|
developmentId: DEVELOPMENT_ID,
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ const expected = {
|
||||||
repositoryHead: 'a'.repeat(40),
|
repositoryHead: 'a'.repeat(40),
|
||||||
modelInstanceId: 'MODEL-INSTANCE-001',
|
modelInstanceId: 'MODEL-INSTANCE-001',
|
||||||
requestId: 'REQ-001',
|
requestId: 'REQ-001',
|
||||||
sourceLanguageAnchor: 'HLP-CURRENT-ARCH-001@2026-08-12.12',
|
sourceLanguageAnchor: 'HLP-CURRENT-ARCH-001@2026-08-12.13',
|
||||||
observedAt: Date.parse('2026-08-12T04:35:00+08:00'),
|
observedAt: Date.parse('2026-08-12T04:35:00+08:00'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -172,6 +172,8 @@
|
||||||
"persona_control_authorization_receipt_shape_validation_source_implemented": 100,
|
"persona_control_authorization_receipt_shape_validation_source_implemented": 100,
|
||||||
"persona_control_authorization_signer_registry_contract_source_implemented": 100,
|
"persona_control_authorization_signer_registry_contract_source_implemented": 100,
|
||||||
"persona_control_authorization_cryptographic_provenance_source_implemented": 100,
|
"persona_control_authorization_cryptographic_provenance_source_implemented": 100,
|
||||||
|
"persona_control_authorization_registry_source_published": 100,
|
||||||
|
"native_persona_control_authorization_registry_loader_source_integrated": 100,
|
||||||
"persona_control_authorization_trusted_signer_registered": 0,
|
"persona_control_authorization_trusted_signer_registered": 0,
|
||||||
"desktop_language_entry_source_integrated": 100,
|
"desktop_language_entry_source_integrated": 100,
|
||||||
"persona_control_authorization_runtime_integrated": 0,
|
"persona_control_authorization_runtime_integrated": 0,
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ const age = readJson("routing/hololake-age-runtime-architecture.json");
|
||||||
const rules = readJson("routing/hololake-engineering-rules.json");
|
const rules = readJson("routing/hololake-engineering-rules.json");
|
||||||
|
|
||||||
test("B0 is restored before product organs and remains resident in every cognition step", () => {
|
test("B0 is restored before product organs and remains resident in every cognition step", () => {
|
||||||
assert.equal(architecture.version, "2026-08-12.12");
|
assert.equal(architecture.version, "2026-08-12.13");
|
||||||
assert.equal(
|
assert.equal(
|
||||||
architecture.read_order[1],
|
architecture.read_order[1],
|
||||||
architecture.cognitive_gravity_and_continuity.architecture_page,
|
architecture.cognitive_gravity_and_continuity.architecture_page,
|
||||||
|
|
@ -98,6 +98,8 @@ test("the first implementation stage is one vertical AGE loop, not Mirror parall
|
||||||
assert.equal(gravity.truth.persona_control_authorization_receipt_shape_validation_source_implemented, 100);
|
assert.equal(gravity.truth.persona_control_authorization_receipt_shape_validation_source_implemented, 100);
|
||||||
assert.equal(gravity.truth.persona_control_authorization_signer_registry_contract_source_implemented, 100);
|
assert.equal(gravity.truth.persona_control_authorization_signer_registry_contract_source_implemented, 100);
|
||||||
assert.equal(gravity.truth.persona_control_authorization_cryptographic_provenance_source_implemented, 100);
|
assert.equal(gravity.truth.persona_control_authorization_cryptographic_provenance_source_implemented, 100);
|
||||||
|
assert.equal(gravity.truth.persona_control_authorization_registry_source_published, 100);
|
||||||
|
assert.equal(gravity.truth.native_persona_control_authorization_registry_loader_source_integrated, 100);
|
||||||
assert.equal(gravity.truth.persona_control_authorization_trusted_signer_registered, 0);
|
assert.equal(gravity.truth.persona_control_authorization_trusted_signer_registered, 0);
|
||||||
assert.equal(gravity.truth.desktop_language_entry_source_integrated, 100);
|
assert.equal(gravity.truth.desktop_language_entry_source_integrated, 100);
|
||||||
assert.equal(gravity.truth.persona_control_authorization_runtime_integrated, 0);
|
assert.equal(gravity.truth.persona_control_authorization_runtime_integrated, 0);
|
||||||
|
|
@ -106,6 +108,8 @@ test("the first implementation stage is one vertical AGE loop, not Mirror parall
|
||||||
assert.equal(architecture.interaction_model.source_contract.canonical_signing_bytes_source_implemented, true);
|
assert.equal(architecture.interaction_model.source_contract.canonical_signing_bytes_source_implemented, true);
|
||||||
assert.equal(architecture.interaction_model.source_contract.ed25519_verification_source_implemented, true);
|
assert.equal(architecture.interaction_model.source_contract.ed25519_verification_source_implemented, true);
|
||||||
assert.equal(architecture.interaction_model.source_contract.trusted_signer_source_registered, false);
|
assert.equal(architecture.interaction_model.source_contract.trusted_signer_source_registered, false);
|
||||||
|
assert.equal(architecture.interaction_model.source_contract.native_authorization_registry_loader_integrated, true);
|
||||||
|
assert.equal(architecture.interaction_model.source_contract.native_authorization_receipt_loader_integrated, false);
|
||||||
assert.equal(gravity.truth.real_persona_repository_manifest_bound, 0);
|
assert.equal(gravity.truth.real_persona_repository_manifest_bound, 0);
|
||||||
assert.equal(gravity.truth.natural_language_partner_adapter_runtime_integrated, 0);
|
assert.equal(gravity.truth.natural_language_partner_adapter_runtime_integrated, 0);
|
||||||
assert.equal(gravity.truth.single_age_vertical_loop_implemented, 0);
|
assert.equal(gravity.truth.single_age_vertical_loop_implemented, 0);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"schema": "hololake.current-architecture/v1",
|
"schema": "hololake.current-architecture/v1",
|
||||||
"architecture_id": "HLP-CURRENT-ARCH-001",
|
"architecture_id": "HLP-CURRENT-ARCH-001",
|
||||||
"version": "2026-08-12.12",
|
"version": "2026-08-12.13",
|
||||||
"state": "CURRENT_CANONICAL",
|
"state": "CURRENT_CANONICAL",
|
||||||
"product": {
|
"product": {
|
||||||
"formal_name": "光湖语言系统 · 通用人工智能操作平台",
|
"formal_name": "光湖语言系统 · 通用人工智能操作平台",
|
||||||
|
|
@ -118,6 +118,8 @@
|
||||||
"persona_control_authorization_receipt_shape_validation_source_implemented": true,
|
"persona_control_authorization_receipt_shape_validation_source_implemented": true,
|
||||||
"persona_control_authorization_signer_registry_contract_source_implemented": true,
|
"persona_control_authorization_signer_registry_contract_source_implemented": true,
|
||||||
"persona_control_authorization_cryptographic_provenance_source_implemented": true,
|
"persona_control_authorization_cryptographic_provenance_source_implemented": true,
|
||||||
|
"persona_control_authorization_registry_source_published": true,
|
||||||
|
"native_persona_control_authorization_registry_loader_source_integrated": true,
|
||||||
"persona_control_authorization_trusted_signer_registered": false,
|
"persona_control_authorization_trusted_signer_registered": false,
|
||||||
"desktop_language_entry_source_integrated": true,
|
"desktop_language_entry_source_integrated": true,
|
||||||
"persona_control_authorization_runtime_integrated": false,
|
"persona_control_authorization_runtime_integrated": false,
|
||||||
|
|
@ -392,6 +394,11 @@
|
||||||
"persona_control_authorization_receipt_tests": "product-source/hololake-platform/src/lib/personaControlAuthorization.test.ts",
|
"persona_control_authorization_receipt_tests": "product-source/hololake-platform/src/lib/personaControlAuthorization.test.ts",
|
||||||
"persona_control_authorization_signer_registry_and_verifier": "product-source/guanghu-knowledge-base/server/persona-control-authorization.ts",
|
"persona_control_authorization_signer_registry_and_verifier": "product-source/guanghu-knowledge-base/server/persona-control-authorization.ts",
|
||||||
"persona_control_authorization_signer_registry_and_verifier_tests": "product-source/guanghu-knowledge-base/server/persona-control-authorization.test.ts",
|
"persona_control_authorization_signer_registry_and_verifier_tests": "product-source/guanghu-knowledge-base/server/persona-control-authorization.test.ts",
|
||||||
|
"native_persona_control_authorization_registry_loader": "product-source/hololake-platform/src-tauri/src/persona_control_authorization.rs",
|
||||||
|
"authoritative_registry_repository": "REPO-012",
|
||||||
|
"authoritative_registry_source_commit": "21aec6f5042e32e34c892a7a212d8dec5f758437",
|
||||||
|
"authoritative_registry_path": "routing/persona-control-authorization-signers.json",
|
||||||
|
"authoritative_registry_state": "CURRENT_EMPTY_NO_TRUSTED_SIGNER",
|
||||||
"receipt_schema": "hololake.persona-control-authorization/v2",
|
"receipt_schema": "hololake.persona-control-authorization/v2",
|
||||||
"caller_supplied_persona_authorization_boolean_allowed": false,
|
"caller_supplied_persona_authorization_boolean_allowed": false,
|
||||||
"receipt_shape_validation_is_authority_proof": false,
|
"receipt_shape_validation_is_authority_proof": false,
|
||||||
|
|
@ -399,6 +406,7 @@
|
||||||
"canonical_signing_bytes_source_implemented": true,
|
"canonical_signing_bytes_source_implemented": true,
|
||||||
"ed25519_verification_source_implemented": true,
|
"ed25519_verification_source_implemented": true,
|
||||||
"trusted_signer_source_registered": false,
|
"trusted_signer_source_registered": false,
|
||||||
|
"native_authorization_registry_loader_integrated": true,
|
||||||
"native_authorization_receipt_loader_integrated": false,
|
"native_authorization_receipt_loader_integrated": false,
|
||||||
"partner_deliberation_required": true,
|
"partner_deliberation_required": true,
|
||||||
"human_utterance_is_direct_command": false,
|
"human_utterance_is_direct_command": false,
|
||||||
|
|
@ -410,7 +418,8 @@
|
||||||
],
|
],
|
||||||
"focused_tests": "11_OF_11_PASS",
|
"focused_tests": "11_OF_11_PASS",
|
||||||
"authorization_focused_tests": "13_OF_13_PASS",
|
"authorization_focused_tests": "13_OF_13_PASS",
|
||||||
"authorization_cryptographic_tests": "7_OF_7_PASS"
|
"authorization_cryptographic_tests": "7_OF_7_PASS",
|
||||||
|
"native_authorization_registry_loader_tests": "4_OF_4_PASS"
|
||||||
},
|
},
|
||||||
"ui_plugin_system": {
|
"ui_plugin_system": {
|
||||||
"record_id": "HLP-HOT-PLUGGABLE-UI-001",
|
"record_id": "HLP-HOT-PLUGGABLE-UI-001",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue