Uh oh!
There was an error while loading. Please reload this page.
docs(ai): add the tool-record guide, routing readers to skills and materialised action tools first - #10358
Conversation
…10222) `tool` is an authorable metadata kind with a generated field reference and no guide. The gap is not "a page is missing" — it is that a reader asking "how do I give my agent a new tool" had nowhere that told them the answer is usually NOT a tool record. So content/docs/ai/tools.mdx opens with the decision, not the shape: the three ways a capability reaches an agent (a platform tool named by a skill, an Action materialised as `action_<name>`, an authored `tool` record) and when each is right. The declaration shape is below that, for the reader who has established they need it, together with an honest statement of what a record does today — ADR-0109 Phase 2 has not landed, so `stack.tools` has no runtime reader and authoring one makes nothing runnable. - ai/index.mdx: the module list gains the page, and the sentence that presented `defineAgent` / `defineTool` / `defineSkill` as coequal now places them per ADR-0063 §2 + ADR-0109 (skills are the primitive; agents are platform-owned; a tool record is an optional refinement layer). - ai/meta.json: one sidebar entry, after actions-as-tools. - .claude/workflows/docs-accuracy-audit.js: one line, produced by `node scripts/docs-audit/check-audit-scope.mjs --write` — a new hand-written page must enter the audit scope or the gate goes red. Both TypeScript examples carry `{/* os:check */}` and type-check against the built @objectstack/spec. Part of #10206 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GawRwpD44VwBDVy3hs77AX
os-elon
commented
Aug 21, 2026
Landed by the PM under the maintainer's explicit instruction — audit record. This is a governed PR ( Provenance — who, what, where. The repository owner, in the PM session driving epic #10206, 2026-08-20. Authorization verbatim: 「你帮我处理合并吧」. Their per-PR verdict on this one, verbatim: 「可合」 — 「以「先别写 tool record」分流开篇,与 ADR-0109 现状诚实对齐」. PM position, recorded rather than dropped. I stated before acting that an agent-executed governed merge removes the human click the fence treats as the review record, and that the audit would flag it. The maintainer instructed anyway. The decision is theirs; this is the record of it, not a silent reinterpretation of the rule. Landing route. A direct merge is refused by repository rules ( Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 32441044667 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
os-elon
commented
Aug 21, 2026
Merge-queue dequeue triage (PM, epic #10206). Verdict: not this PR's failure — requeued once, and only once. The signature, and why it is not branch 1The test lives in An Hypothesis about the mechanism — stated as a hypothesis, not provenThe failure direction is one event too many (expected 3, got 4), not one too few. Reading the test source: the That is consistent with the observed assertion, but I did not prove it: I have not reproduced it, and the file's own docblock argues at length that the case is not a function of runner speed ("it brackets the noise between an opener … and two closers … so nothing about it is a function of how fast the runner happens to be"). If that claim is right, my hypothesis is wrong and something else produced the extra entry. Either way it is not reachable from this diff. Worth flagging for whoever owns ActionRequeued once. The discipline allows exactly one confirming re-run for a failure naming a surface the diff does not touch, and the triage comment's own history line confirms this is this PR's first queue failure in 24h. ⛔ A second failure will not be requeued — it would be real by definition, and I will stop and diagnose rather than burn another full-queue rebuild. The queue logged 38 other failed builds in the preceding 24h, so re-queuing is not free for anything behind it. Generated by Claude Code |
Fixes#10222
What this adds
toolis an authorable metadata kind with a generated field reference (/docs/references/ai/tool) and no guide. The gap was not "a page is missing" — it was that a developer asking "how do I give my agent a new tool" had nowhere that told them the answer is usually not a tool record.So
content/docs/ai/tools.mdxopens with the decision rather than the shape:action_{name}tool, or an authoredtoolrecord — with a table saying which is right and answering "tool record?" with No for the first three.ai-skill-tool-unresolvedcatching fictional names at authoring time.warncallout:ToolSchemahas noimplementation/handler, ADR-0109 Phase 2 has not landed,stack.toolshas no runtime reader. What it does do is narrower and stated exactly.A reader who leaves after section 1 is on the correct path. That was the acceptance criterion, and it is why the shape is deliberately the fifth thing on the page rather than the first.
Files
content/docs/ai/tools.mdxcontent/docs/ai/index.mdxdefineAgent/defineTool/defineSkillas coequal now places them per ADR-0063 §2 + ADR-0109content/docs/ai/meta.jsonactions-as-tools.claude/workflows/docs-accuracy-audit.jsactions-as-tools.mdxandskills.mdxare cross-linked, not edited. Nothing underpackages/spec/**is touched.Declared deviation — and why this PR is human-merge-only
Adding a hand-written page turns
check:docs-audit-scopeRED until the audit scope is regenerated. The one added line is exactly whatnode scripts/docs-audit/check-audit-scope.mjs --writeproduced (+1 added, -0 removed) and was not hand-edited:"content/docs/ai/skills.mdx", + "content/docs/ai/tools.mdx", "content/docs/api/client-sdk.mdx",.claude/**is a governed surface (#9866), so this PR is human-merge-only. It stays draft: not flipped ready, not enqueued, no auto-merge.Verification — all at
8b81c40c, the final commitGate set re-derived from the actual diff with
node scripts/pm/dispatch-gates.mjs(no path arguments — it reads the change set from the merge base itself). That added three families the dispatch list did not name (check:doc-formula-expressions,check:pm-governed-merges,check:skill-frame-sync), and all three were run.check:doc-anchors253 internal #fragment link(s) across 400 source file(s) all resolve to a real headingcheck:doc-authoring381 files clean — no bare metadata literalscheck:docs-audit-scopescope is in sync with content/docs/: 181 hand-written doc(s)check:docs-redirectsOK (92 entries -- 89 page destination(s) resolved ...)check:published-readme-links152 outbound link(s) across 60 published markdown file(s)check:role-wordOK, no new occurrences of the reserved wordcheck:cross-package-test-inputsOK: 12 package(s) read outside themselves, all declaredcheck:nul-bytesOK (scanned 6096 text file(s) ... no raw ASCII control bytes)check:empty-stateall classified (1 closed, 2 open, 4 output, 9 scope)check:livenessevery governed-type property ... is classifiedcheck:strictness-ledger61 file(s) across 5 triaged director(ies)check:variant-docs18 discriminated union(s) — 8 governed, 10 exemptcheck:skill-examples211 prose examples type-check against @objectstack/speccheck:doc-formula-expressions22 record-scoped formula example(s) across 407 files / 1417 TS blocks judged cleancheck:pm-governed-mergesself-test: 81 assertionscheck:skill-frame-sync4 copies of the decision frame are structurally isomorphicBoth TypeScript examples are type-checked, and that was falsified before it was trusted
The page's two code blocks carry
{/* os:check */}, socheck:skill-examplescompiles them against the built@objectstack/specdeclarations. The run names them:content/docs/ai/tools.mdx:55and:161.To confirm the green is a measurement and not a vacancy, the second block was mutated (
label: 'Summarise Case',→label: 42,; confirmed on disk — the removed text went 1 → 0 occurrences and the injected text 0 → 1) and the gate re-run. It went red on the mutated line:The block was then restored from the commit (counts confirmed back at 1 / 0) and the gate re-run green. No spec source changed in either leg, so the built
distunder test is the same tree throughout.Two premises checked before writing, both reported rather than fixed here
ai/actions-as-tools.mdxcovers only the automatic materialisation path — confirmed. It documentslist_actions/run_actionover MCP and the ObjectOSaction_{name}runtime, and says nothing about authoring atoolrecord. The card's shape holds.ai/agents.mdxalready states thatagentis platform-internal (ADR-0063 §2) — confirmed, in three places: the heading "You extend the platform with skills, not agents", theallowRuntimeCreate:false, allowOrgOverride:falsesentence citing §2, and the closingwarningcallout. No fix needed.Two accuracy defects were found in files this card must not touch, and are filed rather than fixed here:
ai/agents.mdxstill documentsagent.toolsas a live field — it was tombstoned in protocol 17 #10355 —ai/agents.mdxstill documentsagent.toolsas a live field; it is aretiredKey()tombstone since protocol 17 (feat(spec,lint)!: accept ADR-0109, remove agent.tools[], lint agent authoring, model AI exposure in tool resolution (#3820) #3894), typedneverand rejected at parse.skill.zod.ts'stoolsdocblock still tells authors to register atoolrecord — the opposite of ADR-0109's default path #10356 —skill.zod.ts'stoolsdocblock still says tools "should also be registered as first-class metadata (type: 'tool')", the opposite of ADR-0109 and of thestack.zod.tsdocblock in the same package.Neither is addressed here, and neither is assigned.
Part of #10206
Generated by Claude Code