@sema-agent/core 7.21.1 → 7.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +290 -1
- package/dist/agents/send-message-tool.js +1 -0
- package/dist/agents/subagent.d.ts +1 -0
- package/dist/agents/subagent.js +2 -1
- package/dist/core/ask-origin.d.ts +1 -0
- package/dist/core/ask-origin.js +3 -2
- package/dist/core/auto-compaction.d.ts +2 -2
- package/dist/core/auto-mode-rebuild.js +6 -2
- package/dist/core/auto-mode.d.ts +40 -18
- package/dist/core/auto-mode.js +63 -45
- package/dist/core/checkpoint-store.d.ts +9 -13
- package/dist/core/context-edit.js +1 -1
- package/dist/core/engine-notice.d.ts +62 -1
- package/dist/core/engine-notice.js +14 -1
- package/dist/core/gate-bounded-await.d.ts +13 -3
- package/dist/core/gate-fold.js +3 -3
- package/dist/core/governance-codes.d.ts +1 -1
- package/dist/core/governance-codes.js +6 -0
- package/dist/core/mcp.d.ts +65 -0
- package/dist/core/mcp.js +190 -41
- package/dist/core/memory-engine/consolidation.d.ts +5 -0
- package/dist/core/memory-engine/consolidation.js +7 -3
- package/dist/core/memory-engine/engine.d.ts +8 -0
- package/dist/core/memory-engine/engine.js +25 -19
- package/dist/core/memory-engine/layout.d.ts +47 -9
- package/dist/core/memory-engine/layout.js +157 -57
- package/dist/core/memory-engine/session-incarnation.d.ts +27 -0
- package/dist/core/memory-engine/session-incarnation.js +63 -0
- package/dist/core/parent-spec-seat.d.ts +15 -3
- package/dist/core/parent-spec-seat.js +5 -0
- package/dist/core/park-selfcheck.js +1 -1
- package/dist/core/path-identity.d.ts +11 -4
- package/dist/core/path-identity.js +5 -2
- package/dist/core/permission-rule-model.d.ts +1 -2
- package/dist/core/read-root-candidate.js +11 -1
- package/dist/core/retention.d.ts +8 -1
- package/dist/core/retention.js +2 -0
- package/dist/core/runner/assemble-result.d.ts +2 -7
- package/dist/core/runner/assemble-result.js +25 -8
- package/dist/core/runner/classifier-ladder.js +1 -0
- package/dist/core/runner/contracts.d.ts +26 -15
- package/dist/core/runner/inherited-ask-grants.d.ts +2 -7
- package/dist/core/runner/inherited-ask-grants.js +1 -0
- package/dist/core/runner/mcp-redial.d.ts +109 -0
- package/dist/core/runner/mcp-redial.js +60 -0
- package/dist/core/runner/memory-consolidation-driver.d.ts +2 -0
- package/dist/core/runner/prepare-ask-lane.js +1 -0
- package/dist/core/runner/prepare-caps-and-workflow.js +9 -12
- package/dist/core/runner/prepare-context-lane.d.ts +43 -1
- package/dist/core/runner/prepare-context-lane.js +25 -4
- package/dist/core/runner/prepare-hands-readface.d.ts +3 -0
- package/dist/core/runner/prepare-hands-readface.js +13 -3
- package/dist/core/runner/prepare-memory.js +3 -3
- package/dist/core/runner/prepare-protocol-tools.d.ts +6 -1
- package/dist/core/runner/prepare-protocol-tools.js +20 -38
- package/dist/core/runner/prepare-task.js +4 -4
- package/dist/core/runner/prepare-turn-wiring.js +2 -2
- package/dist/core/runner/prepare-wiring-manifest.d.ts +4 -0
- package/dist/core/runner/prepare-wiring-manifest.js +2 -1
- package/dist/core/runner/run-harness-handlers.js +4 -2
- package/dist/core/runner/run-identity-wiring.d.ts +3 -1
- package/dist/core/runner/run-identity-wiring.js +4 -1
- package/dist/core/runner/run-recovery-lanes.js +6 -3
- package/dist/core/runner/run-settle-and-teardown.d.ts +3 -1
- package/dist/core/runner/run-settle-and-teardown.js +6 -2
- package/dist/core/runner/run-telemetry-and-budget-seats.js +11 -1
- package/dist/core/runner/run-terminal-adoption.d.ts +4 -1
- package/dist/core/runner/run-terminal-adoption.js +2 -6
- package/dist/core/runner/runtask.js +8 -5
- package/dist/core/runner/stream-lifecycle-verbs.d.ts +5 -1
- package/dist/core/runner/stream-lifecycle-verbs.js +23 -2
- package/dist/core/runner/write-protection-station.d.ts +7 -25
- package/dist/core/runner/write-protection-station.js +18 -0
- package/dist/core/runner-deps.d.ts +16 -7
- package/dist/core/skill-listing-budget.d.ts +5 -4
- package/dist/core/task-registry.d.ts +0 -6
- package/dist/core/task-result.d.ts +31 -12
- package/dist/core/task-spec.d.ts +2 -1
- package/dist/core/task-stream.d.ts +26 -0
- package/dist/core/tool-spec.d.ts +5 -1
- package/dist/core/trace.d.ts +5 -0
- package/dist/core/types.d.ts +3 -3
- package/dist/core/types.js +1 -1
- package/dist/core/wiring-manifest.d.ts +23 -0
- package/dist/core/wiring-manifest.js +3 -0
- package/dist/core/write-protect.d.ts +64 -12
- package/dist/core/write-protect.js +88 -34
- package/dist/engine/execution-env/node-execution-env.d.ts +19 -2
- package/dist/engine/execution-env/node-execution-env.js +5 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +2 -2
- package/dist/orchestration/workflow-governance.js +1 -1
- package/dist/orchestration/workflow-primitives.d.ts +2 -2
- package/dist/tools/fs/bash-program-position.d.ts +26 -5
- package/dist/tools/fs/bash-program-position.js +63 -16
- package/dist/tools/fs/bash-readonly-classifier.d.ts +27 -17
- package/dist/tools/fs/bash-readonly-classifier.js +134 -55
- package/dist/tools/fs/fs-bash.js +43 -18
- package/dist/tools/fs/fs-read.js +2 -1
- package/dist/tools/fs/fs-shared.d.ts +33 -7
- package/dist/tools/fs/fs-shared.js +12 -1
- package/dist/tools/fs/index.d.ts +4 -2
- package/dist/tools/fs/read-deny.d.ts +25 -11
- package/dist/tools/fs/read-deny.js +5 -1
- package/dist/tools/fs/safety.d.ts +38 -4
- package/dist/tools/fs/safety.js +31 -3
- package/package.json +2 -2
- package/test/export-surface.snapshot.json +11 -1
- package/wire-changes/core@7.22.0.json +637 -0
- package/wire-changes/core@7.23.0.json +316 -0
|
@@ -19,7 +19,7 @@ import type { Model } from "../../internal/llm.js";
|
|
|
19
19
|
import { type MaybeCompactOptions } from "../auto-compaction.js";
|
|
20
20
|
import type { SessionStore } from "../session.js";
|
|
21
21
|
import type { PushQueue } from "../push-queue.js";
|
|
22
|
-
import {
|
|
22
|
+
import type { Brain, OwedUserInputAccount, TaskEvent, TaskSpec } from "../types.js";
|
|
23
23
|
import { type Stats } from "./assemble-result.js";
|
|
24
24
|
import type { EndOfTaskCompaction, Prepared, RunnerDepsSeat, RunState } from "./contracts.js";
|
|
25
25
|
export interface RunTerminalAdoptionInput<R> {
|
|
@@ -95,5 +95,8 @@ export interface RunTerminalAdoptionResult {
|
|
|
95
95
|
/** This lane's ONE evaluation of {@link answerSettled}: a clean `"stop"` final with no queued continuation lost. The
|
|
96
96
|
* settle lane hands it to the arbitration (`ResultFlags.answerSettled`), the teardown attribution and the notice. */
|
|
97
97
|
answerSettled: boolean;
|
|
98
|
+
/** The undrained-input account, UNSETTLED: this lane knows every fact but one — whether this leg's consumed
|
|
99
|
+
* checkpoint row comes back — and that one is the next lane's compensation to perform, not to predict. */
|
|
100
|
+
owedUserInput: OwedUserInputAccount;
|
|
98
101
|
}
|
|
99
102
|
export declare function runTerminalAdoption<R>(input: RunTerminalAdoptionInput<R>): Promise<R>;
|
|
@@ -3,7 +3,6 @@ import { DEFAULT_COMPACTION_SETTINGS } from "../../internal/harness.js";
|
|
|
3
3
|
import { eventDefaultOn } from "../../prompt-assembly/event-registry.js";
|
|
4
4
|
import { appendInterruptionMarker, reconcileInterruptedSession } from "../session-reconcile.js";
|
|
5
5
|
import { emitTrace } from "../trace.js";
|
|
6
|
-
import { deliverEngineNotice, owedUserInputCounts, undrainedUserInputNotices } from "../types.js";
|
|
7
6
|
import { answerSettled, errorCodeOf } from "./assemble-result.js";
|
|
8
7
|
import { awaitChargeWithSlowDisclosure, discloseUnevaluableWindow } from "./clock-and-limits.js";
|
|
9
8
|
import { buildWorkingFileAttachments, centerAdoptionOption, contextInstructionFilesOption, emitInputTruncated, forkContextOption } from "./compaction-call-options.js";
|
|
@@ -109,10 +108,7 @@ export async function runTerminalAdoption(input) {
|
|
|
109
108
|
}
|
|
110
109
|
migratedParked = prepared.harness.dropParkedUserInputs(carried);
|
|
111
110
|
}
|
|
112
|
-
const
|
|
113
|
-
for (const notice of undrainedUserInputNotices(owed, spec.taskId ?? prepared.sessionId, prepared.sessionId, prepared.runId)) {
|
|
114
|
-
deliverEngineNotice(runner.deps.onNotice, notice);
|
|
115
|
-
}
|
|
111
|
+
const owedUserInput = { held: undrainedUserAtEnd.current, migrated: migratedParked, continuation: { frames: prepared.undeliveredContinuationRef.current.parkedSteers, carried: carriedContinuation } };
|
|
116
112
|
if (rs.attach.attachState?.postCompactPending === true && (rs.attach.attachmentsCfg?.backgroundTasks ?? eventDefaultOn("background_tasks")) === true) {
|
|
117
113
|
emitTrace(rs.telemetry.tracer, () => ({ kind: "compaction.announce_dropped", version: 1, taskId: rs.telemetry.taskId, ts: Date.now() }));
|
|
118
114
|
}
|
|
@@ -125,7 +121,7 @@ export async function runTerminalAdoption(input) {
|
|
|
125
121
|
onCompactionFailed: (reason) => queue.push({ type: "compaction_outcome", outcome: "failed", trigger: "auto", reason, ...ident() }),
|
|
126
122
|
cancelled: abortedLive,
|
|
127
123
|
}, runner, sessions);
|
|
128
|
-
return await next({ threw, comp, answerSettled: settled });
|
|
124
|
+
return await next({ threw, comp, answerSettled: settled, owedUserInput });
|
|
129
125
|
}
|
|
130
126
|
async function finish(spec, prepared, opts, runner, sessions) {
|
|
131
127
|
let comp;
|
|
@@ -296,6 +296,7 @@ export class Runner {
|
|
|
296
296
|
const acceptedSteerInputs = new Map();
|
|
297
297
|
const notifyRef = {};
|
|
298
298
|
const captureOptOutRef = {};
|
|
299
|
+
const mcpRedialRef = {};
|
|
299
300
|
const manualCompactRef = { requested: false, waiters: [] };
|
|
300
301
|
const drainManualCompactWaiters = (outcome) => {
|
|
301
302
|
manualCompactRef.requested = false;
|
|
@@ -348,6 +349,7 @@ export class Runner {
|
|
|
348
349
|
internals: { ...(internals ?? {}), detachHub, forwardScope: createForwardSinkScope(this.deps.onNotice) },
|
|
349
350
|
notifyRef,
|
|
350
351
|
captureOptOutRef,
|
|
352
|
+
mcpRedialRef,
|
|
351
353
|
entryActor,
|
|
352
354
|
entryTracer,
|
|
353
355
|
});
|
|
@@ -383,7 +385,7 @@ export class Runner {
|
|
|
383
385
|
locallyClaimedTokens: this.locallyClaimedTokens, parentConstraintRegistry: this.parentConstraintRegistry, suspendedEnvReaps: this.suspendedEnvReaps,
|
|
384
386
|
});
|
|
385
387
|
const { steer } = streamSteerVerb({ spec, internals, queue, acceptedSteerInputs, live, ready, orTimeout, readyTimeoutMs: READY_TIMEOUT_MS, steeringError, runner: this.depsSeat });
|
|
386
|
-
const { notify, optOutMemoryCapture, compact, detach, interrupt } = streamLifecycleVerbs({ live, ready, orTimeout, steeringError, notifyRef, captureOptOutRef, manualCompactRef, detachHub });
|
|
388
|
+
const { notify, optOutMemoryCapture, reconnectMcpServer, compact, detach, interrupt } = streamLifecycleVerbs({ live, ready, orTimeout, steeringError, notifyRef, captureOptOutRef, mcpRedialRef, manualCompactRef, detachHub });
|
|
387
389
|
const { halt, destroy } = streamHaltVerbs({ spec, live, ready, orTimeout, readyTimeoutMs: READY_TIMEOUT_MS, run, reapSuspended, runner: this.depsSeat });
|
|
388
390
|
return {
|
|
389
391
|
[Symbol.asyncIterator]: () => queue[Symbol.asyncIterator](),
|
|
@@ -398,6 +400,7 @@ export class Runner {
|
|
|
398
400
|
steer,
|
|
399
401
|
notify,
|
|
400
402
|
optOutMemoryCapture,
|
|
403
|
+
reconnectMcpServer,
|
|
401
404
|
compact,
|
|
402
405
|
detach,
|
|
403
406
|
interrupt,
|
|
@@ -406,14 +409,14 @@ export class Runner {
|
|
|
406
409
|
};
|
|
407
410
|
}
|
|
408
411
|
runLocked(input) {
|
|
409
|
-
const { spec, queue, setResult, onSuggestions, onReady, onSuspend, manualCompactRef, taskIdRef, resume, internals, notifyRef, captureOptOutRef, entryActor, entryTracer } = input;
|
|
412
|
+
const { spec, queue, setResult, onSuggestions, onReady, onSuspend, manualCompactRef, taskIdRef, resume, internals, notifyRef, captureOptOutRef, mcpRedialRef, entryActor, entryTracer } = input;
|
|
410
413
|
return runNotificationLane({
|
|
411
414
|
spec, queue, resume, internals, taskIdRef,
|
|
412
415
|
runner: this.depsSeat, self: this, sessions: this.sessions, sessionReadStates: this.sessionReadStates, pendingSessionNotifications: this.pendingSessionNotifications,
|
|
413
416
|
prepareTask,
|
|
414
417
|
next: ({ prepared, injectTaskNotification, deliveredAtTurnOpen, peerInboundChainRef, modelCatalog, notificationLane, unsubscribeTaskNotifications }) => {
|
|
415
418
|
const { runSourceTaskId, parentToolCallId, ident, emitDelegationLifecycle, loopLatch, stats, undrainedUserAtEnd, userInputLostAtEnd } = runIdentityWiring({
|
|
416
|
-
spec, queue, prepared, internals, taskIdRef, onReady, manualCompactRef, notifyRef, captureOptOutRef, injectTaskNotification, deliveredAtTurnOpen, peerInboundChainRef,
|
|
419
|
+
spec, queue, prepared, internals, taskIdRef, onReady, manualCompactRef, notifyRef, captureOptOutRef, mcpRedialRef, injectTaskNotification, deliveredAtTurnOpen, peerInboundChainRef,
|
|
417
420
|
notificationLane, pendingSessionNotifications: this.pendingSessionNotifications, runner: this.depsSeat,
|
|
418
421
|
});
|
|
419
422
|
const rs = createRunState();
|
|
@@ -472,9 +475,9 @@ export class Runner {
|
|
|
472
475
|
next: ({ final, threw, abortedLive, userInterruptedLive, strandedHumanAnswers }) => runTerminalAdoption({
|
|
473
476
|
spec, queue, prepared, rs, stats, ident, emitCommitted, startedToolCallIds, toolLabels, timeout, compactionBrain, compactionBreaker, windowSafetyOptions,
|
|
474
477
|
undrainedUserAtEnd, userInputLostAtEnd, final, threw, abortedLive, userInterruptedLive, runner: this.depsSeat, sessions: this.sessions,
|
|
475
|
-
next: ({ threw, comp, answerSettled }) => runSettleAndTeardown({
|
|
478
|
+
next: ({ threw, comp, answerSettled, owedUserInput }) => runSettleAndTeardown({
|
|
476
479
|
spec, queue, prepared, resume, internals, rs, stats, ident, parentToolCallId, subagentName, loopLatch, timeout, ownCommittedTailRef,
|
|
477
|
-
emitDelegationLifecycle, taskIdRef, manualCompactRef, drainManualCompact, final, threw, abortedLive, userInterruptedLive, answerSettled, strandedHumanAnswers, reasoningResolution, comp,
|
|
480
|
+
emitDelegationLifecycle, taskIdRef, manualCompactRef, drainManualCompact, final, threw, abortedLive, userInterruptedLive, answerSettled, strandedHumanAnswers, reasoningResolution, comp, owedUserInput,
|
|
478
481
|
setResult, onSuggestions, onSuspend, runner: this.depsSeat, sessions: this.sessions,
|
|
479
482
|
}),
|
|
480
483
|
}),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ToolDetachHub } from "../tool-detach.js";
|
|
2
2
|
import type { TaskStream } from "../types.js";
|
|
3
|
-
import type { CaptureOptOutRef, LiveHandle, ManualCompactRef, NotifyRef, TaskStreamLiveSeat } from "./contracts.js";
|
|
3
|
+
import type { CaptureOptOutRef, LiveHandle, ManualCompactRef, McpRedialRef, NotifyRef, TaskStreamLiveSeat } from "./contracts.js";
|
|
4
4
|
export interface StreamLifecycleVerbsInput {
|
|
5
5
|
/** borrowed-readonly — the stream's live state: `resultValue` (the finished-task refusals) and `handle`, read at each call. */
|
|
6
6
|
live: TaskStreamLiveSeat;
|
|
@@ -14,6 +14,8 @@ export interface StreamLifecycleVerbsInput {
|
|
|
14
14
|
notifyRef: NotifyRef;
|
|
15
15
|
/** borrowed-readonly — the capture opt-out bridge; `flip` is bound by the run body when a memory session mounted. */
|
|
16
16
|
captureOptOutRef: CaptureOptOutRef;
|
|
17
|
+
/** borrowed-readonly — the MCP re-dial bridge; `redial` is bound by the run body when the leg declared MCP servers. */
|
|
18
|
+
mcpRedialRef: McpRedialRef;
|
|
17
19
|
/** borrowed-mutable — the manual-compaction request seat: the compact verb arms it and parks its waiter here. */
|
|
18
20
|
manualCompactRef: ManualCompactRef;
|
|
19
21
|
/** borrowed-readonly — the run-local detach hub the detach verb requests through. */
|
|
@@ -24,6 +26,8 @@ export interface StreamLifecycleVerbsResult {
|
|
|
24
26
|
notify: TaskStream["notify"];
|
|
25
27
|
/** The stream's `optOutMemoryCapture` verb. */
|
|
26
28
|
optOutMemoryCapture: TaskStream["optOutMemoryCapture"];
|
|
29
|
+
/** The stream's `reconnectMcpServer` verb. */
|
|
30
|
+
reconnectMcpServer: TaskStream["reconnectMcpServer"];
|
|
27
31
|
/** The stream's `compact` verb. */
|
|
28
32
|
compact: TaskStream["compact"];
|
|
29
33
|
/** The stream's `detach` verb. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isSystemInjectionPriority, SYSTEM_INJECTION_PRIORITIES } from "../task-notification.js";
|
|
2
2
|
export function streamLifecycleVerbs(input) {
|
|
3
|
-
const { live, ready, orTimeout, steeringError, notifyRef, captureOptOutRef, manualCompactRef, detachHub } = input;
|
|
3
|
+
const { live, ready, orTimeout, steeringError, notifyRef, captureOptOutRef, mcpRedialRef, manualCompactRef, detachHub } = input;
|
|
4
4
|
const notify = async (input, opts) => {
|
|
5
5
|
const notifyError = (msg, code) => {
|
|
6
6
|
const e = new Error(`cannot notify: ${msg}`);
|
|
@@ -69,6 +69,27 @@ export function streamLifecycleVerbs(input) {
|
|
|
69
69
|
}
|
|
70
70
|
return captureOptOutRef.flip(reason);
|
|
71
71
|
};
|
|
72
|
+
const reconnectMcpServer = async (server) => {
|
|
73
|
+
const serverIn = server;
|
|
74
|
+
if (typeof serverIn !== "string" || serverIn.length === 0) {
|
|
75
|
+
const e = new Error(`cannot reconnect an MCP server: \`server\` must be a non-empty server name`);
|
|
76
|
+
e.code = "steering.invalid_content";
|
|
77
|
+
throw e;
|
|
78
|
+
}
|
|
79
|
+
if (live.resultValue)
|
|
80
|
+
throw steeringError("the task has already finished");
|
|
81
|
+
const h = live.handle ?? (await orTimeout(ready));
|
|
82
|
+
if (!h)
|
|
83
|
+
throw steeringError("the task is not running");
|
|
84
|
+
if (live.resultValue !== undefined || h.loop.ended)
|
|
85
|
+
throw steeringError("the task is no longer running");
|
|
86
|
+
if (mcpRedialRef.redial === undefined) {
|
|
87
|
+
const e = new Error(`cannot reconnect an MCP server: this run declared no MCP servers — there is nothing to re-dial`);
|
|
88
|
+
e.code = "mcp.reconnect_unavailable";
|
|
89
|
+
throw e;
|
|
90
|
+
}
|
|
91
|
+
return mcpRedialRef.redial(serverIn);
|
|
92
|
+
};
|
|
72
93
|
const compact = async (opts) => {
|
|
73
94
|
if (live.resultValue)
|
|
74
95
|
throw steeringError("the task has already finished");
|
|
@@ -131,5 +152,5 @@ export function streamLifecycleVerbs(input) {
|
|
|
131
152
|
h.abortController.abort();
|
|
132
153
|
void h.harness.abort();
|
|
133
154
|
};
|
|
134
|
-
return { notify, optOutMemoryCapture, compact, detach, interrupt };
|
|
155
|
+
return { notify, optOutMemoryCapture, reconnectMcpServer, compact, detach, interrupt };
|
|
135
156
|
}
|
|
@@ -12,36 +12,18 @@
|
|
|
12
12
|
*
|
|
13
13
|
* Two readers, one compile: the gate station mounts `check`, and the leg's wiring manifest reports
|
|
14
14
|
* `targetView`. Compiling twice would be two judges free to disagree about the seats they were handed.
|
|
15
|
+
*
|
|
16
|
+
* The SECOND absence this seat carries is the per-judgment one: a judge that HAS its target view but
|
|
17
|
+
* whose environment could not answer a particular target drops that view and judges by the spelling alone.
|
|
18
|
+
* That is a run-time fact, so it cannot be announced at compile like the one above — but it is a fact about
|
|
19
|
+
* the ENVIRONMENT rather than about any one write, so it is announced from here, once per leg per reason,
|
|
20
|
+
* and carries no call identity. This is the leg-scoped home the dedupe needs: the judge is compiled once
|
|
21
|
+
* per leg and every judgment of the leg goes through the check minted here.
|
|
15
22
|
*/
|
|
16
23
|
import type { ExecutionEnv } from "../../internal/harness.js";
|
|
17
24
|
import type { RunnerDeps } from "../runner-deps.js";
|
|
18
25
|
import type { ToolRoster } from "../tool-roster.js";
|
|
19
26
|
import { type WriteProtectionMount } from "../write-protect.js";
|
|
20
|
-
/**
|
|
21
|
-
* Compile the leg's write-protection judge and announce a missing target view.
|
|
22
|
-
*
|
|
23
|
-
* Returns the mount, or `undefined` when the deployment emptied the table (`[]`): no judge, no tighten
|
|
24
|
-
* mounted at all, and nothing announced — an explicit opt-out is not a degrade. A garbage table refuses
|
|
25
|
-
* prepare loudly from here, as it did from the gate station before, so an unusable table cannot lie
|
|
26
|
-
* dormant on a write-tool-less task.
|
|
27
|
-
*
|
|
28
|
-
* The notice fires exactly once per prepared leg and only when a judge with NO target view sits beside at
|
|
29
|
-
* least one tool whose writes it covers. Coverage runs the judge's OWN per-call test ({@link
|
|
30
|
-
* protectivePathTargetOf}) rather than a copy of it, over every name a row DISPATCHES under — its own and
|
|
31
|
-
* its aliases, because the gate hands the judge the name the call was made with. A row that declares a
|
|
32
|
-
* path target is covered by that declaration under every name; a row that declares none is covered under
|
|
33
|
-
* whichever of its names the catalog gives a non-read slot to. Both halves are load-bearing: a tool named
|
|
34
|
-
* `Write` that declares nothing, and a tool aliased to `Write` that declares nothing, are each judged by
|
|
35
|
-
* spelling alone on a hands-less leg, and each would otherwise go unnamed by the very line that exists to
|
|
36
|
-
* name them. Reported by the ROW's own name — what the deployment mounted.
|
|
37
|
-
*
|
|
38
|
-
* SNAPSHOT BOUNDARY, deliberate and disclosed: the roster read here is the LEG-START one, the same one
|
|
39
|
-
* the wiring manifest reports and for the same reason — this is one announcement per prepared leg, not a
|
|
40
|
-
* subscription. A run that gains its FIRST covered write tool after prepare (a mid-run roster delta) is
|
|
41
|
-
* judged by the same spelling-only judge and is not announced; the leg's `writeProtection.targetView`
|
|
42
|
-
* still reports the judge's reading correctly, because the judge never gains an environment mid-run —
|
|
43
|
-
* only the covered SET can widen.
|
|
44
|
-
*/
|
|
45
27
|
export declare function mountWriteProtection(input: {
|
|
46
28
|
/** borrowed-readonly — the deployment seats: the table (`writeProtectedPaths`; absent ⇒ the default
|
|
47
29
|
* table, `[]` ⇒ opted out), the data root the memory library is materialized under
|
|
@@ -1,11 +1,29 @@
|
|
|
1
1
|
import { deliverEngineNotice } from "../engine-notice.js";
|
|
2
2
|
import { protectivePathTargetOf } from "../tool-registry.js";
|
|
3
3
|
import { createWriteProtectionCheck } from "../write-protect.js";
|
|
4
|
+
const ABSENCE_REASON = { symlink: "unresolved-symlink", target: "unresolvable-target" };
|
|
4
5
|
export function mountWriteProtection(input) {
|
|
6
|
+
const announced = new Set();
|
|
5
7
|
const mount = createWriteProtectionCheck(input.deps.writeProtectedPaths, {
|
|
6
8
|
...(input.deps.memoryEngineDir !== undefined ? { dataRoot: input.deps.memoryEngineDir } : {}),
|
|
7
9
|
...(input.env !== undefined ? { env: input.env } : {}),
|
|
8
10
|
rootPath: input.rootPath,
|
|
11
|
+
onViewAbsent: (absence) => {
|
|
12
|
+
const reason = absence.unresolvedSymlink ? ABSENCE_REASON.symlink : ABSENCE_REASON.target;
|
|
13
|
+
if (announced.has(reason))
|
|
14
|
+
return;
|
|
15
|
+
announced.add(reason);
|
|
16
|
+
deliverEngineNotice(input.deps.onNotice, {
|
|
17
|
+
code: "config.write_protection_unresolved",
|
|
18
|
+
message: `This run's write-protection judge could not resolve a write target in its execution environment ` +
|
|
19
|
+
`(${reason === ABSENCE_REASON.symlink ? "a symlink whose real target is unknowable" : "the environment refused or errored on the spelling"}: ${absence.cause}). ` +
|
|
20
|
+
`A view that cannot answer does not vote, so that write was judged by its SPELLING against the table and nothing else — ` +
|
|
21
|
+
`a target reaching a protected path only through an alias, a bind mount or a ".." walk is cleared. Nothing about this run was ` +
|
|
22
|
+
`refused because of it, and nothing here is a defect in the write itself: an environment that cannot answer path questions is a ` +
|
|
23
|
+
`deployment fact. Announced once per leg per reason; later writes of the same shape are judged the same way, silently.`,
|
|
24
|
+
detail: { reason, cause: absence.cause, sessionId: input.sessionId, runId: input.runId },
|
|
25
|
+
});
|
|
26
|
+
},
|
|
9
27
|
});
|
|
10
28
|
if (mount === undefined || mount.targetView !== "spelling-only")
|
|
11
29
|
return mount;
|
|
@@ -179,20 +179,21 @@ export interface RunnerDeps {
|
|
|
179
179
|
/**
|
|
180
180
|
* design/199 件B — DEPLOYMENT-layer ADDITIONS to the built-in sensitive-path READ deny set
|
|
181
181
|
* ({@link import("../tools/fs/read-deny.js").READ_FACE_DEFAULT_DENY_ENTRIES}); see
|
|
182
|
-
* {@link TaskSpec.readDenyPatterns} for the judged surfaces. Add-only on
|
|
183
|
-
* the active built-ins and any task-layer additions, and `[]` ≡ absent — narrowing the built-in
|
|
182
|
+
* {@link TaskSpec.readDenyPatterns} for the judged surfaces. INDEPENDENT of the built-in switch. Add-only on
|
|
183
|
+
* THIS seat: unions with the active built-ins and any task-layer additions, and `[]` ≡ absent — narrowing the built-in
|
|
184
184
|
* set is the sibling knobs' job ({@link readDenyBuiltinTiers} / {@link readDenyBuiltinExclude},
|
|
185
185
|
* #245 revision of D-4), not a replacement escape hatch here. Bad entry shapes refuse loudly at
|
|
186
186
|
* prepare (#123).
|
|
187
187
|
*/
|
|
188
188
|
readDenyPatterns?: readonly import("../tools/fs/read-deny.js").ReadDenyEntry[];
|
|
189
189
|
/**
|
|
190
|
-
* The deployment's built-in deny-table TIER selection
|
|
191
|
-
* EXACTLY the listed tiers of
|
|
190
|
+
* The deployment's built-in deny-table TIER selection — the ON/OFF switch for the whole built-in
|
|
191
|
+
* table, OFF unless this seat says otherwise. EXACTLY the listed tiers of
|
|
192
192
|
* {@link import("../tools/fs/read-deny.js").READ_FACE_BUILTIN_DENY_TABLE} are active (`[]` = none —
|
|
193
|
-
* explicit and legal);
|
|
194
|
-
*
|
|
195
|
-
*
|
|
193
|
+
* explicit and legal); ABSENT = {@link import("../tools/fs/read-deny.js").READ_DENY_DEFAULT_TIERS},
|
|
194
|
+
* which is EMPTY: an unconfigured deployment activates no built-in row, so nothing from that table
|
|
195
|
+
* refuses a read or demotes a shell one. A leg's active tiers are REPORTED on its wiring manifest
|
|
196
|
+
* ({@link import("./wiring-manifest.js").WiringManifest.readDeny}). Composes with
|
|
196
197
|
* {@link readDenyBuiltinExclude} (tiers first, then row removal); never touches the additions
|
|
197
198
|
* seats or the write faces. Unknown tier names refuse loudly at prepare (#123). DEPLOYMENT seat
|
|
198
199
|
* ONLY: deliberately not a TaskSpec key and not in the governed workflow whitelist — a task or
|
|
@@ -324,6 +325,14 @@ export interface RunnerDeps {
|
|
|
324
325
|
memoryCaptureRecordStore?: (plane: {
|
|
325
326
|
controlDir: string;
|
|
326
327
|
}) => import("./memory-engine/layout.js").SessionCaptureRecordStore;
|
|
328
|
+
/** which occupant of a session id is running now (a purge may delete a session tree and the
|
|
329
|
+
* id be handed out again; without this seat a standing opt-out or pollution record binds the NEXT
|
|
330
|
+
* occupant too). An opaque token, STABLE for one occupant's life, DIFFERENT for the next, only
|
|
331
|
+
* ever compared ({@link import("./memory-engine/layout.js").sessionRecordBindsIncarnation}).
|
|
332
|
+
* ABSENT ⇒ records bind by id (the pre-incarnation bytes); an empty or throwing answer reads the same. */
|
|
333
|
+
memorySessionIncarnation?: (session: {
|
|
334
|
+
sessionId: string;
|
|
335
|
+
}) => string | undefined;
|
|
327
336
|
/**
|
|
328
337
|
* design/339 §6.1 — the v3 memory-consolidation switch, threaded verbatim to the engine seat
|
|
329
338
|
* ({@link import("../core/memory-engine/engine.js").MemoryEngineOptions.consolidation} — same
|
|
@@ -65,10 +65,11 @@ export interface ResolvedSkillListingBudget {
|
|
|
65
65
|
* (`200 000 × 4 × 0.01` = 8 000 bytes).
|
|
66
66
|
*
|
|
67
67
|
* The window is `contextTokens ?? contextWindow`, the same physical coordinate the deferral gate
|
|
68
|
-
* measures against.
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
68
|
+
* measures against. `contextTokens: 0` (or any other non-finite/non-positive declared value) does
|
|
69
|
+
* NOT fall through `??` to `contextWindow` — `0` is not nullish — so it lands here as a
|
|
70
|
+
* declared-but-unusable window, and this seat folds it to {@link SKILL_LISTING_DEFAULT_CONTEXT_TOKENS}
|
|
71
|
+
* the same as a genuinely absent window: one rule, not a case per bad shape, because this seat's
|
|
72
|
+
* job is to always hand a renderer a usable number.
|
|
72
73
|
*/
|
|
73
74
|
export declare function resolveSkillListingBudget(opts: {
|
|
74
75
|
fraction?: unknown;
|
|
@@ -185,10 +185,6 @@ export declare class TaskRegistry {
|
|
|
185
185
|
tupleIncomplete: true;
|
|
186
186
|
})>>;
|
|
187
187
|
};
|
|
188
|
-
/** design/151 §7.7 (F-13) — the row's mailbox dies with the row: a WINNING delete also drops
|
|
189
|
-
* the (scope, handle) mailbox (advisory — a mailbox fault never blocks the reap; an orphaned
|
|
190
|
-
* box is bounded by the mailbox's own `reap` policy). Structural face (drop only), so the
|
|
191
|
-
* deployment passes its `RunnerDeps.mailboxStore` directly. */
|
|
192
188
|
mailbox?: {
|
|
193
189
|
drop(scope: string, handle: string): Promise<void>;
|
|
194
190
|
};
|
|
@@ -634,8 +630,6 @@ export declare class TaskRegistry {
|
|
|
634
630
|
private pollBackgroundBash;
|
|
635
631
|
private pollWorkflow;
|
|
636
632
|
private stopBackgroundBash;
|
|
637
|
-
/** design/135 G2: TaskOutput over a monitor — a RE-READABLE spool snapshot (the watcher owns the env
|
|
638
|
-
* cursor, exactly the bash G2b spool posture): repeated polls return the same accumulated output. */
|
|
639
633
|
private pollMonitor;
|
|
640
634
|
private stopMonitor;
|
|
641
635
|
private stopWorkflow;
|
|
@@ -38,6 +38,30 @@ export type TaskStatus = "completed" | "blocked" | "failed" | "suspended" | "nee
|
|
|
38
38
|
* One remote-workspace lifecycle failure, reported as data on {@link TaskResult.remoteEnvFailures}.
|
|
39
39
|
* See that field for why the eleven-code taxonomy needed a structured channel to reach a caller at all.
|
|
40
40
|
*/
|
|
41
|
+
/**
|
|
42
|
+
* ONE `humanReview` ledger row — what `stats.humanReview.gates[]` carries, what the runner's live
|
|
43
|
+
* accumulator holds, and what a checkpoint persists. It lived as six structurally-identical inline
|
|
44
|
+
* copies, the persisted one NARROWER than the rest, so "does a row carry the call it gated?" had six
|
|
45
|
+
* answers and the persisted one said no while the bytes it stored said yes. One declaration now.
|
|
46
|
+
*/
|
|
47
|
+
export interface HumanReviewGateRow {
|
|
48
|
+
/** `kind` / `decision` / `toolName` / `toolArg` are documented once, on `stats.humanReview.gates`. */
|
|
49
|
+
kind: string;
|
|
50
|
+
waitMs: number;
|
|
51
|
+
decision?: string;
|
|
52
|
+
toolName?: string;
|
|
53
|
+
toolArg?: string;
|
|
54
|
+
/**
|
|
55
|
+
* The id of the tool call this row gated — the row's IDENTITY, not a display field. Minted with the
|
|
56
|
+
* row at each of the four mint sites, never re-derived downstream: a run pushes rows from several
|
|
57
|
+
* mints while only one passes through the host's `onAsk`, so the two ledgers' counts are legitimately
|
|
58
|
+
* unequal and there was no key to reconcile on. Absent means one thing — the mint had no call id to
|
|
59
|
+
* give (a probe row; a durable gate whose checkpoint carries a non-`tool_approval` pending action,
|
|
60
|
+
* since a `resource_limit` / `needs_review` / `plan_review` pause gates no call; or an older engine).
|
|
61
|
+
* Never a placeholder.
|
|
62
|
+
*/
|
|
63
|
+
toolCallId?: string;
|
|
64
|
+
}
|
|
41
65
|
export interface RemoteEnvFailureNote {
|
|
42
66
|
/** Which VM-lifecycle call failed. */
|
|
43
67
|
op: "suspendVM" | "resumeVM" | "postResumeInit";
|
|
@@ -562,8 +586,9 @@ export interface TaskResult {
|
|
|
562
586
|
* duplicates, so re-supplying deployment-shared entries is idempotent) — that is how the frozen
|
|
563
587
|
* posture rides every leg that continues this work, not just the delegation subtree.
|
|
564
588
|
*
|
|
565
|
-
* **In-presence condition:** present iff non-empty. Built-in entries are never listed
|
|
566
|
-
*
|
|
589
|
+
* **In-presence condition:** present iff non-empty. Built-in entries are never listed — they are the
|
|
590
|
+
* DEPLOYMENT's own selection (off by default), re-compiled per leg and reported on its wiring
|
|
591
|
+
* manifest ({@link import("./wiring-manifest.js").WiringManifest.readDeny}). Same terminal coverage as
|
|
567
592
|
* {@link effectiveReadFace}: rides any terminal of a leg that ran; absent on prepare failures.
|
|
568
593
|
*
|
|
569
594
|
* On a DURABLE-PAUSE hand-back these seats are additionally the RE-SUPPLY hint: a checkpoint
|
|
@@ -780,16 +805,10 @@ export interface TaskResult {
|
|
|
780
805
|
* `irreversible_ask` for durable; `human` for a synchronous ask). `decision` = the adjudication when
|
|
781
806
|
* known (`allow`/`deny`). design/99 MF-24: `toolName` = the gated tool; `toolArg` = a
|
|
782
807
|
* SHORT, SECRET-SCRUBBED one-line summary of its input (the same `primaryActivityArg` boundary as the MF-W
|
|
783
|
-
* activity arg) — the permission-denial ledger's "denied: Bash(rm …)" display. `toolArg`
|
|
784
|
-
*
|
|
785
|
-
*
|
|
786
|
-
gates:
|
|
787
|
-
kind: string;
|
|
788
|
-
waitMs: number;
|
|
789
|
-
decision?: string;
|
|
790
|
-
toolName?: string;
|
|
791
|
-
toolArg?: string;
|
|
792
|
-
}>;
|
|
808
|
+
* activity arg) — the permission-denial ledger's "denied: Bash(rm …)" display. `toolArg` rides every mint
|
|
809
|
+
* that has the input in scope: the synchronous ask from the request, the durable-resume gate from the
|
|
810
|
+
* checkpoint's `pendingAction`; `toolCallId` names the call the row gated (absent = not joinable). */
|
|
811
|
+
gates: HumanReviewGateRow[];
|
|
793
812
|
};
|
|
794
813
|
/**
|
|
795
814
|
* design/80 D-E-core: a thin FINANCE TAXONOMY of the LLM-derived costs the engine actually prices,
|
package/dist/core/task-spec.d.ts
CHANGED
|
@@ -789,7 +789,8 @@ export interface TaskSpec {
|
|
|
789
789
|
* {@link RunnerDeps.readDenyPatterns}; `[]` ≡ absent (union identity); NOTHING at the task layer
|
|
790
790
|
* can remove a built-in — the one removal channel is the DEPLOYMENT's built-in configuration
|
|
791
791
|
* ({@link RunnerDeps.readDenyBuiltinTiers} / {@link RunnerDeps.readDenyBuiltinExclude}, #245
|
|
792
|
-
* revision of D-4), which no TaskSpec key reaches
|
|
792
|
+
* revision of D-4), which no TaskSpec key reaches — and that half is OFF by default, so on an
|
|
793
|
+
* unconfigured deployment the entries here are the WHOLE judged set. Bad entry shapes refuse loudly at prepare
|
|
793
794
|
* (#123). The write faces are untouched.
|
|
794
795
|
*/
|
|
795
796
|
readDenyPatterns?: readonly import("../tools/fs/read-deny.js").ReadDenyEntry[];
|
|
@@ -275,6 +275,32 @@ export interface TaskStream extends AsyncIterable<TaskEvent> {
|
|
|
275
275
|
}): Promise<{
|
|
276
276
|
outcome: "created" | "existed";
|
|
277
277
|
}>;
|
|
278
|
+
/**
|
|
279
|
+
* **RE-DIAL one MCP server** on the running task, the action `RefreshMcpTools` deliberately
|
|
280
|
+
* is not (its contract is "never dials or re-dials"). Core holds no MCP connection across task
|
|
281
|
+
* legs, so once a server's transport closes this leg is stuck with it: every one of its tools fails
|
|
282
|
+
* fast and a refresh can only keep reporting `not_connected`. This is the verb a host hangs a
|
|
283
|
+
* "Reconnect" control on. ONE NAMED SERVER, required — CC 2.1.259's control-channel request carries
|
|
284
|
+
* a required `serverName` and has no all-servers form, and an all-servers form would CLOSE HEALTHY
|
|
285
|
+
* connections to re-dial them (the stdio server owning a device or a port — the case this verb
|
|
286
|
+
* exists for — is the one that cannot be re-dialed while its predecessor still holds the device).
|
|
287
|
+
*
|
|
288
|
+
* ⚠️ **A FAILED RE-DIAL LEAVES THE SERVER DOWN.** The old connection is closed BEFORE the new one is
|
|
289
|
+
* dialed (no other order works for a device-owning server), so a dial that fails has spent a
|
|
290
|
+
* working connection: the server stays disconnected, with its tools WITHDRAWN from the roster,
|
|
291
|
+
* until another re-dial or the next leg's materialize — and calls in flight on the replaced
|
|
292
|
+
* connection fail with it. Both are inherent to re-dialing; CC behaves the same way.
|
|
293
|
+
*
|
|
294
|
+
* Resolves {@link import("./mcp.js").McpReconnectResult} — `outcome` is one of three words, so a
|
|
295
|
+
* consumer mapping it onto a three-state control answer needs no table: `reconnected` (the only
|
|
296
|
+
* success), `refused` (the engine declined, or the dial failed — `reason` says which and
|
|
297
|
+
* `status.errorCode` keys the next action), `not_declared` (no server of that name on this leg).
|
|
298
|
+
* Throws, never silently no-ops: `mcp.reconnect_unavailable` when this run declared NO MCP servers
|
|
299
|
+
* (a host maps that to "unsupported", not "refused"), `steering.invalid_content` on a missing or
|
|
300
|
+
* non-string name, and the steer-family `steering.not_running` once the task has finished.
|
|
301
|
+
* LEG-LOCAL: the result rides no checkpoint, and a durable resume takes a fresh first listing.
|
|
302
|
+
*/
|
|
303
|
+
reconnectMcpServer(server: string): Promise<import("./mcp.js").McpReconnectResult>;
|
|
278
304
|
/**
|
|
279
305
|
* Hard-**interrupt** the running task — a real abort (not a best-effort hint), equivalent to firing the
|
|
280
306
|
* task's `signal` (design/47). Refused typed (`steering.not_running`, the steer-family liveness code —
|
package/dist/core/tool-spec.d.ts
CHANGED
|
@@ -95,8 +95,12 @@ export interface ReversibilityVerdict {
|
|
|
95
95
|
* spelled, which is the only one derivable from the text.
|
|
96
96
|
*/
|
|
97
97
|
export interface ReadRootGrantCandidate {
|
|
98
|
-
/** An absolute, lexically folded
|
|
98
|
+
/** An absolute, lexically folded path in the boundary's own spelling; never a pattern. A DIRECTORY
|
|
99
|
+
* unless {@link covers} says otherwise. */
|
|
99
100
|
readonly dir: string;
|
|
101
|
+
/** `"exact"` ⇒ {@link dir} is the path the command NAMED, offered verbatim rather than a directory
|
|
102
|
+
* containing it. A consumer ADDS the string itself: expanding it into a pattern grants nothing. */
|
|
103
|
+
readonly covers?: "exact";
|
|
100
104
|
/** Always the literal `true` — a shape, not a value, so the seat cannot be widened into a "maybe this
|
|
101
105
|
* helps" hint without a visible type change. It claims THIS ask: not the deny layer (judged by pattern
|
|
102
106
|
* rather than by root, and unmoved by any grant), and not another ask the same call may raise. */
|
package/dist/core/trace.d.ts
CHANGED
|
@@ -548,6 +548,11 @@ export type TraceEvent = {
|
|
|
548
548
|
verdict: "allow" | "block" | "unavailable" | "parse_error";
|
|
549
549
|
/** Present iff `verdict === "unavailable"`: `error` / `timeout`. */
|
|
550
550
|
cause?: "error" | "timeout";
|
|
551
|
+
/** Present exactly when NO MODEL WAS ASKED because the question did not assemble: `timeout` = the
|
|
552
|
+
* assembly outran its cap, `failed` = it threw. The verdict reads `unavailable` / `error` either way
|
|
553
|
+
* (nothing was dispatched), and `ms` is then time spent BUILDING, not waiting on a provider — which is
|
|
554
|
+
* what separates "the transcript store is slow" from "the provider is down". */
|
|
555
|
+
notAsked?: "failed" | "timeout";
|
|
551
556
|
ts: number;
|
|
552
557
|
} | {
|
|
553
558
|
/** C1 — the failover brain served this call from a FALLBACK entry (`createFailoverBrain`): the
|
package/dist/core/types.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ export type { BeforeWriteRequest, BeforeWriteResult, BeforeWriteHook, TrackEditR
|
|
|
18
18
|
export type { AgentDefinition, SkillManifest, SkillSpec } from "./agent-definition.js";
|
|
19
19
|
export type { McpServerSpec, A2aServerSpec, McpElicitRequest, McpElicitResponse, OnElicit } from "./mcp-server-spec.js";
|
|
20
20
|
export type { TaskLimits } from "./task-limits.js";
|
|
21
|
-
export type { TaskStatus, RemoteEnvFailureNote, EffectiveMemoryScopes, TaskResult } from "./task-result.js";
|
|
21
|
+
export type { TaskStatus, RemoteEnvFailureNote, EffectiveMemoryScopes, TaskResult, HumanReviewGateRow } from "./task-result.js";
|
|
22
22
|
export type { TerminalCause, PausedCause } from "./terminal-cause.js";
|
|
23
23
|
export type { TaskEventIdentity, BrainStatusPhase, BrainRetryErrClass, BrainStatus, ToolActivity, HumanInputSource, HumanInputDelivery, DelegationTaskType, TaskEvent, HumanInputEvent, CompactOutcome } from "./task-event.js";
|
|
24
24
|
export type { TaskStream } from "./task-stream.js";
|
|
@@ -27,6 +27,6 @@ export { AUTO_MODE_DENY_SOURCES, isAutoModeDenySource } from "./runtime-caps.js"
|
|
|
27
27
|
export type { BackgroundChildEvent, DelegationLifecycleEvent } from "./delegation-frames.js";
|
|
28
28
|
export { __resetMalformedDelegationSeatAnnouncement, deliverDelegationLifecycle } from "./delegation-frames.js";
|
|
29
29
|
export type { ProjectMemoryLoad, ResumePreflightInfo, ResumePreflightVerdict, RunnerDeps } from "./runner-deps.js";
|
|
30
|
-
export type { EngineNotice } from "./engine-notice.js";
|
|
31
|
-
export { __resetMalformedNoticeSeatAnnouncement, deliverEngineNotice, owedUserInputCounts, undrainedUserInputNotices } from "./engine-notice.js";
|
|
30
|
+
export type { EngineNotice, OwedUserInputAccount } from "./engine-notice.js";
|
|
31
|
+
export { __resetMalformedNoticeSeatAnnouncement, deliverEngineNotice, owedUserInputCounts, settleOwedUserInput, undrainedUserInputNotices } from "./engine-notice.js";
|
|
32
32
|
export type { AgentTool, Model, StreamFn, ThinkingLevel, ToolInputValidationContext, ToolInputVerdict };
|
package/dist/core/types.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { AUTO_MODE_DENY_SOURCES, isAutoModeDenySource } from "./runtime-caps.js";
|
|
2
2
|
export { __resetMalformedDelegationSeatAnnouncement, deliverDelegationLifecycle } from "./delegation-frames.js";
|
|
3
|
-
export { __resetMalformedNoticeSeatAnnouncement, deliverEngineNotice, owedUserInputCounts, undrainedUserInputNotices } from "./engine-notice.js";
|
|
3
|
+
export { __resetMalformedNoticeSeatAnnouncement, deliverEngineNotice, owedUserInputCounts, settleOwedUserInput, undrainedUserInputNotices } from "./engine-notice.js";
|
|
@@ -347,6 +347,26 @@ export interface WiringManifest {
|
|
|
347
347
|
writeProtection?: {
|
|
348
348
|
targetView: WriteProtectionTargetView;
|
|
349
349
|
};
|
|
350
|
+
/**
|
|
351
|
+
* EFFECTIVE half only; the present-iff law is the contract sentence below. `builtinTiers` names the
|
|
352
|
+
* tiers that MATERIALLY activate rows, in {@link
|
|
353
|
+
* import("../tools/fs/read-deny.js").READ_DENY_BUILTIN_TIERS} order — not the tiers the operator
|
|
354
|
+
* typed: one whose every row `readDenyBuiltinExclude` removed is not named. Deliberately NOT
|
|
355
|
+
* reported: `readDenyPatterns`, deployment-supplied TEXTS rather than an enum, so absence means "no
|
|
356
|
+
* BUILT-IN row judges", never "no read is deny-judged". IN the fingerprint (the
|
|
357
|
+
* {@link WiringManifest.writeProtection} class): the selection follows the deployment seat, so legs
|
|
358
|
+
* of one assembly agree.
|
|
359
|
+
*
|
|
360
|
+
* @contract read_deny.builtin_activation_disclosed — WHETHER the built-in sensitive-path read deny
|
|
361
|
+
* table judges a leg is DISCLOSED, never inferred: the table is a deployment opt-in whose default
|
|
362
|
+
* selection is empty, the leg that compiles the judge relays the tiers its own resolution materially
|
|
363
|
+
* activated, and the manifest carries that section iff at least one built-in row is active (absence
|
|
364
|
+
* = no built-in row judges; an empty array is never emitted — "off" and "on to nothing" are one
|
|
365
|
+
* fact). The disclosure changes no verdict.
|
|
366
|
+
*/
|
|
367
|
+
readDeny?: {
|
|
368
|
+
builtinTiers: readonly string[];
|
|
369
|
+
};
|
|
350
370
|
/**
|
|
351
371
|
* EFFECTIVE half only. PRESENT IFF auto-consolidation is EFFECTIVELY armed on this
|
|
352
372
|
* deployment (`autoRunOnRecommendationEffective`: an explicit `true`, or an absent seat under the
|
|
@@ -441,6 +461,9 @@ export interface WiringFacts {
|
|
|
441
461
|
/** Effective half only — the compiled write-protection judge's OWN target-view word
|
|
442
462
|
* ({@link WiringManifest.writeProtection}); absent ⇒ this leg compiled no judge (an emptied table). */
|
|
443
463
|
writeProtectionTargetView?: WriteProtectionTargetView;
|
|
464
|
+
/** Effective half only — the built-in read-deny TIERS this leg's configuration materially activated
|
|
465
|
+
* ({@link WiringManifest.readDeny}); empty and absent derive the same thing (no section). */
|
|
466
|
+
readDenyBuiltinTiersActive?: readonly string[];
|
|
444
467
|
/** Effective half only — `RunnerDeps.autoRunOnRecommendation === true`
|
|
445
468
|
* ({@link WiringManifest.autoConsolidation}); false ⇒ no section (byte-identical manifest). */
|
|
446
469
|
autoConsolidationOnRecommendation?: boolean;
|
|
@@ -142,6 +142,9 @@ export function deriveWiringManifest(facts) {
|
|
|
142
142
|
...(facts.half === "effective" && facts.hooks !== undefined && facts.hooks.length > 0 ? { hooks: facts.hooks.map((h) => ({ ...h })) } : {}),
|
|
143
143
|
...(facts.half === "effective" && facts.lsp !== undefined ? { lsp: { ...facts.lsp } } : {}),
|
|
144
144
|
...(facts.half === "effective" && facts.writeProtectionTargetView !== undefined ? { writeProtection: { targetView: facts.writeProtectionTargetView } } : {}),
|
|
145
|
+
...(facts.half === "effective" && facts.readDenyBuiltinTiersActive !== undefined && facts.readDenyBuiltinTiersActive.length > 0
|
|
146
|
+
? { readDeny: { builtinTiers: [...facts.readDenyBuiltinTiersActive] } }
|
|
147
|
+
: {}),
|
|
145
148
|
...(facts.half === "effective" && facts.autoConsolidationOnRecommendation === true ? { autoConsolidation: { onRecommendation: true } } : {}),
|
|
146
149
|
};
|
|
147
150
|
if (facts.half === "effective") {
|