@sema-agent/server 7.139.0 → 7.140.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 (194) hide show
  1. package/MIGRATION.md +181 -0
  2. package/USAGE.md +19 -13
  3. package/dist/adoption/runner.js +1 -1
  4. package/dist/adoption/sql.js +1 -1
  5. package/dist/approval-card.d.ts +6 -6
  6. package/dist/bench/s1/live-deps.js +3 -2
  7. package/dist/bench/s1/row.d.ts +5 -2
  8. package/dist/bench/s1/row.js +2 -22
  9. package/dist/boot/adoption.js +1 -1
  10. package/dist/boot/execution-env.js +12 -10
  11. package/dist/boot/execution-lane.d.ts +8 -0
  12. package/dist/boot/execution-lane.js +6 -1
  13. package/dist/boot/memory-boundary.d.ts +14 -51
  14. package/dist/boot/memory-boundary.js +10 -20
  15. package/dist/boot/memory-consolidation.d.ts +15 -11
  16. package/dist/boot/memory-consolidation.js +23 -12
  17. package/dist/boot/resolve-spec.d.ts +3 -5
  18. package/dist/boot/resolve-spec.js +2 -4
  19. package/dist/boot/runner-deps.d.ts +3 -3
  20. package/dist/boot/runner-deps.js +1 -0
  21. package/dist/boot/stage-03-store-backend.d.ts +2 -6
  22. package/dist/boot/stage-03-store-backend.js +2 -3
  23. package/dist/boot/stage-04-stores.d.ts +2 -6
  24. package/dist/boot/stage-04-stores.js +5 -5
  25. package/dist/boot/stage-05-execution-env.d.ts +2 -6
  26. package/dist/boot/stage-06-runners.d.ts +2 -6
  27. package/dist/boot/stage-06-runners.js +2 -2
  28. package/dist/boot/stage-07-capability-layer.d.ts +2 -6
  29. package/dist/boot/stage-08-reapers.d.ts +2 -6
  30. package/dist/boot/stage-09-leader.d.ts +2 -6
  31. package/dist/boot/stage-10-http-server.d.ts +2 -6
  32. package/dist/boot/stage-10-http-server.js +5 -4
  33. package/dist/boot/stores.d.ts +3 -6
  34. package/dist/boot/stores.js +27 -40
  35. package/dist/boot/task-list-lane.d.ts +1 -1
  36. package/dist/boot/task-list-lane.js +1 -1
  37. package/dist/boot/web-admin.js +35 -9
  38. package/dist/capabilities/execution-lane.d.ts +2 -2
  39. package/dist/config-catalog.js +2 -1
  40. package/dist/config-provider.d.ts +14 -13
  41. package/dist/config-provider.js +24 -18
  42. package/dist/config-types.d.ts +11 -2
  43. package/dist/config.js +2 -1
  44. package/dist/delegated-session-owner.d.ts +2 -1
  45. package/dist/delegated-session-owner.js +1 -1
  46. package/dist/deployment-shape.d.ts +9 -8
  47. package/dist/deployment-shape.js +4 -4
  48. package/dist/execution-lane-caps.d.ts +97 -106
  49. package/dist/execution-lane-caps.js +67 -83
  50. package/dist/http/memory-compliance-failure-reply.d.ts +3 -1
  51. package/dist/http/memory-compliance-failure-reply.js +5 -0
  52. package/dist/http/memory-layer-reply.d.ts +30 -0
  53. package/dist/http/memory-layer-reply.js +24 -0
  54. package/dist/http/resume-legs.js +13 -16
  55. package/dist/http/retired-service-deps.d.ts +1 -1
  56. package/dist/http/retired-service-deps.js +1 -1
  57. package/dist/http/routes/adoption.js +1 -1
  58. package/dist/http/routes/memory-bundle.js +3 -0
  59. package/dist/http/routes/memory-compliance.js +8 -1
  60. package/dist/http/routes/memory-consolidation.js +12 -1
  61. package/dist/http/routes/memory-origin.js +14 -2
  62. package/dist/http/routes/memory-policy.js +5 -0
  63. package/dist/http/routes/sessions.js +28 -11
  64. package/dist/http/routes/tasks.js +4 -2
  65. package/dist/http/server.d.ts +5 -25
  66. package/dist/http/server.js +2 -2
  67. package/dist/identity-source.d.ts +1 -1
  68. package/dist/identity-source.js +1 -1
  69. package/dist/lane-home-probe.d.ts +68 -42
  70. package/dist/lane-home-probe.js +53 -30
  71. package/dist/leader/wire.js +5 -4
  72. package/dist/memory-bundle-engine.d.ts +16 -9
  73. package/dist/memory-bundle-engine.js +29 -6
  74. package/dist/memory-operator-faces.d.ts +85 -30
  75. package/dist/memory-operator-faces.js +136 -30
  76. package/dist/memory-project-layer.d.ts +3 -21
  77. package/dist/memory-project-layer.js +11 -8
  78. package/dist/memory-scope-stores.d.ts +73 -0
  79. package/dist/memory-scope-stores.js +86 -0
  80. package/dist/memory-scope.d.ts +29 -5
  81. package/dist/memory-scope.js +16 -4
  82. package/dist/memory-sync-client.d.ts +20 -7
  83. package/dist/memory-sync-client.js +31 -13
  84. package/dist/plugins/adoption-log-sql.js +4 -4
  85. package/dist/plugins/approval-ask-store-sql.js +14 -14
  86. package/dist/plugins/approval-nonce-store.js +4 -4
  87. package/dist/plugins/blob-backend.d.ts +4 -4
  88. package/dist/plugins/blob-backend.js +7 -7
  89. package/dist/plugins/breaker-state-sql.js +2 -2
  90. package/dist/plugins/checkpoint-index-columns.js +2 -2
  91. package/dist/plugins/checkpoint-store-sql.js +16 -16
  92. package/dist/plugins/device-store-sql.js +19 -19
  93. package/dist/plugins/ensure-index.d.ts +1 -2
  94. package/dist/plugins/execution-placement-sql.d.ts +8 -8
  95. package/dist/plugins/execution-placement-sql.js +8 -8
  96. package/dist/plugins/file-history-store-sql.d.ts +2 -2
  97. package/dist/plugins/file-history-store-sql.js +4 -4
  98. package/dist/plugins/image-bake-store-sql.js +9 -9
  99. package/dist/plugins/image-index-sql.js +11 -11
  100. package/dist/plugins/leader-run-store-sql.js +4 -4
  101. package/dist/plugins/mailbox-store-sql.d.ts +2 -1
  102. package/dist/plugins/mailbox-store-sql.js +4 -4
  103. package/dist/plugins/memory-engine-tidb.js +5 -5
  104. package/dist/plugins/memory-optout-grant-store-sql.js +1 -1
  105. package/dist/plugins/memory-sync-store-tidb.js +3 -3
  106. package/dist/plugins/one-time-migrations.d.ts +10 -9
  107. package/dist/plugins/one-time-migrations.js +36 -36
  108. package/dist/plugins/org-delivery-quota-store.js +2 -2
  109. package/dist/plugins/outcome-ledger-sql.js +2 -2
  110. package/dist/plugins/permission-rule-store-sql.d.ts +4 -4
  111. package/dist/plugins/permission-rule-store-sql.js +16 -16
  112. package/dist/plugins/remote-env-adb.d.ts +7 -24
  113. package/dist/plugins/remote-env-adb.js +22 -5
  114. package/dist/plugins/remote-env-device.d.ts +2 -28
  115. package/dist/plugins/remote-env-device.js +2 -1
  116. package/dist/plugins/remote-env-e2b.d.ts +18 -26
  117. package/dist/plugins/remote-env-e2b.js +51 -4
  118. package/dist/plugins/remote-env-file-error.d.ts +1 -1
  119. package/dist/plugins/remote-env-file-error.js +8 -2
  120. package/dist/plugins/remote-env-host.d.ts +19 -35
  121. package/dist/plugins/remote-env-host.js +26 -3
  122. package/dist/plugins/remote-env-k8s.d.ts +3 -14
  123. package/dist/plugins/remote-env-k8s.js +3 -2
  124. package/dist/plugins/remote-env-local-docker.d.ts +4 -15
  125. package/dist/plugins/remote-env-local-docker.js +5 -4
  126. package/dist/plugins/remote-env-ssh.d.ts +4 -24
  127. package/dist/plugins/remote-env-ssh.js +4 -3
  128. package/dist/plugins/resume-anchor-store-sql.js +2 -2
  129. package/dist/plugins/retention-lane-store-sql.d.ts +1 -1
  130. package/dist/plugins/retention-lane-store-sql.js +2 -2
  131. package/dist/plugins/retention-store-sql.d.ts +1 -1
  132. package/dist/plugins/retention-store-sql.js +6 -6
  133. package/dist/plugins/run-store-sql.js +15 -15
  134. package/dist/plugins/schema-consistency.d.ts +6 -6
  135. package/dist/plugins/schema-consistency.js +1 -1
  136. package/dist/plugins/schema-ensure-legs.d.ts +2 -3
  137. package/dist/plugins/schema-ensure-legs.js +2 -2
  138. package/dist/plugins/schema-live-columns.d.ts +1 -1
  139. package/dist/plugins/session-capture-record-store-sql.js +1 -1
  140. package/dist/plugins/session-rules-column.d.ts +1 -1
  141. package/dist/plugins/session-rules-column.js +1 -1
  142. package/dist/plugins/session-workspace-cell.d.ts +1 -1
  143. package/dist/plugins/session-workspace-cell.js +1 -1
  144. package/dist/plugins/shared-memory-store-sql.js +2 -2
  145. package/dist/plugins/sql-driver.d.ts +10 -5
  146. package/dist/plugins/sql-driver.js +6 -6
  147. package/dist/plugins/sql-errors.js +1 -1
  148. package/dist/plugins/store-backend.d.ts +4 -6
  149. package/dist/plugins/store-backend.js +6 -6
  150. package/dist/plugins/task-list-store-sql.js +11 -11
  151. package/dist/plugins/tidb-pool.js +5 -5
  152. package/dist/plugins/tidb-session-storage.js +4 -4
  153. package/dist/plugins/tidb-session-store.js +13 -13
  154. package/dist/plugins/tool-result-store-sql.d.ts +2 -2
  155. package/dist/plugins/tool-result-store-sql.js +3 -3
  156. package/dist/plugins/user-input-ledger-sql.js +2 -2
  157. package/dist/plugins/workflow-journal-store-sql.js +5 -5
  158. package/dist/plugins/workflow-run-store-sql.js +19 -19
  159. package/dist/plugins/write-behind-counter.d.ts +2 -3
  160. package/dist/plugins/write-behind-counter.js +5 -5
  161. package/dist/resource-suspend.d.ts +14 -12
  162. package/dist/resource-suspend.js +1 -1
  163. package/dist/resource-window.d.ts +4 -3
  164. package/dist/run-local.js +14 -19
  165. package/dist/runs.d.ts +8 -4
  166. package/dist/runs.js +49 -65
  167. package/dist/session-incarnation.d.ts +1 -1
  168. package/dist/session-incarnation.js +1 -1
  169. package/dist/session-policy-wire.d.ts +1 -1
  170. package/dist/sql-engine-posture.d.ts +1 -1
  171. package/dist/sql-engine-posture.js +1 -1
  172. package/dist/{plugins → stores-sql}/background-agent-store-sql.d.ts +2 -2
  173. package/dist/{plugins → stores-sql}/background-agent-store-sql.js +8 -8
  174. package/dist/{plugins → stores-sql}/session-policy-store-sql.d.ts +7 -5
  175. package/dist/{plugins → stores-sql}/session-policy-store-sql.js +12 -12
  176. package/dist/{plugins → stores-sql}/usage-window-store-sql.d.ts +1 -1
  177. package/dist/{plugins → stores-sql}/usage-window-store-sql.js +3 -3
  178. package/dist/task-a2a.js +5 -6
  179. package/dist/task-mcp.d.ts +20 -7
  180. package/dist/task-mcp.js +17 -9
  181. package/dist/terminal.d.ts +27 -0
  182. package/dist/terminal.js +6 -0
  183. package/dist/trace/redact.d.ts +3 -1
  184. package/dist/trace/redact.js +80 -28
  185. package/dist/trace/self-minted-wire.d.ts +58 -0
  186. package/dist/trace/self-minted-wire.js +16 -0
  187. package/dist/web-admin-client/candidate-gate.d.ts +11 -7
  188. package/dist/web-admin-client/candidate-gate.js +1 -1
  189. package/dist/web-admin-client/http-client.d.ts +5 -4
  190. package/dist/web-admin-client/http-client.js +2 -2
  191. package/dist/web-admin-client/read-warnings.d.ts +7 -17
  192. package/dist/web-admin-client/read-warnings.js +5 -9
  193. package/package.json +2 -2
  194. package/wire-changes/server@7.140.0.json +184 -0
@@ -1168,21 +1168,37 @@ function unitCountWithin(scan, from, to, max) {
1168
1168
  return true;
1169
1169
  noteEvidenceRead(scan, from);
1170
1170
  noteEvidenceRead(scan, to);
1171
- const st = scan.table.starts;
1172
- if (st.length === 0)
1173
- return false;
1174
- const k = firstCredentialSpanFrom(scan.table, from);
1175
- if (k >= st.length || st[k] >= to)
1171
+ const t = scan.table;
1172
+ const lo = firstCredentialSpanFrom(t, from);
1173
+ let a = lo;
1174
+ let b = t.ends.length;
1175
+ while (a < b) {
1176
+ const mid = (a + b) >>> 1;
1177
+ if (t.ends[mid] <= to)
1178
+ a = mid + 1;
1179
+ else
1180
+ b = mid;
1181
+ }
1182
+ if (a === lo)
1176
1183
  return false;
1177
- let n = 0;
1178
- for (let p = from; p < to;) {
1179
- if (n > max)
1180
- return false;
1181
- const unit = opaqueUnitEnd(scan, p);
1182
- p = unit > 0 && unit <= to ? unit : p + 1;
1183
- n += 1;
1184
+ const saved = unitSavings(t);
1185
+ return to - from - (saved[a] - saved[lo]) <= max;
1186
+ }
1187
+ const UNIT_SAVINGS = new WeakMap();
1188
+ function unitSavings(t) {
1189
+ let saved = UNIT_SAVINGS.get(t);
1190
+ if (saved === undefined) {
1191
+ const n = t.starts.length;
1192
+ saved = new Float64Array(n + 1);
1193
+ for (let k = 0; k < n; k++)
1194
+ saved[k + 1] = saved[k] + (t.ends[k] - t.starts[k] - 1);
1195
+ UNIT_SAVINGS.set(t, saved);
1184
1196
  }
1185
- return n <= max;
1197
+ return saved;
1198
+ }
1199
+ export function unitCountWithinForTest(table, from, to, max) {
1200
+ const t = { starts: Int32Array.from(table, (x) => x[0]), ends: Int32Array.from(table, (x) => x[1]) };
1201
+ return unitCountWithin(buildForensicScan(t, 1), from, to, max);
1186
1202
  }
1187
1203
  function collectSsh2FenceSpans(scan, text, span, isHead) {
1188
1204
  let cachedFrom = 0;
@@ -1241,16 +1257,20 @@ function pemFenceLineEnd(text, labelFrom) {
1241
1257
  }
1242
1258
  return isPemFenceLabel(text, labelFrom, close) ? close + PEM_FENCE_CLOSE.length : PEM_LINE_INVALID;
1243
1259
  }
1244
- function collectPemFenceSpans(text, span, isHead) {
1260
+ function collectPemFenceSpans(scan, text, span, isHead) {
1245
1261
  let endFrom = -1;
1246
1262
  let endAt = -1;
1247
1263
  let endAfter = -1;
1264
+ const visibleEndLine = (b) => {
1265
+ const after = pemFenceLineEnd(text, b + PEM_END_OPEN.length);
1266
+ return after >= 0 && !inOpaqueUnit(scan, b) ? after : -1;
1267
+ };
1248
1268
  const earliestEndFence = (from) => {
1249
1269
  if (endFrom >= 0 && from >= endFrom && (endAt < 0 || endAt >= from))
1250
1270
  return;
1251
1271
  let b = text.indexOf(PEM_END_OPEN, from);
1252
1272
  let after = -1;
1253
- while (b >= 0 && (after = pemFenceLineEnd(text, b + PEM_END_OPEN.length)) < 0)
1273
+ while (b >= 0 && (after = visibleEndLine(b)) < 0)
1254
1274
  b = text.indexOf(PEM_END_OPEN, b + 1);
1255
1275
  endFrom = from;
1256
1276
  endAt = b;
@@ -1260,6 +1280,10 @@ function collectPemFenceSpans(text, span, isHead) {
1260
1280
  const fence = text.indexOf(PEM_FENCE_OPEN, from);
1261
1281
  if (fence < 0)
1262
1282
  return;
1283
+ if (inOpaqueUnit(scan, fence)) {
1284
+ from = fence + 1;
1285
+ continue;
1286
+ }
1263
1287
  const bodyFrom = pemFenceLineEnd(text, fence + PEM_FENCE_OPEN.length);
1264
1288
  if (bodyFrom === PEM_LINE_INVALID) {
1265
1289
  from = fence + 1;
@@ -1272,7 +1296,7 @@ function collectPemFenceSpans(text, span, isHead) {
1272
1296
  span(fence, text.length, true);
1273
1297
  return;
1274
1298
  }
1275
- if (endAt - bodyFrom > PEM_FENCE_BODY_MAX) {
1299
+ if (!unitCountWithin(scan, bodyFrom, endAt, PEM_FENCE_BODY_MAX)) {
1276
1300
  from = fence + 1;
1277
1301
  continue;
1278
1302
  }
@@ -1610,7 +1634,7 @@ let forensicRescanMode = "incremental";
1610
1634
  export function setForensicRescanModeForTest(mode) {
1611
1635
  forensicRescanMode = mode;
1612
1636
  }
1613
- function foldCredentialSpans(prev, spans, from) {
1637
+ function foldCredentialSpans(prev, spans, from, admit) {
1614
1638
  const cap = spans.length - from;
1615
1639
  if (cap === 0)
1616
1640
  return { next: prev, dirty: NO_CREDENTIAL_SPANS };
@@ -1619,6 +1643,8 @@ function foldCredentialSpans(prev, spans, from) {
1619
1643
  let m = 0;
1620
1644
  for (let i = from; i < spans.length; i++) {
1621
1645
  const sp = spans[i];
1646
+ if (admit !== undefined && !admit(sp))
1647
+ continue;
1622
1648
  const k = firstCredentialSpanFrom(prev, sp.start + 1) - 1;
1623
1649
  if (k >= 0 && prev.ends[k] >= sp.end)
1624
1650
  continue;
@@ -1742,7 +1768,7 @@ function buildForensicScan(table, armCount) {
1742
1768
  hdr: { search: 0, contentEnd: 0, next: 0, hitLimit: false, jsonEnd: false },
1743
1769
  };
1744
1770
  }
1745
- function advanceEvidence(scan, table, dirty) {
1771
+ function useEvidenceView(scan, table, dirty) {
1746
1772
  scan.table = table;
1747
1773
  scan.cursor = 0;
1748
1774
  scan.dirty = dirty;
@@ -2417,7 +2443,7 @@ export function structuralScannerForTest(arm) {
2417
2443
  case "json-secret-field":
2418
2444
  return { declared: new RegExp(JSON_SECRET_FIELD_PATTERN[0].source, JSON_SECRET_FIELD_PATTERN[0].flags), spans: collect(collectJsonSecretFieldSpans) };
2419
2445
  case "pem-fence":
2420
- return { declared: new RegExp(PEM_FENCE_PATTERN[0].source, PEM_FENCE_PATTERN[0].flags), spans: collect(collectPemFenceSpans) };
2446
+ return { declared: new RegExp(PEM_FENCE_PATTERN[0].source, PEM_FENCE_PATTERN[0].flags), spans: collect((text, span, isHead) => collectPemFenceSpans(buildForensicScan(NO_CREDENTIAL_SPANS, 1), text, span, isHead)) };
2421
2447
  }
2422
2448
  }
2423
2449
  let ppkScanBytes = 0;
@@ -2574,6 +2600,7 @@ const armPool = (() => {
2574
2600
  retry: boundary === undefined ? undefined : (text, at, out) => collectStickySpans(boundary, text, at, out),
2575
2601
  headSrc: boundary === undefined ? undefined : headSrc,
2576
2602
  headFirst: boundary === undefined ? undefined : headFirst,
2603
+ family: undefined,
2577
2604
  };
2578
2605
  };
2579
2606
  const scannerMember = (token, order, arm, rank = ARM_RANK.structural, lexical = false) => {
@@ -2588,9 +2615,12 @@ const armPool = (() => {
2588
2615
  retry: undefined,
2589
2616
  headSrc: undefined,
2590
2617
  headFirst: undefined,
2618
+ family: undefined,
2591
2619
  };
2592
2620
  };
2593
- const forensicMember = (token, order, arm) => {
2621
+ const forensicMember = (token, order, arm, family = undefined, view = "all") => {
2622
+ if (view === "other-families" && family === undefined)
2623
+ throw new Error(`redact: forensic arm ${token} reads the other-families evidence view but declares no credential family`);
2594
2624
  const repl = spanRepl(token);
2595
2625
  const rank = ARM_RANK.structural;
2596
2626
  return {
@@ -2603,11 +2633,13 @@ const armPool = (() => {
2603
2633
  retry: undefined,
2604
2634
  headSrc: undefined,
2605
2635
  headFirst: undefined,
2636
+ family,
2637
+ view,
2606
2638
  };
2607
2639
  };
2608
2640
  const structuralScannerMember = (row, order) => {
2609
2641
  if (row === PEM_FENCE_PATTERN)
2610
- return scannerMember(row[1], order, (text, _json, _eat, span, isHead) => collectPemFenceSpans(text, span, isHead));
2642
+ return forensicMember(row[1], order, (scan, text, _json, _eat, span, isHead) => collectPemFenceSpans(scan, text, span, isHead), "pem-armor", "other-families");
2611
2643
  if (row === SSH2_FENCE_PATTERN)
2612
2644
  return forensicMember(row[1], order, (scan, text, _json, _eat, span, isHead) => collectSsh2FenceSpans(scan, text, span, isHead));
2613
2645
  if (row === URL_CREDENTIAL_PATTERN)
@@ -2620,7 +2652,7 @@ const armPool = (() => {
2620
2652
  for (const row of STRUCTURAL_SECRET_PATTERNS)
2621
2653
  members.push(structuralScannerMember(row, members.length));
2622
2654
  members.push(forensicMember(PPK_CONTAINER_TOKEN, members.length, (scan, text, _json, eat, span, isHead) => collectPpkContainerSpans(scan, text, eat, span, isHead)));
2623
- members.push(forensicMember(PEM_FRAGMENT_TOKEN, members.length, (scan, text, json, _eat, span) => collectPemFragmentSpans(scan, text, json, span)));
2655
+ members.push(forensicMember(PEM_FRAGMENT_TOKEN, members.length, (scan, text, json, _eat, span) => collectPemFragmentSpans(scan, text, json, span), "pem-armor"));
2624
2656
  members.push(forensicMember(HEADLESS_PPK_TOKEN, members.length, (scan, text, _json, _eat, span, isHead) => collectHeadlessPpkSpans(scan, text, span, isHead)));
2625
2657
  members.push(scannerMember(ANCHORED_VALUE_TOKEN, members.length, (text, json, _eat, span, isHead) => collectAnchoredValueSpans(text, json, span, isHead), ARM_RANK.keyword, true));
2626
2658
  for (const row of KEYWORD_SECRET_PATTERNS)
@@ -2636,6 +2668,13 @@ const armPool = (() => {
2636
2668
  const retryMembers = members.filter((m) => m.retry !== undefined);
2637
2669
  const phase1 = members.filter((m) => m.phase === 1);
2638
2670
  const phase2 = members.filter((m) => m.phase === 2);
2671
+ const familyOfOrder = members.map((m) => m.family);
2672
+ const viewKeyOf = (m) => {
2673
+ switch (m.view) {
2674
+ case "all": return undefined;
2675
+ case "other-families": return m.family;
2676
+ }
2677
+ };
2639
2678
  const laneOf = (scope) => {
2640
2679
  const inScope = (m) => {
2641
2680
  switch (scope) {
@@ -2643,7 +2682,9 @@ const armPool = (() => {
2643
2682
  case "bounded-unit": return !m.lexical;
2644
2683
  }
2645
2684
  };
2646
- return { phase1: phase1.filter(inScope), phase2: phase2.filter(inScope), retry: retryMembers.filter(inScope) };
2685
+ const lanePhase2 = phase2.filter(inScope);
2686
+ const viewKeys = [...new Set(lanePhase2.map(viewKeyOf))];
2687
+ return { phase1: phase1.filter(inScope), phase2: lanePhase2, retry: retryMembers.filter(inScope), viewKeys, viewOf: lanePhase2.map((m) => viewKeys.indexOf(viewKeyOf(m))) };
2647
2688
  };
2648
2689
  const LANES = {
2649
2690
  "free-text": laneOf("free-text"),
@@ -2694,18 +2735,22 @@ const armPool = (() => {
2694
2735
  m.collect(text, json, eat, spans, isHead);
2695
2736
  closeCoveragePositions(0);
2696
2737
  if (lane.phase2.length > 0) {
2697
- const scan = buildForensicScan(credentialSpans(text), lane.phase2.length);
2738
+ const tokens = credentialSpans(text);
2739
+ const scan = buildForensicScan(tokens, lane.phase2.length);
2698
2740
  const reuse = forensicRescanMode === "incremental";
2699
2741
  const foot = scan.armFoot;
2742
+ const views = lane.viewKeys.map((key) => ({ key, table: tokens, dirty: undefined }));
2700
2743
  let folded = 0;
2701
2744
  for (let level = 0;; level += 1) {
2702
2745
  const before = spans.length;
2703
2746
  for (let j = 0; j < lane.phase2.length; j++) {
2704
- const dirty = scan.dirty;
2747
+ const view = views[lane.viewOf[j]];
2748
+ const dirty = view.dirty;
2705
2749
  if (dirty !== undefined && footprintClean(dirty, foot[2 * j], foot[2 * j + 1])) {
2706
2750
  forensicSkips += 1;
2707
2751
  continue;
2708
2752
  }
2753
+ useEvidenceView(scan, view.table, dirty);
2709
2754
  scan.footLo = FOOT_NONE;
2710
2755
  scan.footHi = -1;
2711
2756
  lane.phase2[j].collect(scan, text, json, level === 0 ? eat : undefined, spans, isHead);
@@ -2715,11 +2760,18 @@ const armPool = (() => {
2715
2760
  }
2716
2761
  closeCoveragePositions(before);
2717
2762
  forensicLevels += 1;
2718
- const grown = foldCredentialSpans(scan.table, spans, folded);
2763
+ let grew = false;
2764
+ for (const view of views) {
2765
+ const key = view.key;
2766
+ const grown = foldCredentialSpans(view.table, spans, folded, key === undefined ? undefined : (sp) => familyOfOrder[sp.order] !== key);
2767
+ if (grown.dirty.starts.length > 0)
2768
+ grew = true;
2769
+ view.table = grown.next;
2770
+ view.dirty = reuse ? grown.dirty : undefined;
2771
+ }
2719
2772
  folded = spans.length;
2720
- if (grown.dirty.starts.length === 0)
2773
+ if (!grew)
2721
2774
  break;
2722
- advanceEvidence(scan, grown.next, reuse ? grown.dirty : undefined);
2723
2775
  }
2724
2776
  }
2725
2777
  poolSpanCount += spans.length;
@@ -129,6 +129,10 @@ export declare const SELF_MINTED_WIRE: {
129
129
  readonly attr: 409;
130
130
  readonly since: "7.108.0";
131
131
  };
132
+ readonly "memory.erasure_store_unjudged": {
133
+ readonly attr: 409;
134
+ readonly since: "7.140.0";
135
+ };
132
136
  readonly "internal.memory_control_plane_corrupt": {
133
137
  readonly attr: 500;
134
138
  readonly since: "7.108.0";
@@ -1290,6 +1294,51 @@ export declare const SELF_MINTED_WIRE: {
1290
1294
  readonly attr: 200;
1291
1295
  readonly since: "7.139.0";
1292
1296
  };
1297
+ readonly "GET /v1/memory/entries/:entryId/provenance|POST /v1/memory/erase|GET /v1/memory/origin/clearances|POST /v1/memory/origin/entries/:entryId/clear#layer_unaddressed_two_stores(\u4E0D\u70B9\u540D\u5C42\u7684\u6761\u76EE id / \u5E97\u7EA7\u8D26\u672C\u8BF7\u6C42,\u672C\u90E8\u7F72\u70B9\u540D\u7684\u5C42\u5206\u4F4F\u4E24\u53EA\u5E97;\u4F53 request.memory_layer)": {
1298
+ readonly attr: 400;
1299
+ readonly since: "7.140.0";
1300
+ };
1301
+ readonly "POST /v1/memory/erase|POST /v1/sessions/:id/memory/erase#erasure_store_unjudged(\u62B9\u9664\u843D\u5230\u90E8\u7F72\u7684\u5E97\u4E4B\u5916\u7684\u90A3\u53EA\u5E97:\u70B9\u540D\u7684\u5C42\u4F4F\u5728\u4E2A\u4EBA\u6302\u8F7D\u4E0A,\u6216\u6309\u4F1A\u8BDD\u62B9\u9664\u800C\u8FD9\u53EA\u4F1A\u8BDD\u5728\u53E6\u4E00\u53EA\u5E97\u6709\u8D21\u732E / \u90A3\u53EA\u5E97\u7684\u8D26\u8BFB\u4E0D\u51FA;\u4F53 memory.erasure_store_unjudged,\u4EC0\u4E48\u90FD\u6CA1\u5220)": {
1302
+ readonly attr: 409;
1303
+ readonly since: "7.140.0";
1304
+ };
1305
+ readonly "POST /v1/memory/export|POST /v1/memory/import|GET /v1/memory/origin/external|POST /v1/memory/erase#layers_span_two_stores(\u8BF7\u6C42\u70B9\u540D\u7684\u5C42\u5206\u4F4F\u4E24\u53EA\u5E97;\u4F53 request.memory_layer)": {
1306
+ readonly attr: 400;
1307
+ readonly since: "7.140.0";
1308
+ };
1309
+ readonly "\u8BB0\u5FC6\u8BF8\u53E3 + POST /v1/admin/memory/consolidation/run|GET /v1/admin/memory/consolidation|GET /v1/memory/export|POST /v1/memory/sync/:scope#layer_unreadable(\u8BF7\u6C42\u70B9\u540D\u7684\u5C42\u5F15\u64CE\u8BFB\u4E0D\u51FA;\u4F53 request.memory_layer)": {
1310
+ readonly attr: 400;
1311
+ readonly since: "7.140.0";
1312
+ };
1313
+ };
1314
+ };
1315
+ /**
1316
+ * 记忆动词的**层座**(`<端点>#<查询串 | 体>.scope` → 读法):不点名层的动词(条目 id / 会话 id / 店级账本)多一个可选的 `scope`,只用来定店;唯一读法 =
1317
+ * `http/memory-layer-reply.ts` 的 `readLayerSeat`(在场而不是非空串 ⇒ 400、面不调)。只登本版新增的座。
1318
+ */
1319
+ readonly memoryLayerSeatKey: {
1320
+ readonly at: "记忆动词的层座(<端点>#<query | body>.scope → 读法;只登本版新增的)";
1321
+ readonly members: {
1322
+ readonly "GET /v1/memory/entries/:entryId/provenance#query.scope": {
1323
+ readonly attr: "optional;non-empty-string else 400 request.field_invalid;names the layer whose store answers";
1324
+ readonly since: "7.140.0";
1325
+ };
1326
+ readonly "GET /v1/memory/origin/clearances#query.scope": {
1327
+ readonly attr: "optional;non-empty-string else 400 request.field_invalid;names the layer whose store answers";
1328
+ readonly since: "7.140.0";
1329
+ };
1330
+ readonly "POST /v1/memory/origin/entries/:entryId/clear#body.scope": {
1331
+ readonly attr: "optional;non-empty-string else 400 request.field_invalid;names the layer whose store answers;not passed to the engine";
1332
+ readonly since: "7.140.0";
1333
+ };
1334
+ readonly "GET /v1/sessions/:id/memory-status#query.scope": {
1335
+ readonly attr: "optional;non-empty-string else 400 request.field_invalid;names the layer whose store answers;absent ⇒ every store of this deployment, folded;cache keyed by (session, store control plane)";
1336
+ readonly since: "7.140.0";
1337
+ };
1338
+ readonly "POST /v1/sessions/:id/memory/erase#body.scope": {
1339
+ readonly attr: "optional;non-empty-string else 400 request.field_invalid;names the layer whose store answers;absent ⇒ the deployment's store;selector still minted from the path";
1340
+ readonly since: "7.140.0";
1341
+ };
1293
1342
  };
1294
1343
  };
1295
1344
  /**
@@ -1766,6 +1815,15 @@ export declare const SELF_MINTED_WIRE: {
1766
1815
  readonly attr: "names-engine-notice:model.capability_downgraded";
1767
1816
  readonly since: "7.137.0";
1768
1817
  };
1818
+ /**
1819
+ * 7.140.0:会话记忆状态不带层座 ⇒ 本部署每一只店的引擎答案按一条折叠律合成一份(`memory-operator-faces.ts` `foldPlaneStatuses`;契约 §9 开头):
1820
+ * 计数相加 / 最近一次取大 / 任一店有采集记录即 true / 任一店读不出 ⇒ 那一键缺席。一只店 ⇒ 恒等(单店部署字节同上一版)。
1821
+ * 钉 test/memory-operator-faces.test.ts「逐店折叠律」、test/memory-layer-seat-http.test.ts「会话记忆状态不带层座」。
1822
+ */
1823
+ readonly "GET /v1/sessions/:id/memory-status#committedCount|foldedCount|lastCaptureAt|captureOptedOut|optOutSource(\u4E0D\u5E26\u5C42\u5EA7)": {
1824
+ readonly attr: "fold-across-deployment-stores(sum|max|any-record|absent-if-any-unreadable);one-store⇒identity";
1825
+ readonly since: "7.140.0";
1826
+ };
1769
1827
  };
1770
1828
  };
1771
1829
  };
@@ -45,6 +45,7 @@ export const SELF_MINTED_WIRE = {
45
45
  "memory.erasure_evidence_unavailable": { attr: 409, since: "7.108.0" },
46
46
  "memory.erasure_selector_mismatch": { attr: 409, since: "7.108.0" },
47
47
  "memory.erasure_census_incomplete": { attr: 409, since: "7.108.0" },
48
+ "memory.erasure_store_unjudged": { attr: 409, since: "7.140.0" },
48
49
  "internal.memory_control_plane_corrupt": { attr: 500, since: "7.108.0" },
49
50
  },
50
51
  },
@@ -460,6 +461,20 @@ export const SELF_MINTED_WIRE = {
460
461
  "PATCH /v1/sessions/:id#owner_changed_after_gate(门那一读之后同一会话的属主被改;体 not_found.session)": { attr: 404, since: "7.139.0" },
461
462
  "PATCH /v1/sessions/:id#expectedRowTag_stale(行已不在那只标签上;体 conflict.session_row_changed + currentRow)": { attr: 409, since: "7.139.0" },
462
463
  "PATCH /v1/sessions/:id#expectedRowTag_current(行仍在那只标签上;体 = 列表行)": { attr: 200, since: "7.139.0" },
464
+ "GET /v1/memory/entries/:entryId/provenance|POST /v1/memory/erase|GET /v1/memory/origin/clearances|POST /v1/memory/origin/entries/:entryId/clear#layer_unaddressed_two_stores(不点名层的条目 id / 店级账本请求,本部署点名的层分住两只店;体 request.memory_layer)": { attr: 400, since: "7.140.0" },
465
+ "POST /v1/memory/erase|POST /v1/sessions/:id/memory/erase#erasure_store_unjudged(抹除落到部署的店之外的那只店:点名的层住在个人挂载上,或按会话抹除而这只会话在另一只店有贡献 / 那只店的账读不出;体 memory.erasure_store_unjudged,什么都没删)": { attr: 409, since: "7.140.0" },
466
+ "POST /v1/memory/export|POST /v1/memory/import|GET /v1/memory/origin/external|POST /v1/memory/erase#layers_span_two_stores(请求点名的层分住两只店;体 request.memory_layer)": { attr: 400, since: "7.140.0" },
467
+ "记忆诸口 + POST /v1/admin/memory/consolidation/run|GET /v1/admin/memory/consolidation|GET /v1/memory/export|POST /v1/memory/sync/:scope#layer_unreadable(请求点名的层引擎读不出;体 request.memory_layer)": { attr: 400, since: "7.140.0" },
468
+ },
469
+ },
470
+ memoryLayerSeatKey: {
471
+ at: "记忆动词的层座(<端点>#<query | body>.scope → 读法;只登本版新增的)",
472
+ members: {
473
+ "GET /v1/memory/entries/:entryId/provenance#query.scope": { attr: "optional;non-empty-string else 400 request.field_invalid;names the layer whose store answers", since: "7.140.0" },
474
+ "GET /v1/memory/origin/clearances#query.scope": { attr: "optional;non-empty-string else 400 request.field_invalid;names the layer whose store answers", since: "7.140.0" },
475
+ "POST /v1/memory/origin/entries/:entryId/clear#body.scope": { attr: "optional;non-empty-string else 400 request.field_invalid;names the layer whose store answers;not passed to the engine", since: "7.140.0" },
476
+ "GET /v1/sessions/:id/memory-status#query.scope": { attr: "optional;non-empty-string else 400 request.field_invalid;names the layer whose store answers;absent ⇒ every store of this deployment, folded;cache keyed by (session, store control plane)", since: "7.140.0" },
477
+ "POST /v1/sessions/:id/memory/erase#body.scope": { attr: "optional;non-empty-string else 400 request.field_invalid;names the layer whose store answers;absent ⇒ the deployment's store;selector still minted from the path", since: "7.140.0" },
463
478
  },
464
479
  },
465
480
  refusalSentenceForm: {
@@ -595,6 +610,7 @@ export const SELF_MINTED_WIRE = {
595
610
  "GET /v1/config/catalog#rows[MODEL_VISION].semantics": { attr: "names-engine-notice:model.capability_downgraded", since: "7.137.0" },
596
611
  "GET /v1/config/catalog#rows[MODEL_VISION].derivedDefaultNote": { attr: "names-engine-notice:model.capability_downgraded", since: "7.137.0" },
597
612
  "GET /v1/config/catalog#rows[MODEL_CHEAP_VISION].semantics": { attr: "names-engine-notice:model.capability_downgraded", since: "7.137.0" },
613
+ "GET /v1/sessions/:id/memory-status#committedCount|foldedCount|lastCaptureAt|captureOptedOut|optOutSource(不带层座)": { attr: "fold-across-deployment-stores(sum|max|any-record|absent-if-any-unreadable);one-store⇒identity", since: "7.140.0" },
598
614
  },
599
615
  },
600
616
  };
@@ -1,10 +1,12 @@
1
1
  /**
2
2
  * 配置候选的**唯一判官**:一份候选(中心有效视图,或本地 `config.d` 读出的那份)能不能收 —— 只有这一种判法。
3
3
  *
4
- * 判据(三件,任一即拒;每条拒因带成因词,闭集 {@link CandidateRejectReason}):读腿交出的 `domainErrors`(某个域读不懂 / 拼错键 / 坏文件:那个域已落
4
+ * 判据(三件,任一即拒;每条拒因带成因词,闭集 {@link CandidateRejectReason}):读腿交出的 `domainErrors`(某个域判形失败 / 拼错键 / 悬空引用:那个域已落
5
5
  * schema 缺省)与 prompts 面的判官(`judgePromptsWire`:契约包的 wire 形再交引擎 verify —— 中心层只有一种形)—— 成因 `domain_invalid`;读腿交出的
6
- * `retiredDomains`(带事实的退役域文档,契约包的墓碑;拒句点名退役版本与一次性迁移)—— 成因 `retired_domain`。任一 ⇒ `rejected`:
7
- * **整份候选不收**,一个域都不应用。退役域此前在读腿整包抛、走「源不可达」那条臂(版本读不到、没有拒判行、刷新拍算失败);现在读腿只交数据,
6
+ * `refusedDocuments`(读它的域之前契约就拒了的那份文档 —— 契约的类型 `ConfigDocumentRefusal`:带事实的退役域 = 墓碑,或 `config.d` 里契约的文件层拒的一份 ——
7
+ * 空 / 坏 JSON / 不是对象 / 读失败)—— 成因就是那份发现自带的词(契约闭集 `CONFIG_DOCUMENT_REFUSAL_REASONS`),拒行的 `domain` 是它的 `document`。
8
+ * 任一 ⇒ `rejected`:**整份候选不收**,一个域都不应用。
9
+ * 被拒文档此前要么在读腿整包抛、走「源不可达」那条臂(墓碑;门控域的坏文件),要么被读成「域按缺省落 + 域诊断」(目录域的坏文件);现在读腿只交数据,
8
10
  * 坏候选只有本判官一种判法。
9
11
  * 读腿的逐条丢弃(`droppedEntries`)不在这里 —— 颗粒是条目的失效留在条目上,候选照收(调用方响亮点名)。
10
12
  *
@@ -27,23 +29,25 @@
27
29
  * (盘上 LKG 的读回复判也经本判官,`config-lkg.ts`)。
28
30
  */
29
31
  import type { PublishedPromptArtifact } from "@sema-agent/core";
32
+ import type { ConfigDocumentRefusal, ConfigDocumentRefusalReason } from "@sema-agent/settings-schema";
30
33
  import type { EffectiveConfig } from "./types.js";
31
34
  /** 读腿交出的一条域级诊断(与 `FetchEffectiveResult.domainErrors` 同形;error 文案已在产出边界脱敏)。 */
32
35
  export interface CandidateDomainError {
33
36
  readonly domain: string;
34
37
  readonly error: string;
35
38
  }
36
- /** 判官拒一份候选的成因(闭集):某个域判形失败(含 prompts 面)/ 带事实的退役域文档(墓碑)。 */
37
- export type CandidateRejectReason = "domain_invalid" | "retired_domain";
39
+ /** 判官拒一份候选的成因(闭集):某个域判形失败(含 prompts 面)`domain_invalid` ∪ 被拒文档自带的词(契约闭集 `CONFIG_DOCUMENT_REFUSAL_REASONS`:
40
+ * `empty` / `invalid_json` / `not_object` / `io` 文件层,`retired_domain` 墓碑)—— 被拒文档的词表只在契约一处定义,这里派生(契约加词 ⇒ 按词穷举的读者编译红)。 */
41
+ export type CandidateRejectReason = "domain_invalid" | ConfigDocumentRefusalReason;
38
42
  /** 拒判里的一条:哪一域、为什么(读腿 / 契约包的原句)、成因词。`config_candidate_rejected` 行的 `errors` 就是这一列。 */
39
43
  export interface CandidateDomainRejection extends CandidateDomainError {
40
44
  readonly reason: CandidateRejectReason;
41
45
  }
42
- /** 判官的输入:一份读出来的候选。`retiredDomains` = 读腿交出的退役域发现(两条读腿同形,见 `read-warnings.ts` 的 `RetiredDomainFinding`)。 */
46
+ /** 判官的输入:一份读出来的候选。`refusedDocuments` = 读腿交出的被拒文档(两条读腿同形,契约的类型 `ConfigDocumentRefusal`;判官只读文档名、拒句与成因词)。 */
43
47
  export interface ConfigCandidateRead {
44
48
  readonly effective: EffectiveConfig;
45
49
  readonly domainErrors?: readonly CandidateDomainError[];
46
- readonly retiredDomains?: readonly CandidateDomainError[];
50
+ readonly refusedDocuments?: readonly Pick<ConfigDocumentRefusal, "document" | "error" | "reason">[];
47
51
  }
48
52
  export type ConfigCandidateVerdict =
49
53
  /** `prompts` = 候选的中心层(引擎 verify 过的发布形 artifact;候选不带 prompts 键 ⇒ `undefined` = 撤下中心层、内置提示词服务)。 */
@@ -5,7 +5,7 @@ export function judgeConfigCandidate(r) {
5
5
  const errors = [
6
6
  ...(r.domainErrors ?? []).map((de) => ({ domain: de.domain, error: de.error, reason: "domain_invalid" })),
7
7
  ...(promptsGate !== undefined && !promptsGate.ok ? [{ domain: "prompts", error: promptsGate.error, reason: "domain_invalid" }] : []),
8
- ...(r.retiredDomains ?? []).map((rd) => ({ domain: rd.domain, error: rd.error, reason: "retired_domain" })),
8
+ ...(r.refusedDocuments ?? []).map((d) => ({ domain: d.document, error: d.error, reason: d.reason })),
9
9
  ];
10
10
  if (errors.length === 0)
11
11
  return { verdict: "clean", prompts: promptsGate?.ok ? promptsGate.artifact : undefined };
@@ -1,11 +1,12 @@
1
- import { type EffectiveReadWarning, type EntitlementRuntimeCaps } from "@sema-agent/settings-schema";
1
+ import { type ConfigDocumentRefusal, type EffectiveReadWarning, type EntitlementRuntimeCaps } from "@sema-agent/settings-schema";
2
2
  import type { ScenarioRuling } from "../capabilities/scenarios.js";
3
3
  import type { EffectiveConfig, ExecutionRuling } from "./types.js";
4
- import { type DroppedConfigEntry, type RetiredDomainFinding, type UnreadConfigFile } from "./read-warnings.js";
4
+ import { type DroppedConfigEntry, type UnreadConfigFile } from "./read-warnings.js";
5
5
  import { type CenterEndpoint } from "./center-request.js";
6
6
  /** GET the effective config (Bearer + ETag). null = 304 (unchanged). Throws on transport/HTTP error, and on a
7
7
  * payload that is not an effective config at all(非对象 / version 非有限数 / gate 域坏形——[ref] 裁B)。
8
- * `retiredDomains`([ref]):wire 上带事实的退役域(墓碑)不抛 —— 交成发现、那一键不进 effective,候选判官整拒这份候选(与本地腿同键同义)。
8
+ * `refusedDocuments`:被拒文档(契约类型 `ConfigDocumentRefusal`,与本地腿同键同义;wire 上只有一种 —— 带事实的退役域,墓碑,成因词 `retired_domain`)不抛 —— 交成发现、那一键不进 effective,
9
+ * 候选判官整拒这份候选。
9
10
  * `domainErrors`:坏 catalog 域(schema default 已落)逐域单列——与本地腿 `FetchEffectiveResult` 同键同义,
10
11
  * boot/refresh 的候选门直接消费。`droppedEntries`([ref] ②):schema 逐条丢掉的条目(坐标 + 字段诊断)——
11
12
  * **不**进候选门,调用方响亮点名、其余照用(分面单点 `splitFoldedReadWarnings`,与本地腿同一只)。
@@ -25,7 +26,7 @@ export declare function fetchEffective(center: CenterEndpoint, etag: string | un
25
26
  }>;
26
27
  droppedEntries?: DroppedConfigEntry[];
27
28
  unreadFiles?: UnreadConfigFile[];
28
- retiredDomains?: RetiredDomainFinding[];
29
+ refusedDocuments?: ConfigDocumentRefusal[];
29
30
  readWarnings: readonly EffectiveReadWarning[];
30
31
  credentialIdentity: string;
31
32
  } | null>;
@@ -10,7 +10,7 @@ export async function fetchEffective(center, etag, fetchImpl, worker) {
10
10
  if (!res.ok)
11
11
  throw new Error(`web-admin HTTP ${res.status}`);
12
12
  const warnings = [];
13
- const { body, retiredDomains } = separateRetiredDomains(await res.json());
13
+ const { body, refusedDocuments } = separateRetiredDomains(await res.json());
14
14
  const wire = readEffectiveWire(body, (w) => warnings.push(w));
15
15
  const { domainErrors, droppedEntries, droppedCatalogEntries, unreadFiles } = splitFoldedReadWarnings(warnings, "center");
16
16
  const effective = withDroppedCatalogEntries(wire, droppedCatalogEntries);
@@ -22,7 +22,7 @@ export async function fetchEffective(center, etag, fetchImpl, worker) {
22
22
  ...(domainErrors.length > 0 ? { domainErrors } : {}),
23
23
  ...(droppedEntries.length > 0 ? { droppedEntries } : {}),
24
24
  ...(unreadFiles.length > 0 ? { unreadFiles } : {}),
25
- ...(retiredDomains.length > 0 ? { retiredDomains: [...retiredDomains] } : {}),
25
+ ...(refusedDocuments.length > 0 ? { refusedDocuments: [...refusedDocuments] } : {}),
26
26
  };
27
27
  }
28
28
  export async function fetchPrincipalCaps(center, principal, etag, fetchImpl, worker) {
@@ -25,29 +25,19 @@
25
25
  * 留在条目上,只有颗粒更粗的失效才动候选。
26
26
  */
27
27
  import { z } from "zod";
28
- import { type DroppedEntryIdentity, type DroppedEntryReasonCode, type EffectiveReadWarning, type RetiredDomainName } from "@sema-agent/settings-schema";
29
- /**
30
- * 退役域的一条**发现**(两条读腿同形)。读腿只把契约包的墓碑(`RetiredDomainError`)换成数据交出去 —— 判决只在候选判官
31
- * (`candidate-gate.ts` 的 `judgeConfigCandidate`,成因 `retired_domain`):与域判形失败同一条回落链(候选 → 盘上 LKG → env)、同一行
32
- * `config_candidate_rejected`、刷新拍同形(拍跑完,候选被判拒是结论)。拉取层的抛只剩 I/O 与载荷形(不是一份 effective)两种。
33
- * `error` = 契约包铸的整句(墓碑表那一行:退役版本、事实今天住哪、一次性迁移 id)—— 模板句,不含任何配置值,所以不过 `redactConfigError`
34
- * (那道脱敏把引号段换成指纹,会把句中点名的域名换掉)。
35
- */
36
- export type RetiredDomainFinding = {
37
- readonly domain: RetiredDomainName;
38
- readonly error: string;
39
- readonly migration: string;
40
- };
41
- /** 墓碑 → 发现;不是墓碑 ⇒ `undefined`(调用方照原样抛)。两条读腿的唯一换装点。 */
42
- export declare function retiredDomainFindingOf(e: unknown): RetiredDomainFinding | undefined;
28
+ import { type ConfigDocumentRefusal, type DroppedEntryIdentity, type DroppedEntryReasonCode, type EffectiveReadWarning } from "@sema-agent/settings-schema";
43
29
  /**
44
30
  * 远端读腿在过契约读腿(`readEffectiveWire`)**之前**把退役域键分出去:wire 体上每个退役域键过契约的同一只墓碑(`refuseRetiredDomain`)——
45
- * 带事实 ⇒ 一条发现、这一键从体上拿掉(其余域照读、版本照读,判官整拒这份候选);缺席 / `{}` ⇒ 不理会(契约读腿自己丢 `{}`)。
31
+ * 带事实 ⇒ 一份被拒文档(契约的类型 `ConfigDocumentRefusal` 的墓碑臂:`document` = 退役域名,`reason: "retired_domain"`,`error` / `migration` 取
32
+ * `RetiredDomainError` 的同名字段)、这一键从体上拿掉(其余域照读、版本照读,判官整拒这份候选);缺席 / `{}` ⇒ 不理会(契约读腿自己丢 `{}`)。
46
33
  * 体不是对象 ⇒ 原样交回、不判(载荷形错,契约读腿抛)。墓碑判据只在契约包,这里只分键。
34
+ * 被拒文档是两条读腿同形的发现(判决只在候选判官 `candidate-gate.ts` 的 `judgeConfigCandidate`,成因词 = 发现自带的 `reason`):本地腿的被拒文档是契约整目录拒单
35
+ * `inspectBundle` 的原样(`config-provider.ts`),wire 上没有文件层,只有这一种墓碑。`error` 本模块不脱敏(与折叠产物同律):各腿在自己的产出边界上过
36
+ * `redactSecrets` 兜底、不过 `redactConfigError`(句子不含配置值;引号段读法会把句中点名的域名换成指纹)。
47
37
  */
48
38
  export declare function separateRetiredDomains(body: unknown): {
49
39
  readonly body: unknown;
50
- readonly retiredDomains: readonly RetiredDomainFinding[];
40
+ readonly refusedDocuments: readonly ConfigDocumentRefusal[];
51
41
  };
52
42
  /** 折叠产物:`scope` 决定消费方做什么 —— `"domain"` 进候选门(`domainErrors`),`"entry"` 进逐条丢弃面(`droppedEntries`),
53
43
  * `"unread"` 进读腿不读的文件面(`unreadFiles`;点名不判拒)。 */
@@ -1,26 +1,22 @@
1
1
  import { z } from "zod";
2
2
  import { DROPPED_ENTRY_REASON_CODES, ModelRole, RETIRED_DOMAINS, RetiredDomainError, formatConfigPath, isDisclosableIdentity, isRetiredDomainName, refuseRetiredDomain, renderQuotedSentence, } from "@sema-agent/settings-schema";
3
- export function retiredDomainFindingOf(e) {
4
- return e instanceof RetiredDomainError ? { domain: e.domain, error: e.message, migration: e.migration } : undefined;
5
- }
6
3
  export function separateRetiredDomains(body) {
7
4
  if (body === null || typeof body !== "object" || Array.isArray(body))
8
- return { body, retiredDomains: [] };
9
- const findings = [];
5
+ return { body, refusedDocuments: [] };
6
+ const refused = [];
10
7
  const rest = { ...body };
11
8
  for (const domain of Object.keys(RETIRED_DOMAINS).filter(isRetiredDomainName)) {
12
9
  try {
13
10
  refuseRetiredDomain(domain, rest[domain]);
14
11
  }
15
12
  catch (e) {
16
- const finding = retiredDomainFindingOf(e);
17
- if (finding === undefined)
13
+ if (!(e instanceof RetiredDomainError))
18
14
  throw e;
19
- findings.push(finding);
15
+ refused.push({ document: e.domain, reason: "retired_domain", error: e.message, migration: e.migration });
20
16
  delete rest[domain];
21
17
  }
22
18
  }
23
- return findings.length === 0 ? { body, retiredDomains: [] } : { body: rest, retiredDomains: findings };
19
+ return refused.length === 0 ? { body, refusedDocuments: [] } : { body: rest, refusedDocuments: refused };
24
20
  }
25
21
  export function buildUnreadConfigKeyFields(k, dir) {
26
22
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/server",
3
- "version": "7.139.0",
3
+ "version": "7.140.0",
4
4
  "description": "Sema Server — the server/API implementation layer for Sema, wiring core, registry, model providers, and cloud agent execution. Built on @sema-agent/core.",
5
5
  "type": "module",
6
6
  "license": "BUSL-1.1",
@@ -70,7 +70,7 @@
70
70
  },
71
71
  "dependencies": {
72
72
  "@sema-agent/core": "7.60.0",
73
- "@sema-agent/settings-schema": "15.1.0",
73
+ "@sema-agent/settings-schema": "15.2.0",
74
74
  "e2b": "^2.28.0",
75
75
  "libsodium-wrappers": "^0.8.4",
76
76
  "mysql2": "^3.22.4",