@sema-agent/core 7.30.1 → 7.31.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 (75) hide show
  1. package/CHANGELOG.md +242 -0
  2. package/dist/agents/cross-session-judge.d.ts +4 -12
  3. package/dist/agents/cross-session-judge.js +4 -11
  4. package/dist/agents/peer-session-drain.js +0 -5
  5. package/dist/agents/send-message-tool.js +1 -0
  6. package/dist/agents/subagent.d.ts +1 -0
  7. package/dist/agents/subagent.js +1 -0
  8. package/dist/core/ask-origin.d.ts +6 -0
  9. package/dist/core/ask-origin.js +10 -0
  10. package/dist/core/checkpoint-store.d.ts +14 -0
  11. package/dist/core/checkpoint-store.js +1 -0
  12. package/dist/core/engine-notice.d.ts +4 -0
  13. package/dist/core/governance-codes.d.ts +1 -1
  14. package/dist/core/governance-codes.js +3 -0
  15. package/dist/core/memory-engine/data-plane.d.ts +3 -1
  16. package/dist/core/memory-engine/data-plane.js +1 -1
  17. package/dist/core/memory-engine/delegation-settlement.d.ts +44 -3
  18. package/dist/core/memory-engine/delegation-settlement.js +38 -3
  19. package/dist/core/memory-engine/engine.d.ts +123 -26
  20. package/dist/core/memory-engine/engine.js +426 -149
  21. package/dist/core/memory-engine/entry-scan.d.ts +23 -0
  22. package/dist/core/memory-engine/entry-scan.js +55 -0
  23. package/dist/core/memory-engine/file-backend.d.ts +16 -23
  24. package/dist/core/memory-engine/file-backend.js +122 -99
  25. package/dist/core/memory-engine/layer-observations.d.ts +109 -0
  26. package/dist/core/memory-engine/layer-observations.js +148 -0
  27. package/dist/core/memory-engine/layout.d.ts +11 -0
  28. package/dist/core/memory-engine/layout.js +20 -4
  29. package/dist/core/memory-engine/types.d.ts +26 -2
  30. package/dist/core/parent-spec-seat.d.ts +4 -1
  31. package/dist/core/parent-spec-seat.js +2 -0
  32. package/dist/core/park-selfcheck.js +1 -0
  33. package/dist/core/runner/announce-once-ledger.d.ts +26 -0
  34. package/dist/core/runner/announce-once-ledger.js +37 -0
  35. package/dist/core/runner/contracts.d.ts +22 -5
  36. package/dist/core/runner/denial-limit-arms.d.ts +2 -2
  37. package/dist/core/runner/prepare-acquire-reconcile.d.ts +0 -4
  38. package/dist/core/runner/prepare-acquire-reconcile.js +1 -3
  39. package/dist/core/runner/prepare-file-history.d.ts +13 -15
  40. package/dist/core/runner/prepare-file-history.js +57 -43
  41. package/dist/core/runner/prepare-hands-readface.d.ts +2 -2
  42. package/dist/core/runner/prepare-listings.d.ts +3 -1
  43. package/dist/core/runner/prepare-listings.js +2 -2
  44. package/dist/core/runner/prepare-memory.js +16 -5
  45. package/dist/core/runner/prepare-park-ask.js +27 -16
  46. package/dist/core/runner/prepare-prompt-inputs.d.ts +8 -1
  47. package/dist/core/runner/prepare-prompt-inputs.js +5 -3
  48. package/dist/core/runner/prepare-task.js +7 -5
  49. package/dist/core/runner/prepare-wiring-manifest.d.ts +1 -0
  50. package/dist/core/runner/prepare-wiring-manifest.js +2 -1
  51. package/dist/core/runner/run-attachment-seats.js +1 -1
  52. package/dist/core/runner/run-leg.js +61 -52
  53. package/dist/core/runner/run-settle-and-teardown.js +4 -0
  54. package/dist/core/runner/run-turn-boundary.js +6 -6
  55. package/dist/core/runner/turn-attachments.d.ts +6 -6
  56. package/dist/core/runner-deps.d.ts +3 -1
  57. package/dist/core/secret-env.d.ts +11 -0
  58. package/dist/core/secret-env.js +20 -0
  59. package/dist/core/store-contracts/checkpoint-store-contract.d.ts +2 -0
  60. package/dist/core/store-contracts/checkpoint-store-contract.js +22 -0
  61. package/dist/core/task-result.d.ts +1 -1
  62. package/dist/core/task-spec.d.ts +17 -8
  63. package/dist/core/tool-spec.d.ts +1 -1
  64. package/dist/core/wiring-manifest.d.ts +10 -0
  65. package/dist/core/wiring-manifest.js +7 -1
  66. package/dist/engine/execution-env/node-execution-env.d.ts +6 -0
  67. package/dist/engine/execution-env/node-execution-env.js +15 -17
  68. package/dist/engine/harness/agent-harness.js +7 -5
  69. package/dist/engine/lsp/node-lsp-manager.d.ts +4 -0
  70. package/dist/engine/lsp/node-lsp-manager.js +10 -4
  71. package/dist/index.d.ts +1 -1
  72. package/dist/index.js +1 -1
  73. package/package.json +1 -1
  74. package/test/export-surface.snapshot.json +7 -1
  75. package/wire-changes/core@7.31.0.json +705 -0
@@ -2,7 +2,7 @@ import { NodeExecutionEnv } from "../../engine/execution-env/node-execution-env.
2
2
  import { isRemoteExecutionEnv } from "../remote-env.js";
3
3
  import { resolveTrackKey } from "../file-history-store.js";
4
4
  export async function prepareFileHistory(input) {
5
- const { deps, spec, internals, executionEnv, taskRootFinal, handsEnabled, sessionId, session, resumeAtBeforeParentId, abortController } = input;
5
+ const { deps, spec, internals, executionEnv, taskRootFinal, handsEnabled, sessionId, session, abortController } = input;
6
6
  const rewindNotes = [];
7
7
  const onTrackFailure = deps.onTrackFailure === undefined ? "refuse" : deps.onTrackFailure;
8
8
  if (onTrackFailure !== "refuse" && onTrackFailure !== "proceed-unprotected") {
@@ -11,16 +11,20 @@ export async function prepareFileHistory(input) {
11
11
  throw e;
12
12
  }
13
13
  const wiredSeat = resolveWiredFileHistoryStore(deps.fileHistoryStore);
14
- const fileHistoryStore = wiredSeat === "disabled" ? undefined : wiredSeat;
14
+ const runDeclaredOff = resolveRunFileHistoryWord(spec.fileHistory);
15
+ const captureOff = resolveFileHistoryCaptureWord(deps.fileHistoryCapture, wiredSeat);
16
+ const declaredOff = wiredSeat === "disabled" || runDeclaredOff;
17
+ const fileHistoryStore = declaredOff ? undefined : wiredSeat;
18
+ const captureStore = captureOff ? undefined : fileHistoryStore;
15
19
  const legacyRewindFiles = spec.rewindFiles;
16
20
  if (legacyRewindFiles === true) {
17
21
  if (spec.resumeAt !== undefined) {
18
- const e = new Error(`rewind-files: TaskSpec.rewindFiles is retired (design/381 — rewind now converges the per-edited-file history, not a whole-tree snapshot). This request pairs it with resumeAt, i.e. the RESTORE sense: set restoreFiles: true instead. (The capture sense needs no request anymore — first-touch tracking is always on when a RunnerDeps.fileHistoryStore is wired.)`);
22
+ const e = new Error(`rewind-files: TaskSpec.rewindFiles is retired (design/381 — rewind now converges the per-edited-file history, not a whole-tree snapshot). This request pairs it with resumeAt, i.e. the RESTORE sense: set restoreFiles: true instead. (The capture sense needs no request anymore — first-touch tracking is on whenever a RunnerDeps.fileHistoryStore is wired and neither RunnerDeps.fileHistoryCapture nor TaskSpec.fileHistory turns it off.)`);
19
23
  e.code = "rewind.rewind_files_retired";
20
24
  throw e;
21
25
  }
22
26
  try {
23
- deps.onError?.(new Error(`TaskSpec.rewindFiles (capture sense) is retired and was ignored: per-edited-file first-touch tracking is always on when RunnerDeps.fileHistoryStore is wired, so a per-turn capture request has nothing left to ask for. Drop the field; the restore sense moved to TaskSpec.restoreFiles.`), { phase: "config", sessionId });
27
+ deps.onError?.(new Error(`TaskSpec.rewindFiles (capture sense) is retired and was ignored: per-edited-file first-touch tracking is on whenever RunnerDeps.fileHistoryStore is wired and neither RunnerDeps.fileHistoryCapture nor TaskSpec.fileHistory turns it off, so a per-turn capture request has nothing left to ask for. Drop the field; the restore sense moved to TaskSpec.restoreFiles.`), { phase: "config", sessionId });
24
28
  }
25
29
  catch {
26
30
  }
@@ -35,7 +39,7 @@ export async function prepareFileHistory(input) {
35
39
  e.code = "rewind.conflicting_targets";
36
40
  throw e;
37
41
  }
38
- let rewindTarget = spec.resumeAt !== undefined ? (spec.restoreFiles === true ? spec.resumeAt : undefined) : spec.rewindFilesTo;
42
+ const rewindTarget = spec.resumeAt !== undefined ? (spec.restoreFiles === true ? spec.resumeAt : undefined) : spec.rewindFilesTo;
39
43
  const rewindBefore = rewindTarget !== undefined && spec.resumeAt !== undefined && spec.resumeAtMode === "before";
40
44
  if (spec.resumeAt !== undefined && spec.restoreFiles !== true) {
41
45
  rewindNotes.push({
@@ -43,9 +47,9 @@ export async function prepareFileHistory(input) {
43
47
  message: `the conversation was branched at entry "${spec.resumeAt}" but the working tree was NOT rewound — this task set resumeAt without restoreFiles, so files remain at their current state`,
44
48
  });
45
49
  }
46
- const fileHistoryEnabled = fileHistoryStore !== undefined && handsEnabled;
50
+ const fileHistoryEnabled = captureStore !== undefined && handsEnabled;
47
51
  const livenessArm = fileHistoryStore === undefined ? "file-history-no-store" : "file-history-no-env";
48
- if (!fileHistoryEnabled && wiredSeat !== "disabled" && (handsEnabled || fileHistoryStore !== undefined) && deps.onError !== undefined && !toldAlready(deps.onError, livenessArm)) {
52
+ if (!fileHistoryEnabled && !declaredOff && !captureOff && (handsEnabled || fileHistoryStore !== undefined) && deps.onError !== undefined && !toldAlready(deps.onError, livenessArm)) {
49
53
  const reason = livenessArm === "file-history-no-store"
50
54
  ? `this deployment wired no RunnerDeps.fileHistoryStore, so NOTHING is recorded: no first-touch snapshot before an edit, no turn boundary, and a later restoreFiles / rewindFilesTo has nothing to restore from and will refuse (rewind.store_unconfigured). Supply a store, or accept an unrecoverable working tree knowingly (fileHistoryStore: "disabled" says so and silences this line)`
51
55
  : `RunnerDeps.fileHistoryStore is wired but this run mounts no filesystem-capable ExecutionEnv, so the store is INERT: there is no working tree to snapshot and nothing will ever be written to it. Wire RunnerDeps.executionEnv, or drop the store from this deployment shape`;
@@ -55,14 +59,18 @@ export async function prepareFileHistory(input) {
55
59
  catch {
56
60
  }
57
61
  }
58
- const { historyRoot, historyScope, historyFs } = await resolveFileHistoryCoordinates(fileHistoryEnabled, executionEnv, taskRootFinal, internals?.fileHistoryLineage, sessionId);
59
- if (fileHistoryStore !== undefined && internals?.fileHistoryLineage === undefined)
60
- await adoptForkedFileHistory(fileHistoryStore, session, sessionId, deps.onError);
62
+ const { historyRoot, historyScope, historyFs } = await resolveFileHistoryCoordinates(fileHistoryStore !== undefined && handsEnabled, executionEnv, taskRootFinal, internals?.fileHistoryLineage, sessionId);
63
+ if (captureStore !== undefined && internals?.fileHistoryLineage === undefined)
64
+ await adoptForkedFileHistory(captureStore, session, sessionId, deps.onError);
61
65
  if (rewindTarget !== undefined && historyScope !== sessionId)
62
66
  throw childScopeRewindRefusal(historyScope, rewindTarget);
63
67
  if (fileHistoryStore === undefined) {
68
+ if (rewindTarget !== undefined && runDeclaredOff)
69
+ throw captureDisabledRefusal(rewindTarget);
64
70
  if (rewindTarget !== undefined) {
65
- const e = new Error(`rewind-files: restoring files to entry "${rewindTarget}" requires a history backend, but this deployment wired no RunnerDeps.fileHistoryStore — no file history was ever recorded, so the files were NOT rewound`);
71
+ const e = new Error(wiredSeat === "disabled"
72
+ ? `rewind-files: restoring files to entry "${rewindTarget}" requires a history backend, but this deployment declared file history disabled (RunnerDeps.fileHistoryStore: "disabled"), so there is no history to restore — the files were NOT rewound`
73
+ : `rewind-files: restoring files to entry "${rewindTarget}" requires a history backend, but this deployment wired no RunnerDeps.fileHistoryStore — no file history was ever recorded, so the files were NOT rewound`);
66
74
  e.code = "rewind.store_unconfigured";
67
75
  throw e;
68
76
  }
@@ -78,39 +86,17 @@ export async function prepareFileHistory(input) {
78
86
  let restoredFilePaths = [];
79
87
  if (rewindTarget !== undefined && fileHistoryStore !== undefined && handsEnabled) {
80
88
  const historyStore = fileHistoryStore;
81
- if (rewindBefore) {
82
- let anchor;
83
- if (await historyStore.canRestore(sessionId, rewindTarget)) {
84
- anchor = rewindTarget;
85
- }
86
- else {
87
- const walked = new Set();
88
- let cursor = resumeAtBeforeParentId;
89
- while (cursor !== null && !walked.has(cursor)) {
90
- walked.add(cursor);
91
- if (await historyStore.canRestore(sessionId, cursor)) {
92
- anchor = cursor;
93
- break;
94
- }
95
- cursor = (await session.getEntry(cursor))?.parentId ?? null;
96
- }
97
- }
98
- if (anchor === undefined) {
99
- const e = new Error(`rewind-files: no file-history boundary exists at or above the "before" branch point on session "${sessionId}" — cannot restore files consistent with the rewound context. ${rewindRefusalTail("at-or-above")}`);
100
- e.code = "rewind_snapshot.unresolvable";
101
- throw e;
102
- }
103
- rewindTarget = anchor;
104
- }
89
+ if (rewindBefore && !(await historyStore.canRestore(sessionId, rewindTarget)))
90
+ throw beforeWithoutBoundaryRefusal(rewindTarget, sessionId);
105
91
  const restoreRoot = historyRoot;
106
92
  const restoreSignal = spec.signal ? AbortSignal.any([abortController.signal, spec.signal]) : abortController.signal;
107
93
  const restored = await historyStore.restore(sessionId, rewindTarget, executionEnv, restoreRoot, restoreSignal);
108
94
  const ledgerLine = (r) => `applied ${r.filesChanged.length}, identical ${r.identicalSkipped.length}, refused ${r.refused.length}${r.refused.length > 0 ? ` (${r.refused.map((f) => `${f.path}: ${f.reason}`).join("; ")})` : ""}, failed ${r.failed.length}${r.failed.length > 0 ? ` (${r.failed.map((f) => `${f.path}: ${f.reason}`).join("; ")})` : ""}`;
109
95
  if (restored.outcome === "failed") {
110
96
  if (restored.error?.code === "not_found") {
111
- const e = new Error(rewindBefore
112
- ? `rewind-files: the resolved "before" history anchor "${rewindTarget}" disappeared before restore — files were NOT rewound`
113
- : `rewind-files: no file-history boundary exists for entry "${rewindTarget}" on session "${sessionId}" — the working tree was NOT rewound. ${rewindRefusalTail("keyed")}`);
97
+ if (rewindBefore)
98
+ throw beforeWithoutBoundaryRefusal(rewindTarget, sessionId);
99
+ const e = new Error(`rewind-files: no file-history boundary exists for entry "${rewindTarget}" on session "${sessionId}" — the working tree was NOT rewound. ${rewindRefusalTail()}`);
114
100
  e.code = "rewind_snapshot.unresolvable";
115
101
  throw e;
116
102
  }
@@ -170,7 +156,8 @@ export async function prepareFileHistory(input) {
170
156
  const fileHistoryBoundary = fileHistoryEnabled && historyScope === sessionId
171
157
  ? createFileHistoryBoundarySeat({ store: fileHistoryStore, sessionId, env: executionEnv, root: historyRoot, onError: deps.onError })
172
158
  : undefined;
173
- return { trackFileEdit, fileHistoryBoundary, restoredFilePaths, rewindNotes, fileHistoryEnabled, historyScope, historyRoot, historyFs };
159
+ const fileHistoryFact = fileHistoryEnabled ? "on" : "disabled";
160
+ return { trackFileEdit, fileHistoryBoundary, restoredFilePaths, rewindNotes, fileHistoryEnabled, fileHistoryFact, historyScope, historyRoot, historyFs };
174
161
  }
175
162
  function restoredAbsPathsOf(restored, root) {
176
163
  const out = [];
@@ -203,10 +190,37 @@ function resolveWiredFileHistoryStore(candidate) {
203
190
  }
204
191
  return candidate;
205
192
  }
206
- function rewindRefusalTail(form) {
207
- return form === "keyed"
208
- ? `Boundaries are keyed by a turn's INITIAL entry and exist only for turns that ran with a RunnerDeps.fileHistoryStore wired; a boundary from the retired whole-tree snapshot era is not restorable by this seat, and reaped boundaries have none.`
209
- : `Either the boundary does not exist (its turns ran without a RunnerDeps.fileHistoryStore, or it was reaped), or it was produced in the retired whole-tree snapshot era, which this engine's per-edited-file seat does not restore.`;
193
+ function resolveRunFileHistoryWord(word) {
194
+ if (word === undefined || word === "disabled")
195
+ return word === "disabled";
196
+ const e = new Error(`rewind-files: TaskSpec.fileHistory holds ${shownWord(word)} — the only value is "disabled"; omit the key to leave the deployment's setting in force`);
197
+ e.code = "rewind.invalid_spec";
198
+ throw e;
199
+ }
200
+ function resolveFileHistoryCaptureWord(word, wiredSeat) {
201
+ if (word === undefined || (word === "off" && wiredSeat !== undefined && wiredSeat !== "disabled"))
202
+ return word === "off";
203
+ const e = new Error(word === "off"
204
+ ? `RunnerDeps.fileHistoryCapture: "off" requires a wired RunnerDeps.fileHistoryStore — nothing to switch off; to drop history entirely write fileHistoryStore: "disabled"`
205
+ : `RunnerDeps.fileHistoryCapture holds ${shownWord(word)} — the only value is "off"; omit the key to record whenever a fileHistoryStore is wired`);
206
+ e.code = "config.invalid_file_history_capture";
207
+ throw e;
208
+ }
209
+ function shownWord(word) {
210
+ return typeof word === "string" ? JSON.stringify(word.slice(0, 40)) : word === null || typeof word === "boolean" || typeof word === "number" ? String(word) : `a ${typeof word}`;
211
+ }
212
+ function captureDisabledRefusal(target) {
213
+ const e = new Error(`rewind-files: this run set TaskSpec.fileHistory: "disabled", so it neither records nor restores file history — restoring files to entry "${target}" was refused and the files were NOT rewound`);
214
+ e.code = "rewind.capture_disabled";
215
+ return e;
216
+ }
217
+ function rewindRefusalTail() {
218
+ return `Boundaries are keyed by a turn's INITIAL entry and exist only for turns that recorded history (a RunnerDeps.fileHistoryStore wired, capture on, and the run's file history not disabled); a boundary from the retired whole-tree snapshot era is not restorable by this seat, and reaped boundaries have none.`;
219
+ }
220
+ function beforeWithoutBoundaryRefusal(target, sessionId) {
221
+ const e = new Error(`rewind-files: entry "${target}" has no file-history boundary on session "${sessionId}" — a before-restore needs the target's own boundary and never crosses into an earlier turn, so the working tree was NOT rewound. ${rewindRefusalTail()}`);
222
+ e.code = "rewind_snapshot.unresolvable";
223
+ return e;
210
224
  }
211
225
  const FILE_HISTORY_BOUNDARY_TIMEOUT_MS = 30_000;
212
226
  const FILE_HISTORY_LIVENESS_MEMO = new WeakMap();
@@ -218,8 +218,8 @@ export interface PrepareHandsReadFaceInput {
218
218
  * band's Read/notebook/PDF trailer outlets bump keys on it at tool-execute time (the driver owns
219
219
  * the object and folds it into result stats). */
220
220
  reminderDisclosureCounts: import("../reminder-disclosure.js").ReminderDisclosureCounts;
221
- /** borrowed-readonly — the first-touch history hook prepare built (present iff a fileHistoryStore is
222
- * wired and the run mounts a real fs env); threaded to the write band's trackFileEdit seat. */
221
+ /** borrowed-readonly — the first-touch history hook prepare built (present iff the run records file history into a
222
+ * wired store and mounts a real fs env); threaded to the write band's trackFileEdit seat. */
223
223
  trackFileEdit?: import("../types.js").TrackFileEditHook;
224
224
  /** borrowed-readonly — the mutation lane's LANDED observation seat (the accumulator behind
225
225
  * `TaskResult.editedFiles`); threaded to the write band's onFileEdited seat. Unlike
@@ -15,7 +15,7 @@
15
15
  */
16
16
  import type { AgentTool } from "../../internal/harness.js";
17
17
  import type { TaskSpec } from "../types.js";
18
- import type { AnnounceOnceSink, Prepared, PrepareResume, ToolFaceSnapshot } from "./contracts.js";
18
+ import type { AnnounceOnceSink, DateAnchorRead, Prepared, PrepareResume, ToolFaceSnapshot } from "./contracts.js";
19
19
  import type { AnnouncedListingSnapshot } from "../../internal/harness.js";
20
20
  import type { ResolvedSkillListingBudget } from "../skill-listing-budget.js";
21
21
  export interface PrepareListingsInput {
@@ -65,6 +65,8 @@ export interface PrepareListingsInput {
65
65
  tzValid: boolean;
66
66
  /** borrowed-readonly — the client's declared zone (used only when `tzValid`). */
67
67
  userTz: string | undefined;
68
+ /** borrowed-readonly — the session's date anchor as the prompt-inputs phase read it (rides the seam). */
69
+ dateAnchor: DateAnchorRead | undefined;
68
70
  }
69
71
  export interface PrepareListingsResult {
70
72
  /** owned — the agent-listing announce projection (`Prepared.agentListing`): the roster off the
@@ -2,7 +2,7 @@ import { formatLocalDate } from "../../prompts/default.js";
2
2
  import { SKILL_TOOL_NAME } from "./synthetic-tools.js";
3
3
  import { renderAgentListingDelta } from "./turn-attachments.js";
4
4
  export function prepareListings(input) {
5
- const { spec, tools, onceLedger, sessionId, toolFaceSnapshot, activeTools, resume, skillsListing, listingBudget, listingRideRef, renderWithDate, envFacts, tzValid, userTz } = input;
5
+ const { spec, tools, onceLedger, sessionId, toolFaceSnapshot, activeTools, resume, skillsListing, listingBudget, listingRideRef, renderWithDate, envFacts, tzValid, userTz, dateAnchor } = input;
6
6
  if (spec.agents !== undefined && spec.agents.length > 0) {
7
7
  const known = new Set(tools.flatMap((t) => [t.name, ...(t.aliases ?? [])]));
8
8
  for (const def of spec.agents) {
@@ -72,7 +72,7 @@ export function prepareListings(input) {
72
72
  };
73
73
  }
74
74
  const dateChange = renderWithDate
75
- ? { legDate: envFacts.date, today: () => formatLocalDate(new Date(), tzValid ? userTz : undefined) }
75
+ ? { legDate: envFacts.date, today: () => formatLocalDate(new Date(), tzValid ? userTz : undefined), anchor: dateAnchor }
76
76
  : undefined;
77
77
  return { agentListing, announcedListingsRef, dateChange };
78
78
  }
@@ -81,6 +81,7 @@ export async function prepareMemory(input) {
81
81
  let captureIndeterminate = false;
82
82
  let captureLineageIndeterminate = false;
83
83
  let memoryEngineSession;
84
+ const openedLegs = [];
84
85
  let memoryTools;
85
86
  let writeChannelOpen = false;
86
87
  let memoryMarkedEntriesServed = false;
@@ -385,6 +386,7 @@ export async function prepareMemory(input) {
385
386
  sessionId,
386
387
  ...(m.write === null && shadowNames !== undefined && shadowNames.size > 0 ? { shadowNames } : {}),
387
388
  });
389
+ openedLegs.push(() => void m.engine.endSessionLeg(handle, sessionId));
388
390
  mounted.push(handle);
389
391
  materializedResidue.push(...planeScopes(m.scopes, m.write));
390
392
  if (m.write !== null) {
@@ -425,10 +427,10 @@ export async function prepareMemory(input) {
425
427
  committedHeaders: () => personalEngine.listCommittedHeaders(planeScopes(p.personal, p.writePlane === "personal" ? memorySpec.writeScope : null)),
426
428
  },
427
429
  ];
428
- harvestBoth = async () => {
430
+ harvestBoth = async (phase) => {
429
431
  const writeFirst = writeIsPersonal ? [personalEngine, personalHandle] : [projectEngine, projectHandle];
430
432
  const readOther = writeIsPersonal ? [projectEngine, projectHandle] : [personalEngine, personalHandle];
431
- const writeReport = await writeFirst[0].harvest(writeFirst[1], { ...pollutedOpts(writeFirst[0]), sessionId, ...(await admitNothingOptsNow()) });
433
+ const writeReport = await writeFirst[0].harvest(writeFirst[1], { ...pollutedOpts(writeFirst[0]), sessionId, ...(await admitNothingOptsNow()), phase });
432
434
  let readReport;
433
435
  let readFailure;
434
436
  try {
@@ -448,12 +450,13 @@ export async function prepareMemory(input) {
448
450
  const personalEngine = personal.engine;
449
451
  await armCaptureOptOut(personalEngine);
450
452
  const handle = await personalEngine.materialize(memorySpec.scopes, memorySpec.writeScope, { adoptionRestricted: adoptionRestricted || captureOptedOut || captureIndeterminate, sessionId });
453
+ openedLegs.push(() => void personalEngine.endSessionLeg(handle, sessionId));
451
454
  materializedResidue.push(...planeScopes(memorySpec.scopes, memorySpec.writeScope));
452
455
  memoryMarkedEntriesServed = handle.markedEntriesPresent === true;
453
456
  writeEngine = personalEngine;
454
457
  writeHandle = handle;
455
458
  injectFn = () => personalEngine.inject(handle, { writeToolMounted: writeChannelOpen, reminderMark: input.reminderMark });
456
- harvestBoth = async () => personalEngine.harvest(handle, { ...pollutedOpts(personalEngine), sessionId, ...(await admitNothingOptsNow()) });
459
+ harvestBoth = async (phase) => personalEngine.harvest(handle, { ...pollutedOpts(personalEngine), sessionId, ...(await admitNothingOptsNow()), phase });
457
460
  toolPlanes = [
458
461
  {
459
462
  backend: retrievalBackend(personal.backend, adoptionRestricted || captureOptedOut || captureIndeterminate || memorySpec.writeScope === null),
@@ -477,12 +480,13 @@ export async function prepareMemory(input) {
477
480
  });
478
481
  await armCaptureOptOut(engine);
479
482
  const handle = await engine.materialize(memorySpec.scopes, memorySpec.writeScope, { adoptionRestricted: adoptionRestricted || captureOptedOut || captureIndeterminate, sessionId });
483
+ openedLegs.push(() => void engine.endSessionLeg(handle, sessionId));
480
484
  materializedResidue.push(...planeScopes(memorySpec.scopes, memorySpec.writeScope));
481
485
  memoryMarkedEntriesServed = handle.markedEntriesPresent === true;
482
486
  writeEngine = engine;
483
487
  writeHandle = handle;
484
488
  injectFn = () => engine.inject(handle, { writeToolMounted: writeChannelOpen, reminderMark: input.reminderMark });
485
- harvestBoth = async () => engine.harvest(handle, { ...pollutedOpts(engine), sessionId, ...(await admitNothingOptsNow()) });
489
+ harvestBoth = async (phase) => engine.harvest(handle, { ...pollutedOpts(engine), sessionId, ...(await admitNothingOptsNow()), phase });
486
490
  toolPlanes = [
487
491
  {
488
492
  backend: retrievalBackend(backend, adoptionRestricted || captureOptedOut || captureIndeterminate || memorySpec.writeScope === null),
@@ -574,7 +578,7 @@ export async function prepareMemory(input) {
574
578
  };
575
579
  const harvestSafe = async (phase = "terminal") => {
576
580
  try {
577
- const report = await harvestBoth();
581
+ const report = await harvestBoth(phase);
578
582
  if (!report.ok && report.incident) {
579
583
  const named = report.reportId !== undefined ? `${report.incident.kind}, report ${report.reportId}` : report.incident.kind;
580
584
  deps.onError?.(new Error(`memory harvest refused (${named}): ${report.incident.detail}`), { phase: "memory", sessionId });
@@ -615,6 +619,10 @@ export async function prepareMemory(input) {
615
619
  handle: writeHandle,
616
620
  inject: injectFn,
617
621
  harvest: harvestSafe,
622
+ release: () => {
623
+ for (const end of openedLegs)
624
+ end();
625
+ },
618
626
  captureOptOut: {
619
627
  optedOut: () => {
620
628
  if (captureOptedOut)
@@ -733,6 +741,9 @@ export async function prepareMemory(input) {
733
741
  memoryTools = createMemoryEngineTools({ planes: toolPlanes, sessionPollution: () => writeEngine.sessionPollution(sessionId), provenance: input.memoryProvenance, writeScope: memorySpec.writeScope });
734
742
  }
735
743
  catch (err) {
744
+ if (memoryEngineSession === undefined)
745
+ for (const end of openedLegs)
746
+ end();
736
747
  if (typeof err.code === "string" &&
737
748
  (err.code.startsWith("config.memory_scope") ||
738
749
  err.code.startsWith("config.memory_project") ||
@@ -6,6 +6,7 @@ import { boundInputHashOf } from "../canonical-json.js";
6
6
  import { buildRiskDescriptor, checkpointVersionFor, debitLedger, encodeAtFidelity, mintCheckpointId, mintCheckpointToken, resolveDeclaredFidelity, samePlainValue, } from "../checkpoint-store.js";
7
7
  import { pauseOf } from "../pause-registry.js";
8
8
  import { askCarryRowMembers } from "../hooks.js";
9
+ import { askMandateMember, ownedClearanceFacts } from "../ask-origin.js";
9
10
  import { defaultTaskRegistry } from "../task-registry.js";
10
11
  import { advertisedWritableRootsSeat, isLiveApproverSeat, carriesBidiControls, describeThrown, refuseOutOfContractDecision, tryCloneArgs } from "../tool-policy.js";
11
12
  import { InMemoryToolResultStore, ScopedToolResultStore, isVolatileOffloadStore } from "../tool-result-store.js";
@@ -21,6 +22,9 @@ class ParkRefusal extends Error {
21
22
  this.name = "ParkRefusal";
22
23
  }
23
24
  }
25
+ const wordlessDemand = (toolName) => {
26
+ throw new Error(`a real-approval demand for "${toolName}" reached the park with no origin word — the origin stamp precedes every park`);
27
+ };
24
28
  export function prepareParkAsk(input) {
25
29
  const { askLane, saga, spec, deps, sessionId, checkpointStore, toolRosterDeltas, parkLaneArmed, contentAskRoutable, liveQuestionFace, mountedQuestionTool, contentAskBindings, lateStrandedAnswers, discloseStrandedAnswers, onAsk, runtimeCaps, inheritedUnavailableAsks, basePolicyForResumeEdit, budgetSnapshot, handsCwdRef, advertisedWritableDirs, offloadStore, ownedEnv, incompleteSuspendAdapter, session, sessions, suspendChainBase, maxSuspends, remoteEnvFailures, shellGatedTools, effectiveShellGate, durableApproval, priorLedger, liveSpendRef, resourceTotal, faceCheckpointState, f012CheckpointState, orgAdmissionCheckpointState, ruleOffersOf, now, humanReviewRef, abortController, harness, pausedRef } = input;
26
30
  if (askLane === undefined || saga === undefined)
@@ -148,6 +152,7 @@ export function prepareParkAsk(input) {
148
152
  throw new ParkRefusal(`the arguments of "${req.toolName}" change shape when stored by this checkpoint backend, and no policy is wired to re-adjudicate the stored shape ` +
149
153
  `(no basePolicyForResumeEdit override and no caller toolPolicy) — refusing to file a row whose executable form nothing adjudicated`);
150
154
  }
155
+ let storedShapeFacts;
151
156
  if (projectionMovedArgs && basePolicyForResumeEdit !== undefined) {
152
157
  const presented = encodeAtFidelity(backendFidelity, parkedArgs);
153
158
  if (!presented.ok) {
@@ -177,7 +182,10 @@ export function prepareParkAsk(input) {
177
182
  `${reprojected.action === "deny" && reprojected.message ? `: ${reprojected.message}` : ""} — ` +
178
183
  `refusing to file a row whose executable form nothing adjudicated`);
179
184
  }
185
+ if (reprojected.action === "ask")
186
+ storedShapeFacts = ownedClearanceFacts(reprojected);
180
187
  }
188
+ const rowRealApproval = realApproval ?? (storedShapeFacts?.requiresRealApproval === true ? { origin: carry?.origin ?? wordlessDemand(req.toolName) } : undefined);
181
189
  if (offloadStore && isVolatileOffloadStore(offloadStore) && !offloadStore.isEmpty()) {
182
190
  throw new ParkRefusal("durable suspend requires a durable toolResultStore (the default InMemoryToolResultStore " +
183
191
  "holds offloaded results that are lost across a cross-replica resume); inject " +
@@ -237,15 +245,15 @@ export function prepareParkAsk(input) {
237
245
  shellGateDoctrine: effectiveShellGate,
238
246
  });
239
247
  gate =
240
- safety !== undefined || realApproval !== undefined
248
+ safety !== undefined || rowRealApproval !== undefined
241
249
  ? {
242
250
  kind: "irreversible_ask",
243
251
  reason: safety !== undefined
244
252
  ? `human approval required before safety-tightened tool "${req.toolName}"`
245
- : `real human approval required for tool "${req.toolName}" (non-budgetable: ${realApproval.origin})`,
253
+ : `real human approval required for tool "${req.toolName}" (non-budgetable: ${rowRealApproval.origin})`,
246
254
  toolName: req.toolName,
247
255
  ...(safety !== undefined ? { safetyAxis: safety } : {}),
248
- ...(realApproval !== undefined ? { realApproval } : {}),
256
+ ...(rowRealApproval !== undefined ? { realApproval: rowRealApproval } : {}),
249
257
  riskDescriptor,
250
258
  }
251
259
  : durableApproval
@@ -264,15 +272,26 @@ export function prepareParkAsk(input) {
264
272
  const scope = durableApproval?.scope || checkpointScopeOf({ principal: spec.principal });
265
273
  const ttlMs = sanitizedTtlMs(durableApproval?.ttlMs);
266
274
  const checkpointState = serializeCheckpointState(remoteHandle, inFlightSpendMicroUsd());
267
- if (realApproval !== undefined && checkpointState.readFace !== undefined) {
275
+ if (rowRealApproval !== undefined && checkpointState.readFace !== undefined) {
268
276
  checkpointState.readFace = { ...checkpointState.readFace, realApproval: true };
269
277
  }
270
278
  const approvalLedger = debitLedger(priorLedger, liveSpendRef.get?.() ?? { costMicroUsd: 0, tokens: 0, turns: 0, walltimeMs: 0 }, resourceTotal, { countSlice: false });
279
+ const rowMatchedAskRule = matchedAskRule ?? storedShapeFacts?.matchedAskRule;
280
+ const clearanceFacts = {
281
+ ...(carry?.mandated === true || askMandateMember(storedShapeFacts).mandated === true ? { mandated: true } : {}),
282
+ ...(rowRealApproval !== undefined ? { requiresRealApproval: true } : {}),
283
+ ...(shadowedRule !== undefined ? { persistedRuleShadowed: shadowedRule } : {}),
284
+ ...(askDecisionReason !== undefined ? { decisionReason: askDecisionReason } : {}),
285
+ ...(rowMatchedAskRule !== undefined ? { matchedAskRule: rowMatchedAskRule } : {}),
286
+ ...(probeMandated === true ? { probeMandated: true } : {}),
287
+ ...(inheritedUnavailableAsks.has(req.toolCallId) ? { inheritedUnresolved: true } : {}),
288
+ ...(segmentCoverage !== undefined ? { segmentCoverage } : {}),
289
+ };
271
290
  const mintedAt = Date.now();
272
291
  cp = {
273
292
  token,
274
293
  checkpointId: mintCheckpointId(),
275
- version: checkpointVersionFor({ resource: false, binding: true, token: approvalLedger.totalTokens !== undefined, orgAdmission: orgAdmissionCheckpointState(), f012: f012CheckpointState(), realApproval: realApproval !== undefined, face: faceCheckpointState() }),
294
+ version: checkpointVersionFor({ resource: false, binding: true, token: approvalLedger.totalTokens !== undefined, orgAdmission: orgAdmissionCheckpointState(), f012: f012CheckpointState(), realApproval: rowRealApproval !== undefined, face: faceCheckpointState() }),
276
295
  scope,
277
296
  sessionId,
278
297
  leafId,
@@ -291,18 +310,10 @@ export function prepareParkAsk(input) {
291
310
  ...(bidi ? { hasBidiControls: true } : {}),
292
311
  };
293
312
  })(),
294
- ...(realApproval !== undefined ? { requiresRealApproval: true } : {}),
313
+ ...(rowRealApproval !== undefined ? { requiresRealApproval: true } : {}),
314
+ ...askMandateMember(clearanceFacts),
295
315
  ...askCarryRowMembers(carry),
296
- ...ruleOffersOf(req.toolName, parkedArgs, {
297
- ...(carry?.mandated === true ? { mandated: true } : {}),
298
- ...(realApproval !== undefined ? { requiresRealApproval: true } : {}),
299
- ...(shadowedRule !== undefined ? { persistedRuleShadowed: shadowedRule } : {}),
300
- ...(askDecisionReason !== undefined ? { decisionReason: askDecisionReason } : {}),
301
- ...(matchedAskRule !== undefined ? { matchedAskRule } : {}),
302
- ...(probeMandated === true ? { probeMandated: true } : {}),
303
- ...(inheritedUnavailableAsks.has(req.toolCallId) ? { inheritedUnresolved: true } : {}),
304
- ...(segmentCoverage !== undefined ? { segmentCoverage } : {}),
305
- }),
316
+ ...ruleOffersOf(req.toolName, parkedArgs, clearanceFacts),
306
317
  boundInputHash: boundInputHashOf(parkedArgs),
307
318
  batchToolCallIds,
308
319
  completedCallIds,
@@ -27,7 +27,8 @@ import type { LockedPreflight } from "../locked-config.js";
27
27
  import type { MaterializedMcp } from "../mcp.js";
28
28
  import type { ResolvedRole } from "../roles.js";
29
29
  import type { RunnerDeps, TaskSpec } from "../types.js";
30
- import type { PrepareResume, PromptFeatureFlags, RunInternals, ToolFaceSnapshot } from "./contracts.js";
30
+ import type { SessionTreeEntry } from "../../internal/harness-types.js";
31
+ import type { DateAnchorRead, PrepareResume, PromptFeatureFlags, RunInternals, ToolFaceSnapshot } from "./contracts.js";
31
32
  import type { AdvertisedWritableDirs } from "./advertised-writable-dirs.js";
32
33
  import { type GitStatusLaneRef } from "./git-status-frame.js";
33
34
  import { type ContextWindowOverlay } from "../context-settings.js";
@@ -99,6 +100,10 @@ export interface PreparePromptInputsInput {
99
100
  advertisedWritableDirs?: AdvertisedWritableDirs;
100
101
  /** borrowed-readonly — the acquired session's id (operator-line context). */
101
102
  sessionId: string;
103
+ /** borrowed-readonly — the acquired session; only `getBranch` is read (the date anchor). */
104
+ session: {
105
+ getBranch(): Promise<ReadonlyArray<SessionTreeEntry>>;
106
+ };
102
107
  /** borrowed-readonly — the deployment's window overlay for this leg, as it reads at PREPARE. The prompt's
103
108
  * context-management sentence must not claim mid-task summarization a deployment has turned off for this
104
109
  * model; the seat is live, so a later swap's effect on the SENTENCE lands at the next prepare while its
@@ -123,6 +128,8 @@ export interface PreparePromptInputsResult {
123
128
  tzValid: boolean;
124
129
  /** owned — the client's declared zone as given (paired with `tzValid`; unvalidated on its own). */
125
130
  userTz: string | undefined;
131
+ /** owned — the session's date anchor as read here; `envFacts.date` is its prefix date when present. */
132
+ dateAnchor: DateAnchorRead | undefined;
126
133
  /** owned — the git-status lane's run-local state (empty on a hands-less leg); the run loop and the checkpoint
127
134
  * serializer mutate its fields from here on (`announced`, `mirrorOwed`, …; the frame's receipt rides the leg's shared `Prepared.frameReceipts`). */
128
135
  gitStatusRef: GitStatusLaneRef;
@@ -1,11 +1,12 @@
1
1
  import { defaultPromptProvider, formatLocalDate, isValidTimeZone } from "../../prompts/default.js";
2
2
  import { isIsolated } from "../remote-env.js";
3
+ import { readDateAnchor } from "./announce-once-ledger.js";
3
4
  import { probeGitStatusLane } from "./git-status-frame.js";
4
5
  import { fenceMcpServerInstructions } from "./turn-attachments.js";
5
6
  const ULTRA_REASONING_TIERS = new Set(["xhigh", "max"]);
6
7
  import { compactionEnabled } from "../context-settings.js";
7
8
  export async function preparePromptInputs(input) {
8
- const { spec, deps, failClosedReason, lockedPreflight, selfOrchestrationActive, executionEnv, reminderMark, resolvedReadFace, resolvedWriteFace, toolFaceSnapshot, promptProfile, fableMitigations, internals, thinking, ownedEnv, delegation, resolvedRole, mcp, model, externalContentTargetActive, resume, handsEnabled, taskRootFinal, additionalRootsCanonical, additionalReadRootsCanonical, sessionId, advertisedWritableDirs } = input;
9
+ const { spec, deps, failClosedReason, lockedPreflight, selfOrchestrationActive, executionEnv, reminderMark, resolvedReadFace, resolvedWriteFace, toolFaceSnapshot, promptProfile, fableMitigations, internals, thinking, ownedEnv, delegation, resolvedRole, mcp, model, externalContentTargetActive, resume, handsEnabled, taskRootFinal, additionalRootsCanonical, additionalReadRootsCanonical, sessionId, session, advertisedWritableDirs } = input;
9
10
  const provider = spec.promptProvider ?? deps.promptProvider ?? defaultPromptProvider;
10
11
  const promptPolicyEnabled = Boolean(lockedPreflight.toolPolicy);
11
12
  const promptHooks = spec.hooks ?? deps.hooks;
@@ -37,7 +38,8 @@ export async function preparePromptInputs(input) {
37
38
  : undefined;
38
39
  const userTz = spec.clientContext?.timeZone;
39
40
  const tzValid = userTz !== undefined && isValidTimeZone(userTz);
40
- const envFacts = { date: formatLocalDate(new Date(), tzValid ? userTz : undefined), modelId: model.id };
41
+ const dateAnchor = await readDateAnchor(session);
42
+ const envFacts = { date: dateAnchor?.current?.prefixDate ?? formatLocalDate(new Date(), tzValid ? userTz : undefined), modelId: model.id };
41
43
  if (tzValid)
42
44
  envFacts.timeZone = userTz;
43
45
  if (spec.clientContext?.userEmail)
@@ -141,5 +143,5 @@ export async function preparePromptInputs(input) {
141
143
  taskRoot: taskRootFinal,
142
144
  onDegrade: (reason) => deps.onError?.(new Error(`env git snapshot degraded — ${reason}`), { phase: "degraded", sessionId, classification: "env-git-snapshot" }),
143
145
  });
144
- return { provider, featureFlags, userSystemPrompt, userAppendSystemPrompt, mcpInstructionsBlock, envFacts, tzValid, userTz, gitStatusRef };
146
+ return { provider, featureFlags, userSystemPrompt, userAppendSystemPrompt, mcpInstructionsBlock, envFacts, tzValid, userTz, dateAnchor, gitStatusRef };
145
147
  }
@@ -283,7 +283,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
283
283
  let shellGatedTools = new Set();
284
284
  refuseRequireExistingWithoutSession(spec);
285
285
  refuseRegistryScopeMismatch(spec, internals);
286
- const { acquired, session, conflictRef, wakeRecovered, resumeAtBeforeParentId } = await prepareAcquireReconcile({ sessions, spec, resume, toolEffects, ...(internals?.sessionPlacement !== undefined ? { placement: internals.sessionPlacement } : {}), ...(() => { const g = durableParkGapFor(deps, spec); return g !== undefined ? { durableParkGap: g } : {}; })() });
286
+ const { acquired, session, conflictRef, wakeRecovered } = await prepareAcquireReconcile({ sessions, spec, resume, toolEffects, ...(internals?.sessionPlacement !== undefined ? { placement: internals.sessionPlacement } : {}), ...(() => { const g = durableParkGapFor(deps, spec); return g !== undefined ? { durableParkGap: g } : {}; })() });
287
287
  const sessionId = acquired.sessionId;
288
288
  const onceLedger = await loadAnnounceOnceLedger(session, resume?.seed.announcedListings, deps.onError);
289
289
  const hostTaskId = spec.taskId ?? sessionId;
@@ -382,7 +382,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
382
382
  const ownedEnv = ownedEnvSeat.current;
383
383
  const { taskRootFinal, rebaseRestoredPath } = await prepareWorkspaceRestore({ ownedEnv, deps, spec, internals, resume, taskRootInitial, abortController, sessionId });
384
384
  const { canonical: taskRootCanonical } = await resolveTaskRootCanonical({ env: executionEnv, given: taskRootFinal, onNotice: deps.onNotice, sessionId, runId });
385
- const { trackFileEdit, fileHistoryBoundary, restoredFilePaths, rewindNotes, fileHistoryEnabled, historyScope, historyRoot, historyFs } = await prepareFileHistory({ deps, spec, internals, executionEnv, taskRootFinal, handsEnabled, sessionId, session, resumeAtBeforeParentId, abortController });
385
+ const { trackFileEdit, fileHistoryBoundary, restoredFilePaths, rewindNotes, fileHistoryEnabled, fileHistoryFact, historyScope, historyRoot, historyFs } = await prepareFileHistory({ deps, spec, internals, executionEnv, taskRootFinal, handsEnabled, sessionId, session, abortController });
386
386
  const { noteFileEdited, editedFilesSnapshot, harnessRef, toolProgressRef, skillScope, forwardEvent, reviewRequestRef, requestReview, stopRequestedRef, requestStopAfterTurn, planModeRef, enterPlanMode, subagentRetain, worktreeIsolation } = prepareRunRefs({ spec, internals, executionEnv, taskRootFinal });
387
387
  const legContextOverlay = () => runnerSelf?.contextOverlayOf?.(harnessRef.current?.getModelRef() ?? resolvedRole.modelRef);
388
388
  let resolvedReadFace;
@@ -521,6 +521,8 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
521
521
  governedProvenance: orgGovernedProvenance,
522
522
  },
523
523
  });
524
+ if (memoryEngineSession !== undefined)
525
+ rollback.push(() => memoryEngineSession.release());
524
526
  memoryAdmittedOrgScopesRef.current = memoryAdmittedOrgScopes;
525
527
  ownOrgVerdictRef.current = memoryOwnOrgVerdict ?? priorOwnOrgVerdict;
526
528
  if (internals?.ownOrgAdmissionRef !== undefined && ownOrgVerdictRef.current !== undefined) {
@@ -594,7 +596,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
594
596
  }
595
597
  const projectContext = await prepareProjectContext({ deps, spec, internals, session, sessionId, hostTaskId, taskRootFinal, handsEnabled, delegation, seedContextFiles, memoryBlockFromEngine, skillScope, roster, toolFaceSnapshot, onceLedger, memoryTools, memoryEngineSession, memorySearchToolsPlanned, memoryPairExcludedName, memoryPairOccupiedName, resume, skillListingBudget: doors.skillListingBudget });
596
598
  const { memoryBlock: memoryBlockWithProject, instructionSources, projectInstructionContent, hasSkillManifest, skillsListing, sharedMemoryPairMounted, memoryEnginePairMounted } = projectContext;
597
- const { provider, featureFlags, userSystemPrompt, userAppendSystemPrompt, mcpInstructionsBlock, envFacts, tzValid, userTz, gitStatusRef } = await preparePromptInputs({ spec, deps, contextOverlay: legContextOverlay(), failClosedReason: selfOrchestrationFailClosedReason(spec, deps), lockedPreflight, selfOrchestrationActive, executionEnv, reminderMark, resolvedReadFace, resolvedWriteFace, toolFaceSnapshot, promptProfile, fableMitigations, internals, thinking, ownedEnv, delegation, resolvedRole, mcp, model, externalContentTargetActive, resume, handsEnabled, taskRootFinal, additionalRootsCanonical, additionalReadRootsCanonical, sessionId, ...(advertisedWritableDirs !== undefined ? { advertisedWritableDirs } : {}) });
599
+ const { provider, featureFlags, userSystemPrompt, userAppendSystemPrompt, mcpInstructionsBlock, envFacts, tzValid, userTz, dateAnchor, gitStatusRef } = await preparePromptInputs({ spec, deps, contextOverlay: legContextOverlay(), failClosedReason: selfOrchestrationFailClosedReason(spec, deps), lockedPreflight, selfOrchestrationActive, executionEnv, reminderMark, resolvedReadFace, resolvedWriteFace, toolFaceSnapshot, promptProfile, fableMitigations, internals, thinking, ownedEnv, delegation, resolvedRole, mcp, model, externalContentTargetActive, resume, handsEnabled, taskRootFinal, additionalRootsCanonical, additionalReadRootsCanonical, sessionId, session, ...(advertisedWritableDirs !== undefined ? { advertisedWritableDirs } : {}) });
598
600
  const { deferred, memoryBlock, toolSearch: toolSearchPolicy } = prepareDeferClassify({ spec, deps, roster, toolFaceSnapshot, handsEnabled, fullShellReachable, promptProfile, model, mcp, a2a, sharedMemoryPairMounted, memoryEnginePairMounted, memoryBlock: memoryBlockWithProject, memoryRecallSegment, onceLedger, sessionId });
599
601
  prepareMemoryEngineSession({ memoryEngineSession, internals, memoryDelegationEvidence, externalContentTargetActive, lockedPreflight, mcp, sessionId, runId, deps, provenanceForChildrenRef, delegationSettlementRef, spec, envHandToolNames, roster, contentOriginWrapRef });
600
602
  const { systemPromptSeat, renderWithDate, systemBlocks, promptManifest, epochDeclaredSections, epochArtifactDigestForSnapshot, buildAssembleInputs, centerAdoptionRef } = await preparePromptAssembly({ session, deps, internals, resume, provider, userSystemPrompt, userAppendSystemPrompt, featureFlags, mcpInstructionsBlock, memoryBlock, envFacts, promptProfile, fableMitigations, tools, model, sessionId, reminderMark, onceLedger });
@@ -608,7 +610,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
608
610
  declaredCards: toolRoster.entries.flatMap((e) => e.renderHints?.resultCards ?? []),
609
611
  onUndeclared: (type) => deliverEngineNotice(deps.onNotice, { code: "config.tool_card_undeclared", message: `a tool minted a \`details.type\` card ${JSON.stringify(type)} its definition never declared — dropped from tool_end.structured (declare it on the definition's catalog row or the caller's renderHints.resultCards)`, detail: { type, sessionId, runId } }),
610
612
  });
611
- const { agentListing, announcedListingsRef, dateChange } = prepareListings({ spec, tools, onceLedger, sessionId, toolFaceSnapshot, activeTools, resume, skillsListing, listingBudget: doors.skillListingBudget, listingRideRef, renderWithDate, envFacts, tzValid, userTz });
613
+ const { agentListing, announcedListingsRef, dateChange } = prepareListings({ spec, tools, onceLedger, sessionId, toolFaceSnapshot, activeTools, resume, skillsListing, listingBudget: doors.skillListingBudget, listingRideRef, renderWithDate, envFacts, tzValid, userTz, dateAnchor });
612
614
  const lastBrainContextRef = {};
613
615
  const requestLossyRef = { current: false };
614
616
  const staleOffloadWrittenRefs = new Set();
@@ -707,7 +709,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
707
709
  }
708
710
  }
709
711
  const { hooks, hookTimeoutMs, preToolUseObservational, ownGatePreToolUse, basePolicyForResumeEdit, denyNarrowingPolicy, policyLayers, effectivePolicy, inheritedUnavailableAsks, inheritedAskGrants, askSourceIdentity, riskAxesOf, ruleOffersOf, permissionRuleLane, permissionRuleOrgLane, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, foldAskClasses, ancestorSandboxAdmissions } = await preparePolicyChain({ spec, deps, internals, sessionId, runId, hostTaskId, taskRootFinal, executionEnv, lockedPreflight, tools, harnessTools, toolEffects, egressTools, irreversibilityTier, axisExplicitNegatives, shellGatedTools, envHandToolNames, handsCwdRef, readDenyMatcher, questionToolMounted, runtimeCaps, inheritedAncestorRules, ancestorSessionRulesRef, inheritedParentConstraints, seedInheritedGate, hasSkillManifest, skillScope, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, autoModeDecider, stopForDenialLimit, delegation, abortController, now, ownSessionRulesRef });
710
- const { onAsk, preToolContexts, blockedToolCalls, gateOutcomes, batchHaltRef, blockedTracked, incompleteSuspendAdapter, durableSuspendInfraReady, resourceSuspendEligible, usageGovernance, durableApproval, wiringManifest, writeProtectionCheck, parkLaneArmed, gateMachineryActive, hookIdentity, hookEnvFace, sessionBoxBound } = prepareWiringManifest({ spec, deps, internals, resume, sessionId, runId, hostTaskId, taskScope, hooks, preToolUseObservational, policyLayers, effectivePolicy, handsEnabled, taskRootFinal, mcp, irreversibleTools, egressTools, shellReadStationArmed: shellReadCheck !== undefined, toolEffects, ownedEnv, executionEnv, offloadStore, onceLedger, usageWindows, envLifetimeSuspendAt, runtimeCaps, resolvedInteractionPosture, durableQuestionFace, liveQuestionFace, checkpointStore, sessions, modelGateManifest, autoModeArmReason, lockedPreflight, peerLaneRefs, frameSettlement, harness, pausedRef, frozenOnAsk, liveInheritedGate, delegation, toolRoster, readDenyBuiltinTiersActive: handsReadFace.readDenyBuiltinTiersActive, lspManagerWired, lspDiagnosticsLive: lspDiagnostics !== undefined, sessionBox });
712
+ const { onAsk, preToolContexts, blockedToolCalls, gateOutcomes, batchHaltRef, blockedTracked, incompleteSuspendAdapter, durableSuspendInfraReady, resourceSuspendEligible, usageGovernance, durableApproval, wiringManifest, writeProtectionCheck, parkLaneArmed, gateMachineryActive, hookIdentity, hookEnvFace, sessionBoxBound } = prepareWiringManifest({ spec, deps, internals, resume, sessionId, runId, hostTaskId, taskScope, hooks, preToolUseObservational, policyLayers, effectivePolicy, handsEnabled, taskRootFinal, mcp, irreversibleTools, egressTools, shellReadStationArmed: shellReadCheck !== undefined, toolEffects, ownedEnv, executionEnv, offloadStore, onceLedger, usageWindows, envLifetimeSuspendAt, runtimeCaps, resolvedInteractionPosture, durableQuestionFace, liveQuestionFace, checkpointStore, sessions, modelGateManifest, autoModeArmReason, lockedPreflight, peerLaneRefs, frameSettlement, harness, pausedRef, frozenOnAsk, liveInheritedGate, delegation, toolRoster, readDenyBuiltinTiersActive: handsReadFace.readDenyBuiltinTiersActive, lspManagerWired, lspDiagnosticsLive: lspDiagnostics !== undefined, fileHistoryFact, sessionBox });
711
713
  if (fileHistoryBoundary !== undefined) {
712
714
  harness.on("tool_call", async () => {
713
715
  await fileHistoryBoundary.settle();
@@ -118,6 +118,7 @@ export interface PrepareWiringManifestInput {
118
118
  readDenyBuiltinTiersActive: readonly string[];
119
119
  /** borrowed-readonly — from the LSP phase's manager fold: gates the manifest's LSP section (absent ⇒ byte-identical manifest). */ lspManagerWired: boolean;
120
120
  /** borrowed-readonly — from the LSP phase: is the diagnostics lane live? The `lane` word's only input. */ lspDiagnosticsLive: boolean;
121
+ /** borrowed-readonly — from the file-history phase's one fold of the two off switches: the manifest's word, relayed. */ fileHistoryFact: NonNullable<WiringManifest["fileHistory"]>;
121
122
  /** borrowed-readonly — the arming outcome the caps phase minted (the manifest's auto-mode face). */
122
123
  autoModeArmReason: AutoModeArmFact;
123
124
  /** borrowed-readonly — the frozen preflight; only `mcp` (the declared servers the manifest face joins). */
@@ -116,7 +116,7 @@ function announceDurableGateUnavailable(args) {
116
116
  });
117
117
  }
118
118
  export function prepareWiringManifest(input) {
119
- const { spec, deps, internals, resume, sessionId, runId, hostTaskId, taskScope, hooks, preToolUseObservational, policyLayers, effectivePolicy, handsEnabled, taskRootFinal, mcp, irreversibleTools, egressTools, toolEffects, ownedEnv, executionEnv, offloadStore, onceLedger, usageWindows, envLifetimeSuspendAt, runtimeCaps, resolvedInteractionPosture, durableQuestionFace, liveQuestionFace, checkpointStore, sessions, modelGateManifest, autoModeArmReason, lockedPreflight, peerLaneRefs, frameSettlement, sessionBox, harness, pausedRef, frozenOnAsk, liveInheritedGate, delegation, toolRoster, readDenyBuiltinTiersActive, lspManagerWired, shellReadStationArmed, lspDiagnosticsLive } = input;
119
+ const { spec, deps, internals, resume, sessionId, runId, hostTaskId, taskScope, hooks, preToolUseObservational, policyLayers, effectivePolicy, handsEnabled, taskRootFinal, mcp, irreversibleTools, egressTools, toolEffects, ownedEnv, executionEnv, offloadStore, onceLedger, usageWindows, envLifetimeSuspendAt, runtimeCaps, resolvedInteractionPosture, durableQuestionFace, liveQuestionFace, checkpointStore, sessions, modelGateManifest, autoModeArmReason, lockedPreflight, peerLaneRefs, frameSettlement, sessionBox, harness, pausedRef, frozenOnAsk, liveInheritedGate, delegation, toolRoster, readDenyBuiltinTiersActive, lspManagerWired, shellReadStationArmed, lspDiagnosticsLive, fileHistoryFact } = input;
120
120
  const onAsk = spec.onAsk ?? deps.onAsk;
121
121
  const handWriteTools = toolRoster.entries.filter((e) => e.mountedBy === "hands" && (e.effect === "write" || e.effect === "idempotent")).map((e) => e.name);
122
122
  const hasEffectAwareGate = Boolean(policyLayers.length > 0 || (hooks?.preToolUse !== undefined && !preToolUseObservational));
@@ -218,6 +218,7 @@ export function prepareWiringManifest(input) {
218
218
  tools: toolRoster,
219
219
  hooks: wiredHookEntries(hooks, spec.hooks !== undefined ? "spec" : "deps", preToolUseObservational),
220
220
  ...(lspManagerWired ? { lsp: deriveLspSeam(toolRoster.entries.some((e) => e.contract.contractId === LSP_CONTRACT_ID), lspDiagnosticsLive) } : {}),
221
+ fileHistory: fileHistoryFact,
221
222
  });
222
223
  peerLaneRefs.askEffective = wiringManifest.ask.effective;
223
224
  const sessionBoxBound = sessionBox !== undefined && internals?.onTaskNotification !== undefined ? sessionBox : undefined;
@@ -14,7 +14,7 @@ export async function runAttachmentSeats(input) {
14
14
  const listingsLive = (rs.attach.agentListingOn && prepared.agentListing !== undefined) || (rs.attach.skillsListingOn && prepared.skillsListing !== undefined);
15
15
  const backgroundTasksLive = (rs.attach.attachmentsCfg?.backgroundTasks ?? eventDefaultOn("background_tasks")) === true;
16
16
  rs.attach.attachState = rs.attach.attachmentsCfg !== undefined || listingsLive || backgroundTasksLive ? createAttachmentState() : undefined;
17
- rs.attach.dateState = prepared.dateChange !== undefined ? { announcedDate: prepared.dateChange.legDate } : undefined;
17
+ rs.attach.dateState = prepared.dateChange !== undefined ? { announcedDate: prepared.dateChange.anchor?.current?.announcedDate ?? prepared.dateChange.legDate } : undefined;
18
18
  rs.attach.instrProbe = runner.deps.probeInstructionSources;
19
19
  rs.attach.instrState =
20
20
  rs.attach.instrProbe !== undefined && prepared.instructionSources !== undefined && prepared.instructionSources.length > 0