diff --git a/init/rbac_seed.json b/init/rbac_seed.json new file mode 100644 index 0000000..ff9267d --- /dev/null +++ b/init/rbac_seed.json @@ -0,0 +1,307 @@ +{ + "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 + } +}