Repository navigation
Commit dc3adf3
docs(skills): teach MCP delete_record confirm: true in the objectstack-ai tools table (#31010)
<!-- claude-projects-attribution: {"github_login":"huangyiirene"} -->
_Requested by **Irene** · [project
thread](https://claude.ai/code/project/chan_01TJXtQ1tVD26ecLDZxFS67x?thread=cmsg_01TJXtQ1tVD26ecLDZxFS67x6tDhuaKixCSrDFhtTS2kgC)_
Fixes #30863
Clause-②: no
Metadata-protocol: none
`dispatch-gates` mandates the contract-review model tier for `skills/**`
(clause ①). The maintainer's standing order in this project (2026-11-03)
waives it; this PR was developed below that tier, and the dispatching
seat runs the contract review.
## 维护者速读
- 改了什么:`objectstack-ai` 技能 MCP 工具表 L202 一行:`delete_record` 不带 `confirm:
true` 会被 `ACTION_CONFIRMATION_REQUIRED`(428)拒绝,agent 须先问人再重试;另加一个
`'@objectstack/skills': patch` changeset。
- 为什么改:PR #30861 让 MCP `delete_record` 必须带 `confirm:
true`,旧行只写"annotated destructive",照技能调用的 agent 会被拒。
- 风险与回滚:只改教学文字,无 schema、键或行为变化;回滚即 revert。
- Token 账:SKILL.md 5539 → 5563(上限 6801,余量 1238),无需付账;`skills/**` 净增行 0。
- 先看:`skills/objectstack-ai/SKILL.md` L202 与
`packages/mcp/src/mcp-http-tools.ts` 的 `delete_record` 注册(描述与 `confirm`
成员)。
- 需要你做的:无;席位负责复审与落地。
## What changes
- `skills/objectstack-ai/SKILL.md` L202, the MCP tools-table row for
`create_record`, `update_record`, `delete_record`: "writes;
`delete_record` is annotated destructive" becomes "writes;
`delete_record` is refused with `ACTION_CONFIRMATION_REQUIRED` (428)
unless it sends `confirm: true` — ask the human first, then retry".
- `.changeset/30863-skills-ai-delete-record-confirm.md`:
`'@objectstack/skills': patch`, with `Clause-②: no` and
`Metadata-protocol: none`. No `skip-changeset`.
Measured on `main` at `8ae0ab9b0` (PR #30861 landed as `c77dd17f26`):
- `packages/mcp/src/mcp-http-tools.ts` registers `delete_record` with
the description "A call is REFUSED unless it also sends confirm: true —
ask the human first, then retry; nothing is deleted on a refused call."
Its schema declares the member as `[AI_ACTION_CONFIRMATION_MEMBER]`
(`confirm`), an optional boolean, and the handler answers
`recordDeleteConfirmationRefusal` with code
`ACTION_CONFIRMATION_REQUIRED` and HTTP status 428.
- `packages/runtime/src/action-execution.ts`:
`ACTION_CONFIRMATION_REQUIRED_CODE = 'ACTION_CONFIRMATION_REQUIRED'`,
`ACTION_CONFIRMATION_REQUIRED_STATUS = 428`, the same refusal
`run_action` answers.
- The row's wording follows the server's own `run_action` /
`delete_record` description rule ("send confirm: true — ask the human
first, then retry"); no key or code is introduced that `main` lacks.
Eval sweep: `skills/objectstack-ai/evals/skills-tools-knowledge.json` is
this skill's only eval file, and no case mentions `delete_record`,
`confirm` or `destructive`. Nothing to change there.
**Token ratchet** (`node scripts/check-skills-token-ratchet.mjs`):
`skills/objectstack-ai/SKILL.md` before 5539 tokens, after 5563 tokens,
ceiling 6801 (headroom 1238). No ceiling moves, no deletion needed. Net
lines in `skills/**`: 0 (one row replaced in place).
## Why
After PR #30861, an agent that followed the skill's tools table sent
`delete_record` without `confirm` and was refused. The skill now teaches
the call the server accepts.
## Verification
<details><summary>Local gates on 54666fa: 45 derived, 45 run with exit
0, 0 NOT MEASURED (`dispatch-gates --ran`)</summary>
- `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` derived 45 commands for the 2 changed files.
All ran after `pnpm install --frozen-lockfile` and a full `pnpm build`
(119/119 tasks, exit 0), each under a 900 s timeout with
`NODE_OPTIONS=--max-old-space-size=8192` (heap headroom for this cloud
container) and its exit code captured before any pipe.
- All 45 exited 0, among them `check-skills-token-ratchet.mjs`,
`check:skill-docs`, `check:skill-identifier-liveness`,
`check:skill-compatibility`, `check:skill-frame-sync`,
`check:doc-authoring`, `check-empty-changeset.mjs`,
`check-changeset-no-major.mjs`, `check:dts-closure`,
`check:dual-build-cjs-loads` and `check-comment-mask-corpus.mjs`.
- `--ran` printed: `45 derived famil(ies) accounted for — 45 run, 0
NOT-MEASURED (a DERIVED zero — all 45 recorded an exit code and none of
them is 3)`.
- `node scripts/check-commit-card-trailers.mjs --range
origin/main..HEAD`: exit 0 before the push.
</details>
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(No schema touched.)
- [x] 2. Every name I added uses the casing for its kind. (No names
added.)
- [x] 3. No formatter ran. (Markdown only: no lintable source touched,
so `pnpm lint` was not run.)
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. A change that publishes carries a changeset, and both
declaration lines are filled in here and in the changeset.
- [x] 6. `packages/spec` not touched; nothing to regenerate.
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 8. Title, body and comments are in English. (The 维护者速读 section is
Chinese, per the lane template.)
- [x] The *Before Submitting* list in CONTRIBUTING.md is done.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01J8VVAmcenQmYUv4fvtB68m
Co-authored-by: Claude <noreply@anthropic.com>1 parent 4fae0be commit dc3adf3
2 files changed
Lines changed: 9 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
199 | 199 | | |
200 | 200 | | |
201 | 201 | | |
202 | | - | |
| 202 | + | |
203 | 203 | | |
204 | 204 | | |
205 | 205 | | |
| |||
0 commit comments