From bd45de95ab91ad4f8cb66bc283790c4fd3f58ca4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=89=E6=BE=9C?= Date: Sat, 1 Aug 2026 13:46:54 +0800 Subject: [PATCH] feat(schema): finish declaration-framework migration and remove metadata hints Co-authored-by: Cursor --- AGENTS.md | 99 +++--- Makefile | 31 +- README.md | 2 +- README_zh.md | 2 +- docs/flag-help-schema-homology.md | 6 +- docs/rfc-command-framework-convergence.md | 4 +- docs/schema-dynamic-endpoint-design.md | 7 +- ...ema_interface_disposition_contract_test.go | 77 ++--- internal/app/schema_safety_contract_test.go | 6 +- internal/cli/gen.go | 14 +- .../cli/runtime_schema_coverage_more_test.go | 1 + .../cli/schema_agent_metadata/aisearch.json | 10 +- .../cli/schema_agent_metadata/aitable.json | 64 +--- .../cli/schema_agent_metadata/attendance.json | 24 -- internal/cli/schema_agent_metadata/chat.json | 174 +++-------- .../cli/schema_agent_metadata/contact.json | 74 +---- .../cli/schema_agent_metadata/devdoc.json | 8 - internal/cli/schema_agent_metadata/doc.json | 32 -- internal/cli/schema_agent_metadata/drive.json | 18 +- .../cli/schema_agent_metadata/hrbrain.json | 80 ----- internal/cli/schema_agent_metadata/index.json | 2 +- internal/cli/schema_agent_metadata/mail.json | 28 +- .../cli/schema_agent_metadata/markdown.json | 32 -- .../cli/schema_agent_metadata/minutes.json | 10 +- .../cli/schema_agent_metadata/report.json | 8 - internal/cli/schema_agent_metadata/sheet.json | 24 -- internal/cli/schema_agent_metadata/todo.json | 52 +--- internal/cli/schema_agent_metadata_audit.json | 8 +- internal/cli/schema_catalog/catalog.json | 4 +- .../cli/schema_catalog/tools/aitable.json | 191 ++++-------- .../cli/schema_catalog/tools/attendance.json | 88 +++--- .../cli/schema_catalog/tools/calendar.json | 286 +++++++++--------- internal/cli/schema_catalog/tools/dev.json | 12 - internal/cli/schema_catalog/tools/ding.json | 56 +--- internal/cli/schema_catalog/tools/doc.json | 32 +- internal/cli/schema_catalog/tools/drive.json | 21 ++ .../cli/schema_catalog/tools/minutes.json | 8 +- internal/cli/schema_catalog/tools/pat.json | 16 +- internal/cli/schema_catalog/tools/sheet.json | 32 +- internal/cli/schema_catalog/tools/wiki.json | 20 +- internal/cli/schema_catalog_test.go | 56 +++- internal/cli/schema_hint_dirs.go | 17 +- .../schema_hint_emptiness_contract_test.go | 167 ++++++++++ internal/cli/schema_hints.go | 12 +- internal/cli/schema_hints/README.md | 106 +++---- internal/cli/schema_hints/index.json | 29 +- .../cli/schema_hints/metadata/aisearch.json | 17 -- .../cli/schema_hints/metadata/aitable.json | 47 --- .../cli/schema_hints/metadata/attendance.json | 27 -- internal/cli/schema_hints/metadata/audit.json | 11 - .../cli/schema_hints/metadata/calendar.json | 11 - internal/cli/schema_hints/metadata/chat.json | 107 ------- .../cli/schema_hints/metadata/contact.json | 57 ---- internal/cli/schema_hints/metadata/dev.json | 11 - .../cli/schema_hints/metadata/devapp.json | 11 - .../cli/schema_hints/metadata/devdoc.json | 17 -- internal/cli/schema_hints/metadata/ding.json | 11 - internal/cli/schema_hints/metadata/doc.json | 32 -- internal/cli/schema_hints/metadata/drive.json | 22 -- internal/cli/schema_hints/metadata/event.json | 11 - .../cli/schema_hints/metadata/hrbrain.json | 62 ---- internal/cli/schema_hints/metadata/live.json | 11 - internal/cli/schema_hints/metadata/mail.json | 27 -- .../cli/schema_hints/metadata/markdown.json | 32 -- internal/cli/schema_hints/metadata/mcp.json | 11 - .../cli/schema_hints/metadata/minutes.json | 17 -- internal/cli/schema_hints/metadata/oa.json | 11 - internal/cli/schema_hints/metadata/pat.json | 11 - .../cli/schema_hints/metadata/report.json | 17 -- internal/cli/schema_hints/metadata/sheet.json | 27 -- internal/cli/schema_hints/metadata/todo.json | 42 --- internal/cli/schema_hints/metadata/wiki.json | 11 - internal/cli/schema_hints_aitable.go | 110 ------- internal/cli/schema_hints_attendance.go | 67 ---- internal/cli/schema_hints_ding.go | 43 --- internal/cli/schema_hints_helper_roots.go | 95 ------ internal/cli/schema_hints_runtime.go | 117 ------- internal/cli/schema_manual_hints.go | 22 +- ...ema_parameter_mapping_completeness_test.go | 32 +- .../cli/schema_parameter_precedence_test.go | 2 + internal/cli/schema_small_coverage_test.go | 29 ++ internal/cli/schema_text_precedence_test.go | 30 +- internal/generator/agentmetadata/hints.go | 23 +- .../agentmetadata/hints_coverage_test.go | 27 +- internal/generator/agentmetadata/metadata.go | 3 +- .../coverage_more_test.go | 15 +- .../cmd_schema_agent_metadata/main.go | 11 +- .../cmd_schema_agent_metadata/main_test.go | 30 ++ internal/helpers/aitable.go | 19 ++ internal/helpers/attendance.go | 20 ++ internal/helpers/calendar.go | 25 ++ .../calendar_recurrence_paramdecl_test.go | 40 +++ internal/helpers/ding.go | 9 +- internal/helpers/doc.go | 10 + internal/helpers/minutes.go | 6 +- internal/helpers/sheet_workbook.go | 19 +- internal/helpers/wiki.go | 13 +- internal/pat/chmod.go | 12 + scripts/policy/check-generated-drift.sh | 30 +- .../check-runtime-confirmation-truth.sh | 104 ++++--- scripts/policy/check-schema-catalog.sh | 2 + 101 files changed, 1276 insertions(+), 2410 deletions(-) create mode 100644 internal/cli/schema_hint_emptiness_contract_test.go delete mode 100644 internal/cli/schema_hints/metadata/aisearch.json delete mode 100644 internal/cli/schema_hints/metadata/aitable.json delete mode 100644 internal/cli/schema_hints/metadata/attendance.json delete mode 100644 internal/cli/schema_hints/metadata/audit.json delete mode 100644 internal/cli/schema_hints/metadata/calendar.json delete mode 100644 internal/cli/schema_hints/metadata/chat.json delete mode 100644 internal/cli/schema_hints/metadata/contact.json delete mode 100644 internal/cli/schema_hints/metadata/dev.json delete mode 100644 internal/cli/schema_hints/metadata/devapp.json delete mode 100644 internal/cli/schema_hints/metadata/devdoc.json delete mode 100644 internal/cli/schema_hints/metadata/ding.json delete mode 100644 internal/cli/schema_hints/metadata/doc.json delete mode 100644 internal/cli/schema_hints/metadata/drive.json delete mode 100644 internal/cli/schema_hints/metadata/event.json delete mode 100644 internal/cli/schema_hints/metadata/hrbrain.json delete mode 100644 internal/cli/schema_hints/metadata/live.json delete mode 100644 internal/cli/schema_hints/metadata/mail.json delete mode 100644 internal/cli/schema_hints/metadata/markdown.json delete mode 100644 internal/cli/schema_hints/metadata/mcp.json delete mode 100644 internal/cli/schema_hints/metadata/minutes.json delete mode 100644 internal/cli/schema_hints/metadata/oa.json delete mode 100644 internal/cli/schema_hints/metadata/pat.json delete mode 100644 internal/cli/schema_hints/metadata/report.json delete mode 100644 internal/cli/schema_hints/metadata/sheet.json delete mode 100644 internal/cli/schema_hints/metadata/todo.json delete mode 100644 internal/cli/schema_hints/metadata/wiki.json delete mode 100644 internal/cli/schema_hints_aitable.go delete mode 100644 internal/cli/schema_hints_attendance.go delete mode 100644 internal/cli/schema_hints_ding.go delete mode 100644 internal/cli/schema_hints_helper_roots.go delete mode 100644 internal/cli/schema_hints_runtime.go create mode 100644 internal/helpers/calendar_recurrence_paramdecl_test.go diff --git a/AGENTS.md b/AGENTS.md index d0133a8b..a950a4b4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -45,24 +45,26 @@ The Schema data flow is one way: ```text 1. app.NewRootCommand() └─ builds the real Cobra command tree and flags + └─ leaf Safety / Schema / ParamDecl declare ContractFinal (declare-or-annotate) 2. schema_command_registry.json - + schema_hints/metadata/.json tool parameters (+ cli_path) └─ forms EffectiveCommandRegistry └─ binds exactly to real Cobra leaves and aliases 3. Parameter resolution Cobra flags + schema_parameter_bindings.json - + metadata tool parameters + + ParamDecl / native annotations from leaf declarations └─ produces ParameterSpec and constraints 4. Agent and interface semantics schema_hints/selection/.json (selection prose) - + schema_hints/metadata/.json (safety/interface/runtime_gate) + + ContractFinal Safety / Interface on each leaf + pinned MCP metadata └─ resolves Agent metadata by source precedence Markdown is evidence only; it is not concatenated into final prose + └─ schema_hints/metadata/ is retired (directory may be absent; + index.metadata may be {}/omitted); not a parallel leaf-fact source 5. One typed hub BoundCommandRegistry @@ -86,13 +88,11 @@ The Schema data flow is one way: └─ backed by embedded catalog (sync.Once lazy map, O(1) lookup) ``` -Parameter overlays from metadata are merged into `EffectiveCommandRegistry` -*before* Cobra binding; after that point there is no second identity source and -no identity precedence winner. The binder must reject a missing/non-runnable -Cobra path, an alias collision, and any native identity annotation that -disagrees with the effective registry. A missing native identity annotation is -allowed because annotations are implementation-side assertions, not identity -fallbacks. +After binding there is no second identity source and no identity precedence +winner. The binder must reject a missing/non-runnable Cobra path, an alias +collision, and any native identity annotation that disagrees with the effective +registry. A missing native identity annotation is allowed because annotations +are implementation-side assertions, not identity fallbacks. The assembler resolves every bound command exactly once into one `ToolSpec`. Build-time gates and the snapshot serializer consume that source-resolved typed @@ -114,8 +114,9 @@ The Schema system has two physically separated processes: not in business code). - Tools: `internal/generator/cmd_schema_agent_metadata` + `cmd_schema_catalog` + `cmd_param_aliases` (standalone Go mains). -- Inputs: 7 authored source groups (registry + hints metadata + hints selection + - MCP metadata + parameter bindings + reviewed parameter concepts + cobra tree). +- Inputs: authored source groups (registry + required hints selection + MCP + metadata + parameter bindings + reviewed parameter concepts + cobra tree). + `schema_hints/metadata/` is retired and may be absent. - Output: `schema_catalog/` (per-product shards) + `schema_agent_metadata/` + `param_aliases_generated.go`. - Refresh MCP metadata: `make fetch-mcp-metadata` (iterates 26 MCP server @@ -160,11 +161,16 @@ When adding or changing an Agent-visible command, review all relevant inputs: machine-readable editing contract. Preserve the local `$schema` reference; unknown fields, invalid visibility values, stale paths, and collisions fail Go validation and policy. -- `internal/cli/schema_hints/metadata/.json` for safety, interface, - `runtime_gate`, and optional parameter overlays (`parameters` / `cli_path`). +- Leaf `Safety` / `Schema` / `ParamDecl` (helpers `LeafSpec` or shortcut + `Schema`) for parameter facts, interface disposition, and safety. Delivered + provenance is `contract_final` from `corecmd.contract`. - `internal/cli/schema_hints/selection/.json` for reviewed Agent selection prose (`agent_summary`, `use_when`, `avoid_when`, `examples`). -- `internal/cli/schema_hints/index.json` only maps product IDs to those files. +- `internal/cli/schema_hints/metadata/` is retired (directory may be absent). + Do not reintroduce reviewed tool rows or parameter overlays; declare on the + leaf instead. +- `internal/cli/schema_hints/index.json` maps product IDs to selection files; + `metadata` may be omitted or `{}`. - Native Runtime Schema identity annotations, when present, as consistency assertions against `EffectiveCommandRegistry`. They must agree exactly and must never materialize, infer, or override registry identity. @@ -178,20 +184,18 @@ that works through `dws ` but cannot be found through the matching `dws schema` lookup is a contract failure unless it has a reviewed exact exclusion. -Metadata parameter overlays must reference an exact public runnable Cobra leaf -and real flags. They may override Schema description, interface-property/type -mapping, `required`, and `required_when`; they must not create commands or -flags, define an interface, or advertise an unknown RPC. Every authored entry -requires `reviewed: true` and a non-empty review reason. +Production `RegisterSchemaHints` maps must stay empty after ParamDecl +migration. Temporary hint injection is allowed only inside unit-test fixtures +that exercise precedence edges. -For Agent-authored metadata or selection edits: +For Agent-authored selection edits: 1. Confirm the exact command and flag names in the current Cobra tree. -2. Edit only the owning block (`metadata/` or `selection/`); do not mix fields. +2. Edit `selection/.json` for selection prose; declare safety / + parameters / interface on the owning leaf (`LeafSpec` / `Shortcut.Schema`). 3. Add the smallest possible entry; do not copy generated Catalog fields into the input. -4. Describe user-visible semantics in `review_reason` and parameter - descriptions. +4. Describe user-visible semantics in `review_reason`. 5. Run generation, drift, Schema policy, and the focused CLI tests before proposing the change. @@ -201,15 +205,16 @@ Use this workflow when refreshing Agent selection prose and confirmation alignment. Prefer **agent-authored review** over bulk merge scripts that dump `selection-review.json` or Skill Markdown into Catalog fields. -Human-authored inputs are split into two blocks: +Human-authored inputs are split as follows: | Block | Path | Owns | |---|---|---| -| **metadata** | `internal/cli/schema_hints/metadata/.json` | `effect` / `risk` / `confirmation` / `idempotency` / `interface_*` / `runtime_gate` / optional `parameters` | +| **declaration** | helpers / shortcut `Safety` + `Schema` / ParamDecl | `effect` / `risk` / `confirmation` / `idempotency` / `interface_*` / parameter facts (`contract_final`) | | **selection** | `internal/cli/schema_hints/selection/.json` | `agent_summary` / `use_when` / `avoid_when` / `examples` (+ product routing) | +| **metadata** (retired) | `internal/cli/schema_hints/metadata/` may be absent | not a leaf-fact source; do not reintroduce tool rows | -`index.json` only maps product IDs to those files. Do not mix selection fields -into metadata files or metadata fields into selection files. +`index.json` maps product IDs to selection files; `metadata` is optional +(`{}` / omitted). Do not reintroduce metadata tool rows. ### Goals @@ -217,17 +222,19 @@ into metadata files or metadata fields into selection files. sibling-command routing, and outcome shape — not a restatement of the summary. Delivered Catalog provenance is `reviewed_explicit` from `selection/`. -2. **Safety** follows Runtime: `confirmation=user_required` iff the tool's - metadata `runtime_gate != none` (for example `confirm_delete`, `typed_yes`, - `confirm_dangerous`). -3. **Parameter overrides** (former Manual `commands`) live on metadata tools as - `parameters` (+ `cli_path`) and are applied into EffectiveCommandRegistry. +2. **Safety** follows Runtime: `confirmation=user_required` when the leaf + Contract/Safety (or remaining `runtime_gate` annotate) requires a user gate + (for example `confirm_delete`, `typed_yes`, `confirm_dangerous`). +3. **Parameter facts** are declared on the leaf (`ParamDecl` / + `Schema.Parameters` / FlagSpec). Do not add production + `RegisterSchemaHints` overlays or metadata tool parameter rows. ### Authoring For every curated tool: -1. Edit `metadata/.json` for safety/interface/gates/parameters. +1. Declare safety/interface/parameters on the owning leaf + (`DeclareLeafMetadata` / `Shortcut.Schema` / ParamDecl). 2. Edit `selection/.json` for selection prose (`reviewed: true`, `review_reason`, `source_refs`). 3. Run `make generate-schema`. Do not hand-edit generated @@ -259,9 +266,9 @@ Split work by product groups. Each agent must: - Read Skill, Cobra/`--help`, Runtime confirmation sites, and live `dws schema` for its tools. -- Hand-write selection + metadata; forbid wholesale JSON merges from review - dumps. -- Edit only its `metadata/.json` and `selection/.json`. +- Hand-write selection prose and leaf Contract declarations; forbid wholesale + JSON merges from review dumps. +- Edit only its product’s leaf declarations and `selection/.json`. - **Never** `git checkout` unrelated product files to “clean scope”. ### Regenerate and gates @@ -272,6 +279,12 @@ make generate-schema go test ./internal/app -run '^TestSheetFinalSchemaConfirmationMatchesRuntimeGuards$' -count=1 ``` +`check-runtime-confirmation-truth.sh` compares Catalog +`confirmation=user_required` to Contract SafetySpec (plus any residual +metadata `runtime_gate != none`). It does **not** require a +`schema_hints/metadata` directory: absent, empty shells (`tools: {}`), or +missing `tools` all pass. + Example rules (fail generation otherwise): - At most two examples per tool; no `--yes` in stored examples. @@ -279,16 +292,18 @@ Example rules (fail generation otherwise): - No shell comments in examples. After generation, spot-check Catalog: selection provenance is -`reviewed_explicit` from `selection/`, and `user_required` count equals -metadata `runtime_gate != none`. +`reviewed_explicit` from `selection/`, and safety/interface provenance is +`contract_final` from leaf declarations (`user_required` must match Runtime +confirmation gates). `make generate-schema` is a full deterministic snapshot rebuild, not an incremental patch over the previous Catalog. It rereads every reviewed input, removes stale generated product metadata, and rewrites the exact metadata and Catalog projections. Incremental work happens only when an Agent or human -edits selected `metadata/` or `selection/` entries; the next publication still -recomputes all outputs. Generated files must never be read back as merge input, -and byte guards fail generation if it changes the hint inputs or CommandRegistry. +edits selected leaf declarations or `selection/` entries; the next publication +still recomputes all outputs. Generated files must never be read back as merge +input, and byte guards fail generation if it changes the hint inputs or +CommandRegistry. Selection prose may choose a more or less restrictive recommendation. It cannot create a Cobra command or flag, change parameter facts, invent an diff --git a/Makefile b/Makefile index d1c9d942..464ac4d9 100644 --- a/Makefile +++ b/Makefile @@ -140,13 +140,17 @@ generate-schema: registry_guard=$$(mktemp -d); \ concepts_guard=$$(mktemp); \ concepts_schema_guard=$$(mktemp); \ - metadata_guard=$$(mktemp -d); \ selection_guard=$$(mktemp -d); \ + metadata_dir=internal/cli/schema_hints/metadata; \ + metadata_guard=""; \ + if [ -d "$$metadata_dir" ]; then \ + metadata_guard=$$(mktemp -d); \ + cp -R "$$metadata_dir"/. "$$metadata_guard"/; \ + fi; \ trap 'rm -rf "$$registry_guard" "$$concepts_guard" "$$concepts_schema_guard" "$$metadata_guard" "$$selection_guard"' EXIT HUP INT TERM; \ cp -R internal/cli/schema_command_registry/ "$$registry_guard/"; \ cp internal/cli/param_concepts.json "$$concepts_guard"; \ cp internal/cli/param_concepts.schema.json "$$concepts_schema_guard"; \ - cp -R internal/cli/schema_hints/metadata/. "$$metadata_guard/"; \ cp -R internal/cli/schema_hints/selection/. "$$selection_guard/"; \ $(GO) generate ./internal/cli; \ diff -qr internal/cli/schema_command_registry "$$registry_guard" >/dev/null || { \ @@ -161,18 +165,19 @@ generate-schema: printf '%s\n' 'generation modified reviewed input internal/cli/param_concepts.schema.json' >&2; \ exit 1; \ }; \ - cmp -s internal/cli/param_concepts.json "$$concepts_guard" || { \ - printf '%s\n' 'generation modified reviewed input internal/cli/param_concepts.json' >&2; \ + if [ -n "$$metadata_guard" ]; then \ + if [ ! -d "$$metadata_dir" ]; then \ + printf '%s\n' 'generation removed reviewed input internal/cli/schema_hints/metadata' >&2; \ + exit 1; \ + fi; \ + diff -qr "$$metadata_dir" "$$metadata_guard" >/dev/null || { \ + printf '%s\n' 'generation modified reviewed input internal/cli/schema_hints/metadata' >&2; \ + exit 1; \ + }; \ + elif [ -d "$$metadata_dir" ]; then \ + printf '%s\n' 'generation created reviewed input internal/cli/schema_hints/metadata' >&2; \ exit 1; \ - }; \ - cmp -s internal/cli/param_concepts.schema.json "$$concepts_schema_guard" || { \ - printf '%s\n' 'generation modified reviewed input internal/cli/param_concepts.schema.json' >&2; \ - exit 1; \ - }; \ - diff -qr internal/cli/schema_hints/metadata "$$metadata_guard" >/dev/null || { \ - printf '%s\n' 'generation modified reviewed input internal/cli/schema_hints/metadata' >&2; \ - exit 1; \ - }; \ + fi; \ diff -qr internal/cli/schema_hints/selection "$$selection_guard" >/dev/null || { \ printf '%s\n' 'generation modified reviewed input internal/cli/schema_hints/selection' >&2; \ exit 1; \ diff --git a/README.md b/README.md index b41d933a..32fb6b8c 100644 --- a/README.md +++ b/README.md @@ -396,7 +396,7 @@ The repo ships a complete Agent Skill system under `skills/`, organized into two - `skills/mono/` — single-skill layout (one `SKILL.md` + `references/products/`), recommended default. - `skills/multi/` — per-product skills (`dingtalk-aitable/`, `dingtalk-calendar/`, `dingtalk-chat/`, ...), each with its own `SKILL.md`. 🧪 **EXPERIMENTAL / preview — see banner in each multi `SKILL.md` for caveats.** -Shared reviewed inputs for Schema generation live separately under `internal/cli/schema_hints/`. They are not Agent Skills and are excluded from binaries and release skill bundles. +Shared Schema generation inputs live under `internal/cli/schema_hints/` (required reviewed `selection/` prose; `metadata/` is retired and may be absent; leaf safety/parameters come from Contract). They are not Agent Skills and are excluded from release skill bundles. After installing, AI tools like Claude Code / Cursor can operate DingTalk directly through natural language: diff --git a/README_zh.md b/README_zh.md index 678b375e..23f38619 100644 --- a/README_zh.md +++ b/README_zh.md @@ -390,7 +390,7 @@ dws aitable record query --base-id BASE_ID --table-id TABLE_ID --limit 10 - `skills/mono/` — 单 skill 布局(一个 `SKILL.md` + `references/products/`),默认推荐。 - `skills/multi/` — 每个产品一个独立 skill(`dingtalk-aitable/` / `dingtalk-calendar/` / `dingtalk-chat/` ...),每个 skill 自带 `SKILL.md`。🧪 **试验版 / Preview — 各 multi `SKILL.md` 头部有详细注意事项。** -Schema 生成共享的 reviewed 输入单独位于 `internal/cli/schema_hints/`。它们不是 Agent Skill,也不会进入二进制或发布 skill 包。 +Schema 生成共享输入单独位于 `internal/cli/schema_hints/`(必需的 reviewed `selection/`;`metadata/` 已退役且可缺席;叶子 safety/参数由 Contract 声明)。它们不是 Agent Skill,也不会进入发布 skill 包。 安装之后,Claude Code / Cursor 等 AI 工具就能通过自然语言直接操作钉钉: diff --git a/docs/flag-help-schema-homology.md b/docs/flag-help-schema-homology.md index 4d614a1f..f4b2510f 100644 --- a/docs/flag-help-schema-homology.md +++ b/docs/flag-help-schema-homology.md @@ -140,7 +140,7 @@ NewLeafCommand(LeafSpec{ | `cli.AnnotateRuntimeGate` / `devAppMetaWrite` | `dws.schema.runtime_gate=devAppRequireWriteGuard` | 尚未迁移到 SafetySpec 的旧写命令(`HOM-S2`) | | `cli.AnnotateRuntimeRisk` | `dws.schema.risk=…` | Shortcut 暂存的旧兼容路径;command/Leaf 禁止新增 | | `cli.AnnotateRuntimeFlag` / Constraints | 与 embed 同形 | 手写 cobra 叶补齐表面(长期应迁入 Contract) | -| reviewed `schema_hints/metadata` Safety | effect/risk/confirmation | 迁移期遗留;受管命令收敛后让位于 Safety/gate | +| reviewed `schema_hints/metadata` Safety | effect/risk/confirmation | 已迁出:metadata 壳为 `tools: {}`;受管命令以 Contract.Safety / gate 为准 | 标注与声明冲突时:**Contract 声明胜**(路径 A)。标注不得发明未注册的 CLI flag。 @@ -174,8 +174,8 @@ NewLeafCommand(LeafSpec{ | canonical path / aliases / navigation / exposure | `schema_command_registry`(+ reviewed manual additions) | Schema identity | | use_when / avoid_when / examples / agent_summary 文案 | `schema_hints/selection` | Schema selection | | RPC tool 形状、`interface_ref`、interface 描述 | `schema_mcp_metadata` + `schema_parameter_bindings` | Schema `interface_*` 字段;**不得创建 flag** | -| 参数描述 overlay(可选) | `schema_hints/metadata` 仅补充 usage 文案 | 与 Contract/cobra 冲突时 **Contract/cobra 胜** | -| 遗留 Safety 文案(迁移期) | 今日仍可读 `schema_hints/metadata` safety | 受管命令收敛后以 Contract.Safety / runtime_gate 为准(见 §4) | +| 参数描述 overlay(可选) | 生产 metadata 壳为空;参数事实走 ParamDecl / FlagSpec | **Contract/cobra 胜** | +| 遗留 Safety 文案(迁移期) | 生产 metadata 壳为空;Safety 走 Contract | 以 Contract.Safety / runtime_gate 为准(见 §4) | | dry-run 正能力 | reviewed dry-run registry | Schema `dry_run` | | positionals | Contract Args / 显式 annotate | Schema `positionals` | | FieldProvenance | 组装派生 | Schema provenance(与值一致) | diff --git a/docs/rfc-command-framework-convergence.md b/docs/rfc-command-framework-convergence.md index 2a7b5381..c6edaa82 100644 --- a/docs/rfc-command-framework-convergence.md +++ b/docs/rfc-command-framework-convergence.md @@ -345,13 +345,13 @@ Definition(仅声明;不可编译) | **Identity** | `product_id`, `name`, `cli_name`, `canonical_path` / `cli_path` / `primary_cli_path`, `group`, `aliases`, `source`, `source_product_id` | 绑定树 entry(registry 绑定结果) | `schema_command_registry`(+ reviewed manual additions);`SchemaDecl.Identity` 可声明但**必须与绑定一致**,不一致组装报错 | 可声明(钉扎/自描述),**不得改绑** | | **Display / Title / Description** | 产品展示名;工具 title/description | 评审源为主;cobra Short/Long 可作候选 | registry 产品名;hints/metadata / cobra help 解析 | Short/Long 可声明,但 **canonical 文案不以 Contract 胜 identity** | | **Parameters** | `name`, `type`, `required` / `cli_required`, `default` | **声明**(或手写 annotate 同形) | `Flags` → `embedContractIntoSchema` / cobra | **是** | -| | `description`(usage 文案) | 声明 usage;hints 可 overlay 文案 | `FlagSpec.Usage`;`schema_hints/metadata` 仅补 description | usage **是**;overlay 不得改 type/required/default | +| | `description`(usage 文案) | 声明 usage;生产 metadata 壳为空 | `FlagSpec.Usage` / ParamDecl;勿再往 `schema_hints/metadata` 填 overlay | usage **是**;不得用 hint overlay 改 type/required/default | | | `property`(载荷键) | 声明 | `FlagSpec.Bind`(空则 Name) | **是**(载荷映射) | | | `enum`, `format`, `example`, `required_when` | 声明或评审 annotate | 今日部分仍 hints/手工;目标进 Contract / reviewed 约束 | 有则须 declare 或 reviewed annotate | | | `interface_description`, `interface_type`, `interface_default` | 评审源(interface) | `schema_mcp_metadata` + bindings | 否;**不得创建 CLI flag**(`HOM-I1`) | | **Constraints** | `require_one_of`, `mutually_exclusive`, `require_together` | **声明** | `Constraints` → `AnnotateConstraints` | **是** | | **Positionals** | 位置参数名/必填/说明 | **声明** 或显式 annotate | 目标 `Args`/`PositionalSpec`;今日少量 cobra Args + 注解 | 受管命令应声明,禁止推断 | -| **Safety** | `effect`, `risk`, `confirmation`, `idempotency` | **声明**(完整 `cli.SafetySpec`)**或标注**(`runtime_gate`)或迁移期 reviewed Safety | `Safety` / `AnnotateRuntimeGate` / `schema_hints/metadata` safety | 四字段独立;confirmation 单独驱动运行时 | +| **Safety** | `effect`, `risk`, `confirmation`, `idempotency` | **声明**(完整 `cli.SafetySpec`)**或标注**(`runtime_gate`) | `Safety` / `AnnotateRuntimeGate`(metadata 壳 `tools: {}`,不再承载 reviewed Safety) | 四字段独立;confirmation 单独驱动运行时 | | | `idempotency` | 评审源(或未来 Contract) | reviewed metadata | 今日非框架声明;不得推断 | | | `effect_source` / provenance | 组装派生物 | resolver 写入 `FieldProvenance` | 派生,不手写 | | **DryRun** | `preview_kind`, `remote_reads` | 评审源 | `schema_dry_run_capabilities`(正能力声明) | 否;无条目 ≠ 推断「不支持」之外的假能力 | diff --git a/docs/schema-dynamic-endpoint-design.md b/docs/schema-dynamic-endpoint-design.md index 3e5b655e..6a0cd260 100644 --- a/docs/schema-dynamic-endpoint-design.md +++ b/docs/schema-dynamic-endpoint-design.md @@ -45,7 +45,8 @@ skills/mono Markdown + internal/cli/schema_hints/*.json | +-----------------------+ | live Cobra flag facts / typed parameter metadata - + schema_hints/metadata/*.json (reviewed parameter overlay + safety) + + leaf Contract (Safety / Schema / ParamDecl → contract_final) + + schema_hints/metadata/*.json (reserved product shells; tools: {}) + schema_hints/selection/*.json (reviewed Agent selection prose) + schema_parameter_bindings.json (reviewed flag -> RPC property) + schema_mcp_metadata.json (pinned, sanitized interface facts) @@ -130,7 +131,7 @@ DWS 当前对外仍保留兼容 wire:leaf 使用 flat `parameters`,安全和 | reviewed manual command additions | 将一个精确存在的 runnable Cobra leaf 合并进 `EffectiveCommandRegistry`;必须 reviewed 且带 reason | 运行时 fallback、覆盖冲突 identity、创建命令 | | Go/Cobra | Contract 编译后的可执行投影:路径是否真实可执行、Cobra 接受的 flag、DefValue、help 文本 | 稳定 canonical identity、Agent 场景选择、虚构 RPC;**不得**成为与 Contract 平行的第二套 flag 权威 | | native Schema identity annotations | implementation-side consistency evidence;存在时必须与 `EffectiveCommandRegistry` 精确一致 | 提供、补全、推断或覆盖 identity | -| `schema_hints/metadata/*.json` parameter overlays | 补充 flag **description** 等文案;迁移期可读 safety | 创建命令/flag;**不得**静默改写 type/required/default(与 Contract 冲突时 Contract/cobra 胜);不得绕过 completeness、虚构 RPC | +| `schema_hints/metadata/*.json` product shells | 保留产品壳(`tools: {}`);叶子事实已迁入 Contract/ParamDecl | 重新填入 reviewed 工具行或 parameter overlay;创建命令/flag;绕过 completeness、虚构 RPC | | typed parameter metadata / constraints | 由 Contract 约束投影而来的 `require_one_of` / 互斥等;以及仍需 reviewed 的 `required_when` 等 | 命令 identity | | `schema_parameter_bindings.json` | 稳定 CLI flag 到 RPC property 的映射 | 命令发现、risk 推断、创建 CLI flag | | `schema_mcp_metadata.json` | pinned RPC identity、接口描述和脱敏参数事实(interface 同源) | CLI identity、运行时路由、**创建 CLI flag**、risk 推断 | @@ -329,6 +330,6 @@ go test ./internal/cli ./internal/app ./internal/generator/... -count=1 - renderer、query 或 gate 在 `SchemaRegistry` 之后重新读取 source 并做第二次 merge。 - 用 prefix/wildcard exclusion 隐藏未来命令。 - 让 manual hint、CommandRegistry 或 interface metadata 宣称一个不存在的命令、flag 或 RPC 可用。 -- 让 `schema_hints/metadata` overlay 在与 Contract/cobra 冲突时赢得 type/required/default。 +- 让 `schema_hints/metadata` 重新承载 reviewed 工具行 / parameter overlay,或让任何残留 overlay 在与 Contract/cobra 冲突时赢得 type/required/default。 - 把 `schema --all` 当作普通业务数据查询,或把其完整结果无条件注入 Agent 上下文。 - 将 LeafSpec、`+shortcut` 或 write-guard/cursor/多步命令注册为 `mcp_passthrough` 表面。 diff --git a/internal/app/schema_interface_disposition_contract_test.go b/internal/app/schema_interface_disposition_contract_test.go index b2406459..cc7d3f65 100644 --- a/internal/app/schema_interface_disposition_contract_test.go +++ b/internal/app/schema_interface_disposition_contract_test.go @@ -13,65 +13,55 @@ import ( func TestReviewedRoutedInterfacesReachFinalSchema(t *testing.T) { type interfaceCase struct { - canonical string - mode string - reason string - sourceSuffix string + canonical string + mode string + reason string } tests := []interfaceCase{ { - canonical: "attendance.get_attendance_summary", - mode: "composite", - reason: "Reviewed unpinned remote adapter: the CLI calls attendance-wukong/get_user_attendance_summary, which is absent from the pinned MCP metadata snapshot; the incompatible attendance/get_attendance_summary contract must not be advertised.", - sourceSuffix: "internal/cli/schema_hints/metadata/attendance.json", + canonical: "attendance.get_attendance_summary", + mode: "composite", + reason: "Reviewed unpinned remote adapter: the CLI calls attendance-wukong/get_user_attendance_summary, which is absent from the pinned MCP metadata snapshot; the incompatible attendance/get_attendance_summary contract must not be advertised.", }, { - canonical: "drive.list_files", - mode: "composite", - reason: "The CLI command routes by --workspace between drive/list_files and doc/list_nodes, so the reviewed executable wrapper has no single direct MCP interface.", - sourceSuffix: "internal/cli/schema_hints/metadata/drive.json", + canonical: "drive.list_files", + mode: "composite", + reason: "The CLI command routes by --workspace between drive/list_files and doc/list_nodes, so the reviewed executable wrapper has no single direct MCP interface.", }, { - canonical: "chat.search_groups", - mode: "composite", - reason: "Reviewed unpinned remote adapter: the CLI calls im/search_groups with a flat payload, while the pinned snapshot only contains the incompatible chat/search_groups_by_keyword contract.", - sourceSuffix: "internal/cli/schema_hints/metadata/chat.json", + canonical: "chat.search_groups", + mode: "composite", + reason: "Reviewed unpinned remote adapter: the CLI calls im/search_groups with a flat payload, while the pinned snapshot only contains the incompatible chat/search_groups_by_keyword contract.", }, { - canonical: "sheet.range_batch_set_style", - mode: "composite", - reason: "The CLI reads a local batch file and performs multiple sheet/update_range calls with local continue-on-error control; the workflow has no single direct MCP interface.", - sourceSuffix: "internal/cli/schema_hints/metadata/sheet.json", + canonical: "sheet.range_batch_set_style", + mode: "composite", + reason: "The CLI reads a local batch file and performs multiple sheet/update_range calls with local continue-on-error control; the workflow has no single direct MCP interface.", }, { - canonical: "sheet.range_read", - mode: "composite", - reason: "Reviewed unpinned remote adapter: the CLI calls sheet/get_cell_infos, which is absent from the pinned MCP metadata snapshot; the incompatible sheet/get_range contract must not be advertised.", - sourceSuffix: "internal/cli/schema_hints/metadata/sheet.json", + canonical: "sheet.range_read", + mode: "composite", + reason: "Reviewed unpinned remote adapter: the CLI calls sheet/get_cell_infos, which is absent from the pinned MCP metadata snapshot; the incompatible sheet/get_range contract must not be advertised.", }, { - canonical: "wiki.list_wikiSpaces", - mode: "composite", - reason: "The CLI command routes by --type between wiki/list_wikiSpaces and drive/list_spaces, so the reviewed executable wrapper has no single direct MCP interface.", - sourceSuffix: "internal/cli/schema_hints/metadata/wiki.json", + canonical: "wiki.list_wikiSpaces", + mode: "composite", + reason: "The CLI command routes by --type between wiki/list_wikiSpaces and drive/list_spaces, so the reviewed executable wrapper has no single direct MCP interface.", }, { - canonical: "event.consume", - mode: "composite", - reason: "Reviewed composite workflow: the command creates or reuses a remote personal-event subscription and coordinates the local event bus and Stream consumer; no single pinned RPC represents the workflow.", - sourceSuffix: "internal/cli/schema_hints/metadata/event.json", + canonical: "event.consume", + mode: "composite", + reason: "Reviewed composite workflow: the command creates or reuses a remote personal-event subscription and coordinates the local event bus and Stream consumer; no single pinned RPC represents the workflow.", }, { - canonical: "event.status", - mode: "composite", - reason: "Reviewed composite workflow: the command reads the remote personal-event subscription control plane and combines it with local bus and consumer state; no single pinned RPC represents the result.", - sourceSuffix: "internal/cli/schema_hints/metadata/event.json", + canonical: "event.status", + mode: "composite", + reason: "Reviewed composite workflow: the command reads the remote personal-event subscription control plane and combines it with local bus and consumer state; no single pinned RPC represents the result.", }, { - canonical: "event.stop", - mode: "composite", - reason: "Reviewed composite workflow: the command deletes remote personal-event subscriptions, interrupts local consumers, updates local state, and may stop the local bus; no single pinned RPC represents the workflow.", - sourceSuffix: "internal/cli/schema_hints/metadata/event.json", + canonical: "event.stop", + mode: "composite", + reason: "Reviewed composite workflow: the command deletes remote personal-event subscriptions, interrupts local consumers, updates local state, and may stop the local bus; no single pinned RPC represents the workflow.", }, } for _, canonical := range []string{ @@ -81,10 +71,9 @@ func TestReviewedRoutedInterfacesReachFinalSchema(t *testing.T) { "aitable.view_update_timebar", } { tests = append(tests, interfaceCase{ - canonical: canonical, - mode: "composite", - reason: "The CLI performs an aitable/get_views preflight, locally transforms the requested configuration, and then calls aitable/update_view; the two-call workflow has no single direct MCP interface.", - sourceSuffix: "internal/cli/schema_hints/metadata/aitable.json", + canonical: canonical, + mode: "composite", + reason: "The CLI performs an aitable/get_views preflight, locally transforms the requested configuration, and then calls aitable/update_view; the two-call workflow has no single direct MCP interface.", }) } diff --git a/internal/app/schema_safety_contract_test.go b/internal/app/schema_safety_contract_test.go index 46e48311..43b0dbc4 100644 --- a/internal/app/schema_safety_contract_test.go +++ b/internal/app/schema_safety_contract_test.go @@ -16,8 +16,8 @@ type finalSchemaSafetyWant struct { confirmation string idempotency string // provenance is the expected field_provenance precedence; empty defaults - // to "reviewed_explicit" (hints path). Contract-declared tools (devapp) - // deliver "contract_final". + // to "contract_final" (DeclareLeafMetadata / corecmd.Contract). Production + // metadata shells no longer carry reviewed tool rows. provenance string } @@ -88,7 +88,7 @@ func assertFinalSchemaSafety(t *testing.T, wants []finalSchemaSafetyWant) { } wantProvenance := want.provenance if wantProvenance == "" { - wantProvenance = "reviewed_explicit" + wantProvenance = "contract_final" } provenance := schemaContractMap(tool["field_provenance"]) for field, expected := range values { diff --git a/internal/cli/gen.go b/internal/cli/gen.go index c7309f7e..93b8ea5a 100644 --- a/internal/cli/gen.go +++ b/internal/cli/gen.go @@ -19,12 +19,14 @@ // // Generation inputs (authored, reviewed): // 1. schema_command_registry/ identity (canonical/aliases/navigation) -// 2. schema_hints/metadata/*.json safety (effect/risk/confirmation) -// 3. schema_hints/selection/*.json selection (use_when/avoid_when) -// 4. schema_mcp_metadata.json MCP server tool definitions -// 5. schema_parameter_bindings.json parameter type/property mappings -// 6. param_concepts.json + schema reviewed parameter synonym policy -// 7. cobra command tree (Go runtime) flags/usage/required (reflected) +// 2. schema_hints/selection/*.json selection (use_when/avoid_when) — required +// 3. schema_mcp_metadata.json MCP server tool definitions +// 4. schema_parameter_bindings.json parameter type/property mappings +// 5. param_concepts.json + schema reviewed parameter synonym policy +// 6. cobra command tree (Go runtime) flags/usage/required (reflected) +// +// schema_hints/metadata/ is retired (directory may be absent). +// index.metadata may be omitted or {}; leaf safety/params come from Contract. // // Generation outputs (embedded at build): // - schema_agent_metadata/*.json per-product agent metadata diff --git a/internal/cli/runtime_schema_coverage_more_test.go b/internal/cli/runtime_schema_coverage_more_test.go index 39722646..c856142e 100644 --- a/internal/cli/runtime_schema_coverage_more_test.go +++ b/internal/cli/runtime_schema_coverage_more_test.go @@ -90,6 +90,7 @@ func TestCrossPlatformCoverageCollectRuntimeSchemaEntriesErrorsAndOrdering(t *te } func TestCrossPlatformCoverageRuntimeSchemaMetadataLookupEdges(t *testing.T) { + // Fixture-only hint injection: production RegisterSchemaHints stays empty. originalHints := defaultSchemaHintRegistry t.Cleanup(func() { defaultSchemaHintRegistry = originalHints }) defaultSchemaHintRegistry = newSchemaHintRegistry() diff --git a/internal/cli/schema_agent_metadata/aisearch.json b/internal/cli/schema_agent_metadata/aisearch.json index 21333a1f..daa56dd5 100644 --- a/internal/cli/schema_agent_metadata/aisearch.json +++ b/internal/cli/schema_agent_metadata/aisearch.json @@ -474,11 +474,10 @@ "selected": true }, { - "value": true, - "source": "internal/cli/schema_hints/metadata/aisearch.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed CLI supports an all-content search with default --types all, while --queries and --time-range are optional filters; imported MCP required markers must not turn them into mandatory CLI input." + "value": false, + "source": "internal/cli/schema_mcp_metadata.json#tools.aisearch.search_enterprise", + "precedence": "mcp_fallback", + "selected": false } ] }, @@ -533,7 +532,6 @@ "risk": "low", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/aisearch.json", "internal/cli/schema_mcp_metadata.json#tools.aisearch.search_enterprise", "skills/mono/references/intent-guide.md", "skills/mono/references/products/aisearch.md" diff --git a/internal/cli/schema_agent_metadata/aitable.json b/internal/cli/schema_agent_metadata/aitable.json index f339e366..c9aa846c 100644 --- a/internal/cli/schema_agent_metadata/aitable.json +++ b/internal/cli/schema_agent_metadata/aitable.json @@ -22231,13 +22231,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/aitable.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed query command supports both an optional ID lookup mode and a table scan/filter mode, so --record-ids is not unconditionally required." } ] }, @@ -22292,7 +22285,6 @@ "corecmd.SchemaDecl", "dws-wukong-envelope@4574f7022c32:dws-wukong-discovery.aitable.prod.json#aitable.query_records", "internal/cli/schema_hints/imported/wukong.json", - "internal/cli/schema_hints/metadata/aitable.json", "internal/cli/schema_mcp_metadata.json#tools.aitable.query_records", "skills/mono/references/products/aitable-record-ops.md", "skills/mono/references/products/aitable.md", @@ -31570,11 +31562,10 @@ "selected": true }, { - "value": true, - "source": "internal/cli/schema_hints/metadata/aitable.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed CLI accepts --json, a --field-id/--action pair, or --clear-field-id; the registered typed constraints describe those alternatives." + "value": false, + "source": "internal/cli/schema_mcp_metadata.json#tools.aitable.view_update_aggregate", + "precedence": "mcp_fallback", + "selected": false } ] }, @@ -31624,7 +31615,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/aitable.json", "internal/cli/schema_mcp_metadata.json#tools.aitable.view_update_aggregate", "skills/mono/references/products/aitable/aitable-view-config.md" ], @@ -31850,11 +31840,10 @@ "selected": true }, { - "value": true, - "source": "internal/cli/schema_hints/metadata/aitable.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed CLI merges optional typed card flags over an optional --json block; the registered typed constraints require at least one real update field." + "value": false, + "source": "internal/cli/schema_mcp_metadata.json#tools.aitable.view_update_card", + "precedence": "mcp_fallback", + "selected": false } ] }, @@ -31904,7 +31893,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/aitable.json", "internal/cli/schema_mcp_metadata.json#tools.aitable.view_update_card", "skills/mono/references/products/aitable/aitable-view-config.md" ], @@ -32127,11 +32115,10 @@ "selected": true }, { - "value": true, - "source": "internal/cli/schema_hints/metadata/aitable.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed CLI accepts either --json or the paired --field-id/--width form, which is represented by typed require-one-of and require-together constraints." + "value": false, + "source": "internal/cli/schema_mcp_metadata.json#tools.aitable.view_update_field_widths", + "precedence": "mcp_fallback", + "selected": false } ] }, @@ -32181,7 +32168,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/aitable.json", "internal/cli/schema_mcp_metadata.json#tools.aitable.view_update_field_widths", "skills/mono/references/products/aitable/aitable-view-config.md" ], @@ -34227,11 +34213,10 @@ "selected": true }, { - "value": true, - "source": "internal/cli/schema_hints/metadata/aitable.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed CLI accepts either a complete --json block or one or more typed Gantt timebar fields; --json is therefore not unconditionally required." + "value": false, + "source": "internal/cli/schema_mcp_metadata.json#tools.aitable.view_update_timebar", + "precedence": "mcp_fallback", + "selected": false } ] }, @@ -34281,7 +34266,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/aitable.json", "internal/cli/schema_mcp_metadata.json#tools.aitable.view_update_timebar", "skills/mono/references/products/aitable/aitable-view-config.md" ], @@ -34742,13 +34726,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/aitable.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The command maps --base-id and a decoded workflow-dsl/v1 --dsl object to aitable/create_workflow. The call intentionally bypasses retries because creation is non-idempotent; locale remains optional." } ] }, @@ -34798,7 +34775,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/aitable.json", "skills/mono/references/products/aitable/aitable-workflow.md" ], "use_when": [ @@ -36038,13 +36014,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/aitable.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The command maps --base-id, --workflow-id and a decoded complete workflow-dsl/v1 --dsl object to aitable/update_workflow. This is full replacement rather than a partial patch; locale remains optional." } ] }, @@ -36094,7 +36063,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/aitable.json", "skills/mono/references/products/aitable/aitable-workflow.md" ], "use_when": [ diff --git a/internal/cli/schema_agent_metadata/attendance.json b/internal/cli/schema_agent_metadata/attendance.json index e3018745..ff714ba5 100644 --- a/internal/cli/schema_agent_metadata/attendance.json +++ b/internal/cli/schema_agent_metadata/attendance.json @@ -4697,13 +4697,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/attendance.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "Cobra supplies reviewed page=1 and limit=20 defaults and RunE sends those defaults when omitted, so callers need not pass either pagination flag." } ] }, @@ -4753,7 +4746,6 @@ "risk": "low", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/attendance.json", "skills/mono/references/products/attendance.md" ], "use_when": [ @@ -8781,13 +8773,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/attendance.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "Cobra supplies reviewed page=1 and limit=20 defaults and RunE materializes both PageQuery fields when omitted, so callers need not pass either flag." } ] }, @@ -8837,7 +8822,6 @@ "risk": "low", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/attendance.json", "skills/mono/references/products/attendance-schedule.md", "skills/mono/references/products/attendance.md" ], @@ -9818,13 +9802,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/attendance.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "Cobra supplies reviewed page=1 and limit=20 defaults and RunE sends those defaults when omitted, so callers need not pass either pagination flag." } ] }, @@ -9874,7 +9851,6 @@ "risk": "low", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/attendance.json", "skills/mono/references/products/attendance.md" ], "use_when": [ diff --git a/internal/cli/schema_agent_metadata/chat.json b/internal/cli/schema_agent_metadata/chat.json index daa0f8f6..89707ef9 100644 --- a/internal/cli/schema_agent_metadata/chat.json +++ b/internal/cli/schema_agent_metadata/chat.json @@ -9138,13 +9138,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/chat.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property." } ] }, @@ -9187,8 +9180,7 @@ "reviewed": true, "risk": "medium", "source_refs": [ - "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/chat.json" + "corecmd.SchemaDecl" ], "use_when": [ "当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 通过通讯录关键词搜索做精确匹配,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。" @@ -11266,13 +11258,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/chat.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed handler requires a comma-separated category-ID list, parses it to integers, and invokes get_conv_categories_info without a mutation or confirmation gate." } ] }, @@ -11322,7 +11307,6 @@ "risk": "low", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/chat.json", "skills/mono/references/products/chat.md" ], "use_when": [ @@ -11522,13 +11506,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/chat.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "Expose the existing smart-category helper through the reviewed Agent Schema and preserve its CLI-to-interface parameter contract." } ] }, @@ -11578,7 +11555,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/chat.json", "skills/mono/references/products/chat.md" ], "use_when": [ @@ -12039,13 +12015,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/chat.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed handler accepts one of three conversation locator aliases and invokes list_conv_categories_by_conv without a mutation or confirmation gate." } ] }, @@ -12095,7 +12064,6 @@ "risk": "low", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/chat.json", "skills/mono/references/products/chat.md" ], "use_when": [ @@ -14362,11 +14330,10 @@ "selected": true }, { - "value": true, - "source": "internal/cli/schema_hints/metadata/chat.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed CLI lists all owned or administered groups when --role and --limit are omitted; both flags are optional filters despite stricter imported interface metadata." + "value": false, + "source": "internal/cli/schema_mcp_metadata.json#tools.chat.list_owned_or_admin_groups", + "precedence": "mcp_fallback", + "selected": false } ] }, @@ -14419,7 +14386,6 @@ "risk": "low", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/chat.json", "internal/cli/schema_mcp_metadata.json#tools.chat.list_owned_or_admin_groups", "skills/mono/references/intent-guide.md", "skills/mono/references/products/chat.md" @@ -16212,11 +16178,10 @@ "selected": true }, { - "value": true, - "source": "internal/cli/schema_hints/metadata/chat.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed optional --off switch selects administrator removal; omission deliberately selects administrator assignment." + "value": false, + "source": "internal/cli/schema_mcp_metadata.json#tools.chat.update_conv_member_roles", + "precedence": "mcp_fallback", + "selected": false } ] }, @@ -16269,7 +16234,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/chat.json", "internal/cli/schema_mcp_metadata.json#tools.chat.update_conv_member_roles", "skills/mono/references/intent-guide.md", "skills/mono/references/products/chat.md" @@ -17256,13 +17220,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/chat.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed handler requires the target conversation while intentionally allowing omitted --nick to send an empty nickname and clear the current user's group nickname." } ] }, @@ -17312,7 +17269,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/chat.json", "skills/mono/references/intent-guide.md", "skills/mono/references/products/chat.md" ], @@ -17756,13 +17712,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/chat.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed handler validates the target group and optional string-valued extension object, permits caller-authoritative dry-run, and requires explicit --yes before the irreversible upgrade." } ] }, @@ -17806,7 +17755,6 @@ "risk": "high", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/chat.json", "skills/mono/references/products/chat.md" ], "use_when": [ @@ -18456,11 +18404,10 @@ "selected": true }, { - "value": true, - "source": "internal/cli/schema_hints/metadata/chat.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed optional --off switch selects unmute; omission deliberately selects mute, so false is a valid default rather than missing required input." + "value": false, + "source": "internal/cli/schema_mcp_metadata.json#tools.chat.set_group_mute", + "precedence": "mcp_fallback", + "selected": false } ] }, @@ -18513,7 +18460,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/chat.json", "internal/cli/schema_mcp_metadata.json#tools.chat.set_group_mute", "skills/mono/references/intent-guide.md", "skills/mono/references/products/chat.md" @@ -18719,11 +18665,10 @@ "selected": true }, { - "value": true, - "source": "internal/cli/schema_hints/metadata/chat.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed Cobra contract makes --off an optional mode switch: omission adds members to the mute list, while --off removes them. The shared MCP schema incorrectly marks the boolean as unconditionally required." + "value": false, + "source": "internal/cli/schema_mcp_metadata.json#tools.chat.set_group_member_mute_list", + "precedence": "mcp_fallback", + "selected": false } ] }, @@ -18776,7 +18721,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/chat.json", "internal/cli/schema_mcp_metadata.json#tools.chat.set_group_member_mute_list", "skills/mono/references/intent-guide.md", "skills/mono/references/products/chat.md" @@ -21063,11 +21007,10 @@ "selected": true }, { - "value": true, - "source": "internal/cli/schema_hints/metadata/chat.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The four reviewed conversation locator flags are aliases for one openConversationId property; the typed require-one-of constraint owns their conditional requirement." + "value": false, + "source": "internal/cli/schema_mcp_metadata.json#tools.chat.add_emoji_reaction", + "precedence": "mcp_fallback", + "selected": false } ] }, @@ -21120,7 +21063,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/chat.json", "internal/cli/schema_mcp_metadata.json#tools.chat.add_emoji_reaction", "skills/mono/references/products/chat.md" ], @@ -21573,11 +21515,10 @@ "selected": true }, { - "value": true, - "source": "internal/cli/schema_hints/metadata/chat.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The four reviewed conversation locator flags are aliases for one openConversationId property; the typed require-one-of constraint owns their conditional requirement." + "value": false, + "source": "internal/cli/schema_mcp_metadata.json#tools.chat.add_text_emotion", + "precedence": "mcp_fallback", + "selected": false } ] }, @@ -21630,7 +21571,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/chat.json", "internal/cli/schema_mcp_metadata.json#tools.chat.add_text_emotion", "skills/mono/references/products/chat.md" ], @@ -22582,13 +22522,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/chat.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed handler requires one conversation locator, a message ID, and exactly one of text or raw content; it optionally derives a title and maps mention controls before invoking edit_message." } ] }, @@ -22632,7 +22565,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/chat.json", "skills/mono/references/products/chat.md" ], "use_when": [ @@ -24636,13 +24568,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/chat.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "Preserve the reviewed CLI-to-interface conversion: Cobra validates --size as an integer from 1 to 100, then the helper serializes it to the string-valued list_message_favorites size property." } ] }, @@ -24692,7 +24617,6 @@ "risk": "low", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/chat.json", "skills/mono/references/products/chat.md" ], "use_when": [ @@ -27247,11 +27171,10 @@ "selected": true }, { - "value": true, - "source": "internal/cli/schema_hints/metadata/chat.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The four reviewed conversation locator flags are aliases for one openConversationId property; the typed require-one-of constraint owns their conditional requirement." + "value": false, + "source": "internal/cli/schema_mcp_metadata.json#tools.chat.remove_emoji_reaction", + "precedence": "mcp_fallback", + "selected": false } ] }, @@ -27304,7 +27227,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/chat.json", "internal/cli/schema_mcp_metadata.json#tools.chat.remove_emoji_reaction", "skills/mono/references/products/chat.md" ], @@ -27757,11 +27679,10 @@ "selected": true }, { - "value": true, - "source": "internal/cli/schema_hints/metadata/chat.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The four reviewed conversation locator flags are aliases for one openConversationId property; the typed require-one-of constraint owns their conditional requirement." + "value": false, + "source": "internal/cli/schema_mcp_metadata.json#tools.chat.remove_text_emotion", + "precedence": "mcp_fallback", + "selected": false } ] }, @@ -27814,7 +27735,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/chat.json", "internal/cli/schema_mcp_metadata.json#tools.chat.remove_text_emotion", "skills/mono/references/products/chat.md" ], @@ -30604,13 +30524,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/chat.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "Ported from dws-wukong commits d6831318 and bcf56ccf, merged at 30f13f02. The four conversation locators alias one property; the other six business parameters are required by Cobra before the single im/update_text_emotion call." } ] }, @@ -30660,7 +30573,6 @@ "risk": "low", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/chat.json", "skills/mono/references/products/chat.md" ], "use_when": [ @@ -30864,11 +30776,10 @@ "selected": true }, { - "value": true, - "source": "internal/cli/schema_hints/metadata/chat.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed locator aliases feed one openConversationId property, while optional --off selects unmute; typed constraints require one locator without making the mode switch mandatory." + "value": false, + "source": "internal/cli/schema_mcp_metadata.json#tools.chat.update_notification_off", + "precedence": "mcp_fallback", + "selected": false } ] }, @@ -30921,7 +30832,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/chat.json", "internal/cli/schema_mcp_metadata.json#tools.chat.update_notification_off", "skills/mono/references/intent-guide.md", "skills/mono/references/products/chat.md" @@ -31677,11 +31587,10 @@ "selected": true }, { - "value": true, - "source": "internal/cli/schema_hints/metadata/chat.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed optional --off switch selects unpin; omission deliberately selects pin, so false is a valid default rather than missing required input." + "value": false, + "source": "internal/cli/schema_mcp_metadata.json#tools.chat.set_top_conversation", + "precedence": "mcp_fallback", + "selected": false } ] }, @@ -31734,7 +31643,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/chat.json", "internal/cli/schema_mcp_metadata.json#tools.chat.set_top_conversation", "skills/mono/references/intent-guide.md", "skills/mono/references/products/chat.md" diff --git a/internal/cli/schema_agent_metadata/contact.json b/internal/cli/schema_agent_metadata/contact.json index 58c68b08..6c065854 100644 --- a/internal/cli/schema_agent_metadata/contact.json +++ b/internal/cli/schema_agent_metadata/contact.json @@ -3316,13 +3316,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/contact.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed Wukong-compatible handler requires enterprise display name and login ID, maps optional contact fields and department IDs, and calls exclusive_account_create without a runtime confirmation gate." } ] }, @@ -3372,7 +3365,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/contact.json", "skills/mono/references/products/contact.md" ], "use_when": [ @@ -3572,13 +3564,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/contact.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed handler requires one enterprise-account user ID plus at least one profile or organization update field, confirms, then invokes exclusive_account_user_update." } ] }, @@ -3628,7 +3613,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/contact.json", "skills/mono/references/products/contact.md" ], "use_when": [ @@ -3828,13 +3812,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/contact.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed handler requires one department-name spelling and an explicit boolean group choice, optionally parses a parent department ID, confirms, then invokes department_create." } ] }, @@ -3884,7 +3861,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/contact.json", "skills/mono/references/products/contact.md" ], "use_when": [ @@ -5130,13 +5106,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/contact.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed handler requires one department-ID spelling and one department-name spelling, optionally parses a parent ID, confirms, then invokes department_update." } ] }, @@ -5186,7 +5155,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/contact.json", "skills/mono/references/products/contact.md" ], "use_when": [ @@ -5386,13 +5354,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/contact.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed Wukong-compatible handler requires an organization name and creator display name and calls org_create without a runtime confirmation gate." } ] }, @@ -5442,7 +5403,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/contact.json", "skills/mono/references/products/contact.md" ], "use_when": [ @@ -6674,13 +6634,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/contact.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed Wukong-compatible handler requires employee name and mobile, decodes optional --depts JSON to an array, and calls add_employee without a runtime confirmation gate." } ] }, @@ -6724,7 +6677,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/contact.json", "skills/mono/references/products/contact.md" ], "use_when": [ @@ -7191,11 +7143,10 @@ "selected": true }, { - "value": true, - "source": "internal/cli/schema_hints/metadata/contact.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed helper deliberately permits either or both optional filters and passes an empty request to query the caller's authorized roster scope." + "value": false, + "source": "internal/cli/schema_mcp_metadata.json#tools.contact.get_authorized_emp_rosterInfo", + "precedence": "mcp_fallback", + "selected": false } ] }, @@ -7248,7 +7199,6 @@ "risk": "low", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/contact.json", "internal/cli/schema_mcp_metadata.json#tools.contact.get_authorized_emp_rosterInfo", "skills/mono/references/products/contact.md" ], @@ -7980,13 +7930,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/contact.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed handler requires one employee-ID spelling plus at least one update field, decodes optional department JSON, confirms, then invokes employee_update." } ] }, @@ -8036,7 +7979,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/contact.json", "skills/mono/references/products/contact.md" ], "use_when": [ @@ -8236,13 +8178,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/contact.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed handler requires at least one of nickname or avatar file ID, confirms, then invokes self_user_profile_update for the current user." } ] }, @@ -8292,7 +8227,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/contact.json", "skills/mono/references/products/contact.md" ], "use_when": [ diff --git a/internal/cli/schema_agent_metadata/devdoc.json b/internal/cli/schema_agent_metadata/devdoc.json index 872ed899..cdd6380c 100644 --- a/internal/cli/schema_agent_metadata/devdoc.json +++ b/internal/cli/schema_agent_metadata/devdoc.json @@ -208,13 +208,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/devdoc.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "Search text may be supplied as positional keyword or public --query; hidden --keyword remains a runtime compatibility alias and is intentionally not published as a parameter. The versioned binding owns query -\u003e keyword." } ] }, @@ -269,7 +262,6 @@ "corecmd.SchemaDecl", "dws-wukong-envelope@4574f7022c32:dws-wukong-discovery.devdoc.prod.json#devdoc.search_open_platform_docs", "internal/cli/schema_hints/imported/wukong.json", - "internal/cli/schema_hints/metadata/devdoc.json", "internal/cli/schema_mcp_metadata.json#tools.devdoc.search_open_platform_docs_rag", "skills/mono/references/products/devdoc.md", "skills/mono/references/products/simple.md" diff --git a/internal/cli/schema_agent_metadata/doc.json b/internal/cli/schema_agent_metadata/doc.json index 994e1294..ce46c6a2 100644 --- a/internal/cli/schema_agent_metadata/doc.json +++ b/internal/cli/schema_agent_metadata/doc.json @@ -5106,13 +5106,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/doc.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed handler normalizes repeated or comma-separated group conversation IDs into a stable de-duplicated array while preserving existing user mentions." } ] }, @@ -5167,7 +5160,6 @@ "corecmd.SchemaDecl", "dws-wukong-envelope@4574f7022c32:dws-wukong-discovery.doc.prod.json#doc.create_comment", "internal/cli/schema_hints/imported/wukong.json", - "internal/cli/schema_hints/metadata/doc.json", "internal/cli/schema_mcp_metadata.json#tools.doc.create_comment", "skills/mono/references/products/doc.md", "skills/mono/references/products/doc/doc-comment.md" @@ -6168,13 +6160,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/doc.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed handler normalizes group conversation IDs into a stable de-duplicated array and rejects group mentions for emoji replies, which the remote operation does not support." } ] }, @@ -6229,7 +6214,6 @@ "corecmd.SchemaDecl", "dws-wukong-envelope@4574f7022c32:dws-wukong-discovery.doc.prod.json#doc.reply_comment", "internal/cli/schema_hints/imported/wukong.json", - "internal/cli/schema_hints/metadata/doc.json", "internal/cli/schema_mcp_metadata.json#tools.doc.reply_comment", "skills/mono/references/products/doc.md", "skills/mono/references/products/doc/doc-comment.md" @@ -6434,13 +6418,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/doc.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "Preserve the reviewed user-mention conversion and normalize repeated or comma-separated group conversation IDs into mentionedOpenConversationIds." } ] }, @@ -6490,7 +6467,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/doc.json", "skills/mono/references/products/doc.md", "skills/mono/references/products/doc/doc-comment.md" ], @@ -11123,13 +11099,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/doc.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed handler preserves full Markdown/JSONML reads and adds validated outline, range, section, and tag-scoped JSONML fragment reads with optional file output." } ] }, @@ -11188,7 +11157,6 @@ "corecmd.SchemaDecl", "dws-wukong-envelope@4574f7022c32:dws-wukong-discovery.doc.prod.json#doc.get_document_content", "internal/cli/schema_hints/imported/wukong.json", - "internal/cli/schema_hints/metadata/doc.json", "internal/cli/schema_mcp_metadata.json#tools.doc.get_document_content", "skills/mono/references/products/doc.md", "skills/mono/references/products/doc/doc-read.md", diff --git a/internal/cli/schema_agent_metadata/drive.json b/internal/cli/schema_agent_metadata/drive.json index 09a4e194..fec92141 100644 --- a/internal/cli/schema_agent_metadata/drive.json +++ b/internal/cli/schema_agent_metadata/drive.json @@ -7899,11 +7899,10 @@ "selected": true }, { - "value": true, - "source": "internal/cli/schema_hints/metadata/drive.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed CLI reads node metadata before mutation and strips only the exact current extension for non-folder nodes, avoiding both duplicate extensions and dotted-folder corruption without a suffix whitelist." + "value": false, + "source": "internal/cli/schema_mcp_metadata.json#tools.drive.rename_document", + "precedence": "mcp_fallback", + "selected": false } ] }, @@ -7956,7 +7955,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/drive.json", "internal/cli/schema_mcp_metadata.json#tools.drive.rename_document", "skills/mono/references/products/drive.md" ], @@ -9823,13 +9821,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/drive.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed helper preserves the stable command-level Schema contract for ordinary uploads; --node switches to overwrite mode and the runtime still requires explicit confirmation unless --yes is supplied." } ] }, @@ -9883,7 +9874,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/drive.json", "skills/mono/references/intent-guide.md", "skills/mono/references/products/drive.md" ], diff --git a/internal/cli/schema_agent_metadata/hrbrain.json b/internal/cli/schema_agent_metadata/hrbrain.json index 63e44325..6606d36c 100644 --- a/internal/cli/schema_agent_metadata/hrbrain.json +++ b/internal/cli/schema_agent_metadata/hrbrain.json @@ -176,13 +176,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/hrbrain.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "Reviewed unpinned remote adapter: --work-no maps 1:1 to the workNo MCP call argument observed in internal/helpers/hrbrain.go." } ] }, @@ -226,7 +219,6 @@ "risk": "low", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/hrbrain.json", "skills/mono/references/products/hrbrain.md" ], "use_when": [ @@ -408,13 +400,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/hrbrain.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "Reviewed unpinned remote adapter: flags map 1:1 to the get_profile_label MCP call arguments observed in internal/helpers/hrbrain.go." } ] }, @@ -458,7 +443,6 @@ "risk": "low", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/hrbrain.json", "skills/mono/references/products/hrbrain.md" ], "use_when": [ @@ -640,13 +624,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/hrbrain.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "Reviewed unpinned remote adapter: --work-no maps 1:1 to the workNo MCP call argument observed in internal/helpers/hrbrain.go." } ] }, @@ -690,7 +667,6 @@ "risk": "low", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/hrbrain.json", "skills/mono/references/products/hrbrain.md" ], "use_when": [ @@ -872,13 +848,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/hrbrain.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "Reviewed unpinned remote adapter: --work-no maps 1:1 to the workNo MCP call argument observed in internal/helpers/hrbrain.go." } ] }, @@ -922,7 +891,6 @@ "risk": "low", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/hrbrain.json", "skills/mono/references/products/hrbrain.md" ], "use_when": [ @@ -1125,13 +1093,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/hrbrain.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "Reviewed unpinned remote adapter: flags map 1:1 to the query_profile_data MCP call arguments observed in internal/helpers/hrbrain.go." } ] }, @@ -1181,7 +1142,6 @@ "risk": "low", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/hrbrain.json", "skills/mono/references/products/hrbrain.md" ], "use_when": [ @@ -1387,13 +1347,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/hrbrain.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "Reviewed unpinned remote adapter: flags map 1:1 to the search_employees MCP call arguments observed in internal/helpers/hrbrain.go." } ] }, @@ -1443,7 +1396,6 @@ "risk": "low", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/hrbrain.json", "skills/mono/references/products/hrbrain.md" ], "use_when": [ @@ -1646,13 +1598,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/hrbrain.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "Reviewed unpinned remote adapter: flags map 1:1 to the search_employees_structured MCP call arguments observed in internal/helpers/hrbrain.go." } ] }, @@ -1702,7 +1647,6 @@ "risk": "low", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/hrbrain.json", "skills/mono/references/products/hrbrain.md" ], "use_when": [ @@ -2150,13 +2094,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/hrbrain.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "Reviewed unpinned remote adapter: --pool-code maps 1:1 to the poolCode MCP call argument observed in internal/helpers/hrbrain.go." } ] }, @@ -2206,7 +2143,6 @@ "risk": "low", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/hrbrain.json", "skills/mono/references/products/hrbrain.md" ], "use_when": [ @@ -2391,13 +2327,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/hrbrain.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "Reviewed unpinned remote adapter: flags map 1:1 to the list_pool_employees MCP call arguments observed in internal/helpers/hrbrain.go." } ] }, @@ -2441,7 +2370,6 @@ "risk": "low", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/hrbrain.json", "skills/mono/references/products/hrbrain.md" ], "use_when": [ @@ -2647,13 +2575,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/hrbrain.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "Reviewed unpinned remote adapter: flags map 1:1 to the list_talent_pools MCP call arguments observed in internal/helpers/hrbrain.go." } ] }, @@ -2703,7 +2624,6 @@ "risk": "low", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/hrbrain.json", "skills/mono/references/products/hrbrain.md" ], "use_when": [ diff --git a/internal/cli/schema_agent_metadata/index.json b/internal/cli/schema_agent_metadata/index.json index f72bfb03..24c348d9 100644 --- a/internal/cli/schema_agent_metadata/index.json +++ b/internal/cli/schema_agent_metadata/index.json @@ -1,6 +1,6 @@ { "version": 1, - "source_hash": "sha256:a4622e8ac2ad1f65bae1a9e2487001dfae751f8c70ce45630dcb9a1b12e167ed", + "source_hash": "sha256:5397ea46c3681d39d4532dc18145e6b73d6900472cf6a88faa703d477b078ecb", "surface_hash": "sha256:60eee8e2f37d6d9d60689efce85082798eb9ad38b7ba7c0b471c3de676a85a16", "coverage": { "surface_products": 26, diff --git a/internal/cli/schema_agent_metadata/mail.json b/internal/cli/schema_agent_metadata/mail.json index 14db2df2..9a242979 100644 --- a/internal/cli/schema_agent_metadata/mail.json +++ b/internal/cli/schema_agent_metadata/mail.json @@ -7140,13 +7140,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/mail.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "Preserve the reviewed composite wrapper contract: the CLI maps --limit to the search_emails size property after constructing a folder KQL query." } ] }, @@ -7196,7 +7189,6 @@ "risk": "low", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/mail.json", "skills/mono/references/products/mail.md" ], "use_when": [ @@ -9752,11 +9744,10 @@ "selected": true }, { - "value": true, - "source": "internal/cli/schema_hints/metadata/mail.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed patch command accepts any non-empty subset of mutable template fields; a typed require-one-of constraint owns that requirement." + "value": false, + "source": "internal/cli/schema_mcp_metadata.json#tools.mail.update_user_message_template", + "precedence": "mcp_fallback", + "selected": false } ] }, @@ -9809,7 +9800,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/mail.json", "internal/cli/schema_mcp_metadata.json#tools.mail.update_user_message_template", "skills/mono/references/products/mail.md" ], @@ -10276,11 +10266,10 @@ "selected": true }, { - "value": true, - "source": "internal/cli/schema_hints/metadata/mail.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed CLI accepts either a fuzzy keyword or an exact employee number, represented by a typed require-one-of constraint rather than two unconditional requirements." + "value": false, + "source": "internal/cli/schema_mcp_metadata.json#tools.mail.search_mail_users", + "precedence": "mcp_fallback", + "selected": false } ] }, @@ -10333,7 +10322,6 @@ "risk": "low", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/mail.json", "internal/cli/schema_mcp_metadata.json#tools.mail.search_mail_users", "skills/mono/references/products/mail.md" ], diff --git a/internal/cli/schema_agent_metadata/markdown.json b/internal/cli/schema_agent_metadata/markdown.json index 58fcdb6a..658aa9af 100644 --- a/internal/cli/schema_agent_metadata/markdown.json +++ b/internal/cli/schema_agent_metadata/markdown.json @@ -194,13 +194,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/markdown.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed workflow requires exactly one content source, requires an .md name for literal content, keeps workspace and Drive space mutually exclusive, and routes the upload without a confirmation gate." } ] }, @@ -250,7 +243,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/markdown.json", "skills/mono/references/products/markdown.md" ], "use_when": [ @@ -432,13 +424,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/markdown.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed workflow requires one node locator, keeps explicit Drive and Doc routes mutually exclusive, treats remote content as untrusted data, and protects local output paths." } ] }, @@ -482,7 +467,6 @@ "risk": "low", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/markdown.json", "skills/mono/references/products/markdown.md" ], "use_when": [ @@ -664,13 +648,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/markdown.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed workflow requires a target and exactly one content source, supports a command-owned diff preview, and confirms before replacing the remote file." } ] }, @@ -714,7 +691,6 @@ "risk": "high", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/markdown.json", "skills/mono/references/products/markdown.md" ], "use_when": [ @@ -896,13 +872,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/markdown.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed workflow requires a target, pattern, and replacement; it blocks zero-hit and empty-result writes, supports a command-owned diff preview, and confirms before reupload." } ] }, @@ -946,7 +915,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/markdown.json", "skills/mono/references/products/markdown.md" ], "use_when": [ diff --git a/internal/cli/schema_agent_metadata/minutes.json b/internal/cli/schema_agent_metadata/minutes.json index 9a12bca4..96042c90 100644 --- a/internal/cli/schema_agent_metadata/minutes.json +++ b/internal/cli/schema_agent_metadata/minutes.json @@ -1297,13 +1297,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/minutes.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "Reviewed against the built-in Shortcut registry and mounted Cobra command: publishes the executable risk gate, composite interface, and the custom --pair format/uniqueness validation without inventing a direct MCP identity." } ] }, @@ -1346,8 +1339,7 @@ "reviewed": true, "risk": "medium", "source_refs": [ - "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/minutes.json" + "corecmd.SchemaDecl" ], "use_when": [ "当你要在同一条听记里一次性纠正多个词(如把多个错识别的人名/术语统一替换),而底层工具一次只能替换一组时使用;内部按多个 --pair \"原文=\u003e替换\" 逐组调用替换工具,先在本地校验去重(同一个「原文」不能出现两次,避免两条规则互相打架),再逐组应用并聚合每组的成功/失败结果,某一组失败不会中断其余组。这是写操作,会实际修改听记文字内容,请确认 taskUuid 与替换规则无误。" diff --git a/internal/cli/schema_agent_metadata/report.json b/internal/cli/schema_agent_metadata/report.json index 77af3bd8..47cf6369 100644 --- a/internal/cli/schema_agent_metadata/report.json +++ b/internal/cli/schema_agent_metadata/report.json @@ -1193,13 +1193,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/report.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed optional --to-chat switch defaults to false and only controls post-submit delivery; it is not required to create a report." } ] }, @@ -1254,7 +1247,6 @@ "corecmd.SchemaDecl", "dws-wukong-envelope@4574f7022c32:dws-wukong-discovery.report.prod.json#report.create_report", "internal/cli/schema_hints/imported/wukong.json", - "internal/cli/schema_hints/metadata/report.json", "internal/cli/schema_mcp_metadata.json#tools.report.create_report", "skills/mono/references/products/report.md" ], diff --git a/internal/cli/schema_agent_metadata/sheet.json b/internal/cli/schema_agent_metadata/sheet.json index 828306d4..da59d7b3 100644 --- a/internal/cli/schema_agent_metadata/sheet.json +++ b/internal/cli/schema_agent_metadata/sheet.json @@ -15055,13 +15055,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/sheet.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "Preserve the reviewed CLI-to-interface conversion: --properties accepts inline JSON or @file text and is validated and decoded to the create_pivot_table properties object." } ] }, @@ -15111,7 +15104,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/sheet.json", "skills/mono/references/products/sheet/sheet-pivot-table.md" ], "use_when": [ @@ -15807,13 +15799,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/sheet.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "Preserve the reviewed CLI-to-interface conversion: --properties accepts inline JSON or @file text and is validated and decoded to the update_pivot_table properties object." } ] }, @@ -15863,7 +15848,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/sheet.json", "skills/mono/references/products/sheet/sheet-pivot-table.md" ], "use_when": [ @@ -19692,13 +19676,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/sheet.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "Preserve the reviewed CLI-to-interface conversion: --sheets accepts inline JSON, @file, or stdin and is normalized to the table_put sheets array." } ] }, @@ -19748,7 +19725,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/sheet.json", "skills/mono/references/products/sheet/sheet-write-data.md" ], "use_when": [ diff --git a/internal/cli/schema_agent_metadata/todo.json b/internal/cli/schema_agent_metadata/todo.json index 343d65e7..33d61651 100644 --- a/internal/cli/schema_agent_metadata/todo.json +++ b/internal/cli/schema_agent_metadata/todo.json @@ -3445,13 +3445,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/todo.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed handler requires a task ID and at least one non-empty tag code before invoking tag_todo." } ] }, @@ -3501,7 +3494,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/todo.json", "skills/mono/references/products/todo.md" ], "use_when": [ @@ -3701,13 +3693,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/todo.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed handler requires a non-blank tag name, builds a one-element userTags request, and invokes create_todo_tag without a runtime confirmation gate." } ] }, @@ -3757,7 +3742,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/todo.json", "skills/mono/references/products/todo.md" ], "use_when": [ @@ -3957,13 +3941,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/todo.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed handler requires at least one non-empty tag code, permits caller-authoritative dry-run, and requires explicit --yes before invoking delete_todo_tag." } ] }, @@ -4013,7 +3990,6 @@ "risk": "high", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/todo.json", "skills/mono/references/products/todo.md" ], "use_when": [ @@ -4461,13 +4437,6 @@ "source": "corecmd.contract", "precedence": "contract_final", "selected": true - }, - { - "value": true, - "source": "internal/cli/schema_hints/metadata/todo.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed handler requires a non-null JSON array of tag update records and invokes update_todo_tag without a runtime confirmation gate." } ] }, @@ -4517,7 +4486,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/todo.json", "skills/mono/references/products/todo.md" ], "use_when": [ @@ -7153,11 +7121,10 @@ "selected": true }, { - "value": true, - "source": "internal/cli/schema_hints/metadata/todo.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed handler defaults omitted role-types to executor, preserves current-organization behavior by default, and switches both single-page and auto-page calls to get_user_todos only when --query-all is explicitly true." + "value": false, + "source": "internal/cli/schema_mcp_metadata.json#tools.todo.get_user_todos_in_current_org", + "precedence": "mcp_fallback", + "selected": false } ] }, @@ -7210,7 +7177,6 @@ "risk": "low", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/todo.json", "internal/cli/schema_mcp_metadata.json#tools.todo.get_user_todos_in_current_org", "skills/mono/references/products/todo.md" ], @@ -8210,11 +8176,10 @@ "selected": true }, { - "value": true, - "source": "internal/cli/schema_hints/metadata/todo.json", - "precedence": "reviewed_explicit", - "selected": false, - "review_reason": "The reviewed CLI rejects malformed or structurally invalid non-empty reminder rules before the reset mutation, while preserving omission and [] as explicit clear forms." + "value": false, + "source": "internal/cli/schema_mcp_metadata.json#tools.todo.reset_todo_reminder", + "precedence": "mcp_fallback", + "selected": false } ] }, @@ -8267,7 +8232,6 @@ "risk": "medium", "source_refs": [ "corecmd.SchemaDecl", - "internal/cli/schema_hints/metadata/todo.json", "internal/cli/schema_mcp_metadata.json#tools.todo.reset_todo_reminder", "skills/mono/references/products/todo.md" ], diff --git a/internal/cli/schema_agent_metadata_audit.json b/internal/cli/schema_agent_metadata_audit.json index 872d1199..8fa6680b 100644 --- a/internal/cli/schema_agent_metadata_audit.json +++ b/internal/cli/schema_agent_metadata_audit.json @@ -1,11 +1,11 @@ { "version": 1, - "source_hash": "sha256:a4622e8ac2ad1f65bae1a9e2487001dfae751f8c70ce45630dcb9a1b12e167ed", + "source_hash": "sha256:5397ea46c3681d39d4532dc18145e6b73d6900472cf6a88faa703d477b078ecb", "surface_hash": "sha256:60eee8e2f37d6d9d60689efce85082798eb9ad38b7ba7c0b471c3de676a85a16", - "source_files": 160, - "hint_files": 54, + "source_files": 134, + "hint_files": 28, "hint_products": 43, - "hint_tools": 221, + "hint_tools": 147, "interface_metadata": { "source": "mcp-tools-list+cli-registry", "revision": "4574f7022c32cf4c033e9b7b4156e2fec815fed8", diff --git a/internal/cli/schema_catalog/catalog.json b/internal/cli/schema_catalog/catalog.json index ea5b5127..5149ca32 100644 --- a/internal/cli/schema_catalog/catalog.json +++ b/internal/cli/schema_catalog/catalog.json @@ -1,12 +1,12 @@ { "version": 1, "surface_hash": "sha256:60eee8e2f37d6d9d60689efce85082798eb9ad38b7ba7c0b471c3de676a85a16", - "source_hash": "sha256:26f44334e2182ab20b691e9e6b6221288d4ff9a3c9e13e436b4b52a98eae70b8", + "source_hash": "sha256:391e859404a4ff80a0d05bc35f4aa0ba8d90ffcf82b0ec5648356e7c33be0ef0", "catalog": { "agent_metadata": { "products_with_metadata": 26, "source": "embedded-skill-metadata", - "source_hash": "sha256:a4622e8ac2ad1f65bae1a9e2487001dfae751f8c70ce45630dcb9a1b12e167ed", + "source_hash": "sha256:5397ea46c3681d39d4532dc18145e6b73d6900472cf6a88faa703d477b078ecb", "surface_hash": "sha256:60eee8e2f37d6d9d60689efce85082798eb9ad38b7ba7c0b471c3de676a85a16", "surface_products": 26, "surface_tools": 845, diff --git a/internal/cli/schema_catalog/tools/aitable.json b/internal/cli/schema_catalog/tools/aitable.json index 08a2b970..fadd9f29 100644 --- a/internal/cli/schema_catalog/tools/aitable.json +++ b/internal/cli/schema_catalog/tools/aitable.json @@ -5015,12 +5015,6 @@ "source": "native_annotation", "value": true }, - { - "precedence": "tool_schema_hint", - "selected": false, - "source": "tool_schema_hint", - "value": true - }, { "precedence": "mcp_metadata", "selected": false, @@ -14336,12 +14330,6 @@ "source": "native_annotation", "value": true }, - { - "precedence": "tool_schema_hint", - "selected": false, - "source": "tool_schema_hint", - "value": true - }, { "precedence": "inference", "selected": false, @@ -17119,9 +17107,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -17131,9 +17119,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { @@ -20529,9 +20517,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -20541,9 +20529,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { @@ -22425,8 +22413,14 @@ "interface_type": { "candidates": [ { - "precedence": "mcp_metadata", + "precedence": "native_annotation", "selected": true, + "source": "native_annotation", + "value": "array" + }, + { + "precedence": "mcp_metadata", + "selected": false, "source": "mcp_metadata", "value": "array" }, @@ -22437,9 +22431,9 @@ "value": "string" } ], - "precedence": "mcp_metadata", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "mcp_metadata", + "source": "native_annotation", "value": "array" }, "property": { @@ -22459,9 +22453,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -22477,9 +22471,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { @@ -26548,12 +26542,6 @@ "source": "require_one_of_constraint", "value": false }, - { - "precedence": "tool_schema_hint", - "selected": false, - "source": "tool_schema_hint", - "value": true - }, { "precedence": "default", "selected": false, @@ -32371,6 +32359,26 @@ "source": "cobra_usage", "value": "待新增字段列表 JSON 数组,至少包含 1 个字段,单次最多 15 个。系统会按数组顺序依次创建,返回结果顺序与入参保持一致,并逐项标明成功/失败状态。若是单个字段可直接使用 --name/--type/--config" }, + "interface_type": { + "candidates": [ + { + "precedence": "native_annotation", + "selected": true, + "source": "native_annotation", + "value": "array" + }, + { + "precedence": "fallback", + "selected": false, + "source": "cobra_flag_type", + "value": "string" + } + ], + "precedence": "native_annotation", + "resolution": "highest_precedence", + "source": "native_annotation", + "value": "array" + }, "property": { "candidates": [ { @@ -32388,16 +32396,22 @@ "required": { "candidates": [ { - "precedence": "default", + "precedence": "native_annotation", "selected": true, + "source": "native_annotation", + "value": true + }, + { + "precedence": "default", + "selected": false, "source": "default", "value": false } ], - "precedence": "default", - "resolution": "fallback", - "source": "default", - "value": false + "precedence": "native_annotation", + "resolution": "highest_precedence", + "source": "native_annotation", + "value": true }, "required_when": { "candidates": [ @@ -32428,8 +32442,9 @@ "value": "string" } }, + "interface_type": "array", "property": "fields", - "required": false, + "required": true, "type": "string" }, "name": { @@ -38807,12 +38822,6 @@ "source": "cobra_usage", "value": "Base ID(通过 base list / base search 获取)(必填)" }, - { - "precedence": "tool_schema_hint", - "selected": false, - "source": "tool_schema_hint", - "value": "Base ID。" - }, { "precedence": "mcp_metadata", "selected": false, @@ -39007,12 +39016,6 @@ "source": "cobra_usage", "value": "指定要返回的字段 ID 列表,逗号分隔。省略则返回所有字段。建议在字段较多时按需传入,可显著减少响应体积;单次最多 100 个" }, - { - "precedence": "tool_schema_hint", - "selected": false, - "source": "tool_schema_hint", - "value": "Field ID 列表,CLI 使用逗号分隔。" - }, { "precedence": "mcp_metadata", "selected": false, @@ -39039,12 +39042,6 @@ "source": "native_annotation", "value": "array" }, - { - "precedence": "tool_schema_hint", - "selected": false, - "source": "tool_schema_hint", - "value": "array" - }, { "precedence": "mcp_metadata", "selected": false, @@ -39143,12 +39140,6 @@ "source": "cobra_usage", "value": "结构化过滤条件 JSON,不传则返回全部记录(受 limit 限制)" }, - { - "precedence": "tool_schema_hint", - "selected": false, - "source": "tool_schema_hint", - "value": "过滤条件 JSON。" - }, { "precedence": "mcp_metadata", "selected": false, @@ -39175,12 +39166,6 @@ "source": "native_annotation", "value": "object" }, - { - "precedence": "tool_schema_hint", - "selected": false, - "source": "tool_schema_hint", - "value": "object" - }, { "precedence": "mcp_metadata", "selected": false, @@ -39598,12 +39583,6 @@ "source": "cobra_usage", "value": "指定要获取的记录 ID 列表,逗号分隔,单次最多 100 个。传入时按 ID 返回,忽略 filters 和 sort。适用于已知 recordId(如关联字段中的 linkedRecordIds)时的精准取数" }, - { - "precedence": "tool_schema_hint", - "selected": false, - "source": "tool_schema_hint", - "value": "Record ID 列表,CLI 使用逗号分隔。" - }, { "precedence": "mcp_metadata", "selected": false, @@ -39630,12 +39609,6 @@ "source": "native_annotation", "value": "array" }, - { - "precedence": "tool_schema_hint", - "selected": false, - "source": "tool_schema_hint", - "value": "array" - }, { "precedence": "mcp_metadata", "selected": false, @@ -39740,12 +39713,6 @@ "source": "cobra_usage", "value": "排序条件 JSON 数组,按数组顺序依次生效" }, - { - "precedence": "tool_schema_hint", - "selected": false, - "source": "tool_schema_hint", - "value": "排序 JSON 数组。" - }, { "precedence": "mcp_metadata", "selected": false, @@ -39772,12 +39739,6 @@ "source": "native_annotation", "value": "array" }, - { - "precedence": "tool_schema_hint", - "selected": false, - "source": "tool_schema_hint", - "value": "array" - }, { "precedence": "mcp_metadata", "selected": false, @@ -39876,12 +39837,6 @@ "source": "cobra_usage", "value": "Table ID(通过 base get 获取)(必填)" }, - { - "precedence": "tool_schema_hint", - "selected": false, - "source": "tool_schema_hint", - "value": "Table ID。" - }, { "precedence": "mcp_metadata", "selected": false, @@ -48167,12 +48122,6 @@ "source": "native_annotation", "value": true }, - { - "precedence": "tool_schema_hint", - "selected": false, - "source": "tool_schema_hint", - "value": true - }, { "precedence": "mcp_metadata", "selected": false, @@ -87728,12 +87677,6 @@ "source": "native_annotation", "value": false }, - { - "precedence": "tool_schema_hint", - "selected": false, - "source": "tool_schema_hint", - "value": true - }, { "precedence": "default", "selected": false, @@ -89017,12 +88960,6 @@ "source": "native_annotation", "value": false }, - { - "precedence": "tool_schema_hint", - "selected": false, - "source": "tool_schema_hint", - "value": true - }, { "precedence": "default", "selected": false, @@ -89989,12 +89926,6 @@ "source": "native_annotation", "value": false }, - { - "precedence": "tool_schema_hint", - "selected": false, - "source": "tool_schema_hint", - "value": true - }, { "precedence": "default", "selected": false, @@ -96707,12 +96638,6 @@ "source": "native_annotation", "value": false }, - { - "precedence": "tool_schema_hint", - "selected": false, - "source": "tool_schema_hint", - "value": true - }, { "precedence": "default", "selected": false, @@ -97756,9 +97681,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -97768,9 +97693,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { diff --git a/internal/cli/schema_catalog/tools/attendance.json b/internal/cli/schema_catalog/tools/attendance.json index 870c3bb8..c8a401a7 100644 --- a/internal/cli/schema_catalog/tools/attendance.json +++ b/internal/cli/schema_catalog/tools/attendance.json @@ -2878,9 +2878,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -2902,9 +2902,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { @@ -3035,9 +3035,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -3059,9 +3059,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { @@ -3132,9 +3132,9 @@ "interface_type": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": "array" }, { @@ -3150,9 +3150,9 @@ "value": "string" } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": "array" }, "property": { @@ -3178,9 +3178,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -3202,9 +3202,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { @@ -3753,9 +3753,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -3765,9 +3765,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { @@ -9850,9 +9850,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -9868,9 +9868,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { @@ -9953,9 +9953,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -9971,9 +9971,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { @@ -10056,9 +10056,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -10074,9 +10074,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { @@ -10544,9 +10544,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -10568,9 +10568,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { @@ -10660,9 +10660,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -10684,9 +10684,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { @@ -19976,9 +19976,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -20000,9 +20000,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { diff --git a/internal/cli/schema_catalog/tools/calendar.json b/internal/cli/schema_catalog/tools/calendar.json index 44b71a50..051cce3e 100644 --- a/internal/cli/schema_catalog/tools/calendar.json +++ b/internal/cli/schema_catalog/tools/calendar.json @@ -2973,9 +2973,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -2997,9 +2997,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { @@ -3389,9 +3389,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, { @@ -3401,17 +3401,17 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, "required_when": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": "recurrence-range-type is numbered" }, { @@ -3421,9 +3421,9 @@ "value": "" } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": "recurrence-range-type is numbered" }, "type": { @@ -3492,9 +3492,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, { @@ -3504,17 +3504,17 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, "required_when": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": "recurrence-type is absoluteMonthly or absoluteYearly" }, { @@ -3524,9 +3524,9 @@ "value": "" } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": "recurrence-type is absoluteMonthly or absoluteYearly" }, "type": { @@ -3595,9 +3595,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, { @@ -3607,17 +3607,17 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, "required_when": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": "recurrence-type is weekly or relativeMonthly" }, { @@ -3627,9 +3627,9 @@ "value": "" } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": "recurrence-type is weekly or relativeMonthly" }, "type": { @@ -3718,9 +3718,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, { @@ -3730,17 +3730,17 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, "required_when": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": "recurrence-range-type is endDate" }, { @@ -3750,9 +3750,9 @@ "value": "" } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": "recurrence-range-type is endDate" }, "type": { @@ -3918,9 +3918,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, { @@ -3930,17 +3930,17 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, "required_when": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": "recurrence-type is relativeMonthly" }, { @@ -3950,9 +3950,9 @@ "value": "" } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": "recurrence-type is relativeMonthly" }, "type": { @@ -4021,9 +4021,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, { @@ -4039,17 +4039,17 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, "required_when": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": "any recurrence-* flag is provided" }, { @@ -4059,9 +4059,9 @@ "value": "" } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": "any recurrence-* flag is provided" }, "type": { @@ -4130,9 +4130,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, { @@ -4148,17 +4148,17 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, "required_when": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": "any recurrence-* flag is provided" }, { @@ -4168,9 +4168,9 @@ "value": "" } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": "any recurrence-* flag is provided" }, "type": { @@ -4239,9 +4239,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, { @@ -4257,17 +4257,17 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, "required_when": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": "any recurrence-* flag is provided" }, { @@ -4277,9 +4277,9 @@ "value": "" } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": "any recurrence-* flag is provided" }, "type": { @@ -4713,9 +4713,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -4737,9 +4737,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { @@ -4932,9 +4932,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -4956,9 +4956,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { @@ -12876,12 +12876,6 @@ "source": "require_one_of_constraint", "value": false }, - { - "precedence": "tool_schema_hint", - "selected": false, - "source": "tool_schema_hint", - "value": true - }, { "precedence": "default", "selected": false, @@ -26708,9 +26702,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, { @@ -26720,17 +26714,17 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, "required_when": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": "recurrence-range-type is numbered" }, { @@ -26740,9 +26734,9 @@ "value": "" } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": "recurrence-range-type is numbered" }, "type": { @@ -26811,9 +26805,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, { @@ -26823,17 +26817,17 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, "required_when": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": "recurrence-type is absoluteMonthly or absoluteYearly" }, { @@ -26843,9 +26837,9 @@ "value": "" } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": "recurrence-type is absoluteMonthly or absoluteYearly" }, "type": { @@ -26914,9 +26908,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, { @@ -26926,17 +26920,17 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, "required_when": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": "recurrence-type is weekly or relativeMonthly" }, { @@ -26946,9 +26940,9 @@ "value": "" } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": "recurrence-type is weekly or relativeMonthly" }, "type": { @@ -27037,9 +27031,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, { @@ -27049,17 +27043,17 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, "required_when": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": "recurrence-range-type is endDate" }, { @@ -27069,9 +27063,9 @@ "value": "" } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": "recurrence-range-type is endDate" }, "type": { @@ -27237,9 +27231,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, { @@ -27249,17 +27243,17 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, "required_when": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": "recurrence-type is relativeMonthly" }, { @@ -27269,9 +27263,9 @@ "value": "" } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": "recurrence-type is relativeMonthly" }, "type": { @@ -27340,9 +27334,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, { @@ -27358,17 +27352,17 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, "required_when": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": "any recurrence-* flag is provided" }, { @@ -27378,9 +27372,9 @@ "value": "" } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": "any recurrence-* flag is provided" }, "type": { @@ -27449,9 +27443,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, { @@ -27467,17 +27461,17 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, "required_when": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": "any recurrence-* flag is provided" }, { @@ -27487,9 +27481,9 @@ "value": "" } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": "any recurrence-* flag is provided" }, "type": { @@ -27558,9 +27552,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, { @@ -27576,17 +27570,17 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, "required_when": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": "any recurrence-* flag is provided" }, { @@ -27596,9 +27590,9 @@ "value": "" } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": "any recurrence-* flag is provided" }, "type": { diff --git a/internal/cli/schema_catalog/tools/dev.json b/internal/cli/schema_catalog/tools/dev.json index fd5101f5..56ced3f5 100644 --- a/internal/cli/schema_catalog/tools/dev.json +++ b/internal/cli/schema_catalog/tools/dev.json @@ -19744,12 +19744,6 @@ "source": "native_annotation", "value": false }, - { - "precedence": "tool_schema_hint", - "selected": false, - "source": "tool_schema_hint", - "value": true - }, { "precedence": "default", "selected": false, @@ -24044,12 +24038,6 @@ "source": "native_annotation", "value": false }, - { - "precedence": "tool_schema_hint", - "selected": false, - "source": "tool_schema_hint", - "value": true - }, { "precedence": "default", "selected": false, diff --git a/internal/cli/schema_catalog/tools/ding.json b/internal/cli/schema_catalog/tools/ding.json index a05b5c68..3daedafa 100644 --- a/internal/cli/schema_catalog/tools/ding.json +++ b/internal/cli/schema_catalog/tools/ding.json @@ -931,12 +931,6 @@ "source": "cobra_usage", "value": "消息内容 (必填)" }, - { - "precedence": "tool_schema_hint", - "selected": false, - "source": "tool_schema_hint", - "value": "DING 消息内容。" - }, { "precedence": "mcp_metadata", "selected": false, @@ -972,9 +966,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -996,9 +990,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { @@ -1046,12 +1040,6 @@ "source": "cobra_usage", "value": "机器人 ID,发 DING 的机器人编码 (必填,可从 应用管理→机器人 获取,或设 DINGTALK_DING_ROBOT_CODE)" }, - { - "precedence": "tool_schema_hint", - "selected": false, - "source": "tool_schema_hint", - "value": "DING 机器人编码。通常来自开放平台或应用机器人配置。" - }, { "precedence": "mcp_metadata", "selected": false, @@ -1087,9 +1075,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -1111,9 +1099,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { @@ -1162,12 +1150,6 @@ "source": "cobra_usage", "value": "提醒类型: app/sms/call (默认 app)" }, - { - "precedence": "tool_schema_hint", - "selected": false, - "source": "tool_schema_hint", - "value": "提醒类型。CLI 默认使用 app,对应应用内提醒。" - }, { "precedence": "mcp_metadata", "selected": false, @@ -1298,12 +1280,6 @@ "source": "cobra_usage", "value": "接收人 userId 列表 (必填)" }, - { - "precedence": "tool_schema_hint", - "selected": false, - "source": "tool_schema_hint", - "value": "接收人的 userId 列表。CLI 使用逗号分隔,例如 user1,user2。" - }, { "precedence": "mcp_metadata", "selected": false, @@ -1325,9 +1301,9 @@ "interface_type": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": "array" }, { @@ -1343,9 +1319,9 @@ "value": "string" } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": "array" }, "property": { @@ -1371,9 +1347,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -1395,9 +1371,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { diff --git a/internal/cli/schema_catalog/tools/doc.json b/internal/cli/schema_catalog/tools/doc.json index f6347257..54f1a730 100644 --- a/internal/cli/schema_catalog/tools/doc.json +++ b/internal/cli/schema_catalog/tools/doc.json @@ -3124,9 +3124,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -3148,9 +3148,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { @@ -6794,9 +6794,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -6818,9 +6818,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { @@ -9346,9 +9346,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -9370,9 +9370,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { @@ -40170,9 +40170,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -40194,9 +40194,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { diff --git a/internal/cli/schema_catalog/tools/drive.json b/internal/cli/schema_catalog/tools/drive.json index 05b2b6ff..e4556bcc 100644 --- a/internal/cli/schema_catalog/tools/drive.json +++ b/internal/cli/schema_catalog/tools/drive.json @@ -12459,6 +12459,26 @@ "source": "cobra_usage", "value": "每页返回数量 (默认 20,最大 50),仅 spaceType 为 orgSpace 时有效" }, + "interface_type": { + "candidates": [ + { + "precedence": "mcp_metadata", + "selected": true, + "source": "mcp_metadata", + "value": "number" + }, + { + "precedence": "fallback", + "selected": false, + "source": "cobra_flag_type", + "value": "integer" + } + ], + "precedence": "mcp_metadata", + "resolution": "highest_precedence", + "source": "mcp_metadata", + "value": "number" + }, "property": { "candidates": [ { @@ -12529,6 +12549,7 @@ } }, "interface_description": "每页返回数量,默认 20,最大 50。建议根据实际需求调整,较大的值可以减少请求次数,但会增加单次响应的数据量。仅 spaceType 为 orgSpace 时有效", + "interface_type": "number", "property": "maxResults", "required": false, "type": "integer" diff --git a/internal/cli/schema_catalog/tools/minutes.json b/internal/cli/schema_catalog/tools/minutes.json index 2da0d19f..1f325967 100644 --- a/internal/cli/schema_catalog/tools/minutes.json +++ b/internal/cli/schema_catalog/tools/minutes.json @@ -5181,9 +5181,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -5205,9 +5205,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { diff --git a/internal/cli/schema_catalog/tools/pat.json b/internal/cli/schema_catalog/tools/pat.json index 6fbb0c7c..e8b89e4c 100644 --- a/internal/cli/schema_catalog/tools/pat.json +++ b/internal/cli/schema_catalog/tools/pat.json @@ -1112,9 +1112,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, { @@ -1124,17 +1124,17 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": false }, "required_when": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": "grant-type is session" }, { @@ -1144,9 +1144,9 @@ "value": "" } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": "grant-type is session" }, "type": { diff --git a/internal/cli/schema_catalog/tools/sheet.json b/internal/cli/schema_catalog/tools/sheet.json index cae3c2da..e7bc7935 100644 --- a/internal/cli/schema_catalog/tools/sheet.json +++ b/internal/cli/schema_catalog/tools/sheet.json @@ -12139,9 +12139,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -12163,9 +12163,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { @@ -12254,9 +12254,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -12278,9 +12278,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { @@ -13681,9 +13681,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -13705,9 +13705,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { @@ -28090,9 +28090,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -28114,9 +28114,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { diff --git a/internal/cli/schema_catalog/tools/wiki.json b/internal/cli/schema_catalog/tools/wiki.json index b502b783..e26e534a 100644 --- a/internal/cli/schema_catalog/tools/wiki.json +++ b/internal/cli/schema_catalog/tools/wiki.json @@ -2061,9 +2061,9 @@ "required": { "candidates": [ { - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "selected": true, - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, { @@ -2085,9 +2085,9 @@ "value": false } ], - "precedence": "tool_schema_hint", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "tool_schema_hint", + "source": "native_annotation", "value": true }, "required_when": { @@ -3562,8 +3562,14 @@ "required": { "candidates": [ { - "precedence": "mcp_metadata", + "precedence": "native_annotation", "selected": true, + "source": "native_annotation", + "value": true + }, + { + "precedence": "mcp_metadata", + "selected": false, "source": "mcp_metadata", "value": true }, @@ -3580,9 +3586,9 @@ "value": false } ], - "precedence": "mcp_metadata", + "precedence": "native_annotation", "resolution": "highest_precedence", - "source": "mcp_metadata", + "source": "native_annotation", "value": true }, "required_when": { diff --git a/internal/cli/schema_catalog_test.go b/internal/cli/schema_catalog_test.go index 0d621350..100a8942 100644 --- a/internal/cli/schema_catalog_test.go +++ b/internal/cli/schema_catalog_test.go @@ -742,7 +742,7 @@ func TestEmbeddedCatalogMinutesReplaceBatchPairDescriptionIsNative(t *testing.T) } func TestEmbeddedCatalogTodoParamDeclsFrom87910880Hints(t *testing.T) { - // Spot-check former schema_hints/metadata/todo.json overlays (87910880). + // Spot-check former metadata/todo.json overlays now declared as ParamDecl (87910880). // --query-all is a Cobra Bool: merge-base catalog publishes type=boolean from // cobra_flag_type (no separate interface_type field), while required/description // stay native_annotation after ParamDecl migration. @@ -858,7 +858,7 @@ func TestEmbeddedCatalogTodoParamDeclsFrom87910880Hints(t *testing.T) { } func TestEmbeddedCatalogSheetParamDeclsFrom87910880Hints(t *testing.T) { - // Former schema_hints/metadata/sheet.json overlays (87910880). + // Former metadata/sheet.json overlays now declared as ParamDecl (87910880). for _, tc := range []struct { path string flag string @@ -883,6 +883,48 @@ func TestEmbeddedCatalogSheetParamDeclsFrom87910880Hints(t *testing.T) { } } +func TestEmbeddedCatalogPatSheetWikiRegisterSchemaHintParamDecls(t *testing.T) { + // Former RegisterSchemaHints required / required_when pins for pat, sheet, + // and wiki must publish via ParamDecl (native_annotation). + for _, tc := range []struct { + path string + flag string + wantRequired bool + requiredWhen string + }{ + {"pat chmod", "session-id", false, "grant-type is session"}, + {"sheet create", "name", true, ""}, + {"sheet list", "node", true, ""}, + {"sheet new", "node", true, ""}, + {"sheet new", "name", true, ""}, + {"wiki space create", "name", true, ""}, + {"wiki space get", "workspace", true, ""}, + } { + leaf, err := embeddedSchemaPayload([]string{tc.path}) + if err != nil { + t.Fatalf("%s: %v", tc.path, err) + } + param := schemaMap(leaf["parameters"])[tc.flag] + if param["required"] != tc.wantRequired { + t.Fatalf("%s --%s required = %#v, want %v", tc.path, tc.flag, param["required"], tc.wantRequired) + } + reqProv := schemaMap(param["field_provenance"])["required"] + if got, _ := reqProv["source"].(string); got != "native_annotation" { + t.Fatalf("%s --%s required source = %#v, want native_annotation", tc.path, tc.flag, reqProv) + } + if tc.requiredWhen == "" { + continue + } + if param["required_when"] != tc.requiredWhen { + t.Fatalf("%s --%s required_when = %#v, want %q", tc.path, tc.flag, param["required_when"], tc.requiredWhen) + } + whenProv := schemaMap(param["field_provenance"])["required_when"] + if got, _ := whenProv["source"].(string); got != "native_annotation" { + t.Fatalf("%s --%s required_when source = %#v, want native_annotation", tc.path, tc.flag, whenProv) + } + } +} + func TestEmbeddedCatalogReportCreateToChatRequiredAndAliasView(t *testing.T) { // Former report.create_report overlay: --to-chat required=false (MCP marks // it required). Alias "report create" must keep the same contract. @@ -1083,6 +1125,10 @@ func TestEmbeddedCatalogAitableQueryKeywordAndHintParamDecls(t *testing.T) { {"aitable attachment upload", "size"}, {"aitable chart update", "config"}, {"aitable record upsert", "records"}, + {"aitable field create", "fields"}, + {"aitable dashboard create", "name"}, + {"aitable dashboard update", "name"}, + {"aitable view update visible-fields", "field-ids"}, } { leaf, err := embeddedSchemaPayload([]string{tc.path}) if err != nil { @@ -1158,8 +1204,8 @@ func TestEmbeddedCatalogShortcutQueryMapsToKeyword(t *testing.T) { } func TestEmbeddedCatalogContactParamDeclsMatchMergeBaseContract(t *testing.T) { - // Former schema_hints/metadata/contact.json overlays at 87910880 must stay - // on the published primary flags after ParamDecl migration. Hidden Cobra + // Former metadata/contact.json overlays at 87910880 must stay on the + // published primary flags after ParamDecl migration. Hidden Cobra // aliases (--id/--userid/--dept-name/--super-dept*) must not appear. type wantParam struct { property string @@ -1318,7 +1364,7 @@ func TestEmbeddedCatalogChatParamDeclsFrom87910880Hints(t *testing.T) { } } - // Former schema_hints/metadata/chat.json overlays (87910880) must stay on + // Former metadata/chat.json overlays (87910880) must stay on // helpers/shortcut leaves via ParamDecl after hint clearance. for _, tc := range []struct { path string diff --git a/internal/cli/schema_hint_dirs.go b/internal/cli/schema_hint_dirs.go index fe4c4c12..7419fab2 100644 --- a/internal/cli/schema_hint_dirs.go +++ b/internal/cli/schema_hint_dirs.go @@ -59,9 +59,15 @@ type hintDirTool struct { } func loadManualSchemaHintsFromHintDirs(metadataFS fs.FS, metadataGlob string, selectionFS fs.FS, selectionGlob string) (ManualSchemaHintSnapshot, error) { - commands, err := loadParameterCommandsFromMetadata(metadataFS, metadataGlob) - if err != nil { - return ManualSchemaHintSnapshot{}, err + // Metadata is optional and normally nil/empty after phase 5 deleted + // schema_hints/metadata/. Nil FS or empty glob = no parameter overlays. + var commands []ManualSchemaCommandHint + if metadataFS != nil && strings.TrimSpace(metadataGlob) != "" { + var err error + commands, err = loadParameterCommandsFromMetadata(metadataFS, metadataGlob) + if err != nil { + return ManualSchemaHintSnapshot{}, err + } } agentHints, err := loadAgentHintsFromSelection(selectionFS, selectionGlob) if err != nil { @@ -80,6 +86,11 @@ func loadManualSchemaHintsFromHintDirs(metadataFS fs.FS, metadataGlob string, se } func loadParameterCommandsFromMetadata(metadataFS fs.FS, globPattern string) ([]ManualSchemaCommandHint, error) { + // Nil FS, empty glob, or zero matches are all OK (no overlays). The + // on-disk schema_hints/metadata/ directory may be absent. + if metadataFS == nil || strings.TrimSpace(globPattern) == "" { + return nil, nil + } files, err := fs.Glob(metadataFS, globPattern) if err != nil { return nil, fmt.Errorf("list metadata hints: %w", err) diff --git a/internal/cli/schema_hint_emptiness_contract_test.go b/internal/cli/schema_hint_emptiness_contract_test.go new file mode 100644 index 00000000..36bb17d6 --- /dev/null +++ b/internal/cli/schema_hint_emptiness_contract_test.go @@ -0,0 +1,167 @@ +// Copyright 2026 Alibaba Group +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cli + +import ( + "encoding/json" + "io/fs" + "os" + "path/filepath" + "sort" + "strconv" + "strings" + "testing" +) + +// TestDeletedProductionSchemaHintFilesStayGone locks stage-3 cleanup: the +// former production RegisterSchemaHints init files must not return. Their +// pins live on leaf ParamDecl / ContractFinal; RegisterSchemaHints remains +// only for test-fixture injection. +func TestDeletedProductionSchemaHintFilesStayGone(t *testing.T) { + deleted := []string{ + "schema_hints_aitable.go", + "schema_hints_attendance.go", + "schema_hints_ding.go", + "schema_hints_helper_roots.go", + "schema_hints_runtime.go", + } + for _, name := range deleted { + path := filepath.Join(".", name) + if _, err := os.Stat(path); err == nil { + t.Fatalf("%s must stay deleted after RegisterSchemaHints→ParamDecl migration", name) + } else if !os.IsNotExist(err) { + t.Fatalf("stat %s: %v", name, err) + } + } +} + +// TestEmbeddedMetadataHintShellsHaveEmptyTools locks the phase-5 end-state: +// schema_hints/metadata may be absent. When present, shells must keep +// tools:{} so they emit no parameter overlays. Production embed loading +// always passes nil/empty for metadata. +func TestEmbeddedMetadataHintShellsHaveEmptyTools(t *testing.T) { + commands, err := loadParameterCommandsFromMetadata(nil, "") + if err != nil { + t.Fatalf("loadParameterCommandsFromMetadata(nil, \"\"): %v", err) + } + if got := len(commands); got != 0 { + t.Fatalf("nil metadata parameter overlays = %d, want 0", got) + } + + const metadataDir = "schema_hints/metadata" + entries, err := os.ReadDir(metadataDir) + if err != nil { + if os.IsNotExist(err) { + return + } + t.Fatalf("read %s: %v", metadataDir, err) + } + if len(entries) == 0 { + return + } + + metadataFS := os.DirFS(metadataDir) + files, err := fs.Glob(metadataFS, "*.json") + if err != nil { + t.Fatalf("list metadata shells: %v", err) + } + sort.Strings(files) + + nonEmpty := make([]string, 0) + for _, name := range files { + data, err := fs.ReadFile(metadataFS, name) + if err != nil { + t.Fatalf("read %s: %v", name, err) + } + var file hintDirFile + if err := json.Unmarshal(data, &file); err != nil { + t.Fatalf("decode %s: %v", name, err) + } + if len(file.Tools) != 0 { + paths := make([]string, 0, len(file.Tools)) + for canonical := range file.Tools { + paths = append(paths, canonical) + } + sort.Strings(paths) + nonEmpty = append(nonEmpty, filepath.Base(name)+"="+strings.Join(paths, ",")) + } + } + if len(nonEmpty) != 0 { + t.Fatalf("metadata shells must keep tools:{} (want 0 tool rows); nonempty=%v", nonEmpty) + } + + commands, err = loadParameterCommandsFromMetadata(metadataFS, "*.json") + if err != nil { + t.Fatalf("loadParameterCommandsFromMetadata: %v", err) + } + if got := len(commands); got != 0 { + t.Fatalf("on-disk metadata parameter overlays = %d, want 0", got) + } +} + +// TestEmbeddedCatalogHasNoToolSchemaHintProvenance asserts the published +// Catalog no longer selects tool_schema_hint as a provenance winner or +// retained candidate after RegisterSchemaHints → ParamDecl migration. +func TestEmbeddedCatalogHasNoToolSchemaHintProvenance(t *testing.T) { + if !embeddedSchemaCatalogAvailable() { + t.Fatal("embedded schema catalog unavailable") + } + loaded := embeddedSchemaCatalog() + hits := make([]string, 0) + for _, product := range loaded.Registry.Products { + for _, tool := range product.Tools { + hits = append(hits, toolSchemaHintProvenanceHits(tool.Identity.CanonicalPath, tool.FieldProvenance)...) + for _, param := range tool.Parameters { + prefix := tool.Identity.CanonicalPath + "." + param.Name + hits = append(hits, toolSchemaHintProvenanceHits(prefix, param.FieldProvenance)...) + } + } + } + if total := len(hits); total != 0 { + sample := hits + if total > 20 { + sample = hits[:20] + } + t.Fatalf("catalog field_provenance still references tool_schema_hint (count=%d); sample=%v", total, sample) + } +} + +func toolSchemaHintProvenanceHits(prefix string, provenance map[string]FieldProvenance) []string { + if len(provenance) == 0 { + return nil + } + hits := make([]string, 0) + fields := make([]string, 0, len(provenance)) + for field := range provenance { + fields = append(fields, field) + } + sort.Strings(fields) + for _, field := range fields { + prov := provenance[field] + if prov.Source == runtimeSchemaPrecedenceToolHint { + hits = append(hits, prefix+"."+field+"#winner") + } + for i, candidate := range prov.Candidates { + if candidate.Source == runtimeSchemaPrecedenceToolHint { + hits = append(hits, prefix+"."+field+"#candidate["+strconv.Itoa(i)+"]") + } + } + for i, candidate := range prov.OverriddenCandidates { + if candidate.Source == runtimeSchemaPrecedenceToolHint { + hits = append(hits, prefix+"."+field+"#overridden["+strconv.Itoa(i)+"]") + } + } + } + return hits +} diff --git a/internal/cli/schema_hints.go b/internal/cli/schema_hints.go index 2a00df0e..39e60fb1 100644 --- a/internal/cli/schema_hints.go +++ b/internal/cli/schema_hints.go @@ -50,8 +50,6 @@ type SchemaHintRegistry struct { tools map[string]ToolSchemaHint } -func boolPtr(v bool) *bool { return &v } - var defaultSchemaHintRegistry = newSchemaHintRegistry() func newSchemaHintRegistry() *SchemaHintRegistry { @@ -60,10 +58,12 @@ func newSchemaHintRegistry() *SchemaHintRegistry { } } -// RegisterSchemaHints registers curated hints for one product. Keys in tools may -// be either RPC names ("send_ding_message") or canonical paths -// ("ding.send_ding_message"). Duplicate canonical paths panic during init so -// conflicting product hint files are caught early. +// RegisterSchemaHints registers curated tool_schema_hint overlays for one +// product. Production init no longer registers any product; ParamDecl / +// LeafSchema owns those pins. The registry and this helper remain so runtime +// lookup and test fixtures can still inject temporary hints for precedence +// coverage. Keys may be RPC names ("send_ding_message") or canonical paths +// ("ding.send_ding_message"). Duplicate canonical paths panic. func RegisterSchemaHints(productID string, tools map[string]ToolSchemaHint) { defaultSchemaHintRegistry.RegisterProduct(productID, tools) } diff --git a/internal/cli/schema_hints/README.md b/internal/cli/schema_hints/README.md index b3349f8a..f2d8d95c 100644 --- a/internal/cli/schema_hints/README.md +++ b/internal/cli/schema_hints/README.md @@ -1,25 +1,26 @@ # DWS Agent Schema Hints -This directory contains versioned, structured Agent metadata. Hints belong to -the CLI Schema subsystem rather than either installable Skill layout. They are -excluded from embedded binaries and release Skill bundles. Files generate -`internal/cli/schema_agent_metadata/`; generated runtime metadata must not be -edited directly. +This directory contains versioned, structured Agent inputs for Schema +generation. Hints belong to the CLI Schema subsystem rather than either +installable Skill layout. They are excluded from embedded binaries and release +Skill bundles. Files generate `internal/cli/schema_agent_metadata/`; generated +runtime metadata must not be edited directly. ## Layout -Human-authored inputs live in two blocks: +Human-authored inputs: -- `index.json` (`format: dws-agent-hint-index`) — maps product IDs to metadata - and selection files, plus reference review -- `metadata/.json` — command metadata: safety, interface, - `runtime_gate`, and optional parameter overrides -- `selection/.json` — Agent selection prose +- `index.json` (`format: dws-agent-hint-index`) — maps product IDs to required + selection files and optional metadata map, plus reference review. + Strategy: `metadata` is optional (omitted or `{}`); the on-disk + `metadata/` directory is retired and may be absent. +- `selection/.json` — Agent selection prose (required) - `imported/` — sanitized baseline from a fixed external revision -When `index.json` is present, the generator loads `imported/` plus the -metadata and selection files listed in the index. Sibling review JSON files in -this directory remain CI/audit inputs and are not applied as Agent metadata +When `index.json` is present, the generator loads `imported/` plus any +metadata files listed in `index.metadata` (optional) and the selection files +listed in `index.selection` (required). Sibling review JSON files in this +directory remain CI/audit inputs and are not applied as Agent metadata sources. For the end-to-end Agent curation workflow, see `AGENTS.md` § “Agent curation @@ -27,9 +28,12 @@ workflow (Schema hints)”. ## Source kinds -- `reviewed_explicit`: reviewed metadata or selection HintFiles under - `metadata/` / `selection/` (`reviewed: true`). Selection prose is delivered - only from `selection/`. +- `contract_final`: leaf-declared Safety / Schema / ParamDecl + (`DeclareLeafMetadata`, `Shortcut.Schema`). This is the production authority + for safety, interface disposition, and parameter facts. +- `reviewed_explicit`: reviewed selection HintFiles under `selection/` + (`reviewed: true`) for Agent selection prose. Residual metadata tool rows are + not used in production shells. - `explicit`: explicit but not per-tool-reviewed DWS hints. - `imported`: sanitized metadata from a fixed external revision. It fills missing Agent semantics but cannot redefine command paths or parameter contracts. @@ -54,7 +58,7 @@ current public leaf. `alias` entries bind an old or cross-product path to an explicit current target. `group`, `stale`, and `out_of_surface` entries remain visible in the audit but are never fuzzy-matched to a leaf. -`interface_ref` is a separate interface binding. Use it when a public helper/canonical tool calls a differently named MCP RPC or another source product: +`interface_ref` is a separate interface binding. Use it when a public helper/canonical tool calls a differently named MCP RPC or another source product. Prefer declaring it on the leaf Contract (`Schema.Interface`) rather than adding a metadata tool row: ```json { @@ -94,20 +98,24 @@ current CLI/Catalog tool count. Its `coverage.surface_scope` must remain `source_revision`, and policy verifies the snapshot's internal matched and unmatched arithmetic. Current Catalog interface coverage is instead proved for every generated tool: each tool must have one valid `interface_mode` / -availability disposition and retain reviewed provenance to -`selection-review.json`, `zz-interface-disposition-review.json`, or another -reviewed interface source. This makes newly added CLI tools explicit without -rewriting historical MCP evidence or promoting an unreviewed selection hint. +availability disposition and retain reviewed provenance to a leaf Contract +declaration (`contract_final`) or another reviewed interface source. This makes +newly added CLI tools explicit without rewriting historical MCP evidence or +promoting an unreviewed selection hint. Interface metadata contributes lower-priority typed candidates, including `required`; source precedence is value-neutral for most fields, so a candidate may raise or lower the Agent-facing value when no higher-priority source wins. -It cannot override reviewed manual hints, versioned bindings, typed/native +It cannot override leaf Contract declarations, versioned bindings, typed/native metadata, or current Cobra/constraint facts for those fields. `required` is special: Cobra `MarkFlagRequired` is a hard floor that cannot be projected away as optional. `cli_required` remains the executable Cobra marker with its own provenance. +Production `RegisterSchemaHints` maps are empty after ParamDecl migration. +Temporary `tool_schema_hint` injection is allowed only inside unit-test +fixtures that exercise precedence edges. + ```json { "version": 1, @@ -120,39 +128,30 @@ provenance. "agent_summary": "管理日程、参与人、会议室和闲忙信息" } }, - "tools": { - "calendar.get_calendar_detail": { - "agent_summary": "读取一个日程的完整详情", - "use_when": ["已经取得 eventId,需要查看详情"], - "effect": "read", - "reviewed": true - } - } + "tools": {} } ``` -Run `make generate-schema` after changing Hint or Skill sources. External Wukong metadata must be refreshed by the controlled offline import pipeline with an immutable revision, then committed together with its audit before regenerating the Catalog; runtime refresh is forbidden. +Run `make generate-schema` after changing selection Hint or Skill sources, or +after changing leaf Contract declarations that feed Schema generation. External +Wukong metadata must be refreshed by the controlled offline import pipeline +with an immutable revision, then committed together with its audit before +regenerating the Catalog; runtime refresh is forbidden. -## Metadata parameters and selection prose +## Selection prose -Agent semantic hints in this directory do not change the executable CLI -contract beyond reviewed parameter overlays on metadata tools. +Leaf facts live on Contract declarations; `index.metadata` may be `{}` or +omitted. The on-disk `metadata/` directory is retired and must not be +reintroduced as a leaf-fact source. | Block | Owns | |---|---| -| `metadata/.json` | safety, interface, `runtime_gate`, optional `parameters` / `cli_path` | +| leaf Contract (`Safety` / `Schema` / ParamDecl) | safety, interface, parameter facts (`contract_final`) | | `selection/.json` | `agent_summary`, `use_when`, `avoid_when`, `examples` | -Parameter overlays may override Schema description, interface-property/type -mapping, `required`, and `required_when` for flags that already exist on that -command. They cannot create a command or flag, target a hidden/group command, -define an interface, or mark an unknown RPC available. Missing commands and -flags, wildcards, canonical conflicts, duplicate paths, and unreviewed entries -fail generation. - Selection prose is committed as a reviewed source. `go generate` only reads, validates, and projects this data. It must never call a model, copy a previous -Catalog, or overwrite metadata/selection files. Selection cannot change command +Catalog, or overwrite selection files. Selection cannot change command identity, flags, parameters, safety, or interface facts. Commands intentionally kept outside Schema remain in the separate exact @@ -163,13 +162,11 @@ that exclusion as stale. ### Agent editing workflow 1. Locate the real Cobra leaf and verify its exact path and current flags. -2. Edit only the owning block (`metadata/` or `selection/`); do not mix fields. +2. Declare safety/interface/parameters on the owning leaf; edit + `selection/.json` for selection prose only. 3. Add only fields that need review. Do not copy generated Catalog fields into the input. -4. Use `property` and `interface_type` only for a real CLI-to-interface - conversion. `required` and `required_when` describe the Schema projection; - they do not modify Cobra execution validation. -5. Run: +4. Run: ```bash make generate-schema @@ -179,6 +176,11 @@ that exclusion as stale. go test ./internal/cli ./internal/app ``` -6. Review the generated Catalog diff. A parameter overlay should affect only - the intended contract. A selection edit updates prose provenance to - `reviewed_explicit` from `selection/`. + `check-runtime-confirmation-truth.sh` accepts optional/empty metadata + shells (`tools: {}` or absent directory); gated confirmation truth comes + from leaf Contract SafetySpec, not from metadata tool rows. + +6. Review the generated Catalog diff. A leaf declaration change should affect + only the intended contract. A selection edit updates prose provenance to + `reviewed_explicit` from `selection/`; safety/interface provenance stays + `contract_final`. diff --git a/internal/cli/schema_hints/index.json b/internal/cli/schema_hints/index.json index 37b04a52..0e2f842f 100644 --- a/internal/cli/schema_hints/index.json +++ b/internal/cli/schema_hints/index.json @@ -7,34 +7,7 @@ "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", "channel": "open-source" }, - "metadata": { - "aisearch": "metadata/aisearch.json", - "aitable": "metadata/aitable.json", - "attendance": "metadata/attendance.json", - "audit": "metadata/audit.json", - "calendar": "metadata/calendar.json", - "chat": "metadata/chat.json", - "contact": "metadata/contact.json", - "dev": "metadata/dev.json", - "devapp": "metadata/devapp.json", - "devdoc": "metadata/devdoc.json", - "ding": "metadata/ding.json", - "doc": "metadata/doc.json", - "drive": "metadata/drive.json", - "event": "metadata/event.json", - "hrbrain": "metadata/hrbrain.json", - "live": "metadata/live.json", - "mail": "metadata/mail.json", - "markdown": "metadata/markdown.json", - "mcp": "metadata/mcp.json", - "minutes": "metadata/minutes.json", - "oa": "metadata/oa.json", - "pat": "metadata/pat.json", - "report": "metadata/report.json", - "sheet": "metadata/sheet.json", - "todo": "metadata/todo.json", - "wiki": "metadata/wiki.json" - }, + "metadata": {}, "selection": { "aisearch": "selection/aisearch.json", "aitable": "selection/aitable.json", diff --git a/internal/cli/schema_hints/metadata/aisearch.json b/internal/cli/schema_hints/metadata/aisearch.json deleted file mode 100644 index 9a7268d9..00000000 --- a/internal/cli/schema_hints/metadata/aisearch.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/aisearch", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": { - "aisearch.search_enterprise": { - "reviewed": true, - "cli_path": "aisearch enterprise", - "review_reason": "The reviewed CLI supports an all-content search with default --types all, while --queries and --time-range are optional filters; imported MCP required markers must not turn them into mandatory CLI input." - } - } -} \ No newline at end of file diff --git a/internal/cli/schema_hints/metadata/aitable.json b/internal/cli/schema_hints/metadata/aitable.json deleted file mode 100644 index 7c346607..00000000 --- a/internal/cli/schema_hints/metadata/aitable.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/aitable", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": { - "aitable.query_records": { - "reviewed": true, - "cli_path": "aitable record query", - "review_reason": "The reviewed query command supports both an optional ID lookup mode and a table scan/filter mode, so --record-ids is not unconditionally required." - }, - "aitable.view_update_aggregate": { - "reviewed": true, - "cli_path": "aitable view update aggregate", - "review_reason": "The reviewed CLI accepts --json, a --field-id/--action pair, or --clear-field-id; the registered typed constraints describe those alternatives." - }, - "aitable.view_update_card": { - "reviewed": true, - "cli_path": "aitable view update card", - "review_reason": "The reviewed CLI merges optional typed card flags over an optional --json block; the registered typed constraints require at least one real update field." - }, - "aitable.view_update_field_widths": { - "reviewed": true, - "cli_path": "aitable view update field-widths", - "review_reason": "The reviewed CLI accepts either --json or the paired --field-id/--width form, which is represented by typed require-one-of and require-together constraints." - }, - "aitable.view_update_timebar": { - "reviewed": true, - "cli_path": "aitable view update timebar", - "review_reason": "The reviewed CLI accepts either a complete --json block or one or more typed Gantt timebar fields; --json is therefore not unconditionally required." - }, - "aitable.workflow_create": { - "reviewed": true, - "cli_path": "aitable workflow create", - "review_reason": "The command maps --base-id and a decoded workflow-dsl/v1 --dsl object to aitable/create_workflow. The call intentionally bypasses retries because creation is non-idempotent; locale remains optional." - }, - "aitable.workflow_update": { - "reviewed": true, - "cli_path": "aitable workflow update", - "review_reason": "The command maps --base-id, --workflow-id and a decoded complete workflow-dsl/v1 --dsl object to aitable/update_workflow. This is full replacement rather than a partial patch; locale remains optional." - } - } -} \ No newline at end of file diff --git a/internal/cli/schema_hints/metadata/attendance.json b/internal/cli/schema_hints/metadata/attendance.json deleted file mode 100644 index 95bd6156..00000000 --- a/internal/cli/schema_hints/metadata/attendance.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/attendance", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": { - "attendance.adjustment_search": { - "reviewed": true, - "cli_path": "attendance adjustment search", - "review_reason": "Cobra supplies reviewed page=1 and limit=20 defaults and RunE sends those defaults when omitted, so callers need not pass either pagination flag." - }, - "attendance.group_search": { - "reviewed": true, - "cli_path": "attendance group search", - "review_reason": "Cobra supplies reviewed page=1 and limit=20 defaults and RunE materializes both PageQuery fields when omitted, so callers need not pass either flag." - }, - "attendance.overtime_search": { - "reviewed": true, - "cli_path": "attendance overtime search", - "review_reason": "Cobra supplies reviewed page=1 and limit=20 defaults and RunE sends those defaults when omitted, so callers need not pass either pagination flag." - } - } -} \ No newline at end of file diff --git a/internal/cli/schema_hints/metadata/audit.json b/internal/cli/schema_hints/metadata/audit.json deleted file mode 100644 index a5930f43..00000000 --- a/internal/cli/schema_hints/metadata/audit.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/audit", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": {} -} diff --git a/internal/cli/schema_hints/metadata/calendar.json b/internal/cli/schema_hints/metadata/calendar.json deleted file mode 100644 index 8ae38894..00000000 --- a/internal/cli/schema_hints/metadata/calendar.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/calendar", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": {} -} diff --git a/internal/cli/schema_hints/metadata/chat.json b/internal/cli/schema_hints/metadata/chat.json deleted file mode 100644 index ea07a735..00000000 --- a/internal/cli/schema_hints/metadata/chat.json +++ /dev/null @@ -1,107 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/chat", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": { - "chat.add_emoji_reaction": { - "reviewed": true, - "cli_path": "chat message add-emoji", - "review_reason": "The four reviewed conversation locator flags are aliases for one openConversationId property; the typed require-one-of constraint owns their conditional requirement." - }, - "chat.add_text_emotion": { - "reviewed": true, - "cli_path": "chat message add-text-emotion", - "review_reason": "The four reviewed conversation locator flags are aliases for one openConversationId property; the typed require-one-of constraint owns their conditional requirement." - }, - "chat.create_smart_conv_category": { - "reviewed": true, - "cli_path": "chat category create-smart", - "review_reason": "Expose the existing smart-category helper through the reviewed Agent Schema and preserve its CLI-to-interface parameter contract." - }, - "chat.list_message_favorites": { - "reviewed": true, - "cli_path": "chat message list-favorites", - "review_reason": "Preserve the reviewed CLI-to-interface conversion: Cobra validates --size as an integer from 1 to 100, then the helper serializes it to the string-valued list_message_favorites size property." - }, - "chat.list_owned_or_admin_groups": { - "reviewed": true, - "cli_path": "chat group list-my-groups", - "review_reason": "The reviewed CLI lists all owned or administered groups when --role and --limit are omitted; both flags are optional filters despite stricter imported interface metadata." - }, - "chat.remove_emoji_reaction": { - "reviewed": true, - "cli_path": "chat message remove-emoji", - "review_reason": "The four reviewed conversation locator flags are aliases for one openConversationId property; the typed require-one-of constraint owns their conditional requirement." - }, - "chat.remove_text_emotion": { - "reviewed": true, - "cli_path": "chat message remove-text-emotion", - "review_reason": "The four reviewed conversation locator flags are aliases for one openConversationId property; the typed require-one-of constraint owns their conditional requirement." - }, - "chat.set_group_member_mute_list": { - "reviewed": true, - "cli_path": "chat group-mute-member", - "review_reason": "The reviewed Cobra contract makes --off an optional mode switch: omission adds members to the mute list, while --off removes them. The shared MCP schema incorrectly marks the boolean as unconditionally required." - }, - "chat.set_group_mute": { - "reviewed": true, - "cli_path": "chat group-mute", - "review_reason": "The reviewed optional --off switch selects unmute; omission deliberately selects mute, so false is a valid default rather than missing required input." - }, - "chat.set_top_conversation": { - "reviewed": true, - "cli_path": "chat set-top", - "review_reason": "The reviewed optional --off switch selects unpin; omission deliberately selects pin, so false is a valid default rather than missing required input." - }, - "chat.update_conv_member_roles": { - "reviewed": true, - "cli_path": "chat group set-admin", - "review_reason": "The reviewed optional --off switch selects administrator removal; omission deliberately selects administrator assignment." - }, - "chat.update_notification_off": { - "reviewed": true, - "cli_path": "chat mute", - "review_reason": "The reviewed locator aliases feed one openConversationId property, while optional --off selects unmute; typed constraints require one locator without making the mode switch mandatory." - }, - "chat.edit_message": { - "reviewed": true, - "cli_path": "chat message edit", - "review_reason": "The reviewed handler requires one conversation locator, a message ID, and exactly one of text or raw content; it optionally derives a title and maps mention controls before invoking edit_message." - }, - "chat.get_conv_categories_info": { - "reviewed": true, - "cli_path": "chat category batch-info", - "review_reason": "The reviewed handler requires a comma-separated category-ID list, parses it to integers, and invokes get_conv_categories_info without a mutation or confirmation gate." - }, - "chat.list_conv_categories_by_conv": { - "reviewed": true, - "cli_path": "chat category list-by-conv", - "review_reason": "The reviewed handler accepts one of three conversation locator aliases and invokes list_conv_categories_by_conv without a mutation or confirmation gate." - }, - "chat.update_group_nick": { - "reviewed": true, - "cli_path": "chat group update-nick", - "review_reason": "The reviewed handler requires the target conversation while intentionally allowing omitted --nick to send an empty nickname and clear the current user's group nickname." - }, - "chat.upgrade_group_to_external": { - "reviewed": true, - "cli_path": "chat group upgrade-to-external", - "review_reason": "The reviewed handler validates the target group and optional string-valued extension object, permits caller-authoritative dry-run, and requires explicit --yes before the irreversible upgrade." - }, - "chat.shortcut_messages_send_card": { - "reviewed": true, - "cli_path": "chat +messages-send-card", - "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property." - }, - "chat.update_text_emotion": { - "reviewed": true, - "cli_path": "chat message update-text-emotion", - "review_reason": "Ported from dws-wukong commits d6831318 and bcf56ccf, merged at 30f13f02. The four conversation locators alias one property; the other six business parameters are required by Cobra before the single im/update_text_emotion call." - } - } -} \ No newline at end of file diff --git a/internal/cli/schema_hints/metadata/contact.json b/internal/cli/schema_hints/metadata/contact.json deleted file mode 100644 index cf0aa35a..00000000 --- a/internal/cli/schema_hints/metadata/contact.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/contact", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": { - "contact.add_employee": { - "reviewed": true, - "cli_path": "contact user invite", - "review_reason": "The reviewed Wukong-compatible handler requires employee name and mobile, decodes optional --depts JSON to an array, and calls add_employee without a runtime confirmation gate." - }, - "contact.exclusive_account_create": { - "reviewed": true, - "cli_path": "contact account create", - "review_reason": "The reviewed Wukong-compatible handler requires enterprise display name and login ID, maps optional contact fields and department IDs, and calls exclusive_account_create without a runtime confirmation gate." - }, - "contact.get_authorized_emp_rosterInfo": { - "reviewed": true, - "cli_path": "contact user profile get", - "review_reason": "The reviewed helper deliberately permits either or both optional filters and passes an empty request to query the caller's authorized roster scope." - }, - "contact.org_create": { - "reviewed": true, - "cli_path": "contact org create", - "review_reason": "The reviewed Wukong-compatible handler requires an organization name and creator display name and calls org_create without a runtime confirmation gate." - }, - "contact.department_create": { - "reviewed": true, - "cli_path": "contact dept create", - "review_reason": "The reviewed handler requires one department-name spelling and an explicit boolean group choice, optionally parses a parent department ID, confirms, then invokes department_create." - }, - "contact.department_update": { - "reviewed": true, - "cli_path": "contact dept update", - "review_reason": "The reviewed handler requires one department-ID spelling and one department-name spelling, optionally parses a parent ID, confirms, then invokes department_update." - }, - "contact.employee_update": { - "reviewed": true, - "cli_path": "contact user update", - "review_reason": "The reviewed handler requires one employee-ID spelling plus at least one update field, decodes optional department JSON, confirms, then invokes employee_update." - }, - "contact.exclusive_account_user_update": { - "reviewed": true, - "cli_path": "contact account update", - "review_reason": "The reviewed handler requires one enterprise-account user ID plus at least one profile or organization update field, confirms, then invokes exclusive_account_user_update." - }, - "contact.self_user_profile_update": { - "reviewed": true, - "cli_path": "contact user update-self", - "review_reason": "The reviewed handler requires at least one of nickname or avatar file ID, confirms, then invokes self_user_profile_update for the current user." - } - } -} \ No newline at end of file diff --git a/internal/cli/schema_hints/metadata/dev.json b/internal/cli/schema_hints/metadata/dev.json deleted file mode 100644 index 9a7b1f61..00000000 --- a/internal/cli/schema_hints/metadata/dev.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/dev", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": {} -} diff --git a/internal/cli/schema_hints/metadata/devapp.json b/internal/cli/schema_hints/metadata/devapp.json deleted file mode 100644 index 342fba9c..00000000 --- a/internal/cli/schema_hints/metadata/devapp.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/devapp", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": {} -} diff --git a/internal/cli/schema_hints/metadata/devdoc.json b/internal/cli/schema_hints/metadata/devdoc.json deleted file mode 100644 index bbed507f..00000000 --- a/internal/cli/schema_hints/metadata/devdoc.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/devdoc", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": { - "devdoc.search_open_platform_docs_rag": { - "reviewed": true, - "cli_path": "devdoc article search", - "review_reason": "Search text may be supplied as positional keyword or public --query; hidden --keyword remains a runtime compatibility alias and is intentionally not published as a parameter. The versioned binding owns query -> keyword." - } - } -} \ No newline at end of file diff --git a/internal/cli/schema_hints/metadata/ding.json b/internal/cli/schema_hints/metadata/ding.json deleted file mode 100644 index 97d3d20f..00000000 --- a/internal/cli/schema_hints/metadata/ding.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/ding", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": {} -} diff --git a/internal/cli/schema_hints/metadata/doc.json b/internal/cli/schema_hints/metadata/doc.json deleted file mode 100644 index 6bdd2677..00000000 --- a/internal/cli/schema_hints/metadata/doc.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/doc", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": { - "doc.create_comment": { - "reviewed": true, - "cli_path": "doc comment create", - "review_reason": "The reviewed handler normalizes repeated or comma-separated group conversation IDs into a stable de-duplicated array while preserving existing user mentions." - }, - "doc.get_document_content": { - "reviewed": true, - "cli_path": "doc read", - "review_reason": "The reviewed handler preserves full Markdown/JSONML reads and adds validated outline, range, section, and tag-scoped JSONML fragment reads with optional file output." - }, - "doc.reply_comment": { - "reviewed": true, - "cli_path": "doc comment reply", - "review_reason": "The reviewed handler normalizes group conversation IDs into a stable de-duplicated array and rejects group mentions for emoji replies, which the remote operation does not support." - }, - "doc.update_comment": { - "reviewed": true, - "cli_path": "doc comment update", - "review_reason": "Preserve the reviewed user-mention conversion and normalize repeated or comma-separated group conversation IDs into mentionedOpenConversationIds." - } - } -} \ No newline at end of file diff --git a/internal/cli/schema_hints/metadata/drive.json b/internal/cli/schema_hints/metadata/drive.json deleted file mode 100644 index f7dbc44f..00000000 --- a/internal/cli/schema_hints/metadata/drive.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/drive", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": { - "drive.rename_document": { - "reviewed": true, - "cli_path": "drive rename", - "review_reason": "The reviewed CLI reads node metadata before mutation and strips only the exact current extension for non-folder nodes, avoiding both duplicate extensions and dotted-folder corruption without a suffix whitelist." - }, - "drive.upload": { - "reviewed": true, - "cli_path": "drive upload", - "review_reason": "The reviewed helper preserves the stable command-level Schema contract for ordinary uploads; --node switches to overwrite mode and the runtime still requires explicit confirmation unless --yes is supplied." - } - } -} \ No newline at end of file diff --git a/internal/cli/schema_hints/metadata/event.json b/internal/cli/schema_hints/metadata/event.json deleted file mode 100644 index b4042930..00000000 --- a/internal/cli/schema_hints/metadata/event.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/event", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": {} -} diff --git a/internal/cli/schema_hints/metadata/hrbrain.json b/internal/cli/schema_hints/metadata/hrbrain.json deleted file mode 100644 index 13138842..00000000 --- a/internal/cli/schema_hints/metadata/hrbrain.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/hrbrain", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": { - "hrbrain.list_talent_pools": { - "reviewed": true, - "cli_path": "hrbrain talent-pool list", - "review_reason": "Reviewed unpinned remote adapter: flags map 1:1 to the list_talent_pools MCP call arguments observed in internal/helpers/hrbrain.go." - }, - "hrbrain.get_talent_pool_detail": { - "reviewed": true, - "cli_path": "hrbrain talent-pool detail", - "review_reason": "Reviewed unpinned remote adapter: --pool-code maps 1:1 to the poolCode MCP call argument observed in internal/helpers/hrbrain.go." - }, - "hrbrain.list_pool_employees": { - "reviewed": true, - "cli_path": "hrbrain talent-pool employees", - "review_reason": "Reviewed unpinned remote adapter: flags map 1:1 to the list_pool_employees MCP call arguments observed in internal/helpers/hrbrain.go." - }, - "hrbrain.get_profile_metadata": { - "reviewed": true, - "cli_path": "hrbrain profile metadata", - "review_reason": "Reviewed unpinned remote adapter: --work-no maps 1:1 to the workNo MCP call argument observed in internal/helpers/hrbrain.go." - }, - "hrbrain.query_profile_data": { - "reviewed": true, - "cli_path": "hrbrain profile query", - "review_reason": "Reviewed unpinned remote adapter: flags map 1:1 to the query_profile_data MCP call arguments observed in internal/helpers/hrbrain.go." - }, - "hrbrain.get_profile_label": { - "reviewed": true, - "cli_path": "hrbrain profile labels", - "review_reason": "Reviewed unpinned remote adapter: flags map 1:1 to the get_profile_label MCP call arguments observed in internal/helpers/hrbrain.go." - }, - "hrbrain.get_employee_career": { - "reviewed": true, - "cli_path": "hrbrain profile career", - "review_reason": "Reviewed unpinned remote adapter: --work-no maps 1:1 to the workNo MCP call argument observed in internal/helpers/hrbrain.go." - }, - "hrbrain.get_employee_performance": { - "reviewed": true, - "cli_path": "hrbrain profile performance", - "review_reason": "Reviewed unpinned remote adapter: --work-no maps 1:1 to the workNo MCP call argument observed in internal/helpers/hrbrain.go." - }, - "hrbrain.search_employees": { - "reviewed": true, - "cli_path": "hrbrain search employees", - "review_reason": "Reviewed unpinned remote adapter: flags map 1:1 to the search_employees MCP call arguments observed in internal/helpers/hrbrain.go." - }, - "hrbrain.search_employees_structured": { - "reviewed": true, - "cli_path": "hrbrain search employees-structured", - "review_reason": "Reviewed unpinned remote adapter: flags map 1:1 to the search_employees_structured MCP call arguments observed in internal/helpers/hrbrain.go." - } - } -} \ No newline at end of file diff --git a/internal/cli/schema_hints/metadata/live.json b/internal/cli/schema_hints/metadata/live.json deleted file mode 100644 index 2af3e0db..00000000 --- a/internal/cli/schema_hints/metadata/live.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/live", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": {} -} diff --git a/internal/cli/schema_hints/metadata/mail.json b/internal/cli/schema_hints/metadata/mail.json deleted file mode 100644 index 12bbb025..00000000 --- a/internal/cli/schema_hints/metadata/mail.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/mail", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": { - "mail.list_emails": { - "reviewed": true, - "cli_path": "mail message list", - "review_reason": "Preserve the reviewed composite wrapper contract: the CLI maps --limit to the search_emails size property after constructing a folder KQL query." - }, - "mail.search_mail_users": { - "reviewed": true, - "cli_path": "mail user search", - "review_reason": "The reviewed CLI accepts either a fuzzy keyword or an exact employee number, represented by a typed require-one-of constraint rather than two unconditional requirements." - }, - "mail.update_user_message_template": { - "reviewed": true, - "cli_path": "mail template update", - "review_reason": "The reviewed patch command accepts any non-empty subset of mutable template fields; a typed require-one-of constraint owns that requirement." - } - } -} \ No newline at end of file diff --git a/internal/cli/schema_hints/metadata/markdown.json b/internal/cli/schema_hints/metadata/markdown.json deleted file mode 100644 index e46d7cfd..00000000 --- a/internal/cli/schema_hints/metadata/markdown.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/markdown", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": { - "markdown.create": { - "reviewed": true, - "cli_path": "markdown create", - "review_reason": "The reviewed workflow requires exactly one content source, requires an .md name for literal content, keeps workspace and Drive space mutually exclusive, and routes the upload without a confirmation gate." - }, - "markdown.fetch": { - "reviewed": true, - "cli_path": "markdown fetch", - "review_reason": "The reviewed workflow requires one node locator, keeps explicit Drive and Doc routes mutually exclusive, treats remote content as untrusted data, and protects local output paths." - }, - "markdown.overwrite": { - "reviewed": true, - "cli_path": "markdown overwrite", - "review_reason": "The reviewed workflow requires a target and exactly one content source, supports a command-owned diff preview, and confirms before replacing the remote file." - }, - "markdown.patch": { - "reviewed": true, - "cli_path": "markdown patch", - "review_reason": "The reviewed workflow requires a target, pattern, and replacement; it blocks zero-hit and empty-result writes, supports a command-owned diff preview, and confirms before reupload." - } - } -} \ No newline at end of file diff --git a/internal/cli/schema_hints/metadata/mcp.json b/internal/cli/schema_hints/metadata/mcp.json deleted file mode 100644 index fb0ee42d..00000000 --- a/internal/cli/schema_hints/metadata/mcp.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/mcp", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": {} -} diff --git a/internal/cli/schema_hints/metadata/minutes.json b/internal/cli/schema_hints/metadata/minutes.json deleted file mode 100644 index aa11c02d..00000000 --- a/internal/cli/schema_hints/metadata/minutes.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/minutes", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": { - "minutes.shortcut_replace_batch": { - "reviewed": true, - "cli_path": "minutes +replace-batch", - "review_reason": "Reviewed against the built-in Shortcut registry and mounted Cobra command: publishes the executable risk gate, composite interface, and the custom --pair format/uniqueness validation without inventing a direct MCP identity." - } - } -} \ No newline at end of file diff --git a/internal/cli/schema_hints/metadata/oa.json b/internal/cli/schema_hints/metadata/oa.json deleted file mode 100644 index 0f1e9e5d..00000000 --- a/internal/cli/schema_hints/metadata/oa.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/oa", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": {} -} diff --git a/internal/cli/schema_hints/metadata/pat.json b/internal/cli/schema_hints/metadata/pat.json deleted file mode 100644 index 88665f04..00000000 --- a/internal/cli/schema_hints/metadata/pat.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/pat", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": {} -} diff --git a/internal/cli/schema_hints/metadata/report.json b/internal/cli/schema_hints/metadata/report.json deleted file mode 100644 index 57d67e40..00000000 --- a/internal/cli/schema_hints/metadata/report.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/report", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": { - "report.create_report": { - "reviewed": true, - "cli_path": "report entry submit", - "review_reason": "The reviewed optional --to-chat switch defaults to false and only controls post-submit delivery; it is not required to create a report." - } - } -} \ No newline at end of file diff --git a/internal/cli/schema_hints/metadata/sheet.json b/internal/cli/schema_hints/metadata/sheet.json deleted file mode 100644 index 73839c36..00000000 --- a/internal/cli/schema_hints/metadata/sheet.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/sheet", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": { - "sheet.create_pivot_table": { - "reviewed": true, - "cli_path": "sheet pivot-table create", - "review_reason": "Preserve the reviewed CLI-to-interface conversion: --properties accepts inline JSON or @file text and is validated and decoded to the create_pivot_table properties object." - }, - "sheet.table_put": { - "reviewed": true, - "cli_path": "sheet table-put", - "review_reason": "Preserve the reviewed CLI-to-interface conversion: --sheets accepts inline JSON, @file, or stdin and is normalized to the table_put sheets array." - }, - "sheet.update_pivot_table": { - "reviewed": true, - "cli_path": "sheet pivot-table update", - "review_reason": "Preserve the reviewed CLI-to-interface conversion: --properties accepts inline JSON or @file text and is validated and decoded to the update_pivot_table properties object." - } - } -} \ No newline at end of file diff --git a/internal/cli/schema_hints/metadata/todo.json b/internal/cli/schema_hints/metadata/todo.json deleted file mode 100644 index 1839a7d0..00000000 --- a/internal/cli/schema_hints/metadata/todo.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/todo", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": { - "todo.get_user_todos_in_current_org": { - "reviewed": true, - "cli_path": "todo task list", - "review_reason": "The reviewed handler defaults omitted role-types to executor, preserves current-organization behavior by default, and switches both single-page and auto-page calls to get_user_todos only when --query-all is explicitly true." - }, - "todo.reset_todo_reminder": { - "reviewed": true, - "cli_path": "todo task reset-reminder", - "review_reason": "The reviewed CLI rejects malformed or structurally invalid non-empty reminder rules before the reset mutation, while preserving omission and [] as explicit clear forms." - }, - "todo.create_todo_tag": { - "reviewed": true, - "cli_path": "todo tag create", - "review_reason": "The reviewed handler requires a non-blank tag name, builds a one-element userTags request, and invokes create_todo_tag without a runtime confirmation gate." - }, - "todo.delete_todo_tag": { - "reviewed": true, - "cli_path": "todo tag delete", - "review_reason": "The reviewed handler requires at least one non-empty tag code, permits caller-authoritative dry-run, and requires explicit --yes before invoking delete_todo_tag." - }, - "todo.tag_todo": { - "reviewed": true, - "cli_path": "todo tag add", - "review_reason": "The reviewed handler requires a task ID and at least one non-empty tag code before invoking tag_todo." - }, - "todo.update_todo_tag": { - "reviewed": true, - "cli_path": "todo tag update", - "review_reason": "The reviewed handler requires a non-null JSON array of tag update records and invokes update_todo_tag without a runtime confirmation gate." - } - } -} \ No newline at end of file diff --git a/internal/cli/schema_hints/metadata/wiki.json b/internal/cli/schema_hints/metadata/wiki.json deleted file mode 100644 index 6e360ffe..00000000 --- a/internal/cli/schema_hints/metadata/wiki.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": 1, - "source": { - "kind": "explicit", - "name": "dws-tool-metadata/wiki", - "repository": "DingTalk-Real-AI/dingtalk-workspace-cli", - "channel": "open-source", - "reviewed": true - }, - "tools": {} -} diff --git a/internal/cli/schema_hints_aitable.go b/internal/cli/schema_hints_aitable.go deleted file mode 100644 index 84acf85d..00000000 --- a/internal/cli/schema_hints_aitable.go +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2026 Alibaba Group -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package cli - -func init() { - RegisterSchemaHints("aitable", map[string]ToolSchemaHint{ - "attachment_upload": { - Parameters: map[string]ParameterSchemaHint{ - "size": {Required: boolPtr(true)}, - }, - }, - "chart_update": { - Parameters: map[string]ParameterSchemaHint{ - "config": {Required: boolPtr(true)}, - }, - }, - "dashboard_create": { - Parameters: map[string]ParameterSchemaHint{ - "name": {Required: boolPtr(true)}, - }, - }, - "dashboard_update": { - Parameters: map[string]ParameterSchemaHint{ - "name": {Required: boolPtr(true)}, - }, - }, - "field_create": { - Parameters: map[string]ParameterSchemaHint{ - "fields": {Required: boolPtr(true)}, - }, - }, - "field_update": { - Parameters: map[string]ParameterSchemaHint{ - "name": {Required: boolPtr(true)}, - }, - }, - "query_records": { - Description: "查询 AI 表格记录。默认返回单页;传 --all 时自动翻页累计全部记录。", - Parameters: map[string]ParameterSchemaHint{ - "baseId": { - FlagName: "base-id", - Description: "Base ID。", - }, - "tableId": { - FlagName: "table-id", - Description: "Table ID。", - }, - "fieldIds": { - FlagName: "field-ids", - Type: "array", - Description: "Field ID 列表,CLI 使用逗号分隔。", - }, - "recordIds": { - FlagName: "record-ids", - Type: "array", - Description: "Record ID 列表,CLI 使用逗号分隔。", - }, - "filters": { - Type: "object", - Description: "过滤条件 JSON。", - }, - "sort": { - Type: "array", - Description: "排序 JSON 数组。", - }, - }, - }, - "record_upsert": { - Parameters: map[string]ParameterSchemaHint{ - "records": {Required: boolPtr(true)}, - }, - }, - "view_update_aggregate": { - Parameters: map[string]ParameterSchemaHint{ - "json": {Required: boolPtr(true)}, - }, - }, - "view_update_card": { - Parameters: map[string]ParameterSchemaHint{ - "json": {Required: boolPtr(true)}, - }, - }, - "view_update_field_widths": { - Parameters: map[string]ParameterSchemaHint{ - "json": {Required: boolPtr(true)}, - }, - }, - "view_update_timebar": { - Parameters: map[string]ParameterSchemaHint{ - "json": {Required: boolPtr(true)}, - }, - }, - "view_update_visible_fields": { - Parameters: map[string]ParameterSchemaHint{ - "field-ids": {Required: boolPtr(true)}, - }, - }, - }) -} diff --git a/internal/cli/schema_hints_attendance.go b/internal/cli/schema_hints_attendance.go deleted file mode 100644 index 79cb01bb..00000000 --- a/internal/cli/schema_hints_attendance.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2026 Alibaba Group -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package cli - -func init() { - RegisterSchemaHints("attendance", map[string]ToolSchemaHint{ - "get_user_attendance_record": { - Parameters: map[string]ParameterSchemaHint{ - "user": {Required: boolPtr(true)}, - "date": {Required: boolPtr(true)}, - "users": {Type: "array", Required: boolPtr(true)}, - "start": {Required: boolPtr(true)}, - "end": {Required: boolPtr(true)}, - }, - }, - "batch_get_employee_shifts": { - Parameters: map[string]ParameterSchemaHint{ - "users": {Type: "array", Required: boolPtr(true)}, - "start": {Required: boolPtr(true)}, - "end": {Required: boolPtr(true)}, - }, - }, - "get_attendance_summary": { - Parameters: map[string]ParameterSchemaHint{ - "user": {Required: boolPtr(true)}, - "date": {Required: boolPtr(true)}, - "stats-type": {Required: boolPtr(true)}, - }, - }, - "query_attendance_group_or_rules": { - Parameters: map[string]ParameterSchemaHint{ - "date": {Required: boolPtr(true)}, - }, - }, - "boss_check": { - Parameters: map[string]ParameterSchemaHint{ - "plan-id": {Required: boolPtr(true)}, - }, - }, - "save_self_setting": { - Parameters: map[string]ParameterSchemaHint{ - "check-result-msg": {Required: boolPtr(true)}, - }, - }, - "update_group_member": { - Parameters: map[string]ParameterSchemaHint{ - "add-users": {Required: boolPtr(true)}, - }, - }, - "update_group_setting": { - Parameters: map[string]ParameterSchemaHint{ - "name": {Required: boolPtr(true)}, - }, - }, - }) -} diff --git a/internal/cli/schema_hints_ding.go b/internal/cli/schema_hints_ding.go deleted file mode 100644 index 018ea562..00000000 --- a/internal/cli/schema_hints_ding.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2026 Alibaba Group -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package cli - -func init() { - RegisterSchemaHints("ding", map[string]ToolSchemaHint{ - "send_ding_message": { - Description: "发送 DING 消息给指定用户,支持配置机器人编码、接收人、提醒类型和消息内容。", - Parameters: map[string]ParameterSchemaHint{ - "content": { - Description: "DING 消息内容。", - Required: boolPtr(true), - }, - "robotCode": { - FlagName: "robot-code", - Description: "DING 机器人编码。通常来自开放平台或应用机器人配置。", - Required: boolPtr(true), - }, - "receiverUserIdList": { - FlagName: "users", - Type: "array", - Description: "接收人的 userId 列表。CLI 使用逗号分隔,例如 user1,user2。", - Required: boolPtr(true), - }, - "remindType": { - FlagName: "type", - Description: "提醒类型。CLI 默认使用 app,对应应用内提醒。", - }, - }, - }, - }) -} diff --git a/internal/cli/schema_hints_helper_roots.go b/internal/cli/schema_hints_helper_roots.go deleted file mode 100644 index eb323826..00000000 --- a/internal/cli/schema_hints_helper_roots.go +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2026 Alibaba Group -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package cli - -func init() { - RegisterSchemaHints("pat", map[string]ToolSchemaHint{ - "batch_grant": { - Parameters: map[string]ParameterSchemaHint{ - "sessionId": { - Required: boolPtr(false), - RequiredWhen: "grant-type is session", - }, - }, - }, - }) - - RegisterSchemaHints("doc", map[string]ToolSchemaHint{ - "create_document": { - Parameters: map[string]ParameterSchemaHint{ - "name": {Required: boolPtr(true)}, - }, - }, - "get_document_content": { - Parameters: map[string]ParameterSchemaHint{ - "node": {Required: boolPtr(true)}, - }, - }, - "update_document": { - Parameters: map[string]ParameterSchemaHint{ - "node": {Required: boolPtr(true)}, - }, - }, - "delete_document": { - Parameters: map[string]ParameterSchemaHint{ - "node": {Required: boolPtr(true)}, - }, - }, - }) - - RegisterSchemaHints("drive", map[string]ToolSchemaHint{ - "list_files": { - Parameters: map[string]ParameterSchemaHint{ - "limit": {Type: "integer"}, - }, - }, - "list_spaces": { - Parameters: map[string]ParameterSchemaHint{ - "limit": {Type: "integer"}, - }, - }, - }) - - RegisterSchemaHints("sheet", map[string]ToolSchemaHint{ - "create_workspace_sheet": { - Parameters: map[string]ParameterSchemaHint{ - "name": {Required: boolPtr(true)}, - }, - }, - "get_all_sheets": { - Parameters: map[string]ParameterSchemaHint{ - "node": {Required: boolPtr(true)}, - }, - }, - "create_sheet": { - Parameters: map[string]ParameterSchemaHint{ - "node": {Required: boolPtr(true)}, - "name": {Required: boolPtr(true)}, - }, - }, - }) - - RegisterSchemaHints("wiki", map[string]ToolSchemaHint{ - "create_wikiSpace": { - Parameters: map[string]ParameterSchemaHint{ - "name": {Required: boolPtr(true)}, - }, - }, - "get_wikiSpace": { - Parameters: map[string]ParameterSchemaHint{ - "space": {Required: boolPtr(true)}, - }, - }, - }) -} diff --git a/internal/cli/schema_hints_runtime.go b/internal/cli/schema_hints_runtime.go deleted file mode 100644 index f18981df..00000000 --- a/internal/cli/schema_hints_runtime.go +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2026 Alibaba Group -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package cli - -func init() { - RegisterSchemaHints("calendar", map[string]ToolSchemaHint{ - "create_calendar_event": { - Parameters: calendarRecurrenceSchemaParameters(true), - }, - "query_busy_status": { - Parameters: map[string]ParameterSchemaHint{ - "users": {Required: boolPtr(true)}, - }, - }, - "update_calendar_event": { - Parameters: calendarRecurrenceSchemaParameters(false), - }, - }) - - RegisterSchemaHints("minutes", map[string]ToolSchemaHint{ - "get_minutes_ai_summary": { - Parameters: map[string]ParameterSchemaHint{ - "taskUuid": {Required: boolPtr(true)}, - }, - }, - }) - - RegisterSchemaHints("group-chat", map[string]ToolSchemaHint{ - "search_messages_by_sender": { - Parameters: map[string]ParameterSchemaHint{ - "sender-user-id": {Required: boolPtr(true)}, - }, - }, - }) - - RegisterSchemaHints("dev", map[string]ToolSchemaHint{ - "get_extension_webapp_config": { - Parameters: map[string]ParameterSchemaHint{ - "unifiedAppId": {Required: boolPtr(true)}, - }, - }, - "set_extension_robot_config": { - Parameters: map[string]ParameterSchemaHint{ - "name": {Required: boolPtr(true)}, - }, - }, - "set_extension_webapp_config": { - Parameters: map[string]ParameterSchemaHint{ - "homepageUrl": {Required: boolPtr(true)}, - }, - }, - "update_dev_app": { - Parameters: map[string]ParameterSchemaHint{ - "name": {Required: boolPtr(true)}, - }, - }, - "update_dev_app_security_config": { - Parameters: map[string]ParameterSchemaHint{ - "redirectUrls": {Required: boolPtr(true)}, - }, - }, - }) -} - -func calendarRecurrenceSchemaParameters(includeCreateRequired bool) map[string]ParameterSchemaHint { - parameters := map[string]ParameterSchemaHint{ - "recurrence.pattern.dayOfMonth": { - Required: boolPtr(false), - RequiredWhen: "recurrence-type is absoluteMonthly or absoluteYearly", - }, - "recurrence.pattern.daysOfWeek": { - Required: boolPtr(false), - RequiredWhen: "recurrence-type is weekly or relativeMonthly", - }, - "recurrence.pattern.index": { - Required: boolPtr(false), - RequiredWhen: "recurrence-type is relativeMonthly", - }, - "recurrence.pattern.interval": { - Required: boolPtr(false), - RequiredWhen: "any recurrence-* flag is provided", - }, - "recurrence.pattern.type": { - Required: boolPtr(false), - RequiredWhen: "any recurrence-* flag is provided", - }, - "recurrence.range.endDate": { - Required: boolPtr(false), - RequiredWhen: "recurrence-range-type is endDate", - }, - "recurrence.range.numberOfOccurrences": { - Required: boolPtr(false), - RequiredWhen: "recurrence-range-type is numbered", - }, - "recurrence.range.type": { - Required: boolPtr(false), - RequiredWhen: "any recurrence-* flag is provided", - }, - } - if includeCreateRequired { - parameters["summary"] = ParameterSchemaHint{Required: boolPtr(true)} - parameters["startDateTime"] = ParameterSchemaHint{Required: boolPtr(true)} - parameters["endDateTime"] = ParameterSchemaHint{Required: boolPtr(true)} - } - return parameters -} diff --git a/internal/cli/schema_manual_hints.go b/internal/cli/schema_manual_hints.go index 22c9fa9a..c95d44e0 100644 --- a/internal/cli/schema_manual_hints.go +++ b/internal/cli/schema_manual_hints.go @@ -37,16 +37,10 @@ const ( runtimeSchemaManualReasonAnnotation = "dws.schema.manual.reason" ) -//go:embed schema_hints/metadata/*.json -var embeddedMetadataFS embed.FS - //go:embed schema_hints/selection/*.json var embeddedSelectionFS embed.FS -const ( - embeddedMetadataGlob = "schema_hints/metadata/*.json" - embeddedSelectionGlob = "schema_hints/selection/*.json" -) +const embeddedSelectionGlob = "schema_hints/selection/*.json" // ManualSchemaHintSnapshot is the human-owned bridge from an existing // public Cobra leaf to Schema. It cannot create commands, flags, exclusions, or @@ -218,9 +212,12 @@ var ( applyManualParameter = annotateManualSchemaParameter ) -// ApplyEmbeddedManualSchemaHints applies the committed human review -// file to an already-built Cobra tree. The operation is deterministic and -// idempotent. +// ApplyEmbeddedManualSchemaHints loads committed hint dirs and applies any +// residual metadata parameter overlays to an already-built Cobra tree. +// Selection prose is loaded (and validated) as part of the same snapshot for +// generators/tests; this function only annotates Commands. Metadata overlays +// are optional: empty tools shells produce an empty Commands list. The +// operation is deterministic and idempotent. func ApplyEmbeddedManualSchemaHints(root *cobra.Command) (ManualSchemaHintReport, error) { snapshot, err := loadManualSchemaHints() if err != nil { @@ -231,8 +228,11 @@ func ApplyEmbeddedManualSchemaHints(root *cobra.Command) (ManualSchemaHintReport func embeddedManualSchemaHints() (ManualSchemaHintSnapshot, error) { manualSchemaHintsOnce.Do(func() { + // Selection FS/glob are required. Metadata overlays are retired: + // pass nil/empty so loadManualSchemaHintsFromHintDirs yields no + // parameter Commands (schema_hints/metadata/ may be absent). manualSchemaHintsSnapshot, manualSchemaHintsErr = loadManualSchemaHintsFromHintDirs( - embeddedMetadataFS, embeddedMetadataGlob, + nil, "", embeddedSelectionFS, embeddedSelectionGlob, ) }) diff --git a/internal/cli/schema_parameter_mapping_completeness_test.go b/internal/cli/schema_parameter_mapping_completeness_test.go index c61cea38..81020721 100644 --- a/internal/cli/schema_parameter_mapping_completeness_test.go +++ b/internal/cli/schema_parameter_mapping_completeness_test.go @@ -103,14 +103,13 @@ func TestEmbeddedCatalogLocalInterfacesAreExactAndReviewed(t *testing.T) { for _, field := range []string{"interface_mode", "availability", "interface_ref", "interface_reason"} { entry := provenance[field] prec := schemaString(entry["precedence"]) - if prec != "reviewed_explicit" && prec != "contract_final" { - t.Errorf("%s local %s precedence = %q, want reviewed_explicit or contract_final", canonical, field, prec) + // Production leaf interface facts come from ContractFinal + // (DeclareLeafMetadata / Schema). metadata/*.json shells keep + // tools:{} and must not win reviewed_explicit for these fields. + if prec != "contract_final" { + t.Errorf("%s local %s precedence = %q, want contract_final", canonical, field, prec) } - source := schemaString(entry["source"]) - if prec == "reviewed_explicit" && !strings.Contains(source, "internal/cli/schema_hints/metadata/") { - t.Errorf("%s local %s source = %q, want metadata/", canonical, field, source) - } - if prec == "contract_final" && source != "corecmd.contract" { + if source := schemaString(entry["source"]); source != "corecmd.contract" { t.Errorf("%s local %s source = %q, want corecmd.contract", canonical, field, source) } } @@ -212,10 +211,10 @@ func TestSchemaParameterMappingAuditExclusionRules(t *testing.T) { tools["sample.read"]["interface_ref"] = nil tools["sample.read"]["interface_reason"] = "Reviewed composite fixture" tools["sample.read"]["field_provenance"] = map[string]any{ - "interface_mode": map[string]any{"precedence": "reviewed_explicit"}, - "availability": map[string]any{"precedence": "reviewed_explicit"}, - "interface_ref": map[string]any{"precedence": "reviewed_explicit"}, - "interface_reason": map[string]any{"precedence": "reviewed_explicit"}, + "interface_mode": map[string]any{"precedence": "contract_final"}, + "availability": map[string]any{"precedence": "contract_final"}, + "interface_ref": map[string]any{"precedence": "contract_final"}, + "interface_reason": map[string]any{"precedence": "contract_final"}, } } return tools @@ -626,13 +625,12 @@ func auditCompositeSchemaDisposition(canonical string, tool map[string]any) []st provenance := schemaMap(tool["field_provenance"]) for _, field := range []string{"interface_mode", "availability", "interface_ref", "interface_reason"} { entry := provenance[field] - // A composite disposition must be backed by an explicit authoritative - // source: legacy reviewed hints ("reviewed_explicit") or a Contract - // SchemaDecl pass-through ("contract_final"); declaration is the - // stronger backing per the declare-or-annotate rule. + // Composite dispositions must pass through ContractFinal + // (declare-or-annotate). Production metadata shells are empty and + // must not supply reviewed_explicit for these fields. precedence := strings.TrimSpace(schemaString(entry["precedence"])) - if precedence != "reviewed_explicit" && precedence != "contract_final" { - problems = append(problems, fmt.Sprintf("%s composite %s is not backed by reviewed_explicit/contract_final provenance", canonical, field)) + if precedence != "contract_final" { + problems = append(problems, fmt.Sprintf("%s composite %s is not backed by contract_final provenance", canonical, field)) } } return problems diff --git a/internal/cli/schema_parameter_precedence_test.go b/internal/cli/schema_parameter_precedence_test.go index 1f20d33d..012f2405 100644 --- a/internal/cli/schema_parameter_precedence_test.go +++ b/internal/cli/schema_parameter_precedence_test.go @@ -811,6 +811,8 @@ func TestRuntimeSchemaParameterPrecedenceNativeAndCobraBeatHints(t *testing.T) { } func TestRuntimeSchemaParameterPrecedenceToolHintBeatsMCPWithoutChangingFlagIdentity(t *testing.T) { + // Fixture-only ParameterSchemaHint injection: production RegisterSchemaHints + // stays empty after ParamDecl migration. _, leaf := manualSchemaHintTestTree() parameters, err := runtimeCommandParameters(leaf, "sample.search_items", map[string]ParameterSchemaHint{ "query": { diff --git a/internal/cli/schema_small_coverage_test.go b/internal/cli/schema_small_coverage_test.go index a68c0305..4f13d883 100644 --- a/internal/cli/schema_small_coverage_test.go +++ b/internal/cli/schema_small_coverage_test.go @@ -245,6 +245,10 @@ func TestCrossPlatformCoverageHintDirectoryLoaderRemainingEdges(t *testing.T) { if _, err := loadParameterCommandsFromMetadata(fstest.MapFS{}, "["); err == nil { t.Fatal("invalid metadata glob succeeded") } + emptyCommands, err := loadParameterCommandsFromMetadata(fstest.MapFS{}, "*.json") + if err != nil || len(emptyCommands) != 0 { + t.Fatalf("empty metadata directory = %#v, %v", emptyCommands, err) + } if _, err := loadParameterCommandsFromMetadata(directoryJSON, "*.json"); err == nil { t.Fatal("metadata directory read succeeded") } @@ -290,6 +294,31 @@ func TestCrossPlatformCoverageHintDirectoryLoaderRemainingEdges(t *testing.T) { if _, err := loadManualSchemaHintsFromHintDirs(validMetadata, "*.json", invalidSelection, "*.json"); err == nil { t.Fatal("wrapper selection validation failure succeeded") } + + // Optional metadata: nil FS or empty glob must still load selection. + for _, tc := range []struct { + name string + fs fs.FS + glob string + }{ + {name: "nil FS", fs: nil, glob: "*.json"}, + {name: "empty glob", fs: validMetadata, glob: ""}, + {name: "empty match", fs: fstest.MapFS{}, glob: "*.json"}, + } { + snap, err := loadManualSchemaHintsFromHintDirs(tc.fs, tc.glob, validSelection, "*.json") + if err != nil { + t.Fatalf("optional metadata %s: %v", tc.name, err) + } + if len(snap.Commands) != 0 { + t.Fatalf("optional metadata %s: unexpected commands %#v", tc.name, snap.Commands) + } + if _, ok := snap.AgentHints.Tools["sample.get"]; !ok { + t.Fatalf("optional metadata %s: selection tools missing", tc.name) + } + } + if commands, err := loadParameterCommandsFromMetadata(nil, "*.json"); err != nil || len(commands) != 0 { + t.Fatalf("nil metadata FS = %#v, %v", commands, err) + } } func TestCrossPlatformCoverageInterfaceRegistryRemainingEdges(t *testing.T) { diff --git a/internal/cli/schema_text_precedence_test.go b/internal/cli/schema_text_precedence_test.go index b97fc964..4ae83083 100644 --- a/internal/cli/schema_text_precedence_test.go +++ b/internal/cli/schema_text_precedence_test.go @@ -3,7 +3,10 @@ package cli -import "testing" +import ( + "sort" + "testing" +) func TestRuntimeToolTextPrefersCobraHelpOverGenericMCPMetadata(t *testing.T) { entry := runtimeSchemaEntry{ @@ -37,7 +40,31 @@ func TestRuntimeToolTextPrefersCobraHelpOverGenericMCPMetadata(t *testing.T) { } } +func TestProductionRegisterSchemaHintsHasNoSubstantiveOverlays(t *testing.T) { + // Framework expectation after ParamDecl / ContractFinal migration: production + // RegisterSchemaHints must not publish tool_schema_hint overlays. Temporary + // registry injection is allowed only inside unit-test fixtures. + if got := len(defaultSchemaHintRegistry.tools); got != 0 { + paths := make([]string, 0, got) + for path := range defaultSchemaHintRegistry.tools { + paths = append(paths, path) + } + sort.Strings(paths) + t.Fatalf("production schema hint registry has %d tool overlay(s), want 0; paths=%v", got, paths) + } +} + func TestRuntimeToolTextKeepsReviewedHintAboveCobraHelp(t *testing.T) { + // Production RegisterSchemaHints maps are empty; inject a temporary + // reviewed tool_schema_hint so this precedence unit test stays self-contained. + originalHints := defaultSchemaHintRegistry + t.Cleanup(func() { defaultSchemaHintRegistry = originalHints }) + defaultSchemaHintRegistry = newSchemaHintRegistry() + const wantDescription = "查询 AI 表格记录。默认返回单页;传 --all 时自动翻页累计全部记录。" + RegisterSchemaHints("aitable", map[string]ToolSchemaHint{ + "query_records": {Description: wantDescription}, + }) + entry := runtimeSchemaEntry{ ProductID: "aitable", ToolName: "query_records", @@ -59,7 +86,6 @@ func TestRuntimeToolTextKeepsReviewedHintAboveCobraHelp(t *testing.T) { if title != entry.Title { t.Fatalf("title = %q, want Cobra Help title %q", title, entry.Title) } - wantDescription := schemaHintForCanonicalPath("aitable.query_records").Description if description != wantDescription { t.Fatalf("description = %q, want reviewed hint %q", description, wantDescription) } diff --git a/internal/generator/agentmetadata/hints.go b/internal/generator/agentmetadata/hints.go index a2414228..3025aec3 100644 --- a/internal/generator/agentmetadata/hints.go +++ b/internal/generator/agentmetadata/hints.go @@ -36,16 +36,17 @@ type HintFile struct { ReferenceReview map[string]ReferenceReview `json:"reference_review,omitempty"` } -// HintIndex is the human-authored entrypoint. It maps product IDs to metadata -// (safety/interface/parameters/runtime_gate) and selection (Agent routing prose) -// HintFile paths. Index-level runtime_gates were removed; gates live on each -// metadata tool as runtime_gate. +// HintIndex is the human-authored entrypoint. It maps product IDs to optional +// metadata HintFile paths (legacy safety/interface/parameters/runtime_gate +// overlays; may be omitted once leaf facts live on Contract) and required +// selection (Agent routing prose) HintFile paths. Index-level runtime_gates +// were removed; residual gates live on each metadata tool as runtime_gate. type HintIndex struct { Version int `json:"version"` Format string `json:"format"` Source HintSource `json:"source"` Coverage HintCoverage `json:"coverage,omitempty"` - Metadata map[string]string `json:"metadata"` + Metadata map[string]string `json:"metadata,omitempty"` Selection map[string]string `json:"selection"` ReferenceReview map[string]ReferenceReview `json:"reference_review,omitempty"` } @@ -221,14 +222,16 @@ func parseHintSources(out *File, files []sourceFile, opts Options, stats *Stats, } return nil } - if len(index.Metadata) == 0 { - return false, fmt.Errorf("decode Agent hint index %s: metadata map is required", indexFile.display) - } + // Metadata is optional: Contract/Safety owns leaf safety and params. + // An omitted or empty map is a valid migration end-state for phase 5 + // (directory deletion). Selection remains required. if len(index.Selection) == 0 { return false, fmt.Errorf("decode Agent hint index %s: selection map is required", indexFile.display) } - if err := appendMapped("metadata", index.Metadata, hintRoleMetadata); err != nil { - return false, err + if len(index.Metadata) > 0 { + if err := appendMapped("metadata", index.Metadata, hintRoleMetadata); err != nil { + return false, err + } } if err := appendMapped("selection", index.Selection, hintRoleSelection); err != nil { return false, err diff --git a/internal/generator/agentmetadata/hints_coverage_test.go b/internal/generator/agentmetadata/hints_coverage_test.go index 7031301f..5ea055de 100644 --- a/internal/generator/agentmetadata/hints_coverage_test.go +++ b/internal/generator/agentmetadata/hints_coverage_test.go @@ -51,7 +51,6 @@ func TestCrossPlatformCoverageHintUnmarshalAndIndexValidationEdges(t *testing.T) {"version", `{"version":2}`, nil, "unsupported version"}, {"format", `{"version":1,"format":"other"}`, nil, "unsupported format"}, {"source kind", `{"version":1,"format":"dws-agent-hint-index","source":{"kind":"imported"}}`, nil, "unsupported source kind"}, - {"metadata required", `{"version":1,"format":"dws-agent-hint-index","selection":{"sample":"selection.json"}}`, nil, "metadata map is required"}, {"selection required", `{"version":1,"format":"dws-agent-hint-index","metadata":{"sample":"metadata.json"}}`, nil, "selection map is required"}, {"empty metadata path", validCoverageIndex("", "selection.json"), map[string]string{"selection.json": validHint}, "missing path"}, {"escaping metadata path", validCoverageIndex("../outside.json", "selection.json"), map[string]string{"selection.json": validHint}, "escapes hints root"}, @@ -70,6 +69,32 @@ func TestCrossPlatformCoverageHintUnmarshalAndIndexValidationEdges(t *testing.T) }) } + // Metadata map may be omitted or empty; selection alone is enough. + for _, tc := range []struct { + name string + index string + }{ + {"metadata omitted", `{"version":1,"format":"dws-agent-hint-index","source":{"kind":"explicit"},"selection":{"sample":"selection.json"}}`}, + {"metadata empty", `{"version":1,"format":"dws-agent-hint-index","source":{"kind":"explicit"},"metadata":{},"selection":{"sample":"selection.json"}}`}, + } { + t.Run(tc.name, func(t *testing.T) { + if used, err := parseCoverageHints(root, map[string]string{"index.json": tc.index, "selection.json": validHint}); err != nil || !used { + t.Fatalf("optional metadata = %v, %v", used, err) + } + }) + } + + // Empty-shell metadata files (tools: {}) remain valid when still mapped. + emptyShell := `{"version":1,"source":{"kind":"explicit"},"tools":{}}` + indexWithShell := validCoverageIndex("metadata.json", "selection.json") + if used, err := parseCoverageHints(root, map[string]string{ + "index.json": indexWithShell, + "metadata.json": emptyShell, + "selection.json": validHint, + }); err != nil || !used { + t.Fatalf("empty-shell metadata = %v, %v", used, err) + } + indexWithProjection := `{"version":1,"format":"dws-agent-hint-index","source":{"kind":"explicit"},"coverage":{"source_tools":1},"metadata":{"sample":"metadata.json"},"selection":{"sample":"selection.json"},"reference_review":{"old path":{"status":"stale","reason":"removed"}}}` if used, err := parseCoverageHints(root, map[string]string{"index.json": indexWithProjection, "metadata.json": validHint, "selection.json": validHint}); err != nil || !used { t.Fatalf("index projection = %v, %v", used, err) diff --git a/internal/generator/agentmetadata/metadata.go b/internal/generator/agentmetadata/metadata.go index ac329bc5..b0181f60 100644 --- a/internal/generator/agentmetadata/metadata.go +++ b/internal/generator/agentmetadata/metadata.go @@ -382,7 +382,8 @@ func Generate(opts Options) (File, Stats, error) { // generateFromSources retains the lower-precedence evidence parsers as a // package-internal seam for focused tests. Production callers must use Generate, -// which requires the reviewed selection + metadata hint sources under HintsDir. +// which requires the reviewed selection hint sources under HintsDir +// (metadata map/files are optional; empty metadata is a valid end-state). func generateFromSources(opts Options) (File, Stats, error) { if opts.Root == "" { opts.Root = "." diff --git a/internal/generator/cmd_schema_agent_metadata/coverage_more_test.go b/internal/generator/cmd_schema_agent_metadata/coverage_more_test.go index 2f7821f0..fd6d56a1 100644 --- a/internal/generator/cmd_schema_agent_metadata/coverage_more_test.go +++ b/internal/generator/cmd_schema_agent_metadata/coverage_more_test.go @@ -277,15 +277,14 @@ func TestCrossPlatformCoverageMetadataRegistryAndSelectionFailureEdges(t *testin } root := t.TempDir() + registry := commandRegistryProjection{CanonicalToolPaths: map[string]string{"sample.run": "sample run"}} + if err := validateSelectionHintInput(root, "hints", registry); err == nil || !strings.Contains(err.Error(), "required Agent hint directory missing") { + t.Fatalf("missing selection/ error = %v", err) + } selection := filepath.Join(root, "hints", "selection") - metadata := filepath.Join(root, "hints", "metadata") if err := os.MkdirAll(selection, 0o755); err != nil { t.Fatal(err) } - if err := os.MkdirAll(metadata, 0o755); err != nil { - t.Fatal(err) - } - registry := commandRegistryProjection{CanonicalToolPaths: map[string]string{"sample.run": "sample run"}} loadSelectionMetadataHints = func(fs.FS) (cli.ManualAgentHintSet, error) { return cli.ManualAgentHintSet{}, errors.New("load") } @@ -329,10 +328,8 @@ func TestCrossPlatformCoverageSelectionHintInputExemptsDeclaredTools(t *testing. }) root := t.TempDir() - for _, dir := range []string{"selection", "metadata"} { - if err := os.MkdirAll(filepath.Join(root, "hints", dir), 0o755); err != nil { - t.Fatal(err) - } + if err := os.MkdirAll(filepath.Join(root, "hints", "selection"), 0o755); err != nil { + t.Fatal(err) } declared := &cobra.Command{Use: "run"} diff --git a/internal/generator/cmd_schema_agent_metadata/main.go b/internal/generator/cmd_schema_agent_metadata/main.go index 34c9e3d7..aefb4a6d 100644 --- a/internal/generator/cmd_schema_agent_metadata/main.go +++ b/internal/generator/cmd_schema_agent_metadata/main.go @@ -75,7 +75,7 @@ func main() { flag.StringVar(&skillPath, "skill", "skills/mono/SKILL.md", "Main DWS SKILL.md path") flag.StringVar(&productsDir, "products", "skills/mono/references/products", "Product skill reference directory") flag.StringVar(&intentGuidePath, "intent-guide", "skills/mono/references/intent-guide.md", "Cross-product intent guide path") - flag.StringVar(&hintsDir, "hints", "internal/cli/schema_hints", "Versioned Agent hint JSON directory (metadata/ + selection/)") + flag.StringVar(&hintsDir, "hints", "internal/cli/schema_hints", "Versioned Agent hint JSON directory (required selection/; optional metadata/ shells)") flag.StringVar(&interfaceMetadataPath, "interface-metadata", "internal/cli/schema_mcp_metadata.json", "Sanitized versioned MCP metadata used only for fallback Agent summaries") flag.StringVar(&outputPath, "output", "", "Output embedded Agent metadata JSON file (legacy single-file mode)") flag.StringVar(&outputDir, "output-dir", "", "Output directory for split embedded Agent metadata JSON") @@ -441,11 +441,10 @@ func mergeRegistryShards(dir string) ([]byte, error) { func validateSelectionHintInput(rootPath, hintsDir string, registry commandRegistryProjection) error { hintsRoot := resolveRootPath(rootPath, hintsDir) selectionRoot := filepath.Join(hintsRoot, "selection") - metadataRoot := filepath.Join(hintsRoot, "metadata") - for _, dir := range []string{selectionRoot, metadataRoot} { - if info, err := os.Stat(dir); err != nil || !info.IsDir() { - return fmt.Errorf("required Agent hint directory missing: %s", dir) - } + // selection/ is required. metadata/ is optional: empty tools shells or a + // missing directory are valid once leaf facts live on Contract (phase 5). + if info, err := os.Stat(selectionRoot); err != nil || !info.IsDir() { + return fmt.Errorf("required Agent hint directory missing: %s", selectionRoot) } selectionFS := os.DirFS(selectionRoot) agentHints, err := loadSelectionMetadataHints(selectionFS) diff --git a/internal/generator/cmd_schema_agent_metadata/main_test.go b/internal/generator/cmd_schema_agent_metadata/main_test.go index 4b16cf62..cb9772ba 100644 --- a/internal/generator/cmd_schema_agent_metadata/main_test.go +++ b/internal/generator/cmd_schema_agent_metadata/main_test.go @@ -16,6 +16,7 @@ package main import ( "encoding/json" "flag" + "io/fs" "os" "path/filepath" "strings" @@ -239,6 +240,35 @@ func TestValidateSelectionHintInputRequiresHintDirs(t *testing.T) { } } +func TestValidateSelectionHintInputAllowsMissingMetadataDir(t *testing.T) { + originalLoadHints := loadSelectionMetadataHints + originalValidateSet := validateSelectionMetadataSet + originalExamples := validateSelectionExamples + originalContract := validateSelectionContract + t.Cleanup(func() { + loadSelectionMetadataHints = originalLoadHints + validateSelectionMetadataSet = originalValidateSet + validateSelectionExamples = originalExamples + validateSelectionContract = originalContract + }) + + root := t.TempDir() + if err := os.MkdirAll(filepath.Join(root, "hints", "selection"), 0o755); err != nil { + t.Fatal(err) + } + loadSelectionMetadataHints = func(fs.FS) (cli.ManualAgentHintSet, error) { + return cli.ManualAgentHintSet{}, nil + } + validateSelectionMetadataSet = func(cli.ManualAgentHintSet, map[string]bool, map[string]bool) error { return nil } + validateSelectionExamples = func(cli.BoundCommandRegistry, cli.ManualAgentHintSet) error { return nil } + validateSelectionContract = func(cli.BoundCommandRegistry, cli.ManualAgentHintSet) (cli.ManualAgentSelectionReport, error) { + return cli.ManualAgentSelectionReport{}, nil + } + if err := validateSelectionHintInput(root, "hints", commandRegistryProjection{}); err != nil { + t.Fatalf("missing metadata/ must be optional: %v", err) + } +} + func TestValidateAgentMetadataOutputAllowlist(t *testing.T) { root := t.TempDir() canonicalDir := filepath.Join(root, "internal/cli/schema_agent_metadata") diff --git a/internal/helpers/aitable.go b/internal/helpers/aitable.go index c5fdd932..01aa3f44 100644 --- a/internal/helpers/aitable.go +++ b/internal/helpers/aitable.go @@ -1642,6 +1642,11 @@ config 结构参考: AvoidWhen: []string{"改字段名/配置用 field update(不可改类型);删字段用 field delete;调列顺序用 view update"}, Examples: []string{"dws aitable field create --base-id --table-id --name \"状态\" --type singleSelect"}, }, + // fields required was RegisterSchemaHints tool_schema_hint; publish via + // ParamDecl (Agent may still use --name/--type as a single-field path). + Parameters: []corecmd.ParamDecl{ + {Name: "fields", Required: boolPtr(true), InterfaceType: "array"}, + }, }, }) @@ -3227,6 +3232,10 @@ colorConfigs (JSON 数组) / officialHoliday (bool)。`, AvoidWhen: []string{"没有独立 field reorder;只读用 get visible-fields;首列字段须保留第一位"}, Examples: []string{"dws aitable view update visible-fields --base-id BASE_ID --table-id TABLE_ID --view-id VIEW_ID --field-ids fld1,fld2,fld3"}, }, + // field-ids required was RegisterSchemaHints tool_schema_hint. + Parameters: []corecmd.ParamDecl{ + {Name: "field-ids", Required: boolPtr(true)}, + }, }, }) @@ -4587,6 +4596,11 @@ valid=false 仍表示 DSL 校验或发布未通过,必须读取 issues 修正 AvoidWhen: []string{"配置模板先看 config-example;删仪表盘用 delete"}, Examples: []string{"dws aitable dashboard create --base-id --name \"运营看板\""}, }, + // name required was RegisterSchemaHints tool_schema_hint (Agent prefers + // --name; runtime still accepts --config alone). + Parameters: []corecmd.ParamDecl{ + {Name: "name", Required: boolPtr(true)}, + }, }, }) @@ -4641,6 +4655,11 @@ valid=false 仍表示 DSL 校验或发布未通过,必须读取 issues 修正 AvoidWhen: []string{"排版布局用 dashboard arrange;删用 delete"}, Examples: []string{"dws aitable dashboard update --base-id --dashboard-id --name \"新看板\""}, }, + // name required was RegisterSchemaHints tool_schema_hint (Agent prefers + // --name; runtime still accepts --config alone). + Parameters: []corecmd.ParamDecl{ + {Name: "name", Required: boolPtr(true)}, + }, }, }) diff --git a/internal/helpers/attendance.go b/internal/helpers/attendance.go index 9509e4af..f092c8a4 100644 --- a/internal/helpers/attendance.go +++ b/internal/helpers/attendance.go @@ -583,6 +583,10 @@ func newAttendanceCommand() *cobra.Command { "dws attendance record get --user USER_ID --date 2026-03-08", }, }, + Parameters: []corecmd.ParamDecl{ + {Name: "user", Required: boolPtr(true)}, + {Name: "date", Required: boolPtr(true)}, + }, }, }) @@ -994,6 +998,11 @@ func newAttendanceCommand() *cobra.Command { }, Examples: []string{"dws attendance shift list --users userId1,userId2 --start 2026-03-03 --end 2026-03-07"}, }, + Parameters: []corecmd.ParamDecl{ + {Name: "users", Required: boolPtr(true), InterfaceType: "array"}, + {Name: "start", Required: boolPtr(true)}, + {Name: "end", Required: boolPtr(true)}, + }, }, }) @@ -2310,6 +2319,11 @@ statsType 统计类型支持:week(周统计)、month(月统计)。`, "dws attendance summary --user USER_ID --date \"2026-03-12 15:00:00\" --stats-type month", }, }, + Parameters: []corecmd.ParamDecl{ + {Name: "user", Required: boolPtr(true)}, + {Name: "date", Required: boolPtr(true)}, + {Name: "stats-type", Required: boolPtr(true)}, + }, }, }) @@ -2365,6 +2379,9 @@ statsType 统计类型支持:week(周统计)、month(月统计)。`, "dws attendance rules --date 2026-03-14", }, }, + Parameters: []corecmd.ParamDecl{ + {Name: "date", Required: boolPtr(true)}, + }, }, }) @@ -4107,6 +4124,9 @@ statsType 统计类型支持:week(周统计)、month(月统计)。`, "dws attendance boss-check --result-id 789012 --result Normal", }, }, + Parameters: []corecmd.ParamDecl{ + {Name: "plan-id", Required: boolPtr(true)}, + }, }, }) diff --git a/internal/helpers/calendar.go b/internal/helpers/calendar.go index 25f9bcb5..6d9b0886 100644 --- a/internal/helpers/calendar.go +++ b/internal/helpers/calendar.go @@ -10,6 +10,7 @@ import ( "time" "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/cli" + "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/corecmd" "github.com/spf13/cobra" ) @@ -468,6 +469,13 @@ func newCalendarCommand() *cobra.Command { "dws calendar event create --title \"周会\" --start \"2026-03-10T14:00:00+08:00\" --end \"2026-03-10T15:00:00+08:00\" --attendees userId1,userId2", }, }, + // Former RegisterSchemaHints pins (create required + recurrence + // required_when) — native_annotation outranks tool_schema_hint. + Parameters: append([]corecmd.ParamDecl{ + {Name: "title", Required: boolPtr(true)}, + {Name: "start", Required: boolPtr(true)}, + {Name: "end", Required: boolPtr(true)}, + }, calendarRecurrenceParamDecls()...), }, }) @@ -548,6 +556,7 @@ func newCalendarCommand() *cobra.Command { "dws calendar event update --id --desc \"新描述\" --timezone Asia/Tokyo", }, }, + Parameters: calendarRecurrenceParamDecls(), }, }) @@ -2504,6 +2513,22 @@ var recurrenceFlagNames = []string{ "recurrence-range-type", "recurrence-end-date", "recurrence-count", } +// calendarRecurrenceParamDecls migrates former RegisterSchemaHints recurrence +// required/required_when pins onto create/update event leaves so Schema +// assembly resolves them as native_annotation (outranking tool_schema_hint). +func calendarRecurrenceParamDecls() []corecmd.ParamDecl { + return []corecmd.ParamDecl{ + {Name: "recurrence-day-of-month", Required: boolPtr(false), RequiredWhen: "recurrence-type is absoluteMonthly or absoluteYearly"}, + {Name: "recurrence-days-of-week", Required: boolPtr(false), RequiredWhen: "recurrence-type is weekly or relativeMonthly"}, + {Name: "recurrence-index", Required: boolPtr(false), RequiredWhen: "recurrence-type is relativeMonthly"}, + {Name: "recurrence-interval", Required: boolPtr(false), RequiredWhen: "any recurrence-* flag is provided"}, + {Name: "recurrence-type", Required: boolPtr(false), RequiredWhen: "any recurrence-* flag is provided"}, + {Name: "recurrence-end-date", Required: boolPtr(false), RequiredWhen: "recurrence-range-type is endDate"}, + {Name: "recurrence-count", Required: boolPtr(false), RequiredWhen: "recurrence-range-type is numbered"}, + {Name: "recurrence-range-type", Required: boolPtr(false), RequiredWhen: "any recurrence-* flag is provided"}, + } +} + // recurrenceIncompleteSuggestion is the canonical reminder appended to any // recurrence validation error. It explains that the CLI flattens a nested // MCP object and that partial updates are NOT supported by the backend. diff --git a/internal/helpers/calendar_recurrence_paramdecl_test.go b/internal/helpers/calendar_recurrence_paramdecl_test.go new file mode 100644 index 00000000..e3eddbde --- /dev/null +++ b/internal/helpers/calendar_recurrence_paramdecl_test.go @@ -0,0 +1,40 @@ +package helpers + +import ( + "testing" + + "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/corecmd" +) + +func TestCalendarRecurrenceParamDeclsCoverHintPins(t *testing.T) { + decls := calendarRecurrenceParamDecls() + byName := map[string]corecmd.ParamDecl{} + for _, d := range decls { + byName[d.Name] = d + } + want := map[string]string{ + "recurrence-day-of-month": "recurrence-type is absoluteMonthly or absoluteYearly", + "recurrence-days-of-week": "recurrence-type is weekly or relativeMonthly", + "recurrence-index": "recurrence-type is relativeMonthly", + "recurrence-interval": "any recurrence-* flag is provided", + "recurrence-type": "any recurrence-* flag is provided", + "recurrence-end-date": "recurrence-range-type is endDate", + "recurrence-count": "recurrence-range-type is numbered", + "recurrence-range-type": "any recurrence-* flag is provided", + } + if len(decls) != len(want) { + t.Fatalf("calendarRecurrenceParamDecls len = %d, want %d: %#v", len(decls), len(want), decls) + } + for name, when := range want { + d, ok := byName[name] + if !ok { + t.Fatalf("missing ParamDecl %q", name) + } + if d.Required == nil || *d.Required { + t.Fatalf("%s Required = %#v, want explicit false", name, d.Required) + } + if d.RequiredWhen != when { + t.Fatalf("%s RequiredWhen = %q, want %q", name, d.RequiredWhen, when) + } + } +} diff --git a/internal/helpers/ding.go b/internal/helpers/ding.go index b9ae7b9e..5a9e539e 100644 --- a/internal/helpers/ding.go +++ b/internal/helpers/ding.go @@ -2,11 +2,13 @@ package helpers import ( "fmt" - "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/cli" "os" "strings" "github.com/spf13/cobra" + + "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/cli" + "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/corecmd" ) // ────────────────────────────────────────────────────────── @@ -91,6 +93,11 @@ func newDingCommand() *cobra.Command { "dws ding message send --robot-code --type call --users userId1 --content \"紧急告警\" --format json", }, }, + Parameters: []corecmd.ParamDecl{ + {Name: "content", Required: boolPtr(true)}, + {Name: "robot-code", Required: boolPtr(true)}, + {Name: "users", Required: boolPtr(true), InterfaceType: "array"}, + }, }, }) diff --git a/internal/helpers/doc.go b/internal/helpers/doc.go index 1f1361e7..196c5c3b 100644 --- a/internal/helpers/doc.go +++ b/internal/helpers/doc.go @@ -1097,6 +1097,7 @@ func newDocCommand() *cobra.Command { }, }, Parameters: []corecmd.ParamDecl{ + {Name: "node", Required: boolPtr(true)}, {Name: "content-format", Property: "format", Required: boolPtr(false)}, {Name: "end-block-id", Required: boolPtr(false)}, {Name: "max-depth", Required: boolPtr(false), InterfaceType: "integer"}, @@ -1219,6 +1220,9 @@ func newDocCommand() *cobra.Command { "dws doc create --name \"Q1 总结\" --content \"# Q1 总结\" --folder --format json", }, }, + Parameters: []corecmd.ParamDecl{ + {Name: "name", Required: boolPtr(true)}, + }, }, }) @@ -1344,6 +1348,9 @@ WARNING: --mode overwrite 为破坏性写入,会清空原文档全部内容。 "dws doc update --node --content-file ./body.md --mode overwrite --dry-run", }, }, + Parameters: []corecmd.ParamDecl{ + {Name: "node", Required: boolPtr(true)}, + }, }, }) @@ -2026,6 +2033,9 @@ WARNING: --mode overwrite 为破坏性写入,会清空原文档全部内容。 }, Examples: []string{"dws doc delete --node --format json"}, }, + Parameters: []corecmd.ParamDecl{ + {Name: "node", Required: boolPtr(true)}, + }, }, }) diff --git a/internal/helpers/minutes.go b/internal/helpers/minutes.go index 88759d6e..91d337d5 100644 --- a/internal/helpers/minutes.go +++ b/internal/helpers/minutes.go @@ -2,9 +2,10 @@ package helpers import ( "fmt" - "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/cli" "strconv" + "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/cli" + "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/corecmd" "github.com/spf13/cobra" ) @@ -188,6 +189,9 @@ func newMinutesCommand() *cobra.Command { "dws minutes get summary --id --format json", }, }, + Parameters: []corecmd.ParamDecl{ + {Name: "id", Required: boolPtr(true)}, + }, }, }) diff --git a/internal/helpers/sheet_workbook.go b/internal/helpers/sheet_workbook.go index 0025addf..f22e6b89 100644 --- a/internal/helpers/sheet_workbook.go +++ b/internal/helpers/sheet_workbook.go @@ -2,8 +2,9 @@ package helpers import ( "fmt" - "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/cli" + "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/cli" + "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/corecmd" "github.com/spf13/cobra" ) @@ -50,6 +51,11 @@ func newWorkbookCmds() []*cobra.Command { "dws sheet create --name \"Q1 数据\" --folder ", }, }, + // name is validated via mustGetFlag; publish required via ParamDecl + // instead of relying on RegisterSchemaHints tool_schema_hint. + Parameters: []corecmd.ParamDecl{ + {Name: "name", Required: boolPtr(true)}, + }, }, }) createCmd.Flags().String("name", "", "表格名称 (必填)") @@ -89,6 +95,11 @@ nodeId 支持传入文档链接 URL 或文档 ID(dentryUuid),系统自动 AvoidWhen: []string{"要看单个工作表行列边界与合并区用 sheet info;读单元格内容用 sheet range read"}, Examples: []string{"dws sheet list --node "}, }, + // node is validated via mustGetFlag; publish required via ParamDecl + // instead of relying on RegisterSchemaHints tool_schema_hint. + Parameters: []corecmd.ParamDecl{ + {Name: "node", Required: boolPtr(true)}, + }, }, }) listCmd.Flags().String("node", "", "表格文档 ID 或 URL (必填)") @@ -180,6 +191,12 @@ sheetId 支持传入工作表 ID 或工作表名称,可通过 sheet list 获 AvoidWhen: []string{"要新建整份表格文档用 sheet create;复制已有工作表用 sheet copy;删除工作表用 sheet delete-sheet"}, Examples: []string{"dws sheet new --node --name \"Sheet2\""}, }, + // node/name validated via mustGetFlag; publish required via ParamDecl + // instead of relying on RegisterSchemaHints tool_schema_hint. + Parameters: []corecmd.ParamDecl{ + {Name: "node", Required: boolPtr(true)}, + {Name: "name", Required: boolPtr(true)}, + }, }, }) newCmd.Flags().String("node", "", "表格文档 ID (必填)") diff --git a/internal/helpers/wiki.go b/internal/helpers/wiki.go index 818e9eeb..15e62f28 100644 --- a/internal/helpers/wiki.go +++ b/internal/helpers/wiki.go @@ -2,11 +2,12 @@ package helpers import ( "fmt" - "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/cli" "os" "strconv" "strings" + "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/cli" + "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/corecmd" "github.com/spf13/cobra" ) @@ -196,6 +197,11 @@ func newWikiCommand() *cobra.Command { "dws wiki space create --name \"技术方案\" --desc \"团队技术方案归档\" --format json", }, }, + // name is validated in RunE; publish required via ParamDecl + // instead of relying on RegisterSchemaHints tool_schema_hint. + Parameters: []corecmd.ParamDecl{ + {Name: "name", Required: boolPtr(true)}, + }, }, }) @@ -235,6 +241,11 @@ func newWikiCommand() *cobra.Command { AvoidWhen: []string{"列知识库用 list;删库用 space delete(需确认)"}, Examples: []string{"dws wiki space get --workspace --format json"}, }, + // workspace is validated in RunE; publish required via ParamDecl + // (former RegisterSchemaHints keyed stale "space"). + Parameters: []corecmd.ParamDecl{ + {Name: "workspace", Required: boolPtr(true)}, + }, }, }) diff --git a/internal/pat/chmod.go b/internal/pat/chmod.go index 92c551f3..03ea3f24 100644 --- a/internal/pat/chmod.go +++ b/internal/pat/chmod.go @@ -29,11 +29,14 @@ import ( authpkg "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/auth" "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/cli" + "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/corecmd" apperrors "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/errors" "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/helpers" "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/pkg/edition" ) +func boolPtr(v bool) *bool { return &v } + type LoginRecommendOptions struct { // ProductCodes limits the recommend plan to service-owned product domains. ProductCodes []string @@ -461,6 +464,15 @@ agentCode 配置: }, Examples: []string{"dws pat chmod --products calendar,aitable --grant-type session --session-id --dry-run --format json"}, }, + // session-id is conditionally required in Validate; publish via + // ParamDecl instead of relying on RegisterSchemaHints tool_schema_hint. + Parameters: []corecmd.ParamDecl{ + { + Name: "session-id", + Required: boolPtr(false), + RequiredWhen: "grant-type is session", + }, + }, }, }) return chmodCmd diff --git a/scripts/policy/check-generated-drift.sh b/scripts/policy/check-generated-drift.sh index f42fceef..731d42da 100755 --- a/scripts/policy/check-generated-drift.sh +++ b/scripts/policy/check-generated-drift.sh @@ -30,10 +30,19 @@ concepts_guard="$tmp/param_concepts.json" concepts_schema_guard="$tmp/param_concepts.schema.json" cp internal/cli/param_concepts.json "$concepts_guard" cp internal/cli/param_concepts.schema.json "$concepts_schema_guard" -# Also guard human-authored metadata + selection hint trees. -metadata_guard="$tmp/metadata-hints" +# Guard human-authored selection (required) and metadata (optional). +# schema_hints/metadata may be absent, an empty directory, or hold only +# reserved product shells with tools: {} / missing tools — none of those +# alone is drift. When the directory is present, keep a byte guard so +# generation cannot rewrite those shells; never fail solely because the +# directory is missing or every product shell has empty tools. +metadata_dir="internal/cli/schema_hints/metadata" +metadata_guard="" +if [ -d "$metadata_dir" ]; then + metadata_guard="$tmp/metadata-hints" + cp -R "$metadata_dir" "$metadata_guard" +fi selection_guard="$tmp/selection-hints" -cp -R internal/cli/schema_hints/metadata "$metadata_guard" cp -R internal/cli/schema_hints/selection "$selection_guard" metadata_tmp="$tmp/metadata" @@ -94,8 +103,19 @@ if ! cmp -s internal/cli/param_concepts.schema.json "$concepts_schema_guard"; th exit 1 fi -if ! diff -qr internal/cli/schema_hints/metadata "$metadata_guard" >/dev/null; then - printf '%s\n' 'generation modified reviewed input internal/cli/schema_hints/metadata' >&2 +# Optional metadata: presence/absence and empty tools:{} shells are all OK. +# Fail only if generation mutates, removes, or invents the directory tree. +if [ -n "$metadata_guard" ]; then + if [ ! -d "$metadata_dir" ]; then + printf '%s\n' 'generation removed reviewed input internal/cli/schema_hints/metadata' >&2 + exit 1 + fi + if ! diff -qr "$metadata_dir" "$metadata_guard" >/dev/null; then + printf '%s\n' 'generation modified reviewed input internal/cli/schema_hints/metadata' >&2 + exit 1 + fi +elif [ -d "$metadata_dir" ]; then + printf '%s\n' 'generation created reviewed input internal/cli/schema_hints/metadata' >&2 exit 1 fi diff --git a/scripts/policy/check-runtime-confirmation-truth.sh b/scripts/policy/check-runtime-confirmation-truth.sh index c85f4422..152a3c88 100755 --- a/scripts/policy/check-runtime-confirmation-truth.sh +++ b/scripts/policy/check-runtime-confirmation-truth.sh @@ -2,19 +2,19 @@ set -eu # Ensure catalog confirmation=user_required exactly matches executable truth: -# typed corecmd Contract SafetySpec declarations plus migration-only metadata -# runtime_gate != none entries. +# typed corecmd Contract SafetySpec declarations plus any residual migration-only +# metadata runtime_gate != none entries. +# +# schema_hints/metadata is optional: the directory may be absent, contain no +# JSON files, or hold only empty product shells (tools: {} / missing tools). +# Empty shells contribute zero gated keys; Contract SafetySpec remains the +# production truth source. ROOT="$(CDPATH= cd -- "$(dirname -- "$0")/../.." && pwd)" cd "$ROOT" metadata_dir="internal/cli/schema_hints/metadata" -if [ ! -d "$metadata_dir" ]; then - printf '%s\n' "missing agent metadata directory: $metadata_dir" >&2 - exit 1 -fi - tmp="$(mktemp -d)" trap 'rm -rf "$tmp"' EXIT HUP INT TERM @@ -23,12 +23,24 @@ trap 'rm -rf "$tmp"' EXIT HUP INT TERM catalog="$tmp/catalog-combined.json" scripts/policy/with-catalog.sh >"$catalog" -jq -r ' - .tools - | to_entries[] - | select((.value.runtime_gate // "none") != "none") - | .key -' "$metadata_dir"/*.json >"$tmp/metadata_gated" +: >"$tmp/metadata_files" +: >"$tmp/metadata_gated" +if [ -d "$metadata_dir" ]; then + # Collect JSON paths without relying on nullglob (POSIX sh). + find "$metadata_dir" -maxdepth 1 -type f -name '*.json' | sort >"$tmp/metadata_files" +fi + +if [ -s "$tmp/metadata_files" ]; then + # shellcheck disable=SC2046 + # (.tools // {}) treats missing/null tools as an empty object so reserved + # product shells without tool rows do not fail the gate. + jq -r ' + (.tools // {}) + | to_entries[] + | select((.value.runtime_gate // "none") != "none") + | .key + ' $(cat "$tmp/metadata_files") >"$tmp/metadata_gated" +fi jq -r ' .tools @@ -48,42 +60,46 @@ jq -r ' ' "$catalog" | sort >"$tmp/catalog_required" if ! cmp -s "$tmp/truth_gated" "$tmp/catalog_required"; then - printf '%s\n' 'catalog confirmation=user_required differs from Contract SafetySpec + metadata runtime_gate truth' >&2 - printf '%s\n' 'declare corecmd Safety.Confirmation or update migration-only metadata runtime_gate, then regenerate schema' >&2 + printf '%s\n' 'catalog confirmation=user_required differs from Contract SafetySpec + residual metadata runtime_gate truth' >&2 + printf '%s\n' 'declare corecmd Safety.Confirmation (or residual migration-only metadata runtime_gate), then regenerate schema' >&2 diff -u "$tmp/truth_gated" "$tmp/catalog_required" || true exit 1 fi -jq -s ' - reduce .[] as $file ({}; - . * ( - $file.tools - | to_entries - | map({key: .key, value: (.value.runtime_gate // "none")}) - | from_entries - ) - ) -' "$metadata_dir"/*.json >"$tmp/gates.json" +: >"$tmp/gate_problems" +if [ -s "$tmp/metadata_files" ]; then + # shellcheck disable=SC2046 + jq -s ' + reduce .[] as $file ({}; + . * ( + ($file.tools // {}) + | to_entries + | map({key: .key, value: (.value.runtime_gate // "none")}) + | from_entries + ) + ) + ' $(cat "$tmp/metadata_files") >"$tmp/gates.json" -jq -r --slurpfile catalog "$catalog" ' - . as $gate_map | - ($catalog[0].tools) as $tools | - $gate_map - | to_entries[] - | .key as $canonical - | .value as $gate - | $tools[$canonical] as $tool - | select($tool != null) - | select($tool.field_provenance.confirmation.source != "corecmd.contract") - | select( - if $gate == "none" then - $tool.confirmation != "not_required" or $tool.risk == "high" or $tool.effect == "destructive" - else - $tool.confirmation != "user_required" - end - ) - | "\(.key)\tgate=\(.value)\teffect=\($tool.effect // "MISSING")\trisk=\($tool.risk // "MISSING")\tconfirmation=\($tool.confirmation // "MISSING")" -' "$tmp/gates.json" >"$tmp/gate_problems" || true + jq -r --slurpfile catalog "$catalog" ' + . as $gate_map | + ($catalog[0].tools) as $tools | + $gate_map + | to_entries[] + | .key as $canonical + | .value as $gate + | $tools[$canonical] as $tool + | select($tool != null) + | select($tool.field_provenance.confirmation.source != "corecmd.contract") + | select( + if $gate == "none" then + $tool.confirmation != "not_required" or $tool.risk == "high" or $tool.effect == "destructive" + else + $tool.confirmation != "user_required" + end + ) + | "\(.key)\tgate=\(.value)\teffect=\($tool.effect // "MISSING")\trisk=\($tool.risk // "MISSING")\tconfirmation=\($tool.confirmation // "MISSING")" + ' "$tmp/gates.json" >"$tmp/gate_problems" || true +fi if [ -s "$tmp/gate_problems" ]; then printf '%s\n' 'schema_hints/metadata runtime_gate disagree with catalog effect/risk/confirmation' >&2 diff --git a/scripts/policy/check-schema-catalog.sh b/scripts/policy/check-schema-catalog.sh index ecbe548e..83067cdc 100755 --- a/scripts/policy/check-schema-catalog.sh +++ b/scripts/policy/check-schema-catalog.sh @@ -268,6 +268,8 @@ if policy_search_go '\.ListTools\(' internal/app internal/cli; then exit 1 fi +# Optional/empty schema_hints/metadata shells are fine; gated confirmation +# truth is Contract SafetySpec (+ residual runtime_gate only if present). ./scripts/policy/check-runtime-confirmation-truth.sh # Run the typed content gates as policy, rather than treating non-empty