Merge feat-chv-muse-p9: inference/telemetry restricted channel

- executor.py: P9 _inference_gate inserted before P1 dispatcher
  _run_with_vm; gate call is the first statement, so deny/ask
  fail-closed before any resident resume or cold wake. P9's own
  _run_with_vm (old-body variant) dropped: its body is byte-identical
  to P1 _run_cold (verbatim move), kept once in _run_cold.
- sentinel.py: P9 superset version wins (P5 base + inference entries
  POST /v1/responses, GET /v1/models + comments).
- inference_channel.py / telemetry.py / host.py: P9 as-is.
- Tests: P9 51 + closeup/gaps/optimize/cloud_hypervisor/fix 272 OK.
- mypy on changed files: P9's 5 cross-track errors gone (P5
  capabilities.py now in tree); remaining 4 are 06c3e17 baseline
  legacy (marker_tools.py:142, executor.py:1573/1578), untouched.
This commit is contained in:
host committed 2026-11-07 00:09:26 +00:00
commit 90c42f6e1d
13 files changed
+1455 -15

No files matched your search

+53 -1
View File
@@ -2727,6 +2727,54 @@ class CloudHypervisorExecutor(Executor):
except Exception:
pass
def _inference_gate(self, task: dict,
model_provider: str | None,
extra_env: dict | None = None) -> None:
"""feat-chv-muse-p9:起 VM 前的推理出口预审。
模型调用只允许走受限推理通道(见 inference_channel):
allow → 审计放行;deny/ask → 审计 + ChvFailure 起 VMM
前 fail-closed(ask 在这里就是 deny:wake 等不了审批
UI)。解析器可注入(`sentinel_resolver` 属性,测试用
假解析器)。origin 取任务级 extra_env 覆盖执行器 env;
origin 非法同样记 deny,不抛裸 ValueError。审计 detail
只含 VM 名/主机/verdict,不含任何凭证值。
"""
from cloud.chv.inference_channel import check_inference_call
name = self.vm_name(task)
env = dict(self._env)
if extra_env:
env.update(extra_env)
try:
check = check_inference_call(
model_provider, env=env,
resolve=getattr(self, "sentinel_resolver", None))
except ValueError as exc:
self._emit("inference_egress_deny", task,
"vm=%s reasons=bad_origin" % name)
raise ChvFailure(
"inference_egress_denied",
"推理 origin 配置非法,拒绝启动:%s" % exc)
decision = check.decision
if decision.verdict == "allow":
capability = decision.capability
request = check.request
assert capability is not None # allow 恒带严格能力
assert request is not None # allow 恒带已解析请求
self._emit("inference_egress_allow", task,
"vm=%s host=%s capability=%s"
% (name, request.host, capability.id))
return
host = check.request.host if check.request is not None else ""
self._emit("inference_egress_" + decision.verdict, task,
"vm=%s host=%s reasons=%s"
% (name, host, ",".join(decision.reasons)))
raise ChvFailure(
"inference_egress_denied",
"推理出口预审未通过(%s),拒绝启动:请运维确认 "
"provider 与 CHV_INFERENCE_ORIGIN/CHV_INFERENCE_ALLOW_HOSTS"
% decision.verdict)
def _run_with_vm(self, task, inner_args, goal=False, extra_env=None,
**kwargs):
"""任务 VM 生命周期(feat-chv-muse-p1,见 ADR-17):
@@ -2740,7 +2788,11 @@ class CloudHypervisorExecutor(Executor):
重试(重试是 worker 的 max_retries 语义)。中途死亡
判 interrupted(断点可续跑),见 _run_cold 与
_run_on_resident。dispatch/run/goal/goal_resume/断点
续跑都走本方法,签名不动。"""
续跑都走本方法,签名不动。round-12 合入 P9:起任何 VM
(常驻 resume 或冷启动 wake)之前先过 _inference_gate
推理出口预审,deny/ask 即 fail-closed。"""
self._inference_gate(task, kwargs.get("model_provider"),
extra_env=extra_env)
resident = self._resident_acquire(task, extra_env=extra_env)
if resident is not None:
pool = resident["pool"]