feat-chv-muse-p9: 推理与遥测受限通道(Sentinel 预审 + 遥测最小化 + 训练退出开关)

- 受限推理通道:cloud/chv/inference_channel.py(origin 解析、
  allowlist、上限、Sentinel 预审),执行器 _run_with_vm 起 VM 前
  必过 _inference_gate(allow 才继续,deny/ask 审计 + fail-closed,
  任务级 extra_env 合并进预审);host.py 第二道防线(_server_command
  的 origin 结构校验 + Server.request 超时/重试走 env)。
  origin 规则:https 公网网关(只 443);http 只接受本地中继
  (字面环回/私网 IP,如 http://172.17.0.1:28084,端口保留,
  无 DNS、无重绑定,allowlist 与单次能力照常);未知 provider
  标签走默认网关(与 _server_command 一致)。
- sentinel.py:从 P5(25bcd35)取的超集版本 + 推理连接器条目
  (POST /v1/responses、GET /v1/models;scheme/端口只 https/443,
  本地中继不走 evaluate,不把 http 加进表)。
- 遥测最小化:cloud/chv/telemetry.py(字段白名单、确定性采样、
  落盘失败不影响任务、token 未回传记 null)+ 训练退出开关
  (默认开,本项目决定;关后轨迹不再产生;损坏 fail-closed;变更审计)。
- 访问边界:docs/chv-access-boundary.md(运营访问口径 + 审计钩子,
  不冒充技术不可访问;Confidential VM 明确未做)。
- 测试:cloud/tests/test_chv_muse_p9.py 51 组全过;5 个旧文件
  的 make_exec 配假 origin + 假解析器(新 fail-closed 门要求的
  测试配置);全量 cloud 套件 1918 OK(skipped=8)。
  详见 docs/chv-muse-p9-gap.md(含自定清单与真机待验证清单)。
This commit is contained in:
host committed 2026-11-06 23:03:06 +00:00
1 parent 06c3e172fe
commit c06ba50983
13 files changed
+1922 -11

No files matched your search

+12 -1
View File
@@ -73,6 +73,12 @@ def _write(path, content=b"x"):
return path
def _public_resolver(host, port):
"""feat-chv-muse-p9:假解析器(公网 IP),供推理出口预审用;
实验室绝不联网,真实解析只在真机发生。"""
return ["93.184.216.34"]
class ChvCase(unittest.TestCase):
def setUp(self):
self.tmp = tempfile.TemporaryDirectory()
@@ -106,7 +112,11 @@ class ChvCase(unittest.TestCase):
# genisoimage,测的不是 host key 模式,故显式
# 声明实验室路径,绝不把它写成生产默认。
"CHV_HOST_KEY_MODE": "keyscan",
"CHV_SSH_FORWARD": "1"}
"CHV_SSH_FORWARD": "1",
# feat-chv-muse-p9:推理出口预审的假 origin(公网
# https,配假解析器;实验室不起真 VM、不联网)。
"SUB2API_BASE_URL": "https://xgapi.lol",
"CHV_INFERENCE_ORIGIN": "https://xgapi.lol"}
if env_extra:
env.update(env_extra)
if runner is None:
@@ -124,6 +134,7 @@ class ChvCase(unittest.TestCase):
sleeper=lambda s: None, env=env)
kwargs.update(overrides)
ex = CloudHypervisorExecutor(**kwargs)
ex.sentinel_resolver = _public_resolver
ex.audit_callback = lambda e, t, d, k=None: self.audit.append(
(e, t.get("id") if isinstance(t, dict) else t, d, k))
return ex