@sema-agent/sdk 24.0.0 โ 25.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +140 -3
- package/dist/client.d.ts +6 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +8 -1
- package/dist/client.js.map +1 -1
- package/dist/device/index.d.ts +76 -12
- package/dist/device/index.d.ts.map +1 -1
- package/dist/device/index.js +90 -33
- package/dist/device/index.js.map +1 -1
- package/dist/errors.d.ts +108 -8
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +34 -3
- package/dist/errors.js.map +1 -1
- package/dist/events.d.ts +40 -11
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +3 -2
- package/dist/events.js.map +1 -1
- package/dist/health.d.ts +25 -0
- package/dist/health.d.ts.map +1 -1
- package/dist/health.js.map +1 -1
- package/dist/index.d.ts +28 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -3
- package/dist/index.js.map +1 -1
- package/dist/model-route-env/index.d.ts +129 -0
- package/dist/model-route-env/index.d.ts.map +1 -0
- package/dist/model-route-env/index.js +131 -0
- package/dist/model-route-env/index.js.map +1 -0
- package/dist/resources/adoption.d.ts +8 -2
- package/dist/resources/adoption.d.ts.map +1 -1
- package/dist/resources/adoption.js.map +1 -1
- package/dist/resources/approvals.d.ts +22 -2
- package/dist/resources/approvals.d.ts.map +1 -1
- package/dist/resources/approvals.js +12 -2
- package/dist/resources/approvals.js.map +1 -1
- package/dist/resources/fleet.d.ts +65 -6
- package/dist/resources/fleet.d.ts.map +1 -1
- package/dist/resources/fleet.js.map +1 -1
- package/dist/resources/ops.d.ts +113 -0
- package/dist/resources/ops.d.ts.map +1 -1
- package/dist/resources/ops.js +10 -0
- package/dist/resources/ops.js.map +1 -1
- package/dist/resources/principal-inbox.d.ts +62 -0
- package/dist/resources/principal-inbox.d.ts.map +1 -0
- package/dist/resources/principal-inbox.js +51 -0
- package/dist/resources/principal-inbox.js.map +1 -0
- package/dist/resources/tool-approvals.d.ts +191 -16
- package/dist/resources/tool-approvals.d.ts.map +1 -1
- package/dist/resources/tool-approvals.js +183 -36
- package/dist/resources/tool-approvals.js.map +1 -1
- package/dist/settings.d.ts +70 -1
- package/dist/settings.d.ts.map +1 -1
- package/dist/sse.d.ts +5 -1
- package/dist/sse.d.ts.map +1 -1
- package/dist/sse.js +6 -2
- package/dist/sse.js.map +1 -1
- package/dist/types.d.ts +168 -15
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +5 -3
- package/dist/types.js.map +1 -1
- package/openapi.yaml +781 -44
- package/package.json +6 -2
package/openapi.yaml
CHANGED
|
@@ -3424,7 +3424,7 @@ paths:
|
|
|
3424
3424
|
`synced` (and `synced.count` still counts ONLY the durable queue).
|
|
3425
3425
|
๐ด THE TWO WORDS DELIBERATELY DO NOT REUSE `pending`/`resolved`: those are keyed by
|
|
3426
3426
|
`(sessionId, toolCallId)` and decided at `POST /v1/approvals/{sessionId}/decide`, while a live row is
|
|
3427
|
-
keyed by `approvalId` and decided at `POST /v1/tool-approvals/{
|
|
3427
|
+
keyed by `approvalId` and decided at `POST /v1/tool-approvals/{id}/respond`. Sharing one word
|
|
3428
3428
|
would eventually send a live card to the decide door โ a 404 with no wire evidence of the mistake.
|
|
3429
3429
|
โ ๏ธ Both live words come from an IN-PROCESS window projection, so their cross-replica reach is exactly
|
|
3430
3430
|
that of `GET /v1/approvals`'s `livePending` โ narrower than the durable pair above. The deployment
|
|
@@ -4393,6 +4393,38 @@ paths:
|
|
|
4393
4393
|
'404': { description: no pending question for this id (non-owner, answered, expired, or wrong replica) โ no existence oracle. }
|
|
4394
4394
|
'501': { description: AskUserQuestion is not enabled on this worker (ASK_QUESTION_ENABLED). }
|
|
4395
4395
|
|
|
4396
|
+
/v1/tool-approvals/{id}:
|
|
4397
|
+
parameters:
|
|
4398
|
+
- $ref: '#/components/parameters/PrincipalHeader'
|
|
4399
|
+
- { name: id, in: path, required: true, schema: { type: string }, description: 'The ask''s `approvalId` (server >= 7.133.0 always equal to its `askId`; an opaque string).' }
|
|
4400
|
+
get:
|
|
4401
|
+
tags: [questions]
|
|
4402
|
+
operationId: toolApprovalRead
|
|
4403
|
+
x-status: live # server >= 7.133.0; SDK toolApprovals.get consumes it
|
|
4404
|
+
summary: Read ONE live-card ask โ where is it now (pending, decided, parked or void)? Pure read.
|
|
4405
|
+
description: >
|
|
4406
|
+
server >= 7.133.0 โ the by-ask read door. Same root and same gate as POST /v1/tool-approvals/{id}/respond (one `gatedPrincipal`; an owner-gate miss answers the SAME 404 as an unknown
|
|
4407
|
+
id โ no existence oracle), and the state is read the way the answer door reads it: a live registration on THIS replica waiting for the ask => `pending` (the body is the `livePending[]` row projection +
|
|
4408
|
+
`state`); otherwise the row is read by id: `DECIDED` => `decided`, `PARKING` / `PARKED` => `parked`, `DENIED` / `VOID` => `void`. A row still `STREAM_PENDING` with no local registration lives on
|
|
4409
|
+
another replica => 404 `tool_approval.not_pending` + `cause: "unknown_or_other_replica"` (the same answer as a late respond); a deployment with no ask ledger answers the same 404 WITHOUT `cause`.
|
|
4410
|
+
Pure read: zero writes, no settlement, the local registration is untouched. Use it to ask "is this card still alive / was it decided by anyone" instead of inferring it from a respond 404.
|
|
4411
|
+
An older server (<= 7.132.x) has no such door: routing-level 404 `not_found.route` โ tell it apart from this door's 404 by `errorCode`, never by status.
|
|
4412
|
+
responses:
|
|
4413
|
+
'200':
|
|
4414
|
+
description: The ask's current state.
|
|
4415
|
+
content:
|
|
4416
|
+
application/json:
|
|
4417
|
+
schema: { $ref: '#/components/schemas/ToolApprovalReadBody' }
|
|
4418
|
+
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
4419
|
+
'404':
|
|
4420
|
+
description: >
|
|
4421
|
+
`tool_approval.not_pending` โ unknown / not yours (byte-identical) / still pending on another replica (`cause: unknown_or_other_replica`). Past the owner gate the body may carry the additive `cause`
|
|
4422
|
+
(see ToolApprovalNotPendingCause); no ask ledger => no `cause`.
|
|
4423
|
+
content:
|
|
4424
|
+
application/json:
|
|
4425
|
+
schema: { $ref: '#/components/schemas/ToolApprovalNotPendingBody' }
|
|
4426
|
+
'501': { description: 'Live tool-approval HITL not enabled (TOOL_APPROVAL_ENABLED) โ `feature.tool_approval_disabled`.' }
|
|
4427
|
+
|
|
4396
4428
|
/v1/tool-approvals/{id}/respond:
|
|
4397
4429
|
parameters:
|
|
4398
4430
|
- $ref: '#/components/parameters/PrincipalHeader'
|
|
@@ -5799,6 +5831,70 @@ paths:
|
|
|
5799
5831
|
'403': { description: 'Multi-tenant worker: outcomes view is operator-only.' }
|
|
5800
5832
|
'501': { $ref: '#/components/responses/NotImplemented' }
|
|
5801
5833
|
|
|
5834
|
+
/v1/config/catalog:
|
|
5835
|
+
parameters:
|
|
5836
|
+
- $ref: '#/components/parameters/PrincipalHeader'
|
|
5837
|
+
get:
|
|
5838
|
+
tags: [admin]
|
|
5839
|
+
operationId: configCatalog
|
|
5840
|
+
x-status: live # operator lane (capabilities.configCatalog); SDK configCatalog.get consumes it
|
|
5841
|
+
summary: Deployment configuration catalog โ every env knob's declaration and this process's effective reading (operator-only).
|
|
5842
|
+
description: >
|
|
5843
|
+
The deployment's configuration catalog (operator lane; probe `capabilities.configCatalog` first). One row per env knob: its declared semantics, which lanes can write it, which lane is in force, the
|
|
5844
|
+
process's effective DISPLAY value and the centre seat (`center`) when the knob is centre-publishable; plus the `retired` tombstone list (env names this process refuses to start on). `Cache-Control: no-store`.
|
|
5845
|
+
Gate: `OPERATOR_PRINCIPALS` โ outside the list 403 `auth.operator_only`; empty list on a multi-tenant deployment 501 `capability.operator_principals_required`; `CONFIG_CATALOG_ENABLED=false` 501
|
|
5846
|
+
`feature.config_catalog_disabled`. A server older than 7.53 has no such route (404).
|
|
5847
|
+
`effectiveValue` is a DISPLAY value, never the raw env: `secret` / `opaque` rows report only `{ present, length? }`, a `url` row goes through the display mint (userinfo landed, query values become
|
|
5848
|
+
tokens). Two VERDICT bits on a row are true-only (never `false`; ABSENT = this cell has no such matter): `effectiveValueInvalid` (the effective value falls outside the row's own echo set; `effectiveValue` is then
|
|
5849
|
+
`null`) and, server >= 7.133.0, `effectiveValueWithheld` (a `url` row whose display mint WITHHELD a part โ a credential-shaped piece in a query / path segment โ so the shown value is not the whole value).
|
|
5850
|
+
responses:
|
|
5851
|
+
'200':
|
|
5852
|
+
description: The catalog.
|
|
5853
|
+
content:
|
|
5854
|
+
application/json:
|
|
5855
|
+
schema: { $ref: '#/components/schemas/ConfigCatalog' }
|
|
5856
|
+
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
5857
|
+
'403': { description: 'The caller is not in OPERATOR_PRINCIPALS (`auth.operator_only`).' }
|
|
5858
|
+
'501': { $ref: '#/components/responses/NotImplemented' }
|
|
5859
|
+
|
|
5860
|
+
/v1/principal-inbox/messages:
|
|
5861
|
+
parameters:
|
|
5862
|
+
- $ref: '#/components/parameters/PrincipalHeader'
|
|
5863
|
+
post:
|
|
5864
|
+
tags: [admin]
|
|
5865
|
+
operationId: principalInboxSend
|
|
5866
|
+
x-status: live # server >= 7.133.0; SDK principalInbox.send consumes it
|
|
5867
|
+
summary: Deliver one letter to another principal's inbox in the same organization (cross-principal delivery; default OFF).
|
|
5868
|
+
description: >
|
|
5869
|
+
server >= 7.133.0 โ one letter is appended to the recipient principal's `principal.inbox` ONLY by the organization delivery gate: membership judgement -> mint -> inbox bound -> quota -> append, all inside one gate that answers
|
|
5870
|
+
with a receipt or one of four refusal codes. The SENDER is always your verified identity (`from` is not a body key: sending `from` or any unknown key => 400 `request.body_shape` + `unknownKeys`). DEFAULT OFF: without env
|
|
5871
|
+
`PRINCIPAL_INBOX_ASSISTANT` the route answers 501 `capability.unavailable` (no delivery gate is mounted) โ probe `capabilities.principalInboxDelivery` (true <=> this door works). THIS VERSION SHIPS THE DELIVERY HALF ONLY:
|
|
5872
|
+
a delivered letter sits in the recipient's box (at most 50 unconfirmed envelopes) and no read verb exists yet. Judging order: the sender's ATTEMPT bound (every attempt is recorded, succeeded or not, BEFORE membership) ->
|
|
5873
|
+
membership (including the mailbox-key judge) -> mint (a sender that cannot be spelled into the envelope's sender slot answers the same `not_member`, no quota consumed) -> inbox bound -> quota deduction -> append. A refused
|
|
5874
|
+
delivery appends nothing. Not auto-retried by the SDK (every attempt consumes the sender's attempt quota).
|
|
5875
|
+
The four refusal codes: `org_delivery.not_member` 404 (ONE sentence, byte-identical body for: different organization / no such person / directory could not answer / `to` is not a principal shape / the recipient cannot be a
|
|
5876
|
+
mailbox key / the sender cannot be spelled into the envelope โ the gate is never an existence probe); `org_delivery.rate_limited` 429 (one sentence for three bounds: 60 attempts per sender per hour โ a typo'd recipient costs an
|
|
5877
|
+
attempt โ, 10 letters per (sender, recipient) pair per hour, 30 letters per recipient per hour; fixed clock-hour windows, up to double across a boundary; hard-coded, no knob); `org_delivery.inbox_full` 409 (the recipient's box already holds
|
|
5878
|
+
50 unconfirmed envelopes โ judged BEFORE quota so a full box burns none); `org_delivery.recipient_tombstoned` 410 (the recipient's mailbox is in its pre-delete state).
|
|
5879
|
+
requestBody:
|
|
5880
|
+
required: true
|
|
5881
|
+
content:
|
|
5882
|
+
application/json:
|
|
5883
|
+
schema: { $ref: '#/components/schemas/PrincipalInboxMessage' }
|
|
5884
|
+
responses:
|
|
5885
|
+
'200':
|
|
5886
|
+
description: The letter was appended; `receiptId` is the gate's delivery receipt id.
|
|
5887
|
+
content:
|
|
5888
|
+
application/json:
|
|
5889
|
+
schema: { $ref: '#/components/schemas/PrincipalInboxReceipt' }
|
|
5890
|
+
'400': { description: 'Malformed body: `request.field_invalid` (not an object / empty `to` / empty or over-long `content` / non-boolean `urgent`) or `request.body_shape` (unknown key incl. `from`; body carries `unknownKeys`).' }
|
|
5891
|
+
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
5892
|
+
'404': { description: '`org_delivery.not_member` โ one byte-identical body for six causes (see the description); the gate is not an existence probe.' }
|
|
5893
|
+
'409': { description: '`org_delivery.inbox_full` โ the recipient''s box holds 50 unconfirmed envelopes.' }
|
|
5894
|
+
'410': { description: '`org_delivery.recipient_tombstoned` โ the recipient''s mailbox is in its pre-delete state.' }
|
|
5895
|
+
'429': { description: '`org_delivery.rate_limited` โ one sentence for the sender-attempt bound, the pair bound and the recipient aggregate bound.' }
|
|
5896
|
+
'501': { description: 'No delivery gate mounted (`PRINCIPAL_INBOX_ASSISTANT` off) โ `capability.unavailable`.' }
|
|
5897
|
+
|
|
5802
5898
|
/v1/diagnostics/wiring:
|
|
5803
5899
|
parameters:
|
|
5804
5900
|
- $ref: '#/components/parameters/PrincipalHeader'
|
|
@@ -7064,6 +7160,7 @@ components:
|
|
|
7064
7160
|
promptSummary: { type: string, description: 'a human-readable prompt DIGEST โ NOT the full prompt.' }
|
|
7065
7161
|
enabled: { type: boolean }
|
|
7066
7162
|
available: { type: boolean, description: 'whether this deployment can actually RUN the scenario right now โ same predicate as the 501 rejection arm on submit; false โบ submitting is guaranteed to 501. Independent axis from `enabled` (declared vs runnable).' }
|
|
7163
|
+
attachmentSupplies: { type: array, items: { type: string, enum: [path, content_text, content_image] }, description: 'server >= 7.133.0, always present there: the attachment SUPPLY words this scenario actually carries โ a subset of `capabilities.userAttachments.supplies` (`path` only on hands scenarios, where a workspace lives somewhere; a no-hands scenario drops `path`, and a `path` entry is refused by the engine with `config.user_attachment_invalid`). ABSENT = server <= 7.132.x: fall back to `userAttachments.supplies` plus the existing 400 handling.' }
|
|
7067
7164
|
unavailableReason: { type: string, description: 'machine-readable reason, present ONLY when available:false (absent = no reason). Closed set, currently the single member `git_client_unconfigured`; branch on the key, never match the English prose. Additive-open: treat an unknown word as "unavailable, reason unknown".' }
|
|
7068
7165
|
|
|
7069
7166
|
RunStatus:
|
|
@@ -7704,11 +7801,20 @@ components:
|
|
|
7704
7801
|
`permissions.defaultMode`'s specific fold is documented on `TaskRequest.permissionMode`.
|
|
7705
7802
|
๐ด ON THIS SUBMIT FACE THE KEY SET IS CLOSED (server >= 7.57.0 for the sub-tree): accepted top-level keys
|
|
7706
7803
|
are `env` / `hooks` / `model` / `outputStyle` / `permissions` / `skillListingBudgetFraction` /
|
|
7707
|
-
`skillListingMaxDescChars` / `ultracode` / `webSearch
|
|
7708
|
-
`allow` / `ask` / `defaultMode` / `deny` / `disableAutoMode
|
|
7804
|
+
`skillListingMaxDescChars` / `ultracode` / `webSearch` (server >= 7.133.0 adds the three TIGHTEN-ONLY seats `complianceAdditionalDenies` / `readDenyPatterns` / `writeProtectedExtra`), and accepted `permissions.*` keys are
|
|
7805
|
+
`allow` / `ask` / `defaultMode` / `deny` / `disableAutoMode` (server >= 7.133.0 adds `neverAuto`); anything else is 400 `request.body_shape`
|
|
7709
7806
|
with the names in the refusal's `unknownKeys` / `unsupportedKeys` arrays (REFUSED, not dropped โ a dropped
|
|
7710
7807
|
key reads as "in effect" to the caller). The object stays OPEN here because the same `SemaSettings`
|
|
7711
7808
|
schema also serves the local `settings.json` wiring, where deferred CC keys are legal.
|
|
7809
|
+
๐ด TIGHTEN-ONLY SEATS (server >= 7.133.0; probe `capabilities.taskSettings.tightenOnlySeats`, an absent bit = an older server that answers 400 `request.body_shape` for these four keys): `readDenyPatterns` (entries: a bare
|
|
7810
|
+
pattern string, or `{ pattern, caseSensitive? }`), `writeProtectedExtra` (a bare name โ no `/` reads as `segment`, a `/` reads as `segment-run` โ or `{ name, kind: basename | segment | segment-run }`),
|
|
7811
|
+
`complianceAdditionalDenies` (`mcp_servers` | `workflows` | `web_fetch` | `org_memory_mount`) and `permissions.neverAuto` (tool names that ALWAYS ask a human). Each seat = the deployment table UNION the request list, ONLY EVER GROWING
|
|
7812
|
+
(the request face has no loosening arm); an empty array is the same as not sent. Bad value => 400 `request.field_invalid` with `field` + `reason` (`over_cap` + `count` + `cap` / `bad_entry` + the first bad `index`).
|
|
7813
|
+
Caps: 1000 entries per seat, EXCEPT `readDenyPatterns`: at most 32 entries, at most 2 `*` per path segment and 16 `*` in the whole table (every star counts, nothing is folded). A `neverAuto` name that can never match any tool => 422.
|
|
7814
|
+
A resume replay of a stored body whose seat went bad => 409 `resume_blocked_by_policy`. A compliance deny is a REFUSAL, not a narrowing: a request denying `web_fetch` is refused whole where the default tool surface still mounts `WebFetch` (the single-user default does).
|
|
7815
|
+
๐ด `settings.hooks[]` (server >= 7.133.0; probe `capabilities.taskSettings.pluginHooks` / `managedHookGroups` โ an absent or false bit = the keys are STRIPPED SILENTLY): group key `source` (closed: `managedPolicy` / `user` / `project` / `local` / `flag` /
|
|
7816
|
+
`managedPlugin:<name>` / `plugin:<name>`; absent = unmanaged; managed groups run in an independent lane after the unmanaged rewrites), command-entry keys `plugin { name, root, dataDir?, options? }` and exec-form `args`; a malformed one =>
|
|
7817
|
+
400 `request.field_invalid` with `detail: { reason: "wire_key_invalid", key, path }`; the plugin context has one 8192-character budget.
|
|
7712
7818
|
๐ด `skillListingBudgetFraction` (number in (0,1]) / `skillListingMaxDescChars` (positive integer),
|
|
7713
7819
|
server >= 7.78.1: the SKILL-LISTING RENDER BUDGET, passed to the engine with ZERO processing
|
|
7714
7820
|
(no clamping, no conversion, no folding) โ ABSENT means the key is not written at all (the server does
|
|
@@ -8374,6 +8480,10 @@ components:
|
|
|
8374
8480
|
cause (`terminal`), not the eight parallel plane keys โ see `TerminalCause`.
|
|
8375
8481
|
required: [taskId, sessionId, terminal, stats]
|
|
8376
8482
|
properties:
|
|
8483
|
+
warnings:
|
|
8484
|
+
type: array
|
|
8485
|
+
items: { $ref: '#/components/schemas/EntryProblem' }
|
|
8486
|
+
description: 'server >= 7.133.0, top level of the sync `POST /v1/tasks` 200 body (beside `notice`), present only when non-empty: the accept-time NOTICES for allow-side selector-list entries the engine reads as nothing or that are not in the roster. ABSENT = no notice (older servers too).'
|
|
8377
8487
|
taskId: { type: string }
|
|
8378
8488
|
sessionId: { type: string }
|
|
8379
8489
|
wiringManifest:
|
|
@@ -8676,6 +8786,10 @@ components:
|
|
|
8676
8786
|
taskId: { type: string }
|
|
8677
8787
|
sessionId: { type: string }
|
|
8678
8788
|
status: { $ref: '#/components/schemas/RunStatus' }
|
|
8789
|
+
warnings:
|
|
8790
|
+
type: array
|
|
8791
|
+
items: { $ref: '#/components/schemas/EntryProblem' }
|
|
8792
|
+
description: 'server >= 7.133.0, present only when non-empty: the accept-time NOTICES for allow-side selector-list entries the engine reads as nothing or that are not in the roster (acceptance is unchanged โ the engine takes them, only the operator hears afterwards; this makes "this name will not take effect" visible at the call). Same list as the stream `meta` frame''s and the sync 200 body''s. ABSENT = no notice (older servers too).'
|
|
8679
8793
|
|
|
8680
8794
|
SealedKeyCapability:
|
|
8681
8795
|
type: object
|
|
@@ -9803,6 +9917,11 @@ components:
|
|
|
9803
9917
|
store backend deliberately wires no image index (the pool is cloud/fleet-only) โ false there.
|
|
9804
9918
|
SCOPE: P1 only โ `/v1/images/bakes*` (the P2 bake control plane) is a separate dependency and an
|
|
9805
9919
|
operator/runner-internal face, NOT promised by this bit.
|
|
9920
|
+
principalInboxDelivery:
|
|
9921
|
+
type: boolean
|
|
9922
|
+
description: >-
|
|
9923
|
+
server >= 7.133.0 โ the cross-principal delivery door `POST /v1/principal-inbox/messages` is wired (delivery gate present: env `PRINCIPAL_INBOX_ASSISTANT` on and the gate's dependencies in place).
|
|
9924
|
+
True iff that route works; absent gate => the route answers 501 `capability.unavailable`. ABSENT key = server <= 7.132.x (no such route; routing-level 404). Probe this bit; do not trial-by-501.
|
|
9806
9925
|
sharedMemory:
|
|
9807
9926
|
type: boolean
|
|
9808
9927
|
description: >
|
|
@@ -9973,6 +10092,12 @@ components:
|
|
|
9973
10092
|
lane) or 422 (hosted).
|
|
9974
10093
|
mcp: { type: boolean, description: "MCP servers can be attached." }
|
|
9975
10094
|
mcpInjection: { type: boolean, description: "Per-request MCP injection is accepted." }
|
|
10095
|
+
mcpAssertionHeaderSent:
|
|
10096
|
+
type: boolean
|
|
10097
|
+
description: >-
|
|
10098
|
+
server >= 7.133.0 โ the SEND seat self-report (a boolean, today ALWAYS `false`): whether `mcpServers[].transport.assertionHeader` (accepted since server 7.128.0, mutually exclusive with `principalHeader`)
|
|
10099
|
+
is actually SENT to the MCP peer. `false` = the declaration is carried but NOT sent (the same switch drives the key stripping, the operator info line and the probe-door refusal; the disclosure sentences leave when it turns true).
|
|
10100
|
+
ABSENT = an older server, which does not send either โ treat it as `false`; never rely on the header for peer authentication.
|
|
9976
10101
|
mcpProbe:
|
|
9977
10102
|
type: boolean
|
|
9978
10103
|
description: >
|
|
@@ -10012,6 +10137,17 @@ components:
|
|
|
10012
10137
|
โ ๏ธ ABSENT = an older server (<7.87.1) โ cannot tell whether the push face carries the live family;
|
|
10013
10138
|
do NOT read "no `live_pending` frame arrived yet" as "this deployment never pushes live" โ the two
|
|
10014
10139
|
are indistinguishable on an older server. Fall back to `GET /v1/approvals`'s `livePending` pull face.
|
|
10140
|
+
approvalFrameFamilies:
|
|
10141
|
+
type: array
|
|
10142
|
+
maxItems: 1
|
|
10143
|
+
items: { type: string, enum: [tool_approval, approval_request] }
|
|
10144
|
+
description: >-
|
|
10145
|
+
server >= 7.133.0, ALWAYS present (the projection of the same judgement as `streamApproval`) โ which FRAME FAMILY this worker's approval opening frames belong to:
|
|
10146
|
+
a closed-word array with AT MOST ONE member. `["approval_request"]` = the card protocol is on: one ask travels only `approval_request` -> `approval_complete` / `approval_revoke`
|
|
10147
|
+
(the legacy `tool_approval` / `tool_approval_complete` pair is NOT sent โ BREAKING vs <= 7.132.x, which sent both families for one ask and relied on `approvalId` de-duplication;
|
|
10148
|
+
remedy on the worker: `STREAM_APPROVAL_ENABLED=false`). `["tool_approval"]` = the card protocol is not on (`STREAM_APPROVAL_ENABLED=false`, no store backend, or no checkpoint store) but the live card leg is.
|
|
10149
|
+
`[]` = per-call approvals are off altogether (`TOOL_APPROVAL_ENABLED=false`): no card is presented. Dispatch frame families off THIS array, never off `streamApproval`.
|
|
10150
|
+
KEY ABSENT (not `[]`) = server <= 7.132.x โ there a `streamApproval: true` leg sends BOTH families for one ask.
|
|
10015
10151
|
streamApproval:
|
|
10016
10152
|
type: boolean
|
|
10017
10153
|
description: >
|
|
@@ -10066,6 +10202,13 @@ components:
|
|
|
10066
10202
|
a server <= 7.118.x returns the archive as written; a 7.119.x server already redacts but does not report the bit. A true
|
|
10067
10203
|
bit does not mean the read face exists (that is `sessions`; without a session audit face that door answers 501 and this
|
|
10068
10204
|
bit is still true), nor that the archive holds no credential (the redaction is read-side only).
|
|
10205
|
+
approvalReadRootGrant:
|
|
10206
|
+
type: boolean
|
|
10207
|
+
description: >-
|
|
10208
|
+
server >= 7.133.0, ALWAYS present, a FACT that varies by deployment โ whether this deployment accepts the reply-body key `readRootGrant` ("Yes, and add directory": the card's
|
|
10209
|
+
`readRootCandidate.dir` is registered as a read root together with this one allow). True iff the single-user host-lane posture (the same predicate as `projectContext` / the cwd face); false elsewhere.
|
|
10210
|
+
A client shows the option only when the card carries `readRootCandidate` AND this bit is true. On a non-accepting posture a reply carrying `readRootGrant` is refused
|
|
10211
|
+
`400 request.body_shape` (the ask stays unsettled โ answer again without the key). ABSENT = server <= 7.132.x = not accepted; do not send the key.
|
|
10069
10212
|
approvalReach:
|
|
10070
10213
|
type: boolean
|
|
10071
10214
|
description: >-
|
|
@@ -10178,6 +10321,9 @@ components:
|
|
|
10178
10321
|
outputStyle: { type: boolean }
|
|
10179
10322
|
env: { type: boolean, description: 'TRUE on the single-user host lane (server emits `cwdHonored(config)`). It is NOT hard-coded false any more โ the old always-false value predated the per-task shellEnv seam and hid a live capability.' }
|
|
10180
10323
|
hooks: { type: boolean, description: 'Single-user deployments only (`requirePrincipal !== true`).' }
|
|
10324
|
+
pluginHooks: { type: boolean, description: 'server >= 7.133.0 โ the request `settings.hooks[]` PLUGIN-CONTEXT keys (command entry `plugin { name, root, dataDir?, options? }` / exec-form `args`) are accepted; same predicate as `hooks` (single-user true, multi-tenant false). ABSENT or false = the keys are stripped silently โ send only on sight of the bit.' }
|
|
10325
|
+
managedHookGroups: { type: boolean, description: 'server >= 7.133.0 โ the request `settings.hooks[]` GROUP `source` key (managed lanes `managedPolicy` / `managedPlugin:<name>`) is accepted; same predicate as `hooks`. ABSENT or false = stripped silently (the managed-lane semantics do not apply, it is not a refusal).' }
|
|
10326
|
+
tightenOnlySeats: { type: boolean, description: 'server >= 7.133.0, constant true โ the four tighten-only request seats `settings.readDenyPatterns` / `settings.writeProtectedExtra` / `settings.complianceAdditionalDenies` / `settings.permissions.neverAuto` are accepted (each seat = deployment table UNION request list, only ever growing; an empty array is the same as not sent). ABSENT = server <= 7.132.x, which answers 400 `request.body_shape` for those keys โ send only on sight of the bit.' }
|
|
10181
10327
|
settings:
|
|
10182
10328
|
type: object
|
|
10183
10329
|
description: >
|
|
@@ -10206,6 +10352,7 @@ components:
|
|
|
10206
10352
|
properties:
|
|
10207
10353
|
allowGrant: { type: boolean, description: 'Constant `true` on server >= 7.115.0: `settings.permissions.allow` is read as allow RULES, not as a list. The whole `settings` key being absent = an older server.' }
|
|
10208
10354
|
allowLayer: { type: boolean, description: 'Constant `true` on server >= 7.117.0 (core 7.42.0): the whole `settings.permissions.allow` list goes to the engine allow layer (listed calls are not asked; content forms accepted; entries read as nothing get an `engine_notice` `permission.allowed_tool_not_granted`). Absent = a server without it (7.115.0โ7.116.x: allow is a statement; older: a list).' }
|
|
10355
|
+
callerTrust: { type: string, description: 'server >= 7.133.0 โ THIS caller''s trust tier (per caller / per credential, NOT a version bit). Request rule tables that take effect without a person answering (`settings.permissions` buckets; a named-invoked skill''s `allowedTools` / `disallowedTools`) are admitted by it: `allow` loosens the no-ask surface and needs `global`; `deny` / `ask` only tighten and are admitted at any tier. Today `global` (single-user turnkey; multi-tenant with the deployment service credential; multi-tenant sign-in token whose scope role >= the governance write role) or `project` (everything else). Read OPEN: an unknown word is treated as `project` (fail-closed). A request below the floor is refused whole with 400 `request.field_invalid` (`detail.problems[].reason: below_trust_floor`, `detail.callerTrust`). ABSENT = server <= 7.132.x: no per-tier admission.' }
|
|
10209
10356
|
memoryWrite:
|
|
10210
10357
|
type: boolean
|
|
10211
10358
|
description: >
|
|
@@ -10268,7 +10415,7 @@ components:
|
|
|
10268
10415
|
additionalProperties: true
|
|
10269
10416
|
properties:
|
|
10270
10417
|
enabled: { type: boolean, enum: [true] }
|
|
10271
|
-
protocolVersion: { type: integer }
|
|
10418
|
+
protocolVersion: { type: integer, description: 'The protocol REVISION this server speaks (the `challenge` frame carries the same value; accepted window [1, 2] on server >= 7.133.0). Server >= 7.133.0 reads 2 (<= 7.132.x read 1). An executor declares the SMALLER of its own highest revision and this value, and takes its outcome-code set from the declared revision (revision 2 added `liveness_no_output`).' }
|
|
10272
10419
|
maxInflightPerDevice: { type: integer }
|
|
10273
10420
|
wsPath: { type: string }
|
|
10274
10421
|
management: { type: boolean, description: 'server >= 7.88.0. `/v1/devices/*` admin verbs present. PRESENT-IFF โ absent means a pre-7.88.0 peer (unknown), not false.' }
|
|
@@ -10762,9 +10909,9 @@ components:
|
|
|
10762
10909
|
server >= 7.65.0 (S-167) โ the READ containment rung of this deployment AND WHO SET IT (operator face
|
|
10763
10910
|
`GET /v1/diagnostics/wiring` -> `readFace`). `face` is the same boot artefact as the tenant-facing
|
|
10764
10911
|
`capabilities.readFace` (`null` = nothing pinned by this deployment, the engine default is in force).
|
|
10765
|
-
`source` is a CLOSED
|
|
10912
|
+
`source` is a CLOSED five-word set on the server (exhaustive switch โ adding a word is a compile error
|
|
10766
10913
|
there): `env` = this machine's READ_FACE env var (wins over everything) ยท `center` = the config-center
|
|
10767
|
-
readFace domain (restart-to-apply) ยท `posture` = derived from the single-user turnkey posture
|
|
10914
|
+
readFace domain (restart-to-apply) ยท `lane` = (server >= 7.133.0) the isolated execution lane's default โ with `READ_FACE` absent, e2b / k8s / local-docker mint `open` ยท `posture` = derived from the single-user turnkey posture
|
|
10768
10915
|
(REQUIRE_PRINCIPAL unset โ `open`; server >= 7.65.0 behaviour change) ยท `engine-default` = not pinned.
|
|
10769
10916
|
`note` is a human-facing pointer for operators. Minimal disclosure: the deny table is never on this face.
|
|
10770
10917
|
required: [face, source, note]
|
|
@@ -10774,7 +10921,7 @@ components:
|
|
|
10774
10921
|
enum: [open, roots, null]
|
|
10775
10922
|
source:
|
|
10776
10923
|
type: string
|
|
10777
|
-
enum: [env, center, posture, engine-default]
|
|
10924
|
+
enum: [env, center, lane, posture, engine-default]
|
|
10778
10925
|
note:
|
|
10779
10926
|
type: string
|
|
10780
10927
|
|
|
@@ -10791,9 +10938,9 @@ components:
|
|
|
10791
10938
|
`DURABLE_APPROVAL` ON and a 24h approval window when neither is set, so a default FLIP has to be visible
|
|
10792
10939
|
on an operator surface or nobody sees it.
|
|
10793
10940
|
|
|
10794
|
-
`source` is the CLOSED
|
|
10941
|
+
`source` is the CLOSED five-word set (exhaustive switch on the server โ adding a word is a compile error
|
|
10795
10942
|
there), in PRECEDENCE order: `env` = pinned by this machine's env var (deployment sovereignty; beats any
|
|
10796
|
-
published value) ยท `center` = applied from the config-center (restart-to-apply) ยท `posture` = derived from
|
|
10943
|
+
published value) ยท `center` = applied from the config-center (restart-to-apply) ยท `lane` = (server >= 7.133.0) derived from the isolated execution lane (e2b / k8s / local-docker mint a lane default, e.g. `READ_FACE` -> `open`) ยท `posture` = derived from
|
|
10797
10944
|
the deployment shape (single-user turnkey) ยท `engine-default` = nothing pinned, the built-in default is in
|
|
10798
10945
|
force. Only `env`/`center` count as "an operator asked for this"; a posture-derived `true` does not.
|
|
10799
10946
|
`note` is PROSE for a human (per-knob, and on the `posture` arm it is that knob's own fact sentence) โ
|
|
@@ -10808,7 +10955,7 @@ components:
|
|
|
10808
10955
|
description: 'The knob''s effective value. Typed by the referencing site (boolean / integer / โฆ).'
|
|
10809
10956
|
source:
|
|
10810
10957
|
type: string
|
|
10811
|
-
enum: [env, center, posture, engine-default]
|
|
10958
|
+
enum: [env, center, lane, posture, engine-default]
|
|
10812
10959
|
note: { type: string }
|
|
10813
10960
|
|
|
10814
10961
|
SkillSpec:
|
|
@@ -11630,6 +11777,24 @@ components:
|
|
|
11630
11777
|
`"other"`). This is the "where did those 180 404s actually land" cell. Empty object = zero failures;
|
|
11631
11778
|
key absent = an older server.
|
|
11632
11779
|
|
|
11780
|
+
ModelPlane:
|
|
11781
|
+
type: object
|
|
11782
|
+
additionalProperties: false
|
|
11783
|
+
description: >
|
|
11784
|
+
`GET /v1/models.modelPlane` (server >= 7.133.0; always present; conditional keys are absent, never `null` / empty string) โ the single read for "which model table is this engine serving".
|
|
11785
|
+
Two axes. SERVED TABLE: `servedTable` = `env` (the env table minted from MODEL_ID / MODEL_CHEAP_ID โ no catalog is in charge: none configured / source unreachable with no last-known-good / the candidate was refused /
|
|
11786
|
+
no enabled entry) | `catalog` (a catalog's model plane landed and replaced the whole env table). CANDIDATE OUTCOME: `catalog` = `refused` (the latest candidate was refused whole โ by the candidate judge or the model-plane
|
|
11787
|
+
group; with no previous generation the env table serves, with one the catalog table still serves โ who serves is `servedTable`'s answer, NOT merged into this field) | `adopted` (no whole refusal and the catalog table
|
|
11788
|
+
serves; NOT "the latest candidate landed" โ that question belongs to the /health generation ledger) | `absent` (no whole refusal and the env table serves). START-UP ROUTE VERDICT: `refusalCode` / `gap` (both ABSENT when the
|
|
11789
|
+
judge passes โ the normal state of a running process): `refusalCode` = `config.model_route_endpoint_missing` | `config.gateway_fallback_without_primary`; `gap` = `endpoint_missing` (set MODEL_GATEWAY_BASEURL or the entry's
|
|
11790
|
+
own `baseUrl`) | `lane_credential_missing` (an anthropic-lane choice with neither ANTHROPIC_API_KEY nor ANTHROPIC_AUTH_TOKEN fell into the endpoint-less openai leg). No sentence is carried. Words are server-owned โ read OPEN
|
|
11791
|
+
(an unknown word is "unknown", never "passed").
|
|
11792
|
+
required: [servedTable, catalog]
|
|
11793
|
+
properties:
|
|
11794
|
+
servedTable: { type: string, description: '`env` | `catalog` (open on read).' }
|
|
11795
|
+
catalog: { type: string, description: '`absent` | `adopted` | `refused` (open on read).' }
|
|
11796
|
+
refusalCode: { type: string, description: '`config.model_route_endpoint_missing` | `config.gateway_fallback_without_primary` (open on read); ABSENT = the judge passed.' }
|
|
11797
|
+
gap: { type: string, description: '`endpoint_missing` | `lane_credential_missing` (open on read); ABSENT = the judge passed.' }
|
|
11633
11798
|
ModelsResponse:
|
|
11634
11799
|
type: object
|
|
11635
11800
|
description: >
|
|
@@ -11677,6 +11842,11 @@ components:
|
|
|
11677
11842
|
Upgrade window (as it is): an on-disk LKG written by server <= 7.122.x only recorded the dropped entries that had a name AND were
|
|
11678
11843
|
enabled; while serving from it with the center still unreachable this key lists only those rows (possibly `[]`) and the first pull after the
|
|
11679
11844
|
center is reachable fills it in. An unknown `reasonCode` word reads as "dropped, reason unknown".
|
|
11845
|
+
modelPlane:
|
|
11846
|
+
allOf: [{ $ref: '#/components/schemas/ModelPlane' }]
|
|
11847
|
+
description: >-
|
|
11848
|
+
server >= 7.133.0, ALWAYS present there (appended last): which model table this engine SERVES, whether the catalog was adopted, and what the start-up route judge says โ read this instead of predicting
|
|
11849
|
+
(the judge's inputs are the serving process's facts; mirroring two of its judgements drifts). ABSENT = an earlier server (<= 7.132.x). Field reading: ModelPlane.
|
|
11680
11850
|
candidateRejected:
|
|
11681
11851
|
allOf: [{ $ref: '#/components/schemas/CandidateRejected' }]
|
|
11682
11852
|
description: >
|
|
@@ -12898,14 +13068,14 @@ components:
|
|
|
12898
13068
|
ts: { type: integer }
|
|
12899
13069
|
FleetFrame_hook_notice:
|
|
12900
13070
|
description: >
|
|
12901
|
-
Hook observability frame,
|
|
13071
|
+
Hook observability frame, FOUR kinds (server >= 7.133.0 added the third and fourth; all pure observe โ never block, resume, or inject anything;
|
|
12902
13072
|
visibility fail-CLOSED like bg_notification: the owner keys ownerScope/ownerSessionId gate delivery
|
|
12903
13073
|
and are STRIPPED before send; wire is FLAT โ `send("hook_notice", { type, ...wire, ts })`, the
|
|
12904
13074
|
server-internal `{notice}` nesting never reaches it). codex R1-F4: modeled as the discriminated union
|
|
12905
13075
|
it really is โ the common `{type, ts}` frame base composed with each kind's payload arm โ so a
|
|
12906
13076
|
generated client gets the SAME per-kind narrowing as the TS type (a second-family frame missing
|
|
12907
|
-
hookName/entryType is invalid, not silently accepted). `kind` is CLOSED
|
|
12908
|
-
OPEN ON READ: degrade an unknown future kind to a generic observability row.
|
|
13077
|
+
hookName/entryType is invalid, not silently accepted). `kind` is CLOSED four-member on the server but
|
|
13078
|
+
OPEN ON READ: degrade an unknown future kind to a generic observability row. DISPATCH on `kind`; never infer a call's outcome from any hook_notice frame (read the tool / approval frames).
|
|
12909
13079
|
oneOf:
|
|
12910
13080
|
- allOf:
|
|
12911
13081
|
- $ref: '#/components/schemas/FleetHookNoticeFrameBase'
|
|
@@ -12913,10 +13083,16 @@ components:
|
|
|
12913
13083
|
- allOf:
|
|
12914
13084
|
- $ref: '#/components/schemas/FleetHookNoticeFrameBase'
|
|
12915
13085
|
- $ref: '#/components/schemas/FleetHookNonBlockingFailure'
|
|
13086
|
+
- allOf:
|
|
13087
|
+
- $ref: '#/components/schemas/FleetHookNoticeFrameBase'
|
|
13088
|
+
- $ref: '#/components/schemas/FleetHookManagedUnrun'
|
|
13089
|
+
- allOf:
|
|
13090
|
+
- $ref: '#/components/schemas/FleetHookNoticeFrameBase'
|
|
13091
|
+
- $ref: '#/components/schemas/FleetHookVerdictUntrusted'
|
|
12916
13092
|
|
|
12917
13093
|
FleetHookNoticeFrameBase:
|
|
12918
13094
|
type: object
|
|
12919
|
-
description: 'The hook_notice frame envelope shared by
|
|
13095
|
+
description: 'The hook_notice frame envelope shared by all four kinds: the SSE frame discriminant and the server timestamp.'
|
|
12920
13096
|
required: [type, ts]
|
|
12921
13097
|
properties:
|
|
12922
13098
|
type: { const: hook_notice }
|
|
@@ -12965,7 +13141,7 @@ components:
|
|
|
12965
13141
|
# #315(server โฅ7.43):็ฌฌไบ้กถๅฑ้ฎ `livePending` = streamApproval ็ชๅ
็ๆตๅ
ask(ๆญคๅๅฏน่ฝฎ่ฏขๆถ่ดน็ซฏ
|
|
12966
13142
|
# ็ปๆๆงไธๅฏ่ง)ใADDITIVE / tolerate-absent:้ฎ็ผบๅธญ=ใๅ่ฐๅจๆช่ฃ
้
(ๆฌ้จ็ฝฒๆ live ๅฎกๆน้ข)ใๆ
|
|
12967
13143
|
# ๆง server;็ฉบๆฐ็ป=ใๆ้ขใๆญคๅปๆ ๅพ
ๆนใโโไธคไนๅฏๅคๅซ,ๆถ่ดน็ซฏๆต presenceใ**ๅๆฐ็ปไธๆทท็ผ**:
|
|
12968
|
-
# live ่ก็ๅณ่ฎฎๅฃ=POST /v1/tool-approvals/{
|
|
13144
|
+
# live ่ก็ๅณ่ฎฎๅฃ=POST /v1/tool-approvals/{id}/respond,durable ่ก=decide ๅฃ;ๆฐ็ปๅๅณ่ทฏ็ฑๅคๆฎใ
|
|
12969
13145
|
# 22.0.0:็ฌฌไธใๅ้กถๅฑ้ฎๆญคๅๆผๅฃฐๆ โโ ๅฐ้ญ schema ไธไธไธช็้ฎ = ๅๆณไฟกๅฐ่ขซไธฅๆ ผๆ ก้ชๅจๆๆถใ
|
|
12970
13146
|
additionalProperties: false
|
|
12971
13147
|
required: [pending]
|
|
@@ -13020,7 +13196,7 @@ components:
|
|
|
13020
13196
|
type: object
|
|
13021
13197
|
description: >-
|
|
13022
13198
|
A live (in-stream) pending ask inside its streamApproval window (#315, server โฅ7.43). Decide it via
|
|
13023
|
-
POST /v1/tool-approvals/{
|
|
13199
|
+
POST /v1/tool-approvals/{id}/respond โ NOT the /decide route (that is the durable rows' door).
|
|
13024
13200
|
Optional flags are only-if-true (absent is NEVER encoded as false).
|
|
13025
13201
|
๐ด THE "tool input/args are NOT listed" NARROWING IS GONE (server >= 7.87.0 / S-454 P1). The old reason
|
|
13026
13202
|
was "details ride the stream frame" โ but a SUSPENDED ask never has a stream frame (at mint time it had
|
|
@@ -13038,7 +13214,15 @@ components:
|
|
|
13038
13214
|
additionalProperties: true
|
|
13039
13215
|
required: [approvalId, toolName, ts, expiresAtMs]
|
|
13040
13216
|
properties:
|
|
13041
|
-
approvalId: { type: string, description: 'The SAME id the respond endpoint takes (wire uuidv7
|
|
13217
|
+
approvalId: { type: string, description: 'The SAME id the respond endpoint takes. server >= 7.133.0: for an ask that has a ledger row it is ALWAYS the row''s key `askId` (a 64-character lowercase hexadecimal string โ an OPAQUE string, never a uuid); on <= 7.132.x a wire uuidv7.' }
|
|
13218
|
+
consumerState:
|
|
13219
|
+
type: string
|
|
13220
|
+
enum: [absent]
|
|
13221
|
+
description: >-
|
|
13222
|
+
server >= 7.133.0, TRUE-ONLY (present as `absent`): no engine leg on THIS replica is waiting for this ask. Present <=> the row was ADOPTED from the ask ledger at start-up (minted by a previous
|
|
13223
|
+
process / another replica, the row still undecided โ a "zombie card"): it lists and can be answered (the row becomes decided; the answer ack carries the same bit), but that decision resumes
|
|
13224
|
+
nothing running on this replica โ read the run surface to learn whether anything continued. The `live_pending` stream frame and the `pending` arm of GET /v1/tool-approvals/{id} carry it too. After a restart an
|
|
13225
|
+
ask still undecided on the ledger RETURNS to `livePending[]` (it used to vanish and answer 404). Absent = this replica has an engine leg waiting, or an older server.
|
|
13042
13226
|
toolName: { type: string }
|
|
13043
13227
|
ts: { type: number, description: 'Registration time (ms epoch).' }
|
|
13044
13228
|
expiresAtMs: { type: number, description: 'Absolute window deadline โ the SAME number minted once for the tool_approval frame (never recomputed).' }
|
|
@@ -13063,9 +13247,13 @@ components:
|
|
|
13063
13247
|
allOf: [{ $ref: '#/components/schemas/ToolApprovalCardWord' }]
|
|
13064
13248
|
description: 'server >= 7.126.0 (core 7.49.0 #1414): which card this ask renders on โ the engine-minted card word, the SAME value as `frame.approvalCard` (the row reads the frame''s own seat, no second read), same layer and shape as the operator queue row''s `approvalCard`. It REPLACES `contentKind` (server <= 7.125.x derived it from the tool name; deleted at 7.126.0, no alias). ABSENT = the engine minted none. Display / triage only; it NEVER takes part in decision routing.'
|
|
13065
13249
|
frame:
|
|
13066
|
-
|
|
13250
|
+
oneOf:
|
|
13251
|
+
- $ref: '#/components/schemas/ToolApprovalFrame'
|
|
13252
|
+
- $ref: '#/components/schemas/ApprovalRequestFrame'
|
|
13067
13253
|
description: >-
|
|
13068
|
-
server >= 7.87.0 (S-454 P1; cli L-397) โ THE CARD FRAME THIS ASK WOULD HAVE EMITTED.
|
|
13254
|
+
server >= 7.87.0 (S-454 P1; cli L-397) โ THE CARD FRAME THIS ASK WOULD HAVE EMITTED. TWO SHAPES, by leg (sdk 25.0.0 declares the union; discriminant
|
|
13255
|
+
`frame.type`): on a leg that speaks the card protocol (`capabilities.approvalFrameFamilies` contains `approval_request`, server >= 7.133.0) it is the
|
|
13256
|
+
`approval_request` frame (card facts under `frame.card`, the ten off-card live facts flat at the top); on a legacy-family leg it is the `tool_approval` frame. It is the SAME
|
|
13069
13257
|
OBJECT as the server's `PendingApproval.frame` (the one construction site in `askBroadcast`, already
|
|
13070
13258
|
redacted / byte-capped / window-keys filled), shared by the suspended and the reachable path โ so
|
|
13071
13259
|
this is NOT a second card projection computed for the list, and there is no second redaction surface.
|
|
@@ -13285,6 +13473,7 @@ components:
|
|
|
13285
13473
|
required: [sessionId, scope, createdAt]
|
|
13286
13474
|
additionalProperties: true
|
|
13287
13475
|
properties:
|
|
13476
|
+
checkpointId: { type: string, minLength: 1, maxLength: 128, description: 'server >= 7.133.0: the NON-SECRET stable identity of the pause this row parks on โ the join key where the token cannot go; the SAME value as `PausedCause.checkpointId`. Carried on three durable read surfaces (GET /v1/approvals `pending[]` rows, the /v1/approvals/stream `pending` frame, GET /v1/assistant/inbox rows). A row whose value is unreadable or untrusted (non-string / empty / over 128 / contains the token / an old row / an older server) is STILL LISTED with the key ABSENT โ read absence as "this row has no joinable identity", never as a required key.' }
|
|
13288
13477
|
sessionId: { type: string, description: 'The decide handle: POST /v1/approvals/:sessionId/decide.' }
|
|
13289
13478
|
scope: { type: string, description: 'Principal; "_" = submitted without one.' }
|
|
13290
13479
|
taskId: { type: ['string', 'null'], description: 'Suspended run holding the session claim (service-pinned) โ join key to trace tool-call blocks + context link.' }
|
|
@@ -13496,6 +13685,7 @@ components:
|
|
|
13496
13685
|
additionalProperties: false
|
|
13497
13686
|
properties:
|
|
13498
13687
|
sessionId: { type: string, description: 'The suspended task/session id.' }
|
|
13688
|
+
checkpointId: { type: string, minLength: 1, maxLength: 128, description: 'server >= 7.133.0: the NON-SECRET stable identity of the pause this row parks on โ the join key where the token cannot go; the SAME value as `PausedCause.checkpointId`. Carried on three durable read surfaces (GET /v1/approvals `pending[]` rows, the /v1/approvals/stream `pending` frame, GET /v1/assistant/inbox rows). A row whose value is unreadable or untrusted (non-string / empty / over 128 / contains the token / an old row / an older server) is STILL LISTED with the key ABSENT โ read absence as "this row has no joinable identity", never as a required key.' }
|
|
13499
13689
|
scope: { type: string, description: 'Multi-tenant owner scope.' }
|
|
13500
13690
|
createdAt: { type: number, description: 'Ask creation time (epoch ms).' }
|
|
13501
13691
|
gateKind:
|
|
@@ -13819,6 +14009,17 @@ components:
|
|
|
13819
14009
|
โ ๏ธ The key name is final: `permissionModeAfter` (the build brief once said `nextPermissionMode`,
|
|
13820
14010
|
which never shipped โ zero aliases).
|
|
13821
14011
|
|
|
14012
|
+
SessionAgent:
|
|
14013
|
+
type: object
|
|
14014
|
+
additionalProperties: false
|
|
14015
|
+
description: >-
|
|
14016
|
+
The placement-tuple projection of a delegated subagent's transcript (`SessionRecord.agent`, server >= 7.133.0). Each member is independently optional (only what was stored is projected); `{}` is a legal value
|
|
14017
|
+
(the tuple held only a `kind`). `id` = the tuple's `handle` (the durable agent row's `aโฆ` key โ the SAME string as the fleet row's `id` and `GET /v1/agents/roster`'s `handle`); `parentSessionId` = the host
|
|
14018
|
+
session that spawned it; `rootSessionId` = the delegation tree's root host session (a nested grandchild anchors to the root).
|
|
14019
|
+
properties:
|
|
14020
|
+
id: { type: string }
|
|
14021
|
+
parentSessionId: { type: string }
|
|
14022
|
+
rootSessionId: { type: string }
|
|
13822
14023
|
SessionRecord:
|
|
13823
14024
|
type: object
|
|
13824
14025
|
description: >
|
|
@@ -13851,6 +14052,14 @@ components:
|
|
|
13851
14052
|
$ref: '#/components/schemas/SessionWindow'
|
|
13852
14053
|
promptEpoch:
|
|
13853
14054
|
$ref: '#/components/schemas/PromptEpoch'
|
|
14055
|
+
agent:
|
|
14056
|
+
allOf: [{ $ref: '#/components/schemas/SessionAgent' }]
|
|
14057
|
+
description: >-
|
|
14058
|
+
server >= 7.133.0, top-level additive key โ WHICH delegated subagent's transcript this session is (read by terminal side-chain projections that join a fleet frame's `transcriptId`). Only the stored placement
|
|
14059
|
+
tuple is projected (minted by the engine when a BACKGROUND subagent with a durable agent row creates the session on a store that declares placements; a synchronously delegated subagent's transcript is not in
|
|
14060
|
+
the host store and has no tuple); the three members are each optional. ๐ด READ IT AS "WAS IT STORED", NEVER AS "IS IT A SUBAGENT": key PRESENT = a delegated subagent's transcript (even `{}` when the tuple held only a
|
|
14061
|
+
kind); key ABSENT has three causes โ an older server (<= 7.132.x) / an ordinary session / a deployment whose store keeps no placement tuple (the local backend: the copy parked from the private short-TTL store is an
|
|
14062
|
+
ordinary session row). Absence is NOT "not a subagent": fall back to the identity the fleet row (`id`) / `GET /v1/agents/roster` (`handle`) already carry.
|
|
13854
14063
|
userInputUndrained:
|
|
13855
14064
|
type: array
|
|
13856
14065
|
description: >-
|
|
@@ -14885,7 +15094,7 @@ components:
|
|
|
14885
15094
|
center 404 / 429 / 3xx included). On 400 `request.field_invalid` for a `settings.permissions` bucket (server >= 7.106.0 /
|
|
14886
15095
|
S-904): `over_cap` (more than `cap` entries; beside `count` + `cap`) / `bad_entry` (a non-string or empty item; beside
|
|
14887
15096
|
`index`); server >= 7.132.0 widens that group to every tool-name list on the body, the agent definitions and the two host-path lists, and adds
|
|
14888
|
-
`too_long` (a text over its character cap; beside `count` + `cap`) โ closed
|
|
15097
|
+
`too_long` (a text over its character cap; beside `count` + `cap`) โ closed words `over_cap` / `too_long` / `bad_entry` (SDK `RequestFieldRefusalExtra`); server >= 7.133.0 adds `too_large` (a payload over its BYTE cap, only on 413 `request.payload_too_large`: `{ field: "body", reason: "too_large", cap }` โ `count` ABSENT when the read stopped at the cap and cannot measure; a request body over 8 MiB is now always that 413) and the `request.invalid_json` reasons `not_json` | `not_object` (400, every JSON-body door; formerly `request.rejected`/`request.body_shape` by door).
|
|
14889
15098
|
On 409 refusals of a resume (server >= 7.132.0): the engine's `CheckpointErrorReason` arm (`detail.reason` passed through; see `blockedBy`). On 400 `rules.inert_entry` (server >= 7.129.0): the engine's `ALLOW_ENTRY_INERT_REASONS` (`tool_name` / `wildcard_all` / `namespace_wildcard` / `content_unsupported` / `grammar` / `near_miss` / `earlier_grammar`). Out-of-vocabulary word โ treat as unknown. (Other codes carry their own `reason` words.)
|
|
14890
15099
|
retryAfterSec:
|
|
14891
15100
|
type: number
|
|
@@ -15006,6 +15215,14 @@ components:
|
|
|
15006
15215
|
properties:
|
|
15007
15216
|
reason: { type: string, enum: [unnamed_refusal] }
|
|
15008
15217
|
path: { $ref: '#/components/schemas/SettingsHooksConfigPath' }
|
|
15218
|
+
- type: object
|
|
15219
|
+
description: 'one of the three wire keys this service reads itself is malformed (server >= 7.133.0): the group `source` / a command entry''s `plugin` / `args`; `key` names it, `path` is its coordinate. The whole request is refused (they used to be stripped silently as unknown keys).'
|
|
15220
|
+
required: [reason, key, path]
|
|
15221
|
+
additionalProperties: false
|
|
15222
|
+
properties:
|
|
15223
|
+
reason: { type: string, enum: [wire_key_invalid] }
|
|
15224
|
+
key: { type: string }
|
|
15225
|
+
path: { $ref: '#/components/schemas/SettingsHooksConfigPath' }
|
|
15009
15226
|
- type: object
|
|
15010
15227
|
description: 'server 7.115.0โ7.125.x: the dead-alias matcher refusal before `reason` existed.'
|
|
15011
15228
|
required: [event, alias, canonical]
|
|
@@ -15027,13 +15244,41 @@ components:
|
|
|
15027
15244
|
properties:
|
|
15028
15245
|
scenario: { type: string }
|
|
15029
15246
|
source: { type: string, enum: [ruling, deployment] }
|
|
15247
|
+
- type: object
|
|
15248
|
+
description: >-
|
|
15249
|
+
server >= 7.133.0 โ entry problems on a tool-name list / settings-rule refusal (400 `request.field_invalid`, 422): `problems` (at most 1000, each EntryProblem) + `total` (the true count; `total > problems.length` => cut).
|
|
15250
|
+
With `callerTrust` it is the below-trust-floor refusal: the caller's admission tier (`global` | `project`, read open; the same words as `capabilities.settings.permissions.callerTrust`).
|
|
15251
|
+
required: [problems, total]
|
|
15252
|
+
additionalProperties: false
|
|
15253
|
+
properties:
|
|
15254
|
+
problems: { type: array, items: { $ref: '#/components/schemas/EntryProblem' } }
|
|
15255
|
+
total: { type: integer }
|
|
15256
|
+
callerTrust: { type: string }
|
|
15257
|
+
- type: object
|
|
15258
|
+
description: >-
|
|
15259
|
+
server >= 7.133.0 โ 400 `request.field_conflict`: the request body contradicts itself. `kind` = which constraint (a CLOSED fourteen-word set, read open: cascade_verify | image_profile | resume_anchor |
|
|
15260
|
+
system_prompt_fold | file_history_restore | skills_disabled | existing_session | scratchpad_root | ask_answer | policy_person_ask | plan_edit | plan_mode_after | bound_call_door | remember_decision);
|
|
15261
|
+
`fields` = the named body coordinates, subject first (at least one; a dynamic index reads `agents[1].skills`); `count` / `cap` only on the fold-cap kind (the folded total and its cap).
|
|
15262
|
+
required: [kind, fields]
|
|
15263
|
+
additionalProperties: false
|
|
15264
|
+
properties:
|
|
15265
|
+
kind: { type: string }
|
|
15266
|
+
fields: { type: array, items: { type: string } }
|
|
15267
|
+
count: { type: integer }
|
|
15268
|
+
cap: { type: integer }
|
|
15269
|
+
- type: object
|
|
15270
|
+
description: '409 `conflict.session_placed` (server >= 7.133.0): the session sync commit targeted a session that holds a delegated agent''s transcript. `placement_kind` is the stored placement kind (today only `subagent`; read open).'
|
|
15271
|
+
required: [placement_kind]
|
|
15272
|
+
additionalProperties: false
|
|
15273
|
+
properties:
|
|
15274
|
+
placement_kind: { type: string }
|
|
15030
15275
|
- type: string
|
|
15031
15276
|
count:
|
|
15032
15277
|
type: integer
|
|
15033
|
-
description: '`reason: over_cap` / `too_long`
|
|
15278
|
+
description: '`reason: over_cap` / `too_long` / `too_large` โ how much was sent (entries / characters / bytes; every capped face since >= 7.132.0). ABSENT on the unmeasured form (a body read that stopped at the cap). SDK: `err.extra.count`.'
|
|
15034
15279
|
cap:
|
|
15035
15280
|
type: integer
|
|
15036
|
-
description: '`reason: over_cap` / `too_long`
|
|
15281
|
+
description: '`reason: over_cap` / `too_long` / `too_large` โ the cap (1000 for a permissions bucket; per face otherwise; bytes on a too_large 413). SDK: `err.extra.cap`.'
|
|
15037
15282
|
index:
|
|
15038
15283
|
type: integer
|
|
15039
15284
|
description: '`reason: bad_entry` only โ the index of the first bad item; ABSENT when the list itself is not an array. SDK: `err.extra.index`.'
|
|
@@ -15169,6 +15414,11 @@ components:
|
|
|
15169
15414
|
- $ref: '#/components/schemas/Event_tool_approval_complete'
|
|
15170
15415
|
- $ref: '#/components/schemas/Event_approval_request'
|
|
15171
15416
|
- $ref: '#/components/schemas/Event_approval_revoke'
|
|
15417
|
+
# server >= 7.133.0 (sdk 25.0.0): the card family's single-card CLOSE frame (`approval_complete`; one frame family per leg โ it replaces the legacy
|
|
15418
|
+
# `tool_approval_complete` on a leg where `capabilities.approvalFrameFamilies` = ["approval_request"]) and the LIVE-ONLY `session_titled` frame (a session
|
|
15419
|
+
# title was written; never ledgered, no eventId).
|
|
15420
|
+
- $ref: '#/components/schemas/Event_approval_complete'
|
|
15421
|
+
- $ref: '#/components/schemas/Event_session_titled'
|
|
15172
15422
|
# sdk 9.1.0: two LIVE-leg arms the service has been emitting while neither this union nor the
|
|
15173
15423
|
# SDK's declared them โ `text_end` since server 7.66.0 (segment boundary; retires the idle-flush
|
|
15174
15424
|
# heuristic) and `tool_roster_delta` since server 7.70.0 (run-time roster change). A generated client
|
|
@@ -15230,6 +15480,8 @@ components:
|
|
|
15230
15480
|
tool_approval_complete: '#/components/schemas/Event_tool_approval_complete'
|
|
15231
15481
|
approval_request: '#/components/schemas/Event_approval_request'
|
|
15232
15482
|
approval_revoke: '#/components/schemas/Event_approval_revoke'
|
|
15483
|
+
approval_complete: '#/components/schemas/Event_approval_complete'
|
|
15484
|
+
session_titled: '#/components/schemas/Event_session_titled'
|
|
15233
15485
|
text_end: '#/components/schemas/Event_text_end'
|
|
15234
15486
|
tool_roster_delta: '#/components/schemas/Event_tool_roster_delta'
|
|
15235
15487
|
reasoning_end: '#/components/schemas/Event_reasoning_end'
|
|
@@ -15259,13 +15511,18 @@ components:
|
|
|
15259
15511
|
condition: durable-ledger leg only (no ledger => neither header nor frame). sessionId rides along
|
|
15260
15512
|
(needed to bind subsequent turns when the server minted a fresh session). Always precedes any content
|
|
15261
15513
|
frame. NOT an engine event โ server-minted, no EventIdentity.
|
|
15262
|
-
# ๅฐ้ญ:้ธ้ ็น routes/tasks.ts ๆฏ้ๅญๅๆญป็ไธ้ฎๅญ้ข้(sessionId ๆกไปถๅจๅบ)ใ
|
|
15514
|
+
# ๅฐ้ญ:้ธ้ ็น routes/tasks.ts ๆฏ้ๅญๅๆญป็ไธ้ฎๅญ้ข้(sessionId ๆกไปถๅจๅบ);server >= 7.133.0 ่ตท็ฌฌๅไธชๆกไปถ้ฎ `warnings`(ๆๆๅ)ใ
|
|
15263
15515
|
additionalProperties: false
|
|
15264
15516
|
required: [type, taskId]
|
|
15265
15517
|
properties:
|
|
15266
15518
|
type: { const: meta }
|
|
15267
15519
|
taskId: { type: string }
|
|
15268
15520
|
sessionId: { type: string }
|
|
15521
|
+
warnings:
|
|
15522
|
+
type: array
|
|
15523
|
+
items: { $ref: '#/components/schemas/EntryProblem' }
|
|
15524
|
+
description: 'server >= 7.133.0, present only when non-empty: the accept-time NOTICES for entries of the allow-side selector lists (root / agent `allowTools`) the engine reads as nothing or that are not in the roster. Same list as the 202 receipt''s and the sync 200 body''s `warnings`. ABSENT = no notice (older servers too).'
|
|
15525
|
+
|
|
15269
15526
|
Event_reasoning:
|
|
15270
15527
|
type: object
|
|
15271
15528
|
description: durable stream only โ turn-aggregated thinking.
|
|
@@ -15857,6 +16114,29 @@ components:
|
|
|
15857
16114
|
WHO ASKED. Same-present/same-absent as `settlement` (I1). CLOSED here (archive read, `GateRecordAskOrigin`) โ see the
|
|
15858
16115
|
note above.
|
|
15859
16116
|
|
|
16117
|
+
McpProbeFaceRow:
|
|
16118
|
+
# server 7.133.0: the face''s row = the wiring-manifest row projection + TWO face-only optional keys. The manifest row is CLOSED (so an `allOf` over it would reject the two extra keys), hence a
|
|
16119
|
+
# standalone closed schema whose per-key shapes are `$ref`s into WiringManifestMcpEntry's own properties (one source per shape); the key SET is pinned by test (manifest row keys + the two).
|
|
16120
|
+
type: object
|
|
16121
|
+
description: >
|
|
16122
|
+
One row of the no-run MCP status face (GET /v1/capabilities/mcp and POST /v1/capabilities/mcp/probe): the SAME projection a prepared leg pushes onto `wiring_manifest.mcp[]`, PLUS two optional keys only this
|
|
16123
|
+
face carries (server >= 7.133.0). `toolNames` = the tool names this server will mount (the same probe reading `servers[i].tools`, engine namespace form `mcp__<server>__<tool>`, after the schema gate and the per-server
|
|
16124
|
+
allow-list; the server neither composes nor renames), at most 200 per server, the reading-order prefix. ABSENT = an older server or no `tools` in that server's reading โ NEVER invent `[]` (it would read as "this server
|
|
16125
|
+
has no tools"); a present `[]` is real. `toolNamesTruncated` = TRUE-ONLY: the list was cut (more than 200; exactly 200 is NOT cut and the key stays absent, never `false`) โ when true `toolCount` is the true count, not
|
|
16126
|
+
`toolNames.length`. A misaligned reading (not an array / count differs from the row count) answers 500 `internal.error` on both doors instead of shipping a list that could be paired wrongly.
|
|
16127
|
+
additionalProperties: false
|
|
16128
|
+
required: [name, status]
|
|
16129
|
+
properties:
|
|
16130
|
+
name: { $ref: '#/components/schemas/WiringManifestMcpEntry/properties/name' }
|
|
16131
|
+
status: { $ref: '#/components/schemas/WiringManifestMcpEntry/properties/status' }
|
|
16132
|
+
source: { $ref: '#/components/schemas/WiringManifestMcpEntry/properties/source' }
|
|
16133
|
+
toolCount: { $ref: '#/components/schemas/WiringManifestMcpEntry/properties/toolCount' }
|
|
16134
|
+
errorCode: { $ref: '#/components/schemas/WiringManifestMcpEntry/properties/errorCode' }
|
|
16135
|
+
delivered: { $ref: '#/components/schemas/WiringManifestMcpEntry/properties/delivered' }
|
|
16136
|
+
httpStatus: { $ref: '#/components/schemas/WiringManifestMcpEntry/properties/httpStatus' }
|
|
16137
|
+
liveness: { $ref: '#/components/schemas/WiringManifestMcpEntry/properties/liveness' }
|
|
16138
|
+
toolNames: { type: array, items: { type: string }, maxItems: 200 }
|
|
16139
|
+
toolNamesTruncated: { type: boolean, enum: [true] }
|
|
15860
16140
|
McpProbeFace:
|
|
15861
16141
|
type: object
|
|
15862
16142
|
description: >
|
|
@@ -15882,8 +16162,8 @@ components:
|
|
|
15882
16162
|
description: 'How long this reading may be reused (seconds; 30s per identity + declaration set server-side). A hit inside the window does NOT count against the rate limit.'
|
|
15883
16163
|
servers:
|
|
15884
16164
|
type: array
|
|
15885
|
-
items: { $ref: '#/components/schemas/
|
|
15886
|
-
description: 'One row per declaration,
|
|
16165
|
+
items: { $ref: '#/components/schemas/McpProbeFaceRow' }
|
|
16166
|
+
description: 'One row per declaration, the wiring-manifest row shape plus (server >= 7.133.0) this face''s two optional keys, index-aligned (see this schema''s description).'
|
|
15887
16167
|
|
|
15888
16168
|
McpLivenessState:
|
|
15889
16169
|
type: string
|
|
@@ -16654,6 +16934,12 @@ components:
|
|
|
16654
16934
|
(`capabilities.rewindFiles`); only a run the REQUEST word turned off cannot restore itself.
|
|
16655
16935
|
OPEN on read: the server does not enumerate the word (a present non-string is dropped), a third word passes
|
|
16656
16936
|
through โ treat it as unknown. ABSENT = an older engine / external derivation, never "capturing".
|
|
16937
|
+
permissionMode:
|
|
16938
|
+
allOf: [{ $ref: '#/components/schemas/WiringManifestPermissionMode' }]
|
|
16939
|
+
description: >-
|
|
16940
|
+
server >= 7.133.0 (core 7.53.0; TENANT and OPERATOR faces alike) โ this leg's PERMISSION-MODE receipt `{ requested?, effective, foldedBy? }`; the shell renders its mode indicator from `effective`
|
|
16941
|
+
(`foldedBy` present = the requested mode was folded), never from the word it sent. ABSENT = an older engine / server, not an assertion of the default mode. Effective half only (this frame);
|
|
16942
|
+
the same section rides the non-streaming `wiringManifest` receipt and the ledger row. Section shape: WiringManifestPermissionMode.
|
|
16657
16943
|
instructions:
|
|
16658
16944
|
allOf: [{ $ref: '#/components/schemas/WiringManifestInstructions' }]
|
|
16659
16945
|
description: >
|
|
@@ -17533,7 +17819,7 @@ components:
|
|
|
17533
17819
|
payload carried `type` (the read boundary emits `{type, ...data}`) so runtime discrimination worked,
|
|
17534
17820
|
but a generated client had nothing to switch on and dropped approval cards. That gap is closed.
|
|
17535
17821
|
The shell renders `tool_approval` as the three-choice card and dismisses it on `tool_approval_complete`.
|
|
17536
|
-
Respond via POST /v1/tool-approvals/{
|
|
17822
|
+
Respond via POST /v1/tool-approvals/{id}/respond.
|
|
17537
17823
|
required: [type, approvalId]
|
|
17538
17824
|
additionalProperties: true
|
|
17539
17825
|
properties:
|
|
@@ -17929,8 +18215,8 @@ components:
|
|
|
17929
18215
|
|
|
17930
18216
|
# โโ design/172 ๆตๅ
ๅฎกๆนๅ่ฎฎ(#151)โโ ๅทฒ้ server 7.3.0 ไธ็บฟ;ๅผๅ
ณ STREAM_APPROVAL_ENABLED ็้ป่ฎคๅผ
|
|
17931
18217
|
# ๅไธคๆฎต:server โค7.4.0 ้ป่ฎค OFF,โฅ7.5.0 ้ป่ฎค ON(BREAKING,่ง server CHANGELOG)ใโโ
|
|
17932
|
-
# ไธไธ้ข็ ToolApprovalFrame
|
|
17933
|
-
#
|
|
18218
|
+
# ไธไธ้ข็ ToolApprovalFrame ๆฏไธคไธชๅธงๆ,**ไธๆก่
ฟๅช่ตฐไธไธช**(server >= 7.133.0,capabilities.approvalFrameFamilies):ๅๅกๅ่ฎฎไธๅบ็่
ฟไธไธๅช ask ๅชๅบๆฌๆ็ๅธงใ
|
|
18219
|
+
# ๆงๆไธๅธง้ฝไธๅ,ๆถ่ดน็ซฏไธๅๆ `approvalId` ๅป้;โค7.132.x ็ๅๅก่
ฟไธคๆๅนถๅ(ๅ
tool_approvalใๅ approval_request,ๅๅธฆ `approvalId`)โ ๆๅฎๅป้ใไผๅ
ๆธฒๆๆฐๅธงใ
|
|
17934
18220
|
classifierUnavailable:
|
|
17935
18221
|
$ref: '#/components/schemas/ClassifierUnavailable'
|
|
17936
18222
|
description: >-
|
|
@@ -17972,6 +18258,14 @@ components:
|
|
|
17972
18258
|
(a malformed shape, or a `dir` over 1024 UTF-16 code units โ the key is ABSENT โ never truncated,
|
|
17973
18259
|
because a truncated directory is a DIFFERENT directory and adding it would not clear this ask;
|
|
17974
18260
|
see the STRING-LENGTH UNIT convention in `info.description` for this `maxLength`'s counting unit).
|
|
18261
|
+
covers:
|
|
18262
|
+
allOf: [{ $ref: '#/components/schemas/ReadRootCover' }]
|
|
18263
|
+
description: >-
|
|
18264
|
+
Optional (engine core 7.22.0 `ReadRootGrantCandidate.covers`; the server carries it through key by key). ABSENT โ `dir` is a DIRECTORY
|
|
18265
|
+
(adding it to the read roots releases what lies under it). `exact` โ `dir` is the path the command NAMED, offered verbatim
|
|
18266
|
+
(a file or one concrete path, not a directory containing it): the consumer ADDS the string itself โ expanding it into a
|
|
18267
|
+
pattern grants nothing โ and must not render the offer as "add directory". The domain is the single word `exact`
|
|
18268
|
+
(a word outside it makes the server drop the whole candidate). The `approval_request` frame reads this very definition.
|
|
17975
18269
|
clearsThisAsk:
|
|
17976
18270
|
type: boolean
|
|
17977
18271
|
enum: [true]
|
|
@@ -18052,8 +18346,23 @@ components:
|
|
|
18052
18346
|
approvalId:
|
|
18053
18347
|
type: string
|
|
18054
18348
|
description: >
|
|
18055
|
-
|
|
18056
|
-
|
|
18349
|
+
The id of POST /v1/tool-approvals/{id}/respond and GET /v1/tool-approvals/{id}. server >= 7.133.0: ALWAYS EQUAL TO `askId` (the row's key is the ask's one wire
|
|
18350
|
+
identity; a 64-character lowercase hexadecimal string โ treat it as an OPAQUE string, never parse it as a uuid); the matching close frame `approval_complete` carries it too.
|
|
18351
|
+
On server <= 7.132.x it is the legacy bridge / dedupe key (a uuid, the same value as the parallel tool_approval frame).
|
|
18352
|
+
# โโ server >= 7.133.0: the TEN off-card LIVE facts on the opening frame's top level (one frame family per leg) โโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
18353
|
+
# Same keys, same shapes, same values as on the legacy `tool_approval` frame (each is a `$ref` into ToolApprovalFrame's own property โ one
|
|
18354
|
+
# source per shape). Only the frame minted LIVE carries them (and what the durable ledger recorded of that frame): a disconnect-replay frame
|
|
18355
|
+
# (rebuilt from `card_json`) never does. Absence means "this frame does not carry it", not "there is none". See APPROVAL_REQUEST_LIVE_FACT_KEYS (sdk) / the server's twin.
|
|
18356
|
+
mandated: { $ref: '#/components/schemas/ToolApprovalFrame/properties/mandated' }
|
|
18357
|
+
mandate: { $ref: '#/components/schemas/ToolApprovalFrame/properties/mandate' }
|
|
18358
|
+
origin: { $ref: '#/components/schemas/ToolApprovalFrame/properties/origin' }
|
|
18359
|
+
boundGrantDigest: { $ref: '#/components/schemas/ToolApprovalFrame/properties/boundGrantDigest' }
|
|
18360
|
+
boundGrants: { $ref: '#/components/schemas/ToolApprovalFrame/properties/boundGrants' }
|
|
18361
|
+
classifierNoRuling: { $ref: '#/components/schemas/ToolApprovalFrame/properties/classifierNoRuling' }
|
|
18362
|
+
boundGrantAbsence: { $ref: '#/components/schemas/ToolApprovalFrame/properties/boundGrantAbsence' }
|
|
18363
|
+
approvalCard: { $ref: '#/components/schemas/ToolApprovalFrame/properties/approvalCard' }
|
|
18364
|
+
readRootCandidate: { $ref: '#/components/schemas/ToolApprovalFrame/properties/readRootCandidate' }
|
|
18365
|
+
probeReason: { $ref: '#/components/schemas/ToolApprovalFrame/properties/probeReason' }
|
|
18057
18366
|
|
|
18058
18367
|
ApprovalCard:
|
|
18059
18368
|
type: object
|
|
@@ -18316,6 +18625,13 @@ components:
|
|
|
18316
18625
|
and a word outside the set all read as ABSENT โ a card without this word must not be treated as "approving it grants nothing else"; whether to render "allow for this session" is `rememberRefused`.
|
|
18317
18626
|
Display metadata, never an adjudication input. CLOSED: the server narrows with the engine's members, anything else reads as absent.
|
|
18318
18627
|
|
|
18628
|
+
ReadRootCover:
|
|
18629
|
+
type: string
|
|
18630
|
+
enum: [exact]
|
|
18631
|
+
description: >
|
|
18632
|
+
The closed vocabulary of `readRootCandidate.covers` (engine core 7.22.0 `ReadRootGrantCandidate.covers`; the server's narrow read `readReadRootCandidate` drops the whole
|
|
18633
|
+
candidate for a word outside it). One word today: `exact` โ `dir` is the path the command NAMED, not a directory containing it. The SDK exports the same table as
|
|
18634
|
+
`READ_ROOT_COVERS` and its `isApprovalRequestFrameV1` judges `covers` by membership in it; a source-level anchor reads the word off the server's minting site and the engine's type.
|
|
18319
18635
|
PersistedRuleMandate:
|
|
18320
18636
|
type: string
|
|
18321
18637
|
enum: [operator_always, tool_marks, probe_mandate, probe_unanswered, write_protection, target_unresolved]
|
|
@@ -18729,6 +19045,40 @@ components:
|
|
|
18729
19045
|
depth: { type: integer, description: 'Delegation depth (a direct child of the host = 1).' }
|
|
18730
19046
|
agentName: { type: string, description: 'Child agent name. UNTRUSTED โ spawning-model free text (server-redacted and length-bounded).' }
|
|
18731
19047
|
|
|
19048
|
+
ApprovalCompleteFrame:
|
|
19049
|
+
type: object
|
|
19050
|
+
description: >
|
|
19051
|
+
The CLOSE frame of the card family (`approval_complete`; server >= 7.133.0; SSE, `type` IS the event name; the durable leg appends the same frame, so it replays through
|
|
19052
|
+
GET /v1/runs/:id/events as the `Event_approval_complete` arm). ONE FRAME FAMILY PER LEG: on a leg where the card protocol is on (`capabilities.approvalFrameFamilies`
|
|
19053
|
+
= `["approval_request"]`) one ask travels only `approval_request` -> `approval_complete` / `approval_revoke`; the legacy `tool_approval` / `tool_approval_complete` pair is NOT sent
|
|
19054
|
+
(BREAKING vs <= 7.132.x, which sent both families for one ask; remedy on the worker: `STREAM_APPROVAL_ENABLED=false`).
|
|
19055
|
+
Same meaning as the legacy `tool_approval_complete` (one settle, one verdict: the `outcome` three words, the non-human `cause`, the park-route `parked`); dismiss the card by the opening frame's
|
|
19056
|
+
`askId`. Division of labour with ApprovalRevokeFrame: the revoke frame is BATCH-level (siblings voided by a winner), this one is the SINGLE card's end (answered / window expired / park route / cancelled);
|
|
19057
|
+
one ask can receive both โ clearing by `askId` is enough. The gate is "this connection's opening frame was actually delivered". The frame is a notification, the row is the source of truth: a lost
|
|
19058
|
+
frame is compensated by the open-stream preamble (see ApprovalRequestFrame). THIS SCHEMA DESCRIBES v1 ONLY (read it as ApprovalFrameEnvelope first; the SDK's `isApprovalCompleteFrameV1` narrows).
|
|
19059
|
+
required: [type, schemaVersion, askId, taskId, approvalId, outcome, serverNowMs]
|
|
19060
|
+
additionalProperties: true
|
|
19061
|
+
properties:
|
|
19062
|
+
type: { type: string, enum: [approval_complete] }
|
|
19063
|
+
schemaVersion: { type: integer, enum: [1], description: 'This schema describes v1 only (see ApprovalFrameEnvelope for the unknown-version read).' }
|
|
19064
|
+
askId: { type: string, description: 'The durable identity โ dismiss the card by it (the same key as the opening frame''s `askId`).' }
|
|
19065
|
+
taskId: { type: string, description: 'wire run id (same as the opening frame).' }
|
|
19066
|
+
approvalId: { type: string, description: 'Always equal to `askId` (same as the opening frame).' }
|
|
19067
|
+
outcome:
|
|
19068
|
+
type: string
|
|
19069
|
+
enum: [allowed, denied, expired]
|
|
19070
|
+
description: 'How the ask settled โ the same three words as the legacy frame: `allowed` / `denied` = a decision; `expired` = a non-human ending (the reason is in `cause`).'
|
|
19071
|
+
cause:
|
|
19072
|
+
allOf: [{ $ref: '#/components/schemas/ApprovalSettleCause' }]
|
|
19073
|
+
description: >-
|
|
19074
|
+
The non-human ending''s cause (present only on `outcome: "expired"`; the fourteen words of the approval seat''s ending-cause set, the same word as on the audit settle row). A human answer carries none.
|
|
19075
|
+
ABSENCE IS NOT EVIDENCE.
|
|
19076
|
+
parked:
|
|
19077
|
+
type: boolean
|
|
19078
|
+
enum: [true]
|
|
19079
|
+
description: 'TRUE-ONLY: this ask itself ended on the park route (row moved to PARKING / PARKED; a late answer is reachable). Absent = no evidence โ NEVER read as a real denial.'
|
|
19080
|
+
serverNowMs: { type: integer, description: 'Server clock at mint time.' }
|
|
19081
|
+
|
|
18732
19082
|
ApprovalRevokeFrame:
|
|
18733
19083
|
type: object
|
|
18734
19084
|
description: >
|
|
@@ -19028,7 +19378,7 @@ components:
|
|
|
19028
19378
|
description: >
|
|
19029
19379
|
server >= 7.126.0 (sdk 21.1.0 `APPROVAL_DECIDE_GATE_KINDS`, verbatim and in order; single owner = server
|
|
19030
19380
|
`APPROVAL_GATE_KINDS`) โ the parked gate kinds the DURABLE decision door `POST /v1/approvals/{sessionId}/decide`
|
|
19031
|
-
accepts (the live `POST /v1/tool-approvals/{
|
|
19381
|
+
accepts (the live `POST /v1/tool-approvals/{id}/respond` answers the same card family). A parked row of
|
|
19032
19382
|
kind `plan_review` goes to the plan-review door instead (`PlanReviewGateKind`); `resource_limit` / `needs_review` /
|
|
19033
19383
|
`task_done` have no human decision door (resume / terminal). Clients route a pending row by reading this set,
|
|
19034
19384
|
never by a hand-written copy of it.
|
|
@@ -19043,7 +19393,7 @@ components:
|
|
|
19043
19393
|
enum: [person, policy]
|
|
19044
19394
|
description: >
|
|
19045
19395
|
server >= 7.118.0 (`APPROVAL_DECIDED_BY`, verbatim and in order) โ WHO made an approval decision, one key on all three decision
|
|
19046
|
-
doors (live `POST /v1/tool-approvals/{
|
|
19396
|
+
doors (live `POST /v1/tool-approvals/{id}/respond`, durable `POST /v1/tasks/{taskId}/asks/{askId}/decision`, durable
|
|
19047
19397
|
`POST /v1/approvals/{sessionId}/decide`). `person` = a person decided through the approval channel (ABSENT means this);
|
|
19048
19398
|
`policy` = this deployment's own policy decided (a rule / posture answering on someone's behalf, a headless lane) โ BOTH
|
|
19049
19399
|
directions: the engine records `tool_end.gate.settlement.kind` = `policy_allowed` / `policy_refused` (`who.party: "policy"`).
|
|
@@ -19135,6 +19485,20 @@ components:
|
|
|
19135
19485
|
`updatedInputForwarded` this field IS persisted, so an idempotent replay DOES promise byte-identity.
|
|
19136
19486
|
The 409 `conflict.ask_decided` body echoes the same field โ and there it is always the FIRST
|
|
19137
19487
|
decision's note, not the one the rejected request carried.
|
|
19488
|
+
noteRecorded:
|
|
19489
|
+
type: boolean
|
|
19490
|
+
description: >
|
|
19491
|
+
server >= 7.133.0, ADDITIVE: did the `note` THIS request carried land as the row's text? Present ONLY when the request carried a `note`. `true` <=> the row's `decisionNote` is
|
|
19492
|
+
verbatim the text this request submitted (text that happens to be identical counts even if someone else wrote it first); `false` = not confirmed (the row holds another reason /
|
|
19493
|
+
the store could not be read back). Same shape and meaning as `noteRecorded` on the live respond ack and on its replayed arm (one judgement for the three doors). Carried by the
|
|
19494
|
+
first-decision and idempotent-replay forms; the PARKED redemption leg does not carry it (read it as unknown). ABSENT is not `false`.
|
|
19495
|
+
consumerState:
|
|
19496
|
+
type: string
|
|
19497
|
+
enum: [absent]
|
|
19498
|
+
description: >
|
|
19499
|
+
TRUE-ONLY disclosure (present as `absent`): no engine leg on THIS replica is waiting for this ask โ the decision is on the row (an idempotent replay will read it, the audit surface keeps it)
|
|
19500
|
+
but nothing running here resumes because of it (the holder of the suspended promise may be another replica, or this replica restarted and its local window is empty). Read the RUN surface to
|
|
19501
|
+
learn whether anything continued; NEVER take a 200 without this key as proof the run continued (older servers never send it). Not a 409 / 410: the decision DID take effect.
|
|
19138
19502
|
|
|
19139
19503
|
QuestionFrame:
|
|
19140
19504
|
type: object
|
|
@@ -19669,7 +20033,7 @@ components:
|
|
|
19669
20033
|
Event_tool_approval:
|
|
19670
20034
|
description: >
|
|
19671
20035
|
DURABLE-leg replay of the legacy tool-approval OPEN frame. Same payload as ToolApprovalFrame with the
|
|
19672
|
-
discriminant narrowed to `tool_approval`. Settle it via POST /v1/tool-approvals/{
|
|
20036
|
+
discriminant narrowed to `tool_approval`. Settle it via POST /v1/tool-approvals/{id}/respond.
|
|
19673
20037
|
Anchor the card on `toolCallId` (NOT `approvalId`); render `governanceForced` as a non-bypassable
|
|
19674
20038
|
"forced by governance" badge. UNTRUSTED for display: `message`/`args` are redacted but model-authored.
|
|
19675
20039
|
allOf:
|
|
@@ -19692,9 +20056,11 @@ components:
|
|
|
19692
20056
|
type: { type: string, enum: [tool_approval_complete] }
|
|
19693
20057
|
Event_approval_request:
|
|
19694
20058
|
description: >
|
|
19695
|
-
The design/172 in-stream approval card as an AgentEvent arm.
|
|
19696
|
-
|
|
19697
|
-
`
|
|
20059
|
+
The design/172 in-stream approval card as an AgentEvent arm. ONE FRAME FAMILY PER LEG (server >= 7.133.0,
|
|
20060
|
+
`capabilities.approvalFrameFamilies`): on a leg where the card protocol is on, one ask emits only this family
|
|
20061
|
+
(`approval_request` -> `approval_complete` / `approval_revoke`) and none of the legacy `tool_approval` family,
|
|
20062
|
+
so there is nothing to deduplicate. On server <= 7.132.x the two families ran side by side (legacy first) carrying
|
|
20063
|
+
the SAME `approvalId` โ there, dedupe on it and prefer this arm. The decision key is `askId`; settle via
|
|
19698
20064
|
POST /v1/tasks/{taskId}/asks/{askId}/decision.
|
|
19699
20065
|
|
|
19700
20066
|
๐ด THIS ARM IS THE OPEN ENVELOPE, NOT `ApprovalRequestFrame`, AND THAT IS DELIBERATE. The v1 frame
|
|
@@ -19741,6 +20107,37 @@ components:
|
|
|
19741
20107
|
properties:
|
|
19742
20108
|
type: { type: string, enum: [approval_revoke] }
|
|
19743
20109
|
|
|
20110
|
+
Event_approval_complete:
|
|
20111
|
+
description: >
|
|
20112
|
+
The card family's single-card CLOSE frame as an AgentEvent arm (server >= 7.133.0). One frame family per leg: with `capabilities.approvalFrameFamilies` = `["approval_request"]` this frame
|
|
20113
|
+
REPLACES the legacy `tool_approval_complete` (one ask no longer travels two families). Live SSE and the durable ledger replay carry the same shape (same settle, same verdict: `outcome`,
|
|
20114
|
+
non-human `cause`, `parked`).
|
|
20115
|
+
๐ด THIS ARM IS THE OPEN ENVELOPE, NOT `ApprovalCompleteFrame` โ same ruling as Event_approval_request / Event_approval_revoke: narrow with `schemaVersion == 1` (SDK:
|
|
20116
|
+
`isApprovalCompleteFrameV1`) before touching `outcome` / `cause` / `parked`; a frame that does not narrow still dismisses the card by its `askId` (when it has one) โ never guess the outcome.
|
|
20117
|
+
๐ด Consumption discipline: (a) dismiss by the opening frame's `askId`; (b) a ledger-replayed frame is for TIMELINE RENDERING ONLY โ the card-set baseline stays the open-stream preamble;
|
|
20118
|
+
(c) NEVER derive the run's fate from this frame (read the run row / checkpoint face); (d) it does not conflict with ApprovalRevokeFrame โ one ask can receive both.
|
|
20119
|
+
allOf:
|
|
20120
|
+
- $ref: '#/components/schemas/ApprovalFrameEnvelope'
|
|
20121
|
+
- type: object
|
|
20122
|
+
required: [type]
|
|
20123
|
+
properties:
|
|
20124
|
+
type: { type: string, enum: [approval_complete] }
|
|
20125
|
+
Event_session_titled:
|
|
20126
|
+
description: >
|
|
20127
|
+
server >= 7.133.0 โ the session title was WRITTEN (contract ยง4a-ttl): the title generator wrote the title into the session row and minted this frame on THE RUN'S LIVE STREAM afterwards.
|
|
20128
|
+
๐ด LIVE-ONLY, NEVER STORED: the session row (`GET /v1/sessions` list row `title`) is the single source of the title; this frame only says "the row just changed". It is not ledgered
|
|
20129
|
+
(GET /v1/runs/:id/events replay never carries it), not part of any replay surface, and has NO `eventId` (no SSE `id:` line, no part in the `Last-Event-ID` cursor). Only a leg holding a live stream
|
|
20130
|
+
receives it (today `POST /v1/tasks/stream`); the sync-JSON leg and the durable background leg structurally cannot. NOT sent when the session already has a title, on a user rename / pin
|
|
20131
|
+
(`PATCH /v1/sessions/{id}` does not go through the generator), with `SESSION_AUTO_TITLE=false`, after `done`, or once the connection is gone. THE FRAME MAY NOT ARRIVE โ the title is whatever
|
|
20132
|
+
the session row says: refresh on the frame, read the row on cold start / another window / reconnect. `title` has passed the generator's redaction and cleaning and is the SAME value as the row's
|
|
20133
|
+
(still UNTRUSTED for display โ model-authored text).
|
|
20134
|
+
type: object
|
|
20135
|
+
required: [type, sessionId, title]
|
|
20136
|
+
additionalProperties: false
|
|
20137
|
+
properties:
|
|
20138
|
+
type: { type: string, enum: [session_titled] }
|
|
20139
|
+
sessionId: { type: string, description: 'The session whose row was just written.' }
|
|
20140
|
+
title: { type: string, description: 'The title that landed in the session row (redacted and cleaned; bounded by the server''s TITLE_MAX_CHARS).' }
|
|
19744
20141
|
# โโ resources/*.ts schema backfill, batch 2 (2026-07-28) โ the 28-item WIRE_PENDING ratchet zeroed.
|
|
19745
20142
|
# Each schema below is cross-checked against the server source (file:line cited in its description
|
|
19746
20143
|
# or in the SDK resource JSDoc it mirrors). Wire objects are OPEN sets (additionalProperties: true).
|
|
@@ -19765,6 +20162,10 @@ components:
|
|
|
19765
20162
|
sessionId: { type: string, description: '`resolved` frames: which pending settled.' }
|
|
19766
20163
|
toolCallId: { type: string, description: '`resolved` frames: the settled pending''s bound tool-call id (absent when the pending carried none).' }
|
|
19767
20164
|
count: { type: integer, description: '`synced` frames: how many pendings the connect-time snapshot carried.' }
|
|
20165
|
+
checkpointId: { type: string, description: '`pending` frames only (server >= 7.133.0): the spread PendingCheckpoint row''s `checkpointId` (key absent when the row has no trusted value โ read as "no joinable identity").' }
|
|
20166
|
+
consumerState: { type: string, enum: [absent], description: '`live_pending` frames only (server >= 7.133.0): the spread LivePendingRow''s true-only `consumerState` (no engine leg on this replica is waiting for the ask).' }
|
|
20167
|
+
errorCode: { type: string, description: '`error` frames: the machine code (`STREAM_MAX_DURATION` / `draining` / server >= 7.133.0 `approvals.read_unavailable` โ the stream STAYS open, do NOT reconnect on it โ / `approvals.read_corrupt` โ a corrupt row was read, the server closes the stream after the frame).' }
|
|
20168
|
+
message: { type: string, description: '`error` frames: the human sentence (redacted); never match on it.' }
|
|
19768
20169
|
hasBidiControls:
|
|
19769
20170
|
type: boolean
|
|
19770
20171
|
enum: [true]
|
|
@@ -19885,20 +20286,24 @@ components:
|
|
|
19885
20286
|
|
|
19886
20287
|
FleetHookNotice:
|
|
19887
20288
|
description: >
|
|
19888
|
-
Hook observability payload,
|
|
20289
|
+
Hook observability payload, FOUR kinds (server >= 7.133.0 added `hook_managed_unrun` and `hook_verdict_untrusted`; service fleet-bus.ts `HookNotice` minus the wire-stripped
|
|
19889
20290
|
ownerScope/ownerSessionId โ the payload view of FleetFrame_hook_notice; a discriminated union on
|
|
19890
20291
|
`kind`, mirroring the SDK type verbatim). Both kinds are pure observe โ never block, resume, or
|
|
19891
20292
|
inject. Visibility is fail-CLOSED: a ?session= subscriber only receives notices provably owned by
|
|
19892
|
-
that session. `kind` is a CLOSED
|
|
20293
|
+
that session. `kind` is a CLOSED four-member set on the server (exhaustive-switch discipline) but
|
|
19893
20294
|
OPEN ON READ: degrade an unknown future kind to a generic observability row, never crash.
|
|
19894
20295
|
oneOf:
|
|
19895
20296
|
- $ref: '#/components/schemas/FleetHookDecisionUnavailable'
|
|
19896
20297
|
- $ref: '#/components/schemas/FleetHookNonBlockingFailure'
|
|
20298
|
+
- $ref: '#/components/schemas/FleetHookManagedUnrun'
|
|
20299
|
+
- $ref: '#/components/schemas/FleetHookVerdictUntrusted'
|
|
19897
20300
|
discriminator:
|
|
19898
20301
|
propertyName: kind
|
|
19899
20302
|
mapping:
|
|
19900
20303
|
hook_decision_unavailable: '#/components/schemas/FleetHookDecisionUnavailable'
|
|
19901
20304
|
hook_non_blocking_failure: '#/components/schemas/FleetHookNonBlockingFailure'
|
|
20305
|
+
hook_managed_unrun: '#/components/schemas/FleetHookManagedUnrun'
|
|
20306
|
+
hook_verdict_untrusted: '#/components/schemas/FleetHookVerdictUntrusted'
|
|
19902
20307
|
|
|
19903
20308
|
FleetHookDecisionUnavailable:
|
|
19904
20309
|
type: object
|
|
@@ -19933,7 +20338,7 @@ components:
|
|
|
19933
20338
|
reason:
|
|
19934
20339
|
# ๐ด NO `enum` โ same open-on-read ruling as kind 1 (SDK type is `... | (string & {})`).
|
|
19935
20340
|
type: string
|
|
19936
|
-
description: 'Machine-branchable failure shape. CLOSED server-side, OPEN ON READ โ KNOWN WORDS TODAY: exit_nonzero | timeout | spawn_failed | bad_json.'
|
|
20341
|
+
description: 'Machine-branchable failure shape. CLOSED server-side, OPEN ON READ โ KNOWN WORDS TODAY: exit_nonzero | timeout | spawn_failed | bad_json | matcher_over_budget (server >= 7.133.0: the group matcher / the entry `if` name part did not finish evaluating within its 1000 ms budget on this name โ NOT a broken hook script but an unevaluable selection condition; the server treats it as selected, the entry still runs; ONE frame per group, `if` one per entry, no exitCode / stderr).'
|
|
19937
20342
|
hookName: { type: string, description: 'Hook identity (statusMessage, else command/URL/prompt; redacted + bounded, http entries stripped of query/fragment). Always sent.' }
|
|
19938
20343
|
entryType: { type: string, description: 'command | http | prompt | agent โ without it, hookName''s nature is a guess. Closed server-side, open on read. Always sent.' }
|
|
19939
20344
|
exitCode: { type: integer, description: 'Absent for timeout/spawn_failed (no exit code exists โ the server never mints a legit-looking 0).' }
|
|
@@ -19941,6 +20346,57 @@ components:
|
|
|
19941
20346
|
stderr: { type: string, description: 'Redacted + truncated stderr digest (512-char cap incl. marker). Empty stderr => absent.' }
|
|
19942
20347
|
detail: { type: string, description: 'Redacted supplement (e.g. where an exit-2 had no venue). Additive / tolerate-absent.' }
|
|
19943
20348
|
|
|
20349
|
+
FleetHookManagedUnrun:
|
|
20350
|
+
type: object
|
|
20351
|
+
description: >
|
|
20352
|
+
Kind 3 (server >= 7.133.0): a MANAGED hook did not complete โ the group carries a `source`; managed groups (`managedPolicy` / `managedPlugin:<name>`) are the organization policy's guard and run in an independent lane
|
|
20353
|
+
after the unmanaged rewrites, on the final input. A synchronous managed entry that gave neither a legal verdict (exit 0 with no verdict / a closed-set verdict) nor a legal veto (exit 2 / `decision:"block"` /
|
|
20354
|
+
`continue:false`) is "unrun": on `PreToolUse` the conclusion folds to `ask` when nothing vetoed (a person in the loop; unmanaged allows are not trusted; any phase's veto is still the last vote), on other events the
|
|
20355
|
+
conclusion is unchanged โ but this frame is ALWAYS sent. One frame per unrun managed entry. The frame does NOT assert how the call ended (read the tool / approval frames).
|
|
20356
|
+
required: [kind, event, reason, source, hookName, entryType]
|
|
20357
|
+
additionalProperties: true
|
|
20358
|
+
properties:
|
|
20359
|
+
kind: { type: string, enum: [hook_managed_unrun] }
|
|
20360
|
+
event: { type: string, description: 'Which hook event. On PreToolUse this entry sets the managed lane: with no veto the call folds to `ask`.' }
|
|
20361
|
+
reason:
|
|
20362
|
+
# NO `enum` โ same open-on-read ruling as kinds 1 and 2.
|
|
20363
|
+
type: string
|
|
20364
|
+
description: >-
|
|
20365
|
+
Why it did not complete. CLOSED on the server (thirteen words), OPEN ON READ โ KNOWN WORDS TODAY: matcher_invalid | llm_carrier_unavailable | llm_cap | powershell_unsupported | if_unevaluable | budget_exhausted |
|
|
20366
|
+
spawn_failed | timeout | exit_nonzero | bad_json | decision_out_of_set | evidence_unavailable | rewrite_unsettled. `input_truncated` / `matcher_over_budget` are NOT in this kind (they belong to kind 4).
|
|
20367
|
+
source: { type: string, description: 'The group''s source word (`managedPolicy` or `managedPlugin:<name>`; the name is trace only, never a criterion).' }
|
|
20368
|
+
hookName: { type: string, description: 'Hook identity (same rule as kind 2); redacted + bounded.' }
|
|
20369
|
+
entryType: { type: string, description: 'command | http | prompt | agent โ closed server-side, open on read.' }
|
|
20370
|
+
toolName: { type: string, description: 'Present on tool events.' }
|
|
20371
|
+
detail: { type: string, description: 'Redacted supplement.' }
|
|
20372
|
+
|
|
20373
|
+
FleetHookVerdictUntrusted:
|
|
20374
|
+
type: object
|
|
20375
|
+
description: >
|
|
20376
|
+
Kind 4 (server >= 7.133.0): a hook's VERDICT IS UNTRUSTED โ one rule: an entry that did not get the complete payload, or was pulled in BY SELECTION by an over-budget matcher, has its VETO count (deny / exit 2 /
|
|
20377
|
+
`decision:"block"` / `continue:false` / ask) and its ALLOW and `updatedInput` NOT count. The rule holds on both lanes, so there is one frame; reason, lane and identity are machine fields. Emission condition per lane:
|
|
20378
|
+
managed = the entry ran with an untrusted cause (sent whatever it judged; `PreToolUse` then folds to `ask` when nothing vetoed); unmanaged = it gave an allow or a real rewrite (an identity echo does not count) that was
|
|
20379
|
+
dropped. Today only on `PreToolUse` (the event with an allow word). THE FRAME DOES NOT ASSERT HOW THE CALL ENDED: a managed entry that itself vetoes ends in deny with the frame sent; another trusted allow in the group still
|
|
20380
|
+
lets the call through โ read the call's own result. NEVER infer a call outcome from any hook_notice frame.
|
|
20381
|
+
required: [kind, event, reason, lane, hookName, entryType]
|
|
20382
|
+
additionalProperties: true
|
|
20383
|
+
properties:
|
|
20384
|
+
kind: { type: string, enum: [hook_verdict_untrusted] }
|
|
20385
|
+
event: { type: string, description: 'Which hook event (today always PreToolUse).' }
|
|
20386
|
+
reason:
|
|
20387
|
+
# NO `enum` โ same open-on-read ruling as kinds 1โ3.
|
|
20388
|
+
type: string
|
|
20389
|
+
description: >-
|
|
20390
|
+
Why the verdict is untrusted. CLOSED on the server (two words), OPEN ON READ โ KNOWN WORDS TODAY: input_truncated (the entry did not get the full payload: `tool_input` over the cap was replaced by a truncation marker, or a prompt /
|
|
20391
|
+
agent entry''s whole payload text was cut at the same cap) | matcher_over_budget (the group matcher / entry `if` name part ran past its budget and the entry ran BY SELECTION; the same moment also sends a kind-2 frame
|
|
20392
|
+
`matcher_over_budget`).
|
|
20393
|
+
lane: { type: string, description: 'The lane the entry sits in, read off the source table: `managedPolicy` / `managedPlugin:*` => `managed`, everything else and absent => `unmanaged`. Closed (two words) server-side, open on read. Read THIS field, never re-derive from `source`.' }
|
|
20394
|
+
hookName: { type: string, description: 'Hook identity (same rule as kind 2); redacted + bounded.' }
|
|
20395
|
+
entryType: { type: string, description: 'command | http | prompt | agent โ closed server-side, open on read.' }
|
|
20396
|
+
toolName: { type: string, description: 'Present on tool events.' }
|
|
20397
|
+
source: { type: string, description: 'The source word the group declared (both lanes give it; ABSENT = the group declared none, so only unmanaged). Trace only, never a criterion.' }
|
|
20398
|
+
detail: { type: string, description: 'Redacted supplement (human-facing; machines read `reason` / `lane`).' }
|
|
20399
|
+
|
|
19944
20400
|
BakeStatus:
|
|
19945
20401
|
# ๆฐ(census ๆน2 ๅๆฎต)โโserver `BakeStatus`(plugins/store-contracts.ts), the COARSE lifecycle
|
|
19946
20402
|
# bakeView/claimResponse/bakesCreate all key on.
|
|
@@ -20450,6 +20906,11 @@ components:
|
|
|
20450
20906
|
K-24 (server >= 7.104.0 / S-724) โ does this leg capture file history (`on` / `disabled`, OPEN word). EFFECTIVE
|
|
20451
20907
|
HALF ONLY โ ALWAYS ABSENT ON THIS ENDPOINT; the deployment-level reading is `capabilities.fileHistoryCapture`.
|
|
20452
20908
|
Full per-key contract: see Event_wiring_manifest.fileHistory.
|
|
20909
|
+
permissionMode:
|
|
20910
|
+
allOf: [{ $ref: '#/components/schemas/WiringManifestPermissionMode' }]
|
|
20911
|
+
description: >-
|
|
20912
|
+
core 7.53.0, server >= 7.133.0 โ the leg's permission-mode receipt (section shape WiringManifestPermissionMode). EFFECTIVE HALF ONLY โ this (static) face NEVER carries it, and absence here carries no
|
|
20913
|
+
information; the reading holds only on a live `wiring_manifest` frame.
|
|
20453
20914
|
instructions:
|
|
20454
20915
|
allOf: [{ $ref: '#/components/schemas/WiringManifestInstructions' }]
|
|
20455
20916
|
description: >
|
|
@@ -20521,6 +20982,24 @@ components:
|
|
|
20521
20982
|
type: array
|
|
20522
20983
|
description: 'The selected chain member(s), spelled as the chain spells them (relative to the cwd); `[]` = the chain was walked, nothing was selected.'
|
|
20523
20984
|
items: { type: string, enum: ['CLAUDE.md', '.claude/CLAUDE.md', 'AGENTS.md', '.claude/AGENTS.md'] }
|
|
20985
|
+
WiringManifestPermissionMode:
|
|
20986
|
+
# server 7.133.0 / core 7.53.0:ๅไธๆฎตๅฝข่ขซ live ๅธง(ไธคๅผ ่ธ)ใ้ๆ่ฏๆญ้ขใ`POST /v1/tasks` ็ `wiringManifest` ๅๆงไธ่ดฆๆฌ่กๅผ็จ โ ๅ
ทๅๅๆบ(`spec-field-drift-gate` ไนๆใๅฏผๅบ็ interface ๅฟ
ๆๅๅ schemaใ้ผๅบๅฎ)ใ
|
|
20987
|
+
type: object
|
|
20988
|
+
additionalProperties: false
|
|
20989
|
+
description: >
|
|
20990
|
+
The `wiring_manifest.permissionMode` section (core 7.53.0 `PermissionModeReceipt`; server >= 7.133.0 projects it on BOTH faces โ tenant and operator โ and the same section rides the `wiringManifest`
|
|
20991
|
+
receipt of the `POST /v1/tasks` 200 body and the `/events` ledger row; the server judges SHAPE only: `effective` a non-empty string, `requested` / `foldedBy` absent or non-empty strings, else the whole section
|
|
20992
|
+
is dropped). The engine gives the same three-member receipt on EVERY mode question: `requested` = the mode word the caller declared (ABSENT = declared nothing โ a root inherits `default`, a child inherits its
|
|
20993
|
+
parent); `effective` = the mode the leg actually runs under (the request clamped under a parent's ceiling, then folded to `default` where the deployment denies it or the classifier face is absent) โ ALWAYS present,
|
|
20994
|
+
the shell renders its mode indicator from it; `foldedBy` = PRESENT IFF `requested` and `effective` differ โ `operator_deny` (the deployment / organization ceiling denies the mode) / `face_absent` (`auto` needs
|
|
20995
|
+
a classifier face this leg lacks) / `inherited_ceiling` (a delegated child clamped under its parent's ceiling); read OPEN (a fourth word passes through as "folded, cause unknown"). ABSENT section = an older
|
|
20996
|
+
engine / server (<= 7.132.x), not an assertion of the default mode. This is ONE added key on a closed object: a consumer validating `wiring_manifest` strictly against sdk <= 24.0.0's spec fails the whole frame
|
|
20997
|
+
on 7.133.0+ โ upgrade to sdk 25.0.0 or relax unknown keys on this section.
|
|
20998
|
+
required: [effective]
|
|
20999
|
+
properties:
|
|
21000
|
+
requested: { type: string, description: 'The mode word the caller declared (a PermissionMode word today; read open). ABSENT = declared nothing.' }
|
|
21001
|
+
effective: { type: string, description: 'The mode the leg actually runs under (a PermissionMode word today; read open). Always present.' }
|
|
21002
|
+
foldedBy: { type: string, description: 'Present iff `requested` and `effective` differ: `operator_deny` / `face_absent` / `inherited_ceiling` (engine words; read OPEN โ an unknown word means "folded, cause unknown").' }
|
|
20524
21003
|
WiringManifestModEntry:
|
|
20525
21004
|
# server 7.132.0 / core 7.52.0:ๅไปฃ้ฉๅญๅธญไฝ่กๅฝข(ๅ ,้ถๅซๅ)ใๅไธไปฝ่กๅฝข่ขซ live ๅธงไธ้ๆ่ฏๆญ้ขไธคๅคๅผ็จ โ ๅ
ทๅ;ไธคๅฝขๅ่ชๅ
ทๅ(โคbis ๅๅ้ๅฝขๅฏน่ดฆ)ใ
|
|
20526
21005
|
description: >
|
|
@@ -21050,10 +21529,218 @@ components:
|
|
|
21050
21529
|
remember for this session's category (fs-write tools share ONE category: approving Write covers
|
|
21051
21530
|
Edit/NotebookEdit; other tools are per-tool) โ the CC "don't ask again this session" semantic.
|
|
21052
21531
|
|
|
21532
|
+
ConfigCatalog:
|
|
21533
|
+
type: object
|
|
21534
|
+
description: >
|
|
21535
|
+
The 200 body of GET /v1/config/catalog (server `ConfigCatalogWire`) โ a PROJECTION, left open on read (the producer ships independently and adds keys additively between SDK releases; the request side has no body).
|
|
21536
|
+
required: [catalogVersion, envLaneTiming, restartSlices, centerDomains, summary, rows, retired]
|
|
21537
|
+
additionalProperties: true
|
|
21538
|
+
properties:
|
|
21539
|
+
catalogVersion: { type: integer, enum: [1] }
|
|
21540
|
+
envLaneTiming: { type: string, description: 'The env lane''s uniform timing (`deploy`: env is immutable at runtime, so changing env = changing the deployment). Open on read.' }
|
|
21541
|
+
restartSlices: { type: array, items: { type: string }, description: 'The restart-slice names a centre write can land in (open on read).' }
|
|
21542
|
+
centerDomains: { type: array, items: { type: string }, description: 'The contract package''s centre-configuration domains.' }
|
|
21543
|
+
summary:
|
|
21544
|
+
type: object
|
|
21545
|
+
required: [total, envHeld, secret, centerManaged]
|
|
21546
|
+
additionalProperties: true
|
|
21547
|
+
properties:
|
|
21548
|
+
total: { type: integer }
|
|
21549
|
+
envHeld: { type: integer }
|
|
21550
|
+
secret: { type: integer }
|
|
21551
|
+
centerManaged: { type: integer }
|
|
21552
|
+
rows: { type: array, items: { $ref: '#/components/schemas/ConfigCatalogRow' } }
|
|
21553
|
+
retired: { type: array, items: { $ref: '#/components/schemas/ConfigCatalogRetiredEnv' }, description: 'Tombstoned env names this process refuses to start on (always present, may be empty). A name is never in `rows` and here at once.' }
|
|
21554
|
+
ConfigCatalogRow:
|
|
21555
|
+
type: object
|
|
21556
|
+
description: >
|
|
21557
|
+
One catalog row (server `ConfigCatalogRow`): a deployment knob's static declaration plus this process's effective reading. OPEN on read (projection). The two VERDICT bits are the true-only family:
|
|
21558
|
+
`effectiveValueInvalid` (the effective value fell outside the row's echo set; `effectiveValue` is `null`) and `effectiveValueWithheld` (server >= 7.133.0) โ see the property.
|
|
21559
|
+
required: [name, domain, type, semantics, writeLanes, effectiveLane, envHeld, envTiming, effectiveValue, valueClass, danger]
|
|
21560
|
+
additionalProperties: true
|
|
21561
|
+
properties:
|
|
21562
|
+
name: { type: string, description: 'The knob (env) name; the catalog is sorted by it.' }
|
|
21563
|
+
domain: { type: string, description: 'One of the nine configuration groups (store / modelPlane / approval / memory / auth / orchestration / limitsHttp / observability / integrations). Open on read.' }
|
|
21564
|
+
type: { type: string, description: 'Value type: boolean | number | string | enum | csv | json | path | url | secret | opaque. Open on read.' }
|
|
21565
|
+
semantics: { type: string, description: 'Human sentence (true to the read site).' }
|
|
21566
|
+
writeLanes: { type: array, items: { type: string, enum: [env, center] }, description: 'Which lanes can write this knob.' }
|
|
21567
|
+
effectiveLane: { type: string, description: 'The lane actually in force: env | center | default. Open on read.' }
|
|
21568
|
+
envHeld: { type: boolean, description: 'This machine''s env sets it explicitly.' }
|
|
21569
|
+
envTiming: { type: string, description: '`deploy` (changing env = changing the deployment) | `inert` (retired / zero-consumer key). Open on read.' }
|
|
21570
|
+
staticDefault: { type: string }
|
|
21571
|
+
derivedDefaultNote: { type: string }
|
|
21572
|
+
effectiveValue:
|
|
21573
|
+
description: 'This process''s effective DISPLAY value: a scalar / a word list / `null` (unset) / `{ present, length? }` (`secret` / `opaque` rows report presence and length only).'
|
|
21574
|
+
oneOf:
|
|
21575
|
+
- { type: [string, number, boolean, 'null'] }
|
|
21576
|
+
- { type: array, items: { type: string } }
|
|
21577
|
+
- { type: object, required: [present], additionalProperties: true, properties: { present: { type: boolean }, length: { type: integer } } }
|
|
21578
|
+
valueClass: { type: string, description: '`plain` (echoable) | `secret` | `opaque` (the value never goes on the wire). Open on read.' }
|
|
21579
|
+
danger: { type: array, items: { type: string }, description: 'The risk axes of a wrong setting: security | billing | data (open on read).' }
|
|
21580
|
+
center: { $ref: '#/components/schemas/ConfigCatalogRowCenter' }
|
|
21581
|
+
centerDomain: { type: string }
|
|
21582
|
+
centerPath: { type: string }
|
|
21583
|
+
scope: { type: string, description: '`bootstrap-only` = read only at start-up.' }
|
|
21584
|
+
enumValues: { type: array, items: { type: string }, description: 'An `enum` row''s writable word set.' }
|
|
21585
|
+
effectiveValueInvalid:
|
|
21586
|
+
type: boolean
|
|
21587
|
+
enum: [true]
|
|
21588
|
+
description: 'TRUE-ONLY verdict bit: the effective value fell OUTSIDE the row''s own echo set (or a boolean without a declared mapping) โ `effectiveValue` is then `null` (echoing an out-of-set value would teach a consumer to write back an illegal word). Enum rows only. ABSENT = this cell has no such matter.'
|
|
21589
|
+
effectiveValueWithheld:
|
|
21590
|
+
type: boolean
|
|
21591
|
+
enum: [true]
|
|
21592
|
+
description: >-
|
|
21593
|
+
server >= 7.133.0, TRUE-ONLY verdict bit on `type: url` rows (present only when true, never `false`): the display mint judged this cell (single value) or any item of it (list) WITHHELD โ a part the position rule
|
|
21594
|
+
would have shown (the whole query / a path segment) was NOT shown because it held a credential-shaped piece. The mint owns the verdict; the catalog does not judge again. So the shown value is not the whole value:
|
|
21595
|
+
a catalog page / `sema config show` marks the row ("part of this value is withheld"), and must not read the shown value as "the value is exactly that". ABSENT = nothing withheld (older servers never send it).
|
|
21596
|
+
The standard position rule (userinfo landed, query values become tokens) holds for every row and is NOT a withholding; a value that became a placeholder as a whole means the row's display rule cannot show it
|
|
21597
|
+
(not a hierarchical URL; the two outbound-proxy rows show only scheme://host[:port]) โ also not this bit.
|
|
21598
|
+
ConfigCatalogRowCenter:
|
|
21599
|
+
type: object
|
|
21600
|
+
description: 'A catalog row''s centre seat: whether the knob is centre-publishable, who wins, when it takes effect. Present only on rows with a centre seat.'
|
|
21601
|
+
required: [domain, path, precedence, timing, managedNow, effectiveNow]
|
|
21602
|
+
additionalProperties: true
|
|
21603
|
+
properties:
|
|
21604
|
+
domain: { type: string }
|
|
21605
|
+
path: { type: string, description: 'Path in the domain (`a.b` into objects; `xs[].c` into array elements).' }
|
|
21606
|
+
precedence: { type: string, description: '`center-wins` | `env-wins` (open on read).' }
|
|
21607
|
+
timing: { type: string, description: '`hot` | `restart` | `inert` (open on read; not `deploy`).' }
|
|
21608
|
+
restartSlice: { type: string }
|
|
21609
|
+
restartReason: { type: string }
|
|
21610
|
+
managedNow: { type: boolean, description: 'The centre''s latest effective config currently MANAGES this key (no config pipeline => always false).' }
|
|
21611
|
+
effectiveNow: { type: boolean, description: 'The centre write is in force right now (managed AND not held down by an env placeholder).' }
|
|
21612
|
+
ConfigCatalogRetiredEnv:
|
|
21613
|
+
type: object
|
|
21614
|
+
description: 'A tombstoned env name (the contract package''s RETIRED_ENVS wire projection): a name this process refuses to start on. `renamed` carries only `replacement`; `replaced` carries `replacement` + `reason` (how the value semantics changed); `removed` carries only `reason`.'
|
|
21615
|
+
required: [name, kind]
|
|
21616
|
+
additionalProperties: true
|
|
21617
|
+
properties:
|
|
21618
|
+
name: { type: string }
|
|
21619
|
+
kind: { type: string, description: '`renamed` | `replaced` | `removed` (open on read).' }
|
|
21620
|
+
replacement: { type: string }
|
|
21621
|
+
reason: { type: string }
|
|
21622
|
+
EntryProblem:
|
|
21623
|
+
type: object
|
|
21624
|
+
description: >
|
|
21625
|
+
One ENTRY PROBLEM (server >= 7.133.0): a refusal body's `detail.problems[]` element and an accept-time `warnings[]` element share this shape. `code` = the refusal code the problem belongs to (in `warnings[]`: the engine's
|
|
21626
|
+
reading code for that entry); `field` = the coordinate of the list holding the entry in the request body (`settings.permissions.allow`, `skills[i].allowedTools` โฆ); `entry` = the entry string (passed through the server''s
|
|
21627
|
+
redaction mouth โ not a guarantee of your original bytes); `reason` = the machine reason โ mostly the ENGINE''s word verbatim (why it read the entry as nothing); the server mints two of its own, `not_in_roster` (accept-time
|
|
21628
|
+
warnings only: the name in an allow-side selector list is not in the roster and is no protocol namespace name โ the engine accepts it anyway) and `home_unresolvable` (settings-rule 422: a `~/` path rule on a deployment that cannot
|
|
21629
|
+
resolve the execution environment''s home); and `below_trust_floor` (the caller''s trust tier is below the member''s admission floor โ see ErrorResponse.detail.callerTrust). Read OPEN.
|
|
21630
|
+
required: [code, field, entry, reason]
|
|
21631
|
+
additionalProperties: false
|
|
21632
|
+
properties:
|
|
21633
|
+
code: { type: string }
|
|
21634
|
+
field: { type: string }
|
|
21635
|
+
entry: { type: string }
|
|
21636
|
+
reason: { type: string }
|
|
21637
|
+
PrincipalInboxMessage:
|
|
21638
|
+
type: object
|
|
21639
|
+
description: 'The request body of POST /v1/principal-inbox/messages: a CLOSED three-key shape (`from` is minted by the server from the verified identity and cannot be sent).'
|
|
21640
|
+
required: [to, content]
|
|
21641
|
+
additionalProperties: false
|
|
21642
|
+
properties:
|
|
21643
|
+
to: { type: string, minLength: 1, description: 'The recipient principal string. Must belong to the sender''s organization (the membership judgement reads the organization directory); a failed judgement is 404 `org_delivery.not_member`, byte-identical to "no such person".' }
|
|
21644
|
+
content: { type: string, minLength: 1, maxLength: 32000, description: 'The letter body (characters; over 32000 => 400 `request.field_invalid`).' }
|
|
21645
|
+
urgent: { type: boolean, description: 'The urgent flag on the envelope (absent = ordinary).' }
|
|
21646
|
+
PrincipalInboxReceipt:
|
|
21647
|
+
type: object
|
|
21648
|
+
description: 'The 200 receipt: the letter was appended. `receiptId` = the gate-minted delivery receipt id (the envelope''s `gateReceiptId` carries the same value).'
|
|
21649
|
+
required: [receiptId]
|
|
21650
|
+
additionalProperties: false
|
|
21651
|
+
properties:
|
|
21652
|
+
receiptId: { type: string }
|
|
21653
|
+
OrgDeliveryRefusalCode:
|
|
21654
|
+
type: string
|
|
21655
|
+
enum: [org_delivery.not_member, org_delivery.rate_limited, org_delivery.inbox_full, org_delivery.recipient_tombstoned]
|
|
21656
|
+
description: >
|
|
21657
|
+
The four cross-principal delivery refusal codes (server >= 7.133.0; the engine's closed `ORG_DELIVERY_REFUSAL_CODES`, one frozen sentence each โ machines read the CODE): `org_delivery.not_member` (404),
|
|
21658
|
+
`org_delivery.rate_limited` (429), `org_delivery.inbox_full` (409), `org_delivery.recipient_tombstoned` (410). See POST /v1/principal-inbox/messages.
|
|
21659
|
+
ToolApprovalReadState:
|
|
21660
|
+
type: string
|
|
21661
|
+
enum: [pending, decided, parked, void]
|
|
21662
|
+
description: >
|
|
21663
|
+
`state` of GET /v1/tool-approvals/{id} (server >= 7.133.0), a CLOSED four-word set โ read it exhaustively: `pending` = a live registration on this replica is waiting (answer door open);
|
|
21664
|
+
`decided` = the row is DECIDED; `parked` = PARKING / PARKED (a late answer redeems the parked card); `void` = DENIED / VOID (nobody decided it, the answer has nowhere to land).
|
|
21665
|
+
ApprovalsStreamReadErrorCode:
|
|
21666
|
+
type: string
|
|
21667
|
+
enum: [approvals.read_unavailable, approvals.read_corrupt]
|
|
21668
|
+
description: >
|
|
21669
|
+
The `errorCode` of the two READ-FAILURE `error` frames on GET /v1/approvals/stream (server >= 7.133.0). `approvals.read_unavailable` = this tick's approval read failed (the store was momentarily
|
|
21670
|
+
unreadable) โ the stream STAYS open and the next tick reads again; it is NOT a terminal frame and NOT a reconnect signal (do not reconnect on it, and do not read it as "nothing pending").
|
|
21671
|
+
`approvals.read_corrupt` = a corrupt row was read โ the server closes the stream after the frame; deal with that row before reopening. Branch on the code, never match the message.
|
|
21672
|
+
Older servers (<= 7.132.x) answer a read failure with nothing but heartbeats.
|
|
21673
|
+
ToolApprovalReadProjection:
|
|
21674
|
+
type: object
|
|
21675
|
+
description: >
|
|
21676
|
+
The row projection shared by the three non-`pending` arms of GET /v1/tool-approvals/{id} (server >= 7.133.0): a SUBSET of the `livePending[]` row keys โ one reader, one key set. `frame` = the disconnect-replay
|
|
21677
|
+
opening frame (an `approval_request` frame; ABSENT when the card cannot be read back โ never invented).
|
|
21678
|
+
required: [approvalId, ts, expiresAtMs]
|
|
21679
|
+
additionalProperties: true
|
|
21680
|
+
properties:
|
|
21681
|
+
approvalId: { type: string }
|
|
21682
|
+
ts: { type: number, description: 'Registration time (ms epoch).' }
|
|
21683
|
+
expiresAtMs: { type: number, description: 'Absolute window deadline (cast once, never recomputed).' }
|
|
21684
|
+
sessionId: { type: string }
|
|
21685
|
+
toolName: { type: string }
|
|
21686
|
+
frame: { $ref: '#/components/schemas/ApprovalRequestFrame' }
|
|
21687
|
+
ToolApprovalReadBody:
|
|
21688
|
+
description: >
|
|
21689
|
+
The 200 body of GET /v1/tool-approvals/{id} (server >= 7.133.0) โ a four-arm union discriminated by `state` (closed, read it exhaustively): `pending` = a live registration on this replica is waiting
|
|
21690
|
+
(the `livePending[]` row + `state`; answer door open); `decided` = the row is DECIDED (`decision` / `decidedAtMs` / `decisionNote?`, the same three keys as the late-replay body); `parked` = PARKING / PARKED
|
|
21691
|
+
(a late answer redeems the parked card; `decidePath?` points at the durable decision path); `void` = DENIED / VOID (nobody decided it, the answer has nowhere to land; `cause?` is the same cause word as the
|
|
21692
|
+
late-answer 404's, see ToolApprovalNotPendingCause).
|
|
21693
|
+
oneOf:
|
|
21694
|
+
- $ref: '#/components/schemas/ToolApprovalReadPending'
|
|
21695
|
+
- $ref: '#/components/schemas/ToolApprovalReadDecided'
|
|
21696
|
+
- $ref: '#/components/schemas/ToolApprovalReadParked'
|
|
21697
|
+
- $ref: '#/components/schemas/ToolApprovalReadVoid'
|
|
21698
|
+
discriminator:
|
|
21699
|
+
propertyName: state
|
|
21700
|
+
mapping:
|
|
21701
|
+
pending: '#/components/schemas/ToolApprovalReadPending'
|
|
21702
|
+
decided: '#/components/schemas/ToolApprovalReadDecided'
|
|
21703
|
+
parked: '#/components/schemas/ToolApprovalReadParked'
|
|
21704
|
+
void: '#/components/schemas/ToolApprovalReadVoid'
|
|
21705
|
+
ToolApprovalReadPending:
|
|
21706
|
+
allOf:
|
|
21707
|
+
- $ref: '#/components/schemas/LivePendingRow'
|
|
21708
|
+
- type: object
|
|
21709
|
+
required: [state]
|
|
21710
|
+
properties:
|
|
21711
|
+
state: { type: string, enum: [pending] }
|
|
21712
|
+
ToolApprovalReadDecided:
|
|
21713
|
+
allOf:
|
|
21714
|
+
- $ref: '#/components/schemas/ToolApprovalReadProjection'
|
|
21715
|
+
- type: object
|
|
21716
|
+
required: [state, decision, decidedAtMs]
|
|
21717
|
+
properties:
|
|
21718
|
+
state: { type: string, enum: [decided] }
|
|
21719
|
+
decision: { type: string, enum: [allow, deny] }
|
|
21720
|
+
decidedAtMs: { type: integer }
|
|
21721
|
+
decisionNote: { type: string }
|
|
21722
|
+
ToolApprovalReadParked:
|
|
21723
|
+
allOf:
|
|
21724
|
+
- $ref: '#/components/schemas/ToolApprovalReadProjection'
|
|
21725
|
+
- type: object
|
|
21726
|
+
required: [state]
|
|
21727
|
+
properties:
|
|
21728
|
+
state: { type: string, enum: [parked] }
|
|
21729
|
+
decidePath: { type: string, description: 'The durable decision path for this ask when it can be built.' }
|
|
21730
|
+
ToolApprovalReadVoid:
|
|
21731
|
+
allOf:
|
|
21732
|
+
- $ref: '#/components/schemas/ToolApprovalReadProjection'
|
|
21733
|
+
- type: object
|
|
21734
|
+
required: [state]
|
|
21735
|
+
properties:
|
|
21736
|
+
state: { type: string, enum: [void] }
|
|
21737
|
+
cause:
|
|
21738
|
+
allOf: [{ $ref: '#/components/schemas/AskRowEndingCause' }]
|
|
21739
|
+
description: 'The row''s recorded ending cause (absent for a legacy row with no cause written โ never invented).'
|
|
21053
21740
|
ToolApprovalRespondApplied:
|
|
21054
21741
|
type: object
|
|
21055
21742
|
description: >
|
|
21056
|
-
The APPLIED arm of the 200 ack of POST /v1/tool-approvals/{
|
|
21743
|
+
The APPLIED arm of the 200 ack of POST /v1/tool-approvals/{id}/respond (server tool-approval.ts โ exact
|
|
21057
21744
|
shape, `decision` echoed): the decision settled a live gate. Owner-gated with a 404 and NO existence oracle: non-owner and
|
|
21058
21745
|
unknown/settled/expired/wrong-replica ids are indistinguishable. See ToolApprovalRespondAck for the replayed arm.
|
|
21059
21746
|
# ๅฐ้ญ(census ๆน2 ็ฌฌไธๆฎต,2026-07-30):้ธ้ ็น `tool-approval.ts` ไธๆๅจ้ฎ + ไธคๆกไปถ้ฎ
|
|
@@ -21069,6 +21756,13 @@ components:
|
|
|
21069
21756
|
approvalId: { type: string }
|
|
21070
21757
|
delivery: { type: string, enum: [applied] }
|
|
21071
21758
|
decision: { $ref: '#/components/schemas/ToolApprovalDecision' }
|
|
21759
|
+
consumerState:
|
|
21760
|
+
type: string
|
|
21761
|
+
enum: [absent]
|
|
21762
|
+
description: >-
|
|
21763
|
+
server >= 7.133.0, TRUE-ONLY: no engine leg on THIS replica was waiting for the ask this answer settled โ the same bit, with the same meaning, as `LivePendingRow.consumerState` and the
|
|
21764
|
+
durable decision ack's. Present <=> the answered entry was ADOPTED from the ask ledger at start-up. The decision lands on the row as usual, but nothing running here resumes because of it โ read the run
|
|
21765
|
+
surface; do not read the 200 as "the run continued". Absent = a local engine leg was waiting, or an older server.
|
|
21072
21766
|
rememberApplied:
|
|
21073
21767
|
type: boolean
|
|
21074
21768
|
description: >
|
|
@@ -21160,7 +21854,7 @@ components:
|
|
|
21160
21854
|
ToolApprovalRespondReplayed:
|
|
21161
21855
|
type: object
|
|
21162
21856
|
description: >
|
|
21163
|
-
The REPLAYED arm of the 200 ack of POST /v1/tool-approvals/{
|
|
21857
|
+
The REPLAYED arm of the 200 ack of POST /v1/tool-approvals/{id}/respond: the ask was already DECIDED
|
|
21164
21858
|
(by anyone) when this answer arrived, so the server replays the FIRST decision โ `decision` is the row's two-word
|
|
21165
21859
|
value (`allow_session` was folded to `allow` when it landed), `decidedAtMs` the first decision's clock,
|
|
21166
21860
|
`decisionNote` only when the row has one, `rememberApplied: false` only when THIS request asked `allow_session`.
|
|
@@ -21176,14 +21870,57 @@ components:
|
|
|
21176
21870
|
decidedAtMs: { type: integer }
|
|
21177
21871
|
decisionNote: { type: string }
|
|
21178
21872
|
rememberApplied: { type: boolean, enum: [false] }
|
|
21873
|
+
noteRecorded: { type: boolean, description: 'server >= 7.133.0 (two doors, one shape): present ONLY when THIS request carried a `note`; `true` <=> the row''s text is verbatim what this request submitted, `false` = not confirmed (another reason is on the row / no store / read-back failed). A late answer''s note never overwrites the first decision''s reason โ that is `decisionNote`.' }
|
|
21874
|
+
rulePersisted: { type: boolean, enum: [false], description: 'server >= 7.133.0: present (as `false`) only when this late answer carried `persistRule`: the rule is redeemed on the FIRST decision only, a late answer never saves one.' }
|
|
21875
|
+
ruleRefusal:
|
|
21876
|
+
type: string
|
|
21877
|
+
enum: [rule_lane_unavailable]
|
|
21878
|
+
description: 'with `rulePersisted: false`; on this arm always `rule_lane_unavailable` (the only word the published late-answer path mints).'
|
|
21879
|
+
ToolApprovalRespondParkedRedeemed:
|
|
21880
|
+
type: object
|
|
21881
|
+
description: >
|
|
21882
|
+
The PARKED-REDEEMED arm of the 200 ack of POST /v1/tool-approvals/{id}/respond (server >= 7.133.0; server tool-approval.ts `redeemParkedAsk` /
|
|
21883
|
+
`replayRedeemReceipt`): the card's window had run out and the ask moved to background waiting (PARKED); this late answer โ on another replica or after a restart โ
|
|
21884
|
+
goes through the EXISTING durable redemption leg (the same CAS as POST /v1/approvals/{sessionId}/decide) instead of the old 404 `tool_approval.not_pending`
|
|
21885
|
+
(`cause: unknown_or_other_replica`). Body = the redemption leg's receipt (ApprovalDecisionResult's keys โ `status` / `taskId` / `sessionId` / ... as they come) plus the three keys
|
|
21886
|
+
this door adds: `approvalId` / `askId` (the same 64-hex value) and the discriminant `accepted`. `decision` is the two-word direction on the REPLAY form only (`allow` / `deny`,
|
|
21887
|
+
`allow_session` folded to `allow`); `rememberApplied: false` appears only when this request asked `allow_session` (a parked redemption cannot remember a session grant);
|
|
21888
|
+
`rulePersisted` / `ruleRefusal` / `persistedRule*` are the `persistRule` outcome on the redemption leg (a rule that fails to store NEVER flips the verdict).
|
|
21889
|
+
`idempotent: true` appears only on the REPLAY (the same already-redeemed card answered again returns the first redemption's receipt).
|
|
21890
|
+
CLOSED like its two sibling arms (the census keeps this op's 200 body closed): the key set is ApprovalDecisionResult's own keys (one source per shape, by `$ref`) plus the added ones.
|
|
21891
|
+
required: [approvalId, askId, accepted]
|
|
21892
|
+
additionalProperties: false
|
|
21893
|
+
properties:
|
|
21894
|
+
approvalId: { type: string }
|
|
21895
|
+
askId: { type: string }
|
|
21896
|
+
accepted: { type: string, enum: [parked_redeemed] }
|
|
21897
|
+
status: { $ref: '#/components/schemas/ApprovalDecisionResult/properties/status' }
|
|
21898
|
+
taskId: { $ref: '#/components/schemas/ApprovalDecisionResult/properties/taskId' }
|
|
21899
|
+
sessionId: { $ref: '#/components/schemas/ApprovalDecisionResult/properties/sessionId' }
|
|
21900
|
+
bindingEnforced: { $ref: '#/components/schemas/ApprovalDecisionResult/properties/bindingEnforced' }
|
|
21901
|
+
decision: { type: string, description: 'REPLAY form: `allow` / `deny` (`allow_session` folded to `allow`). FIRST redemption: whatever the redemption leg''s own receipt says (`approve` / `deny` today) โ read it open.' }
|
|
21902
|
+
errorCode: { $ref: '#/components/schemas/ApprovalDecisionResult/properties/errorCode' }
|
|
21903
|
+
errorMessage: { $ref: '#/components/schemas/ApprovalDecisionResult/properties/errorMessage' }
|
|
21904
|
+
retriable: { $ref: '#/components/schemas/ApprovalDecisionResult/properties/retriable' }
|
|
21905
|
+
idempotent: { $ref: '#/components/schemas/ApprovalDecisionResult/properties/idempotent' }
|
|
21906
|
+
executionOutcome: { $ref: '#/components/schemas/ApprovalDecisionResult/properties/executionOutcome' }
|
|
21907
|
+
rememberApplied: { type: boolean, enum: [false] }
|
|
21908
|
+
rulePersisted: { $ref: '#/components/schemas/ToolApprovalRespondApplied/properties/rulePersisted' }
|
|
21909
|
+
ruleRefusal: { $ref: '#/components/schemas/ToolApprovalRespondApplied/properties/ruleRefusal' }
|
|
21910
|
+
persistedRule: { $ref: '#/components/schemas/ToolApprovalRespondApplied/properties/persistedRule' }
|
|
21911
|
+
persistedRules: { $ref: '#/components/schemas/ToolApprovalRespondApplied/properties/persistedRules' }
|
|
21912
|
+
persistedRuleAnchors: { $ref: '#/components/schemas/ToolApprovalRespondApplied/properties/persistedRuleAnchors' }
|
|
21179
21913
|
ToolApprovalRespondAck:
|
|
21180
21914
|
description: >
|
|
21181
|
-
The 200 ack of POST /v1/tool-approvals/{
|
|
21915
|
+
The 200 ack of POST /v1/tool-approvals/{id}/respond โ a discriminated union: the decision was APPLIED to a live
|
|
21182
21916
|
gate (ToolApprovalRespondApplied, `delivery: "applied"`) or the ask was already decided and the first decision is
|
|
21183
|
-
REPLAYED (ToolApprovalRespondReplayed, `idempotent: true`).
|
|
21917
|
+
REPLAYED (ToolApprovalRespondReplayed, `idempotent: true`), or (server >= 7.133.0, sdk 25.0.0) the answer REDEEMED a PARKED card through the durable redemption
|
|
21918
|
+
leg (ToolApprovalRespondParkedRedeemed, `accepted: "parked_redeemed"`). The discriminants are `delivery` / `idempotent` / `accepted` (a replayed redemption carries
|
|
21919
|
+
BOTH `accepted: "parked_redeemed"` and `idempotent: true` โ read `accepted` first).
|
|
21184
21920
|
oneOf:
|
|
21185
21921
|
- $ref: '#/components/schemas/ToolApprovalRespondApplied'
|
|
21186
21922
|
- $ref: '#/components/schemas/ToolApprovalRespondReplayed'
|
|
21923
|
+
- $ref: '#/components/schemas/ToolApprovalRespondParkedRedeemed'
|
|
21187
21924
|
UsageMetric:
|
|
21188
21925
|
type: string
|
|
21189
21926
|
enum: [tasks, tokensIn, tokensOut, costUsd]
|
|
@@ -22141,7 +22878,7 @@ components:
|
|
|
22141
22878
|
|
|
22142
22879
|
AdoptionNotMigratedFace:
|
|
22143
22880
|
type: string
|
|
22144
|
-
enum: [usage-window, cost-quota, rate-limit, approval-exemption-grantor, approval-ask-decision-actor, image-bake-requested-by]
|
|
22881
|
+
enum: [usage-window, cost-quota, rate-limit, approval-exemption-grantor, approval-ask-decision-actor, image-bake-requested-by, permission-rule-approval-history, permission-rule-import-ticket, org-delivery-quota]
|
|
22145
22882
|
description: >
|
|
22146
22883
|
FROZEN machine-readable vocabulary of the faces the server deliberately does not migrate. Renaming or
|
|
22147
22884
|
removing a member is a wire break; adding one is a new behaviour face. Consumers assert POSITIVELY on
|