Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ OpenWorkProof 不保证 Agent 的结果一定正确,也不替客户作出验
执行有证据、验证与验收不会被混为一谈,并把接受、拒绝、撤销和申诉的权利留给人。

[安装](#五分钟开始) · [工作原理](#工作原理) ·
[OWP Guard 本地候选](docs/integrations/agent-guard-codex.md) ·
[Human Agency](#human-agency能力越强人的决定权越不能消失) ·
[DeepSeek Harness](docs/integrations/deepseek-harness.md) ·
[协议文档](docs/protocol/human-agency-profile-v0.1.md) ·
Expand Down Expand Up @@ -75,6 +76,20 @@ OpenWorkProof 与维护者 [dengyier](https://github.com/dengyier) 的相关公

</details>

## OWP Guard:在原 Agent 中保护预览目录(本地候选)

用户继续在 Codex 中提任务,OWP 在受支持的工具执行前自动检查:允许读取、增加和
修改指定预览目录内的普通文件,拒绝越界访问、删除/移动、任意命令和未支持工具。
首版提供项目级安装、状态检查、显式升级与卸载恢复,适用于 POSIX 本地文本编辑。

这项能力尚未发布到 PyPI,也不会随已有 MCP 配置自动启用。宿主必须实际加载并信任
Hook;它不是全电脑隔离,在线搜索等宿主未开放的路径不在保护范围。
安装、验收与完整边界见 [接入说明](docs/integrations/agent-guard-codex.md)。

首次使用可按 `install → enable → doctor → run` 完成项目接入、当前版本授权、真实检查
和 Codex 任务运行。该入口使用原厂单项 session trust,不跳过 Hook 信任检查,也不修改
全局配置;详见 [首次启用与受保护启动](docs/integrations/agent-guard-onboarding.md)。

## Agent 说 `完成了`,还缺什么

MCP 连接 Agent 与工具,A2A 连接 Agent 与 Agent。它们解决如何连接和通信,不能单独
Expand Down
116 changes: 116 additions & 0 deletions docs/integrations/agent-guard-codex.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# OWP Guard:Codex 本地预览目录保护(首版)

状态:本地开发,尚未发布。首个适配宿主为本机 Codex CLI 0.147.0。

## 使用目的与验收约定

用户在原 Agent 中修改一份预览副本。OWP 自动检查宿主交来的工具请求:
允许读取、增加和修改指定预览目录内的普通文件;拒绝越界文件、删除/移动、
任意执行命令及未支持的工具。用户无需创建另一套工作单。

首版有意限制命令能力,适合文本/静态页面预览编辑,不适合构建、测试、部署等
需要任意程序执行的任务。具体命令白名单随实现列明。

实现顺序和成功标准:

1. 检查器:真实工具输入得到稳定的允许/拒绝;路径穿越、符号链接、多文件补丁、
命令拼接、未知工具、缺失策略均有负例,拒绝前没有执行副作用。
2. 项目安装:只注册本项目的同步 PreToolUse,保留其他 Hook;重复安装不叠加;
状态分别显示已配置与本地检查记录;宿主是否调用另用真实宿主事件核验。
卸载恢复原配置或保留安装后的其他改动。
3. 真实宿主:在单独体验目录让 Codex 读取/编辑预览、尝试越界与命令写入,
对照文件结果和本地检查记录。测试脚本调用检查器不算真实宿主验收。

## 数据与权限

- 策略由安装者设置,存放在项目可编辑范围之外;Agent 工具输入不能授予权限。
- 首版策略格式 `openworkproof/agent-guard/0.1`,字段为 `project_root`、
`allowed_directory`、`installation_id`。所有目录在安装时解析为绝对真实路径。
- 运行时文件为独立的标准库模块 `agent_guard.py`,安装时复制到本机状态目录,
由固定 Python 路径以 `-I` 启动,避免从 Agent 工作目录导入代码。
- `Bash` 与 `apply_patch` 输入使用 `tool_input.command`;补丁按宿主格式解析
所有路径。只读命令也只能访问预览目录;隐藏路径、链接和多硬链接文件拒绝。
- 不信任提示词中的批准声明,不读取 transcript,不发送遥测或增加外部模型服务。
本地记录只含时间、决定、固定原因码、工具类别、输入摘要及策略摘要,不存原文。
这些记录未签名,手动运行检查器也能产生,不能单独证明宿主触达或独立验收。
- 正常请求返回空 JSON,保留宿主原有权限判断;拒绝返回原厂支持的 `deny`。
Python 失败由外层包装器转为拒绝,不能使用异步 Hook 或不受支持的 `ask`。

## 首版边界

这是宿主执行前的工具限制,不是操作系统隔离,也没有运行中终止/回滚能力。
本组件只处理宿主交来的执行前请求,不宣称已运行完整签名授权与独立验收协议。
既有 Core、Desk 和运行中的服务不因安装而改变。

必须由宿主实际启用并信任 Hook。Codex 默认在 Hook 缺失、超时、定义不受信任或
部分错误时继续;包装器只能处理它已经启动后的内部失败。状态不能据配置存在
宣称全局生效。项目可信、Hook 可信、原厂权限设置仍由宿主管理。

官方不为 `write_stdin` 的后续输入再次触发 PreToolUse,所以首版拒绝交互/PTY和
任意命令。Hosted WebSearch 等原厂列明路径未覆盖;专用体验启动应关闭在线搜索,
不能据未知工具拒绝推成所有行为受控。管理员/同一系统用户禁用 Hook、外部进程
同时替换文件、检查与执行间的竞态均不属于本机制能消除的威胁。

原厂契约:<https://learn.chatgpt.com/docs/hooks>(核查日期 2026-10-26)。
WorkBuddy 5.8.3 当前尚未核实同等桌面执行前阻断契约,不能标为已支持。

## 开发与验证

### 从当前源码使用

以下命令在仓库根目录运行,使用已装依赖的开发环境;`owp-guard` 是新增的包入口,
尚不在已发布的 PyPI 版本中。安装当前源码到独立环境后,也可直接使用该入口。

```sh
PYTHONPATH=src .venv/bin/python -m openworkproof.guard_cli install \
--project /absolute/site-project --allow-dir preview --human
PYTHONPATH=src .venv/bin/python -m openworkproof.guard_cli status \
--project /absolute/site-project --human
PYTHONPATH=src .venv/bin/python -m openworkproof.guard_cli uninstall \
--project /absolute/site-project --human
```

项目与预览子目录应已经存在。默认控制文件位于
`~/.local/share/openworkproof/guard/<项目路径摘要>/`,不在 Agent 可编辑目录内。
`--state-dir` 可以指定本地控制目录;后续状态、升级与卸载须使用同一目录。
不带 `--human` 时返回 JSON,供自动化使用。

安装只配置项目 `.codex/hooks.json`,不会替用户设置全局项目可信或 Hook 信任。
已新增 [首次启用与受保护启动](agent-guard-onboarding.md):通过 `enable` 审阅当前版本并
完成真实检查,再用 `run` 在原生 Codex 引擎中执行任务。该入口只传入单条 session trust。
若直接普通启动 Codex,仍需将项目设为可信,再通过 `/hooks` 审阅、信任并启用 OWP 项。
源码、范围或包装器升级会改变定义;使用 `install --upgrade` 显式更新并重新信任。
有漂移时安装拒绝覆盖;卸载在可确认唯一自有条目时仍能移除接入,保留他人配置。
卸载会保留本地安装记录与事件文件,输出其位置,不宣称已经删除所有本地数据。

只读命令限 `/bin/pwd`、不带选项的 `/bin/ls`、`/bin/cat`(可用 `-n`)。
文件路径须位于预览目录;不接受拼接、替换、通配符、交互参数或隐含执行能力。
不支持的操作会向原 Agent 返回中文理由;允许结果不会绕过宿主自己的权限检查。

### 2026-10-26 本地验收结果

- 检查器与安装生命周期测试:130 passed。
- 本地 wheel 在独立环境安装,包入口完成安装、幂等、状态和卸载;原有 Hook
配置按原始字节恢复。
- 真实 Codex CLI 0.147.0 从项目 Hook 文件加载:正常读取与单处页面标题修改成功;
越界创建、命令写入、隐藏假密钥读取均被拒绝。原件和官网源码未变,两个拒绝目标
没有生成,假密钥值未出现在最终宿主事件流中。
- 实机验收显式设置了**本次调用的项目信任**并使用
`--dangerously-bypass-hook-trust`,该开关跳过 Codex 自己的持久信任审阅。
因此它证明所安装检查器在这次调用中的真实阻断,不证明普通启动已自动启用或已经
通过 Codex `/hooks` 的交互式信任流程。验收没有修改用户全局配置或持久化信任。

失败的调试轮次也保留:桌面模型别名不适用于 CLI、关闭工具执行入口,以及测试命令
错误设置项目信任,均未计入成功。后者曾让负例实际执行,测试文件已恢复。
该版本 CLI 的 `-c` 左侧按点拆分,不解析 TOML 带引号的路径键;自动化中应把整个
项目表放在右值,例如单个参数
`projects={"/absolute/site-project"={trust_level="trusted"}}`。
不要因为跳过了 Hook 信任检查,就认为项目层也已受信任。

```sh
PYTHONPATH=src .venv/bin/python -m pytest -q \
tests/test_agent_guard.py tests/test_guard_cli.py
```

验收使用合成拒绝目标与假密钥;代码审查来自同一 AI 协作团队的另一审查 Agent,
不是客户独立验收。尚未发布安装包到外部渠道、接入 WorkBuddy 或验证企业部署。
83 changes: 83 additions & 0 deletions docs/integrations/agent-guard-onboarding.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# OWP Guard 首次启用:当前版本授权与真实检查

本地候选(2026-10-26):承接已有 Codex 预览目录保护,完成安装后的启用与确认生效。
不改现有运行时策略,不重写用户的 Codex 配置,不使用跳过 Hook 信任检查的参数。

## 用户流程

1. `install` 继续只安装项目接入。
2. `enable` 展示允许目录、限制、当前检查版本与使用的 Codex 启动方式。用户交互确认
或明确使用 `--trust-own-hook` 后,记录只针对这条 OWP 定义的授权,并执行真实检查。
3. `doctor` 分别显示安装完整性、宿主识别结果、当前版本授权、最近真实检查结果。
4. `run` 在原有 Codex CLI 中执行任务;每次启动前核对身份并交给原厂信任机制核验。
升级、重装、定义或宿主版本变化会使旧授权/检查失效,需重新启用。

## 接入与失败契约

- 原厂 `hooks/list` 读取真实 key、currentHash、enabled 和 trustStatus;不自己计算
原厂的定义哈希。只选择来源、命令、事件、位置及安装清单均匹配的唯一 OWP 条目。
- 用户授权记录放在 OWP 本地控制目录,每次受保护启动仅将这一项的精确 trusted_hash
交给 Codex 的 session hooks.state。项目可信也限本次启动。没有全局信任绕过。
- 受保护运行使用 Codex 默认模型及原有登录,本次不载入个人 MCP/插件配置,关闭
在线搜索。该方式避开本机桌面特有配置与 CLI 不兼容的情况;不改变其他会话设置。
- 原厂支持的 session trust 与持久全局 trust 分开标注;不称普通 Codex 启动已受保护。
- 真实检查在同一目标项目中只操作新建的独占合成目录。正常读取和修改必须成功,
越界补丁与命令写入必须在执行前被拒绝。结果同时核对宿主事件/原厂拒绝提示、
本次检查器决定和实际文件,模型自述或手动制造本地日志不能作为通过依据。
- 授权与检查绑定安装 ID、目录、配置和控制文件摘要、原厂 key/hash、Codex 版本。
缺失、漂移、宿主不可读、请求没发生、仅被其他权限层阻止或超时均不标为通过。
- 检查记录是一次本地运行的证据,不是未来会话保证、签名协议凭证或客户独立验收。
卸载仍只移除项目接入,保留本地记录,并撤去后续受保护启动的可用状态。

验收:保留此前安装/运行时测试;新增 native RPC、授权隔离、旧授权失效、探针反假绿
与失败清理测试;最后用本机真实 Codex 在无 bypass 参数的情况下完成启用与一次任务。

## 使用方法

以下入口来自当前本地源码构建的包,尚未对外发布;已经安装的旧 PyPI 包不含这些命令。
也可在仓库现有开发环境用 `PYTHONPATH=src .venv/bin/python -m openworkproof.guard_cli`
代替 `owp-guard`。

```sh
owp-guard install --project /absolute/site-project --allow-dir preview --human
owp-guard enable --project /absolute/site-project --human
owp-guard doctor --project /absolute/site-project --human
owp-guard run --project /absolute/site-project --prompt "修改预览首页的标题,先预览不发布" --human
owp-guard uninstall --project /absolute/site-project --human
```

`enable` 展示授权目录、限制、检查版本与 Codex 程序位置,用户输入“确认”后才授权
当前这一条检查并运行真实探针。非交互自动化只有明确传 `--trust-own-hook` 才会继续。
取消不会更改现有授权;不以安装成功或模型自报完成当作启用成功。

使用自定义 `--state-dir` 时,每个命令都须带同一路径。`--codex` 可以指定 Codex 程序;
授权同时绑定其解析后的绝对路径、文件摘要和版本。替换程序后须重新启用。
标准输出默认 JSON,`--human` 为中文。doctor 不会调用模型,只检查安装和原厂清单;
enable 和 run 使用已有 Codex 登录运行真实 Agent。

## 已验证与限制

- 首次启用阶段的授权、原生 RPC 和探针测试与已有守卫测试合计 218 项通过;
推送前另补充了初始化时 KeyboardInterrupt/SystemExit 清理的两项真实子进程回归。
- 首次启用实机通过:本地只读原厂清单从未信任变为本次启动信任,未使用
`--dangerously-bypass-hook-trust`,也未向原厂写入持久全局信任。
- 原厂信任核验后,四步真实探针同时通过原生读取、新文件内容、两项执行前拒绝、
本次守卫决定与合成文件清理检查。
- 新 wheel 在独立环境安装,包入口 doctor 通过;随后真实 run 读取预览并仅修改
一处标题,源网站及原始副本未变,全局 Codex 配置摘要未变。
- 升级/重装/范围或配置变化/宿主程序变化使旧 review 或 probe 失效,有相应负例。
启用与任务运行全程持本项目锁,避免本 CLI 自己的升级、卸载在检查与执行间插入。
Ctrl-C 结束检查/任务并清理子进程后可以卸载。

这一路径称为 **OWP 受保护启动**:用户仍使用原生 Codex 引擎,但由 OWP 带入当前已审阅
的单条 session trust。普通启动 Codex 的窗口仍须按原厂流程自行设置项目与 Hook 信任,
本轮没有把它标为已保护。

`run` 的 completed 表示 Agent 本次运行结束并通过当前身份核对;不是业务结果验收。
有原生工具活动而缺少对应时间窗内的守卫活动,或存在 Hook 失败提示时,返回未核实。
时间窗中的日志没有 session 级密码学关联,另一同项目会话的记录仍可能混入,所以
明确返回 `per_tool_session_proof=false`,不把数量对应当成逐项操作的独立证明。

本地 review/probe 由当前系统用户控制,没有密码学用户认证。无法抵御同权限外部进程
替换包装器、宿主或配置的竞态;原厂没有提供检查点的路径仍不在本组件范围。
WorkBuddy 当前只完成底层可行性核查,外部插件在真实桌面任务中还未验收。
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ dev = [
openworkproof = "openworkproof.mcp_transport:main"
owp = "openworkproof.cli:app"
owp-mcp = "openworkproof.mcp_transport:main"
owp-guard = "openworkproof.guard_cli:main"

[tool.setuptools]
package-dir = {"" = "src"}
Expand Down
Loading
Loading