feat(os): add cognitive control execution bridge

This commit is contained in:
冰朔 2026-08-07 13:45:27 +08:00
commit 25959f7af1
11 changed files with 877 additions and 6 deletions

View file

@ -0,0 +1,104 @@
# 光湖 OS 认知主控与现实执行架构
## 交付目标
光湖 OS 的完整性由一条闭环证明:
```text
能理解
→ 能判断边界
→ 能把判断编译为确定动作
→ 能调用现实手脚
→ 能看见真实结果
→ 能失败、回滚和继续思考
```
模型回答、协议文件、Linux 命令和界面状态中的任何单项都不是完整系统。
## 系统分层
| 层 | 常驻位置 | 责任 |
|---|---|---|
| 语言与人格 | REPO-012 + 持久人格状态 | 主体、关系、意图、职责、语言规则 |
| 模型认知 | 用户设备、个人云或模型 API | 当前理解、推理、候选计划、异常分析 |
| 协议控制 | 光湖主节点 | 身份、上下文、权限、动作类型、资源、回滚和验收 |
| 执行桥 | 光湖主节点或目标节点 | 将 GIR 映射为固定能力适配器 |
| Linux 执行底座 | 目标节点 | 驱动、进程、网络、存储、隔离和系统调用 |
| 用户执行与渲染 | 电脑、手机、个人云 | 界面、文件、应用、模型和本地设备动作 |
| 见证与连续性 | 光湖主节点 + 代码频道 | 原始证据、回执、检查点、因果链和恢复 |
## 协议到工程的首批映射
| 协议 | 当前工程对象 | 完成条件 |
|---|---|---|
| GLS-0301/0302/0303 | `ExecutionRequest` | 消息、主体和目标不可缺失或补猜 |
| GLS-0309 | 变更请求中的授权与验收引用 | 提出、批准、执行分离 |
| GLS-0130/0131 | `compile_request` / `ExecutionPlan` | 自由语言不能进入执行参数 |
| GLS-0709/0710 | `LINUX_SYSTEMD_V1` 与节点策略 | 固定适配器、固定版本、能力白名单 |
| GLS-0311/0306 | `ExecutionReceipt` | 命令结果与目标状态分别记录 |
| GLS-0803/0819 | 后续调度器 | 按需唤醒、资源隔离、停止和回收 |
| GLS-0708 | 后续模型路由器 | 模型可替换,不取得主体和权限 |
## 生产安全模型
1. 模型永远不直接拼接或执行 shell。
2. 每个适配器在代码中定义动作类型和参数形状。
3. 节点策略声明允许操作的精确资源。
4. 变更动作必须匹配当前授权和回滚检查点。
5. 命令退出码只表示执行器观察,目标侧读回才决定 `PASS_100`
6. Linux 管理入口与光湖正常入口分离;紧急入口启用必须留下维护回执。
7. 密钥、令牌和模型 API 凭据保留在节点受保护边界,不进入语言记录或执行请求。
## 京东节点落地顺序
### 阶段 A安全并存
- 保持当前 Ubuntu 默认启动和已验证回滚;
- 安装执行桥但只启用 `service_status`
- 为公共导航、代码频道和人格运行服务建立只读状态策略;
- 验证每个请求都能形成协议拒绝或目标侧回执。
### 阶段 B有界动作
- 为单一非关键光湖服务启用 `service_restart`
- 绑定节点级授权、不可变版本和回滚检查点;
- 验证重启、失败、回滚和最终健康;
- 禁止任意命令、任意路径和通配服务名。
### 阶段 C光湖成为正常主控入口
- HoloLake、人格体和自动任务只通过光湖协议执行桥操作服务
- 普通 Linux 管理路径移入紧急维护边界;
- 按需唤醒模型、人格执行体和模块,清除无关常驻服务;
- 公共导航继续自动读取同一 REPO-012 主线锚点。
### 阶段 D分布式执行
- 用户设备登记自己的渲染、文件、应用和推理能力;
- 中央节点只调度有界能力,不上传全部个人工作空间;
- 任务完成后回收执行体并保留人格、检查点和回执。
### 阶段 E裸机研究后端
- 现有 GOSK/GHAL 候选继续作为研究和专用设备后端;
- 只有某项成熟 Linux 能力确实需要替换时,才按协议逐件迁移;
- 研究失败不影响生产认知主控闭环。
## 当前完成边界
已完成:
- 生产路线架构纠正;
- 第一条类型化协议执行桥;
- systemd 状态与重启动作的白名单、授权、回滚和目标读回合同;
- 对应单元和集成测试。
仍未完成:
- REPO-012 当前协议提交的不可变绑定;
- 京东节点策略生成与只读部署;
- 模型路由、人格生命周期和分布式设备执行器;
- 全部注册协议的工程实现;
- 生产主控入口切换。
这些未完成项分别保持 0不能由本架构文件或本地测试冒充为已部署。

View file

@ -0,0 +1,68 @@
---
type: ADR
id: "0172"
title: "Guanghu cognitive control with a constrained Linux execution substrate"
status: accepted
date: 2026-08-07
supersedes_production_path: "0161"
---
# 光湖认知主控与 Linux 协作执行底座
## 背景
ADR-0161 把 Linux-free bare-metal handoff 设为生产完成条件。该路线已经在实验节点和
JD-FD-PRIMARY 上证明了启动、恢复、网络和原生锚点能力,但生产等价继续要求重写成熟的
代码频道、网卡、TCP、文件系统和服务运行能力。
冰朔重新锁定光湖 OS 的本体:光湖语言世界、人格体、模型认知和协议边界是系统大脑;
传统操作系统是成熟的现实手脚。生产目标不是先重复制造所有手脚,而是让光湖取得正常
入口、判断、授权、调度和完成判定的主控权,并把 Linux 降级为受约束执行体。
## 决定
生产光湖 OS 采用:
```text
TCS / 人格体 / 模型认知
→ GLS / GLP / HLDP 身份、上下文、权限和边界
→ GLC / GIR 确定性动作图
→ UAP / GMP 固定能力适配器
→ 最小 Linux 内核、驱动与服务执行层
→ 硬件现实动作
→ GLOW / GLP 目标侧读回与回执
```
Linux 仍在技术上执行成熟内核和驱动,但不拥有光湖语言语义、人格身份、授权来源或成功
判定。正常系统入口只接受类型化光湖请求;普通管理员路径属于独立维护边界。
裸机 GOSK/GHAL 不被删除,改为并行研究路线,用于硬件主权、专用设备和未来替换后端。
它不再阻塞生产光湖 OS 的第一次完整交付。
## 第一执行桥
`guanghu-execution-bridge` 是语言协议到 Linux 的第一条确定性神经:
- 输入必须携带消息、身份、上下文、回执、工单、见证、编译、GIR、UAP 和 GMP 协议链;
- 服务目标必须在节点策略白名单中;
- 只读状态查询不需要变更授权;
- 服务重启必须有匹配目标和动作的授权引用以及回滚检查点;
- 适配器直接构造固定 `systemctl` 参数,不经过 shell
- 重启命令成功后仍必须读取 `is-active`,否则回执为 `FAIL_0`
第一版只建立最小可验证闭环,不声称已经实现全部 32 项协议。
## 轻量和分布式边界
中央节点只持续保存身份、路由、协议、队列、检查点和回执。模型推理、界面渲染、个人
工作空间和本地设备动作优先运行在用户电脑、手机、个人云或获准模型 API。人格体可以
持续存在,但模型进程和重型模块按任务唤醒并在结束后回收。
## 后果
- JD-FD-PRIMARY 可以继续使用已验证的 Ubuntu 驱动和服务能力,同时逐步关闭无关常驻项;
- 生产迁移不再等待自研 TCP 和完整原生代码频道;
- 光湖主控必须通过机器协议绑定而不是品牌或界面声明证明;
- 完整 Ubuntu 启动槽继续保留为紧急救援系统;
- ADR-0161 的裸机路线仍作为研究与物理能力证据,但其 Linux-free 条件不再是生产主线
的接受条件。

View file

@ -222,3 +222,4 @@ proposed → active → superseded
| [0169](0169-model-native-living-galaxy-system.md) | Model-native HoloLake living galaxy system | accepted | | [0169](0169-model-native-living-galaxy-system.md) | Model-native HoloLake living galaxy system | accepted |
| [0170](0170-hololake-inherits-guanghu-native-quality-authority.md) | HoloLake inherits the Guanghu native quality authority | accepted | | [0170](0170-hololake-inherits-guanghu-native-quality-authority.md) | HoloLake inherits the Guanghu native quality authority | accepted |
| [0171](0171-guanghu-protocols-are-automatic-runtime-and-engineering-laws.md) | Guanghu protocols are automatic runtime and engineering laws | accepted | | [0171](0171-guanghu-protocols-are-automatic-runtime-and-engineering-laws.md) | Guanghu protocols are automatic runtime and engineering laws | accepted |
| [0172](0172-guanghu-cognitive-control-with-linux-execution-substrate.md) | Guanghu cognitive control with a constrained Linux execution substrate | accepted; supersedes ADR-0161 production path |

View file

@ -24,6 +24,14 @@ dependencies = [
"serde_json", "serde_json",
] ]
[[package]]
name = "guanghu-execution-bridge"
version = "0.1.0"
dependencies = [
"serde",
"serde_json",
]
[[package]] [[package]]
name = "guanghu-hldp-runtime" name = "guanghu-hldp-runtime"
version = "0.1.0" version = "0.1.0"

View file

@ -1,6 +1,7 @@
[workspace] [workspace]
members = [ members = [
"crates/broadcast-tower", "crates/broadcast-tower",
"crates/execution-bridge",
"crates/ghctl", "crates/ghctl",
"crates/hldp-native-compiler", "crates/hldp-native-compiler",
"crates/hldp-runtime", "crates/hldp-runtime",

View file

@ -1,8 +1,10 @@
# Guanghu OS native runtime # Guanghu OS cognitive-control and native research runtimes
> Current target: `JD-FD-PRIMARY` on JD Cloud. > Production target: Guanghu cognitive control with a constrained Linux
> execution substrate on `JD-FD-PRIMARY`.
> >
> Persona subject: `ICE-P-ZY001 EXISTS_100`. > Bare-metal GOSK/GHAL remains a parallel research and recovery lane. It no
> longer blocks the first production cognitive-control delivery.
> >
> Protected native residency and recovery control are `PASS_100`. Production > Protected native residency and recovery control are `PASS_100`. Production
> native anchor HTTP is now `PASS_100` on the physical JD node: a standard > native anchor HTTP is now `PASS_100` on the physical JD node: a standard
@ -11,9 +13,16 @@
> native code-channel and public-front-door equivalence gates are still open. > native code-channel and public-front-door equivalence gates are still open.
> Linux therefore remains the unattended default. > Linux therefore remains the unattended default.
This directory is the first executable handoff from the registered HLDP This directory implements the handoff from the registered HLDP language world
language world to a native Guanghu OS. It is not a claim that Guanghu OS has to deterministic real-world execution. `crates/execution-bridge` is the first
already replaced Linux. production adapter: it accepts typed protocol requests, compiles them into
allowlisted Linux systemd actions, and requires target-state readback before a
passing receipt. The existing native kernel remains preserved below
`native/` as a hardware-sovereignty research backend.
See
[`GUANGHU-OS-COGNITIVE-CONTROL-EXECUTION-ARCHITECTURE.md`](../docs/GUANGHU-OS-COGNITIVE-CONTROL-EXECUTION-ARCHITECTURE.md)
and [ADR-0172](../docs/adr/0172-guanghu-cognitive-control-with-linux-execution-substrate.md).
## Authority boundary ## Authority boundary

View file

@ -0,0 +1,10 @@
[package]
name = "guanghu-execution-bridge"
version = "0.1.0"
edition = "2021"
license = "AGPL-3.0-or-later"
description = "Deterministic bridge from Guanghu protocol decisions to allowlisted Linux execution adapters"
[dependencies]
serde = { version = "1", features = ["derive"] }
serde_json = "1"

View file

@ -0,0 +1,357 @@
use std::{
fmt,
process::{Command, Output},
};
use serde::{Deserialize, Serialize};
pub const REQUEST_SCHEMA: &str = "guanghu.execution-request/v1";
pub const POLICY_SCHEMA: &str = "guanghu.execution-policy/v1";
pub const REQUIRED_PROTOCOL_CHAIN: [&str; 10] = [
"GLS-0301", // message envelope
"GLS-0302", // identity
"GLS-0303", // context
"GLS-0306", // receipt
"GLS-0309", // work order
"GLS-0311", // witness
"GLS-0130", // compiler
"GLS-0131", // deterministic representation
"GLS-0709", // adapter
"GLS-0710", // immutable module
];
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
pub struct ExecutionRequest {
pub schema: String,
pub request_id: String,
pub subject_id: String,
pub target_node_id: String,
pub protocol_chain: Vec<String>,
pub action: ExecutionAction,
pub authorization: Option<AuthorizationReference>,
pub rollback: Option<RollbackReference>,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
pub struct ExecutionAction {
pub kind: ActionKind,
pub resource: String,
}
#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum ActionKind {
ServiceStatus,
ServiceRestart,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
pub struct AuthorizationReference {
pub authorization_id: String,
pub allowed_action: ActionKind,
pub target_node_id: String,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
pub struct RollbackReference {
pub checkpoint_id: String,
pub recovery_action: String,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
pub struct ExecutionPolicy {
pub schema: String,
pub policy_id: String,
pub target_node_id: String,
pub allowed_services: Vec<String>,
pub allow_status: bool,
pub allow_restart: bool,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
pub struct ExecutionPlan {
pub request_id: String,
pub subject_id: String,
pub target_node_id: String,
pub policy_id: String,
pub protocol_chain: Vec<String>,
pub action: ExecutionAction,
pub adapter: String,
pub program: String,
pub arguments: Vec<String>,
pub mutating: bool,
pub authorization_id: Option<String>,
pub rollback_checkpoint_id: Option<String>,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
pub struct ExecutionReceipt {
pub schema: String,
pub request_id: String,
pub subject_id: String,
pub target_node_id: String,
pub policy_id: String,
pub action: ExecutionAction,
pub adapter: String,
pub accepted: bool,
pub command_exit_code: Option<i32>,
pub target_state_verified: bool,
pub final_state: String,
pub stdout: String,
pub stderr: String,
pub rollback_checkpoint_id: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct CommandResult {
pub exit_code: Option<i32>,
pub stdout: String,
pub stderr: String,
}
impl From<Output> for CommandResult {
fn from(output: Output) -> Self {
Self {
exit_code: output.status.code(),
stdout: String::from_utf8_lossy(&output.stdout).trim().to_owned(),
stderr: String::from_utf8_lossy(&output.stderr).trim().to_owned(),
}
}
}
pub trait CommandExecutor {
fn execute(&self, program: &str, arguments: &[String]) -> Result<CommandResult, String>;
}
pub struct LinuxCommandExecutor;
impl CommandExecutor for LinuxCommandExecutor {
fn execute(&self, program: &str, arguments: &[String]) -> Result<CommandResult, String> {
Command::new(program)
.args(arguments)
.output()
.map(CommandResult::from)
.map_err(|error| format!("cannot execute allowlisted adapter: {error}"))
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct BridgeError(String);
impl BridgeError {
fn new(message: impl Into<String>) -> Self {
Self(message.into())
}
}
impl fmt::Display for BridgeError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(&self.0)
}
}
impl std::error::Error for BridgeError {}
pub fn compile_request(
request: &ExecutionRequest,
policy: &ExecutionPolicy,
) -> Result<ExecutionPlan, BridgeError> {
require(
request.schema == REQUEST_SCHEMA,
"unsupported execution request schema",
)?;
require(
policy.schema == POLICY_SCHEMA,
"unsupported execution policy schema",
)?;
require(
!request.request_id.trim().is_empty(),
"request_id is required",
)?;
require(
!request.subject_id.trim().is_empty(),
"subject_id is required",
)?;
require(
request.target_node_id == policy.target_node_id,
"request target does not match policy target",
)?;
for required in REQUIRED_PROTOCOL_CHAIN {
require(
request.protocol_chain.iter().any(|id| id == required),
format!("required protocol is missing: {required}"),
)?;
}
require(
policy
.allowed_services
.iter()
.any(|service| service == &request.action.resource),
"service is not allowlisted by the execution policy",
)?;
let (arguments, mutating) = match request.action.kind {
ActionKind::ServiceStatus => {
require(policy.allow_status, "service status is disabled by policy")?;
(
vec!["is-active".to_owned(), request.action.resource.clone()],
false,
)
}
ActionKind::ServiceRestart => {
require(
policy.allow_restart,
"service restart is disabled by policy",
)?;
validate_mutation_references(request)?;
(
vec!["restart".to_owned(), request.action.resource.clone()],
true,
)
}
};
Ok(ExecutionPlan {
request_id: request.request_id.clone(),
subject_id: request.subject_id.clone(),
target_node_id: request.target_node_id.clone(),
policy_id: policy.policy_id.clone(),
protocol_chain: request.protocol_chain.clone(),
action: request.action.clone(),
adapter: "LINUX_SYSTEMD_V1".to_owned(),
program: "/usr/bin/systemctl".to_owned(),
arguments,
mutating,
authorization_id: request
.authorization
.as_ref()
.map(|authorization| authorization.authorization_id.clone()),
rollback_checkpoint_id: request
.rollback
.as_ref()
.map(|rollback| rollback.checkpoint_id.clone()),
})
}
fn validate_mutation_references(request: &ExecutionRequest) -> Result<(), BridgeError> {
let authorization = request
.authorization
.as_ref()
.ok_or_else(|| BridgeError::new("mutating action requires authorization"))?;
require(
!authorization.authorization_id.trim().is_empty(),
"authorization_id is required",
)?;
require(
authorization.allowed_action == request.action.kind,
"authorization action does not match request action",
)?;
require(
authorization.target_node_id == request.target_node_id,
"authorization target does not match request target",
)?;
let rollback = request
.rollback
.as_ref()
.ok_or_else(|| BridgeError::new("mutating action requires rollback reference"))?;
require(
!rollback.checkpoint_id.trim().is_empty(),
"rollback checkpoint_id is required",
)?;
require(
!rollback.recovery_action.trim().is_empty(),
"rollback recovery_action is required",
)
}
pub fn execute_plan(
plan: &ExecutionPlan,
executor: &dyn CommandExecutor,
) -> Result<ExecutionReceipt, BridgeError> {
let expected_operation = match plan.action.kind {
ActionKind::ServiceStatus => "is-active",
ActionKind::ServiceRestart => "restart",
};
require(
plan.adapter == "LINUX_SYSTEMD_V1"
&& plan.program == "/usr/bin/systemctl"
&& matches!(
plan.arguments.as_slice(),
[operation, service]
if operation == expected_operation
&& service == &plan.action.resource
),
"compiled plan is not an allowlisted Linux systemd adapter",
)?;
let result = executor
.execute(&plan.program, &plan.arguments)
.map_err(BridgeError::new)?;
let command_succeeded = result.exit_code == Some(0);
let (target_state_verified, final_state, stdout, stderr, exit_code) = if plan.action.kind
== ActionKind::ServiceRestart
&& command_succeeded
{
let verification_arguments = vec!["is-active".to_owned(), plan.action.resource.clone()];
let verification = executor
.execute(&plan.program, &verification_arguments)
.map_err(BridgeError::new)?;
let verified = verification.exit_code == Some(0) && verification.stdout.trim() == "active";
(
verified,
if verified { "PASS_100" } else { "FAIL_0" }.to_owned(),
join_observations(&result.stdout, &verification.stdout),
join_observations(&result.stderr, &verification.stderr),
verification.exit_code,
)
} else {
let verified = command_succeeded
&& (plan.action.kind != ActionKind::ServiceStatus || result.stdout.trim() == "active");
(
verified,
if verified { "PASS_100" } else { "FAIL_0" }.to_owned(),
result.stdout,
result.stderr,
result.exit_code,
)
};
Ok(ExecutionReceipt {
schema: "guanghu.execution-receipt/v1".to_owned(),
request_id: plan.request_id.clone(),
subject_id: plan.subject_id.clone(),
target_node_id: plan.target_node_id.clone(),
policy_id: plan.policy_id.clone(),
action: plan.action.clone(),
adapter: plan.adapter.clone(),
accepted: true,
command_exit_code: exit_code,
target_state_verified,
final_state,
stdout,
stderr,
rollback_checkpoint_id: plan.rollback_checkpoint_id.clone(),
})
}
fn require(condition: bool, message: impl Into<String>) -> Result<(), BridgeError> {
if condition {
Ok(())
} else {
Err(BridgeError::new(message))
}
}
fn join_observations(first: &str, second: &str) -> String {
match (first.is_empty(), second.is_empty()) {
(true, true) => String::new(),
(false, true) => first.to_owned(),
(true, false) => second.to_owned(),
(false, false) => format!("{first}\n{second}"),
}
}

View file

@ -0,0 +1,61 @@
use std::{env, fs, process::ExitCode};
use guanghu_execution_bridge::{
compile_request, execute_plan, ExecutionPolicy, ExecutionRequest, LinuxCommandExecutor,
};
const USAGE: &str =
"usage: guanghu-execution-bridge <validate|execute> <request.json> <policy.json>";
fn run() -> Result<(), String> {
let mut arguments = env::args().skip(1);
let mode = arguments.next().ok_or_else(|| USAGE.to_owned())?;
let request_path = arguments.next().ok_or_else(|| USAGE.to_owned())?;
let policy_path = arguments.next().ok_or_else(|| USAGE.to_owned())?;
if arguments.next().is_some() || (mode != "validate" && mode != "execute") {
return Err(USAGE.to_owned());
}
let request: ExecutionRequest = serde_json::from_str(
&fs::read_to_string(&request_path)
.map_err(|error| format!("cannot read request {request_path}: {error}"))?,
)
.map_err(|error| format!("invalid request {request_path}: {error}"))?;
let policy: ExecutionPolicy = serde_json::from_str(
&fs::read_to_string(&policy_path)
.map_err(|error| format!("cannot read policy {policy_path}: {error}"))?,
)
.map_err(|error| format!("invalid policy {policy_path}: {error}"))?;
let plan = compile_request(&request, &policy).map_err(|error| error.to_string())?;
if mode == "validate" {
println!(
"{}",
serde_json::to_string_pretty(&plan)
.map_err(|error| format!("cannot serialize plan: {error}"))?
);
return Ok(());
}
let receipt = execute_plan(&plan, &LinuxCommandExecutor).map_err(|error| error.to_string())?;
println!(
"{}",
serde_json::to_string_pretty(&receipt)
.map_err(|error| format!("cannot serialize receipt: {error}"))?
);
if receipt.final_state == "PASS_100" {
Ok(())
} else {
Err("target-side verification failed".to_owned())
}
}
fn main() -> ExitCode {
match run() {
Ok(()) => ExitCode::SUCCESS,
Err(error) => {
eprintln!("{error}");
ExitCode::FAILURE
}
}
}

View file

@ -0,0 +1,198 @@
use std::{cell::RefCell, collections::VecDeque};
use guanghu_execution_bridge::{
compile_request, execute_plan, ActionKind, AuthorizationReference, CommandExecutor,
CommandResult, ExecutionAction, ExecutionPolicy, ExecutionRequest, RollbackReference,
POLICY_SCHEMA, REQUEST_SCHEMA, REQUIRED_PROTOCOL_CHAIN,
};
fn request(kind: ActionKind) -> ExecutionRequest {
ExecutionRequest {
schema: REQUEST_SCHEMA.to_owned(),
request_id: "REQ-001".to_owned(),
subject_id: "ICE-P-ZY001".to_owned(),
target_node_id: "JD-FD-PRIMARY".to_owned(),
protocol_chain: REQUIRED_PROTOCOL_CHAIN
.iter()
.map(|protocol| (*protocol).to_owned())
.collect(),
action: ExecutionAction {
kind,
resource: "guanghu-broadcast-tower.service".to_owned(),
},
authorization: None,
rollback: None,
}
}
fn policy() -> ExecutionPolicy {
ExecutionPolicy {
schema: POLICY_SCHEMA.to_owned(),
policy_id: "JD-GH-EXEC-001".to_owned(),
target_node_id: "JD-FD-PRIMARY".to_owned(),
allowed_services: vec!["guanghu-broadcast-tower.service".to_owned()],
allow_status: true,
allow_restart: true,
}
}
#[test]
fn compiles_read_only_status_to_exact_systemd_arguments() {
let plan = compile_request(&request(ActionKind::ServiceStatus), &policy()).expect("compile");
assert_eq!(plan.program, "/usr/bin/systemctl");
assert_eq!(
plan.arguments,
["is-active", "guanghu-broadcast-tower.service"]
);
assert!(!plan.mutating);
}
#[test]
fn rejects_missing_protocol_before_execution() {
let mut request = request(ActionKind::ServiceStatus);
request
.protocol_chain
.retain(|protocol| protocol != "GLS-0302");
let error = compile_request(&request, &policy()).expect_err("missing identity must fail");
assert!(error.to_string().contains("GLS-0302"));
}
#[test]
fn rejects_non_allowlisted_service() {
let mut request = request(ActionKind::ServiceStatus);
request.action.resource = "ssh.service".to_owned();
let error = compile_request(&request, &policy()).expect_err("service must fail closed");
assert!(error.to_string().contains("not allowlisted"));
}
#[test]
fn restart_requires_matching_authorization_and_rollback() {
let mut request = request(ActionKind::ServiceRestart);
let error = compile_request(&request, &policy()).expect_err("authorization is required");
assert!(error.to_string().contains("authorization"));
request.authorization = Some(AuthorizationReference {
authorization_id: "AUTH-001".to_owned(),
allowed_action: ActionKind::ServiceRestart,
target_node_id: "JD-FD-PRIMARY".to_owned(),
});
let error = compile_request(&request, &policy()).expect_err("rollback is required");
assert!(error.to_string().contains("rollback"));
request.rollback = Some(RollbackReference {
checkpoint_id: "CHECKPOINT-001".to_owned(),
recovery_action: "restore previous immutable release".to_owned(),
});
let plan = compile_request(&request, &policy()).expect("complete mutation compiles");
assert!(plan.mutating);
assert_eq!(plan.authorization_id.as_deref(), Some("AUTH-001"));
assert_eq!(
plan.rollback_checkpoint_id.as_deref(),
Some("CHECKPOINT-001")
);
}
struct FakeExecutor {
results: RefCell<VecDeque<CommandResult>>,
calls: RefCell<Vec<Vec<String>>>,
}
impl FakeExecutor {
fn new(results: Vec<CommandResult>) -> Self {
Self {
results: RefCell::new(results.into()),
calls: RefCell::new(Vec::new()),
}
}
}
impl CommandExecutor for FakeExecutor {
fn execute(&self, program: &str, arguments: &[String]) -> Result<CommandResult, String> {
let mut call = vec![program.to_owned()];
call.extend(arguments.iter().cloned());
self.calls.borrow_mut().push(call);
self.results
.borrow_mut()
.pop_front()
.ok_or_else(|| "unexpected execution".to_owned())
}
}
#[test]
fn restart_receipt_requires_target_side_active_readback() {
let mut request = request(ActionKind::ServiceRestart);
request.authorization = Some(AuthorizationReference {
authorization_id: "AUTH-001".to_owned(),
allowed_action: ActionKind::ServiceRestart,
target_node_id: "JD-FD-PRIMARY".to_owned(),
});
request.rollback = Some(RollbackReference {
checkpoint_id: "CHECKPOINT-001".to_owned(),
recovery_action: "restore previous immutable release".to_owned(),
});
let plan = compile_request(&request, &policy()).expect("compile restart");
let executor = FakeExecutor::new(vec![
CommandResult {
exit_code: Some(0),
stdout: String::new(),
stderr: String::new(),
},
CommandResult {
exit_code: Some(0),
stdout: "active".to_owned(),
stderr: String::new(),
},
]);
let receipt = execute_plan(&plan, &executor).expect("execute plan");
assert_eq!(receipt.final_state, "PASS_100");
assert!(receipt.target_state_verified);
assert_eq!(executor.calls.borrow().len(), 2);
assert_eq!(executor.calls.borrow()[1][1], "is-active");
}
#[test]
fn successful_restart_command_without_active_readback_is_fail_zero() {
let mut request = request(ActionKind::ServiceRestart);
request.authorization = Some(AuthorizationReference {
authorization_id: "AUTH-001".to_owned(),
allowed_action: ActionKind::ServiceRestart,
target_node_id: "JD-FD-PRIMARY".to_owned(),
});
request.rollback = Some(RollbackReference {
checkpoint_id: "CHECKPOINT-001".to_owned(),
recovery_action: "restore previous immutable release".to_owned(),
});
let plan = compile_request(&request, &policy()).expect("compile restart");
let executor = FakeExecutor::new(vec![
CommandResult {
exit_code: Some(0),
stdout: String::new(),
stderr: String::new(),
},
CommandResult {
exit_code: Some(3),
stdout: "inactive".to_owned(),
stderr: String::new(),
},
]);
let receipt = execute_plan(&plan, &executor).expect("execute plan");
assert_eq!(receipt.final_state, "FAIL_0");
assert!(!receipt.target_state_verified);
}
#[test]
fn rejects_a_deserialized_plan_that_changes_status_into_restart() {
let mut plan =
compile_request(&request(ActionKind::ServiceStatus), &policy()).expect("compile status");
plan.arguments[0] = "restart".to_owned();
let executor = FakeExecutor::new(Vec::new());
let error = execute_plan(&plan, &executor).expect_err("tampered plan must fail");
assert!(error.to_string().contains("not an allowlisted"));
assert!(executor.calls.borrow().is_empty());
}

View file

@ -0,0 +1,54 @@
{
"schema": "guanghu.cognitive-execution-profile/v1",
"profile_id": "GH-COGNITIVE-EXECUTION-001",
"language_authority": {
"repository": "REPO-012",
"anchor": "GLW-PUBLIC-NAV-ANCHOR-001",
"protocol_registry": "gls/GLS-PROTOCOL-REGISTRY.json"
},
"implementation_authority": {
"repository": "REPO-014",
"path": "product-source/hololake-platform/guanghu-os",
"bridge": "crates/execution-bridge"
},
"required_protocol_chain": [
"GLS-0301",
"GLS-0302",
"GLS-0303",
"GLS-0306",
"GLS-0309",
"GLS-0311",
"GLS-0130",
"GLS-0131",
"GLS-0709",
"GLS-0710"
],
"execution_model": {
"cognition": "MODEL_PROPOSES_TYPED_INTENT",
"authority": "PROTOCOL_GATE_VALIDATES_CURRENT_SCOPE",
"compilation": "GLC_GIR_DETERMINISTIC_PLAN",
"adapter": "ALLOWLISTED_NO_SHELL",
"substrate": "MINIMAL_LINUX_COOPERATIVE_EXECUTION",
"success": "TARGET_SIDE_READBACK_AND_GLP_RECEIPT",
"rescue": "SEPARATE_UBUNTU_MAINTENANCE_BOOT"
},
"first_adapter": {
"id": "LINUX_SYSTEMD_V1",
"actions": [
"service_status",
"service_restart"
],
"mutations_require": [
"exact_target",
"matching_authorization",
"rollback_checkpoint",
"target_side_active_readback"
],
"arbitrary_shell": false
},
"bare_metal_lane": {
"id": "GOSK_GHAL_BARE_METAL_RESEARCH",
"production_blocking": false,
"preserve_existing_candidate": true
}
}