@sema-agent/settings-schema 15.2.0 → 16.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/CHANGELOG.md +137 -0
- package/README.md +52 -46
- package/conformance/VERSION +1 -1
- package/conformance/cases/c16-deep-nesting-205/expected.json +2 -2
- package/conformance/cases/c16-deep-nesting-205/meta.json +1 -1
- package/conformance/cases/c50-s784-lane-host-legal/expected.json +6 -2
- package/conformance/cases/c50-s784-lane-host-legal/input.json +3 -1
- package/conformance/cases/c51-s784-lane-e2b-legal/expected.json +6 -2
- package/conformance/cases/c51-s784-lane-e2b-legal/input.json +3 -1
- package/conformance/cases/c52-s784-lane-k8s-legal/expected.json +6 -2
- package/conformance/cases/c52-s784-lane-k8s-legal/input.json +3 -1
- package/conformance/cases/c53-s784-lane-ssh-legal/expected.json +6 -2
- package/conformance/cases/c53-s784-lane-ssh-legal/input.json +3 -1
- package/conformance/cases/c54-s784-lane-adb-legal/expected.json +6 -2
- package/conformance/cases/c54-s784-lane-adb-legal/input.json +3 -1
- package/conformance/cases/c55-s784-lane-local-docker-legal/expected.json +6 -2
- package/conformance/cases/c55-s784-lane-local-docker-legal/input.json +3 -1
- package/conformance/cases/c56-s784-lane-device-legal/expected.json +8 -2
- package/conformance/cases/c56-s784-lane-device-legal/input.json +5 -2
- package/conformance/cases/c57-s784-g1-enabled-no-lane/meta.json +1 -1
- package/conformance/cases/c58-s784-g2-multitenant-host/input.json +3 -1
- package/conformance/cases/c59-s784-g3-k8s-missing-image/input.json +3 -1
- package/conformance/cases/c60-s784-g3-e2b-missing-key/input.json +3 -1
- package/conformance/cases/c61-s784-g3-other-lane-key/input.json +3 -1
- package/conformance/cases/c62-s784-g7a-session-tidb/input.json +3 -1
- package/conformance/cases/c63-s784-host-two-replicas/input.json +3 -1
- package/conformance/cases/c64-s784-multitenant-local-store/input.json +3 -1
- package/conformance/cases/c65-s784-pg-without-db/input.json +3 -1
- package/conformance/cases/c66-s784-memory-backend-mismatch/input.json +3 -1
- package/conformance/cases/c66-s784-memory-backend-mismatch/meta.json +1 -1
- package/conformance/cases/c68-s784-device-local-store/input.json +6 -1
- package/conformance/cases/cli04-env-value-with-newline/expected.json +6 -2
- package/conformance/cases/cli04-env-value-with-newline/input.json +3 -1
- package/dist/bundle.d.ts +0 -18
- package/dist/bundle.js +1 -54
- package/dist/cli.d.ts +1 -1
- package/dist/config-d-file.d.ts +5 -5
- package/dist/config-d-file.js +58 -14
- package/dist/config-document-refusal.d.ts +9 -7
- package/dist/config-document-refusal.js +2 -2
- package/dist/device-relay.d.ts +21 -0
- package/dist/device-relay.js +23 -0
- package/dist/env-model-table.d.ts +2 -9
- package/dist/env-model-table.js +6 -14
- package/dist/execution-lane-index.d.ts +19 -7
- package/dist/execution-lane-index.js +26 -8
- package/dist/execution-lanes.d.ts +9 -4
- package/dist/execution-lanes.js +18 -6
- package/dist/file-store.d.ts +30 -3
- package/dist/file-store.js +74 -8
- package/dist/fleet.d.ts +6 -8
- package/dist/fleet.js +5 -7
- package/dist/hooks.d.ts +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -1
- package/dist/migration-receipt.d.ts +1 -1
- package/dist/migration-receipt.js +1 -1
- package/dist/one-time-migrations.d.ts +1 -1
- package/dist/one-time-migrations.js +166 -45
- package/dist/remote-exec.js +11 -4
- package/dist/types.d.ts +15 -11
- package/dist/types.js +99 -48
- package/dist/url-shape.d.ts +18 -0
- package/dist/url-shape.js +22 -0
- package/docs/API-SURFACE.md +12 -8
- package/docs/CONFORMANCE.md +1 -7
- package/docs/CONSUMER-INTEGRATION.md +3 -3
- package/llms-full.txt +24 -28
- package/llms.txt +9 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,143 @@
|
|
|
8
8
|
|
|
9
9
|
## Unreleased
|
|
10
10
|
|
|
11
|
+
## 16.0.0 — 2026-10-30 — major:worker 的执行车道由单值改为有序车道集 `runtime.execution.lanes` · device 车道的设备入口 `DEVICE_RELAY_URL` 必需且有值文法 · 记忆持久面方言词 `tidb` → `mysql` · 退役模型面组拒码 `config.summarize_model_missing` · `HostStatus.ts` 判 RFC 3339(加可选 `heartbeatMs`)· 本地配置单读口 `FileConfigStore.read()`(过深的文档是文件层的拒)· 本地文件契约 `RemoteExecSpec` 的非空串字段:只含空白 = 空 ⇒ 拒 · 一次性迁移 SS-M12
|
|
12
|
+
|
|
13
|
+
> 档位(按发版纪律):**major** —— 七处硬破坏(B1–B7,逐条三问在下),加性若干。发版纪律按消费方在**运行期**与**编译期**的可见性判档。
|
|
14
|
+
> 每一件先写律:一件事只有一处说法、一种读法 —— 本版每条都是把「同一件事两种说法」收成一种,规则变少,不是变多。
|
|
15
|
+
> 导出面:包根 +7(`DEVICE_RELAY_NONE` / `DEVICE_RELAY_RULE` / `deviceRelayFlaws` / `wsUrlFlaws` / `WS_URL_SHAPE_RULE` / `WsUrlFlaw` / `DIAL_ADDRESS_URL_FORBIDDEN_PARTS`)−1(`SUMMARIZE_MODEL_MISSING_CODE`);
|
|
16
|
+
> `./fleet` −1(同名);`./node` +1(`FileConfigRead`)−2(`inspectBundle` / `BundleInspection`);导出面登记表合计 1468 → 1472 名。零别名、零双读、零过渡读法 —— 消费方的 tsc 红就是通知;存下来的数据另配一只一次性迁移 SS-M12。
|
|
17
|
+
|
|
18
|
+
### BREAKING 清单(逐条三问 + 下游动作)
|
|
19
|
+
|
|
20
|
+
**B1 · 执行车道:单值 `runtime.execution.lane` → 有序车道集 `runtime.execution.lanes`。**
|
|
21
|
+
律:**一台 worker 声明的是它启用的车道集,不是一条车道** —— 根会话各自绑定其中一条,首项是缺省。
|
|
22
|
+
形:`lanes` = 车道词的非空、去重有序表(`["k8s", "device"]`;首项缺省)。键归属按集判:`coords` / `secretRefs` 的每个键归表里**某一条声明的**车道
|
|
23
|
+
(归表外车道 ⇒ 点名它属于哪条车道);每条声明的车道各自的必需键都要在场且非空白;多租户姿态(`requirePrincipal`)对每条不分租户的车道各拒一条(落在 `lanes` 的那一格);
|
|
24
|
+
「只能一个副本」读车道表新列 `ExecutionLaneRow.singleReplica`(host、device 为真:会话的活挂在一个副本上)—— 声明了这种车道的 worker 副本数 > 1 拒一条、点名这些车道,写闸不再按 `host` 这个词判;
|
|
25
|
+
`device ∈ lanes` ⇒ 要真开得出 SQL 池的店(同 15.x 的 device 规则)。旧单值 `lane` 是墓碑:读写两面拒,拒句点名新形与一次性迁移 SS-M12。
|
|
26
|
+
保留名表里 `REMOTE_EXEC` / `REQUIRE_EXECUTION_LANE` 的归属字段改指 `runtime.execution.lanes`。
|
|
27
|
+
**谁需要**:执行车道从「引擎进程的属性」降为「根会话的放置」之后,部署声明的是一台引擎启用哪几条车道(device 与 k8s 共存是第一个真实形),单值装不下。
|
|
28
|
+
**谁受伤**:① 存下来的每一行 15.x workers(都带 `lane`)—— 整域读函数抛、`readWorkersRows` 扣下;② 按 `.lane` 读规格的代码(tsc 红);③ 渲染器:`REMOTE_EXEC` 改写成按序的逗号表(`lanes.join(",")`,首项缺省);
|
|
29
|
+
④ 引擎侧:把 `REMOTE_EXEC` 当一个词读的引擎读不了两条车道的表 —— 引擎与渲染器须同窗改读有序表。
|
|
30
|
+
**补偿**:跑一次性迁移(`npx @sema-agent/settings-schema migrate <config.d directory>` 或 `migrateStoredDocuments`):SS-M12 把 `lane: L` 改成 `lanes: [L]`,一元表的读法与旧单值逐位同。
|
|
31
|
+
|
|
32
|
+
**B2 · device 车道的设备入口 `DEVICE_RELAY_URL` 是必需坐标,值有文法。**
|
|
33
|
+
律:**设备拨哪里是部署的必填声明,只有两种合法值** —— 一个 ws(s) 绝对 URL(不带 userinfo / query / fragment:引擎把它逐字发布给设备,地址里没有凭据的位置),或字面 `none`(没有中继,设备拨引擎自己的地址)。
|
|
34
|
+
车道表 device 行 `requiredEnv` = `["DEVICE_RELAY_URL"]`(此前它是 device 臂读而表漏登记的键;写在 env 逃生口里的 15.x 写闸照收)。值的唯一判官 `deviceRelayFlaws(value)`(包根,纯函数):合格 ⇒ `[]`,
|
|
35
|
+
否则按判序交回 `not-ws-url` / `userinfo` / `query` / `fragment`;规则句 `DEVICE_RELAY_RULE`;`none` 只认这一种拼法。写闸按坐标文法表对有文法的坐标问它(拒句 `coords.DEVICE_RELAY_URL <规则> — found: <词>`,
|
|
36
|
+
不回显值);值里认得出凭据形的片段照旧由坐标的密钥判据拒。缺席 / 空白走必需坐标的同一句(`lane "device" requires coords.DEVICE_RELAY_URL …`)。
|
|
37
|
+
ws(s) 的形判官 `wsUrlFlaws` 与这个座位禁的部件集 `DIAL_ADDRESS_URL_FORBIDDEN_PARTS` 住在 URL 形判官模块(本包判 URL 的正则只在那一处)。`RESERVED_WORKER_ENV` 多一名 `DEVICE_RELAY_URL`。
|
|
38
|
+
**谁需要**:引擎缺席即拒起;表不登记这一键,写闸、中心表单与部署清单就放行一台起不来的 device worker。
|
|
39
|
+
**谁受伤**:存下来的 device 行没有这一键(SS-M12 拒、原行留着 —— 迁移不在 URL 与 `none` 之间替运维猜);把它写在 `env` 里的 15.x 行;任一处把它写成别的形状的值。
|
|
40
|
+
**补偿**:给 device 行写 `coords.DEVICE_RELAY_URL`(经中继拨 ⇒ 那个 ws(s) URL;直拨引擎 ⇒ `none`)再跑迁移;写在 `env` 里的,SS-M12 搬进 `coords`(声明了 device 的行)或丢掉(没声明 device 的行:引擎从没读它)。
|
|
41
|
+
**部署序:先补、后升级** —— 15.2.x 的写闸收 `env.DEVICE_RELAY_URL`(那时它不在车道表里),旧版本下先给每个 device 行补上,升级时 SS-M12 搬进 `coords`,没有读不出的窗。
|
|
42
|
+
|
|
43
|
+
**B3 · 记忆持久面方言词 `tidb` → `mysql`(`MEMORY_ENGINE_BACKENDS` = `file` / `pg` / `mysql`)。**
|
|
44
|
+
律:**MySQL 族那只 SQL 店只有一个字**,与店词 `store.backend: "mysql"` 同字。`runtime.store.memory.backend: "tidb"` 读写两面拒,拒句点名 `mysql` 与 SS-M12;方言与店的配对规则不变(`pg` 要 pg 店,`mysql` 要 mysql 店)。
|
|
45
|
+
**谁需要**:同一件事三个字(店词、记忆方言、引擎内部的会话店值)让每个读者各自翻译。**谁受伤**:存下来写着 `tidb` 的行;部署环境里 `MEMORY_ENGINE_BACKEND=tidb`(引擎直接读本表的词,提货后拒起)。
|
|
46
|
+
**补偿**:SS-M12 把存下来的 `tidb` 改写成 `mysql`(6.x 行的 `env.MEMORY_ENGINE_BACKEND=tidb` 由 SS-M4 一并写成 `mysql`);部署环境变量改写成 `MEMORY_ENGINE_BACKEND=mysql`。
|
|
47
|
+
|
|
48
|
+
**B4 · 模型面组拒码 `config.summarize_model_missing` 退役(不重定义),写者计划助手的 `fix_first` 结局一并删。**
|
|
49
|
+
律:**闭集里只列真会被铸出来的码**。角色席点名目录里没有的条目时,引擎把它读成未设席、按回退链落下一级,没有哪种读法因 summarize 悬空而拒组 —— 列着它就是说一件不成立的事。
|
|
50
|
+
`MODEL_PLANE_REFUSAL_CODES` 五码(其余次序不动);`SUMMARIZE_MODEL_MISSING_CODE` 从包根与 `./fleet` 删。心跳 / `/health` 上若还带着它,读口按集外码丢掉(诊断键的失败方向 = 不说)。
|
|
51
|
+
`planEnvModelTableWrite` 的结局删 `fix_first` 一臂:summarize 悬空照样写在回执里(`dangles`),要确认的写法照旧把它给用户看;`envModelTableWriteRefusal` 只收 `confirm` 计划。
|
|
52
|
+
**谁需要**:按码渲染的消费方不再为一个不会出现的码写臂。**谁受伤**:import 这个常量或对 `fix_first` 分支的代码(tsc 红)。**补偿**:删那一臂;悬空的 summarize 从回执里读。
|
|
53
|
+
|
|
54
|
+
**B5 · `HostStatus.ts` 判 RFC 3339 时刻(此前只判非空串)。** 加性同节:`HostStatus.heartbeatMs?`(正整数毫秒,上报方声明的心跳节律,与实例公告的同名字段同一个义;缺席 = 没声明,**没有缺省**;多久没报算不新鲜是中心的判,本包只给字段)。
|
|
55
|
+
律:**注释说是时刻的字段就判成时刻**。**谁需要**:读方按时刻比较新鲜度;`Date.parse` 读成 NaN 的串不该过写闸。**谁受伤**:上报非 RFC 3339 时刻的宿主状态写入被拒。**补偿**:上报 `new Date().toISOString()` 形。
|
|
56
|
+
|
|
57
|
+
**B6 · 本地配置的单读口 `FileConfigStore.read()`(`./node`)取代 `inspectBundle` / `BundleInspection`;过深的文档是一份文件层被拒的文档。**
|
|
58
|
+
律:**一次读,一个结局**。`read(): Promise<FileConfigRead>`:每份文档只读一次 —— 文件层都读得进 ⇒ `{ kind: "effective", effective, warnings }`(effective 与严读 `getEffective()` 逐位同,读侧告警交成数据、不经 `onWarning`);
|
|
59
|
+
有文档被拒 ⇒ `{ kind: "refused", refusals, version, warnings }`(拒单形、次序与版本与 15.2.0 的目录口同)。读得出却过不了闸域 schema 的拒照严读抛(不是文件层)。
|
|
60
|
+
深度:一份文档嵌得比整棵目录的内容版本能算的深(根下 199 层)⇒ 文件层拒,闭集词 `CONFIG_DOCUMENT_REFUSAL_REASONS` 多一个 `too_deep`(墓碑仍在末位)—— 此前在算版本那一步抛,已收集的拒全部丢掉。
|
|
61
|
+
严读(`getEffective` / `readBundle`)对过深的文档抛文件层那一句(点名文件路径);宽容读把它落进 `domainErrors`;一致性语料 c16 的本地腿拒在 `parse`(此前 `hash`)。
|
|
62
|
+
**谁需要**:要「读得进就要 effective、读不进就要拒单」的本地读腿 —— 此前只能严读一次、抛了再问目录口一次,两读之间文档被修好时这一拍是过期诊断。
|
|
63
|
+
**谁受伤**:import `inspectBundle` / `BundleInspection` 的代码(tsc 红);对 `ConfigDocumentRefusalReason` 穷举的 `switch`(多一个词,tsc 红);按「hash 层拒」认过深文档的读者。
|
|
64
|
+
**补偿**:改调 `new FileConfigStore(root).read()`,按 `kind` 分两支;`switch` 补 `too_deep` 一臂。
|
|
65
|
+
|
|
66
|
+
**B7 · 本地文件契约 `RemoteExecSpec`(`config.d/remote-exec.json`)的非空串字段:只含空白 = 空 ⇒ 拒。**
|
|
67
|
+
律:**「空白」只有一种读法** —— 文件契约里每个非空串字段(沙箱镜像 / 命名空间 / 主机 / 用户名 / 设备序列号 / 工作目录 / 挂载路径 / shell / 模板 / 桶 … 共二十一处,此前凡拒空串的字符串字段)问的是写闸对必需坐标问的**同一只**判官 `isBlankCoordinate`:
|
|
68
|
+
空串或只含空白(`trim()` 认的空白:空格 / 制表 / 换行 / 不换行空格 / 字节序标记 …)一律拒。此前同一个部署声明(沙箱镜像、命名空间)在写闸里「纯空白 = 缺」,在文件里却只拒空串、收下 `" "` —— 同一个包里两种读法。
|
|
69
|
+
空串与纯空白现在是**同一条拒、同一句话**(`must not be empty or whitespace-only — give it a real value (an optional key can simply be left out)`),issue 指到那一格,不回显值;
|
|
70
|
+
此前空串的拒句是 zod 内建的 `too_small` 那一句,现在换成这一句 —— 被拒的集合只增不减,但句子与 issue 码变了。判官只判「是不是空白」:非空白的值(含前后带空白的)逐字承运,不 trim;NUL 仍是它自己的一句。
|
|
71
|
+
**谁需要**:本地配置模式下引擎起服读 `config.d/remote-exec.json` 的部署 —— 把一个空白当镜像 / 命名空间去起容器或拉 pod,是起服之后才响的坏声明;同一件事写闸(workers 的必需坐标)早已拒。
|
|
72
|
+
**谁受伤**:`config.d/remote-exec.json` 里把任一非空串字段写成纯空白的部署声明(病态输入):`loadRemoteExec` 抛(读文件的引擎起服拒)、`validateRemoteExec` / `parseRemoteExecDocument` 拒、`writeRemoteExec` 不落盘;
|
|
73
|
+
按 zod 的 `too_small` 码认「空串」的 issue 读者(读码不读路径的)—— 空串的拒现在也是这一句 custom issue。
|
|
74
|
+
**补偿**:删掉那一键(可选字段:缺席 = 缺省行为),或给真值(必填的 `image` / `namespace` / `host` / `username` / `serial`:只能给真值)。没有迁移 —— 空白值没有「正确的改写」,替运维猜只会把错藏起来。
|
|
75
|
+
|
|
76
|
+
### 一次性迁移 SS-M12(workers 7.0–15.x 行 → 16.0.0 形)
|
|
77
|
+
|
|
78
|
+
只认形、不认义、幂等:`lane: L` ⇒ `lanes: [L]`(moved,原位改名);`store.memory.backend: "tidb"` ⇒ `"mysql"`(rewritten);`env` 里的 `DEVICE_RELAY_URL` ⇒ 声明了 device 的行搬进 `coords`(moved),没声明的丢(dropped-inert)。
|
|
79
|
+
拒且原行留盘(`readWorkersRows` 读时扣下):`lane` 与 `lanes` 并存、声明了 device 却把 `DEVICE_RELAY_URL` 写在 `secretEnv`(值读不到)或 `env` 与 `coords` 两处都写、改写后仍读不进的行(没有 `DEVICE_RELAY_URL` 的 device 行在内)。
|
|
80
|
+
与 SS-M4 在同一个 workers 行步里做:先 SS-M12 改、再 SS-M4 改,两只都改完才用读侧那一只判一次(一行可以同时带 7.0+ 的单值车道与 6.x 的店字段;各判各的会互相卡死),
|
|
81
|
+
改完读不进的那一张拒记在改了这一行的最新那只迁移名下;SS-M4 的产出直接是 16.0.0 形;窗 = 发布日 + 30 天,登记在 `ONE_TIME_MIGRATIONS` 一行。拒因里的指路点名**搬这个键的最新一只迁移**:`DEVICE_RELAY_URL` 指 SS-M12,其余车道 / 店键仍指 SS-M4(同一条命令跑整族)。
|
|
82
|
+
|
|
83
|
+
### 文档
|
|
84
|
+
|
|
85
|
+
随包文字说真话:7.0.0 的 workers 一次性抬升函数与它的文件子命令 11.0.0 就删了,llms 两档、接入档入口表、一致性门档的目录树与 README 仍有现在时的宣传 —— 改成「已删」并指向一次性迁移族;
|
|
86
|
+
`FileConfigStore.getDomain` 的注释把纯空白文件算进缺席,实际读法抛(纯空白 = 半写,坏文件)—— 注释改真。
|
|
87
|
+
|
|
88
|
+
### 钉
|
|
89
|
+
|
|
90
|
+
新:`test/lane-set-16.0.0.test.ts`(车道集形 · 去重 / 空 / 墓碑 · 键归属按集 · 每条声明车道的必需键 · 多租户逐车道 · `singleReplica` 列 · device 店规则按集)、`test/device-relay-16.0.0.test.ts`(表行 · 判官真值表 · 写闸同答 · 凭据形片段 · 拒句不回显值)、
|
|
91
|
+
`test/memory-backend-mysql-16.0.0.test.ts`、`test/summarize-code-retired-16.0.0.test.ts`、`test/host-status-heartbeat-16.0.0.test.ts`、`test/config-read-one-16.0.0.test.ts`(单读口 · 文件层拒交成数据 · 深度闸收进文件层 · 边界 199 / 200)、
|
|
92
|
+
`test/one-time-migration-ss-m12-16.0.0.test.ts`、`test/docs-rot-16.0.0.test.ts`、`test/exec-str-blank-16.0.0.test.ts`(文件契约字符串叶子从 schema 现算 · 空串与纯空白同一句 · 与写闸必需坐标对拍六对 · 只拒不改 · 读写入口同答);随形改的旧钉逐格翻到新形(车道夹具一元表、拒因落点 `lanes.<i>`、方言词、码闭集、迁移 id 闭集、指路律读两只迁移的读数、目录口的钉经单读口交出、变异靶点随新拼法)。
|
|
93
|
+
|
|
94
|
+
另:`docs/API-SURFACE.md` 随导出面重生成;一致性语料 c50–c68 / cli04 的输入改成车道集形(device 两条补 `DEVICE_RELAY_URL: "none"`)并重新加冕,c16 本地腿的拒层改 `parse`。
|
|
95
|
+
|
|
96
|
+
**自 v15.2.0 起运行期代码有改动的公开导出(机器重算;上界 —— 可达 ≠ 一定变,不可达 ⇒ 一定不变;本版新增的导出不入表)**
|
|
97
|
+
|
|
98
|
+
```text
|
|
99
|
+
CONFIG_DOCUMENT_REFUSAL_REASONS [.]
|
|
100
|
+
DOMAINS [., ./types]
|
|
101
|
+
DOMAIN_SCHEMAS [., ./types]
|
|
102
|
+
EXECUTION_LANES [., ./execution-lanes]
|
|
103
|
+
FileConfigStore [./node]
|
|
104
|
+
HostStatus [., ./types]
|
|
105
|
+
MEMORY_ENGINE_BACKENDS [., ./execution-lanes]
|
|
106
|
+
MODEL_PLANE_REFUSAL_CODES [., ./fleet]
|
|
107
|
+
ModelPlaneRefusalCode [., ./fleet]
|
|
108
|
+
NON_PORTABLE_DOMAINS [./conformance]
|
|
109
|
+
ONE_TIME_MIGRATIONS [./one-time-migrations]
|
|
110
|
+
ONE_TIME_MIGRATION_IDS [./one-time-migrations]
|
|
111
|
+
RESERVED_WORKER_ENV [., ./types]
|
|
112
|
+
RemoteExecSpec [., ./remote-exec]
|
|
113
|
+
WorkerSpec [., ./types]
|
|
114
|
+
WorkersConfig [., ./types]
|
|
115
|
+
buildEffective [., ./config-fns]
|
|
116
|
+
deriveLocalExpectation [./conformance]
|
|
117
|
+
deriveWireExpectation [./conformance]
|
|
118
|
+
domainFilePath [./node]
|
|
119
|
+
emptyEffective [., ./config-fns]
|
|
120
|
+
envModelTableWriteRefusal [.]
|
|
121
|
+
foreignKeysOf [./conformance]
|
|
122
|
+
isDomainName [., ./types]
|
|
123
|
+
loadLocalConfig [./node]
|
|
124
|
+
loadRemoteExec [./node]
|
|
125
|
+
migrateConfigDirectory [./node]
|
|
126
|
+
migrateConfigDocuments [./node]
|
|
127
|
+
migrateEffectiveSnapshot [./one-time-migrations]
|
|
128
|
+
migrateEnvModelsDecision [./node]
|
|
129
|
+
migrateStoredDocuments [./one-time-migrations]
|
|
130
|
+
parseDomain [., ./config-fns]
|
|
131
|
+
parseDomainLoud [., ./config-fns]
|
|
132
|
+
parseDomainSalvaged [., ./config-fns]
|
|
133
|
+
planEnvModelTableWrite [.]
|
|
134
|
+
readBundle [./node]
|
|
135
|
+
readEffectiveWire [., ./config-fns]
|
|
136
|
+
readModelRefusals [., ./fleet]
|
|
137
|
+
readWorkersRows [.]
|
|
138
|
+
resolveLegExpectation [./conformance]
|
|
139
|
+
runConformance [./conformance]
|
|
140
|
+
urlSeatPatterns [./one-time-migrations]
|
|
141
|
+
validateDomain [./node]
|
|
142
|
+
validateRemoteExec [./node]
|
|
143
|
+
writeBundle [./node]
|
|
144
|
+
writeDomainFile [./node]
|
|
145
|
+
writeRemoteExec [./node]
|
|
146
|
+
```
|
|
147
|
+
|
|
11
148
|
## 15.2.0 — 2026-10-29 — minor:文件层读不出 `config.d` 文档时契约自己交类型化的拒(`inspectBundle` + 闭集词 `CONFIG_DOCUMENT_REFUSAL_REASONS`)· 车道坐标判官 `isBlankCoordinate` 也从 `./execution-lanes` 子路径取(与包根同一只)· 安全合并规格 `memoryScopes` 行的 seam 显示串改叫 `MemoryEngine`
|
|
12
149
|
|
|
13
150
|
> 档位(按发版纪律):**minor** —— 加性:新导出 7 个(包根 4:`CONFIG_DOCUMENT_REFUSAL_REASONS` / `ConfigDocumentName` / `ConfigDocumentRefusal` / `ConfigDocumentRefusalReason`;`./node` 2:`inspectBundle` / `BundleInspection`;`./execution-lanes` 1:`isBlankCoordinate`);
|
package/README.md
CHANGED
|
@@ -47,6 +47,40 @@ therefore shows only `zod`. Node built-ins only (`node:crypto`, `node:fs`).
|
|
|
47
47
|
> zod 3, nested inside every zod-4 host). The move to zod 4 did not change what any schema accepts or produces —
|
|
48
48
|
> the conformance corpus reads byte-identically on both — only the wording of validation errors (see CHANGELOG 11.0.0).
|
|
49
49
|
|
|
50
|
+
## 升级指引:15.2.x → 16.0.0(BREAKING:执行车道集 · 设备入口必需且有文法 · 记忆方言词 mysql · 退役一只模型面组拒码 · 宿主状态时刻判形 · 本地配置单读口 · 文件契约的纯空白字段)
|
|
51
|
+
|
|
52
|
+
- **改了什么**(逐条三问见 CHANGELOG 16.0.0):
|
|
53
|
+
① worker 的 `runtime.execution.lane`(单值)换成有序车道集 `runtime.execution.lanes`(非空、去重,首项缺省);键归属、必需键、多租户与「只能一个副本」都按集判(后者读车道表新列 `singleReplica`);旧 `lane` 是墓碑。
|
|
54
|
+
② device 车道的 `DEVICE_RELAY_URL` 进车道表必需栏,值只收 ws(s) 绝对 URL(无 userinfo / query / fragment)或字面 `none`;判官 `deviceRelayFlaws` / 规则句 `DEVICE_RELAY_RULE` / `DEVICE_RELAY_NONE` 在包根。
|
|
55
|
+
③ `MEMORY_ENGINE_BACKENDS` = `file` / `pg` / `mysql`(`tidb` 退役,与店词同字)。
|
|
56
|
+
④ `MODEL_PLANE_REFUSAL_CODES` 删 `config.summarize_model_missing` 与常量 `SUMMARIZE_MODEL_MISSING_CODE`;`planEnvModelTableWrite` 删 `fix_first` 结局(悬空的 summarize 留在回执里)。
|
|
57
|
+
⑤ `HostStatus.ts` 判 RFC 3339 时刻;加可选 `HostStatus.heartbeatMs`(正整数毫秒,无缺省)。
|
|
58
|
+
⑥ `./node`:`inspectBundle` / `BundleInspection` 删,单读口 `FileConfigStore.read()` → `FileConfigRead`;拒因闭集加 `too_deep`(过深的文档是一份文件层被拒的文档)。
|
|
59
|
+
⑦ 本地文件契约 `RemoteExecSpec`(`config.d/remote-exec.json`)的非空串字段(镜像 / 命名空间 / 主机 / 用户名 / 序列号 / 工作目录 / 路径 …)对只含空白的值同空串一样拒 —— 问的是写闸对必需坐标问的同一只判官 `isBlankCoordinate`,空串与纯空白是同一句拒;接受的值逐字不变(不 trim)。
|
|
60
|
+
- **存下来的数据**:跑一次一次性迁移 —— `npx @sema-agent/settings-schema migrate <config.d directory>`,或对中心的存量调 `migrateStoredDocuments` / `migrateEffectiveSnapshot`(`./one-time-migrations`)。
|
|
61
|
+
SS-M12 改写 15.x workers 行(`lane: L` ⇒ `lanes: [L]`;记忆方言 `tidb` ⇒ `mysql`;`env` 里的 `DEVICE_RELAY_URL` 搬进 device 行的 `coords` 或丢掉)。
|
|
62
|
+
**拒且原行留着**的行要人补:没有 `DEVICE_RELAY_URL` 的 device 行(写 `coords.DEVICE_RELAY_URL`:经中继拨 ⇒ 那个 ws(s) URL,直拨引擎 ⇒ `none`)、`lane` 与 `lanes` 并存的行、声明了 device 却把 `DEVICE_RELAY_URL` 写在 `secretEnv` 或 `env` 与 `coords` 两处都写的行(没声明 device 的行里它是惰性件,迁移丢掉)。
|
|
63
|
+
- **部署环境**:`MEMORY_ENGINE_BACKEND=tidb` 改写成 `mysql`;device 车道的部署必须声明 `DEVICE_RELAY_URL`(URL 或 `none`)。
|
|
64
|
+
- **部署序(device 行):先补、后升级** —— 15.2.x 的写闸把 `DEVICE_RELAY_URL` 当普通 env 收(它那时不在车道表里),所以可以在旧版本下先给每个 device 行写 `env.DEVICE_RELAY_URL`,
|
|
65
|
+
升级后 SS-M12 把它搬进 `coords`;不先补的 device 行升级后被迁移拒、原行留着,整域读函数读不出 workers 文档(按行读的 `readWorkersRows` 扣下那一行),直到补上为止。
|
|
66
|
+
- **各消费方的读点**:
|
|
67
|
+
|
|
68
|
+
| 消费方 | 读点 | 动作 |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| server | 本地读腿:`getEffective` 抛了再问 `inspectBundle` 的两读 | 改调 `FileConfigStore.read()` 一次读,按 `kind` 分两支;拒因 `switch` 补 `too_deep` |
|
|
71
|
+
| server | 记忆方言:比较 `"tidb"` 的臂、目录行说明、`/v1/capabilities` 里报的记忆后端值 | 改 `"mysql"`(类型从本包来,tsc 红指路);能力面上的值随之改字,对外是 wire 改字 |
|
|
72
|
+
| server | 设备入口:自持的 `DEVICE_RELAY_NONE` 与 ws(s) 形判 | 改 import 本包 `DEVICE_RELAY_NONE` / `deviceRelayFlaws`,删自己那一份;缺席判交给车道必需键门(本表 device 行已含它) |
|
|
73
|
+
| server | `REMOTE_EXEC` 读成一个词 | 改读有序逗号表(首项缺省),与渲染器同窗;此前读不了两条车道的表 |
|
|
74
|
+
| server | 模型面组拒码 | 本包这一码的读点已为零,无动作 |
|
|
75
|
+
| web-admin | 渲染器 `REMOTE_EXEC = execution.lane`、向导与团队形对 `execution.lane` 的读 | `REMOTE_EXEC = lanes.join(",")`(`REQUIRE_EXECUTION_LANE=true` 不变);读 `lanes`(tsc 红指路) |
|
|
76
|
+
| web-admin | device 行表单 | 写 `coords.DEVICE_RELAY_URL`,提示读 `DEVICE_RELAY_RULE`、判读 `deviceRelayFlaws`;「撤中继」写 `none`,不是删键 |
|
|
77
|
+
| web-admin | 宿主状态写入口 `HostStatus.safeParse` | 上报方的 `ts` 须是 RFC 3339;`heartbeatMs` 可选,新鲜度窗公式在中心 |
|
|
78
|
+
| web-admin | 存量 workers | 跑 SS-M12(同一条迁移命令 / 函数) |
|
|
79
|
+
| cli | 自起引擎注的 `REMOTE_EXEC=host` | 一个词即一元表,无动作 |
|
|
80
|
+
| cli | 由本包车道表派生的「车道 → 必需键」 | 随表:device 多 `DEVICE_RELAY_URL`(无手抄一份,提货即生效;与钉版引擎的对拍随引擎版本) |
|
|
81
|
+
| 部署 | 车道清单 / compose 透传 | 随车道表重生成(device 多 `DEVICE_RELAY_URL`);`MEMORY_ENGINE_BACKEND=mysql` |
|
|
82
|
+
| server / 部署 | 本地配置模式:`config.d/remote-exec.json` 里的非空串字段(镜像 / 命名空间 / 工作目录 / shell / 主机 …)写成纯空白 | 16.0.0 起被拒 —— `loadRemoteExec` 抛、起服拒;出路 = 删掉那一键(可选字段)或给真值(必填字段);没有迁移 |
|
|
83
|
+
|
|
50
84
|
## 升级指引:15.1.x → 15.2.0(加性,零动作可升)
|
|
51
85
|
|
|
52
86
|
三件,都是加性的,既有导出的答案逐位不变:
|
|
@@ -287,7 +321,7 @@ therefore shows only `zod`. Node built-ins only (`node:crypto`, `node:fs`).
|
|
|
287
321
|
env-NAME ref. Every `provider` word is an execution-lane word (`EXECUTION_LANE_WORDS`, pinned at runtime and at
|
|
288
322
|
compile time). **7.0.0** deleted the `remote-docker` variant: no engine read point ever ran it; a remote docker
|
|
289
323
|
daemon is the `local-docker` lane pointed at it (`DOCKER_HOST`). **11.0.0**: retired lane VALUES have a tombstone,
|
|
290
|
-
`RETIRED_LANE_WORDS` (`[old, to, how]`, permanent, one hop); a worker spec's `runtime.execution.
|
|
324
|
+
`RETIRED_LANE_WORDS` (`[old, to, how]`, permanent, one hop); a worker spec's `runtime.execution.lanes` entry or this file's
|
|
291
325
|
`provider` naming one is refused with the way out (`retiredLaneWordRefusal(word)` is the one sentence; the issue code
|
|
292
326
|
stays `invalid_value` / `invalid_union`).
|
|
293
327
|
- **WorkerSpec execution lane + store (7.0.0, M-R2)** (`execution-lanes.ts`, also subpath `./execution-lanes`, + `types.ts`): the lane / store
|
|
@@ -297,53 +331,24 @@ therefore shows only `zod`. Node built-ins only (`node:crypto`, `node:fs`).
|
|
|
297
331
|
`optionalSecretEnv`, copied from the engine with per-row coordinates), `STORE_BACKENDS`, `SESSION_BACKENDS`,
|
|
298
332
|
`MEMORY_ENGINE_BACKENDS`. Web-admin's write gate (this package's `WorkerSpec.safeParse`), web-admin's env
|
|
299
333
|
renderer and the engine's boot checks all read that one table, so they cannot drift. A worker declares
|
|
300
|
-
`runtime.execution = {
|
|
301
|
-
|
|
334
|
+
`runtime.execution = { lanes, coords, secretRefs }` (16.0.0: an ordered, de-duplicated, non-empty lane set — the first one is the default;
|
|
335
|
+
non-secret coordinates as literals, secrets as host env-NAMEs, each key owned by a declared lane, every declared lane's required ones present
|
|
336
|
+
and not blank — an empty or whitespace-only value counts as absent; a coordinate with a grammar — `DEVICE_RELAY_URL`, a ws(s) URL or the
|
|
337
|
+
literal `none` — must also match it) and `runtime.store = { backend, session, memory,
|
|
302
338
|
db? }` (+ `secretRefs.dbPasswordEnv`); an enabled worker must declare both. Cross-field refusals live in the
|
|
303
339
|
schema as zod issues whose `path` names the field to change and whose message carries the way out: a
|
|
304
|
-
multi-tenant worker (`requirePrincipal`)
|
|
305
|
-
table),
|
|
306
|
-
without a SQL store that actually builds its coordinates (the engine's `device-durable-store`), SQL coordinates
|
|
340
|
+
multi-tenant worker (`requirePrincipal`) with a declared lane that does not separate tenants (one refusal per such lane; outlets
|
|
341
|
+
computed from the table), a lane whose row says `singleReplica` (host, device) with more than one replica (`replicas` or
|
|
342
|
+
`autoscaling.maxReplicas`), the `device` lane without a SQL store that actually builds its coordinates (the engine's `device-durable-store`), SQL coordinates
|
|
307
343
|
without a SQL store (or the reverse), a memory backend that does not match the store, a multi-tenant worker
|
|
308
344
|
without a SQL store, and the two session × store combinations the engine refuses at boot (`session: mysql` on a
|
|
309
|
-
`memory` store; a pg /
|
|
345
|
+
`memory` store; a pg / mysql memory engine with `session: memory`). `WorkerSpec` is no longer a plain object schema — the worker-name rule is exported on its
|
|
310
346
|
own as `WORKER_NAME`. `RESERVED_WORKER_ENV` (derived from a name → owning-field table) now reserves every
|
|
311
347
|
env name those blocks produce, so the `env` / `secretEnv` escape hatches can no longer set a lane or a store.
|
|
312
|
-
Stored
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
`env.REMOTE_EXEC` — the migration never guesses a lane) come back in `refused` with the field to fix and the
|
|
317
|
-
`original` row verbatim — they are NOT in the migrated `doc`, so a caller that writes `doc` back must put each
|
|
318
|
-
`refused[].original` back at its `index` (or store it aside), or that worker's spec disappears. The final judgement
|
|
319
|
-
is per row (since 8.2.0 the same one for rows it rewrote and rows it left alone): every worker with a string name must read
|
|
320
|
-
as a one-row workers domain under the read side's own `WorkersConfig`, or it goes to `refused` — so each row of `doc`
|
|
321
|
-
reads on its own; what the whole-domain read can still refuse is a nameless entry (left as is) and the cross-row rules
|
|
322
|
-
(unique names / route prefixes).
|
|
323
|
-
- **`migrate-workers` CLI: report shape + rejection signposts (7.0.1)** (`bin/settings-schema.mjs`, core in `cli.ts`):
|
|
324
|
-
`npx @sema-agent/settings-schema migrate-workers <workers.json> [--check]` prints exactly two lines on stdout (exit 0 / 1 / 3): line 1 is the
|
|
325
|
-
ONE conclusion line `outcome=<refused|applied|noop|pending> written=<true|false>`, line 2 is the JSON report (`event: "workers_domain_migrated"`,
|
|
326
|
-
`outcome`, `written`, `file`, the worker lists, `refused[]`). Only `applied` writes the file (`written` is derived from `outcome`; `pending` =
|
|
327
|
-
`--check` with changes). The list keys carry tense — `changed` / `dropped` exist **only when `written=true`**; when nothing was written
|
|
328
|
-
(refused / noop / pending) the same lists are `wouldChange` / `wouldDrop`, so a script that reads only stdout can never take a worker that was
|
|
329
|
-
not migrated for migrated. Exit codes are unchanged (0 applied or noop · 1 refused or the migrated document does not read as a 7.0.0 workers
|
|
330
|
-
domain, nothing written · 2 usage / unreadable / not JSON, empty stdout · 3 `--check` with changes).
|
|
331
|
-
|
|
332
|
-
| 7.0.0 stdout | 7.0.1 stdout |
|
|
333
|
-
|---|---|
|
|
334
|
-
| one JSON line | the conclusion line, then the JSON line (parse the **last** line) |
|
|
335
|
-
| `changed` (always) | `changed` when `written=true`, else `wouldChange` |
|
|
336
|
-
| `dropped` (always) | `dropped` when `written=true`, else `wouldDrop` |
|
|
337
|
-
| — | `outcome`, `written` |
|
|
338
|
-
|
|
339
|
-
**8.0.0**: `--check` and a real run go through ONE verdict (per-worker refusals → nothing to change ⇒ `noop` → the whole-domain final judgment →
|
|
340
|
-
changes); `--check` only decides whether the "changes" branch writes (`pending`) or not. A document the whole-domain judgment refuses (two workers
|
|
341
|
-
with one name …) is `outcome=refused` / exit 1 under `--check` too (7.x: `pending` / exit 3), and `refused[]` names the refused items in the
|
|
342
|
-
per-worker shape (`name` / `field` / `reason`; `name` is `null` for an entry that carries no string name) instead of being empty.
|
|
343
|
-
|
|
344
|
-
Rejections that a migration can lift carry ONE signpost sentence (a constant, `MIGRATION_SIGNPOST`): the seven deleted 6.x fields, and an
|
|
345
|
-
`env` / `secretEnv` key the migration moves or drops (the execution-lane keys incl. `REMOTE_EXEC` / `REQUIRE_EXECUTION_LANE`, and the store keys
|
|
346
|
-
`DB_BACKEND` / `MEMORY_ENGINE` / `MEMORY_ENGINE_BACKEND`). A reserved name the migration cannot move (`PORT`, `MODEL_*`, `MYSQL_*` …) carries none.
|
|
348
|
+
Stored rows of an older form are rewritten ONCE by the one-time migrations (`./one-time-migrations`: 6.x rows by SS-M4, 15.x rows by
|
|
349
|
+
SS-M12 since 16.0.0; the directory form is the package's `bin`, `npx @sema-agent/settings-schema migrate <config.d directory>`) — the
|
|
350
|
+
read side holds a row it cannot read (`readWorkersRows`) instead of lifting it on every read. The 7.0.0 one-off lift function and its
|
|
351
|
+
file subcommand were deleted in 11.0.0.
|
|
347
352
|
- **Safety merge-spec** (`safety-merge-spec.ts`, subpath `./safety-merge-spec`): `SAFETY_MERGE_SPEC`, the ONE
|
|
348
353
|
per-category merge/enforcement table every settings resolver reads (`mergeShape` / `minTrust` / `tighten` /
|
|
349
354
|
`enforcement` / `fail`) — no consumer re-implements the merge law. 1.1.0 adds **member-level admission**:
|
|
@@ -484,7 +489,8 @@ therefore shows only `zod`. Node built-ins only (`node:crypto`, `node:fs`).
|
|
|
484
489
|
identity) and `enabledEntryCount(doc)`. The env model table read once — `readEnvModelSlots` / `envModelTableDeclared` (`MODEL_ID` present and non-empty) /
|
|
485
490
|
`buildEnvModelBaseline` — and the writer's plan `planEnvModelTableWrite({ env, target, decision, candidate, intent? })` (receipt by upstream id with landings
|
|
486
491
|
`{name, id}`, `confirmKey` = the receipt's sorted JSON) with its one sentence `envModelTableWriteRefusal(plan)`. Group-refusal codes
|
|
487
|
-
`CATALOG_REPLACES_ENV_MODELS_CODE`
|
|
492
|
+
`CATALOG_REPLACES_ENV_MODELS_CODE` (tail of `MODEL_PLANE_REFUSAL_CODES`; the summarize code next to it was retired in 16.0.0 —
|
|
493
|
+
a role seat naming an entry the catalog does not serve reads as unset and falls back, so no reading refuses a model plane for it).
|
|
488
494
|
- **Session web link** (`web-admin-session-url.ts`, main barrel): `webAdminSessionUrl(webBaseUrl, { worker, sessionId })` — the ONE
|
|
489
495
|
template for a web-admin session link, `<webBaseUrl>/chat?agent=<worker>&session=<sessionId>`: both parts required (a link with only
|
|
490
496
|
the session id lands on whichever worker the page picks and may not find it), each part `encodeURIComponent`-escaped, the base a
|
|
@@ -641,7 +647,7 @@ therefore shows only `zod`. Node built-ins only (`node:crypto`, `node:fs`).
|
|
|
641
647
|
unchanged); `readModelRefusals(body)` reads either exit and narrows to `ModelRefusalsSignal` — the codes are CLOSED
|
|
642
648
|
sets owned here, `MODEL_ENTRY_REFUSAL_CODES` (`config.model_no_brain`, `config.model_entry_invalid`) and
|
|
643
649
|
`MODEL_PLANE_REFUSAL_CODES` (`config.default_model_missing`, `config.model_refused_name_minted`,
|
|
644
|
-
`config.model_route_endpoint_missing`, `config.gateway_fallback_without_primary`), and a code this package version
|
|
650
|
+
`config.model_route_endpoint_missing`, `config.gateway_fallback_without_primary`, `config.catalog_replaces_env_models`), and a code this package version
|
|
645
651
|
does not know is dropped ("not said"). It is a diagnostic key, so its failure direction is "not said": an unknown
|
|
646
652
|
code or a shape violation on the heartbeat never fails the announcement (the key drops to absent). Present ⇔ at
|
|
647
653
|
least one reportable refusal; absence is read by the announced `version` — an engine that predates the key never
|
|
@@ -762,7 +768,7 @@ defaults. Each `config.d/<domain>.json` is exactly that domain's zod object.
|
|
|
762
768
|
自 `1.0.0`(改名)起本包按**标准 semver** 发版;`0.x` 时代的「破坏性变更必 bump minor」规矩**已撤**
|
|
763
769
|
(末条仅作历史注记)。判档看**消费方可见性**,不看 diff 大小:
|
|
764
770
|
|
|
765
|
-
- **CLI
|
|
771
|
+
- **CLI 报告形的契约边界**:`migrate` 的 stdout = 结论行 + JSON;其中 `outcome` / `written` / `refused` 三字段是机读契约(再改按 minor),其余键与行形是诊断面,patch 可变(CLI 报告形不在包导出面)。机读请取最后一行解析。
|
|
766
772
|
- **破坏性变更必 bump major**:字段/导出改名、改形(retype)、删除、默认值变更、校验收紧或放宽
|
|
767
773
|
(例:`.passthrough()` → 默认 strip、宽读 → 严判)、枚举**重排**——凡是能让一个按上一版契约写的
|
|
768
774
|
消费方在**运行期**变红、或让同一份配置解析出不同结果的改动;编译期同判,**唯一裁定例外** = 下一条的
|
|
@@ -778,7 +784,7 @@ defaults. Each `config.d/<domain>.json` is exactly that domain's zod object.
|
|
|
778
784
|
但标记不豁免版号义务。每版 CHANGELOG 一节,git tag `v<version>` 同名。
|
|
779
785
|
- **持久数据面的破坏性变更(例:7.0.0)**:类型 / API 面直接删改、零别名(消费方 tsc 红即通知);**存下来的数据**不会自己红,
|
|
780
786
|
所以同版配三件:读到旧形即**响亮拒**(拒因指路迁移命令,不是被 zod 静默剥掉)、一只**一次性迁移**(纯函数、幂等、
|
|
781
|
-
表达不了就 refused 点名,不替运维猜)、以及一个**写明的删除窗**(7.0.0
|
|
787
|
+
表达不了就 refused 点名,不替运维猜)、以及一个**写明的删除窗**(窗只登记在一次性迁移的登记表 `ONE_TIME_MIGRATIONS`;7.0.0 那一只一次性抬升函数已在 11.0.0 删)——
|
|
782
788
|
绝不长成长命双读。
|
|
783
789
|
- **历史注记(0.x 时代)**:0.x 下 `^0.7.0` 这类 range 只自动收 patch,故当年规矩是「破坏性必 bump
|
|
784
790
|
minor,patch 只装 additive/修 bug/文档」。0.7.1(2026-07-10)曾携带两件预协调 BREAKING(撤 governance
|
package/conformance/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
16.0.0
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
},
|
|
102
102
|
"localRoot": {
|
|
103
103
|
"outcome": "rejected",
|
|
104
|
-
"stage": "
|
|
105
|
-
"why": "
|
|
104
|
+
"stage": "parse",
|
|
105
|
+
"why": "本地腿读的是文件:16.0.0 起一份文档嵌得比整棵目录的内容版本能算的深(根下 199 层)是这一份文档的文件层拒(`too_deep`,在读文档那一步),不再等到算内容哈希时才抛;domains/wire 两腿不读文件、不哈希"
|
|
106
106
|
}
|
|
107
107
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"contributor": "contract",
|
|
3
|
-
"claim": "205 层嵌套的未知值:域解析照常(剥键扫描有深度上限,只报顶层那个键),但 local-root
|
|
3
|
+
"claim": "205 层嵌套的未知值:域解析照常(剥键扫描有深度上限,只报顶层那个键),但 local-root 腿读文件:一份文档嵌得比整棵目录的内容版本能算的深 ⇒ 它在读文档那一步(文件层,parse)确定性地拒(16.0.0 前在算内容哈希那一步抛)。同一份文档 domains/wire 两腿读得出、local 腿读不出 —— 这条差异必须是**报告里看得见**的,而不是某一腿悄悄回落。",
|
|
4
4
|
"firstRedOn": []
|
|
5
5
|
}
|
|
@@ -65,7 +65,9 @@
|
|
|
65
65
|
"coords": {
|
|
66
66
|
"HOST_WORKSPACE_BASE": "/work"
|
|
67
67
|
},
|
|
68
|
-
"
|
|
68
|
+
"lanes": [
|
|
69
|
+
"host"
|
|
70
|
+
],
|
|
69
71
|
"secretRefs": {}
|
|
70
72
|
},
|
|
71
73
|
"rateLimitRpm": 0,
|
|
@@ -108,7 +110,9 @@
|
|
|
108
110
|
"coords": {
|
|
109
111
|
"HOST_WORKSPACE_BASE": "/work"
|
|
110
112
|
},
|
|
111
|
-
"
|
|
113
|
+
"lanes": [
|
|
114
|
+
"host"
|
|
115
|
+
],
|
|
112
116
|
"secretRefs": {}
|
|
113
117
|
},
|
|
114
118
|
"rateLimitRpm": 0,
|
|
@@ -65,7 +65,9 @@
|
|
|
65
65
|
"coords": {
|
|
66
66
|
"E2B_TEMPLATE": "base"
|
|
67
67
|
},
|
|
68
|
-
"
|
|
68
|
+
"lanes": [
|
|
69
|
+
"e2b"
|
|
70
|
+
],
|
|
69
71
|
"secretRefs": {
|
|
70
72
|
"E2B_API_KEY": "HOST_E2B_KEY"
|
|
71
73
|
}
|
|
@@ -110,7 +112,9 @@
|
|
|
110
112
|
"coords": {
|
|
111
113
|
"E2B_TEMPLATE": "base"
|
|
112
114
|
},
|
|
113
|
-
"
|
|
115
|
+
"lanes": [
|
|
116
|
+
"e2b"
|
|
117
|
+
],
|
|
114
118
|
"secretRefs": {
|
|
115
119
|
"E2B_API_KEY": "HOST_E2B_KEY"
|
|
116
120
|
}
|
|
@@ -67,7 +67,9 @@
|
|
|
67
67
|
"K8S_RUNTIME_CLASS": "",
|
|
68
68
|
"K8S_SANDBOX_IMAGE": "registry.internal/sandbox@sha256:abc"
|
|
69
69
|
},
|
|
70
|
-
"
|
|
70
|
+
"lanes": [
|
|
71
|
+
"k8s"
|
|
72
|
+
],
|
|
71
73
|
"secretRefs": {
|
|
72
74
|
"K8S_TOKEN": "HOST_K8S_TOKEN"
|
|
73
75
|
}
|
|
@@ -114,7 +116,9 @@
|
|
|
114
116
|
"K8S_RUNTIME_CLASS": "",
|
|
115
117
|
"K8S_SANDBOX_IMAGE": "registry.internal/sandbox@sha256:abc"
|
|
116
118
|
},
|
|
117
|
-
"
|
|
119
|
+
"lanes": [
|
|
120
|
+
"k8s"
|
|
121
|
+
],
|
|
118
122
|
"secretRefs": {
|
|
119
123
|
"K8S_TOKEN": "HOST_K8S_TOKEN"
|
|
120
124
|
}
|
|
@@ -67,7 +67,9 @@
|
|
|
67
67
|
"SSH_PORT": "2222",
|
|
68
68
|
"SSH_USER": "deploy"
|
|
69
69
|
},
|
|
70
|
-
"
|
|
70
|
+
"lanes": [
|
|
71
|
+
"ssh"
|
|
72
|
+
],
|
|
71
73
|
"secretRefs": {
|
|
72
74
|
"SSH_PRIVATE_KEY": "HOST_SSH_KEY"
|
|
73
75
|
}
|
|
@@ -114,7 +116,9 @@
|
|
|
114
116
|
"SSH_PORT": "2222",
|
|
115
117
|
"SSH_USER": "deploy"
|
|
116
118
|
},
|
|
117
|
-
"
|
|
119
|
+
"lanes": [
|
|
120
|
+
"ssh"
|
|
121
|
+
],
|
|
118
122
|
"secretRefs": {
|
|
119
123
|
"SSH_PRIVATE_KEY": "HOST_SSH_KEY"
|
|
120
124
|
}
|
|
@@ -65,7 +65,9 @@
|
|
|
65
65
|
"coords": {
|
|
66
66
|
"ADB_SERIAL": "emulator-5554"
|
|
67
67
|
},
|
|
68
|
-
"
|
|
68
|
+
"lanes": [
|
|
69
|
+
"adb"
|
|
70
|
+
],
|
|
69
71
|
"secretRefs": {}
|
|
70
72
|
},
|
|
71
73
|
"rateLimitRpm": 0,
|
|
@@ -108,7 +110,9 @@
|
|
|
108
110
|
"coords": {
|
|
109
111
|
"ADB_SERIAL": "emulator-5554"
|
|
110
112
|
},
|
|
111
|
-
"
|
|
113
|
+
"lanes": [
|
|
114
|
+
"adb"
|
|
115
|
+
],
|
|
112
116
|
"secretRefs": {}
|
|
113
117
|
},
|
|
114
118
|
"rateLimitRpm": 0,
|
|
@@ -66,7 +66,9 @@
|
|
|
66
66
|
"DOCKER_HOST": "tcp://docker.internal:2376",
|
|
67
67
|
"DOCKER_IMAGE": "registry.internal/sandbox:1"
|
|
68
68
|
},
|
|
69
|
-
"
|
|
69
|
+
"lanes": [
|
|
70
|
+
"local-docker"
|
|
71
|
+
],
|
|
70
72
|
"secretRefs": {}
|
|
71
73
|
},
|
|
72
74
|
"rateLimitRpm": 0,
|
|
@@ -110,7 +112,9 @@
|
|
|
110
112
|
"DOCKER_HOST": "tcp://docker.internal:2376",
|
|
111
113
|
"DOCKER_IMAGE": "registry.internal/sandbox:1"
|
|
112
114
|
},
|
|
113
|
-
"
|
|
115
|
+
"lanes": [
|
|
116
|
+
"local-docker"
|
|
117
|
+
],
|
|
114
118
|
"secretRefs": {}
|
|
115
119
|
},
|
|
116
120
|
"rateLimitRpm": 0,
|
|
@@ -63,9 +63,12 @@
|
|
|
63
63
|
"runtime": {
|
|
64
64
|
"execution": {
|
|
65
65
|
"coords": {
|
|
66
|
+
"DEVICE_RELAY_URL": "none",
|
|
66
67
|
"DEVICE_SUPERSEDE": "deny"
|
|
67
68
|
},
|
|
68
|
-
"
|
|
69
|
+
"lanes": [
|
|
70
|
+
"device"
|
|
71
|
+
],
|
|
69
72
|
"secretRefs": {}
|
|
70
73
|
},
|
|
71
74
|
"rateLimitRpm": 0,
|
|
@@ -113,9 +116,12 @@
|
|
|
113
116
|
"runtime": {
|
|
114
117
|
"execution": {
|
|
115
118
|
"coords": {
|
|
119
|
+
"DEVICE_RELAY_URL": "none",
|
|
116
120
|
"DEVICE_SUPERSEDE": "deny"
|
|
117
121
|
},
|
|
118
|
-
"
|
|
122
|
+
"lanes": [
|
|
123
|
+
"device"
|
|
124
|
+
],
|
|
119
125
|
"secretRefs": {}
|
|
120
126
|
},
|
|
121
127
|
"rateLimitRpm": 0,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"contributor": "contract",
|
|
3
|
-
"claim": "G1:enabled 的 worker 没有 runtime.execution ⇒ 拒(拒因点名 runtime.execution.
|
|
3
|
+
"claim": "G1:enabled 的 worker 没有 runtime.execution ⇒ 拒(拒因点名 runtime.execution.lanes —— 16.0.0 起车道集)。打「声明不了车道也能过闸、起服落进程内 stub、无手照回 completed」那条静默路(WA-49)。",
|
|
4
4
|
"firstRedOn": []
|
|
5
5
|
}
|