diff --git a/CHANGELOG.md b/CHANGELOG.md index ddb57d0..44cc31b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,13 @@ - 小节正文写用户能看懂的变化(新能力、修复、注意事项),避免堆砌内部实现细节 - 打 tag 前**必须**为即将发布的版本新增一节;找不到匹配小节时,本次发布不会更新 changelog 字段 +## 1.0.121 + +- 沉淀 Lookup **分页勾选小表**:`display_type: lookup` + `presentation: "paged_table"` + 可选 `page_size`(仍是 Lookup,不要新造控件类型) +- 约定 `skill_cli` 追加 `--page` / `--limit`,stdout 为一行 `{"items","total"}`;0 条也是成功,界面显示「暂无可选项」 +- 只读列表命令不要在入口加载整包 platform-kit 或 Playwright;同库一个过滤条件优先 `local_sql` +- 更新 Schema / ACTIONS / SCHEMA / CHECKLIST A4-12;新增 `lookup-paged-table.action.example.json` + ## 1.0.120 - 正式沉淀行菜单显隐契约 **`bind.visibleWhen`**(宿主已支持:按当前行列值显示/隐藏行按钮) diff --git a/SKILL.md b/SKILL.md index b269489..b47f4d6 100644 --- a/SKILL.md +++ b/SKILL.md @@ -1,7 +1,7 @@ --- name: 技能开发模板(通用业务版) description: "OpenClaw 通用业务技能开发模板,供复制后定制新业务 skill。定制步骤见 development/DEVELOPMENT.md。" -version: 1.0.120 +version: 1.0.121 author: 深圳匠厂科技有限公司 metadata: openclaw: diff --git a/assets/README.md b/assets/README.md index e03c2ee..90d1481 100644 --- a/assets/README.md +++ b/assets/README.md @@ -8,7 +8,7 @@ - `examples/`:CLI 成功输出形状示例、Action 形状参考(含 `data-sources.mysql.example.json`、`path-root-file-action.example.json`、`selection-label-column.action.example.json`、`selection-mode-optional.action.example.json`、`render-html.action.example.json` 等;虚构路径与数据)。 - `schemas/`:轻量 JSON Schema(`skill-actions.schema.json` 为**新技能严格规范**)。 -`skill-actions.schema.json` 使用 `additionalProperties: false`。正式支持 `bind.tables`(toolbar Action 必填)与可选 `bind.inputMapping` / `columnMapping` / **`labelColumn`**(选择摘要标签列)/ **`selectionMode`**(`required` \| `none` \| `optional`:表勾选如何驱动 Action;省略则宿主兼容推断)/ **`visibleWhen`**(行菜单/行按钮按当前行列值显隐)。placements 含 `toolbar` / `row` / `batch` / `cron` / `agent` / `skill-detail`(对齐匠厂宿主)。数据管理 confirm/form 弹层在会应用勾选时展示「已选择」摘要;**form + 有摘要时映射 `readOnly` 默认不占参数区(仍提交)**,可选 **`revealInForm`** 强制显示。弹窗 `description` / 确认黄条 / 参数说明须**用户可见中文**(勿写 `pickCount`/`async`/`pending`/CLI 子命令;见 ACTIONS.md「用户可见文案」)。可选 `hoverHint` 为数据管理工具栏悬停(省略不显示,不回退)。`concurrency`/`locks` 仍为预留。`placements` 与 `executionProfile` 正交——进任务中心只看 `async`,与入口无关。表级 Action 与 Agent 契约见 [`references/ACTIONS.md`](../references/ACTIONS.md);开发深度规范见 [`development/SKILL_ACTION_RUNTIME.md`](../development/SKILL_ACTION_RUNTIME.md)。 +`skill-actions.schema.json` 使用 `additionalProperties: false`。正式支持 `bind.tables`(toolbar Action 必填)与可选 `bind.inputMapping` / `columnMapping` / **`labelColumn`**(选择摘要标签列)/ **`selectionMode`**(`required` \| `none` \| `optional`:表勾选如何驱动 Action;省略则宿主兼容推断)/ **`visibleWhen`**(行菜单/行按钮按当前行列值显隐)。Action Lookup 可选 **`presentation: "paged_table"`** + **`page_size`**(分页勾选小表,仍是 `display_type: lookup`)。placements 含 `toolbar` / `row` / `batch` / `cron` / `agent` / `skill-detail`(对齐匠厂宿主)。数据管理 confirm/form 弹层在会应用勾选时展示「已选择」摘要;**form + 有摘要时映射 `readOnly` 默认不占参数区(仍提交)**,可选 **`revealInForm`** 强制显示。弹窗 `description` / 确认黄条 / 参数说明须**用户可见中文**(勿写 `pickCount`/`async`/`pending`/CLI 子命令;见 ACTIONS.md「用户可见文案」)。可选 `hoverHint` 为数据管理工具栏悬停(省略不显示,不回退)。`concurrency`/`locks` 仍为预留。`placements` 与 `executionProfile` 正交——进任务中心只看 `async`,与入口无关。表级 Action 与 Agent 契约见 [`references/ACTIONS.md`](../references/ACTIONS.md);开发深度规范见 [`development/SKILL_ACTION_RUNTIME.md`](../development/SKILL_ACTION_RUNTIME.md)。 - 用户市场四 Tab 见根目录 [`README.md`](../README.md) / [`TUTORIAL.md`](../TUTORIAL.md) / [`DEMO.md`](../DEMO.md) / [`CHANGELOG.md`](../CHANGELOG.md);写法契约见 [`development/TUTORIAL_SURFACES.md`](../development/TUTORIAL_SURFACES.md) - Agent 调用/编排参考见 [`references/`](../references/)(含 [`ACTIONS.md`](../references/ACTIONS.md)) diff --git a/assets/examples/README.md b/assets/examples/README.md index e78052a..44559ef 100644 --- a/assets/examples/README.md +++ b/assets/examples/README.md @@ -8,6 +8,7 @@ - `render-html.action.example.json`:HTML 报告「重新生成」Action 形状参考(固定 id `render-html`;见 `references/ACTIONS.md`)。 - `lookup-action.example.json`:Action 内联 Lookup(**local_sql**)形状参考(单选 + `multiple: true`;同库跨表勿填编号;见 `references/ACTIONS.md`「跨表引用:Lookup」)。 - `lookup-skill-cli.action.example.json`:Action Lookup **`skill_cli`** 形状参考(打开表单时宿主调兄弟技能 CLI 抽 JSON 选项;跨技能账号列表勿再造本库缓存表;见同节)。 +- `lookup-paged-table.action.example.json`:Lookup **分页勾选小表** `presentation: "paged_table"` 形状参考(仍是 `display_type: lookup`;见 `references/ACTIONS.md`「分页勾选小表」)。 - `year-month-action.example.json`:Action / CRUD 账期月份字段 `display_type: year_month` 形状参考(见 `references/ACTIONS.md`「表单字段类型对照」)。 - `visible-when-action.example.json`:Action 参数字段条件显隐 `visibleWhen` 形状参考(互斥模式联动;见 `references/ACTIONS.md`「字段条件显隐」;≠ `bind.visibleWhen`,≠ Policy L3)。 - `bind-visible-when-row.action.example.json`:行菜单显隐 `bind.visibleWhen` 形状参考(按当前行状态显示/隐藏行按钮;见 `references/ACTIONS.md`「行菜单显隐」)。 diff --git a/assets/examples/lookup-paged-table.action.example.json b/assets/examples/lookup-paged-table.action.example.json new file mode 100644 index 0000000..e37aa9c --- /dev/null +++ b/assets/examples/lookup-paged-table.action.example.json @@ -0,0 +1,47 @@ +{ + "_comment": "形状参考:Action Lookup 分页勾选小表。仍是 display_type=lookup,加 presentation=paged_table。完整契约见 references/ACTIONS.md「分页勾选小表」。不要新造 display_type。skill_cli 的 stdout 须为一行 {items,total};0 条也成功退出。列表命令不要在 main.py 入口加载整包 jiangchang_skill_core 或 Playwright。", + "schemaVersion": 1, + "skill": "your-skill-slug", + "actions": [ + { + "id": "import-picked", + "label": "导入文章", + "description": "从已生成文章里勾选要导入的,可翻页。", + "placements": ["toolbar"], + "executionProfile": "sync", + "interaction": "form", + "bind": { + "tables": ["articles"], + "selectionMode": "none" + }, + "entrypoint": { + "type": "cli", + "command": "import-articles", + "args": ["--ids", "{{articleIds}}"] + }, + "inputSchema": { + "type": "object", + "required": ["articleIds"], + "properties": { + "articleIds": { + "type": "string", + "title": "选择文章", + "description": "勾选要导入的文章。可翻页,可本页全选。", + "display_type": "lookup", + "lookup": { + "source": "skill_cli", + "skill": "geo-generate-article-all", + "command": "title", + "args": ["list-generated-json", "--platform", "toutiaohao"], + "value_column": "id", + "label_column": "title", + "multiple": true, + "presentation": "paged_table", + "page_size": 10 + } + } + } + } + } + ] +} diff --git a/assets/schemas/skill-actions.schema.json b/assets/schemas/skill-actions.schema.json index aa0e47b..365e3f3 100644 --- a/assets/schemas/skill-actions.schema.json +++ b/assets/schemas/skill-actions.schema.json @@ -290,6 +290,17 @@ "multiple": { "type": "boolean", "description": "可选。true=多选 Lookup(存/提交 TEXT 逗号分隔 id);省略或 false=单选(默认)。" + }, + "presentation": { + "type": "string", + "enum": ["select", "paged_table"], + "description": "可选。省略或 select=下拉/勾选/Chip。paged_table=分页勾选小表(编号|文案,可翻页、可本页全选)。仍是 lookup,不要新造 display_type。" + }, + "page_size": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "description": "可选。presentation=paged_table 时每页条数,默认 10,最大 100。" } }, "oneOf": [ diff --git a/development/CHECKLIST.md b/development/CHECKLIST.md index 74a68ac..130bca9 100644 --- a/development/CHECKLIST.md +++ b/development/CHECKLIST.md @@ -114,6 +114,7 @@ checklist_version: 1.0 - [ ] A4-9 **P1** 若同一能力既支持「勾选处理」又支持「按数量从队列领取」:用一个 Action + `bind.selectionMode: "optional"`(勿拆两个同义顶栏按钮);无勾选可点、有勾选显示「已选择」、空选数量字段用 `pickCount` 等约定名(见 `references/ACTIONS.md`) - [ ] A4-10 **P0** 数据管理弹窗与任务失败文案:全中文产品用语;禁止在 `description` / `confirmation.message` / 参数 `description` / 用户向 `message` 写英文字段名、CLI 子命令、`async`/`pending`/`status=` 等(Agent 路由放 `SKILL.md`;见 `references/ACTIONS.md`「用户可见文案」) - [ ] A4-11 **P1** 若行操作应按业务状态显隐(如仅待确认可「采用」、仅已采用可「加入待写」):用 **`bind.visibleWhen`**(对当前行列值求值;存库原始值如 `approved`);勿指望 Policy L3;CLI 侧仍须校验状态(见 `references/ACTIONS.md`「行菜单显隐」) +- [ ] A4-12 **P1** 若要在表单里翻页勾选一批业务行(文章、平台等):用 Lookup **`presentation: "paged_table"`**(仍是 `display_type: lookup`,勿新造类型);`skill_cli` 的 stdout 为一行 `{"items","total"}`,0 条也成功退出;该列表命令不要在入口加载整包 platform-kit 或 Playwright(见 `references/ACTIONS.md`「分页勾选小表」) --- ## 5. 账号与浏览器会话(网页 RPA 适用;其他形态标 N/A 或改测等价项) diff --git a/development/SKILL_ACTION_RUNTIME.md b/development/SKILL_ACTION_RUNTIME.md index 19ed30f..a3ebf67 100644 --- a/development/SKILL_ACTION_RUNTIME.md +++ b/development/SKILL_ACTION_RUNTIME.md @@ -9,7 +9,7 @@ | 文档 | 职责 | |------|------| | 本文 | sync/async、任务中心、Agent 禁令、单内核编排、队列 pick、同步 vs 导出 | -| [`../references/ACTIONS.md`](../references/ACTIONS.md) | `actions.json` 字段、placements、`bind.tables`、`bind.selectionMode`、`bind.visibleWhen`(行菜单显隐)、**用户可见文案**、inputSchema、跨表 Lookup、字段条件显隐 `visibleWhen`、本地路径 `file`/`directory` + 可选 **`pathRoot`**、选择摘要「已选择」与映射 **`readOnly` / `revealInForm`**、**按钮中文名 `label` 参考** | +| [`../references/ACTIONS.md`](../references/ACTIONS.md) | `actions.json` 字段、placements、`bind.tables`、`bind.selectionMode`、`bind.visibleWhen`(行菜单显隐)、**用户可见文案**、inputSchema、跨表 Lookup(含分页勾选 `presentation: paged_table`)、字段条件显隐 `visibleWhen`、本地路径 `file`/`directory` + 可选 **`pathRoot`**、选择摘要「已选择」与映射 **`readOnly` / `revealInForm`**、**按钮中文名 `label` 参考** | | [`LOGGING.md`](LOGGING.md) | `job_context` / `emit` / `finish` / Run Journal | | [`DATA_PATHS.md`](DATA_PATHS.md) | 下载/导入等落盘路径 | diff --git a/references/ACTIONS.md b/references/ACTIONS.md index 781047b..41e3831 100644 --- a/references/ACTIONS.md +++ b/references/ACTIONS.md @@ -1064,7 +1064,56 @@ const data = await jiangchang.call("方法名", { date: "2026-09-19" }); **多选存值与模板:** Action / CRUD 存 **`TEXT` 逗号分隔 id**(如 `1,2,5`);`{{engineIds}}` 原样替换进 CLI。多选字段在 `inputSchema` 里用 `type: "string"`(逗号串),不要用尚未稳定的 JSON array 当业务控件。 -**多选控件(宿主策略):** 选项少(建议 ≤6)用勾选列表;选项多用字段内 Chip + 可搜索下拉(不是再开业务弹窗)。 +**多选控件(宿主策略):** 选项少(建议 ≤6)用勾选列表;选项多用字段内 Chip + 可搜索下拉(不是再开业务弹窗)。需要编号+文案的小表、翻页、本页全选时,用下面的 `paged_table`,不要再做一套控件。 + +#### 分页勾选小表(`presentation: "paged_table"`) + +仍是 **`display_type: "lookup"`**。在已有 `lookup` 上增加 `presentation` 与可选 `page_size`。提交值与 `multiple: true` 相同:**TEXT 逗号分隔 id**。`local_sql` 与 `skill_cli` 都能用。列 Lookup(`_jiangchang_columns`)**不要**声明 `paged_table`。 + +```json +{ + "articleIds": { + "type": "string", + "title": "选择文章", + "description": "勾选要导入的文章。可翻页,可本页全选。", + "display_type": "lookup", + "lookup": { + "source": "skill_cli", + "skill": "geo-generate-article-all", + "command": "title", + "args": ["list-generated-json", "--platform", "toutiaohao"], + "value_column": "id", + "label_column": "title", + "multiple": true, + "presentation": "paged_table", + "page_size": 10 + } + } +} +``` + +| 字段 | 必填 | 说明 | +|------|------|------| +| `presentation` | 用小表时必填 | 只认 `"paged_table"`。省略或 `"select"` = 现有下拉 / 勾选 / Chip | +| `page_size` | 否 | 每页条数,默认 10,限制 1–100 | +| `multiple` | 建议 `true` | 小表按多选提交;一个都不勾时把字段放进 `required`,宿主拒绝空提交 | + +**`skill_cli` 分页:** 宿主在 argv 后追加 `--page`、`--limit`。stdout **只有一行 JSON 对象**:`{"items":[{"id":"1","title":"标题"}],"total":42}`。`total` 是过滤后的总条数,不是本页条数。命令可以自己切片;若一次返回全量且带 `total`,宿主也会按页切开。 + +**空列表:** 分页小表把 `{"items":[],"total":0}` 且退出码 0 当成成功,界面显示「暂无可选项」。普通下拉 Lookup 仍把 0 条当成命令失败。不要为「没有数据」退出码 1,也不要往 stdout 打日志。 + +**同库过滤只有一列:** `local_sql` 的 `filter_column` / `filter_value` 只支持一个等值条件。要「已启用并且提示词齐全」这类两个条件,用一条只读 `skill_cli`,或先做成同库视图再 `local_sql`。同库、一个条件就能列出来的,优先 `local_sql`(打开即查库)。`skill_cli` 每次打开和翻页都会再起进程。 + +**只读列表命令要轻:** 供这张表调用的命令,在 `scripts/main.py` 分到该命令之前,不要 `import jiangchang_skill_core` 整包(包初始化会带上授权客户端),也不要导入 Playwright / 发布栈。0 条也打印空 `items` 后退出码 0。健康检查、真正执行任务仍走 `cli/app.py` 的 `setup_skill_logging`,不要把那条路径拆掉。 + +**反模式(在上一节之外再加):** + +- 新造 `display_type: "paged_lookup"` 或另一套分页控件(应只加 `lookup.presentation`) +- 列表命令在模块顶导入浏览器 / RPA / 整包 platform-kit,打开小表要等数秒 +- 没有数据时让命令失败,小表里出现英文报错而不是「暂无可选项」 +- 用两个 `filter_column` 表达 AND(宿主只认一个等值过滤) + +形状参考:[`assets/examples/lookup-paged-table.action.example.json`](../assets/examples/lookup-paged-table.action.example.json)。 **可选「自动」(单选常见):** 字段不要放进 `required`;不要用 `minimum: 1` 卡死留空。宿主会省略空的可选数字参数,避免「提交的数据无效」。 @@ -1075,11 +1124,11 @@ const data = await jiangchang.call("方法名", { date: "2026-09-19" }); - 标题写成「某某编号」,说明里教用户去左侧表抄 id - 用静态 `enum` 罗列会增长/变更的业务行(会过期) - 在技能里自己拼假 label 列代替宿主统一格式(难维护) -- 另造 `lookup_multi` / 第二套 display_type(应只加 `multiple: true`) +- 另造 `lookup_multi` / `paged_lookup` / 第二套 display_type(多选只加 `multiple: true`;小表只加 `presentation: "paged_table"`) - 为跨技能列表在本库维护镜像缓存表再 `local_sql`(应用 `skill_cli`) - 在列 `options_json` 上声明 `skill_cli`(列 Lookup **只**支持同库) -形状参考:[`assets/examples/lookup-action.example.json`](../assets/examples/lookup-action.example.json)、[`assets/examples/lookup-skill-cli.action.example.json`](../assets/examples/lookup-skill-cli.action.example.json)。 +形状参考:[`assets/examples/lookup-action.example.json`](../assets/examples/lookup-action.example.json)、[`assets/examples/lookup-skill-cli.action.example.json`](../assets/examples/lookup-skill-cli.action.example.json)、[`assets/examples/lookup-paged-table.action.example.json`](../assets/examples/lookup-paged-table.action.example.json)。 ### 表单字段类型对照(须与 CRUD 对称) @@ -1093,7 +1142,7 @@ Skill Action 弹窗与数据管理「新增 / 编辑」使用**同一套控件 | 数字 | `type: number` | `display_type: number` 或 INT/REAL/NUMERIC | | 开关 | `type: boolean` | `display_type: boolean` | | 枚举下拉 | `enum: [...]` | `options_json` 数组 | -| 关联下拉(Lookup) | 内联 `display_type: lookup` + `lookup`(`local_sql` / `skill_cli` / `external_api`;可选 `multiple`),或绑列 | 列侧仅同库 `local_sql`;多选存 `TEXT` 逗号分隔 id | +| 关联下拉(Lookup) | 内联 `display_type: lookup` + `lookup`(`local_sql` / `skill_cli` / `external_api`;可选 `multiple`;可选 `presentation: "paged_table"`),或绑列 | 列侧仅同库 `local_sql`;多选存 `TEXT` 逗号分隔 id;分页小表只在 Action | | 密码 | `sensitive: true` | 列 `sensitive` | | 年份 | `display_type` 或 `format`: `year` | `display_type: year` → 存 `YYYY` | | 年月 | `display_type` 或 `format`: `year_month`(别名 `month`) | `display_type: year_month` → 存 `YYYY-MM` | @@ -1111,7 +1160,7 @@ Skill Action 弹窗与数据管理「新增 / 编辑」使用**同一套控件 | **列筛选「值」** | **无对称**(Action 无表格筛选) | 见 [`SCHEMA.md`](SCHEMA.md)「数据管理:列筛选与全局搜索」:枚举 / boolean / lookup 在筛选栏用**下拉 Select**(非开关、非分段单选);存库仍用 value,展示与搜索认 label | **本版不做(勿宣传):** 浏览器内文件上传控件、复杂 `oneOf` / nested object 专用表单;`visibleWhen` 多条件 AND/OR 树、跨 Action 依赖、CRUD 新增/编辑对称显隐;Action 参数表单的列筛选对称。 -(**Lookup 多选**已支持:同一 `lookup` + `multiple: true`,见上文;不是任意标签数组。) +(**Lookup 多选**已支持:同一 `lookup` + `multiple: true`,见上文;不是任意标签数组。**分页勾选小表**已支持:同一 `lookup` + `presentation: "paged_table"`,见「分页勾选小表」。) (**本地路径选择**已支持:`file` / `directory` + 可选 `pathRoot`,见下节;提交值仍是本机绝对路径字符串,不是 multipart 上传。) 日期时间约定: diff --git a/references/SCHEMA.md b/references/SCHEMA.md index bd02e78..a37f753 100644 --- a/references/SCHEMA.md +++ b/references/SCHEMA.md @@ -750,8 +750,9 @@ CREATE TABLE demo_items ( - 单选:下拉 Select(现状) - 多选且选项较少(建议 ≤6):勾选列表 - 多选且选项较多:字段内 Chip + 可搜索下拉(**不是**再开一层业务弹窗) +- **分页勾选小表**(`lookup.presentation: "paged_table"`)只属于 **Action** 参数表单,列 Lookup 不声明。见 [`ACTIONS.md`](ACTIONS.md)「分页勾选小表」 -Action 弹窗内联 Lookup 与上表 **同构**(字段名一致,含 `multiple`),见 [`ACTIONS.md`](ACTIONS.md)「跨表引用:Lookup」。 +Action 弹窗内联 Lookup 与上表 **同构**(字段名一致,含 `multiple`;Action 另可加 `presentation` / `page_size`),见 [`ACTIONS.md`](ACTIONS.md)「跨表引用:Lookup」。 示例:账号表的平台字段 → 平台信息表;凭据表的账号编号 → 账号信息表;私信 Action 选话术 → `message_templates`;抽检 Action 多选引擎 → `engines` + `multiple: true`。 diff --git a/scripts/util/constants.py b/scripts/util/constants.py index 3abaf33..8c21945 100644 --- a/scripts/util/constants.py +++ b/scripts/util/constants.py @@ -1,6 +1,6 @@ """技能标识、版本与平台公共库约束(复制后请修改 slug/version/logger)。""" SKILL_SLUG = "your-skill-slug" -SKILL_VERSION = "1.0.120" +SKILL_VERSION = "1.0.121" LOG_LOGGER_NAME = "openclaw.skill.your_skill_slug" PLATFORM_KIT_MIN_VERSION = "1.2.11" diff --git a/tests/test_docs_standards.py b/tests/test_docs_standards.py index 14b8bd3..579202a 100644 --- a/tests/test_docs_standards.py +++ b/tests/test_docs_standards.py @@ -417,6 +417,9 @@ class TestDocsStandards(unittest.TestCase): "extra_column", "multiple", "skill_cli", + "paged_table", + "page_size", + "暂无可选项", "local_sql", "external_api", "items_path", @@ -437,14 +440,24 @@ class TestDocsStandards(unittest.TestCase): ), msg="lookup-skill-cli.action.example.json missing", ) + self.assertTrue( + os.path.isfile( + os.path.join(get_skill_root(), "assets/examples/lookup-paged-table.action.example.json") + ), + msg="lookup-paged-table.action.example.json missing", + ) checklist = self._read("development/CHECKLIST.md") self.assertIn("skill_cli", checklist) + self.assertIn("A4-12", checklist) + self.assertIn("paged_table", checklist) account_mgr = self._read("development/ACCOUNT_MANAGER.md") self.assertIn("skill_cli", account_mgr) schema = self._read("references/SCHEMA.md") self.assertIn("skill_cli", schema) schema_json = self._read("assets/schemas/skill-actions.schema.json") self.assertIn("skill_cli", schema_json) + self.assertIn("paged_table", schema_json) + self.assertIn("page_size", schema_json) self.assertIn('"skill"', schema_json) def test_actions_md_disambiguates_visible_when_from_policy(self) -> None: