host
466cf7eae7
merge(chv-muse-round12): 合入 P12 审计轨迹与活动视图 ( 9759be4)
2026-11-07 00:10:34 +00:00
host
77743e734d
merge(chv-muse-round12): 合入 P11 用量计量与配额 ( 60c371d)
...
- 冲突仅一处:docs/chv-production-readiness.md §15 撞号——
P11 节顺延为 §19(§15 P2 / §16 P4 / §17 P6 / §18 P7
保持不动),节内无自引 §15,无内容改动。
- P11 未决冲突原样保留(见 docs/chv-muse-p11-gap.md §5):
档位门只做准入、USD 路径不动,等待用户裁决,不悄悄统一。
- 测试:test_usage_quota 22/22 OK。
2026-11-07 00:10:32 +00:00
host
b55b49b358
feat(chv): 对齐 Muse P10 支付安全——凭证隔离 + 结账检测 + 每次购买人工审批 + 一次性卡号
...
- 支付凭证隔离:PaymentCredentialVault(只活内存、白名单
stripe-link/shop-pay、只存不透明 id + 掩码标签、原始卡号
PAN 拒绝入库、按次释放绑定商家/金额/货币、单次 + TTL)
- 结账页检测:detect_checkout(URL + 无障碍树信号,确定性
规则、不读原始 DOM、与 P4 detect_form_risk 同输入形状)
- 每次购买人工审批:PaymentGate 经 P5 对话外通道发审批,
payload 含确切购买详情;完成时先验签、再验详情摘要
(篡改即拒且审批保持待处理)、最后单次消费答复
- 一次性卡号:OneTimeCard 绑定商家/金额/货币/有效期,单次
兑现;SimulatedWalletBackend 沙箱钱包(假 PAN 只在后端
私有内存、charge 只记账不联网、取消即 void)
- 限额:SpendLimits 三档 minor units 比对,限额不可用时
不编造上限(limits_checked=False)
- 审计:PaymentAudit 只留允许字段,秘密字段名丢弃 + redacted
- 审批通道最小扩展:ApprovalRequest 增加可选 details 字段,
不传时 payload 与 P5 完全一致
- 真实支付与扣款不做:全部沙箱验证,真实钱包集成待用户
另行批准;新测试 79 项,全量 cloud 套件 2037 OK
round-12 集成说明:本提交为 acf98f8 的 cherry-pick(只含 P10
自有 diff,基线 25bcd35 已含的 P3/P5 内容未重复合入;
approval_channel.py 仅加可选 details 字段)。
2026-11-07 00:09:55 +00:00
host
90c42f6e1d
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.
2026-11-07 00:09:26 +00:00
host
240949e444
merge(chv-muse-round12): 合入 P8 后台工作 ( 8d4771b)
2026-11-07 00:03:00 +00:00
host
320cd36921
merge(chv-muse-round12): 合入 P7 状态与记忆分离 ( 29fa0c8)
...
冲突按并集解:build.sh 保留 P2+P3+P4 检查/拷入 + P7 的
chv-memory 检查/拷入(P7 的重复 runcmd 行删掉——同一文件
写两次会盖掉 authd 启动行);buildinfo.py 加 chv-memory 一项;
production-readiness.md P7 一节顺延为 §18。P7 测试 46 项全过。
2026-11-07 00:02:54 +00:00
host
b0b9f5ed9d
merge(chv-muse-round12): 合入 P6 privsep worker + 确定性安全检查层 ( 81e4eaf)
...
唯一冲突是文档 §15 撞号:P6 一节顺延为 §17,基线说明更新
(P3 已在树里,接线走真实代码)。chv-sync.sh 自动合入正确:
P6 的 worker 路径与 P3 的 authd 路径(useHttpPath)都在。
P6 测试 43 项全过(skipped=1 是 root 下 uid 否定测试)。
2026-11-07 00:02:22 +00:00
host
d1c9a8e647
merge(chv-muse-round12): 合入 P5 Sentinel 纵深 ( 25bcd35)
2026-11-07 00:01:39 +00:00
host
c24cc0ba92
merge(chv-muse-round12): 合入 P4 浏览器完全对齐 ( 1c8fc3f)
...
冲突按并集解:build.sh 保留 P3 authd 检查/拷入/runcmd(含
start chv-authd)+ P4 三件套检查/拷入(P4 的重复 runcmd 行
删掉——同一文件写两次会盖掉 authd 启动行)+ P4 的
cdp-broker.service/tmpfiles(含 ask-queue)+ P3 叶子模块条件
拷入;buildinfo.py 两边内容项并集;chv-browser.py 取 P4 重构
版(broker 客户端);production-readiness.md P4 的 §15 顺延为
§16。P2 的 BrowserTest 改走假 CDP broker(断言不变),两路
干跑夹具补齐并集文件集。
2026-11-07 00:01:35 +00:00
chv
29d3a5a474
feat(chv-muse-round11): build.sh 补 P3 authd 进镜像 + gt 脚本哈希轮换
...
- authd 三件套 copy-in(chv-guest/authd.py 与 git-credential-chv-authd
-> /usr/local/bin/ 并 chmod +x,chv-authd.service ->
/etc/systemd/system/),云端叶子模块 cloud/chv/authd.py 与
sentinel.py + 两个 __init__.py -> /usr/local/lib/chv-authd/,
systemctl enable chv-authd;99-chv-sync.cfg runcmd 在 chv-sync
boot 之前加 systemctl start chv-authd;缺件即 fail-fast
- buildinfo BASE_CONTENTS 登记新增件;P2 干跑夹具补 P3 文件并断言
authd 步骤出现在干跑输出里
- GT_INSTALL_SH_SHA256 cf82... -> 49ffe090...:上游 2026-11-07
06:44 轮换,V-9 已核实(WSL fresh curl 与失败镜像内残留逐字节
一致;新脚本全文已读,只从 dl.gitea.com 取 1.0.0 二进制并验 hash)
- vsock_notify 条件拷入在合入后生效(cloud/chv/guest/vsock_notify.py
已在仓里,干跑不再报缺失警告)
- 定向单测 P1/P2/P3/chv_fix 172 项全过;全量套件仍在跑
2026-11-06 23:08:40 +00:00
host
c06ba50983
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(含自定清单与真机待验证清单)。
2026-11-06 23:03:06 +00:00
host
8d4771bce3
feat(chv): align Muse P8 background work (crons/swarm/presentation/per-task browser)
...
- crons: pause/resume, exponential-backoff retry (cap 1h), retry claim
single-winner reusing quota+task build, run_cron_tick cap 5/project
- swarm: per-agent task id + isolated workspace (resolve_inside gate),
tool register + invocation audit (no execution in swarm layer)
- presentation: worth-presenting rules (needs_input/failed/new
content only) + notification ledger dedup 1h per (task, reason)
- browser_tasks: one BrowserTransport instance per browser task,
single-use (reuse after destroy refused), shots dir per instance
- automations: paused status + retry columns (max_retries,
retry_backoff_seconds, consecutive_failures, next_retry_at)
- gap table docs/chv-muse-p8-gap.md; self-defined values listed there
(not Meta official): tick cap 5, swarm max 32/default 8, retry
base 60s cap 3600s, ledger window 3600s, snapshot trunc 200/64KB
- tests: 49 new in cloud/tests/test_chv_muse_p8.py (incl. negatives:
cron unauthorized trigger, cross-workspace access, no-content
silence, dedup); full cloud suite 1916 OK (skipped=8)
2026-11-06 22:42:31 +00:00
host
60c371d9d5
feat(chv): 对齐 Muse P11 用量计量与配额执行——四项计量 + 三档档位门 + 哈希链账本
...
- cloud/usage.py(新):TIER_LIMITS 三档提案(Free $0/Paid $19/Heavy $99,
提案非定价,payload 带 proposal 标注)、TierStore(无档位行不受档位门
约束)、UsageLedger(追加写哈希链,篡改可发现)、UsageMeter(token 读
cost_records、消息读账本、并发/存储注入实测)、QuotaGate(纯准入判定,
402,不碰在跑任务)、80% 提醒每维度每窗口一次
- cloud/server.py:_reject_if_over_quota 内加档位门(同一漏斗,双人门
自动覆盖;查询异常 fail-closed 503)、GET /users/me/usage、
GET/POST /admin/tiers、存储实测复用 _task_worktree_for_files
- docs/chv-muse-p11-gap.md:差距表(先写表再动手)+ 诚实边界(USD 路径
30 秒轮询掐断与“不掐断”语义不一致是已知待决;并发即拒与设计文档
排队不同;cloud 任务存储量不到;Heavy 消息/天提案未给,本轨定不限)
- 测试 22/22,全量 1889 OK(skipped=8);mypy 在 usage.py 上干净,
server.py 5 错均为基线旧错(marker_tools/sub2api/_row_get,与本轨无关)
- 真机验证排队在 round-11 与 P4~P9 之后;不接真实计费
2026-11-06 22:42:30 +00:00
host
29fa0c8813
feat(chv): 对齐 Muse P7——状态与记忆分离
...
- 每 VM 一个 SQLite 状态库(cloud/chv/app_state.py):
state_dir/<vm>/app-state.sqlite(0600,WAL),表 tasks/goals/
sessions/audit(只追加)/meta;写操作过无凭证守卫(键名 +
值模式);备份用 sqlite3 在线备份 + manifest(sha256),恢复
先验 manifest、先留 pre-restore 副本;DDL 用 SQLite 与
Postgres 共通受限子集,换 Postgres = 换连接工厂。
- 记忆文件接线(cloud/chv/memory_files.py):宿主镜像读/列/
写/追加(路径穿越守卫、写审计);MemorySystemClient 调真实
记忆系统 CLI(search/get/explain/forget-plan/forget-confirm/
backup/restore/export),不重造引擎;forget = plan → confirm
→ 本地清行 → search 验证查不到;pull_memory_home 经 SSH +
tar 拉取客机记忆家目录。
- 客内脚本 chv-guest/chv-memory.py(纯标准库,list/read/
append/forget/export),家目录 /home/chv/memory(workspace
之外,不同步到 Gitea);build.sh 拷入 + buildinfo 登记。
- 新测试 cloud/tests/test_chv_muse_p7.py 46 项全过(含真 CLI
write/search/forget/backup/restore 实测、假 ssh 拉取、否定
测试);全量 cloud 套件 1913 项 OK(skipped=8)。
- 存储选型:SQLite 不是 Postgres(见差距表 §4;轻量 VM 跑
Postgres server 太重,宿主共享 Postgres 破坏每用户 VM
隔离);忘记是尽力删除 + 验证,不是密码学擦除。
- 真机待验证(未做,等测试机空闲):见
docs/chv-muse-p7-gap.md §6 清单
2026-11-06 22:39:04 +00:00
host
9759be47bb
feat(chv): 对齐 Muse P12——审计轨迹与活动视图
...
统一审计记录模型(时间/主体/动作/对象/结果/原因/关联任务/
关联审批)+ 追加写 JSONL + SHA-256 哈希链(改写/删除/调序可
被 verify 发现)+ 字段级白名单清洗(密钥/token 值/对话原文
绝不进审计);事件分类覆盖任务派发、VM 生命周期、同步、审批、
支付、配额、记忆、后台、推理/遥测;from_legacy_row 承接现有
audit_log 行;导出选 JSON。
活动视图后端:计划登记(已做 vs 计划做,流转受控)+ 已批准
权限登记(接 P5 describe 形状)+ activity_summary 纯函数;
结构化审批卡数据(风险分级 + 接受/拒绝明确动作 + 五档授权
选项,永久档须显式 opt-in)+ card_matches_channel 校验卡与
P5 通道载荷一致。
只做后端 + 数据接口,前端视图留接口;P3/P5 不在本基线,
接线走 dict 契约,集成由 round-11 合并;审计持久化先落独立
JSONL,待 P7 状态库就绪后迁移。真机验证排队在 round-11 之后。
新测试 43/43,全量 cloud 套件 1910 OK(skipped=8);
mypy 在改动文件上干净。
2026-11-06 22:38:19 +00:00
host
1c8fc3f7c8
对齐 Muse P4:浏览器完全对齐(CDP broker 单元外 + a11y-tree-only + 确定性分类器)
...
- chv-guest/chv-cdp-broker.py(新):单元外 CDP broker,用户 chv-browser,
独家 chromium.launch(headless=True, args=LAUNCH_ARGS);启动参数白名单
无 --remote-debugging-port、无 devtools;导航前 URL 校验 + 拦截名单;
快照恒带 untrusted_input 与 injection_flags;高风险表单在页时 open
即 ask 入队;观测到导航 POST 自动暂停;命中拦截规则的下载取消 + 暂停
+ ask;全部回包与错误经 sanitize_error + response_leaks 检查。
- chv-guest/chv-browser.py(P2 版重构):改为 broker 客户端,不再直连
Playwright(本文件无 playwright import),保留 URL 校验 + 快照截断
作为第二层防线;暂停状态与 broker 同步。
- chv-guest/chv_browser_guard.py(新):纯 stdlib 共享规则——validate_url、
拦截名单加载/匹配、快照截断、错误消毒(去 HTML、截断 200 字符、凭据形
key=value 与 sk- 形 token 打码)、注入启发式(中英文各 6 条)、表单风险
扫描、下载扫描(可执行扩展名)、文件型 ask 队列(pending/allowed/denied,
与 P3 ApprovalQueue 同语义)、启动参数与回包泄露检查、脚本注入面
禁止清单(FORBIDDEN_PAGE_ATTRS/FORBIDDEN_OPS)。
- chv-guest/browser-blocklist.txt(新):静态拦截名单;首版只有 RFC 2606
.test 自测条目,生产条目由运维构建时填入,无在线更新。
- chv-guest/build.sh/buildinfo.py:P2 三脚本 + P4 三文件纳入镜像与
buildinfo;新增 chv-cdp-broker.service 与 /run/chv/ask-queue tmpfiles。
- docs/chv-muse-p4-gap.md(新):现状 vs Muse 官方要求差距表、改动、
诚实边界、P2 合入约定、真机待验证清单(round 12)。
- docs/chv-production-readiness.md:补 §15(P4 一节;编号合入时若与
P2 的 §15 撞,顺延)。
- cloud/tests/test_chv_muse_p4.py(新,36 项):guard 单元、AST 钉住
禁止属性、假 Playwright broker 测试、假 broker agent 测试、真 Unix
socket 联调、buildinfo/build 干跑断言;含否定测试(evaluate 被拒、
DOM 外泄被拒、DevTools 不可达、私有地址被拒、高风险表单被拦、
注入文本被标注)。
测试:P4 新测试 36/36;全量 cloud 套件 1903 项,两次连续全过
(skipped=8)。附记:第一次全量跑出 1 个失败但输出未保留、后两次
均未复现,疑为时序抖动,未追认。
真机验证未做:排队等 round-11/第三棒释放 100.65.51.33,清单见 gap
表 §5。本地提交,未推未合未部署。
2026-11-06 22:36:56 +00:00
host
81e4eaf4db
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。
2026-11-06 22:31:54 +00:00
host
25bcd355f8
feat(chv): 对齐 Muse P5 纵深——eBPF 污点传播 + 五档严格能力 + 对话外审批 + 默认策略
...
- taint.py:污点追踪器(登记/污点不可逆/子进程继承/审计)
- ebpf_taint.py:eBPF 程序源码 + 加载器(能力探测 + 降级);
本机实测加载被 seccomp 挡(bpf() EPERM),报 blocked 不冒充
- capabilities.py:五档严格能力(一次/会话/任务/时限/永久,
三元组绑定 + 精确匹配 + 撤销;permanent 默认不签发)
- policy.py:默认策略规则表 + 谨慎度三档(写操作与敏感路径
永远不自动放行,规则变化审计)
- approval_channel.py:对话外审批通道(nonce + 15 分钟过期 +
HMAC,答复一次有效,对话伪造无效)
- sentinel.py 接线:evaluate() 可选接 taint/policy/tier/scope,
不传时行为与 P3 一致;自动放行步骤 + 档位签发回落单次;
Capability 基类属性放宽为 Optional(None = 不限)
- 新测试 61 项;全量 cloud 套件 1958 项 OK(skipped=8)
真机待验证(未做,排队在 round-11 之后):见
docs/chv-muse-p5-gap.md §4
2026-11-06 22:25:55 +00:00
host
ee456e6625
merge(feat-chv-muse-p3): P5 起点——authd 替身凭证 + Sentinel 最小实现
2026-11-06 22:06:23 +00:00
host
73176e135c
feat(chv-muse-round11): 执行器接 nspawn 单元(P2 差距表 §4)
...
客内 host.py 调用改为 chv-cell run -- python3 /app/host.py
--state /home/chv/.codex/host-state.json --codex-home
/home/chv/.codex --sandbox danger-full-access …,其余原参数
原样保留。--sandbox 放全局参数最后(argparse 后胜出),
单元内恒为 danger-full-access,调用方 read-only 不得盖回
bwrap;非单元路径(本地/Docker/冷启动回落)不动。
开关 CHV_CELL_ENABLED:只认 0/1,默认 1 开;非法值
ValueError(_to_switch 同款口径)。关时走原命令,给
lite10 及更早无单元的旧镜像留逃生口。
测试:新 test_chv_muse_round11_cell.py 7 项(开/关 argv、
原参数保留、sandbox 只在单元路径、非法值报错、SSH 层
接线);test_host_command_options_identical_across_executors
显式关单元测三执行器参数全等,断言本身未动。
全量 cloud 套件 2011 OK(skipped=8)。
2026-11-06 21:58:01 +00:00
host
304707b372
merge(chv-muse-round11): 合入 P3 authd 替身凭证 + Sentinel 出口审批 ( a90cf78)
...
冲突解决(3 处,均为并集保留,双方改动无一丢弃):
- cloud/chv/executor.py _copy_config_fields:P1 的 balloon/
vsock/vsock_cid 与 P3 的 sentinel_allow_hosts 合并进同一元组
- cloud/tests/test_chv_arch_maint_fe.py EXPECTED_FIELDS:P1 三字段
+ P3 sentinel_allow_hosts;len 断言 41/39 → 42(并集)
- cloud/chv/config.py 自动合入:P3 sentinel_allow_hosts(网络
片段内)+ P1 _balloon_vsock_fragment 均保留;仅更新
build_chv_config docstring 注明字段集含 P3 字段
2026-11-06 21:36:56 +00:00
host
3209f59cd6
merge(chv-muse-round11): 合入 P2 nspawn 单元 + broker + 浏览器子代理 ( c61484a)
2026-11-06 21:35:53 +00:00
host
55f6d7ad6c
merge(chv-muse-round11): 合入 P1 常驻 VM + 气球 + vsock ( 78098c5)
2026-11-06 21:35:51 +00:00
host
78098c5594
feat(chv-muse-p1): 常驻 VM + WarmPool 扶正 + 气球 + vsock,对齐 Muse
...
每用户一台常驻 VM(暂停态,resume 到 SSH 5 秒内为待验证目标),
池空/失败回落冷启动;CHV 配置加 virtio-balloon + free-page-reporting
与 vsock notify 最小实现(SSH 仍是命令通道与就绪判定)。
新模块 resident_pool.py / vsock.py + 客内 vsock_notify.py;
_config 增加 CHV_RESIDENT_IDLE_MINUTES / CHV_BALLOON / CHV_VSOCK;
worker_adapter 接常驻孤儿清理 facade;ADR-17 差距表见
docs/chv-muse-p1-gap.md。
恢复收尾(分离后回归,见 gap.md §4):VmDeathTest 死亡模拟改杀
实际跑命令的 VM;两处冷路径旧测试显式关常驻;_balloon_vsock_payload
与 listen_notify 拆到 50 行内;resident_pool.py:208 mypy 修掉。
executor.py out 未注解与 marker_tools.py:142 是基线旧错,未动。
测试:全量 cloud 套件 1934 OK(skipped=8);mypy 在改动文件上
干净(仅基线旧错 4 处)。真机验证待第三棒让出 WSL 测试机。
2026-11-06 21:31:48 +00:00
host
a90cf78d84
feat(chv): 对齐 Muse P3 收尾——authd 替身凭证 + Sentinel 出口审批
...
- 新测试 cloud/tests/test_chv_muse_p3.py 30 项:替身过期、真 token
泄露面、SSRF 挡截、deny/ask 路径、authd-seed 拆分、wake 预审、
客内 authd 守护进程、git credential helper 端到端(真 git fill)
- 8 个旧测试按新 authd 行为改写(未删测试、未放宽断言):
GITEA_TOKEN 改走 authd-seed,build_ssh_command 不再 source 进
codex 环境;wake 测试补 Sentinel 白名单 + 假解析器
- 7 处超 50 行函数拆到 50 行内(不改行为);补 authd/sentinel
公共 API 注解,mypy 在改动文件上干净
- 真问题修复:git 默认不把 path 发给 helper,chv-sync boot 加
credential.useHttpPath=true,否则 authd 路径每次都拒绝
- 全量 cloud 套件 1897 项 OK(skipped=8)
真机待验证(未做,等第三棒让出 WSL 测试机):见
docs/chv-muse-p3-gap.md §3.6 清单
2026-11-06 21:21:55 +00:00
host
c61484aa68
feat(chv-guest): 对齐 Muse P2——nspawn 单元 + broker + 浏览器子代理
...
- chv-cell:systemd-nspawn 单命令单元,--private-users=1000:65536
(单元 root → 客机 chv),丢 8 项能力(含 SYS_PTRACE/NET_ADMIN),
syscall 过滤扣 io_uring,遮蔽 /etc/chv 与 playwright,
--network-veth(10.200.0.0/24 + NAT),白名单环境透传
- chv-broker:Unix socket + SO_PEERCRED(uid 范围 + pid ns 对照),
白名单 ping/sync/browser;sync 只调 chv-sync(runuser -u chv)
- chv-browser:单元外独立进程,只暴露 open/snapshot/screenshot/
close/ping,返回无障碍树快照(截断);evaluate/content 拒绝
- build.sh:装 systemd-container/iproute2/iptables,拷入三脚本,
建 chv-browser 用户与两个 systemd 单元;vsock_notify 条件拷入
- buildinfo:内容项加 P2 四项,支持可选 extra_contents
- 测试:cloud/tests/test_chv_muse_p2.py 40 项全过;broker/browser
真实 socket 回路冒烟通过(root 连 broker 被拒)
- 差距表:docs/chv-muse-p2-gap.md;真机验证待测试机空闲(round 11)
本地做,不推、不合、不部署
2026-11-06 20:53:15 +00:00
host
06c3e172fe
fix(chv): restore 路径补 H7 net 校验+登记,seed 暂存文件走 atomic_file
...
restore_vm 此前既不校验 net 冲突、也不登记 net.json:
已登记 VM 的 tap/mac/ip 会被恢复出的 VM 静默复用,且
恢复出的 VM 自身不登记、后来的 wake 也看不到它,两边
都漏判。现与 wake 同款:_validate_restore 在起 VMM 前
校验冲突(net_tap_conflict + vm_failed 审计),
_restore_boot 在 restore 成功后登记 net.json,登记失败
审计 net_registry_write_failed + 拒绝恢复(P2-19 语义,
stop_vm 清半恢复 VM)。
hostkeys.write_seed/_apply_seed_extras 的 meta-data、
user-data、network-config 改走 atomic_file(mkstemp 0600
→ 写 → fsync → rename):user-data 含 host 私钥明文,
直接写 + 事后 chmod 会在 chmod 前以 umask 权限短暂可读;
半截文件本身到不了 ISO(唯一消费者 genisoimage 只在
write_seed 返回后跑),原子写同时堵住权限窗口与半截残留。
回归测试 6 个:restore 冲突拒起/恢复后登记/登记失败
拒起/无 net_json 不登记;seed 走原子写(0600、无 tmp
残留)/写失败不留半截文件。CHV 全套件 395 测试通过。
2026-11-06 19:32:41 +00:00
host
f448ecb74b
docs(chv): L4/M6 取舍定案 + 部署核对清单
...
- L4:保持警告不改硬拒(CHV_NET 是手动直接启动命令透传值,
与 API 的 CHV_NET_JSON 是两条路径;硬拒会断手动运维,
误配代价只是 API 模式忽略 CHV_NET);写清兼容影响与
将来改硬拒的前置条件;部署核对只设 CHV_NET_JSON
- M6:确认声明 + 审计就是本项机制,不假装已校验;部署核对
加人工项(部署记录写明已核对租户数 = 1 与项目名一致,
并复核 disk_reuse_experiment_allowed 审计)
- §11.4 加环境变量核对与残留尾巴审计抽查项
(net_registry_write_failed / dirty_marker_write_failed /
vm_net_registry_delete_failed 任一出现即先修宿主再启用)
2026-11-06 18:41:56 +00:00
host
2ad29eeb1f
feat(chv-guest): M4 Chromium 单独钉死 + /app 收紧为最小集
...
- Chromium 钉死:CHROMIUM_HEADLESS_SHELL_REV(纯数字修订号)
设即钉死,buildinfo.py 校验读回的 ms-playwright 缓存目录名
须恰好是该修订号,否则构建失败;generate/check 的 --verify
也复核;未设时只记录、构建输出明说未钉死,BUILDINFO 记 null
- /app 最小集:build.sh 不再把整个 $REPO_DIR/cloud/ 拷进客机,
只拷 host.py(只用标准库,不依赖 cloud/);REPO_DIR 预检
不再要求 cloud/ 存在
- generate_lockfile.py 只读 BUILDINFO.versions 一事已在 to10 轨
改写,本棒以合成 BUILDINFO 干跑复核(假版本 9.9.9 进 lockfile,
宿主 git 1:2.43.0 未混入)并补钉死复核;真实 lockfile 产出
仍待 V-9 真机构建,不编造版本号
2026-11-06 18:41:56 +00:00
host
c39715659e
fix(chv): P2-20/P2-19/P2-17/P2-18 残留收尾 + NO_PROXY 合并
...
- P2-20:_guest_env_delivered 加专用锁,读写只走
_delivered_secrets/_mark/_clear 三个入口,并发 hammer 测试钉死
- P2-19:_record_net_entries 失败发 net_registry_write_failed
独立审计并返回 False;_boot_vm 见 False 即拒起(wake 随后清半醒 VM)
- P2-17:net.json 删失败发 vm_net_registry_delete_failed 审计;
_write_dirty_marker 失败发 dirty_marker_write_failed 审计并返回
False,stop 不抛的契约不变
- P2-18:新增 cloud/chv/atomic_file.py(mkstemp 随机名 + 文件
fsync + rename + 目录 fsync),net.json/known_hosts/
snapshots.json/pool registry/脏标记/spill 全部走它,固定 .tmp 清零
- H1 附带:NO_PROXY 实测确有覆盖 bug(env 重复赋值以后者为准,
调用方 NO_PROXY 被 egress 的 localhost 值静默覆盖),改为合并
单条发出;egress 已设时调用方代理变量(含小写)一律不发
- 测试:新增 cloud/tests/test_chv_residual.py(23 项),旧 closeup
两处钉死旧语义的测试按新语义更新
2026-11-06 18:41:50 +00:00
host
ba5df980bf
fix(chv): known_hosts 22 端口写裸 host 行,修 provisioned 钉死失效
...
OpenSSH 默认端口只查裸 host 名、非默认端口只查
'[host]:port':known_hosts_line 对 22 端口也写
'[192.168.10.10]:22',ssh 永远匹配不上,报 Host key
verification failed、wake fail-closed 关 VM。keyscan
TOFU 输出裸行,lite9 没暴露。非 22 端口仍用括号形式。
2026-11-06 17:59:53 +00:00
host
4f3a176771
fix(chv): CHV 54 VmConfig 形态——payload.kernel/cmdline 纯字符串 + 磁盘显式 image_type Raw
...
真机 CHV 54.0.0 实测:旧顶层 kernel:{path}/cmdline:{args}
create 时 204 照放、vm.boot 400 'No bootitem provided';
补 payload 后又报 'Image type required for disk'(raw 盘
无魔数、探测失败),磁盘须显式 image_type,枚举原名
Raw(JSON 写小写 raw 报 unknown variant)。
2026-11-06 17:59:53 +00:00
host
5b6514d019
fix(chv): api_client 接受 204 无 Content-Length 响应
...
WSL 真机实测(CHV 54.0.0):vm.create 成功回 204 No Content,
且不带 Content-Length、无体;严格校验(P1-6)把合法成功当
失败拒掉,wake_vm 卡在 vm.create。204/304 按 HTTP 语义体长
恒为 0,不要求长度、不读体(keep-alive 下读会等到超时);
其它状态仍严格(无长度/截断/chunked 均拒绝)。
测试:test_chv_cover100 新增 3 项(204 成功、200 无长度仍拒、
_parse_status)
2026-11-06 17:43:54 +00:00
host
d7cc482ed5
feat(chv-guest): seed 附加项供客机用户与静态网络(wake 路径前置)
...
wake_vm 在 WSL 台架上跑通需要客机身份与网络:镜像本身不建
用户、tap 无 DHCP,缺 users 块的 VM 登不进去、缺 network-config
的 VM 拿不到静态 IP。最小补法(复用 write_seed 机制):
- hostkeys.write_seed 新增 user_data_extra(原样追加进
user-data,供 users: 块)与 network_config(写 seed
network-config 文件,0600);附加项含 runcmd: 即 ValueError
- config _seed_fragment:CHV_SEED_USER_DATA_EXTRA_FILE /
CHV_SEED_NETWORK_CONFIG_FILE(只存路径)
- executor._seed_extras 在 wake 起 VMM 前读入,缺失即
ChvFailure seed_extra_missing;provision_host_key 透传
- README §7 残留更新:guest-env 集成已做
- 测试:test_chv_gitea_sync 新增 5 项(写盘/禁 runcmd/
配置映射/wake 带附加项/缺失 fail-closed)
2026-11-06 16:58:27 +00:00
host
e7f699c62b
feat(chv-guest): Gitea 同步变量经 seed 进 guest-env(执行器集成)
...
- 新增 cloud/chv/gitea_sync.py:6 键白名单,三源合并
(宿主 CHV_GITEA_* < 任务 gitea_sync < extra_env),
必填 4 键缺失即 fail-closed,空即不同步
- ssh_transport:GITEA_TOKEN 进密钥集(argv 拒绝),其余
5 键进 guest-env 集(split_guest_env)
- hostkeys.write_seed:guest_env 与 secret_env 合并写同一
条目,仍无 runcmd、0600
- config:_gitea_fragment 产 gitea_sync_env(函数内 import,
叶子模块顶层只许标准库)
- executor.wake_vm:起 VMM 前合并+校验(gitea_sync_incomplete),
guest-env 随 seed 投递;provision_host_key 透传 guest_env
- worker:_run_attempt 仅对 CHV 执行器把同步变量并进 gateway_env
- 测试:cloud/tests/test_chv_gitea_sync.py 20 项
- 边界:tasks 表无 JSON 列,DB 往返丢任务 gitea_sync;
生产主来源是宿主 CHV_GITEA_* 环境变量
2026-11-06 16:55:32 +00:00
host
67ca0b86cd
fix(chv-guest): seed user-data 不再自带 runcmd,防顶掉镜像钩子
...
sync-test 首轮实测:seed 的 runcmd 整体替换了镜像
/etc/cloud/cloud.cfg.d/99-chv-sync.cfg 的 runcmd(cloud-init
不跨配置类型合并,merge_how 救不了 conf.d),chv-sync
boot 钩子静默不跑、启动 clone 没跑。
- hostkeys.build_seed_user_data 不再发 runcmd;chmod 600
已由 write_files 0600 保证;sshd 重启搬到镜像自己的
runcmd(cloud-final,sshd 首次启动之后)。
- build.sh:99-chv-sync.cfg 的 runcmd 增加 restart ssh
一行(在 chv-sync boot 之前)。
- README §5 同步硬性要求;回归测试 2 项(无 runcmd、
带 secret 仍单 write_files 列表无 runcmd)。
- 针对性 147 项全过(test_chv_to10/gaps/secfix/fix/
arch95plus)。
本地提交,未推未部署。
2026-11-06 16:35:14 +00:00
host
cbd5ab7c0b
fix(chv-guest): 首启缺 key 时才生成 host key(B-23)
...
Minimal 底座 cloud.cfg 不含 ssh 模块,build.sh 又写
ssh_genkeytypes: [] 彻底关掉首启生成:客机无 host key、
sshd -t 失败、ssh.service 连败 5 次,SSH 全程不通(真机
冒烟 131s 未通,console 已到 login、ping 通、tap 正常)。
修正:99-chv-hostkey.cfg 改写首启 bootcmd,只在缺
ed25519 key 时 ssh-keygen -A;ssh_deletekeys: false 保留,
绝不重生成已预置的 per-VM key(bootcmd 跑在 seed
write_files 之前,预置 key 随后覆盖生成值)。README §5
同步修正;新增 BuildScriptTest 回归断言。
2026-11-06 12:05:43 +00:00
host
dcb0824f78
fix(chv-guest): 浏览器装系统路径(B-22)
...
Round 7 构建本身成功,但 BUILDINFO.versions.chromium 为空:
virt-customize 的客机 shell 里 HOME=/,Playwright 默认缓存
~/.cache/ms-playwright 落到根目录 /.cache(实测浏览器在
/.cache/ms-playwright/chromium_headless_shell-1248),而
build.sh 读的是 /root/.cache/ms-playwright(不存在),ls 读回
空文件;buildinfo.py 当时不校验 chromium 非空,静默放过,
事后 check_lockfile / generate --verify 兜底报未覆盖(exit 1)。
改:安装与读回都走 PLAYWRIGHT_BROWSERS_PATH=
/usr/local/share/ms-playwright(agent 运行时也须设同一变量,
否则 chv 用户在家目录找不到浏览器);buildinfo.py 加
playwright_browsers_path 字段,并校验 playwright=1 时
versions.chromium 非空;README 同步。
2026-11-06 10:55:02 +00:00
host
4c8e4eac7b
fix(chv-guest): apt 用 --no-install-recommends(B-21)
...
Round 6 真机构建在 Playwright 步 ENOSPC 失败:--install 默认装
Recommends,python3-pip 连带拉入 python3-dev → gcc/g++/
build-essential 全套,根分区 2.4G 用到 2.2G(95M 空闲),
headless-shell 下到 70% 写满。改走 --run-command apt-get
install --no-install-recommends,必需项显式列出(fontconfig、
openssh-client),两轮 apt 后 apt-get clean + 清 lists 收尾。
buildinfo contents 与 README 同步加 openssh-client/fontconfig。
2026-11-06 10:29:59 +00:00
host
5206dfbc43
fix(chv-guest): gt 用绝对路径调用(B-20)
...
Round 5 真机构建在 gt 安装步失败:install.sh 已装好
/usr/local/bin/gt,但 virt-customize 的客机 sh 里 PATH 不含
/usr/local/bin,同一 --run-command 链里的 gt version 报
command not found,整个 virt-customize 退出非 0。
改两处为 /usr/local/bin/gt version(安装断言 + 版本读回文件)。
install.sh 自身的 SHA256 校验与二进制下载均已通过,不是下载问题。
2026-11-06 10:09:02 +00:00
host
4d09518338
feat(chv-guest): 轻量镜像 + Gitea 双向同步(停全量版,改 Ubuntu Minimal)
...
- build.sh 改轻量:Ubuntu Minimal 底座、apt 精简(git/ssh/cloud-init/
python3/pip/curl/ca-certificates/xz-utils/fonts-wqy-microhei)、
Playwright + chromium-headless-shell、去 B-16 +12G 扩盘;
加 git + gt 1.0.0(官方 install.sh + SHA256 校验,GITEA_CLI_VERSION
钉 1.0.0)与 chv-sync 启动钩子(cloud-init runcmd)
- B-19(新发现):dpkg freeze 的 ${Package} 会被客机 shell 展开
成空,284 行全空白;加反斜杠转义,探针实测已出真实版本
- buildinfo.py:轻量 contents、chromium-headless-shell、gt_version
- generate/check_lockfile.py:gt/chv-sync 声明来源、headless-shell 映射
- chv-sync.sh(新):boot/pull/push/status,分叉/脏树失败关闭,
凭证走 seed 盘 guest-env,不进镜像
- README §1/§2/§3/§4 改轻量口径,新增 §7 Gitea 双向同步
- tests:ChvSyncTest 6 项(本地 bare 仓当远端);针对性测试 144 项全过
2026-11-06 09:47:54 +00:00
host
9e60d5dfaa
fix(chv-guest): B-18 virt-get-kernel -o 是目录不是文件
...
- 第三轮真机构建:virt-customize 全程通过(Playwright 步已过),
随后 virt-get-kernel -a disk.raw -o $OUT/vmlinux 失败;手动
查 --help 确认 -o 是 output directory——旧写法会在 OUT 里
建出 vmlinux 目录,后面的 test -s 文件校验必然失败,即使
下载成功构建也会失败。
- 修复:-o 改为 $OUT,下载 vmlinuz-<ver> 与 initrd.img-<ver>
后把 vmlinuz-* 移为 vmlinux 文件;initrd.img-* 留在 OUT 里
作配套产物(与任务产物清单一致)。
- 同轮里 virt-get-kernel 首跑另报过一次 "file receive
cancelled by daemon",同一盘手动重跑即成功(瞬时故障),
此处失败重跑一次,与 B-05/B-06 重试口径一致。
2026-11-06 09:01:20 +00:00
host
b5e75f156d
fix(chv-guest): B-17 Playwright 安装加 --break-system-packages
...
- 第二轮真机构建实测:单次 virt-customize 在 playwright 步
失败,pip3 install --no-cache-dir playwright 在 Ubuntu 24.04
上报 PEP 668 externally-managed-environment 而拒绝安装;
随后 python3 -m playwright 报 No module named playwright。
此前 PLAYWRIGHT 默认 0,该步从未在默认构建里跑过,缺口
被默认开启暴露出来。
- 修复:playwright 的 pip 安装与第一处 pip 安装同款口径
(--break-system-packages,失败回落无 flag 再试),且只有
pip 成功才跑 python3 -m playwright install --with-deps
chromium(括号分组 + &&,失败即停,不再以 ; 带病续跑)。
- 第二轮中间证据:B-10 步已过(sshd -t 完成、99-chv.conf 与
cloud-init hostkey 配置已写入、客机 /etc/ssh 无残留 host
key;dpkg/pip freeze 已写 876/92 行)。
2026-11-06 08:34:14 +00:00
host
368bccd16e
fix(chv-guest): B-16 真机构建扩根分区(云镜像根分区仅 2.4G 会写满)
...
- 首轮真机构建实测:单次 virt-customize 在 playwright
--with-deps 装 g++/make 时报 No space left on device,
根分区 /dev/sda1 仅 2.4G、已用 97%。
- 修复:qemu-img resize +12G 后 sgdisk 只扩 1 号分区
(起始扇区实测取,不写死;14/15/16 不动),再 guestfish
resize2fs;实测根分区 2.4G→14G、可用 12G、编号仍为 sda1。
- 不用 virt-resize:实测它重写分区表、把根分区从 1 号重编号
为 4 号,而执行器默认 cmdline 是 root=/dev/vda1,重编号后
无法启动。工具检查清单加 sgdisk、guestfish。
2026-11-06 07:59:29 +00:00
host
3b41f864e8
test(chv-guest): 构建脚本测试夹具跟进 B-09 新契约
...
- 假 codex 二进制须报出版本号(codex --version 核对)
- 假仓库改为真 git 仓库,REPO_COMMIT 取其实测短 hash
(旧 test123 非 hex,B-03 格式校验本应拒绝)
- 干跑行补 BUILDINFO.json 字样(断言依赖)
另:79ba56b(并行轨)已把 Playwright 改默认开启、单次
virt-customize、补 fonts-noto-cjk,本提交只补测试与干跑
文案,不动构建逻辑
2026-11-06 15:34:06 +08:00
host
79ba56bd51
feat(chv-guest): Playwright 默认开启、单次 virt-customize、补 fonts-noto-cjk
...
- virt-customize 3 次调用合并为 1 次(VC_ARGS 数组按序执行;
PLAYWRIGHT=0 时仍可显式关掉,freeze 步骤保留兜底)。
- PLAYWRIGHT 默认 0→1:浏览器常驻复用;最终 freeze 在
Playwright 安装之后(B-08),BUILDINFO.versions.pip 含
playwright,chromium 目录名照常记录。
- apt 清单加 fonts-noto-cjk(浏览器 CJK 渲染字体,不是 LaTeX;
xelatex 仍不装)。
- 针对性测试:to10+gaps+secfix 94 项,91 过;3 项失败为
7f18c2d 已有 fixture 陈旧(REPO_COMMIT=test123 非 hex),
与本次改动无关,改前改后一致。
2026-11-06 07:25:15 +00:00
host
7f18c2d13b
fix(chv-guest): 客机镜像构建缺口补齐(B-02/B-03/B-04/B-05/B-06/B-07/B-08/B-09/B-10/B-13/B-15)
...
- B-10(实测):virt-customize chroot 里 sshd -t 必败,双因:
无 host key(exit 1)+ 缺 /run/sshd(exit 255);修为
mkdir -p /run/sshd + ssh-keygen -A 临时生成,断言通过后
立删临时 key,镜像仍不带 host key(已在 WSL 真机预演验证)
- B-08:Playwright 装在第二次定制,须重写 pip freeze 否则
BUILDINFO 里无 playwright;Chromium 以 ms-playwright 缓存
目录名记录进 guest-versions-chromium.txt
- B-09:codex --version 须含 CODEX_VERSION;REPO_COMMIT 须
等于 HEAD 短 hash;工作树脏即拒绝构建
- B-02/B-13:BUILDINFO 生成抽成 buildinfo.py(可单元测试),
补 disk.raw/vmlinux sha256+大小、ubuntu 镜像 sha、cmdline、
playwright 开关、image_sha256 字段
- generate_lockfile.py 改写:版本唯一来源改为
BUILDINFO.versions(客机读回),codex 三件套取
codex_version、/app/host.py 取 repo_commit、chromium 取
versions.chromium;不再查构建宿主 dpkg/pip(旧方法不成立)
- check_lockfile.py 补强:条目格式、contents 全覆盖、冻结
清单双向比对
- B-03/B-04 输入格式校验、B-05 curl 重试、B-06 哈希不符
删文件重下、B-07 磁盘预检、B-15 set -euo pipefail
- 同步改 test_chv_to10.py:generate 不再查宿主,改断言客机
版本来源 + 不回落宿主
2026-11-06 15:13:23 +08:00
host
8c8d62f70d
test(chv): 补齐 chv 模块剩余覆盖到 100%(生产与实验分开计分)
2026-11-01 07:00:21 +00:00
host
e718f0f326
test(chv): 修复 isWorkerAlive 边界测试抖动(精确边界改确定性字段测)
2026-11-01 00:44:12 +08:00
host
54f20dfe55
feat-chv-closeup:收尾(executor 覆盖到 100%、合并/灰度准备,堆叠于 #264)
...
- 后端新增 cloud/tests/test_chv_closeup.py 85 项:唤醒失败
(vm.create/vm.boot/API 超时/guest 就绪超时/host key 不匹配/
provisioned 缺钉死)、恢复与快照失败、取消与清理(残留
socket/登记/磁盘/密钥、脏标记)、中途死亡分类、只读
execute 归类、入口校验、preflight 事后改写、防御性
except、worker_adapter 剩余分支;executor.py 覆盖 100%。
- 前端新增 src/api/chv.closeup.test.ts 13 项:显式 false、
undefined、可用性优先级、Workers 旧 bug 文案不复发、
120 秒边界;控制按钮与新页面仍不做。
- 新增 tools/chv_merge_precheck.py(只读):逐个核 base/head/
mergeable/CI/链衔接,实测 11 个 PR 全 NOT-READY(CI 全
FAIL、mergeState 全 UNSTABLE),退出码 1,绝不合并。
- docs/chv-production-readiness.md 新增 §14:审计落盘运维
runbook(定位/轮转/读取/清理,ADR-14 取舍不变)、mypy
默认口径 2 错评估(沙箱验证过的标注修法,本轨不改
其它链文件)、灰度三阶段可执行清单、V-1~V-9 检查表
(全部未验证)、逐项评分。
- 安全语义不变:egress、key seed 投递、磁盘删除、默认
provisioned、tap 校验、前端不绕后端白名单均未放宽。
- 只到 PR OPEN,不合并、不部署;CI 账单仍是硬门禁。
2026-10-31 12:15:56 +00:00