@sema-agent/sdk 9.8.1 → 9.10.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 +64 -0
- package/dist/client.d.ts +4 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +4 -0
- package/dist/client.js.map +1 -1
- package/dist/errors.d.ts +6 -2
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +25 -5
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/resources/memory.d.ts +151 -4
- package/dist/resources/memory.d.ts.map +1 -1
- package/dist/resources/memory.js +177 -0
- package/dist/resources/memory.js.map +1 -1
- package/dist/types.d.ts +357 -0
- package/dist/types.d.ts.map +1 -1
- package/openapi.yaml +814 -0
- package/package.json +1 -1
package/dist/types.d.ts
CHANGED
|
@@ -674,6 +674,24 @@ export interface TaskRequest {
|
|
|
674
674
|
* narrows honestly. Tighten-only: core's inheritance invariant unions it into EVERY child spawn path.
|
|
675
675
|
* Malformed (non-array / empty-string items) → 400 fail-loud at submit. */
|
|
676
676
|
excludeTools?: string[];
|
|
677
|
+
/** server ≥7.90.0 (core 7.8.0 design/388 的**请求面**;契约 G.9b / 判据 G-40): **整只工具面卸载** ——
|
|
678
|
+
* 这一 run 里调用方工具、脚手架、手(Bash/Edit/Write…)、MCP、A2A、skills 一个都不挂,模型没有任何
|
|
679
|
+
* 工具可调,终局必然是**纯文本**。wire 上看得见的样子:`wiring_manifest.tools` 的 `count === 0` 且
|
|
680
|
+
* `entries` 为空(披露**一次**,一条 leg 一帧),整条流上零 `tool_start` / `tool_end` / `tool_disclosure`。
|
|
681
|
+
*
|
|
682
|
+
* 🔴 **与 {@link excludeTools} 是两种语义,刻意不折叠**:`"*"` 是一个**合法的调用方工具名**,所以
|
|
683
|
+
* 「卸全部」不能写成 `excludeTools:["*"]`(那会把「卸全部」与「卸一只叫 `*` 的工具」塌成一件事)。
|
|
684
|
+
* 两键**同带各自生效**,不冲突、不拒(全卸之后名单里那几只本来也不在)。
|
|
685
|
+
* 🔴 **类型只收字面 `true`**:server 只把 literal `true` 写上 `TaskSpec` —— 挂一个 `false` 上去等于
|
|
686
|
+
* 替引擎重申一次它自己的缺省,而那个缺省的属主是引擎。要动态开关就写
|
|
687
|
+
* `...(off ? { excludeAllTools: true } : {})`,别送 `false`。
|
|
688
|
+
* 🔴 **探测靠键闭集,没有能力位**:没接线的 server(≤7.89.x)把它当**未知顶层键**,400
|
|
689
|
+
* `request.body_shape` 并在 `unknownKeys` 里逐字列名 ⇒ trial-by-400 就是探测路(一个键一条探测路,
|
|
690
|
+
* 刻意不长第二条)。坏形(非 boolean)在同步提交腿是 400 `request.field_invalid`;**耐久 resume 腿
|
|
691
|
+
* 不拒**(重放存量 body,4xx 会砖死已 park 的任务)⇒ 在那条腿上降级为「键缺席」。
|
|
692
|
+
* ⚠️ **辖域**:A2A 入站面(`message/send`)**不承载本键** —— 那条腿的提交体是服务端从协议消息重建的
|
|
693
|
+
* 闭四字段,消息里放这个键**无效且不报错**,名册照旧。A2A peer 要零工具面就走 skill 路由。 */
|
|
694
|
+
excludeAllTools?: true;
|
|
677
695
|
/** server ≥1.221 (core 1.314): DEFERRED DISCLOSURE list — the named MOUNTED tools (built-ins included)
|
|
678
696
|
* ride the wire as a placeholder (schema bytes out of the cache prefix) and materialize via ToolSearch
|
|
679
697
|
* on demand. The carrier for the shell's "Workflow on by default but not exposed" posture. Same
|
|
@@ -3886,6 +3904,9 @@ export interface SessionSummary {
|
|
|
3886
3904
|
* 真实带这个字段——会话自动摘要(session-titler.ts,首次提交后台起一次廉价模型调用生成,IS NULL 门控幂等,
|
|
3887
3905
|
* SESSION_AUTO_TITLE 默认开)。null = 未生成(自动摘要关闭 / 该 session 首次提交后台任务还没跑完)。 */
|
|
3888
3906
|
title: string | null;
|
|
3907
|
+
/** server ≥7.91.0(additive,老 server 缺席):会话活动词,由最近 run 的状态经 server 与 peer 目录**同一张**映射表派生
|
|
3908
|
+
* (running → `active`;suspended / needs_review → `blocked`;无非终态 run → `idle`)。壳的会话列表 / peer 行 tempo 同源。 */
|
|
3909
|
+
tempo?: "active" | "idle" | "blocked";
|
|
3889
3910
|
[k: string]: unknown;
|
|
3890
3911
|
}
|
|
3891
3912
|
/** `GET /v1/sessions` 的分页信封(service handleSessionList,keyset)。`nextCursor` 缺 = 末页。 */
|
|
@@ -4898,6 +4919,342 @@ export interface MemoryCaptureOptOutResult {
|
|
|
4898
4919
|
sessionId: string;
|
|
4899
4920
|
outcome: "created" | "existed";
|
|
4900
4921
|
}
|
|
4922
|
+
/** core 的 `transfers.jsonl` 托管事件行 —— **OPEN 判别形**:三个基键是契约,其余是变体载荷。
|
|
4923
|
+
* 🔴 **消费义务**:容忍未知 `channel`(报告 / 跳过 / 原样显示),**绝不**写一个会抛的穷举 `switch` ——
|
|
4924
|
+
* 通道词表由写这条链的那个二进制定,一条由更新的引擎写下的链照样要在这里读得出来。 */
|
|
4925
|
+
export interface MemoryTransferEvidence {
|
|
4926
|
+
/** 事件唯一 id(证据链的追加幂等键)。 */
|
|
4927
|
+
ev: string;
|
|
4928
|
+
/** 事件种类 —— **故意开集**(见顶注的消费义务)。 */
|
|
4929
|
+
channel: string;
|
|
4930
|
+
/** 事件时刻(ms epoch)。 */
|
|
4931
|
+
at: number;
|
|
4932
|
+
[k: string]: unknown;
|
|
4933
|
+
}
|
|
4934
|
+
/** 已提交账的**绑定半场**(core `CommittedBinding` 的 tagged 形)。`"unbound"` 是一个**合法的过渡态**
|
|
4935
|
+
* (v1→v2 迁移行推导不出投影坐标),不是一次拒绝。 */
|
|
4936
|
+
export type MemoryCommittedBinding = {
|
|
4937
|
+
state: "bound";
|
|
4938
|
+
scope: string;
|
|
4939
|
+
slug: string;
|
|
4940
|
+
at?: number;
|
|
4941
|
+
prev?: {
|
|
4942
|
+
scope: string;
|
|
4943
|
+
slug: string;
|
|
4944
|
+
at: number;
|
|
4945
|
+
};
|
|
4946
|
+
} | {
|
|
4947
|
+
state: "unbound";
|
|
4948
|
+
};
|
|
4949
|
+
/**
|
|
4950
|
+
* 一条 entry 的绑定状态,**四形不折叠**(契约 §9.2)。
|
|
4951
|
+
* 🔴 `{state:"unknown"}`(这个后端没有审计快照面 ⇒ **判不了**)**绝不**折叠成 `{state:"absent"}`
|
|
4952
|
+
* (**确实不存在**):两句话的合规结论相反。
|
|
4953
|
+
*/
|
|
4954
|
+
export type MemoryProvenanceBinding = MemoryCommittedBinding | {
|
|
4955
|
+
state: "absent";
|
|
4956
|
+
} | {
|
|
4957
|
+
state: "unknown";
|
|
4958
|
+
reason: "audit-snapshot-capability-absent";
|
|
4959
|
+
};
|
|
4960
|
+
/**
|
|
4961
|
+
* `GET /v1/memory/entries/{entryId}/provenance` 的 200 体 —— core `EntryProvenanceAccount` **本身**
|
|
4962
|
+
* (server 不包一层、不投影、不补键;契约 §9.2)。
|
|
4963
|
+
*
|
|
4964
|
+
* 🔴 **`binding` 与 `custody` 是判别式,消费方必须按判别位分支**;`contentState` 与 `custody.state` 同族
|
|
4965
|
+
* 三值(`capability-absent` = 面缺席、`unavailable`/`damaged` = 面在但答不全),core 从不自造事件行。
|
|
4966
|
+
* 🔴 `v` 是版本信封:读到 `v > 1` 必须**拒绝**,绝不重新解释 —— 本型只描述 `v: 1` 这一代的字段律,
|
|
4967
|
+
* 所以判别位写在运行时(读 `v` 再用),不是靠类型帮你挡住。
|
|
4968
|
+
* 失败面:控制面账本损坏 ⇒ 500 `internal.memory_control_plane_corrupt`(fail-closed:完整性未知时 core
|
|
4969
|
+
* 宁可不答,也不在说不清的账上拼一个答案),core 的诊断文案原样透传。
|
|
4970
|
+
*/
|
|
4971
|
+
export interface EntryProvenanceAccount {
|
|
4972
|
+
v: 1;
|
|
4973
|
+
id: string;
|
|
4974
|
+
binding: MemoryProvenanceBinding;
|
|
4975
|
+
/** 已提交 lineage 的 by-entry 投影,每行与它那条会话的污染记录 join。**未结算的 lineage 行不是贡献**
|
|
4976
|
+
* —— 它们以 `exclusion.code: "lineage_pending"` 露面。 */
|
|
4977
|
+
contributors: Array<{
|
|
4978
|
+
sessionId: string;
|
|
4979
|
+
lastRev: string;
|
|
4980
|
+
lastAt?: number;
|
|
4981
|
+
polluted?: {
|
|
4982
|
+
at: number;
|
|
4983
|
+
reason: string;
|
|
4984
|
+
};
|
|
4985
|
+
}>;
|
|
4986
|
+
/** 模型可见读面对这条 id 的**扣留**状态(有才在场)。 */
|
|
4987
|
+
exclusion?: {
|
|
4988
|
+
code: "challenged" | "lineage_pending";
|
|
4989
|
+
generation?: number;
|
|
4990
|
+
at?: number;
|
|
4991
|
+
};
|
|
4992
|
+
/** 内容半场,与 {@link binding} **按构造联动**:`absent` ⇔ binding `absent`;`capability-absent` ⇔
|
|
4993
|
+
* binding `unknown`;有行时是 `present`(只有它在场 {@link ingest} 才骑得上)或 `unavailable`。 */
|
|
4994
|
+
contentState: "present" | "unavailable" | "capability-absent" | "absent";
|
|
4995
|
+
/** 已提交内容的 frontmatter 携带的 repo 文件 ingest 出处(含洗不掉的 `trust` 标)。 */
|
|
4996
|
+
ingest?: {
|
|
4997
|
+
kind: "repo_file";
|
|
4998
|
+
path: string;
|
|
4999
|
+
contentHash: string;
|
|
5000
|
+
ingestedAt: number;
|
|
5001
|
+
trust?: "untrusted";
|
|
5002
|
+
};
|
|
5003
|
+
/** 按 id 的证据链读数。`damaged` = 链的完整性被弹劾、但仍有一份说得通的读法(断尾 / 证据缺失 /
|
|
5004
|
+
* ev 身份矛盾,`reason` 在已知时带出);`capability-absent` = 这个后端没有托管面(事件必为空数组 ——
|
|
5005
|
+
* core 从不伪造)。 */
|
|
5006
|
+
custody: {
|
|
5007
|
+
state: "complete" | "damaged" | "capability-absent";
|
|
5008
|
+
events: MemoryTransferEvidence[];
|
|
5009
|
+
reason?: string;
|
|
5010
|
+
};
|
|
5011
|
+
[k: string]: unknown;
|
|
5012
|
+
}
|
|
5013
|
+
/**
|
|
5014
|
+
* `POST /v1/memory/erase` 的请求体(契约 §9.3)。
|
|
5015
|
+
*
|
|
5016
|
+
* 🔴 **`requestId` 是这次抹除的幂等身份,server 与引擎都从不替你铸一个** —— 重试**必须**带**同一个**
|
|
5017
|
+
* id(一个丢失的 ack 不得开出第二次真删)。缺席 / 空串 ⇒ 400 `request.request_id_required`(与
|
|
5018
|
+
* `request.body_shape` 刻意分家:两句话的运维动作不同)。
|
|
5019
|
+
* ⚠️ 与 {@link MemoryOriginClearRequest.requestId} **同名不同义**,别把两边的重试纪律互相套用。
|
|
5020
|
+
*/
|
|
5021
|
+
export interface MemoryErasureRequest {
|
|
5022
|
+
requestId: string;
|
|
5023
|
+
/**
|
|
5024
|
+
* 选择子 —— 文档化的三形是 `{ids: string[]}` / `{scope: string}` / `{sessionId: string}`,**恰好一个**。
|
|
5025
|
+
*
|
|
5026
|
+
* 🔴 类型故意写成开放 record 而**不是**三形联合:这条规则的**单一属主是 core**
|
|
5027
|
+
* (`erasureRequestInvalid`),server 自己也只验顶层结构(zod 的 `z.record(z.string(), z.unknown())`)。
|
|
5028
|
+
* 在 SDK 里再写一遍字段表就是第二真源 —— 而且 TS 的联合表达不出「恰好一个」,却能把 core 将来长出的
|
|
5029
|
+
* 第四形提前拒掉。`{ids:[…], scope:…}` 这种**形对义错**的请求拿到的是 400 `config.memory_erasure_request`。
|
|
5030
|
+
*/
|
|
5031
|
+
select: Record<string, unknown>;
|
|
5032
|
+
/**
|
|
5033
|
+
* **证据面缺席时的降级授权**,一次**人的**签字。
|
|
5034
|
+
* 🔴 缺席时 SDK **不会替你补一个 `false`**(server 侧同律:递交给引擎的就是调用方发的那个体)——
|
|
5035
|
+
* 中间层替调用方勾上就是替他签字。
|
|
5036
|
+
*/
|
|
5037
|
+
allowUnevidenced?: boolean;
|
|
5038
|
+
}
|
|
5039
|
+
/** 一条被抹除行的坐标(core `ErasedBinding`:快照的 tagged 绑定律,不带账本 trace 的额外键)。 */
|
|
5040
|
+
export type MemoryErasedBinding = {
|
|
5041
|
+
state: "bound";
|
|
5042
|
+
scope: string;
|
|
5043
|
+
slug: string;
|
|
5044
|
+
} | {
|
|
5045
|
+
state: "unbound";
|
|
5046
|
+
};
|
|
5047
|
+
/**
|
|
5048
|
+
* `POST /v1/memory/erase` 的 200 体 —— core `MemoryErasureAttestation` **本身**(契约 §9.3)。
|
|
5049
|
+
*
|
|
5050
|
+
* 🔴 **幂等有两条腿,契约不同 —— 先读 {@link evidenceCapability} 再决定能不能重试**:
|
|
5051
|
+
* · `"journal"`(**证据腿**):`requestId` 是幂等身份,重发同一个 id 会**读回**托管链上那条 anchor
|
|
5052
|
+
* pinned 的 id 集、绝不重新解析;换了选择子还用同一个 id ⇒ 409 `memory.erasure_selector_mismatch`;
|
|
5053
|
+
* · `"none"`(**降级腿**):core 的原话逐字是 *"same requestId = a NEW request (re-resolved — replay
|
|
5054
|
+
* convergence is not promised)"* —— **重发就是第二次真删**。这条腿上 {@link erasedPreviously} 与
|
|
5055
|
+
* `erased[].evidenceEv` 永不出现,每一行 {@link notFound} 都带 `historyUnknown`(「从没存在过」与
|
|
5056
|
+
* 「无证据地被删过」不可判别)。
|
|
5057
|
+
* 🔴 **不要给这一口配自动重试策略**:`"none"` 时任何重发都必须是人做的决定。
|
|
5058
|
+
*/
|
|
5059
|
+
export interface MemoryErasureAttestation {
|
|
5060
|
+
/** 版本信封 —— 读到 `v > 1` 必须拒绝,绝不重新解释。 */
|
|
5061
|
+
v: 1;
|
|
5062
|
+
requestId: string;
|
|
5063
|
+
at: number;
|
|
5064
|
+
/** `"complete"` ⇔ 冲突为空 ∧ 每个 pinned id 都落在 erased ∪ erasedPreviously ∪(`custodyState`
|
|
5065
|
+
* 为 `complete` 的 notFound)里;其余一律 `"partial"`(重放会把它收敛)。 */
|
|
5066
|
+
status: "complete" | "partial";
|
|
5067
|
+
evidenceCapability: "journal" | "none";
|
|
5068
|
+
/** 证据链在组装时刻的完整性。`"damaged"` ⇒ 每一行 notFound 都带 `historyUnknown` 且永不产出
|
|
5069
|
+
* `erasedPreviously`(「没有行」这件事无法在一条有已知缺口的链上做历史判定)。 */
|
|
5070
|
+
custodyState: "complete" | "damaged" | "capability-absent";
|
|
5071
|
+
/** 选择子,原样回显(形与请求体的同一条:判决属主是 core)。 */
|
|
5072
|
+
select: Record<string, unknown>;
|
|
5073
|
+
/** 选择子 canonical JSON 的 sha256 hex。 */
|
|
5074
|
+
selectHash: string;
|
|
5075
|
+
/** pinned id 集(= anchor 行的 `ids`;重放读回它,绝不重新解析)。 */
|
|
5076
|
+
resolvedIds: string[];
|
|
5077
|
+
erased: Array<{
|
|
5078
|
+
id: string;
|
|
5079
|
+
rev: string;
|
|
5080
|
+
binding: MemoryErasedBinding;
|
|
5081
|
+
/** 删除证据行的 `ev` —— `"none"` 腿上缺席。 */
|
|
5082
|
+
evidenceEv?: string;
|
|
5083
|
+
/** 本事务**物理删掉**的、经普查确认的投影文件数(清扫臂可以 >1)。 */
|
|
5084
|
+
projectionsRemoved: number;
|
|
5085
|
+
/** 贡献会话(`"none"` 腿答 `[]`)。崩溃后的重放带的是链上那一份 —— **诚实降级,绝不伪造重建**。 */
|
|
5086
|
+
sessions: string[];
|
|
5087
|
+
}>;
|
|
5088
|
+
/** 判决时刻没有行、且不能在**这次请求**名下主张为已抹除。涵盖「从没存在过 / 自然删除 / 被另一次请求
|
|
5089
|
+
* 删掉」—— 链分得出来,收执不假装分得出来。`historyUnknown` ⇔ `custodyState !== "complete"`。 */
|
|
5090
|
+
notFound: Array<{
|
|
5091
|
+
id: string;
|
|
5092
|
+
historyUnknown?: true;
|
|
5093
|
+
}>;
|
|
5094
|
+
/** 链读出来的行:带**本** requestId 的、origin 缺席的删除行。非空才在场;`"none"` 腿与受损链上永不产出。 */
|
|
5095
|
+
erasedPreviously?: Array<{
|
|
5096
|
+
id: string;
|
|
5097
|
+
ev: string;
|
|
5098
|
+
at: number;
|
|
5099
|
+
from?: {
|
|
5100
|
+
scope: string;
|
|
5101
|
+
slug: string;
|
|
5102
|
+
};
|
|
5103
|
+
}>;
|
|
5104
|
+
/** 按 id 的**计划期**故障(锁内的 io/plan 错;单锁跨度里没有 CAS 输家)。非致命,重放会收敛。 */
|
|
5105
|
+
conflicts: Array<{
|
|
5106
|
+
id: string;
|
|
5107
|
+
reason: string;
|
|
5108
|
+
}>;
|
|
5109
|
+
residuals: {
|
|
5110
|
+
/** frontmatter id 落在 pinned 集里的隔离区文件(**保留不删**:收执负责枚举,清理是另一个显式动作)。 */
|
|
5111
|
+
quarantineHits: string[];
|
|
5112
|
+
/** 归因不了的隔离区文件(碎片 / 非条目形)—— 这次枚举**诚实的上界**。 */
|
|
5113
|
+
quarantineOpaque: number;
|
|
5114
|
+
/** 抹除时的索引清扫读不到 / 写不动的派生 `MEMORY.md`(可能仍挂着被删条目的行)。非空才在场。 */
|
|
5115
|
+
indexUncleared?: string[];
|
|
5116
|
+
/** **自陈的传播边界,恒在场**:删除是**本店**的事实;远端 peer 的收敛是同步部署自己要证的另一半。 */
|
|
5117
|
+
propagation: "local-store-only";
|
|
5118
|
+
};
|
|
5119
|
+
[k: string]: unknown;
|
|
5120
|
+
}
|
|
5121
|
+
/** 外源标记的成因词表(core `MemoryOriginCause`)。🔴 **缺席合法且绝不猜**:标记铸于本词表存在之前的
|
|
5122
|
+
* 条目就是诚实地没有 cause。 */
|
|
5123
|
+
export type MemoryOriginCause = "observed" | "derived" | "static" | "unattributed";
|
|
5124
|
+
/**
|
|
5125
|
+
* 一条 entry 的**外源标记**:这条记忆的内容来自模型看到的**外部材料**(网页、第三方文档、别人的仓),
|
|
5126
|
+
* 而不是这次会话里的一手事实。语义不是「有毒」而是「**用前先核**」—— 它跟着条目一路走到每一次模型挂载。
|
|
5127
|
+
*
|
|
5128
|
+
* 🔴 **三键是契约,但这只对象是开集**,而且三条读面给的**保证强度不同**,别按最强的那条写围栏:
|
|
5129
|
+
* · {@link MemoryOriginExternalEntry.origin} —— core 的窄重建(`committedOriginOf` 逐字只铸 taint/cause?/at);
|
|
5130
|
+
* · {@link MemoryOriginClearanceRow.origin} —— server 的深投影(三键之外的成员**剥值留名**到 `originUnknownKeys`);
|
|
5131
|
+
* · {@link MemoryOriginClearReceipt.origin} —— **原样转发**。新开行时它是上面那个窄重建,但**恢复腿**
|
|
5132
|
+
* 回的是账本**原始对象**(core `clearEntryOrigin` 读到 pending 行即 `origin: row.origin`),于是版本
|
|
5133
|
+
* 偏斜 / core 日后加键 / core 明写的手工恢复都可能让它多带成员 —— 那是一次**已经成功提交**的清标,
|
|
5134
|
+
* 消费端不许判它违约。
|
|
5135
|
+
*/
|
|
5136
|
+
export interface MemoryEntryOriginMark {
|
|
5137
|
+
taint: "external";
|
|
5138
|
+
cause?: MemoryOriginCause;
|
|
5139
|
+
at: number;
|
|
5140
|
+
[k: string]: unknown;
|
|
5141
|
+
}
|
|
5142
|
+
/** `GET /v1/memory/origin/external` 的一行:标记 + **完整出处账**(契约 §11.2)。 */
|
|
5143
|
+
export interface MemoryOriginExternalEntry {
|
|
5144
|
+
id: string;
|
|
5145
|
+
slug: string;
|
|
5146
|
+
scope: string;
|
|
5147
|
+
origin: MemoryEntryOriginMark;
|
|
5148
|
+
/** **就是** {@link EntryProvenanceAccount} 本身(同一条判别式,同一条透传纪律)。
|
|
5149
|
+
* 一条被**挑战**的标记条目照样列在这里 —— 排除态骑在这份账的 `exclusion` 里,人要先看见才能裁。 */
|
|
5150
|
+
provenance: EntryProvenanceAccount;
|
|
5151
|
+
[k: string]: unknown;
|
|
5152
|
+
}
|
|
5153
|
+
/**
|
|
5154
|
+
* `GET /v1/memory/origin/external?scopes=…` 的 200 体(契约 §11.2)。
|
|
5155
|
+
*
|
|
5156
|
+
* 🔴 **答案只覆盖你点名的那些 scope,空结果绝不读作「本店干净」。** server 这一代**没有 scope 枚举
|
|
5157
|
+
* 读面**,所以 scope 名由调用方给;不完备是**静默**的(空数组与「这些 scope 干净」在 wire 上同形),
|
|
5158
|
+
* 这句话就是它唯一的告示。审计脚本必须自己保证名单完备(scope 键与 `GET /v1/memory/export?scope=`
|
|
5159
|
+
* 用的是同一套)。
|
|
5160
|
+
* {@link scopes} 是**这次真正被审的那一份**(服务端归一化之后:逐段去空白、去空段、保序去重)——
|
|
5161
|
+
* 回显它是为了让**覆盖面可观察**,消费端不该靠自己记得发了什么去反推答案的边界。
|
|
5162
|
+
*/
|
|
5163
|
+
export interface MemoryOriginExternalResult {
|
|
5164
|
+
scopes: string[];
|
|
5165
|
+
entries: MemoryOriginExternalEntry[];
|
|
5166
|
+
[k: string]: unknown;
|
|
5167
|
+
}
|
|
5168
|
+
/** 一条清标**终态事件**(who / when / to / detail 四件正是「事件」这个概念的全部)。
|
|
5169
|
+
* `detail` 缺席时键**不出现** —— 审计面上「没写细节」与「细节是空」不同义。 */
|
|
5170
|
+
export interface MemoryOriginClearanceEvent {
|
|
5171
|
+
eventId: string;
|
|
5172
|
+
at: number;
|
|
5173
|
+
to: "done" | "failed";
|
|
5174
|
+
/** **这条事件**的解决者(正常路径上是开行者;崩溃路径上是后来的恢复者)。 */
|
|
5175
|
+
requestId: string;
|
|
5176
|
+
detail?: string;
|
|
5177
|
+
[k: string]: unknown;
|
|
5178
|
+
}
|
|
5179
|
+
/**
|
|
5180
|
+
* 一条清标行的 wire 形 —— core `OriginClearanceRow` 的**显式白名单投影**(契约 §11.3)。
|
|
5181
|
+
*
|
|
5182
|
+
* 🔴 **`entryText` 恒不上 wire,但它的在场用 {@link custodyBytes} 如实披露。** core 的行上有一个
|
|
5183
|
+
* `entryText` = 被清标条目的**完整正文**:它是**崩溃恢复席**(墓碑批与重录批之间崩了,这一行是那条
|
|
5184
|
+
* 记忆世界上唯一的一份),而恢复的手段是**再调一次 `originClear`**(引擎自己从行里重放),不是让人
|
|
5185
|
+
* 把字节读出来贴回去 —— 把整条记忆的正文放上一个审计**列表**面,等于给每一次「看看清标记录」都附赠
|
|
5186
|
+
* 一份全文导出。⇒ 剥掉。但**剥了要说**:`custodyBytes > 0` 的 `pending` 行 = 恢复席里还揣着一条记忆,
|
|
5187
|
+
* **要人处置**。
|
|
5188
|
+
* 🔴 `entryText` **不在本型的具名键集上** —— 这是 SDK 侧「不承诺自己没见过的东西」的机器面。它与
|
|
5189
|
+
* **索引签名在场**(容得下未知键)不矛盾:前者说「我不替 server 承诺发什么」,后者说「生产方先走一步
|
|
5190
|
+
* 时我不判它违约」。全文见本族顶注的「响应体一律宽进」段。
|
|
5191
|
+
*/
|
|
5192
|
+
export interface MemoryOriginClearanceRow {
|
|
5193
|
+
clearanceId: string;
|
|
5194
|
+
/** 被清标的条目。清标**保留同一个 id**,所以这个键把清标与条目的一生 join 起来。 */
|
|
5195
|
+
entryId: string;
|
|
5196
|
+
scope: string;
|
|
5197
|
+
slug: string;
|
|
5198
|
+
/** 判决所锚的已提交 rev(墓碑的 CAS 锚)。 */
|
|
5199
|
+
baseRev: string;
|
|
5200
|
+
/** **被清掉的那个标记**,深投影成文档化的三键(审计:宿主到底替什么担了保)。 */
|
|
5201
|
+
origin: MemoryEntryOriginMark;
|
|
5202
|
+
/** 磁盘上那行的 `origin` 携带了三键之外的成员时,**只列它们的键名**(值永不上 wire);正常行没有这个键。 */
|
|
5203
|
+
originUnknownKeys?: string[];
|
|
5204
|
+
/** **谁**清的 —— 强制审计归属,core 从不替调用方铸。
|
|
5205
|
+
* 🔴 它是**自称**的、不是已验证的:任一够得着这口的 operator 都能把一次不可逆的清标记到别人名下。
|
|
5206
|
+
* 部署侧的对照物在 server 日志(`memory_origin_cleared`,同时带**已验证的** principal 与调用方自称的
|
|
5207
|
+
* requestId,按 `clearanceId` 可 join)—— **合规结论不要只读账本**。 */
|
|
5208
|
+
requestId: string;
|
|
5209
|
+
/** **为什么** —— 宿主陈述的理由,core 从不填默认值(自由文本)。 */
|
|
5210
|
+
reason: string;
|
|
5211
|
+
/** 开行时刻。 */
|
|
5212
|
+
at: number;
|
|
5213
|
+
status: "pending" | "done" | "failed";
|
|
5214
|
+
/** 本次清标的墓碑提交时刻(**在场才发**);缺席的行在恢复腿上会保守拒。 */
|
|
5215
|
+
tombstonedAt?: number;
|
|
5216
|
+
events: MemoryOriginClearanceEvent[];
|
|
5217
|
+
/** **托管 UTF-8 字节数**(不是 JS 字符串长度)。`0` = 这行没揣着字节;`>0` = 恢复席里还有一条记忆的正文。 */
|
|
5218
|
+
custodyBytes: number;
|
|
5219
|
+
[k: string]: unknown;
|
|
5220
|
+
}
|
|
5221
|
+
/** `GET /v1/memory/origin/clearances` 的 200 体(契约 §11.3)。 */
|
|
5222
|
+
export interface MemoryOriginClearancesResult {
|
|
5223
|
+
clearances: MemoryOriginClearanceRow[];
|
|
5224
|
+
[k: string]: unknown;
|
|
5225
|
+
}
|
|
5226
|
+
/**
|
|
5227
|
+
* `POST /v1/memory/origin/entries/{entryId}/clear` 的请求体(契约 §11.4)。
|
|
5228
|
+
*
|
|
5229
|
+
* 🔴 **`requestId` 是审计归属,不是幂等键。** 与 {@link MemoryErasureRequest.requestId} **语义不同**:
|
|
5230
|
+
* 那边是幂等身份(重试必须复用同一个 id);这边是「**谁**清的标」,它会原样落进审计行与终态事件。
|
|
5231
|
+
* 恢复一条 pending 行时传一个**新的** requestId 是合法且常见的(后来的恢复者就是另一个人)。
|
|
5232
|
+
* 缺席 / 空串 ⇒ 400 `request.request_id_required`。**不设长度上限**(体积由请求体上限兜)。
|
|
5233
|
+
* 🔴 `reason` 只验**形**(必须是串);**空串合不合法是引擎的判决** ⇒ 422 `memory.origin_clear_invalid`。
|
|
5234
|
+
* SDK 在这一层不加 min(1):那就是第二真源,而且会把一个 core 明确铸了码的拒因永久挡在 wire 之外。
|
|
5235
|
+
*/
|
|
5236
|
+
export interface MemoryOriginClearRequest {
|
|
5237
|
+
requestId: string;
|
|
5238
|
+
reason: string;
|
|
5239
|
+
}
|
|
5240
|
+
/**
|
|
5241
|
+
* `POST /v1/memory/origin/entries/{entryId}/clear` 的 200 收执(契约 §11.4)。
|
|
5242
|
+
*
|
|
5243
|
+
* 🔴 **收执里没有「这是一次恢复」的判别位。** 引擎读到同一条 entry 上的 pending 行就**恢复它**,
|
|
5244
|
+
* 你写的 `reason` 一个字都不看 —— 账上留下的仍是**开行者**的理由与 requestId,只有终态**事件**里那条
|
|
5245
|
+
* requestId 是你的。于是按 409 `memory.origin_clear_pending` 的指示重发、拿到 200 的那个人,完成的
|
|
5246
|
+
* 可能是别人的行。⇒ **拿到 200 之后回读 `originClearances()` 对一次 `reason` / `requestId`**,别把 200
|
|
5247
|
+
* 读成「我的理由已入账」;{@link clearanceId} 就是那一行的键。
|
|
5248
|
+
*/
|
|
5249
|
+
export interface MemoryOriginClearReceipt {
|
|
5250
|
+
entryId: string;
|
|
5251
|
+
clearanceId: string;
|
|
5252
|
+
/** 刚被清掉的那个标记,逐字。 */
|
|
5253
|
+
origin: MemoryEntryOriginMark;
|
|
5254
|
+
/** 重录后条目的落点。 */
|
|
5255
|
+
landedSlug: string;
|
|
5256
|
+
[k: string]: unknown;
|
|
5257
|
+
}
|
|
4901
5258
|
/** `POST /v1/approvals/{sessionId}/decide` 的 200 体(spec `ApprovalDecisionResult` 的型面镜像;此前 SDK 只给 `unknown`)。
|
|
4902
5259
|
* 三种真实形共用这只信封(spec 长注有全文):**受理形**(server ≥7.37 durable 部署默认)`{taskId, sessionId,
|
|
4903
5260
|
* status:"resuming", bindingEnforced:true}` —— `errorCode`/`errorMessage`/`retriable` **从不**上这形,失败落 run 行与
|