@sema-agent/settings-schema 13.0.1 → 14.1.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 (136) hide show
  1. package/CHANGELOG.md +134 -0
  2. package/README.md +19 -1
  3. package/conformance/VERSION +1 -1
  4. package/conformance/baseline.json +1 -3
  5. package/conformance/cases/c01-entry-salvage-then-typo/expected.json +1 -3
  6. package/conformance/cases/c02-hosts-clamp-stacked/expected.json +1 -3
  7. package/conformance/cases/c03-literal-dotted-top-key/expected.json +1 -3
  8. package/conformance/cases/c04-all-bad-collection-not-salvaged/expected.json +1 -3
  9. package/conformance/cases/c07-hooks-is-not-a-config-domain/expected.json +1 -3
  10. package/conformance/cases/c08-limits-unknown-carried-64/expected.json +1 -3
  11. package/conformance/cases/c09-limits-unknown-carried-65/expected.json +1 -3
  12. package/conformance/cases/c10-record-key-secret-redacted-twice/expected.json +1 -3
  13. package/conformance/cases/c11-unicode-unknown-keys/expected.json +1 -3
  14. package/conformance/cases/c12-prototype-name-top-keys/expected.json +1 -3
  15. package/conformance/cases/c13-models-field-null/expected.json +1 -3
  16. package/conformance/cases/c14-models-field-empty-array/expected.json +1 -3
  17. package/conformance/cases/c15-models-field-number/expected.json +1 -3
  18. package/conformance/cases/c16-deep-nesting-205/expected.json +1 -3
  19. package/conformance/cases/c17-empty-domain-file/expected.json +1 -3
  20. package/conformance/cases/c18-wire-envelope-not-an-object/expected.json +1 -3
  21. package/conformance/cases/c19-wire-envelope-no-version/expected.json +1 -3
  22. package/conformance/cases/c21-governance-empty-object-wins/expected.json +1 -3
  23. package/conformance/cases/c23-mixed-validity-models/expected.json +1 -3
  24. package/conformance/cases/c24-valid-entries-with-unknown-keys/expected.json +1 -3
  25. package/conformance/cases/c25-published-roundtrip-zero-warnings/expected.json +1 -3
  26. package/conformance/cases/c26-hosts-array-1024/expected.json +1 -3
  27. package/conformance/cases/c27-hosts-array-1025/expected.json +1 -3
  28. package/conformance/cases/c28-large-document-over-1mb/expected.json +1 -3
  29. package/conformance/cases/c29-salvage-then-domain-refine-fails/expected.json +1 -3
  30. package/conformance/cases/c30-version-triple-a-first/expected.json +1 -3
  31. package/conformance/cases/c31-version-triple-b-changed/expected.json +1 -3
  32. package/conformance/cases/c32-version-triple-a-restored/expected.json +1 -3
  33. package/conformance/cases/c33-limits-nested-carried-key/expected.json +1 -3
  34. package/conformance/cases/c34-skills-content-vs-manifest/expected.json +1 -3
  35. package/conformance/cases/c35-portable-domain-file-is-null/expected.json +1 -3
  36. package/conformance/cases/c36-skills-entry-without-content/expected.json +1 -3
  37. package/conformance/cases/c37-skills-field-null/expected.json +1 -3
  38. package/conformance/cases/c38-remote-exec-is-a-non-domain-file/expected.json +1 -3
  39. package/conformance/cases/c39-hidden-file-in-config-d/expected.json +1 -3
  40. package/conformance/cases/c40-s712-identity-only-what-reads-out/expected.json +1 -3
  41. package/conformance/cases/c41-s792-encoded-pem-identity/expected.json +1 -3
  42. package/conformance/cases/c42-s792-unknown-key-secret-redacted/expected.json +1 -3
  43. package/conformance/cases/c43-s792-form-and-deep-encoded-pem/expected.json +1 -3
  44. package/conformance/cases/c44-s792-utf8-escape-glued-token/expected.json +1 -3
  45. package/conformance/cases/c45-s792-identity-bounds-and-decode-depth/expected.json +1 -3
  46. package/conformance/cases/c46-s811-host-name-url-userinfo-withheld/expected.json +1 -3
  47. package/conformance/cases/c47-s811-roles-key-url-userinfo-withheld/expected.json +1 -3
  48. package/conformance/cases/c48-s935-model-headers-transported/expected.json +1 -3
  49. package/conformance/cases/c49-s935-model-headers-secret-entry-dropped/expected.json +1 -3
  50. package/conformance/cases/c50-s784-lane-host-legal/expected.json +1 -3
  51. package/conformance/cases/c51-s784-lane-e2b-legal/expected.json +1 -3
  52. package/conformance/cases/c52-s784-lane-k8s-legal/expected.json +1 -3
  53. package/conformance/cases/c53-s784-lane-ssh-legal/expected.json +1 -3
  54. package/conformance/cases/c54-s784-lane-adb-legal/expected.json +1 -3
  55. package/conformance/cases/c55-s784-lane-local-docker-legal/expected.json +1 -3
  56. package/conformance/cases/c56-s784-lane-device-legal/expected.json +1 -3
  57. package/conformance/cases/c57-s784-g1-enabled-no-lane/expected.json +1 -3
  58. package/conformance/cases/c58-s784-g2-multitenant-host/expected.json +1 -3
  59. package/conformance/cases/c59-s784-g3-k8s-missing-image/expected.json +1 -3
  60. package/conformance/cases/c60-s784-g3-e2b-missing-key/expected.json +1 -3
  61. package/conformance/cases/c61-s784-g3-other-lane-key/expected.json +1 -3
  62. package/conformance/cases/c62-s784-g7a-session-tidb/expected.json +1 -3
  63. package/conformance/cases/c63-s784-host-two-replicas/expected.json +1 -3
  64. package/conformance/cases/c64-s784-multitenant-local-store/expected.json +1 -3
  65. package/conformance/cases/c65-s784-pg-without-db/expected.json +1 -3
  66. package/conformance/cases/c66-s784-memory-backend-mismatch/expected.json +1 -3
  67. package/conformance/cases/c67-s784-retired-field-loud/expected.json +1 -3
  68. package/conformance/cases/c68-s784-device-local-store/expected.json +1 -3
  69. package/conformance/cases/c69-deep-encoded-token-past-every-reading/expected.json +1 -3
  70. package/conformance/cases/c70-rewritten-token-in-front-of-encoded-pem-header/expected.json +1 -3
  71. package/conformance/cases/c71-one-scanner-write-reads-display-forms/expected.json +1 -3
  72. package/conformance/cases/c72-dangling-reference-write-seat-refuses/expected.json +1 -3
  73. package/conformance/cases/c73-projects-extended-registration-reads/expected.json +1 -3
  74. package/conformance/cases/c74-projects-over-bound-refused/expected.json +1 -3
  75. package/conformance/cases/c75-projects-patch-remote-uniqueness/expected.json +1 -3
  76. package/conformance/cases/c76-projects-entry-salvage-nested/expected.json +1 -3
  77. package/conformance/cases/c77-prompts-center-artifact-carried/expected.json +252 -0
  78. package/conformance/cases/c77-prompts-center-artifact-carried/input.json +93 -0
  79. package/conformance/cases/c77-prompts-center-artifact-carried/meta.json +5 -0
  80. package/conformance/cases/c78-prompts-empty-bindings-refused/expected.json +82 -0
  81. package/conformance/cases/c78-prompts-empty-bindings-refused/input.json +11 -0
  82. package/conformance/cases/c78-prompts-empty-bindings-refused/meta.json +5 -0
  83. package/conformance/cases/c79-prompts-bad-worker-artifact-not-salvaged/expected.json +82 -0
  84. package/conformance/cases/c79-prompts-bad-worker-artifact-not-salvaged/input.json +129 -0
  85. package/conformance/cases/c79-prompts-bad-worker-artifact-not-salvaged/meta.json +5 -0
  86. package/conformance/cases/c80-prompts-wire-v2-verbatim/expected.json +195 -0
  87. package/conformance/cases/c80-prompts-wire-v2-verbatim/input.json +65 -0
  88. package/conformance/cases/c80-prompts-wire-v2-verbatim/meta.json +5 -0
  89. package/conformance/cases/c81-prompts-declaration-bindings-refused/expected.json +82 -0
  90. package/conformance/cases/c81-prompts-declaration-bindings-refused/input.json +23 -0
  91. package/conformance/cases/c81-prompts-declaration-bindings-refused/meta.json +5 -0
  92. package/conformance/cases/c82-prompts-v1-catalog-refused/expected.json +82 -0
  93. package/conformance/cases/c82-prompts-v1-catalog-refused/input.json +35 -0
  94. package/conformance/cases/c82-prompts-v1-catalog-refused/meta.json +5 -0
  95. package/conformance/cases/c83-prompts-bad-overlay-not-salvaged/expected.json +82 -0
  96. package/conformance/cases/c83-prompts-bad-overlay-not-salvaged/input.json +56 -0
  97. package/conformance/cases/c83-prompts-bad-overlay-not-salvaged/meta.json +5 -0
  98. package/conformance/cases/cc01-mcp-toolfaces-non-object/expected.json +1 -3
  99. package/conformance/cases/cc02-mcp-source-key-is-transported/expected.json +1 -3
  100. package/conformance/cases/cc03-model-compat-unknown-subkey/expected.json +1 -3
  101. package/conformance/cases/cli01-model-name-nfc-vs-nfd/expected.json +1 -3
  102. package/conformance/cases/cli02-control-and-zero-width-chars/expected.json +1 -3
  103. package/conformance/cases/cli03-credential-pasted-into-unknown-key/expected.json +1 -3
  104. package/conformance/cases/cli04-env-value-with-newline/expected.json +1 -3
  105. package/conformance/cases/cli05-long-and-prefix-colliding-names/expected.json +1 -3
  106. package/conformance/cases/t01-absent-domain-key-not-null/expected.json +1 -3
  107. package/conformance/cases/t03-prototype-name-key-not-swallowed/expected.json +1 -3
  108. package/conformance/cases/t04-secret-literal-never-in-warning-value/expected.json +1 -3
  109. package/conformance/cases/z01-every-domain-empty-object/expected.json +2 -6
  110. package/conformance/cases/z02-every-domain-unknown-key/expected.json +2 -6
  111. package/dist/config-fns.d.ts +7 -3
  112. package/dist/config-fns.js +19 -16
  113. package/dist/conformance/derive.js +2 -2
  114. package/dist/index.d.ts +1 -0
  115. package/dist/index.js +1 -0
  116. package/dist/mcp-request-entry.d.ts +118 -0
  117. package/dist/mcp-request-entry.js +266 -0
  118. package/dist/migration-receipt.d.ts +1 -1
  119. package/dist/migration-receipt.js +1 -1
  120. package/dist/node.d.ts +0 -1
  121. package/dist/node.js +0 -1
  122. package/dist/one-time-migrations.d.ts +1 -1
  123. package/dist/one-time-migrations.js +39 -0
  124. package/dist/safety-merge-spec.d.ts +6 -6
  125. package/dist/types.d.ts +438 -355
  126. package/dist/types.js +161 -136
  127. package/dist/url-shape.d.ts +8 -0
  128. package/dist/url-shape.js +10 -0
  129. package/docs/API-SURFACE.md +41 -27
  130. package/docs/CONFORMANCE.md +1 -1
  131. package/docs/CONSUMER-INTEGRATION.md +3 -2
  132. package/llms-full.txt +14 -11
  133. package/llms.txt +8 -2
  134. package/package.json +2 -2
  135. package/dist/prompts-digest.d.ts +0 -16
  136. package/dist/prompts-digest.js +0 -49
package/dist/types.js CHANGED
@@ -777,8 +777,8 @@ export const ScenarioEntry = z.object({
777
777
  * a release just to NAME a toolset a newer service ships. */
778
778
  toolset: z.string().regex(/^[a-z][a-z0-9-]{0,63}$/, "toolset key (lowercase slug)"),
779
779
  // ScenarioEntry.prompt 已废弃(产品裁定 2026-07-17,[ref]③a;第二评审独立同判「second
780
- // registry field would become an ambiguous precedence channel」):配置域 prompt 单入口=web-admin
781
- // prompts binding(scenario 维度);引擎 API 层 TaskSpec.systemPrompt 保留(不同层,勿混)。
780
+ // registry field would become an ambiguous precedence channel」):配置域 prompt 单入口=prompts 域的中心 artifact
781
+ // (场景维度 = overlay 的 `when.binding`,14.0.0);引擎 API 层 TaskSpec.systemPrompt 保留(不同层,勿混)。
782
782
  // 现网无用户直删;z.object 非 strict ⇒ 存量数据带 prompt 被 strip,parse 不炸。
783
783
  // 落日(2.0.0):本条是**纯墓碑**(零代码,靠 strip 生效),没有要删的兼容码;它留在这里的唯一作用
784
784
  // 是让下一个读到这段 schema 的人知道 `prompt` 这个名字曾经在这里、别再铸回来。0.19.0 起存量文档带
@@ -2577,147 +2577,172 @@ export const PluginsConfig = z
2577
2577
  seen.add(p.name);
2578
2578
  });
2579
2579
  });
2580
- // ── The domain registry ───────────────────────────────────────────────────────
2581
- // ═══ prompts 域(web-admin prompts 战役 v1;[ref] 五定夺/[1051] 产品终稿/[1057] M2 下发形)═══
2582
- // schema=编译目标非用户界面([1051]⓪):三卡(角色卡/场景说明/行为守则)是 web UI 编译层心智,
2583
- // 本契约只承载编译产物(typed 声明)与 binding。单真源纪律:存储/解析在 web-admin(sema-web),
2584
- // 消费投影在 server(声明数组逐字喂 core typed stableBlocks 钩子),schema 恒在本仓(零第二份)。
2585
- /** 提示声明的槽位闭集(core `PromptTextDeclaration.slot` 同形):identity = 角色卡、scenario = 场景说明、behavior = 行为守则。
2586
- * declaration 轴与 catalog 轴({@link PromptArtifactSection})共用这一只。 */
2587
- export const PROMPT_SLOTS = ["identity", "scenario", "behavior"];
2588
- /** The slot enum, DERIVED from {@link PROMPT_SLOTS} (the runtime member table —— same form as `REF_CHECKED_DOMAINS`). */
2589
- export const PromptSlot = z.enum(PROMPT_SLOTS);
2590
- /** core `PromptTextDeclaration` 的契约层同形(core prompts/default.d.ts 逐字:id/slot 闭集/text)。
2591
- * slot ↔ 三卡:identity=角色卡、scenario=场景说明、behavior=行为守则([1051]①)。 */
2592
- export const PromptTextDeclaration = z.object({
2593
- id: z.string().min(1).max(128),
2594
- slot: PromptSlot,
2595
- text: z.string().max(65536),
2596
- /** core 1.315 opt-in 逐 section 对账锚([1062]①):声明方对 `text` 铸 sha256,core 校验后逐字
2597
- * 透传进 manifest `contentHash`(错值丢弃+warn,core 永不自算非盐化 digest)。缺省=退化为
2598
- * 整包 contentDigest 对账。契约层显式声明防非 strict parse strip 断锚([1062]③)。 */
2599
- contentHash: Sha256Digest.optional(),
2600
- });
2601
- /** 三维 binding([ref]①a:v1=global/worker/scenario,砍 model 维——per-model 微调走
2602
- * ModelEntry.promptGuidance 专用通道)。covering 语义([1050]①b,解析只在 web-admin 一处):
2603
- * 同 slot **层间整体替换**(胜出层该 slot 声明数组整体替换低层同 slot 全部条目;层内数组保序,
2604
- * 与 core assemble「declaration order preserved」无缝);层序 scenario > worker > global。
2605
- * 发布即物化([1051]②a):declarations 是 publish 时物化的不可变声明(意图层/编译器版本归
2606
- * web-admin 编辑面存储,非跨仓契约面)。 */
2607
- export const PromptBinding = z.object({
2608
- /** 绑定层。 */
2609
- level: z.enum(["global", "worker", "scenario"]),
2610
- /** level=worker 时必填:worker 名。 */
2611
- worker: z.string().min(1).max(190).optional(),
2612
- /** level=scenario 时必填:scenario slug(ScenarioEntry.name 同形)。 */
2613
- scenario: z.string().regex(/^[a-z][a-z0-9-]{1,31}$/).optional(),
2614
- /** 该层声明(可含多 slot;覆盖粒度=slot,见上)。 */
2615
- declarations: z.array(PromptTextDeclaration).max(64),
2616
- enabled: z.boolean().default(true),
2617
- notes: z.string().optional(),
2618
- }).superRefine((b, ctx) => {
2619
- if (b.level === "worker" && !b.worker)
2620
- ctx.addIssue({ code: "custom", ...buildQuotedIssue `level=worker requires \`worker\`` });
2621
- if (b.level === "scenario" && !b.scenario)
2622
- ctx.addIssue({ code: "custom", ...buildQuotedIssue `level=scenario requires \`scenario\`` });
2623
- if (b.level === "global" && (b.worker || b.scenario))
2624
- ctx.addIssue({ code: "custom", ...buildQuotedIssue `level=global must not carry a selector` });
2625
- });
2626
- // ═══ prompts 域 catalog 轴(0.10.20;[ref]a/[1242]/[1248] 过轮定稿;core design/148 S1 seam)═══
2627
- // 形 = core 1.336+ 的 `PublishedPromptArtifactEnvelope`(sema-core src/prompt-assembly/artifact.ts,
2628
- // [1236]① seam 形即终形):v1 骑 declaration 轴的 immutable by-digest artifact——协议 §5.1 全 catalog
2629
- // (overlays/profiles/modelPolicies/bindings)是后续 additive 切片,本轴到时 additive 扩,零迁移。
2630
- // 单真源纪律:server 候选门用 core 导出的 `verifyPromptArtifact`(digest 复算+上限+range 全管线),
2631
- // 本 zod 只是**传输门**(防 DoS/坏形早拒);上限=[[镜像常量]],见 PROMPT_ARTIFACT_LIMITS。
2632
- /** core `ARTIFACT_LIMITS` 的镜像常量(本包不加 core 运行期依赖轴 ⇒ 镜像)。对表钉住在**镜像的属主**这里:上游漂移门 ⑤ 逐键
2633
- * === devDependency 钉住的那只 core 的导出 —— 改上限必须同版动两处、过钉。 */
2580
+ // ═══ prompts 域(14.0.0:只装一种东西 —— 引擎当期 schema 的中心 artifact)═══════════════════════════════════════════
2581
+ // 律:存储存 artifact 的**身份**(`{payload, artifactDigest}`,按 worker 分区);每条下发腿只发 `{schemaVersion: 2, artifact}`(发布出处 `sourceRevision`
2582
+ // 由服务席盖);「哪个场景用哪段」只在 artifact 里 `when.binding` 一处表达;哪一份给哪台 worker 只有 {@link promptArtifactFor} 一只读法。
2583
+ // 本包对 artifact 只镜像**结构与上界**(键闭集、类型、上界、`when.binding` 文法),不镜像任何引擎词表(op / band / target / trait / fact / host 词 /
2584
+ // target kind)—— 语义只有引擎的 verify 一个判官(传输门宽、语义门准:引擎收的,本包必收;对拍门 = 上游漂移门 ⑤ ⑦)。
2585
+ // 13.x 的两轴(声明轴 `bindings` 与 catalog 轴 v1 信封)在 14.0.0 硬退役:型面删除,存量键是墓碑,一次性迁移 SS-M10 只删空的 `bindings: []`。
2586
+ /** 引擎 `ARTIFACT_LIMITS` 的镜像常量(本包不带引擎运行期依赖 ⇒ 镜像)。对表钉在**镜像的属主**这里:上游漂移门 ⑤ 逐键 === devDependency 钉住的那只引擎的导出。
2587
+ * `maxOverlayTextBytes` / `maxTotalTextBytes` 引擎按 UTF-8 字节量;本包的 zod 按字符(UTF-16 码元)量 —— 码元数恒 ≤ UTF-8 字节数,所以本包的门恒宽于引擎、方向对。
2588
+ * `maxIntentChars` / `maxRefChars` / `maxSourceRevisionChars` 引擎按 Unicode 码点量;本包用 `withinCodePoints` 同一把尺(不用 zod 的 `.max()`,它的单位随 zod 版本变)。 */
2634
2589
  export const PROMPT_ARTIFACT_LIMITS = {
2635
- maxSections: 64,
2636
- maxSectionBytes: 32_000,
2637
- maxTotalBytes: 131_072,
2638
- maxIdLength: 128,
2639
- maxPackIdLength: 200,
2590
+ maxOverlays: 64,
2591
+ maxOverlayTextBytes: 32_000,
2592
+ maxTotalTextBytes: 131_072,
2593
+ maxIntentChars: 2_000,
2594
+ maxRefs: 32,
2595
+ maxRefChars: 500,
2596
+ maxSourceRevisionChars: 500,
2640
2597
  };
2641
- /** catalog 轴 section(core `CenterOverlaySection` 同形):center lane 的 contentHash **必备**
2642
- * (对账锚,[1050]② tiering;与 declaration 轴的 optional 不同)。text 上限按镜像常量(zod length
2643
- * 为 UTF-16 码元数,core verify 按 UTF-8 字节复核——传输门宽、语义门准)。 */
2644
- export const PromptArtifactSection = z.object({
2645
- id: z.string().min(1).max(PROMPT_ARTIFACT_LIMITS.maxIdLength).regex(/^[a-z0-9][a-z0-9/._-]*$/),
2646
- slot: PromptSlot,
2647
- text: z.string().min(1).max(PROMPT_ARTIFACT_LIMITS.maxSectionBytes),
2648
- contentHash: Sha256Digest,
2649
- });
2650
- /** core `PromptCatalogSnapshot` 同形。packId=逻辑名(如 `center:acme@3`),历史身份恒在 digest。 */
2651
- export const PromptCatalogSnapshot = z.object({
2652
- packId: z.string().min(1).max(PROMPT_ARTIFACT_LIMITS.maxPackIdLength),
2653
- sections: z.array(PromptArtifactSection).min(1).max(PROMPT_ARTIFACT_LIMITS.maxSections),
2654
- });
2655
- /** core `PromptEpochArtifactPayload` 同形(schemaVersion/assemblyApi 常量 1;catalogDigest=
2656
- * sha256(canonical(closure.promptCatalog)),server 候选门经 core verify 逐位复算;compatibleCore=
2657
- * 无依赖 dotted-triple range,schema 层只判形不解释)。 */
2658
- export const PromptEpochArtifactPayload = z.object({
2659
- schemaVersion: z.literal(1),
2660
- assemblyApi: z.literal(1),
2661
- catalogDigest: Sha256Digest,
2662
- compatibleCore: z
2663
- .object({
2664
- minCore: z.string().regex(/^\d+\.\d+\.\d+$/).optional(),
2665
- maxCoreExclusive: z.string().regex(/^\d+\.\d+\.\d+$/).optional(),
2666
- })
2667
- .optional(),
2668
- closure: z.object({
2669
- basePackId: z.string().min(1).max(PROMPT_ARTIFACT_LIMITS.maxPackIdLength),
2670
- promptCatalog: PromptCatalogSnapshot,
2598
+ /** 一个 binding 名(= 一次运行的场景名,`TaskSpec.promptBinding`)的长界 —— 引擎包根同名常量的镜像(对拍 = 上游漂移门 ⑤,逐值)。 */
2599
+ export const PROMPT_BINDING_MAX_CHARS = 128;
2600
+ /** 一张 `when.binding` 表至多点名几个 binding —— 引擎包根同名常量的镜像(同上)。 */
2601
+ export const PROMPT_BINDING_LIST_MAX = 64;
2602
+ /** overlay id 的长界(引擎同值、未从包根导出;对拍 = 上游漂移门 ⑦ 的行为探针)。 */
2603
+ const PROMPT_OVERLAY_ID_MAX_CHARS = 128;
2604
+ const isNonBlank = (s) => s.trim() !== "";
2605
+ /** 引擎字符界的同一把尺:按 Unicode 码点量(一个非 BMP 字符算一个),与引擎 `codePointsOver` 同答 —— binding 名 / `evidence.intent` / 每条 ref / `sourceRevision` 四处共用。
2606
+ * 不用 zod 的 `.max()`:它的单位随 zod 版本变(低端量 UTF-16 码元、高端量码点;版本界与实测见 CHANGELOG 14.0.0 B4),而本包声明的 zod 区间两端都在 —— 那样宿主解析到哪一版 zod,
2607
+ * 镜像对非 BMP 字符的答案就跟着变,比引擎窄一步就破「引擎收的,本包必收」。镜像自带这把尺,答案不随 zod 版本动。
2608
+ * 码元数 ≤ max ⇒ 码点数 ≤ max;码元数 > 2·max ⇒ 码点数 > max;只有夹在中间的才逐点数(不整串拷贝)。 */
2609
+ const withinCodePoints = (max) => (s) => {
2610
+ if (s.length <= max)
2611
+ return true;
2612
+ if (s.length > 2 * max)
2613
+ return false;
2614
+ let n = 0;
2615
+ for (const _ of s)
2616
+ if (++n > max)
2617
+ return false;
2618
+ return true;
2619
+ };
2620
+ /** 一个 binding 名:非空白、≤ {@link PROMPT_BINDING_MAX_CHARS} 个码点(引擎同尺,见 `withinCodePoints`)。 */
2621
+ const PromptBindingName = z
2622
+ .string()
2623
+ .refine(withinCodePoints(PROMPT_BINDING_MAX_CHARS), buildQuotedIssue `a binding is at most ${fixed(String(PROMPT_BINDING_MAX_CHARS))} characters (code points)`)
2624
+ .refine(isNonBlank, buildQuotedIssue `a binding is a non-blank string`);
2625
+ /** 一张 binding 表:1–{@link PROMPT_BINDING_LIST_MAX} 个、互不重名。 */
2626
+ const PromptBindingList = z
2627
+ .array(PromptBindingName)
2628
+ .min(1)
2629
+ .max(PROMPT_BINDING_LIST_MAX)
2630
+ .refine((l) => new Set(l).size === l.length, buildQuotedIssue `a binding list names a binding twice`);
2631
+ /** `when.binding`:**恰一张表** —— `{anyOf}`(运行的 binding 在表里才成立;没有 binding 的运行在每张 anyOf 之外)或 `{noneOf}`(没有 binding、或不在表里才成立)。
2632
+ * 两张都给 / 都不给 / 别的键 ⇒ 拒。场景覆写写成一对互斥条件:通用的 `noneOf: [x]` 旁边是场景的 `anyOf: [x]`。 */
2633
+ export const PromptBindingCondition = z.union([z.object({ anyOf: PromptBindingList }).strict(), z.object({ noneOf: PromptBindingList }).strict()], {
2634
+ error: '"when.binding" is exactly one list: {"anyOf": [...]} or {"noneOf": [...]}',
2635
+ });
2636
+ /** overlay 的适用条件(引擎选择器的同一套词):traits / host / facts / binding 的合取;键闭合,词开放(词归引擎)。 */
2637
+ export const PromptOverlayWhen = z
2638
+ .object({
2639
+ traits: z.object({ allOf: z.array(z.string()).optional(), noneOf: z.array(z.string()).optional() }).strict().optional(),
2640
+ host: z.object({ role: z.string().optional(), form: z.string().optional() }).strict().optional(),
2641
+ facts: z.record(z.string(), z.boolean()).optional(),
2642
+ binding: PromptBindingCondition.optional(),
2643
+ })
2644
+ .strict();
2645
+ /** 一条中心 overlay:对一个目标的一个操作(`replace` / `append` 一条目录消息、`add` 进一个档、`drop` 一段),带文本或引一条目录消息。
2646
+ * 键闭合(v3 没有 `scope`:binding 只在 `when.binding`);op / target / message 的词与存在性、id 文法、text ⊕ message 的互斥都归引擎。 */
2647
+ export const PromptOverlay = z
2648
+ .object({
2649
+ id: z.string().min(1).max(PROMPT_OVERLAY_ID_MAX_CHARS),
2650
+ op: z.string(),
2651
+ target: z.string().min(1),
2652
+ text: z.string().max(PROMPT_ARTIFACT_LIMITS.maxOverlayTextBytes).optional(),
2653
+ message: z.string().optional(),
2654
+ when: PromptOverlayWhen.optional(),
2655
+ })
2656
+ .strict();
2657
+ /** artifact 向引擎要的东西:它点名的目标(带种类)、用到的操作、条件读到的 trait、点名的 binding。引擎从 overlay 复算并比对,本包只判形。 */
2658
+ export const PromptArtifactRequires = z
2659
+ .object({
2660
+ targets: z.array(z.object({ id: z.string(), kind: z.string() }).strict()),
2661
+ ops: z.array(z.string()),
2662
+ traits: z.array(z.string()),
2663
+ bindings: z.array(z.string()),
2664
+ })
2665
+ .strict();
2666
+ /** artifact 为什么存在:一句意图(必填)与它背后的评测 / 金样引用。 */
2667
+ export const PromptArtifactEvidence = z
2668
+ .object({
2669
+ intent: z
2670
+ .string()
2671
+ .refine(withinCodePoints(PROMPT_ARTIFACT_LIMITS.maxIntentChars), buildQuotedIssue `evidence.intent is at most ${fixed(String(PROMPT_ARTIFACT_LIMITS.maxIntentChars))} characters (code points)`)
2672
+ .refine(isNonBlank, buildQuotedIssue `evidence.intent is a non-blank sentence`),
2673
+ refs: z
2674
+ .array(z
2675
+ .string()
2676
+ .refine(withinCodePoints(PROMPT_ARTIFACT_LIMITS.maxRefChars), buildQuotedIssue `an evidence reference is at most ${fixed(String(PROMPT_ARTIFACT_LIMITS.maxRefChars))} characters (code points)`)
2677
+ .refine(isNonBlank, buildQuotedIssue `an evidence reference is a non-blank string`))
2678
+ .max(PROMPT_ARTIFACT_LIMITS.maxRefs),
2679
+ })
2680
+ .strict();
2681
+ /** artifact 被摘要的那一半(引擎的 `artifactDigest` = sha256(canonical(payload)))。`schemaVersion` 只收 3。 */
2682
+ export const PromptArtifactPayload = z
2683
+ .object({
2684
+ schemaVersion: z.literal(3, {
2685
+ error: 'artifact payload schemaVersion: this contract carries schemaVersion 3 only — rebuild the artifact with the engine\'s buildPromptArtifact (an overlay\'s "scope": {"binding": b} becomes "when": {"binding": {"anyOf": [b]}})',
2671
2686
  }),
2672
- });
2673
- /** core `PublishedPromptArtifactEnvelope` 同形:发布信封=artifact(payload+artifactDigest)+ opaque
2674
- * sourceRevision(只比较相等、绝不排序;不进任何 digest——协议 §9.2 内容身份/发布事件分离)。 */
2675
- export const PublishedPromptArtifactEnvelope = z.object({
2676
- artifact: z.object({
2677
- payload: PromptEpochArtifactPayload,
2678
- artifactDigest: Sha256Digest,
2687
+ requires: PromptArtifactRequires,
2688
+ overlays: z
2689
+ .array(PromptOverlay)
2690
+ .min(1)
2691
+ .max(PROMPT_ARTIFACT_LIMITS.maxOverlays)
2692
+ .superRefine((overlays, ctx) => {
2693
+ const total = overlays.reduce((n, o) => n + (o.text?.length ?? 0), 0);
2694
+ if (total > PROMPT_ARTIFACT_LIMITS.maxTotalTextBytes)
2695
+ ctx.addIssue({ code: "custom", ...buildQuotedIssue `overlay texts total ${total} characters (at most ${fixed(String(PROMPT_ARTIFACT_LIMITS.maxTotalTextBytes))})` });
2679
2696
  }),
2680
- sourceRevision: z.string().min(1).max(256),
2681
- });
2682
- /** prompts 域存储形 v1(web-admin 存储真形;[1043] PromptCatalogPayload 的 v1 最小面)。
2683
- * overlays/profiles/modelPolicies = 协议 §5.1 的后续 additive 面,留位不预设形(等 core S6
2684
- * catalog schema 班车,additive 补键零迁移)。 */
2697
+ evidence: PromptArtifactEvidence,
2698
+ })
2699
+ .strict();
2700
+ const ARTIFACT_IDENTITY = { payload: PromptArtifactPayload, artifactDigest: Sha256Digest };
2701
+ /** 存储形:一份 artifact 的**身份**(payload + 引擎铸的 digest),不带发布出处。键闭合 —— 带 `sourceRevision` 的不收(出处是「哪一次发布」,由服务席在下发时盖)。 */
2702
+ export const PromptArtifact = z.object(ARTIFACT_IDENTITY).strict();
2703
+ /** 下发形:身份 + 发布出处 `sourceRevision`(只比相等、绝不排序;不进 digest)。键闭合。 */
2704
+ export const PublishedPromptArtifact = z
2705
+ .object({
2706
+ ...ARTIFACT_IDENTITY,
2707
+ sourceRevision: z
2708
+ .string()
2709
+ .min(1)
2710
+ .refine(withinCodePoints(PROMPT_ARTIFACT_LIMITS.maxSourceRevisionChars), buildQuotedIssue `sourceRevision is at most ${fixed(String(PROMPT_ARTIFACT_LIMITS.maxSourceRevisionChars))} characters (code points)`),
2711
+ })
2712
+ .strict();
2713
+ /** 13.x 两轴的墓碑(14.0.0):`bindings` / `catalog` 同一行。 */
2714
+ const PROMPTS_AXES_RETIRED = {
2715
+ retiredIn: "14.0.0",
2716
+ now: "the center artifact (prompts.artifact for every worker, prompts.workers.<name> for one worker)",
2717
+ migration: "SS-M10",
2718
+ };
2719
+ /** prompts 域存储形 v2:中心层的身份。web-admin 店(草稿 / 发布快照 / 回滚史)与本地 `config.d/prompts.json` 同形。 */
2685
2720
  export const PromptsConfig = z.object({
2686
- bindings: z.array(PromptBinding).max(256).prefault([]),
2687
- /** catalog 轴存储位(0.10.20,[985]a):web-admin 发布门铸好的 immutable envelope 原样存(发布即
2688
- * 物化,店内零解析);local FileConfigStore lane 的 config.d/prompts.json 也可直接携带——catalog
2689
- * 免 covering 解析,两 lane 自此同形(结束 local lane prompts 不透传的过渡态,[1234]① 位)。 */
2690
- catalog: PublishedPromptArtifactEnvelope.optional(),
2691
- });
2692
- /** effective 下发形([ref] 逐字;`GET /api/config/effective?worker=` 的 additive `prompts`
2693
- * key)。语义定死([1057]①):packId=`center:`+contentDigest 前 12(纯内容寻址,无 rev);
2694
- * contentDigest=canonical JSON 全量 sha256 非盐化(operator 对账位,digest 函数在 /node 绑定
2695
- * `promptsContentDigest`);sections=covering 已走完的基线终形(worker/core 零解析义务);
2696
- * scenarioOverrides[s]=该场景完整重算终形(整包替换非增量),无键=用基线;fail-closed=
2697
- * publish 闸关时整个 key 不出现。 */
2698
- /** prompts 包身份 `packId` 的前缀(铸点 `promptsContentDigest` 与判官 {@link PromptPackId} 都引它)。值落在引擎的会话记录里、是
2699
- * epoch 不误重 pin 的依据,所以值本身不随叫法归一改(换前缀 = 每条活会话的提示包身份翻一次,要引擎先读 epoch 判据)。 */
2700
- export const PROMPT_PACK_ID_PREFIX = "center:";
2701
- /** prompts 包身份的形:前缀 + 内容摘要的前 12 位小写 hex(纯内容寻址:同内容重发布 = 同 packId)。判它的每一处都引这一只。 */
2702
- export const PromptPackId = z.string().regex(new RegExp(`^${PROMPT_PACK_ID_PREFIX}[0-9a-f]{12}$`));
2703
- export const EffectivePrompts = z.object({
2704
- packId: PromptPackId,
2705
- contentDigest: Sha256Digest,
2706
- sections: z.array(PromptTextDeclaration),
2707
- scenarioOverrides: z.record(z.string(), z.array(PromptTextDeclaration)).optional(),
2708
- });
2709
- /** effective 下发形 v2(双轴,[985]a §1/[1242] Q1 裁:单 domain 单键、两轴是过渡窗内的两种表达)。
2710
- * declarations=现行 A 形(centerPromptProvider 继续消费);catalog=B 形(core S1 verify 管线的输入,
2711
- * server 原样交 core 不解释)。至少一轴必须在场(空对象=坏形);催收面语义照旧=publish 闸关时整个
2712
- * `prompts` key 消失(fail-closed)。引擎的候选门**只认本形**:没有 `schemaVersion` 的平铺 {@link EffectivePrompts} 体被响亮拒
2713
- * (整个 prompts 面不采用,落最后一份好配置 / 内置)。 */
2721
+ /** 每台 worker 都组装的中心层(`workers` 点名的那台除外)。缺席 = 不管提示词(引擎内置)。 */
2722
+ artifact: PromptArtifact.optional(),
2723
+ /** 按 worker 的中心层:点名的 worker 组装这一份,**整份取代** `artifact`(不叠加;覆盖语义只在编出它的那一处)。键 = worker 名(唯一的 worker 名判据)。 */
2724
+ workers: z.record(WORKER_NAME, PromptArtifact).optional(),
2725
+ bindings: retiredKey("prompts.bindings", PROMPTS_AXES_RETIRED),
2726
+ catalog: retiredKey("prompts.catalog", PROMPTS_AXES_RETIRED),
2727
+ });
2728
+ /** **唯一的选择读法**:这台 worker 组装哪一份中心层 —— 它有自己的那份 ⇒ 它;否则 scope 的那份;都没有 ⇒ `undefined`(不下发)。
2729
+ * `worker = null` = 没有 worker 身份的读者(本地腿、不带 worker 的全局拉取、个人面),恒读 scope 那份。只读自有键(名字恰是原型链上的名字时不会读出别的东西)。 */
2730
+ export function promptArtifactFor(prompts, worker) {
2731
+ const own = worker !== null && prompts.workers !== undefined && Object.prototype.hasOwnProperty.call(prompts.workers, worker) ? prompts.workers[worker] : undefined;
2732
+ return own ?? prompts.artifact;
2733
+ }
2734
+ /** effective 下发形 v2:`{ schemaVersion: 2, artifact }`(键闭合)。每条腿(按 worker 的 / 不带 worker 的 / 个人面)只发这一形;
2735
+ * 发布闸关 / 没有发布 / 选不出 artifact ⇒ 整个 `prompts` 键不出现(fail-closed)。外壳的 `schemaVersion` 只在外壳形变时抬(artifact 自带 payload 版本)。
2736
+ * 消费方的判官:先过本形,再交引擎 verify。13.x 的 `{schemaVersion: 1, declarations?, catalog?}` 被响亮拒(拒句点名升级路径)。 */
2714
2737
  export const EffectivePromptsWire = z
2715
2738
  .object({
2716
- schemaVersion: z.literal(1),
2717
- declarations: EffectivePrompts.optional(),
2718
- catalog: PublishedPromptArtifactEnvelope.optional(),
2739
+ schemaVersion: z.literal(2, {
2740
+ error: "prompts wire schemaVersion: this contract carries {schemaVersion: 2, artifact} only — the declarations / catalog axes were retired in settings-schema 14.0.0; the center serves its center artifact (upgrade the center)",
2741
+ }),
2742
+ artifact: PublishedPromptArtifact,
2719
2743
  })
2720
- .refine((w) => w.declarations !== undefined || w.catalog !== undefined, buildQuotedIssue `at least one axis (declarations|catalog) required`);
2744
+ .strict();
2745
+ // ── The domain registry ───────────────────────────────────────────────────────
2721
2746
  export const DOMAIN_SCHEMAS = {
2722
2747
  models: ModelsConfig,
2723
2748
  rosters: RostersConfig,
@@ -2733,7 +2758,7 @@ export const DOMAIN_SCHEMAS = {
2733
2758
  entitlement: EntitlementConfig,
2734
2759
  execution: ExecutionPolicy, // 0.8.0: S3 execution-lane policy (scope 级; client-advisory until service gate)
2735
2760
  projects: ProjectsConfig, // 0.10.0: 142-S3 project identity ledger + 无仓铸造权威 (scope=tenant 轴; NOT portable — 租户身份数据)
2736
- prompts: PromptsConfig, // 0.10.18: web-admin prompts 战役 v1([ref] 五定夺/产品终稿/M2 下发形;写门/store 携带解锁=[1064]②)
2761
+ prompts: PromptsConfig, // 0.10.18 起;14.0.0 单轴:中心 artifact 的身份(`{ artifact?, workers? }`);13.x 两轴的键是墓碑(SS-M10)
2737
2762
  limits: LimitsConfig, // 0.19.0: cost/限流族热更新发布位(消费方 #322 批1;本地腿闭集缺口的源头修复)
2738
2763
  // integrations + access: DELETED in 0.6.0 (EXPERT-REDESIGN §9) — parseDomain/effective/路由随之 404。
2739
2764
  };
@@ -12,6 +12,11 @@
12
12
  * 只看后者会把它们放过去(改前本包 `NON_SECRET_URL` 正是这样收下了 `https://gw/v1#`)。
13
13
  *
14
14
  * 拒句里值的样子(展示铸点)不在本模块:那是各宿主自己的展示律(server `buildRefusalShownUrl`)。本模块零 import,纯函数,浏览器安全。
15
+ *
16
+ * ## 本模块里的第二个答案(如实,14.0.0)
17
+ * 请求面 MCP 传输的 url(任务提交体 `mcpServers[i].transport.url`,`./mcp-request-entry`)今天不走上面的形判官,而是只看前缀
18
+ * ({@link startsWithHttpScheme}):那是消费方请求腿既有的读法,入包时语义逐字冻结。两者对同一个值可以答得不同(空 host、带 userinfo 的
19
+ * url 前缀判收、形判官拒)—— 一项已知待收的分歧;放在这里,是为了让「本包里判 URL 的正则」只有这一个模块。
15
20
  */
16
21
  /** 座位可以禁掉的部件(闭集;判序 = 本数组序)。 */
17
22
  export declare const HTTP_URL_PARTS: readonly ["userinfo", "query", "fragment"];
@@ -30,5 +35,8 @@ export declare function isHierarchicalUrl(raw: string): boolean;
30
35
  * 层级式非 http(s) ⇒ `not-http-url` 之后照判部件。返回类型按 `forbid` 收窄:座位没禁的部件不会出现在答案里。
31
36
  */
32
37
  export declare function httpUrlFlaws<P extends HttpUrlPart>(raw: string, forbid: readonly P[]): ReadonlyArray<"not-http-url" | P>;
38
+ /** 以 `http://` / `https://` 起头(大小写不敏感)—— 一道**语法前缀**守卫,不是形判官:不解析、不看 host / 部件(见头注「第二个答案」)。
39
+ * 唯一读者是请求面 MCP 传输读器(`readRequestMcpTransport`)。 */
40
+ export declare function startsWithHttpScheme(raw: string): boolean;
33
41
  /** 一个拒因词的规则句(穷举;新词不补 = 编译红)。句子只说规则,不含值。 */
34
42
  export declare function httpUrlRule(flaw: HttpUrlFlaw): string;
package/dist/url-shape.js CHANGED
@@ -12,6 +12,11 @@
12
12
  * 只看后者会把它们放过去(改前本包 `NON_SECRET_URL` 正是这样收下了 `https://gw/v1#`)。
13
13
  *
14
14
  * 拒句里值的样子(展示铸点)不在本模块:那是各宿主自己的展示律(server `buildRefusalShownUrl`)。本模块零 import,纯函数,浏览器安全。
15
+ *
16
+ * ## 本模块里的第二个答案(如实,14.0.0)
17
+ * 请求面 MCP 传输的 url(任务提交体 `mcpServers[i].transport.url`,`./mcp-request-entry`)今天不走上面的形判官,而是只看前缀
18
+ * ({@link startsWithHttpScheme}):那是消费方请求腿既有的读法,入包时语义逐字冻结。两者对同一个值可以答得不同(空 host、带 userinfo 的
19
+ * url 前缀判收、形判官拒)—— 一项已知待收的分歧;放在这里,是为了让「本包里判 URL 的正则」只有这一个模块。
15
20
  */
16
21
  /** 座位可以禁掉的部件(闭集;判序 = 本数组序)。 */
17
22
  export const HTTP_URL_PARTS = ["userinfo", "query", "fragment"];
@@ -46,6 +51,11 @@ export function httpUrlFlaws(raw, forbid) {
46
51
  const shape = u.protocol === "http:" || u.protocol === "https:" ? [] : ["not-http-url"];
47
52
  return [...shape, ...HTTP_URL_PARTS.filter((p) => forbid.includes(p) && present[p])];
48
53
  }
54
+ /** 以 `http://` / `https://` 起头(大小写不敏感)—— 一道**语法前缀**守卫,不是形判官:不解析、不看 host / 部件(见头注「第二个答案」)。
55
+ * 唯一读者是请求面 MCP 传输读器(`readRequestMcpTransport`)。 */
56
+ export function startsWithHttpScheme(raw) {
57
+ return /^https?:\/\//i.test(raw);
58
+ }
49
59
  /** 一个拒因词的规则句(穷举;新词不补 = 编译红)。句子只说规则,不含值。 */
50
60
  export function httpUrlRule(flaw) {
51
61
  switch (flaw) {
@@ -4,9 +4,9 @@
4
4
  > 每次全量重算并逐名比对 —— 加 / 删 / 改形一个导出而不重生成本档 ⇒ 红。导出面的每次变动因此以本档的 diff 出现在评审里。
5
5
  > 形:`value` = 运行期拿得到的值;`type` = 只在类型层;`value+type` = 同名的值与类型(zod schema 与它推出的类型)。
6
6
 
7
- 子路径 24 条(资产出口 `./package.json` / `./fleet-paths.json` 不是模块,不列),导出名合计 1316 个(同名在多条子路径上各计一次)。
7
+ 子路径 24 条(资产出口 `./package.json` / `./fleet-paths.json` 不是模块,不列),导出名合计 1330 个(同名在多条子路径上各计一次)。
8
8
 
9
- ## `.`(638)
9
+ ## `.`(654)
10
10
 
11
11
  - `ABSOLUTE_HOST_PATH_MAX` — value
12
12
  - `ACCESS_TOKEN_TTL_SECONDS` — value
@@ -122,7 +122,6 @@
122
122
  - `EXTENSION_NAMESPACES` — value
123
123
  - `EffectiveConfig` — type
124
124
  - `EffectiveKey` — value+type
125
- - `EffectivePrompts` — value+type
126
125
  - `EffectivePromptsWire` — value+type
127
126
  - `EffectiveReadWarning` — type
128
127
  - `EffectiveWire` — type
@@ -239,6 +238,7 @@
239
238
  - `MODEL_SWITCH_SOURCES` — value
240
239
  - `McpConfig` — value+type
241
240
  - `McpContentOrigin` — type
241
+ - `McpEntryKeyIssue` — type
242
242
  - `McpPolicyBlock` — type
243
243
  - `McpPolicyLayer` — type
244
244
  - `McpPolicyRule` — type
@@ -285,8 +285,8 @@
285
285
  - `PROJECT_ID_REGEX` — value
286
286
  - `PROJECT_LIMITS` — value
287
287
  - `PROMPT_ARTIFACT_LIMITS` — value
288
- - `PROMPT_PACK_ID_PREFIX` — value
289
- - `PROMPT_SLOTS` — value
288
+ - `PROMPT_BINDING_LIST_MAX` — value
289
+ - `PROMPT_BINDING_MAX_CHARS` — value
290
290
  - `ParseTransparentKey` — type
291
291
  - `ParseTransparentValidator` — type
292
292
  - `PendingPublish` — type
@@ -316,16 +316,16 @@
316
316
  - `ProjectRegistration` — value+type
317
317
  - `ProjectRegistrationPatch` — value+type
318
318
  - `ProjectsConfig` — value+type
319
- - `PromptArtifactSection` — value+type
320
- - `PromptBinding` — value+type
321
- - `PromptCatalogSnapshot` — value+type
322
- - `PromptEpochArtifactPayload` — value+type
319
+ - `PromptArtifact` — value+type
320
+ - `PromptArtifactEvidence` — value+type
321
+ - `PromptArtifactPayload` — value+type
322
+ - `PromptArtifactRequires` — value+type
323
+ - `PromptBindingCondition` — value+type
323
324
  - `PromptHookEntry` — value+type
324
- - `PromptPackId` — value
325
- - `PromptSlot` — value+type
326
- - `PromptTextDeclaration` — value+type
325
+ - `PromptOverlay` — value+type
326
+ - `PromptOverlayWhen` — value+type
327
327
  - `PromptsConfig` — value+type
328
- - `PublishedPromptArtifactEnvelope` — value+type
328
+ - `PublishedPromptArtifact` — value+type
329
329
  - `PublishedSnapshot` — type
330
330
  - `QuotaLease` — value+type
331
331
  - `QuotaResetEvent` — value+type
@@ -354,6 +354,8 @@
354
354
  - `RefReferrer` — type
355
355
  - `RefReferrerDomain` — type
356
356
  - `RemoteExecSpec` — value+type
357
+ - `RequestMcpTransport` — type
358
+ - `RequestMcpTransportRead` — type
357
359
  - `ResolvedEffective` — type
358
360
  - `ResolvedMemberAdmission` — type
359
361
  - `ResolvedTokenScope` — type
@@ -458,6 +460,7 @@
458
460
  - `TENANT_SEPARATION_BASES` — value
459
461
  - `TENANT_SEPARATION_WORDS` — value
460
462
  - `TOKEN_SCOPE_REFUSALS` — value
463
+ - `TOOL_WIRE_NAME_MAX_CHARS` — value
461
464
  - `TaskCompletedHookInput` — value
462
465
  - `TaskCreatedHookInput` — value
463
466
  - `TeammateIdleHookInput` — value
@@ -529,6 +532,11 @@
529
532
  - `containsSecretToken` — value
530
533
  - `createSiblingResolver` — value
531
534
  - `danglingRefs` — value
535
+ - `describeBadContentOrigin` — value
536
+ - `describeBadWireName` — value
537
+ - `describeNotStringArray` — value
538
+ - `describeNotStringRecord` — value
539
+ - `describeValueShape` — value
532
540
  - `domainWriteRole` — value
533
541
  - `drainVerdict` — value
534
542
  - `effectiveScopeRole` — value
@@ -548,6 +556,7 @@
548
556
  - `isAbsoluteHostPath` — value
549
557
  - `isAtLeast` — value
550
558
  - `isCanonicalGeneration` — value
559
+ - `isContentOriginWord` — value
551
560
  - `isDisclosableIdentity` — value
552
561
  - `isDomainName` — value
553
562
  - `isHierarchicalUrl` — value
@@ -563,6 +572,9 @@
563
572
  - `isRole` — value
564
573
  - `isRoutable` — value
565
574
  - `isSchedulerRecord` — value
575
+ - `isStringArray` — value
576
+ - `isStringRecord` — value
577
+ - `isUsableWireName` — value
566
578
  - `judgeReadiness` — value
567
579
  - `judgeRoutability` — value
568
580
  - `judgeWebAdminCredentialDeclaration` — value
@@ -589,6 +601,7 @@
589
601
  - `parseWebAdminSessionUrl` — value
590
602
  - `pickInstance` — value
591
603
  - `projectWarning` — value
604
+ - `promptArtifactFor` — value
592
605
  - `readCapabilityReading` — value
593
606
  - `readCrossSessionInbound` — value
594
607
  - `readDialogExpiry` — value
@@ -597,7 +610,9 @@
597
610
  - `readEffectiveWire` — value
598
611
  - `readEngineSignal` — value
599
612
  - `readHttpHookAllowlistLayer` — value
613
+ - `readMcpIdentityHeaders` — value
600
614
  - `readModelRefusals` — value
615
+ - `readRequestMcpTransport` — value
601
616
  - `readScopedTokenBinding` — value
602
617
  - `readServingLeaseRequest` — value
603
618
  - `readServingLeaseResponse` — value
@@ -633,6 +648,7 @@
633
648
  - `skillContentHash` — value
634
649
  - `stableHash` — value
635
650
  - `stableStringify` — value
651
+ - `startsWithHttpScheme` — value
636
652
  - `statusRowsToPrune` — value
637
653
  - `stopAttributionText` — value
638
654
  - `toSkillsManifest` — value
@@ -677,7 +693,6 @@
677
693
  - `ENV_NAME` — value
678
694
  - `EffectiveConfig` — type
679
695
  - `EffectiveKey` — value+type
680
- - `EffectivePrompts` — value+type
681
696
  - `EffectivePromptsWire` — value+type
682
697
  - `EffectiveWire` — type
683
698
  - `EntitlementBudget` — value+type
@@ -723,8 +738,8 @@
723
738
  - `PROJECT_ID_REGEX` — value
724
739
  - `PROJECT_LIMITS` — value
725
740
  - `PROMPT_ARTIFACT_LIMITS` — value
726
- - `PROMPT_PACK_ID_PREFIX` — value
727
- - `PROMPT_SLOTS` — value
741
+ - `PROMPT_BINDING_LIST_MAX` — value
742
+ - `PROMPT_BINDING_MAX_CHARS` — value
728
743
  - `ParseTransparentKey` — type
729
744
  - `ParseTransparentValidator` — type
730
745
  - `PluginSource` — value+type
@@ -737,15 +752,15 @@
737
752
  - `ProjectRegistration` — value+type
738
753
  - `ProjectRegistrationPatch` — value+type
739
754
  - `ProjectsConfig` — value+type
740
- - `PromptArtifactSection` — value+type
741
- - `PromptBinding` — value+type
742
- - `PromptCatalogSnapshot` — value+type
743
- - `PromptEpochArtifactPayload` — value+type
744
- - `PromptPackId` — value
745
- - `PromptSlot` — value+type
746
- - `PromptTextDeclaration` — value+type
755
+ - `PromptArtifact` — value+type
756
+ - `PromptArtifactEvidence` — value+type
757
+ - `PromptArtifactPayload` — value+type
758
+ - `PromptArtifactRequires` — value+type
759
+ - `PromptBindingCondition` — value+type
760
+ - `PromptOverlay` — value+type
761
+ - `PromptOverlayWhen` — value+type
747
762
  - `PromptsConfig` — value+type
748
- - `PublishedPromptArtifactEnvelope` — value+type
763
+ - `PublishedPromptArtifact` — value+type
749
764
  - `QuotedIssueParams` — type
750
765
  - `RBAC_AUDIT` — value
751
766
  - `RESERVED_WORKER_ENV` — value
@@ -792,6 +807,7 @@
792
807
  - `isAbsoluteHostPath` — value
793
808
  - `isDomainName` — value
794
809
  - `isRetiredDomainName` — value
810
+ - `promptArtifactFor` — value
795
811
  - `renderQuotedSentence` — value
796
812
  - `retiredDomainSentence` — value
797
813
  - `urlQueryFragmentHasSecret` — value
@@ -1035,7 +1051,7 @@
1035
1051
  - `resolveMemberAdmission` — value
1036
1052
  - `trustRank` — value
1037
1053
 
1038
- ## `./node`(38)
1054
+ ## `./node`(36)
1039
1055
 
1040
1056
  - `ConfigBundle` — type
1041
1057
  - `ConfigDirectoryDocument` — type
@@ -1065,11 +1081,9 @@
1065
1081
  - `migrateConfigDirectory` — value
1066
1082
  - `mutateSchedulerStore` — value
1067
1083
  - `nodeConfigDirectoryIo` — value
1068
- - `promptsContentDigest` — value
1069
1084
  - `readBundle` — value
1070
1085
  - `remoteExecPath` — value
1071
1086
  - `saveSchedulerStore` — value
1072
- - `sectionContentHash` — value
1073
1087
  - `validateDomain` — value
1074
1088
  - `validateRemoteExec` — value
1075
1089
  - `writeBundle` — value
@@ -221,7 +221,7 @@ sema-test 的读数,是本仓自己重跑 `node scripts/conformance-historical.m
221
221
 
222
222
  | id | 影响的腿 | 动了什么 |
223
223
  |---|---|---|
224
- | `T1-prompts-materialisation` | wire | `buildEffective` 恒物化 `prompts:{bindings:[]}`;wire 按**在场性** verbatim 挂回(缺席进缺席出,且在场时是**未解析的原文档**) |
224
+ | `T1-prompts-materialisation` | wire | `buildEffective` 恒物化 `prompts`(缺席 ⇒ `{}`;14.0.0 前是 `{bindings:[]}`);wire 按**在场性** verbatim 挂回(缺席进缺席出,且在场时是**未解析的原文档**) |
225
225
  | `T2-skills-representation` | wire | 域形带 `content`,wire 形带 `contentHash`(manifest);判据 schema 随表示走,于是 wire 腿**没有** skills 的剥键告警 |
226
226
  | `T3-non-portable-domains` | local-root | `config.d/` 只读 `PORTABLE_DOMAINS`;其余域取 schema 默认 + `unread-config-file{non-portable-domain}`。**由常量派生,不手抄域名** |
227
227
  | `T4-unknown-top-level-key` | wire + local-root | wire 是 open-world,不认识的顶层键**逐字承运**;`domains` 腿按域名取文档故无声;local-root 报 `unread-config-file{not-a-domain}` |
@@ -108,10 +108,11 @@
108
108
  - 目录形:`npx @sema-agent/settings-schema migrate <config.d directory> [--check]`(同一只函数,目录当一个 scope;有 refused 一字不写、退出 1;
109
109
  `--check` 有改动退出 3;目录里有条目却没有一份域文档 —— 填成了上一层 / 只有非域文件 —— 退出 2、stdout 空、stderr 点名目录;目录真空(零条目或只有 `.` 开头的条目)= noop 退出 0;
110
110
  stdout 两行:结论行 `outcome=… written=…` + JSON 报告 `event: "stored_documents_migrated"`)。
111
- - **九条迁移**(登记表 `ONE_TIME_MIGRATIONS` 是窗的唯一属主,各条的 `rewrites` / `removal` / `afterRemoval` 写在那里):SS-M1 退役 runtime 域 ·
111
+ - **十条迁移**(登记表 `ONE_TIME_MIGRATIONS` 是窗的唯一属主,各条的 `rewrites` / `removal` / `afterRemoval` 写在那里):SS-M1 退役 runtime 域 ·
112
112
  SS-M2 hosts 超界(名 > 63 删条目、数组 > 1024 截断)· SS-M3 调度店 durable 键(读时)· SS-M4 workers 6.x 行 · SS-M5 钥匙双设(删
113
113
  `apiKeyEnv`,sealed 赢)· SS-M6 `atModelAllowlist` → `atMention` · SS-M7 URL fragment(`#` 及其后剥掉)· SS-M8 退役角色词(删 `roles.team` /
114
- `roles.synthesize`,12.0.0 随引擎 core 7.49.0)· SS-M9 `models.default` → `roles.default`(缺省模型只有一位)。
114
+ `roles.synthesize`,12.0.0 随引擎 core 7.49.0)· SS-M9 `models.default` → `roles.default`(缺省模型只有一位)· SS-M10 prompts 两轴(删空的 `bindings: []`;非空
115
+ `bindings` 与 `catalog` 拒、原样留,经中心编辑器重新发布)。
115
116
  - **读侧的新形**:`ModelEntry` 钥匙二选一(`sealedApiKey` 与 `apiKeyEnv` 同设 ⇒ 拒);`atMention`(`{mode:"all"}` 缺省 /
116
117
  `{mode:"none"}` / `{mode:"only",models}`,roster 位缺席 = 继承,收窄读法一只 `narrowAtMention` —— 收窄到一个都不剩就是 `none`);
117
118
  workers 6.x 字段与 `atModelAllowlist` 是 schema 里原位的**墓碑字段**(在场即拒,句子点名迁移);`readWorkersRows(raw) → { doc, held }`