@sema-agent/core 5.57.0 → 5.59.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 (192) hide show
  1. package/CHANGELOG.md +96 -0
  2. package/dist/agents/cascade.d.ts +1 -1
  3. package/dist/agents/cumulative-stats.d.ts +1 -1
  4. package/dist/agents/observer.d.ts +2 -2
  5. package/dist/agents/peer-admission.d.ts +1 -1
  6. package/dist/agents/retain-ledger.d.ts +2 -2
  7. package/dist/agents/roster-store.d.ts +8 -8
  8. package/dist/agents/send-message-tool.d.ts +2 -2
  9. package/dist/agents/subagent-steps.d.ts +1 -1
  10. package/dist/agents/subagent.d.ts +13 -13
  11. package/dist/agents/team.d.ts +5 -5
  12. package/dist/agents/tool-filter.d.ts +2 -2
  13. package/dist/agents/verify.d.ts +1 -1
  14. package/dist/bench/metrics.d.ts +35 -35
  15. package/dist/brain/degrading.d.ts +1 -1
  16. package/dist/brain/errors.d.ts +3 -3
  17. package/dist/brain/reasoning.d.ts +2 -2
  18. package/dist/brain/repetition.d.ts +1 -1
  19. package/dist/brain/route-adjudicator.d.ts +8 -1
  20. package/dist/brain/route-adjudicator.js +8 -1
  21. package/dist/brain/status-sink.d.ts +2 -2
  22. package/dist/brain/stream-shared.d.ts +1 -1
  23. package/dist/config/catalog.d.ts +5 -5
  24. package/dist/core/arg-summary.d.ts +4 -4
  25. package/dist/core/ask-class.d.ts +2 -2
  26. package/dist/core/ask-question.d.ts +1 -1
  27. package/dist/core/auto-compaction.d.ts +15 -15
  28. package/dist/core/auto-mode.d.ts +5 -5
  29. package/dist/core/background-agent-store.d.ts +20 -20
  30. package/dist/core/background-shell.d.ts +4 -4
  31. package/dist/core/checkpoint-store.d.ts +35 -27
  32. package/dist/core/context-edit.d.ts +1 -1
  33. package/dist/core/context-guard.d.ts +1 -1
  34. package/dist/core/exec-output-tail.d.ts +6 -6
  35. package/dist/core/file-snapshot-store.d.ts +8 -8
  36. package/dist/core/git-worktree-env.d.ts +3 -3
  37. package/dist/core/governance-codes.d.ts +37 -10
  38. package/dist/core/governance-codes.js +54 -1
  39. package/dist/core/hooks.d.ts +73 -33
  40. package/dist/core/hooks.js +87 -25
  41. package/dist/core/image-downsample.d.ts +1 -1
  42. package/dist/core/locked-config.d.ts +1 -1
  43. package/dist/core/lsp.d.ts +1 -1
  44. package/dist/core/mailbox-store.d.ts +1 -1
  45. package/dist/core/mcp.d.ts +3 -3
  46. package/dist/core/memory-engine/consolidation-driver.d.ts +211 -0
  47. package/dist/core/memory-engine/consolidation-driver.js +427 -0
  48. package/dist/core/memory-engine/consolidation.d.ts +119 -3
  49. package/dist/core/memory-engine/consolidation.js +22 -1
  50. package/dist/core/memory-engine/data-plane.d.ts +1 -1
  51. package/dist/core/memory-engine/distiller.d.ts +550 -0
  52. package/dist/core/memory-engine/distiller.js +598 -0
  53. package/dist/core/memory-engine/dual-root.d.ts +1 -1
  54. package/dist/core/memory-engine/engine.d.ts +143 -10
  55. package/dist/core/memory-engine/engine.js +149 -23
  56. package/dist/core/memory-engine/file-backend.d.ts +14 -2
  57. package/dist/core/memory-engine/file-backend.js +3 -0
  58. package/dist/core/memory-engine/index.d.ts +6 -3
  59. package/dist/core/memory-engine/index.js +4 -2
  60. package/dist/core/memory-engine/layout.js +20 -6
  61. package/dist/core/memory-engine/origin-clearance.d.ts +1 -1
  62. package/dist/core/memory-engine/scope-contract.d.ts +4 -4
  63. package/dist/core/memory-engine/sync-client.d.ts +16 -16
  64. package/dist/core/memory-engine/sync.d.ts +4 -4
  65. package/dist/core/memory-engine/types.d.ts +17 -0
  66. package/dist/core/memory-recall.d.ts +1 -1
  67. package/dist/core/memory.d.ts +2 -2
  68. package/dist/core/permission-rule-consent.d.ts +185 -36
  69. package/dist/core/permission-rule-consent.js +219 -44
  70. package/dist/core/permission-rule-model.d.ts +235 -31
  71. package/dist/core/permission-rule-model.js +105 -35
  72. package/dist/core/permission-rules.d.ts +9 -9
  73. package/dist/core/remote-env.d.ts +8 -8
  74. package/dist/core/roles.d.ts +3 -3
  75. package/dist/core/roles.js +1 -0
  76. package/dist/core/runner/assemble-result.d.ts +2 -2
  77. package/dist/core/runner/compaction-call-options.d.ts +3 -3
  78. package/dist/core/runner/memory-consolidation-driver.d.ts +49 -0
  79. package/dist/core/runner/memory-consolidation-driver.js +60 -0
  80. package/dist/core/runner/memory-consolidation.d.ts +1 -1
  81. package/dist/core/runner/prepare-config-doors.d.ts +3 -3
  82. package/dist/core/runner/prepare-task.d.ts +21 -21
  83. package/dist/core/runner/prepare-task.js +24 -17
  84. package/dist/core/runner/prepare-workspace-restore.d.ts +2 -2
  85. package/dist/core/runner/runtask.d.ts +11 -11
  86. package/dist/core/runner/runtask.js +4 -4
  87. package/dist/core/runner/session-rule-policy.d.ts +1 -1
  88. package/dist/core/runner/teardown-bounded.d.ts +1 -1
  89. package/dist/core/runner/tool-disclosure.d.ts +2 -2
  90. package/dist/core/runner/turn-attachments.d.ts +11 -11
  91. package/dist/core/scheduler.d.ts +5 -5
  92. package/dist/core/secret-env.d.ts +1 -1
  93. package/dist/core/sensitive-path-policy.d.ts +1 -1
  94. package/dist/core/session-policy-store.d.ts +2 -2
  95. package/dist/core/session-reconcile.d.ts +2 -2
  96. package/dist/core/session-store.d.ts +3 -3
  97. package/dist/core/session.d.ts +1 -1
  98. package/dist/core/shutdown-debug.d.ts +2 -2
  99. package/dist/core/side-query.d.ts +2 -2
  100. package/dist/core/spec-contract.d.ts +1 -1
  101. package/dist/core/store-contracts/contract-harness.d.ts +2 -2
  102. package/dist/core/store-contracts/contract-kit-version.d.ts +2 -2
  103. package/dist/core/store-contracts/mailbox-store-contract.d.ts +1 -1
  104. package/dist/core/store-contracts/mailbox-store-contract.js +1 -1
  105. package/dist/core/task-notification.d.ts +5 -5
  106. package/dist/core/task-registry-agent.d.ts +12 -12
  107. package/dist/core/task-registry-monitor.d.ts +1 -1
  108. package/dist/core/task-registry-shared.d.ts +41 -41
  109. package/dist/core/task-registry.d.ts +12 -12
  110. package/dist/core/tool-detach.d.ts +2 -2
  111. package/dist/core/tool-errors.d.ts +3 -3
  112. package/dist/core/tool-policy.d.ts +113 -28
  113. package/dist/core/tool-policy.js +80 -1
  114. package/dist/core/tool-result-budget.d.ts +1 -1
  115. package/dist/core/tool-result-store.d.ts +2 -2
  116. package/dist/core/tools.d.ts +1 -1
  117. package/dist/core/trace.d.ts +26 -23
  118. package/dist/core/types.d.ts +164 -86
  119. package/dist/core/types.js +4 -3
  120. package/dist/core/untrusted-egress.d.ts +1 -1
  121. package/dist/core/untrusted-text.d.ts +7 -7
  122. package/dist/core/wiring-manifest.d.ts +5 -5
  123. package/dist/core/workflow-journal-store.d.ts +14 -14
  124. package/dist/core/workflow-run-store-contract.d.ts +1 -1
  125. package/dist/core/workflow-run-store-contract.js +1 -1
  126. package/dist/core/workflow-run-store.d.ts +4 -4
  127. package/dist/engine/compaction/compaction.d.ts +3 -3
  128. package/dist/engine/compaction/utils.d.ts +2 -2
  129. package/dist/engine/execution-env/kill-tree.d.ts +1 -1
  130. package/dist/engine/execution-env/node-execution-env.d.ts +8 -8
  131. package/dist/engine/harness/agent-harness.d.ts +6 -6
  132. package/dist/engine/harness/messages.d.ts +1 -1
  133. package/dist/engine/harness/types.d.ts +10 -10
  134. package/dist/engine/llm/types.d.ts +14 -14
  135. package/dist/engine/loop/agent-loop.d.ts +3 -3
  136. package/dist/engine/loop/types.d.ts +4 -4
  137. package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
  138. package/dist/engine/session/import-validate.d.ts +1 -1
  139. package/dist/engine/session/log-digest.d.ts +1 -1
  140. package/dist/engine/session/memory-repo.d.ts +2 -2
  141. package/dist/engine/session/session.d.ts +4 -4
  142. package/dist/fixtures/index.d.ts +4 -4
  143. package/dist/index.d.ts +6 -5
  144. package/dist/index.js +5 -4
  145. package/dist/orchestration/goal.d.ts +1 -1
  146. package/dist/orchestration/run-spec.d.ts +1 -1
  147. package/dist/orchestration/run-workflow-tool.d.ts +12 -12
  148. package/dist/orchestration/workflow-governance.d.ts +4 -4
  149. package/dist/orchestration/workflow-observe.d.ts +1 -1
  150. package/dist/orchestration/workflow-script-runner.d.ts +1 -1
  151. package/dist/orchestration/workflow-script-store.d.ts +9 -9
  152. package/dist/orchestration/workflow-size-guideline.d.ts +1 -1
  153. package/dist/orchestration/workflow-types.d.ts +5 -5
  154. package/dist/orchestration/workflow.d.ts +10 -10
  155. package/dist/prompt-assembly/artifact-store.d.ts +1 -1
  156. package/dist/prompt-assembly/artifact.d.ts +1 -1
  157. package/dist/prompt-assembly/assemble.d.ts +1 -1
  158. package/dist/prompt-assembly/composer.d.ts +2 -2
  159. package/dist/prompt-assembly/epoch.d.ts +2 -2
  160. package/dist/prompt-assembly/event-registry.d.ts +1 -1
  161. package/dist/prompt-assembly/explain.d.ts +3 -3
  162. package/dist/prompt-assembly/tool-catalog.d.ts +1 -1
  163. package/dist/prompt-assembly/turn-snapshot.d.ts +4 -4
  164. package/dist/prompt-assembly/types.d.ts +12 -12
  165. package/dist/prompts/coordinator.d.ts +1 -1
  166. package/dist/prompts/default.d.ts +8 -8
  167. package/dist/prompts/simple-sections.d.ts +3 -3
  168. package/dist/prompts/supervisor.d.ts +2 -2
  169. package/dist/scenarios/full-body.d.ts +3 -3
  170. package/dist/scenarios/scenario-registry.d.ts +1 -1
  171. package/dist/stores/cc/sidecar-transcript.d.ts +3 -3
  172. package/dist/stores/file/fs-atomic.d.ts +2 -2
  173. package/dist/stores/file/index.d.ts +1 -1
  174. package/dist/stores/file/session-store.d.ts +2 -2
  175. package/dist/stores/file/workflow-journal-store.d.ts +4 -4
  176. package/dist/tools/fs/bash-readonly-classifier.d.ts +1 -1
  177. package/dist/tools/fs/encoding.d.ts +4 -4
  178. package/dist/tools/fs/fs-bash.d.ts +3 -3
  179. package/dist/tools/fs/fs-pdf.d.ts +1 -1
  180. package/dist/tools/fs/fs-shared.d.ts +6 -6
  181. package/dist/tools/fs/index.d.ts +2 -2
  182. package/dist/tools/fs/notebook.d.ts +1 -1
  183. package/dist/tools/fs/pdf.d.ts +1 -1
  184. package/dist/tools/fs/read-deny.d.ts +1 -1
  185. package/dist/tools/fs/safety.d.ts +9 -9
  186. package/dist/tools/fs/search.d.ts +2 -2
  187. package/dist/tools/monitor.d.ts +3 -3
  188. package/dist/tools/task-list.d.ts +2 -2
  189. package/dist/tools/web.d.ts +4 -4
  190. package/dist/tools/worktree.d.ts +5 -5
  191. package/package.json +1 -1
  192. package/test/export-surface.snapshot.json +1826 -3
@@ -91,6 +91,25 @@ export interface MemoryConsolidationOptions {
91
91
  maxDirectedPatchesPerPlan?: number;
92
92
  minRunIntervalMs?: number;
93
93
  minSessionsBetweenRuns?: number;
94
+ /** design/376 C-2② — the scan-refusal fuse's ratio leg, in (0, 1]: scan findings refuse the
95
+ * affected PRODUCT (disclosed beside eligibility drift), and the whole plan refuses only when
96
+ * more than max(1, ⌊ratio × submitted products⌋) of them fail the scan (the floor keeps the
97
+ * per-product tolerance alive on 1-4 product plans — the drive lane's common size) — see
98
+ * {@link scanRefusalCeiling}. Default 0.25. */
99
+ scanRefusalRatioCap?: number;
100
+ /** design/376 C-2② — the fuse's absolute leg (positive integer): the large-batch upper bound on
101
+ * tolerated scan refusals per plan, so the ratio cannot scale the tolerance without limit.
102
+ * Default 8 (the point where the 0.25 ratio hands over at 32 submitted products — the family's
103
+ * "小 N" quantification; below that the ratio leg alone governs). */
104
+ scanRefusalMaxPerPlan?: number;
105
+ /** design/376 C-3 — the EXPLICIT escape hatch for the unconditional instruction-form gate:
106
+ * instruction-form consolidation products (`type: "feedback"` / v2 hint carriers) are refused
107
+ * by default REGARDLESS of the visible set's markers — a clean-set instruction product is the
108
+ * model-reachable privilege route (N ordinary notes in, one instruction entry out). `true` is
109
+ * the only accepted value (a posture declaration, like {@link multiNode}); it opens the
110
+ * CLEAN-set arm only — a marked visible set refuses instruction forms under the laundering
111
+ * hard gate no matter what (privilege and hard gate enter and exit through one door). */
112
+ allowInstructionProducts?: true;
94
113
  /** D-13a — the multi-node POSTURE declaration: present ⇒ `lease` must be injected (constructor
95
114
  * refusal otherwise). Multi-node without declaring is OUT OF CONTRACT (structurally
96
115
  * undetectable — the declaration turns a silent omission into an explicit choice). */
@@ -113,6 +132,8 @@ export declare const CONSOLIDATION_DEFAULTS: {
113
132
  readonly maxDirectedPatchesPerPlan: 32;
114
133
  readonly minRunIntervalMs: number;
115
134
  readonly minSessionsBetweenRuns: 5;
135
+ readonly scanRefusalRatioCap: 0.25;
136
+ readonly scanRefusalMaxPerPlan: 8;
116
137
  };
117
138
  /**
118
139
  * §2.2 — the HARD throttle floor: even a `force` run cannot start a second same-scope run within
@@ -126,7 +147,7 @@ export declare const CONSOLIDATION_FORCE_THROTTLE_FLOOR_MS = 60000;
126
147
  /** The bounded distinct-session ring (§2.3 sessionsSince dedup). */
127
148
  export declare const CONSOLIDATION_SESSION_RING_MAX = 64;
128
149
  /**
129
- * codex r2 — the seat's FREEZE GRACE: reconcile's orphan-release arm treats a seat whose plan file
150
+ * the seat's FREEZE GRACE: reconcile's orphan-release arm treats a seat whose plan file
130
151
  * is absent as crashed ONLY once the claim is at least this old. Calibration: the freeze between
131
152
  * the seat CAS and the plan file's durable write is committed READS only (headers + a bounded
132
153
  * getByIds) — seconds on any healthy store; ten minutes is orders of magnitude past it, while a
@@ -142,6 +163,9 @@ export interface ScreenedConsolidationOptions {
142
163
  maxDirectedPatchesPerPlan: number;
143
164
  minRunIntervalMs: number;
144
165
  minSessionsBetweenRuns: number;
166
+ scanRefusalRatioCap: number;
167
+ scanRefusalMaxPerPlan: number;
168
+ allowInstructionProducts: boolean;
145
169
  multiNode: boolean;
146
170
  lease?: ConsolidationLeaseSeat;
147
171
  }
@@ -159,6 +183,21 @@ export declare function screenConsolidationOptions(raw: MemoryConsolidationOptio
159
183
  /** §1.2-2 — the supersession fuse ceiling: min(N-1, max(floor, ⌊ratio×N⌋)); N ≤ 1 ⇒ 0 (one plan
160
184
  * may NEVER empty the active set — the N-1 ceiling is unconditional, G21). */
161
185
  export declare function supersessionFuseCeiling(activeSetSize: number, opts: Pick<ScreenedConsolidationOptions, "supersedeRatioCap" | "supersedeAbsoluteFloor">): number;
186
+ /**
187
+ * design/376 C-2② — the scan-refusal fuse ceiling: how many scan-refused products ONE plan may
188
+ * carry before the whole plan refuses instead of committing around them.
189
+ * `min(max(1, ⌊ratio × submitted⌋), absolute max)`; the ratio leg governs small plans, the
190
+ * absolute leg is the large-batch upper bound, and the FLOOR of one keeps C-2①'s per-product
191
+ * tolerance alive at the drive lane's common plan sizes — under the default 0.25 ratio a bare
192
+ * floor answers 0 for every ≤3-product plan, so one stray refused product re-killed the whole
193
+ * plan there, exactly the shape C-2① was adopted to remove (an adopted review finding). The
194
+ * floor is NOT a hole for the fully-refused tiny plan: a plan whose every product is refused
195
+ * (and which carries no directed work) still dies at the freeze-emptied C-2③ backstop, never a
196
+ * quiet mostly-no-op — what the floor tolerates is exactly one refused product beside at least
197
+ * one survivor. Submitted count = the proposal's product count (per THIS plan, never a
198
+ * cross-run tally).
199
+ */
200
+ export declare function scanRefusalCeiling(submittedProducts: number, opts: Pick<ScreenedConsolidationOptions, "scanRefusalRatioCap" | "scanRefusalMaxPerPlan">): number;
162
201
  /** §3.1 — the type axis of the eligibility predicate: episodic entries are read-only evidence
163
202
  * (never candidates, never supersession/directed targets, A-7); procedural promotion is a v3
164
203
  * follow-on ticket. Unknown/absent types are ordinary semantic notes — eligible. */
@@ -177,13 +216,23 @@ export interface ConsolidationGateRow {
177
216
  /** The plan-seat mutex: the one non-terminal (or conflict-parked) plan of this scope. */
178
217
  openPlanId?: string;
179
218
  /** When the seat was claimed (ms epoch) — the reconcile orphan-release arm's staleness anchor
180
- * (codex r2: a freeze legitimately computes for a while between the seat CAS and the plan
219
+ * (a freeze legitimately computes for a while between the seat CAS and the plan
181
220
  * file's durable write; an absent file alone must never read as a crash). */
182
221
  seatClaimedAt?: number;
183
222
  /** §1.4.5 collapse-fuse baseline (last observed active-set size). */
184
223
  activeSetBaseline?: number;
185
224
  /** Once-per-crossing edge for the recommendation notice. */
186
225
  lastRecommendedAt?: number;
226
+ /** The last force requestId whose FORCED announcement was enqueued (additive; design/376 §1.1-4):
227
+ * a RUN-scoped force carries ONE requestId across every cycle of a multi-cycle run, and the
228
+ * audit announcement is deduplicated on it — one disclosure per run, never one per cycle (a
229
+ * cold start would otherwise flood the next session's injection face with a dozen identical
230
+ * lines). A NEW requestId re-arms the disclosure. The dedup is the ONLY record: this row keeps
231
+ * just the LAST id (no history structure exists — the gate row is mutated in place, the
232
+ * announcement queue is drained destructively, and plan files do not mark forced-ness), so
233
+ * per-force facts beyond the one announcement are not persisted, and a caller that reuses a
234
+ * fixed requestId across runs keeps the disclosure silent for as long as it does. */
235
+ lastForcedRequestId?: string;
187
236
  /** Run watermark: increments on every completed/discarded settlement (the stale-proposal gate). */
188
237
  epoch: number;
189
238
  /** §1.2-1 — the last COMPLETED run's full-eligible-set fingerprint (id → committed rev):
@@ -221,6 +270,24 @@ export declare function updateConsolidationGate<T>(controlDir: string, fn: (file
221
270
  export declare function readConsolidationGateFile(controlDir: string): ConsolidationGateFile;
222
271
  /** True ⇔ the gate store file exists at all (G1's zero-file pin reads this negatively). */
223
272
  export declare function consolidationGateFileExists(controlDir: string): boolean;
273
+ /**
274
+ * design/376 slice ③ (#437②) — the gate read face's DISCRIMINATED answer
275
+ * ({@link import("./engine.js").MemoryEngine.readConsolidationGateState}): `present` carries the
276
+ * row; `absent` means the store is readable and simply has no row for the scope (a never-run
277
+ * scope, or no gate file at all); `corrupt` means the store cannot be trusted and carries the
278
+ * refusal detail. The undiscriminated `readConsolidationGate` face folds corrupt into `undefined`
279
+ * — an operator (or a driver's scheduling read) could not tell a healthy never-run scope from a
280
+ * store every verb will refuse fail-closed.
281
+ */
282
+ export type ConsolidationGateRead = {
283
+ state: "present";
284
+ row: ConsolidationGateRow;
285
+ } | {
286
+ state: "absent";
287
+ } | {
288
+ state: "corrupt";
289
+ detail: string;
290
+ };
224
291
  /**
225
292
  * §2.2 — the engine-minted session count (harvest-tail bookkeeping; ≤1 row write per terminal
226
293
  * harvest; the OFF mode never calls this — D-9a zero-write). Returns the recommendation edge:
@@ -294,7 +361,15 @@ export interface ConsolidationDirectedPatch {
294
361
  }
295
362
  export type ConsolidationPlanState = "open" | "applying" | "completed" | "conflict" | "discarded";
296
363
  export interface ConsolidationPlanFile {
297
- v: 1;
364
+ /** Plan schema version. `2` ⇔ the plan carries {@link freezeRefusedInputIds} — that member is a
365
+ * LOAD-BEARING settle input (C-2④ keeps the named ids out of the completion fingerprint), and
366
+ * a reader that predates it would accept the file as v1, ignore the member, and settle a
367
+ * fingerprint that stamps the refused members (silently blinding the incremental face — the
368
+ * exact hole the field closes). Version-gating the member makes such a reader answer its
369
+ * "unrecognized version" corrupt arm instead: the plan parks loudly for the valve, never
370
+ * settles wrong (mixed-fleet crash window between the durable plan write and gate settlement).
371
+ * Plans without the member stay v1 — zero noise on the common path. */
372
+ v: 1 | 2;
298
373
  planId: string;
299
374
  scope: string;
300
375
  requestId: string;
@@ -308,6 +383,13 @@ export interface ConsolidationPlanFile {
308
383
  /** Frozen products — FULL entry bytes (id/frontmatter incl. distilled + origin/body/rev). */
309
384
  products: MemoryEntry[];
310
385
  productStates: Record<string, "pending" | "applied" | "conflict">;
386
+ /** design/376 C-2④ — the declared input ids of every product the FREEZE refused (scan findings
387
+ * and eligibility drift alike). Settlement keeps these ids OUT of the completion fingerprint:
388
+ * a scan-refused input's rev never moved, so stamping it would make every later incremental
389
+ * snapshot read it as unchanged and never offer it again — the refused member must stay a
390
+ * candidate. Absent on plans frozen before the field existed, and on plans with nothing
391
+ * refused (either way the settle filter simply has nothing extra to exclude). */
392
+ freezeRefusedInputIds?: string[];
311
393
  directed: ConsolidationDirectedPatch[];
312
394
  intents: Array<{
313
395
  requestId: string;
@@ -375,4 +457,38 @@ export declare class ConsolidationRefusedError extends Error {
375
457
  }
376
458
  /** A NotePatch list for one frozen product (the §1.3 add-only arm's one spelling). */
377
459
  export declare function productAddPatch(product: MemoryEntry): NotePatch;
460
+ /**
461
+ * Why a driver run stopped — ONE closed set shared verbatim by the run receipt and the
462
+ * `memory.consolidation_incomplete` notice (two vocabularies for the same fact would let an
463
+ * operator-facing channel and the host-facing receipt drift). Non-`converged` values mark a
464
+ * library in a PARTIAL fold — a transitional state the readings show is worse than unfolded, so
465
+ * it must never pass silently:
466
+ * - `converged` — nothing left to fold (the only completed-run value; includes the
467
+ * empty-plan no-op: a model that proposes nothing commits nothing);
468
+ * - `fuse_residue` — the supersession fuse admits no remaining product; the residue is named
469
+ * and the next run's full snapshot re-distills the shrunken library;
470
+ * - `max_cycles` — the cycle bound elapsed before a fixpoint;
471
+ * - `parked` — a plan settled conflict (or a corrupt plan holds the seat); the host
472
+ * valve `resolveConsolidationPlan` is the only way forward;
473
+ * - `refused` — an engine verb refused and the drive could not continue this run;
474
+ * - `driver_failed` — the DRIVER half could not complete. Two grains, one verdict: a failed
475
+ * MINT (model unreachable/unreadable/over the repair budget) settles with
476
+ * zero writes, zero seat and an unburned time gate; a run whose surviving
477
+ * plan reached its fixpoint while the driver's own half left groups
478
+ * unfolded (writing-pass failures, or products dropped stale against
479
+ * inputs edited mid-run) settles here TOO — committed cycles stand
480
+ * (add-only, no rollback), the residue is named, and a fresh run re-mints
481
+ * over the current bytes. The clean `converged` label never covers a
482
+ * driver-side residue.
483
+ * Extending this set is a consumer-visible closed-set expansion (release-note duty: every
484
+ * downstream that pinned the enumeration becomes a named party).
485
+ *
486
+ * The type DERIVES from the array (never `satisfies` beside it): the array exists precisely for
487
+ * downstream enumeration, and two independent declarations would let a new union arm skip the
488
+ * array with no compile error — the derived form makes an edit to either side a type error at
489
+ * the other.
490
+ */
491
+ export declare const CONSOLIDATION_RUN_STOP_REASONS: readonly ["converged", "fuse_residue", "max_cycles", "parked", "refused", "driver_failed"];
492
+ /** See the doc on {@link CONSOLIDATION_RUN_STOP_REASONS} — the single source this derives from. */
493
+ export type ConsolidationRunStopReason = (typeof CONSOLIDATION_RUN_STOP_REASONS)[number];
378
494
  export {};
@@ -40,6 +40,8 @@ export const CONSOLIDATION_DEFAULTS = {
40
40
  maxDirectedPatchesPerPlan: 32,
41
41
  minRunIntervalMs: 24 * 60 * 60 * 1000,
42
42
  minSessionsBetweenRuns: 5,
43
+ scanRefusalRatioCap: 0.25,
44
+ scanRefusalMaxPerPlan: 8,
43
45
  };
44
46
  export const CONSOLIDATION_FORCE_THROTTLE_FLOOR_MS = 60_000;
45
47
  export const CONSOLIDATION_SESSION_RING_MAX = 64;
@@ -70,12 +72,18 @@ export function screenConsolidationOptions(raw, provenance) {
70
72
  maxDirectedPatchesPerPlan: num("maxDirectedPatchesPerPlan", raw.maxDirectedPatchesPerPlan, (n) => Number.isInteger(n) && n >= 1, "a positive integer"),
71
73
  minRunIntervalMs: num("minRunIntervalMs", raw.minRunIntervalMs, (n) => n > 0, "a positive number of milliseconds"),
72
74
  minSessionsBetweenRuns: num("minSessionsBetweenRuns", raw.minSessionsBetweenRuns, (n) => Number.isInteger(n) && n >= 0, "a non-negative integer"),
75
+ scanRefusalRatioCap: num("scanRefusalRatioCap", raw.scanRefusalRatioCap, (n) => n > 0 && n <= 1, "a number in (0, 1]"),
76
+ scanRefusalMaxPerPlan: num("scanRefusalMaxPerPlan", raw.scanRefusalMaxPerPlan, (n) => Number.isInteger(n) && n >= 1, "a positive integer"),
77
+ allowInstructionProducts: raw.allowInstructionProducts === true,
73
78
  multiNode: raw.multiNode === true,
74
79
  ...(raw.lease !== undefined ? { lease: raw.lease } : {}),
75
80
  };
76
81
  if (raw.multiNode !== undefined && raw.multiNode !== true) {
77
82
  throw coded(`MemoryEngineOptions.consolidation.multiNode must be exactly true when present (a posture declaration, not a boolean knob).`, "config.memory_consolidation");
78
83
  }
84
+ if (raw.allowInstructionProducts !== undefined && raw.allowInstructionProducts !== true) {
85
+ throw coded(`MemoryEngineOptions.consolidation.allowInstructionProducts must be exactly true when present (a posture declaration, not a boolean knob — absent means the instruction-form gate stays closed).`, "config.memory_consolidation");
86
+ }
79
87
  if (screened.multiNode && screened.lease === undefined) {
80
88
  throw coded(`MemoryEngineOptions.consolidation.multiNode declared without a lease seat — a multi-node deployment MUST inject the host's global lease (the local plan-seat CAS does not reach across nodes). Inject consolidation.lease or remove the multiNode declaration.`, "config.memory_consolidation_lease_required");
81
89
  }
@@ -89,6 +97,11 @@ export function supersessionFuseCeiling(activeSetSize, opts) {
89
97
  return 0;
90
98
  return Math.min(activeSetSize - 1, Math.max(opts.supersedeAbsoluteFloor, Math.floor(opts.supersedeRatioCap * activeSetSize)));
91
99
  }
100
+ export function scanRefusalCeiling(submittedProducts, opts) {
101
+ if (submittedProducts <= 0)
102
+ return 0;
103
+ return Math.min(Math.max(1, Math.floor(opts.scanRefusalRatioCap * submittedProducts)), opts.scanRefusalMaxPerPlan);
104
+ }
92
105
  export function consolidationTypeEligible(type) {
93
106
  return type !== "episodic" && type !== "procedural";
94
107
  }
@@ -186,7 +199,7 @@ function planShapeInvalid(raw, planId) {
186
199
  if (typeof raw !== "object" || raw === null)
187
200
  return "not an object";
188
201
  const p = raw;
189
- if (p["v"] !== 1)
202
+ if (p["v"] !== 1 && p["v"] !== 2)
190
203
  return "unrecognized version";
191
204
  if (p["planId"] !== planId)
192
205
  return "planId mismatch";
@@ -248,6 +261,13 @@ function planShapeInvalid(raw, planId) {
248
261
  }
249
262
  if (!p["directed"].every((d) => intentIds.has(d.intentRequestId)))
250
263
  return "directed patch references an undeclared intent";
264
+ const freezeRefused = p["freezeRefusedInputIds"];
265
+ if (freezeRefused !== undefined && (!Array.isArray(freezeRefused) || !freezeRefused.every((x) => typeof x === "string"))) {
266
+ return "malformed freezeRefusedInputIds";
267
+ }
268
+ if ((p["v"] === 2) !== (freezeRefused !== undefined)) {
269
+ return p["v"] === 2 ? "v2 plan without its freezeRefusedInputIds member" : "freezeRefusedInputIds on a v1 plan";
270
+ }
251
271
  if (!Array.isArray(p["audit"]))
252
272
  return "malformed audit trail";
253
273
  return undefined;
@@ -340,3 +360,4 @@ export class ConsolidationRefusedError extends Error {
340
360
  export function productAddPatch(product) {
341
361
  return { op: "add", id: product.id, entry: product, guard: "absent" };
342
362
  }
363
+ export const CONSOLIDATION_RUN_STOP_REASONS = ["converged", "fuse_residue", "max_cycles", "parked", "refused", "driver_failed"];
@@ -4,7 +4,7 @@ import type { HarvestRejection, MemoryBackend, MemoryEntry, NotePatch, PatchRepo
4
4
  export declare const REMOTE_HARVEST_PER_FILE_BYTES: number;
5
5
  /** Missing-file ratio above which the harvest refuses wholesale (engine MASS_DELETION_FUSE_RATIO). */
6
6
  export declare const REMOTE_MASS_DELETION_FUSE_RATIO = 0.5;
7
- /** File-count cap per harvest (host DEFAULT_MAX_MEMORY_FILES parity — codex H10). */
7
+ /** File-count cap per harvest (host DEFAULT_MAX_MEMORY_FILES parity). */
8
8
  export declare const REMOTE_HARVEST_MAX_FILES = 500;
9
9
  /** Max DIRECTORY nesting depth below the memory root (host DEFAULT_MAX_ENTRY_DEPTH parity — the
10
10
  * host's `scanEntryFiles` walks a subdir only while `depth + 1 <= maxDepth`, so it counts directory