Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .changeset/skill-tools-docblock-adr-0109.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
---
"@objectstack/spec": patch
---

**Docs:** the `skill.tools[]` docblock now states ADR-0109's authoring model instead of its rejected alternative (#10356).

`SkillSchema.tools`' docblock told authors that "Tools should also be registered as first-class metadata (type: 'tool') unless they are dynamically materialised at runtime" — the shape ADR-0109 explicitly **rejected** ("a required tool record per exposed action": a second authoring step, a second namespace to keep consistent, and a second surface for AI authors to hallucinate into, for zero added capability). It also inverted the exemption, treating the materialised path as the exception when ADR-0109 makes it — together with the platform registry — the rule. The sibling docblock over `stack.zod.ts`'s `tools` already said the opposite, so the package shipped two contradictory answers to the same question.

The text now mirrors the resolution universe `@objectstack/lint`'s `validate-ai-tool-references` actually implements: a `tool` record is never required and the default third-party path declares none; a `skill.tools[]` name resolves against the stack's own `stack.tools[]` names, `PLATFORM_PROVIDED_TOOL_NAMES`, and the `action_<name>` family the runtime materialises from AI-exposed declarative actions (`ai.exposed` + `ai.description` on a headless action type, per ADR-0011). It also records that `stack.tools` is the optional Phase-2 AI-presentation refinement layer with no runtime reader until that phase lands — so a record authored today is inert, which the old sentence recommended authoring without saying.

Prose only: no schema shape, no `.describe()` text, no runtime behaviour and no authorable-surface change (`check:authorable-surface` and the whole `check:generated` set are unmoved by this diff). It is graded rather than skipped because the text ships to consumers: `@objectstack/spec`'s `files` list publishes `src/**/*.zod.ts`, so this docblock travels in the npm tarball as source. It does **not** reach `dist/*.d.ts` — property-level comments inside the `z.object({ … })` literal are dropped from the emitted declarations, which is measurable in the built chunk (`tools: z.ZodArray<z.ZodString>;`, no comment). Published source is the surface that matters here anyway: this is the docblock an AI author reads while writing `skill.tools[]`, the exact surface ADR-0109 was written to keep clean.
14 changes: 12 additions & 2 deletions packages/spec/src/ai/skill.zod.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -345,8 +345,18 @@ export const SkillSchema = lazySchema(() => strictObject({
* of dynamically registered tools (e.g. the `action_<name>` tools
* materialised from each object's declarative Action list).
*
* Tools should also be registered as first-class metadata
* (type: 'tool') unless they are dynamically materialised at runtime.
* A `tool` record is NEVER required, and the default third-party path
* declares none (ADR-0109). A name here resolves against, in order: the
* stack's own `stack.tools[]` names; `PLATFORM_PROVIDED_TOOL_NAMES`, the
* curated registry of tools the cloud AI runtime registers at boot; and the
* `action_<name>` family the runtime materialises from the app's own
* AI-exposed declarative actions (`ai.exposed` + `ai.description` on a
* headless action type — ADR-0011). The first of those is the OPTIONAL
* AI-presentation refinement layer (Phase 2: LLM-facing description,
* parameter narrowing, flow exposure) and has no runtime reader until that
* lands, so a `stack.tools` record authored today is inert. In the default
* path the executable, its authz and its audit stay on the action/flow the
* app already ships.
*
* **CLOUD-RUNTIME-ONLY** (#3905). Tool binding is consumed by the in-product
* agent runtime, which composes an agent's tool set from its
Expand Down
Loading