@sema-agent/settings-schema 17.1.0 → 18.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 +212 -0
- package/README.md +73 -5
- package/conformance/VERSION +1 -1
- package/conformance/baseline.json +3 -0
- package/conformance/cases/c01-entry-salvage-then-typo/expected.json +4 -1
- package/conformance/cases/c02-hosts-clamp-stacked/expected.json +4 -1
- package/conformance/cases/c03-literal-dotted-top-key/expected.json +4 -1
- package/conformance/cases/c04-all-bad-collection-not-salvaged/expected.json +4 -1
- package/conformance/cases/c07-hooks-is-not-a-config-domain/expected.json +4 -1
- package/conformance/cases/c08-limits-unknown-carried-64/expected.json +4 -1
- package/conformance/cases/c09-limits-unknown-carried-65/expected.json +4 -1
- package/conformance/cases/c10-record-key-secret-redacted-twice/expected.json +4 -1
- package/conformance/cases/c11-unicode-unknown-keys/expected.json +4 -1
- package/conformance/cases/c12-prototype-name-top-keys/expected.json +4 -1
- package/conformance/cases/c13-models-field-null/expected.json +4 -1
- package/conformance/cases/c14-models-field-empty-array/expected.json +4 -1
- package/conformance/cases/c15-models-field-number/expected.json +4 -1
- package/conformance/cases/c16-deep-nesting-205/expected.json +3 -0
- package/conformance/cases/c17-empty-domain-file/expected.json +3 -0
- package/conformance/cases/c18-wire-envelope-not-an-object/expected.json +4 -1
- package/conformance/cases/c19-wire-envelope-no-version/expected.json +4 -1
- package/conformance/cases/c21-governance-empty-object-wins/expected.json +4 -1
- package/conformance/cases/c23-mixed-validity-models/expected.json +4 -1
- package/conformance/cases/c24-valid-entries-with-unknown-keys/expected.json +4 -1
- package/conformance/cases/c25-published-roundtrip-zero-warnings/expected.json +4 -1
- package/conformance/cases/c26-hosts-array-1024/expected.json +4 -1
- package/conformance/cases/c27-hosts-array-1025/expected.json +4 -1
- package/conformance/cases/c28-large-document-over-1mb/expected.json +4 -1
- package/conformance/cases/c29-salvage-then-domain-refine-fails/expected.json +4 -1
- package/conformance/cases/c30-version-triple-a-first/expected.json +4 -1
- package/conformance/cases/c31-version-triple-b-changed/expected.json +4 -1
- package/conformance/cases/c32-version-triple-a-restored/expected.json +4 -1
- package/conformance/cases/c33-limits-nested-carried-key/expected.json +4 -1
- package/conformance/cases/c34-skills-content-vs-manifest/expected.json +7 -1
- package/conformance/cases/c35-portable-domain-file-is-null/expected.json +3 -0
- package/conformance/cases/c36-skills-entry-without-content/expected.json +7 -1
- package/conformance/cases/c37-skills-field-null/expected.json +6 -0
- package/conformance/cases/c38-remote-exec-is-a-non-domain-file/expected.json +4 -1
- package/conformance/cases/c39-hidden-file-in-config-d/expected.json +4 -1
- package/conformance/cases/c40-s712-identity-only-what-reads-out/expected.json +4 -1
- package/conformance/cases/c41-s792-encoded-pem-identity/expected.json +4 -1
- package/conformance/cases/c42-s792-unknown-key-secret-redacted/expected.json +4 -1
- package/conformance/cases/c43-s792-form-and-deep-encoded-pem/expected.json +4 -1
- package/conformance/cases/c44-s792-utf8-escape-glued-token/expected.json +4 -1
- package/conformance/cases/c45-s792-identity-bounds-and-decode-depth/expected.json +4 -1
- package/conformance/cases/c46-s811-host-name-url-userinfo-withheld/expected.json +4 -1
- package/conformance/cases/c47-s811-roles-key-url-userinfo-withheld/expected.json +4 -1
- package/conformance/cases/c48-s935-model-headers-transported/expected.json +4 -1
- package/conformance/cases/c49-s935-model-headers-secret-entry-dropped/expected.json +4 -1
- package/conformance/cases/c50-s784-lane-host-legal/expected.json +4 -1
- package/conformance/cases/c51-s784-lane-e2b-legal/expected.json +4 -1
- package/conformance/cases/c52-s784-lane-k8s-legal/expected.json +4 -1
- package/conformance/cases/c53-s784-lane-ssh-legal/expected.json +4 -1
- package/conformance/cases/c54-s784-lane-adb-legal/expected.json +4 -1
- package/conformance/cases/c55-s784-lane-local-docker-legal/expected.json +4 -1
- package/conformance/cases/c56-s784-lane-device-legal/expected.json +4 -1
- package/conformance/cases/c57-s784-g1-enabled-no-lane/expected.json +4 -1
- package/conformance/cases/c58-s784-g2-multitenant-host/expected.json +4 -1
- package/conformance/cases/c59-s784-g3-k8s-missing-image/expected.json +4 -1
- package/conformance/cases/c60-s784-g3-e2b-missing-key/expected.json +4 -1
- package/conformance/cases/c61-s784-g3-other-lane-key/expected.json +4 -1
- package/conformance/cases/c62-s784-g7a-session-tidb/expected.json +4 -1
- package/conformance/cases/c63-s784-host-two-replicas/expected.json +4 -1
- package/conformance/cases/c64-s784-multitenant-local-store/expected.json +4 -1
- package/conformance/cases/c65-s784-pg-without-db/expected.json +4 -1
- package/conformance/cases/c66-s784-memory-backend-mismatch/expected.json +4 -1
- package/conformance/cases/c67-s784-retired-field-loud/expected.json +4 -1
- package/conformance/cases/c68-s784-device-local-store/expected.json +4 -1
- package/conformance/cases/c69-deep-encoded-token-past-every-reading/expected.json +4 -1
- package/conformance/cases/c70-rewritten-token-in-front-of-encoded-pem-header/expected.json +4 -1
- package/conformance/cases/c71-one-scanner-write-reads-display-forms/expected.json +4 -1
- package/conformance/cases/c72-dangling-reference-write-seat-refuses/expected.json +4 -1
- package/conformance/cases/c73-projects-extended-registration-reads/expected.json +4 -1
- package/conformance/cases/c74-projects-over-bound-refused/expected.json +4 -1
- package/conformance/cases/c75-projects-patch-remote-uniqueness/expected.json +4 -1
- package/conformance/cases/c76-projects-entry-salvage-nested/expected.json +4 -1
- package/conformance/cases/c77-prompts-center-artifact-carried/expected.json +4 -1
- package/conformance/cases/c78-prompts-empty-bindings-refused/expected.json +4 -1
- package/conformance/cases/c79-prompts-bad-worker-artifact-not-salvaged/expected.json +4 -1
- package/conformance/cases/c80-prompts-wire-v2-verbatim/expected.json +7 -1
- package/conformance/cases/c81-prompts-declaration-bindings-refused/expected.json +4 -1
- package/conformance/cases/c82-prompts-v1-catalog-refused/expected.json +4 -1
- package/conformance/cases/c83-prompts-bad-overlay-not-salvaged/expected.json +4 -1
- package/conformance/cases/c84-sandbox-git-block-carried-verbatim/expected.json +7 -1
- package/conformance/cases/c85-sandbox-git-refused-block-still-carried/expected.json +7 -1
- package/conformance/cases/c86-a2a-peers-legal/expected.json +135 -0
- package/conformance/cases/c86-a2a-peers-legal/input.json +32 -0
- package/conformance/cases/c86-a2a-peers-legal/meta.json +5 -0
- package/conformance/cases/c87-a2a-credential-refs-not-partially-salvaged/expected.json +123 -0
- package/conformance/cases/c87-a2a-credential-refs-not-partially-salvaged/input.json +39 -0
- package/conformance/cases/c87-a2a-credential-refs-not-partially-salvaged/meta.json +5 -0
- package/conformance/cases/cc01-mcp-toolfaces-non-object/expected.json +4 -1
- package/conformance/cases/cc02-mcp-source-key-is-transported/expected.json +4 -1
- package/conformance/cases/cc03-model-compat-unknown-subkey/expected.json +4 -1
- package/conformance/cases/cli01-model-name-nfc-vs-nfd/expected.json +4 -1
- package/conformance/cases/cli02-control-and-zero-width-chars/expected.json +4 -1
- package/conformance/cases/cli03-credential-pasted-into-unknown-key/expected.json +4 -1
- package/conformance/cases/cli04-env-value-with-newline/expected.json +4 -1
- package/conformance/cases/cli05-long-and-prefix-colliding-names/expected.json +4 -1
- package/conformance/cases/t01-absent-domain-key-not-null/expected.json +4 -1
- package/conformance/cases/t03-prototype-name-key-not-swallowed/expected.json +4 -1
- package/conformance/cases/t04-secret-literal-never-in-warning-value/expected.json +4 -1
- package/conformance/cases/z01-every-domain-empty-object/expected.json +4 -1
- package/conformance/cases/z02-every-domain-unknown-key/expected.json +4 -1
- package/dist/atomic-write.d.ts +4 -3
- package/dist/atomic-write.js +25 -11
- package/dist/catalog-manages.d.ts +8 -3
- package/dist/catalog-manages.js +16 -7
- package/dist/center-refs.d.ts +4 -3
- package/dist/center-refs.js +8 -6
- package/dist/cli.d.ts +1 -1
- package/dist/config-d-file.d.ts +4 -2
- package/dist/config-d-file.js +27 -6
- package/dist/config-fns.d.ts +6 -1
- package/dist/config-fns.js +16 -2
- package/dist/config-root-documents.d.ts +2 -2
- package/dist/config-root-documents.js +1 -1
- package/dist/config-root-node.d.ts +8 -1
- package/dist/config-root-node.js +105 -23
- package/dist/env-model-table.js +3 -3
- package/dist/execution-lanes.d.ts +158 -11
- package/dist/execution-lanes.js +76 -11
- package/dist/file-edit.d.ts +1 -1
- package/dist/file-edit.js +2 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/mcp-request-entry.d.ts +11 -21
- package/dist/mcp-request-entry.js +21 -38
- package/dist/node.d.ts +4 -1
- package/dist/node.js +6 -2
- package/dist/one-time-migrations.js +1 -1
- package/dist/portable-domains.d.ts +1 -1
- package/dist/portable-domains.js +1 -1
- package/dist/remote-exec.d.ts +5 -0
- package/dist/remote-exec.js +5 -0
- package/dist/reserved-member-name.d.ts +13 -0
- package/dist/reserved-member-name.js +14 -0
- package/dist/retired-envs.js +2 -0
- package/dist/secret-refs.d.ts +1 -1
- package/dist/secret-refs.js +5 -1
- package/dist/settings-units.d.ts +3 -0
- package/dist/settings-units.js +18 -0
- package/dist/types.d.ts +70 -41
- package/dist/types.js +179 -32
- package/dist/url-credential.d.ts +12 -2
- package/dist/url-credential.js +164 -9
- package/dist/wire-name.d.ts +19 -0
- package/dist/wire-name.js +21 -0
- package/docs/API-SURFACE.md +31 -6
- package/docs/CC-DIVERGENCE.md +6 -0
- package/docs/CONSUMER-INTEGRATION.md +127 -7
- package/llms-full.txt +40 -17
- package/llms.txt +9 -9
- package/package.json +1 -1
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
{
|
|
2
|
+
"domains": {
|
|
3
|
+
"outcome": "effective",
|
|
4
|
+
"effective": {
|
|
5
|
+
"a2a": {
|
|
6
|
+
"peers": [
|
|
7
|
+
{
|
|
8
|
+
"allowSkills": [
|
|
9
|
+
"search"
|
|
10
|
+
],
|
|
11
|
+
"enabled": true,
|
|
12
|
+
"headerRefs": {
|
|
13
|
+
"Authorization": "KB_TOKEN"
|
|
14
|
+
},
|
|
15
|
+
"name": "kb",
|
|
16
|
+
"principalHeader": "X-Principal",
|
|
17
|
+
"scenarios": [],
|
|
18
|
+
"url": "https://kb.example/a2a"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"cardUrl": "https://ops.example/agent-card.json",
|
|
22
|
+
"enabled": false,
|
|
23
|
+
"name": "ops",
|
|
24
|
+
"scenarios": [
|
|
25
|
+
"oncall"
|
|
26
|
+
],
|
|
27
|
+
"url": "https://ops.example/"
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
"collab": {
|
|
32
|
+
"templates": []
|
|
33
|
+
},
|
|
34
|
+
"entitlement": {
|
|
35
|
+
"budgetGroups": [],
|
|
36
|
+
"groupBindings": [],
|
|
37
|
+
"subjects": [],
|
|
38
|
+
"tiers": []
|
|
39
|
+
},
|
|
40
|
+
"execution": {
|
|
41
|
+
"allowedLanes": [
|
|
42
|
+
"host"
|
|
43
|
+
],
|
|
44
|
+
"required": false
|
|
45
|
+
},
|
|
46
|
+
"governance": {},
|
|
47
|
+
"hosts": {
|
|
48
|
+
"hosts": []
|
|
49
|
+
},
|
|
50
|
+
"limits": {},
|
|
51
|
+
"mcp": {
|
|
52
|
+
"servers": []
|
|
53
|
+
},
|
|
54
|
+
"models": {
|
|
55
|
+
"atMention": {
|
|
56
|
+
"mode": "all"
|
|
57
|
+
},
|
|
58
|
+
"models": [],
|
|
59
|
+
"roles": {},
|
|
60
|
+
"tierGroups": []
|
|
61
|
+
},
|
|
62
|
+
"plugins": {
|
|
63
|
+
"plugins": []
|
|
64
|
+
},
|
|
65
|
+
"projects": {
|
|
66
|
+
"projects": {}
|
|
67
|
+
},
|
|
68
|
+
"prompts": {},
|
|
69
|
+
"rosters": {
|
|
70
|
+
"rosters": []
|
|
71
|
+
},
|
|
72
|
+
"scenarios": {
|
|
73
|
+
"scenarios": []
|
|
74
|
+
},
|
|
75
|
+
"skills": {
|
|
76
|
+
"skills": []
|
|
77
|
+
},
|
|
78
|
+
"systems": {
|
|
79
|
+
"systems": []
|
|
80
|
+
},
|
|
81
|
+
"workers": {
|
|
82
|
+
"workers": []
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"warnings": [],
|
|
86
|
+
"metadata": {
|
|
87
|
+
"version": 7,
|
|
88
|
+
"updatedAt": "2026-11-03T00:00:00.000Z"
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
"strictWrite": {
|
|
92
|
+
"outcome": "effective",
|
|
93
|
+
"effective": {
|
|
94
|
+
"a2a": {
|
|
95
|
+
"peers": [
|
|
96
|
+
{
|
|
97
|
+
"allowSkills": [
|
|
98
|
+
"search"
|
|
99
|
+
],
|
|
100
|
+
"enabled": true,
|
|
101
|
+
"headerRefs": {
|
|
102
|
+
"Authorization": "KB_TOKEN"
|
|
103
|
+
},
|
|
104
|
+
"name": "kb",
|
|
105
|
+
"principalHeader": "X-Principal",
|
|
106
|
+
"scenarios": [],
|
|
107
|
+
"url": "https://kb.example/a2a"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"cardUrl": "https://ops.example/agent-card.json",
|
|
111
|
+
"enabled": false,
|
|
112
|
+
"name": "ops",
|
|
113
|
+
"scenarios": [
|
|
114
|
+
"oncall"
|
|
115
|
+
],
|
|
116
|
+
"url": "https://ops.example/"
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
"warnings": [],
|
|
122
|
+
"metadata": {
|
|
123
|
+
"version": 7,
|
|
124
|
+
"updatedAt": "2026-11-03T00:00:00.000Z"
|
|
125
|
+
},
|
|
126
|
+
"why": "受理:两个对端都合 `A2aPeerSpec`(URL 不带凭据与 fragment、头名合 token 文法、引用是 env-NAME、对端名可当线上名且不重名);严写收下的就是读腿 a2a 那一格。"
|
|
127
|
+
},
|
|
128
|
+
"wire": {
|
|
129
|
+
"derive": true
|
|
130
|
+
},
|
|
131
|
+
"localRoot": {
|
|
132
|
+
"derive": true,
|
|
133
|
+
"localVersion": 206605001400842
|
|
134
|
+
}
|
|
135
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"version": 7,
|
|
4
|
+
"updatedAt": "2026-11-03T00:00:00.000Z"
|
|
5
|
+
},
|
|
6
|
+
"domains": {
|
|
7
|
+
"a2a": {
|
|
8
|
+
"peers": [
|
|
9
|
+
{
|
|
10
|
+
"name": "kb",
|
|
11
|
+
"url": "https://kb.example/a2a",
|
|
12
|
+
"headerRefs": {
|
|
13
|
+
"Authorization": "KB_TOKEN"
|
|
14
|
+
},
|
|
15
|
+
"principalHeader": "X-Principal",
|
|
16
|
+
"allowSkills": [
|
|
17
|
+
"search"
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "ops",
|
|
22
|
+
"url": "https://ops.example/",
|
|
23
|
+
"cardUrl": "https://ops.example/agent-card.json",
|
|
24
|
+
"scenarios": [
|
|
25
|
+
"oncall"
|
|
26
|
+
],
|
|
27
|
+
"enabled": false
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"contributor": "contract",
|
|
3
|
+
"claim": "`a2a`(常驻出站 A2A 对端名册)是便携域:两个合法对端在四条腿上同读 —— 缺省物化(缺 `scenarios` ⇒ `[]`、缺 `enabled` ⇒ `true`),停用的对端照样在表里(`enabled: false` 由读方过滤,不是读腿丢),header 值只以 env-NAME 引用出现(`headerRefs`),零告警。本地腿读 `config.d/a2a.json`:在没有这个域的包上,同一份文件报 `unread-config-file`、远端 `/effective.a2a` 原样透传 —— 一个仍按旧读法的读腿会把这条读成「对端名册缺席」或「未校验的原文」。",
|
|
4
|
+
"firstRedOn": []
|
|
5
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
{
|
|
2
|
+
"domains": {
|
|
3
|
+
"outcome": "effective",
|
|
4
|
+
"effective": {
|
|
5
|
+
"a2a": {
|
|
6
|
+
"peers": [
|
|
7
|
+
{
|
|
8
|
+
"enabled": true,
|
|
9
|
+
"headerRefs": {
|
|
10
|
+
"Authorization": "KB_TOKEN"
|
|
11
|
+
},
|
|
12
|
+
"name": "kb",
|
|
13
|
+
"scenarios": [],
|
|
14
|
+
"url": "https://kb.example/a2a"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"allowSkills": [
|
|
18
|
+
"search"
|
|
19
|
+
],
|
|
20
|
+
"enabled": true,
|
|
21
|
+
"name": "narrow",
|
|
22
|
+
"scenarios": [],
|
|
23
|
+
"url": "https://narrow.example/a2a"
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
"collab": {
|
|
28
|
+
"templates": []
|
|
29
|
+
},
|
|
30
|
+
"entitlement": {
|
|
31
|
+
"budgetGroups": [],
|
|
32
|
+
"groupBindings": [],
|
|
33
|
+
"subjects": [],
|
|
34
|
+
"tiers": []
|
|
35
|
+
},
|
|
36
|
+
"execution": {
|
|
37
|
+
"allowedLanes": [
|
|
38
|
+
"host"
|
|
39
|
+
],
|
|
40
|
+
"required": false
|
|
41
|
+
},
|
|
42
|
+
"governance": {},
|
|
43
|
+
"hosts": {
|
|
44
|
+
"hosts": []
|
|
45
|
+
},
|
|
46
|
+
"limits": {},
|
|
47
|
+
"mcp": {
|
|
48
|
+
"servers": []
|
|
49
|
+
},
|
|
50
|
+
"models": {
|
|
51
|
+
"atMention": {
|
|
52
|
+
"mode": "all"
|
|
53
|
+
},
|
|
54
|
+
"models": [],
|
|
55
|
+
"roles": {},
|
|
56
|
+
"tierGroups": []
|
|
57
|
+
},
|
|
58
|
+
"plugins": {
|
|
59
|
+
"plugins": []
|
|
60
|
+
},
|
|
61
|
+
"projects": {
|
|
62
|
+
"projects": {}
|
|
63
|
+
},
|
|
64
|
+
"prompts": {},
|
|
65
|
+
"rosters": {
|
|
66
|
+
"rosters": []
|
|
67
|
+
},
|
|
68
|
+
"scenarios": {
|
|
69
|
+
"scenarios": []
|
|
70
|
+
},
|
|
71
|
+
"skills": {
|
|
72
|
+
"skills": []
|
|
73
|
+
},
|
|
74
|
+
"systems": {
|
|
75
|
+
"systems": []
|
|
76
|
+
},
|
|
77
|
+
"workers": {
|
|
78
|
+
"workers": []
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"warnings": [
|
|
82
|
+
{
|
|
83
|
+
"domain": "a2a",
|
|
84
|
+
"identity": {
|
|
85
|
+
"name": "half"
|
|
86
|
+
},
|
|
87
|
+
"kind": "entry-dropped",
|
|
88
|
+
"path": [
|
|
89
|
+
"peers",
|
|
90
|
+
1
|
|
91
|
+
],
|
|
92
|
+
"reasonCode": "entry-schema-invalid"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"domain": "a2a",
|
|
96
|
+
"kind": "entry-dropped",
|
|
97
|
+
"path": [
|
|
98
|
+
"peers",
|
|
99
|
+
2,
|
|
100
|
+
"allowSkills",
|
|
101
|
+
1
|
|
102
|
+
],
|
|
103
|
+
"reasonCode": "entry-schema-invalid"
|
|
104
|
+
}
|
|
105
|
+
],
|
|
106
|
+
"metadata": {
|
|
107
|
+
"version": 7,
|
|
108
|
+
"updatedAt": "2026-11-03T00:00:00.000Z"
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
"strictWrite": {
|
|
112
|
+
"outcome": "rejected",
|
|
113
|
+
"stage": "validate",
|
|
114
|
+
"why": "拒:`half` 的一条 header 引用不是 env-NAME、`half` 与 `narrow` 的 `allowSkills` 各有一个空串 —— 写是一个动作,一处坏整份不受理。"
|
|
115
|
+
},
|
|
116
|
+
"wire": {
|
|
117
|
+
"derive": true
|
|
118
|
+
},
|
|
119
|
+
"localRoot": {
|
|
120
|
+
"derive": true,
|
|
121
|
+
"localVersion": 3675868689326288
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"version": 7,
|
|
4
|
+
"updatedAt": "2026-11-03T00:00:00.000Z"
|
|
5
|
+
},
|
|
6
|
+
"domains": {
|
|
7
|
+
"a2a": {
|
|
8
|
+
"peers": [
|
|
9
|
+
{
|
|
10
|
+
"name": "kb",
|
|
11
|
+
"url": "https://kb.example/a2a",
|
|
12
|
+
"headerRefs": {
|
|
13
|
+
"Authorization": "KB_TOKEN"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"name": "half",
|
|
18
|
+
"url": "https://half.example/a2a",
|
|
19
|
+
"headerRefs": {
|
|
20
|
+
"Authorization": "HALF_TOKEN",
|
|
21
|
+
"X-Tenant": "not an env name"
|
|
22
|
+
},
|
|
23
|
+
"allowSkills": [
|
|
24
|
+
"search",
|
|
25
|
+
""
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"name": "narrow",
|
|
30
|
+
"url": "https://narrow.example/a2a",
|
|
31
|
+
"allowSkills": [
|
|
32
|
+
"search",
|
|
33
|
+
""
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"contributor": "contract",
|
|
3
|
+
"claim": "凭据引用集合不可部分抢救:对端 `half` 的 `headerRefs` 里一条引用坏形(值不是 env-NAME)⇒ **整个对端** `entry-dropped`(域 `a2a`、坐标 `[\"peers\",1]`、身份 `half`),不是只丢那一条引用、留下一个带着一半凭据去拨远端的对端;兄弟 `kb` 原样保留。对照组 `narrow`:非凭据集合(`allowSkills`)里的坏元素照旧逐条丢(坐标 `[\"peers\",2,\"allowSkills\",1]`;丢了只会更窄),对端本身活下来。严写腿整份拒。一个对每个 Record 都逐条抢救的读腿会把 `half` 读成「只带 Authorization 的对端」。",
|
|
4
|
+
"firstRedOn": []
|
|
5
|
+
}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
"domains": {
|
|
3
3
|
"outcome": "effective",
|
|
4
4
|
"effective": {
|
|
5
|
+
"a2a": {
|
|
6
|
+
"peers": []
|
|
7
|
+
},
|
|
5
8
|
"collab": {
|
|
6
9
|
"templates": []
|
|
7
10
|
},
|
|
@@ -161,6 +164,6 @@
|
|
|
161
164
|
},
|
|
162
165
|
"localRoot": {
|
|
163
166
|
"derive": true,
|
|
164
|
-
"localVersion":
|
|
167
|
+
"localVersion": 3253988119103129
|
|
165
168
|
}
|
|
166
169
|
}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
"domains": {
|
|
3
3
|
"outcome": "effective",
|
|
4
4
|
"effective": {
|
|
5
|
+
"a2a": {
|
|
6
|
+
"peers": []
|
|
7
|
+
},
|
|
5
8
|
"collab": {
|
|
6
9
|
"templates": []
|
|
7
10
|
},
|
|
@@ -107,6 +110,6 @@
|
|
|
107
110
|
},
|
|
108
111
|
"localRoot": {
|
|
109
112
|
"derive": true,
|
|
110
|
-
"localVersion":
|
|
113
|
+
"localVersion": 3591318400132154
|
|
111
114
|
}
|
|
112
115
|
}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
"domains": {
|
|
3
3
|
"outcome": "effective",
|
|
4
4
|
"effective": {
|
|
5
|
+
"a2a": {
|
|
6
|
+
"peers": []
|
|
7
|
+
},
|
|
5
8
|
"collab": {
|
|
6
9
|
"templates": []
|
|
7
10
|
},
|
|
@@ -116,6 +119,6 @@
|
|
|
116
119
|
},
|
|
117
120
|
"localRoot": {
|
|
118
121
|
"derive": true,
|
|
119
|
-
"localVersion":
|
|
122
|
+
"localVersion": 1663867526020649
|
|
120
123
|
}
|
|
121
124
|
}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
"domains": {
|
|
3
3
|
"outcome": "effective",
|
|
4
4
|
"effective": {
|
|
5
|
+
"a2a": {
|
|
6
|
+
"peers": []
|
|
7
|
+
},
|
|
5
8
|
"collab": {
|
|
6
9
|
"templates": []
|
|
7
10
|
},
|
|
@@ -112,6 +115,6 @@
|
|
|
112
115
|
},
|
|
113
116
|
"localRoot": {
|
|
114
117
|
"derive": true,
|
|
115
|
-
"localVersion":
|
|
118
|
+
"localVersion": 2654544430240950
|
|
116
119
|
}
|
|
117
120
|
}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
"domains": {
|
|
3
3
|
"outcome": "effective",
|
|
4
4
|
"effective": {
|
|
5
|
+
"a2a": {
|
|
6
|
+
"peers": []
|
|
7
|
+
},
|
|
5
8
|
"collab": {
|
|
6
9
|
"templates": []
|
|
7
10
|
},
|
|
@@ -125,6 +128,6 @@
|
|
|
125
128
|
},
|
|
126
129
|
"localRoot": {
|
|
127
130
|
"derive": true,
|
|
128
|
-
"localVersion":
|
|
131
|
+
"localVersion": 3769852229872529
|
|
129
132
|
}
|
|
130
133
|
}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
"domains": {
|
|
3
3
|
"outcome": "effective",
|
|
4
4
|
"effective": {
|
|
5
|
+
"a2a": {
|
|
6
|
+
"peers": []
|
|
7
|
+
},
|
|
5
8
|
"collab": {
|
|
6
9
|
"templates": []
|
|
7
10
|
},
|
|
@@ -121,6 +124,6 @@
|
|
|
121
124
|
},
|
|
122
125
|
"localRoot": {
|
|
123
126
|
"derive": true,
|
|
124
|
-
"localVersion":
|
|
127
|
+
"localVersion": 1531100058823047
|
|
125
128
|
}
|
|
126
129
|
}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
"domains": {
|
|
3
3
|
"outcome": "effective",
|
|
4
4
|
"effective": {
|
|
5
|
+
"a2a": {
|
|
6
|
+
"peers": []
|
|
7
|
+
},
|
|
5
8
|
"collab": {
|
|
6
9
|
"templates": []
|
|
7
10
|
},
|
|
@@ -149,6 +152,6 @@
|
|
|
149
152
|
},
|
|
150
153
|
"localRoot": {
|
|
151
154
|
"derive": true,
|
|
152
|
-
"localVersion":
|
|
155
|
+
"localVersion": 1531100058823047
|
|
153
156
|
}
|
|
154
157
|
}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
"domains": {
|
|
3
3
|
"outcome": "effective",
|
|
4
4
|
"effective": {
|
|
5
|
+
"a2a": {
|
|
6
|
+
"peers": []
|
|
7
|
+
},
|
|
5
8
|
"collab": {
|
|
6
9
|
"templates": []
|
|
7
10
|
},
|
|
@@ -148,6 +151,6 @@
|
|
|
148
151
|
},
|
|
149
152
|
"localRoot": {
|
|
150
153
|
"derive": true,
|
|
151
|
-
"localVersion":
|
|
154
|
+
"localVersion": 3555569200054848
|
|
152
155
|
}
|
|
153
156
|
}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
"domains": {
|
|
3
3
|
"outcome": "effective",
|
|
4
4
|
"effective": {
|
|
5
|
+
"a2a": {
|
|
6
|
+
"peers": []
|
|
7
|
+
},
|
|
5
8
|
"collab": {
|
|
6
9
|
"templates": []
|
|
7
10
|
},
|
|
@@ -91,6 +94,6 @@
|
|
|
91
94
|
},
|
|
92
95
|
"localRoot": {
|
|
93
96
|
"derive": true,
|
|
94
|
-
"localVersion":
|
|
97
|
+
"localVersion": 1409565868890479
|
|
95
98
|
}
|
|
96
99
|
}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
"domains": {
|
|
3
3
|
"outcome": "effective",
|
|
4
4
|
"effective": {
|
|
5
|
+
"a2a": {
|
|
6
|
+
"peers": []
|
|
7
|
+
},
|
|
5
8
|
"collab": {
|
|
6
9
|
"templates": []
|
|
7
10
|
},
|
|
@@ -152,6 +155,6 @@
|
|
|
152
155
|
},
|
|
153
156
|
"localRoot": {
|
|
154
157
|
"derive": true,
|
|
155
|
-
"localVersion":
|
|
158
|
+
"localVersion": 3557208461559525
|
|
156
159
|
}
|
|
157
160
|
}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
"domains": {
|
|
3
3
|
"outcome": "effective",
|
|
4
4
|
"effective": {
|
|
5
|
+
"a2a": {
|
|
6
|
+
"peers": []
|
|
7
|
+
},
|
|
5
8
|
"collab": {
|
|
6
9
|
"templates": []
|
|
7
10
|
},
|
|
@@ -108,6 +111,6 @@
|
|
|
108
111
|
},
|
|
109
112
|
"localRoot": {
|
|
110
113
|
"derive": true,
|
|
111
|
-
"localVersion":
|
|
114
|
+
"localVersion": 3944259292559843
|
|
112
115
|
}
|
|
113
116
|
}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
"domains": {
|
|
3
3
|
"outcome": "effective",
|
|
4
4
|
"effective": {
|
|
5
|
+
"a2a": {
|
|
6
|
+
"peers": []
|
|
7
|
+
},
|
|
5
8
|
"collab": {
|
|
6
9
|
"templates": []
|
|
7
10
|
},
|
|
@@ -131,6 +134,6 @@
|
|
|
131
134
|
},
|
|
132
135
|
"localRoot": {
|
|
133
136
|
"derive": true,
|
|
134
|
-
"localVersion":
|
|
137
|
+
"localVersion": 3006809479574243
|
|
135
138
|
}
|
|
136
139
|
}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
"domains": {
|
|
3
3
|
"outcome": "effective",
|
|
4
4
|
"effective": {
|
|
5
|
+
"a2a": {
|
|
6
|
+
"peers": []
|
|
7
|
+
},
|
|
5
8
|
"collab": {
|
|
6
9
|
"templates": []
|
|
7
10
|
},
|
|
@@ -425,6 +428,6 @@
|
|
|
425
428
|
},
|
|
426
429
|
"localRoot": {
|
|
427
430
|
"derive": true,
|
|
428
|
-
"localVersion":
|
|
431
|
+
"localVersion": 1287865876181806
|
|
429
432
|
}
|
|
430
433
|
}
|
package/dist/atomic-write.d.ts
CHANGED
|
@@ -16,10 +16,11 @@ export declare function danglingSymlinkSentence(link: string, pointsAt: string):
|
|
|
16
16
|
/** 读写的真目标 —— **一只判法**(写器与目录迁移的读口共用):`target` 是符号链接 ⇒ 解析到它指向的真文件(悬空 ⇒ 抛 {@link danglingSymlinkSentence});
|
|
17
17
|
* 不是链接或不存在 ⇒ 原样(不存在的由调用方的读 / 写照常报)。 */
|
|
18
18
|
export declare function resolveSymlinkTarget(target: string): string;
|
|
19
|
-
/** 读一份**可以缺席**的 UTF-8 文本 —— `config.d` 文档与 `.env`
|
|
20
|
-
*
|
|
21
|
-
* 别的读不出(`EACCES` / `EISDIR` / `ELOOP` …)原样抛。配置根自己是悬空链接(祖先座)不在问的范围内:`dirSeats` 只列文件所在的那一级布局座。 */
|
|
19
|
+
/** 读一份**可以缺席**的 UTF-8 文本 —— `config.d` 文档与 `.env` 的缺席律在 {@link absentUnlessDangling}:读得到 ⇒ 文本;读不出 ⇒ 缺席尾(`ENOENT` 且无座位是悬空链接 ⇒ `undefined`;悬空 ⇒ 抛那一句;别的读不出原样抛)。
|
|
20
|
+
* 配置根自己是悬空链接(祖先座)不在问的范围内:`dirSeats` 只列文件所在的那一级布局座。 */
|
|
22
21
|
export declare function readTextIfPresent(file: string, dirSeats?: readonly string[]): Promise<string | undefined>;
|
|
22
|
+
/** {@link readTextIfPresent} 的同步孪生(壳在同步具名锁里读 `config.d` 文档要它):同一个缺席尾,只有读文本那一行 I/O 不同。 */
|
|
23
|
+
export declare function readTextIfPresentSync(file: string, dirSeats?: readonly string[]): string | undefined;
|
|
23
24
|
/** 原子写 `text`(UTF-8)到 `target`(符号链接则写到它指向的真文件,见文件头);模式按 `kind` 在 {@link ATOMIC_FILE_CLASSES} 里的行。父目录须已存在。 */
|
|
24
25
|
export declare function writeFileAtomic(target: string, text: string, kind: AtomicFileClass): void;
|
|
25
26
|
/**
|
package/dist/atomic-write.js
CHANGED
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
* 「链接 ⇒ 真文件、悬空 ⇒ 响亮抛」这一只判法是 {@link resolveSymlinkTarget}:目录迁移的读口(`./config-dir-io`)读目录 / 读文件前也问它,
|
|
21
21
|
* 悬空链接在读阶段与写阶段是**同一句**({@link danglingSymlinkSentence})。
|
|
22
22
|
*
|
|
23
|
-
* ## `config.d` 文档与 `.env` 的缺席只有一种读法({@link
|
|
23
|
+
* ## `config.d` 文档与 `.env` 的缺席只有一种读法({@link absentUnlessDangling})
|
|
24
24
|
* **缺席 = 路径上没有任何条目。** `readFile` 跟着符号链接走,链接在而目标不在时内核同样答 `ENOENT`:那是在场却读不出,不是缺席。读一份可以缺席的文本(`config.d` 的文档、配置根下的 `.env`)
|
|
25
|
-
*
|
|
25
|
+
* 因此都过同一只缺席尾({@link absentUnlessDangling};异步读者 {@link readTextIfPresent} 与同步读者 {@link readTextIfPresentSync} 各留一行读文本的 I/O) —— 读不出且是 `ENOENT` ⇒ 在**缺席臂里**问一次链接判法再答「缺席」,悬空 ⇒ 抛那一句(同一句,不带 errno 码)。判在缺席臂而不在读前:读得到的路径零变化(不多一次系统调用);读之后目标恰好出现仍答缺席 —— 读的那一刻它确实不在,与旧读法同一边界,不是放宽。
|
|
26
26
|
*
|
|
27
27
|
* ## 不存在才建({@link createFileExclusive})
|
|
28
28
|
* 另一种写法只有一处不同:最后一步不是 `rename` 盖过目标,而是把(已 fsync 的)临时文件 `link` 成目标名 —— 目标名已在(任何东西:文件、目录、哪怕是悬空的符号链接)⇒
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
*/
|
|
44
44
|
import { randomBytes } from "node:crypto";
|
|
45
45
|
import { readFile } from "node:fs/promises";
|
|
46
|
-
import { chmodSync, closeSync, existsSync, fsyncSync, linkSync, lstatSync, mkdirSync, openSync, readlinkSync, realpathSync, renameSync, statSync, unlinkSync, writeFileSync, writeSync } from "node:fs";
|
|
46
|
+
import { chmodSync, closeSync, existsSync, fsyncSync, linkSync, lstatSync, mkdirSync, openSync, readFileSync, readlinkSync, realpathSync, renameSync, statSync, unlinkSync, writeFileSync, writeSync } from "node:fs";
|
|
47
47
|
import path from "node:path";
|
|
48
48
|
import { FsFailure } from "./fs-failure.js";
|
|
49
49
|
/** 按文档类的模式表(闭集)。 */
|
|
@@ -80,20 +80,34 @@ export function resolveSymlinkTarget(target) {
|
|
|
80
80
|
throw e;
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
|
-
/**
|
|
84
|
-
*
|
|
85
|
-
*
|
|
83
|
+
/** 读一份**可以缺席**的文本之后,「读不出」怎么答的**缺席尾**(异步 {@link readTextIfPresent} 与同步 {@link readTextIfPresentSync} 共用,缺席律只此一处):读失败 `e` 不是 `ENOENT` ⇒ 原样抛(`EACCES` / `EISDIR` / `ELOOP` …);
|
|
84
|
+
* 是 `ENOENT` ⇒ 先在缺席臂里对 `file` 自己与 `dirSeats`(这份文件所在、包把它当布局座的目录,如 `config.d`)各问一次 {@link resolveSymlinkTarget}(与目录迁移的读口同一只判官):任一座是悬空链接 ⇒ 抛
|
|
85
|
+
* {@link danglingSymlinkSentence} 那一句(在场却读不出,不是缺席);都不是 ⇒ `undefined`(路径上真的没有条目)。 */
|
|
86
|
+
function absentUnlessDangling(e, file, dirSeats) {
|
|
87
|
+
if (e.code !== "ENOENT")
|
|
88
|
+
throw e;
|
|
89
|
+
for (const seat of [file, ...dirSeats])
|
|
90
|
+
resolveSymlinkTarget(seat);
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
/** 读一份**可以缺席**的 UTF-8 文本 —— `config.d` 文档与 `.env` 的缺席律在 {@link absentUnlessDangling}:读得到 ⇒ 文本;读不出 ⇒ 缺席尾(`ENOENT` 且无座位是悬空链接 ⇒ `undefined`;悬空 ⇒ 抛那一句;别的读不出原样抛)。
|
|
94
|
+
* 配置根自己是悬空链接(祖先座)不在问的范围内:`dirSeats` 只列文件所在的那一级布局座。 */
|
|
86
95
|
export async function readTextIfPresent(file, dirSeats = []) {
|
|
87
96
|
try {
|
|
88
97
|
return await readFile(file, "utf8");
|
|
89
98
|
}
|
|
90
99
|
catch (e) {
|
|
91
|
-
|
|
92
|
-
|
|
100
|
+
return absentUnlessDangling(e, file, dirSeats);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/** {@link readTextIfPresent} 的同步孪生(壳在同步具名锁里读 `config.d` 文档要它):同一个缺席尾,只有读文本那一行 I/O 不同。 */
|
|
104
|
+
export function readTextIfPresentSync(file, dirSeats = []) {
|
|
105
|
+
try {
|
|
106
|
+
return readFileSync(file, "utf8");
|
|
107
|
+
}
|
|
108
|
+
catch (e) {
|
|
109
|
+
return absentUnlessDangling(e, file, dirSeats);
|
|
93
110
|
}
|
|
94
|
-
for (const seat of [file, ...dirSeats])
|
|
95
|
-
resolveSymlinkTarget(seat);
|
|
96
|
-
return undefined;
|
|
97
111
|
}
|
|
98
112
|
/** 原子写 `text`(UTF-8)到 `target`(符号链接则写到它指向的真文件,见文件头);模式按 `kind` 在 {@link ATOMIC_FILE_CLASSES} 里的行。父目录须已存在。 */
|
|
99
113
|
export function writeFileAtomic(target, text, kind) {
|