【免费下载链接】super-simple-software-factory
Repeatable agents-plus-code workflows, packaged as one skill, stamped into any repo. Deterministic Python owns the graph; coding agents are bounded nodes inside it.
让 AI Agent 写代码不难,难的是保证它"只改该改的"。Super Simple Software Factory(下文简称 SSSF)是一个可重复的 agents+code 工作流框架:确定性的 Python 拥有整个执行图,编码 Agent 只是图中受限的节点。它的权限模型核心是writes边界——用代码在每次 Agent 调用后对比仓库快照,发现越权写入就自动回滚并让该阶段失败,从而从机制上防止 Agent 越权改代码,而不是靠 prompt 求它"别乱动"。
为什么 tools 列表挡不住越权改代码
直觉上,给 Agent 一个工具白名单(tools)应该就够了。但 SSSF 的设计者明确指出:tools只是能力清单,不是沙箱。permissions.py 开头就列出了两个挡不住的洞:
bash可以执行任何命令。给 builder 的bash是为了跑测试,但同样能跑git checkout adws/——这不是假想:真的有一个 Agent 这么干过,丢弃了它马上要被评判的那份未提交的质量检查。write能到达任意路径。一个"配置为只读"的 reviewer,理论上仍可能悄悄改写它正在审查的代码。
所以"这个 Agent 什么都不改"这句话,工具列表只能说出来,却守不住。SSF 的解法是:像系统里其他所有声明一样,事后用代码对照仓库本身来验证。
writes 与 protected_files:边界是怎么定义的
权限规则全部集中在 sssf.config.yaml,由两个键驱动:
defaults: protected_files: # 任何 Agent 默认都碰不到 - adws/adw_modules/ - adws/adw_sssf_config/ - adws/adw_*.py agents: - name: scout writes: [] # 对仓库只读 - name: planner writes: [specs/] # 只能留下计划文档writes有三种取值,语义完全不同(见 config.md):
| 写法 | 含义 |
|---|---|
省略writes | 不受限(但protected_files仍碰不到) |
writes: [] | 对仓库完全只读 |
writes: [specs/] | 只能写这些路径 |
路径匹配规则:结尾/表示目录前缀,*只匹配一层路径,**才能跨目录——这是刻意的,否则adws/adw_*.py会悄悄匹配到adws/adw_data/sessions/x/y.py,把白名单放大成漏洞(permissions.py)。
protected_files是全员禁入名单:adws/adw_modules/是判定 Agent 工作是否通过的"评分机制",Agent 绝不能编辑裁判。唯一开口:某个 Agent 如果在自己的writes里明确点名了该路径,才算解锁。
事后验证:快照对比如何抓到"擦屁股式"越权
权限执行分两步,实现在 permissions.py:
snapshot()跑前打指纹:Agent 发出第一条 prompt 前,用git diff --numstat+git ls-files --others指纹化当前工作区的全部变更集——已修改的文件带增删行数,未跟踪文件按名字记录。enforce()跑后对比:Agent 所有发送(包括 JSON 重试和 gate 纠正)结束后再打一次指纹,任何出现、消失或被改写的路径都算该 Agent 所为。
关键设计是"对比变更集"而不是"监听写入":一个跑前已修改、跑后变干净的路径,意味着它被还原了——还原本身就是修改。这正是抓住git checkout擦除未提交工作的方式,纯写入监听器根本发现不了。
调用点在 agents.py:
tree_before = permissions.snapshot(run) # Agent 动手之前 # ... 发 prompt、解析 envelope、跑 gates ... touched = permissions.enforce(run, phase, agent, tree_before) # 全部结束之后注意时机:权限检查发生在所有发送完成后、envelope 被接受前——Agent 不能在一个它越权写入的阶段里谎报成功。
越权发生后的三步处置:回滚、保留、失败
一旦enforce()发现违约(breach),处置逻辑在 permissions.py:
- 回滚 Agent 引入的每一次越权变更——已跟踪文件用
git checkout --还原,未跟踪文件直接删除; - Agent 运行前就脏的路径原样保留——那是工程师的未提交工作,清理时丢弃它会造成和 Agent 一样的伤害,宁可大声报
REVERTED-BY-AGENT也不假装处理了; - 该阶段直接失败,错误信息点名每一条违规路径及处置结果,同时以
permission_breach事件写入 SQLite 追踪库(agents.py)。
这里有一个重要的概念区分:越权不是 gate 违规。gate 针对的是可以让 Agent 重做的"工作";而写入已经发生了,重新 prompt 救不回来。所以 gate 失败会带着纠正信息回到同一会话重试,越权则直接中止阶段、回滚了事。
只读 Agent 的例外:data_dir 永远可写
一个容易踩坑的细节:writes: []表示对仓库只读,不是"这个 Agent 不能写任何文件"。always_writable() 保证data_dir下的会话运行时目录对所有 Agent 永远可写——context_handoff/是 Agent 之间交接工作的唯一通道,每个 Agent 的envelope.json、原始输出也都落在那里。scout 把发现写进去,reviewer 把审查意见写进去。
这个豁免刻意来自data_dir配置而不是.gitignore:Agent 记录自己工作的能力,不该系在一条随时可能被删掉的 gitignore 行上。
按角色收窄,而不是凭直觉
SSSF 出厂的五个 Agent,权限梯度一目了然(sssf.config.yaml):
| Agent | writes配置 | 角色语义 |
|---|---|---|
| builder | 省略(唯一不受限) | 改仓库就是它的工作,但裁判仍碰不到 |
| planner | [specs/] | 留下的只能是计划文档 |
| scout | [] | 侦察型,真的只读 |
| reviewer | [] | 不能修,才不会悄悄修 |
| documenter | 仅文档路径 | "只写文档"现在是规则,不再是约定 |
收窄的原则是按角色,不是按反射。任何需要产出context_handoff/产物的 Agent 都得保留write,否则它会绕道用bashheredoc 写文件;而edit/write只在"限制本身就是保证"时才应该扣掉——一个不能编辑的 reviewer,它的"只评审"才真正成立。
小结
SSSF 权限模型的全部逻辑浓缩成一句话:Agent 提议,代码定夺。tools描述能力,writes划定边界,permissions.py在事后用仓库快照执行边界——越权写入被回滚、被记录、让阶段失败,而不是被一句"下次注意"放过。这也是整个工厂的基调:确定性代码拥有流程与验收,Agent 只拥有有界阶段内的工作。
想深入阅读实现,建议按这个顺序:
- permissions.py — 快照、对比、回滚的完整实现(约 190 行,可读性很好)
- config.md 的 "Write permissions" 一节 — 两个键的完整语义
- sssf.config.yaml — 五个 starter Agent 的权限梯度示例
【免费下载链接】super-simple-software-factory
Repeatable agents-plus-code workflows, packaged as one skill, stamped into any repo. Deterministic Python owns the graph; coding agents are bounded nodes inside it.
相关推荐
Zotero插件Ethereal Style完整指南:进度追踪+智能标签+跨设备同步3步快速上手
Zotero插件Ethereal Style完整指南:进度追踪+智能标签+跨设备同步3步快速上手 换台电脑打开文献,发现忘了上次读到第几页?几百篇文献堆在一起,
科研桌面应用Node-Casbin 安全防护:如何防止权限提升和越权访问
Node Casbin 安全防护:如何防止权限提升和越权访问 在当今数字化时代,权限提升和越权访问已成为网络安全领域的头号威胁。据统计,超过70%的数据泄露事件
7个关键策略:如何用Ory Keto构建安全权限边界防止权限滥用
7个关键策略:如何用Ory Keto构建安全权限边界防止权限滥用 权限管理是现代应用安全的核心,Ory Keto作为开源的授权系统,提供了强大的工具来防止权限过
后端应用安全云原生
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考