@sema-agent/sdk 7.3.0 → 8.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 +99 -0
- package/dist/errors.d.ts +32 -6
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +35 -3
- package/dist/errors.js.map +1 -1
- package/dist/events.d.ts +31 -7
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js.map +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/resources/approvals.d.ts +6 -0
- package/dist/resources/approvals.d.ts.map +1 -1
- package/dist/resources/approvals.js.map +1 -1
- package/dist/resources/fleet.d.ts +39 -6
- package/dist/resources/fleet.d.ts.map +1 -1
- package/dist/resources/fleet.js.map +1 -1
- package/dist/resources/images.d.ts +5 -1
- package/dist/resources/images.d.ts.map +1 -1
- package/dist/resources/images.js +11 -7
- package/dist/resources/images.js.map +1 -1
- package/dist/resources/rules.d.ts +33 -8
- package/dist/resources/rules.d.ts.map +1 -1
- package/dist/resources/rules.js.map +1 -1
- package/dist/resources/runs.d.ts +6 -1
- package/dist/resources/runs.d.ts.map +1 -1
- package/dist/resources/runs.js +13 -7
- package/dist/resources/runs.js.map +1 -1
- package/dist/resources/sessions.d.ts +19 -1
- package/dist/resources/sessions.d.ts.map +1 -1
- package/dist/resources/sessions.js +22 -0
- package/dist/resources/sessions.js.map +1 -1
- package/dist/resources/tool-approvals.d.ts +22 -7
- package/dist/resources/tool-approvals.d.ts.map +1 -1
- package/dist/resources/tool-approvals.js +7 -2
- package/dist/resources/tool-approvals.js.map +1 -1
- package/dist/resources/trace.d.ts +9 -8
- package/dist/resources/trace.d.ts.map +1 -1
- package/dist/resources/trace.js +15 -14
- package/dist/resources/trace.js.map +1 -1
- package/dist/sse.d.ts +25 -2
- package/dist/sse.d.ts.map +1 -1
- package/dist/sse.js +30 -16
- package/dist/sse.js.map +1 -1
- package/dist/types.d.ts +74 -0
- package/dist/types.d.ts.map +1 -1
- package/openapi.yaml +387 -65
- package/package.json +1 -1
package/openapi.yaml
CHANGED
|
@@ -1962,6 +1962,73 @@ paths:
|
|
|
1962
1962
|
schema: { $ref: '#/components/schemas/McpStatusPanel' }
|
|
1963
1963
|
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
1964
1964
|
|
|
1965
|
+
/v1/sessions/{sessionId}/memory-status:
|
|
1966
|
+
parameters:
|
|
1967
|
+
- $ref: '#/components/parameters/PrincipalHeader'
|
|
1968
|
+
- in: path
|
|
1969
|
+
name: sessionId
|
|
1970
|
+
required: true
|
|
1971
|
+
schema: { type: string }
|
|
1972
|
+
get:
|
|
1973
|
+
tags: [sessions]
|
|
1974
|
+
operationId: sessionsMemoryStatus
|
|
1975
|
+
x-status: live # S-53 seam① (server 7.53.0; core 7.0.2 #511 item 1 / design/383 §S-7); SDK sessions.memoryStatus.
|
|
1976
|
+
summary: Session memory status — the pure-derivation projection of core's `sessionMemoryStatus`.
|
|
1977
|
+
description: >
|
|
1978
|
+
S-53 seam① (server >=7.53, core 7.0.2 #511 item 1; board [5785]/[5786] key shapes). 200 body =
|
|
1979
|
+
`{sessionId}` + core `MemoryEngine.sessionMemoryStatus(sessionId)` (`SessionMemoryStatus`) projected
|
|
1980
|
+
KEY BY KEY (each of the five optional keys is copied only when present). 🔴 ABSENCE IS HONEST, NOT A
|
|
1981
|
+
DEFAULT — but its meaning is PER KEY (read off core 7.0.2 `engine.js sessionMemoryStatus`, not off a
|
|
1982
|
+
blanket rule): `captureOptedOut` absent = the record store faulted (then `optOutSource:"fault"` rides
|
|
1983
|
+
along; indeterminate ≠ false); `optOutSource` absent = store readable and NO opt-out record (the
|
|
1984
|
+
HEALTHY default — it is only minted as `record`/`fault`); `committedCount` absent = lineage ledger
|
|
1985
|
+
unreadable (a session with no contribution gets `0`, not absence); `lastCaptureAt` absent = ledger
|
|
1986
|
+
unreadable OR no committed contribution at all (a healthy empty session omits it); `foldedCount`
|
|
1987
|
+
absent = ledger unreadable, or the backend cannot enumerate scopes, or the product read failed (`0`
|
|
1988
|
+
when there is nothing to fold). A zero-history session therefore reads
|
|
1989
|
+
`{sessionId, captureOptedOut:false, committedCount:0, foldedCount:0}` — two keys absent and NOTHING
|
|
1990
|
+
degraded. The server never coins a `false`/`0` stand-in for a faulted source. Gate order, same family as the erase
|
|
1991
|
+
face: 401 (multi-tenant, no principal — BEFORE any store read: zero existence oracle) → 501
|
|
1992
|
+
`capability.memory_engine_required` (no owner audit face: a deployment without one must not fake a 404)
|
|
1993
|
+
→ 404 `not_found.session` (unknown AND non-owner — SAME code, SAME message; anti-enumeration) → 501
|
|
1994
|
+
`capability.memory_engine_required` (status face absent: engine not wired / the pg+tidb memory backends
|
|
1995
|
+
do not own the control plane — same code as the first 501) → 200. 400 `request.path_malformed` on a bad
|
|
1996
|
+
percent-encoded id segment. Non-billable, non-mutating; served through a short-TTL single-flight cache
|
|
1997
|
+
per session id. 🔴 NO capability bit advertises this face (deliberately — [5785]/[5786] fixed no bit
|
|
1998
|
+
name): the route answers for itself; probe by calling it, a 501 is the honest "not on this deployment".
|
|
1999
|
+
🔴 VERSION SKEW (codex R2; the SDK support floor is far below 7.53): a supported OLDER server
|
|
2000
|
+
(<7.53) has no such route and answers the version-stable generic fallback 404 `not_found.route` —
|
|
2001
|
+
treat it like the 501 ("face not here"), and distinguish it BY errorCode from this op's own 404
|
|
2002
|
+
`not_found.session` (unknown/non-owner session). Same HTTP status, different codes — never collapse
|
|
2003
|
+
the two.
|
|
2004
|
+
Cross-incarnation caveat (server-side, cannot be fixed at this layer): the capture record and the
|
|
2005
|
+
lineage ledger are keyed by the BARE sessionId and outlive the session, so a re-claimed id reads the
|
|
2006
|
+
PREVIOUS incarnation's counts/opt-out (metadata only, no content bytes).
|
|
2007
|
+
responses:
|
|
2008
|
+
'200':
|
|
2009
|
+
description: >-
|
|
2010
|
+
The session's memory status. Absence is PER-KEY (see SessionMemoryStatusResponse): a healthy
|
|
2011
|
+
zero-history session omits `optOutSource`/`lastCaptureAt` while answering
|
|
2012
|
+
`captureOptedOut:false, committedCount:0, foldedCount:0` — nothing degraded; the other keys are
|
|
2013
|
+
absent only when their source could not be read.
|
|
2014
|
+
content:
|
|
2015
|
+
application/json:
|
|
2016
|
+
schema: { $ref: '#/components/schemas/SessionMemoryStatusResponse' }
|
|
2017
|
+
'400': { $ref: '#/components/responses/BadRequest' }
|
|
2018
|
+
'401': { $ref: '#/components/responses/Unauthorized' }
|
|
2019
|
+
'404': { $ref: '#/components/responses/NotFound' }
|
|
2020
|
+
'500':
|
|
2021
|
+
description: >-
|
|
2022
|
+
errorCode "internal.error" — `routes/sessions.ts`'s catch around `face.status(sessionId)`: core
|
|
2023
|
+
promises the face never throws, so reaching this arm is an assembly defect; the server fails LOUD
|
|
2024
|
+
(500) rather than answering a plausible all-keys-absent body. The SDK maps it to
|
|
2025
|
+
`InternalServerError`. (codex R1 of the 7.3.1 batch: the arm exists in the shipped 7.53.0 route and
|
|
2026
|
+
was missing here.)
|
|
2027
|
+
content:
|
|
2028
|
+
application/json:
|
|
2029
|
+
schema: { $ref: '#/components/schemas/ErrorResponse' }
|
|
2030
|
+
'501': { $ref: '#/components/responses/NotImplemented' }
|
|
2031
|
+
|
|
1965
2032
|
# ── 2c session-sync (P1d) — the cloud as a SYNC PEER ──────────────────────────────────────────────────────────
|
|
1966
2033
|
# The local shell's local backend ⇄ this cloud service. PULL a session's whole state out, or PUSH the local
|
|
1967
2034
|
# peer's in. Gate the whole surface off `capabilities.sessionSync` — a FOUR-way conjunction (durable backend
|
|
@@ -2466,7 +2533,11 @@ paths:
|
|
|
2466
2533
|
member since core 5.7.0/RB-459: the content-ask `answer` payload was refused) — your binding does
|
|
2467
2534
|
NOT match the current pending action (TOCTOU/swap). The SDK splits these by `errorCode` into
|
|
2468
2535
|
ConflictError vs ApprovalBindingMismatchError. binding_mismatch = SAFETY signal: refetch + re-present
|
|
2469
|
-
to the human, NEVER auto-retry.
|
|
2536
|
+
to the human, NEVER auto-retry. (S-57, server >= 7.54.0: the `field:"boundCallId"` shape is
|
|
2537
|
+
intercepted in steady state by the `approval_stale` second trigger source below — the server
|
|
2538
|
+
compares the echoed boundCallId against the current pending pre-CAS and answers 409
|
|
2539
|
+
`approval_stale` + `currentPending`; this code's boundCallId arm covers only the remaining race
|
|
2540
|
+
window between that compare and the core CAS. The hash/answer arms are unchanged.)
|
|
2470
2541
|
FOURTH member ([2400] CB-2, declared 2026-08-02): `gate_not_tool_approval` — the suspension this
|
|
2471
2542
|
sessionId is parked on is NOT a tool-approval gate (`src/http/server.ts` rejects pre-CAS when the
|
|
2472
2543
|
gate kind is neither `human` nor `irreversible_ask`: nothing is consumed, no model leg burns). It is
|
|
@@ -2474,6 +2545,14 @@ paths:
|
|
|
2474
2545
|
`gate_not_plan_review` (§4c) → SDK `GateNotToolApprovalError`. Client action: route by the row's
|
|
2475
2546
|
`gateKind` — `plan_review` → `POST /v1/assistant/tasks/{taskId}/plan_review`, `resource_limit` →
|
|
2476
2547
|
`POST /v1/assistant/tasks/{taskId}/resume`. Retrying the same body never succeeds.
|
|
2548
|
+
SIXTH group (A-075.10, TIME-BASED retry-later pair): `resume.usage_window_exhausted` (#449 G1,
|
|
2549
|
+
core 5.60.1 — the deployment governance window on this run's ledger key is full; NOTHING was
|
|
2550
|
+
consumed or unpinned, the SAME token with the SAME decision redeems once the window slides) and
|
|
2551
|
+
`resume.preflight_rejected` (#376, core 5.65 retry-later form). Both are PRE-CAS (the checkpoint
|
|
2552
|
+
stays pending) and their body ADDITIVELY carries `retryAfterSec` (seconds, ceil, min 1; the
|
|
2553
|
+
server mints the key ONLY on these two codes with a finite positive wait) → SDK
|
|
2554
|
+
`ResumeRetryLaterError` (a `SubagentResumeConflictError` subclass so existing family catches
|
|
2555
|
+
keep matching; `.retryAfterSec` is the actionable wait).
|
|
2477
2556
|
FIFTH group ([2400] CB-2): the core `checkpoint.*` family the server mirrors verbatim
|
|
2478
2557
|
(`src/http/server.ts`) — `checkpoint.gate_mismatch` / `checkpoint.reopen_failed` /
|
|
2479
2558
|
`checkpoint.reopen_revote` / `checkpoint.already_exists` / `checkpoint.resume_aborted` /
|
|
@@ -2493,11 +2572,15 @@ paths:
|
|
|
2493
2572
|
checkpointToken. Absent when there is no pending / the gate is not a tool approval / the row read
|
|
2494
2573
|
failed (loud fail-open ledger arm) / an older server. Owner domain = the route's owner gate (no
|
|
2495
2574
|
new disclosure surface). SDK: `ApprovalStaleError.currentPending`, whole-or-absent guard.
|
|
2496
|
-
REACHABILITY (
|
|
2497
|
-
`checkpointToken
|
|
2498
|
-
resume credentials never ride the compliant decide),
|
|
2499
|
-
|
|
2500
|
-
|
|
2575
|
+
REACHABILITY (REWRITTEN for S-57, server >= 7.54.0): the stale arm now has TWO trigger sources —
|
|
2576
|
+
(1) a caller echoing a legacy `checkpointToken` (this SDK's ApprovalDecision deliberately has no
|
|
2577
|
+
such field, removed in 1.0.0 — resume credentials never ride the compliant decide), and
|
|
2578
|
+
(2) an echoed `boundCallId` that does not match the session's CURRENT pending row (the COMPLIANT
|
|
2579
|
+
SDK shape — the server compares pre-CAS and answers this 409 + `currentPending` directly; this
|
|
2580
|
+
form never carries `terminal`). So a decide issued through this SDK DOES reach this 409 under
|
|
2581
|
+
coordinate rotation (before S-57 that shape fell through to `approval_binding_mismatch` +
|
|
2582
|
+
`field:"boundCallId"` with no pointer key; that arm now covers only the race window between the
|
|
2583
|
+
server-side compare and the core CAS).
|
|
2501
2584
|
ALSO an S-02 behavior NARROWING on this arm: an echoed `checkpointToken` that does NOT belong to
|
|
2502
2585
|
this session, when the session has NO pending, now folds into the byte-identical 404
|
|
2503
2586
|
`not_found.approval` (it used to 409 — a single-bit cross-tenant "who is parked on an approval"
|
|
@@ -5697,15 +5780,42 @@ components:
|
|
|
5697
5780
|
Run state (`GET /v1/runs/:id`) — live shape per the pinned wire contract Drift 2: `result` is the NESTED TaskResult
|
|
5698
5781
|
object (output text in result.result, stats in result.stats; NO top-level stats), and the error text
|
|
5699
5782
|
field is `error` (not errorMessage; errorCode is floated up from result.errorCode).
|
|
5700
|
-
# 封闭(census 轴一,2026-07-30):铸造点 routes/runs.ts
|
|
5701
|
-
# (taskId/sessionId/status/result/supervisorCost/
|
|
5702
|
-
#
|
|
5783
|
+
# 封闭(census 轴一,2026-07-30;A-075.21 回填后 12 键):铸造点 routes/runs.ts 是一个逐键写死的
|
|
5784
|
+
# 字面量(taskId/sessionId/status/msSinceLastActivity/crossSliceUsage/result/supervisorCost/
|
|
5785
|
+
# suggestions/errorCode/error/jobId/source),与本 properties 一一对上;只有 taskId/sessionId/status
|
|
5786
|
+
# 无条件在场(其余走 `?? undefined` / 条件 spread ⇒ JSON 丢键)⇒ required 维持 3 键。
|
|
5787
|
+
# (A-075.21:此前的「恰好 10 键」对 msSinceLastActivity(#245 S1)/crossSliceUsage([3833] S-4)
|
|
5788
|
+
# 两条铸键路径结构性失明 —— server test/producer-contract.test.ts 的 S-4 登记钉逐字记着这笔账。)
|
|
5703
5789
|
additionalProperties: false
|
|
5704
5790
|
required: [taskId, sessionId, status]
|
|
5705
5791
|
properties:
|
|
5706
5792
|
taskId: { type: string }
|
|
5707
5793
|
sessionId: { type: string }
|
|
5708
5794
|
status: { $ref: '#/components/schemas/RunStatus' }
|
|
5795
|
+
msSinceLastActivity:
|
|
5796
|
+
type: integer
|
|
5797
|
+
description: >
|
|
5798
|
+
#245 S1 (server >= 7.18) — ms since the run's last activity (poll-face liveness evidence; same key
|
|
5799
|
+
and semantics as the 409 conflict body). SAME-REPLICA BEST-EFFORT: absent when the poll lands on a
|
|
5800
|
+
replica that never ran this run. Absence = cannot prove, NOT 0/fresh.
|
|
5801
|
+
crossSliceUsage:
|
|
5802
|
+
type: object
|
|
5803
|
+
description: >
|
|
5804
|
+
[3833] S-4 (server >= 7.48.0) — cross-slice governance-window usage, present only on a running
|
|
5805
|
+
(non-stale) row polled on the replica that registered the window. Reading discipline: values are
|
|
5806
|
+
LOWER BOUNDS (ledgered at turn boundaries, delegation subtree excluded); the three axes come in
|
|
5807
|
+
PAIRS (an unconfigured cap omits its pair; spentMicroUsd may also be absent when unpriced — 0
|
|
5808
|
+
would lie); WHOLE-KEY ABSENCE does NOT mean "nothing spent" (no cap / not running / wrong replica
|
|
5809
|
+
/ ledger unavailable are indistinguishable); on resumed legs the totals stay frozen on the first
|
|
5810
|
+
slice's ledger, never overwritten by current env.
|
|
5811
|
+
additionalProperties: false
|
|
5812
|
+
properties:
|
|
5813
|
+
totalTokens: { type: integer }
|
|
5814
|
+
spentTokens: { type: integer }
|
|
5815
|
+
totalBudgetMicroUsd: { type: integer, description: 'Integer micro-USD (display divides by 1e6).' }
|
|
5816
|
+
spentMicroUsd: { type: integer, description: 'Integer micro-USD; absent on unpriced deployments (unknown, not 0).' }
|
|
5817
|
+
maxSlices: { type: integer }
|
|
5818
|
+
sliceCount: { type: integer }
|
|
5709
5819
|
result: { $ref: '#/components/schemas/TaskResult' }
|
|
5710
5820
|
errorCode:
|
|
5711
5821
|
type: string
|
|
@@ -6358,6 +6468,20 @@ components:
|
|
|
6358
6468
|
`resumeAt`); absent ⇒ an older server, send the old spelling. `rewindFiles` keeps its name (same
|
|
6359
6469
|
affordance — "rewind can move files"); this bit is what tells the two epochs apart.
|
|
6360
6470
|
manualCompact: { type: boolean, description: "`POST /v1/runs/:id/compact` (needs a run store)." }
|
|
6471
|
+
configCatalog:
|
|
6472
|
+
type: boolean
|
|
6473
|
+
description: >-
|
|
6474
|
+
S-32 (server >=7.53, `routes/capabilities.ts:731`): the `GET /v1/config/catalog` operator lane
|
|
6475
|
+
(DESIGN-278 §5 S2 — deployment config self-description) is mounted on this DEPLOYMENT. TWO-term
|
|
6476
|
+
conjunction, written against the route's own refusal arms: ① the `CONFIG_CATALOG_ENABLED` knob is
|
|
6477
|
+
on (default on; a compliance deployment that turns it off makes the path a 404 — the valve-family
|
|
6478
|
+
precedent) AND ② the operator principal list is NON-EMPTY (with an empty list the route 403s every
|
|
6479
|
+
identity). 🔴 DEPLOYMENT-LEVEL AVAILABILITY, NOT THE CALLER'S AUTHORIZATION: the caller's own
|
|
6480
|
+
identity is NOT in the predicate — the route additionally requires the CURRENT principal to be an
|
|
6481
|
+
explicit operator (`routes/config-catalog.ts` `explicitOperatorOk`, else 403 `auth.operator_only`),
|
|
6482
|
+
so a non-operator reads `true` and still gets 403. Show/invoke the catalog only for an identity you
|
|
6483
|
+
have ALREADY established as an operator; the bit tells you whether that operator's control exists
|
|
6484
|
+
here at all. `false` does not say WHICH term failed. ABSENT = an older server (<7.53), not "off".
|
|
6361
6485
|
sessions: { type: boolean, description: "Session read face (`GET /v1/sessions/:id`)." }
|
|
6362
6486
|
sessionList: { type: boolean, description: "`GET /v1/sessions` list/picker face." }
|
|
6363
6487
|
sessionSearch: { type: boolean, description: "Server-side session search." }
|
|
@@ -7190,19 +7314,25 @@ components:
|
|
|
7190
7314
|
note: { type: string }
|
|
7191
7315
|
SessionWakeResult:
|
|
7192
7316
|
# 4.3.0(SM-9):wake 200 形提成具名 schema(形与下面 /wake 路径的 200 逐字同源)。
|
|
7317
|
+
# A-075.1(车AE,2026-09-01):#354 只修了 inline 路径 200,这只具名形停在旧二键 required、封闭形下
|
|
7318
|
+
# 缺 `bindingEnforced` ⇒「逐字同源」自称为假、严格生成客户端拒收真响应。现与 inline 重新逐字对齐
|
|
7319
|
+
# (spec.test.ts 的 A-075.1 组机器看守同源等式)。
|
|
7193
7320
|
type: object
|
|
7194
7321
|
description: >
|
|
7195
7322
|
POST /v1/sessions/{sessionId}/wake 的 200 形。⚠️ 200 也可能带 `errorCode`(core 侧 `wake.*` 拒了) ——
|
|
7196
|
-
按机器码分支,别只看 HTTP 状态码。
|
|
7323
|
+
按机器码分支,别只看 HTTP 状态码。ACCEPTANCE form (durable row present, [3833] S-1): status
|
|
7324
|
+
"resuming", the leg keeps running server-side. SYNCHRONOUS form (no durable run row): status is the
|
|
7325
|
+
run's resulting terminal enum. `bindingEnforced` is always true on BOTH forms (both mint points).
|
|
7197
7326
|
additionalProperties: false
|
|
7198
|
-
required: [sessionId, status]
|
|
7327
|
+
required: [sessionId, status, bindingEnforced]
|
|
7199
7328
|
properties:
|
|
7200
|
-
sessionId: { type: string }
|
|
7201
|
-
status: { type: string, description: 'The run''s resulting status (core TaskStatus verbatim).' }
|
|
7202
7329
|
taskId: { type: string, description: 'The active run id; OMITTED when no active row.' }
|
|
7203
|
-
|
|
7204
|
-
|
|
7205
|
-
|
|
7330
|
+
sessionId: { type: string }
|
|
7331
|
+
status: { type: string, description: 'ACCEPTANCE form (durable row present, [3833] S-1): "resuming" — the leg keeps running server-side; follow GET /v1/runs/:id or the events tail for the outcome. SYNCHRONOUS form (no durable run row): the run''s resulting status (completed/failed/suspended/needs_review/blocked — core TaskStatus verbatim; "timeout" retired in core 5.8.0: walltime exhaustion now lands as failed + errorCode limits.max_walltime_exceeded).' }
|
|
7332
|
+
bindingEnforced: { type: boolean, description: '[2400] HITL-12 generation probe — this server enforces decision-action binding. Always true (present on BOTH 200 forms).' }
|
|
7333
|
+
errorCode: { type: string, description: 'Failure code when the resumed leg failed (e.g. `cancelled`). Synchronous form only — never on the acceptance form.' }
|
|
7334
|
+
errorMessage: { type: string, description: 'Human-readable failure detail (server-side secret-redacted). Synchronous form only.' }
|
|
7335
|
+
retriable: { type: boolean, description: 'true = the park is STILL pending (re-parked); refetch and retry. Synchronous form only.' }
|
|
7206
7336
|
WorkflowJournalRow:
|
|
7207
7337
|
# 🔴 census 批2 四段:CLOSED against server's real projected/truncated row shapes — a row is EITHER the
|
|
7208
7338
|
# projected result OR an honest truncated stub(超 64KiB 的行从不进程内存,投影为 truncated stub)。
|
|
@@ -7596,27 +7726,29 @@ components:
|
|
|
7596
7726
|
parentToolCallId: { type: string, description: 'The parent tool_use id VERBATIM (E2 domain, engine-minted) — [1832] P1-2, server >= 1.290 / engine 1.432; the terminal notification frame carries it too. Additive / tolerate-absent.' }
|
|
7597
7727
|
ts: { type: integer }
|
|
7598
7728
|
FleetFrame_hook_notice:
|
|
7599
|
-
type: object
|
|
7600
7729
|
description: >
|
|
7601
|
-
|
|
7602
|
-
|
|
7603
|
-
|
|
7604
|
-
|
|
7605
|
-
`{
|
|
7606
|
-
|
|
7607
|
-
|
|
7730
|
+
Hook observability frame, TWO kinds (both pure observe — never block, resume, or inject anything;
|
|
7731
|
+
visibility fail-CLOSED like bg_notification: the owner keys ownerScope/ownerSessionId gate delivery
|
|
7732
|
+
and are STRIPPED before send; wire is FLAT — `send("hook_notice", { type, ...wire, ts })`, the
|
|
7733
|
+
server-internal `{notice}` nesting never reaches it). codex R1-F4: modeled as the discriminated union
|
|
7734
|
+
it really is — the common `{type, ts}` frame base composed with each kind's payload arm — so a
|
|
7735
|
+
generated client gets the SAME per-kind narrowing as the TS type (a second-family frame missing
|
|
7736
|
+
hookName/entryType is invalid, not silently accepted). `kind` is CLOSED two-member on the server but
|
|
7737
|
+
OPEN ON READ: degrade an unknown future kind to a generic observability row.
|
|
7738
|
+
oneOf:
|
|
7739
|
+
- allOf:
|
|
7740
|
+
- $ref: '#/components/schemas/FleetHookNoticeFrameBase'
|
|
7741
|
+
- $ref: '#/components/schemas/FleetHookDecisionUnavailable'
|
|
7742
|
+
- allOf:
|
|
7743
|
+
- $ref: '#/components/schemas/FleetHookNoticeFrameBase'
|
|
7744
|
+
- $ref: '#/components/schemas/FleetHookNonBlockingFailure'
|
|
7745
|
+
|
|
7746
|
+
FleetHookNoticeFrameBase:
|
|
7747
|
+
type: object
|
|
7748
|
+
description: 'The hook_notice frame envelope shared by both kinds: the SSE frame discriminant and the server timestamp.'
|
|
7749
|
+
required: [type, ts]
|
|
7608
7750
|
properties:
|
|
7609
7751
|
type: { const: hook_notice }
|
|
7610
|
-
kind:
|
|
7611
|
-
type: string
|
|
7612
|
-
enum: [hook_decision_unavailable]
|
|
7613
|
-
description: 'Only one kind today; an enum slot so the next observability frame kind needs no new frame arm.'
|
|
7614
|
-
event: { type: string, description: 'Which hook event (Stop / PreToolUse / …) — defined by "a hook adjudication did not complete", not any single feature.' }
|
|
7615
|
-
reason:
|
|
7616
|
-
type: string
|
|
7617
|
-
enum: [no_content, unparsed, skipped]
|
|
7618
|
-
description: 'Machine-branchable cause (same taxonomy as the server''s structured log lines). CLOSED on the server side but OPEN ON READ — an unknown future value must not crash a consumer.'
|
|
7619
|
-
detail: { type: string, description: 'Redacted supplement (e.g. why skipped). Additive / tolerate-absent.' }
|
|
7620
7752
|
ts: { type: integer }
|
|
7621
7753
|
|
|
7622
7754
|
TraceStreamEvent:
|
|
@@ -7902,6 +8034,22 @@ components:
|
|
|
7902
8034
|
presence may differ between the two legs for one ask. Derived from hot-reloadable governance knobs —
|
|
7903
8035
|
long subscribers follow the stream's re-emitted frames. Absence ≠ "not governance-forced"; it means
|
|
7904
8036
|
"no governance-origin evidence". Never written as false.
|
|
8037
|
+
hasBidiControls:
|
|
8038
|
+
type: boolean
|
|
8039
|
+
enum: [true]
|
|
8040
|
+
description: >
|
|
8041
|
+
S-30① (server >=7.53; core 5.60.0 #438), ADDITIVE, present ONLY when true: the parked action's
|
|
8042
|
+
execution payload contains at least one DIRECTIONAL formatting control (Trojan Source — what a
|
|
8043
|
+
human reads may not be the byte order that executes). Value is ENTIRELY core-minted (the
|
|
8044
|
+
`PendingAction.hasBidiControls` bit at park time; the SQL store denormalises it into the row's
|
|
8045
|
+
`has_bidi_controls` column and reads `=== 1`, the local file store reads the parked
|
|
8046
|
+
`pendingAction` bit `=== true` — neither recomputes). Rides BOTH durable
|
|
8047
|
+
read faces through the same projection (this row on `GET /v1/approvals` and the `pending` frame of
|
|
8048
|
+
`/v1/approvals/stream`). Never null, never false: ABSENCE = "not detected" (clean / core's bounded
|
|
8049
|
+
scan did not reach it / a row parked before the column existed) and MUST NOT be read as "confirmed
|
|
8050
|
+
clean". The live-card leg's sibling key is `inputHasBidi` (E-14, computed by the server over the
|
|
8051
|
+
frame's own serialised args) — a different name on purpose. Display/triage only; never part of
|
|
8052
|
+
resume / gate / CAS.
|
|
7905
8053
|
|
|
7906
8054
|
# ── assistant-scheduler wire (ASSISTANT-WIRE-CONTRACT.md, service main 6cd0164 / core 1.110.0, LIVE) ──
|
|
7907
8055
|
CheckpointSummary:
|
|
@@ -7966,6 +8114,17 @@ components:
|
|
|
7966
8114
|
severity: { type: integer, minimum: 1, maximum: 5, description: 'Sort key; only human/irreversible_ask carry it.' }
|
|
7967
8115
|
spentMicroUsd: { type: number, description: 'Accumulated spend on the suspend chain (micro-USD).' }
|
|
7968
8116
|
deadline: { type: number, description: 'Awaiting-human SLA deadline (epoch ms).' }
|
|
8117
|
+
hasBidiControls:
|
|
8118
|
+
type: boolean
|
|
8119
|
+
enum: [true]
|
|
8120
|
+
description: >-
|
|
8121
|
+
server >=7.53 (S-30① / core 5.60.0 #438), ADDITIVE, present ONLY when true: the parked action's
|
|
8122
|
+
payload carries a DIRECTIONAL formatting control (Trojan Source). Third read face of the same
|
|
8123
|
+
core-minted bit (`routes/approvals-assistant.ts` inbox whitelist arm `s.hasBidiControls === true`;
|
|
8124
|
+
`summarizeCheckpoint` back-fills it for pre-bit rows on THIS face, so the absent set differs from
|
|
8125
|
+
the /v1/approvals row's — the reading of absence does not). Absence = "not detected", never
|
|
8126
|
+
"confirmed clean". Declared here because this schema is CLOSED — without the key a strict validator
|
|
8127
|
+
rejects every >=7.53 inbox row that carries it.
|
|
7969
8128
|
objective: { type: ['string', 'null'], description: 'task objective, null if unavailable.' }
|
|
7970
8129
|
input:
|
|
7971
8130
|
description: >
|
|
@@ -8334,6 +8493,53 @@ components:
|
|
|
8334
8493
|
items: { $ref: '#/components/schemas/McpServerStatus' }
|
|
8335
8494
|
degraded: { type: boolean }
|
|
8336
8495
|
|
|
8496
|
+
SessionMemoryStatus:
|
|
8497
|
+
type: object
|
|
8498
|
+
description: >
|
|
8499
|
+
core 7.0.2 `SessionMemoryStatus` (design/383 §S-7, #511 item 1; `dist/core/memory-engine/engine.d.ts`) —
|
|
8500
|
+
SAME NAME, SAME SHAPE as core's export. Every key is optional, and each key's absence has ITS OWN
|
|
8501
|
+
meaning (below, read off `engine.js sessionMemoryStatus`): two of them (`optOutSource`, `lastCaptureAt`)
|
|
8502
|
+
are legitimately absent on a healthy session, the other three are absent only when their source could
|
|
8503
|
+
not be read. A fault never coins a `false`/`0` stand-in.
|
|
8504
|
+
# 封闭:core 的接口恰是这五键;server 逐键条件拷贝(禁 spread)⇒ 闭集本身。
|
|
8505
|
+
additionalProperties: false
|
|
8506
|
+
properties:
|
|
8507
|
+
captureOptedOut:
|
|
8508
|
+
type: boolean
|
|
8509
|
+
description: 'TRUE = a standing capture opt-out record; FALSE = store readable, no record (capture on). ABSENT = the record store faulted — indeterminate (`optOutSource: "fault"` accompanies).'
|
|
8510
|
+
committedCount:
|
|
8511
|
+
type: integer
|
|
8512
|
+
description: 'Committed entries carrying this session''s lineage contribution. Absent = ledger unreadable.'
|
|
8513
|
+
foldedCount:
|
|
8514
|
+
type: integer
|
|
8515
|
+
description: 'Of those, entries already folded into consolidation products (lineage × `distilled.inputs`); `0` when the session has no contribution. Absent = lineage ledger unreadable, or the backend cannot enumerate scopes, or the product read failed.'
|
|
8516
|
+
optOutSource:
|
|
8517
|
+
type: string
|
|
8518
|
+
enum: [record, fault]
|
|
8519
|
+
description: 'WHY `captureOptedOut` reads as it does: `record` = a standing one-way record (rides with `captureOptedOut:true`); `fault` = the store faulted and the capture state is INDETERMINATE (rides with `captureOptedOut` ABSENT). ABSENT = store readable and no record (`captureOptedOut:false`) — the healthy default, NOT a fault. Closed two-value set, same as core.'
|
|
8520
|
+
lastCaptureAt:
|
|
8521
|
+
type: integer
|
|
8522
|
+
description: 'Newest lineage `lastAt` for this session (ms epoch) — rides the same single ledger read as `committedCount`. Absent = ledger unreadable, or no committed contribution exists at all.'
|
|
8523
|
+
|
|
8524
|
+
SessionMemoryStatusResponse:
|
|
8525
|
+
type: object
|
|
8526
|
+
description: >
|
|
8527
|
+
`GET /v1/sessions/{sessionId}/memory-status` 200 body (server >=7.53, S-53 seam①): `sessionId` + the
|
|
8528
|
+
five `SessionMemoryStatus` keys copied ONE BY ONE when present (the server forbids spreading and forbids
|
|
8529
|
+
defaults — the five conditional copies ARE the closed set). Per-key absence meaning = exactly
|
|
8530
|
+
`SessionMemoryStatus` (a healthy zero-history session omits `optOutSource` and `lastCaptureAt`). Keys
|
|
8531
|
+
are mirrored locally rather than via allOf so the closed schema stays self-describing (spec rule:
|
|
8532
|
+
closed + allOf must mirror every key).
|
|
8533
|
+
additionalProperties: false
|
|
8534
|
+
required: [sessionId]
|
|
8535
|
+
properties:
|
|
8536
|
+
sessionId: { type: string, description: 'The session the status is about (echo of the path segment, percent-decoded).' }
|
|
8537
|
+
captureOptedOut: { type: boolean, description: 'See SessionMemoryStatus.captureOptedOut — absent = indeterminate, never a coined false.' }
|
|
8538
|
+
committedCount: { type: integer, description: 'See SessionMemoryStatus.committedCount.' }
|
|
8539
|
+
foldedCount: { type: integer, description: 'See SessionMemoryStatus.foldedCount.' }
|
|
8540
|
+
optOutSource: { type: string, enum: [record, fault], description: 'See SessionMemoryStatus.optOutSource — absent = no opt-out record (healthy), never a fault by itself.' }
|
|
8541
|
+
lastCaptureAt: { type: integer, description: 'See SessionMemoryStatus.lastCaptureAt (ms epoch) — absent on a session with no committed contribution (healthy) as well as on an unreadable ledger.' }
|
|
8542
|
+
|
|
8337
8543
|
# ── 2c session-sync (P1d) — the cloud-as-a-SYNC-PEER schemas ──────────────────────────────────────────────
|
|
8338
8544
|
SyncEntry:
|
|
8339
8545
|
type: object
|
|
@@ -8651,10 +8857,12 @@ components:
|
|
|
8651
8857
|
# had no arm to switch on and dropped approval cards. Each arm is `allOf: [<the frame schema>, the
|
|
8652
8858
|
# narrowed discriminant]` — the key set stays owned by ToolApprovalFrame / ApprovalRequestFrame,
|
|
8653
8859
|
# so a frame gaining a key (7.5.0's governanceForced) needs no edit here.
|
|
8654
|
-
# `approval_revoke`
|
|
8860
|
+
# `approval_revoke` joined as the FOURTH arm ([5924]/S-58, server >= 7.55.0): the bg/resume durable
|
|
8861
|
+
# legs append it to the run's ledger now (the sync leg stays live-SSE-only), so it replays here too.
|
|
8655
8862
|
- $ref: '#/components/schemas/Event_tool_approval'
|
|
8656
8863
|
- $ref: '#/components/schemas/Event_tool_approval_complete'
|
|
8657
8864
|
- $ref: '#/components/schemas/Event_approval_request'
|
|
8865
|
+
- $ref: '#/components/schemas/Event_approval_revoke'
|
|
8658
8866
|
discriminator:
|
|
8659
8867
|
propertyName: type
|
|
8660
8868
|
mapping:
|
|
@@ -8697,6 +8905,7 @@ components:
|
|
|
8697
8905
|
tool_approval: '#/components/schemas/Event_tool_approval'
|
|
8698
8906
|
tool_approval_complete: '#/components/schemas/Event_tool_approval_complete'
|
|
8699
8907
|
approval_request: '#/components/schemas/Event_approval_request'
|
|
8908
|
+
approval_revoke: '#/components/schemas/Event_approval_revoke'
|
|
8700
8909
|
|
|
8701
8910
|
# design/99 §E2 (SHIPPED, core TaskEventIdentity) — additive per-event identity on every CONTENT event (NOT on
|
|
8702
8911
|
# the lifecycle arms turn_end/compacted/suspended/done/failed). eventId = uuidv7 dedup/resume handle (the durable
|
|
@@ -9017,6 +9226,16 @@ components:
|
|
|
9017
9226
|
properties:
|
|
9018
9227
|
type: { const: task_progress }
|
|
9019
9228
|
taskId: { type: string, description: 'The subagent task id (the delegated sub-run).' }
|
|
9229
|
+
seq:
|
|
9230
|
+
type: integer
|
|
9231
|
+
description: >-
|
|
9232
|
+
core 5.36.0 (#258), server-forwarded: the GENERATION number of the child's `a*` registry row
|
|
9233
|
+
(fresh spawn = 1, +1 per revival; same axis as `TaskNotificationPayload.seq` and the fleet
|
|
9234
|
+
`BackgroundChildEvent.seq`). Lets a consumer tell a late first frame of a known generation (same
|
|
9235
|
+
value) from an un-folded revival (greater). ABSENT = the run has no `a*` row (sync delegated child /
|
|
9236
|
+
workflow `wa*` / top-level) — no generation concept exists, do NOT read absence as cycle 1.
|
|
9237
|
+
core-minted number, no user content. (codex R2 of the SDK 7.3.1 batch: this key was really on the
|
|
9238
|
+
wire and this closed arm omitted it — a strict validator rejected every generation-tagged tick.)
|
|
9020
9239
|
taskType:
|
|
9021
9240
|
type: string
|
|
9022
9241
|
description: >
|
|
@@ -9034,6 +9253,15 @@ components:
|
|
|
9034
9253
|
durationMs: { type: integer }
|
|
9035
9254
|
status: { type: string, description: 'running 为主;core [1414]#3 的 settle 终态 tick 亦可为 completed/failed(开集,按未知值兜底渲染)。' }
|
|
9036
9255
|
name: { type: string, description: '子代的人类展示名(UNTRUSTED,已 redactSecrets)。缺席 ⇒ 无名,别回退到 objective。' }
|
|
9256
|
+
model:
|
|
9257
|
+
type: string
|
|
9258
|
+
description: >-
|
|
9259
|
+
server >=7.53 (core 7.0.1 #508①, P-42): the resolved catalog id of the model this child leg was
|
|
9260
|
+
PREPARED with — same value/meaning as `TaskResult.model` (a mid-run degrade does NOT rewrite it; the
|
|
9261
|
+
switch is disclosed on `TaskResult.degraded`). Minted unconditionally by both core task_progress
|
|
9262
|
+
sites (running tick + settle terminal tick) and forwarded verbatim by the server whitelist on all
|
|
9263
|
+
three live legs + the durable ledger row. ABSENT = an older producer (core <7.0.1 / server <7.53)
|
|
9264
|
+
or unstated — never read absence as "no model". core-minted, no user content.
|
|
9037
9265
|
parentTaskId: { type: string, description: '嵌套子代的上级 taskId;缺席 ⇒ 一级子代。' }
|
|
9038
9266
|
currentAction: { type: string, description: '子代最近一次 tool_start 的一行人话("Bash npm test");UNTRUSTED,已 redactSecrets。' }
|
|
9039
9267
|
workflowRunId: { type: string, description: 'core 1.401:后台 workflow 子代的不透明 run id(下游据此跳过与 fleet 行的重复渲染)。' }
|
|
@@ -10021,9 +10249,14 @@ components:
|
|
|
10021
10249
|
clears that batch's local cards (whitelist-pick by `askIds`) and waits for the new askIds a resume mints.
|
|
10022
10250
|
|
|
10023
10251
|
Siblings already DECIDED are NOT in `askIds` (an accepted decision is not affected by revocation).
|
|
10024
|
-
|
|
10025
|
-
|
|
10026
|
-
|
|
10252
|
+
Emission is PER CONTEXT (S-58, server >= 7.55.0 — the old "reconciler/orphan legs have no seq, live
|
|
10253
|
+
plane only" wording pinned a mint-site constraint on the delivery plane and is retired): the sync leg
|
|
10254
|
+
stays live-SSE-only, the bg/resume durable legs append the frame to the run's own ledger and
|
|
10255
|
+
GET /v1/runs/:id/events replays it (see Event_approval_revoke). Revoke frames CAN STILL BE LOST on any
|
|
10256
|
+
leg (shell offline, connection drop, emit-target churn, ledger write failure — the frame is a
|
|
10257
|
+
notification, the row is the source of truth) — the structural compensation is the open-stream preamble
|
|
10258
|
+
baseline (see ApprovalRequestFrame), not a redelivery of this frame; a ledger-replayed revoke frame is
|
|
10259
|
+
for timeline rendering only.
|
|
10027
10260
|
required: [type, schemaVersion, batchId, askIds, reason, serverNowMs]
|
|
10028
10261
|
additionalProperties: true
|
|
10029
10262
|
properties:
|
|
@@ -10038,6 +10271,15 @@ components:
|
|
|
10038
10271
|
`aborted` = the run was cancelled. Read as OPEN: an unknown reason is handled as a generic revoke
|
|
10039
10272
|
(clear the cards), never specially.
|
|
10040
10273
|
serverNowMs: { type: integer }
|
|
10274
|
+
taskId:
|
|
10275
|
+
type: string
|
|
10276
|
+
description: >
|
|
10277
|
+
S-58 (server >= 7.55.0, always sent there; ABSENT on <= 7.54.0 — the frame family was live-only
|
|
10278
|
+
then, hence not in `required`): the ORIGIN run''s wire id (= the `taskId` of the same ask''s card
|
|
10279
|
+
frame; server buildRevokeFrame''s originTaskId). The dispatch set is session-shaped ((owner,
|
|
10280
|
+
sessionId) closure) and can contain OTHER runs'' contexts — durable legs ledger the frame into
|
|
10281
|
+
their own run, so without this key an orphan revoke row (no paired card frame) could not be
|
|
10282
|
+
attributed or filtered; consumers ignore frames whose taskId is not theirs.
|
|
10041
10283
|
|
|
10042
10284
|
AskDecidedConflictBody:
|
|
10043
10285
|
allOf:
|
|
@@ -10704,6 +10946,30 @@ components:
|
|
|
10704
10946
|
required: [type]
|
|
10705
10947
|
properties:
|
|
10706
10948
|
type: { type: string, enum: [approval_request] }
|
|
10949
|
+
Event_approval_revoke:
|
|
10950
|
+
description: >
|
|
10951
|
+
The design/172 batch-level card REVOCATION frame as an AgentEvent arm ([5924]/S-58, server >= 7.55.0).
|
|
10952
|
+
Emission is PER CONTEXT: the sync stream leg carries it live-SSE-only (unchanged, never ledgered),
|
|
10953
|
+
while the bg/resume durable legs append it to the run's own ledger — so GET /v1/runs/:id/events
|
|
10954
|
+
tails/replays it, and a durable consumer can finally tell "actively revoked (halt/cancel/park
|
|
10955
|
+
degradation)" from "stream ended". On <= 7.54.0 the durable leg never carries this frame.
|
|
10956
|
+
|
|
10957
|
+
🔴 THIS ARM IS THE OPEN ENVELOPE, NOT `ApprovalRevokeFrame` — same ruling as Event_approval_request:
|
|
10958
|
+
narrow with `schemaVersion == 1` (SDK: `isApprovalRevokeFrameV1`) before touching
|
|
10959
|
+
`batchId`/`askIds`/`taskId`; a frame that does not narrow is handled as a generic revoke (clear that
|
|
10960
|
+
batch's local cards), never specially.
|
|
10961
|
+
|
|
10962
|
+
🔴 Consumption discipline: (a) attribute/filter by `taskId` (always present >= 7.55.0) — a run that
|
|
10963
|
+
joined the dispatch set late can carry an ORPHAN revoke ledger row with no paired card frame; "not
|
|
10964
|
+
mine" is safely ignored. (b) A replayed revoke frame is for TIMELINE RENDERING ONLY — the card-set
|
|
10965
|
+
reconciliation baseline stays the open-stream preamble (the frame can be lost on any leg: it is a
|
|
10966
|
+
notification, the row is the source of truth). (c) Siblings already DECIDED are never in `askIds`.
|
|
10967
|
+
allOf:
|
|
10968
|
+
- $ref: '#/components/schemas/ApprovalFrameEnvelope'
|
|
10969
|
+
- type: object
|
|
10970
|
+
required: [type]
|
|
10971
|
+
properties:
|
|
10972
|
+
type: { type: string, enum: [approval_revoke] }
|
|
10707
10973
|
|
|
10708
10974
|
# ── resources/*.ts schema backfill, batch 2 (2026-07-28) — the 28-item WIRE_PENDING ratchet zeroed.
|
|
10709
10975
|
# Each schema below is cross-checked against the server source (file:line cited in its description
|
|
@@ -10729,6 +10995,14 @@ components:
|
|
|
10729
10995
|
sessionId: { type: string, description: '`resolved` frames: which pending settled.' }
|
|
10730
10996
|
toolCallId: { type: string, description: '`resolved` frames: the settled pending''s bound tool-call id (absent when the pending carried none).' }
|
|
10731
10997
|
count: { type: integer, description: '`synced` frames: how many pendings the connect-time snapshot carried.' }
|
|
10998
|
+
hasBidiControls:
|
|
10999
|
+
type: boolean
|
|
11000
|
+
enum: [true]
|
|
11001
|
+
description: >-
|
|
11002
|
+
`pending` frames only (server >=7.53, S-30①): the spread PendingCheckpoint row's bidi-presence bit —
|
|
11003
|
+
SAME projection as the `GET /v1/approvals` row (`projectPendingForWire`), declared here explicitly so
|
|
11004
|
+
a stream consumer sees it typed instead of through the open index signature. Present ONLY when true;
|
|
11005
|
+
absence = "not detected", never "confirmed clean" (see PendingCheckpoint.hasBidiControls).
|
|
10732
11006
|
|
|
10733
11007
|
ParkedDecideAccepted:
|
|
10734
11008
|
type: object
|
|
@@ -10812,21 +11086,31 @@ components:
|
|
|
10812
11086
|
parentToolCallId: { type: string, description: 'The parent tool_use id VERBATIM (E2 domain, engine-minted) — [1832] P1-2, server >= 1.290 / engine 1.432. Additive / tolerate-absent.' }
|
|
10813
11087
|
|
|
10814
11088
|
FleetHookNotice:
|
|
11089
|
+
description: >
|
|
11090
|
+
Hook observability payload, TWO kinds (service fleet-bus.ts `HookNotice` minus the wire-stripped
|
|
11091
|
+
ownerScope/ownerSessionId — the payload view of FleetFrame_hook_notice; a discriminated union on
|
|
11092
|
+
`kind`, mirroring the SDK type verbatim). Both kinds are pure observe — never block, resume, or
|
|
11093
|
+
inject. Visibility is fail-CLOSED: a ?session= subscriber only receives notices provably owned by
|
|
11094
|
+
that session. `kind` is a CLOSED two-member set on the server (exhaustive-switch discipline) but
|
|
11095
|
+
OPEN ON READ: degrade an unknown future kind to a generic observability row, never crash.
|
|
11096
|
+
oneOf:
|
|
11097
|
+
- $ref: '#/components/schemas/FleetHookDecisionUnavailable'
|
|
11098
|
+
- $ref: '#/components/schemas/FleetHookNonBlockingFailure'
|
|
11099
|
+
discriminator:
|
|
11100
|
+
propertyName: kind
|
|
11101
|
+
mapping:
|
|
11102
|
+
hook_decision_unavailable: '#/components/schemas/FleetHookDecisionUnavailable'
|
|
11103
|
+
hook_non_blocking_failure: '#/components/schemas/FleetHookNonBlockingFailure'
|
|
11104
|
+
|
|
11105
|
+
FleetHookDecisionUnavailable:
|
|
10815
11106
|
type: object
|
|
10816
11107
|
description: >
|
|
10817
|
-
|
|
10818
|
-
|
|
10819
|
-
are "could not evaluate", NOT "evaluated to fail": render as "this cycle went unguarded, allowed
|
|
10820
|
-
through", never "the guard is broken". Pure observe — it does not block, resume, or inject.
|
|
10821
|
-
Visibility is fail-CLOSED: a ?session= subscriber only receives notices provably owned by that
|
|
10822
|
-
session.
|
|
11108
|
+
Kind 1 — a hook adjudication FAILED TO COMPLETE this cycle ("could not evaluate", NOT "evaluated to
|
|
11109
|
+
fail": render as "this cycle went unguarded, allowed through", never "the guard is broken").
|
|
10823
11110
|
required: [kind, event, reason]
|
|
10824
11111
|
additionalProperties: true
|
|
10825
11112
|
properties:
|
|
10826
|
-
kind:
|
|
10827
|
-
type: string
|
|
10828
|
-
enum: [hook_decision_unavailable]
|
|
10829
|
-
description: 'Only one kind today; an enum slot so the next observability frame kind needs no new frame arm.'
|
|
11113
|
+
kind: { type: string, enum: [hook_decision_unavailable] }
|
|
10830
11114
|
event: { type: string, description: 'Which hook event (Stop / PreToolUse / …) — defined by "a hook adjudication did not complete", not any single feature.' }
|
|
10831
11115
|
reason:
|
|
10832
11116
|
# 🔴 NO `enum` — same ruling as `FleetTaskRow.retiredBy` (codex R1-F3, family case): the description
|
|
@@ -10834,9 +11118,31 @@ components:
|
|
|
10834
11118
|
# so a closed enum here would make a strict generated client drop the whole hook_notice frame the day the
|
|
10835
11119
|
# server mints a fourth cause word — and that frame is the ONLY disclosure that a guard cycle went unwatched.
|
|
10836
11120
|
type: string
|
|
10837
|
-
description: 'Machine-branchable cause. CLOSED on the server side (fleet-bus.ts
|
|
11121
|
+
description: 'Machine-branchable cause. CLOSED on the server side (fleet-bus.ts) but OPEN ON READ — KNOWN WORDS TODAY: no_content | unparsed | skipped (named here rather than pinned as an `enum`, deliberately — see the comment above): branch known values, render anything else as the generic "could not evaluate".'
|
|
10838
11122
|
detail: { type: string, description: 'Redacted supplement (e.g. why skipped). Additive / tolerate-absent.' }
|
|
10839
11123
|
|
|
11124
|
+
FleetHookNonBlockingFailure:
|
|
11125
|
+
type: object
|
|
11126
|
+
description: >
|
|
11127
|
+
Kind 2 (server >= 7.48.0, #281 — A-075.17): the CONFIGURED HOOK ITSELF BROKE (non-blocking failure:
|
|
11128
|
+
exit nonzero-and-not-2 / timeout / spawn failure / bad JSON). Render "<hookName> hook error" + stderr
|
|
11129
|
+
(CC-parity attachment shape) — this one IS "this hook is broken", unlike kind 1.
|
|
11130
|
+
required: [kind, event, reason, hookName, entryType]
|
|
11131
|
+
additionalProperties: true
|
|
11132
|
+
properties:
|
|
11133
|
+
kind: { type: string, enum: [hook_non_blocking_failure] }
|
|
11134
|
+
event: { type: string, description: 'Which hook event (PreToolUse / Stop / …).' }
|
|
11135
|
+
reason:
|
|
11136
|
+
# 🔴 NO `enum` — same open-on-read ruling as kind 1 (SDK type is `... | (string & {})`).
|
|
11137
|
+
type: string
|
|
11138
|
+
description: 'Machine-branchable failure shape. CLOSED server-side, OPEN ON READ — KNOWN WORDS TODAY: exit_nonzero | timeout | spawn_failed | bad_json.'
|
|
11139
|
+
hookName: { type: string, description: 'Hook identity (statusMessage, else command/URL/prompt; redacted + bounded, http entries stripped of query/fragment). Always sent.' }
|
|
11140
|
+
entryType: { type: string, description: 'command | http | prompt | agent — without it, hookName''s nature is a guess. Closed server-side, open on read. Always sent.' }
|
|
11141
|
+
exitCode: { type: integer, description: 'Absent for timeout/spawn_failed (no exit code exists — the server never mints a legit-looking 0).' }
|
|
11142
|
+
toolName: { type: string, description: 'Present on tool events (PreToolUse/PostToolUse/PostToolUseFailure).' }
|
|
11143
|
+
stderr: { type: string, description: 'Redacted + truncated stderr digest (512-char cap incl. marker). Empty stderr => absent.' }
|
|
11144
|
+
detail: { type: string, description: 'Redacted supplement (e.g. where an exit-2 had no venue). Additive / tolerate-absent.' }
|
|
11145
|
+
|
|
10840
11146
|
BakeStatus:
|
|
10841
11147
|
# 新(census 批2 四段)——server `BakeStatus`(plugins/store-contracts.ts), the COARSE lifecycle
|
|
10842
11148
|
# bakeView/claimResponse/bakesCreate all key on.
|
|
@@ -11946,29 +12252,45 @@ components:
|
|
|
11946
12252
|
never hand it to another user.
|
|
11947
12253
|
expiresAtMs: { type: integer, description: 'Absolute server-clock expiry (the window is 10 minutes — one interaction, not a session).' }
|
|
11948
12254
|
|
|
12255
|
+
CcImportRedeemedMember:
|
|
12256
|
+
type: object
|
|
12257
|
+
description: >
|
|
12258
|
+
One member of the redeem 200 (core `RedeemedBatchMember`, the 200-REACHABLE arm verbatim — core d.ts
|
|
12259
|
+
permission-rule-consent.d.ts). The union's third arm `{status:"refused", reason}` is STRUCTURALLY
|
|
12260
|
+
UNREACHABLE on this route's 200: any refused member makes the server treat the whole redeem as
|
|
12261
|
+
indeterminate, release the claim and answer 503 `state.rule_import_retry` (server rules-consent.ts) —
|
|
12262
|
+
so this schema honestly describes the two-value `status` only.
|
|
12263
|
+
additionalProperties: false
|
|
12264
|
+
required: [candidateIndex, rule, scope, status, alreadyRedeemed, dot]
|
|
12265
|
+
properties:
|
|
12266
|
+
candidateIndex: { type: integer, description: 'Index into the prepare preview''s candidate set (candidate space).' }
|
|
12267
|
+
rule: { type: string, description: 'Canonical rule text.' }
|
|
12268
|
+
scope: { $ref: '#/components/schemas/RuleScope' }
|
|
12269
|
+
status:
|
|
12270
|
+
type: string
|
|
12271
|
+
enum: [persisted, deduped]
|
|
12272
|
+
description: '`persisted` = landed this redeem; `deduped` = an equal rule was already in the store (the consent took effect — not a failure).'
|
|
12273
|
+
alreadyRedeemed: { type: boolean, description: 'true = this outcome was REPLAYED verbatim from the ticket row (lost-response retry; idempotency evidence — zero double-mint).' }
|
|
12274
|
+
dot: { $ref: '#/components/schemas/RuleDot' }
|
|
12275
|
+
|
|
11949
12276
|
CcImportResult:
|
|
11950
12277
|
type: object
|
|
11951
12278
|
description: >
|
|
11952
|
-
What the import ACTUALLY did (
|
|
11953
|
-
|
|
11954
|
-
the two.
|
|
12279
|
+
What the import ACTUALLY did (server >= 7.46.0, BREAKING #2 there / core 5.58.0 redeemRuleBatch
|
|
12280
|
+
members passthrough) — a different moment and a different contract from the preview, because dedup,
|
|
12281
|
+
concurrency and redemption-time validation can each move an entry between the two.
|
|
11955
12282
|
|
|
11956
|
-
|
|
11957
|
-
|
|
11958
|
-
|
|
12283
|
+
🔴 SHAPE CHANGE (A-075.13): the old three-bucket form `{persisted[], deduped[], skippedAtRedeem[],
|
|
12284
|
+
rev}` left the wire in server 7.46.0 — a consumer reading `result.persisted.length` gets undefined.
|
|
12285
|
+
This schema describes the real wire since then; the SDK type changed with it (a staleness fix, not a
|
|
12286
|
+
behavior change).
|
|
11959
12287
|
additionalProperties: false
|
|
11960
|
-
required: [
|
|
12288
|
+
required: [members, rev]
|
|
11961
12289
|
properties:
|
|
11962
|
-
|
|
11963
|
-
type: array
|
|
11964
|
-
items: { $ref: '#/components/schemas/RuleCandidate' }
|
|
11965
|
-
deduped:
|
|
12290
|
+
members:
|
|
11966
12291
|
type: array
|
|
11967
|
-
items: { $ref: '#/components/schemas/
|
|
11968
|
-
description: '
|
|
11969
|
-
skippedAtRedeem:
|
|
11970
|
-
type: array
|
|
11971
|
-
items: { $ref: '#/components/schemas/CcImportSkippedRule' }
|
|
12292
|
+
items: { $ref: '#/components/schemas/CcImportRedeemedMember' }
|
|
12293
|
+
description: 'Per-candidate outcome (discriminate on `status`; refused never rides a 200 — see CcImportRedeemedMember).'
|
|
11972
12294
|
rev: { type: integer, description: 'The rule store''s monotonic revision after the batch.' }
|
|
11973
12295
|
|
|
11974
12296
|
CcImportRedeemResult:
|