Files
admin c1b5e4d966 chore(工作区): 全量入库 + 补齐 .gitignore(以工作区为准)
- 变更规模:新增 514 / 修改 62 / 重命名 155 / 删除 4(归档重组与文档轮次)
- .gitignore 修:`归档/**/db-cwd归一-备份-*/` —— 原规则写绝对层级(归档/db-cwd归一-…),
  目录搬进 归档/配置与备份/ 后**静默失效**,43 MB 的 DB 备份又变成未跟踪
- .gitignore 补:嵌套 git 内部数据(归档/内嵌git-20261008/、归档/skills-git-旧线-20261007/dotgit-原样移出/)
- .gitignore 补:运行态与部署副本(.workbuddy/collab/、.workbuddy/tools/、.workbuddy/.load-pending、.workbuddy/tmp-*)
- .gitignore 补:备份件(*.bak-*)
- 未跟踪文件从 2190 降到 890(其余为 归档/ 归档件与 .workbuddy/memory/ 知识文件,按口径入库)
2026-10-10 23:13:22 +08:00

59 lines
2.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
# 档案 18/17 P1(H2):把平台策略文件在实例内设为只读(bwrap --ro-bind-try)
# 用法: python3 patch-b1-write-protect.py /opt/dshs
import io, os, sys
root = sys.argv[1] if len(sys.argv) > 1 else '.'
p = os.path.join(root, 'src/supervisor/orchestrator.ts')
s = io.open(p, encoding='utf-8').read()
# 1) spawnAsUser 增加 role 形参(用于定位 profile 目录名)
old_sig = """ private async spawnAsUser(
userId: string,
command: string,
args: string[],
options: { cwd: string; env: Record<string, string> },
): Promise<{ child: ChildProcess; unit?: string }> {"""
new_sig = """ private async spawnAsUser(
userId: string,
command: string,
args: string[],
options: { cwd: string; env: Record<string, string> },
role: InstanceRole = 'main',
): Promise<{ child: ChildProcess; unit?: string }> {"""
assert old_sig in s, 'sig'
s = s.replace(old_sig, new_sig, 1)
# 2) 调用点传入 role
old_call = """ const { child, unit } = await this.spawnAsUser(userId, command, [...args, ...launchArgs], { cwd: folder, env })"""
new_call = """ const { child, unit } = await this.spawnAsUser(userId, command, [...args, ...launchArgs], { cwd: folder, env }, role)"""
assert old_call in s, 'call'
s = s.replace(old_call, new_call, 1)
# 3) 在 --bind root root 之后追加平台策略文件的只读覆盖
old_bind = """ '--bind', tmpDir, '/tmp',
'--bind', root, root,
'--unshare-pid',"""
new_bind = """ '--bind', tmpDir, '/tmp',
'--bind', root, root,
// 2026-09-11(档案 18 v3 收尾 / 档案 17 §P1):平台策略文件在实例内**只读**。
// 威胁模型:用户可把 <userRoot>/home/profiles/web 加为工作区,随后用 bash 直接改写
// cordis.patch.yml(去掉平台段 → 恢复全盘 picker)或 package.json(挂任意 bundle)→
// 属"绕过平台策略"(跨租户仍不成立,uid/bwrap 隔离不变)。
// 只读三个文件;**不动 cordis.yml**——实测 dsh 启动时会写它(01:16:22),ro 会导致启动异常。
// 注意:必须放在 '--bind root root' **之后**(bwrap 后写覆盖前写)。
...(() => {
const profileDir = join(homeRoot(root), 'profiles', role === 'main' ? 'web' : 'headless')
const protectedFiles = ['cordis.patch.yml', 'package.json', 'pnpm-lock.yaml']
const out: string[] = []
for (const name of protectedFiles) {
const file = join(profileDir, name)
out.push('--ro-bind-try', file, file)
}
return out
})(),
'--unshare-pid',"""
assert old_bind in s, 'bind'
s = s.replace(old_bind, new_bind, 1)
io.open(p, 'w', encoding='utf-8', newline='').write(s)
print('B1 补丁脚本已生成')