@sema-agent/settings-schema 3.0.0 → 3.0.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 +24 -1
- package/README.md +10 -6
- package/conformance/VERSION +1 -1
- package/conformance/cases/t01-absent-domain-key-not-null/expected.json +93 -0
- package/conformance/cases/t01-absent-domain-key-not-null/input.json +29 -0
- package/conformance/cases/t01-absent-domain-key-not-null/meta.json +6 -0
- package/conformance/cases/t02-entry-salvage-vs-whole-domain-refusal/expected.json +16 -0
- package/conformance/cases/t02-entry-salvage-vs-whole-domain-refusal/input.json +32 -0
- package/conformance/cases/t02-entry-salvage-vs-whole-domain-refusal/meta.json +6 -0
- package/conformance/cases/t03-prototype-name-key-not-swallowed/expected.json +107 -0
- package/conformance/cases/t03-prototype-name-key-not-swallowed/input.json +25 -0
- package/conformance/cases/t03-prototype-name-key-not-swallowed/meta.json +6 -0
- package/conformance/cases/t04-secret-literal-never-in-warning-value/expected.json +105 -0
- package/conformance/cases/t04-secret-literal-never-in-warning-value/input.json +25 -0
- package/conformance/cases/t04-secret-literal-never-in-warning-value/meta.json +14 -0
- package/conformance/historical/settings-schema@1.0.0.json +84 -3
- package/conformance/historical/settings-schema@1.10.0.json +84 -3
- package/conformance/historical/settings-schema@1.5.0.json +84 -3
- package/conformance/historical/settings-schema@2.0.0.json +83 -2
- package/conformance/historical/settings-schema@2.1.0.json +83 -2
- package/dist/config-fns.d.ts +4 -4
- package/dist/config-fns.js +5 -5
- package/dist/cross-domain.d.ts +1 -1
- package/dist/cross-domain.js +1 -1
- package/dist/hooks.d.ts +2 -2
- package/dist/hooks.js +2 -2
- package/dist/scheduler-store.d.ts +1 -1
- package/dist/scheduler-store.js +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/types.js +3 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,29 @@
|
|
|
6
6
|
> `@sema-agent/registry-core`(更早还曾是 `@sema-ai/registry-core`)。本档 `0.19.0` 以下各节里的
|
|
7
7
|
> 包名是**历史记录**,如实保留不追改。
|
|
8
8
|
|
|
9
|
+
## 3.0.1 — 2026-09-22 — 纯文档 patch:订正幽灵版号、重写消费接入档到 3.0.0、README 真话、待裁账并入 ROADMAP、产品名统一、一致性门新增 4 条对抗语料
|
|
10
|
+
|
|
11
|
+
**零行为改动、零类型改动、零 wire 面变化。**
|
|
12
|
+
|
|
13
|
+
- 全仓订正开发期遗留的幽灵版号 `1.11.0`:这一批开发时叫 `1.11.0`,发布定版时改叫 `2.0.0`,但改名没
|
|
14
|
+
传导进源码注释与文档(npm 上从未有过 `1.11.0`)。本档给 config-center 产品的迁移句 `^1.11.0` 是一个
|
|
15
|
+
永远解析不到任何版本的提货范围,已订正为 `^2.0.0`。
|
|
16
|
+
- 新增一格门:文档 / `src/` 里出现的 `x.y.z` 必须是本档真有的一节(或落在有理由的外部产品版本白名单
|
|
17
|
+
里)——不许再有第二个幽灵版号。
|
|
18
|
+
- `docs/CONSUMER-INTEGRATION.md` 重写到 3.0.0(此前停在改名定版前一节,2.0.0/2.1.0/3.0.0 三版未跟):
|
|
19
|
+
删除两条今天会带消费方接错线的过期指路 —— 老 env 名 `CONFIG_CENTER_URL` 在真实部署里是**拒启键**
|
|
20
|
+
(已改名 `SEMA_REGISTRY_URL`);「service 与 client 都调 `loadLocalConfig`」的说法与四仓生产码
|
|
21
|
+
(零 import)不符,真实接线是 `FileConfigStore` 直连。补齐 `ConfigPath`/`formatConfigPath`、
|
|
22
|
+
`./conformance`、已删 `./api/wire` 四节。
|
|
23
|
+
- README 改正一条过期的「待迁移」声明:cli 的 trust-rank 消费批早已兑现(不再是 pending)。
|
|
24
|
+
- 三条仍然有效的历史待裁事项(GC 工具的 `new Date()`、`refIntegrityIssues` 无级联校验、
|
|
25
|
+
`atModelAllowlist` 空语义二义)从一份标着「历史存档」却记着未拍板项的文档,搬进 `ROADMAP.md`
|
|
26
|
+
「立案」(坐标复核到 3.0.0),原文档删除 —— 待裁事项只留一份真源。
|
|
27
|
+
- 产品旧名(`sema-registry` / `sema-web`)统一为现名 `sema-web-admin`。
|
|
28
|
+
- 一致性门语料新增 4 条对抗用例(`contributor: test`),覆盖:告警对象上 `domain` 缺席必须原样传成
|
|
29
|
+
缺席、逐条容错域与闸门域的结论必须隔离、域内条目键上的原型名(`__proto__`/`constructor`/`toString`)
|
|
30
|
+
不被剥键扫描吞掉、坏条目值里的秘密字面永不上线四个面。
|
|
31
|
+
|
|
9
32
|
## 3.0.0 — 2026-09-16 — 告警坐标改铸**结构化段** `ConfigPath`(BREAKING)+ 删死出口 `./api/wire`(BREAKING)+ wire 透传判据修原型链漏洞 + 跨仓一致性门 kit(新 subpath `./conformance`)
|
|
10
33
|
|
|
11
34
|
> **版号裁定(发布方)**:本批三件里有两件是**纯 API 面**的破坏性改动 —— ①`EffectiveReadWarning` 的
|
|
@@ -445,7 +468,7 @@ parse 失败** —— 一份在上游合法的 `settings.json` 只因带了 `Pre
|
|
|
445
468
|
两边可以直接对拍(派生 vs 登记),不必各自反射。
|
|
446
469
|
- **config-center 产品(舰队管理台)**:①写侧仍走 `parseDomain`(严判,一字未变)—— 逐条容错只在**读**
|
|
447
470
|
路径;②读面同 worker 服务:坏条目不再连坐;③它今天装的是改名前、冻结在 `0.15.0` 的旧名包,本版之前的
|
|
448
|
-
全部契约它都不认,提货 `^
|
|
471
|
+
全部契约它都不认,提货 `^2.0.0` 是它自己的车。
|
|
449
472
|
|
|
450
473
|
## 1.10.0 — 2026-09-09 — `models.models[].compat` 引擎兼容声明席(镜像 `OpenAICompletionsCompat`;新键=minor)
|
|
451
474
|
|
package/README.md
CHANGED
|
@@ -22,12 +22,12 @@
|
|
|
22
22
|
> deprecate 标指向新名。
|
|
23
23
|
|
|
24
24
|
Engine-agnostic, zero-dependency contract layer for the sema stack — **one source of truth** for the
|
|
25
|
-
config domain across the center (the config-center product — today `sema-web` — the fleet admin), the
|
|
25
|
+
config domain across the center (the config-center product — today `sema-web-admin` — the fleet admin), the
|
|
26
26
|
server (the workers), and the client (desktop/CLI) seams. No two copies of the schema.
|
|
27
27
|
|
|
28
|
-
> 命名说明:config-center 这个**产品**曾叫 `sema-registry`,现在是 `sema-web`
|
|
29
|
-
>
|
|
30
|
-
> 下文凡提「center / config-center 产品」即指该产品的当期实现。
|
|
28
|
+
> 命名说明:config-center 这个**产品**曾叫 `sema-registry`,又改成 `sema-web`,现在是 `sema-web-admin`
|
|
29
|
+
> (clay 令 2026-08-26 仓改名;后续仍可能再改)。本**包**名与产品名解耦,**不随产品改名而动**(1.0.0 这次
|
|
30
|
+
> 改名是本包自身的正名,与产品名无关)—— 下文凡提「center / config-center 产品」即指该产品的当期实现。
|
|
31
31
|
|
|
32
32
|
- **Source of truth**: `github.com/sema-agent/sema-settings-schema`, branch `main` (private org repo; renamed from `sema-registry-core` on 2026-08-26, old URLs redirect).
|
|
33
33
|
仓名本步不动(只改包名)。
|
|
@@ -71,8 +71,12 @@ sound). `npm ls --prod` therefore shows only `zod`. Node built-ins only (`node:c
|
|
|
71
71
|
step — those live in the consumers (engine import door, shell resolver), each on its own release schedule.
|
|
72
72
|
1.2.0 adds the **trust ordering primitives**: `trustRank(layer)` (v2-design §1 verbatim, `managed 6 > global 5 >
|
|
73
73
|
project 4 > local 3 > session 2 > task 1`) and `isAtLeast(layer, minTrust)` — the ladder every resolver is to
|
|
74
|
-
compare floors against; consumers retire their own rank tables onto it
|
|
75
|
-
|
|
74
|
+
compare floors against; consumers retire their own rank tables onto it. **3.0.1 correction**: this used to say
|
|
75
|
+
the CLI's `TRUST_RANK` migration was still pending (board [5807] ③) — it shipped in the CLI's own 1.2.0
|
|
76
|
+
consumption batch (board [5815], 2026-08-31): the CLI's third literal copy of the ladder is deleted
|
|
77
|
+
(`src/sema/settings/keyContracts.ts` self-documents the retirement) and its resolver now really imports
|
|
78
|
+
`isAtLeast` from this package (`src/sema/settings/resolver.ts`). Exporting the primitive DID make it the
|
|
79
|
+
single source, for this consumer.
|
|
76
80
|
`MinTrust` gains the `task` word (the runtime task overlay, the loosest floor; appended, declaration order
|
|
77
81
|
otherwise unchanged — the declaration order is not the ladder, `trustRank` is). The published table does not
|
|
78
82
|
use `task`; the widened vocabulary is visible to consumers that hold a `Record<MinTrust, …>` / exhaustive
|
package/conformance/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.0.
|
|
1
|
+
3.0.1
|
|
@@ -0,0 +1,93 @@
|
|
|
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
|
+
"approved": true,
|
|
25
|
+
"drain": false,
|
|
26
|
+
"enabled": true,
|
|
27
|
+
"labels": [],
|
|
28
|
+
"name": "box1"
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
"limits": {},
|
|
33
|
+
"mcp": {
|
|
34
|
+
"servers": []
|
|
35
|
+
},
|
|
36
|
+
"models": {
|
|
37
|
+
"models": [
|
|
38
|
+
{
|
|
39
|
+
"api": "openai-completions",
|
|
40
|
+
"apiKeyEnv": "OPENAI_API_KEY",
|
|
41
|
+
"enabled": true,
|
|
42
|
+
"id": "m0-id",
|
|
43
|
+
"name": "m0",
|
|
44
|
+
"provider": "openai",
|
|
45
|
+
"quotaWeight": 1,
|
|
46
|
+
"reasoning": false,
|
|
47
|
+
"tier": "standard",
|
|
48
|
+
"vision": false
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
"roles": {},
|
|
52
|
+
"tierGroups": []
|
|
53
|
+
},
|
|
54
|
+
"plugins": {
|
|
55
|
+
"plugins": []
|
|
56
|
+
},
|
|
57
|
+
"projects": {
|
|
58
|
+
"projects": {}
|
|
59
|
+
},
|
|
60
|
+
"prompts": {
|
|
61
|
+
"bindings": []
|
|
62
|
+
},
|
|
63
|
+
"rosters": {
|
|
64
|
+
"rosters": []
|
|
65
|
+
},
|
|
66
|
+
"runtime": {},
|
|
67
|
+
"scenarios": {
|
|
68
|
+
"scenarios": []
|
|
69
|
+
},
|
|
70
|
+
"skills": {
|
|
71
|
+
"skills": []
|
|
72
|
+
},
|
|
73
|
+
"systems": {
|
|
74
|
+
"systems": []
|
|
75
|
+
},
|
|
76
|
+
"workers": {
|
|
77
|
+
"workers": []
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"warnings": [],
|
|
81
|
+
"metadata": {
|
|
82
|
+
"version": 7,
|
|
83
|
+
"updatedAt": "2026-09-16T00:00:00.000Z"
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
"wire": {
|
|
87
|
+
"derive": true
|
|
88
|
+
},
|
|
89
|
+
"localRoot": {
|
|
90
|
+
"derive": true,
|
|
91
|
+
"localVersion": 2247688933988744
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"version": 7,
|
|
4
|
+
"updatedAt": "2026-09-16T00:00:00.000Z"
|
|
5
|
+
},
|
|
6
|
+
"domains": {
|
|
7
|
+
"models": {
|
|
8
|
+
"models": [
|
|
9
|
+
{
|
|
10
|
+
"name": "m0",
|
|
11
|
+
"provider": "openai",
|
|
12
|
+
"id": "m0-id",
|
|
13
|
+
"apiKeyEnv": "OPENAI_API_KEY"
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
"hosts": {
|
|
18
|
+
"hosts": [
|
|
19
|
+
{
|
|
20
|
+
"name": "box1",
|
|
21
|
+
"approved": true
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
"web-admin-ui": {
|
|
26
|
+
"theme": "dark"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"contributor": "test",
|
|
3
|
+
"claim": "告警对象上 `domain` **缺席**(不是 `null`、不是空串)时,三腿必须原样传成缺席。消费方普遍写 `{domain: w.domain, …}` 这种投影(web-admin [7285] ③ 实测 `unread-config-file` 无必填 `domain`),谁把缺席折成 `null` 或 `\"\"`,谁就让下游多红一处而自己看不见。",
|
|
4
|
+
"firstRedOn": [],
|
|
5
|
+
"note": "一条输入里同时放两条 `unread-config-file`:`hosts.json`(非便携域 ⇒ **带** `domain`)与 `web-admin-ui.json`(非域名 ⇒ **不带** `domain`)。两种形并排,所以「把缺席一律折成 null」与「把 domain 整个丢掉」两种错法都会红,而不是只挡住其中一种。诚实边界:`unread-config-file` 是 `config.d/` 扫描**独有**的 kind(闭集里唯一 `domain` 可选的那条),所以「缺席传成缺席」这件事**结构上只在 local-root 腿上可观察**;domains / wire 两腿在本条上是零告警的正控(它们不该凭空造出这条告警)。firstRedOn 空是**实跑**出来的:五个历史版本(1.0.0/1.5.0/1.10.0/2.0.0/2.1.0)在本条上全绿 ⇒ 护栏,不是回归凭证。"
|
|
6
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"domains": {
|
|
3
|
+
"outcome": "rejected",
|
|
4
|
+
"stage": "validate"
|
|
5
|
+
},
|
|
6
|
+
"wire": {
|
|
7
|
+
"outcome": "rejected",
|
|
8
|
+
"stage": "validate",
|
|
9
|
+
"why": "domains 腿是拒绝态,不派生;wire 腿把同一份 rosters 文档交给同一个 buildEffective(skills/prompts 之外零改道),闸门域的 throw 穿过信封层 ⇒ 拒绝层与 domains 腿相同"
|
|
10
|
+
},
|
|
11
|
+
"localRoot": {
|
|
12
|
+
"outcome": "rejected",
|
|
13
|
+
"stage": "validate",
|
|
14
|
+
"why": "models 与 rosters 都是便携域,两份文件层都过得去(都是 JSON 对象),拒绝发生在域校验层而不是 parse 层"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"version": 7,
|
|
4
|
+
"updatedAt": "2026-09-16T00:00:00.000Z"
|
|
5
|
+
},
|
|
6
|
+
"domains": {
|
|
7
|
+
"models": {
|
|
8
|
+
"models": [
|
|
9
|
+
{
|
|
10
|
+
"name": "keep",
|
|
11
|
+
"provider": "openai",
|
|
12
|
+
"id": "keep-id",
|
|
13
|
+
"apiKeyEnv": "OPENAI_API_KEY"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"name": 5,
|
|
17
|
+
"id": "bad-id"
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
"rosters": {
|
|
22
|
+
"rosters": [
|
|
23
|
+
{
|
|
24
|
+
"name": "r1"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"name": 5
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"contributor": "test",
|
|
3
|
+
"claim": "同一份坏条目,放进逐条容错的域(`models`,`DOMAIN_READ_FALLBACK=\"default\"`)与放进 fail-loud 的闸门域(`rosters`,`=\"throw\"`),结论必须不同:前者丢那一条并恰报一条 `entry-dropped`、**不得同时**报 `domain-defaulted`(一域一个结论);后者**整份读在 validate 层被拒**(不是回落到 schema 默认 —— 对闸门域回落就是放宽闸门)。server [6782] 与 web-admin [7285] G2/G4 是同一件事的两半,跨腿读错会把『逐条容错』顺手放宽到闸门域,把这条设计为拒的输入读成绿(带两条 `entry-dropped`)。",
|
|
4
|
+
"firstRedOn": [],
|
|
5
|
+
"note": "【claim 措辞订正 2026-09-19,test 自纠】初稿写的是「后者整域回落」—— **是本方写错**:「回落」是 `DOMAIN_READ_FALLBACK=\"default\"` 那一族的动作,闸门域是 `\"throw\"` = fail-loud,整份读被拒。出处:契约自述 `config-fns.js` 的 `DOMAIN_READ_FALLBACK` 头注(defaulting would LOOSEN gates)+ 契约自带 `c05-gate-domain-bad-entry-throws` 金样(rejected/validate)+ 本仓 historical 实跑五版一致。claim 已按实测改写,对抗意图不变。两域放**同形**坏条目(`name` 是数字):`models`(DOMAIN_READ_FALLBACK=\"default\")与 `rosters`(=\"throw\",且是唯一一个便携的数组形闸门域)。3.0.0 实测:闸门域坏条目使**整份读**在 `validate` 层拒,三腿同形 —— 因此本条的期望是 `rejected/validate`,`models` 那半场在同一份输入里**结构上观察不到**。这正是本条的判别力所在:一个把逐条容错顺手放宽到闸门域的消费方,会把这条设计为拒的 case 读成绿(带两条 `entry-dropped`)。claim 前半场(`models` 恰一条 `entry-dropped`、零 `domain-defaulted`)由 verify.mjs 的配对正控臂(同一份输入去掉 `rosters` 域)钉住,读数记在 _SUMMARY.json 的 t02.pairedControl。claim 里「闸门域整域回落」的『回落』一词与契约自述的 `\"throw\"` = fail-loud 不符 —— 见 _SUMMARY.json 的 claimVsObserved。firstRedOn 空是**实跑**出来的:1.0.0/1.5.0/1.10.0/2.0.0/2.1.0 五版在本条上都是 expected-rejected(闸门域坏条目整份拒这条律从 1.0.0 起一字未动)⇒ 护栏,不是回归凭证。"
|
|
6
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
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
|
+
"models": [
|
|
30
|
+
{
|
|
31
|
+
"api": "openai-completions",
|
|
32
|
+
"apiKeyEnv": "OPENAI_API_KEY",
|
|
33
|
+
"enabled": true,
|
|
34
|
+
"id": "m0-id",
|
|
35
|
+
"name": "m0",
|
|
36
|
+
"provider": "openai",
|
|
37
|
+
"quotaWeight": 1,
|
|
38
|
+
"reasoning": false,
|
|
39
|
+
"tier": "standard",
|
|
40
|
+
"vision": false
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
"roles": {},
|
|
44
|
+
"tierGroups": []
|
|
45
|
+
},
|
|
46
|
+
"plugins": {
|
|
47
|
+
"plugins": []
|
|
48
|
+
},
|
|
49
|
+
"projects": {
|
|
50
|
+
"projects": {}
|
|
51
|
+
},
|
|
52
|
+
"prompts": {
|
|
53
|
+
"bindings": []
|
|
54
|
+
},
|
|
55
|
+
"rosters": {
|
|
56
|
+
"rosters": []
|
|
57
|
+
},
|
|
58
|
+
"runtime": {},
|
|
59
|
+
"scenarios": {
|
|
60
|
+
"scenarios": []
|
|
61
|
+
},
|
|
62
|
+
"skills": {
|
|
63
|
+
"skills": []
|
|
64
|
+
},
|
|
65
|
+
"systems": {
|
|
66
|
+
"systems": []
|
|
67
|
+
},
|
|
68
|
+
"workers": {
|
|
69
|
+
"workers": []
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"warnings": [
|
|
73
|
+
{
|
|
74
|
+
"domain": "models",
|
|
75
|
+
"keys": [
|
|
76
|
+
[
|
|
77
|
+
"models",
|
|
78
|
+
0,
|
|
79
|
+
"__proto__"
|
|
80
|
+
],
|
|
81
|
+
[
|
|
82
|
+
"models",
|
|
83
|
+
0,
|
|
84
|
+
"constructor"
|
|
85
|
+
],
|
|
86
|
+
[
|
|
87
|
+
"models",
|
|
88
|
+
0,
|
|
89
|
+
"toString"
|
|
90
|
+
]
|
|
91
|
+
],
|
|
92
|
+
"kind": "unknown-keys-dropped"
|
|
93
|
+
}
|
|
94
|
+
],
|
|
95
|
+
"metadata": {
|
|
96
|
+
"version": 7,
|
|
97
|
+
"updatedAt": "2026-09-16T00:00:00.000Z"
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
"wire": {
|
|
101
|
+
"derive": true
|
|
102
|
+
},
|
|
103
|
+
"localRoot": {
|
|
104
|
+
"derive": true,
|
|
105
|
+
"localVersion": 3232605402901914
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"version": 7,
|
|
4
|
+
"updatedAt": "2026-09-16T00:00:00.000Z"
|
|
5
|
+
},
|
|
6
|
+
"domains": {
|
|
7
|
+
"models": {
|
|
8
|
+
"models": [
|
|
9
|
+
{
|
|
10
|
+
"name": "m0",
|
|
11
|
+
"provider": "openai",
|
|
12
|
+
"id": "m0-id",
|
|
13
|
+
"apiKeyEnv": "OPENAI_API_KEY",
|
|
14
|
+
"__proto__": {
|
|
15
|
+
"polluted": true
|
|
16
|
+
},
|
|
17
|
+
"constructor": {
|
|
18
|
+
"polluted": true
|
|
19
|
+
},
|
|
20
|
+
"toString": "nope"
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"contributor": "test",
|
|
3
|
+
"claim": "`__proto__` / `constructor` / `toString` 作为域内条目的键,**在坏条目上**:告警坐标必须把它当**普通字面键**点名、`effective` 的原型必须不被污染、三腿读法一致。本方在 server 7.87.0 G6 实测过同族(`answer.answers[0].__proto__` ⇒ `400 request.field_invalid` 且 `unknownKeys` 逐字点名);也在本仓自证里把 `__proto__` 的断言方向搞反过一次(`JSON.parse` + spread **保留** own 属性、plain assignment 才污染原型),所以这条同时是护栏。",
|
|
4
|
+
"firstRedOn": [],
|
|
5
|
+
"note": "【claim 收窄 2026-09-19,server [7621] ① 指出、主会话亲验】初稿把 `__proto__` **作好条目的 record 键**也算进「当普通字面键报进坐标」。**实测不成立**:`parseDomainLoud('limits', {__proto__:1, ok:2}, …)` 的告警 keys 只有 `['ok']`,`parsed` 上无 own `__proto__`(原型仍是 `Object.prototype`)—— 好条目上的原型名键在 zod 3 正常解析路径上本来就被丢,是 [7617] 已知限制,不是本条要钉的东西。claim 已收窄到**坏条目**那半场(真的、可判、有判别力);好条目那半场不入语料。与契约仓 c12 的差别:c12 打的是**顶层键**(`k in built` 一路问到 Object.prototype ⇒ open-world 承诺失效),本条打的是**域内条目的键**(剥键扫描 `collectDropped` 的 `Object.keys` / `hasOwnProperty` 两处判据,以及 salvage/rebase 路径上的对象重建)。构造坑(本方亲踩,记在此处防下一个人重踩):用 JS 对象字面量 `{\"__proto__\": {...}}` 造这条输入会**设置原型而不是加一个键**,于是 `isPlainJsonObject` 判假、整条扫描被跳过、case 测了个寂寞;语料走 `JSON.parse` 才拿到自有键 —— 这也是为什么这条必须以磁盘语料形存在,而不是测试里一个内联对象。firstRedOn 空是**实跑**出来的:五个旧版(1.0.0/1.5.0/1.10.0/2.0.0/2.1.0)在本条上全绿 —— S-332 那个 bug 只落在**顶层键**那一层(契约 c12 五版全红),域内条目键这一层从 1.0.0 起就一直对 ⇒ 本条是护栏,不是回归凭证。"
|
|
6
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
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
|
+
"models": [
|
|
30
|
+
{
|
|
31
|
+
"api": "openai-completions",
|
|
32
|
+
"apiKeyEnv": "OPENAI_API_KEY",
|
|
33
|
+
"enabled": true,
|
|
34
|
+
"id": "keep-id",
|
|
35
|
+
"name": "keep",
|
|
36
|
+
"provider": "openai",
|
|
37
|
+
"quotaWeight": 1,
|
|
38
|
+
"reasoning": false,
|
|
39
|
+
"tier": "standard",
|
|
40
|
+
"vision": false
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
"roles": {},
|
|
44
|
+
"tierGroups": []
|
|
45
|
+
},
|
|
46
|
+
"plugins": {
|
|
47
|
+
"plugins": []
|
|
48
|
+
},
|
|
49
|
+
"projects": {
|
|
50
|
+
"projects": {}
|
|
51
|
+
},
|
|
52
|
+
"prompts": {
|
|
53
|
+
"bindings": []
|
|
54
|
+
},
|
|
55
|
+
"rosters": {
|
|
56
|
+
"rosters": []
|
|
57
|
+
},
|
|
58
|
+
"runtime": {},
|
|
59
|
+
"scenarios": {
|
|
60
|
+
"scenarios": []
|
|
61
|
+
},
|
|
62
|
+
"skills": {
|
|
63
|
+
"skills": []
|
|
64
|
+
},
|
|
65
|
+
"systems": {
|
|
66
|
+
"systems": []
|
|
67
|
+
},
|
|
68
|
+
"workers": {
|
|
69
|
+
"workers": []
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"warnings": [
|
|
73
|
+
{
|
|
74
|
+
"domain": "models",
|
|
75
|
+
"kind": "entry-dropped",
|
|
76
|
+
"path": [
|
|
77
|
+
"models",
|
|
78
|
+
1
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"domain": "models",
|
|
83
|
+
"keys": [
|
|
84
|
+
[
|
|
85
|
+
"models",
|
|
86
|
+
0,
|
|
87
|
+
"apiKeyInline"
|
|
88
|
+
]
|
|
89
|
+
],
|
|
90
|
+
"kind": "unknown-keys-dropped"
|
|
91
|
+
}
|
|
92
|
+
],
|
|
93
|
+
"metadata": {
|
|
94
|
+
"version": 7,
|
|
95
|
+
"updatedAt": "2026-09-16T00:00:00.000Z"
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
"wire": {
|
|
99
|
+
"derive": true
|
|
100
|
+
},
|
|
101
|
+
"localRoot": {
|
|
102
|
+
"derive": true,
|
|
103
|
+
"localVersion": 2614200563056761
|
|
104
|
+
}
|
|
105
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"version": 7,
|
|
4
|
+
"updatedAt": "2026-09-16T00:00:00.000Z"
|
|
5
|
+
},
|
|
6
|
+
"domains": {
|
|
7
|
+
"models": {
|
|
8
|
+
"models": [
|
|
9
|
+
{
|
|
10
|
+
"name": "keep",
|
|
11
|
+
"provider": "openai",
|
|
12
|
+
"id": "keep-id",
|
|
13
|
+
"apiKeyEnv": "OPENAI_API_KEY",
|
|
14
|
+
"apiKeyInline": "sk-FAKE-CORPUS-0000000000000000"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"name": "bad",
|
|
18
|
+
"provider": "openai",
|
|
19
|
+
"id": "bad-id",
|
|
20
|
+
"api": "ghp_FAKE-CORPUS-1111111111111111"
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"contributor": "test",
|
|
3
|
+
"claim": "坏条目的**值**里埋 `sk-`/`ghp_` 形秘密字面:告警面必须**名字上线、值永不上线**(与 `hosts-grandfathered` 同律)。本方给 web-admin G3 加过同款正控 —— 没有正控时『没打印秘密』与『判据没跑到那一行』同形。",
|
|
4
|
+
"firstRedOn": [
|
|
5
|
+
"settings-schema@1.0.0",
|
|
6
|
+
"settings-schema@1.10.0",
|
|
7
|
+
"settings-schema@1.5.0"
|
|
8
|
+
],
|
|
9
|
+
"secrets": [
|
|
10
|
+
"sk-FAKE-CORPUS-0000000000000000",
|
|
11
|
+
"ghp_FAKE-CORPUS-1111111111111111"
|
|
12
|
+
],
|
|
13
|
+
"note": "两条秘密走**两条不同的告警路径**,所以「值不上线」在两条路上分别被判:①`sk-` 那把是**存活条目**上一个未知键的值 ⇒ 只该出现在 `unknown-keys-dropped` 的键坐标里(键名 `apiKeyInline` 上线、值不上线);②`ghp_` 那把是**被丢条目**上一个 enum 字段的值 ⇒ zod 的 `invalid_enum_value` 会把 `received` 原样回显,只有 `sanitizeZodError`/`redactSecrets` 挡着 ⇒ 它落在 `entry-dropped.error` 的文案面上,而 `findSecretLeaks` 恰恰扫这一面。正控(判据到达性)由 expected 的两条告警坐标承担:`[\"models\",0,\"apiKeyInline\"]` 与 `[\"models\",1]` 必须在场,证明剥键扫描与抢救路径都真跑到了。扫描器自身的判别力由 verify.mjs 的 decoy 臂钉住(把一个**非**秘密形的 enum 值当秘密登记 ⇒ findSecretLeaks 必须命中),否则「零命中」与「扫描器恒返回空」同形。语料里的两把是**假串**,不是任何真凭据。⚠️ firstRedOn 里的三个旧版**不是在秘密轴上红的**:逐版直读 `findSecretLeaks`(1.0.0/1.5.0/1.10.0/2.0.0/2.1.0)**五版全零命中**;那三版红是因为 1.11.0 才有的逐条容错还不存在,整个 `models` 域退默认(只报一条 `domain-defaulted`),于是 effective 与告警多重集都对不上。⇒ 在**秘密轴**上这条同样是护栏;把「这条 case 在旧版上红」读成「旧版泄过秘密」是从读数推到结论的那一类错,读数见 _historical-readout.json#t04SecretAxis。"
|
|
14
|
+
}
|
|
@@ -8,9 +8,10 @@
|
|
|
8
8
|
"why": "旧版坐标是点号串、今天是段数组;归一 = 按 `.` 拼串,这正是 3.0.0 要消掉的有损编码(`[\"a.b\"]` 与 `[\"a\",\"b\"]` 归一后同串)"
|
|
9
9
|
},
|
|
10
10
|
"summary": {
|
|
11
|
-
"pass":
|
|
12
|
-
"diff":
|
|
13
|
-
"
|
|
11
|
+
"pass": 105,
|
|
12
|
+
"diff": 39,
|
|
13
|
+
"diff-ledgered": 0,
|
|
14
|
+
"expected-rejected": 15,
|
|
14
15
|
"harness-error": 0,
|
|
15
16
|
"skipped": 0
|
|
16
17
|
},
|
|
@@ -955,6 +956,86 @@
|
|
|
955
956
|
}
|
|
956
957
|
}
|
|
957
958
|
},
|
|
959
|
+
"t01-absent-domain-key-not-null": {
|
|
960
|
+
"firstRed": false,
|
|
961
|
+
"legs": {
|
|
962
|
+
"domains": {
|
|
963
|
+
"status": "pass",
|
|
964
|
+
"behaviour": false,
|
|
965
|
+
"detail": "effective, warnings and metadata all match"
|
|
966
|
+
},
|
|
967
|
+
"wire": {
|
|
968
|
+
"status": "pass",
|
|
969
|
+
"behaviour": false,
|
|
970
|
+
"detail": "effective, warnings and metadata all match"
|
|
971
|
+
},
|
|
972
|
+
"localRoot": {
|
|
973
|
+
"status": "pass",
|
|
974
|
+
"behaviour": false,
|
|
975
|
+
"detail": "effective, warnings and metadata all match"
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
},
|
|
979
|
+
"t02-entry-salvage-vs-whole-domain-refusal": {
|
|
980
|
+
"firstRed": false,
|
|
981
|
+
"legs": {
|
|
982
|
+
"domains": {
|
|
983
|
+
"status": "expected-rejected",
|
|
984
|
+
"behaviour": false,
|
|
985
|
+
"detail": "rejected at `validate` as expected"
|
|
986
|
+
},
|
|
987
|
+
"wire": {
|
|
988
|
+
"status": "expected-rejected",
|
|
989
|
+
"behaviour": false,
|
|
990
|
+
"detail": "rejected at `validate` as expected"
|
|
991
|
+
},
|
|
992
|
+
"localRoot": {
|
|
993
|
+
"status": "expected-rejected",
|
|
994
|
+
"behaviour": false,
|
|
995
|
+
"detail": "rejected at `validate` as expected"
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
},
|
|
999
|
+
"t03-prototype-name-key-not-swallowed": {
|
|
1000
|
+
"firstRed": false,
|
|
1001
|
+
"legs": {
|
|
1002
|
+
"domains": {
|
|
1003
|
+
"status": "pass",
|
|
1004
|
+
"behaviour": false,
|
|
1005
|
+
"detail": "effective, warnings and metadata all match"
|
|
1006
|
+
},
|
|
1007
|
+
"wire": {
|
|
1008
|
+
"status": "pass",
|
|
1009
|
+
"behaviour": false,
|
|
1010
|
+
"detail": "effective, warnings and metadata all match"
|
|
1011
|
+
},
|
|
1012
|
+
"localRoot": {
|
|
1013
|
+
"status": "pass",
|
|
1014
|
+
"behaviour": false,
|
|
1015
|
+
"detail": "effective, warnings and metadata all match"
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
},
|
|
1019
|
+
"t04-secret-literal-never-in-warning-value": {
|
|
1020
|
+
"firstRed": true,
|
|
1021
|
+
"legs": {
|
|
1022
|
+
"domains": {
|
|
1023
|
+
"status": "diff",
|
|
1024
|
+
"behaviour": true,
|
|
1025
|
+
"detail": "1 effective diff(s), 2 missing / 1 extra warning(s), 0 metadata diff(s)"
|
|
1026
|
+
},
|
|
1027
|
+
"wire": {
|
|
1028
|
+
"status": "diff",
|
|
1029
|
+
"behaviour": true,
|
|
1030
|
+
"detail": "1 effective diff(s), 2 missing / 1 extra warning(s), 0 metadata diff(s)"
|
|
1031
|
+
},
|
|
1032
|
+
"localRoot": {
|
|
1033
|
+
"status": "diff",
|
|
1034
|
+
"behaviour": true,
|
|
1035
|
+
"detail": "1 effective diff(s), 2 missing / 1 extra warning(s), 0 metadata diff(s)"
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
},
|
|
958
1039
|
"z01-every-domain-empty-object": {
|
|
959
1040
|
"firstRed": false,
|
|
960
1041
|
"legs": {
|