feat(skill): 新增 verify-fast-ship 验证技能与功能验证地图(INT-58) #37

Merged
gitbobobo merged 5 commits from t3code/verify-fast-ship-skill into main 2026-10-07 11:44:57 +08:00
gitbobobo commented 2026-10-07 02:51:25 +08:00 (Migrated from github.com)

相关需求

INT-58 用 create-verification-skill 为 fast_ship 生成 verify-fast-ship 验证技能

改动内容

新增项目本地验证技能 .agents/skills/verify-fast-ship/(create-verification-skill 的首次实战产物),并按其自身步骤真跑通过:

  • SKILL.md:隔离启动配方——不用 make dev(4888/4999 与 vite proxy 写死无法双开,改为构建二进制 + FAST_SHIP_* 环境覆盖直接运行);断言式 Doctor(PID 身份、端口归属、401 探活、bundle hash 逐项断言,失败即停);无头 Playwright 驱动约定(全部来自本仓库源码的真实选择器,含 Base UI combobox 的 name= 不可匹配陷阱);证据规则(凭据永不进 evidence);Cleanup 只杀已核对身份的自家 PID。
  • scripts/fsdrive.py:薄驱动 CLI,register/login/shot/run 四个命令 + scenario 注入 helper(api_get 带 JWT、save_secret 0600 落 scratch)。
  • features/:README 索引 + 5 个功能文件(auth、projects、issues-list、issue-detail、api-keys),每个四个 H2,覆盖登录鉴权、项目、问题列表、问题详情、API Key 管理。
  • .gitignore 补 __pycache__/(驱动脚本为 Python)。

技能位置:根目录 skills/ 是对外分发的技能(fast-ship API 技能被外部仓库导入),仓库内部技能归入 .agents/skills/——除新增的 verify-fast-ship 外,version-release(驱动 make release,不对外安装)也一并从 skills/ 迁入;README 项目结构同步标注两个目录的分工。

过程:首轮生成并跑通后,经独立审查发现 15 处问题(并发 RUN_ID 撞目录可能误杀他人实例、API Key 会落入证据、若干选择器与源码不符等),全部修复并重跑一轮验证通过。

修改范围

.agents/skills/(新增 verify-fast-ship、迁入 version-release)、skills/(迁出 version-release)、.gitignore、README.md

本地验证

检查命令 结果
make lint 通过,ESLint 0 错误 0 警告 + tsc + gofmt/go vet
make test 通过,web 42 文件 326 用例 + server go test ./... 全绿
  • 验证方式(命令 / 无头浏览器):无头 Python Playwright(技能自带 fsdrive.py,headless chromium)

  • 启动命令:技能 Launch 节的隔离实例——go build 至 scratch + FAST_SHIP_SERVER_PORT=5088 / FAST_SHIP_DATABASE_PATH / FAST_SHIP_WEB_DIST_DIR 等环境覆盖(本机 4888 已被其他工作树实例占用,验证全程未触碰)

  • 验证提交 SHA:ee09e59

  • 应用可以启动(隔离实例 READY + doctor 断言通过),主要使用流程已验证:注册/登录、对话框创建项目(自动跳问题页)、项目网格/搜索、新建问题、问题筛选与搜索、API Key 创建/使用/删除

  • 异常或空状态已验证(doctor 负路径 exit 1、端口被他人占用拒绝驱动、问题空态、搜索未命中、key 删除后 API 返回 401)

已修复的基线问题

无

端到端截图

无界面变化(仅新增 .agents/skills/ 文档与驱动脚本)。替代证据:技能实跑的采集截图(证据目录在工作树外,cleanup 后存活,共 42 个文件含 ARIA 快照、API 读回、sqlite 行核对):

  • 对话框创建项目后自动跳到问题页:04-project-created.png
  • 新建内部问题 INT-1 详情页(元数据/协作区/任务清单):11-issue-created.png
  • API Key 管理页(完整 key 只落 scratch,证据零泄漏):16-apikeys-list.png

未验证范围与原因

feature map 首批覆盖 5 个用户面;版本与发货依赖 GitHub Release(超出本地可验证边界),documents/logs/board/settings 未入首批——后续按 maintain-verification-skill 扩展。

API 变更说明

无

创建 PR 前完成

  • 本地验证表已填完,每条检查零警告、零错误、零失败
  • 端到端截图已贴入,或已写明无需截图的原因
  • 补充需求编号(如果存在)
  • 变更影响范围已补充到 PR 描述中

审查意见处理

  • 逐条处理所有审查评论:真实问题修复后回复并重新验证;误报或不适用意见回复理由。
  • 推送新提交后分别重新请求上一轮未通过的审查者(跳过审查通过的和未添加顶层评论的),并检查新增评论。不同 bot 不要写在同一条评论里,也不要在回复线程里触发:
    • Code Bot:顶层评论单独发 @CodeBot review
  • 请求复审后按 $pr-review-loop 自动等待并处理新意见,直到收敛
## 相关需求 [INT-58 用 create-verification-skill 为 fast_ship 生成 verify-fast-ship 验证技能](http://192.168.31.31:4888/projects/5ca4b87d-7014-4d48-809e-b0c80cd9fff7/issues/28ea4bed-b427-4f04-8dce-6a185176a4da) ## 改动内容 新增项目本地验证技能 `.agents/skills/verify-fast-ship/`(`create-verification-skill` 的首次实战产物),并按其自身步骤真跑通过: - **SKILL.md**:隔离启动配方——不用 `make dev`(4888/4999 与 vite proxy 写死无法双开,改为构建二进制 + `FAST_SHIP_*` 环境覆盖直接运行);断言式 Doctor(PID 身份、端口归属、401 探活、bundle hash 逐项断言,失败即停);无头 Playwright 驱动约定(全部来自本仓库源码的真实选择器,含 Base UI combobox 的 `name=` 不可匹配陷阱);证据规则(凭据永不进 evidence);Cleanup 只杀已核对身份的自家 PID。 - **scripts/fsdrive.py**:薄驱动 CLI,`register`/`login`/`shot`/`run` 四个命令 + scenario 注入 helper(`api_get` 带 JWT、`save_secret` 0600 落 scratch)。 - **features/**:README 索引 + 5 个功能文件(auth、projects、issues-list、issue-detail、api-keys),每个四个 H2,覆盖登录鉴权、项目、问题列表、问题详情、API Key 管理。 - `.gitignore` 补 `__pycache__/`(驱动脚本为 Python)。 技能位置:根目录 `skills/` 是**对外分发**的技能(`fast-ship` API 技能被外部仓库导入),仓库内部技能归入 `.agents/skills/`——除新增的 `verify-fast-ship` 外,`version-release`(驱动 `make release`,不对外安装)也一并从 `skills/` 迁入;README 项目结构同步标注两个目录的分工。 过程:首轮生成并跑通后,经独立审查发现 15 处问题(并发 RUN_ID 撞目录可能误杀他人实例、API Key 会落入证据、若干选择器与源码不符等),全部修复并重跑一轮验证通过。 ## 修改范围 .agents/skills/(新增 verify-fast-ship、迁入 version-release)、skills/(迁出 version-release)、.gitignore、README.md ## 本地验证 | 检查命令 | 结果 | | --- | --- | | `make lint` | 通过,ESLint 0 错误 0 警告 + tsc + gofmt/go vet | | `make test` | 通过,web 42 文件 326 用例 + server `go test ./...` 全绿 | - 验证方式(命令 / 无头浏览器):无头 Python Playwright(技能自带 `fsdrive.py`,headless chromium) - 启动命令:技能 Launch 节的隔离实例——`go build` 至 scratch + `FAST_SHIP_SERVER_PORT=5088` / `FAST_SHIP_DATABASE_PATH` / `FAST_SHIP_WEB_DIST_DIR` 等环境覆盖(本机 4888 已被其他工作树实例占用,验证全程未触碰) - 验证提交 SHA:`ee09e59` - [x] 应用可以启动(隔离实例 READY + doctor 断言通过),主要使用流程已验证:注册/登录、对话框创建项目(自动跳问题页)、项目网格/搜索、新建问题、问题筛选与搜索、API Key 创建/使用/删除 - [x] 异常或空状态已验证(doctor 负路径 exit 1、端口被他人占用拒绝驱动、问题空态、搜索未命中、key 删除后 API 返回 401) ### 已修复的基线问题 无 ## 端到端截图 无界面变化(仅新增 `.agents/skills/` 文档与驱动脚本)。替代证据:技能实跑的采集截图(证据目录在工作树外,cleanup 后存活,共 42 个文件含 ARIA 快照、API 读回、sqlite 行核对): - 对话框创建项目后自动跳到问题页:![04-project-created.png](https://uiv.frp.musiver.cn/f/TxWznbGU4f.png) - 新建内部问题 INT-1 详情页(元数据/协作区/任务清单):![11-issue-created.png](https://uiv.frp.musiver.cn/f/KpBUr8h4Q1.png) - API Key 管理页(完整 key 只落 scratch,证据零泄漏):![16-apikeys-list.png](https://uiv.frp.musiver.cn/f/5hTjcgzZbT.png) ## 未验证范围与原因 feature map 首批覆盖 5 个用户面;版本与发货依赖 GitHub Release(超出本地可验证边界),documents/logs/board/settings 未入首批——后续按 `maintain-verification-skill` 扩展。 ## API 变更说明 无 ## 创建 PR 前完成 - [x] 本地验证表已填完,每条检查零警告、零错误、零失败 - [x] 端到端截图已贴入,或已写明无需截图的原因 - [x] 补充需求编号(如果存在) - [x] 变更影响范围已补充到 PR 描述中 ## 审查意见处理 - [ ] 逐条处理所有审查评论:真实问题修复后回复并重新验证;误报或不适用意见回复理由。 - [ ] 推送新提交后分别重新请求上一轮未通过的审查者(跳过审查通过的和未添加顶层评论的),并检查新增评论。不同 bot 不要写在同一条评论里,也不要在回复线程里触发: - Code Bot:顶层评论单独发 `@CodeBot review` - [ ] 请求复审后按 `$pr-review-loop` 自动等待并处理新意见,直到收敛
gitbobobo commented 2026-10-07 02:51:46 +08:00 (Migrated from github.com)

@codex review

@codex review
gitbobobo commented 2026-10-07 02:51:47 +08:00 (Migrated from github.com)

@CodeBot review

@CodeBot review
chatgpt-codex-connector[bot] commented 2026-10-07 02:52:05 +08:00 (Migrated from github.com)

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-06T19:16:01.388627Z a6e7a11 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

<!-- codex-pull-request-review-summary --> ## Codex Review Summary This comment shows the latest Codex review activity on this pull request. | Review | Status | Commit | Review trigger | | --- | --- | --- | --- | | 📝 **Code Review** | ✅ **Completed** <relative-time datetime="2026-10-06T19:16:01.388627Z">2026-10-06T19:16:01.388627Z</relative-time> | `a6e7a11` | Manual request | <details> <summary>ℹ️ About Codex in GitHub</summary> <br/> [Your team has set up Codex to review pull requests in this repo](https://chatgpt.com/codex/cloud/settings/general). Reviews are triggered when you - Open a pull request for review - Mark a draft as ready - Comment "@codex review" or "@codex security review". Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. </details>
gitbobobo (Migrated from github.com) reviewed 2026-10-07 02:53:37 +08:00
gitbobobo (Migrated from github.com) left a comment

行内备注见下方;完整结论见 PR 会话顶层评论。

行内备注见下方;完整结论见 PR 会话顶层评论。
@ -0,0 +206,4 @@
username, email, password = ns.args
fresh_auth_page("/register")
fill_register(username, email, password)
shot("register-form") # filled form, before submit
gitbobobo (Migrated from github.com) commented 2026-10-07 02:53:37 +08:00

P2 填好表单后的 shot() 会把明文密码写进 evidence/*.aria.txt。

Playwright 的 aria_snapshot() 对 type=password 也输出 value,不做掩码。我用同样的写法实测过:

- textbox "密码": VerifyPass1

所以 register-form.aria.txt(以及下面第 197 行的 login-form.aria.txt)会带上密码,和 SKILL.md「Credentials never enter evidence… not in .aria.txt」的规则冲突;如果 login 用的是真实账号,就是真实凭据落进了 cleanup 后仍保留的证据目录。建议提交前的这一张只截 .png(密码框本身是圆点),或者在生成快照前把密码值替换掉 / 写入后对 .aria.txt 做脱敏。

**P2** 填好表单后的 `shot()` 会把明文密码写进 `evidence/*.aria.txt`。 Playwright 的 `aria_snapshot()` 对 `type=password` 也输出 value,不做掩码。我用同样的写法实测过: ``` - textbox "密码": VerifyPass1 ``` 所以 `register-form.aria.txt`(以及下面第 197 行的 `login-form.aria.txt`)会带上密码,和 SKILL.md「Credentials never enter evidence… not in `.aria.txt`」的规则冲突;如果 `login` 用的是真实账号,就是真实凭据落进了 cleanup 后仍保留的证据目录。建议提交前的这一张只截 `.png`(密码框本身是圆点),或者在生成快照前把密码值替换掉 / 写入后对 `.aria.txt` 做脱敏。
gitbobobo commented 2026-10-07 02:53:58 +08:00 (Migrated from github.com)

Code Bot 审查结论:

审查范围:HEAD ee09e59(首审),新增 skills/verify-fast-ship/(SKILL.md、features/ 5 个功能文件、scripts/fsdrive.py)及 .gitignore。已对照 server/internal/config/config.go、server/cmd/server/main.go、configs/config.yaml 核对启动配方:CONFIG_PATH、FAST_SHIP_* 覆盖(含单独绑定的 FAST_SHIP_WEB_DIST_DIR)、服务启动 日志行与 release 模式行为都与源码一致。

  • P2 register / login 命令把明文密码写进证据目录 — fsdrive.py 在提交前调用 shot("register-form") / shot("login-form"),而 Playwright 的 aria_snapshot() 对 type=password 输入框照样输出 value(已实测得到 - textbox "密码": VerifyPass1)。于是 evidence/register-form.aria.txt、login-form.aria.txt 里都有密码,违反 SKILL.md 自己定的「Credentials never enter evidence … not in .aria.txt」,且 evidence 在 cleanup 后保留;用真实账号 login 时泄漏的就是真实凭据。PR 描述的「证据零泄漏」只覆盖了 API Key。详见行内备注。
  • Note Doctor / Cleanup 的 PID 身份校验只在 macOS 上成立 — ps -p PID -o comm= 在 macOS 返回完整可执行路径,但在 Linux 只返回进程名(fast_ship,最多 15 字符),和 $V/scratch/fast_ship 永远不相等:Doctor 必然失败,Cleanup 则会走「leaving it alone」分支把服务留在后台。若技能只面向 macOS,建议在 SKILL.md 写明;否则可改用 ps -o args= 或 /proc/$PID/exe 比对。另外 Doctor 的 fail() 用 exit 1,若 agent 在持久 shell 里直接粘贴执行会把整个会话退出,可考虑放进子 shell ( … ) 运行。
复审

如需复审,请单独在顶层评论回复 @CodeBot review

**Code Bot 审查结论:** 审查范围:HEAD `ee09e59`(首审),新增 `skills/verify-fast-ship/`(SKILL.md、features/ 5 个功能文件、`scripts/fsdrive.py`)及 `.gitignore`。已对照 `server/internal/config/config.go`、`server/cmd/server/main.go`、`configs/config.yaml` 核对启动配方:`CONFIG_PATH`、`FAST_SHIP_*` 覆盖(含单独绑定的 `FAST_SHIP_WEB_DIST_DIR`)、`服务启动` 日志行与 `release` 模式行为都与源码一致。 - **P2** `register` / `login` 命令把明文密码写进证据目录 — `fsdrive.py` 在提交前调用 `shot("register-form")` / `shot("login-form")`,而 Playwright 的 `aria_snapshot()` 对 `type=password` 输入框照样输出 value(已实测得到 `- textbox "密码": VerifyPass1`)。于是 `evidence/register-form.aria.txt`、`login-form.aria.txt` 里都有密码,违反 SKILL.md 自己定的「Credentials never enter evidence … not in `.aria.txt`」,且 evidence 在 cleanup 后保留;用真实账号 `login` 时泄漏的就是真实凭据。PR 描述的「证据零泄漏」只覆盖了 API Key。详见行内备注。 - **Note** Doctor / Cleanup 的 PID 身份校验只在 macOS 上成立 — `ps -p PID -o comm=` 在 macOS 返回完整可执行路径,但在 Linux 只返回进程名(`fast_ship`,最多 15 字符),和 `$V/scratch/fast_ship` 永远不相等:Doctor 必然失败,Cleanup 则会走「leaving it alone」分支把服务留在后台。若技能只面向 macOS,建议在 SKILL.md 写明;否则可改用 `ps -o args=` 或 `/proc/$PID/exe` 比对。另外 Doctor 的 `fail()` 用 `exit 1`,若 agent 在持久 shell 里直接粘贴执行会把整个会话退出,可考虑放进子 shell `( … )` 运行。 <details> <summary>复审</summary> 如需复审,请单独在顶层评论回复 `@CodeBot review` </details>
gitbobobo (Migrated from github.com) reviewed 2026-10-07 02:54:08 +08:00
gitbobobo (Migrated from github.com) left a comment

行内备注见下方;完整结论见 PR 会话顶层评论。

行内备注见下方;完整结论见 PR 会话顶层评论。
@ -0,0 +206,4 @@
username, email, password = ns.args
fresh_auth_page("/register")
fill_register(username, email, password)
shot("register-form") # filled form, before submit
gitbobobo (Migrated from github.com) commented 2026-10-07 02:54:08 +08:00

P2 填好表单后的 shot() 会把明文密码写进 evidence/register-form.aria.txt — Playwright 的 aria_snapshot() 把 type=password 当 textbox,并把 input.value 原样输出成子节点(只跳过 checkbox/radio/file),所以快照里会出现 - textbox "密码": VerifyPass1。这和 SKILL.md「凭据永不进 evidence,含 .aria.txt」的规则直接冲突。建议提交前截图时跳过 aria 快照,或在 shot() 里先把密码框清空/掩码后再取快照。

**P2** 填好表单后的 `shot()` 会把明文密码写进 `evidence/register-form.aria.txt` — Playwright 的 `aria_snapshot()` 把 `type=password` 当 `textbox`,并把 `input.value` 原样输出成子节点(只跳过 checkbox/radio/file),所以快照里会出现 `- textbox "密码": VerifyPass1`。这和 SKILL.md「凭据永不进 evidence,含 `.aria.txt`」的规则直接冲突。建议提交前截图时跳过 aria 快照,或在 `shot()` 里先把密码框清空/掩码后再取快照。
@ -0,0 +214,4 @@
login, password = ns.args
fresh_auth_page("/login")
fill_login(login, password)
shot("login-form") # filled form, before submit
gitbobobo (Migrated from github.com) commented 2026-10-07 02:54:08 +08:00

P2 同上:login-form.aria.txt 也会带出明文密码。

**P2** 同上:`login-form.aria.txt` 也会带出明文密码。
gitbobobo (Migrated from github.com) commented 2026-10-07 02:54:08 +08:00

P2 ps -o comm= 在 Linux 上只给可执行文件名(截断到 15 字符,即 fast_ship),不是完整路径,所以这里在 Linux(云端 agent / CI)上永远不等于 $V/scratch/fast_ship,Doctor 必然失败;Cleanup(第 183 行)用的是同一判断,会走「不是我们的进程」分支,把服务器留在后台。macOS 上 comm 恰好是完整路径才跑通。可改用 ps -p "$PID" -o args= 的首个字段,或在 Linux 上比对 readlink /proc/$PID/exe。

**P2** `ps -o comm=` 在 Linux 上只给可执行文件名(截断到 15 字符,即 `fast_ship`),不是完整路径,所以这里在 Linux(云端 agent / CI)上永远不等于 `$V/scratch/fast_ship`,Doctor 必然失败;Cleanup(第 183 行)用的是同一判断,会走「不是我们的进程」分支,把服务器留在后台。macOS 上 `comm` 恰好是完整路径才跑通。可改用 `ps -p "$PID" -o args=` 的首个字段,或在 Linux 上比对 `readlink /proc/$PID/exe`。
gitbobobo commented 2026-10-07 02:54:23 +08:00 (Migrated from github.com)

Code Bot 审查结论:

审查范围:HEAD ee09e59(首轮,skills/verify-fast-ship/ 全部新增文件 + .gitignore)。

  • P2 register / login 命令把明文密码写进 evidence — fsdrive.py 在提交前对已填表单调用 shot("register-form") / shot("login-form"),而 Playwright aria_snapshot() 会把 type=password 识别为 textbox 并原样输出 input.value,所以 register-form.aria.txt / login-form.aria.txt 里会出现 - textbox "密码": VerifyPass1。这违反了本技能自己「凭据永不进 evidence(含 .aria.txt)」的硬规则;目前是一次性测试账号影响有限,但别人按技能换用真实密码时就会泄露。建议提交前的截图不取 aria 快照,或先清空/掩码密码框。
  • P2 Doctor 与 Cleanup 的进程身份校验只在 macOS 上成立 — 两处都用 ps -p "$PID" -o comm= 去比对完整路径 $V/scratch/fast_ship。Linux 上 comm 只返回截断到 15 字符的文件名(fast_ship),Doctor 会永远报「pid is not …」,Cleanup 会走「leaving it alone」分支把服务器留在后台。云端 agent / CI 多为 Linux,这条会让技能在那里不可用且泄漏进程。可改为比对 ps -o args= 首字段或 /proc/$PID/exe。
  • Note Doctor 块用 fail() { …; exit 1; }:如果 agent 在持久 shell 里直接粘贴执行(而不是 bash -c / 子 shell),失败时会把整个会话 shell 退出,$V/$PORT 等变量随之丢失,后续 Cleanup 也找不到目录。可以把整块包在 ( … ) 里,或改成 return/显式说明用子 shell 运行。
  • Note SKILL.md frontmatter 的 description 声称覆盖 versions、documents、logs、settings,但首批 feature map 只有 auth / projects / issues-list / issue-detail / api-keys(PR 描述也说明了其余未入首批)。建议 description 与实际覆盖面对齐,避免调用方以为这些面已有配方。
复审

如需复审,请单独在顶层评论回复 @CodeBot review

**Code Bot 审查结论:** 审查范围:HEAD `ee09e59`(首轮,`skills/verify-fast-ship/` 全部新增文件 + `.gitignore`)。 - **P2** `register` / `login` 命令把明文密码写进 evidence — `fsdrive.py` 在提交前对已填表单调用 `shot("register-form")` / `shot("login-form")`,而 Playwright `aria_snapshot()` 会把 `type=password` 识别为 `textbox` 并原样输出 `input.value`,所以 `register-form.aria.txt` / `login-form.aria.txt` 里会出现 `- textbox "密码": VerifyPass1`。这违反了本技能自己「凭据永不进 evidence(含 `.aria.txt`)」的硬规则;目前是一次性测试账号影响有限,但别人按技能换用真实密码时就会泄露。建议提交前的截图不取 aria 快照,或先清空/掩码密码框。 - **P2** Doctor 与 Cleanup 的进程身份校验只在 macOS 上成立 — 两处都用 `ps -p "$PID" -o comm=` 去比对完整路径 `$V/scratch/fast_ship`。Linux 上 `comm` 只返回截断到 15 字符的文件名(`fast_ship`),Doctor 会永远报「pid is not …」,Cleanup 会走「leaving it alone」分支把服务器留在后台。云端 agent / CI 多为 Linux,这条会让技能在那里不可用且泄漏进程。可改为比对 `ps -o args=` 首字段或 `/proc/$PID/exe`。 - **Note** Doctor 块用 `fail() { …; exit 1; }`:如果 agent 在持久 shell 里直接粘贴执行(而不是 `bash -c` / 子 shell),失败时会把整个会话 shell 退出,`$V`/`$PORT` 等变量随之丢失,后续 Cleanup 也找不到目录。可以把整块包在 `( … )` 里,或改成 `return`/显式说明用子 shell 运行。 - **Note** SKILL.md frontmatter 的 description 声称覆盖 versions、documents、logs、settings,但首批 feature map 只有 auth / projects / issues-list / issue-detail / api-keys(PR 描述也说明了其余未入首批)。建议 description 与实际覆盖面对齐,避免调用方以为这些面已有配方。 <details> <summary>复审</summary> 如需复审,请单独在顶层评论回复 `@CodeBot review` </details>
chatgpt-codex-connector[bot] (Migrated from github.com) reviewed 2026-10-07 02:57:03 +08:00
chatgpt-codex-connector[bot] (Migrated from github.com) left a comment

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ee09e59742

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

### 💡 Codex Review Here are some automated review suggestions for this pull request. **Reviewed commit:** `ee09e59742` <details> <summary>ℹ️ About Codex in GitHub</summary> <br/> [Your team has set up Codex to review pull requests in this repo](https://chatgpt.com/codex/cloud/settings/general). Reviews are triggered when you - Open a pull request for review - Mark a draft as ready - Comment "@codex review". If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". </details>
chatgpt-codex-connector[bot] (Migrated from github.com) commented 2026-10-07 02:57:04 +08:00

P1 Badge Compare the server PID by executable path

On Linux, ps -o comm= returns only the executable basename, not its full path (the GNU ps manual defines comm as “only the executable name”), so this comparison of fast_ship with $V/scratch/fast_ship always fails and Doctor aborts before every verification run. Cleanup repeats the same comparison at line 183, so a run that reaches teardown also leaves its own server running; use a path-aware identity check such as /proc/$PID/exe or compare against the basename.

Useful? React with 👍 / 👎.

**<sub><sub>![P1 Badge](https://img.shields.io/badge/P1-orange?style=flat)</sub></sub> Compare the server PID by executable path** On Linux, `ps -o comm=` returns only the executable basename, not its full path (the GNU `ps` manual defines `comm` as “only the executable name”), so this comparison of `fast_ship` with `$V/scratch/fast_ship` always fails and Doctor aborts before every verification run. Cleanup repeats the same comparison at line 183, so a run that reaches teardown also leaves its own server running; use a path-aware identity check such as `/proc/$PID/exe` or compare against the basename. Useful? React with 👍 / 👎.
chatgpt-codex-connector[bot] (Migrated from github.com) commented 2026-10-07 02:57:03 +08:00

P1 Badge Redact passwords before writing ARIA evidence

When the register or login command calls shot after filling the form, this aria_snapshot() includes the password input's value, so register-form.aria.txt and login-form.aria.txt contain the plaintext password despite the skill's rule that credentials never enter evidence. Playwright's ARIA serialization exposes input values, including password fields (official issue); omit these pre-submit snapshots or redact password controls before writing them.

Useful? React with 👍 / 👎.

**<sub><sub>![P1 Badge](https://img.shields.io/badge/P1-orange?style=flat)</sub></sub> Redact passwords before writing ARIA evidence** When the `register` or `login` command calls `shot` after filling the form, this `aria_snapshot()` includes the password input's value, so `register-form.aria.txt` and `login-form.aria.txt` contain the plaintext password despite the skill's rule that credentials never enter evidence. Playwright's ARIA serialization exposes input values, including password fields ([official issue](https://github.com/microsoft/playwright-cli/issues/317)); omit these pre-submit snapshots or redact password controls before writing them. Useful? React with 👍 / 👎.
gitbobobo commented 2026-10-07 02:59:23 +08:00 (Migrated from github.com)

Code Bot 审查结论(P2 密码泄漏 + Note 进程识别可移植性)

两条都是真问题,已在 c47ca99 修复并重验:

P2 密码进证据:fsdrive.py 的 shot() 在写 .aria.txt 前,先 eval_on_selector_all("input[type=password]") 收集密码框的值并统一替换成 •••。实跑验证:注册哨兵密码 S3ntinel-Pw9 后 register-form.aria.txt 输出 textbox "密码": •••,全证据目录 grep 零命中。PNG 本来就只渲染掩码,无需处理。

Note 可移植性:Doctor 与 Cleanup 的 PID 身份核对从 ps -o comm= 改为 ps -o args= 首字段比对(comm 在 Linux 只给截断进程名,macOS 才是完整路径),Linux/macOS 通用。Doctor 断言块整体包进 ( … ) 子 shell,fail 的 exit 1 不再带走粘贴执行的会话。已在活实例上验证:DOCTOR OK、负路径 exit 1、cleanup 杀自己 PID 后端口释放。

> Code Bot 审查结论(P2 密码泄漏 + Note 进程识别可移植性) 两条都是真问题,已在 c47ca99 修复并重验: **P2 密码进证据**:`fsdrive.py` 的 `shot()` 在写 `.aria.txt` 前,先 `eval_on_selector_all("input[type=password]")` 收集密码框的值并统一替换成 `•••`。实跑验证:注册哨兵密码 `S3ntinel-Pw9` 后 `register-form.aria.txt` 输出 `textbox "密码": •••`,全证据目录 grep 零命中。PNG 本来就只渲染掩码,无需处理。 **Note 可移植性**:Doctor 与 Cleanup 的 PID 身份核对从 `ps -o comm=` 改为 `ps -o args=` 首字段比对(`comm` 在 Linux 只给截断进程名,macOS 才是完整路径),Linux/macOS 通用。Doctor 断言块整体包进 `( … )` 子 shell,`fail` 的 `exit 1` 不再带走粘贴执行的会话。已在活实例上验证:DOCTOR OK、负路径 exit 1、cleanup 杀自己 PID 后端口释放。
gitbobobo commented 2026-10-07 02:59:25 +08:00 (Migrated from github.com)

@CodeBot review

@CodeBot review
gitbobobo commented 2026-10-07 03:01:44 +08:00 (Migrated from github.com)

Code Bot 审查结论:

审查范围:HEAD c47ca99(复审,上轮 ee09e59),增量为 fsdrive.py 的 shot() 密码掩码与 SKILL.md 的 Doctor / Cleanup 进程识别改动。

上轮问题处理情况:

  • P2 Doctor / Cleanup 用 ps -o comm= 在 Linux 失效 — 已修复。已在 Linux 上按 Launch 的 nohup "$V/scratch/fast_ship" 方式实测,ps -p PID -o args= | awk '{print $1}' 得到的就是完整路径,与 $V/scratch/fast_ship 相等。

  • Note Doctor 的 exit 1 会退掉持久 shell — 已修复,整块已包进 ( … )。

  • Note SKILL.md description 声称覆盖 versions、documents、logs、settings,但 feature map 只有 5 个功能 — 仍未处理。

  • P2 register / login 把明文密码写进 evidence — 部分修复,见下条。

  • P2 密码掩码用原始值对快照文本做 str.replace,一部分密码仍会以明文落进 .aria.txt — aria_snapshot() 输出的不是 input.value 原文:它会合并空白(连续空格、Tab 变成单个空格,末尾空格被去掉),遇到 : 、 # 等需要 YAML 加引号的值时,会把 " 和 \ 转义。这样快照里的文本和原值对不上,replace 匹配不到。我用同版本的 shot() 写法实测:a b 输出 a b,end 输出 end,a"b: c 输出 "a\"b: c",x\y #z 输出 "x\\y #z",都没被掩码。普通测试密码(如 VerifyPass1、p@ss"w0rd!)确实能掩掉,但用 login 跑真实账号时,带空格或符号的强密码仍可能泄漏,和「凭据永不进 evidence」的规则冲突。更稳的做法是不依赖文本匹配:取快照前先把密码框的 DOM value 临时换成占位符,快照后再恢复;或者提交前那一张只截 .png,不写 .aria.txt。

  • Note 同一个 replace 也会替换页面上其他与密码相同的文本。用短密码或常见词做测试时,快照里的正常文案可能被改成 •••,影响证据可读性。改成上面不靠文本匹配的方案后,这个问题也会一起消失。

复审

如需复审,请单独在顶层评论回复 @CodeBot review

**Code Bot 审查结论:** 审查范围:HEAD `c47ca99`(复审,上轮 `ee09e59`),增量为 `fsdrive.py` 的 `shot()` 密码掩码与 SKILL.md 的 Doctor / Cleanup 进程识别改动。 上轮问题处理情况: - **P2** Doctor / Cleanup 用 `ps -o comm=` 在 Linux 失效 — **已修复**。已在 Linux 上按 Launch 的 `nohup "$V/scratch/fast_ship"` 方式实测,`ps -p PID -o args= | awk '{print $1}'` 得到的就是完整路径,与 `$V/scratch/fast_ship` 相等。 - **Note** Doctor 的 `exit 1` 会退掉持久 shell — **已修复**,整块已包进 `( … )`。 - **Note** SKILL.md description 声称覆盖 versions、documents、logs、settings,但 feature map 只有 5 个功能 — 仍未处理。 - **P2** `register` / `login` 把明文密码写进 evidence — **部分修复**,见下条。 - **P2** 密码掩码用原始值对快照文本做 `str.replace`,一部分密码仍会以明文落进 `.aria.txt` — `aria_snapshot()` 输出的不是 `input.value` 原文:它会合并空白(连续空格、Tab 变成单个空格,末尾空格被去掉),遇到 `: `、` #` 等需要 YAML 加引号的值时,会把 `"` 和 `\` 转义。这样快照里的文本和原值对不上,`replace` 匹配不到。我用同版本的 `shot()` 写法实测:`a b` 输出 `a b`,`end ` 输出 `end`,`a"b: c` 输出 `"a\"b: c"`,`x\y #z` 输出 `"x\\y #z"`,都没被掩码。普通测试密码(如 `VerifyPass1`、`p@ss"w0rd!`)确实能掩掉,但用 `login` 跑真实账号时,带空格或符号的强密码仍可能泄漏,和「凭据永不进 evidence」的规则冲突。更稳的做法是不依赖文本匹配:取快照前先把密码框的 DOM value 临时换成占位符,快照后再恢复;或者提交前那一张只截 `.png`,不写 `.aria.txt`。 - **Note** 同一个 `replace` 也会替换页面上其他与密码相同的文本。用短密码或常见词做测试时,快照里的正常文案可能被改成 `•••`,影响证据可读性。改成上面不靠文本匹配的方案后,这个问题也会一起消失。 <details> <summary>复审</summary> 如需复审,请单独在顶层评论回复 `@CodeBot review` </details>
gitbobobo commented 2026-10-07 03:14:05 +08:00 (Migrated from github.com)

Code Bot 复审结论(掩码 str.replace 可被 aria 序列化绕过 + 误伤相同文案)

P2 掩码不可靠 — 已在 a6e7a11 改为你建议的方案:shot() 不再做文本匹配,序列化前用 eval_on_selector_all 把所有 input[type=password] 的 DOM value 置为 •••,拿到快照后在 finally 里按序恢复原值。实测验证:登录表单填入 a b" c: end (连续空格+引号+冒号+尾随空格,正是文本匹配会漏的组合),login-tricky.aria.txt 输出 textbox "密码": •••,全证据目录 grep 无任何密码片段;恢复后字段值与原文一致(断言通过)。误伤相同文案的问题也随之消失。

Note description 范围夸大 — 已修:frontmatter 的 surface 列表从 "auth, projects, issues, versions, documents, logs, settings" 收敛为 feature map 实际覆盖的 "auth, projects, issues, API keys"。

另:Codex 在 ee09e59 上留的两条 P1(aria 明文密码、ps -o comm= Linux 不兼容)分别对应本 PR 的 c47ca99 与 a6e7a11 修复,均已闭环。

> Code Bot 复审结论(掩码 str.replace 可被 aria 序列化绕过 + 误伤相同文案) **P2 掩码不可靠** — 已在 a6e7a11 改为你建议的方案:`shot()` 不再做文本匹配,序列化前用 `eval_on_selector_all` 把所有 `input[type=password]` 的 DOM `value` 置为 `•••`,拿到快照后在 `finally` 里按序恢复原值。实测验证:登录表单填入 `a b" c: end `(连续空格+引号+冒号+尾随空格,正是文本匹配会漏的组合),`login-tricky.aria.txt` 输出 `textbox "密码": •••`,全证据目录 grep 无任何密码片段;恢复后字段值与原文一致(断言通过)。误伤相同文案的问题也随之消失。 **Note description 范围夸大** — 已修:frontmatter 的 surface 列表从 "auth, projects, issues, versions, documents, logs, settings" 收敛为 feature map 实际覆盖的 "auth, projects, issues, API keys"。 另:Codex 在 `ee09e59` 上留的两条 P1(aria 明文密码、`ps -o comm=` Linux 不兼容)分别对应本 PR 的 c47ca99 与 a6e7a11 修复,均已闭环。
gitbobobo commented 2026-10-07 03:14:06 +08:00 (Migrated from github.com)

@CodeBot review

@CodeBot review
gitbobobo commented 2026-10-07 03:14:08 +08:00 (Migrated from github.com)

@codex review

@codex review
gitbobobo commented 2026-10-07 03:15:27 +08:00 (Migrated from github.com)

Code Bot 审查结论:

审查范围:HEAD a6e7a11(复审,上轮 c47ca99),增量为 fsdrive.py 中 shot() 的密码掩码改法和 SKILL.md frontmatter 的 description。

上轮问题处理情况:

  • P2 密码掩码用 str.replace 做文本匹配,带空白或需 YAML 转义的密码仍会明文进 .aria.txt — 已修复。现在在调用 aria_snapshot() 前把所有 input[type=password] 的 DOM value 临时改成 •••,并在 finally 里按顺序恢复。我用同样写法在 Linux 无头 Chrome 上实测:两个密码框分别填 a b" c: end (连续空格、引号、冒号、尾随空格)和 x\y #z,快照输出都是 textbox "密码": •••,恢复后的值与原值逐个相等。PNG 先于掩码截取,而浏览器本身只渲染圆点,没有泄漏。
  • Note replace 会误伤页面上与密码相同的文本 — 已修复,不再做文本匹配,这个问题随之消失。
  • Note SKILL.md description 声称的覆盖面多于 feature map — 已修复,现在只列 auth、projects、issues、API keys,与 features/ 一致。

本轮未发现需处理的问题。

复审

如需复审,请单独在顶层评论回复 @CodeBot review

**Code Bot 审查结论:** 审查范围:HEAD `a6e7a11`(复审,上轮 `c47ca99`),增量为 `fsdrive.py` 中 `shot()` 的密码掩码改法和 SKILL.md frontmatter 的 description。 上轮问题处理情况: - **P2** 密码掩码用 `str.replace` 做文本匹配,带空白或需 YAML 转义的密码仍会明文进 `.aria.txt` — **已修复**。现在在调用 `aria_snapshot()` 前把所有 `input[type=password]` 的 DOM `value` 临时改成 `•••`,并在 `finally` 里按顺序恢复。我用同样写法在 Linux 无头 Chrome 上实测:两个密码框分别填 `a b" c: end `(连续空格、引号、冒号、尾随空格)和 `x\y #z`,快照输出都是 `textbox "密码": •••`,恢复后的值与原值逐个相等。PNG 先于掩码截取,而浏览器本身只渲染圆点,没有泄漏。 - **Note** `replace` 会误伤页面上与密码相同的文本 — **已修复**,不再做文本匹配,这个问题随之消失。 - **Note** SKILL.md description 声称的覆盖面多于 feature map — **已修复**,现在只列 auth、projects、issues、API keys,与 `features/` 一致。 本轮未发现需处理的问题。 <details> <summary>复审</summary> 如需复审,请单独在顶层评论回复 `@CodeBot review` </details>
chatgpt-codex-connector[bot] (Migrated from github.com) reviewed 2026-10-07 03:15:57 +08:00
chatgpt-codex-connector[bot] (Migrated from github.com) left a comment

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a6e7a1159f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

### 💡 Codex Review Here are some automated review suggestions for this pull request. **Reviewed commit:** `a6e7a1159f` <details> <summary>ℹ️ About Codex in GitHub</summary> <br/> [Your team has set up Codex to review pull requests in this repo](https://chatgpt.com/codex/cloud/settings/general). Reviews are triggered when you - Open a pull request for review - Mark a draft as ready - Comment "@codex review". If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". </details>
@ -0,0 +49,4 @@
FAST_SHIP_SERVER_MODE=release \
FAST_SHIP_DATABASE_PATH="$V/scratch/data/fast_ship.db" \
FAST_SHIP_UPLOAD_STORAGE_PATH="$V/scratch/data/uploads" \
FAST_SHIP_WEB_DIST_DIR="$REPO/web/dist" \
chatgpt-codex-connector[bot] (Migrated from github.com) commented 2026-10-07 03:15:58 +08:00

P1 Badge Bind the isolation settings before launching the server

The launch command relies on FAST_SHIP_SERVER_PORT, FAST_SHIP_DATABASE_PATH, FAST_SHIP_UPLOAD_STORAGE_PATH, and FAST_SHIP_ISSUES_AUTO_SYNC_ENABLED to isolate each run, but config.Load only explicitly binds server.mode, database.log_sql, jwt.secret, encryption.key, and server.web_dist_dir; Viper's AutomaticEnv values are not populated by Unmarshal for these unbound keys. As a result, the binary uses the YAML defaults (port 4888, ./data/fast_ship.db, shared uploads, and auto-sync enabled), so the documented verification either collides with another instance or mutates the shared database and may contact GitHub.

Useful? React with 👍 / 👎.

**<sub><sub>![P1 Badge](https://img.shields.io/badge/P1-orange?style=flat)</sub></sub> Bind the isolation settings before launching the server** The launch command relies on `FAST_SHIP_SERVER_PORT`, `FAST_SHIP_DATABASE_PATH`, `FAST_SHIP_UPLOAD_STORAGE_PATH`, and `FAST_SHIP_ISSUES_AUTO_SYNC_ENABLED` to isolate each run, but `config.Load` only explicitly binds `server.mode`, `database.log_sql`, `jwt.secret`, `encryption.key`, and `server.web_dist_dir`; Viper's `AutomaticEnv` values are not populated by `Unmarshal` for these unbound keys. As a result, the binary uses the YAML defaults (port 4888, `./data/fast_ship.db`, shared uploads, and auto-sync enabled), so the documented verification either collides with another instance or mutates the shared database and may contact GitHub. Useful? React with 👍 / 👎.
gitbobobo (Migrated from github.com) reviewed 2026-10-07 03:17:39 +08:00
@ -0,0 +49,4 @@
FAST_SHIP_SERVER_MODE=release \
FAST_SHIP_DATABASE_PATH="$V/scratch/data/fast_ship.db" \
FAST_SHIP_UPLOAD_STORAGE_PATH="$V/scratch/data/uploads" \
FAST_SHIP_WEB_DIST_DIR="$REPO/web/dist" \
gitbobobo (Migrated from github.com) commented 2026-10-07 03:17:39 +08:00

这条对旧版本 Viper 成立,但本项目不适用——四个隔离键都经由 AutomaticEnv 生效:

  1. config.Load(server/internal/config/config.go:54-56)设置了 SetEnvPrefix("FAST_SHIP") + SetEnvKeyReplacer(".", "_") + AutomaticEnv(),go.mod 里 viper 是 v1.21.0——Unmarshal 遍历 AllKeys() 时对每个键走 Get,Get 会查 AutomaticEnv 绑定的环境变量,配置文件里存在的键都能被 env 覆盖。
  2. 被覆盖的四个键(server.port、database.path、upload.storage_path、issues.auto_sync_enabled)都真实存在于 server/configs/config.yaml,所以都在 AllKeys() 里,不存在「未显式 BindEnv 所以 Unmarshal 读不到」的问题。

实证:本 PR 的整轮验证就依赖这套覆盖——验证实例在 5088 监听时本机 4888 正被另一个 fast_ship 实例占用,若 env 不生效会去撞 4888 直接启动失败;数据库读写落在 $V/scratch/data/fast_ship.db(db-*.txt 读回证据即来自该文件);Doctor 也断言「端口属主 PID + /api/auth/me 401 + 启动日志」。假设哪天 env 真的失效,Doctor 的端口/属主断言会第一时间失败,不会静默用上共享实例。

这条对旧版本 Viper 成立,但本项目不适用——四个隔离键都经由 `AutomaticEnv` 生效: 1. `config.Load`(server/internal/config/config.go:54-56)设置了 `SetEnvPrefix("FAST_SHIP")` + `SetEnvKeyReplacer(".", "_")` + `AutomaticEnv()`,go.mod 里 viper 是 v1.21.0——`Unmarshal` 遍历 `AllKeys()` 时对每个键走 `Get`,`Get` 会查 AutomaticEnv 绑定的环境变量,配置文件里存在的键都能被 env 覆盖。 2. 被覆盖的四个键(`server.port`、`database.path`、`upload.storage_path`、`issues.auto_sync_enabled`)都真实存在于 `server/configs/config.yaml`,所以都在 `AllKeys()` 里,不存在「未显式 BindEnv 所以 Unmarshal 读不到」的问题。 实证:本 PR 的整轮验证就依赖这套覆盖——验证实例在 `5088` 监听时本机 `4888` 正被另一个 fast_ship 实例占用,若 env 不生效会去撞 `4888` 直接启动失败;数据库读写落在 `$V/scratch/data/fast_ship.db`(`db-*.txt` 读回证据即来自该文件);Doctor 也断言「端口属主 PID + `/api/auth/me` 401 + 启动日志」。假设哪天 env 真的失效,Doctor 的端口/属主断言会第一时间失败,不会静默用上共享实例。
gitbobobo commented 2026-10-07 03:22:40 +08:00 (Migrated from github.com)

应要求把技能从 skills/verify-fast-ship/ 移到了 .agents/skills/verify-fast-ship/(fa3f805):根目录 skills/ 是对外分发的位置(fast-ship、version-release),verify-fast-ship 是仓库内部验证技能,属于 .agents/。纯 git mv,内容仅改两处驱动路径引用(SKILL.md $DRV、features/auth.md $DRV_NOAUTH)。

应要求把技能从 `skills/verify-fast-ship/` 移到了 `.agents/skills/verify-fast-ship/`(fa3f805):根目录 `skills/` 是对外分发的位置(fast-ship、version-release),verify-fast-ship 是仓库内部验证技能,属于 `.agents/`。纯 `git mv`,内容仅改两处驱动路径引用(SKILL.md `$DRV`、features/auth.md `$DRV_NOAUTH`)。
gitbobobo commented 2026-10-07 03:22:42 +08:00 (Migrated from github.com)

@CodeBot review

@CodeBot review
gitbobobo commented 2026-10-07 03:23:55 +08:00 (Migrated from github.com)

Code Bot 审查结论:

审查范围:HEAD fa3f805(复审,上轮 a6e7a11),增量为把技能目录从 skills/verify-fast-ship/ 整体移到 .agents/skills/verify-fast-ship/。

本轮核对:

  • 8 个文件均为 rename,内容只改了 SKILL.md 的 $DRV 和 features/auth.md 的 $DRV_NOAUTH 两处驱动路径,已确认两处都指向新位置 $REPO/.agents/skills/verify-fast-ship/scripts/fsdrive.py。

  • 移动后技能目录内已没有残留的旧路径 skills/verify-fast-ship;fsdrive.py 不依赖 __file__ 或目录层级(scratch 由 --evidence 的父目录推出,$REPO 由 git rev-parse --show-toplevel 得到),多嵌套一层不影响运行。

  • AGENTS.md、CLAUDE.md、README.md、Makefile、CI workflow、.gitignore / .dockerignore 都没有引用旧路径,也没有忽略 .agents/;根目录 skills/ 现在只剩对外分发的 fast-ship 和 version-release。

  • 上轮已修复的问题(密码掩码改为临时替换 DOM value、PID 用 ps -o args= 比对、Doctor 子 shell、description 覆盖面)在新位置的文件里保持不变。

  • Note PR 描述还停留在旧位置 — 「改动内容」写的是 skills/verify-fast-ship/,「修改范围」写的是 skills/、.gitignore,建议同步成 .agents/skills/,免得合并后按描述找不到文件。

本轮未发现需处理的问题。

复审

如需复审,请单独在顶层评论回复 @CodeBot review

**Code Bot 审查结论:** 审查范围:HEAD `fa3f805`(复审,上轮 `a6e7a11`),增量为把技能目录从 `skills/verify-fast-ship/` 整体移到 `.agents/skills/verify-fast-ship/`。 本轮核对: - 8 个文件均为 rename,内容只改了 SKILL.md 的 `$DRV` 和 `features/auth.md` 的 `$DRV_NOAUTH` 两处驱动路径,已确认两处都指向新位置 `$REPO/.agents/skills/verify-fast-ship/scripts/fsdrive.py`。 - 移动后技能目录内已没有残留的旧路径 `skills/verify-fast-ship`;`fsdrive.py` 不依赖 `__file__` 或目录层级(scratch 由 `--evidence` 的父目录推出,`$REPO` 由 `git rev-parse --show-toplevel` 得到),多嵌套一层不影响运行。 - `AGENTS.md`、`CLAUDE.md`、`README.md`、`Makefile`、CI workflow、`.gitignore` / `.dockerignore` 都没有引用旧路径,也没有忽略 `.agents/`;根目录 `skills/` 现在只剩对外分发的 `fast-ship` 和 `version-release`。 - 上轮已修复的问题(密码掩码改为临时替换 DOM value、PID 用 `ps -o args=` 比对、Doctor 子 shell、description 覆盖面)在新位置的文件里保持不变。 - **Note** PR 描述还停留在旧位置 — 「改动内容」写的是 `skills/verify-fast-ship/`,「修改范围」写的是 `skills/、.gitignore`,建议同步成 `.agents/skills/`,免得合并后按描述找不到文件。 本轮未发现需处理的问题。 <details> <summary>复审</summary> 如需复审,请单独在顶层评论回复 `@CodeBot review` </details>
gitbobobo commented 2026-10-07 03:28:36 +08:00 (Migrated from github.com)

Code Bot 复审:PR 描述还停留在旧位置

已修:gh pr edit 把描述里三处 skills/verify-fast-ship / skills/ 更新为 .agents/skills/(「改动内容」「修改范围」「替代证据」段),现在与 fa3f805 的实际文件位置一致。

> Code Bot 复审:PR 描述还停留在旧位置 已修:`gh pr edit` 把描述里三处 `skills/verify-fast-ship` / `skills/` 更新为 `.agents/skills/`(「改动内容」「修改范围」「替代证据」段),现在与 fa3f805 的实际文件位置一致。
gitbobobo commented 2026-10-07 03:31:32 +08:00 (Migrated from github.com)

version-release 同样是仓库内部技能(只在仓库内驱动 make release,不被外部安装),已一并移入 .agents/skills/version-release/(0d95776)。现在 skills/ 只剩对外分发的 fast-ship API 技能;README 项目结构补了一行标注两个目录的分工。version-release 的 SKILL.md 无自引用路径,纯 rename。

version-release 同样是仓库内部技能(只在仓库内驱动 `make release`,不被外部安装),已一并移入 `.agents/skills/version-release/`(0d95776)。现在 `skills/` 只剩对外分发的 `fast-ship` API 技能;README 项目结构补了一行标注两个目录的分工。version-release 的 SKILL.md 无自引用路径,纯 rename。
gitbobobo commented 2026-10-07 03:31:33 +08:00 (Migrated from github.com)

@CodeBot review

@CodeBot review
gitbobobo commented 2026-10-07 03:33:07 +08:00 (Migrated from github.com)

Code Bot 审查结论:

审查范围:HEAD 0d95776(复审,上轮 fa3f805),增量为把 skills/version-release/ 移到 .agents/skills/version-release/,以及 README 项目结构的两行说明。

上轮问题处理情况:

  • Note PR 描述还停留在旧位置 — 已修复,「改动内容」「替代证据」已改为 .agents/skills/verify-fast-ship/。

本轮核对:

  • version-release/SKILL.md 是纯 rename(blob 不变),内容只引用 make release / scripts/release.sh / VERSION,没有依赖自身目录的路径。

  • 在 HEAD 上全仓检索 version-release 和 skills/:Makefile、scripts/、两个 CI workflow、AGENTS.md、CLAUDE.md、.cursor/rules/、.gitignore / .dockerignore 都没有引用旧路径;剩下的 skills/ 引用全部指向 skills/fast-ship(apidocgen 输出路径和测试、make api-docs 说明、README 链接),未受影响。

  • README 新增的两行目录说明与实际结构一致:根目录 skills/ 只剩 fast-ship,.agents/skills/ 下是 verify-fast-ship 和 version-release。

  • Note PR 描述和标题没覆盖这次的额外改动 — 「修改范围」仍写 .agents/skills/、.gitignore,没提 README.md,也没提 version-release 从 skills/ 迁出;标题只说新增 verify-fast-ship。建议在描述里补一句,方便以后按 PR 追溯这次目录调整。

本轮未发现需处理的问题。

复审

如需复审,请单独在顶层评论回复 @CodeBot review

**Code Bot 审查结论:** 审查范围:HEAD `0d95776`(复审,上轮 `fa3f805`),增量为把 `skills/version-release/` 移到 `.agents/skills/version-release/`,以及 README 项目结构的两行说明。 上轮问题处理情况: - **Note** PR 描述还停留在旧位置 — **已修复**,「改动内容」「替代证据」已改为 `.agents/skills/verify-fast-ship/`。 本轮核对: - `version-release/SKILL.md` 是纯 rename(blob 不变),内容只引用 `make release` / `scripts/release.sh` / `VERSION`,没有依赖自身目录的路径。 - 在 HEAD 上全仓检索 `version-release` 和 `skills/`:`Makefile`、`scripts/`、两个 CI workflow、`AGENTS.md`、`CLAUDE.md`、`.cursor/rules/`、`.gitignore` / `.dockerignore` 都没有引用旧路径;剩下的 `skills/` 引用全部指向 `skills/fast-ship`(`apidocgen` 输出路径和测试、`make api-docs` 说明、README 链接),未受影响。 - README 新增的两行目录说明与实际结构一致:根目录 `skills/` 只剩 `fast-ship`,`.agents/skills/` 下是 `verify-fast-ship` 和 `version-release`。 - **Note** PR 描述和标题没覆盖这次的额外改动 — 「修改范围」仍写 `.agents/skills/、.gitignore`,没提 `README.md`,也没提 `version-release` 从 `skills/` 迁出;标题只说新增 verify-fast-ship。建议在描述里补一句,方便以后按 PR 追溯这次目录调整。 本轮未发现需处理的问题。 <details> <summary>复审</summary> 如需复审,请单独在顶层评论回复 `@CodeBot review` </details>
gitbobobo commented 2026-10-07 03:36:16 +08:00 (Migrated from github.com)

Code Bot 复审:PR 描述和标题没覆盖 version-release 迁移

已修:「改动内容」补了一段说明技能目录的分工(skills/ 对外分发、.agents/skills/ 仓库内部)及 version-release 的迁入;「修改范围」更新为 .agents/skills/(新增 verify-fast-ship、迁入 version-release)、skills/(迁出 version-release)、.gitignore、README.md。标题保持不动——本单主体仍是新增 verify-fast-ship,version-release 迁移是顺带的目录归位,描述里已可追溯。

> Code Bot 复审:PR 描述和标题没覆盖 version-release 迁移 已修:「改动内容」补了一段说明技能目录的分工(`skills/` 对外分发、`.agents/skills/` 仓库内部)及 `version-release` 的迁入;「修改范围」更新为 `.agents/skills/(新增 verify-fast-ship、迁入 version-release)、skills/(迁出 version-release)、.gitignore、README.md`。标题保持不动——本单主体仍是新增 verify-fast-ship,version-release 迁移是顺带的目录归位,描述里已可追溯。
Sign in to join this conversation.
No description provided.