{ "module": "pbl_scense_ext", "milestone": "M9(覆盖层前端与页面注册)", "note": "pbl_scense_ext 26 条 RBAC 路径权限种子清单(M9-收口C,消 P-1/P-2 pending=26)。逐条显式登记,禁止 % / * 通配符(module-development-spec 硬门禁 6.6)。由 scripts/m9c_rbac_seed.py 幂等导入 permission/rolepermission,并由 scripts/rbac_set_perm.py 作为 scripts/load_path.py register() 的 RBAC_SET_PERM 工具,使 'rbac paths: total=26 ok=26 pending=0'。traceability 中函数名/文件/行号均为 grep 实测值(沿用 pbl_runtime_ext b54ff00 做法)。", "source_of_truth": "scripts/load_path.py PATHS(26 条,22 logined + 4 any)", "default_role": "logined", "permissions": [ { "name": "pbl_session_context_get", "path": "/pbl_scense_ext/api/pbl_session_context_get.dspy", "kind": "api", "role": "logined", "endpoint": "wwwroot/api/pbl_session_context_get.dspy", "milestone": "M9", "title": "会话上下文读取(租户/世界/角色)", "traceability": "pbl_scense_ext/api.py::pbl_session_context_get(api.py:102)→ __init__.py:9 → init.py:20 env 挂载 → wwwroot/api/pbl_session_context_get.dspy → load_path.py PATHS[0]" }, { "name": "pbl_page_registry_list", "path": "/pbl_scense_ext/api/pbl_page_registry_list.dspy", "kind": "api", "role": "logined", "endpoint": "wwwroot/api/pbl_page_registry_list.dspy", "milestone": "M9", "title": "覆盖层 12 页面注册表(含渲染时延预算)", "traceability": "pbl_scense_ext/api.py::pbl_page_registry_list(api.py:46,读 PAGES api.py:16)→ __init__.py:10 → init.py:21 → wwwroot/api/pbl_page_registry_list.dspy → load_path.py PATHS[1]" }, { "name": "pbl_playtest_feedback_save", "path": "/pbl_scense_ext/api/pbl_playtest_feedback_save.dspy", "kind": "api", "role": "logined", "endpoint": "wwwroot/api/pbl_playtest_feedback_save.dspy", "milestone": "M9", "title": "Playtest 反馈/反思落库", "traceability": "pbl_scense_ext/api.py::pbl_playtest_feedback_save(api.py:113)→ __init__.py:11 → init.py:22 → wwwroot/api/pbl_playtest_feedback_save.dspy → load_path.py PATHS[2]" }, { "name": "pbl_overlay_bootstrap", "path": "/pbl_scense_ext/api/pbl_overlay_bootstrap.dspy", "kind": "api", "role": "logined", "endpoint": "wwwroot/api/pbl_overlay_bootstrap.dspy", "milestone": "M9", "title": "覆盖层启动上下文(bootstrap)", "traceability": "pbl_scense_ext/api.py::pbl_overlay_bootstrap(api.py:62)→ __init__.py:12 → init.py:23 → wwwroot/api/pbl_overlay_bootstrap.dspy → load_path.py PATHS[3]" }, { "name": "pbl_scense_ext_root", "path": "/pbl_scense_ext", "kind": "page", "role": "logined", "endpoint": "wwwroot/index.ui(模块根目录路由,indexes=index.ui)", "milestone": "M9", "title": "pbl_scense_ext 模块入口(目录路由)", "traceability": "wwwroot/index.ui(由 wwwroot 软链挂载,apps/pbls build.sh 第 5 步)→ load_path.py PATHS[4]" }, { "name": "pbl_scense_ext_index_ui", "path": "/pbl_scense_ext/index.ui", "kind": "page", "role": "logined", "endpoint": "wwwroot/index.ui", "milestone": "M9", "title": "pbl_scense_ext 入口页壳", "traceability": "wwwroot/index.ui → load_path.py PATHS[5]" }, { "name": "pbl_overlay_loader_js", "path": "/pbl_scense_ext/overlay/pbl_overlay_loader.js", "kind": "static", "role": "any", "endpoint": "wwwroot/overlay/pbl_overlay_loader.js", "milestone": "M9", "title": "覆盖层脚本/CSS 注入器 + 运行时 i18n(预鉴权页壳首屏)", "traceability": "wwwroot/overlay/pbl_overlay_loader.js:2(FILES L51 注入 core/transport/play;I18N_DIR L48 fetch msg.txt)→ load_path.py PATHS[6](any,QC #1/#6)" }, { "name": "pbl_overlay_css", "path": "/pbl_scense_ext/overlay/pbl_overlay.css", "kind": "static", "role": "any", "endpoint": "wwwroot/overlay/pbl_overlay.css", "milestone": "M9", "title": "覆盖层主题 CSS(页壳首屏样式,不含业务数据)", "traceability": "wwwroot/overlay/pbl_overlay.css → load_path.py PATHS[7](any,QC #1)" }, { "name": "pbl_overlay_core_js", "path": "/pbl_scense_ext/overlay/pbl_overlay_core.js", "kind": "static", "role": "logined", "endpoint": "wwwroot/overlay/pbl_overlay_core.js", "milestone": "M9", "title": "覆盖层业务内核 JS(登录后由 loader 注入)", "traceability": "wwwroot/overlay/pbl_overlay_loader.js FILES L51 → wwwroot/overlay/pbl_overlay_core.js → load_path.py PATHS[8](logined)" }, { "name": "pbl_overlay_transport_js", "path": "/pbl_scense_ext/overlay/pbl_overlay_transport.js", "kind": "static", "role": "logined", "endpoint": "wwwroot/overlay/pbl_overlay_transport.js", "milestone": "M9", "title": "覆盖层广播/意图通道 JS", "traceability": "wwwroot/overlay/pbl_overlay_loader.js FILES L51 → wwwroot/overlay/pbl_overlay_transport.js → load_path.py PATHS[9](logined)" }, { "name": "pbl_overlay_play_js", "path": "/pbl_scense_ext/overlay/pbl_overlay_play.js", "kind": "static", "role": "logined", "endpoint": "wwwroot/overlay/pbl_overlay_play.js", "milestone": "M9", "title": "覆盖层装配 JS(世界内 5 页)", "traceability": "wwwroot/overlay/pbl_overlay_loader.js FILES L51 → wwwroot/overlay/pbl_overlay_play.js → load_path.py PATHS[10](logined)" }, { "name": "pbl_overlay_i18n_zh", "path": "/pbl_scense_ext/i18n/zh/msg.txt", "kind": "static", "role": "any", "endpoint": "wwwroot/i18n/zh/msg.txt", "milestone": "M9", "title": "覆盖层中文文案表(运行时 i18n 单一事实源)", "traceability": "wwwroot/overlay/pbl_overlay_loader.js loadLang()(I18N_DIR L48)→ wwwroot/i18n/zh/msg.txt;生成期同源校验 scripts/gen_overlay_pages.py::load_msg(gen_overlay_pages.py:90)→ load_path.py PATHS[11](any,QC #6)" }, { "name": "pbl_overlay_i18n_en", "path": "/pbl_scense_ext/i18n/en/msg.txt", "kind": "static", "role": "any", "endpoint": "wwwroot/i18n/en/msg.txt", "milestone": "M9", "title": "覆盖层英文文案表(运行时 i18n 单一事实源)", "traceability": "wwwroot/overlay/pbl_overlay_loader.js loadLang()(I18N_DIR L48)→ wwwroot/i18n/en/msg.txt;生成期同源校验 scripts/gen_overlay_pages.py::load_msg(gen_overlay_pages.py:90)→ load_path.py PATHS[12](any,QC #6)" }, { "name": "pbl_overlay_page_home", "path": "/pbl_scense_ext/pbl_overlay/home.ui", "kind": "page", "role": "logined", "endpoint": "wwwroot/pbl_overlay/home.ui", "milestone": "M9", "title": "PBL 首页(覆盖层页壳)", "traceability": "scripts/gen_overlay_pages.py PAGES(gen_overlay_pages.py:72)→ wwwroot/pbl_overlay/home.ui;运行时路由 pbl_scense_ext/api.py PAGES[0](api.py:17)→ load_path.py PATHS[13]" }, { "name": "pbl_overlay_page_blueprint_list", "path": "/pbl_scense_ext/pbl_overlay/blueprint_list.ui", "kind": "page", "role": "logined", "endpoint": "wwwroot/pbl_overlay/blueprint_list.ui", "milestone": "M9", "title": "蓝图列表(覆盖层页壳)", "traceability": "scripts/gen_overlay_pages.py PAGES(gen_overlay_pages.py:72)→ wwwroot/pbl_overlay/blueprint_list.ui;运行时路由 api.py PAGES[1](api.py:18)→ load_path.py PATHS[14]" }, { "name": "pbl_overlay_page_blueprint_editor", "path": "/pbl_scense_ext/pbl_overlay/blueprint_editor.ui", "kind": "page", "role": "logined", "endpoint": "wwwroot/pbl_overlay/blueprint_editor.ui", "milestone": "M9", "title": "蓝图编辑器(覆盖层页壳)", "traceability": "scripts/gen_overlay_pages.py PAGES(gen_overlay_pages.py:72)→ wwwroot/pbl_overlay/blueprint_editor.ui;运行时路由 api.py PAGES[2](api.py:19)→ load_path.py PATHS[15]" }, { "name": "pbl_overlay_page_validation_report", "path": "/pbl_scense_ext/pbl_overlay/validation_report.ui", "kind": "page", "role": "logined", "endpoint": "wwwroot/pbl_overlay/validation_report.ui", "milestone": "M9", "title": "校验报告 14 维(覆盖层页壳)", "traceability": "scripts/gen_overlay_pages.py PAGES(gen_overlay_pages.py:72)→ wwwroot/pbl_overlay/validation_report.ui;运行时路由 api.py PAGES[3](api.py:20)→ load_path.py PATHS[16]" }, { "name": "pbl_overlay_page_agent_console", "path": "/pbl_scense_ext/pbl_overlay/agent_console.ui", "kind": "page", "role": "logined", "endpoint": "wwwroot/pbl_overlay/agent_console.ui", "milestone": "M9", "title": "Agent 控制台(覆盖层页壳)", "traceability": "scripts/gen_overlay_pages.py PAGES(gen_overlay_pages.py:72)→ wwwroot/pbl_overlay/agent_console.ui;运行时路由 api.py PAGES[4](api.py:21)→ load_path.py PATHS[17]" }, { "name": "pbl_overlay_page_approval_center", "path": "/pbl_scense_ext/pbl_overlay/approval_center.ui", "kind": "page", "role": "logined", "endpoint": "wwwroot/pbl_overlay/approval_center.ui", "milestone": "M9", "title": "人工审批中心(覆盖层页壳)", "traceability": "scripts/gen_overlay_pages.py PAGES(gen_overlay_pages.py:72)→ wwwroot/pbl_overlay/approval_center.ui;运行时路由 api.py PAGES[5](api.py:22)→ load_path.py PATHS[18]" }, { "name": "pbl_overlay_page_play_preview", "path": "/pbl_scense_ext/pbl_overlay/play_preview.ui", "kind": "page", "role": "logined", "endpoint": "wwwroot/pbl_overlay/play_preview.ui", "milestone": "M9", "title": "Play 预览(覆盖层页壳,世界内)", "traceability": "scripts/gen_overlay_pages.py PAGES(gen_overlay_pages.py:72)→ wwwroot/pbl_overlay/play_preview.ui;运行时路由 api.py PAGES[6](api.py:23)→ load_path.py PATHS[19]" }, { "name": "pbl_overlay_page_mission_board", "path": "/pbl_scense_ext/pbl_overlay/mission_board.ui", "kind": "page", "role": "logined", "endpoint": "wwwroot/pbl_overlay/mission_board.ui", "milestone": "M9", "title": "驱动问题板(覆盖层页壳,世界内)", "traceability": "scripts/gen_overlay_pages.py PAGES(gen_overlay_pages.py:72)→ wwwroot/pbl_overlay/mission_board.ui;运行时路由 api.py PAGES[7](api.py:24)→ load_path.py PATHS[20]" }, { "name": "pbl_overlay_page_role_panel", "path": "/pbl_scense_ext/pbl_overlay/role_panel.ui", "kind": "page", "role": "logined", "endpoint": "wwwroot/pbl_overlay/role_panel.ui", "milestone": "M9", "title": "角色面板(覆盖层页壳,世界内)", "traceability": "scripts/gen_overlay_pages.py PAGES(gen_overlay_pages.py:72)→ wwwroot/pbl_overlay/role_panel.ui;运行时路由 api.py PAGES[8](api.py:25)→ load_path.py PATHS[21]" }, { "name": "pbl_overlay_page_artifact_studio", "path": "/pbl_scense_ext/pbl_overlay/artifact_studio.ui", "kind": "page", "role": "logined", "endpoint": "wwwroot/pbl_overlay/artifact_studio.ui", "milestone": "M9", "title": "产出物工坊(覆盖层页壳,世界内)", "traceability": "scripts/gen_overlay_pages.py PAGES(gen_overlay_pages.py:72)→ wwwroot/pbl_overlay/artifact_studio.ui;运行时路由 api.py PAGES[9](api.py:26)→ load_path.py PATHS[22]" }, { "name": "pbl_overlay_page_evidence_wall", "path": "/pbl_scense_ext/pbl_overlay/evidence_wall.ui", "kind": "page", "role": "logined", "endpoint": "wwwroot/pbl_overlay/evidence_wall.ui", "milestone": "M9", "title": "证据墙(覆盖层页壳,世界内)", "traceability": "scripts/gen_overlay_pages.py PAGES(gen_overlay_pages.py:72)→ wwwroot/pbl_overlay/evidence_wall.ui;运行时路由 api.py PAGES[10](api.py:27)→ load_path.py PATHS[23]" }, { "name": "pbl_overlay_page_assessment_report", "path": "/pbl_scense_ext/pbl_overlay/assessment_report.ui", "kind": "page", "role": "logined", "endpoint": "wwwroot/pbl_overlay/assessment_report.ui", "milestone": "M9", "title": "评估报告(覆盖层页壳)", "traceability": "scripts/gen_overlay_pages.py PAGES(gen_overlay_pages.py:72)→ wwwroot/pbl_overlay/assessment_report.ui;运行时路由 api.py PAGES[11](api.py:28)→ load_path.py PATHS[24]" }, { "name": "pbl_overlay_page_dir", "path": "/pbl_scense_ext/pbl_overlay", "kind": "page", "role": "logined", "endpoint": "wwwroot/pbl_overlay/(目录路由)", "milestone": "M9", "title": "覆盖层页面壳目录(目录路由)", "traceability": "wwwroot/pbl_overlay/(12 个 .ui)→ load_path.py PATHS[25](目录条目,audit 不做文件存在性检查)" } ], "role_grants": { "logined": [ "pbl_session_context_get", "pbl_page_registry_list", "pbl_playtest_feedback_save", "pbl_overlay_bootstrap", "pbl_scense_ext_root", "pbl_scense_ext_index_ui", "pbl_overlay_core_js", "pbl_overlay_transport_js", "pbl_overlay_play_js", "pbl_overlay_page_home", "pbl_overlay_page_blueprint_list", "pbl_overlay_page_blueprint_editor", "pbl_overlay_page_validation_report", "pbl_overlay_page_agent_console", "pbl_overlay_page_approval_center", "pbl_overlay_page_play_preview", "pbl_overlay_page_mission_board", "pbl_overlay_page_role_panel", "pbl_overlay_page_artifact_studio", "pbl_overlay_page_evidence_wall", "pbl_overlay_page_assessment_report", "pbl_overlay_page_dir" ], "any": [ "pbl_overlay_loader_js", "pbl_overlay_css", "pbl_overlay_i18n_zh", "pbl_overlay_i18n_en" ] }, "superadmin_grant": { "note": "超管授权:运行时从 role 表按 id / name 解析真实超管角色(rbac 伪角色 logined/any 之外的实体角色),命中即授予全部 26 条。role 表列集合按 information_schema 取交集后写,缺列不猜。解析不到任何超管角色时打印 WARN 但不 FAIL——logined/any 两条伪角色已按 rbac userperm.py:204/217/298 的语义覆盖全部登录/匿名主体。", "role_ids": ["pbl_admin", "superadmin", "admin"], "role_names": ["pbl_admin", "superadmin", "admin"], "grant_all": true } }