Found while implementing #10355 (the agent.tools docs row). Out of that card's file surface — it is scoped to content/docs/ai/agents.mdx alone — so filed rather than fixed there.
Two accuracy defects in packages/spec/src/ai/agent.zod.ts, both about the file's own tombstones.
1. The AgentSchema docblock @example writes a key the same file rejects
The docblock immediately above export const AgentSchema reads:
* - **skills**: THE capability model — an agent references skill names, and
* its tool set is exactly the union of those skills' tools (ADR-0064).
* There is no direct-tool slot and no global fall-through.
*
* @example Agent-Skill Architecture
* defineAgent({
* name: 'support_tier_1',
* label: 'First Line Support',
* role: 'Help Desk Assistant',
* instructions: 'You are a helpful assistant. Always verify user identity first.',
* skills: ['case_management', 'knowledge_search'],
* knowledge: { sources: ['faq', 'policies'], indexes: ['support_docs'] },
* });
knowledge is declared roughly 110 lines below, in the same object, as retiredKey(...) — i.e. z.never(). So it fails tsc at the authoring site and is rejected at parse. The schema's canonical example teaches a key the schema itself refuses, three lines under a bullet stating the opposite rule.
This is the ADR-0033 channel: the @example is what an AI author copies, and it is the same reader the tombstone was written for. The tombstone and the example currently disagree.
2. The tools tombstone's stated rationale no longer holds
The comment above tools: retiredKey(...) says:
* Tombstoned rather than deleted: `AgentSchema` is not `.strict()`, so a
* plain deletion would silently strip the key and the agent would quietly
* reach none of the tools its author listed ...
AgentSchema is now built with strictObject({ ... }, { ... }) from ../shared/strict-object, and the guidance block a few lines above it says as much in its own words ("Closing the shape creates that channel, so they get one now").
The conclusion is still correct — the tombstone should stay, because the prescription is the payload, not merely the non-strip — but the stated reason is stale, and it is exactly the reason a future author would lean on when deciding whether this tombstone can be dropped or must be kept. A tombstone defended by an argument that no longer applies is one someone will delete on inspection.
Suggested repair
- Drop the
knowledge: line from the @example; the example already carries skills, which is the block's whole point. - Reword the
tools tombstone rationale to rest on the reason that is actually load-bearing today.
Both are contained edits in one file. Worth a pass over the other retiredKey docblocks in packages/spec/src/ for the same .strict() phrasing, since the strictObject conversion was repo-wide.
Generated by Claude Code
Found while implementing #10355 (the
agent.toolsdocs row). Out of that card's file surface — it is scoped tocontent/docs/ai/agents.mdxalone — so filed rather than fixed there.Two accuracy defects in
packages/spec/src/ai/agent.zod.ts, both about the file's own tombstones.1. The
AgentSchemadocblock@examplewrites a key the same file rejectsThe docblock immediately above
export const AgentSchemareads:knowledgeis declared roughly 110 lines below, in the same object, asretiredKey(...)— i.e.z.never(). So it failstscat the authoring site and is rejected at parse. The schema's canonical example teaches a key the schema itself refuses, three lines under a bullet stating the opposite rule.This is the ADR-0033 channel: the
@exampleis what an AI author copies, and it is the same reader the tombstone was written for. The tombstone and the example currently disagree.2. The
toolstombstone's stated rationale no longer holdsThe comment above
tools: retiredKey(...)says:AgentSchemais now built withstrictObject({ ... }, { ... })from../shared/strict-object, and theguidanceblock a few lines above it says as much in its own words ("Closing the shape creates that channel, so they get one now").The conclusion is still correct — the tombstone should stay, because the prescription is the payload, not merely the non-strip — but the stated reason is stale, and it is exactly the reason a future author would lean on when deciding whether this tombstone can be dropped or must be kept. A tombstone defended by an argument that no longer applies is one someone will delete on inspection.
Suggested repair
knowledge:line from the@example; the example already carriesskills, which is the block's whole point.toolstombstone rationale to rest on the reason that is actually load-bearing today.Both are contained edits in one file. Worth a pass over the other
retiredKeydocblocks inpackages/spec/src/for the same.strict()phrasing, since thestrictObjectconversion was repo-wide.Generated by Claude Code