@sema-agent/settings-schema 1.6.0 → 1.7.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/CHANGELOG.md CHANGED
@@ -6,6 +6,26 @@
6
6
  > `@sema-agent/registry-core`(更早还曾是 `@sema-ai/registry-core`)。本档 `0.19.0` 以下各节里的
7
7
  > 包名是**历史记录**,如实保留不追改。
8
8
 
9
+ ## 1.7.1 — 2026-09-06 — `source` 改**只管类型**(撤回 1.7.0 的 min/max 解析拒;patch)
10
+
11
+ - 1.7.0 把标签规则(非空 ≤80)写进 zod ⇒ 本域整域 all-or-nothing 解析下,**一个**空/超长标签让整套 `mcp.servers`
12
+ 在解析处整域默认(每台 server 消失),消费方 boot 期还容忍空目录——一个显示标签不该有这种爆炸半径
13
+ (消费方 codex 对抗复审 [high],真库复现:一坏一好两条 server 双双消失)。1.7.1 起 `source: z.string().optional()`,
14
+ 规则单点留在消费方投影层(坏形丢键留 server、留痕)。非字符串仍在解析处拒(那是 JSON 类型错,与任何字段同类)。
15
+ - 顺带如实记:本域 all-or-nothing 解析 + 消费方 boot 容忍空目录,对 `contentOrigin` 闭表等一切解析拒的键**早已**是
16
+ 同一爆炸半径(类病,先于本键存在)——归消费方与本包另立单据处置(逐条目拒而不是整域拒),不在本 patch 射程。
17
+
18
+ ## 1.7.0 — 2026-09-06 — `mcp.servers[].source` 分组标签(sema-server B-036 / S-143 源头修的声明面半场;新键=minor)
19
+
20
+ - **`McpServerSpec.source?: string`**(非空、≤80 字;`.optional()` 无默认):声明方自述的层级标签,1:1 对应引擎
21
+ `McpServerSpec.source`(core ≥7.5.0 在 `wiring_manifest.mcp[].source` 逐字回显、single-line + 80 字封顶)。
22
+ **开集**——`plugin`/`user`/`project`/`local` 是 CC 惯用词不是词表,部署自己的分组词同样合法,故刻意不做闭词表
23
+ (信任轴仍是 `contentOrigin` 的闭表)。空串/超长/非字符串在解析处拒;缺席保持缺席。
24
+ - 病:本包 default-strip 对象没有这个键 ⇒ `config.d/mcp.json` 写的 `source` 在本地腿与 wire 腿都被剥掉,引擎读到缺席
25
+ ——与 1.4.0 前的 `contentOrigin` 同形。消费方 sema-server 的投影半场(请求腿 `normalizeServer` + center 腿
26
+ `resolveMcpServers`)随 server 7.62.0。红先:`test/mcp-source-label.test.ts` 五格(①保留 ②缺席 ③坏形拒 ④本地腿
27
+ round-trip ⑤wire 腿)。
28
+
9
29
  ## 1.6.0 — 2026-09-05 — `settings.json` 跨会话两键 `crossSessionInbound` / `dialogExpiry`(新模块/新导出=minor)
10
30
 
11
31
  成案:跨终端会话设计稿(design/385 §4.4/§8)把这两个 settings 键的属主定在 worker 服务侧,而键的**格式契约**
package/dist/types.d.ts CHANGED
@@ -7317,6 +7317,21 @@ export declare const McpServerSpec: z.ZodObject<{
7317
7317
  * declared `"local"`, the engine read ABSENT. A value outside the table is REJECTED at parse — a mistyped trust
7318
7318
  * word must never be read as a legal one (the consumer's gate is equally severe: no case-folding). */
7319
7319
  contentOrigin: z.ZodOptional<z.ZodEnum<["local", "execution", "external"]>>;
7320
+ /** Declaration-plane GROUPING LABEL for this server — maps 1:1 onto the engine's `McpServerSpec.source`
7321
+ * (core ≥7.5.0 echoes it verbatim on `wiring_manifest.mcp[].source`, single-line + 80-char cap, so a
7322
+ * consumer can group servers by where they were declared). An OPEN set: CC's `plugin` / `user` /
7323
+ * `project` / `local` are conventions, not a vocabulary — a deployment's own word is equally legal, so
7324
+ * no closed table here (a closed table would reject the operator's grouping word at parse). ABSENT =
7325
+ * no label (`.optional()`, no default — a label has no default tier). 🔴 TYPE-ONLY here (any string):
7326
+ * the label RULE (non-empty, ≤80 chars) lives in ONE place — the consumer's projection helper, which
7327
+ * drops a malformed label's KEY, keeps the server and records the drop. It deliberately does NOT live
7328
+ * here: this domain parses all-or-nothing, so a `min(1)`/`max(80)` at parse would let one empty label
7329
+ * default the ENTIRE mcp domain (every server gone) — a blast radius a display label must never have
7330
+ * (1.7.0 shipped that shape for a few hours; 1.7.1 retracts it). Display-only: no gate / policy / trust
7331
+ * effect (the trust axis is `contentOrigin` above, which stays a closed table). Before this key existed
7332
+ * both legs stripped it (default-strip object); this is the declaration half of the consumer-side fix
7333
+ * (ticket B-036 / S-143), the projection half lives in the consumer. */
7334
+ source: z.ZodOptional<z.ZodString>;
7320
7335
  notes: z.ZodOptional<z.ZodString>;
7321
7336
  }, "strip", z.ZodTypeAny, {
7322
7337
  name: string;
@@ -7338,6 +7353,7 @@ export declare const McpServerSpec: z.ZodObject<{
7338
7353
  notes?: string | undefined;
7339
7354
  allowTools?: string[] | undefined;
7340
7355
  contentOrigin?: "local" | "execution" | "external" | undefined;
7356
+ source?: string | undefined;
7341
7357
  }, {
7342
7358
  name: string;
7343
7359
  transport: {
@@ -7358,6 +7374,7 @@ export declare const McpServerSpec: z.ZodObject<{
7358
7374
  allowTools?: string[] | undefined;
7359
7375
  elicitation?: boolean | undefined;
7360
7376
  contentOrigin?: "local" | "execution" | "external" | undefined;
7377
+ source?: string | undefined;
7361
7378
  }>;
7362
7379
  export type McpServerSpec = z.infer<typeof McpServerSpec>;
7363
7380
  export declare const McpConfig: z.ZodEffects<z.ZodObject<{
@@ -7429,6 +7446,21 @@ export declare const McpConfig: z.ZodEffects<z.ZodObject<{
7429
7446
  * declared `"local"`, the engine read ABSENT. A value outside the table is REJECTED at parse — a mistyped trust
7430
7447
  * word must never be read as a legal one (the consumer's gate is equally severe: no case-folding). */
7431
7448
  contentOrigin: z.ZodOptional<z.ZodEnum<["local", "execution", "external"]>>;
7449
+ /** Declaration-plane GROUPING LABEL for this server — maps 1:1 onto the engine's `McpServerSpec.source`
7450
+ * (core ≥7.5.0 echoes it verbatim on `wiring_manifest.mcp[].source`, single-line + 80-char cap, so a
7451
+ * consumer can group servers by where they were declared). An OPEN set: CC's `plugin` / `user` /
7452
+ * `project` / `local` are conventions, not a vocabulary — a deployment's own word is equally legal, so
7453
+ * no closed table here (a closed table would reject the operator's grouping word at parse). ABSENT =
7454
+ * no label (`.optional()`, no default — a label has no default tier). 🔴 TYPE-ONLY here (any string):
7455
+ * the label RULE (non-empty, ≤80 chars) lives in ONE place — the consumer's projection helper, which
7456
+ * drops a malformed label's KEY, keeps the server and records the drop. It deliberately does NOT live
7457
+ * here: this domain parses all-or-nothing, so a `min(1)`/`max(80)` at parse would let one empty label
7458
+ * default the ENTIRE mcp domain (every server gone) — a blast radius a display label must never have
7459
+ * (1.7.0 shipped that shape for a few hours; 1.7.1 retracts it). Display-only: no gate / policy / trust
7460
+ * effect (the trust axis is `contentOrigin` above, which stays a closed table). Before this key existed
7461
+ * both legs stripped it (default-strip object); this is the declaration half of the consumer-side fix
7462
+ * (ticket B-036 / S-143), the projection half lives in the consumer. */
7463
+ source: z.ZodOptional<z.ZodString>;
7432
7464
  notes: z.ZodOptional<z.ZodString>;
7433
7465
  }, "strip", z.ZodTypeAny, {
7434
7466
  name: string;
@@ -7450,6 +7482,7 @@ export declare const McpConfig: z.ZodEffects<z.ZodObject<{
7450
7482
  notes?: string | undefined;
7451
7483
  allowTools?: string[] | undefined;
7452
7484
  contentOrigin?: "local" | "execution" | "external" | undefined;
7485
+ source?: string | undefined;
7453
7486
  }, {
7454
7487
  name: string;
7455
7488
  transport: {
@@ -7470,6 +7503,7 @@ export declare const McpConfig: z.ZodEffects<z.ZodObject<{
7470
7503
  allowTools?: string[] | undefined;
7471
7504
  elicitation?: boolean | undefined;
7472
7505
  contentOrigin?: "local" | "execution" | "external" | undefined;
7506
+ source?: string | undefined;
7473
7507
  }>, "many">>;
7474
7508
  }, "strip", z.ZodTypeAny, {
7475
7509
  servers: {
@@ -7492,6 +7526,7 @@ export declare const McpConfig: z.ZodEffects<z.ZodObject<{
7492
7526
  notes?: string | undefined;
7493
7527
  allowTools?: string[] | undefined;
7494
7528
  contentOrigin?: "local" | "execution" | "external" | undefined;
7529
+ source?: string | undefined;
7495
7530
  }[];
7496
7531
  }, {
7497
7532
  servers?: {
@@ -7514,6 +7549,7 @@ export declare const McpConfig: z.ZodEffects<z.ZodObject<{
7514
7549
  allowTools?: string[] | undefined;
7515
7550
  elicitation?: boolean | undefined;
7516
7551
  contentOrigin?: "local" | "execution" | "external" | undefined;
7552
+ source?: string | undefined;
7517
7553
  }[] | undefined;
7518
7554
  }>, {
7519
7555
  servers: {
@@ -7536,6 +7572,7 @@ export declare const McpConfig: z.ZodEffects<z.ZodObject<{
7536
7572
  notes?: string | undefined;
7537
7573
  allowTools?: string[] | undefined;
7538
7574
  contentOrigin?: "local" | "execution" | "external" | undefined;
7575
+ source?: string | undefined;
7539
7576
  }[];
7540
7577
  }, {
7541
7578
  servers?: {
@@ -7558,6 +7595,7 @@ export declare const McpConfig: z.ZodEffects<z.ZodObject<{
7558
7595
  allowTools?: string[] | undefined;
7559
7596
  elicitation?: boolean | undefined;
7560
7597
  contentOrigin?: "local" | "execution" | "external" | undefined;
7598
+ source?: string | undefined;
7561
7599
  }[] | undefined;
7562
7600
  }>;
7563
7601
  export type McpConfig = z.infer<typeof McpConfig>;
@@ -10079,6 +10117,21 @@ export declare const DOMAIN_SCHEMAS: {
10079
10117
  * declared `"local"`, the engine read ABSENT. A value outside the table is REJECTED at parse — a mistyped trust
10080
10118
  * word must never be read as a legal one (the consumer's gate is equally severe: no case-folding). */
10081
10119
  contentOrigin: z.ZodOptional<z.ZodEnum<["local", "execution", "external"]>>;
10120
+ /** Declaration-plane GROUPING LABEL for this server — maps 1:1 onto the engine's `McpServerSpec.source`
10121
+ * (core ≥7.5.0 echoes it verbatim on `wiring_manifest.mcp[].source`, single-line + 80-char cap, so a
10122
+ * consumer can group servers by where they were declared). An OPEN set: CC's `plugin` / `user` /
10123
+ * `project` / `local` are conventions, not a vocabulary — a deployment's own word is equally legal, so
10124
+ * no closed table here (a closed table would reject the operator's grouping word at parse). ABSENT =
10125
+ * no label (`.optional()`, no default — a label has no default tier). 🔴 TYPE-ONLY here (any string):
10126
+ * the label RULE (non-empty, ≤80 chars) lives in ONE place — the consumer's projection helper, which
10127
+ * drops a malformed label's KEY, keeps the server and records the drop. It deliberately does NOT live
10128
+ * here: this domain parses all-or-nothing, so a `min(1)`/`max(80)` at parse would let one empty label
10129
+ * default the ENTIRE mcp domain (every server gone) — a blast radius a display label must never have
10130
+ * (1.7.0 shipped that shape for a few hours; 1.7.1 retracts it). Display-only: no gate / policy / trust
10131
+ * effect (the trust axis is `contentOrigin` above, which stays a closed table). Before this key existed
10132
+ * both legs stripped it (default-strip object); this is the declaration half of the consumer-side fix
10133
+ * (ticket B-036 / S-143), the projection half lives in the consumer. */
10134
+ source: z.ZodOptional<z.ZodString>;
10082
10135
  notes: z.ZodOptional<z.ZodString>;
10083
10136
  }, "strip", z.ZodTypeAny, {
10084
10137
  name: string;
@@ -10100,6 +10153,7 @@ export declare const DOMAIN_SCHEMAS: {
10100
10153
  notes?: string | undefined;
10101
10154
  allowTools?: string[] | undefined;
10102
10155
  contentOrigin?: "local" | "execution" | "external" | undefined;
10156
+ source?: string | undefined;
10103
10157
  }, {
10104
10158
  name: string;
10105
10159
  transport: {
@@ -10120,6 +10174,7 @@ export declare const DOMAIN_SCHEMAS: {
10120
10174
  allowTools?: string[] | undefined;
10121
10175
  elicitation?: boolean | undefined;
10122
10176
  contentOrigin?: "local" | "execution" | "external" | undefined;
10177
+ source?: string | undefined;
10123
10178
  }>, "many">>;
10124
10179
  }, "strip", z.ZodTypeAny, {
10125
10180
  servers: {
@@ -10142,6 +10197,7 @@ export declare const DOMAIN_SCHEMAS: {
10142
10197
  notes?: string | undefined;
10143
10198
  allowTools?: string[] | undefined;
10144
10199
  contentOrigin?: "local" | "execution" | "external" | undefined;
10200
+ source?: string | undefined;
10145
10201
  }[];
10146
10202
  }, {
10147
10203
  servers?: {
@@ -10164,6 +10220,7 @@ export declare const DOMAIN_SCHEMAS: {
10164
10220
  allowTools?: string[] | undefined;
10165
10221
  elicitation?: boolean | undefined;
10166
10222
  contentOrigin?: "local" | "execution" | "external" | undefined;
10223
+ source?: string | undefined;
10167
10224
  }[] | undefined;
10168
10225
  }>, {
10169
10226
  servers: {
@@ -10186,6 +10243,7 @@ export declare const DOMAIN_SCHEMAS: {
10186
10243
  notes?: string | undefined;
10187
10244
  allowTools?: string[] | undefined;
10188
10245
  contentOrigin?: "local" | "execution" | "external" | undefined;
10246
+ source?: string | undefined;
10189
10247
  }[];
10190
10248
  }, {
10191
10249
  servers?: {
@@ -10208,6 +10266,7 @@ export declare const DOMAIN_SCHEMAS: {
10208
10266
  allowTools?: string[] | undefined;
10209
10267
  elicitation?: boolean | undefined;
10210
10268
  contentOrigin?: "local" | "execution" | "external" | undefined;
10269
+ source?: string | undefined;
10211
10270
  }[] | undefined;
10212
10271
  }>;
10213
10272
  readonly plugins: z.ZodEffects<z.ZodObject<{
package/dist/types.js CHANGED
@@ -1798,7 +1798,7 @@ export const SkillsManifestSchema = z.object({
1798
1798
  });
1799
1799
  // ── Domain: mcp (MCP server 注册表 — docs/MCP-SKILLS.md, Roadmap B1) ────────────
1800
1800
  // sema-registry = an MCP-server REGISTRY: a scenario mounts a subset by `scenarios[]`. Maps onto core's
1801
- // `McpServerSpec = { name, transport: {kind:"stdio",command,args?,env?} | {kind:"http",url,headers?}, allowTools?, contentOrigin? }`.
1801
+ // `McpServerSpec = { name, transport: {kind:"stdio",command,args?,env?} | {kind:"http",url,headers?}, allowTools?, contentOrigin?, source? }`.
1802
1802
  // SECRET BOUNDARY (§3.1, design/15): a transport's env/header VALUES may be secret → the center stores only
1803
1803
  // env-NAME references (`envRefs`/`headerRefs`: target-key → an ENV_NAME in the SERVICE's env). The service's
1804
1804
  // `resolveSpec` reads the real values from its own environment — this DB never holds a credential. Like
@@ -1888,6 +1888,21 @@ export const McpServerSpec = z.object({
1888
1888
  * declared `"local"`, the engine read ABSENT. A value outside the table is REJECTED at parse — a mistyped trust
1889
1889
  * word must never be read as a legal one (the consumer's gate is equally severe: no case-folding). */
1890
1890
  contentOrigin: z.enum(MCP_CONTENT_ORIGINS).optional(),
1891
+ /** Declaration-plane GROUPING LABEL for this server — maps 1:1 onto the engine's `McpServerSpec.source`
1892
+ * (core ≥7.5.0 echoes it verbatim on `wiring_manifest.mcp[].source`, single-line + 80-char cap, so a
1893
+ * consumer can group servers by where they were declared). An OPEN set: CC's `plugin` / `user` /
1894
+ * `project` / `local` are conventions, not a vocabulary — a deployment's own word is equally legal, so
1895
+ * no closed table here (a closed table would reject the operator's grouping word at parse). ABSENT =
1896
+ * no label (`.optional()`, no default — a label has no default tier). 🔴 TYPE-ONLY here (any string):
1897
+ * the label RULE (non-empty, ≤80 chars) lives in ONE place — the consumer's projection helper, which
1898
+ * drops a malformed label's KEY, keeps the server and records the drop. It deliberately does NOT live
1899
+ * here: this domain parses all-or-nothing, so a `min(1)`/`max(80)` at parse would let one empty label
1900
+ * default the ENTIRE mcp domain (every server gone) — a blast radius a display label must never have
1901
+ * (1.7.0 shipped that shape for a few hours; 1.7.1 retracts it). Display-only: no gate / policy / trust
1902
+ * effect (the trust axis is `contentOrigin` above, which stays a closed table). Before this key existed
1903
+ * both legs stripped it (default-strip object); this is the declaration half of the consumer-side fix
1904
+ * (ticket B-036 / S-143), the projection half lives in the consumer. */
1905
+ source: z.string().optional(),
1891
1906
  notes: z.string().optional(),
1892
1907
  });
1893
1908
  export const McpConfig = z
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/settings-schema",
3
- "version": "1.6.0",
3
+ "version": "1.7.1",
4
4
  "description": "Sema settings schema — pure config contract (zod domains + effective-config + roster resolution + ref-integrity + remoteExec) shared by sema-registry, sema-server, and the TOC desktop/CLI. One source of truth. (Renamed at 1.0.0 from @sema-agent/registry-core — name and docs only, no behavior change; note the range moves 0.19.0 -> 1.0.0, so a dependency must become ^1.0.0. The old names @sema-agent/registry-core <=0.19.0 and @sema-ai/registry-core remain published, frozen, for migration.)",
5
5
  "type": "module",
6
6
  "license": "BUSL-1.1",