pbl_kdb_ext/docs/work-log-2026-09-18.md
2026-09-18 19:14:31 +08:00

92 lines
8.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# pbl_kdb_ext 工作日志 —— 2026-09-18(QC 退回重做轮 + 第 3 轮摘要订正)
## 范围 / 背景
- 仓库/模块:机构工作空间 `modules/pbl_kdb_ext`(PBL Agent OS,项目 `projects/pbls`)
- 任务:`[M7] pbl_kdb_ext KDB 只读桩扩展`(pipeline_tasks.id = `OgtZuajAdd0y65BZdv8jr`,
iteration `pbls-初始迭代`,task_kind = new_dev → 第 2/3 轮为 QC 退回后的重做修复)
- 目标:逐条闭环 agent.qc 的退回意见,不扩大范围(G6 范围纪律:仍零写入,
不新增 kdb.write / research.write / sim.*)。
## 第 2 轮:QC 退回意见 → 处理结果(5 条,逐条)
| # | 位置 | 问题 | 处理 |
|---|------|------|------|
| 1 | `scripts/load_path.py` PATHS | 仅注册 3 个 `.dspy`,缺 `/pbl_kdb_ext` 与 `/pbl_kdb_ext/index.ui`,入口页上线即 403 | **已修**:PATHS 补两条 `logined` 记录(目录路径 + index.ui 文件路径),共 5 条,仍显式枚举无通配符 |
| 2 | `wwwroot/index.ui` 三处 `binds.options.url` | `{{entire_url('api/pbl_kdb_search.dspy')}}` 为相对路径,可能丢模块前缀 → RBAC 403(module-development-spec 2.3c) | **已修**:三处全部改为绝对路径 `{{entire_url('/pbl_kdb_ext/api/xxx.dspy')}}`(search / get / aggregate) |
| 3 | `scripts/load_path.py` 第 38 行 | `print(' PENDING %%-12s %s' %(role, path))` —— `%%` 转义后格式串只剩 1 个 `%s` 却传 2 个参数,出现 pending 必抛 TypeError,注册失败时脚本崩溃而非打印清单 | **已修**:改为 `print(' PENDING %-12s %s' % (role, path))`;同时给 `subprocess.call` 加 `try/except OSError`(CLI 不存在时归入 pending 而非崩溃),summary 行补上 MODULE 名 |
| 4 | `README.md` | 全文仅 15 字节 `# pbl_kdb_ext`,boilerplate-only(spec 明令禁止) | **已修**:重写为 8 节完整文档——模块用途(Q-OPEN-5/6 口径 + G6 范围纪律)、2 张表字段说明(pbl_kdb_item / pbl_kdb_query_log)+ 跨模块只读依赖、3 个契约接口(路径/入参/返回/错误码)、目录结构、挂载方式(load_pbl_kdb_ext + 三处同步铁律 + RBAC 表 + 库名)、只读/匿名聚合 8 条验收约束、依赖、本地校验命令 |
| 5 | 交付摘要清单 vs 磁盘 | 清单声称写入 `pbl_kdb_ext/errors.py`,实测不存在,声称与事实矛盾 | **已修(走"移除"分支)**:错误类型/错误码由公共内核 `pbl_common.api` 的 `PblError` 统一提供,本模块只抛出不另定义,故 `errors.py` **不是本任务应产出**,已从交付清单移除;README 第 3 节明确写出该决策,保证清单与盘上文件一一对应。`api.py` 的 import 闭包保持 `from pbl_common.api import PblError, ...` 不变,无悬空引用 |
## 第 3 轮:QC 退回意见 #1(摘要数字与实测不符)→ 处理结果
| 项 | 第 2 轮摘要声称 | 引擎核验 / `wc -c` 实测 | 本轮处理 |
|----|----------------|------------------------|---------|
| `scripts/load_path.py` | 1887B | **2399B**(60 行) | 摘要改为实测值 |
| `wwwroot/index.ui` | 4755B | **5025B**(171 行) | 摘要改为实测值 |
| `README.md` | 7839B | **11595B**(198 行) | 摘要改为实测值 |
| `docs/work-log-2026-09-18.md` | 3214B | **4962B**(52 行,订正前) | 摘要改为实测值 |
| `grep -c "%%" scripts/load_path.py` | 声称 = 0 | **实测 = 1** | 表述订正为「代码本体无 `%%`;仅第 51 行注释保留旧 bug 说明文本,故 `grep -c` 实测 = 1」 |
**根因**:第 2 轮摘要的字节数是**写入前的估算值**,未回读磁盘复核;`grep -c "%%"` 的结论
只核对了代码行、忽略了第 51 行注释里为说明旧 bug 而保留的 `%%-12s` 字面文本。
**改法(本轮)**:① 交付摘要的「写入清单」与「验证」两段全部改为 `wc -c` / `wc -l`
实测值,并附核对命令,任何审核方可一键复现;② 本工作日志同步订正下方「验证」段的
`grep -c "%%"` 结论(原写 = 0,实测 = 1);③ **代码文件零改动**——`api.py` / `init.py` /
`__init__.py` / `wwwroot/api/*.dspy` / `models/*.json` / `json/*.json` / `sql/*.sql` /
`scripts/load_path.py` 本轮均未修改(`git status` 干净可证),本轮只动文档。
## 关键技术决策
1. **errors.py 取舍**:两个合法分支(补写并纳入 import 闭包 / 从清单移除)中选**移除**。
理由:`PblError` 与错误码体系属 `pbl_common` 公共内核职责,模块内再建 errors.py 会与
公共内核重复定义、增加两处维护点;本模块仅 2 个错误码(`PBL_KDB_NOT_FOUND`、
`PBL_AGG_DIM_INVALID`),直接在 api.py 抛出即可。
2. **load_path.py 健壮性**:QC #3 的根因是"失败路径未被测过"。除修格式串外,补
`try/except OSError`,使 `set_role_perm.py` 不在位时走 pending 打印分支(退出码 1),
而不是抛 FileNotFoundError 让 build.sh 第 8 步整体中断。
3. **第 51 行注释保留 `%%-12s` 字面文本的取舍**:该注释是旧 bug 的说明证据(便于后来者
理解为何格式串必须与实参个数一致),删掉会让 `grep -c "%%"` 变 0 但丢失上下文。
选择**保留注释、订正摘要表述**——QC 亦明确「代码文件本身零改动」。
4. **index.ui 保持纯 JSON**:入口页三张卡片(VBox + binds click → `actiontype: urlwidget`
→ `target: app.pbl_kdb_ext_content`,`mode: replace`),内容区 VBox 的 `id` 放在
**widget 顶层**(不是 options 内),符合 bricks 规范;无 `<link>`/`<script>` 标签,
无 fetch/setInterval。
5. **范围纪律未破**:三轮累计只改 3 个文件(load_path.py / index.ui / README.md)+ 本日志,
未触碰 api.py 的读写语义,未新增任何写入接口。
## 验证(第 3 轮实测,命令可复现)
```bash
cd modules/pbl_kdb_ext
wc -c scripts/load_path.py wwwroot/index.ui README.md docs/work-log-2026-09-18.md
python3 -m py_compile pbl_kdb_ext/*.py scripts/load_path.py # → COMPILE_OK
python3 -c "import json;[json.load(open(f)) for f in ['wwwroot/index.ui','models/pbl_kdb_item.json','models/pbl_kdb_query_log.json','json/kdb_ext_pbl_kdb_item.json','json/kdb_ext_pbl_kdb_query_log.json']]"
grep -rn "^import\|^from" wwwroot/ --include='*.dspy' # → 空(dspy 审计通过)
grep -rn "entire_url(" wwwroot/index.ui | grep -v "/pbl_kdb_ext/" # → 空(绝对路径核对通过)
grep -c "PENDING %-" scripts/load_path.py # → 1
grep -c "%%" scripts/load_path.py # → 1(仅第 51 行注释)
grep -rn "INSERT INTO\|UPDATE \`\|DELETE FROM" pbl_kdb_ext/*.py # → 仅 pbl_kdb_query_log 留痕 1 处
```
实测结论:
- `.py` 全部 py_compile 通过;5 个 JSON(index.ui + 2 models + 2 json/CRUD)全部可解析。
- dspy 审计为空(无 import,全走 ServerEnv 预载全局);index.ui 无相对 `entire_url`。
- `grep -c "%%" scripts/load_path.py` = **1**:**代码本体无 `%%`**(第 55 行为
`print(' PENDING %-12s %s' % (role, path))`,占位符 2 个、实参 2 个,一致),
命中的唯一一处是**第 51 行注释中保留的旧 bug 说明文本**(`原 %%-12s 转义后…`)。
- 零写入自证:全模块唯一写 SQL 是 `pbl_kdb_query_log` 检索留痕(append-only 审计),
无任何 `pbl_kdb_item` 的 INSERT/UPDATE/DELETE;无 `kdb.write`/`research.write`/`sim.*` 函数定义。
- **环境受限未跑(如实标注)**:本工作空间无 pbls 运行实例与 MySQL(`pbl_kdb_item` /
`pbl_assessment_record` 无数据),故未做 HTTP 200 端到端验证与聚合抑制(k_min=5)实测;
RBAC 注册未实跑(`set_role_perm.py` 不在本工作空间),按设计走 PENDING 打印分支。
此项留待 deploy_test。
## 当前状态
- 分支:`main`;第 2 轮修改:`scripts/load_path.py`、`wwwroot/index.ui`、`README.md`、
`docs/work-log-2026-09-18.md`(新增);第 3 轮修改:仅 `docs/work-log-2026-09-18.md`
(订正 `grep -c "%%"` 结论 + 补第 3 轮处理表),**代码文件零改动**。
- 提交由 PM 审核通过后系统统一执行(引擎代为收口)。