Files
dsh_ai1net_server/归档/poc-dsh-local/patch-b1-write-protect.py
T
admin ce8e6ceed9 chore(工作区): 纳入版本控制基线(回收 411 MB 过程产物)
回收 411 MB(470 M → 58.8 M),全部经回收站,可恢复:
- 待清理/(146.2 M,含 relay 分片 128 M 与 42 项过程目录)
- tmp/(32.4 M,按接续棒命名的过程临时区)
- .workbuddy/tmp/(39.5 M)
- 4 份 workbuddy.db 冗余副本(101 M,09-23 事故的坏副本 / 抢救产物)
- tmp/im16/gw/centrifugo 二进制(63.9 M,可重下)+ 缓存残留

入库范围:常驻规则(CODEBUDDY.md / README.md / state.py)、在途接续入口与
接续包、docs/、交付物/、交接单/、归档/、scripts/、.codebuddy/、
.workbuddy/memory/;共 398 件,其中 >60 KB 的 26 件全为文档。

排除(.gitignore):tmp/、待清理/、运行态日志与缓存、*.db 与 DB 备份整目录、
打包二进制(*.tar.gz / *.tgz)、记忆修复前备份。
2026-09-24 07:51:03 +08:00

59 lines
2.7 KiB
Python
Raw 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 补丁脚本已生成')