# 团队 Codex 工作动态：本机采集与团队云端同步

2026-09-30 云端对接：以同事返回的 `team-codex-integration-guide.md` 为实际协议；下方本地采集逻辑保持不变，旧云端需求稿仅供追踪尚未支持的需求。

接入入口：联系人 → 团队 → 选择团队 → 团队功能 → Codex 同步（弹窗）。团队成员列表始终保留在弹窗下方的原页面。阅读入口：完成绑定后，对话 → Codex；成员行「查看对话」可进入对应成员的阅读区。

## 使用方式

1. 点击“接入本机 Codex”，复制接入指令，粘贴到本机任意一个 Codex 对话。
2. 让 Codex 审查本机脚本后执行 enroll 命令。不再需要任务 ID，也不需要每个项目/任务重复配置。
3. 用户在 Codex 中审查并信任新的 capture Hooks；已打开的会话可能需要恢复或重启才能加载配置。脚本不会修改信任设置。
4. 接入后，使用这份 Codex 配置的所有本地任务的新输入、最终回答和中断状态自动出现。已有对话继续工作也适用，不扫描此前历史。
5. 对话 → Codex 按项目、任务呈现输入输出，显示原生任务标题、分支、状态和最近时间。队列采用与 DSH 一致的紧凑行：单项直接显示，多项默认折叠，可展开查阅；历史按需分页。工作目录位于任务信息中，支持项目筛选与搜索。团队弹窗只承担接入和同步管理，不重复显示任务正文。
6. 可暂停全部同步、排除项目（含后续新任务）或单个任务、恢复同步、断开连接。删除任务记录需要确认，不删除 Codex 原任务；本地保留不含正文的排除标记，避免再次自动导入。

### 云端版接入指引

- 接入区明确显示账号昵称/即我号、团队名称/团队号。本机接入与云端上传独立显示；本机已连接不表示已授权上传，已授权也不等于全部上传成功。
- 接入指令按当前账号、所选团队及上传授权动态生成：未开启、已授权、仅本机支持、暂无法核验。不能仅因为插件存在云端模块就宣称已开启。名称和标识放入 JSON 数据块，不作为 Codex 额外指令。
- 点击复制时重新核验并生成指令；失败不复制旧文案。显示在文本框中的状态为生成时快照，实际以 Arkme 当前状态为准。变更本机/云端控制后收起旧指令，避免手动复制过期状态。
- 每位成员、每台采集电脑必须在自己的 Arkme 生成本机指令，不转发他人指令。仅在另一电脑查看已有云端记录无需接入采集。采集来源是本机 Codex；云端是同步目的地，两者不混称。
- 接入本机不会自动授权云端上传。当前账号需在 Arkme 单独确认；暂停、排除规则仍生效。已接入用户可从「管理连接 → 查看接入指令」查看，不需要断开重连。
- Python、Hooks 信任、已有会话恢复/重启及首次有效期说明折叠在「接入说明」中。不会代用户执行接入、修改 Hooks 信任或触发测试事件。

未配置的首次接入指令有效期 20 分钟。已完成配置不会因为 20 分钟到期停止同步。运行脚本成功只代表“已配置，等待 Codex 真实事件”，不是 Hooks 已获信任或同步已验收。

需要 Python 3 和支持 Hooks 的 Codex。本轮在 macOS 验证，Windows 接入命令尚未验收。测试使用独立 Web 3100，需保持该服务运行、登录对应账号；无需一直停留在团队页。不增加监听端口，不改变已安装桌面客户端。

## 项目与任务识别

- 接入实例（installation）和任务（session）分开：一份本机 Codex 配置接入一次，多个 session 自动创建独立任务。
- Hooks 提供 session_id、turn_id、cwd。对于本机 CODEX_HOME/.chatgpt-projects/<项目 ID> 及其子目录，优先按 Codex 项目 ID 归组；只读取 Codex 自动生成的 AGENTS.md 前三行固定元数据头获取项目名称，不读取后续项目指令。名称缺失时显示项目 ID，改名不改变项目 key。
- 普通项目按 cwd 查找 Git 根和 common Git directory，同仓库不同 worktree 使用同一项目 key，另显示各自分支和工作目录。托管项目中的 Git 子目录仍归原 Codex 项目，并保留 Git 分支和工作目录信息。
- 只读 .git / HEAD / commondir 等身份元数据，不执行仓库命令、不读取源码、不查询远程地址或访问网络。
- 非 Git 项目使用工作目录归类；缺少目录、主目录或 Codex 内部的无仓库任务使用“未归属项目”。同名不同路径的项目 key 不同，可从详情目录区分。
- 官方 Hook 合同不保证提供 Codex 侧栏的自定义项目名/任务标题。托管项目名称来自本地镜像元数据，其他项目名来自仓库或目录。任务标题通过下述只读兼容层同步，不再把首条输入第一行当作正式名称。
- 任务状态“本轮结束”仅表示收到 Stop，不等于需求完成或代码已验收。输入/最终回答/中断按 task + turn + kind 去重；显式标记 agent_id/subagent_id 的子任务输出跳过。
- 当前增加了桌面队列的只读兼容适配，见下节。Hook inbox 和待上传缓冲不是用户的任务队列，不以历史输入输出推算排队数量。
- 同一 Codex 配置之外的另一电脑、不同 CODEX_HOME、远程任务和云端编排不自动采集。启用团队云端同步后，其他电脑可读取已上传记录；若要采集那台电脑的 Codex，仍需独立接入并确认上传。

## 原生任务标题同步（2026-09-30）

- 仅查询已通过真实 Hook 绑定的 session ID。新版读取 `CODEX_HOME/state_5.sqlite` 的 `threads.name`（实际显示名称），不是可能保留首条需求的 `threads.title`；旧版无 name 时使用 `session_index.jsonl` 的最新 `thread_name`。不读取历史正文、rollout、工具输出或推理。
- 每次后台采集同时检查名称，无须发送新消息或打开团队页。校正已有任务和后续重命名；保留 task ID、事件、状态和活动时间，不因改名创建新任务或改动排序。未取得名称的新任务暂显示 Codex；读取失败保留最近有效名称，不回退到正文截断标题。
- 本机采集服务需运行并登录原账号。机器级接入校验 homeKey；暂停、排除、删除及归属不明的跨账号任务不采集名称。旧版单任务连接只查询原绑定 ID，不扩大到其他会话。
- SQLite 只读读取实时 WAL，拒绝符号链接/不支持的结构；索引有大小边界。此为本机版本兼容，不是官方稳定接口，Codex 格式变化时可能需要升级适配。
- 已授权团队上传直接复用 `/api/v1/team-codex/sync`：只有名称变化时递增任务元数据 version，发送 `task_title` 与 `events: []`；事件不重传。云端按现有轮询刷新，不新增后端接口。后端 task_title 上限为 1024 UTF-8 字节，极长标题云端按协议安全截断；正常标题完整同步。

## 本地与隐私边界

- 默认仅本地采集，不调用模型。用户确认开启后，将当前账号在指定即我团队下未暂停、未排除的已有输入输出及后续事件上传；团队成员可见。云端授权按账号、团队持久保存，不继承给其他账号。可停止云端上传而保留本机采集。
- 同步接入后的 UserPromptSubmit.prompt、Stop.last_assistant_message、Interrupt，以及已关联会话的当前排队文本。绝不扫描 transcript、历史对话、工具日志或内部推理；队列只提取白名单字段，不保存全局状态中的其他信息或排队附件正文。
- 所有项目默认纳入。敏感项目/任务应及时排除；排除在脚本写入队列之前执行，Host 还会再次校验。不补采暂停、排除或 Arkme 离线期间的内容。
- 普通输入/回答也可能含私密信息。只做常见密钥格式的尽力脱敏，不保证识别所有秘密。每条保存前 65,536 字符，页面按纯文本显示，不执行 HTML、不自动加载外部图片。
- 配置时备份并合并用户级 hooks.json，不覆盖其他 Hooks，不修改模型、登录、权限、信任设置或系统启动项。
- 全局版本使用新的 capture 命令，需要新的信任审查；原先只获授权的 record 命令始终保持单任务范围，不因升级插件扩大采集。
- 退出/切号同步清除在线标记；崩溃后标记最多 15 秒失效。控制变更轮换 generation，未消费的旧队列被丢弃（包括同批其他任务事件），防止撤销之后迟到事件重新出现。
- 文件位于插件 stateDirectory/team-codex，目录 0700、文件 0600；这是权限隔离，不是加密。Hooks 失败不阻塞 Codex，只返回空 JSON，不注入模型指令。

## 排队请求只读试用（2026-09-30）

- 只读两种本机来源：新版 app-server 的 `CODEX_HOME/queue_1.sqlite`（`queued_items` 表），以及旧版/本地待发送的 `.codex-global-state.json` → `queued-follow-ups`。按桌面端逻辑先呈现 server 的 `queue_order` 顺序，再合并本地待发送项，用 server ID / client ID 去重，不按正文或创建时间猜测。这些不是公开稳定接口；后续 Codex 升级可能需要适配，不能承诺通用于所有版本。
- 新版数据库按只读连接读取实时 WAL，不用忽略 WAL 的 immutable 模式；只查询已绑定 thread_id，逐项限制载荷和条目数，拒绝符号链接、未知表结构和载荷类型。数据库出错、运行期间消失或有一部分来源不可读时，不把旧 JSON 中缺少会话键解释为完整的零条。
- 必须匹配接入的 homeKey，并且 session 已通过真实 Hook 关联账号/团队；未接入过的新对话暂不采集。跨账号同一会话的归属存在冲突时停止队列导入，不猜归属。
- 后台每秒检查本机快照，页面每三秒刷新。编辑、调序、移出以新快照反映；没有 Stop 也能更新。条目移出不推断“已完成”，当前输入仍来自 Hook。
- 仅保存原条目 ID、正文、时间、顺序、发送状态、附件数量；正文最多 4,096 字符，列表最多 200 项。常见凭据尽力脱敏；不复制附件内容/路径、IDE 上下文。
- 格式完整可读才显示确切数量；失败保留上次内容并提示不可读，部分可读提示不完整；没有队列字段不等于空队列。不因文件很久没变就误报队列过期，读取时间与文件时间分别记录。
- `queue` 是后续请求；`send-now` 只标待发送，不猜成 steer；sending/unknown 单列其状态，不计为下一轮排队。执行状态仅基于已收到的 Hook，实际运行情况以 Codex 为准。
- 停止同步/排除时不继续采集，退出及切号沿用原账号隔离。恢复后读取当前队列，不补历史排队编辑记录。支持 SQLite 持久化和单调快照版本；重启不归零，相同内容重读不增版本。
- 不向 Codex 写文件、不代用户插入/修改/取消排队、不远程调度。2026-10-23 增加能力门控的云端队列适配，后端声明支持之前仍不上传队列；见下方云端协议。尚未关联队列 request ID 与实际 turn ID。

## 旧版本兼容

原 connections/events 表和真实旧记录保留。升级本身不安装全局 Hooks。

第一次收到用户明确接入的全局真实事件后，将该账号/团队的旧单任务记录接入新实例，保留原内容，并停用旧采集器，避免绕过全局暂停或排除。同一 session 合并为一个任务，不重复显示；尚无项目元数据的旧任务先显示在“未归属项目”，继续工作时补齐。旧版已暂停/断开的任务保留排除状态。

尚未接入、过期的旧版邀请仍在“旧版单任务记录”中，用户可删除；不把它误显示为已同步的真实任务。

## 本机接口

本机 Host API 要求 loopback 调用及与当前页面完全一致的 Origin。

| 操作 | 参数 | 用途 |
| --- | --- | --- |
| team.codex.state | teamRef, page?, memberRef?, sourceId?, projectKey? | 本人、设备连接、本机任务及云端分页；项目过滤与 sourceId 配套 |
| team.codex.invite | teamRef | 一次性设备接入指令；有效连接重复请求返回同一实例 |
| team.codex.events | teamRef, id, before?, sourceId?, cursor? | 本地 before；云端 sourceId + 后端 cursor，不能混用 |
| team.codex.change | teamRef, id, action, projectKey? | 设备 pause/resume/disconnect；任务 exclude/include/delete；项目 exclude/include；enable-cloud / disable-cloud |

SQLite 新增 codex_installations、codex_tasks、codex_events、codex_project_exclusions、codex_queue_snapshots 和 legacy migration 映射；旧表不破坏。v2 Hook 传输缓冲显式记录 homeKey、sessionId、turnId、project 元数据和 generation，事件去重键为 installation + session + turn + kind。

活动页每 3 秒拉快照，隐藏时停轮询、出错退避 30 秒；历史展开才加载事件正文，各项目先显示 20 项并支持更多。后台每秒消费最多 100 条 Hook 事件，传输缓冲最多 1,000 条；饱和会丢弃新事件，不保证完整审计日志。这不是所有工具步骤/进程输出的采集器，也不是远程调度器。

## 已对接的云端协议

- 生产域名 `https://team.jotmo.cc`，复用当前登录 JWT，Host 刷新凭据，不向网页或 Hook 暴露令牌。
- 先检查所选 opaque teamRef 对应 `arkme_cn`，再从 `/api/v1/team/list-mine` 读取真实十进制 team_id；不拿 opaque ref 代替，不猜 ID，不创建或加入团队。
- `/api/v1/team-codex/sync`：按绑定上传。SQLite 保存稳定 source/task/event UUID、turn_seq、独立任务/事件版本和逐项 ACK。超时同 ID 同版本重试；stale/conflict/永久拒绝保留且阻断，不直接加版本覆盖。
- source_name 首次绑定后固定；原有正文批次严格白名单，不带 cwd、附件、工具日志、排队快照或 Token 用量。批次最多 100 任务/100 事件、实际 JSON 最多 1 MiB，正文最多 256 KiB UTF-8，按 Unicode 字符边界截断。新增队列使用独立批次和 ACK，须通过下述能力声明后才上传。
- `/api/v1/team-codex/tasks/list`：团队视图，成员/来源项目筛选与 page 分页。页面轮询替换当前页、按 task_id 去重，不假称固定快照或服务端增量协议。搜索仅作用于当前页已加载任务。
- `/api/v1/team-codex/events/list`：正文按需读取，opaque cursor 向前翻页、event_id + version 合并；即使任务元数据/时间没变化，当前展开的远端正文仍定期刷新。
- 其他电脑不必安装采集 Hooks 即可读取云端。远端不提供本地暂停/删除按钮。2026-10-23 已补齐能力门控的队列上传/读取与本人跨设备展示；后端未声明支持时明确提示接口开发中，不显示假零。协议及上线边界见 [队列跨设备交接](Codex排队请求跨设备同步-后端交接-20261023.md)。
- 退出、切号、暂停、排除均中断当前上传；账号/团队重新核验，旧队列不重新归属。云端权限失败移除远端页面数据，保留本机记录。删除本地任务同时删除待上传正文副本，但没有云端删除接口，不承诺删除已上传副本。
- 仍缺后端：队列/执行快照、Token 用量、云端删除、远程派发。队列插件适配已完成、待后端接通；新的 queue_snapshot v1 声明前不上传。不能发送旧草案 work_state 等未列字段。真实接口可用性及跨电脑验证单独记录，不用合成测试替代线上验收。

## 尚未落地的后端需求（历史交接）

以下保留此前提案背景。输入输出上传、任务查询和正文读取已经按实际返回协议接入；队列、Token 用量、远程派发等未列入返回协议的能力仍未落地。

2026-09-30 更新：用户已确认简化首期方案，以 [云端同步首期后端交接](team-codex-cloud-sync-minimal-v1-2026-09-30.md) 为准，保留本地采集，只新增：

- 按明确账号和团队批量上传/更新，重试去重，逐条确认。
- 按本人或团队成员、项目分页查询任务，检查增量更新。
- 按任务分页读取内容；复用现有登录和团队权限，切号及退组时停止越权读写。
- 旧本地数据经用户选择后，使用同一上传接口分批补传，不建独立迁移平台。
- 同一对话的当前执行情况、待执行请求及顺序，复用上述三个接口同步独立版本 work_state。本地已接只读来源，需进一步联调云端及验证来源覆盖范围，不等待一轮执行完才展示后续排队。仅同步查看，不增加远程调度。

先前完整云端设计已标为后续参考，不是当前必做项；上述接口仍为交接提案，不表示已上线。

当前保留安装 ID、原始 session ID、turn ID、事件种类和时间，已增加上述云端上传与读取；此节中的队列 work_state 仍是提案，不是已实现协议。

## 验证与限制

- 回归使用临时 CODEX_HOME、合成 Hook 事件及临时 Git 仓库/worktree，不修改用户真实 Codex 配置。
- 覆盖一次接入多项目/任务、独立去重、项目归组、全局暂停、项目/任务排除、账号隔离、旧记录迁移、分页、非法事件、Hook 合并备份及信任边界。
- UI 回归覆盖项目分组、搜索、按需正文读取、设备/项目/任务操作分离、删除确认及卸载取消。
- 队列测试使用临时全局状态文件和与真实结构一致的 SQLite/WAL，覆盖编辑/重排/删除、新旧 ID 去重、同文不同请求、与事件无关的刷新、重启版本、跨账号隔离、暂停/排除、格式未知/损坏、符号链接、超限和尽力脱敏。只读测试同时核对源数据库与 WAL 内容未改动。合成测试不代表真实端到端全部验收。
- 2026-09-30 修正原验收结论：原先“3 个已关联对话没有非空排队”只是旧 JSON 的结果，不能代表桌面真实队列。用户截图中的请求实际存在于新版 `queue_1.sqlite`，旧读取器遗漏该来源；新版读取器已在本机只读匹配到该真实请求。
- 本轮 6 个相关测试文件共 58 项通过，类型检查和完整构建通过。未代用户创建、编辑、调序、取消或执行任何真实请求。入队→编辑→调序→移出→开始执行的完整真实操作验收仍未完成；队列 request ID 到 turn ID 的映射仍未实现。
- 19:06 已更新并在 3100 浏览器确认：登录及原有 3 个任务保留，当前任务显示真实「排队 2 条」，包含用户截图对应内容及随后新增请求；读取器初验为 1 条、页面随后自然更新为 2 条，无需等待当前轮结束。验证截图在本机 `.codex-artifacts/team-codex-new-queue-20260930-5EW5U1/queue-visible-3100.png`。本轮只更新独立 Web 预览，未推送或发布插件。

官方机制：[Codex Hooks](https://learn.chatgpt.com/docs/hooks)。

### 云端对接验收（2026-09-30 19:48 CST）

- 12 个测试文件共 269 项通过，覆盖云端协议、逐项 ACK、重试、账号/团队隔离、授权开关、身份迁移、UI 筛选与既有团队/认证接口；类型检查和完整构建通过。
- 独立 3100 已部署最终构建，`client.js` 与仓库构建 SHA256 一致。先备份源码、原构建和 SQLite；未修改已安装桌面端或 Codex 配置，未推送或发布插件。
- 当前账号在即我团队下的 3 个任务、36 条输入输出已收到真实生产接口确认。重启预览后授权保留，待上传 0、冲突 0，数据库完整性检查通过。
- 使用云端 `source_id + task_id` 读取全部 3 个任务正文，36 条记录的 ID、版本、种类、时间及正文哈希与本地上传账本一致；此验证没有用本地正文接口替代。
- 浏览器已验证云端连接提示、成员/来源电脑/项目分组、项目筛选及保留本机队列。没有代用户发送新的测试消息或执行排队请求。
- 尚未在另一台真实电脑或另一位团队成员账号验收。其他端需安装包含本轮改动的插件，登录有权访问即我团队的账号，进入「联系人 → 团队 → 即我 → 工作动态」。仅查看云端不需要重新接入采集。

### 接入文案与双状态验收（2026-09-30 19:57 CST）

- 按已确认的简洁布局补齐账号/团队显示、本机接入与云端上传双状态、条件化指令及折叠说明。13 个测试文件共 279 项通过，类型检查和完整构建通过。
- 新测试覆盖未授权、已授权后关闭、跨账号不继承授权、不支持的团队/本地环境、核验失败、核验时切号，以及复制前重新获取文案、失败拒绝复制旧文案。现有采集/云端测试通过。
- 3100 实际指令正确绑定当前账号与即我团队，状态为已授权上传；核验前后授权表完全一致。未执行接入脚本、未更改 Codex 配置、未代用户新开上传授权。
- 浏览器确认「管理连接 → 查看接入指令」可用，绑定信息、双状态和折叠说明正常。预览与源码构建 `client.js` SHA256 一致；截图：`.codex-artifacts/team-codex-onboarding-20260930-GqYHnp/onboarding-3100.png`。尚未推送或发布。

### 自动派发方向与验证阻塞（2026-09-30）

- 用户已确认「远端提交后，来源电脑自动通过 Codex 原生输入框入队」的方向；见 [本机界面试用与云端增补](team-codex-ui-dispatch-handoff-2026-09-30.md)。现有上传授权不自动变为远程控制授权。
- 当前开发会话的电脑使用服务初始化反复超时，尚未读取原生输入框或发送测试请求。此问题只能证明本轮验证通道不可用，不能据此断言独立辅助程序不可行或系统权限缺失。
- 本轮只补充接口/状态/验收交接文档，未增加可执行的派发入口、修改 Codex 队列或重启客户端。当前 3100 仍是上传与查看版本，不支持远端输入控制。
