docs(skills): objectstack-ai says guardrails is enforced per turn and output validation lives on action.ai.outputSchema - #21302
Conversation
… output validation lives on action.ai.outputSchema The ToolSchema paragraph no longer says a tool's outputSchema keys are folded into the model-facing description; it says nothing reads the key on a tool record and steers the author to ai.outputSchema on the action, which the AI runtime enforces by withholding a non-conforming result. Common Pitfalls 1 no longer lists guardrails as declared-only: it is enforced per user turn (token and time limits, blocked tool names and categories refused) but is a limit, not an approval. memory stays described as declared-only. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FNKm1SmPpuJASnbjxWGtsJ
Contract reviewServed-tier: Face: governed skill text ( ① Derived judgments
② Semver levelDocs-only in a governed surface no package ships; ③ Boundary flags
Implemented-by: VERDICT: PASS |
维护者速读(终稿)席位(skills 席 1, 改了什么。 对外发布的 为什么改。 这是 AI 作者写 agent/tool 元数据时读的教材。cloud 已落地 guardrails 与 action 返回值校验(cloud 风险与代价(含回滚)。 纯文档,不动发布包与运行时;风险只在措辞与读数是否对齐:席位逐条对照三条读数,新句只说读数证明了的事; 席位意见。 建议批准。无同文件在飞 PR。spec 侧 你要做的(一个动作)。 在本 PR 上留一条 APPROVED review( |
Fixes #21288
Clause-②: no
What this does
Two sentences in the published
objectstack-aiskill said the opposite of what the cloud AI runtime now does. Both are rewritten to state only what the readings on the parent card prove. The skill text cites no card number (it cites ADRs, as the rest of the file does); the readings are cited here.ToolSchemaparagraph, theoutputSchemaclause (lines 279–281 at4e6dc233). It said the key's top-level keys are folded into the tool description shown to the model and outputs are not validated. It now says nothing reads the key on a tool record, and steers the author toai.outputSchemaon the action, which the AI runtime ☁️ enforces by withholding a result that does not conform.guardrails,memory,structuredOutput,lifecycleandtool.outputSchemaare enforced by the agent runtime (5 keys), starting with the guardrails the built-in agents already declare #20274, of cloudmaincb62c3ea.packages/service-ai/src/tools/action-tools.ts#compileOutputContractreadsaction.ai.outputSchemadirectly;AIToolDefinition.outputSchemais only a copy of it and nothing reads it back; no reader turns an authoredtoolrecord into a tool definition.content/docs/ai/tools.mdxrow (nothing reads it on a tool record; declare it asai.outputSchemaon the action, where the cloud AI runtime validates the action result), not copied. The ☁️ marker is the file's own edition-boundary convention for a cloud surface.4e6dc233). It saidguardrails/memory/structuredOutputare declared only, no runtime reads them, and real limits come from the quota service. It now saysguardrailsis enforced per user turn by the AI runtime ☁️ (token and time limits; blocked tool names and categories refused) but is a limit, not an approval, and thatmemoryis declared only, no runtime reads it. The pitfall's heading and its second half (what an enforced gate is) are unchanged.guardrails,memory,structuredOutput,lifecycleandtool.outputSchemaare enforced by the agent runtime (5 keys), starting with the guardrails the built-in agents already declare #20274, of cloudmain235c5b29.packages/service-ai/src/ai-service.ts#TurnGovernorchecksmaxExecutionTimeSecandmaxTokensPerInvocationper user turn, before every model round, with each refusal audited;packages/service-ai/src/agent-runtime.ts#matchBlockedTopicmatchesblockedTopicsexactly on the tool name, onaction_Tor on the tool category, removes the match from the offer and refuses it at call time.structuredOutputis removed from the declared-only enumeration and nothing is written in its place. Its new semantics wait on spec(ai):agent.structuredOutputis now enforced by cloud, which refuses four authorable members (regex/grammar/xmlformats, thecoerce_typesstep) — retire them or build them, then flip the row #21277 (decision box); triage's sequencing leaves that clause out of this PR rather than rewriting it twice. The premise the PM set for dropping the word held: the sentence is rewritten anyway, a version that kept the word in the declared-only list fits the same four lines, so the deletion cost no line and introduced no new claim.memorystays described as declared-only. The skill never namedlifecycle, so there is nothing to keep unenforced there.Line budget (the
skills/**discipline)4e6dc233)8f4222b5)skills/objectstack-ai/SKILL.mdlinesceil(utf8 bytes / 4)skills/*/SKILL.md, linesskills/*/SKILL.md,ceil(bytes / 4)Each position pays +1 line; no neighbouring line is re-wrapped (the diff is 7 insertions, 5 deletions, inside the two clauses only). The dispatch gave the file as 337 lines; at
4e6dc233it is 416 (git show 4e6dc233:skills/objectstack-ai/SKILL.md | wc -l).Verification (at
8f4222b5, worktreeobjectstack-issue-21288)node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commandsderived 24 commands from the merge base4e6dc233(1 path, +7/−5). Each ran with its exit code captured before any pipe;--rananswered: "✓ dispatch-gates --ran: 24 derived famil(ies) accounted for — 24 run, 0 NOT-MEASURED".node scripts/check-skills-token-ratchet.mjsexit 0: "✓ check-skills-token-ratchet: skills/objectstack-ai/SKILL.md is 5486 tokens (ceiling 6806; headroom 1320)".pnpm --filter @objectstack/spec run check:skill-docs,pnpm check:skill-identifier-liveness,pnpm check:skill-frame-sync,pnpm check:skill-compatibility,pnpm check:corpus-claim-drift,pnpm check:doc-authoring,pnpm check:role-word,pnpm check:nul-bytes,pnpm check:pm-governed-merges,pnpm check:gitlink-declared,pnpm check:agent-test-spelling,pnpm check:cross-package-test-inputs,pnpm check:driver-memory-census,pnpm check:refd-timer-probe,pnpm check:watch-hint-literal, and the directnode scripts/check-*.mjsrows (ci-filter-parity, closing-keyword-parity and its self-test, comment-mask-corpus, doc-route-spelling advisory and self-test).pnpm --filter @objectstack/lint run check:doc-formula-expressions: first run exit 3, PREREQUISITE NOT MET (@objectstack/formulaand@objectstack/lintnot built), nothing measured; afterpnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lintunder the shared verify lock, exit 0.os:checkblocks inskills/**:pnpm --filter @objectstack/spec run check:skill-examplesexit 0, "✅ 259 prose examples type-check across 3 surface(s)" (needed@objectstack/spec,@objectstack/clientand@objectstack/client-reactbuilt first, all under the lock).pnpm lint), the type-check lanes and Test Core; the--ranfooter names them as outside the derived total.Changeset
skip-changeset.skills/**is in no published package'sfiles[]: a scan of everypackage.jsonin the tree for afiles[]entry namingskillsorcontent/docsfinds zero; the positive control@objectstack/speclistsdist,json-schema,liveness,prompts,llms.txt,README.md,src/**/*.zod.ts,CHANGELOG.md,api-surface,spec-changes.json. The catalog ships to customer projects throughnpx skills add, not through npm.Governance
Tier H:
skills/**is a governed surface (Prime Directive #14). This PR stays draft and lands only after an authorized APPROVED review; no seat readies, queues or arms auto-merge on it. The sibling docs line of the same card is a separate, ordinary PR onclaude/issue-21288-actions-mdx-outputschema, which carries no closing keyword.Acceptance notes
mainat4e6dc233the same folded-into-the-description claim still stands inpackages/spec/src/ai/tool.zod.ts:195(the describe),packages/spec/liveness/tool.json:49(the row note),content/docs/ai/tools.mdx:148and the generatedcontent/docs/references/ai/tool.mdx:37/agent.mdx:62. PR feat(spec): agent.guardrails is live, enforced by the cloud AI runtime; tool.outputSchema steers authors to action.ai.outputSchema #21280 (open, draft) rewrites all of them and regenerates the reference pages. Carrier: that PR; noted, not filed.structuredOutputnow has no sentence in this skill. When spec(ai):agent.structuredOutputis now enforced by cloud, which refuses four authorable members (regex/grammar/xmlformats, thecoerce_typesstep) — retire them or build them, then flip the row #21277 is ruled, the skill owes one sentence on what the runtime enforces and refuses; that is the follow-up triage already sequenced.维护者速读(草稿)
skills/objectstack-ai/SKILL.md两句。①ToolSchema段里outputSchema的括注:不再说「顶层键被折进工具描述、输出不校验」,改为「tool 记录上没人读它;把 schema 写在 action 的ai.outputSchema,AI 运行时 ☁️ 会扣住不合规的返回值」。② 常见陷阱第 1 条:不再把guardrails列为「只声明、运行时不读」,改为「每个用户回合由 AI 运行时 ☁️ 强制(token/时间上限;封禁的工具名与类别被拒),但它是限额不是审批」;memory仍写为只声明。235c5b29/cb62c3ea起已是假话,会把 AI 作者引离一个已经生效的控制,或让它以为 tool 上的outputSchema有人读。写给 AI 的 skill 说错一句等于产品缺陷。每句新话只说 ai:guardrails,memory,structuredOutput,lifecycleandtool.outputSchemaare enforced by the agent runtime (5 keys), starting with the guardrails the built-in agents already declare #20274 上 cloud 读数(5940785002、5943158888)证明了的事,不多说一字。structuredOutput一词从「只声明」枚举中删去但未写任何新语义,等 spec(ai):agent.structuredOutputis now enforced by cloud, which refuses four authorable members (regex/grammar/xmlformats, thecoerce_typesstep) — retire them or build them, then flip the row #21277 裁决后再补一句。回滚即 revert 本 PR 的一个 commit。skills/**)。需要你的 APPROVED review;批后由席位落地,不需要你动手合并。Generated by Claude Code