@sema-agent/sdk 26.0.0 โ 26.1.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 +48 -0
- package/dist/errors.d.ts +53 -3
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +18 -1
- package/dist/errors.js.map +1 -1
- package/dist/events.d.ts +28 -2
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js.map +1 -1
- package/dist/index.d.ts +12 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/resources/approvals.d.ts +4 -2
- package/dist/resources/approvals.d.ts.map +1 -1
- package/dist/resources/approvals.js +1 -1
- package/dist/resources/approvals.js.map +1 -1
- package/dist/resources/fleet.d.ts +4 -0
- package/dist/resources/fleet.d.ts.map +1 -1
- package/dist/resources/fleet.js.map +1 -1
- package/dist/resources/rules.d.ts +1 -1
- package/dist/resources/runs.d.ts +4 -1
- package/dist/resources/runs.d.ts.map +1 -1
- package/dist/resources/runs.js +4 -1
- package/dist/resources/runs.js.map +1 -1
- package/dist/resources/session-sync.d.ts +9 -2
- package/dist/resources/session-sync.d.ts.map +1 -1
- package/dist/resources/session-sync.js +9 -2
- package/dist/resources/session-sync.js.map +1 -1
- package/dist/resources/sessions.d.ts +5 -3
- package/dist/resources/sessions.d.ts.map +1 -1
- package/dist/resources/sessions.js +5 -3
- package/dist/resources/sessions.js.map +1 -1
- package/dist/resources/side-query.d.ts +8 -0
- package/dist/resources/side-query.d.ts.map +1 -1
- package/dist/resources/side-query.js.map +1 -1
- package/dist/resources/tasks.d.ts +2 -0
- package/dist/resources/tasks.d.ts.map +1 -1
- package/dist/resources/tasks.js +2 -0
- package/dist/resources/tasks.js.map +1 -1
- package/dist/resources/tool-approvals.d.ts +47 -3
- package/dist/resources/tool-approvals.d.ts.map +1 -1
- package/dist/resources/tool-approvals.js +18 -3
- package/dist/resources/tool-approvals.js.map +1 -1
- package/dist/settings.d.ts +1 -1
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +2 -0
- package/dist/sync.js.map +1 -1
- package/dist/transport.d.ts +5 -2
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +6 -2
- package/dist/transport.js.map +1 -1
- package/dist/types.d.ts +104 -19
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -1
- package/openapi.yaml +333 -31
- package/package.json +2 -3
package/openapi.yaml
CHANGED
|
@@ -2428,7 +2428,7 @@ paths:
|
|
|
2428
2428
|
summary: Write the per-session tool-permission rules (tighten-only).
|
|
2429
2429
|
description: >
|
|
2430
2430
|
E6 โ write the per-session rules. ๐ด TIGHTEN-ONLY for a normal principal: a loosen (remove a deny / widen
|
|
2431
|
-
an allowlist or allowDirs) โ 403 `loosen_forbidden` (operator-only). `expectedRev` = optimistic-concurrency
|
|
2431
|
+
an allowlist or allowDirs) โ 403 `loosen_forbidden` (operator-only). ๐ด server >= 7.135.0 (engine 7.55.0): the tighten gate is a gate on the row's OPERATOR PART (`operatorRules`), not on the whole row โ a non-operator (the session's owner) can take back what NON-operator writes added, but not what an operator wrote (moving anything inside the operator part, even an entry both sides wrote, answers 403 `loosen_forbidden`; the row stays). <= 7.134.x: a non-operator write was subtract-only against the whole row. Read the CODE (the sentence changed: `a non-operator session-rule write may not loosen what an operator wrote; refused: โฆ` vs `โฆ may only tighten โฆ`) โ never the sentence. `expectedRev` = optimistic-concurrency
|
|
2432
2432
|
CAS; a stale rev โ 409 `conflict`. Each rule field must be `string[]` and the body carries only the three buckets (`toolAllow` / `toolDeny` / `allowDirs`; any other
|
|
2433
2433
|
key, including the retired `commandAllow` / `commandDeny`, โ 400 `rules.invalid_shape` on server >= 7.129.0) โ malformed body 400. ownerless
|
|
2434
2434
|
session โ 409; non-owner โ 404. 501 without a session-policy store.
|
|
@@ -2456,6 +2456,9 @@ paths:
|
|
|
2456
2456
|
# write judge stamps the current grammar). `grammar` newer than the engine's โ `400 rules.invalid_shape`.
|
|
2457
2457
|
rev: { type: integer, minimum: 0 }
|
|
2458
2458
|
grammar: { type: integer, minimum: 0 }
|
|
2459
|
+
# server >= 7.135.0 (engine 7.55.0): a stored body echoed back (GET โ edit โ PUT) may also carry its `operatorRules`; on THIS door the echoed part is ALWAYS ignored โ the route reads the value through the write reader
|
|
2460
|
+
# (its product carries no `rev`) and the store judges it again: over an existing row the STORED row's operator part is kept, over no row an empty stamped part is minted. Do not rely on an echo to move the operator line โ send the new value without `operatorRules`.
|
|
2461
|
+
operatorRules: { $ref: '#/components/schemas/SessionRulesOperatorPart' }
|
|
2459
2462
|
expectedRev: { type: integer, minimum: 0, description: CAS โ reject if the stored rev differs. }
|
|
2460
2463
|
responses:
|
|
2461
2464
|
'200':
|
|
@@ -2492,7 +2495,8 @@ paths:
|
|
|
2492
2495
|
schema: { $ref: '#/components/schemas/ErrorResponse' }
|
|
2493
2496
|
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
2494
2497
|
'403':
|
|
2495
|
-
description:
|
|
2498
|
+
description: >-
|
|
2499
|
+
403 `loosen_forbidden` โ a non-operator write tried to relax what an OPERATOR wrote (server >= 7.135.0; <= 7.134.x: relax the rules at all, tighten-only). Branch on the code, never the sentence (it changed with 7.135.0).
|
|
2496
2500
|
content:
|
|
2497
2501
|
application/json:
|
|
2498
2502
|
schema: { $ref: '#/components/schemas/ErrorResponse' }
|
|
@@ -2581,7 +2585,7 @@ paths:
|
|
|
2581
2585
|
narrow it, switch with a default arm; `httpStatus` 401 is a re-authorize door); `reason` is HUMAN TEXT
|
|
2582
2586
|
(server-redacted, length-bounded) and must NOT be parsed.
|
|
2583
2587
|
Gates, the same family as steer / capture-optout: 501 `capability.run_store_required` (no durable run
|
|
2584
|
-
ledger) ยท 501 `capability.session_ownership_required` (no `sessionStorage.ownerOf`) ยท 400
|
|
2588
|
+
ledger) ยท 501 `capability.session_ownership_required` (no `sessionStorage.headOf`; <= 7.134.x: `ownerOf`) ยท 400
|
|
2585
2589
|
`request.path_malformed` (bad percent-encoding in the id) ยท 404 `not_found.session` โ unknown session
|
|
2586
2590
|
AND someone else's session answer the SAME code and SAME message (deliberate: no existence oracle); an
|
|
2587
2591
|
EXPLICIT operator may re-dial any tenant's session ยท 422 `steering.invalid_content` ยท 409
|
|
@@ -2647,7 +2651,7 @@ paths:
|
|
|
2647
2651
|
the model's description, falling back to the launch command text (content family: redacted, cut at 500
|
|
2648
2652
|
chars). At most 500 rows (core `list()`'s own cap). ๐ด IN-PROCESS: only rows on THIS replica.
|
|
2649
2653
|
Zero model work: not billable, not refused by drain. Gates (same family as `mcp/reconnect`): 501
|
|
2650
|
-
`capability.session_ownership_required` (no `sessionStorage.ownerOf`) ยท 404 `not_found.session` โ unknown
|
|
2654
|
+
`capability.session_ownership_required` (no `sessionStorage.headOf`; <= 7.134.x: `ownerOf`) ยท 404 `not_found.session` โ unknown
|
|
2651
2655
|
session AND someone else's session answer the SAME code and SAME message (no existence oracle); an EXPLICIT
|
|
2652
2656
|
operator may read any session ยท 400 `request.path_malformed`. Probe with `capabilities.background.listFace`;
|
|
2653
2657
|
ABSENT key = an older server, where this path is 404 `not_found.route` (same status, different code).
|
|
@@ -2920,6 +2924,14 @@ paths:
|
|
|
2920
2924
|
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
2921
2925
|
'404': { $ref: '#/components/responses/NotFound' }
|
|
2922
2926
|
'501': { $ref: '#/components/responses/NotImplemented' }
|
|
2927
|
+
'503':
|
|
2928
|
+
description: >-
|
|
2929
|
+
server >= 7.135.0: `503 state.file_history_unreadable` โ this session's file history cannot be read WHOLE (a boundary torn / unreadable, the tracked set unreadable); nothing is exported this time. ๐ด It is NOT "no history":
|
|
2930
|
+
with nothing to export the manifest still answers `200` with `fileHistory: null`. May carry `permanence` (`transient` / `terminal`; absent = the store did not judge โ see `ErrorResponse.permanence`). Older servers read an
|
|
2931
|
+
unreadable history as "none" (manifest 200 / blob 404).
|
|
2932
|
+
content:
|
|
2933
|
+
application/json:
|
|
2934
|
+
schema: { $ref: '#/components/schemas/ErrorResponse' }
|
|
2923
2935
|
|
|
2924
2936
|
/v1/sessions/{sessionId}/sync/entries:
|
|
2925
2937
|
parameters:
|
|
@@ -2994,6 +3006,14 @@ paths:
|
|
|
2994
3006
|
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
2995
3007
|
'404': { $ref: '#/components/responses/NotFound' }
|
|
2996
3008
|
'501': { $ref: '#/components/responses/NotImplemented' }
|
|
3009
|
+
'503':
|
|
3010
|
+
description: >-
|
|
3011
|
+
server >= 7.135.0: `503 state.file_history_unreadable` โ the history cannot be read WHOLE, so the server cannot tell whether this hash is one the session references โ it does NOT answer "no such blob" (that is `404 not_found.blob`) and gives no bytes. ๐ด It is NOT "no history":
|
|
3012
|
+
with nothing to export the manifest still answers `200` with `fileHistory: null`. May carry `permanence` (`transient` / `terminal`; absent = the store did not judge โ see `ErrorResponse.permanence`). Older servers read an
|
|
3013
|
+
unreadable history as "none" (manifest 200 / blob 404).
|
|
3014
|
+
content:
|
|
3015
|
+
application/json:
|
|
3016
|
+
schema: { $ref: '#/components/schemas/ErrorResponse' }
|
|
2997
3017
|
|
|
2998
3018
|
/v1/sessions/{sessionId}/sync/blobs/{hash}:
|
|
2999
3019
|
parameters:
|
|
@@ -3091,12 +3111,15 @@ paths:
|
|
|
3091
3111
|
description: >
|
|
3092
3112
|
2c session-sync PUSH Phase A โ a SMALL metadata body (`entryIds, fileHistory?, policy, anchors, resolution?, logDigest?, title?, pinned?`); the
|
|
3093
3113
|
entries stream in Phase B. The cloud classifies (ยง7), pre-checks blob presence (a missing referenced hash โ
|
|
3094
|
-
422 `missing_blob` โ PUT it first
|
|
3114
|
+
422 `missing_blob` โ PUT it first; server >= 7.135.0 answers it in this FIRST phase โ zero staging, zero commit, ahead of the `identical` replay arm โ and
|
|
3115
|
+
a deployment whose `capabilities.sessionSyncFileHistory` is false, e.g. `DB_BACKEND=local`, takes a `fileHistory` that references blobs as a first-phase 422 too: the conversation does not land either; <= 7.134.x answered it after the conversation
|
|
3116
|
+
had committed), guards the import lease + any active run (409), then mints a stagingId. ๐ด server >= 7.135.0: a file-history replay fault (the replay arms of `identical` re-push and of the commit) answers `422 adopt_failed`
|
|
3117
|
+
(+ optional `permanence`, see `ErrorResponse.permanence`; <= 7.134.x: `unsupported_format`) โ distinct from `missing_blob`.
|
|
3095
3118
|
The file history rides `fileHistory` (a `FileHistoryExport` envelope, `null` / absent = none) and every blob it references must have been
|
|
3096
3119
|
`PUT โฆ/sync/blobs/{hash}` first (the `snapshots` key of servers <= 7.51 is outside the support range; a supported server ignores it and sdk 26.0.0
|
|
3097
3120
|
no longer declares it). The SDK carries `fileHistory` in `pushSessionBundle` / `importSessionBundle`; a hand-rolled
|
|
3098
|
-
push must send `fileHistory` itself, and only to a peer whose `capabilities.sessionSyncFileHistory` is not false (server >= 7.116.0 โ else
|
|
3099
|
-
commit
|
|
3121
|
+
push must send `fileHistory` itself, and only to a peer whose `capabilities.sessionSyncFileHistory` is not false (server >= 7.116.0 โ else
|
|
3122
|
+
`422 missing_blob` in the first phase from server >= 7.135.0; after the commit on <= 7.134.x).
|
|
3100
3123
|
`identical` โ `{ relation:"identical", basis, payloadVerified }` with NO stagingId (skip Phase B);
|
|
3101
3124
|
`basis` is `"entry-ids+digest"` when the caller supplied a comparable digest and it matched, else
|
|
3102
3125
|
`"entry-ids"` (id-set equality only) โ see the `ImportStaged` schema, which has carried these two
|
|
@@ -3169,7 +3192,12 @@ paths:
|
|
|
3169
3192
|
content:
|
|
3170
3193
|
application/json:
|
|
3171
3194
|
schema: { $ref: '#/components/schemas/SyncConflict' }
|
|
3172
|
-
'422':
|
|
3195
|
+
'422':
|
|
3196
|
+
description: >-
|
|
3197
|
+
422 โ `missing_blob` (first phase from server >= 7.135.0), `restore_failed`, and (server >= 7.135.0) `adopt_failed` (+ optional `permanence`) for the file-history replay; `invalid_entries` etc. as before. Branch on `errorCode`.
|
|
3198
|
+
content:
|
|
3199
|
+
application/json:
|
|
3200
|
+
schema: { $ref: '#/components/schemas/ErrorResponse' }
|
|
3173
3201
|
'501': { $ref: '#/components/responses/NotImplemented' }
|
|
3174
3202
|
'503': { $ref: '#/components/responses/Unauthorized' } # (declared 2026-08-01) E6 ๅ
ๅผๅฎๅซ:ๆ service token + ๆชๅผ ALLOW_UNAUTHED_WRITES ๆถ,่ฟๆก import ๆไบค่
ฟไธ `PUT โฆ/policy` ๅ็ๆฏๅไธไธช policy store โ ๅ้จๅ็ `auth.service_token_required`(server 3.15.0 ่ตท)
|
|
3175
3203
|
|
|
@@ -3211,7 +3239,8 @@ paths:
|
|
|
3211
3239
|
'400': { $ref: '#/components/responses/BadRequest' }
|
|
3212
3240
|
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
3213
3241
|
'403':
|
|
3214
|
-
description:
|
|
3242
|
+
description: >-
|
|
3243
|
+
403 `loosen_forbidden` โ a post-commit policy replay tried to relax what an operator wrote (server >= 7.135.0; <= 7.134.x: tighten-only against the whole row). A non-operator replay keeps each record's own operator part; an operator replay makes the imported row the operator's.
|
|
3215
3244
|
content:
|
|
3216
3245
|
application/json:
|
|
3217
3246
|
schema: { $ref: '#/components/schemas/ErrorResponse' }
|
|
@@ -3259,7 +3288,14 @@ paths:
|
|
|
3259
3288
|
server >= 7.134.0: a queue row whose stored body cannot be read (the store's refusal contract โ a retry fails the same way; an operator has to repair
|
|
3260
3289
|
or delete that row) answers `500` + `errorCode: "approvals.read_corrupt"` (body `{ error, errorCode }`; the bad row's coordinates stay off the wire) โ
|
|
3261
3290
|
the same judge and the same code as `GET /v1/approvals/stream`. Do NOT retry it as-is (the SDK's GET retry arm exempts the code). Every other read
|
|
3262
|
-
failure (connection / timeout / store hiccup) is
|
|
3291
|
+
failure (connection / timeout / store hiccup) is `503 approvals.read_unavailable` from server >= 7.135.0 (below); servers <= 7.134.x answered it `500 internal.error`. Older servers answered the corrupt row with `internal.error`.
|
|
3292
|
+
content:
|
|
3293
|
+
application/json:
|
|
3294
|
+
schema: { $ref: '#/components/schemas/ErrorResponse' }
|
|
3295
|
+
'503':
|
|
3296
|
+
description: >-
|
|
3297
|
+
server >= 7.135.0: `503 approvals.read_unavailable` โ the approvals queue could not be read RIGHT NOW (the store hiccuped; transient โ the SDK retries it by status). Until a read succeeds, an answer here does NOT mean nothing is pending.
|
|
3298
|
+
Body `{ error, errorCode }`. Older servers answered a read that could not complete with the global fallback `500 internal.error`.
|
|
3263
3299
|
content:
|
|
3264
3300
|
application/json:
|
|
3265
3301
|
schema: { $ref: '#/components/schemas/ErrorResponse' }
|
|
@@ -3707,6 +3743,20 @@ paths:
|
|
|
3707
3743
|
application/json:
|
|
3708
3744
|
schema: { $ref: '#/components/schemas/InboxList' }
|
|
3709
3745
|
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
3746
|
+
'500':
|
|
3747
|
+
description: >-
|
|
3748
|
+
server >= 7.135.0: `500 approvals.read_corrupt` โ a queue row's stored body cannot be read (the store's refusal contract: a retry fails the same way; an operator has to repair or delete that row) โ the SAME judge and the same code as `GET /v1/approvals`
|
|
3749
|
+
and `GET /v1/approvals/stream`. Do NOT retry it as-is (the SDK's retry arm exempts the code). Every other read failure is `503 approvals.read_unavailable` (below). Older servers: `500 internal.error`.
|
|
3750
|
+
content:
|
|
3751
|
+
application/json:
|
|
3752
|
+
schema: { $ref: '#/components/schemas/ErrorResponse' }
|
|
3753
|
+
'503':
|
|
3754
|
+
description: >-
|
|
3755
|
+
server >= 7.135.0: `503 approvals.read_unavailable` โ the approvals queue could not be read RIGHT NOW (the store hiccuped; transient โ the SDK retries it by status). Until a read succeeds, an answer here does NOT mean nothing is pending.
|
|
3756
|
+
Body `{ error, errorCode }`. Older servers answered a read that could not complete with the global fallback `500 internal.error`.
|
|
3757
|
+
content:
|
|
3758
|
+
application/json:
|
|
3759
|
+
schema: { $ref: '#/components/schemas/ErrorResponse' }
|
|
3710
3760
|
|
|
3711
3761
|
/v1/assistant/tasks:
|
|
3712
3762
|
parameters:
|
|
@@ -3728,6 +3778,20 @@ paths:
|
|
|
3728
3778
|
application/json:
|
|
3729
3779
|
schema: { $ref: '#/components/schemas/AssistantTaskList' }
|
|
3730
3780
|
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
3781
|
+
'500':
|
|
3782
|
+
description: >-
|
|
3783
|
+
server >= 7.135.0: `500 approvals.read_corrupt` โ a queue row's stored body cannot be read (the store's refusal contract: a retry fails the same way; an operator has to repair or delete that row) โ the SAME judge and the same code as `GET /v1/approvals`
|
|
3784
|
+
and `GET /v1/approvals/stream`. Do NOT retry it as-is (the SDK's retry arm exempts the code). Every other read failure is `503 approvals.read_unavailable` (below). Older servers: `500 internal.error`.
|
|
3785
|
+
content:
|
|
3786
|
+
application/json:
|
|
3787
|
+
schema: { $ref: '#/components/schemas/ErrorResponse' }
|
|
3788
|
+
'503':
|
|
3789
|
+
description: >-
|
|
3790
|
+
server >= 7.135.0: `503 approvals.read_unavailable` โ the approvals queue could not be read RIGHT NOW (the store hiccuped; transient โ the SDK retries it by status). Until a read succeeds, an answer here does NOT mean nothing is pending.
|
|
3791
|
+
Body `{ error, errorCode }`. Older servers answered a read that could not complete with the global fallback `500 internal.error`.
|
|
3792
|
+
content:
|
|
3793
|
+
application/json:
|
|
3794
|
+
schema: { $ref: '#/components/schemas/ErrorResponse' }
|
|
3731
3795
|
|
|
3732
3796
|
/v1/assistant/tasks/{taskId}/resume:
|
|
3733
3797
|
parameters:
|
|
@@ -5921,6 +5985,14 @@ paths:
|
|
|
5921
5985
|
schema: { $ref: '#/components/schemas/WorkflowJournalPage' }
|
|
5922
5986
|
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
5923
5987
|
'404': { $ref: '#/components/responses/NotFound' }
|
|
5988
|
+
'500':
|
|
5989
|
+
description: >-
|
|
5990
|
+
server >= 7.135.0 (core 7.55.0): `500 workflow.journal_incompatible` โ a journal row the engine's judge rejects (a parked row with no checkpoint token, a parked row whose terminal is not paused, a row that does not read as an object โ hand-edited / another writer /
|
|
5991
|
+
a newer format). The judgment covers the WHOLE journal, on every backend, on every page (a bad row on another page, or one over 64 KiB, answers the same); the body carries `ordinal` (the first bad row, ascending; `-1` = the refusal names no entry). The run's resume is refused by the engine
|
|
5992
|
+
with the same code. Repair that row from the retained copy โ NEVER by deleting it (a missing entry re-runs that step live). A retry changes nothing (the SDK's retry arm exempts the code). <= 7.134.x read such rows back as `200`.
|
|
5993
|
+
content:
|
|
5994
|
+
application/json:
|
|
5995
|
+
schema: { $ref: '#/components/schemas/ErrorResponse' }
|
|
5924
5996
|
'501': { $ref: '#/components/responses/NotImplemented' }
|
|
5925
5997
|
|
|
5926
5998
|
/v1/workflows/{workflowRunId}/agents/{label}/steer:
|
|
@@ -7006,8 +7078,32 @@ components:
|
|
|
7006
7078
|
enabled: { type: boolean }
|
|
7007
7079
|
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).' }
|
|
7008
7080
|
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.' }
|
|
7081
|
+
skills:
|
|
7082
|
+
type: array
|
|
7083
|
+
items: { $ref: '#/components/schemas/ScenarioSkill' }
|
|
7084
|
+
description: >-
|
|
7085
|
+
server >= 7.135.0, always present there (`[]` when none): the deployment SKILLS this scenario's run mounts (the deployment skills directory UNION what the config source hands over, filtered by scenario; a request's own `skills` are not
|
|
7086
|
+
included) โ the same single filter that feeds `TaskSpec`, same group, same order. A client's `/skill-name` completion reads it; naming one goes through `userInvokedSkills`. Entries carry no body and none of a skill's tool lists. On the card
|
|
7087
|
+
but not in the run: `disableSkills: true` (nothing mounted) and a skill whose body exceeds the engine's load cap (naming it answers `config.user_invoked_skill_unknown`). ABSENT = an older server: the list cannot be read โ
|
|
7088
|
+
NOT "no skills" (that is `[]`). Bit: `capabilities.scenarioSkills`.
|
|
7009
7089
|
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".' }
|
|
7010
7090
|
|
|
7091
|
+
ScenarioSkill:
|
|
7092
|
+
type: object
|
|
7093
|
+
description: One row of `ScenarioDetail.skills` (server >= 7.135.0). No body, no tool lists.
|
|
7094
|
+
additionalProperties: false
|
|
7095
|
+
required: [name, description, source]
|
|
7096
|
+
properties:
|
|
7097
|
+
name: { type: string }
|
|
7098
|
+
description: { type: string }
|
|
7099
|
+
source: { $ref: '#/components/schemas/ScenarioSkillSource' }
|
|
7100
|
+
ScenarioSkillSource:
|
|
7101
|
+
type: string
|
|
7102
|
+
description: >
|
|
7103
|
+
Where a scenario skill came from (server >= 7.135.0; the server's self-minted word table `scenarioSkillSource`, closed two words): `factory` = the deployment's skills directory (`SKILLS_DIR`);
|
|
7104
|
+
`center` = the config source (the center / the local `config.d` skills list, or a config-declared plugin) โ a skill that overrides a same-named factory one by name is also `center`.
|
|
7105
|
+
enum: [factory, center]
|
|
7106
|
+
|
|
7011
7107
|
RunStatus:
|
|
7012
7108
|
type: string
|
|
7013
7109
|
enum: [running, completed, failed, suspended, needs_review, blocked]
|
|
@@ -7290,7 +7386,7 @@ components:
|
|
|
7290
7386
|
CC Rewind parity (E18). Fork the conversation FROM this user-message SessionTreeEntry.id (non-destructive
|
|
7291
7387
|
branch via setLeafId). With `restoreFiles: true` โ "both" (also restore the working tree โ the retired spelling
|
|
7292
7388
|
`rewindFiles` still rides the wire but its restore sense is core's typed migration rejection naming `restoreFiles`). Alone โ
|
|
7293
|
-
"conversation". HONORED only where the deployment wired a resume-anchor store + getLeafId (capabilities.resumeAt);
|
|
7389
|
+
"conversation". HONORED only where the deployment wired a resume-anchor store + the session head read `headOf` (<= 7.134.x: `getLeafId`) (capabilities.resumeAt);
|
|
7294
7390
|
unknown anchor โ 4xx, capability-off โ 501. Cannot combine with a durable resume.
|
|
7295
7391
|
resumeAtMode:
|
|
7296
7392
|
type: string
|
|
@@ -7324,7 +7420,7 @@ components:
|
|
|
7324
7420
|
kind of handle as `resumeAt`, resolved through the SAME anchor store โ typically the `taskId` from that turn's
|
|
7325
7421
|
202 receipt (the server keys the user-message anchor by the run's taskId). Server `src/boot/resolve-spec.ts:686-697`:
|
|
7326
7422
|
`resumeAnchorStore.resolve(sessionId, handle, principal)` โ entry id; unknown handle โ 404
|
|
7327
|
-
`rewind_files_to.unknown_event`; no session โ 422 `rewind_files_to.no_session`; no anchor store / no getLeafId โ
|
|
7423
|
+
`rewind_files_to.unknown_event`; no session โ 422 `rewind_files_to.no_session`; no anchor store / no session head read (`headOf`; <= 7.134.x: `getLeafId`) โ
|
|
7328
7424
|
501. โ ๏ธ The 501 is NOT the capability's whole predicate: `capabilities.rewindFilesTo` also requires the
|
|
7329
7425
|
file-history store; without it the server does not 501 โ core refuses at prepare with
|
|
7330
7426
|
`rewind.store_unconfigured` (server >= 7.104.0 / S-724: a 409 error body on the synchronous `POST /v1/tasks` when
|
|
@@ -7920,6 +8016,15 @@ components:
|
|
|
7920
8016
|
combination); `taskWriteFaceOpen` is NOT its reading. Residual (server S-908): the binding is keyed by SESSION and written
|
|
7921
8017
|
after the run is claimed (a refused request writes nothing); on deployments without a run store two concurrently accepted
|
|
7922
8018
|
runs on one session are last-writer-wins. Delegated children's shells keep the default scrub.
|
|
8019
|
+
projectMemory:
|
|
8020
|
+
type: string
|
|
8021
|
+
enum: [disabled]
|
|
8022
|
+
description: >
|
|
8023
|
+
server >= 7.135.0 (engine 7.55.0 `TaskSpec.projectMemory`, passed through verbatim): this ONE run does not read the deployment's project context โ the engine does not call the deployment's project-context seat, so the project layer,
|
|
8024
|
+
the declared instruction files and the few things they feed are all absent (the engine's own git-status lane, the memory engine, skills / hooks / MCP are unaffected; delegated / background / fork / workflow children inherit it from
|
|
8025
|
+
the parent). The only word is `disabled`; the key ABSENT = call the seat. The leg's `wiring_manifest.projectMemory` reads `disabled` and the server-minted `instructions` section is absent. A deployment without the seat still accepts it
|
|
8026
|
+
(the manifest answers `absent`). Anything else (`off`, a boolean, `null`) โ a fresh submit answers 400 `request.field_invalid`; a resume replay judges the same and folds into 409 `resume_blocked_by_policy`
|
|
8027
|
+
(`blockedBy: request.field_invalid`). Read `capabilities.projectMemory` beforehand: older servers answer 400 `request.body_shape` (`unknownKeys: ["projectMemory"]`).
|
|
7923
8028
|
attachments:
|
|
7924
8029
|
type: object
|
|
7925
8030
|
description: >
|
|
@@ -9596,8 +9701,8 @@ components:
|
|
|
9596
9701
|
(`decision: "approve"`, `decidedBy` absent or `person`): on a deny or a `decidedBy: "policy"` decision โ 400 `request.field_conflict` with
|
|
9597
9702
|
`detail.kind: "approval_feedback"` and `detail.fields` `["feedback", "decision"]` / `["feedback", "decidedBy"]` (a denial's words go in `reason`);
|
|
9598
9703
|
a non-string โ 400 `request.field_invalid`; any value on a direct-door worker โ 400 `feedback_not_in_proof` (not inside the signed proof); words
|
|
9599
|
-
carrying `<system-reminder>` โ 409 `
|
|
9600
|
-
do not auto-refetch and re-decide on the code). The same door serves parked background-agent cards and workflow child cards; the live
|
|
9704
|
+
carrying `<system-reminder>` โ server >= 7.135.0 (engine 7.55.0): 409 `resume_outcome_invalid` + `field: "feedback"` + `retriable: true` (the engine's sentence naming `feedback`; refused before the CAS, the card stays pending โ ask the person to change
|
|
9705
|
+
or drop the words, do not auto-refetch and re-decide on the code); server 7.134.x: 409 `approval_binding_mismatch` (no `field`). The same door serves parked background-agent cards and workflow child cards; the live
|
|
9601
9706
|
`POST /v1/tool-approvals/{id}/respond` does NOT take it. Servers <= 7.133.x refuse the key (400 `request.body_shape`, `unknownKeys: ["feedback"]`).
|
|
9602
9707
|
|
|
9603
9708
|
Capabilities:
|
|
@@ -9807,7 +9912,7 @@ components:
|
|
|
9807
9912
|
type: boolean
|
|
9808
9913
|
description: >-
|
|
9809
9914
|
Code-only rewind (`TaskRequest.rewindFilesTo`) is wired โ mint `routes/capabilities.ts:839` =
|
|
9810
|
-
`Boolean(deps.fileHistoryStore && deps.resumeAnchorStore && deps.sessionStorage?.getLeafId)
|
|
9915
|
+
`Boolean(deps.fileHistoryStore && deps.resumeAnchorStore && headReadOf(deps.sessionStorage))` (<= 7.134.x last conjunct: `deps.sessionStorage?.getLeafId`): it needs the
|
|
9811
9916
|
file-history store (to restore) AND the anchor map (to resolve the target HANDLE). Corrected in sdk 11.4.0
|
|
9812
9917
|
(board [8437] U3): the store is the FILE-HISTORY store (not the pre-S-15 whole-tree snapshot store).
|
|
9813
9918
|
๐ด K-24: on server 7.97.0โ7.103.x that seat was the CAPTURE face (backend AND the `FILE_HISTORY_CAPTURE` knob), so a
|
|
@@ -9889,8 +9994,9 @@ components:
|
|
|
9889
9994
|
description: >
|
|
9890
9995
|
๐ด ๅฅ็บฆ่ฐๅ่ฝฆ1 Hโก (2026-08-02): server HAS been emitting this key (the `sessionEvents` bit in `src/http/routes/capabilities.ts`)
|
|
9891
9996
|
while both this spec and the SDK type were missing it. Gates `GET /v1/sessions/{sessionId}/events`
|
|
9892
|
-
(the session-level SSE head subscription). Predicate is a
|
|
9893
|
-
plus a session store exposing BOTH `getLeafId` and `ownerOf
|
|
9997
|
+
(the session-level SSE head subscription). Predicate (server >= 7.135.0) is a TWO-way AND: a durable session-watch seam
|
|
9998
|
+
plus a session store exposing the session head read `headOf` (<= 7.134.x it was a THREE-way AND with BOTH `getLeafId` and `ownerOf`; those two
|
|
9999
|
+
methods left the store contract in 7.135.0, so `DB_BACKEND=memory` now answers `true`, was `false`) โ the route's 501 uses the same
|
|
9894
10000
|
predicate, so "says yes <=> route works" holds here. False/absent => fall back to polling
|
|
9895
10001
|
`GET /v1/sessions/{sessionId}/head`. NOTE (server [2373]A-5): no consumer is wired to it yet โ it is
|
|
9896
10002
|
a prepared slot, correct to gate on, wrong to read as "widely consumed".
|
|
@@ -10222,11 +10328,29 @@ components:
|
|
|
10222
10328
|
โ SQL backends only; `DB_BACKEND=local` is always false). Advertises exactly the two file-history blob faces
|
|
10223
10329
|
`PUT /v1/sessions/{sessionId}/sync/blobs/{hash}` and `GET /v1/sessions/{sessionId}/sync/history/blobs/{hash}`.
|
|
10224
10330
|
READ IT ON BOTH ENDS of a sync: if either is false, sync the conversation only โ do not push `fileHistory`, do
|
|
10225
|
-
not PUT blobs (a `fileHistory` pushed to a peer without the blob faces 422s `missing_blob` after
|
|
10331
|
+
not PUT blobs (a `fileHistory` pushed to a peer without the blob faces 422s `missing_blob` in the FIRST phase โ zero staging, zero commit, the conversation does not land either โ from server >= 7.135.0; <= 7.134.x answered it in the second phase, after the conversation committed). When
|
|
10226
10332
|
false the two routes answer 501 `capability.snapshot_store_required` (any session id, ahead of the owner check).
|
|
10227
10333
|
A blob that the session history graph does not reference / whose bytes are gone stays a 404 `not_found.blob`.
|
|
10228
10334
|
ABSENT = an older server (<= 7.115.x): the bit cannot be read there (a `DB_BACKEND=local` deployment with
|
|
10229
10335
|
`sessionSync: true` answered PUT blob 501 on every call), so try as before.
|
|
10336
|
+
sessionRulesNamespaceForms:
|
|
10337
|
+
type: boolean
|
|
10338
|
+
description: >
|
|
10339
|
+
server >= 7.135.0 (predicate class "always true", read per request from the engine's protocol table): the session-rule write faces (`PUT /v1/sessions/{id}/policy`, the `policy` face of `POST /v1/sessions/{id}/sync/import`)
|
|
10340
|
+
accept โ in `toolAllow` / `toolDeny` โ the three COVERING FORMS of every protocol namespace the engine knows (today `mcp__` and `a2a__`): the whole peer (`mcp__srv`), a tool-segment wildcard (`mcp__srv__*`)
|
|
10341
|
+
and a tool-segment glob (`mcp__srv__get_*`); the engine's matcher reads each as ONE GROUP of tools. A client may stop refusing those three forms losslessly on this bit alone (never on a version guess).
|
|
10342
|
+
The bit says NOTHING about other wildcards: `*`, partial peer-segment wildcards (`mcp__git*`) and a trailing-separator `mcp__srv__` are still refused by the write face (`400 rules.inert_entry`); the whole-protocol
|
|
10343
|
+
name `mcp__*` is accepted only in `toolDeny`. Orthogonal to `sessionPolicy` (does the deployment have a session-rules write face at all): read `sessionPolicy` AND this bit. ABSENT (older server) and `false` โ read as "do not widen".
|
|
10344
|
+
projectMemory:
|
|
10345
|
+
type: boolean
|
|
10346
|
+
description: >
|
|
10347
|
+
server >= 7.135.0 (always true): the top-level request key `projectMemory: "disabled"` is accepted. The read face hangs on no facility โ a deployment without a project-context seat still accepts it
|
|
10348
|
+
(the manifest answers `"absent"`). ABSENT = an older server, whose key-closure gate answers `400 request.body_shape` (`unknownKeys` names it): send the key on sight of the bit only.
|
|
10349
|
+
scenarioSkills:
|
|
10350
|
+
type: boolean
|
|
10351
|
+
description: >
|
|
10352
|
+
server >= 7.135.0 (always true): `GET /v1/capabilities/scenarios/{name}` carries `skills[]` (`ScenarioDetail.skills`). ABSENT = an older server: the card has no list โ do NOT read that as "this scenario has no skills"
|
|
10353
|
+
(that is `skills: []`).
|
|
10230
10354
|
|
|
10231
10355
|
# โโโ S-139(sdk 8.3.0):ๅฏน server 7.60.0 ็ๆดไฝ้ๅฏน่ดฆ่กฅ้ฝ็ 19 ไฝ โโโโโโโโโโโโโโโโโโโโโโโ
|
|
10232
10356
|
# ่กๅท = server 7.60.0 ๆ ็ `src/http/routes/capabilities.ts`ใ่ฏญไนไธ่ฐ่ฏ็ๅ
จๆๅจ
|
|
@@ -10513,7 +10637,7 @@ components:
|
|
|
10513
10637
|
type: boolean
|
|
10514
10638
|
description: >
|
|
10515
10639
|
server >= 7.85.0 (S-381 / core 7.22.0 #857; mint `routes/capabilities.ts:264` =
|
|
10516
|
-
`Boolean(deps.runStore) && Boolean(deps.sessionStorage?.ownerOf)`) โ presence of
|
|
10640
|
+
`Boolean(deps.runStore) && Boolean(deps.sessionStorage?.ownerOf)`; server >= 7.135.0 the last conjunct is `headReadOf(deps.sessionStorage) !== undefined`) โ presence of
|
|
10517
10641
|
`POST /v1/sessions/{sessionId}/mcp/reconnect`. FACILITY DEPENDENCY, two conjuncts: a durable run
|
|
10518
10642
|
ledger (the verb reaches the live stream through the run row) AND the session-ownership face (the
|
|
10519
10643
|
inbound owner gate is fail-closed; without it the whole door is 501). Both 501s derive from the SAME
|
|
@@ -10634,7 +10758,7 @@ components:
|
|
|
10634
10758
|
sessionBackgroundFacesAvailable(deps), exitFaces: sessionBackgroundFacesAvailable(deps) }`) โ presence of the
|
|
10635
10759
|
session background-task doors: `listFace` = `GET /v1/sessions/{sessionId}/background`, `exitFaces` =
|
|
10636
10760
|
`POST /v1/sessions/{sessionId}/background/stop` (contract ยง16). Both bits use the SAME predicate as the two
|
|
10637
|
-
doors' 501 (the session-ownership face `sessionStorage.ownerOf`), so "says yes but 501s" is structurally
|
|
10761
|
+
doors' 501 (the session-ownership face: `sessionStorage.headOf` on server >= 7.135.0, `ownerOf` on <= 7.134.x), so "says yes but 501s" is structurally
|
|
10638
10762
|
impossible; without it both bits are explicitly `false` and both doors answer 501
|
|
10639
10763
|
`capability.session_ownership_required`. ENDPOINT-GATE FORM: `false` โ do not call. True only promises the
|
|
10640
10764
|
endpoint โ not that this replica holds any background row of that session (the registry is in-process).
|
|
@@ -11685,7 +11809,7 @@ components:
|
|
|
11685
11809
|
modelPlane:
|
|
11686
11810
|
allOf: [{ $ref: '#/components/schemas/ModelPlane' }]
|
|
11687
11811
|
description: >-
|
|
11688
|
-
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
|
|
11812
|
+
server >= 7.133.0, ALWAYS present there (appended last on 7.133.0โ7.134.x; from server >= 7.135.0 the last key is `aliases` and this one precedes it โ key order is not a contract, read by name): which model table this engine SERVES, whether the catalog was adopted, and what the start-up route judge says โ read this instead of predicting
|
|
11689
11813
|
(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.
|
|
11690
11814
|
candidateRejected:
|
|
11691
11815
|
allOf: [{ $ref: '#/components/schemas/CandidateRejected' }]
|
|
@@ -11697,6 +11821,25 @@ components:
|
|
|
11697
11821
|
configuration is clean" (it is also an earlier server): render the real cause only when the key is present; keep the old behaviour when absent.
|
|
11698
11822
|
Same read as `models`: key present => this `models` is the fallback generation (none of the candidate's models are in it). No capability bit
|
|
11699
11823
|
(the endpoint is always there; the presence of the key is the presence rule).
|
|
11824
|
+
aliases:
|
|
11825
|
+
type: array
|
|
11826
|
+
items: { $ref: '#/components/schemas/ModelAlias' }
|
|
11827
|
+
description: >
|
|
11828
|
+
server >= 7.135.0, ALWAYS present there (appended LAST; `[]` when none): the model WORDS besides `models[].name` that the server's acceptance gate takes (tier words / `default` / a catalog entry's id spelling, ...).
|
|
11829
|
+
ACCEPTANCE RULE (one rule; a model-word judge reads this key, never infers from a row's id): a model word is submittable IFF its name is in `models[].name` UNION `aliases[].name` AND its row's `atMentionable !== false`
|
|
11830
|
+
(`atMentionable` absent = no allowlist verdict, not "not mentionable"). `aliases` deliberately does not say which row a word lands on. ABSENT = an earlier server (<= 7.134.x): tier words / `default` stay "cannot tell" โ
|
|
11831
|
+
do not read the absence as "no aliases". Known boundary (not introduced by this version): a catalog entry literally named `default` does not appear in `models[]`.
|
|
11832
|
+
|
|
11833
|
+
ModelAlias:
|
|
11834
|
+
type: object
|
|
11835
|
+
additionalProperties: false
|
|
11836
|
+
required: [name]
|
|
11837
|
+
description: >
|
|
11838
|
+
One row of `ModelsResponse.aliases` (server >= 7.135.0): a submittable model word that is not a `models[]` row. `name` = the word (never equal to a `models[].name`); `atMentionable` = the SAME projection as on a `models[]`
|
|
11839
|
+
row, present ONLY when the deployment configured an at-mention allowlist (the allowlist verdict for the catalog entry the word resolves to); absent = no allowlist verdict, NOT "not mentionable".
|
|
11840
|
+
properties:
|
|
11841
|
+
name: { type: string }
|
|
11842
|
+
atMentionable: { type: boolean }
|
|
11700
11843
|
|
|
11701
11844
|
CandidateRejected:
|
|
11702
11845
|
type: object
|
|
@@ -12077,6 +12220,8 @@ components:
|
|
|
12077
12220
|
name: { type: string, description: "The workflow script's declared `meta.name`." }
|
|
12078
12221
|
description: { type: string, description: "The workflow script's declared `meta.description` (one-liner)." }
|
|
12079
12222
|
agentFailures: { type: integer, description: 'Count of agent-runs that ended failed โ present only when > 0 (a "completed, with failures" flag without an N+1 get).' }
|
|
12223
|
+
parked: { type: boolean, enum: [true], description: 'server >= 7.135.0 (core 7.55.0 `runParkedOf`) โ present, always the literal `true`, ONLY while the run is `running` AND at least one of its agents is parked at an approval gate; otherwise the key is ABSENT (never `false`). Read it as "the run is waiting on a person", not "failed". Older servers never send it.' }
|
|
12224
|
+
errorCode: { type: string, description: 'The run row''s machine code (open set; e.g. `workflow.agent_parked` for a drained parked terminal) โ present only when the row has one. (Declared here in 26.1.0: the engine summary has emitted it since before 7.134.0.)' }
|
|
12080
12225
|
currentPhase: { type: string, description: 'Title of the phase currently executing (absent once terminal).' }
|
|
12081
12226
|
status: { $ref: '#/components/schemas/WorkflowRunStatus' }
|
|
12082
12227
|
phaseCount: { type: integer, description: 'Phases recorded.' }
|
|
@@ -12255,6 +12400,8 @@ components:
|
|
|
12255
12400
|
description: { type: string, description: "The workflow script's declared `meta.description` (redacted, one-liner)." }
|
|
12256
12401
|
status: { $ref: '#/components/schemas/WorkflowRunStatus' }
|
|
12257
12402
|
agentFailures: { type: integer, description: 'run-level count of agents whose status ended failed โ stamped at run end, only when > 0.' }
|
|
12403
|
+
parked: { type: boolean, enum: [true], description: 'server >= 7.135.0 (core 7.55.0 `runParkedOf`) โ present, always the literal `true`, ONLY while the run is `running` AND at least one of its agents is parked at an approval gate; otherwise the key is ABSENT (never `false`). Read it as "the run is waiting on a person", not "failed". Older servers never send it.' }
|
|
12404
|
+
errorCode: { type: string, description: 'The run row''s machine code (open set; the same words as the same-named slot on the fleet row, e.g. `workflow.agent_parked` for a drained parked terminal) โ present only when the row has one. (Declared here in 26.1.0: the detail projection has forwarded it since before 7.134.0.)' }
|
|
12258
12405
|
stats: { $ref: '#/components/schemas/WorkflowRunStats' }
|
|
12259
12406
|
startedAt: { type: integer }
|
|
12260
12407
|
endedAt: { type: integer }
|
|
@@ -12727,6 +12874,11 @@ components:
|
|
|
12727
12874
|
run row has one, the key ABSENT otherwise (never an empty string). A parked workflow run reads `status: "failed"` + `errorCode: "workflow.agent_parked"`
|
|
12728
12875
|
(parked, not failed; the `status` vocabulary gains no word). Snapshot rows, `workflow` upsert frames and rows merged from the terminal window share one mint
|
|
12729
12876
|
point; a `?session=` subscriber's demoted rows carry it too. ABSENT = an older server, or no code on this row โ fall back to `status`.
|
|
12877
|
+
parked:
|
|
12878
|
+
type: boolean
|
|
12879
|
+
enum: [true]
|
|
12880
|
+
description: >-
|
|
12881
|
+
server >= 7.135.0 (core 7.55.0 `runParkedOf`) โ present, always the literal `true`, ONLY while the run is `running` AND at least one of its agents is parked at an approval gate; otherwise the key is ABSENT (never `false`). Read it as "the run is waiting on a person", not "failed". Older servers never send it. On a fleet row the workflow-bus row is now replaced WHOLE on every `workflow` upsert (server >= 7.135.0; no longer merged by `id` into the old row), so a key that left is gone from the row.
|
|
12730
12882
|
FleetFrame:
|
|
12731
12883
|
description: >
|
|
12732
12884
|
One decoded frame off GET /v1/fleet/stream (service streamFleet emit set, src/http/routes/fleet.ts). On the
|
|
@@ -14148,12 +14300,20 @@ components:
|
|
|
14148
14300
|
server >= 7.92.0 (engine 7.25.0): the session's rule LINEAGE generation. An erase
|
|
14149
14301
|
(`deleteBySession`) ends the lineage โ the next write carries gen+1 โ so a reader treats a
|
|
14150
14302
|
different gen as a new lineage, never a continuation, regardless of rev. Absent on older servers.
|
|
14303
|
+
operatorRules:
|
|
14304
|
+
allOf: [{ $ref: '#/components/schemas/SessionRulesOperatorPart' }]
|
|
14305
|
+
description: >
|
|
14306
|
+
server >= 7.135.0 (engine 7.55.0): the row's OPERATOR PART โ the buckets (and their own `grammar` stamp) the last OPERATOR write set; the line a non-operator write may not loosen (`403 loosen_forbidden` on a move inside it).
|
|
14307
|
+
ABSENT = the whole row is the operator's (an operator write; every row stored before 7.135.0, read as before the upgrade: the owner can take nothing back). Minted by the engine's write judge alone, stored whole and read back verbatim; also on the 2c export `policy[].rules`.
|
|
14308
|
+
A non-operator write over an EMPTY row stamps an empty part (stamp only) โ the owner can then take back what the owner added. A part ECHOED back is read per door: on `PUT /v1/sessions/{sessionId}/policy` it is ALWAYS ignored (the stored row's part is kept over an existing row; an empty stamped part is minted over none).
|
|
14309
|
+
On the sync-import replay (`POST โฆ/sync/import`, `policy[]` records, which carry `rev`): over an existing row the judge keeps the STORED row's part and ignores the echo; over NO row, a non-operator record that looks like a stored row (carries `rev` >= 1)
|
|
14310
|
+
has its own part adopted (from then on that part IS the row's operator line: taking it back answers 403 `loosen_forbidden`), otherwise an empty stamped part is minted; an operator write never carries a part.
|
|
14151
14311
|
grammar:
|
|
14152
14312
|
type: integer
|
|
14153
14313
|
minimum: 0
|
|
14154
14314
|
description: >
|
|
14155
14315
|
server >= 7.129.0 (engine 7.51.2): the rule GRAMMAR the row's entries are read in, stamped by the
|
|
14156
|
-
engine's write judge on every row written through it (
|
|
14316
|
+
engine's write judge on every row written through it (server >= 7.135.0 writes `4` โ the engine's `SESSION_RULES_GRAMMAR`; 7.129.0 wrote `1`).
|
|
14157
14317
|
Absent = a row stored before the stamp (grammar 0: an allow entry spelled as a rule, `Bash(rm:*)`,
|
|
14158
14318
|
named no tool and admitted nothing โ the engine keeps reading such a row that way and announces it
|
|
14159
14319
|
once; the one-time migration rewrites stored rows and stamps them). Echoing a stored body back into
|
|
@@ -14174,6 +14334,18 @@ components:
|
|
|
14174
14334
|
rev: { type: integer }
|
|
14175
14335
|
gen: { type: integer }
|
|
14176
14336
|
grammar: { type: integer }
|
|
14337
|
+
operatorRules: { $ref: '#/components/schemas/SessionRulesOperatorPart' }
|
|
14338
|
+
|
|
14339
|
+
SessionRulesOperatorPart:
|
|
14340
|
+
type: object
|
|
14341
|
+
description: '`StoredSessionRules.operatorRules` (server >= 7.135.0): the three buckets plus their own grammar stamp. The `grammar` is always present (the write judge stamps it).'
|
|
14342
|
+
additionalProperties: false
|
|
14343
|
+
required: [grammar]
|
|
14344
|
+
properties:
|
|
14345
|
+
toolAllow: { type: array, items: { type: string } }
|
|
14346
|
+
toolDeny: { type: array, items: { type: string } }
|
|
14347
|
+
allowDirs: { type: array, items: { type: string } }
|
|
14348
|
+
grammar: { type: integer, minimum: 0 }
|
|
14177
14349
|
|
|
14178
14350
|
McpServerStatus:
|
|
14179
14351
|
type: object
|
|
@@ -14816,7 +14988,18 @@ components:
|
|
|
14816
14988
|
fail-closed) and `state.scenario_assignment_unknown` (503, server >= 7.119.0 โ the center's scenario assignment for the
|
|
14817
14989
|
principal is dangling; only re-pointing the assignment, or adding the scenario back to the deployment, helps) and
|
|
14818
14990
|
`approvals.read_corrupt` (500, server >= 7.134.0 on `GET /v1/approvals` โ a queue row's stored body cannot be read; an operator has to repair or
|
|
14819
|
-
delete the row
|
|
14991
|
+
delete the row; server >= 7.135.0 the same judge answers `GET /v1/assistant/inbox` and `GET /v1/assistant/tasks` too) and `workflow.journal_incompatible`
|
|
14992
|
+
(500, server >= 7.135.0 on `GET /v1/workflows/{id}/journal` โ a journal row the engine's judge rejects; the body carries `ordinal`; repair the row from the retained copy, never by deleting it).
|
|
14993
|
+
Every other 5xx code keeps the status-based retry.
|
|
14994
|
+
๐ด server >= 7.135.0 read-failure and store-fault codes (all additive; branch on the code, never the sentence): `503 approvals.read_unavailable` on `GET /v1/approvals`, `/v1/assistant/inbox` and
|
|
14995
|
+
`/v1/assistant/tasks` (the queue cannot be read RIGHT NOW โ transient, retried by status; until a read succeeds an answer does NOT mean nothing is pending; it moved from the SSE-only table into the status-bearing catalog, status `-` โ 503) and, on
|
|
14996
|
+
the same three faces, `500 approvals.read_corrupt` (above); `503 state.file_history_unreadable` on the session-sync pull faces (`GET /v1/sessions/{id}/sync/manifest`, `GET /v1/sessions/{id}/sync/history/blobs/{hash}` โ the file history
|
|
14997
|
+
cannot be read WHOLE; it is NOT "no history", which stays `200` with `fileHistory: null`); `422 adopt_failed` on `POST /v1/sessions/{id}/sync/import` (the file-history replay hit a store fault; 7.134.x answered `unsupported_format`;
|
|
14998
|
+
NOT a missing blob โ that is `422 missing_blob`, now answered in the FIRST phase). The two store-fault codes may carry `permanence` (`transient` = nothing changed, retry the same shape later / `terminal` = repair the store first; absent = the store did not judge).
|
|
14999
|
+
`422 request.unprocessable` now also answers a deny / ask rule whose PARAMETER does not belong to the tool (the sentence carries the engine code `unsupported.param_unknown`, the same word in `detail.problems[].reason`; a stored body that
|
|
15000
|
+
resumes โ `409 resume_blocked_by_policy` with `blockedBy: request.unprocessable`; 7.134.x accepted such a rule, and it never matched). `400 request.body_shape` also names an unread key inside a `settings.hooks` group / entry in
|
|
15001
|
+
`unknownKeys` as a FULL coordinate (`settings.hooks.PreToolUse.0.hooks.0.onFailure`) on a fresh submit.
|
|
15002
|
+
`409 resume_outcome_invalid` + `field: "feedback"` (`retriable: true`) now answers a release `feedback` that carries an engine `<system-reminder>` tag (refused before the CAS, the card stays pending; fix or drop the words and decide again โ it was `409 approval_binding_mismatch` without `field` on 7.134.x). A `feedback` on a deny / policy decision stays `400 request.field_conflict` (`detail.kind: approval_feedback`).
|
|
14820
15003
|
๐ด `request.host_posture_refused` (422) has TWO triggers (same code, same status โ "you wrote it right, this
|
|
14821
15004
|
deployment will not grant that host posture"): (1) the write-containment face (`permissionMode: bypassPermissions` โ
|
|
14822
15005
|
`writeFace: open`; read `capabilities.taskWriteFaceOpen` first); (2) server >= 7.106.0 / S-895: `inheritEnv: "all"` on a
|
|
@@ -14880,10 +15063,23 @@ components:
|
|
|
14880
15063
|
the ids of the background children rooted at this session that are still alive (count = length) โ the SAME
|
|
14881
15064
|
strings as the `handle` on `GET /v1/agents/roster` rows. Nothing was deleted; wait for them to finish (or stop
|
|
14882
15065
|
them where they run) and retry the delete verbatim. SDK: `err.extra.remaining` on the ConflictError.
|
|
15066
|
+
permanence:
|
|
15067
|
+
type: string
|
|
15068
|
+
enum: [transient, terminal]
|
|
15069
|
+
description: >-
|
|
15070
|
+
server >= 7.135.0, on `503 state.file_history_unreadable` and `422 adopt_failed` only: the file-history store's own judgment of the fault (the engine's `GovernanceRetryClass`) โ
|
|
15071
|
+
`transient` = nothing was changed, retrying the same shape later may succeed; `terminal` = repair the store first. ABSENT = the store did not judge (retry later once; still red โ look at the store). SDK: `err.extra.permanence`.
|
|
15072
|
+
ordinal:
|
|
15073
|
+
type: integer
|
|
15074
|
+
description: >-
|
|
15075
|
+
server >= 7.135.0, on `500 workflow.journal_incompatible`: the journal ordinal of the FIRST bad row (ascending); `-1` = the refusal names no entry. SDK: `err.extra.ordinal`.
|
|
14883
15076
|
reason:
|
|
14884
15077
|
type: string
|
|
14885
15078
|
description: >-
|
|
14886
|
-
A per-code closed word โ read it by `errorCode`, never across codes. On
|
|
15079
|
+
A per-code closed word โ read it by `errorCode`, never across codes. On 400 `request.field_invalid` for a URL that carries a credential (server >= 7.135.0): `url_userinfo` (`user:pass@host`) / `url_credential_param` (a credential-named
|
|
15080
|
+
query / fragment parameter โ the names the service's log redactor treats as credentials), beside `field` = the body coordinate (`mcpServers[i].transport.url`, `a2aPeers[i].url`, `a2aPeers[i].cardUrl`,
|
|
15081
|
+
`settings.hooks.<event>[g].hooks[h].url` โ the FULL coordinate, not `field: "settings.hooks"` + `detail` โ and `settings.webSearch.endpoint`; a `settings.webSearch.endpoint` with userinfo keeps its sentence and gains `field` / `reason`);
|
|
15082
|
+
`a2aPeers` over 32 entries answers `over_cap` + `count` + `cap` on `field: "a2aPeers"`. On 503 `fleet.lease_unavailable` (server >=
|
|
14887
15083
|
7.106.0 / S-866 โข): `auth-rejected` (the center refused this engine's credential, or the credential file is
|
|
14888
15084
|
unreadable) / `unreachable` (unreachable / 5xx / timeout / bad body / any status other than 200 / 409 / 400 / 401 / 403 โ
|
|
14889
15085
|
center 404 / 429 / 3xx included). On 400 `request.field_invalid` for a `settings.permissions` bucket (server >= 7.106.0 /
|
|
@@ -15699,6 +15895,12 @@ components:
|
|
|
15699
15895
|
K-32 (server >= 7.106.0 / core 7.34.0 design/1111) โ `bypassPermissions` RELEASED an ask nobody answered (see
|
|
15700
15896
|
`ModeRelease`). Absent = this allow was not a mode release (a plain allow / a person's yes / a rule), or an older
|
|
15701
15897
|
server (<= 7.105.0 stripped it).
|
|
15898
|
+
clearedBy:
|
|
15899
|
+
allOf: [{ $ref: '#/components/schemas/AllowRuleClearance' }]
|
|
15900
|
+
description: >
|
|
15901
|
+
server >= 7.135.0 (core 7.55.0) โ the allow layer's account of a call it let run WITHOUT asking: which member's allow rule cleared a standing ask that nobody answered
|
|
15902
|
+
(`AllowRuleClearance`). Present exactly when an allow member cleared the ask; absent on a call nothing asked about, a mode's release or acceptance, the read-only arm's,
|
|
15903
|
+
the classifier's or the sandbox's allow, and a person's yes. Never present together with `released`. Older servers stripped it.
|
|
15702
15904
|
- type: object
|
|
15703
15905
|
additionalProperties: false
|
|
15704
15906
|
required: [kind, deniedBy]
|
|
@@ -16156,6 +16358,10 @@ components:
|
|
|
16156
16358
|
`MCP_FAILURE_CODES` spellings โ including `network` and the `http_<status>` encoding โ are gone,
|
|
16157
16359
|
and an HTTP status now rides the structured `httpStatus` seat on `wiring_manifest.mcp[]` instead of
|
|
16158
16360
|
being baked into the code. The set as a WHOLE stays open (a tool owns its own codes).
|
|
16361
|
+
๐ด core 7.55.0 / server >= 7.135.0 โ two MCP words minted BEFORE the call is sent (`delivered: "no"`; the server has no mint point, they pass through verbatim): after the engine redials a Streamable HTTP
|
|
16362
|
+
server that LOST its session, `mcp.tool_declaration_changed` (the server now declares the tool differently โ safety axis / read-only reading / the "a person must answer" mark / task support โ or no longer lists it) and
|
|
16363
|
+
`mcp.tool_listing_unreached` (the post-redial listing walk stopped before reaching the tool, so its new declaration cannot be proved). Every later call to that tool is refused the same way until a listing of the connection
|
|
16364
|
+
reaches it โ the way out is `POST /v1/sessions/{id}/mcp/reconnect` (or the engine's refresh); do not resend as-is. The lost-session failure itself stays `http_status` + `httpStatus: 404` + `delivered: "unknown"`.
|
|
16159
16365
|
Consumers MUST branch with a `default` arm and MUST NOT exhaustively switch on known values.
|
|
16160
16366
|
The service enforces only a length bound (>128 chars = malformed, the whole key is DROPPED rather
|
|
16161
16367
|
than truncated โ truncating would mint a code core never sent). NOTE: this is a DIFFERENT
|
|
@@ -16505,6 +16711,21 @@ components:
|
|
|
16505
16711
|
type: object
|
|
16506
16712
|
additionalProperties: false
|
|
16507
16713
|
properties: { kind: { type: string, description: 'root | child | resume. Open on read.' } }
|
|
16714
|
+
sessionRules:
|
|
16715
|
+
type: object
|
|
16716
|
+
additionalProperties: false
|
|
16717
|
+
required: [childrenReadLive]
|
|
16718
|
+
description: >
|
|
16719
|
+
server >= 7.135.0 (engine 7.55.0; effective half only, both faces): whether the session-rules layer is handed to the delegated legs. `childrenReadLive: true` = this leg wired the session-rules layer (the deployment has a session-rules
|
|
16720
|
+
store and the task carries a session id) and handed the session's key to every leg it delegates (sync / background / fork / workflow / resume / observer side-car, any depth) โ a rule written into the session NOW governs an
|
|
16721
|
+
already-running child's NEXT call; `false` = no rules layer, nothing handed out. The section ABSENT = an older engine (say nothing; do not read it as `false`). An unreadable section (not `{ childrenReadLive: <boolean> }`) is dropped.
|
|
16722
|
+
properties:
|
|
16723
|
+
childrenReadLive: { type: boolean }
|
|
16724
|
+
projectMemory:
|
|
16725
|
+
type: string
|
|
16726
|
+
description: >
|
|
16727
|
+
server >= 7.135.0 (engine 7.55.0; effective half only, both faces): did this leg call the deployment's project-context seat โ `on` = it did; `disabled` = the seat is wired but the request's `projectMemory: "disabled"` turned it off;
|
|
16728
|
+
`absent` = the deployment wired no seat (whatever the request said). On `disabled` / `absent` legs the server-minted `instructions` section is ABSENT. Open on read (a new engine word passes through); ABSENT = an older engine.
|
|
16508
16729
|
ask:
|
|
16509
16730
|
type: object
|
|
16510
16731
|
additionalProperties: false
|
|
@@ -17096,6 +17317,10 @@ components:
|
|
|
17096
17317
|
own failure carries the same code. `{ modelId, boundOrigin, requestOrigin, sessionId, runId }` โ both origins in display spelling (scheme + host +
|
|
17097
17318
|
port, no userinfo / path), never a credential or a digest of one. Once per run per (modelId, boundOrigin, requestOrigin). It replaces the retired
|
|
17098
17319
|
operator code `route.base_url_changed_key_unchanged` (never on this whitelist). `config.credential_not_withheld` is operator-audience โ ops log only.
|
|
17320
|
+
`advisor.not_attached` (server >= 7.135.0 / core 7.55.0; D.3 is now 42 codes) โ the request's advisor model did NOT attach (the engine's pairing judge refuses the (advisor, main) pair).
|
|
17321
|
+
`{ advisorModel, mainModel, reason, sessionId, runId? }` โ the two model names are the catalog id / the reference the request wrote (display spelling); `reason` is an engine word (`unknown_model` / `advisor_unranked` /
|
|
17322
|
+
`weakest_tier` / `main_unranked` / `pairing` / `hold_unknown`; the server echoes it โ read OPEN). Unreachable on this server today: it does not accept `advisorModel` (the request body does not take it, and the
|
|
17323
|
+
`advisor` section is not projected on either `wiring_manifest` face).
|
|
17099
17324
|
Value change: `permission.rule_row_dropped`'s `detail.rows[].rule` is, since core 7.53.0, the rule's original text (the same reading as
|
|
17100
17325
|
`allowed_tool_not_granted`'s `entries[].entry`: at most 1 024 code points, longer cut to 1 024 + a truncation mark, CONTROL CHARACTERS RIDE AS DATA โ
|
|
17101
17326
|
neutralize at render); before it was the engine-neutralized single-line form (at most 201 code points). Same keys.
|
|
@@ -18300,6 +18525,27 @@ components:
|
|
|
18300
18525
|
The closed five-word vocabulary of `AllowRuleShadow.member` (server >= 7.117.0 / core 7.42.0 `ALLOW_RULE_MEMBERS`, verbatim and in the order the engine reads the members). The SDK exports
|
|
18301
18526
|
it at runtime as `ALLOW_RULE_MEMBERS`. Owner = core; read it as an open string with a default arm (core may add a member and the server follows).
|
|
18302
18527
|
|
|
18528
|
+
AllowRuleClearance:
|
|
18529
|
+
type: object
|
|
18530
|
+
additionalProperties: false
|
|
18531
|
+
required: [member, entries]
|
|
18532
|
+
description: >
|
|
18533
|
+
`tool_end.gate.disposition.clearedBy` (server >= 7.135.0 / core 7.55.0 `AllowRuleClearance`): the allow-layer member whose rule CLEARED a standing ask (the pair of `AllowRuleShadow`, which is
|
|
18534
|
+
"matched and could NOT clear"). Same `member` / `entries` / `omitted` shape (minted and capped by the same seat), plus `positions` for a LIST member (`request`, `deployment`): the index of every element of the
|
|
18535
|
+
list the run received that is one of those entries (a string listed twice has both indices), so a host reads which line of its own declaration spoke even where the shown text is capped.
|
|
18536
|
+
properties:
|
|
18537
|
+
member: { $ref: '#/components/schemas/AllowRuleMember' }
|
|
18538
|
+
entries:
|
|
18539
|
+
type: array
|
|
18540
|
+
maxItems: 32
|
|
18541
|
+
items: { type: string, maxLength: 512 }
|
|
18542
|
+
description: 'The entries that member stood on (UNTRUSTED for display, secret-redacted, <= 512 chars each, <= 32 listed).'
|
|
18543
|
+
omitted: { type: integer, minimum: 1, description: 'How many entries were not listed (beyond the cap). Absent = none omitted.' }
|
|
18544
|
+
positions:
|
|
18545
|
+
type: array
|
|
18546
|
+
items: { type: integer, minimum: 0 }
|
|
18547
|
+
description: 'LIST members only: the indices, in the list this run received, of the elements that are those entries. Absent for a non-list member.'
|
|
18548
|
+
|
|
18303
18549
|
AllowRuleShadow:
|
|
18304
18550
|
type: object
|
|
18305
18551
|
additionalProperties: false
|
|
@@ -18431,7 +18677,7 @@ components:
|
|
|
18431
18677
|
equality). ONE vocabulary for two faces: a card's rule offer (`RuleOffer.match`, the
|
|
18432
18678
|
server's card schema validates it with this very enum) and a persisted rule row (`GET /v1/rules`).
|
|
18433
18679
|
|
|
18434
|
-
`exact` = this one command only (`Bash(git status)`). `prefix` = the historical colon-star
|
|
18680
|
+
`exact` = this one command only (`Bash(git status)`). `pattern` (server >= 7.135.0 / core 7.55.0) = the MID-STAR command form (`Bash(git * main)`) โ the fourth Bash command form a card edit may persist; the persisted `command` is the written pattern itself. `prefix` = the historical colon-star
|
|
18435
18681
|
word-boundary prefix (`Bash(git status:*)`) and the ONLY spelling for a compound prefix form; it stays
|
|
18436
18682
|
a permanent compatibility read. `wildcard` = the trailing space-star form (`Bash(npm run *)`), the
|
|
18437
18683
|
same predicate as `prefix` on a single command body. `subpath` = the `Read(//abs-dir/**)` directory form,
|
|
@@ -18445,11 +18691,11 @@ components:
|
|
|
18445
18691
|
always refuses these two words (no network grant is minted through a card). A replica rolled back to 7.125.x reads such a
|
|
18446
18692
|
row as a damaged row.
|
|
18447
18693
|
|
|
18448
|
-
๐ด
|
|
18694
|
+
๐ด TEN MEMBERS, closed (server >= 7.135.0 / core 7.55.0 added `pattern`, between `wildcard` and `subpath` โ the engine's order): the server validates the member on both faces. A consumer type narrower than the
|
|
18449
18695
|
mint point is a lie โ it lets a `switch` claim exhaustiveness the wire does not honour (SDK <= 16 declared
|
|
18450
18696
|
four here, so a `path` offer and every 7.118.0 skill-card offer were dropped as malformed; SDK <= 21 declared
|
|
18451
18697
|
seven, so every domain grant row on `GET /v1/rules` was dropped the same way).
|
|
18452
|
-
enum: [exact, prefix, wildcard, subpath, path, name, name_prefix, host, subdomain]
|
|
18698
|
+
enum: [exact, prefix, wildcard, pattern, subpath, path, name, name_prefix, host, subdomain]
|
|
18453
18699
|
|
|
18454
18700
|
RuleOfferUncoveredReason:
|
|
18455
18701
|
type: string
|
|
@@ -19785,6 +20031,12 @@ components:
|
|
|
19785
20031
|
runId: { type: string }
|
|
19786
20032
|
status: { type: string }
|
|
19787
20033
|
summary: { type: string }
|
|
20034
|
+
completionId:
|
|
20035
|
+
type: string
|
|
20036
|
+
description: >
|
|
20037
|
+
server >= 7.135.0 โ the idempotency anchor of this workflow completion: the SAME id rides every notification path of one completion (this frame / `task_notification` / fleet `bg_notification` / inbox replay) and
|
|
20038
|
+
is the dedup key ACROSS paths (the same value domain as `task_notification.completionId`). ABSENT when the engine gave none (an orphan the service terminated itself) โ dedup on `runId` as before. The read faces
|
|
20039
|
+
(`GET /v1/workflows/{id}` etc.) deliberately never carry it. Older servers' re-delivered frames have no such key.
|
|
19788
20040
|
|
|
19789
20041
|
# โโ ๐ด #185a (2026-08-08): the DURABLE leg's three APPROVAL arms โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
19790
20042
|
# Shape rule for all three: `allOf: [<frame schema>, {the narrowed discriminant}]`. The keys are NOT
|
|
@@ -20484,7 +20736,7 @@ components:
|
|
|
20484
20736
|
๐ด ONE RULE FOR EVERY "EFFECTIVE HALF ONLY" KEY (sdk 9.7.0, after a codex adversarial-review [high]):
|
|
20485
20737
|
this schema's only consumer today is `GET /v1/diagnostics/wiring`'s `static` half, and every key marked
|
|
20486
20738
|
"effective half only" (`leg`, `ask.effective`, `configFingerprint`, `tools`, `mods`, `lsp`,
|
|
20487
|
-
`modelGate`, `autoMode`, `writeProtection`, `readDeny`, `autoConsolidation`, `fileHistory`, `instructions`) is ALWAYS ABSENT on that
|
|
20739
|
+
`modelGate`, `autoMode`, `writeProtection`, `readDeny`, `autoConsolidation`, `fileHistory`, `instructions`, `sessionRules`, `projectMemory`) is ALWAYS ABSENT on that
|
|
20488
20740
|
wire โ THEIR ABSENCE HERE CARRIES NO INFORMATION. The per-key absence readings ("absent = not armed",
|
|
20489
20741
|
"absent = a third state", โฆ) hold for the LIVE FRAME (`Event_wiring_manifest`) and must not be carried
|
|
20490
20742
|
over to this response. For the facts behind those keys: a tenant reads
|
|
@@ -20497,7 +20749,7 @@ components:
|
|
|
20497
20749
|
are EFFECTIVE-half only (the live `wiring_manifest` event) โ as are the four per-leg sections
|
|
20498
20750
|
`modelGate`, `autoMode`, `mcp` and `tools`, which describe what THIS leg did and have no static
|
|
20499
20751
|
counterpart โ and the STATIC half
|
|
20500
|
-
(GET /v1/diagnostics/wiring) NEVER mints them; every other section, plus `governance`, is always
|
|
20752
|
+
(GET /v1/diagnostics/wiring) NEVER mints them; every other section NOT in the effective-half-only list above, plus `governance`, is always
|
|
20501
20753
|
present on the static half. Fields stay optional because core may add or drop sections and that
|
|
20502
20754
|
must not hard-break a client โ read by half, and never wait on a key the half never sends.
|
|
20503
20755
|
๐ด EVERY section is declared HERE, each saying which half mints it (sdk 8.9.0). Before that, `tools`
|
|
@@ -20518,6 +20770,18 @@ components:
|
|
|
20518
20770
|
description: 'Which leg emitted it (effective half only; the static half has no leg identity).'
|
|
20519
20771
|
properties:
|
|
20520
20772
|
kind: { type: string, enum: [root, child, resume] }
|
|
20773
|
+
sessionRules:
|
|
20774
|
+
type: object
|
|
20775
|
+
required: [childrenReadLive]
|
|
20776
|
+
description: >
|
|
20777
|
+
server >= 7.135.0 (engine 7.55.0; effective half only โ the static half never mints it): whether the session-rules layer is handed to the delegated legs. Same reading as on the live frame (`Event_wiring_manifest.sessionRules`):
|
|
20778
|
+
`childrenReadLive: true` = a rule written into the session NOW governs an already-running child's NEXT call; `false` = no rules layer; the section ABSENT = an older engine, or this half.
|
|
20779
|
+
properties:
|
|
20780
|
+
childrenReadLive: { type: boolean }
|
|
20781
|
+
projectMemory:
|
|
20782
|
+
type: string
|
|
20783
|
+
description: >
|
|
20784
|
+
server >= 7.135.0 (engine 7.55.0; effective half only): did the leg call the deployment's project-context seat โ `on` / `disabled` (the request's `projectMemory: "disabled"`) / `absent` (no seat wired). Open on read; ABSENT = an older engine, or this half.
|
|
20521
20785
|
ask:
|
|
20522
20786
|
type: object
|
|
20523
20787
|
description: 'Approval seam: wired form, which seat it came from, and (effective half) what it adjudicates to.'
|
|
@@ -21285,6 +21549,19 @@ components:
|
|
|
21285
21549
|
usageMissing: { type: boolean, enum: [true] }
|
|
21286
21550
|
stopReason: { type: string }
|
|
21287
21551
|
errorMessage: { type: string, description: 'A post-stream error (contract: not thrown as HTTP).' }
|
|
21552
|
+
errorCode:
|
|
21553
|
+
type: string
|
|
21554
|
+
description: >-
|
|
21555
|
+
server >= 7.135.0 (core 7.55.0, passed through verbatim; failure only): the engine's brain error code of the failed reply (open on read; today `auth` / `invalid_request` / `rate_limit` / `server` / `network` /
|
|
21556
|
+
`http` / `stream_torn` / `refusal` / `length_empty`). ABSENT on success and on older servers.
|
|
21557
|
+
errorKind:
|
|
21558
|
+
type: string
|
|
21559
|
+
enum: [input_too_long, degenerate, length_empty]
|
|
21560
|
+
description: 'server >= 7.135.0 (failure only): the STRUCTURAL failure kind the reply carried, forwarded as is โ `input_too_long` (the provider refused the request as over its window), `degenerate`, `length_empty`. Absent when the reply carried none.'
|
|
21561
|
+
inputTooLongRuledOut:
|
|
21562
|
+
type: boolean
|
|
21563
|
+
enum: [true]
|
|
21564
|
+
description: 'server >= 7.135.0 (failure only): present (always `true`) when the failure was a provider refusal whose minter RULED OUT input-too-long as the explanation (core `AssistantMessage.inputTooLongRuledOut`, passed through). It speaks ONLY to that negative: it does not say the status is 400 / 422 and does not say a verbatim resend repeats the failure (the engine also rules input length out for statuses such as 401 / 429 / 500) โ triage on `errorCode`. Absent = no such judgment.'
|
|
21288
21565
|
|
|
21289
21566
|
ToolApprovalDecision:
|
|
21290
21567
|
type: string
|
|
@@ -21463,6 +21740,8 @@ components:
|
|
|
21463
21740
|
to settle it): a parked row's `decided` can return to `parked` when the resume leg fails before the approved action starts (the engine reopens the same gate), and
|
|
21464
21741
|
a cancelled resume reads `void` once the server collects the reopened gate (`parked` in between, or `void` for an instant during the reopen).
|
|
21465
21742
|
Older servers answered all of these with `parked` + `decidePath`.
|
|
21743
|
+
๐ด server >= 7.135.0: a gate that was DECIDED and then REOPENED by the engine reads `parked` WITH `reopened` (`ToolApprovalReopened`: the engine's reopen reason + the earlier decision's
|
|
21744
|
+
`decision` / `decidedAtMs` / `decisionNote?`). `reopened` ABSENT = the read cannot say it was reopened (not "confirmed never reopened"). Older servers: always absent.
|
|
21466
21745
|
oneOf:
|
|
21467
21746
|
- $ref: '#/components/schemas/ToolApprovalReadPending'
|
|
21468
21747
|
- $ref: '#/components/schemas/ToolApprovalReadDecided'
|
|
@@ -21500,6 +21779,29 @@ components:
|
|
|
21500
21779
|
properties:
|
|
21501
21780
|
state: { type: string, enum: [parked] }
|
|
21502
21781
|
decidePath: { type: string, description: 'The durable decision path for this ask when it can be built.' }
|
|
21782
|
+
reopened:
|
|
21783
|
+
allOf: [{ $ref: '#/components/schemas/ToolApprovalReopened' }]
|
|
21784
|
+
description: 'server >= 7.135.0: present when the gate was decided and then reopened by the engine (the resume leg failed before the approved action started). Absent = the read cannot say it was reopened.'
|
|
21785
|
+
ToolApprovalReopenReason:
|
|
21786
|
+
type: string
|
|
21787
|
+
description: >
|
|
21788
|
+
`ToolApprovalReopened.reason` (server >= 7.135.0) โ the engine's `REOPEN_REASONS`, verbatim and in order (engine-owned; the server echoes a word only when it is in this
|
|
21789
|
+
set, otherwise `reopened` is omitted entirely): `env_failed` (the environment / session side failed) ยท `tool_unavailable` (the approved tool is not there now โ decide again) ยท
|
|
21790
|
+
`constraint_rejected` (the decision input was rejected โ decide again) ยท `config_refused` (the configuration was refused). Read open on the consumer side: an unknown word is "reopened, reason unknown".
|
|
21791
|
+
enum: [env_failed, tool_unavailable, constraint_rejected, config_refused]
|
|
21792
|
+
ToolApprovalReopened:
|
|
21793
|
+
type: object
|
|
21794
|
+
description: >
|
|
21795
|
+
`ToolApprovalReadParked.reopened` (server >= 7.135.0): evidence that a DECIDED gate was reopened by the engine. `reason` = the engine's reopen reason; `decision` / `decidedAtMs` / `decisionNote?` = the
|
|
21796
|
+
decision made BEFORE the reopen (the same three keys as a `decided` body). An unreadable earlier decision โ the three keys are absent TOGETHER (only `reason` stays; `decisionNote` may always be absent).
|
|
21797
|
+
Single-instant read: if the row is decided and reopened between the two reads the server re-judges (three rounds in a row โ falls back to plain `parked`).
|
|
21798
|
+
additionalProperties: false
|
|
21799
|
+
required: [reason]
|
|
21800
|
+
properties:
|
|
21801
|
+
reason: { $ref: '#/components/schemas/ToolApprovalReopenReason' }
|
|
21802
|
+
decision: { type: string, enum: [allow, deny] }
|
|
21803
|
+
decidedAtMs: { type: integer }
|
|
21804
|
+
decisionNote: { type: string }
|
|
21503
21805
|
ToolApprovalReadVoid:
|
|
21504
21806
|
allOf:
|
|
21505
21807
|
- $ref: '#/components/schemas/ToolApprovalReadProjection'
|
|
@@ -22217,8 +22519,8 @@ components:
|
|
|
22217
22519
|
match:
|
|
22218
22520
|
allOf: [{ $ref: '#/components/schemas/RuleOfferMatch' }]
|
|
22219
22521
|
description: >
|
|
22220
|
-
The match form โ the same
|
|
22221
|
-
`PERSISTED_RULE_MATCHES`): `exact` / `prefix` / `wildcard` / `subpath` / `path`, and from server >= 7.118.0
|
|
22522
|
+
The match form โ the same ten-member vocabulary as a card's rule offer (`RuleOfferMatch`, the server's
|
|
22523
|
+
`PERSISTED_RULE_MATCHES`): `exact` / `prefix` / `wildcard` / `pattern` (server >= 7.135.0: the mid-star command form) / `subpath` / `path`, and from server >= 7.118.0
|
|
22222
22524
|
`name` / `name_prefix` (a `Skill(<name>)` / `Skill(<prefix>:*)` rule).
|
|
22223
22525
|
command: { type: string, description: 'What the matcher actually compares against, parsed out of `rule` at mint time and stored so no consumer re-parses. Trust this + `match`, not your own parse of `rule`.' }
|
|
22224
22526
|
adds:
|