From 433983625cd4db7a21076a6029fdc5bb9f72c3e8 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 11 Sep 2026 14:49:36 +0000 Subject: [PATCH 1/2] docs(spec): point the `agent.tools` rejection at the record that binds here MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The author-facing tombstone for `agent.tools` cites ADR-0064 for the invariant it rests on. That record's own header reads `Status: Proposed` and carries a cloud-owned callout marking it superseded in part, so an author who follows the citation cannot tell from the record itself that the rule still binds them. ADR-0064 remains the correct authority: it is the record that states the invariant ("an agent's tool set is the union of its surface-compatible skills' tools"), and ADR-0109 never names `agent.tools` at all. So this adds one clarifying clause rather than retargeting the citation: the `Proposed` / cloud-owned status scopes the runtime half that lives in cloud `service-ai`, while the authoring half is in force here and ADR-0109 (Accepted — implemented) is the in-repo record carrying it. Prose only — no behaviour, no schema, no accept-set change. The generated reference page is rebuilt from the same source. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01MkQhmuuJAVDjmeWNixwDDH --- content/docs/references/ai/agent.mdx | 2 +- packages/spec/src/ai/agent.zod.ts | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/content/docs/references/ai/agent.mdx b/content/docs/references/ai/agent.mdx index 880bc15536..159db8c9f8 100644 --- a/content/docs/references/ai/agent.mdx +++ b/content/docs/references/ai/agent.mdx @@ -51,7 +51,7 @@ const result = AIModelConfigSchema.parse(data); | **lifecycle** | `{ id: string; description?: string; contextSchema?: Record; initial: string; … }` | optional | [EXPERIMENTAL — not enforced] State machine defining the agent conversation flow and constraints. Parsed but no runtime consumer yet. | | **surface** | `Enum<'ask' \| 'build'>` | optional (default: `"ask"`) | Product surface this agent binds ('ask' \| 'build') — ADR-0063 §1 | | **skills** | `string[]` | optional | Skill names to attach (Agent→Skill→Tool architecture) | -| **tools** | `never` | optional | [REMOVED] `agent.tools` was removed in @objectstack/spec 17 — use `skills`. An agent reaches exactly the tools its surface-compatible skills declare (ADR-0064), so move each reference into a skill: a platform tool by its registered name, or `action_` for one of your own AI-exposed Actions. This is NOT a rename — there is no key the value moves to: the migration DELETES the key and emits a notice naming each tool that was listed, and you re-declare each one in a skill by hand. Run `os migrate meta --from 16` to list the mechanical edits for existing sources; apply them by hand. | +| **tools** | `never` | optional | [REMOVED] `agent.tools` was removed in @objectstack/spec 17 — use `skills`. An agent reaches exactly the tools its surface-compatible skills declare (ADR-0064), so move each reference into a skill: a platform tool by its registered name, or `action_` for one of your own AI-exposed Actions. This is NOT a rename — there is no key the value moves to: the migration DELETES the key and emits a notice naming each tool that was listed, and you re-declare each one in a skill by hand. ADR-0064 itself still reads `Proposed` and is cloud-owned — that scopes its RUNTIME half (tool resolution, which lives in cloud `service-ai`), not this rejection: the authoring invariant binds you here, and ADR-0109 (Accepted — implemented) is the in-repo record that carries it. Run `os migrate meta --from 16` to list the mechanical edits for existing sources; apply them by hand. | | **knowledge** | `never` | optional | [REMOVED] `agent.knowledge` was removed in @objectstack/spec 17.0.0 (audit close-out) — declaring knowledge sources/indexes on an agent never scoped retrieval: the `search_knowledge` tool takes `sourceIds` from the LLM's tool-call arguments, not from the agent record. Delete the block. Restrict retrieval at the knowledge-service / source level (per-source permissions), and describe intended grounding in `instructions` so the model asks for the right sources. Run `os migrate meta --from 16` to list the mechanical edits for existing sources; apply them by hand. | | **active** | `boolean` | optional (default: `true`) | | | **access** | `string[]` | optional | Who can chat with this agent | diff --git a/packages/spec/src/ai/agent.zod.ts b/packages/spec/src/ai/agent.zod.ts index 690dc4e58e..db3e7e4e16 100644 --- a/packages/spec/src/ai/agent.zod.ts +++ b/packages/spec/src/ai/agent.zod.ts @@ -239,6 +239,10 @@ export const AgentSchema = lazySchema(() => strictObject({ 'This is NOT a rename — there is no key the value moves to: the migration ' + 'DELETES the key and emits a notice naming each tool that was listed, and ' + 'you re-declare each one in a skill by hand. ' + + 'ADR-0064 itself still reads `Proposed` and is cloud-owned — that scopes its ' + + 'RUNTIME half (tool resolution, which lives in cloud `service-ai`), not this ' + + 'rejection: the authoring invariant binds you here, and ADR-0109 ' + + '(Accepted — implemented) is the in-repo record that carries it. ' + 'Run `os migrate meta --from 16` to list the mechanical edits for existing sources; apply them by hand.', ), From 1a55b9dc0bc17f2392c9127dcfc110c21b1b6677 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 11 Sep 2026 15:06:14 +0000 Subject: [PATCH 2/2] docs(spec): changeset for the `agent.tools` citation clause MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The edited source file ships from a released package — `@objectstack/spec` lists both `dist` and `src/**/*.zod.ts` in its `files[]`, and the new clause was measured into 18 `dist` artefacts and the shipped `agent.zod.ts` — so the prose change is user-visible and graded `patch`. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01MkQhmuuJAVDjmeWNixwDDH --- .../16927-agent-tools-retirement-citation.md | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .changeset/16927-agent-tools-retirement-citation.md diff --git a/.changeset/16927-agent-tools-retirement-citation.md b/.changeset/16927-agent-tools-retirement-citation.md new file mode 100644 index 0000000000..820b091504 --- /dev/null +++ b/.changeset/16927-agent-tools-retirement-citation.md @@ -0,0 +1,24 @@ +--- +'@objectstack/spec': patch +--- + +The `agent.tools` rejection now says why ADR-0064 binds, so its `Proposed` status does not read as "not yet in force" + +An author who writes the retired `agent.tools` key gets the tombstone's +prescription, which rests the rule on **ADR-0064** (*"an agent's tool set is the +union of its surface-compatible skills' tools"*). Following that citation lands +on a record whose own header reads `**Status**: Proposed (2026-06-22)` and +carries a `🔶 Cloud-owned — superseded in part by cloud ADR-0025` callout. From +the record itself an author cannot tell that the rule still binds them — the +weaker reading is the one the metadata invites. + +ADR-0064 stays the cited authority, because it is the record that states the +invariant the key violated; **ADR-0109** (`Accepted — implemented (Phase 1)`) +names `agent.tools` nowhere and only *builds on* that invariant, so retargeting +the citation would send the author to a record that does not contain the rule +they broke. The message instead gains one clarifying clause: the `Proposed` / +cloud-owned status scopes the **runtime** half (tool resolution, which lives in +cloud `service-ai`), while the **authoring** half is in force in this repo and +ADR-0109 is the in-repo record carrying it. + +Prose only — the rejection, the retirement and the accept set are unchanged.