@sema-agent/settings-schema 6.2.0 → 6.4.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.
Files changed (48) hide show
  1. package/CHANGELOG.md +197 -0
  2. package/README.md +21 -9
  3. package/conformance/VERSION +1 -1
  4. package/conformance/cases/c41-s792-encoded-pem-identity/expected.json +166 -0
  5. package/conformance/cases/c41-s792-encoded-pem-identity/input.json +62 -0
  6. package/conformance/cases/c41-s792-encoded-pem-identity/meta.json +12 -0
  7. package/conformance/cases/c42-s792-unknown-key-secret-redacted/expected.json +120 -0
  8. package/conformance/cases/c42-s792-unknown-key-secret-redacted/input.json +25 -0
  9. package/conformance/cases/c42-s792-unknown-key-secret-redacted/meta.json +11 -0
  10. package/conformance/cases/c43-s792-form-and-deep-encoded-pem/expected.json +137 -0
  11. package/conformance/cases/c43-s792-form-and-deep-encoded-pem/input.json +44 -0
  12. package/conformance/cases/c43-s792-form-and-deep-encoded-pem/meta.json +12 -0
  13. package/conformance/cases/c44-s792-utf8-escape-glued-token/expected.json +115 -0
  14. package/conformance/cases/c44-s792-utf8-escape-glued-token/input.json +30 -0
  15. package/conformance/cases/c44-s792-utf8-escape-glued-token/meta.json +10 -0
  16. package/conformance/cases/c45-s792-identity-bounds-and-decode-depth/expected.json +185 -0
  17. package/conformance/cases/c45-s792-identity-bounds-and-decode-depth/input.json +78 -0
  18. package/conformance/cases/c45-s792-identity-bounds-and-decode-depth/meta.json +11 -0
  19. package/conformance/cases/c46-s811-host-name-url-userinfo-characterization/expected.json +88 -0
  20. package/conformance/cases/c46-s811-host-name-url-userinfo-characterization/input.json +18 -0
  21. package/conformance/cases/c46-s811-host-name-url-userinfo-characterization/meta.json +6 -0
  22. package/conformance/cases/c47-s811-roles-key-url-userinfo-characterization/expected.json +98 -0
  23. package/conformance/cases/c47-s811-roles-key-url-userinfo-characterization/input.json +26 -0
  24. package/conformance/cases/c47-s811-roles-key-url-userinfo-characterization/meta.json +6 -0
  25. package/conformance/cases/c48-s935-model-headers-transported/expected.json +115 -0
  26. package/conformance/cases/c48-s935-model-headers-transported/input.json +37 -0
  27. package/conformance/cases/c48-s935-model-headers-transported/meta.json +6 -0
  28. package/conformance/cases/c49-s935-model-headers-secret-entry-dropped/expected.json +98 -0
  29. package/conformance/cases/c49-s935-model-headers-secret-entry-dropped/input.json +28 -0
  30. package/conformance/cases/c49-s935-model-headers-secret-entry-dropped/meta.json +9 -0
  31. package/conformance/cases/cli01-model-name-nfc-vs-nfd/expected.json +0 -8
  32. package/conformance/cases/cli01-model-name-nfc-vs-nfd/meta.json +2 -1
  33. package/conformance/cases/cli02-control-and-zero-width-chars/expected.json +0 -8
  34. package/conformance/cases/cli02-control-and-zero-width-chars/meta.json +2 -1
  35. package/dist/config-fns.d.ts +53 -22
  36. package/dist/config-fns.js +87 -33
  37. package/dist/cross-session.d.ts +8 -5
  38. package/dist/cross-session.js +8 -5
  39. package/dist/fleet.d.ts +3 -2
  40. package/dist/fleet.js +3 -2
  41. package/dist/hash.d.ts +3 -3
  42. package/dist/hash.js +3 -3
  43. package/dist/hooks.d.ts +8 -8
  44. package/dist/secret-scan.d.ts +39 -0
  45. package/dist/secret-scan.js +110 -0
  46. package/dist/types.d.ts +65 -7
  47. package/dist/types.js +57 -44
  48. package/package.json +1 -1
@@ -0,0 +1,88 @@
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": false,
25
+ "drain": false,
26
+ "enabled": true,
27
+ "labels": [],
28
+ "name": "ok-host"
29
+ }
30
+ ]
31
+ },
32
+ "limits": {},
33
+ "mcp": {
34
+ "servers": []
35
+ },
36
+ "models": {
37
+ "models": [],
38
+ "roles": {},
39
+ "tierGroups": []
40
+ },
41
+ "plugins": {
42
+ "plugins": []
43
+ },
44
+ "projects": {
45
+ "projects": {}
46
+ },
47
+ "prompts": {
48
+ "bindings": []
49
+ },
50
+ "rosters": {
51
+ "rosters": []
52
+ },
53
+ "runtime": {},
54
+ "scenarios": {
55
+ "scenarios": []
56
+ },
57
+ "skills": {
58
+ "skills": []
59
+ },
60
+ "systems": {
61
+ "systems": []
62
+ },
63
+ "workers": {
64
+ "workers": []
65
+ }
66
+ },
67
+ "warnings": [
68
+ {
69
+ "domain": "hosts",
70
+ "droppedNames": [
71
+ "https://admin:hunter2@hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh…"
72
+ ],
73
+ "kind": "hosts-grandfathered"
74
+ }
75
+ ],
76
+ "metadata": {
77
+ "version": 17,
78
+ "updatedAt": "2026-09-27T00:00:00.000Z"
79
+ }
80
+ },
81
+ "wire": {
82
+ "derive": true
83
+ },
84
+ "localRoot": {
85
+ "derive": true,
86
+ "localVersion": 2617555914511015
87
+ }
88
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "meta": {
3
+ "version": 17,
4
+ "updatedAt": "2026-09-27T00:00:00.000Z"
5
+ },
6
+ "domains": {
7
+ "hosts": {
8
+ "hosts": [
9
+ {
10
+ "name": "ok-host"
11
+ },
12
+ {
13
+ "name": "https://admin:hunter2@hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh.com"
14
+ }
15
+ ]
16
+ }
17
+ }
18
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "contributor": "contract",
3
+ "claim": "🚧 S-811 特征格(既有,非回归;本版刻意不修,设计随 S-809 三表归一):超长主机名 `https://admin:hunter2@hhh…h.com`(81 字)被 `hosts-grandfathered` 按名剔掉,`droppedNames` 的标签过出门那一道 —— 但那一道(`redactSecrets`)不查 URL userinfo,于是 63 字标签里原样带着 `admin:hunter2`。本条把**今天的读数**钉成金样:S-811 修后(自由文本面加 userinfo 判定)本条翻红 —— 届时金样改成 `droppedNames: [\"[redacted-secret]\"]`、meta.secrets 补上 `hunter2`,这一格就从特征钉变成护栏。",
4
+ "firstRedOn": [],
5
+ "note": "车PE(2026-09-27)按主会话令加(codex 验修腿 [high] S-811)。刻意**不**在 secrets 里登 `hunter2`:登了,告警面零命中门会把今天的现状判红 —— 现状要能如实入库,修复时一并补。"
6
+ }
@@ -0,0 +1,98 @@
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
+ "summarize": {
45
+ "model": "keep"
46
+ }
47
+ },
48
+ "tierGroups": []
49
+ },
50
+ "plugins": {
51
+ "plugins": []
52
+ },
53
+ "projects": {
54
+ "projects": {}
55
+ },
56
+ "prompts": {
57
+ "bindings": []
58
+ },
59
+ "rosters": {
60
+ "rosters": []
61
+ },
62
+ "runtime": {},
63
+ "scenarios": {
64
+ "scenarios": []
65
+ },
66
+ "skills": {
67
+ "skills": []
68
+ },
69
+ "systems": {
70
+ "systems": []
71
+ },
72
+ "workers": {
73
+ "workers": []
74
+ }
75
+ },
76
+ "warnings": [
77
+ {
78
+ "domain": "models",
79
+ "kind": "entry-dropped",
80
+ "path": [
81
+ "roles",
82
+ "https://admin:hunter2@db.example.com/x"
83
+ ]
84
+ }
85
+ ],
86
+ "metadata": {
87
+ "version": 18,
88
+ "updatedAt": "2026-09-27T00:00:00.000Z"
89
+ }
90
+ },
91
+ "wire": {
92
+ "derive": true
93
+ },
94
+ "localRoot": {
95
+ "derive": true,
96
+ "localVersion": 715023802301241
97
+ }
98
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "meta": {
3
+ "version": 18,
4
+ "updatedAt": "2026-09-27T00: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
+ "roles": {
17
+ "summarize": {
18
+ "model": "keep"
19
+ },
20
+ "https://admin:hunter2@db.example.com/x": {
21
+ "model": "keep"
22
+ }
23
+ }
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "contributor": "contract",
3
+ "claim": "🚧 S-811 特征格(既有,非回归;本版刻意不修,设计随 S-809 三表归一):坏 roles 键 `https://admin:hunter2@db.example.com/x` 被逐条丢掉,坐标段与 zod 回显的 received / message 都只过 `redactSecrets`,它不查 URL userinfo,于是坐标 `[\"roles\", \"https://admin:hunter2@db.example.com/x\"]` 原样出门(错误句同带)。同一个串作身份 6.3.0 起不可披露(身份面有 userinfo 否决),自由文本面没有 —— 本条把今天的读数钉成金样:S-811 修后本条翻红,届时坐标段改成 `[redacted-secret]`、meta.secrets 补上 `hunter2`。",
4
+ "firstRedOn": [],
5
+ "note": "车PE(2026-09-27)按主会话令加(codex 验修腿 [high] S-811)。刻意**不**在 secrets 里登 `hunter2`(登了即判红今天的现状)。"
6
+ }
@@ -0,0 +1,115 @@
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": "anthropic-messages",
32
+ "apiKeyEnv": "ANTHROPIC_API_KEY",
33
+ "enabled": true,
34
+ "headers": {
35
+ "anthropic-beta": "context-1m-2025-08-07"
36
+ },
37
+ "id": "claude-x",
38
+ "name": "claude-1m",
39
+ "provider": "anthropic",
40
+ "quotaWeight": 1,
41
+ "reasoning": false,
42
+ "tier": "standard",
43
+ "vision": false
44
+ },
45
+ {
46
+ "api": "openai-completions",
47
+ "apiKeyEnv": "OPENAI_API_KEY",
48
+ "enabled": true,
49
+ "headers": [
50
+ "Anthropic-Beta: not-a-header-bag"
51
+ ],
52
+ "id": "gw-id",
53
+ "name": "gw",
54
+ "provider": "openai",
55
+ "quotaWeight": 1,
56
+ "reasoning": false,
57
+ "tier": "standard",
58
+ "vision": false
59
+ },
60
+ {
61
+ "api": "openai-completions",
62
+ "apiKeyEnv": "OPENAI_API_KEY",
63
+ "enabled": true,
64
+ "id": "plain-id",
65
+ "name": "plain",
66
+ "provider": "openai",
67
+ "quotaWeight": 1,
68
+ "reasoning": false,
69
+ "tier": "standard",
70
+ "vision": false
71
+ }
72
+ ],
73
+ "roles": {},
74
+ "tierGroups": []
75
+ },
76
+ "plugins": {
77
+ "plugins": []
78
+ },
79
+ "projects": {
80
+ "projects": {}
81
+ },
82
+ "prompts": {
83
+ "bindings": []
84
+ },
85
+ "rosters": {
86
+ "rosters": []
87
+ },
88
+ "runtime": {},
89
+ "scenarios": {
90
+ "scenarios": []
91
+ },
92
+ "skills": {
93
+ "skills": []
94
+ },
95
+ "systems": {
96
+ "systems": []
97
+ },
98
+ "workers": {
99
+ "workers": []
100
+ }
101
+ },
102
+ "warnings": [],
103
+ "metadata": {
104
+ "version": 7,
105
+ "updatedAt": "2026-10-01T00:00:00.000Z"
106
+ }
107
+ },
108
+ "wire": {
109
+ "derive": true
110
+ },
111
+ "localRoot": {
112
+ "derive": true,
113
+ "localVersion": 1883250445565322
114
+ }
115
+ }
@@ -0,0 +1,37 @@
1
+ {
2
+ "meta": {
3
+ "version": 7,
4
+ "updatedAt": "2026-10-01T00:00:00.000Z"
5
+ },
6
+ "domains": {
7
+ "models": {
8
+ "models": [
9
+ {
10
+ "name": "claude-1m",
11
+ "provider": "anthropic",
12
+ "api": "anthropic-messages",
13
+ "id": "claude-x",
14
+ "apiKeyEnv": "ANTHROPIC_API_KEY",
15
+ "headers": {
16
+ "anthropic-beta": "context-1m-2025-08-07"
17
+ }
18
+ },
19
+ {
20
+ "name": "gw",
21
+ "provider": "openai",
22
+ "id": "gw-id",
23
+ "apiKeyEnv": "OPENAI_API_KEY",
24
+ "headers": [
25
+ "Anthropic-Beta: not-a-header-bag"
26
+ ]
27
+ },
28
+ {
29
+ "name": "plain",
30
+ "provider": "openai",
31
+ "id": "plain-id",
32
+ "apiKeyEnv": "OPENAI_API_KEY"
33
+ }
34
+ ]
35
+ }
36
+ }
37
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "contributor": "contract",
3
+ "claim": "S-935(6.4.0):`models[].headers` 是解析透明键(与 `compat` 同一只变换)⇒ 三读腿**逐字交出、零告警**,不剥、不报 `unknown-keys-dropped`;并且本包**不做形校验** —— 写在 openai 线路上的数组形 `headers`(非规范大小写的名、根本不是头袋)照样逐字过,形与线路归 sema-server 的目录条目判据。任一腿把它剥掉,经生产配置通道写下的附加请求头(开 1M 上下文的 `anthropic-beta`)就到不了 server 目录且零告警;任一腿对它做形校验,就是本包复述了 server 的白名单(两个写者)。第三条不带 `headers` 的条目是负控:不铸键。",
4
+ "firstRedOn": [],
5
+ "note": "车SL(2026-10-01)红先:6.3.0 读腿在本条上三腿同红 —— 两条带 `headers` 的条目都被剥掉该键,`unknown-keys-dropped` 点名 `[\"models\",0,\"headers\"]` / `[\"models\",1,\"headers\"]`(实测读数见车SL 收车档)。firstRedOn 为空:`conformance/historical/` 的阶梯证据(2.1.0 及更早)真跑于本条入库之前,没有本条的读数,那一栏只收 historical 真跑,不手填(c41 同口径)。"
6
+ }
@@ -0,0 +1,98 @@
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": "gw-id",
35
+ "name": "gw",
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
+ "identity": {
76
+ "id": "claude-x",
77
+ "name": "claude-1m"
78
+ },
79
+ "kind": "entry-dropped",
80
+ "path": [
81
+ "models",
82
+ 0
83
+ ]
84
+ }
85
+ ],
86
+ "metadata": {
87
+ "version": 7,
88
+ "updatedAt": "2026-10-01T00:00:00.000Z"
89
+ }
90
+ },
91
+ "wire": {
92
+ "derive": true
93
+ },
94
+ "localRoot": {
95
+ "derive": true,
96
+ "localVersion": 496785931148953
97
+ }
98
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "meta": {
3
+ "version": 7,
4
+ "updatedAt": "2026-10-01T00:00:00.000Z"
5
+ },
6
+ "domains": {
7
+ "models": {
8
+ "models": [
9
+ {
10
+ "name": "claude-1m",
11
+ "provider": "anthropic",
12
+ "api": "anthropic-messages",
13
+ "id": "claude-x",
14
+ "apiKeyEnv": "ANTHROPIC_API_KEY",
15
+ "headers": {
16
+ "x-api-key": "sk-ant-api03-FAKES935CORPUS000000000000000000"
17
+ }
18
+ },
19
+ {
20
+ "name": "gw",
21
+ "provider": "openai",
22
+ "id": "gw-id",
23
+ "apiKeyEnv": "OPENAI_API_KEY"
24
+ }
25
+ ]
26
+ }
27
+ }
28
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "contributor": "contract",
3
+ "claim": "S-935(6.4.0):`models[].headers` 里粘了一把密钥形值(`x-api-key: sk-ant-…`)⇒ 与 `compat` 同一只自由形安全判据拒 ⇒ 该条目**逐条丢**(`entry-dropped`,坐标 `[\"models\",0]`)、兄弟条目幸存、告警面零回显那把钥匙。打的是两种读错:① 腿把 `headers` 当未知键剥掉(6.3.0 形)⇒ 条目带着「看起来干净」的形幸存,明文凭据却已经进了持久层且没人拒;② 腿对 `headers` 另起一套判据(或把拒句拼上值)⇒ 告警面带出密钥。",
4
+ "firstRedOn": [],
5
+ "secrets": [
6
+ "sk-ant-api03-FAKES935CORPUS000000000000000000"
7
+ ],
8
+ "note": "车SL(2026-10-01)红先:6.3.0 读腿在本条上三腿同红 —— 条目幸存(`headers` 被剥)+ `unknown-keys-dropped` 点名 `[\"models\",0,\"headers\"]`,没有 `entry-dropped`(实测读数见车SL 收车档)。firstRedOn 为空:同 c48 / c41 口径(historical 阶梯证据真跑于本条入库之前,不手填)。"
9
+ }
@@ -72,10 +72,6 @@
72
72
  "warnings": [
73
73
  {
74
74
  "domain": "models",
75
- "identity": {
76
- "id": "café-id",
77
- "name": "café"
78
- },
79
75
  "kind": "entry-dropped",
80
76
  "path": [
81
77
  "models",
@@ -84,10 +80,6 @@
84
80
  },
85
81
  {
86
82
  "domain": "models",
87
- "identity": {
88
- "id": "café-id",
89
- "name": "café"
90
- },
91
83
  "kind": "entry-dropped",
92
84
  "path": [
93
85
  "models",
@@ -5,5 +5,6 @@
5
5
  "settings-schema@1.0.0",
6
6
  "settings-schema@1.10.0",
7
7
  "settings-schema@1.5.0"
8
- ]
8
+ ],
9
+ "note": "6.3.0(车PE,2026-09-27):被丢条目的身份改走白名单闭形 `DISCLOSABLE_IDENTITY_RE`(`A-Za-z0-9._:/@+-`,1–256)—— 两条的 name / id 含非 ASCII 字母(é / 组合符),落在集外 ⇒ 按无名处置,`identity` 键缺席;两条仍各自按下标点名(坐标照旧),effective 与三腿一致性不动。expected.json 随之重 bless,diff 只少两处 identity。"
9
10
  }
@@ -85,10 +85,6 @@
85
85
  "warnings": [
86
86
  {
87
87
  "domain": "models",
88
- "identity": {
89
- "id": "a\u0007b-id",
90
- "name": "a\u0007b"
91
- },
92
88
  "kind": "entry-dropped",
93
89
  "path": [
94
90
  "models",
@@ -97,10 +93,6 @@
97
93
  },
98
94
  {
99
95
  "domain": "models",
100
- "identity": {
101
- "id": "zero​width-id",
102
- "name": "zero​width"
103
- },
104
96
  "kind": "entry-dropped",
105
97
  "path": [
106
98
  "models",
@@ -5,5 +5,6 @@
5
5
  "settings-schema@1.0.0",
6
6
  "settings-schema@1.10.0",
7
7
  "settings-schema@1.5.0"
8
- ]
8
+ ],
9
+ "note": "6.3.0(车PE,2026-09-27):被丢条目的身份改走白名单闭形 `DISCLOSABLE_IDENTITY_RE`(`A-Za-z0-9._:/@+-`,1–256)—— 两条的 name / id 含控制字符(BEL)/ 零宽空格,落在集外 ⇒ 按无名处置,`identity` 键缺席;两条仍各自按下标点名(坐标照旧),effective 与三腿一致性不动。expected.json 随之重 bless,diff 只少两处 identity。"
9
10
  }