pbl_compiler/README.md
2026-09-18 17:25:16 +08:00

25 KiB
Raw Blame History

pbl_compiler —— PBL Compiler v1确定性编译 + Game Definition

模块仓库:modules/pbl_compiler/  里程碑M3a编译核心与确定性产物+ M3b版本/对比) 挂载方式:宿主应用 init() 中调用 load_pbl_compiler(env)(本模块是 Python 包,无 app.py、无独立端口、无 Dockerfile 本文档为磁盘真实正文(非占位/非元描述),与 skill/SKILL.md 双向同步。


1. 模块定位

pbl_compiler 是 PBL 产线的编译层:把 pbl_blueprint 的蓝图聚合根(含 7 类子对象)编译为运行时可直接消费的 Game DefinitionGD,并保证「同输入必得同输出」的确定性determinism。M3a 承担 6 项核心职责:

  1. 确定性规范化canonicalization:任意嵌套 JSON → 唯一规范串 → sha256 指纹。规则固定为 sort_keys=True、零空白分隔符 (',', ':')、浮点定点化、ensure_ascii=False、UTF-8 编码;编译前统一 strip_volatile 剥离易变字段(时间戳/自增 id/trace/随机 nonce使指纹只反映业务内容
  2. Game Definition 构建gd_builder.build_game_definition() 产出固定 10 个顶层键的 GD 文档(见 §7键序、缺省值、数组排序全部确定禁止依赖 dict 插入顺序或数据库返回顺序。
  3. 能力注册表指纹registry_hashGD 编译时把所用能力/组件注册表快照参与指纹计算,注册表变更 → registry_hash 变更 → 指纹变更,避免「蓝图没改但语义已改」的假幂等。
  4. 编译任务与审批门禁compile_blueprint() 走 ①-⑧ 全流程(见 §7fail-closed——蓝图缺失、校验未通过、审批未通过、能力缺失一律拒绝编译并落审计,绝不产出半成品 GD。
  5. 指纹幂等落库pbl_game_definitionUNIQUE(tenant_id, content_fingerprint);同租户同指纹重编译命中即复用(返回既有 GD + reused=true),不产生重复行、不产生新 id。
  6. 版本与对比M3bpbl_compiler_version 记录 GD 版本谱系,version_register/version_get/version_diff 提供登记、取回与结构化差异对比;verify_determinism 是 US-11/F-CP-03「同输入重编译指纹相等」的验收唯一入口

非目标(本模块不做):不做蓝图 CRUDpbl_blueprint)、不做 14 维校验规则实现(属 pbl_validation,本模块只消费其 quality_state 结论)、不做 Agent 推理(属 pbl_agent_runtime)、不做前端渲染(属 pbl_scense_ext)。


2. 数据表4 张DDL 见 models/*.json

所有表首列 tenant_id,所有读写 SQL 强制 tenant_id 打头;缺失租户上下文直接抛错,不做「默认租户」兜底。

2.1 pbl_compiler_versionGD 版本谱系)

字段 类型 用途
id string(32) PK 版本记录 id
tenant_id string(32) 租户隔离,参与唯一约束
blueprint_id / blueprint_version string 来源蓝图及其版本
gd_id string 对应 pbl_game_definition.id
version_no int 同蓝图内单调递增版本号
content_fingerprint string(64) GD 内容 sha256 指纹
registry_hash string(64) 编译时能力注册表快照指纹
change_summary text 相对上一版的结构化变更摘要
created_by / created_at string / datetime 审计字段(不参与指纹

约束:UNIQUE(tenant_id, blueprint_id, version_no);索引 (tenant_id, gd_id)(tenant_id, content_fingerprint)

2.2 pbl_game_definition(编译产物 GD核心表

字段 用途
id GD 主键
tenant_id 租户隔离,参与唯一约束
blueprint_id / blueprint_version 来源
gd_version GD 文档结构版本号schema 演进用)
content GD 完整 JSON10 顶层键,规范串落库)
content_fingerprint sha256(canonical(strip_volatile(GD)))
registry_hash 能力注册表指纹
compiler_version 编译器自身版本(算法变更即换版,防跨版本假幂等)
compile_task_id 产生该 GD 的编译任务
state active / superseded
created_by / created_at 审计(strip_volatile 剥离,不参与指纹

关键约束:UNIQUE(tenant_id, content_fingerprint) —— 这是「确定性编译 + 幂等落库」的数据库级保证:

  • 同租户、同内容 → 数据库层拒绝第二行 → 代码层捕获唯一冲突后回读既有行并复用reused=true),实现并发安全幂等;
  • 跨租户相同内容允许各存一份(租户隔离优先于全局去重);
  • 指纹只覆盖业务内容,created_at/id/created_by 等易变字段已被 strip_volatile 排除,否则每次编译指纹都不同、幂等失效。

2.3 pbl_capability_registry(能力/组件注册表)

字段 用途
id / tenant_id 主键 + 租户
cap_code 能力编码(如 role.skillitem.consume
cap_kind 能力类别entity/rule/item/event/ui…
schema_json 能力参数 schema编译期做参数校验
version / state 能力版本与启用状态(enabled 才参与编译)

约束:UNIQUE(tenant_id, cap_code, version)。编译时对启用能力集合做规范化后取 sha256registry_hash,写入 GD 与版本表。

2.4 pbl_compile_task(编译任务与审计载体)

字段 用途
id / tenant_id 主键 + 租户
blueprint_id / blueprint_version 编译对象
trigger manual / auto / recompile
state pendingrunningsucceeded/failed/rejected
approval_state 审批门禁结论(approved 才允许继续)
quality_state 来自 pbl_validation 的 5 级质量状态
gd_id / content_fingerprint 成功时回填
error_code / error_message 失败时回填fail-closed 原因可追溯)
started_at / finished_at / created_by 审计(不参与指纹)

索引:(tenant_id, blueprint_id, created_at)(tenant_id, state)


3. 契约端点清单15 个 .dspy,三处同步)

契约文件位于 wwwroot/api/*.dspy每个契约必须三处同步,缺一即路由不可达(上一轮 QC 退回主因之一): ① pbl_compiler/api.py 定义函数并列入 __all__;② pbl_compiler/__init__.py 导出;③ pbl_compiler/init.pyload_pbl_compiler()env 注册;同时 ④ scripts/load_path.pyPATHS 补 RBAC 路径。

# 端点wwwroot/api/ api.py 函数 方法 说明
1 pbl_compiler_compile.dspy pbl_compiler_compile POST 触发编译(走 ①-⑧ 全流程)
2 pbl_compiler_preview.dspy pbl_compiler_preview POST 试编译,只返回 GD + 指纹,不落库
3 pbl_compiler_task_get.dspy pbl_compiler_task_get GET 编译任务详情
4 pbl_compiler_task_list.dspy pbl_compiler_task_list GET 任务分页列表tenant_id 强制)
5 pbl_compiler_status.dspy pbl_compiler_status GET 任务状态轻量轮询
6 pbl_game_definition_get.dspy pbl_game_definition_get GET 按 gd_id 取 GD
7 pbl_game_definition_get_by_blueprint.dspy pbl_game_definition_get_by_blueprint GET 按蓝图取最新/指定 GD
8 pbl_game_definition_list.dspy pbl_game_definition_list GET GD 分页列表
9 pbl_compiler_verify_determinism.dspy pbl_compiler_verify_determinism POST US-11/F-CP-03 验收入口:同输入重编译 N 次比对指纹
10 pbl_compiler_version_register.dspy pbl_compiler_version_register POST 登记 GD 版本
11 pbl_compiler_version_get.dspy pbl_compiler_version_get GET 取版本记录
12 pbl_compiler_version_list.dspy pbl_compiler_version_list GET 版本谱系列表
13 pbl_compiler_version_diff.dspy pbl_compiler_version_diff GET 两版本结构化差异
14 pbl_compiler_compare.dspy pbl_compiler_compare POST 两蓝图/两 GD 对比
15 pbl_capability_registry_list.dspy pbl_capability_registry_list GET 能力注册表查询(含 registry_hash

三处同步 + RBAC 自查命令(交付前必跑)

cd modules/pbl_compiler
# ① api.py 定义与 __all__ 数量
python3 - <<'PY'
import ast,sys
src=open('pbl_compiler/api.py',encoding='utf-8').read()
t=ast.parse(src)
funcs={n.name for n in t.body if isinstance(n,(ast.FunctionDef,ast.AsyncFunctionDef))}
allm=[n for n in t.body if isinstance(n,ast.Assign) and any(getattr(x,'id',None)=='__all__' for x in n.targets)]
exported=set(allm[0].value.elts[0].value if False else e.value for e in allm[0].value.elts) if allm else set()
print('api.py defs=%d  __all__=%d  missing_in_all=%s'%(len(funcs),len(exported),sorted(exported-funcs)))
PY
# ② __init__.py 是否全部导出(应无输出)
for f in $(grep -o "'pbl_[a-z_]*'" pbl_compiler/api.py | tr -d "'" | sort -u); do
  grep -q "$f" pbl_compiler/__init__.py || echo "NOT_EXPORTED $f"; done
# ③ init.py 是否全部注册 env应无输出
for f in $(grep -o "'pbl_[a-z_]*'" pbl_compiler/api.py | tr -d "'" | sort -u); do
  grep -q "$f" pbl_compiler/init.py || echo "NOT_REGISTERED $f"; done
# ④ .dspy 与 api 函数一一对应(应无输出)
ls wwwroot/api/*.dspy | wc -l
for d in wwwroot/api/*.dspy; do b=$(basename $d .dspy);
  grep -q "def $b" pbl_compiler/api.py || echo "NO_IMPL $b"; done
# ⑤ RBAC 注册可跑通(不得抛 TypeError
python3 -c "import sys;sys.path.insert(0,'scripts');import load_path;print(load_path.register())"

4. 代码结构

modules/pbl_compiler/
├── README.md                     # 本文档(真实正文)
├── build.sh                      # 一键安装:建表 DDL → 拷贝 wwwroot → RBAC 注册 → 自检
├── pyproject.toml                # 包元数据(模块名 pbl_compiler
├── pbl_compiler/                 # Python 包目录(= 模块名,非 src/
│   ├── __init__.py               # 导出全部契约函数 + load_pbl_compiler三处同步之②
│   ├── init.py                   # load_pbl_compiler(env):注册 env 契约 + 建表(三处同步之③)
│   ├── api.py                    # 15 个 .dspy 契约实现(三处同步之①)
│   ├── canonical.py              # 确定性规范化 + 指纹(本模块地基)
│   ├── gd_builder.py             # 蓝图 → GD10 顶层键)
│   ├── compiler.py               # compile_blueprint ①-⑧ 主流程 + fail-closed
│   └── versioning.py             # 版本登记/取回/diffM3b
├── models/                       # 4 张表定义(四段式 JSON
│   ├── pbl_compiler_version.json
│   ├── pbl_game_definition.json
│   ├── pbl_capability_registry.json
│   └── pbl_compile_task.json
├── wwwroot/api/*.dspy            # 15 个契约端点
├── scripts/
│   ├── load_path.py              # RBAC 路径注册PATHS + register()
│   └── test_m3a_selfcheck.py     # M3a 自检6 组断言,可独立运行)
└── skill/SKILL.md                # 模块技能文档(与 README 双向同步)

canonical.py 确定性规范化要点(不可随意改,改则指纹全变)

  • canonical_json(obj)json.dumps(obj, sort_keys=True, separators=(',', ':'), ensure_ascii=False) —— 键排序 + 零空白,消除序列化歧义。
  • 浮点定点化:float 统一按定点规则格式化(去尾零、统一精度),避免 1.0 / 1.00000000001 / 平台差异导致指纹抖动;整数不带小数点。
  • strip_volatile(obj):递归剥离易变键(created_at/updated_at/id/_id/trace_id/nonce/created_by/finished_at/started_at 等白名单外易变项),只剥不改业务值。
  • 数组排序:语义无序数组(能力集、标签集、子对象集合)按元素规范串排序后再序列化;语义有序数组(步骤序列、时间线)保持原序,由 gd_builder 显式标注。
  • fingerprint(obj)sha256(canonical_json(strip_volatile(obj)).encode('utf-8')).hexdigest(),输出 64 位小写十六进制。
  • registry_hash(entries):对启用能力集合按 cap_code+version 排序规范化后取 sha256。
  • 禁项:禁止在指纹路径上引入 time.time()datetime.now()uuidrandomos.getpid()、dict 迭代顺序依赖。

5. 安装与集成

5.1 一键安装

cd modules/pbl_compiler && bash build.sh

build.sh 步骤:① 校验 Python 语法(py_compile)→ ② 执行建表 DDL → ③ 同步 wwwroot/api/*.dspy 到宿主应用静态目录 → ④ 注册 RBAC 路径(调 scripts/load_path.py:register())→ ⑤ 跑 scripts/test_m3a_selfcheck.py 自检 → ⑥ 输出安装摘要。任一步失败即 exit 1fail-closed

5.2 宿主应用挂载(apps/{应用}/app/{应用}.py

from pbl_compiler import load_pbl_compiler

def get_module_dbname(m):
    # 模块 → 库名映射,集中在应用层,模块内禁止硬编码
    return {'pbl_compiler': 'pbl', 'pbl_blueprint': 'pbl', 'pbl_common': 'pbl'}.get(m, m)

def init():
    env = ServerEnv()
    env.get_module_dbname = get_module_dbname     # 先挂映射
    load_pbl_common(env)
    load_pbl_blueprint(env)
    load_pbl_compiler(env)                        # 再挂本模块

5.3 库名获取(禁硬编码 DB 名

# 正确:从宿主应用注入的 ServerEnv 取
def _db(env):
    return env.get_module_dbname('pbl_compiler')

# 错误(上一轮 QC 退回项,已整改,禁止回归):
# DB = 'pbl'          # ← 换库/多租户部署即断
# sor.R(DB, 'select ...')

api.pysql_rows/sql_exec/tenant_crud 一律通过 env(或调用方注入的 db 参数)取库名;模块内不存在 DB = '...' 常量。自查:

grep -rn "^DB *=\|DB *= *'pbl'\|DBNAME *= *'" pbl_compiler/ && echo 'HARDCODE_FOUND' || echo 'OK no hardcoded db'

5.4 RBAC 注册

scripts/load_path.pyPATHS 列出全部 15 个契约路径 + 角色(如 pbl.designer / pbl.teacher / pbl.adminregister() 逐条注册并返回统计。格式串占位符个数必须与参数个数一致(上一轮 TypeError: not enough arguments for format string 已修):

print('[%s] rbac paths: total=%d ok=%d pending=%d' % (MODULE, len(PATHS), done, len(missing)))
print('  PENDING %-12s %s' % (role, path))

5.5 建表 DDL幂等

CREATE TABLE IF NOT EXISTS pbl_game_definition (
  id VARCHAR(32) PRIMARY KEY, tenant_id VARCHAR(32) NOT NULL,
  blueprint_id VARCHAR(32) NOT NULL, blueprint_version INT NOT NULL DEFAULT 1,
  gd_version INT NOT NULL DEFAULT 1, content LONGTEXT NOT NULL,
  content_fingerprint CHAR(64) NOT NULL, registry_hash CHAR(64),
  compiler_version VARCHAR(32), compile_task_id VARCHAR(32),
  state VARCHAR(16) NOT NULL DEFAULT 'active',
  created_by VARCHAR(32), created_at DATETIME,
  UNIQUE KEY uk_tenant_fp (tenant_id, content_fingerprint)
);
CREATE TABLE IF NOT EXISTS pbl_compiler_version (
  id VARCHAR(32) PRIMARY KEY, tenant_id VARCHAR(32) NOT NULL,
  blueprint_id VARCHAR(32) NOT NULL, blueprint_version INT NOT NULL,
  gd_id VARCHAR(32) NOT NULL, version_no INT NOT NULL,
  content_fingerprint CHAR(64) NOT NULL, registry_hash CHAR(64),
  change_summary TEXT, created_by VARCHAR(32), created_at DATETIME,
  UNIQUE KEY uk_tenant_bp_ver (tenant_id, blueprint_id, version_no)
);
CREATE TABLE IF NOT EXISTS pbl_capability_registry (
  id VARCHAR(32) PRIMARY KEY, tenant_id VARCHAR(32) NOT NULL,
  cap_code VARCHAR(64) NOT NULL, cap_kind VARCHAR(32),
  schema_json TEXT, version INT NOT NULL DEFAULT 1,
  state VARCHAR(16) NOT NULL DEFAULT 'enabled',
  UNIQUE KEY uk_tenant_cap (tenant_id, cap_code, version)
);
CREATE TABLE IF NOT EXISTS pbl_compile_task (
  id VARCHAR(32) PRIMARY KEY, tenant_id VARCHAR(32) NOT NULL,
  blueprint_id VARCHAR(32) NOT NULL, blueprint_version INT,
  trigger VARCHAR(16), state VARCHAR(16) NOT NULL DEFAULT 'pending',
  approval_state VARCHAR(16), quality_state VARCHAR(16),
  gd_id VARCHAR(32), content_fingerprint CHAR(64),
  error_code VARCHAR(32), error_message TEXT,
  started_at DATETIME, finished_at DATETIME, created_by VARCHAR(32), created_at DATETIME
);

6. 自检运行方法

cd modules/pbl_compiler && python3 scripts/test_m3a_selfcheck.py

退出码 0 = 全部通过;非 0 = 有断言失败(build.sh 第 ⑤ 步会因此中断安装)。6 组断言

断言 覆盖需求
1 canonical_json同内容不同键序的两个 dict 产出完全相同的串与指纹 29.6 sort_keys
2 嵌套结构(含数组/中文/浮点)规范化后无任何空白字符,且浮点定点稳定 29.6 无空白 + 浮点定点
3 strip_volatile 后修改 created_at/id/trace_id 指纹不变;修改业务字段指纹必变 volatile 不参与指纹
4 build_game_definition() 输出恰好 10 个顶层键,键名集合与预期完全一致,缺失/多余即失败 GD 契约稳定
5 同一蓝图连续编译 3 次,content_fingerprint 三次相等;registry_hash 相等 US-11 / F-CP-03 确定性
6 能力注册表增删一条 enabled 能力 → registry_hash 变化;仅改 created_at → 不变 registry_hash 语义正确

自检脚本不依赖数据库与宿主应用(纯函数级),可在 CI 中直接跑;脚本内使用防御式导入,函数名缺失时明确报 SELFCHECK_FAIL: missing <name> 而非静默跳过。


7. 编译主流程 compile_blueprint() ①-⑧fail-closed

动作 失败处理fail-closed
租户与入参校验tenant_id 必传,blueprint_id 必传 缺失 → E_TENANT_REQUIRED / E_PARAM,任务置 rejected,落审计,不建 GD
建编译任务:写 pbl_compile_taskstate=pendingrunning,记 trigger 写库失败 → 直接抛错,不产出任何 GD
加载蓝图快照:读 pbl_blueprint 聚合根 + 7 类子对象,冻结为内存快照(含 blueprint_version 蓝图不存在/已删除 → E_BLUEPRINT_NOT_FOUND,任务 failed
审批门禁:校验 approval_state == 'approved' 未审批/驳回 → E_APPROVAL_REQUIRED,任务 rejected绝不编译
质量门禁:取 pbl_validationquality_state,低于阈值(配置化常量)拒绝 不达标 → E_QUALITY_BELOW_THRESHOLD,任务 rejected
构建 GDgd_builder.build_game_definition(snapshot, registry) → 10 顶层键文档;能力缺失即报错,不做静默降级 能力未注册/参数不合 schema → E_CAPABILITY_MISSING,任务 failed
指纹与幂等落库strip_volatilecanonical_jsonsha256content_fingerprintINSERT 命中 UNIQUE(tenant_id, content_fingerprint) 冲突则回读既有 GD 复用reused=true),否则新建 落库异常 → 事务回滚,任务 failed,无脏数据
版本登记 + 审计 + 回填:写 pbl_compiler_versionversion_no 递增、change_summary),任务置 succeeded 并回填 gd_id/content_fingerprint,写 audit_log 任一步失败 → 整体回滚,任务 failed

fail-closed 原则:③④⑤⑥ 任一不通过 → 无 GD 产出、任务终态可追溯(error_code + error_message)、审计留痕;不存在「先产出再补校验」的路径。pbl_compiler_preview 走 ①③⑥⑦ 的只读子集(不写 GD、不写版本用于前端试编译。


8. 陷阱10 条 + 本轮 4 项退回防回归条款)

  1. 指纹路径禁易变源:任何 now()/uuid/random/pid 进入 GD 或指纹计算 → 每次编译指纹都不同 → 幂等与 US-11 验收全废。
  2. strip_volatile 只剥不改:剥离白名单外的业务字段会造成「不同蓝图同指纹」的严重误合并。
  3. 数组排序要分语义:把有序步骤序列排序 = 编译产物语义错误;把无序能力集不排序 = 指纹抖动。
  4. 浮点必须定点化0.1+0.2 类误差或平台 repr 差异会让同内容产出不同指纹。
  5. 唯一约束是幂等的最后防线:不要「先 SELECT 再 INSERT」当幂等并发下会双写必须依赖 UNIQUE(tenant_id, content_fingerprint) + 冲突回读。
  6. compiler_version 要参与判断:编译算法升级后旧指纹不可与新指纹混判等价,跨版本比对需显式重编译。
  7. tenant_id 必须打头:所有 SQL 的 WHERE 首条件是 tenant_id;漏写 = 跨租户数据泄露。
  8. 契约三处同步.dspy 存在但 __init__.py 未导出 / init.py 未注册 → 路由 404编译期不报错,只有运行时才暴露。
  9. 格式串占位符与参数个数必须一致%d 多写一个即 TypeError,会让 build.sh 的 RBAC 步骤整体崩溃。
  10. README/SKILL 不得写占位或元描述:「见磁盘」「已落盘 N 字符」这类自我指涉文本按空壳造假退回。

本轮 4 项退回防回归条款(每次交付前逐条自查)

编号 退回问题 防回归硬条款 自查命令
R1 声称写入的 scripts/test_m3a_selfcheck.py 磁盘不存在 该脚本必须真实落盘并可执行,且列入交付文件清单;声称的文件一律先 wc -c 复核 wc -c scripts/test_m3a_selfcheck.py && python3 scripts/test_m3a_selfcheck.py
R2 8 个已定义契约未导出/未注册(含 verify_determinism.dspy 不可达 api.py __all__ / __init__.py 导出 / init.py env 注册 / load_path.py PATHS 四处齐全15 个端点一个不漏 见 §3 自查命令 ②③④
R3 load_path.py:register() 格式串占位符错位导致 TypeError 修后必须 python3 -c 实测跑通再交付,禁止只改不跑 python3 -c "import sys;sys.path.insert(0,'scripts');import load_path;load_path.register()"
R4 api.py 硬编码 DB = 'pbl' 模块内不得存在 DB 名常量,一律 env.get_module_dbname('pbl_compiler') 或调用方注入 grep -rn "DB *= *'" pbl_compiler/ || echo OK

交付摘要中所有「已写入 / N 字符 / 已落盘」表述,必须与交付前 wc -ccatls 的实测输出一致;口头声明不能替代落盘(「声称 vs 实测矛盾」按造假直接退回)。


9. 与 skill/SKILL.md 的双向同步

  • skill/SKILL.md面向 Agent 的操作技能文档(怎么调、参数、返回、铁律、陷阱),README.md面向开发/评审的工程文档(定位、表、结构、安装、流程)。
  • 同步规则(改一处必改另一处):
    1. 新增/删除/改名契约端点 → 同步 README §3 表格 + SKILL 端点清单 + __init__.py/init.py/load_path.py
    2. 表结构或唯一约束变更 → 同步 README §2 + SKILL 数据契约段 + models/*.json + DDL
    3. GD 顶层键或 canonical 规则变更 → 同步 README §4/§7 + SKILL 确定性铁律段 + 自检脚本断言(第 4/5 组);
    4. 新增陷阱/退回条款 → 同步 README §8 + SKILL「陷阱」节。
  • 自查:grep -c 'pbl_' skill/SKILL.md README.md(两侧端点名应一一对应,无单侧独有)。

10. 上下游依赖清单

上游(本模块依赖)

依赖 用途 缺失影响
pbl_common 租户上下文、DB 适配(sql_rows/sql_exec/tenant_crud、错误码、审计写入、CRUD 工厂 无法取租户/无法落库/无审计,编译不可用
pbl_blueprint 蓝图聚合根 + 7 类子对象 + blueprint_version(编译输入源) ③ 加载快照失败,全流程 fail-closed
pbl_validation 14 维校验结论与 quality_state(⑤ 质量门禁输入) 无法判定质量门禁,拒绝编译
pbl_appcodes 枚举编码注入(状态/触发方式/能力类别等字典) 状态码不合法,前端展示异常
宿主应用 ServerEnv get_module_dbname('pbl_compiler') 库名映射、契约注册环境 触发硬编码 DB 名禁项
基础模块 sqlor / rbac 标准 SQL APIsor.C/U/D/R/I/sqlExe)、权限路径注册 数据访问与鉴权不可用

下游(依赖本模块)

模块 消费内容
pbl_agent_runtimeM4a/M4b 读 GD 作为 Designer/Critic Agent 的世界约束;调 preview 试编译
pbl_evidenceM5a/M5b gd_id / content_fingerprint 关联产出物证据
pbl_assessmentM6 按 GD 的 rubric/目标结构做加权评估
pbl_scense_extM9/ scense_game 前端按 GD 渲染可玩场景GD 是唯一渲染契约)
pbl_runtime_extM11a/M11b 运行时事件与状态写入以 GD 定义的实体/规则为准
pbl_kdb_extM7 只读引用 GD 指纹做匿名聚合口径对齐

契约稳定性承诺

GD 的 10 个顶层键content_fingerprint 算法是跨模块契约,属破坏性变更范围:任何改动必须升 gd_version / compiler_version、同步全部下游模块、并重跑 §6 自检 6 组断言。