Repository navigation
fix(spec): the tool.requiresConfirmation guidance names the one pair REST /actions asks ai.exposed of - #33056
Conversation
…REST /actions asks ai.exposed of The rejection prescription said REST /actions is never ai.exposed-gated. That route now asks the opt-in of an AI service account starting a runAs: 'system' flow action, with no confirmation asked there; the bound now says so. The permissions system-context table's flow-start row names the same rule. Text only; no accept-set change. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibyxGyX6L3NhaTF6yiA
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibyxGyX6L3NhaTF6yiA
📓 Docs Drift CheckThis PR changes 1 package(s): 3 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
What this run could not see
Coarse fallback — 171 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin d67edaf6ddbffc0c6bc4a64ed09c107e4895d6f3 && git checkout d67edaf6ddbffc0c6bc4a64ed09c107e4895d6f3
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 157051ceb48d2d9ed289f21f7018a39ce7249178 a8f3da02c48a08873d486c6bfbfaae2e940789f6 && git checkout -B drift-repro 157051ceb48d2d9ed289f21f7018a39ce7249178 && git merge --no-ff a8f3da02c48a08873d486c6bfbfaae2e940789f6
node scripts/docs-audit/affected-docs.mjs --json 157051ceb48d2d9ed289f21f7018a39ce7249178
|
…ames the REST ai.exposed pair Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibyxGyX6L3NhaTF6yiA
|
domain:spec#2 · os-tesla · session_01L9qibvfX5bawZKtfa6u7j9 Contract reviewServed-tier: ① Derived judgments
② Semver level
③ Boundary flags
④ Design judgment
Docs row 57 — agrees with the tree ( Against ruling C (6812617393), ADR-0151 and PR #32912: no sentence contradicts them; nothing widens or narrows a door. Implemented-by: VERDICT: PASS — one should-fix (S1) earns a delta review of its fix; two nits; conditional on |
… a person's or on-behalf call Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibyxGyX6L3NhaTF6yiA
|
domain:spec#2 · os-tesla · session_01L9qibvfX5bawZKtfa6u7j9 Contract reviewDelta round of record 6846718400 Served-tier: ① Derived judgments
② Semver levelUnchanged: ③ Boundary flagsNothing new. Item 2 of the card is neither implemented nor decided. The escalation in record 6846718400 stands: item 2's premise is overtaken by the tree, which already refuses an AI service account 428 at REST ④ Design judgment
No must-fix, no should-fix in the delta. Implemented-by: VERDICT: PASS |
|
domain:spec#2 · os-tesla · session_01L9qibvfX5bawZKtfa6u7j9 维护者速读
席位意见:可以落地。 席位核对ACCEPT · seat
|
Requested by Tesla · project thread
Part of #32924 (item 1 only; item 2, whether REST also asks
confirm: true, stays with the maintainer and keeps the card open)Clause-②: no
Metadata-protocol: none
Skills-docs: none owed —
skills/**never says REST/actionsis notai.exposed-gated (itsrequiresConfirmationhits teach the action-level flag and the tool-level removal, both still true); incontent/docs/**the only stale spot waspermissions/system-context.mdxrow 57, fixed here.ui/actions.mdx(the'rest'posture row),ai/actions-as-tools.mdxandai/connect-mcp.mdxalready state the AI-service-account rules correctly.维护者速读
requiresConfirmation时报错里给作者的那段说明,原来说「REST/actions不读ai.exposed」;现在改为「只在一种情况下读:AI 服务账号经type: 'flow'动作启动runAs: 'system'的流程,此时只要求作者的 AI 授权,不要求确认」,其余照旧。权限文档 system-context 第 57 行补上这条 AI 服务账号规则;os migrate meta对已删除的工具requiresConfirmation给出的升级说明(17 版语义迁移条目)同样改正,并说明代表某个人的调用仍需作者自己把关、AI 服务账号自身在每道动作门都被拒。ai.exposed,原句随版本发出会误导写 AI 动作的作者。Clause-②: no);回滚即 revert。packages/spec/src/ai/tool.zod.ts(requiresConfirmation那段说明的第 (1) 条边界);packages/spec/src/migrations/entries/semantic/17.tool-requires-confirmation-retired.ts(replacement与验收说明两句);content/docs/permissions/system-context.mdx第 57 行。pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 src/ai/tool-confirmation-prescription-tense.pin.test.ts,应见全部通过。confirm: true)仍待你在卡上定夺。What changes
The prescription.
TOOL_RETIRED_KEY_GUIDANCE.requiresConfirmationinpackages/spec/src/ai/tool.zod.tsis the message an author meets when a tool still declaresrequiresConfirmation(the.strict()ToolSchemarejects it). Its first bound said REST/actions"is NOTai.exposed-gated". Since #32912 that is untrue for one pair. The bound now reads:The account rule that follows it (an AI service account never confirms for itself and is refused at every action door, REST included) is unchanged. The source comment above the entry names the runtime rule it now describes.
Both halves read off the code at
c54a23d2:packages/runtime/src/flow-start-admission.ts#flowStartRefusalrule 2,flow.runAs === 'system' && isAiServiceAccount(executionContext) && door.aiExposed !== true→403 PERMISSION_DENIED;dispatchFlowAction(action-execution.ts, shared by the REST actions route and MCPrun_action) hands{ aiExposed: actionIsAiExposed(action) }.domains/actions.tsruns the admitted sequence underposture: 'rest', andadmitResolvedActionasksactionConfirmationRefusalonly under'ai'or for an AI service account. The pinai/tool-confirmation-prescription-tense.pin.test.tsasserts that relation and stays green.Docs.
content/docs/permissions/system-context.mdxrow 57 (what the system principal bypasses at a flow start) gains the AI-service-account rule beside the elevated self-triggered start andrequiredPermissions(comment 6839421711). Prose only; the row's anchors and function list are unchanged.Generated artefacts. The describe string feeds none: it is a parse-error message, not a
.describe()on a schema field, so no JSON schema,content/docs/references/**page or authorable-surface shard carries it.check:generatedagainst a dist built from this head: all 14 artefacts up to date.The upgrade guidance (seat rework, file surface amended in comment 6846193569).
packages/spec/src/migrations/entries/semantic/17.tool-requires-confirmation-retired.ts, the entryos migrate metareports for a tool still carrying the key, carried the same sentence twice. Itsreplacement(printed alone byos migrate metaand the upgrade guide) now says REST/actionsreadsai.exposedonly of an AI service account starting arunAs: 'system'flow action (asking for the opt-in, not a confirmation) and sits outside the gate for a person's call or one an agent makes on a person's behalf, while an AI service account acting for itself is refused a gated action at every action door, REST/actionsincluded (contract review S1, record 6846718400). Its acceptance text says the same, and replaces "an agent holding an API key on that route is still yours to put a human in front of" with: the confirmation gate is not enforced there, so a person or an agent acting on a person's behalf on that route is still yours to put a human in front of (an AI service account acting for itself is refused a gated action at every action door; review N2 dropped "with an API key", since that principal is the OAuth-delegated client). No generated artefact carries the entry's text (check:generated,check:spec-changes,check:upgrade-guidegreen).Changeset.
.changeset/32924-requires-confirmation-describe.md,@objectstack/specpatch.Tests
No new test. The existing pin already ties this text to the runtime door in both directions, and it keeps passing with the rewording (
ai.exposedbound, REST/actionscarve-out, account rule,REST \/actions` included,unverifiable caller claim`). Prose only, so no ablation.Acceptance notes
ruling|Ruling-ref|maintainer|⛔):tool.zod.ts0 hits;system-context.mdxhits at rows 6b, 21, 23f, 31, 57, 62 and the ruling sections (L285, L316–337, L369, L446). Only row 57 is edited, and it cites ruling 6812617393 letter C, the ruling the new sentence restates.4379cff9(Test UI, TypeScript Type Check) were aggregator jobs readingcancelledshards and lanes after the rework push superseded that head; neither log holds a test or tsc failure.system-context.mdx; this PR touches row 57's text only.confirm: trueof an AI service account) is not implemented in either direction.Verification
All readings at head
a8f3da02.pnpm --filter @objectstack/spec build(lock VERDICT command-exit 0), thenpnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 src/migrations/ src/ai/: Test Files 21 passed (21), Tests 604 passed (604), includingtool-confirmation-prescription-tense.pin.test.tsandsemantic-relevance.test.ts.pnpm --filter @objectstack/cli exec vitest run --project integration --maxWorkers=2 test/migrate-meta-engine-guidance.test.ts(afterpnpm --filter @objectstack/cli build): Test Files 1 passed (1), Tests 3 passed (3).pnpm --filter @objectstack/spec run check:generated(against the dist built from this change): all 14 generated artefacts up to date; the working tree stayed clean.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack→ 103 families (the entry addscheck:spec-changes,check:upgrade-guide,check:cli-command-ids,check:query-options-erasure), all run with</dev/nullafter apnpm turbo run build --concurrency=2 --filter='./packages/**'(81/81), exit codes captured before any pipe; every one exit 0. Reconciliation--ran:103 derived famil(ies) accounted for — 103 run, 0 NOT-MEASURED (a DERIVED zero — all 103 recorded an exit code and none of them is 3).ToolSchema; no package parses its wording (the runtime pin reads the runtime, not this string), so no consumer test is owed beyond the spec pin.test:repoand the full farm are CI's.Gate record (103 lines)
🤖 Generated with Claude Code
https://claude.ai/code/session_01L9qibyxGyX6L3NhaTF6yiA