pbl_compiler/docs/work-log-2026-09-19.md

118 lines
8.6 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_compiler 工作日志 — 2026-09-19M3b 规则映射与导出 · 整改轮)
任务:`[M3b] pbl_compiler script_engine 规则映射与导出`
第12章 event→condition→response → script_type=1 规则 JSON 映射、产物导出、game_definition 写入)
角色agent.develop 迭代pbls-初始迭代 任务性质new_dev含 QC 退回意见逐条整改)
## 1. 本轮范围
只做「登记面接线 + 审计工具自身缺陷 + 提交可追溯性」的增量整改,**不重写已合规的
models/ 表定义本体**(前轮 QC 已确认四段式 / primary str32 / codes parentid 全过)。
| # | 退回意见 | 处置 |
|---|---------|------|
| QC #1(硬门禁·第四章 RBAC | 5 个 M3b Web 契约未登记 RBAC 路径init.py 注释条数与代码不符 | 已修:`scripts/load_path.py` 逐条显式登记(无通配符),`pbl_compiler/init.py` 注释与事实对齐 |
| QC #2(流程·真实性) | 交付前未自行 git commit由引擎代为收口 | 已修:本轮 agent 自行选择性 `git add` + `git commit` + `git push`commit `cb1132e` |
| 前轮 #2GD 唯一写入口) | gd_rules_writer 无调用入口 | 保持:`pbl_compiler/api.py` L606 编译主流程 ⑥.5 调用 `write_gd_rules()``rules_export_api.py` L223 亦经此入口 |
| 前轮 #3CRUD editable | editable 仅 get_data_urlxls2ui 会回退默认写入口 | 保持方案 A9 个只读拒绝端点 + params 顶层三 URL 绝对路径 |
| 前轮 #4work log | 无 dated work log | 本文件补齐归档 |
## 2. 时间线
1. **实跑审计定位根因**`python3 scripts/audit_rbac_parity.py` → rc=1
「load_path.py PATHS 为空RBAC 零登记 → 全部 403」。
2. **交叉核验发现是两处事实叠加**
- 工作区 `scripts/load_path.py` 实际已登记 29 条(`grep -c "('/pbl_compiler/api/"` = 29
`ls wwwroot/api/*.dspy | wc -l` = 29 一致 → QC 引用的「仅 15/20 条」是
**git HEAD 版本**(前轮变更未提交,`git show HEAD:scripts/load_path.py` 实测 20 条、
`git ls-tree HEAD wwwroot/api/` 实测 20 个),审核方读的是仓库而非工作区。
- 审计脚本自身存在解析缺陷:`parse()` 对纯字面量列表已 `literal_eval` 成 python list
`resolved` 字典只收 `ast.List` 形态,导致 `PATHS = PATHS_CONTRACTS + PATHS_READONLY_DENY`
BinOp回查 `resolved` 拿到空列表 → 把已登记的 29 条误判成「零登记」,产生假 FAIL。
3. **修审计工具**`resolved` 同时接受 `list`(已求值)与 `ast.List`(含函数引用求值失败)两种形态。
4. **修注释**`init.py` 文件头「共 20 条 + 只读列表 CRUD 6 条」→
「共 29 条 = Web 契约端点 20 + CRUD 只读拒绝端点 9无通配符」。
5. **实跑自证**audit rc=0 PASS`scripts/test_m3b_mapping.py` PASS=113 / FAIL=0
`python3 -m py_compile pbl_compiler/*.py scripts/*.py` OK。
6. **自行收口**:选择性暂存 15 个文件6 改 + 9 新增 .dspy`git commit``cb1132e`
`git push origin HEAD` 成功(`d203811..cb1132e HEAD -> main`)。未使用 `git add -A`
`__pycache__` / 生成物未入库。
## 3. 技术决策与陷阱
- **RBAC 登记分两个集合而非一个**`PATHS_CONTRACTS`20进 init.py CONTRACTS /
__init__.py `__all__` / wwwroot/api`PATHS_READONLY_DENY`9**不是** ServerEnv 契约,
只为封死 xls2ui 默认 `add_/update_/delete_<table>.dspy` 写入口)。审计按
`CONTRACTS READONLY_DENY` 比对,既不漏登记也不产生幽灵登记。
- **只读表为何仍要建 create/update/delete 端点**crud-definition-spec 要求 editable 三 URL
齐备,缺项时 xls2ui 回退生成默认写入口 → `rules_hash`29.6 确定性指纹)可被手工改写。
故 9 个端点显式返回 `{"widgettype":"Error","options":{"label":"...只读,禁止手工增删改"}}`
把「拒绝」变成可机械验证的事实audit 第 ⑪ 项检查 Error widget
- **不登记不存在的路径**QC #1 提到「若引入 pbl_script_rule 只读列表 CRUD 生成目录则补 6 条」。
实测 `wwwroot/` 下仅有 `api/` 一个子目录(无 CRUD 生成目录),`pbl_script_rule_list` 是手写
Web 契约而非 xls2ui CRUD → 补登 `/pbl_compiler/pbl_script_rule` 等 6 条会形成幽灵登记、
污染 permission 表。此判断已固化进 audit 第 ⑫ 项检查。
- **禁通配符**29 条全部显式audit 第 ④ 项用正则扫 `*`/`%` 通配命中即 FAIL。
- **审计工具也要被审计**`resolved` 只认 AST 形态这一缺陷,会让「已正确整改」被判成
「RBAC 零登记」,白白烧掉退回预算。凡登记面比对,脚本必须同时兼容字面量求值成功/失败两种形态。
## 4. 验证(实跑输出摘录)
```
$ python3 scripts/audit_rbac_parity.py
PASS init.py CONTRACTS = 20 个契约
PASS 20 个契约在 api.py/rules_export_api.py 均有同名实现
PASS __init__.py __all__ 覆盖全部 20 个契约
PASS load_path.py 无通配符29 条全显式)
PASS load_path.py 登记 29 条无重复(契约 20 + 只读拒绝 9
PASS PATHS_CONTRACTS 与 CONTRACTS 一一对应20 条)
PASS PATHS 登记 29 条,与期望端点集合(契约 20 + 只读拒绝 9一一对应
PASS wwwroot/api/*.dspy = 29 个,与 CONTRACTSREADONLY_DENY 一一对应
PASS grep 口径自证PATHS 中 /api/ 条目=29wwwroot/api/*.dspy=29
PASS 29 个 .dspy 无非法 import仅允许 sqlor.filter
PASS 29 个 .dspy 均有显式 return
PASS .dspy 无 ServerEnv() 取请求态
PASS 9 个只读拒绝端点均显式返回 Error widgetCRUD 写入口已封死)
PASS wwwroot/ 无 CRUD 生成子目录(只读列表走手写契约 api/pbl_script_rule_list.dspy
PASS json/*.json 共 3 个:根键白名单(['_comment','alias','params','tblname','title']) / alias
/ editable 三 URL 齐备且指向真实 .dspy / 字段与 models 全对齐
RESULT: PASS (contracts=20, readonly_deny=9, dspy=29, rbac_api_paths=29, json=3) rc=0
$ python3 scripts/test_m3b_mapping.py
PASS: 113 FAIL: 0
$ grep -c "('/pbl_compiler/api/" scripts/load_path.py → 29
$ ls wwwroot/api/*.dspy | wc -l → 29
$ grep -n 'pbl_compiler_export_rules|pbl_compiler_rules_preview|pbl_compiler_rules_diff|
pbl_game_definition_rules_get|pbl_script_rule_list' scripts/load_path.py
→ 68,69,70,71,72 五行命中5 个 M3b 契约全部显式登记)
$ git log --oneline -1 → cb1132e fix(pbl_compiler): M3b RBAC 29条显式登记+...
$ git push origin HEAD → d203811..cb1132e HEAD -> main
```
## 5. 环境受限项(如实说明,不谎报已验证)
1. **`~/repos/sage` 不存在**QC 改法要求
`cd ~/repos/sage && ./py3/bin/python ~/repos/pbl_modules/pbl_compiler/scripts/load_path.py`
并「同步中央 sage/load_path.py 兜底」。本工作空间实测 `ls -d ~/repos/sage` → 无该目录,
中央 `sage` 仓库与 `py3` 虚拟环境均不在位;`apps/pbls/` 下也**没有**中央 load_path.py
(全库 `grep -rln "pbl_compiler/api/" apps/` 零命中),各 pbl_* 模块一律以
`modules/{模块}/scripts/load_path.py` 为唯一登记面。故本轮只完成模块侧登记与自证,
中央兜底无法执行,需部署角色在有 sage 的环境跑 `register()`
2. **未连库、未起服务**`register()` 依赖 rbac CLI`set_role_perm.py`)与 MariaDB
本工作空间无 DB 实例(`PBLS_DB_USER` 空、mysql 未授权)。脚本设计为 CLI 不在位时
打印 PENDING 清单并以 rc=1 暴露(不静默跳过),部署阶段据此补登。
3. **未重跑 xls2ui/build.sh**`wwwroot/` 无 CRUD 生成子目录(三表按只读列表呈现,
走手写契约),本轮无 .ui 产物需再生成;若后续引入 CRUD 目录audit 第 ⑫ 项会 FAIL 提醒补登。
4. **「登录后调用不再 403」未做端到端实测**:受 1/2 限制,只能以「登记面与端点集合一一对应」
作为可达性的机械证明,真实 HTTP 200 验证需部署环境。
## 6. 分支状态
- 仓库:`modules/pbl_compiler`origin `git@git.opencomputing.cn:yumoqing/pbl_compiler.git`
- 分支:`main`HEAD = `cb1132e`agent.develop 自行提交并推送,非引擎代为收口)
- 工作区:暂存区已清空;未跟踪仅剩 `docs/work-log-2026-09-19.md`(本文件,随交付入库)
`__pycache__`.gitignore 已排除)
- 前序 6 个 `deliver: 交付收口(引擎代为提交)` 提交626b2c0/eb18a7d/4051e9d/c276af5/2c14bf5/d203811
为历史事实,本轮不改写历史,仅在其上追加 agent 自有提交。