memory: goalctl 两处口径分叉修复记录(§40)+ vibe-product 收口挂账
This commit is contained in:
1 parent
1b68b1ac3f
commit
0cf981f419
1 file changed
+81
@@ -288,3 +288,84 @@
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 40、goalctl 两处口径分叉修复(用户 ⑤-2「vibe-product 最新会话反应新问题 看看如何解决」)
|
||||
|
||||
### 40.1 是什么问题
|
||||
|
||||
vibe-product 上一条会话(10-06 08:15~08:20)已诊断出两条缺陷并**修了数据侧**(换任务图、存值改 `pass`),
|
||||
但它自己在记忆里登记了「**同族缺陷未修 / 技能侧缺陷未修**」⇒ 我这一轮把**技能侧**修了。
|
||||
|
||||
用户在 ⑤-2 里说的「新问题」,逐字对应那份 `目标执行状态.md` 的两条**阻断**:
|
||||
|
||||
| 阻断 | 内容 | 归属 |
|
||||
|---|---|---|
|
||||
| ① | `goal.json.execution_doc` 指向**前身目标的目录**(换目标漏改) | 工作区数据(前一会话已修) |
|
||||
| ② | 本目标**从未建立过任务会话**(零排期)+ `NEXT.md` 是过期投影 | 工作区数据(已随目标完成自然消解) |
|
||||
|
||||
⇒ 但**真正跨工作区、属技能侧的根因有两处**,前一会话只**绕开**了、没修:
|
||||
|
||||
### 40.2 🔴 根因一:`goalctl.py:262` 判定层死板比字面值
|
||||
|
||||
- 原文:`if str(acc[k]) != "pass":` —— **只认英文 `pass`**。
|
||||
- 而存值**真源就是中文**(`过|pid 8024 活…` / `已过|…` / `达(1440 与 390 两视口都有)`)。
|
||||
- ⇒ 已通过的验收**全部被计入 why** ⇒ 恒判「未完成」⇒ 控制台打出
|
||||
「未完成(验收 V1=过;V2=过;…)」这种**字面自相矛盾**的读数。
|
||||
- 🔴 **病根不只是这一行**:`board.py::acc_is_pass()` 的 docstring 明写
|
||||
「三处判据(`board.py` / `collabd.py::_acc_is_pass` / `board.html::accIsPass`)**必须同款**」,
|
||||
而 `board.py:1618` 与 `collabd.py:3022` **都做了中文归一化**(`ACC_PASS_WORDS` + 剥完成副词)
|
||||
—— **实际是四处,`goalctl` 被漏掉了** ⇒ 同一字段三套读法。
|
||||
|
||||
### 40.3 🔴 根因二:`goalctl.py:136` 配置落点写死技能目录
|
||||
|
||||
- 原文:`CFG = HERE / "collabd.config.json"`,`HERE` = **技能包目录**。
|
||||
- 按定则「**技能就是技能、程序就是程序,谁用产生的文件放在他自己那里**」⇒
|
||||
**技能目录里⛔ 不放生产配置** ⇒ 该文件**恒不存在** ⇒ `_load(CFG,{})` 恒 `{}`。
|
||||
- ⇒ `taskgraph` 取默认 `INBOX/taskgraph.json` ⇒ **配置改了不生效**
|
||||
(实测:vibe-product 配置里已改指 proto-board,`goals_open()` 仍报「任务图读不到」)。
|
||||
- `collabd.py` 早有 `_cfg_candidates()` 三级解析(env → 工作区标准落点)⇒ **又是"一个技能两套读法"**。
|
||||
|
||||
### 40.4 处置
|
||||
|
||||
1. `goalctl` 新增 `_acc_is_pass()`:**复用 `collabd._acc_is_pass()`**(它自己再复用 `board` 真身);
|
||||
拿不到 ⇒ **fail-closed 声明式兜底**+stderr 留痕,⛔ 绝不静默返回。
|
||||
2. `CFG` 改为与 `collabd._cfg_candidates()` **同款三级**(env → 工作区标准落点 → 旧路径+告警)。
|
||||
3. 修正 `:605` 误导文案(原「要 `名字=pass` 或 `名字=未过`」——`未过` 与任意中文值旧判定层同样恒判未过)。
|
||||
4. 新增 2 条自检用例+`pitfalls.md` **P0-87**。
|
||||
|
||||
### 40.5 实测读数
|
||||
|
||||
| 项 | 修前 | 修后 |
|
||||
|---|---|---|
|
||||
| vibe-product `goalctl.goals_open()` | `{'open': True, 'why': [], 'bad': ['任务图读不到(taskgraph.json)']}` | **`{'open': False, 'why': [], 'bad': []}`** |
|
||||
| vibe-product `goalctl` 状态台 | (目标判不出来) | **「目标状态 = 三路全过」** |
|
||||
| 技能 `selftest` | PASS 97 / FAIL 0 | **PASS 99 / FAIL 0** |
|
||||
| `--verify` | — | **rc=0 ✅** |
|
||||
|
||||
**变异对照**:改回 `!= "pass"` ⇒ PASS 97 / FAIL 1(**命中本用例**);还原 ⇒ 99/0 ✅
|
||||
|
||||
### 40.6 🔴 两处踩坑(都是"我喂错了,不是代码错")
|
||||
|
||||
1. **`selftest` 的 `imp()` 加载的是 `collabd`,不是 `goalctl`** —— 两者 `goals_open()` **同名但返回类型不同**
|
||||
(collabd 返 `bool`、goalctl 返 `dict`)⇒ 直接用 ⇒ `TypeError: 'bool' object is not subscriptable`。
|
||||
2. **两个模块的 `INBOX` 不是同一个目录**(`collabd` 来自配置、`goalctl` 硬编码 `WS/tmp/supervise-inbox`)
|
||||
⇒ 夹具写错落点 ⇒ `bad=['任务图读不到']` ⇒ **用例恒红**。
|
||||
⭐ **教训:用例红了先分"被测代码错"还是"我喂错了"** —— 三次都是后者,
|
||||
若直接去"修代码",会把好的代码改坏。
|
||||
|
||||
### 40.7 🔴 又撞一次 CRLF(本轮第二次)
|
||||
|
||||
`goalctl.py` 工作副本被改成 **CRLF**(877 个 CR),HEAD 是 LF ⇒ `git diff` **整文件重写**
|
||||
(877 增 / 672 删)⇒ 按字节归一化回 LF ⇒ 降到 **228 增 / 23 删**真内容。
|
||||
**铁律:看到"整文件重写"先查行尾**(`b.count(b'\r')`)。前一次是 `board.html`。
|
||||
|
||||
### 40.8 挂账(未做,需用户拍板)
|
||||
|
||||
🔴 **vibe-product 的收口动作未做**:它的 `lifecycle` 仍是 `进行中`(前一会话只改了 `acceptance_state`,
|
||||
**没走收口流程**)⇒ 常驻程序**按设计继续跑**(收工只在 `--set-life 已完成` 时触发)。
|
||||
要收工=改 `lifecycle=已完成` ⇒ 会 **`supervise_stop` 停掉该工作区的常驻进程**。
|
||||
⚠️ 这属「**影响面超出本平台/跨工作区状态变更**」⇒ **先报用户,⛔ 不擅自动手**。
|
||||
⚠️ 另:vibe-product 常驻主循环跑的是**旧代码**(09-29 启动,配置改动需重启才生效)——
|
||||
本次修的是**技能源**,其工作区副本要同步+重启才生效(这一步同样未做)。
|
||||
Reference in new issue
Block a user