feat(chv): 对齐 Muse P6 privsep worker + 确定性安全检查层
- cloud/chv/privsep.py(新):Gitea worker 注册表(凭证白名单只含 GITEA_TOKEN)+ 类型化请求/响应(request_id 绑定、64KB 上限)+ Unix socket 客户端(超时/崩溃 -> 类型化失败 WorkerRefusal)+ 客户端白名单校验 - cloud/chv/safety.py(新):UntrustedData 来源标记 + InjectionScanner 确定性规则(block/flag/allow,中英)+ redact_secrets + AuditLogger(只记指纹,不记值)+ audit_inference_request/response - chv-guest/chv-gitea-worker.py + .service(新):systemd 沙箱化 worker(SO_PEERCRED 只放 root,仓限 ~/workspace,git 只配 authd helper,绝不持 token;输出先扫描再返回) - chv-guest/chv-sync-worker-client.py(新):agent 侧薄 CLI - chv-guest/chv-sync.sh:pull/push/status 有 socket 时走 worker, 否则旧路径 + stderr 警告(过渡兼容) - cloud/chv/executor.py:_run_guest 前后加推理边界审计钩子 (best-effort) - docs/chv-muse-p6-gap.md(新):差距表 + 覆盖边界 + 真机待验证清单 - docs/chv-production-readiness.md:§15 - cloud/tests/test_chv_muse_p6.py(新):43 项 测试:新测试 43/43;全量 cloud 套件 1910 OK(skipped=9);mypy 在新增文件上干净(剩余 4 处为基线旧错 executor.py:1396/1401、 marker_tools.py:142,未动)。 真机验证:未做,排队在 round-11 之后,清单见 docs/chv-muse-p6-gap.md §4。
This commit is contained in:
1 parent
06c3e172fe
commit
81e4eaf4db
10 files changed
+2071
No files matched your search
@@ -0,0 +1,87 @@
|
||||
#!/usr/bin/env python3
|
||||
"""chv-sync-worker-client:Gitea worker 薄客户端(feat-chv-muse-p6)。
|
||||
|
||||
agent 侧(broker / chv-sync)只剩薄 CLI:解析参数、发类型化 JSON
|
||||
请求到 worker socket、原样回显 worker 的 stdout/stderr、按 worker
|
||||
的 returncode 退出。本进程不跑 git、不碰凭证、不做业务逻辑。
|
||||
|
||||
用法:chv-sync-worker-client <pull|push|status|ping> [仓目录]
|
||||
仓目录省略时由 worker 侧取唯一仓(与 chv-sync 同款语义,由 worker
|
||||
的 repo=None 处理——本客户端只透传,不自己解析)。
|
||||
只用标准库。
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import socket
|
||||
import sys
|
||||
import time
|
||||
|
||||
DEFAULT_SOCKET_PATH = "/run/chv-gitea/worker.sock"
|
||||
|
||||
|
||||
def _exchange(sock_path, request):
|
||||
"""连 worker、发请求、收一帧回包。
|
||||
返回 (resp_dict, error_str),成功时 error_str 为 None。"""
|
||||
try:
|
||||
conn = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
conn.settimeout(310)
|
||||
conn.connect(sock_path)
|
||||
except OSError as exc:
|
||||
return None, "worker 连不上:%s" % exc
|
||||
try:
|
||||
conn.sendall((json.dumps(request) + "\n").encode("utf-8"))
|
||||
data = b""
|
||||
while len(data) < 65536:
|
||||
chunk = conn.recv(4096)
|
||||
if not chunk:
|
||||
break
|
||||
data += chunk
|
||||
if data.endswith(b"\n"):
|
||||
break
|
||||
except OSError as exc:
|
||||
return None, "worker 通信失败:%s" % exc
|
||||
finally:
|
||||
conn.close()
|
||||
try:
|
||||
resp = json.loads(data.decode("utf-8"))
|
||||
except (ValueError, UnicodeDecodeError):
|
||||
return None, "worker 回包不是 JSON"
|
||||
if not isinstance(resp, dict) or "ok" not in resp:
|
||||
return None, "worker 回包格式不对"
|
||||
return resp, None
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
"""发一次类型化请求并回显。返回 worker 的 returncode;
|
||||
通信失败即 exit 2(调用方按失败处理,不静默成功)。"""
|
||||
args = list(argv if argv is not None else sys.argv[1:])
|
||||
if not args or args[0] not in ("pull", "push", "status", "ping"):
|
||||
print("用法:chv-sync-worker-client "
|
||||
"pull|push|status|ping [仓目录]", file=sys.stderr)
|
||||
return 2
|
||||
op = args[0]
|
||||
repo = args[1] if len(args) > 1 and args[1] else None
|
||||
sock_path = os.environ.get("CHV_GITEA_WORKER_SOCK",
|
||||
DEFAULT_SOCKET_PATH)
|
||||
request = {"op": op, "connector": "gitea", "repo": repo,
|
||||
"request_id": "cli-%d" % int(time.time() * 1000)}
|
||||
resp, err = _exchange(sock_path, request)
|
||||
if err is not None:
|
||||
print("chv-sync-worker-client: %s" % err, file=sys.stderr)
|
||||
return 2
|
||||
if resp.get("stdout"):
|
||||
sys.stdout.write(resp["stdout"])
|
||||
if resp.get("stderr"):
|
||||
sys.stderr.write(resp["stderr"])
|
||||
if resp.get("error"):
|
||||
print("chv-sync-worker-client: %s" % resp["error"],
|
||||
file=sys.stderr)
|
||||
if resp.get("safety", {}).get("verdict") == "flag":
|
||||
print("chv-sync-worker-client: 输出已标记复核:%s"
|
||||
% resp["safety"], file=sys.stderr)
|
||||
return int(resp.get("returncode") or (0 if resp["ok"] else 1))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in new issue
Block a user