@sema-agent/settings-schema 17.2.0 → 19.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 +216 -0
- package/README.md +53 -6
- 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/center-refs.d.ts +4 -3
- package/dist/center-refs.js +8 -6
- package/dist/cli.d.ts +1 -1
- package/dist/config-fns.d.ts +6 -1
- package/dist/config-fns.js +16 -2
- 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/hooks-config.d.ts +23 -5
- package/dist/hooks-config.js +33 -5
- package/dist/hooks.d.ts +6 -4
- package/dist/hooks.js +3 -1
- package/dist/mcp-request-entry.d.ts +11 -21
- package/dist/mcp-request-entry.js +21 -38
- 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/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 +27 -6
- package/docs/CC-DIVERGENCE.md +2 -2
- package/docs/CONSUMER-INTEGRATION.md +72 -7
- package/llms-full.txt +38 -18
- package/llms.txt +10 -10
- package/package.json +1 -1
package/dist/types.d.ts
CHANGED
|
@@ -1428,17 +1428,9 @@ export declare const WorkerSpec: z.ZodObject<{
|
|
|
1428
1428
|
runtime: z.ZodObject<{
|
|
1429
1429
|
execution: z.ZodOptional<z.ZodObject<{
|
|
1430
1430
|
lane: z.ZodOptional<z.ZodNever>;
|
|
1431
|
-
lanes: z.
|
|
1432
|
-
host: "host";
|
|
1433
|
-
e2b: "e2b";
|
|
1434
|
-
k8s: "k8s";
|
|
1435
|
-
ssh: "ssh";
|
|
1436
|
-
adb: "adb";
|
|
1437
|
-
"local-docker": "local-docker";
|
|
1438
|
-
device: "device";
|
|
1439
|
-
}>>;
|
|
1431
|
+
lanes: z.ZodPreprocess<z.ZodPipe<z.ZodUnknown, z.ZodTransform<("none" | "host" | "e2b" | "k8s" | "ssh" | "adb" | "local-docker" | "device")[], unknown>>, unknown>;
|
|
1440
1432
|
coords: z.ZodPrefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
1441
|
-
secretRefs: z.ZodPrefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
1433
|
+
secretRefs: z.ZodPrefault<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodString>, unknown>>;
|
|
1442
1434
|
}, z.core.$strip>>;
|
|
1443
1435
|
store: z.ZodOptional<z.ZodObject<{
|
|
1444
1436
|
backend: z.ZodEnum<{
|
|
@@ -1492,7 +1484,7 @@ export declare const WorkerSpec: z.ZodObject<{
|
|
|
1492
1484
|
tidbPasswordEnv: z.ZodOptional<z.ZodNever>;
|
|
1493
1485
|
}, z.core.$strip>;
|
|
1494
1486
|
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
1495
|
-
secretEnv: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
1487
|
+
secretEnv: z.ZodOptional<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodString>, unknown>>;
|
|
1496
1488
|
recreateNonce: z.ZodOptional<z.ZodString>;
|
|
1497
1489
|
lifecycle: z.ZodOptional<z.ZodObject<{
|
|
1498
1490
|
kind: z.ZodDefault<z.ZodEnum<{
|
|
@@ -1597,17 +1589,9 @@ export declare const WorkersConfig: z.ZodObject<{
|
|
|
1597
1589
|
runtime: z.ZodObject<{
|
|
1598
1590
|
execution: z.ZodOptional<z.ZodObject<{
|
|
1599
1591
|
lane: z.ZodOptional<z.ZodNever>;
|
|
1600
|
-
lanes: z.
|
|
1601
|
-
host: "host";
|
|
1602
|
-
e2b: "e2b";
|
|
1603
|
-
k8s: "k8s";
|
|
1604
|
-
ssh: "ssh";
|
|
1605
|
-
adb: "adb";
|
|
1606
|
-
"local-docker": "local-docker";
|
|
1607
|
-
device: "device";
|
|
1608
|
-
}>>;
|
|
1592
|
+
lanes: z.ZodPreprocess<z.ZodPipe<z.ZodUnknown, z.ZodTransform<("none" | "host" | "e2b" | "k8s" | "ssh" | "adb" | "local-docker" | "device")[], unknown>>, unknown>;
|
|
1609
1593
|
coords: z.ZodPrefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
1610
|
-
secretRefs: z.ZodPrefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
1594
|
+
secretRefs: z.ZodPrefault<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodString>, unknown>>;
|
|
1611
1595
|
}, z.core.$strip>>;
|
|
1612
1596
|
store: z.ZodOptional<z.ZodObject<{
|
|
1613
1597
|
backend: z.ZodEnum<{
|
|
@@ -1661,7 +1645,7 @@ export declare const WorkersConfig: z.ZodObject<{
|
|
|
1661
1645
|
tidbPasswordEnv: z.ZodOptional<z.ZodNever>;
|
|
1662
1646
|
}, z.core.$strip>;
|
|
1663
1647
|
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
1664
|
-
secretEnv: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
1648
|
+
secretEnv: z.ZodOptional<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodString>, unknown>>;
|
|
1665
1649
|
recreateNonce: z.ZodOptional<z.ZodString>;
|
|
1666
1650
|
lifecycle: z.ZodOptional<z.ZodObject<{
|
|
1667
1651
|
kind: z.ZodDefault<z.ZodEnum<{
|
|
@@ -1844,15 +1828,28 @@ export declare const SkillsManifestSchema: z.ZodObject<{
|
|
|
1844
1828
|
contentHash: z.ZodString;
|
|
1845
1829
|
}, z.core.$strip>>>;
|
|
1846
1830
|
}, z.core.$strip>;
|
|
1831
|
+
/**
|
|
1832
|
+
* 18.0.0 —— **凭据引用集合不可部分抢救**(按 schema 身份的集合)。成员是「名 → 宿主 env-NAME」的凭据引用 Record:mcp 的 `envRefs` / `headerRefs`
|
|
1833
|
+
* (a2a 对端的 `headerRefs` 复用后者,因此同在)、车道块的 `secretRefs` 与 worker 的 `secretEnv`。逐条抢救(`salvageEntries`)走到成员**不下钻**、把它当一个值判:
|
|
1834
|
+
* 集合里任一键 / 值坏形 ⇒ 它所属的那一条条目整条 `entry-dropped`,兄弟条目保留。理由:丢掉一条坏引用不是「更窄」,而是让条目带着**一半凭据**活下来 ——
|
|
1835
|
+
* 拨一个远端服务 / 智能体时错误的失败方向(读方对「任一引用的 env 缺席」本来就整条跳过,同一个方向)。
|
|
1836
|
+
* 既有读数只变一处:直接对 `WorkersConfig` 调 `salvageEntries` 时,`secretEnv` 带坏引用的 worker 由「只丢那一条引用、worker 存活」变「整条丢」
|
|
1837
|
+
* (各域读数不变:workers 域不逐条抢救;mcp 的两只住在传输判别联合里,走查不进联合;车道块住在不是集合的 `runtime` 对象里)
|
|
1838
|
+
* —— 由 17.2.0 包的真读数逐行对拍钉住(`test/atomic-salvage-18.0.0.test.ts`,改了读数的那一行逐行登记)。别的集合字段(allowTools / scenarios / allowSkills …)照旧逐条抢救:丢坏元素只会更窄。
|
|
1839
|
+
* 成员读键按自有属性名判:`__proto__` / `constructor` / `prototype` 任一在场 ⇒ 集合坏 ⇒ 条目整条丢(见 `credentialRefs`;zod 的 record 读键前跳过 `__proto__`、不判它的值)。
|
|
1840
|
+
* 新的凭据引用集合必须复用这几只 schema 或由 `credentialRefs` 铸出并登记进这里(按身份判,换一只「形一样」的新 schema 不算成员)。
|
|
1841
|
+
* 登记的是剥掉包装之后的那只 `record`(与抢救走查同一只读法 `unwrapSchema`)。
|
|
1842
|
+
*/
|
|
1843
|
+
export declare const ATOMIC_SALVAGE: ReadonlySet<z.ZodType>;
|
|
1847
1844
|
export declare const McpTransport: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
1848
1845
|
kind: z.ZodLiteral<"stdio">;
|
|
1849
1846
|
command: z.ZodString;
|
|
1850
1847
|
args: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1851
|
-
envRefs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
1848
|
+
envRefs: z.ZodOptional<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodString>, unknown>>;
|
|
1852
1849
|
}, z.core.$strip>, z.ZodObject<{
|
|
1853
1850
|
kind: z.ZodLiteral<"http">;
|
|
1854
1851
|
url: z.ZodString;
|
|
1855
|
-
headerRefs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
1852
|
+
headerRefs: z.ZodOptional<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodString>, unknown>>;
|
|
1856
1853
|
principalHeader: z.ZodOptional<z.ZodString>;
|
|
1857
1854
|
assertionHeader: z.ZodOptional<z.ZodString>;
|
|
1858
1855
|
}, z.core.$strip>], "kind">;
|
|
@@ -1870,11 +1867,11 @@ export declare const McpServerSpec: z.ZodObject<{
|
|
|
1870
1867
|
kind: z.ZodLiteral<"stdio">;
|
|
1871
1868
|
command: z.ZodString;
|
|
1872
1869
|
args: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1873
|
-
envRefs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
1870
|
+
envRefs: z.ZodOptional<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodString>, unknown>>;
|
|
1874
1871
|
}, z.core.$strip>, z.ZodObject<{
|
|
1875
1872
|
kind: z.ZodLiteral<"http">;
|
|
1876
1873
|
url: z.ZodString;
|
|
1877
|
-
headerRefs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
1874
|
+
headerRefs: z.ZodOptional<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodString>, unknown>>;
|
|
1878
1875
|
principalHeader: z.ZodOptional<z.ZodString>;
|
|
1879
1876
|
assertionHeader: z.ZodOptional<z.ZodString>;
|
|
1880
1877
|
}, z.core.$strip>], "kind">;
|
|
@@ -1905,11 +1902,11 @@ export declare const McpConfig: z.ZodObject<{
|
|
|
1905
1902
|
kind: z.ZodLiteral<"stdio">;
|
|
1906
1903
|
command: z.ZodString;
|
|
1907
1904
|
args: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1908
|
-
envRefs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
1905
|
+
envRefs: z.ZodOptional<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodString>, unknown>>;
|
|
1909
1906
|
}, z.core.$strip>, z.ZodObject<{
|
|
1910
1907
|
kind: z.ZodLiteral<"http">;
|
|
1911
1908
|
url: z.ZodString;
|
|
1912
|
-
headerRefs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
1909
|
+
headerRefs: z.ZodOptional<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodString>, unknown>>;
|
|
1913
1910
|
principalHeader: z.ZodOptional<z.ZodString>;
|
|
1914
1911
|
assertionHeader: z.ZodOptional<z.ZodString>;
|
|
1915
1912
|
}, z.core.$strip>], "kind">;
|
|
@@ -1934,6 +1931,32 @@ export declare const McpConfig: z.ZodObject<{
|
|
|
1934
1931
|
}, z.core.$strip>>>;
|
|
1935
1932
|
}, z.core.$strip>;
|
|
1936
1933
|
export type McpConfig = z.infer<typeof McpConfig>;
|
|
1934
|
+
/** 一个常驻出站 A2A 对端。 */
|
|
1935
|
+
export declare const A2aPeerSpec: z.ZodObject<{
|
|
1936
|
+
name: z.ZodString & z.ZodType<string, string, z.core.$ZodTypeInternals<string, string>>;
|
|
1937
|
+
url: z.ZodString;
|
|
1938
|
+
cardUrl: z.ZodOptional<z.ZodString>;
|
|
1939
|
+
headerRefs: z.ZodOptional<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodString>, unknown>>;
|
|
1940
|
+
principalHeader: z.ZodOptional<z.ZodString>;
|
|
1941
|
+
allowSkills: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1942
|
+
scenarios: z.ZodPrefault<z.ZodArray<z.ZodString>>;
|
|
1943
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
1944
|
+
}, z.core.$strip>;
|
|
1945
|
+
export type A2aPeerSpec = z.infer<typeof A2aPeerSpec>;
|
|
1946
|
+
/** `a2a` 域:常驻出站 A2A 对端名册。空 / 缺席 = 不拨任何对端。对端名唯一(重名拒,同 mcp)。 */
|
|
1947
|
+
export declare const A2aConfig: z.ZodObject<{
|
|
1948
|
+
peers: z.ZodPrefault<z.ZodArray<z.ZodObject<{
|
|
1949
|
+
name: z.ZodString & z.ZodType<string, string, z.core.$ZodTypeInternals<string, string>>;
|
|
1950
|
+
url: z.ZodString;
|
|
1951
|
+
cardUrl: z.ZodOptional<z.ZodString>;
|
|
1952
|
+
headerRefs: z.ZodOptional<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodString>, unknown>>;
|
|
1953
|
+
principalHeader: z.ZodOptional<z.ZodString>;
|
|
1954
|
+
allowSkills: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1955
|
+
scenarios: z.ZodPrefault<z.ZodArray<z.ZodString>>;
|
|
1956
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
1957
|
+
}, z.core.$strip>>>;
|
|
1958
|
+
}, z.core.$strip>;
|
|
1959
|
+
export type A2aConfig = z.infer<typeof A2aConfig>;
|
|
1937
1960
|
/** A plugin/marketplace ORIGIN string: **https only**(contract freeze [ref] tightening-① /
|
|
1938
1961
|
* [1366]①,0.10.23 单真源修:此前这条规则只落在 web UI 层的表单校验,API 直写仍放行任意形——
|
|
1939
1962
|
* 同一条规则两处真源,API 这处敞了 8 天)。`ssh:`/`scp 形`/`git:`/`file:`/裸 `http:`/`owner/repo`
|
|
@@ -2509,11 +2532,11 @@ export declare const DOMAIN_SCHEMAS: {
|
|
|
2509
2532
|
kind: z.ZodLiteral<"stdio">;
|
|
2510
2533
|
command: z.ZodString;
|
|
2511
2534
|
args: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2512
|
-
envRefs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
2535
|
+
envRefs: z.ZodOptional<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodString>, unknown>>;
|
|
2513
2536
|
}, z.core.$strip>, z.ZodObject<{
|
|
2514
2537
|
kind: z.ZodLiteral<"http">;
|
|
2515
2538
|
url: z.ZodString;
|
|
2516
|
-
headerRefs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
2539
|
+
headerRefs: z.ZodOptional<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodString>, unknown>>;
|
|
2517
2540
|
principalHeader: z.ZodOptional<z.ZodString>;
|
|
2518
2541
|
assertionHeader: z.ZodOptional<z.ZodString>;
|
|
2519
2542
|
}, z.core.$strip>], "kind">;
|
|
@@ -2677,17 +2700,9 @@ export declare const DOMAIN_SCHEMAS: {
|
|
|
2677
2700
|
runtime: z.ZodObject<{
|
|
2678
2701
|
execution: z.ZodOptional<z.ZodObject<{
|
|
2679
2702
|
lane: z.ZodOptional<z.ZodNever>;
|
|
2680
|
-
lanes: z.
|
|
2681
|
-
host: "host";
|
|
2682
|
-
e2b: "e2b";
|
|
2683
|
-
k8s: "k8s";
|
|
2684
|
-
ssh: "ssh";
|
|
2685
|
-
adb: "adb";
|
|
2686
|
-
"local-docker": "local-docker";
|
|
2687
|
-
device: "device";
|
|
2688
|
-
}>>;
|
|
2703
|
+
lanes: z.ZodPreprocess<z.ZodPipe<z.ZodUnknown, z.ZodTransform<("none" | "host" | "e2b" | "k8s" | "ssh" | "adb" | "local-docker" | "device")[], unknown>>, unknown>;
|
|
2689
2704
|
coords: z.ZodPrefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
2690
|
-
secretRefs: z.ZodPrefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
2705
|
+
secretRefs: z.ZodPrefault<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodString>, unknown>>;
|
|
2691
2706
|
}, z.core.$strip>>;
|
|
2692
2707
|
store: z.ZodOptional<z.ZodObject<{
|
|
2693
2708
|
backend: z.ZodEnum<{
|
|
@@ -2741,7 +2756,7 @@ export declare const DOMAIN_SCHEMAS: {
|
|
|
2741
2756
|
tidbPasswordEnv: z.ZodOptional<z.ZodNever>;
|
|
2742
2757
|
}, z.core.$strip>;
|
|
2743
2758
|
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
2744
|
-
secretEnv: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
2759
|
+
secretEnv: z.ZodOptional<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodString>, unknown>>;
|
|
2745
2760
|
recreateNonce: z.ZodOptional<z.ZodString>;
|
|
2746
2761
|
lifecycle: z.ZodOptional<z.ZodObject<{
|
|
2747
2762
|
kind: z.ZodDefault<z.ZodEnum<{
|
|
@@ -3083,6 +3098,18 @@ export declare const DOMAIN_SCHEMAS: {
|
|
|
3083
3098
|
runStaleSec: z.ZodOptional<z.ZodNumber>;
|
|
3084
3099
|
toolResultTtlSec: z.ZodOptional<z.ZodNumber>;
|
|
3085
3100
|
}, z.core.$loose>;
|
|
3101
|
+
readonly a2a: z.ZodObject<{
|
|
3102
|
+
peers: z.ZodPrefault<z.ZodArray<z.ZodObject<{
|
|
3103
|
+
name: z.ZodString & z.ZodType<string, string, z.core.$ZodTypeInternals<string, string>>;
|
|
3104
|
+
url: z.ZodString;
|
|
3105
|
+
cardUrl: z.ZodOptional<z.ZodString>;
|
|
3106
|
+
headerRefs: z.ZodOptional<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodString>, unknown>>;
|
|
3107
|
+
principalHeader: z.ZodOptional<z.ZodString>;
|
|
3108
|
+
allowSkills: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
3109
|
+
scenarios: z.ZodPrefault<z.ZodArray<z.ZodString>>;
|
|
3110
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
3111
|
+
}, z.core.$strip>>>;
|
|
3112
|
+
}, z.core.$strip>;
|
|
3086
3113
|
};
|
|
3087
3114
|
export type DomainName = keyof typeof DOMAIN_SCHEMAS;
|
|
3088
3115
|
export type DomainConfig = {
|
|
@@ -3130,6 +3157,8 @@ export interface EffectiveConfig {
|
|
|
3130
3157
|
/** cost/限流族的热更新发布位(0.19.0,消费方 #322 批1)。域缺席 ⇒ `{}`(每一键都 ABSENT =
|
|
3131
3158
|
* web-admin 不管 ⇒ 消费方回 env 底);11.0.0 起五个限额键的唯一位。 */
|
|
3132
3159
|
limits: LimitsConfig;
|
|
3160
|
+
/** 常驻出站 A2A 对端名册(18.0.0)。域缺席 ⇒ `{ peers: [] }`(缺席 ≡ 空表:不拨任何对端);header 值只以 env-NAME 引用出现,读方从自己的环境取值。 */
|
|
3161
|
+
a2a: A2aConfig;
|
|
3133
3162
|
}
|
|
3134
3163
|
/** One provenance source in a key's resolution trail. Two orthogonal axes: the TOC file LAYER, or the TOB
|
|
3135
3164
|
* PRINCIPAL dimension. `applied:false` + `reason` mark a source whose attempt was REJECTED by the monotone
|
package/dist/types.js
CHANGED
|
@@ -22,21 +22,24 @@ import { MAX_EXTRA_BODY_DEPTH } from "./hash.js"; // reconcile the extraBody dep
|
|
|
22
22
|
import { DispatchPolicy, FLEET_GENERATION_ENV, FLEET_SCOPE_ENV } from "./fleet.js"; // WorkerSpec.fleet.dispatch (scheduling framework D3)
|
|
23
23
|
import { isLoopbackAuthHost } from "./loopback.js";
|
|
24
24
|
import { isJsonArray, isPlainJsonObject } from "./plain-json-object.js"; // THE "is this a JSON object" predicate + the total array test
|
|
25
|
-
import { appendOwn, guardedSafeParse, isAccessorDescriptor } from "./own-key-read.js"; // the one spelling of "is this descriptor an accessor" (its own fields only) + the one guarded zod verdict
|
|
25
|
+
import { appendOwn, guardedSafeParse, isAccessorDescriptor, ownEntriesOf } from "./own-key-read.js"; // the one spelling of "is this descriptor an accessor" (its own fields only) + the one guarded zod verdict
|
|
26
26
|
import { httpUrlFlaws, httpUrlRule } from "./url-shape.js"; // 11.0.0: THE URL shape judge // 11.0.0: the one narrow「本机」predicate (auth relaxation)
|
|
27
27
|
import { secretScanForms } from "./secret-scan.js"; // package-private normalization — the one set of forms both scanners read (not in the barrel)
|
|
28
28
|
import { WEB_ADMIN_ENV } from "./web-admin-env.js"; // the three connection keys the config renderer writes are reserved worker env
|
|
29
29
|
import { PREVIOUS_WEB_ADMIN_ENV } from "./previous-web-admin-env.js"; // the previous generation's names of those three (the renderer still writes them for engines that read them)
|
|
30
30
|
import { retiredEnvRefusal } from "./retired-envs.js"; // the worker env write gate asks the retired-env tombstone table too (one table, one refusal sentence)
|
|
31
31
|
import { Sha256Digest } from "./sha256.js"; // the one `sha256:<hex>` digest form
|
|
32
|
-
import { EXECUTION_LANES, EXECUTION_LANE_WORDS, MEMORY_ENGINE_BACKENDS, SESSION_BACKENDS, STORE_BACKENDS, isBlankCoordinate, retiredLaneWordRefusal } from "./execution-lanes.js"; // 7.0.0 M-R2: the lane / store vocabulary (one exported table)
|
|
32
|
+
import { EXECUTION_LANES, EXECUTION_LANE_WORDS, LANE_SET_RULE, MEMORY_ENGINE_BACKENDS, SESSION_BACKENDS, STORE_BACKENDS, isBlankCoordinate, laneSetFlaws, retiredLaneWordRefusal } from "./execution-lanes.js"; // 7.0.0 M-R2: the lane / store vocabulary (one exported table)
|
|
33
33
|
import { LANE_ENV_OWNER, envKeyMigration, laneEnvSeat, laneRowOf } from "./execution-lane-index.js"; // package-private indexes derived from that table (none of them is in the barrel)
|
|
34
34
|
import { migrationSignpost, retiredFormSentence, retiredKey } from "./retired-form.js"; // 11.0.0: the ONE retired-form sentence + key tombstone (package-private)
|
|
35
35
|
import { retiredRoleWordsRefusal } from "./retired-role-words.js"; // 12.0.0: the retired role-word tombstone (package-private; SS-M8)
|
|
36
36
|
import { buildQuotedIssue, fixed } from "./quoted-issue.js"; // THE minting point of custom issues (package-private)
|
|
37
|
+
import { unwrapSchema } from "./zod-unwrap.js"; // 18.0.0: ATOMIC_SALVAGE registers the schema the salvage walker reaches (wrappers peeled with the walker's own reader)
|
|
38
|
+
import { RESERVED_MEMBER_NAMES, isReservedMemberName } from "./reserved-member-name.js"; // 18.0.0: the one reserved-member-name table (the record reader and the center-refs resolver ask the same predicate)
|
|
37
39
|
import { AbsoluteHostPath } from "./host-path.js"; // the one host-path shape judge (a task's cwd and a project's folder / file entries)
|
|
38
40
|
import { RFC3339_DATE_TIME } from "./rfc3339.js"; // the package's one RFC 3339 date-time judge (package-private)
|
|
39
41
|
import { DEVICE_RELAY_RULE, deviceRelayFlaws } from "./device-relay.js"; // 16.0.0: the value grammar of the device lane's DEVICE_RELAY_URL (ws(s) URL or the literal none)
|
|
42
|
+
import { TOOL_WIRE_NAME_MAX_CHARS, isUsableWireName } from "./wire-name.js"; // 18.0.0: the one "usable wire name" judge (the a2a peer name; the request-plane MCP / A2A readers ask the same function)
|
|
40
43
|
// COARSE, best-effort literal-secret SHAPE detector (NOT exhaustive — the real boundary is the env-NAME schema
|
|
41
44
|
// on structured fields). Rejected in free-form value fields (worker `env`, model `extraBody`), URL components,
|
|
42
45
|
// AND as an env-NAME value (an AWS key id is a valid env-NAME charset yet is a secret VALUE, not a NAME). Case-
|
|
@@ -1476,7 +1479,11 @@ export const ExecutionPolicy = z.object({
|
|
|
1476
1479
|
/** Which execution lanes are allowed. OPEN value domain — z.string(), NEVER an enum: adding a lane
|
|
1477
1480
|
* must not be a BREAKING schema change (promised to the service). The closed set of lanes a worker can
|
|
1478
1481
|
* declare is `EXECUTION_LANE_WORDS` (`execution-lanes.ts`, 7.0.0) — read it there, not from a copy in this
|
|
1479
|
-
* comment. Unknown strings are consumer-defined.
|
|
1482
|
+
* comment. Unknown strings are consumer-defined.
|
|
1483
|
+
* 18.0.0 —— the declarable word for "no execution environment" is `none`; the engine's older internal name for that state, `in-process`,
|
|
1484
|
+
* was never a declarable lane. While engines that answer with the old name and engines that answer with `none` both read a policy, the policy
|
|
1485
|
+
* DATA lists both strings (`["in-process", "none", …]` — legal content of this open list, not a second reading in code); once every engine
|
|
1486
|
+
* reading it answers `none`, delete `"in-process"` from the data. */
|
|
1480
1487
|
allowedLanes: z.array(z.string().min(1)).prefault(["host"]),
|
|
1481
1488
|
/** Org 默认会话镜像目标(0.10.1,附B 两层)。ABSENT = INERT(web-admin 未管镜像,壳解析序里本腿为空)。
|
|
1482
1489
|
* 读损档随域(DOMAIN_READ_FALLBACK.execution="throw" 已覆盖:损坏绝不静默退默认放权)。 */
|
|
@@ -1796,6 +1803,8 @@ const WorkerSecretRefs = z.object({
|
|
|
1796
1803
|
* · **加** `DB_BACKEND` / `MEMORY_ENGINE` / `MEMORY_ENGINE_BACKEND` —— `runtime.store` 产出它们。
|
|
1797
1804
|
* · **删** `MEMORY_BACKEND`(引擎从不读的死名,渲染器不再产出)与 `TIDB_*` 族(引擎的墓碑名,见之拒启;结构字段不再产出它们)。
|
|
1798
1805
|
* MYSQL_* / PG_* 两族归 `runtime.store.db` + `secretRefs.dbPasswordEnv`。
|
|
1806
|
+
* 18.0.0 删 `REQUIRE_EXECUTION_LANE`:每个部署都点名车道之后它恒真,不再是旋钮 —— 引擎不读、渲染器不写,名字进墓碑表 `RETIRED_ENVS`(去向 `REMOTE_EXEC`);
|
|
1807
|
+
* 逃生口里写它 ⇒ 墓碑句(下一段的第二个问题)。迁移 SS-M4 识别它的键集(`LANE_WORD_KEYS`)不动。
|
|
1799
1808
|
*
|
|
1800
1809
|
* `env` / `secretEnv` 的写闸问**两张表**,各答一个问题,互相独立:
|
|
1801
1810
|
* · 本表答「规格作者可不可以自己设这个名」—— 不可以:它归某个结构字段,或归渲染器 / 编排器写,或与渲染器 / 编排器写的名互斥(拒句指路到那个写位);
|
|
@@ -1857,7 +1866,6 @@ const RESERVED_ENV_FIELD = Object.freeze({
|
|
|
1857
1866
|
[WEB_ADMIN_ENV.tokenFile]: WEB_ADMIN_OPERATOR_FILE_SEAT, [PREVIOUS_WEB_ADMIN_ENV.tokenFile]: WEB_ADMIN_OPERATOR_FILE_SEAT,
|
|
1858
1867
|
[WEB_ADMIN_ENV.assertionToken]: WEB_ADMIN_ASSERTION_SEAT.token,
|
|
1859
1868
|
[WEB_ADMIN_ENV.assertionTokenFile]: WEB_ADMIN_OPERATOR_FILE_SEAT,
|
|
1860
|
-
REQUIRE_EXECUTION_LANE: "runtime.execution.lanes (the renderer emits REQUIRE_EXECUTION_LANE=true for every declared lane set)",
|
|
1861
1869
|
...Object.fromEntries([...LANE_ENV_OWNER].map(([name, owner]) => [name, laneEnvSeat(name, owner)])),
|
|
1862
1870
|
});
|
|
1863
1871
|
/** 结构化 WorkerSpec 字段已经产出的 env 名 —— 通用 `env` / `secretEnv` 逃生口**不许**设它们(用专属字段)。由
|
|
@@ -1896,11 +1904,117 @@ const nonSecretLiteral = (minLength) => z
|
|
|
1896
1904
|
const COORDINATE_VALUE_GRAMMAR = new Map([
|
|
1897
1905
|
["DEVICE_RELAY_URL", { flaws: deviceRelayFlaws, rule: DEVICE_RELAY_RULE }],
|
|
1898
1906
|
]);
|
|
1899
|
-
/**
|
|
1900
|
-
const LANES_REQUIRED = `runtime.execution.lanes
|
|
1907
|
+
/** 车道集缺席 / 为空时的那一句(块在而缺 `lanes`、`lanes` 是空表,与 enabled 的 worker 根本没有车道块,同一句)。规则句取判官的 {@link LANE_SET_RULE}。 */
|
|
1908
|
+
const LANES_REQUIRED = `runtime.execution.lanes ${LANE_SET_RULE}`;
|
|
1901
1909
|
/**
|
|
1902
|
-
*
|
|
1903
|
-
*
|
|
1910
|
+
* 写闸对车道表的那一读:判官 {@link laneSetFlaws} 的每条拒因一条 issue(穷举 switch:判官加一种拒因而这里不补 ⇒ 编译红)。`path` 相对 `lanes`。
|
|
1911
|
+
* issue 的机读码与此前三只判据(枚举 / `.min(1)` / 去重)各自给的码逐一相同:词形坏(空白 / 不认识 / 退役)= `invalid_value`(`values` = 车道词表;退役词的句子是墓碑句),
|
|
1912
|
+
* 空表 = `too_small`(句子 = 车道集必填那一句),重复 = `custom`;独占车道与别的项同集(18.0.0)= `custom`,落在整张表上。句子都经铸点 `buildQuotedIssue`(写进表里的值是洞)。
|
|
1913
|
+
* 不是字符串的项也是「不是车道词」(`unknown`,同一个码,句子不回显它的值)。
|
|
1914
|
+
* 可续性:表里有不是车道词的项 ⇒ 不可续(`continue: false`)—— 列表连「车道」都不是,后面按车道表行判的(坐标归属 / 必需坐标 / 租户 / 单副本 / 店)都不跑,
|
|
1915
|
+
* 与此前枚举拒的读法同;空表 / 重复 / 不独占 ⇒ 可续(每一项都是车道词)。判官交回全部拒因,这里每条都出(一张表里坏词与重复同在 ⇒ 两条都报)。
|
|
1916
|
+
*/
|
|
1917
|
+
function addLaneSetIssue(ctx, lanes, flaw) {
|
|
1918
|
+
const values = [...EXECUTION_LANE_WORDS];
|
|
1919
|
+
switch (flaw.kind) {
|
|
1920
|
+
case "empty_set":
|
|
1921
|
+
return ctx.addIssue({ code: "too_small", origin: "array", minimum: 1, inclusive: true, input: lanes, ...buildQuotedIssue `${fixed(LANES_REQUIRED)}` });
|
|
1922
|
+
case "blank_entry":
|
|
1923
|
+
return ctx.addIssue({ code: "invalid_value", values, input: lanes[flaw.at], path: [flaw.at], continue: false, ...buildQuotedIssue `an entry of runtime.execution.lanes is empty or whitespace-only — runtime.execution.lanes ${fixed(LANE_SET_RULE)}` });
|
|
1924
|
+
case "unknown": {
|
|
1925
|
+
const { word } = flaw;
|
|
1926
|
+
return ctx.addIssue({
|
|
1927
|
+
code: "invalid_value",
|
|
1928
|
+
values,
|
|
1929
|
+
input: word,
|
|
1930
|
+
path: [flaw.at],
|
|
1931
|
+
continue: false,
|
|
1932
|
+
...(typeof word === "string"
|
|
1933
|
+
? buildQuotedIssue `"${word}" is not an execution lane — runtime.execution.lanes ${fixed(LANE_SET_RULE)}`
|
|
1934
|
+
: buildQuotedIssue `an entry of runtime.execution.lanes is not a string — runtime.execution.lanes ${fixed(LANE_SET_RULE)}`),
|
|
1935
|
+
});
|
|
1936
|
+
}
|
|
1937
|
+
case "retired": {
|
|
1938
|
+
const refusal = retiredLaneWordRefusal(flaw.word);
|
|
1939
|
+
if (refusal === undefined)
|
|
1940
|
+
throw new Error("addLaneSetIssue: a retired-lane flaw names a word the tombstone has no row for (package invariant broken)", { cause: flaw });
|
|
1941
|
+
// the tombstone sentence itself: its way out is given at the source, once
|
|
1942
|
+
return ctx.addIssue({ code: "invalid_value", values, input: flaw.word, path: [flaw.at], continue: false, ...buildQuotedIssue `${fixed(refusal)}` });
|
|
1943
|
+
}
|
|
1944
|
+
case "duplicate":
|
|
1945
|
+
return ctx.addIssue({ code: "custom", path: [flaw.at], ...buildQuotedIssue `lane "${flaw.lane}" is declared twice in runtime.execution.lanes — each lane appears once (the first one is the default)` });
|
|
1946
|
+
case "not_alone":
|
|
1947
|
+
return ctx.addIssue({
|
|
1948
|
+
code: "custom",
|
|
1949
|
+
...buildQuotedIssue `runtime.execution.lanes declares ${fixed(JSON.stringify(flaw.lane))} (no execution environment for the agent's tools) together with other entries — it stands alone: declare lanes: [${fixed(JSON.stringify(flaw.lane))}], or remove it`,
|
|
1950
|
+
});
|
|
1951
|
+
default: {
|
|
1952
|
+
const unhandled = flaw;
|
|
1953
|
+
throw new Error("addLaneSetIssue: unhandled lane-set flaw", { cause: unhandled });
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1956
|
+
}
|
|
1957
|
+
/**
|
|
1958
|
+
* 凭据引用集合(名 → 宿主 env-NAME)的**唯一铸法**:先按**自有属性名**判保留成员名(`isReservedMemberName`,一张表,记录读器与中心引用解析口问同一个谓词;
|
|
1959
|
+
* 经读内核 `ownEntriesOf` 的严归类读名:每个自有串键都读到名字,不调 getter),一条就使集合判不过、record 不再判;再交给 `record`。
|
|
1960
|
+
* zod 的 record 读键前先跳过 `__proto__`(不判它的值、输出里也没有它),只靠 record 判会把「带着一条被剥掉的引用」读成「没有那条引用」,条目带着其余引用活下来。
|
|
1961
|
+
* 只判朴素对象(形状问座位 `isPlainJsonObject`;别的形由 `record` 自己拒,拒句不变);成员名读不出(隐藏键 / 访问器 / 陷阱抛)⇒ 同样判坏,句子是内核那一句(fail-closed:守卫看不清名字就不担保)。
|
|
1962
|
+
* 每一只成员都由它铸,所以成员复用到哪个座位,这道判据就跟到哪个座位;{@link ATOMIC_SALVAGE} 登记的是剥掉包装之后的那只 `record`(抢救走查按它判身份)。
|
|
1963
|
+
*/
|
|
1964
|
+
function credentialRefs(record) {
|
|
1965
|
+
return z.preprocess((input, ctx) => {
|
|
1966
|
+
if (!isPlainJsonObject(input))
|
|
1967
|
+
return input;
|
|
1968
|
+
const members = ownEntriesOf(input);
|
|
1969
|
+
if (!members.ok) {
|
|
1970
|
+
ctx.addIssue({ code: "custom", input, ...buildQuotedIssue `${fixed(members.sentence)}` });
|
|
1971
|
+
return input;
|
|
1972
|
+
}
|
|
1973
|
+
for (const [name] of members.value)
|
|
1974
|
+
if (isReservedMemberName(name))
|
|
1975
|
+
ctx.addIssue({ code: "custom", input, ...buildQuotedIssue `a credential reference is named "${fixed(name)}" — a reserved member name (${fixed(RESERVED_MEMBER_NAMES.join(" | "))}) never names a reference; rename it` });
|
|
1976
|
+
return input;
|
|
1977
|
+
}, record);
|
|
1978
|
+
}
|
|
1979
|
+
/** 车道块的密钥引用(服务变量名 → 宿主 env-NAME)—— 一只具名 schema:它是凭据引用集合,在 {@link ATOMIC_SALVAGE} 里按身份登记。 */
|
|
1980
|
+
const LaneSecretRefs = credentialRefs(z.record(ENV_NAME, ENV_NAME));
|
|
1981
|
+
/** worker 的密钥 env 透传(服务变量名 → 宿主 env-NAME)—— 一只具名 schema:它是凭据引用集合,在 {@link ATOMIC_SALVAGE} 里按身份登记。 */
|
|
1982
|
+
const WorkerSecretEnv = credentialRefs(z.record(ENV_NAME, ENV_NAME).superRefine((rec, ctx) => {
|
|
1983
|
+
retiredEnvIssue(rec, ctx);
|
|
1984
|
+
for (const k of Object.keys(rec))
|
|
1985
|
+
if (RESERVED_WORKER_ENV.has(k))
|
|
1986
|
+
ctx.addIssue({ code: "custom", ...reservedKeyIssue("secretEnv", k) });
|
|
1987
|
+
}));
|
|
1988
|
+
/** 一项是不是可声明的车道词(只给下面的变换收窄类型用:判官放行之后每一项都是)。 */
|
|
1989
|
+
const isDeclarableLane = (v) => EXECUTION_LANE_WORDS.some((w) => w === v);
|
|
1990
|
+
/** 列表的一次快照(长度只读一次,空洞读成 `undefined`):判官判的与变换收窄的是同一份项,不对调用方的数组读第二遍。不是列表 ⇒ 原样(下面的判据拒)。 */
|
|
1991
|
+
const laneListSnapshot = (v) => (isJsonArray(v) ? Array.from({ length: v.length }, (_, i) => v[i]) : v);
|
|
1992
|
+
/**
|
|
1993
|
+
* `runtime.execution.lanes`:写闸只判「是一个列表」(缺 ⇒ 车道集必填那一句;不是列表 ⇒ `invalid_type`),每一项是不是车道词与整张表的合法性一起交给判官
|
|
1994
|
+
* {@link laneSetFlaws}(唯一一处)。不写成 `z.array(元素)`:元素 schema 先判 ⇒ 不是字符串的项得到另一个码、同表其余的项不判;元素写成什么都收的 schema,
|
|
1995
|
+
* 它又成了「本包不判形的解析透明键」—— 它不是,判官判它。有不可续的拒因时 zod 不跑变换;变换只把已判过的项收窄成车道词。
|
|
1996
|
+
*/
|
|
1997
|
+
const DeclaredLanes = z.preprocess(laneListSnapshot, z
|
|
1998
|
+
.unknown()
|
|
1999
|
+
.superRefine((value, ctx) => {
|
|
2000
|
+
if (!isJsonArray(value)) {
|
|
2001
|
+
ctx.addIssue({
|
|
2002
|
+
code: "invalid_type",
|
|
2003
|
+
expected: "array",
|
|
2004
|
+
input: value,
|
|
2005
|
+
continue: false,
|
|
2006
|
+
...(value === undefined ? buildQuotedIssue `${fixed(LANES_REQUIRED)}` : buildQuotedIssue `runtime.execution.lanes is not a list — runtime.execution.lanes ${fixed(LANE_SET_RULE)}`),
|
|
2007
|
+
});
|
|
2008
|
+
return;
|
|
2009
|
+
}
|
|
2010
|
+
for (const flaw of laneSetFlaws(value))
|
|
2011
|
+
addLaneSetIssue(ctx, value, flaw);
|
|
2012
|
+
})
|
|
2013
|
+
.transform((value) => (isJsonArray(value) ? value.filter(isDeclarableLane) : [])));
|
|
2014
|
+
/**
|
|
2015
|
+
* `runtime.execution` —— 这台 worker 的执行车道集(16.0.0;渲染:车道表 `lanes` → `REMOTE_EXEC` + coords / secretRefs 逐键;18.0.0 起不再渲总开关)。
|
|
2016
|
+
* - `lanes`:**有序、去重、非空**的车道表({@link EXECUTION_LANE_WORDS} 的词),首项 = 缺省;合不合法只问判官 {@link laneSetFlaws}。
|
|
2017
|
+
* 不给智能体的工具提供执行环境的 worker 写 `lanes: ["none"]`(18.0.0;独成一集)。
|
|
1904
2018
|
* - `coords`:声明的车道的**非密坐标**(服务变量名 → 字面值),每个键归表里的某一条车道(车道表 `requiredEnv ∪ optionalEnv`);每条声明的车道的必需键都在场且不是空白
|
|
1905
2019
|
* (空串或只含空白按缺 —— 唯一判官 `isBlankCoordinate`);有文法的键({@link COORDINATE_VALUE_GRAMMAR})值还要合它的文法。可选键的空串照收(例:`K8S_RUNTIME_CLASS=""` 在引擎里是「不用 Kata」)。
|
|
1906
2020
|
* - `secretRefs`:声明的车道的**密钥**(服务变量名 → 宿主 env-NAME),每个键归表里的某一条车道,每条声明的车道的必需键在场。
|
|
@@ -1910,21 +2024,13 @@ const LANES_REQUIRED = `runtime.execution.lanes must be a non-empty list — the
|
|
|
1910
2024
|
const ExecutionBlock = z
|
|
1911
2025
|
.object({
|
|
1912
2026
|
lane: retiredKey("runtime.execution.lane", { retiredIn: "16.0.0", now: "runtime.execution.lanes (an ordered lane set; the first one is the default)", migration: "SS-M12" }),
|
|
1913
|
-
lanes:
|
|
1914
|
-
.array(z.enum(EXECUTION_LANE_WORDS, { error: (iss) => retiredLaneWordRefusal(iss.input) }), { error: (iss) => (iss.input === undefined ? LANES_REQUIRED : undefined) }) // a retired lane word gets its way out
|
|
1915
|
-
.min(1, { error: LANES_REQUIRED }),
|
|
2027
|
+
lanes: DeclaredLanes,
|
|
1916
2028
|
coords: z.record(ENV_NAME, nonSecretLiteral(0)).prefault({}),
|
|
1917
|
-
secretRefs:
|
|
2029
|
+
secretRefs: LaneSecretRefs.prefault({}),
|
|
1918
2030
|
})
|
|
1919
2031
|
.superRefine((x, ctx) => {
|
|
1920
|
-
//
|
|
1921
|
-
const declared =
|
|
1922
|
-
x.lanes.forEach((lane, i) => {
|
|
1923
|
-
if (declared.includes(lane))
|
|
1924
|
-
ctx.addIssue({ code: "custom", path: ["lanes", i], ...buildQuotedIssue `lane "${lane}" is declared twice in runtime.execution.lanes — each lane appears once (the first one is the default)` });
|
|
1925
|
-
else
|
|
1926
|
-
declared.push(lane);
|
|
1927
|
-
});
|
|
2032
|
+
// 车道表本身合不合法只问判官(`lanes` 那一格,见 DeclaredLanes);这里按去重后的车道读表行(重复是可续的拒因,所以这里可能见到重复项)。
|
|
2033
|
+
const declared = x.lanes.filter((lane, i) => x.lanes.indexOf(lane) === i);
|
|
1928
2034
|
const rows = declared.map(laneRowOf);
|
|
1929
2035
|
const issue = (slot, key, q) => ctx.addIssue({ code: "custom", path: [slot, key], ...q });
|
|
1930
2036
|
const owned = (secret) => rows.flatMap((row) => (secret ? [...row.requiredSecretEnv, ...row.optionalSecretEnv] : [...row.requiredEnv, ...row.optionalEnv]));
|
|
@@ -2131,15 +2237,7 @@ const WorkerSpecObject = z.object({
|
|
|
2131
2237
|
* 故无法粘贴真值)。给 app 专属令牌用(如 `MY_APP_TOKEN` → 某 env-名)。在 reconciler 里于 `env` 之后解析,
|
|
2132
2238
|
* 故密钥永不被 `env` 同名键遮蔽。`RESERVED_WORKER_ENV` 里的键被拒(那些结构化 secret 走 `secretRefs`);墓碑表 `RETIRED_ENVS` 里的旧名被拒。
|
|
2133
2239
|
*/
|
|
2134
|
-
secretEnv:
|
|
2135
|
-
.record(ENV_NAME, ENV_NAME)
|
|
2136
|
-
.superRefine((rec, ctx) => {
|
|
2137
|
-
retiredEnvIssue(rec, ctx);
|
|
2138
|
-
for (const k of Object.keys(rec))
|
|
2139
|
-
if (RESERVED_WORKER_ENV.has(k))
|
|
2140
|
-
ctx.addIssue({ code: "custom", ...reservedKeyIssue("secretEnv", k) });
|
|
2141
|
-
})
|
|
2142
|
-
.optional(),
|
|
2240
|
+
secretEnv: WorkerSecretEnv.optional(),
|
|
2143
2241
|
/** Opaque recreate trigger (hash-INCLUDED): bump it to force the reconciler to recreate the worker — e.g. to
|
|
2144
2242
|
* re-project a secret VALUE that changed (a secret write doesn't alter the spec, so without this the running
|
|
2145
2243
|
* pod keeps the old value). Set by POST /api/config/workers/<name>/rotate. */
|
|
@@ -2180,7 +2278,7 @@ function workerSpecIssues(w, ctx) {
|
|
|
2180
2278
|
const { execution, store, requirePrincipal } = w.runtime;
|
|
2181
2279
|
// G1:enabled 的 worker 必须声明车道集与店(停用的不渲染,可缺)。
|
|
2182
2280
|
if (w.enabled && execution === undefined) {
|
|
2183
|
-
issue(["runtime", "execution", "lanes"], buildQuotedIssue `an enabled worker must declare its execution lanes (
|
|
2281
|
+
issue(["runtime", "execution", "lanes"], buildQuotedIssue `an enabled worker must declare its execution lanes (the lane set is the deployment's own statement — nothing reads a missing one as some lane) — ${fixed(LANES_REQUIRED)}`);
|
|
2184
2282
|
}
|
|
2185
2283
|
if (w.enabled && store === undefined) {
|
|
2186
2284
|
issue(["runtime", "store", "backend"], buildQuotedIssue `an enabled worker must declare its store — runtime.store.backend: ${fixed(STORE_BACKENDS.join(" | "))}`);
|
|
@@ -2459,7 +2557,7 @@ export const SkillsManifestSchema = z.object({
|
|
|
2459
2557
|
// env-NAME references (`envRefs`/`headerRefs`: target-key → an ENV_NAME in the SERVICE's env). The service's
|
|
2460
2558
|
// `resolveSpec` reads the real values from its own environment — this DB never holds a credential. Like
|
|
2461
2559
|
// skills, MCP is applied at boot/reconcile (not hot) and writing is gated to `publisher` + the publish gate.
|
|
2462
|
-
const McpEnvRefs = z.record(ENV_NAME, ENV_NAME); // target ENV key → ENV_NAME holding its value (both env-name-shaped)
|
|
2560
|
+
const McpEnvRefs = credentialRefs(z.record(ENV_NAME, ENV_NAME)); // target ENV key → ENV_NAME holding its value (both env-name-shaped)
|
|
2463
2561
|
// An HTTP header NAME: an RFC 7230 token that ALSO must not be a secret literal. A secret-SHAPED header name
|
|
2464
2562
|
// (a headerRefs key `sk-live-…`, or principalHeader `ghp_…`) is stored + shipped verbatim on /effective — the
|
|
2465
2563
|
// SAME invariant-① gap as worker.env / model.extraBody / mcp stdio command+args (credentials belong on the
|
|
@@ -2471,7 +2569,20 @@ const HTTP_HEADER_NAME = z
|
|
|
2471
2569
|
.regex(/^[A-Za-z0-9!#$%&'*+.^_`|~-]+$/, "must be an HTTP header NAME")
|
|
2472
2570
|
.refine((s) => !containsSecretToken(s), buildQuotedIssue `HTTP header name must not contain a secret literal — credentials go in the env-NAME value, never the header name`);
|
|
2473
2571
|
// Header NAME → ENV_NAME holding its value. Header names are tokens (RFC 7230) — not env-name-shaped.
|
|
2474
|
-
const McpHeaderRefs = z.record(HTTP_HEADER_NAME, ENV_NAME);
|
|
2572
|
+
const McpHeaderRefs = credentialRefs(z.record(HTTP_HEADER_NAME, ENV_NAME));
|
|
2573
|
+
/**
|
|
2574
|
+
* 18.0.0 —— **凭据引用集合不可部分抢救**(按 schema 身份的集合)。成员是「名 → 宿主 env-NAME」的凭据引用 Record:mcp 的 `envRefs` / `headerRefs`
|
|
2575
|
+
* (a2a 对端的 `headerRefs` 复用后者,因此同在)、车道块的 `secretRefs` 与 worker 的 `secretEnv`。逐条抢救(`salvageEntries`)走到成员**不下钻**、把它当一个值判:
|
|
2576
|
+
* 集合里任一键 / 值坏形 ⇒ 它所属的那一条条目整条 `entry-dropped`,兄弟条目保留。理由:丢掉一条坏引用不是「更窄」,而是让条目带着**一半凭据**活下来 ——
|
|
2577
|
+
* 拨一个远端服务 / 智能体时错误的失败方向(读方对「任一引用的 env 缺席」本来就整条跳过,同一个方向)。
|
|
2578
|
+
* 既有读数只变一处:直接对 `WorkersConfig` 调 `salvageEntries` 时,`secretEnv` 带坏引用的 worker 由「只丢那一条引用、worker 存活」变「整条丢」
|
|
2579
|
+
* (各域读数不变:workers 域不逐条抢救;mcp 的两只住在传输判别联合里,走查不进联合;车道块住在不是集合的 `runtime` 对象里)
|
|
2580
|
+
* —— 由 17.2.0 包的真读数逐行对拍钉住(`test/atomic-salvage-18.0.0.test.ts`,改了读数的那一行逐行登记)。别的集合字段(allowTools / scenarios / allowSkills …)照旧逐条抢救:丢坏元素只会更窄。
|
|
2581
|
+
* 成员读键按自有属性名判:`__proto__` / `constructor` / `prototype` 任一在场 ⇒ 集合坏 ⇒ 条目整条丢(见 `credentialRefs`;zod 的 record 读键前跳过 `__proto__`、不判它的值)。
|
|
2582
|
+
* 新的凭据引用集合必须复用这几只 schema 或由 `credentialRefs` 铸出并登记进这里(按身份判,换一只「形一样」的新 schema 不算成员)。
|
|
2583
|
+
* 登记的是剥掉包装之后的那只 `record`(与抢救走查同一只读法 `unwrapSchema`)。
|
|
2584
|
+
*/
|
|
2585
|
+
export const ATOMIC_SALVAGE = new Set([McpEnvRefs, McpHeaderRefs, LaneSecretRefs, WorkerSecretEnv].map(unwrapSchema));
|
|
2475
2586
|
export const McpTransport = z.discriminatedUnion("kind", [
|
|
2476
2587
|
z.object({
|
|
2477
2588
|
kind: z.literal("stdio"),
|
|
@@ -2609,6 +2720,41 @@ export const McpConfig = z
|
|
|
2609
2720
|
seen.add(s.name);
|
|
2610
2721
|
});
|
|
2611
2722
|
});
|
|
2723
|
+
// ── Domain: a2a (常驻出站 A2A 对端名册 —— 18.0.0) ─────────────────────────────────────────────────────────────
|
|
2724
|
+
// 一个 A2A 对端 = 一个 https 端点(单一传输,没有判别);形是 mcp http 条目的近亲,判官一律复用:URL = NON_SECRET_URL(存量文档座位,与 mcp `transport.url`
|
|
2725
|
+
// 同座;名形判官 `findUrlCredential` 是新提交门的事,不接进读已落盘字节的 schema),`headerRefs` = mcp 的头名 → env-NAME 引用集合(凭据引用,
|
|
2726
|
+
// 在 ATOMIC_SALVAGE 里:坏一项 ⇒ 整个对端丢),`principalHeader` = 头名判官,`name` = 线上名判官(对端名是线上工具名 `a2a__<名>__…` 的身份片)。
|
|
2727
|
+
// 秘密边界同 mcp:中心只存 env-NAME,值在读方自己的环境里。写权限 publisher(一个对端就是一组新挂进智能体的远端技能,同 mcp)。
|
|
2728
|
+
// 首版不收 `notes` / `rosters`(按 roster 定向)/ `toolAxes`(中心面不替调用方担保远端技能的副作用轴):三者都被剥并告警。
|
|
2729
|
+
/** 一个常驻出站 A2A 对端。 */
|
|
2730
|
+
export const A2aPeerSpec = z.object({
|
|
2731
|
+
/** 对端的身份:线上工具名 `a2a__<名>__…` 的命名空间段 —— 线上名判官({@link isUsableWireName}:非空、≤128、首尾无空白;不截断、不 trim)。 */
|
|
2732
|
+
name: z.string().refine(isUsableWireName, buildQuotedIssue `a2a peer name must be non-empty, at most ${fixed(String(TOOL_WIRE_NAME_MAX_CHARS))} characters, with no leading or trailing whitespace — it is the peer's identity in the wire tool names (a2a__<name>__…); it is never trimmed or truncated`),
|
|
2733
|
+
/** 对端的服务 URL(也是知名路径上的 agent card 相对它解析的源)。不带凭据(userinfo / 密钥形值)、不带 fragment。 */
|
|
2734
|
+
url: NON_SECRET_URL,
|
|
2735
|
+
/** agent card 的显式位置(对端不在知名路径上发布时);在场 ⇒ 只用它。同一只 URL 判官。 */
|
|
2736
|
+
cardUrl: NON_SECRET_URL.optional(),
|
|
2737
|
+
/** 头名 → 读方环境里的 env-NAME(例:`Authorization → KB_TOKEN`),**绝不是值**。任一引用坏形 ⇒ 整个对端读不进(不部分抢救);读方对任一缺席的 env 整个对端跳过。 */
|
|
2738
|
+
headerRefs: McpHeaderRefs.optional(),
|
|
2739
|
+
/** 读方把任务的已鉴权终端主体填进去的那个头名(不是引用 —— 值由读方逐请求填,模型碰不到)。 */
|
|
2740
|
+
principalHeader: HTTP_HEADER_NAME.optional(),
|
|
2741
|
+
/** 只挂这些技能 id(白名单);缺席或空 = 对端发布的全部。 */
|
|
2742
|
+
allowSkills: z.array(z.string().min(1)).optional(),
|
|
2743
|
+
/** 挂在哪些场景;空 = 全部(与 mcp / skills 同一条读方过滤)。 */
|
|
2744
|
+
scenarios: z.array(z.string().min(1)).prefault([]),
|
|
2745
|
+
enabled: z.boolean().default(true),
|
|
2746
|
+
});
|
|
2747
|
+
/** `a2a` 域:常驻出站 A2A 对端名册。空 / 缺席 = 不拨任何对端。对端名唯一(重名拒,同 mcp)。 */
|
|
2748
|
+
export const A2aConfig = z
|
|
2749
|
+
.object({ peers: z.array(A2aPeerSpec).prefault([]) })
|
|
2750
|
+
.superRefine((cfg, ctx) => {
|
|
2751
|
+
const seen = new Set();
|
|
2752
|
+
cfg.peers.forEach((p, i) => {
|
|
2753
|
+
if (seen.has(p.name))
|
|
2754
|
+
ctx.addIssue({ code: "custom", ...buildQuotedIssue `duplicate a2a peer "${p.name}"`, path: ["peers", i, "name"] });
|
|
2755
|
+
seen.add(p.name);
|
|
2756
|
+
});
|
|
2757
|
+
});
|
|
2612
2758
|
// ── Domain: plugins (plugin SOURCE REFERENCES — C2 plugins 上云, additive 0.5.0) ──────────────────────────
|
|
2613
2759
|
// The cloud stores WHERE a plugin comes from, NEVER its content (产品拍板): {name, source, version/sha pin}.
|
|
2614
2760
|
// The consuming shell materializes the plugin locally from the ref (git clone / marketplace install) — the
|
|
@@ -2863,6 +3009,7 @@ export const DOMAIN_SCHEMAS = {
|
|
|
2863
3009
|
projects: ProjectsConfig, // 0.10.0: 142-S3 project identity ledger + 无仓铸造权威 (scope=tenant 轴; NOT portable — 租户身份数据)
|
|
2864
3010
|
prompts: PromptsConfig, // 0.10.18 起;14.0.0 单轴:中心 artifact 的身份(`{ artifact?, workers? }`);13.x 两轴的键是墓碑(SS-M10)
|
|
2865
3011
|
limits: LimitsConfig, // 0.19.0: cost/限流族热更新发布位(消费方 #322 批1;本地腿闭集缺口的源头修复)
|
|
3012
|
+
a2a: A2aConfig, // 18.0.0: 常驻出站 A2A 对端名册(便携;本地腿 config.d/a2a.json 与中心腿 /effective.a2a 同一个声明座)
|
|
2866
3013
|
// integrations + access: DELETED in 0.6.0 (EXPERT-REDESIGN §9) — parseDomain/effective/路由随之 404。
|
|
2867
3014
|
};
|
|
2868
3015
|
// ── Effective-config PROVENANCE (the unified shape TOC `sema config --effective` and TOB `/effective?principal=`
|
package/dist/url-credential.d.ts
CHANGED
|
@@ -2,13 +2,23 @@
|
|
|
2
2
|
export declare const URL_CREDENTIAL_REASONS: readonly ["url_userinfo", "url_credential_param"];
|
|
3
3
|
export type UrlCredentialReason = (typeof URL_CREDENTIAL_REASONS)[number];
|
|
4
4
|
/**
|
|
5
|
-
* 凭据参数名表(闭集,23 词,全部是小写 ASCII `[a-z][a-z0-9_-]*`)。query / fragment 里名字整名(ASCII 大小写不敏感)
|
|
5
|
+
* 凭据参数名表(闭集,23 词,全部是小写 ASCII `[a-z][a-z0-9_-]*`)。query / fragment 里名字整名(ASCII 大小写不敏感)在这张表上的参数就是凭据;
|
|
6
|
+
* 18.0.0 起以其中的强档词收尾的复合名也是(`db_password` 等,判由 {@link credentialParamWordOf})。
|
|
6
7
|
* 加一个词 = 表里加一格(minor);判官与 {@link isCredentialParamName} 现算,不手抄第二份。
|
|
7
8
|
*/
|
|
8
9
|
export declare const CREDENTIAL_PARAM_NAMES: readonly ["api_key", "apikey", "api-key", "key", "token", "access_token", "refresh_token", "id_token", "auth", "authorization", "proxy-authorization", "password", "passwd", "pwd", "secret", "client_secret", "private_key", "signature", "sig", "x-amz-signature", "x-amz-security-token", "x-amz-credential", "sas"];
|
|
9
10
|
export type CredentialParamName = (typeof CREDENTIAL_PARAM_NAMES)[number];
|
|
10
11
|
/**
|
|
11
|
-
*
|
|
12
|
+
* 🔴 **「这个已解码的参数名是不是凭据名」的唯一答者**(18.0.0):是 ⇒ 名表里的那个词(小写);不是 ⇒ `undefined`。入参是收方读到的那一形(`URLSearchParams` 解过一次码的名字)。
|
|
13
|
+
* · 整名(ASCII 大小写不敏感)在 {@link CREDENTIAL_PARAM_NAMES} 里 ⇒ 那个词(整名优先);
|
|
14
|
+
* · 否则末段的尾部是强档词(`password` / `passwd` / `pwd` / `secret` / `apikey`),或名字末尾是尾串闭集的一条(`secret_key` / `secret_access_key` ⇒ `secret`;`api_key` ⇒ `api_key`;`access_token` ⇒ `access_token`;答词的律见 {@link COMPOUND_TAIL_PHRASES})⇒ 那个词。
|
|
15
|
+
* 切段、粘连与对齐的律见模块头「名字判定」。
|
|
16
|
+
* 返回的词是**表词**:消费方拿它去查自己挂在名表上的那一列(例:日志脱敏器的锚强度),不对整名再查一遍表。
|
|
17
|
+
*/
|
|
18
|
+
export declare function credentialParamWordOf(decodedName: string): CredentialParamName | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* 「这个**已解码**的参数名是不是凭据名」:{@link credentialParamWordOf} 有词。入参是收方读到的那一形(`URLSearchParams` 解过一次码的名字);
|
|
21
|
+
* 整名在 {@link CREDENTIAL_PARAM_NAMES} 里、或末段 / 尾串收在强档词上(`db_password` / `PGPASSWORD` / `SECRET_KEY`)才算。
|
|
12
22
|
*/
|
|
13
23
|
export declare function isCredentialParamName(decodedName: string): boolean;
|
|
14
24
|
/** 每个拒因词带的细节(键集必须覆盖 {@link URL_CREDENTIAL_REASONS} 的每个词:数组里加一个词而这里没跟 ⇒ 下面的映射型编译红,{@link urlCredentialRule} 的穷举 switch 也红)。 */
|