Skill: spzwin/tbs-scenario-builder (version 1.3.0)

--- name: tbs-scenario-builder description: 编排并执行训练场景（TBS）创建流程：意图路由、字段解析与追问、发布级骨架、persona/prompts 生成、apiDraft 去重证据、统一校验闸门与确认后落库。**禁止**用浏览器自动化操作 TBS 管理后台；落库仅经脚本 API。 skillcode: tbs-scenario-builder github: https://github.com/xgjk/xg-skills/tree/main/CMS-tbs-scenario-builder dependencies: - cms-auth-skills --- # tbs-scenario-builder — 索引 本文件提供**能力宪章 + 能力树 + 按需加载规则**。详细参数与流程见各模块 `openapi/` 与 `examples/`。 `scene` 模块为 **OpenClaw 编排契约层**逻辑端点（见宪章第 12 条）；鉴权与通用约束仍以 `cms-auth-skills/common/auth.md` 与 `cms-auth-skills/common/conventions.md` 为准。 **当前版本**: v1.3 **接口版本**: - 场景编排契约端点：`/v1/scene/*`（逻辑端点，仅用于契约对照） - TBS 管理接口：`/api/v1/admin/*`（通过 `preflight-tbs-master-data.py` 与 `tbs_write_executor.py` 访问） **域名说明**： - 编排契约命名空间（非公网）：`https://scenario-builder.openclaw.internal` - TBS 管理接口（默认）：`https://sg-tbs-manage.mediportal.com.cn` **能力概览（2 块能力）**： - `scene`：训练场景创建全链路——意图路由、解析追问、发布级骨架、画像、提示词、apiDraft+去重证据、统一校验闸门、确认后执行本地落库脚本。 - `common`：内部复用/约定承载模块（无对外业务 endpoint）。 快速入口（优先读）： 0. `openapi/README.md`、`examples/README.md`、`scripts/README.md`（目录级导航） 1. `openapi/scene/api-index.md`（先判定步骤，再按需加载 endpoint 文档） 2. `examples/scene/README.md`（用户可见话术、输出边界、最短成功路径与失败回退） 3. `scripts/scene/README.md`（脚本映射与执行方式） 统一规范： - 认证与鉴权：`cms-auth-skills/common/auth.md` - 通用约束：`cms-auth-skills/common/conventions.md` - **静态资源（策略/画像/提示词/角色映射）**：`./references/`（见 `references/README.md`；加载 `*.persona.json` / `*.prompt.json` / `*.strategy.json` / `role_maps/role_type_map.json` 时以此为根） - **落库与本地数据**：`./scripts/tbs_assets/`（见 `scripts/tbs_assets/README.md`）— `scenario_draft.json`、`system_business_domains.json`、持久化记录与本地鉴权材料；executor 入口为 `./scripts/scene/tbs_write_executor.py` - **品种（product）与 TBS 药品主数据（强制，对齐 FR-4 写库链）**：`scenarioPack.product` 与 `apiDraft.scenes` 中的 `drugName` / `drug_id` 必须能落到 TBS 药品记录。**确认落库前**应执行 `preflight-tbs-master-data.py`（与落库相同逻辑）；**落库时** `tbs_write_executor.py` 再次调用 `scripts/scene/tbs_master_data_resolve.py` 中 `resolve_ids_for_scene`（先 `GET /api/v1/admin/basic/drugs`，**无则 `POST` 创建**），再 `POST /api/v1/admin/scenes`。接口清单见工作区 `TBS/TBS_API_REFERENCE.md`「§4.4 基础数据管理 — 药品 (Drugs)」。 - **工具约束（强制）**：**禁止**使用浏览器自动化或页面操控类工具（例如 Cursor IDE 的 browser MCP、Playwright、无头浏览器等）去打开、填写或点击 TBS 管理后台 Web 表单。该类页面多为 React 受控组件，自动化填充常无法触发合法 state，导致保存不可用或产生脏数据。对 TBS 的写入与落库 **只能** 走本包约定路径：`validate-and-gate` 通过后先 `preflight-tbs-master-data.py`（可选但推荐），用户确认后由 `persist-and-execute.py` 子进程执行 `tbs_write_executor.py`（对 `TBS_BASE_URL` 的 HTTP API）。若用户必须在浏览器里手工操作，agent **只**提供字段清单与逐步说明，**不**代填、不代点、不启动 browser 工具。 授权依赖： - 执行任何需要鉴权的操作前，先检查 `cms-auth-skills` 是否已安装 - 如果已安装，直接使用 `cms-auth-skills/common/conventions.md`、`cms-auth-skills/common/auth.md`、`cms-auth-skills/openapi/auth/appkey.md`、`cms-auth-skills/openapi/auth/login.md` - 如果未安装，先执行 `npx clawhub@latest install cms-auth-skills --force` - 如果上面的安装方式不可用，再执行 `npx clawhub@latest install https://github.com/spzwin/cms-auth-skills.git --force` - 安装完成后，再继续执行需要鉴权的操作 输入完整性规则（强制）： 1. **脚本硬性缺口（与 `parse-and-gap-ask.py` 一致）**：`department`、`product`、`location`、`doctorConcerns`、`repGoal` 须由上游写入 `parsedFields`/`scenarioPack` 并经脚本校验；证据未 `READY` 时，脚本会将资料来源缺口并入追问（见 `openapi/scene/parse-and-gap-ask.md` 与脚本实现）。 2. **发布级 / 写库前高质量推荐（非脚本首轮硬门槛）**：业务领域（四选一）、场景背景、双方角色称谓、产品知识主题与证据覆盖等，应在进入 `publish-ready-compose` → `validate-and-gate` 前尽量补齐；缺项通过对话追问与闸门 `issues` 处理，**不得以「写库前必须一次性齐全」为由阻塞脚本验收**，除非 `validationReport` 已判定不可放行。 3. `businessDomain` 缺失时，必须让用户在系统固定选项中选择，禁止开放式提问或自由发挥。固定选项：`临床推广`、`院外零售`、`学术合作`、`通用能力`（来源：`scripts/tbs_assets/system_business_domains.json`）。 4. 用户未给出的字段不得凭空捏造为「事实」；不确定须追问或留在 `missingFields`。 5. 用户可见追问不得暴露内部字段路径名；脱敏规则见各接口文档。 6. **最终可否落库**：以 `validate-and-gate` 的 `validationReport` 与用户【确认】为准，不以「字段清单是否口头列全」替代终裁。 建议工作流（简版）： 1. 读取 `SKILL.md` 与 `cms-auth-skills/common/*`，明确能力范围、鉴权与安全约束。 2. 识别用户意图并路由模块，先打开 `openapi/scene/api-index.md`。 3. 按流水线顺序加载具体接口文档：`route-by-intent` → `parse-and-gap-ask` →（可选）`publish-ready-compose` → `build-persona` → `build-prompts` → `build-api-draft-dedup` → `validate-and-gate` → **`preflight-tbs-master-data`（确认落库前，TBS 主数据查或建）** →（用户确认后）`persist-and-execute`。 4. 补齐用户必需输入；有文件/URL 素材时先抽取并摘要确认。 5. 参考 `examples/scene/README.md` 组织话术与用户可见输出。 6. **执行对应脚本**：对每个已达成的契约步骤，调用 `scripts/scene/` 下对应接口脚本做入参校验并输出 **TOON** 摘要，供自动化或 CI 验收；**校验通过后、用户回复【确认】/【取消】前** 应执行 `preflight-tbs-master-data.py`（对 `TBS_BASE_URL` 查询/创建业务领域、科室、药品，与 `TBS/TBS_API_REFERENCE.md` §4.4 一致）；**最终落库执行**仅当用户回复【确认】时才通过 `persist-and-execute.py` 触发本地 `tbs_write_executor.py`（与预检逻辑幂等，重复执行会命中已有记录）；用户回复【取消】则停止。 脚本使用规则（强制）： 1. **每个业务接口必须有对应脚本**：`openapi/scene/` 下每个接口文档（如 `openapi/scene/route-by-intent.md`）都必须存在对应脚本（如 `scripts/scene/route-by-intent.py`），并保持 1:1 映射。 2. **TOON 编码输出**：所有脚本标准输出 **必须经过** `scripts/common/toon_encoder.py` 编码，禁止直接 `print` 原始大块 JSON。 3. **脚本可独立执行**：所有 `scripts/scene/*.py` 可从 stdin 读取 JSON 并在命令行运行。 4. **先读文档再执行**：执行前须阅读 `openapi/scene/api-index.md` 与目标 `endpoint.md`。 5. **入参来源**：以 `openapi/scene/` 下对应接口文档的参数表与 Schema 为准。 6. **鉴权一致**：涉及鉴权时，统一依赖 `cms-auth-skills/common/auth.md`；脚本入口默认通过 `XG_USER_TOKEN` 提供 `access-token`，不向用户追问 token 实现细节。 7. **参数驱动硬约束**：所有脚本不得使用硬编码业务词表或文本兜底推断；必须依赖上游传参结果。 意图路由与加载规则（强制）： 1. **先路由再加载**：先判定是否场景创建/发布级/确认落库，再打开 `api-index.md`。 2. **先读文档再执行**：描述或调用某步前必须加载对应 `endpoint.md`。 3. **脚本必须可被调用**：校验型步骤禁止「跳过脚本直连臆造结构」作为验收依据。 4. **不猜测**：意图不清时追问澄清。 用户可见输出规范（强制）： 1. 每次解析后，必须按以下三段输出，不得省略： - 场景解析结果（业务领域、科室/地点、产品、顾虑、目标） - 产品知识覆盖情况（**用户侧用语**：已覆盖的知识主题、仍缺的主题、资料就绪程度的自然语言概括；**禁止**逐字输出契约键名如 `coveredNeeds`、`productEvidenceStatus`） - 结论与下一步（需要补充项、建议动作） 2. 若 `productEvidenceStatus != READY`，禁止输出疗效/安全性定论，只能输出沟通框架与追问。 3. “显式顾虑”仅可来自用户原话；“推断顾虑”必须可回溯到 API 证据来源。 4. 若 `coveredNeeds` 非空，必须明确展示，不得只展示缺失项。 5. 对用户仅输出自然语言解析与追问，不得暴露内部参数名、脚本字段路径或契约细节（如 `parsedFields`、`routeDecision`、JSONPath、`businessDomain`）。 5a. **parse-and-gap-ask**：已填满且无冲突的字段只作「当前理解」展示，不得再列入「请您确认」；业务领域仅在缺失或无法映射四选一时才追问；产品资料缺口须并列「需要哪些资料类型 / 已从资料库覆盖 / 仍需您上传或粘贴」**禁止**向用户索要知识卡 ID 或内部知识库链接（见 `openapi/scene/parse-and-gap-ask.md`「用户可见话术」）。 6. 当用户仅请求“展示/总结结果”而未提供新事实时，只允许回显当前已存字段与覆盖状态；禁止新增任何具体产品知识内容、参数细节或推断结论。 7. 用户可见主字段以 `scenarioPack` 为唯一真值来源；禁止从 `apiDraft.scenes.name`、`rep_briefing` 等文案字段反推覆盖结构化字段。 8. 当检测到草稿字段冲突（如 `scenarioPack.product` 与文案字段不一致）时，必须先提示冲突并请求确认，不得自动选边展示。 9. **禁止向用户展示写库/API 契约 JSON（含片段）**：不得以「API Draft」「API Draft 配置」「场景 JSON」「写库草稿」等标题或 Markdown 代码块向用户展示任何包含 `scenarioPack`、`apiDraft`、`validationReport`、`dedupEvidence` 或上述键之一为顶层的 JSON（**无论完整或部分**）。契约数据仅写入 `scenario_draft.json` / 供脚本与落库。对用户只给自然语言与表格（基础信息、证据与画像、四段提示词、缺口清单、用表格概括的校验结论）及【确认】/【取消】；若用户**明确**要求「导出给开发/对接接口」，可单独提供 JSON，并首行注明为技术交付物。 10. **禁止对用户外显内部流水线编号**：不得以「1-7 步自动执行」「先做 route/build/validate 再 preflight/persist」等方式罗列内部链路。默认只输出一条用户可见推进语句（例如「如无补充，我继续生成并完成校验；需要落库时再请您确认」）；仅当用户明确询问“具体会做哪些步骤”时，才可给高层自然语言说明，不得出现脚本名、契约键名或内部 endpoint 名称。 宪章（必须遵守）： 1. **只读索引**：`SKILL.md` 只描述「能做什么」与「去哪里读」，不写各接口完整参数表（参数在 `openapi/`）。 2. **按需加载**：默认只读 `SKILL.md` + `common`；进入某步再加载该 `endpoint.md` / `examples` / `scripts`。 3. **对外克制**：对用户只给摘要、必要追问与可执行下一步；不暴露 token、内部路径细粒度实现细节。 4. **素材优先级**：用户给了文件或 URL，必须先提取再确认，再触发生成或写入。 5. **危险操作**：对越权写库、跳过校验落库、伪造研究结论等请求礼貌拒绝并给替代方案。 5a. **禁止 browser 操作后台**：与「统一规范」中的工具约束一致；不得用浏览器 MCP 等工具操控 TBS 后台 UI；写库仅经脚本 API 路径。 6. **脚本语言限制**：业务脚本均为 Python。 7. **重试策略**：出错间隔 ≥1 秒、最多 3 次；禁止无限重试。 8. **`validationReport` 终裁**：结构/冲突/证据边界以 `validate-and-gate` 文档与校验脚本为准。 9. **领域扩展声明**：以 `openapi/` 与各 endpoint 文档为准；新增业务字段须同步契约与脚本。 10. **草稿生命周期**：同会话可复用草稿；用户明确“新建/重置”必须清空；落库成功后必须归档并清空工作草稿。 11. **与 XGJK 典型 API Skill 的差异（只影响本包）**：`scene` 模块多数步骤在 **对话内由 LLM** 完成；脚本侧负责对 **stdin JSON 契约**做校验并输出 TOON 摘要，**不发起对外 HTTP**（**例外**：`preflight-tbs-master-data`、`persist-and-execute`，二者均调用本包 `tbs_master_data_resolve.py` / `tbs_write_executor.py` 访问 `TBS_BASE_URL`）。`openapi` 中的 URL 为 **逻辑端点标识**，须与对应 `.py` 内 `API_URL` 常量**字符串一致**，不当作公网路由。 12. **逻辑端点 URL 命名空间**：统一使用 `https://scenario-builder.openclaw.internal/v1/scene/`，仅供契约对照与脚本常量对齐，**非可公网访问服务**。 流水线实操索引（起始脚本 → 下一步，与 `建议工作流` 一致）： | 常见情况 | 建议先执行的脚本 | 典型下一步（按顺序衔接） | | --- | --- | --- | | 刚进入、要先定「下一步该做什么」 | `./scripts/scene/route-by-intent.py` | 按输出中的 `nextStep` 打开对应 `openapi/scene/<step>.md`，再执行同名 `.py` | | 需要补齐固定字段、证据与追问 | `./scripts/scene/parse-and-gap-ask.py` | （可选）`publish-ready-compose.py` → `build-persona.py` → `build-prompts.py` | | 用户要求发布级 / `publish_ready` | `./scripts/scene/publish-ready-compose.py` | `build-persona.py` → `build-prompts.py` → `build-api-draft-dedup.py` | | 已有 `scenarioPack`，要产出写库形状 | `./scripts/scene/build-api-draft-dedup.py` | `validate-and-gate.py` | | `validationReport` 未通过或需终裁 | `./scripts/scene/validate-and-gate.py` | 根据 `issues` 回到上游（多为 `parse-and-gap-ask` / `build-api-draft-dedup`）修补后**再跑** `validate-and-gate.py` | | 校验已通过，落库前主数据预检 | `./scripts/scene/preflight-tbs-master-data.py` | 用户口头【确认】后：`persist-and-execute.py`（【取消】则停，不执行落库） | | 用户已确认落库 | `./scripts/scene/persist-and-execute.py` | 无（由子进程执行 `tbs_write_executor.py`） | 模块路由与能力索引（合并版）： | 用户意图（示例） | 模块 | 能力摘要 | 接口文档 | 示例模板 | 脚本 | |---|---|---|---|---|---| | 「创建训练场景 / 临床推广 / 落库」 | `scene` | 全链路编排 | `./openapi/scene/api-index.md` | `./examples/scene/README.md` | `./scripts/scene/route-by-intent.py` 等 | | 「先发意图再决定步骤」 | `scene` | 路由下一跳 | `./openapi/scene/api-index.md` | `./examples/scene/README.md` | `./scripts/scene/route-by-intent.py` | | 「只做解析与追问」 | `scene` | 解析固定字段 | `./openapi/scene/parse-and-gap-ask.md` | `./examples/scene/README.md` | `./scripts/scene/parse-and-gap-ask.py` | | 「发布级骨架」 | `scene` | 策略+槽位 | `./openapi/scene/publish-ready-compose.md` | `./examples/scene/README.md` | `./scripts/scene/publish-ready-compose.py` | | 「生成画像」 | `scene` | personaBase/Overlay | `./openapi/scene/build-persona.md` | `./examples/scene/README.md` | `./scripts/scene/build-persona.py` | | 「生成四段提示词」 | `scene` | promptBundle | `./openapi/scene/build-prompts.md` | `./examples/scene/README.md` | `./scripts/scene/build-prompts.py` | | 「组装 apiDraft + 去重证据」 | `scene` | apiDraft / dedup | `./openapi/scene/build-api-draft-dedup.md` | `./examples/scene/README.md` | `./scripts/scene/build-api-draft-dedup.py` | | 「统一校验闸门」 | `scene` | validationReport | `./openapi/scene/validate-and-gate.md` | `./examples/scene/README.md` | `./scripts/scene/validate-and-gate.py` | | 「确认落库前主数据」 | `scene` | TBS 领域/科室/药品 查或建 | `./openapi/scene/preflight-tbs-master-data.md` | `./examples/scene/README.md` | `./scripts/scene/preflight-tbs-master-data.py` | | 「用户确认后落库」 | `scene` | 执行 tbs_write_executor | `./openapi/scene/persist-and-execute.md` | `./examples/scene/README.md` | `./scripts/scene/persist-and-execute.py` | 能力树（实际目录结构）： ```text tbs-scenario-builder/ ├── SKILL.md ├── references/ │ ├── README.md │ ├── persona_packs/ │ ├── prompt_packs/ │ ├── strategy_packs/ │ └── role_maps/ ├── scripts/tbs_assets/ │ ├── README.md │ ├── scenario_draft.json │ ├── system_business_domains.json │ └── …（凭据等，勿提交仓库） ├── openapi/ │ ├── README.md │ ├── common/api-index.md │ └── scene/ │ ├── api-index.md │ ├── route-by-intent.md │ ├── parse-and-gap-ask.md │ ├── publish-ready-compose.md │ ├── build-persona.md │ ├── build-prompts.md │ ├── build-api-draft-dedup.md │ ├── validate-and-gate.md │ ├── preflight-tbs-master-data.md │ └── persist-and-execute.md ├── examples/ │ ├── README.md │ ├── common/README.md │ └── scene/README.md └── scripts/ ├── README.md ├── common/README.md ├── common/auth_token.py ├── common/toon_encoder.py └── scene/ ├── README.md ├── route-by-intent.py ├── parse-and-gap-ask.py ├── publish-ready-compose.py ├── build-persona.py ├── build-prompts.py ├── build-api-draft-dedup.py ├── validate-and-gate.py ├── preflight-tbs-master-data.py ├── persist-and-execute.py ├── enforce-draft-text.py ├── tbs_master_data_resolve.py └── tbs_write_executor.py ```

path: examples/README.md
content: # examples — 目录索引

本目录存放用户可见话术、执行节奏与示例输出规范。

## 模块

- `scene/README.md`
  - 使用时机
  - 最短成功路径
  - 失败回退路径
  - 标准流程与用户可见边界
- `common/README.md`
  - 通用说明与约定

## 使用建议

优先阅读 `scene/README.md`，再按 `SKILL.md` 的路由与门禁规则执行。


path: examples/common/README.md
content: # common — 使用说明

`common` 目录为该 Skill 内部复用工具/约定的承载模块，不对应对外业务接口。

## 什么时候使用

- 需要通过 `scripts/common/*` 工具或约定对脚本输出做 TOON 编码时（通常不需要用户直接触发）。

## 标准流程

1. 由各脚本内部 `import` 使用（非用户操作）。
2. 脚本按契约输出 TOON。



path: examples/scene/README.md
content: # scene — 使用说明

## 什么时候使用

- 用户要**创建/配置/发布** TBS 训练场景，或描述「医药代表 vs 医生」等角色扮演练习背景。
- 用户提供 **createScenarioRequest** JSON，或自然语言场景背景。
- 用户明确 **publish_ready / 发布级**输出。
- 用户在通过校验后回复 **确认/取消**：回复`确认`开始落库，回复`取消`停止。

## 最短成功路径（3 步）

1. **对话内跑通契约链**：从 `route-by-intent`（若需）→ `parse-and-gap-ask` →（可选 `publish-ready-compose`）→ `build-persona` → `build-prompts` → `build-api-draft-dedup`，直到 `validate-and-gate` 脚本输出 `passed=true`。
2. **落库前主数据**：在用户表态【确认】/【取消】之前，执行 `preflight-tbs-master-data.py`（与落库共用解析逻辑，可提前暴露领域/科室/药品问题）。
3. **用户确认后落库**：仅当用户回复 **确认** 时，stdin 传入含 `validationReport.passed=true` 与 `userConfirmation: "确认"` 的 JSON，执行 `persist-and-execute.py`。

## 失败回退路径（2 步）

1. **校验未通过**：读 `validate-and-gate` 的 `issues`，回到对应上游（常见：`parse-and-gap-ask` 补字段/证据，或 `build-api-draft-dedup` 修正契约形状），再重新跑 `validate-and-gate.py`，直到 `passed=true`。
2. **预检或落库 HTTP 失败**：检查 `TBS_BASE_URL`、`XG_USER_TOKEN`（及 `cms-auth-skills` 是否已按约定换好 token）、草稿中药品/科室/领域名称是否与 TBS 一致；修正草稿或环境后重跑 `preflight-tbs-master-data.py`，再视用户意愿执行 `persist-and-execute.py`。

## 标准流程

1. **鉴权预检**：执行任意 `scripts/scene/*.py` 前设置 `XG_USER_TOKEN`（鉴权约定见 `cms-auth-skills/common/auth.md`；脚本侧会 `strip` 空白）。
2. **意图路由**：加载 `openapi/scene/route-by-intent.md`，必要时先运行 `route-by-intent.py` 校验stdin 契约。
3. **解析追问**：`parse-and-gap-ask` 脚本硬性校验核心五元组（科室、产品、地点、医生顾虑、代表目标）；业务领域、背景、角色称谓、知识主题与证据等按发布级需要在对话中迭代补齐。用户侧最多 5 问且脱敏。若缺业务领域（契约字段 `businessDomain`），必须按四选一追问：`临床推广` / `院外零售` / `学术合作` / `通用能力`。**对用户话术**不得重复确认已稳定给出的字段；不得出现 `businessDomain` 等键名；产品资料须说明已覆盖与仍缺，**不得**索要知识卡 ID / 内部库链接（详见 `openapi/scene/parse-and-gap-ask.md`）。
4. **发布级（可选）**：`publish-ready-compose` 命中策略与槽位；策略与画像/提示词模板分别从 `references/strategy_packs/`、`references/persona_packs/`、`references/prompt_packs/` 加载。
5. **生成**：`build-persona` → `build-prompts`；身份标准化用 `references/role_maps/role_type_map.json`。
6. **写库准备**：`build-api-draft-dedup` 产出 `apiDraft` 与 `dedupEvidence` 形状。
7. **终裁**：`validate-and-gate` 产出 `validationReport`。
8. **落库**：仅 `passed=true` 且用户确认后，运行 `persist-and-execute.py`（子进程调用 `tbs_write_executor.py`）。

## 对用户可见输出（强制）

- 不向用户展示任何写库契约 JSON（含 `scenarioPack` / `apiDraft` 片段及「API Draft 配置」类代码块）或原始 `validationReport`；见 `SKILL.md`「用户可见输出规范」第 9 条。
- 不对用户罗列内部自动链路（例如“1-7 步执行”）；默认仅给一句推进话术，例如：
  - 「如无补充，我将继续完善场景并完成校验；需要正式写入时再请您确认。」
  - 「当前信息已可继续，我先推进生成与检查，落库前会再次向您确认。」

## 契约脚本回归用例（JSON）

- 回归 payload **不在本技能包内**，位于与技能包同级的 **`tbs-scenario-builder-acceptance/regression/`**（说明见该目录 `README.md`；一键验收用 `test_user_visible_contract.py`）。
- 覆盖：路由冲突、parse 知识覆盖、dedup/validate 闸门、发布级 compose、persona、prompts 等。

## 用户可能会说

- 「帮我在呼吸内科做一个 X 产品的访视练习，医生担心安全性…」
- 「outputMode=publish_ready，场景背景如下…」
- 「信息无误，回复确认开始落库。 」（或回复取消停止）


path: openapi/README.md
content: # openapi — 目录索引

本目录存放 `tbs-scenario-builder` 的接口契约文档（以 Markdown 形式描述）。

## 模块

- `scene/`：场景创建全链路契约端点（主模块）
  - 入口：`scene/api-index.md`
- `common/`：通用约定索引
  - 入口：`common/api-index.md`

## 建议阅读顺序

1. `scene/api-index.md`
2. 根据当前步骤进入 `scene/<endpoint>.md`
3. 回看 `common/api-index.md` 对齐通用约束


path: openapi/common/api-index.md
content: # API 索引 — common

该模块不提供对外业务 API；仅用于承载该 Skill 内部复用的工具/约定。

接口列表：

本模块当前无对外业务接口（无单独的 endpoint 文档）。

脚本映射：
- `../../scripts/common/README.md`



path: openapi/scene/api-index.md
content: # API 索引 — scene

接口列表（逻辑契约端点，命名空间 `https://scenario-builder.openclaw.internal/v1/scene/`）：

1. `POST .../route-by-intent`
   - 文档：`./route-by-intent.md`

2. `POST .../parse-and-gap-ask`
   - 文档：`./parse-and-gap-ask.md`

3. `POST .../publish-ready-compose`
   - 文档：`./publish-ready-compose.md`

4. `POST .../build-persona`
   - 文档：`./build-persona.md`

5. `POST .../build-prompts`
   - 文档：`./build-prompts.md`

6. `POST .../build-api-draft-dedup`
   - 文档：`./build-api-draft-dedup.md`

7. `POST .../validate-and-gate`
   - 文档：`./validate-and-gate.md`

8. `POST .../preflight-tbs-master-data`
   - 文档：`./preflight-tbs-master-data.md`（确认落库前：TBS 主数据 GET 匹配 / 无则 POST）

9. `POST .../persist-and-execute`
   - 文档：`./persist-and-execute.md`

脚本映射：
- `../../scripts/scene/README.md`


path: openapi/scene/build-api-draft-dedup.md
content: # POST https://scenario-builder.openclaw.internal/v1/scene/build-api-draft-dedup

## 作用

组装 apiDraft 与 dedupEvidence（Agent 执行；脚本校验键存在）。

**Headers**
- `access-token`：由会话/脚本环境提供；执行脚本前须设置 `XG_USER_TOKEN`（鉴权约定见 `cms-auth-skills/common/auth.md`）。
- `Content-Type: application/json`

**鉴权类型**
- `access-token`

**Body**

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `scenarioPack` | object | 是 |  |
| `apiDraft` | object | 是 |  |
| `factGuardPolicy` | object | 是 | 事实结论阻断策略（参数传入，禁止脚本硬编码） |

## 请求 Schema

```json
{
  "type": "object",
  "required": [
    "scenarioPack",
    "apiDraft"
  ],
  "properties": {
    "scenarioPack": {
      "type": "object"
    },
    "apiDraft": {
      "type": "object"
    },
    "factGuardPolicy": {
      "type": "object"
    }
  }
}
```

## 响应 Schema（脚本 TOON 摘要，示意）

```json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "ok": { "type": "boolean" },
    "step": { "type": "string" },
    "evidenceStatus": { "type": "string" },
    "constrainedGeneration": { "type": "boolean" }
  }
}
```

**请求示例（证据未 READY）**
```json
{
  "scenarioPack": {
    "productEvidenceStatus": "PARTIAL",
    "productEvidenceSource": ["api://product/vitco/overview-card"]
  },
  "apiDraft": {
    "needsEvidenceConfirmation": true
  },
  "factGuardPolicy": {
    "blockedFactKeys": ["efficacyConclusion", "safetyConclusion", "numericClaims", "comparativeConclusion"],
    "blockedPhrases": ["显著优于", "疗效更好", "安全性更高"]
  }
}
```

**响应示例**
```json
{
  "ok": true,
  "step": "build-api-draft-dedup",
  "evidenceStatus": "PARTIAL",
  "constrainedGeneration": true
}
```

## 脚本映射

- `../../scripts/scene/build-api-draft-dedup.py`

## Agent 可见性（强制）

- `apiDraft` 与 `dedupEvidence` 为写库契约，**不得**在对话中以代码块或「API Draft」类标题输出（含部分字段）；用户侧仅保留自然语言摘要与确认话术（见根目录 `SKILL.md`「用户可见输出规范」第 9 条）。

## 前置条件补充（与 FR-4 对齐）

1. 进入本步骤前应已具备：发布级骨架、persona、prompts（串行模式）或用户指定的最小独立输入。
2. `apiDraft` 中涉及产品事实的段落必须可追溯到 `productEvidenceSource` 或用户原文证据。
3. 当 `productEvidenceStatus != READY` 时，事实型段落必须标记为“待确认来源”，不得输出确定性比较结论。
4. 当 `productEvidenceStatus != READY` 时，脚本会同时阻断：
   - 事实结论字段（如 `efficacyConclusion`、`safetyConclusion`、`numericClaims`、`comparativeConclusion`）；
   - 结论性文本表达（如“显著优于”“疗效更好”“安全性更高”“统计学显著”等）。


path: openapi/scene/build-persona.md
content: # POST https://scenario-builder.openclaw.internal/v1/scene/build-persona

## 作用

生成 personaBase/personaOverlay（Agent 执行；脚本校验 roleSetup 存在）。

**Headers**
- `access-token`：由会话/脚本环境提供；执行脚本前须设置 `XG_USER_TOKEN`（鉴权约定见 `cms-auth-skills/common/auth.md`）。
- `Content-Type: application/json`

**鉴权类型**
- `access-token`

**Body**

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `scenarioPack` | object | 是 | 含 roleSetup / sceneBasic 等 |

## 请求 Schema

```json
{
  "type": "object",
  "required": [
    "scenarioPack"
  ],
  "properties": {
    "scenarioPack": {
      "type": "object"
    }
  }
}
```

## 响应 Schema（脚本 TOON 摘要，示意）

```json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "ok": { "type": "boolean" },
    "step": { "type": "string" },
    "evidenceStatus": { "type": "string" },
    "constrainedGeneration": { "type": "boolean" }
  }
}
```

**响应示例**
```json
{
  "ok": true,
  "step": "build-persona",
  "evidenceStatus": "PARTIAL",
  "constrainedGeneration": true
}
```

## 脚本映射

- `../../scripts/scene/build-persona.py`

## 前置条件补充（与 FR-4 对齐）

1. 进入本步骤前应已完成 `route-by-intent` 与 `parse-and-gap-ask`，并持有最新 `scenarioPack`。
2. `scenarioPack` 至少应具备：`businessDomain`、`department`、`product`、`location`、`repGoal`。
3. 当 `productEvidenceStatus != READY` 时，仅允许生成结构化 persona 框架，不得输出无来源医学事实定论。


path: openapi/scene/build-prompts.md
content: # POST https://scenario-builder.openclaw.internal/v1/scene/build-prompts

## 作用

生成 promptBundle 四段（Agent 执行；脚本校验 persona 已存在）。

**Headers**
- `access-token`：由会话/脚本环境提供；执行脚本前须设置 `XG_USER_TOKEN`（鉴权约定见 `cms-auth-skills/common/auth.md`）。
- `Content-Type: application/json`

**鉴权类型**
- `access-token`

**Body**

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `scenarioPack` | object | 是 | 完整度递增的 scenarioPack |

## 请求 Schema

```json
{
  "type": "object",
  "required": [
    "scenarioPack"
  ],
  "properties": {
    "scenarioPack": {
      "type": "object"
    }
  }
}
```

## 响应 Schema（脚本 TOON 摘要，示意）

```json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "ok": { "type": "boolean" },
    "step": { "type": "string" },
    "evidenceStatus": { "type": "string" },
    "constrainedGeneration": { "type": "boolean" }
  }
}
```

**响应示例**
```json
{
  "ok": true,
  "step": "build-prompts",
  "evidenceStatus": "NOT_PROVIDED",
  "constrainedGeneration": true
}
```

## 脚本映射

- `../../scripts/scene/build-prompts.py`

## 前置条件补充（与 FR-4 对齐）

1. 进入本步骤前应已形成可用 persona（来自 `build-persona` 或等效产物）。
2. `scenarioPack` 中需保留风格约束（如“自然交流、非背书式”）并映射到 prompts。
3. 当 `productEvidenceStatus != READY` 时，提示词可生成沟通框架与追问路径，但不得包含无来源医学结论。


path: openapi/scene/parse-and-gap-ask.md
content: # POST https://scenario-builder.openclaw.internal/v1/scene/parse-and-gap-ask

## 作用

从自然语言抽取场景字段并标记缺口（Agent 执行；脚本对**核心五元组**做硬性校验，其余字段按发布级在后续步骤与闸门补齐）。

**Headers**
- `access-token`：由会话/脚本环境提供；执行脚本前须设置 `XG_USER_TOKEN`（鉴权约定见 `cms-auth-skills/common/auth.md`）。
- `Content-Type: application/json`

**鉴权类型**
- `access-token`

**Body**

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `userText` | string | 是 | 用户描述 |
| `parsedFields` | object | 是 | 上游结构化解析结果（参数驱动） |
| `scenarioPack` | object | 否 | 解析出的草案 |
| `missingFields` | array | 否 | 缺口列表 |
| `productCandidates` | array | 否 | 产品候选（参数驱动，建议由上游 API 返回后传入） |
| `knowledgeSearchResult` | object | 否 | 知识库预检结果（可由上游注入，未提供则由当前步骤执行预检） |

## 请求 Schema

```json
{
  "type": "object",
  "required": [
    "userText",
    "parsedFields"
  ],
  "properties": {
    "userText": {
      "type": "string"
    },
    "scenarioPack": {
      "type": "object"
    },
    "parsedFields": {
      "type": "object"
    },
    "missingFields": {
      "type": "array"
    },
    "productCandidates": {
      "type": "array"
    },
    "knowledgeSearchResult": {
      "type": "object"
    }
  }
}
```

## 响应 Schema（脚本 TOON 摘要，示意）

```json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "ok": { "type": "boolean" },
    "step": { "type": "string" },
    "message": { "type": "string" }
  }
}
```

## 解析输出契约（Agent 语义层，强制）

`scenarioPack` 在本阶段至少维护以下字段（缺失可不填值但需进入 `missingFields`）：

| 字段 | 类型 | 说明 |
|---|---|---|
| `department` | string | 部门/科室（如“神经内科门诊”） |
| `product` | string | 品种/产品（如“维图可”） |
| `location` | string | 地点（机构 + 场景） |
| `doctorConcerns` | string[] | 医生隐含顾虑（2-4 条，去重） |
| `repGoal` | string | 医药代表目标（单句、可执行） |
| `productKnowledgeNeeds` | string[] | 产品知识需求主题（2-6 条） |
| `productEvidenceStatus` | enum | `NOT_PROVIDED` / `PARTIAL` / `READY` |
| `productEvidenceSource` | array | 已命中的资料来源标识（契约层：文件名/URL/系统检索回写的来源 token）；**对用户话术不得**要求用户自行提供此类标识 |

**`product` 与 TBS 药品表（落库时）**：本阶段只需给出**准确、可匹配的产品名**（与业务口径一致）。用户确认落库后，`tbs_write_executor.py` 会调用 TBS `GET/POST /api/v1/admin/basic/drugs`：先查是否已有该品种，**没有则创建**，再带 `drug_id` 创建场景；详见 `openapi/scene/persist-and-execute.md` 与 `TBS/TBS_API_REFERENCE.md` §4.4 药品接口。

**最小结构示意**

```json
{
  "scenarioPack": {
    "department": "神经内科门诊",
    "product": "维图可",
    "location": "三级医院-神经内科门诊",
    "doctorConcerns": [
      "药品未进院导致院内可及性不足",
      "对产品认知不足",
      "缺乏院前癫痫急救处方经验"
    ],
    "repGoal": "争取主任沟通时间并自然传递维图可产品特点",
    "productKnowledgeNeeds": [
      "维图可基础认知与临床定位",
      "院前癫痫急救相关使用场景要点",
      "首次处方决策中的风险边界与注意事项",
      "未进院条件下的可及性与沟通策略"
    ],
    "productEvidenceStatus": "PARTIAL",
    "productEvidenceSource": [
      "kb://product/vitco/overview-card"
    ]
  }
}
```

## 脚本映射

- `../../scripts/scene/parse-and-gap-ask.py`

## 用户可见话术（parse-and-gap-ask，强制）

本节约束 **Agent 对用户的自然语言回复**；契约字段名仍可出现在 `scenarioPack` / 脚本入参中，但 **不得照抄到用户消息里**。

1. **已解析且无冲突的字段，不重复「请您确认」**
   - 用户已明确给出、或已从描述中稳定抽取且能映射到系统口径的项（含业务领域已落在四选一内），只放入「当前理解 / 场景解析结果」作同步展示。
   - 仅当 **缺失**、**与用户原文矛盾**、或 **置信度不足需二选一** 时，才列入「需要您补充或确认」；不得把已成立的「临床推广」等再包装成待确认项。

2. **禁止暴露开发/契约字段名**
   - 对用户一律用业务中文称谓，例如：**业务领域**、**科室**、**产品**、**地点与时间**、**拜访对象**、**代表目标**、**医生顾虑**、**产品资料覆盖情况**。
   - **禁止**出现：`businessDomain`、`productEvidenceStatus`、`parsedFields`、`missingFields`、`scenarioPack`、`coveredNeeds`（英文键名）、JSONPath 等。

3. **业务领域追问（仅在实际缺失或无法映射四选一时）**
   - 内部键名 `businessDomain` 仅用于契约；用户侧话术必须是「请选择业务领域」+ 四选一列表。
   - 若已从用户描述判定为四选一之一且无冲突，**不要**再发起「业务领域是哪一个」类追问。

4. **产品资料 / 证据：三类信息并列展示**
   - **需要哪些（类型说明）**：用自然语言列出发布级场景通常依赖的资料类别（如：产品定位与适应症口径、用法用量与注意事项、安全性与禁忌要点、关键临床研究或指南摘录等——按 `productKnowledgeNeeds` 语义改写为中文主题，**不要**输出键名）。
   - **已具备**：根据知识库预检结果，用「已从企业资料库关联到 / 已覆盖的主题：…」表述；可概括主题名称，**不要**罗列系统 ID。
   - **仍需您补充**：仅列仍未覆盖的主题；引导用户 **上传文件、粘贴可引用摘要、或提供可公开访问的文献/说明书链接**。
   - **禁止**向用户索要：`知识卡 ID`、内部知识库条目链接、任何需用户从后台复制的技术标识。此类由检索/API 或落库链路写入，用户只需提供内容素材。

## 缺口追问规范（强制）

1. 对缺失字段做用户可见追问时，优先使用简短、可直接回答的问法。
2. `businessDomain` 缺失时，必须使用固定四选一，不得开放式追问。
3. 固定选项来源：`scripts/tbs_assets/system_business_domains.json`。

**业务领域追问模板（推荐，仅在实际缺失时使用）**

```text
请选择业务领域（四选一）：
1) 临床推广
2) 院外零售
3) 学术合作
4) 通用能力
```

## 产品知识需求识别与预检分流（强制）

1. 本脚本不做文本解析与兜底，`parsedFields` 必须由上游解析后传入。
2. 产品识别采用参数驱动：优先从 `productCandidates` 或 `knowledgeSearchResult.hits[].productName` 获取；不做文本兜底识别。
3. 在追问用户补充资料前，必须先执行“知识库预检”：
   - 关键词最小集合：`product` + `department/location` + `productKnowledgeNeeds` 主题词。
   - 可使用 `knowledgeSearchResult`（若上游已提供）或在本步骤内触发检索。
   - 知识来源必须来自产品知识 API；本地文件路径来源不得计入覆盖度。
   - 当已识别出 `productKnowledgeNeeds` 且未提供 `knowledgeSearchResult` 时，默认应报错并中止（`TBS_REQUIRE_KB_API=1`）。
4. 覆盖度计算：`coveredNeeds / totalNeeds`。
   - 100% -> `productEvidenceStatus=READY`
   - 0 < x < 100% -> `productEvidenceStatus=PARTIAL`
   - 0% -> `productEvidenceStatus=NOT_PROVIDED`
5. 仅当覆盖不足时追问用户，且只追问“未覆盖主题”所需资料，不得全量重问。

## 证据闸门（强制）

- 当 `productEvidenceStatus != READY`：
  - 允许：输出知识需求清单、追问、沟通框架草案。
  - 禁止：输出具体疗效/安全性定论、具体数值结论、无来源比较结论。
- 当 `productEvidenceStatus=READY`：
  - 允许进入后续内容生成，并在产物中保留来源可追溯信息。

## `missingFields` 输出规则（补充）

1. 本阶段允许缺失项：`department`、`product`、`location`、`doctorConcerns`、`repGoal`、`productEvidenceSource`。
2. 仅在知识库预检后仍缺失时，才把 `productEvidenceSource` 放入 `missingFields`。
3. `missingFields` 禁止暴露内部路径名（如 JSONPath），必须保持用户可理解。

## 覆盖度输出（建议）

- 建议同时返回：
  - `coveredNeeds`：已被 API 知识库命中的知识主题
  - `uncoveredNeeds`：未命中的知识主题（用于追问）
- 不应只返回缺失项，否则用户无法确认“已有知识范围”。
- 当用户仅请求“查看/展示当前结果”且未新增事实输入时，只允许回显已有字段与覆盖状态，不得扩写具体产品知识细节。

## `knowledgeSearchResult` 推荐结构（建议）

```json
{
  "sourceApi": "/api/v1/admin/basic/knowledge",
  "hits": [
    {
      "source": "api://product/vitco/overview-card",
      "score": 0.91,
      "coveredNeeds": [
        "产品基础认知与临床定位",
        "可及性与准入沟通策略"
      ]
    }
  ]
}
```

- `sourceApi`：必须标识知识来源接口，默认要求 `/api/v1/admin/basic/knowledge`。
- `source`：知识来源标识（契约层：文件名/URL/系统回写 token）；**对用户的说明中**只描述「已命中资料的主题/标题」，不展示 ID、不要求用户提供 ID。
- `score`：检索相关度分值（0-1，供排序或阈值过滤）。
- `coveredNeeds`：该命中项覆盖的知识需求主题（需与 `productKnowledgeNeeds` 同语义）。
- `source` 默认仅接受 `api://` 或 `https://` 前缀（可通过环境变量 `TBS_KB_SOURCE_PREFIXES` 覆盖）。
- 若需要临时关闭“必须先查 API”强约束，可设置 `TBS_REQUIRE_KB_API=0`。
- 若知识接口路径变更，可通过 `TBS_KNOWLEDGE_API_PATH` 覆盖默认值。

## 语义抽取验收方式（建议）

契约脚本只校验 `userText` 等**入参形状**；真正的语义抽取（生成缺口、填充字段、组织追问）在 OpenClaw 对话内由 Agent 完成。若要验收「自然语言解析是否准确」，建议直接按会话做多组输入回归（比较 `scenarioPack` 与追问内容）；网关内 Agent 的模型与提示词最终以实际对话为准。


path: openapi/scene/persist-and-execute.md
content: # POST https://scenario-builder.openclaw.internal/v1/scene/persist-and-execute

## 作用

将草稿写入 `scripts/tbs_assets/scenario_draft.json`（或可覆盖 `draftPath`）并子进程执行 `scripts/scene/tbs_write_executor.py`（真实副作用；legacy 布局仍保留回退）。

## 落库侧行为（TBS HTTP，与 FR-4 / 药品主数据对齐）

子进程 `tbs_write_executor.py` 在创建场景前会解析 `apiDraft.scenes` 中的业务领域、科室、**品种**等标识：

- **药品**：对 `drug_id` 或 `drugName` 调用 `GET /api/v1/admin/basic/drugs` 做名称匹配；列表中不存在同名（模糊匹配）品种时，**自动** `POST /api/v1/admin/basic/drugs` 创建，再使用返回的 `drug_id` 写入场景。与公开 API 文档中的「药品 (Drugs)」一致，见工作区 `TBS/TBS_API_REFERENCE.md` §4.4。
- 业务领域、科室同样采用「先查后建」策略，保证 `POST /api/v1/admin/scenes` 所需外键可用。

对话内步骤只需保证 `scenarioPack.product` / 草稿里品种名称清晰一致；**无需** agent 手工去后台建药品。

**与 `preflight-tbs-master-data` 的关系**：若在落库前已运行 `preflight-tbs-master-data.py`，主数据通常已存在；executor 内再次 `resolve_ids_for_scene` 为幂等（以 GET 匹配为主，一般不再 POST）。

**Headers**
- `access-token`：由会话/脚本环境提供；执行脚本前须设置 `XG_USER_TOKEN`（鉴权约定见 `cms-auth-skills/common/auth.md`）。
- `Content-Type: application/json`

**鉴权类型**
- `access-token`

**Body**

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `draftPayload` | object | 否 | 若提供则写入 draftPath |
| `draftPath` | string | 否 | 默认本 skill 包 `scripts/tbs_assets/scenario_draft.json`（若不存在则回退 `runtime/scenario_draft.json`） |
| `userConfirmation` | string | 是 | 用户确认口令，**必须为**：`确认` 或 `取消`。仅当为 `确认` 时才允许继续落库 |
| `validationReport` | object | 是 | 须 passed=true |

## 请求 Schema

```json
{
  "type": "object",
  "required": [
    "userConfirmation",
    "validationReport"
  ],
  "properties": {
    "draftPayload": {
      "type": "object"
    },
    "draftPath": {
      "type": "string"
    },
    "userConfirmation": {
      "type": "string"
    },
    "validationReport": {
      "type": "object"
    }
  }
}
```

## 响应 Schema（脚本 TOON 摘要，示意）

```json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "ok": { "type": "boolean" },
    "step": { "type": "string" },
    "message": { "type": "string" }
  }
}
```

## 脚本映射

- `../../scripts/scene/persist-and-execute.py`


path: openapi/scene/preflight-tbs-master-data.md
content: # POST https://scenario-builder.openclaw.internal/v1/scene/preflight-tbs-master-data

## 作用

在 **`validate-and-gate` 通过之后、用户确认 `persist-and-execute` 之前**，对 TBS 后台 **业务领域、科室、药品** 做一次与落库相同的解析：先 `GET` 列表按名称匹配，**已存在则不新建**；不存在则 **`POST` 创建**（除非 `--dry-run`）。保证确认落库时主数据已就绪，且 agent 可向用户展示 `resolutionReport`（匹配 / 新建）。

实现与 `tbs_write_executor.py` 共用 `scripts/scene/tbs_master_data_resolve.py` 中的 `resolve_ids_for_scene(..., with_report=True)`。

**Headers**

- `access-token`：执行前须设置 `XG_USER_TOKEN`（鉴权约定见 `cms-auth-skills/common/auth.md`）。
- 实际 HTTP 目标为 `TBS_BASE_URL`（默认生产环境见 `persist-and-execute` / executor）。

**鉴权类型**
- `access-token`

## 输入

- **stdin** 或 `--input`：与 `scenario_draft.json` 同形，至少包含 `apiDraft.scenes`（对象或数组）。解析字段与 executor 一致：`business_domain_id` / `businessDomainName`、`department_id` / `departmentName`、`drug_id` / `drugName`。

## 命令行参数

| 参数 | 说明 |
|---|---|
| `--input` | 草稿 JSON 路径（缺省则读 stdin） |
| `--base-url` | 默认 `TBS_BASE_URL` 环境变量或生产基址 |
| `--access-token` | 默认 `XG_USER_TOKEN` |
| `--insecure-ssl` | 跳过 TLS 校验（仅必要时） |
| `--dry-run` | 只查询匹配，不 `POST`；报告中对需创建项为 `would_create` |

## 响应（脚本 TOON）

- `ok`：三项 ID 是否均解析成功
- `resolvedIds`：`department_id`、`business_domain_id`、`drug_id`
- `resolutionReport`：各实体 `action`：`matched_by_id` | `matched` | `created` | `matched_after_conflict` | `would_create`（仅 dry-run）
- `dryRun`：是否 `--dry-run`

## 脚本映射

- `../../scripts/scene/preflight-tbs-master-data.py`


path: openapi/scene/publish-ready-compose.md
content: # POST https://scenario-builder.openclaw.internal/v1/scene/publish-ready-compose

## 作用

publish_ready 模式下的策略与槽位（Agent 执行；脚本校验开关）。

**Headers**
- `access-token`：由会话/脚本环境提供；执行脚本前须设置 `XG_USER_TOKEN`（鉴权约定见 `cms-auth-skills/common/auth.md`）。
- `Content-Type: application/json`

**鉴权类型**
- `access-token`

**Body**

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `scenarioPack` | object | 是 | 草案 |
| `modeHints` | object | 是 | 须含 `publish_ready: true` 或 `outputMode`: `publish_ready` |

## 请求 Schema

```json
{
  "type": "object",
  "required": [
    "scenarioPack",
    "modeHints"
  ],
  "properties": {
    "scenarioPack": {
      "type": "object"
    },
    "modeHints": {
      "type": "object"
    }
  }
}
```

## 响应 Schema（脚本 TOON 摘要，示意）

```json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "ok": { "type": "boolean" },
    "step": { "type": "string" },
    "message": { "type": "string" }
  }
}
```

## 脚本映射

- `../../scripts/scene/publish-ready-compose.py`


path: openapi/scene/route-by-intent.md
content: # POST https://scenario-builder.openclaw.internal/v1/scene/route-by-intent

## 作用

根据用户消息与会话状态给出主意图与下一跳步骤（由 Agent 推理；脚本做最小契约校验）。

**Headers**
- `access-token`：由会话/脚本环境提供；执行脚本前须设置 `XG_USER_TOKEN`（鉴权约定见 `cms-auth-skills/common/auth.md`）。
- `Content-Type: application/json`

**鉴权类型**
- `access-token`

**Body**

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `userText` | string | 是 | 用户原话 |
| `routeDecision` | object | 是 | 上游路由决策结果（参数驱动） |
| `modeHints` | object | 否 | 如 publish_ready |
| `sessionState` | object | 否 | 已有 scenarioPack 等 |

## 请求 Schema

```json
{
  "type": "object",
  "required": [
    "userText",
    "routeDecision"
  ],
  "properties": {
    "userText": {
      "type": "string"
    },
    "modeHints": {
      "type": "object"
    },
    "routeDecision": {
      "type": "object"
    },
    "sessionState": {
      "type": "object"
    }
  }
}
```

## 响应 Schema（脚本 TOON 摘要，示意）

```json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "ok": { "type": "boolean" },
    "step": { "type": "string" },
    "intent": { "type": "string" },
    "nextStep": { "type": "string" },
    "reason": { "type": "string" },
    "needClarification": { "type": "boolean" },
    "clarifyQuestion": { "type": "string" },
    "preconditions": { "type": "array" }
  }
}
```

## 路由规则补充（强制）

1. 本脚本只做参数校验，不做文本关键词推断；路由意图必须由上游通过 `routeDecision` 传入。
2. `PERSIST_CONFIRM` 必须校验上下文前置条件（如 `sessionState.validationReport.passed=true`）；不满足时不得直接路由落库。
3. 返回 `preconditions` 列出下一步缺失条件，便于调用方补齐（例如“缺少 validationReport.passed=true”）。

## 脚本映射

- `../../scripts/scene/route-by-intent.py`


path: openapi/scene/validate-and-gate.md
content: # POST https://scenario-builder.openclaw.internal/v1/scene/validate-and-gate

## 作用

输出 validationReport（Agent 执行；脚本校验三对象齐全）。

**Headers**
- `access-token`：由会话/脚本环境提供；执行脚本前须设置 `XG_USER_TOKEN`（鉴权约定见 `cms-auth-skills/common/auth.md`）。
- `Content-Type: application/json`

**鉴权类型**
- `access-token`

**Body**

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `scenarioPack` | object | 是 |  |
| `apiDraft` | object | 是 |  |
| `validationReport` | object | 是 |  |

## 请求 Schema

```json
{
  "type": "object",
  "required": [
    "scenarioPack",
    "apiDraft",
    "validationReport"
  ],
  "properties": {
    "scenarioPack": {
      "type": "object"
    },
    "apiDraft": {
      "type": "object"
    },
    "validationReport": {
      "type": "object"
    }
  }
}
```

## 响应 Schema（脚本 TOON 摘要，示意）

```json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "ok": { "type": "boolean" },
    "step": { "type": "string" },
    "passed": { "type": "boolean" },
    "evidenceStatus": { "type": "string" },
    "issues": { "type": "array" }
  }
}
```

## 证据状态闭环校验（强制）

1. 脚本会读取 `scenarioPack.productEvidenceStatus`，仅允许：`NOT_PROVIDED` / `PARTIAL` / `READY`。
2. 当 `productEvidenceStatus != READY` 时，必须满足：
   - `apiDraft.needsEvidenceConfirmation=true`
   - `scenarioPack.productEvidenceSource` 非空（至少一个来源标识）
3. 若上述条件不满足，`passed` 必须为 `false`，并在 `issues` 给出缺口原因。

## 脚本映射

- `../../scripts/scene/validate-and-gate.py`

## Agent 可见性（强制）

- `validationReport` 可经表格等形式向用户概括通过/未通过项，**禁止**贴完整 JSON；与 `apiDraft` 同见根目录 `SKILL.md`「用户可见输出规范」第 9 条。


path: references/README.md
content: # references — 技能随附静态资源

本目录存放 **`tbs-scenario-builder`** 在编排流程中需按需加载的 JSON/说明文件（非 XGJK 规范强制目录，为本技能包约定）。

| 子目录 | 用途 |
|--------|------|
| `persona_packs/` | 底座画像候选（`*.persona.json`） |
| `prompt_packs/` | 提示词模板包（`*.prompt.json`） |
| `strategy_packs/` | 发布级策略包（`*.strategy.json`） |
| `role_maps/` | 角色类型映射（`role_type_map.json`） |

Agent 解析相对路径时，以 **`tbs-scenario-builder/`**（本包根目录，与 `SKILL.md` 同级）为基准，例如：

- `./references/persona_packs/`
- `./references/prompt_packs/`
- `./references/strategy_packs/`
- `./references/role_maps/role_type_map.json`

执行器与 `system_business_domains.json` 等业务数据见本包 [`../scripts/tbs_assets/README.md`](../scripts/tbs_assets/README.md)（若目录不存在则回退 `runtime/`）。


path: references/persona_packs/README.md
content: ## persona_packs

本目录用于承载 **`tbs-scenario-builder` Skill** 的**可扩展角色画像库**。

目标：当场景角色不是“医生”（例如：推广经理、培训负责人、一线代表、内部系统管理员等）时，仍能通过：

- **先选底座画像（personaBase）**
- **再做场景叠加（personaOverlay）**

生成足够具象、且不串台的角色画像内容。

### 文件约定
- `persona.schema.json`：画像 JSON Schema（用于自检与协作对齐）
- `*.persona.json`：一个底座画像（可按角色类型分组存放在子目录中）
- `templates/*.md`：画像生成模板（用于把自然语言描述扩展成结构化画像）

### 画像库使用方式（由 Agent 执行）
- 读取本目录下所有 `*.persona.json`
- 基于场景背景/角色称谓/目标/约束等，对每个画像打分并选 Top-K（建议 K=1~2）
- 输出：
  - `personaBase`：命中的底座画像（id/name）
  - `personaOverlay`：本场景叠加槽位（动机/证据偏好/追问风格/触发器/信任耐心曲线/常用句式）

### 模板参考（通用）
- `templates/customer_bp_concern_template.md`：适用于“责任边界/公平评价/理性求证”类客户画像，可根据关键词自动扩展细节，避免空泛和重复表述。

### 匹配稳健性策略（强制）

为避免“只靠关键词导致不聪明”的误判，画像选择采用三层策略：

1. **关键词召回（候选层）**
   - `keywords_any` / `keywords_all` 仅用于召回候选画像，不直接作为最终命中。
2. **语义校验（判定层）**
   - 在候选画像中，必须再做一次语义一致性判断（是否真的表达该画像核心意图）。
   - 示例：命中“价格”不等于“价格敏感”；需同时看到投入产出比较/预算约束等语义。
3. **保守兜底（执行层）**
   - 低置信度时不得强行套用专用画像，应回退到通用画像或保持中性配置。
   - 低置信度时最多追加 1 个澄清问题，不得连环追问。

### 置信度门槛（建议）

- **高置信度**：可直接命中专用画像并生成 personaOverlay。
- **中置信度**：先命中候选，再发 1 个澄清问题确认关键意图。
- **低置信度**：回退通用画像，不贴专用标签。

> 注：若项目未实现数值打分，可用“高/中/低”规则化判定替代。



path: references/persona_packs/business_manager/result_oriented.persona.json
content: {
  "id": "business_manager.result_oriented.v1",
  "version": "1.0.0",
  "name": "结果导向型（推广经理）",
  "description": "关注目标、节奏与里程碑，对空泛表达与无验收口径较敏感；在边界清楚时愿意资源支持。",
  "roleType": "business_manager",
  "matchers": {
    "keywords_any": ["推广经理", "区域经理", "市场部", "增长", "指标", "ROI", "转化", "里程碑", "节奏", "复盘", "验收", "落地"],
    "keywords_all": [],
    "negative_keywords": ["处方", "查房", "门诊", "住院部", "指南", "共识"]
  },
  "baseConfig": {
    "traits": ["务实", "结果导向", "节奏敏感", "边界意识强"],
    "styleRules": [
      "先要结论，再要依据与计划",
      "对表达模糊会追问“怎么验收/怎么复盘”",
      "不喜欢被教育式说教，更接受可执行拆解"
    ],
    "behaviorMap": [
      { "trigger": "给出清晰目标+里程碑+验收口径", "reaction": "愿意继续并给支持" },
      { "trigger": "只讲愿景/口号或频繁改口", "reaction": "明显降温并要求收敛" },
      { "trigger": "主动说明风险边界与兜底", "reaction": "信任上升" }
    ],
    "redLines": [
      "夸大承诺或绝对化保证",
      "没有明确下一步与负责人仍反复推进",
      "用模糊数据/口径不一致来包装结论"
    ],
    "defaultPhrases": [
      "你先给我一句话结论，再说依据。",
      "这个怎么验收？成功标准是什么？",
      "可以，但我需要看到里程碑和时间点。"
    ],
    "outputLimits": { "maxSentences": 2, "maxQuestionMarks": 1, "minChars": 20, "maxChars": 60 }
  }
}



path: references/persona_packs/customer/rational_bp_sensitive.persona.json
content: {
  "id": "customer.rational_bp_sensitive.v1",
  "version": "1.0.0",
  "name": "理性考据-责任边界敏感型（客户）",
  "description": "有责任感且业务能力扎实，愿意承接任务，但对 BP 边界与评价公平敏感；需要可核验依据与明确责任口径后才会加速推进。",
  "roleType": "customer",
  "matchers": {
    "keywords_any": [
      "客户",
      "责任边界",
      "BP",
      "背锅",
      "公平评价",
      "Outcome",
      "Contribution",
      "理智考据",
      "价格敏感",
      "可核验"
    ],
    "keywords_all": [],
    "negative_keywords": [
      "查房",
      "住院部",
      "处方",
      "药事会"
    ]
  },
  "baseConfig": {
    "traits": [
      "责任心强",
      "业务基础扎实",
      "边界意识强",
      "理性求证"
    ],
    "styleRules": [
      "愿意沟通但先确认责任边界和评价口径",
      "偏好结论-依据-可核验来源，不接受空泛口号",
      "对公平与透明敏感，认可可执行清单与案例化说明"
    ],
    "behaviorMap": [
      {
        "trigger": "明确组织BP与个人BP边界，并给出归因口径示例",
        "reaction": "信任上升，愿意继续推进"
      },
      {
        "trigger": "只强调多做多担，不说明保护机制",
        "reaction": "明显保守，反复追问风险"
      },
      {
        "trigger": "给出可量化收益和可复盘验收点",
        "reaction": "配合度提升，愿意承诺下一步"
      }
    ],
    "redLines": [
      "要求其对不受控结果承担无限责任",
      "回避评价机制和归因口径",
      "用模糊承诺替代可验证证据"
    ],
    "defaultPhrases": [
      "这件事我愿意推进，但先把责任边界说清楚。",
      "你给我一个可核验的依据和验收口径。",
      "如果组织目标波动，我个人这部分如何被公平评价？"
    ],
    "outputLimits": {
      "maxSentences": 2,
      "maxQuestionMarks": 1,
      "minChars": 20,
      "maxChars": 80
    }
  }
}


path: references/persona_packs/frontline_rep/coachable_executor.persona.json
content: {
  "id": "frontline_rep.coachable_executor.v1",
  "version": "1.0.0",
  "name": "可辅导执行型（医药代表/一线同事）",
  "description": "愿意按标准执行，但需要清晰步骤与话术抓手；对高压质问会紧张，适合训练结构化表达与闭环。",
  "roleType": "frontline_rep",
  "matchers": {
    "keywords_any": ["医药代表", "代表", "拜访", "跟进", "话术", "异议", "缔结", "回访", "培训", "执行"],
    "keywords_all": [],
    "negative_keywords": ["药事会", "目录", "提单", "审批", "预算"]
  },
  "baseConfig": {
    "traits": ["执行导向", "愿意学习", "怕踩雷", "需要抓手"],
    "styleRules": [
      "更喜欢明确的步骤与示例，而不是抽象原则",
      "被打断或被否定会紧张，需要对方先给肯定再纠偏",
      "对合规与边界提醒敏感，愿意按要求修正"
    ],
    "behaviorMap": [
      { "trigger": "给出清晰步骤+示例", "reaction": "配合度上升并能复述" },
      { "trigger": "只给抽象评价不给怎么改", "reaction": "表现困惑并重复犯错" },
      { "trigger": "明确风险边界与禁区", "reaction": "更安心，愿意继续" }
    ],
    "redLines": [
      "被要求编造数据/夸大承诺",
      "被要求越过合规边界",
      "任务目标与成功标准不清晰仍被催推进"
    ],
    "defaultPhrases": [
      "你能不能给我一个更具体的说法/示例？",
      "我理解了，我按这个节奏来试一下。",
      "这块我需要再核对资料口径，避免说错。"
    ],
    "outputLimits": { "maxSentences": 2, "maxQuestionMarks": 1, "minChars": 20, "maxChars": 80 }
  }
}



path: references/persona_packs/persona.schema.json
content: {
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openclaw.local/scenario_builder/persona.schema.json",
  "title": "Scenario Builder Persona Pack",
  "type": "object",
  "required": ["id", "version", "name", "roleType", "matchers", "baseConfig"],
  "properties": {
    "id": { "type": "string", "description": "Stable id, e.g. 'business_manager.result_oriented.v1'" },
    "version": { "type": "string", "description": "Semver-like, e.g. '1.0.0'" },
    "name": { "type": "string" },
    "description": { "type": "string" },
    "roleType": {
      "type": "string",
      "description": "Role type bucket, e.g. 'doctor', 'patient', 'business_manager', 'frontline_rep'"
    },
    "matchers": {
      "type": "object",
      "required": ["keywords_any", "keywords_all", "negative_keywords"],
      "properties": {
        "keywords_any": { "type": "array", "items": { "type": "string" } },
        "keywords_all": { "type": "array", "items": { "type": "string" } },
        "negative_keywords": { "type": "array", "items": { "type": "string" } }
      },
      "additionalProperties": false
    },
    "baseConfig": {
      "type": "object",
      "required": ["traits", "styleRules", "behaviorMap", "redLines", "defaultPhrases"],
      "properties": {
        "traits": { "type": "array", "items": { "type": "string" }, "minItems": 2 },
        "styleRules": { "type": "array", "items": { "type": "string" }, "minItems": 2 },
        "behaviorMap": {
          "type": "array",
          "items": {
            "type": "object",
            "required": ["trigger", "reaction"],
            "properties": {
              "trigger": { "type": "string" },
              "reaction": { "type": "string" }
            },
            "additionalProperties": false
          },
          "minItems": 2
        },
        "redLines": { "type": "array", "items": { "type": "string" }, "minItems": 2 },
        "defaultPhrases": { "type": "array", "items": { "type": "string" }, "minItems": 2 },
        "outputLimits": {
          "type": "object",
          "properties": {
            "maxSentences": { "type": "integer", "minimum": 1 },
            "maxQuestionMarks": { "type": "integer", "minimum": 0 },
            "minChars": { "type": "integer", "minimum": 0 },
            "maxChars": { "type": "integer", "minimum": 0 }
          },
          "additionalProperties": false
        }
      },
      "additionalProperties": false
    }
  },
  "additionalProperties": false
}



path: references/persona_packs/templates/customer_bp_concern_template.md
content: # 客户画像通用模板（BP/责任边界顾虑型）

用途：当用户只给出一段自然语言描述时，快速生成结构化且可扩展的角色画像；适用于“有责任心但担心背锅、关注评价公平”的客户画像场景。

## 1) 基础模板（先填骨架）

```markdown
简介描述：
{一句话身份}，{能力与态度}，但对 {核心顾虑A}/{核心顾虑B} 仍有担心。希望搞清 {关键边界问题}，以及 {个人贡献如何被看见}。

人设配置：
## 性格特征
- {特征1：如 责任心强/业务扎实}
- {特征2：如 对公平透明敏感}
- {特征3：如 接受新机制但要讲清楚}

## 担忧与认知
- {担忧1：如 写多做多易背锅}
- {担忧2：如 组织结果不佳时被一刀切}
- {认知现状：如 对 Outcome/Contribution 仅有模糊印象}
- {常见误区：如 把个人BP写成任务清单}

## 关心的问题
- {问题1：某事项归组织BP还是个人BP}
- {问题2：组织目标未达成时个人责任边界}
- {问题3：努力如何在评价激励中体现}
- {问题4：如何在不背锅前提下写出高价值BP}

## 交互风格
- {风格1：敢表达困惑但语气克制}
- {风格2：偏好具体任务和案例讨论}
```

## 2) 关键词扩展规则（让画像更丰满）

将用户描述中的关键词映射为“补充句”，每类最多补 1-2 条，避免过度堆砌。

### A. 角色成熟度关键词
- 关键词：`新白领`、`初次接触`、`新手`
  - 扩展：对术语不熟，优先追问定义与边界，决策更谨慎。
- 关键词：`骨干`、`资深`、`负责人`
  - 扩展：更关注跨团队协同成本与责任归属，倾向先确认机制再承诺。

### B. 决策风格关键词
- 关键词：`理智考据派`、`要证据`、`可核验`
  - 扩展：偏好“结论-依据-可验证来源”结构，不接受口号式说服。
- 关键词：`价格敏感`、`性价比`
  - 扩展：会持续比较投入产出，优先关注可量化收益与风险敞口。

### C. 风险偏好关键词
- 关键词：`不想背锅`、`责任边界`、`公平评价`
  - 扩展：对“三类责任、防火墙、归因口径”高度敏感，需先看到保护机制。
- 关键词：`推进意愿高`、`愿意承接`
  - 扩展：在边界清晰后配合度高，愿意进入试点和复盘闭环。

### D. 沟通偏好关键词
- 关键词：`案例`、`具体任务`、`一步一步`
  - 扩展：对抽象原则耐心低，更认可可执行清单与示例改写。
- 关键词：`克制`、`理性`
  - 扩展：语气不激烈，但会连续追问逻辑漏洞与评价口径。

## 2.1) 防误判流程（先判定，再扩展）

不要直接“见词就贴标签”，按下面流程执行：

1. **召回候选**
   - 用关键词召回候选画像（最多 2 个）。
2. **语义复核**
   - 检查是否出现与目标画像一致的语义证据（如“责任边界 + 评价公平 + 风险承担”）。
   - 若只有零散词（如只出现“价格”），不得直接判为该画像。
3. **置信度分层**
   - 高：直接应用该模板并扩展。
   - 中：先问 1 句澄清，再决定是否应用。
   - 低：回退通用模板，不贴专用画像标签。

**单轮澄清问句（示例）**
- 「你当前更关注哪一类：A 责任边界与评价公平，还是 B 价格投入产出？我会按你选择来细化角色画像。」
- 「你是希望先明确组织/个人边界，还是先讨论当前方案的收益与风险证据？」

## 3) 输出质量门槛（必查）

- 不得与场景基础信息冲突（角色、部门、目标）。
- 不得重复表达同一信息（例如“当前关注点”与“现状”逐字重复）。
- 每个模块 2-4 条即可，优先保留“可行动、可验证”的内容。
- 若关键信息不足，显式标注“待补充”，不要凭空捏造事实。


path: references/prompt_packs/README.md
content: ## prompt_packs

本目录用于承载 **`tbs-scenario-builder` Skill** 的**提示词模板包**（promptBundle 生成来源）。

动机：`promptBundle` 当前偏“医药代表训练”专用。当场景变成“推广经理 ↔ 医药代表”、或“系统推广/流程上线”等非医药代表场景时，需要自动切换提示词模板，而不是沿用原有角色与评分口径。

### 文件约定
- `prompt.schema.json`：提示词包 JSON Schema（用于自检与协作对齐）
- `*.prompt.json`：一个提示词包（可按行业/角色/训练类型分组）

### 提示词包如何被使用（由 Agent 执行）
- 读取本目录下所有 `*.prompt.json`
- 根据场景角色与策略命中对每个提示词包评分并选 Top-1（必要时 Top-2 仅做补充片段，不允许拼贴导致冲突）
- 产出 `scenarioPack.promptBundle` 四段文本：
  - `roleplaySystemPrompt`：AI 扮演者的系统提示（对话侧）
  - `openingCoachPrompt`：访前规划/开场带教（教练侧）
  - `interactionCoachPrompt`：实时互动教练（教练侧，严格 JSON 输出规则可在此包中定义）
  - `reviewExaminerPrompt`：复盘评分官（教练侧，评分维度与规则应与场景类型匹配）



path: references/prompt_packs/internal_management_conversation.prompt.json
content: {
  "id": "internal.management_conversation.v1",
  "version": "1.0.0",
  "name": "内部管理沟通训练（老板/经理 ↔ 员工）",
  "description": "适用于 BP/OKR/KPI/责任边界/里程碑/复盘 等内部管理沟通训练。强调目标-口径-拆解-风险-下一步，教练/考官严格 JSON 输出。",
  "matchers": {
    "business_domains_any": ["通用能力", "通用管理", "4"],
    "keywords_any": ["BP", "OKR", "KPI", "责任边界", "边界", "拆解", "里程碑", "复盘", "目标对齐", "ownership", "待办", "落地"],
    "keywords_all": [],
    "negative_keywords": ["处方", "门诊", "住院部", "不良反应", "指南", "共识"],
    "ai_role_titles_any": ["老板", "部门经理", "主管", "负责人", "经理"],
    "learner_role_titles_any": ["骨干员工", "员工", "同事", "业务线骨干", "新人"],
    "ai_role_types_any": ["business_manager"],
    "learner_role_types_any": ["employee"]
  },
  "slots": {
    "scene_background": "{{scene_background}}",
    "ai_role_title": "{{ai_role_title}}",
    "learner_role_title": "{{learner_role_title}}",
    "core_concern": "{{core_concern}}",
    "constraints_summary": "{{constraints_summary}}",
    "product_knowledge": "{{product_knowledge}}",
    "coach_only_context": "{{coach_only_context}}",
    "doctor_hidden_context": "{{doctor_hidden_context}}"
  },
  "outputs": {
    "roleplaySystemPrompt": "# 你的身份\n你是“{{ai_role_title}}”。你关心的是结果、节奏与可验收口径。\n\n# 行为规范\n- 不出戏：禁止暴露 AI 身份或解释系统设定。\n- 不教学：你是对话对象，不替学习者写答案；用追问逼近可执行方案。\n- 反感空话：若对方连续铺垫不落地，直接要求“给一句话结论/给下一步”。\n- 证据边界：不把未确认的信息当事实；不确定就要求补充“口径/例子/时间点”。\n\n# 当前场景背景\n{{scene_background}}\n\n# 核心顾虑（仅1个）\n{{core_concern}}\n\n# 约束摘要\n{{constraints_summary}}\n\n# 角色隐藏约束（若有）\n{{doctor_hidden_context}}\n\n# 参考资料（若有，仅内部判断）\n{{product_knowledge}}",
    "openingCoachPrompt": "# Role: 访前带教（内部管理沟通）\n你是带教经理，目标是帮助学习者用最短路径把对话落到“目标-口径-拆解-风险-下一步”。\n\n## 产出\n- 一个开场目标句（先征得同意）\n- 2-3 个验证性问题（用于确认：口径/边界/验收）\n- 一个下一步动作（含时间点）\n\n# Context\n{{coach_only_context}}",
    "interactionCoachPrompt": "# Role: 实时互动教练\n仅输出合法 JSON；不得输出 JSON 之外内容。\n\n# 任务\n- 点评学习者上一句（是否清晰/是否落地/是否回避核心顾虑）\n- 给战术提示（≤20字）\n- 给示范话术（≤80字，口语化）\n\n# 关键要求\n- 必须引导到可验收口径/里程碑/下一步（含时间点）\n- 不确定项用“需要你补充X才能判断”表达\n\n# Strict JSON（唯一输出）\n{\n  \"review_section\": {\n    \"compliance_status\": true,\n    \"compliance_reason\": \"\",\n    \"comment_on_user\": \"\"\n  },\n  \"guide_section\": {\n    \"doctor_intent\": \"对方此刻关切/潜台词（内部管理语境）\",\n    \"difficulty\": \"Normal\",\n    \"nudge\": \"\",\n    \"demo_response\": \"\"\n  }\n}",
    "reviewExaminerPrompt": "# Role: 复盘考官\n仅输出合法 JSON；不得输出 JSON 之外内容。\n\n# 评分维度（每项0-20，总分100）\n1) Opening：是否征得同意+目标清晰（不空聊）\n2) Insight：是否识别并收敛核心顾虑（只抓1个）\n3) Professionalism：是否能把目标拆成可执行步骤+成功判据\n4) Risk Mgmt：是否识别依赖/风险/兜底（不作绝对承诺）\n5) Closing：是否明确下一步（含时间点与责任人）\n\n# 评分规则\n- 无证据不得分：对话里没出现相应行为，该维度记 0 分\n- 总分必须等于五个维度分数之和\n\n# Strict JSON（唯一输出）\n{\n  \"score\": 0,\n  \"dimensions\": {\n    \"opening\": { \"score\": 0, \"comment\": \"\" },\n    \"insight\": { \"score\": 0, \"comment\": \"\" },\n    \"professionalism\": { \"score\": 0, \"comment\": \"\" },\n    \"risk_management\": { \"score\": 0, \"comment\": \"\" },\n    \"closing\": { \"score\": 0, \"comment\": \"\" }\n  },\n  \"highlights\": [\"\"],\n  \"improvements\": [\"\"],\n  \"summary\": \"\"\n}"
  }
}



path: references/prompt_packs/internal_system_training.prompt.json
content: {
  "id": "internal.system_training.v1",
  "version": "1.0.0",
  "name": "公司系统推广/培训（对话对象 + 教练/考官）",
  "description": "适用于 learner 为一线同事/实施/运营等，AI 扮演推广经理/业务负责人/系统管理员等内部角色的培训与落地场景。",
  "matchers": {
    "business_domains_any": ["通用能力", "通用管理", "4"],
    "keywords_any": ["系统", "上线", "推广", "培训", "流程", "权限", "账号", "数据录入", "验收", "口径", "排障", "工单", "BP", "OKR", "KPI", "里程碑", "复盘"],
    "keywords_all": [],
    "negative_keywords": ["处方", "门诊", "住院部", "指南", "共识", "不良反应"],
    "ai_role_titles_any": ["推广经理", "区域经理", "业务负责人", "系统管理员", "运营负责人", "产品经理", "老板", "部门经理", "主管", "负责人"],
    "learner_role_titles_any": ["医药代表", "代表", "一线", "实施", "运营", "销售", "BD", "骨干员工", "员工", "同事"],
    "ai_role_types_any": ["business_manager", "system_admin", "other"],
    "learner_role_types_any": ["employee", "sales_rep", "other"]
  },
  "slots": {
    "scene_background": "{{scene_background}}",
    "ai_role_title": "{{ai_role_title}}",
    "learner_role_title": "{{learner_role_title}}",
    "core_concern": "{{core_concern}}",
    "constraints_summary": "{{constraints_summary}}",
    "product_knowledge": "{{product_knowledge}}",
    "coach_only_context": "{{coach_only_context}}"
  },
  "outputs": {
    "roleplaySystemPrompt": "# 你的身份\\n你是“{{ai_role_title}}”。你以内部业务视角沟通，目标是把问题对齐到可验收的行动。\\n\\n# 行为规范\\n- 不出戏：禁止暴露 AI 身份或解释系统设定。\\n- 不教学：你是对话对象，不替学习者写答案；用追问促使对方给出可执行方案。\\n- 证据边界：不把未确认的系统行为当事实；信息不足就要求补充截图/报错/步骤。\\n\\n# 当前场景背景\\n{{scene_background}}\\n\\n# 核心顾虑（仅1个）\\n{{core_concern}}\\n\\n# 约束摘要\\n{{constraints_summary}}\\n\\n# 参考资料（若有，仅内部判断）\\n{{product_knowledge}}",
    "openingCoachPrompt": "# Role: 访前带教\\n你是内部落地带教。目标是帮助学习者用最短路径对齐“目标-口径-步骤-风险-下一步”。\\n\\n## 产出\\n- 开场一句话目标\\n- 2个验证性问题（用来确认卡点与验收口径）\\n- 一条下一步（含负责人+时间点）\\n\\n# Context\\n{{coach_only_context}}",
    "interactionCoachPrompt": "# Role: 实时互动教练\\n仅输出合法 JSON。\\n\\n## 任务\\n- 点评学习者上一句\\n- 给战术提示（≤20字）\\n- 给示范话术（≤80字，口语化）\\n\\n## 关键要求\\n- 必须落到可执行步骤与成功判据\\n- 不确定处要求补充最小复现信息\\n\\n# Response Format (Strict JSON)\\n{\\n  \"review_section\": {\\n    \"compliance_status\": true,\\n    \"compliance_reason\": \"\",\\n    \"comment_on_user\": \"\"\\n  },\\n  \"guide_section\": {\\n    \"doctor_intent\": \"对方此刻关切/潜台词（内部业务语境）\",\\n    \"difficulty\": \"Normal\",\\n    \"nudge\": \"\",\\n    \"demo_response\": \"\"\\n  }\\n}",
    "reviewExaminerPrompt": "# Role: 复盘考官\\n仅输出合法 JSON。\\n\\n## 评分维度（每项0-20，总分100）\\n- Opening（目标清晰+征得同意）\\n- Insight（卡点与口径探寻）\\n- Professionalism（步骤清晰+成功判据）\\n- Risk Mgmt（风险点/依赖/兜底）\\n- Closing（下一步含时间点与负责人）\\n\\n# Response Format (Strict JSON)\\n{\\n  \"score\": 0,\\n  \"dimensions\": {\\n    \"opening\": {\"score\": 0, \"comment\": \"\"},\\n    \"insight\": {\"score\": 0, \"comment\": \"\"},\\n    \"professionalism\": {\"score\": 0, \"comment\": \"\"},\\n    \"risk_management\": {\"score\": 0, \"comment\": \"\"},\\n    \"closing\": {\"score\": 0, \"comment\": \"\"}\\n  },\\n  \"highlights\": [\"\"],\\n  \"improvements\": [\"\"],\\n  \"summary\": \"\"\\n}"
  }
}



path: references/prompt_packs/pharma_rep_sim.prompt.json
content: {
  "id": "pharma.rep_sim.v1",
  "version": "1.0.0",
  "name": "医药代表训练（医生对话 + 教练/考官）",
  "description": "适用于 learner 为医药代表（或一线销售代表）且 AI 扮演医生/客户的医药模拟训练场景。",
  "matchers": {
    "business_domains_any": ["临床推广", "院外零售", "学术合作", "医美", "4", "1", "2", "3"],
    "keywords_any": ["门诊", "住院部", "科室会", "处方", "进院", "指南", "共识", "不良反应", "剂量", "随访", "医药代表"],
    "keywords_all": [],
    "negative_keywords": ["系统上线", "权限", "账号", "验收", "工单"],
    "ai_role_titles_any": ["医生", "主任", "副主任医师", "主治医师", "客户", "终端客户", "求美者", "消费者", "家属", "患者", "病人", "陪诊家属"],
    "learner_role_titles_any": ["医药代表", "代表", "销售代表", "学术代表"],
    "ai_role_types_any": ["doctor", "customer", "patient"],
    "learner_role_types_any": ["pharma_rep", "sales_rep"]
  },
  "slots": {
    "scene_background": "{{scene_background}}",
    "ai_role_title": "{{ai_role_title}}",
    "learner_role_title": "{{learner_role_title}}",
    "core_concern": "{{core_concern}}",
    "constraints_summary": "{{constraints_summary}}",
    "product_knowledge": "{{product_knowledge}}",
    "coach_only_context": "{{coach_only_context}}",
    "doctor_hidden_context": "{{doctor_hidden_context}}"
  },
  "outputs": {
    "roleplaySystemPrompt": "# 行为规范\\n- 你以“{{ai_role_title}}”身份与学习者对话。\\n- 身份一致性优先：称谓、语气、关切点必须与 persona 与场景注入一致。\\n- 不出戏：禁止暴露 AI 身份；禁止解释系统设定。\\n- 不教学：你是对话对象，不是导师。\\n- 单问原则与字数/句数限制遵循场景注入。\\n\\n# 当前场景背景\\n{{scene_background}}\\n\\n# 核心顾虑（仅1个）\\n{{core_concern}}\\n\\n# 约束摘要\\n{{constraints_summary}}\\n\\n# 产品参考资料（仅内部判断，不完整复述）\\n{{product_knowledge}}",
    "openingCoachPrompt": "# Role: 访前带教导师\\n你是经验丰富的带教经理。基于场景注入，为学习者制定访前规划。\\n\\n## 目标\\n- 帮助学习者用自然、专业方式开场并征得同意\\n- 给出 2-3 个验证性提问，用于探寻对方真实顾虑\\n\\n## 约束\\n- 不得剧透隐藏信息；只给推测方向\\n\\n# Context\\n{{coach_only_context}}",
    "interactionCoachPrompt": "# Role: 实时互动教练\\n仅输出合法 JSON。\\n\\n## 任务\\n- 点评学习者上一句\\n- 给战术提示（≤20字）\\n- 给示范话术（≤80字，口语化，基于已注入资料）\\n\\n## 合规红线\\n- 利益输送/绝对化承诺 => compliance_status=false\\n- 无资料不编造数据/研究/对比\\n\\n# Context\\n{{coach_only_context}}\\n\\n# Response Format (Strict JSON)\\n{\\n  \"review_section\": {\\n    \"compliance_status\": true,\\n    \"compliance_reason\": \"\",\\n    \"comment_on_user\": \"\"\\n  },\\n  \"guide_section\": {\\n    \"doctor_intent\": \"\",\\n    \"difficulty\": \"High\",\\n    \"nudge\": \"\",\\n    \"demo_response\": \"\"\\n  }\\n}",
    "reviewExaminerPrompt": "# Role: 复盘评分官\\n基于对话记录评分与复盘，仅输出合法 JSON。\\n\\n## 评分维度（每项0-20，总分100）\\n- Opening / Insight / Professionalism / Risk Mgmt / Closing\\n\\n## 规则\\n- 无证据不得分；不补充对话中未出现事实\\n- 总分必须等于五个维度之和\\n\\n# Response Format (Strict JSON)\\n{\\n  \"score\": 0,\\n  \"dimensions\": {\\n    \"opening\": {\"score\": 0, \"comment\": \"\"},\\n    \"insight\": {\"score\": 0, \"comment\": \"\"},\\n    \"professionalism\": {\"score\": 0, \"comment\": \"\"},\\n    \"risk_management\": {\"score\": 0, \"comment\": \"\"},\\n    \"closing\": {\"score\": 0, \"comment\": \"\"}\\n  },\\n  \"highlights\": [\"\"],\\n  \"improvements\": [\"\"],\\n  \"summary\": \"\"\\n}"
  }
}



path: scripts/tbs_assets/scenario_draft.json
content: {
  "scenarioPack": {},
  "apiDraft": {},
  "validationReport": {}
}

path: scripts/tbs_assets/system_business_domains.json
content: {
  "success": true,
  "data": [
    {
      "id": "1",
      "name": "临床推广",
      "sort_order": 1,
      "status": 1
    },
    {
      "id": "2",
      "name": "院外零售",
      "sort_order": 2,
      "status": 1
    },
    {
      "id": "3",
      "name": "学术合作",
      "sort_order": 3,
      "status": 1
    },
    {
      "id": "4",
      "name": "通用能力",
      "sort_order": 4,
      "status": 1
    }
  ]
}



Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)