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
5 changes: 5 additions & 0 deletions WORKMEMORY/PROTOCOL.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
5. **UTF-8 写入**:所有 WORKMEMORY 文件一律 UTF-8;Windows 下禁止依赖控制台默认编码(GBK 陷阱)。
6. **禁止敏感信息**:work.log / handoff / NOTES 禁止 API key、token、密码字面量(引用名称即可);pre-commit 密钥扫描兜底。
7. **协议靠约定维持**:某 agent 漏写事件不是灾难——下一个 agent 读 tail 发现缺口时补一条 `NOTE` 说明即可,不回改历史。
8. **实现任务 MUST 在独立分支 / worktree 上做**:开工前先判分支 —— 实现 / 多步任务走分支 + PR 合入 `master`;
仅发版类操作(bump / tag / Release 文案 / 发版文档)允许直推 `master`(须用户批准)。
本条于 2026-10-14 补入:此前它只存在于 `dfs-pipeline` skill 与一条记忆里,本仓文档零命中
⇒ 2026-10-13 那批 9 个含生产源码与 CI 定义的提交全程直推 `master`、零 PR。完整复盘见
`docs/agents/ops.md`「Agent 工作惯例」第 9 条与 work.log 同日 NOTE。

## 2. 事件 Schema(work.log)

Expand Down
10 changes: 10 additions & 0 deletions WORKMEMORY/work.log
Original file line number Diff line number Diff line change
Expand Up @@ -644,3 +644,13 @@ Caps: filesystem-read, filesystem-write, shell-exec
- **门禁(本机实测)**:全量 **1814 passed + 2 skipped**(= 1800 + Task5 12 + 黄牌 2);ruff 0;mypy `--strict tools` 24 files / `--platform win32 --strict` 4 files 零错误。RED 收据均以**临时 git worktree 在改动前 HEAD 上跑新测试**取得(不污染主工作区)。
- **两条值得记的坑(都真实发生)**:① `Path.read_text()/write_text()` 默认通用换行翻译(CRLF↔`\n`)——子代理修 MUTATION 表时用 `write_text` 把测试文件写成 CRCRLF,靠 `git show HEAD:<file>` 取原字节二进制写回才复原;**动 CRLF 文件必须 `open(newline="")`,写完必须验 `CRCRLF==0`**(这与 10-12 那次自伤同族,今天第二次)。② 测试名/docstring **不许过度承诺**:`..._before_window_creation` 曾声称"挪到建窗之后会转红"却无顺序断言(虚报)⇒ 改为"隔离调用用例去时机承诺 + 位置无关 AST 顺序断言"双轨,变异矩阵证明"删/晚挪"红、"建窗前换函数"仍绿 ⇒ 调时机不会被迫删断言。
- **仍待办**:① **真机双击验收**(HITL,只能用户做):无黑框 / 品牌图标 / 冷启动 splash / 故意制造启动失败时有弹窗;若任务栏仍归 Python 组 ⇒ 调 AppUserModelID 时机。② **CI 首次真跑 no-console 步**(run 38430807173):必须去日志确认四行 `[PASS]` 而非 `[SKIP]`(本机无 dist/ 产物,该步①–④ 未在真实产物上执行过)。③ 本计划按「成果已发版」判据留待下一版发布后再归档。

### 2026-10-14 | codebuddy | NOTE 流程缺陷:2026-10-13 那批实现提交全程直推 master、零 PR
Caps: filesystem-read, filesystem-write, shell-exec
事件:用户指出「这次更新没有按要求开分支,直接在 master 上操作了」⇒ 复盘定因 + 补规则。
- **事实**:`0f7b80f`…`b05a367` 共 **9 个提交全在 `master`**,`git branch` 只有 master,**0 个 PR**;改动面含生产源码(`desktop.py` / `start.py`)、打包面(`package_windows.py`)、CI 定义(`ci.yml` / `build-release.yml` / `tools/verify_windows_portable.py`)。**实际损失 0**(CI 全绿、未产生红 master),但风险与「红 master 事故」(PR #117 在 CI 未跑完时被合并)同族:一旦 CI 红,红提交会**直接留在 master 历史里**。
- **根因三层(不是"忘了")**:① **规则不可见**——grep `AGENTS.md` / `docs/agents/ops.md` / `WORKMEMORY/PROTOCOL.md` / `PROJECT_OVERVIEW.md` **零命中**;规矩只存在于两处:`dfs-pipeline` 的 *Worktree Isolation Invariant*(本轮走 grill→plan→exec,**没调用 dfs-pipeline**)与一条**未打开的记忆 topic 文件** ⇒ 按 AGENTS.md 路由 bootstrap 的 agent 读不到它。② **流程缺环**——`dfs-plan` / `dfs-exec` / `plan-schema` 均**无任何 branch/worktree 步骤**;唯一带隔离不变量的是 `dfs-pipeline`。③ **上下文惯性 + 无机械闸**——会话由发版流程延续(发版在 master 上做且是用户批准的),切到实现任务未重新判定;分支纪律**没有机械闸**(对比:发版门 `tag == v+APP_VERSION` 是机械闸,同轮就抓到过一条写死旧 tag 名的测试)。**靠人记的规矩没有机械闸,必漏。**
- **我自己两点直接失误**:写计划(`0f7b80f`)时没把分支写进 Global Constraints;第一次 push 前没核分支。**且讽刺的是**——中途确实用过临时 worktree(`/tmp/del-red`,为 RED 取证据),工具在手却只当验证手段,没当成"工作发生的地方"。
- **修复(本次提交)**:`docs/agents/ops.md`「Agent 工作惯例」**第 12 条** + `WORKMEMORY/PROTOCOL.md` 铁律**第 8 条**写明——**实现 / 多步任务 MUST 走独立分支(或 worktree)+ PR 合入 master;仅发版类操作(bump / tag / Release 文案 / 发版文档)允许直推 master 且须用户批准**。**本次补规则的改动本身走分支 `docs/branch-discipline-rule` + PR**(否则"改规矩不守规矩",规则当场失效)。
- **暂缓**:给 `dfs-plan` / `dfs-exec` 补「分支隔离」步骤(全局 skill + 发布仓两侧同步)——用户指示 skill 先不动。
- **未做**:不回滚那 9 个提交(CI 全绿、历史已推送,重写收益低且风险高)。
9 changes: 9 additions & 0 deletions docs/agents/ops.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,15 @@ TTS 链路(真机判定层):`AndroidNativeTTS.speak`(系统 TTS,免网
- 判别法(先给用户做,不先改码):F12 → 右键刷新按钮 →「清空缓存并硬性重新加载」;
或开**无痕窗口**访问(无痕无缓存/SW = 服务器磁盘真实文件)。无痕正常 ⇒ 用户侧缓存,代码不用动。
- 教训:别在 `setupPWA`/`#sw-source` 上花时间"增强"离线——那段 SW 从没注册成功过。
12. **开工前先判分支(MUST)**:**实现 / 多步任务一律在独立分支(或 worktree)上做,再走 PR 合入 `master`**;
只有**发版类操作**(版本 bump / 打 tag / Release 文案 / 发版文档回填)允许直接在 `master` 上推,且推送前须用户显式批准。
为什么把这条写在这里:2026-10-13「去控制台 + 桌面化观感」那批 **9 个提交**(含生产源码 `desktop.py` / `start.py`、
打包面 `package_windows.py` 与 CI 定义 `ci.yml` / `build-release.yml` / `tools/verify_windows_portable.py`)**全程直推
`master`、零 PR**。事后复盘的根因**不是"忘了"**,而是这条规矩此前只存在于两处不可见的地方 ——
`dfs-pipeline` 的 Worktree Isolation Invariant(那轮没调用该 skill)与一条未打开的记忆文件 ——
而**本仓文档里一行都没有** ⇒ 按 `AGENTS.md` 路由做 bootstrap 的 agent 根本读不到它。
**机械对照**:发版门(`tag == v+APP_VERSION`)是机械闸,所以那类错误会被构建当场抓住(同轮就抓到过一条
写死旧 tag 名的测试);分支纪律**没有机械闸** ⇒ 只能靠"写进可见文档" + 推送前自问一句「我现在在哪个分支」。

---

Expand Down
Loading