@sema-agent/settings-schema 11.1.0 → 11.3.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 +151 -0
- package/README.md +14 -1
- package/bin/settings-schema.mjs +5 -9
- package/conformance/VERSION +1 -1
- package/conformance/cases/c73-projects-extended-registration-reads/expected.json +150 -0
- package/conformance/cases/c73-projects-extended-registration-reads/input.json +42 -0
- package/conformance/cases/c73-projects-extended-registration-reads/meta.json +6 -0
- package/conformance/cases/c74-projects-over-bound-refused/expected.json +89 -0
- package/conformance/cases/c74-projects-over-bound-refused/input.json +29 -0
- package/conformance/cases/c74-projects-over-bound-refused/meta.json +5 -0
- package/conformance/cases/c75-projects-patch-remote-uniqueness/expected.json +89 -0
- package/conformance/cases/c75-projects-patch-remote-uniqueness/input.json +35 -0
- package/conformance/cases/c75-projects-patch-remote-uniqueness/meta.json +5 -0
- package/dist/api/feedback.js +2 -3
- package/dist/api/scopes.js +2 -1
- package/dist/atomic-write.d.ts +7 -1
- package/dist/atomic-write.js +43 -5
- package/dist/cli.d.ts +34 -6
- package/dist/cli.js +80 -130
- package/dist/config-d-file.d.ts +11 -0
- package/dist/config-d-file.js +35 -1
- package/dist/config-dir-io.d.ts +2 -0
- package/dist/config-dir-io.js +14 -0
- package/dist/config-dir-migration.d.ts +67 -0
- package/dist/config-dir-migration.js +181 -0
- package/dist/cross-domain.d.ts +8 -3
- package/dist/cross-domain.js +23 -13
- package/dist/file-edit.js +7 -5
- package/dist/file-store.js +2 -1
- package/dist/fleet.js +3 -4
- package/dist/hooks.d.ts +14 -1
- package/dist/hooks.js +61 -16
- package/dist/host-path.d.ts +17 -0
- package/dist/host-path.js +22 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/integer.js +2 -1
- package/dist/local-load.d.ts +1 -1
- package/dist/local-load.js +9 -31
- package/dist/migration-receipt.d.ts +3 -2
- package/dist/node.d.ts +2 -0
- package/dist/node.js +3 -0
- package/dist/one-time-migrations.d.ts +5 -3
- package/dist/one-time-migrations.js +21 -7
- package/dist/previous-web-admin-env.d.ts +15 -0
- package/dist/previous-web-admin-env.js +20 -0
- package/dist/quoted-issue.d.ts +41 -0
- package/dist/quoted-issue.js +35 -0
- package/dist/remote-exec.d.ts +3 -0
- package/dist/remote-exec.js +12 -7
- package/dist/retired-envs.js +13 -2
- package/dist/retired-form.d.ts +6 -1
- package/dist/retired-form.js +10 -2
- package/dist/rfc3339.d.ts +10 -0
- package/dist/rfc3339.js +12 -0
- package/dist/runtime-lift-targets.d.ts +7 -0
- package/dist/runtime-lift-targets.js +7 -0
- package/dist/shell-quote.d.ts +1 -0
- package/dist/shell-quote.js +14 -0
- package/dist/types.d.ts +140 -20
- package/dist/types.js +224 -114
- package/dist/web-admin-credential.d.ts +2 -2
- package/dist/web-admin-credential.js +5 -10
- package/dist/web-admin-env.d.ts +2 -1
- package/dist/web-admin-env.js +2 -1
- package/dist/web-admin-session-url.d.ts +17 -0
- package/dist/web-admin-session-url.js +64 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,157 @@
|
|
|
6
6
|
> `@sema-agent/registry-core`(更早还曾是 `@sema-ai/registry-core`)。本档 `0.19.0` 以下各节里的
|
|
7
7
|
> 包名是**历史记录**,如实保留不追改。
|
|
8
8
|
|
|
9
|
+
## 11.3.0 — 2026-10-11 — 六件 additive:运行期成员表三张(AUTONOMY_MODES / COMMAND_DECISIONS / PROMPT_SLOTS)· 项目登记扩形(goal / contextItems / archivedAt / icon / color,displayName 上界 200)+ PATCH 形 · 命令行环境错一臂(I/O 错 rc 2 一句点名路径)· 一次性迁移 SS-M7 走到 remote-exec.json · 每条自铸 custom issue 带结构化句子(QuotedIssueParams)· hookMatcherForm(minor:新导出主桶 19 / hooks 2 / remote-exec 1 / node 1 型,零删零改名)
|
|
10
|
+
|
|
11
|
+
> 本节六件,全部 additive(零删导出、零改名;minor):运行期成员表三张 · 项目登记扩形 + PATCH 形 · 命令行环境错一臂 · 一次性迁移 SS-M7 走到 `remote-exec.json` ·
|
|
12
|
+
> 每条自铸 custom issue 一律带结构化句子 · `hookMatcherForm`。新导出:主桶 19 个(其中 16 个也在 `./types`)、`./hooks` 2 个、`./remote-exec` 1 个、`./node` 1 个型。
|
|
13
|
+
> 消费方:server 7.125.0 提货(读点见各条);web-admin 的 projects 编辑面跟扩形。
|
|
14
|
+
|
|
15
|
+
### 新导出:运行期成员表 `AUTONOMY_MODES` / `COMMAND_DECISIONS` / `PROMPT_SLOTS`
|
|
16
|
+
|
|
17
|
+
与 `REF_CHECKED_DOMAINS` 同形:`as const` 只读数组是正本,zod enum(`AutonomyMode` / `CommandDecision` / `PromptSlot`)与类型都从表派生 ——
|
|
18
|
+
`governance.autonomy`、`commandPolicy[].decision`、提示声明与 catalog 的 `slot` 引用的就是这几只 enum(同词同序,判法不变)。
|
|
19
|
+
- **谁要改**:server 今天经 `GovernanceConfig.shape.autonomy.unwrap().options` / `….commandPolicy.unwrap().element.shape.decision.options` 取词表,提示域校验手抄一份三词槽位表 —— 换成 import 这三张表。
|
|
20
|
+
|
|
21
|
+
### 新导出:项目登记 additive 扩形 —— `goal` / `contextItems` / `archivedAt` / `icon` / `color`,`displayName` 上界 120 → 200;PATCH 形
|
|
22
|
+
|
|
23
|
+
`ProjectRegistration` 原六键不改名,加五个可选键:`goal`(≤ 2000)、`contextItems`(≤ 64 条,`{ kind: "folder" | "file" | "note", value }`;folder / file 的值过
|
|
24
|
+
**与任务 `cwd` 同一只**主机路径形判官 `isAbsoluteHostPath` —— 非空、≤ 4096、无 NUL、以 `/` 开头、无 `..` 段;note ≤ 4000)、`archivedAt`(RFC 3339 时刻,与凭证信封
|
|
25
|
+
`expiresAt` 同一只判)、`icon`(`^[a-z][a-z0-9-]{0,63}$`)、`color`(`^#[0-9a-f]{6}$`)。`displayName` 上界放宽到 200(放宽 = 旧数据全部照读)。
|
|
26
|
+
上界常量导出:`PROJECT_LIMITS`、`ABSOLUTE_HOST_PATH_MAX`、`PROJECT_ICON_REGEX`、`PROJECT_COLOR_REGEX`、`PROJECT_CONTEXT_ITEM_KINDS` —— 读方 import,不手抄数字。
|
|
27
|
+
PATCH 形 `ProjectRegistrationPatch`(strict:`registeredBy` / `registeredAt` 与未知键拒;可选键给 `null` = 清掉,如 `archivedAt: null` 取消归档)+ `applyProjectPatch(doc, id, patch)`:
|
|
28
|
+
它先自己按 PATCH 形判入参(调用方原样递进请求体也改不了 `registeredBy` / `registeredAt`、带不进未知键;失败的坐标是文档坐标 `projects.<id>.…`),
|
|
29
|
+
合并后由**同一只** `ProjectsConfig`(同一个 remote 全局唯一判)整文档再判,被改的项目排在最后判 —— 冲突恒落在被改的项目上、句子点名已占用的项目;成功时保持原键序;
|
|
30
|
+
没登记的 id ⇒ 抛(调用方先答「没有这个项目」)。一致性语料 +3(合法扩形 / 超界拒 / PATCH 形 remote 唯一)。
|
|
31
|
+
- **谁要改**:server 的项目读写面读新键与这些常量、PATCH 走 `applyProjectPatch`;server 受理任务 `cwd` 的形判改调 `isAbsoluteHostPath`(同一条律,posix 宿主上与现判逐字同);
|
|
32
|
+
web-admin 的 projects 编辑面渲染 / 写新键,`displayName` 输入上界跟到 200。
|
|
33
|
+
|
|
34
|
+
### 行为修复:命令行退出码闭集补「环境错」一臂(rc 2)
|
|
35
|
+
|
|
36
|
+
`migrate` 写回阶段的 I/O 错(写盘 / 删文件:权限、磁盘、悬空符号链接……)以前原样抛出 —— Node 打裸栈、进程 rc 1,而 rc 1 是 `outcome=refused`(拒迁)的约定码,
|
|
37
|
+
只看 rc 的脚本会把权限错读成「拒绝迁移」。现在并入 rc 2(与读目录 / 读文件错同一臂):stdout 空,stderr **一行**点名要写的那份文件与原错误句(含 errno 码),不打栈;
|
|
38
|
+
之前已写完的文档留在新形上,修好再跑一次幂等收尾。函数形 `migrateConfigDirectory` 的契约不变(写回阶段的 I/O 错仍原样抛给调用方)。
|
|
39
|
+
读阶段遇**悬空符号链接**(域文件或 `config.d` 目录本身):读口先过原子写器同一只链接判法,句子与写器**同一句**(以前读阶段先撞 ENOENT,句子不提链接)。
|
|
40
|
+
写器那一句的措辞随之改成读写通用(去掉 `writeFileAtomic:` 前缀;判法与抛不抛都不变)。
|
|
41
|
+
|
|
42
|
+
### 行为变:一次性迁移 SS-M7(URL fragment)走到 `config.d/remote-exec.json`
|
|
43
|
+
|
|
44
|
+
`remote-exec.json` 的两个端点(k8s `apiUrl`、`s3Snapshot.endpoint`)与域文档里的 URL 座位改为同一只带迁移指路的判官:规则句不变,fragment 拒句尾多一句 SS-M7 指路;
|
|
45
|
+
座位仍由 schema 派生(`urlSeatPatterns()` 多两行)。命令行 `migrate` 把 `remote-exec.json` 当又一份文档:读(文本判与 `loadRemoteExec` 同一只)、剥 fragment、
|
|
46
|
+
改过的整文档终判、写回(与 `writeRemoteExec` 同一只原子写器、同一种文本形)。收据的 `document` 闭集多一个 `remote-exec`;文档名的唯一拼写导出为 `REMOTE_EXEC_DOCUMENT`;
|
|
47
|
+
`migrateConfigDirectory` 的覆盖面可含它(`./node` 的型 `ConfigDirectoryDocument`)。凭证信封的 `issuer` 是 wire 输入、不是存量,不走迁移,拒句照旧不指路。
|
|
48
|
+
11.0.0 起披露的「`remote-exec.json` 里带 `#` 的端点只能手改」就此收口。
|
|
49
|
+
- **行为变(命令行)**:目录里只有 `remote-exec.json`(外加非文档条目)时,以前报「没有域文档」rc 2,现在读到了文档、零改动 ⇒ `noop` rc 0;
|
|
50
|
+
`remote-exec.json` 是空 / 坏 JSON 时,以前命令行不读它,现在与其它文档一样 ⇒ 读不进 rc 2(这样的文件引擎读侧本就拒)。
|
|
51
|
+
- **谁要改**:server 起服的本地目录迁移若要一并迁 `remote-exec.json`,把它加进覆盖面(读回面本就读它);不加则照旧只由命令行迁。
|
|
52
|
+
|
|
53
|
+
### 新契约:本包自铸的每一条 custom issue 都带结构化句子 `QuotedIssueParams`
|
|
54
|
+
|
|
55
|
+
全包只剩一只铸点:每条 `code: "custom"` 的 issue(`.refine` / `z.custom` / `addIssue` / 合成 issue / 引用完整性 `RefIssue`)都带 `params.template` + `params.operands`
|
|
56
|
+
(值位是洞),`message` 由 `renderQuotedSentence` 从它渲出、铸点不手写第二遍;没有值的定句 `operands` 为空。句子逐字不变。URL 形判官的 issue 的 `params` 是
|
|
57
|
+
`{ template, operands, flaw }`(`flaw` = 判官的规则词,保留);`RefIssue` 加 `params`,`renderRefIssue` 经同一只渲染器。不在此列的(如实):zod 内建码的 issue ——
|
|
58
|
+
`.max(n, 句)` / `.regex(re, 句)`、墓碑字段的 `invalid_type`、联合的错误映射 —— 它们的句子是定句、读 `message`。
|
|
59
|
+
- **谁要改**:server 读 issue 句子的那一处对 custom issue 可以只读 `params`(不再退回 `message`);zod 内建码的 issue 照旧读 `message`。
|
|
60
|
+
|
|
61
|
+
### 新导出:`hookMatcherForm(matcher)` —— `"literal" | "regex" | "invalid"`
|
|
62
|
+
|
|
63
|
+
与 `hookMatcherSelects` 调**同一只解析步**(不另写判形):缺席 / `""` / `"*"`(选中一切)与名字表形 = `literal`(不编、不跑正则),其余编得出的 = `regex`(不锚定),
|
|
64
|
+
编不出 = `invalid`;对任一 matcher,`hookMatcherForm === "invalid"` ⇔ `hookMatcherSelects(…) === "invalid"`。给要在求值前分流的调用方(字面形直接跑、正则形进有预算的求值)。
|
|
65
|
+
- **谁要改**:server 的 hooks 执行器今天自带一只「无回溯形」判断(字符扫描)决定要不要进预算求值,改问这一只后删掉自带的。
|
|
66
|
+
|
|
67
|
+
## 11.2.0 — 2026-10-10 — 六小件:SEMA_REGISTRY_* 八名加回退役墓碑(换名窗期与保留表交集写明)· 断言令牌 / 凭证文件键进保留表 · 会话网页链接模板函数与配对解析 · CLI 命令路径 shell 引用 · 原子写器保留符号链接 · node 侧目录迁移函数导出(minor:新导出与新墓碑行,零删零改名)
|
|
68
|
+
|
|
69
|
+
> 本节六件:上一代连接名 `SEMA_REGISTRY_*` 八名进墓碑表(硬破坏,读侧同代要求)· 断言令牌两键进保留 env 名表 · 会话网页链接模板函数与配对解析 · 命令行印出的命令路径加 shell 引用 ·
|
|
70
|
+
> 原子写器遇符号链接保留链接 · 目录形迁移函数导出。新导出:主桶 3 个(会话链接)、`./node` 6 个(目录迁移),其余零新导出;唯一的硬破坏是第一件。
|
|
71
|
+
|
|
72
|
+
### 硬破坏:上一代 web-admin 连接名 `SEMA_REGISTRY_*` 八名进墓碑表(读侧同代要求)
|
|
73
|
+
|
|
74
|
+
`RETIRED_ENVS` 加八行 `renamed` 墓碑:`SEMA_REGISTRY_URL` / `_TOKEN` / `_TOKEN_FILE` / `_WORKER` / `_LIVE_URL` / `_WEB_URL` / `_DRY_RUN` / `_ADMIN_TOKEN`,去向各是 `WEB_ADMIN_ENV` 同键的现名
|
|
75
|
+
(`SEMA_WEB_ADMIN_*`,一跳)。进表的判据没变 —— 没有任何受支持的引擎还读这个名:11.0.0 把现名换进 `WEB_ADMIN_ENV` 时,在跑的引擎还把这八个名当活旋钮读,所以当时不登记;
|
|
76
|
+
引擎换读现名之后的这一版加回。旧名在场即拒启(替代名设没设都一样,空串 = 未设),`WorkerSpec` 的 `env` / `secretEnv` 写闸同拒(拒句就是墓碑句 `retiredEnvRefusal`),
|
|
77
|
+
读侧 `readWorkersRows` 把带着它们的存量行逐行扣下,目录 wire 的 `retired[]` 多这八行(`buildRetiredEnvWire()` 同表派生,零代码改动)。上一代名字面只在包内私有的一处写一次,
|
|
78
|
+
墓碑行与保留表都从那里取,去向从 `WEB_ADMIN_ENV` 取、不手抄;包根不多导出任何名字。
|
|
79
|
+
|
|
80
|
+
- **读侧同代要求**:server ≥ 7.124.0 起才拒旧名;更老的 server 仍把它们当活旋钮读。给 worker 渲染 env 的一方(web-admin 渲染器)按**目标引擎的代**写名 ——
|
|
81
|
+
目标引擎 ≥ 7.124.0 写 `SEMA_WEB_ADMIN_*`,只有还读上一代名的引擎才写上一代名(混版本车队按目标版本渲)。
|
|
82
|
+
- **谁受影响**:部署里仍设着 `SEMA_REGISTRY_*` 的运维(server ≥ 7.124.0 拒启);在 worker 规格的 `env` / `secretEnv` 里自写其中任一名的(写闸拒;11.0.0 时这八名里只有 URL / WORKER / TOKEN 三名被拒,
|
|
83
|
+
其余五名照收,现在八名都拒);存量里带着它们的 worker 行(读侧扣下、在列表里标红)。
|
|
84
|
+
- **怎么改**:把这八个名字改成同键的现名(`SEMA_WEB_ADMIN_URL` 等);worker 规格里自写的删掉(渲染器会写)。
|
|
85
|
+
- **不改会怎样**:server ≥ 7.124.0 拒启,拒句点名旧名与现名;存量 worker 行读侧被扣下。
|
|
86
|
+
|
|
87
|
+
**两张表答两个问题,交集是窗期形,终态是零交集**:
|
|
88
|
+
- 保留表 `RESERVED_WORKER_ENV` =「规格作者可不可以自己设这个名」(不可以:渲染器 / 编排器写它,或某个结构字段产出它,或它与渲染器 / 编排器写的名互斥);
|
|
89
|
+
- 墓碑表 `RETIRED_ENVS` =「带着这张表的引擎还读不读这个名」(≥ 7.124.0 的引擎不读、见之拒启)。≤ 7.123.0 的引擎内带的是 10.1.1,看不见本版的表、仍读上一代名 ——
|
|
90
|
+
所以墓碑的进表判据读作「没有带着本表的引擎还读这个名」。
|
|
91
|
+
- **窗期**:渲染器对 ≤ 7.123.0 的目标引擎仍写上一代的 `URL` / `WORKER` / `TOKEN`(`TOKEN_FILE` 与 `TOKEN` 互斥,同组同入),这四名既是保留名也是墓碑,写闸交两句(墓碑句在前、保留句在后,
|
|
92
|
+
保留句与现名同一结构位);另外四名(`LIVE_URL` / `WEB_URL` / `DRY_RUN` / `ADMIN_TOKEN`)没有谁写、也不与谁互斥,只是墓碑。窗期交集是个写死的闭集,有钉盯着。
|
|
93
|
+
- **窗关即终态**:web-admin 渲染器不再对任何目标引擎写上一代名之后(此后没有引擎要读它们),这四名离开保留表,两表回到**零交集** —— 11.0.0 记的「老三名搬去墓碑表」就是这个终态,不是本版。
|
|
94
|
+
那一刻窗期交集那一钉翻回零交集,保留名增词账里记删词。
|
|
95
|
+
|
|
96
|
+
### 行为变:断言令牌(`wat_`)的两个声明键与主凭证的文件键进保留 env 名表
|
|
97
|
+
|
|
98
|
+
`RESERVED_WORKER_ENV` 加三名:`SEMA_WEB_ADMIN_ASSERTION_TOKEN`(值键,编排器注入)、`SEMA_WEB_ADMIN_ASSERTION_TOKEN_FILE` 与 `SEMA_WEB_ADMIN_TOKEN_FILE`(两把凭证的文件键,只给不经编排器的手接引擎、由运维直设)。
|
|
99
|
+
文件键与同一份凭证的值键互斥(`judgeWebAdminCredentialDeclaration(env, "assertion" | "access")`:一对里两个都设 ⇒ 拒启),规格里写了任一个就与渲染器 / 编排器注入的值键撞 —— 主凭证与断言令牌是同一条规则,所以同一个答案。名字取自 `WEB_ADMIN_ENV`。
|
|
100
|
+
换名窗里上一代的 `SEMA_REGISTRY_TOKEN_FILE` 与老三名同组同入(见上一节)。`WorkerSpec` 的 `env` / `secretEnv` 写闸同拒,拒句点名各自的出路:值键 ⇒ 「由编排器注入」,文件键 ⇒ 「由运维直设,不经 worker 规格」
|
|
101
|
+
(句尾仍是 `set it via <出路>`);读侧 `readWorkersRows` 把带着它们的存量行逐行扣下。
|
|
102
|
+
|
|
103
|
+
- **谁受影响**:在 worker 规格的 `env` / `secretEnv` 里自写这三个名字的(此前照收;引擎起服时与注入的凭证撞而拒启)。
|
|
104
|
+
- **怎么改**:从规格里删掉;值由编排器注入,不经编排器的手接引擎由运维在引擎进程环境里直设。
|
|
105
|
+
- **不改会怎样**:写闸拒;存量行读侧被扣下、在列表里标红。
|
|
106
|
+
|
|
107
|
+
### 新增:会话网页链接的一只模板函数与它的配对解析(`webAdminSessionUrl` / `parseWebAdminSessionUrl`)
|
|
108
|
+
|
|
109
|
+
web-admin 里一个会话的网页链接此前由各处按地址形手拼(把别仓的路由抄成自己的字符串)。路由属于 web-admin,现形是 `<webBaseUrl>/chat?agent=<worker>&session=<sessionId>`
|
|
110
|
+
(聊天页只读这两个查询参数;只带 `session` 的链接会落到页面自己挑的 worker 上,会话不在那一台就落空)。新导出(主桶,纯函数、浏览器安全,additive):
|
|
111
|
+
|
|
112
|
+
- `webAdminSessionUrl(webBaseUrl, { worker, sessionId })` —— 两位必填(空 / 缺位 / 非串 ⇒ 抛 `TypeError`),逐位 `encodeURIComponent`(含 `&` `#` `=` `?` 的 id 不串位;孤立代理项 ⇒ `URIError`,不静默替换),
|
|
113
|
+
基址须是干净的绝对 http(s) URL(无 userinfo / query / fragment,可带路径前缀,尾斜杠折掉;判的是 `NON_SECRET_URL` 同一只形判官),返回绝对 URL。
|
|
114
|
+
- `parseWebAdminSessionUrl(link)` —— 配对解析,收绝对 / 相对串、`URL`、`URLSearchParams`;宽读(旧链接可能缺 `agent`):缺的或空的那一位不出现在结果里,重复参数取第一个,路径与别的参数不看;串不是 URL ⇒ 抛 `TypeError`。
|
|
115
|
+
- 型 `WebAdminSessionTarget`(`{ worker, sessionId }`)。
|
|
116
|
+
|
|
117
|
+
往返钉:任意含特殊字符的 (worker, sessionId) 经模板再经解析逐位还原。链接没有 scope 位;日后加 scope 时作可选第三位、同一函数。
|
|
118
|
+
- **谁需要**:要给用户一个会话链接的壳 / 客户端 / 服务端文档;web-admin 聊天页的深链读写改读配对解析(路径与参数名只此一份)。
|
|
119
|
+
- **谁受伤**:无(纯增)。已手拼 `…/chat?session=<id>` 的调用方到货改调(只带 `session` 的形今天就会落空)。
|
|
120
|
+
|
|
121
|
+
### 行为变:命令行印出的命令,路径按 shell 单引号规则引用
|
|
122
|
+
|
|
123
|
+
`migrate` 命令的 stderr 指路句(上一层目录里 `config.d` 在场时,「`<目录>/config.d` exists — run: …」)此前把路径原样接在命令后面:配置根路径含空格(或引号、`$`)的运维照原样粘贴,
|
|
124
|
+
shell 把路径拆成多个参数 ⇒ 用法行 rc 2。现在印出的命令里路径过一只 `shellQuote`(POSIX 单引号规则;只有 ASCII 字母数字与 `_ @ + : , . / -` 组成的串原样不加引号,其余整串单引号包起来,
|
|
125
|
+
串里的 `'` 写成 `'\''`;空串写成 `''`),指路句可以直接粘贴跑通。用法行与迁移指路句里的 `<config.d directory>` 是元变量,不是参数,原样不引用(这两处的句子逐字不变)。
|
|
126
|
+
命令的拼写收在一处(带占位的模板 / 带真路径的函数),别处不再各自拼。无新导出(`shellQuote` 包内私有)。
|
|
127
|
+
- **谁需要**:配置根路径含空格 / 特殊字符的运维与脚本。
|
|
128
|
+
- **谁受伤**:按字面比对该指路句的脚本 —— 路径含特殊字符时句子里的路径多了引号;路径在安全字符集内的句子逐字不变。
|
|
129
|
+
- **补偿**:无需;要路径本身,去掉引号即可(引用遵循 POSIX shell,Windows cmd.exe 不认单引号)。
|
|
130
|
+
|
|
131
|
+
### 行为变:写盘处遇符号链接 —— 保留链接、更新目标(悬空链接响亮拒)
|
|
132
|
+
|
|
133
|
+
`config.d` 里的域文件若是符号链接(运维用链接把 `config.d` 指到别处管理的部署),写盘处此前在链接所在目录建临时文件再 `rename` 盖到链接路径上:链接本身被换成普通文件、链接目标不动 ——
|
|
134
|
+
写一次后链接断,以后两份漂移。现在那一只原子写器(`writeDomainFile` / `writeRemoteExec` / 调度店 / 命令行迁移写器都调它)先把目标解析到真文件(`realpath`),临时文件建在**真文件所在目录**、
|
|
135
|
+
rename 到真文件:链接(及链上每一环)原样保留,真文件内容更新,文件模式规则作用在真文件上。临时文件与真文件同目录 ⇒ rename 不会跨文件系统;真文件所在目录写不进、或 rename 因别的原因失败 ⇒
|
|
136
|
+
响亮抛,**绝不**退回成「在链接位置写一个普通文件」(那是静默换形)。路径本身是悬空链接 ⇒ 响亮抛(消息点名这条链接与它指向的位置),既不在链接位置建普通文件,也不替链接建它指向的文件;成环的链接抛 `ELOOP`。
|
|
137
|
+
目标不存在 ⇒ 新建(经符号链接的目录写新文件时,文件落在真目录里)。
|
|
138
|
+
- **谁需要**:用符号链接管理 `config.d` 域文件的部署(迁移命令、`writeDomainFile` 写一次后链接不再被换掉)。
|
|
139
|
+
- **谁受伤**:(1) 域文件是悬空链接的 —— 此前写成功(并把链接换成普通文件),现在抛;(2) 链接指向的真文件所在目录对进程不可写的 —— 此前写进链接所在目录成功(链接被换形),现在抛。
|
|
140
|
+
- **补偿**:修好或删掉悬空链接;让进程对真文件所在目录可写,或去掉链接改用普通文件。
|
|
141
|
+
|
|
142
|
+
### 新增:目录形迁移函数导出(`migrateConfigDirectory` / `nodeConfigDirectoryIo`,`./node`)
|
|
143
|
+
|
|
144
|
+
「读目录 → 迁 → 整域终判 → 原子写 → 删退役域文件」这条语义此前只活在命令行里,没有覆盖面开关、没导出 —— 引擎起服对本地 `config.d` 的迁移只能按同语义自写一份(读法 / 写法 / 模式规则各一小段)。
|
|
145
|
+
现在语义只此一处:`./node` 导出 `migrateConfigDirectory(dir, { documents, io, check? })`,命令行成了它的渲染器(退出码与报告行),引擎调同一只函数。新导出(additive,`./node` 子路径):
|
|
146
|
+
`migrateConfigDirectory`、真 I/O 绑定 `nodeConfigDirectoryIo`(`node:fs` + 本包唯一的原子写器与它的模式表)、型 `ConfigDirectoryIo` / `ConfigDirectoryMigration` / `ConfigDirectoryRefusal` / `MigrateConfigDirectoryOptions`。
|
|
147
|
+
|
|
148
|
+
- **覆盖面 = 调用方读的域名集**(`documents`):覆盖面外的文件不读、不判、不写、不删,它们是坏文件也挡不住覆盖面内的迁移;拼错的名字抛 `TypeError`。命令行的覆盖面是全部配置域加退役域。
|
|
149
|
+
**迁移不越过覆盖面去写**:退役的 `runtime` 域迁出时要写 `governance` 与 `limits`,覆盖面没把这两个域一并包进来(只含 `runtime`,或只含其中一个)时,目录算不上「一个 scope 的全集」,
|
|
150
|
+
`runtime` 的迁移以收据 `refused` 拒迁、一字不写 —— 不会把覆盖面外已有的 `governance.json` / `limits.json` 当作「从未设过」覆盖掉;
|
|
151
|
+
日后若别的迁移步新建覆盖面外的文档,函数响亮抛(守卫),不静默写。要迁 `runtime`,覆盖面里放齐 `runtime`、`governance`、`limits`。
|
|
152
|
+
- **结果是一个闭集**(调用方穷举):`unreadable`(读不了目录 / 文件,或某份文档是坏文件;一字不写)· `no-documents`(覆盖面内一份文档都没有;带回目录清单,调用方自己判「填错了目录」还是「真空」)·
|
|
153
|
+
`refused`(迁移步拒,或要写回的文档整域读不进;一字不写)· `noop` · `pending`(`check: true` 且有改动;一字不写)· `applied`(带写了哪些、删了哪些;先写后删,中途断掉再跑幂等)。
|
|
154
|
+
写盘阶段的 I/O 错误原样抛出。
|
|
155
|
+
- **命令行行为逐字不变**:既有命令行钉全绿(退出码、stdout 两行、stderr 句子);并有一道钉盯着「命令行没有自己的语义」—— 对仓内一致性语料的**每个 case 目录**,`migrate` 与 `migrate --check`
|
|
156
|
+
经命令行和直接调 `migrateConfigDirectory` 的退出码 / stdout / stderr / 落盘字节逐字同(函数这一边的期望由一只独立的小渲染器算出;语料的结局分布也被钉住,五形都有样本),
|
|
157
|
+
外加真 bin × 真 I/O 绑定的磁盘端到端对拍;唯一有意的差别是上面「命令行印出的命令」那一条的路径引用。
|
|
158
|
+
- **谁需要**:对本地 `config.d` 做一次性迁移的进程(引擎起服)。**谁受伤**:无(纯增)。已自写同语义一份的调用方到货改调、删掉自写段。
|
|
159
|
+
|
|
9
160
|
## 11.1.0 — 2026-10-10 — 11.0.0 持久面三件收口:URL fragment 拒句补迁移指路 + 全称律源码钉 · 迁移命令对零域文档目录响亮拒 · 写盘处收成一只原子写器与模式表(minor:一个新导出,零删零改名)
|
|
10
161
|
|
|
11
162
|
> 本节三件,都是对 11.0.0 持久面的收口:拒句补指路、迁移命令填错目录响亮拒、写盘处收成一只。一个新导出(`NON_SECRET_URL_NO_MIGRATION`,additive),零删零改名。
|
package/README.md
CHANGED
|
@@ -74,6 +74,11 @@ therefore shows only `zod`. Node built-ins only (`node:crypto`, `node:fs`).
|
|
|
74
74
|
`--check` 有改动退出 3)。参数是 `config.d` 目录**本身**(里面直接放 `<域>.json`):目录里有条目却没有一份域文档 —— 填成了它的上一层、只有
|
|
75
75
|
`remote-exec.json` 之类非域文件 —— 退出 2、stdout 空,stderr 点名这个目录(`<目录>/config.d` 在场就直接点它);目录真空(零条目,或只有以 `.` 开头的条目)是合法态
|
|
76
76
|
(新部署的空 `config.d`),和「有域文档、只是没有要改的」一样是 noop、退出 0。
|
|
77
|
+
- **目录形的函数**(`./node`):`migrateConfigDirectory(dir, { documents, io, check? })` 是命令行背后的那只函数 —— 「读目录 → 迁 → 整域终判 → 原子写 → 删退役域文件」这条语义只此一处,
|
|
78
|
+
命令行只是它的渲染器(退出码 + 报告行),要对本地 `config.d` 做同一件事的进程(比如引擎起服)调它,不按同语义自写一份。`documents` = 调用方读的域名集(覆盖面:覆盖面外的文件不读、不判、不写、不删);
|
|
79
|
+
覆盖面要迁 `runtime` 就得把 `governance` 与 `limits` 一并放进来(迁出的旧值要写那两份,不能覆盖面外去写;缺了就按 `partial` 拒迁 `runtime`、一字不写)。
|
|
80
|
+
`io` 注入 `{ readDir, readFile, writeFileAtomic, removeFile }`,真绑定是 `nodeConfigDirectoryIo`(`node:fs` + 本包唯一的原子写器与它的模式表)。返回一个闭集
|
|
81
|
+
(`unreadable` / `no-documents` / `refused` / `noop` / `pending` / `applied`),调用方穷举;写盘阶段的 I/O 错误原样抛出(已写完的留在新位上,再跑一次幂等收尾)。
|
|
77
82
|
- **迁什么**(七条,`ONE_TIME_MIGRATIONS` 每行写着改写规则、删法、删后由谁接住):退役 `runtime` 域(治理三闸 → `governance`、五个限额键 → `limits`)·
|
|
78
83
|
hosts 超界 · 调度店 durable 键(读时改写,下一个写者落盘)· workers 6.x 行 · 模型钥匙双设 · `atModelAllowlist` → `atMention` · URL fragment。
|
|
79
84
|
- **什么时候删**:每条的窗 = 11.0.0 发布日 + 30 天,窗关之后的那个 major 整族删(删法与删后的响亮臂见登记表那一行);本包的到期门到点即红。
|
|
@@ -295,7 +300,8 @@ therefore shows only `zod`. Node built-ins only (`node:crypto`, `node:fs`).
|
|
|
295
300
|
`WebAdminCredentialEnvelope` (strict JSON: `kind: "user-session"` = `WEB_ADMIN_CREDENTIAL_ENVELOPE_KIND`, a JWT
|
|
296
301
|
`accessToken` and a `refreshToken` under the same token law as the bare line, RFC 3339
|
|
297
302
|
`expiresAt` with seconds and a `Z` / `±hh:mm` offset in range, `issuer` = the issuing web-admin's base URL judged
|
|
298
|
-
by the
|
|
303
|
+
by the URL shape judge for seats no one-time migration reaches (`NON_SECRET_URL_NO_MIGRATION` — the issuer is a wire input, not stored
|
|
304
|
+
data) — same-origin is the reader's comparison).
|
|
299
305
|
`parseWebAdminCredentialFile(text)` is the ONE discrimination law — trimmed text starting with `{` is read ONLY
|
|
300
306
|
as an envelope (a failure is `unreadable`, never a fallback to a bare line); anything else is a bare line,
|
|
301
307
|
and a first line that is not a token is `unreadable` too (never sent as a bearer); empty is `unreadable`. The `reason` names envelope fields / zod issue codes / an unknown-key COUNT, never file
|
|
@@ -308,6 +314,13 @@ therefore shows only `zod`. Node built-ins only (`node:crypto`, `node:fs`).
|
|
|
308
314
|
no default) → `env` / `file` / `absent`, the one pick-exactly-one rule for every credential: an empty string is unset, BOTH set (non-empty) throws (the refusal
|
|
309
315
|
names the two keys, never a value), the file path comes back verbatim (resolving a relative one against a cwd
|
|
310
316
|
is the reader's job).
|
|
317
|
+
- **Session web link** (`web-admin-session-url.ts`, main barrel): `webAdminSessionUrl(webBaseUrl, { worker, sessionId })` — the ONE
|
|
318
|
+
template for a web-admin session link, `<webBaseUrl>/chat?agent=<worker>&session=<sessionId>`: both parts required (a link with only
|
|
319
|
+
the session id lands on whichever worker the page picks and may not find it), each part `encodeURIComponent`-escaped, the base a
|
|
320
|
+
clean absolute http(s) URL (trailing slashes folded; userinfo / query / fragment refused), the result absolute; bad input throws,
|
|
321
|
+
never a half link. `parseWebAdminSessionUrl(link)` is its paired reader (absolute / relative string, `URL` or `URLSearchParams`;
|
|
322
|
+
a missing or empty part is simply absent from the result) — the page and every link-minting caller share this one definition of the
|
|
323
|
+
route and the parameter names. No scope part today; a scope would be an optional third part of the same function.
|
|
311
324
|
- **Retired env names** (`retired-envs.ts`, main barrel): `RETIRED_ENVS` — the ONE tombstone table (literal tuples
|
|
312
325
|
`[old, to, "renamed"]` / `[old, to, "replaced", why]` / `[old, why, "removed"]`, a closed set of three families,
|
|
313
326
|
frozen). A tombstone is permanent: the old name present ⇒ refuse to start, whether or not the replacement is also
|
package/bin/settings-schema.mjs
CHANGED
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// `settings-schema` — this package's command line (`migrate <config.d directory> [--check]`, the one-time migrations).
|
|
3
3
|
// The real-I/O injection point: the logic is `runSettingsSchemaCli` (dist/cli.js), which never touches the filesystem itself — this
|
|
4
|
-
// entry hands it
|
|
5
|
-
// is written and with what mode
|
|
6
|
-
|
|
4
|
+
// entry hands it the package's one directory-migration I/O binding (dist/config-dir-io.js: directory / file reads and removal, and
|
|
5
|
+
// writes through the one atomic writer, dist/atomic-write.js, which alone decides how a file is written and with what mode) plus the
|
|
6
|
+
// two output streams.
|
|
7
7
|
import { runSettingsSchemaCli } from "../dist/cli.js";
|
|
8
|
-
import {
|
|
8
|
+
import { nodeConfigDirectoryIo } from "../dist/config-dir-io.js";
|
|
9
9
|
|
|
10
10
|
const io = {
|
|
11
|
-
|
|
12
|
-
readFile: (path) => readFile(path, "utf8"),
|
|
13
|
-
// the files this command writes are config.d domain documents
|
|
14
|
-
writeFileAtomic: async (path, text) => writeFileAtomic(path, text, "config-document"),
|
|
15
|
-
removeFile: (path) => unlink(path),
|
|
11
|
+
...nodeConfigDirectoryIo,
|
|
16
12
|
stdout: (text) => process.stdout.write(text),
|
|
17
13
|
stderr: (text) => process.stderr.write(text),
|
|
18
14
|
};
|
package/conformance/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
11.
|
|
1
|
+
11.3.0
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
{
|
|
2
|
+
"domains": {
|
|
3
|
+
"outcome": "effective",
|
|
4
|
+
"effective": {
|
|
5
|
+
"collab": {
|
|
6
|
+
"templates": []
|
|
7
|
+
},
|
|
8
|
+
"entitlement": {
|
|
9
|
+
"budgetGroups": [],
|
|
10
|
+
"groupBindings": [],
|
|
11
|
+
"subjects": [],
|
|
12
|
+
"tiers": []
|
|
13
|
+
},
|
|
14
|
+
"execution": {
|
|
15
|
+
"allowedLanes": [
|
|
16
|
+
"host"
|
|
17
|
+
],
|
|
18
|
+
"required": false
|
|
19
|
+
},
|
|
20
|
+
"governance": {},
|
|
21
|
+
"hosts": {
|
|
22
|
+
"hosts": []
|
|
23
|
+
},
|
|
24
|
+
"limits": {},
|
|
25
|
+
"mcp": {
|
|
26
|
+
"servers": []
|
|
27
|
+
},
|
|
28
|
+
"models": {
|
|
29
|
+
"atMention": {
|
|
30
|
+
"mode": "all"
|
|
31
|
+
},
|
|
32
|
+
"models": [],
|
|
33
|
+
"roles": {},
|
|
34
|
+
"tierGroups": []
|
|
35
|
+
},
|
|
36
|
+
"plugins": {
|
|
37
|
+
"plugins": []
|
|
38
|
+
},
|
|
39
|
+
"projects": {
|
|
40
|
+
"projects": {
|
|
41
|
+
"01890a5d-ac96-774b-bcce-b302099a8057": {
|
|
42
|
+
"archivedAt": "2026-10-11T08:00:00.000Z",
|
|
43
|
+
"color": "#1f6feb",
|
|
44
|
+
"contextItems": [
|
|
45
|
+
{
|
|
46
|
+
"kind": "folder",
|
|
47
|
+
"value": "/home/alice/webapp"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"kind": "file",
|
|
51
|
+
"value": "/home/alice/webapp/README.md"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"kind": "note",
|
|
55
|
+
"value": "release gates first"
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
"defaultScopes": [
|
|
59
|
+
"proj"
|
|
60
|
+
],
|
|
61
|
+
"displayName": "pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp",
|
|
62
|
+
"gitRemotes": [
|
|
63
|
+
"example.com/acme/webapp"
|
|
64
|
+
],
|
|
65
|
+
"goal": "ship the project object",
|
|
66
|
+
"icon": "rocket",
|
|
67
|
+
"notes": "free notes",
|
|
68
|
+
"registeredAt": "2026-10-01T00:00:00.000Z",
|
|
69
|
+
"registeredBy": "alice"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"prompts": {
|
|
74
|
+
"bindings": []
|
|
75
|
+
},
|
|
76
|
+
"rosters": {
|
|
77
|
+
"rosters": []
|
|
78
|
+
},
|
|
79
|
+
"scenarios": {
|
|
80
|
+
"scenarios": []
|
|
81
|
+
},
|
|
82
|
+
"skills": {
|
|
83
|
+
"skills": []
|
|
84
|
+
},
|
|
85
|
+
"systems": {
|
|
86
|
+
"systems": []
|
|
87
|
+
},
|
|
88
|
+
"workers": {
|
|
89
|
+
"workers": []
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
"warnings": [],
|
|
93
|
+
"metadata": {
|
|
94
|
+
"version": 17,
|
|
95
|
+
"updatedAt": "2026-10-12T00:00:00.000Z"
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
"strictWrite": {
|
|
99
|
+
"outcome": "effective",
|
|
100
|
+
"effective": {
|
|
101
|
+
"projects": {
|
|
102
|
+
"projects": {
|
|
103
|
+
"01890a5d-ac96-774b-bcce-b302099a8057": {
|
|
104
|
+
"archivedAt": "2026-10-11T08:00:00.000Z",
|
|
105
|
+
"color": "#1f6feb",
|
|
106
|
+
"contextItems": [
|
|
107
|
+
{
|
|
108
|
+
"kind": "folder",
|
|
109
|
+
"value": "/home/alice/webapp"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"kind": "file",
|
|
113
|
+
"value": "/home/alice/webapp/README.md"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"kind": "note",
|
|
117
|
+
"value": "release gates first"
|
|
118
|
+
}
|
|
119
|
+
],
|
|
120
|
+
"defaultScopes": [
|
|
121
|
+
"proj"
|
|
122
|
+
],
|
|
123
|
+
"displayName": "pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp",
|
|
124
|
+
"gitRemotes": [
|
|
125
|
+
"example.com/acme/webapp"
|
|
126
|
+
],
|
|
127
|
+
"goal": "ship the project object",
|
|
128
|
+
"icon": "rocket",
|
|
129
|
+
"notes": "free notes",
|
|
130
|
+
"registeredAt": "2026-10-01T00:00:00.000Z",
|
|
131
|
+
"registeredBy": "alice"
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
"warnings": [],
|
|
137
|
+
"metadata": {
|
|
138
|
+
"version": 17,
|
|
139
|
+
"updatedAt": "2026-10-12T00:00:00.000Z"
|
|
140
|
+
},
|
|
141
|
+
"why": "受理:扩形五键与放宽后的 displayName 上界都是本版契约的合法形,严写腿与读腿同答。"
|
|
142
|
+
},
|
|
143
|
+
"wire": {
|
|
144
|
+
"derive": true
|
|
145
|
+
},
|
|
146
|
+
"localRoot": {
|
|
147
|
+
"derive": true,
|
|
148
|
+
"localVersion": 2617555914511015
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"version": 17,
|
|
4
|
+
"updatedAt": "2026-10-12T00:00:00.000Z"
|
|
5
|
+
},
|
|
6
|
+
"domains": {
|
|
7
|
+
"projects": {
|
|
8
|
+
"projects": {
|
|
9
|
+
"01890a5d-ac96-774b-bcce-b302099a8057": {
|
|
10
|
+
"gitRemotes": [
|
|
11
|
+
"example.com/acme/webapp"
|
|
12
|
+
],
|
|
13
|
+
"defaultScopes": [
|
|
14
|
+
"proj"
|
|
15
|
+
],
|
|
16
|
+
"registeredBy": "alice",
|
|
17
|
+
"registeredAt": "2026-10-01T00:00:00.000Z",
|
|
18
|
+
"displayName": "pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp",
|
|
19
|
+
"notes": "free notes",
|
|
20
|
+
"goal": "ship the project object",
|
|
21
|
+
"contextItems": [
|
|
22
|
+
{
|
|
23
|
+
"kind": "folder",
|
|
24
|
+
"value": "/home/alice/webapp"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"kind": "file",
|
|
28
|
+
"value": "/home/alice/webapp/README.md"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"kind": "note",
|
|
32
|
+
"value": "release gates first"
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
"archivedAt": "2026-10-11T08:00:00.000Z",
|
|
36
|
+
"icon": "rocket",
|
|
37
|
+
"color": "#1f6feb"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"contributor": "contract",
|
|
3
|
+
"claim": "项目登记的 additive 扩形:原六键之外带 goal / contextItems(folder / file / note)/ archivedAt / icon / color,displayName 150 字(上界 120 → 200 放宽之后才合法)。读腿与严写腿都原样收、零告警。打的是「读方按旧形把新键剥掉」或「仍按 120 的旧上界拒」两种读法分歧(11.2.0 及更早:150 字的 displayName 整域拒)。",
|
|
4
|
+
"firstRedOn": [],
|
|
5
|
+
"note": "firstRedOn 为空:historical 阶梯(≤ 2.1.0)不覆盖 11.3.0 的新键;对 11.2.0 这一条会红(displayName 150 > 120),那一版不在入库的真跑证据里。"
|
|
6
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{
|
|
2
|
+
"domains": {
|
|
3
|
+
"outcome": "rejected",
|
|
4
|
+
"stage": "validate"
|
|
5
|
+
},
|
|
6
|
+
"strictWrite": {
|
|
7
|
+
"outcome": "rejected",
|
|
8
|
+
"stage": "validate",
|
|
9
|
+
"why": "拒:displayName 超过 200、folder 不是主机绝对路径 —— 与读腿同一只 schema。"
|
|
10
|
+
},
|
|
11
|
+
"wire": {
|
|
12
|
+
"outcome": "rejected",
|
|
13
|
+
"stage": "validate",
|
|
14
|
+
"why": "domains 腿是拒绝态,不派生;wire 腿把同一份文档交给同一个 buildEffective,拒绝层相同"
|
|
15
|
+
},
|
|
16
|
+
"localRoot": {
|
|
17
|
+
"outcome": "effective",
|
|
18
|
+
"effective": {
|
|
19
|
+
"collab": {
|
|
20
|
+
"templates": []
|
|
21
|
+
},
|
|
22
|
+
"entitlement": {
|
|
23
|
+
"budgetGroups": [],
|
|
24
|
+
"groupBindings": [],
|
|
25
|
+
"subjects": [],
|
|
26
|
+
"tiers": []
|
|
27
|
+
},
|
|
28
|
+
"execution": {
|
|
29
|
+
"allowedLanes": [
|
|
30
|
+
"host"
|
|
31
|
+
],
|
|
32
|
+
"required": false
|
|
33
|
+
},
|
|
34
|
+
"governance": {},
|
|
35
|
+
"hosts": {
|
|
36
|
+
"hosts": []
|
|
37
|
+
},
|
|
38
|
+
"limits": {},
|
|
39
|
+
"mcp": {
|
|
40
|
+
"servers": []
|
|
41
|
+
},
|
|
42
|
+
"models": {
|
|
43
|
+
"atMention": {
|
|
44
|
+
"mode": "all"
|
|
45
|
+
},
|
|
46
|
+
"models": [],
|
|
47
|
+
"roles": {},
|
|
48
|
+
"tierGroups": []
|
|
49
|
+
},
|
|
50
|
+
"plugins": {
|
|
51
|
+
"plugins": []
|
|
52
|
+
},
|
|
53
|
+
"projects": {
|
|
54
|
+
"projects": {}
|
|
55
|
+
},
|
|
56
|
+
"prompts": {
|
|
57
|
+
"bindings": []
|
|
58
|
+
},
|
|
59
|
+
"rosters": {
|
|
60
|
+
"rosters": []
|
|
61
|
+
},
|
|
62
|
+
"scenarios": {
|
|
63
|
+
"scenarios": []
|
|
64
|
+
},
|
|
65
|
+
"skills": {
|
|
66
|
+
"skills": []
|
|
67
|
+
},
|
|
68
|
+
"systems": {
|
|
69
|
+
"systems": []
|
|
70
|
+
},
|
|
71
|
+
"workers": {
|
|
72
|
+
"workers": []
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"warnings": [
|
|
76
|
+
{
|
|
77
|
+
"domain": "projects",
|
|
78
|
+
"file": "projects.json",
|
|
79
|
+
"kind": "unread-config-file",
|
|
80
|
+
"why": "non-portable-domain"
|
|
81
|
+
}
|
|
82
|
+
],
|
|
83
|
+
"metadata": {
|
|
84
|
+
"version": 2617555914511015,
|
|
85
|
+
"updatedAt": "1970-01-01T00:00:00.000Z"
|
|
86
|
+
},
|
|
87
|
+
"why": "projects 不是便携域:config.d 腿不读它(T3),文件报 unread-config-file、域取默认 —— 本地读腿看不见这份坏登记"
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"version": 17,
|
|
4
|
+
"updatedAt": "2026-10-12T00:00:00.000Z"
|
|
5
|
+
},
|
|
6
|
+
"domains": {
|
|
7
|
+
"projects": {
|
|
8
|
+
"projects": {
|
|
9
|
+
"01890a5d-ac96-774b-bcce-b302099a8057": {
|
|
10
|
+
"gitRemotes": [
|
|
11
|
+
"example.com/acme/webapp"
|
|
12
|
+
],
|
|
13
|
+
"defaultScopes": [
|
|
14
|
+
"proj"
|
|
15
|
+
],
|
|
16
|
+
"registeredBy": "alice",
|
|
17
|
+
"registeredAt": "2026-10-01T00:00:00.000Z",
|
|
18
|
+
"displayName": "ppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp",
|
|
19
|
+
"contextItems": [
|
|
20
|
+
{
|
|
21
|
+
"kind": "folder",
|
|
22
|
+
"value": "relative/dir"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|