@sema-agent/server 7.128.0 → 7.129.1
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/MIGRATION.md +140 -0
- package/USAGE.md +114 -18
- package/dist/approval-card.d.ts +53 -26
- package/dist/approval-card.js +40 -11
- package/dist/approval-crash-convergence.js +4 -4
- package/dist/bake-runner/main.js +2 -1
- package/dist/boot/execution-env.js +1 -0
- package/dist/boot/memory-consolidation.d.ts +46 -16
- package/dist/boot/memory-consolidation.js +15 -8
- package/dist/boot/side-query-lane.d.ts +7 -20
- package/dist/boot/side-query-lane.js +0 -24
- package/dist/boot/stage-01-config.js +3 -0
- package/dist/boot/stage-06-runners.js +1 -1
- package/dist/boot/stores.js +2 -2
- package/dist/boot/web-admin.js +17 -10
- package/dist/boot/webfetch-summarize-lane.d.ts +10 -7
- package/dist/boot/webfetch-summarize-lane.js +2 -3
- package/dist/brain.js +6 -9
- package/dist/capabilities/builtin-tools.d.ts +2 -2
- package/dist/capabilities/engine-capabilities.d.ts +14 -0
- package/dist/capabilities/engine-capabilities.js +12 -0
- package/dist/capability-facts.d.ts +3 -1
- package/dist/capability-facts.js +1 -0
- package/dist/config-catalog.js +5 -1
- package/dist/config-types.d.ts +7 -3
- package/dist/config.js +7 -1
- package/dist/egress-redirect.d.ts +12 -0
- package/dist/egress-redirect.js +7 -0
- package/dist/entry-mode-clamp-notice.d.ts +30 -0
- package/dist/entry-mode-clamp-notice.js +13 -0
- package/dist/exec-bounds.d.ts +69 -0
- package/dist/exec-bounds.js +37 -0
- package/dist/fleet/fleet-bus.d.ts +7 -0
- package/dist/fleet/fleet-bus.js +1 -0
- package/dist/hooks/hook-llm.js +6 -2
- package/dist/host-lsp-manager.d.ts +3 -3
- package/dist/http/admission.js +5 -2
- package/dist/http/resume-legs.js +46 -27
- package/dist/http/route-ctx.d.ts +1 -1
- package/dist/http/routes/approvals-assistant.js +6 -4
- package/dist/http/routes/capabilities.js +1 -0
- package/dist/http/routes/session-sync.js +3 -4
- package/dist/http/routes/sessions.js +4 -17
- package/dist/http/send.d.ts +1 -1
- package/dist/http/send.js +4 -3
- package/dist/http/wire-types.d.ts +3 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/observability/fail-open.d.ts +7 -3
- package/dist/observability/fail-open.js +7 -3
- package/dist/observability/secret-env-scrub.d.ts +37 -3
- package/dist/observability/secret-env-scrub.js +2 -2
- package/dist/parked-decide.js +5 -2
- package/dist/plugins/memory-embedder.js +5 -0
- package/dist/plugins/one-time-migrations.d.ts +180 -9
- package/dist/plugins/one-time-migrations.js +315 -3
- package/dist/plugins/pg-pool.js +3 -1
- package/dist/plugins/remote-env-e2b.d.ts +31 -9
- package/dist/plugins/remote-env-e2b.js +77 -26
- package/dist/plugins/remote-env-host.d.ts +17 -20
- package/dist/plugins/remote-env-host.js +20 -30
- package/dist/plugins/remote-env-k8s.d.ts +12 -4
- package/dist/plugins/remote-env-k8s.js +22 -31
- package/dist/plugins/session-policy-store-sql.d.ts +16 -4
- package/dist/plugins/session-policy-store-sql.js +17 -20
- package/dist/plugins/session-rules-column.d.ts +16 -0
- package/dist/plugins/session-rules-column.js +6 -0
- package/dist/plugins/tidb-pool.js +4 -1
- package/dist/read-face-posture.d.ts +2 -1
- package/dist/request-value-closure.js +1 -1
- package/dist/retired-card-words.d.ts +17 -0
- package/dist/retired-card-words.js +49 -0
- package/dist/rule-entry-list.js +2 -0
- package/dist/run-local.js +10 -3
- package/dist/server-secret-env.d.ts +77 -85
- package/dist/server-secret-env.js +40 -26
- package/dist/session-policy-wire.d.ts +61 -124
- package/dist/session-policy-wire.js +59 -121
- package/dist/session-sync.d.ts +8 -6
- package/dist/session-sync.js +6 -5
- package/dist/spec-fields.d.ts +3 -2
- package/dist/standing-answer-grant.d.ts +17 -9
- package/dist/standing-answer-grant.js +11 -8
- package/dist/task-settings.d.ts +6 -1
- package/dist/task-settings.js +1 -1
- package/dist/tool-approval.d.ts +14 -7
- package/dist/tool-approval.js +23 -18
- package/dist/trace/core-keyset-guard.d.ts +3 -3
- package/dist/trace/engine-notice-wire.d.ts +1 -1
- package/dist/trace/engine-notice-wire.js +1 -0
- package/dist/trace/project.d.ts +7 -4
- package/dist/trace/project.js +6 -75
- package/dist/trace/tool-output-media.d.ts +2 -1
- package/dist/trace/tool-output-media.js +3 -25
- package/dist/web-admin-client/apply-effective.js +28 -11
- package/dist/web-admin-client/facade.d.ts +1 -1
- package/dist/web-admin-client/facade.js +1 -1
- package/dist/web-admin-client/read-face.d.ts +73 -20
- package/dist/web-admin-client/read-face.js +76 -36
- package/dist/web-admin-client/skills-mcp.d.ts +1 -1
- package/dist/web-admin-client/skills-mcp.js +1 -1
- package/dist/web-admin-client/types.d.ts +3 -3
- package/package.json +3 -3
- package/dist/mcp-tool-axes.d.ts +0 -62
- package/dist/mcp-tool-axes.js +0 -47
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { joinRequestUrl } from "@sema-agent/core";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
+
import { egressRedirectRefusal } from "../egress-redirect.js";
|
|
3
4
|
import { buildDisplaySafeRefusal, buildDisplaySafeUrl } from "../trace/redact.js";
|
|
4
5
|
const EmbeddingsResponse = z.object({
|
|
5
6
|
data: z.array(z.object({ embedding: z.array(z.number()) })).min(1),
|
|
@@ -43,11 +44,15 @@ export function createOpenAiCompatEmbedder(opts) {
|
|
|
43
44
|
},
|
|
44
45
|
body: JSON.stringify({ model, input: text }),
|
|
45
46
|
signal: AbortSignal.timeout(timeoutMs),
|
|
47
|
+
redirect: "manual",
|
|
46
48
|
});
|
|
47
49
|
}
|
|
48
50
|
catch (transportErr) {
|
|
49
51
|
throw new Error(`memory embedder POST ${shownUrl}: transport failure — ${safeSlice(String(transportErr))}`);
|
|
50
52
|
}
|
|
53
|
+
const redirected = egressRedirectRefusal(res, "declare the final endpoint as MEMORY_EMBEDDER_ENDPOINT");
|
|
54
|
+
if (redirected !== undefined)
|
|
55
|
+
throw new Error(`memory embedder POST ${shownUrl}: ${redirected}`);
|
|
51
56
|
const raw = await res.text().catch((readErr) => {
|
|
52
57
|
throw new Error(`memory embedder POST ${shownUrl}: response body unreadable — ${safeSlice(String(readErr))}`);
|
|
53
58
|
});
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* 占位日期)—— 不计到期;抬 `package.json` 到那一版的发布准备提交把两格回填成发布日 / +30 天。到期门同时是回填门:`package.json` 版本
|
|
12
12
|
* **≥** 某条未发布形的 `introducedIn` 而两格仍是 `null` ⇒ 红(发布准备提交就是回填时刻,忘了就当场红;版本更低 = 还在开发,不红)。
|
|
13
13
|
* 最后一条删掉时,整个文件连同 `StoreBackend.runOneTimeMigrations()`(npm 公面上的接口成员)、`NO_SQL_MIGRATIONS`、
|
|
14
|
-
* `logOneTimeMigrations`、三只后端与两只测试夹具上的实现、`boot/stores.ts` 的调用点一起删 —— 唯一例外是退役 schema 的拒启臂
|
|
14
|
+
* `logOneTimeMigrations` / `runAndLogOneTimeMigrations`、三只后端与两只测试夹具上的实现、`boot/stores.ts` 的调用点一起删 —— 唯一例外是退役 schema 的拒启臂
|
|
15
15
|
* ({@link assertRetiredSchemaAbsent}、探针口 {@link assertRetiredSchemaAbsentOnPool} 与它们的错误类型、两件退役 schema 的坐标):它没有窗,跳版升级的库永远可能出现,
|
|
16
16
|
* 删最后一条的车要把它搬进启动期对账(`schema-consistency.ts` 一族)并保住它先于一切建表与改写的位置(现位:`store-backend.ts` 里 SQL 两后端的 `ensureSchema()` 自身,探针先于它的第一条 CREATE),不要随文件删掉。
|
|
17
17
|
* 其余文件一律只写「窗口见本文件登记表」,不各写一个日期或版本 —— S-590 之前本文件头写死了一个删除版本号(7.75.0),
|
|
@@ -37,9 +37,9 @@
|
|
|
37
37
|
* 发出的任何一条 CREATE —— 一次会拒的起服不许先在库里建出几十张本版新表(`task_run` 还带着新列),否则拒句里「没动过库」就是假话,而按拒句指路去 7.125.x 起服的人会撞上
|
|
38
38
|
* 「库比 7.125.x 新」的第二道拒。探针与建表的先后只写在 `store-backend.ts` 里 SQL 两后端的 `ensureSchema()` 自身(装配处包一次)。迁移段入口({@link runSqlOneTimeMigrations})**不再问**这一问:
|
|
39
39
|
* 它只在 `ensureSchema()` 之后被起服序列调用,一个事实不在两处各读一遍;嵌入方走公开序列 `createStoreBackend()` → `ensureSchema()` → `runOneTimeMigrations()` 即得到这一问,零动作。
|
|
40
|
-
* 残余(如实):运维在第一次起带迁移的版本之前就把两件退役 schema
|
|
41
|
-
*
|
|
42
|
-
* (下游不改上游盘上格式),同由那条读腿接住。
|
|
40
|
+
* 残余(如实):运维在第一次起带迁移的版本之前就把两件退役 schema 都手工删掉的库,残留的旧拼法由门记录的读腿接住 —— 7.129.0 起(core 7.51.0 #1731)
|
|
41
|
+
* 那只读腿按 core 的档案读法读,`unresolvable` 是 core 退役词注册表里的词 ⇒ 记录原词原样读回、不改写(`trace/project.ts` `screenedGate`);local 文件车道
|
|
42
|
+
* 没有表与列,没有这一问的探针 —— 引擎 File 店里已决 checkpoint 的记录按契约物理不可变,本仓没有合法缝改写它们(下游不改上游盘上格式),同由那条读腿接住。
|
|
43
43
|
*
|
|
44
44
|
* ## 窗内的迁移(逐条的失败方向刻意不同)
|
|
45
45
|
* · **M4 审计明细里的 JSON 文本 `null`** —— S-550 把 `device_audit.detail` 的读回收进唯一属主并判形之后,
|
|
@@ -122,10 +122,58 @@
|
|
|
122
122
|
* 调契约的目录迁移 `migrateConfigDirectory`(覆盖面 = 本地读腿会读的那几份:便携域 + 退役域 `runtime`),整域终判通过才原子写回、搬空的
|
|
123
123
|
* `runtime.json` 删;读腿不读的域文件(`hosts` / `workers` …)不碰;
|
|
124
124
|
* 迁不动 ⇒ 一字不写、`config_dir_migration_refused` 一行。没有读数键(它不写库)。
|
|
125
|
+
* · **M17 会话规则一列一文法**(7.129.0,引擎 7.51.0 #1480)—— 引擎把会话规则的 `toolDeny` / `toolAllow` 换成规则条目文法(`Bash(rm:*)` 是一条拒 `rm`
|
|
126
|
+
* 的规则),退役 `commandAllow` / `commandDeny` 两只命令桶。持久面三件事,同一步做:
|
|
127
|
+
* ① **列改名** `session_policy.rules` → `rule_entries`(列定义唯一属主 `session-rules-column.ts`):7.128.x 及以前的副本按整串工具名读 `rules`,
|
|
128
|
+
* `Bash(rm:*)` 在那种读法下匹配不到任何工具 —— 一只没改名的列会让混跑窗里的旧副本、回滚上来的旧二进制把本版写下的命令拒读成「没有这条拒」。
|
|
129
|
+
* 改名之后它们找不到那一列:已在跑的旧副本每一条规则语句响亮失败(新任务起不来、规则面 500,在跑的腿留着它已执行的快照),旧二进制起服被列册探针拒启 ——
|
|
130
|
+
* 没有一只副本按旧文法读到新文法的行。行里不带文法版本(一个旧写者维护不了的第二个事实,恰在混跑窗里说谎),也不读规则体猜版本。
|
|
131
|
+
* MySQL 协议方言 `CHANGE COLUMN`(MariaDB 10.5 以前没有 `RENAME COLUMN`;定义内插同一串),PG `RENAME COLUMN`;成功判据是后置条件(列名换过来了)。
|
|
132
|
+
* ② **改名那一拍的改写:每一行在它自己的文法里由引擎读,改写成当前文法的同一句话**(core 7.51.2 #1761,行自带规则文法戳 `grammar`:写口判官盖、店整只存、
|
|
133
|
+
* 引擎按行自带的戳读;无戳行 = 戳之前写的行,引擎读成文法 0)。改名那一刻库里每一行都是无戳行(≤7.128.x 写的)—— 判据只有引擎的:行(体 + `rev`)经
|
|
134
|
+
* `readSessionRulesShape` 读成它自己的文法,`compileSessionRuleBucket` 在那种文法下编译 `toolAllow`,归 `earlier_grammar` 的条目(文法 0 里拼写不是它所指名字的条目
|
|
135
|
+
* —— `Bash(rm:*)` / `Edit(src/**)` / `Bash(*)`:什么都不放行,文法 1 里是一条放行规则)删掉,其余原样,盖 `grammar: SESSION_RULES_GRAMMAR` —— 文法 0 与 1 在引擎里只差
|
|
136
|
+
* 这一条子句,所以改写后的行是引擎对原行读法的逐调用同义重述(名单保持在场:删到空 = 在场的空名单,什么都不放行)。**每一行**都改写(只盖戳的也写):改写之后
|
|
137
|
+
* 部署里零无戳行(被 `*` 遮蔽的行除外:引擎把带 `*` 的 allow 名单整张读成 `wildcard_all`,遮住其余条目的旧文法读法 ⇒ 不改写、不盖戳、只点名,留在原文法里),引擎的文法 0 路径与每层一次的 `earlier_grammar` 通告在本服务上只剩这类行会触发。`toolDeny` 一个字节不动、不点名:引擎的文法只修订 allow 方向的读法
|
|
138
|
+
* (deny 条目在任何文法下读法相同),「deny 条目升级后开始拒」是本仓对 7.128.x 实际行为的自铸判断,引擎没有它的席位 —— deny 条目留在行里,谁要知道都读得到。
|
|
139
|
+
* 本仓零自铸文法判断、零 `readRuleEntry` 直调(修前的 `oldGrammarReadingOf` 按条目种类自铸三分类,是第二只文法读者)。按原文 CAS 回写(MySQL 协议两边
|
|
140
|
+
* `CAST(… AS BINARY)`),`rev` / `gen` 不动;有被删条目的行一条 warn `session_rule_row_old_grammar_entries`(键哈希 / 会话 / 被删的条目,过脱敏器)。
|
|
141
|
+
* 这一拍没有别的写者(旧副本找不到 `rules`,本版副本在起服锁上等)。
|
|
142
|
+
* **终名只在每一行都判完之后出现**:`rules` 先改成进行中的名 `rule_entries_old_grammar`(旧副本从此找不到列),判读在这个名下跑(幂等:已改写的行再判零动作),
|
|
143
|
+
* 判完才改成 `rule_entries`。于是判读没走完 —— 抛了、或进程被杀 —— 列都停在进行中的名,下一次起服从它续判(已带戳的行引擎按它的戳读:零 `earlier_grammar`、
|
|
144
|
+
* 已有戳 ⇒ 零动作);没有「改回」臂(一条自己也可能失败的补偿),也没有「改名即终名」的窄窗(被杀后下一次起服把没判的行当新文法行读)。
|
|
145
|
+
* **收据随提交落,不随成功落**:一行改写提交(CAS 命中)的那一刻,它被删的条目就记进本次起服的收据账({@link SessionRuleReceipts});之后本次起服的**任何**一步
|
|
146
|
+
* 失败 —— 判读半途、终名改名、改名后的退役桶扫描、其后的迁移(M11)—— 拒因都带着账里已有的收据({@link OneTimeMigrationInterruptedError}),起服日志在抛之前把它们打出来
|
|
147
|
+
* ({@link runAndLogOneTimeMigrations})。理由:被删的条目没有第二次被报出来的机会 —— 下一次起服续判时那一行已是新形、没有可删的条目,零命中。只盖戳的改写不记:
|
|
148
|
+
* 戳不丢任何信息,重来再判零动作。
|
|
149
|
+
* 如实的残余:改写与那一行日志之间进程被杀、或一条改写的确认在连接上丢了 —— 收据没有耐久载体(不为一条短命的迁移另建迁移账表,见 M4 一节的同一条论证)。
|
|
150
|
+
* ③ **存量命令桶只点名、不改写**:新文法写不出旧命令桶的拒 —— 旧桶(引擎 7.50.x 粗命令名策略,`defaultAction: "deny"`)对读不成「一条命令名」的命令行
|
|
151
|
+
* 一律拒(`/bin/rm …`、管道、`&&`),`Bash(rm:*)` 只按命令名判、放过 `/bin/rm`。任何改写都是放宽(`commandDeny`)或改变放行面(`commandAllow`),
|
|
152
|
+
* 不由本仓替人做。⇒ 退役桶**一个字节不动**,读回照旧 `corrupt`(引擎形读法点名那只桶;与引擎文件店对同一形同判 —— 每一种店一个结局),
|
|
153
|
+
* 每次起服一行一条 warn `session_rule_row_retired_bucket`(键哈希 / 会话 / 桶名;规则正文不出店),出路是人(按新文法改写那一行,或删会话)。
|
|
154
|
+
* 同一行其余的桶照 ② 判、盖戳(人按出路删掉退役桶的那一刻,行已是文法 1 的真话)。
|
|
155
|
+
* 够不到的两格(如实登记):local 车道的会话规则在引擎自己的文件店里(盘上格式归引擎,本仓没有合法缝改写),读数 `file-store`;带命令桶的文件由引擎读侧判坏
|
|
156
|
+
* (句子给出路),引擎按行自带的文法读无戳文件(文法 0),旧文法写下的 `toolAllow` 规则形条目照旧什么都不放行、不放宽(MIGRATION 写了)。待决停驻行里持久化的
|
|
157
|
+
* 祖先会话规则快照(`checkpoint` 文档 `state.inheritedGate.ancestorRules`)同理照新文法读,而它是引擎行摘要(`requirementsDigest`)覆盖的成员 ——
|
|
158
|
+
* 改写它 = 续跑被判 `requirements_damaged`;本仓不重铸引擎的摘要 ⇒ 不改写,引擎续跑同样按文法 0 读它(不放宽;MIGRATION 写了)。
|
|
159
|
+
* · **M18 存卡上两个退役词(停驻行只有读侧半场)**(7.129.0,引擎 7.51.0 #1515 / #1702)—— 7.128.x 写下的 `approval_ask.card_json`(卡)与停驻行
|
|
160
|
+
* (`checkpoint.checkpoint` 文档 `pendingAction` 的 `tool_approval` 臂)上两座可能带引擎退役的词:`ruleOffersAbsence: "shadowed"`、类对里的
|
|
161
|
+
* `governance_unavailable`。今天的读者只读引擎的今日闭集 ⇒ 修前整张存卡读不出(断连重放跳过、幂等重入走 park、回决口按要人)、停驻行的
|
|
162
|
+
* `shadowed` 读成「读不出 ⇒ 按强制」。⇒ **一只改写规则**(`src/retired-card-words.ts`:前者删键 = 合法缺席 —— 一词两义不可确定拆;后者换成
|
|
163
|
+
* `rule_unreadable`,类集去重、按引擎序、首员重取),**两处两种用法,按谁写的字节分**:
|
|
164
|
+
* · **卡 = 本服务自己写的**(`approval_ask.card_json`):起服**一次性改写** + 应用侧解析 + CAS 回写(`WHERE <列文本> = <读到的原文>`;第二跑零命中)。
|
|
165
|
+
* 全表按字样扫(`card_json` 是 TEXT,按 `ask_id` 键集分页)。
|
|
166
|
+
* · **停驻行 = 引擎写的文档**(`checkpoint.checkpoint`):本服务**一个字节不改写**。引擎的行摘要(`requirementsDigest`,引擎 7.49.0 #1320 起每条 v10 行都带)
|
|
167
|
+
* 覆盖 `pendingAction` 的 `askClass` / `classes`(`decision-read` 成员),续跑入口 `judgeCheckpointRequirements` 重算摘要 —— 成员被改 = 摘要不符 =
|
|
168
|
+
* 判 `damaged` ⇒ 拒续跑(`checkpoint.invalid_outcome`,行留 pending、无人能续);盖章的函数不在引擎包根出口,重铸摘要不是本服务的事
|
|
169
|
+
* (与 M17 对祖先会话规则快照同一条纪律)。停驻行上的退役词对引擎续跑无害:续跑入口读的是摘要,引擎里 `askClass` 只在铸造 / 拒数 / 出门路径读(core 7.51.1 dist 亲读)。
|
|
170
|
+
* **读侧半场**(同一行、同一窗,不另起登记行):由存卡唯一读者入口 `approval-card.ts` `readStoredCardEnvelope`(起服改写够不着的卡 —— 滚动升级窗里
|
|
171
|
+
* 7.128.x 副本新写的、local 车道的文件 ask 账)与停驻行入口 `currentParkArm`(**所有**停驻行 —— SQL 与 local 车道引擎 File 店的同一条路径)读时过同一只改写,
|
|
172
|
+
* **响亮**(`server.approval-card.retired-card-word-read`);读的是浅拷贝,被读的行一个字节不动。local 车道读数恒零(`NO_SQL_MIGRATIONS`)。
|
|
125
173
|
*
|
|
126
174
|
* ## 幂等
|
|
127
175
|
* 改写的几条都可重复跑(M4:`detail IS NOT NULL AND … = 'null'`;M5:列在场探针 + `WHERE incarnation = ''`;M6:`WHERE error_code IS NULL`;
|
|
128
|
-
* M8
|
|
176
|
+
* M8 / M18:字样扫描 + CAS 回写 —— 写过的行不再命中;M17 的改写只在改名那一拍跑,第二跑列名已是新名 ⇒ 零读零写;续判时已带戳的行零动作)。并发起动由 {@link runSqlOneTimeMigrations} 的 advisory 锁 + 每步的后置条件判据兜住(见那里)。
|
|
129
177
|
*/
|
|
130
178
|
import type { Pool as MysqlPool } from "mysql2/promise";
|
|
131
179
|
import type { Pool as PgPool } from "pg";
|
|
@@ -160,6 +208,61 @@ export interface OneTimeMigrationReport {
|
|
|
160
208
|
/** M11:读腿整桶拒的桶(唯一判官判不过:形 / 指纹 / behavior 闭集 / 墓碑规范文本 / 单一验证器)—— 一个字节没动,一桶一条拒因
|
|
161
209
|
* (不带行内容),启动日志逐桶 warn;local 车道恒空(见头注 M11 段)。 */
|
|
162
210
|
readonly undurableScopeRuleBucketsUnreadable: readonly UnreadableRuleBucket[];
|
|
211
|
+
/** M17:`session_policy` 装规则的那一列 —— `renamed` = 本次把 `rules` 改名成 `rule_entries`;`current` = 早已是新名(新库 / 第二跑);
|
|
212
|
+
* `no-table` = 这只库上没有 `session_policy`(中央 DDL 之后不可达,只为不编一个读数);`file-store` = local 文件车道(规则在引擎自己的文件店里)。 */
|
|
213
|
+
readonly sessionRuleColumn: "renamed" | "current" | "no-table" | "file-store";
|
|
214
|
+
/** M17:带退役命令桶的行 —— 退役桶一个字节不动,读回 `corrupt`;一行一条 warn 点名(不带规则正文)。每次起服都报,直到有人改写或删掉它。 */
|
|
215
|
+
readonly sessionRuleRowsWithRetiredBuckets: readonly SessionRuleRowRetiredBuckets[];
|
|
216
|
+
/** M17:改名那一拍(`sessionRuleColumn: "renamed"`)按引擎的条目读法判过、两种文法下读法不同的行 —— toolAllow 里被剔的条目(行已按原文 CAS 回写)、
|
|
217
|
+
* toolDeny 里升级后开始生效的条目(不改写);一行一条 warn 点名。只在改名那一拍有;第二跑起恒空(列名已是新名,行由本版的写者按新文法写)。 */
|
|
218
|
+
readonly sessionRuleRowsWithOldGrammarEntries: readonly SessionRuleRowOldGrammarEntries[];
|
|
219
|
+
/** M18:本次把 `approval_ask.card_json` 上引擎 7.51.0 退役的两个词改写掉的卡行数(SQL 独有;local 恒 0)。非零 = 真写了存量行。 */
|
|
220
|
+
readonly retiredCardWordAskRowsRewritten: number;
|
|
221
|
+
/** M18:带字样、但 `approval_ask.card_json` 的 JSON 读不懂 ⇒ 没改写的卡行数(留给读者自己的坏行臂;非零 = 运维该看一眼这些行)。SQL 独有;local 恒 0。 */
|
|
222
|
+
readonly retiredCardWordRowsUnreadable: number;
|
|
223
|
+
}
|
|
224
|
+
/** 退役的两只命令桶(引擎 7.51.0 起不是桶;只给 M17 点名认)。 */
|
|
225
|
+
export type RetiredSessionRuleBucket = "commandAllow" | "commandDeny";
|
|
226
|
+
/** M17 点名的一行(键是单向哈希;只带桶名,规则正文不出店)。 */
|
|
227
|
+
export interface SessionRuleRowRetiredBuckets {
|
|
228
|
+
readonly policyKey: string;
|
|
229
|
+
readonly sessionId: string;
|
|
230
|
+
readonly buckets: readonly RetiredSessionRuleBucket[];
|
|
231
|
+
}
|
|
232
|
+
/** M17 改名那一拍的一条收据(键是单向哈希;只带被删的那几条条目,过本仓唯一脱敏器 —— 其余规则正文不出店)。 */
|
|
233
|
+
export interface SessionRuleRowOldGrammarEntries {
|
|
234
|
+
readonly policyKey: string;
|
|
235
|
+
readonly sessionId: string;
|
|
236
|
+
/** toolAllow 里删掉的条目:引擎在行自己的文法(0)里读成 `earlier_grammar` —— 拼写不是它所指的名字,什么都不放行;当前文法里是一条放行规则 ——
|
|
237
|
+
* 删掉后盖戳的行是引擎对原行读法的逐调用同义重述。 */
|
|
238
|
+
readonly toolAllowDropped: readonly string[];
|
|
239
|
+
/** 在场 = 这一行没改写也没盖戳:引擎在它的文法里把 toolAllow 整张读成作废(名单里有 `*`),其余条目的读法被遮住(见 {@link OldGrammarEntries.wildcardMasked})。 */
|
|
240
|
+
readonly wildcardMasked?: true;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* M17 收据账 —— **收据随提交落,不随成功落**:一行有被删条目的改写提交(CAS 命中)的那一刻就记进来,不等本段走完。本次起服之后的任何一步抛了,{@link interruptedWith}
|
|
244
|
+
* 把账里已有的收据装进 {@link OneTimeMigrationInterruptedError} 随拒因交出 —— 下一次起服续判时这些行已是新形、零命中,收据只有这一拍说得出。
|
|
245
|
+
* · `rows` —— 本次起服提交了的、有被删条目的改写(只盖戳的改写不记:戳不丢信息,重来再判零动作);两次起服的账并起来恰是一次不被打断的全部事实;
|
|
246
|
+
* · `renamed` —— 终名由本次起服发布了(下一次起服读到的是 `current`)。
|
|
247
|
+
*/
|
|
248
|
+
export interface SessionRuleReceipts {
|
|
249
|
+
rows: SessionRuleRowOldGrammarEntries[];
|
|
250
|
+
renamed: boolean;
|
|
251
|
+
}
|
|
252
|
+
/** 一本空的 M17 收据账(迁移段每次起服一本;{@link migrateSessionRuleGrammar} 往里记)。 */
|
|
253
|
+
export declare function buildSessionRuleReceipts(): SessionRuleReceipts;
|
|
254
|
+
/** 迁移段被打断时随拒因交出的收据(读数键与 {@link OneTimeMigrationReport} 同名同形;`sessionRuleColumn` 只在终名已由本次起服发布时在场)。 */
|
|
255
|
+
export interface OneTimeMigrationReceipts {
|
|
256
|
+
readonly sessionRuleColumn?: "renamed";
|
|
257
|
+
readonly sessionRuleRowsWithOldGrammarEntries: readonly SessionRuleRowOldGrammarEntries[];
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* 一次起服的迁移在**已提交**一些下次起服推不出来的改写之后失败了:原错误在 `cause` 与句子里原样在场,已提交的收据在 `receipts`(结构化)与句子尾(同一份读数的人读形)。
|
|
261
|
+
* 没有提交过这类改写就失败的路径不包这只错(原错误原样抛)。起服调用点({@link runAndLogOneTimeMigrations})在抛之前把 `receipts` 打进日志。
|
|
262
|
+
*/
|
|
263
|
+
export declare class OneTimeMigrationInterruptedError extends Error {
|
|
264
|
+
readonly receipts: OneTimeMigrationReceipts;
|
|
265
|
+
constructor(cause: unknown, receipts: OneTimeMigrationReceipts);
|
|
163
266
|
}
|
|
164
267
|
/**
|
|
165
268
|
* S-590 —— 一条一次性迁移的窗(登记表的一行;纯数据)。字段注写着每个值的取证方式,改一行之前照着重核。
|
|
@@ -195,7 +298,7 @@ export declare const ONE_TIME_MIGRATIONS: readonly OneTimeMigrationWindow[];
|
|
|
195
298
|
* 只给**窗内才生效的行为臂**用(M10 的认领):那种臂过了窗就停,不等删码车 —— 删码因此是零行为变化,而窗只写在本表这一处。
|
|
196
299
|
*/
|
|
197
300
|
export declare function migrationWindowOpen(window: Pick<OneTimeMigrationWindow, "removableAfter">, today: string): boolean;
|
|
198
|
-
/** local 车道上 SQL 独有的几条(M4 / M5 / M8 / M9 / M11)的读数(M6 两车道都有,local 腿的读数由 `LocalBackend.runOneTimeMigrations` 现算):那几张表 / 列在文件底座上从来不存在 ⇒ 如实答 absent / 0。 */
|
|
301
|
+
/** local 车道上 SQL 独有的几条(M4 / M5 / M8 / M9 / M11 / M17 / M18)的读数(M6 两车道都有,local 腿的读数由 `LocalBackend.runOneTimeMigrations` 现算):那几张表 / 列在文件底座上从来不存在 ⇒ 如实答 absent / 0。 */
|
|
199
302
|
export declare const NO_SQL_MIGRATIONS: Omit<OneTimeMigrationReport, "holderDeathCodeRowsBackfilled">;
|
|
200
303
|
/** 启动期的日志口(logger 的子集)。两级各有其用,见 {@link logOneTimeMigrations}。 */
|
|
201
304
|
export interface MigrationLogSink {
|
|
@@ -213,6 +316,14 @@ export declare class RetiredSchemaPresentError extends StoreBootRefusalError {
|
|
|
213
316
|
readonly code = "config.schema_mismatch";
|
|
214
317
|
constructor(found: readonly string[]);
|
|
215
318
|
}
|
|
319
|
+
/** 方言无关的最小查询口(两方言的返回形不同,由下面两只适配器收平)。`params` 只给带值的语句用(M5 的回填:会话 id 是
|
|
320
|
+
* 调用方自选的任意串,不许内插进 SQL 文本);占位符形由调用方按方言写(`?` / `$n`)。 */
|
|
321
|
+
export interface MigrationDb {
|
|
322
|
+
/** 取行(只读探针用)。 */
|
|
323
|
+
rows(sql: string, params?: readonly unknown[]): Promise<Record<string, unknown>[]>;
|
|
324
|
+
/** 执行并回报受影响行数(DDL 返回 0)。 */
|
|
325
|
+
exec(sql: string, params?: readonly unknown[]): Promise<number>;
|
|
326
|
+
}
|
|
216
327
|
/** 探针口的池参数:方言与它的池一起走(判别联合 ⇒ 不靠调用方断言「这个池是哪种」)。 */
|
|
217
328
|
export type RetiredSchemaProbeTarget = {
|
|
218
329
|
readonly dialect: "tidb";
|
|
@@ -239,17 +350,55 @@ export declare function assertRetiredSchemaAbsentOnPool(target: RetiredSchemaPro
|
|
|
239
350
|
* 一次滚动升级会让 N 个副本同时跑到这里。整段因此跑在**一条连接**上、握着**与 `ensureSchema` 同一把**
|
|
240
351
|
* advisory 锁(MySQL 具名锁 / PG `pg_try_advisory_lock`,两方言都是非阻塞轮询形):本段是「启动期改 schema 的活」,与 ensure 属同一类,
|
|
241
352
|
* 复用同一把锁 ⇒ 本仓这一类工作只有**一个**锁身份,而且本段也不会与另一个副本的 ensure 交错。
|
|
242
|
-
*
|
|
243
|
-
*
|
|
353
|
+
* 锁拿不到时**不降级**(7.83.0 起 `tidb-pool.ts` / `pg-pool.ts` 的锁腿永不无锁跑 schema 活:拿不到就等到拿到或拒启)—— 所以进行中的改名列下只有一个写者;
|
|
354
|
+
* 每条改表 DDL 的成功判据仍是它的**后置条件**({@link execUntil}),「另一个副本抢先把同一张表换了形」不会把滚动升级变成启动失败循环。
|
|
244
355
|
*
|
|
245
356
|
* ## 次序(codex r1 [medium] 同轮)
|
|
246
|
-
* 非破坏改写(M4–M9:改值不丢信息 / 加法 DDL / 复制 + 换名)在前,破坏性步骤(M11 的删行)排在最后;
|
|
357
|
+
* 非破坏改写(M4–M9、M18:改值不丢信息 / 加法 DDL / 复制 + 换名)在前,破坏性步骤(M11 的删行)排在最后;
|
|
247
358
|
* M11 自己半途失败时,拒因自带已删的行(`purgeUndurableScopeRows`)—— 否则重试看不见已删的行,证据永久消失。
|
|
248
359
|
*
|
|
249
360
|
* 本函数**不问**退役 schema:带着它的库在更早处就被 `ensureSchema()` 自身拒掉了({@link assertRetiredSchemaAbsentOnPool},先于建表);走公开序列
|
|
250
361
|
* `createStoreBackend()` → `ensureSchema()` → `runOneTimeMigrations()` 的嵌入方与本服务的起服序列一样,有这一问、零动作。
|
|
251
362
|
*/
|
|
252
363
|
export declare function runSqlOneTimeMigrations(dialect: "tidb" | "pg", pool: MysqlPool | PgPool): Promise<OneTimeMigrationReport>;
|
|
364
|
+
/**
|
|
365
|
+
* M17 —— 一份存量规则体带哪几只退役命令桶(纯函数,点名判据):只认**对象上自有**的 `commandAllow` / `commandDeny` 键(不论值形 —— 坏形的退役桶照样是退役桶);
|
|
366
|
+
* 不是对象 / 没有这两个键 / 条目文字里出现同名字样 ⇒ 空。不改写:新文法写不出旧命令桶的拒(头注 M17 段 ③)。
|
|
367
|
+
*/
|
|
368
|
+
export declare function retiredSessionRuleBucketsOf(body: unknown): readonly RetiredSessionRuleBucket[];
|
|
369
|
+
/** M17 —— 一份存量规则体按引擎在它自己的文法里的读法改写成当前文法的同一句话({@link oldGrammarEntriesOf} 的读数)。 */
|
|
370
|
+
export interface OldGrammarEntries {
|
|
371
|
+
/** toolAllow 里删掉的条目(引擎的 `earlier_grammar` 读数;见 {@link SessionRuleRowOldGrammarEntries.toolAllowDropped})。 */
|
|
372
|
+
readonly toolAllowDropped: readonly string[];
|
|
373
|
+
/** 这一行要落的新体 —— 被删条目去掉、其余键原样(退役命令桶也原样)、`grammar: SESSION_RULES_GRAMMAR`;在场 = 要写。缺席 = 零动作:行已带戳且没有可删的条目
|
|
374
|
+
* (上一次没走完的判读已改写过的行),或 {@link wildcardMasked}。 */
|
|
375
|
+
readonly rewritten?: Record<string, unknown>;
|
|
376
|
+
/** 在场 = 引擎在这一行自己的文法里把 `toolAllow` 整张读成作废(`wildcard_all`:名单里有 `*`),遮住了其余条目在那种文法里各算什么 ——
|
|
377
|
+
* 本函数因此**不改写、不盖戳**(改写会把被遮住的条目定成当前文法的规则;引擎修正文法 0 的 `*` 读法后,留在原文法里的行自动读真),只点名。 */
|
|
378
|
+
readonly wildcardMasked?: true;
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* M17 —— 一行存量规则(体 + 它的 `rev`)的改写判读(纯函数,判据只有引擎的):
|
|
382
|
+
* · 行按引擎的形读法在**它自己的文法**里读 —— `readSessionRulesShape` 对与 `rev` 并排的值按戳读,无戳 ⇒ 文法 0(戳之前写的行);退役命令桶先放一边(形读法拒它们,
|
|
383
|
+
* 而改写的是同一行其余的桶 —— 人按出路删掉退役桶的那一刻,行已是当前文法的真话);
|
|
384
|
+
* · `toolAllow` 经 `compileSessionRuleBucket` 在那种文法下编译,归 `earlier_grammar` 的条目删掉(文法 0 与 1 在引擎里只差这一条子句:拼写不是它所指名字的 allow 条目
|
|
385
|
+
* 在文法 0 里什么都不放行、在文法 1 里是一条放行规则),名单**保持在场**(在场的空 `toolAllow` 引擎读作「什么都不放行」);别的桶一个字节不动;
|
|
386
|
+
* · 新体盖 `grammar: SESSION_RULES_GRAMMAR`:无戳行每一行都写(改写之后部署里零无戳行);已带戳且没有可删条目的行零动作(幂等)。
|
|
387
|
+
* 读不出形(不是对象、有别的非桶键、桶不是一列字符串、坏戳 / 比引擎新的戳)⇒ `undefined`,不判(读回照旧 `corrupt`)。本函数零处读 / 比较戳的数值:
|
|
388
|
+
* 「有没有戳」是形读法自己判戳之前的同一问;条目在哪种文法下算什么只有引擎读。
|
|
389
|
+
*/
|
|
390
|
+
export declare function oldGrammarEntriesOf(body: unknown, rev: number): OldGrammarEntries | undefined;
|
|
391
|
+
/**
|
|
392
|
+
* M17 —— 会话规则一列一文法(规则与理由见头注 M17 段)。三段,每段的成功判据都是**列此刻叫什么**(后置条件,{@link execUntil}),所以任何一拍被杀都能从列名续上:
|
|
393
|
+
* ① 旧名 `rules` 在 ⇒ 改成进行中的名 `rule_entries_old_grammar`(≤7.128.x 副本从此找不到列,响亮失败;MySQL 协议方言 `CHANGE COLUMN`,定义内插 `SESSION_RULES_COLUMN`
|
|
394
|
+
* 同一串;PG `RENAME COLUMN`);
|
|
395
|
+
* ② 进行中的名在 ⇒ 改写它下面的每一行({@link judgeOldGrammarRows}:这个名下的行只可能是 ≤7.128.x 写的无戳行,或上一次没走完的判读已改写过的带戳行 —— 再判零动作),
|
|
396
|
+
* 判完才改成终名 `rule_entries`;判读抛了 ⇒ 原样上抛,列停在进行中的名,下一次起服从这里续。**收据随提交落**:有被删条目的改写提交的那一刻记进 `receipts` ——
|
|
397
|
+
* 本函数之后的任何一步(含终名改名本身、其后的退役桶扫描、`migrateOn` 里排在它后面的迁移)失败,收据都由 `migrateOn` 外层随拒因带出去;
|
|
398
|
+
* ③ 带退役命令桶的行每次起服在终名下逐页扫、逐行点名(文字预筛 + {@link retiredSessionRuleBucketsOf} 精判)—— 退役桶一个字节不动(读回照旧 `corrupt`)。
|
|
399
|
+
* 表不在(中央 DDL 之前被调到)⇒ `no-table`,不编读数。`renamed` = 本次把终名发布出来(含从进行中的名续判到底的那一次);`current` = 起服时已是终名。
|
|
400
|
+
*/
|
|
401
|
+
export declare function migrateSessionRuleGrammar(db: MigrationDb, dialect: "tidb" | "pg", receipts: SessionRuleReceipts): Promise<Pick<OneTimeMigrationReport, "sessionRuleColumn" | "sessionRuleRowsWithRetiredBuckets" | "sessionRuleRowsWithOldGrammarEntries">>;
|
|
253
402
|
/** M8 一行改写的结论:改写后的文本 / 这一行不用动 / 读不懂(解析错误原样交出,调用方计数进读数)。 */
|
|
254
403
|
export type ShadowedRuleRewrite = {
|
|
255
404
|
readonly kind: "rewrite";
|
|
@@ -266,6 +415,19 @@ export type ShadowedRuleRewrite = {
|
|
|
266
415
|
* JSON 读不懂 ⇒ `unreadable`(这一行不动,交给读口自己的响亮臂;迁移不替它猜,但把它数进读数,不静默)。
|
|
267
416
|
*/
|
|
268
417
|
export declare function migrateShadowedRuleDescriptor(text: string): ShadowedRuleRewrite;
|
|
418
|
+
/** M18 一行改写的结论(与 M8 同形,不共用型 —— 两条各自窗关各自删):改写后的文本 / 这一行不用动 / 读不懂(解析错误原样交出,调用方计数进读数)。 */
|
|
419
|
+
export type RetiredCardWordsRowRewrite = {
|
|
420
|
+
readonly kind: "rewrite";
|
|
421
|
+
readonly text: string;
|
|
422
|
+
readonly value: Record<string, unknown>;
|
|
423
|
+
} | {
|
|
424
|
+
readonly kind: "untouched";
|
|
425
|
+
} | {
|
|
426
|
+
readonly kind: "unreadable";
|
|
427
|
+
readonly error: unknown;
|
|
428
|
+
};
|
|
429
|
+
/** M18 —— `approval_ask.card_json` 一行的改写(纯函数;导出给钉用):信封里 `card` 两座上的退役词按 `retired-card-words.ts` 那一只改写。 */
|
|
430
|
+
export declare function migrateRetiredCardWordsInCardJson(text: string): RetiredCardWordsRowRewrite;
|
|
269
431
|
/**
|
|
270
432
|
* 启动日志的读数行。零命中(第二跑起的常态)也照发 —— 「跑过了、什么都没改」与「压根没跑」必须可分辨。
|
|
271
433
|
*
|
|
@@ -273,4 +435,13 @@ export declare function migrateShadowedRuleDescriptor(text: string): ShadowedRul
|
|
|
273
435
|
* 没动 ⇒ `info`。把恒常的空转也发成 warn 会训练运维忽略 warn —— 那是在为了本段的可见性去损耗整条告警轴。
|
|
274
436
|
*/
|
|
275
437
|
export declare function logOneTimeMigrations(log: MigrationLogSink, backend: string, report: OneTimeMigrationReport): void;
|
|
438
|
+
/**
|
|
439
|
+
* **起服调用点用的那一只**(`boot/stores.ts`;嵌入方走公开序列自己调 `runOneTimeMigrations()` 时拿到的是 {@link OneTimeMigrationInterruptedError} 本身,收据在 `receipts`):
|
|
440
|
+
* 跑迁移、成功则打读数行({@link logOneTimeMigrations});被打断(已提交了下次起服推不出来的改写)则**先把收据打进日志再抛**,抛的就是迁移段那只错。
|
|
441
|
+
* 其余失败原样抛、不多打一行。
|
|
442
|
+
*/
|
|
443
|
+
export declare function runAndLogOneTimeMigrations(log: MigrationLogSink, backend: {
|
|
444
|
+
readonly kind: string;
|
|
445
|
+
runOneTimeMigrations(): Promise<OneTimeMigrationReport>;
|
|
446
|
+
}): Promise<void>;
|
|
276
447
|
//# sourceMappingURL=one-time-migrations.d.ts.map
|