@sema-agent/core 7.5.0 → 7.5.2
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 +44 -0
- package/dist/core/auto-mode.d.ts +9 -0
- package/dist/core/auto-mode.js +11 -0
- package/dist/core/checkpoint-store.js +5 -1
- package/dist/core/protocol-table.d.ts +5 -0
- package/dist/core/protocol-table.js +1 -0
- package/dist/core/runner/abort-race.d.ts +41 -0
- package/dist/core/runner/abort-race.js +38 -0
- package/dist/core/runner/checkpoint-scope.d.ts +44 -0
- package/dist/core/runner/checkpoint-scope.js +7 -0
- package/dist/core/runner/compaction-call-options.d.ts +1 -1
- package/dist/core/runner/content-ask-bindings.d.ts +27 -0
- package/dist/core/runner/content-ask-bindings.js +1 -0
- package/dist/core/runner/contracts.d.ts +1990 -0
- package/dist/core/runner/contracts.js +1 -0
- package/dist/core/runner/denial-limit-arms.d.ts +24 -1
- package/dist/core/runner/denial-limit-arms.js +21 -0
- package/dist/core/runner/derived-route-fallback.d.ts +34 -0
- package/dist/core/runner/derived-route-fallback.js +16 -0
- package/dist/core/runner/inherited-ask-grants.d.ts +46 -0
- package/dist/core/runner/inherited-ask-grants.js +29 -0
- package/dist/core/runner/park-commit.d.ts +108 -0
- package/dist/core/runner/park-commit.js +32 -0
- package/dist/core/runner/{prepare-permission-rules.d.ts → permission-rule-lanes.d.ts} +109 -3
- package/dist/core/runner/{prepare-permission-rules.js → permission-rule-lanes.js} +47 -1
- package/dist/core/runner/prepare-acquire-reconcile.d.ts +1 -1
- package/dist/core/runner/prepare-ask-lane.d.ts +110 -0
- package/dist/core/runner/prepare-ask-lane.js +133 -0
- package/dist/core/runner/prepare-boundary-parks.d.ts +105 -0
- package/dist/core/runner/prepare-boundary-parks.js +169 -0
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +170 -0
- package/dist/core/runner/prepare-caps-and-workflow.js +255 -0
- package/dist/core/runner/prepare-config-doors.d.ts +2 -10
- package/dist/core/runner/prepare-context-lane.d.ts +119 -0
- package/dist/core/runner/prepare-context-lane.js +230 -0
- package/dist/core/runner/prepare-defer-classify.d.ts +86 -0
- package/dist/core/runner/prepare-defer-classify.js +107 -0
- package/dist/core/runner/prepare-delegation-surface.d.ts +104 -0
- package/dist/core/runner/prepare-delegation-surface.js +144 -0
- package/dist/core/runner/prepare-execution-env.d.ts +54 -0
- package/dist/core/runner/prepare-execution-env.js +86 -0
- package/dist/core/runner/prepare-file-history.d.ts +95 -0
- package/dist/core/runner/prepare-file-history.js +383 -0
- package/dist/core/runner/prepare-gate-stations.d.ts +177 -0
- package/dist/core/runner/prepare-gate-stations.js +290 -0
- package/dist/core/runner/prepare-hands-readface.d.ts +9 -11
- package/dist/core/runner/prepare-hands-readface.js +1 -1
- package/dist/core/runner/prepare-inherited-gate.d.ts +268 -0
- package/dist/core/runner/prepare-inherited-gate.js +266 -0
- package/dist/core/runner/prepare-listings.d.ts +77 -0
- package/dist/core/runner/prepare-listings.js +76 -0
- package/dist/core/runner/prepare-lsp.d.ts +55 -0
- package/dist/core/runner/prepare-lsp.js +27 -0
- package/dist/core/runner/prepare-memory-engine-session.d.ts +84 -0
- package/dist/core/runner/prepare-memory-engine-session.js +233 -0
- package/dist/core/runner/prepare-memory.d.ts +1 -1
- package/dist/core/runner/prepare-offload-wrappers.d.ts +62 -0
- package/dist/core/runner/prepare-offload-wrappers.js +45 -0
- package/dist/core/runner/prepare-park-ask.d.ts +164 -0
- package/dist/core/runner/prepare-park-ask.js +377 -0
- package/dist/core/runner/prepare-policy-chain.d.ts +208 -0
- package/dist/core/runner/prepare-policy-chain.js +584 -0
- package/dist/core/runner/prepare-project-context.d.ts +119 -0
- package/dist/core/runner/prepare-project-context.js +148 -0
- package/dist/core/runner/prepare-prompt-assembly.d.ts +95 -0
- package/dist/core/runner/prepare-prompt-assembly.js +162 -0
- package/dist/core/runner/prepare-prompt-inputs.d.ts +119 -0
- package/dist/core/runner/prepare-prompt-inputs.js +141 -0
- package/dist/core/runner/prepare-protocol-tools.d.ts +91 -0
- package/dist/core/runner/prepare-protocol-tools.js +179 -0
- package/dist/core/runner/prepare-question-face.d.ts +101 -0
- package/dist/core/runner/prepare-question-face.js +84 -0
- package/dist/core/runner/prepare-run-refs.d.ts +89 -0
- package/dist/core/runner/prepare-run-refs.js +39 -0
- package/dist/core/runner/prepare-safety-scan.d.ts +3 -7
- package/dist/core/runner/prepare-safety-scan.js +1 -2
- package/dist/core/runner/prepare-suspend-saga.d.ts +170 -0
- package/dist/core/runner/prepare-suspend-saga.js +308 -0
- package/dist/core/runner/prepare-task.d.ts +14 -1976
- package/dist/core/runner/prepare-task.js +182 -5162
- package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +111 -0
- package/dist/core/runner/prepare-tool-disclosure-mount.js +219 -0
- package/dist/core/runner/prepare-turn-wiring.d.ts +154 -0
- package/dist/core/runner/prepare-turn-wiring.js +201 -0
- package/dist/core/runner/prepare-wiring-manifest.d.ts +192 -0
- package/dist/core/runner/prepare-wiring-manifest.js +247 -0
- package/dist/core/runner/prepare-workspace-restore.d.ts +3 -56
- package/dist/core/runner/prepare-workspace-restore.js +4 -38
- package/dist/core/runner/prompt-hash-salt.d.ts +1 -0
- package/dist/core/runner/prompt-hash-salt.js +2 -0
- package/dist/core/runner/remote-env-retry.d.ts +29 -0
- package/dist/core/runner/remote-env-retry.js +16 -0
- package/dist/core/runner/rollback-stack.d.ts +32 -0
- package/dist/core/runner/rollback-stack.js +30 -0
- package/dist/core/runner/runtask.js +1 -1
- package/dist/core/runner/workspace-path.d.ts +33 -0
- package/dist/core/runner/workspace-path.js +22 -0
- package/dist/core/session.d.ts +12 -0
- package/dist/core/session.js +3 -0
- package/dist/core/tool-policy.d.ts +16 -0
- package/dist/core/tool-policy.js +3 -0
- package/dist/core/types.d.ts +2 -2
- package/dist/core/write-protect.js +3 -2
- package/package.json +6 -2
- /package/dist/core/runner/{prepare-announce-once.d.ts → announce-once-ledger.d.ts} +0 -0
- /package/dist/core/runner/{prepare-announce-once.js → announce-once-ledger.js} +0 -0
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { forkGovernanceDenial, resolveDelegationEntryCaps } from "../../agents/subagent.js";
|
|
2
|
+
import { isLiveQuestionFace } from "../ask-question.js";
|
|
3
|
+
import { createPreToolUseConstraintPolicy } from "../hooks.js";
|
|
4
|
+
import { StubExecutionEnv } from "../stub-env.js";
|
|
5
|
+
import { askApproverIdentity, isLiveApproverSeat } from "../tool-policy.js";
|
|
6
|
+
import { attachRebuiltDenialTrackers, createDenialLimitStop } from "./denial-limit-arms.js";
|
|
7
|
+
export function prepareInheritedGate(input) {
|
|
8
|
+
const { spec, deps, internals, resume, sessions, sessionId, runId, hostTaskId, taskRootFinal, executionEnv, ownedEnv, lockedPreflight, toolFaceSnapshot, promptProfile, resolvedInteractionPosture, autoModeSeat, handsEnabled, reportUsage, harnessRef, skillScope, forwardEvent, subagentRetain, worktreeIsolation, requestReview, requestStopAfterTurn, enterPlanMode, reminderMark, reminderDisclosureCounts, fileHistoryEnabled, historyScope, historyRoot, historyFs, abortRun } = input;
|
|
9
|
+
const liveInheritedGate = internals?.inheritedGate;
|
|
10
|
+
const seedInheritedGate = resume?.seed.inheritedGate;
|
|
11
|
+
const inheritedAncestorRules = (() => {
|
|
12
|
+
const seedRules = seedInheritedGate?.ancestorRules;
|
|
13
|
+
const liveRules = liveInheritedGate?.ancestorRules;
|
|
14
|
+
if (seedRules === undefined || seedRules.length === 0)
|
|
15
|
+
return liveRules ?? seedRules;
|
|
16
|
+
if (liveRules === undefined || liveRules.length === 0)
|
|
17
|
+
return seedRules;
|
|
18
|
+
const merged = seedRules.map((s) => {
|
|
19
|
+
const live = liveRules.find((l) => l.sessionId === s.sessionId && l.principal === s.principal);
|
|
20
|
+
return live !== undefined && live.rev >= s.rev ? live : s;
|
|
21
|
+
});
|
|
22
|
+
const extras = liveRules.filter((l) => !seedRules.some((s) => s.sessionId === l.sessionId && s.principal === l.principal));
|
|
23
|
+
return [...merged, ...extras];
|
|
24
|
+
})();
|
|
25
|
+
const shellGateRank = { off: 0, classify: 1, always: 2 };
|
|
26
|
+
const liveShellGate = liveInheritedGate?.shellGate;
|
|
27
|
+
const seedShellGate = seedInheritedGate?.shellGate;
|
|
28
|
+
const inheritedShellGate = liveShellGate === undefined
|
|
29
|
+
? seedShellGate
|
|
30
|
+
: seedShellGate === undefined
|
|
31
|
+
? liveShellGate
|
|
32
|
+
: shellGateRank[liveShellGate] >= shellGateRank[seedShellGate]
|
|
33
|
+
? liveShellGate
|
|
34
|
+
: seedShellGate;
|
|
35
|
+
const inheritedParentConstraints = attachRebuiltDenialTrackers(liveInheritedGate?.parentConstraints, deps.autoMode?.denialLimit);
|
|
36
|
+
const autoModeIntent = autoModeSeat || liveInheritedGate?.autoModeRequested === true || seedInheritedGate?.autoModeRequested === true;
|
|
37
|
+
const liveAdmittedOrg = liveInheritedGate?.admittedOrgScopes;
|
|
38
|
+
const seedAdmittedOrg = seedInheritedGate?.admittedOrgScopes;
|
|
39
|
+
const inheritedAdmittedOrgScopes = liveAdmittedOrg === undefined ? seedAdmittedOrg : seedAdmittedOrg === undefined ? liveAdmittedOrg : liveAdmittedOrg.filter((s) => seedAdmittedOrg.includes(s));
|
|
40
|
+
const inheritedOrgGoverned = liveInheritedGate?.orgAdmissionGoverned === true || seedInheritedGate?.orgAdmissionGoverned === true;
|
|
41
|
+
const checkpointOwnOrgVerdict = resume?.seed.inheritedGate?.ownAdmittedOrgScopes !== undefined
|
|
42
|
+
? { scopes: resume.seed.inheritedGate.ownAdmittedOrgScopes, writeScope: resume.seed.inheritedGate.ownAdmittedOrgWriteScope ?? null }
|
|
43
|
+
: undefined;
|
|
44
|
+
const refOwnOrgVerdict = internals?.ownOrgAdmissionRef?.current;
|
|
45
|
+
const priorOwnOrgVerdict = checkpointOwnOrgVerdict === undefined
|
|
46
|
+
? refOwnOrgVerdict
|
|
47
|
+
: refOwnOrgVerdict === undefined
|
|
48
|
+
? checkpointOwnOrgVerdict
|
|
49
|
+
: {
|
|
50
|
+
scopes: checkpointOwnOrgVerdict.scopes.filter((sc) => refOwnOrgVerdict.scopes.includes(sc)),
|
|
51
|
+
writeScope: checkpointOwnOrgVerdict.writeScope !== null && checkpointOwnOrgVerdict.writeScope === refOwnOrgVerdict.writeScope
|
|
52
|
+
? checkpointOwnOrgVerdict.writeScope
|
|
53
|
+
: null,
|
|
54
|
+
};
|
|
55
|
+
const orgGovernedProvenance = deps.memoryScopeAdmission !== undefined ||
|
|
56
|
+
(deps.deploymentMemoryScopes !== undefined && deps.deploymentMemoryScopes.length > 0) ||
|
|
57
|
+
deps.compliancePostureResolver !== undefined ||
|
|
58
|
+
inheritedOrgGoverned ||
|
|
59
|
+
priorOwnOrgVerdict !== undefined;
|
|
60
|
+
const specShellGate = spec.shellGate ?? "off";
|
|
61
|
+
const effectiveShellGate = inheritedShellGate !== undefined && shellGateRank[inheritedShellGate] > shellGateRank[specShellGate] ? inheritedShellGate : specShellGate;
|
|
62
|
+
const ownSessionRulesRef = {};
|
|
63
|
+
const memoryAdmittedOrgScopesRef = { current: [] };
|
|
64
|
+
const ownOrgVerdictRef = { current: undefined };
|
|
65
|
+
const orgAdmissionCheckpointState = () => inheritedAdmittedOrgScopes !== undefined || ownOrgVerdictRef.current !== undefined || orgGovernedProvenance;
|
|
66
|
+
const faceCheckpointSection = () => {
|
|
67
|
+
const resolvedReadFace = input.resolvedReadFace();
|
|
68
|
+
const handsLessResolvedFace = input.handsLessResolvedFace();
|
|
69
|
+
const readDenyAdditionsNormalized = input.readDenyAdditionsNormalized();
|
|
70
|
+
if (resolvedReadFace === undefined && resume !== undefined) {
|
|
71
|
+
const seed = resume.seed.readFace;
|
|
72
|
+
return seed !== undefined ? { face: seed.face, ...(seed.denyEntries !== undefined ? { denyEntries: seed.denyEntries.map((e) => ({ ...e })) } : {}) } : undefined;
|
|
73
|
+
}
|
|
74
|
+
const face = resolvedReadFace ?? handsLessResolvedFace;
|
|
75
|
+
if (face === undefined)
|
|
76
|
+
return undefined;
|
|
77
|
+
if (face === "open" || readDenyAdditionsNormalized.length > 0) {
|
|
78
|
+
return { face, ...(readDenyAdditionsNormalized.length > 0 ? { denyEntries: readDenyAdditionsNormalized.map((e) => ({ ...e })) } : {}) };
|
|
79
|
+
}
|
|
80
|
+
return undefined;
|
|
81
|
+
};
|
|
82
|
+
const faceCheckpointState = () => faceCheckpointSection() !== undefined;
|
|
83
|
+
const f012CheckpointState = () => (inheritedParentConstraints?.length ?? 0) > 0 ||
|
|
84
|
+
seedInheritedGate?.constraintChain !== undefined ||
|
|
85
|
+
internals?.delegationProvenance !== undefined;
|
|
86
|
+
const frozenOnAsk = spec.onAsk ?? deps.onAsk;
|
|
87
|
+
const hookEnvSource = (ownedEnv ?? deps.executionEnv) != null ? executionEnv : undefined;
|
|
88
|
+
const notifyOwnHookCrash = (err) => {
|
|
89
|
+
try {
|
|
90
|
+
deps.onError?.(err instanceof Error ? err : new Error(String(err)), { phase: "hook", sessionId });
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
const frozenOnQuestion = spec.onQuestion ?? deps.onQuestion;
|
|
96
|
+
const provenanceForChildrenRef = {};
|
|
97
|
+
const delegationProvenanceForChildren = () => provenanceForChildrenRef.current;
|
|
98
|
+
const delegationSettlementRef = {};
|
|
99
|
+
const delegationSettlementForChildren = () => delegationSettlementRef.current;
|
|
100
|
+
const inheritedGateForChildren = () => {
|
|
101
|
+
const autoModeDecider = input.autoModeDecider();
|
|
102
|
+
const autoModeDenialTracking = input.autoModeDenialTracking();
|
|
103
|
+
const autoModeArming = input.autoModeArming();
|
|
104
|
+
const ancestorRules = [
|
|
105
|
+
...(inheritedAncestorRules ?? []),
|
|
106
|
+
...(ownSessionRulesRef.current !== undefined ? [ownSessionRulesRef.current] : []),
|
|
107
|
+
];
|
|
108
|
+
const ownCallerPolicy = lockedPreflight.toolPolicy;
|
|
109
|
+
const durableMandate = input.runtimeCaps()?.forceDurableGate === true ||
|
|
110
|
+
(spec.durableApproval !== undefined && !isLiveApproverSeat(frozenOnAsk));
|
|
111
|
+
const contentMandate = input.runtimeCaps()?.forceDurableGate === true ||
|
|
112
|
+
(spec.durableApproval !== undefined && !isLiveQuestionFace(frozenOnQuestion));
|
|
113
|
+
const ownPreToolUse = input.preToolUseObservational() ? undefined : input.hooks()?.preToolUse;
|
|
114
|
+
const hookConstraint = ownPreToolUse !== undefined &&
|
|
115
|
+
!(inheritedParentConstraints ?? []).some((pc) => pc.preToolUse === ownPreToolUse &&
|
|
116
|
+
askApproverIdentity(pc.onAsk) === askApproverIdentity(frozenOnAsk) &&
|
|
117
|
+
(pc.durableMandate === true) === durableMandate &&
|
|
118
|
+
(pc.contentMandate === true) === contentMandate &&
|
|
119
|
+
pc.hookEnv === hookEnvSource &&
|
|
120
|
+
pc.autoMode?.decider === autoModeDecider)
|
|
121
|
+
? [
|
|
122
|
+
{
|
|
123
|
+
policy: createPreToolUseConstraintPolicy(ownPreToolUse, input.hookEnvFace(), notifyOwnHookCrash, input.hookTimeoutMs()),
|
|
124
|
+
preToolUse: ownPreToolUse,
|
|
125
|
+
...(hookEnvSource !== undefined ? { hookEnv: hookEnvSource } : {}),
|
|
126
|
+
...(frozenOnAsk !== undefined ? { onAsk: frozenOnAsk } : {}),
|
|
127
|
+
...(durableMandate ? { durableMandate: true } : {}),
|
|
128
|
+
...(contentMandate ? { contentMandate: true } : {}),
|
|
129
|
+
...(autoModeDecider !== undefined
|
|
130
|
+
? { autoMode: { decider: autoModeDecider, ...(autoModeDenialTracking !== undefined ? { denialTracking: autoModeDenialTracking } : {}), ...(autoModeArming !== undefined ? { arming: autoModeArming } : {}) } }
|
|
131
|
+
: {}),
|
|
132
|
+
},
|
|
133
|
+
]
|
|
134
|
+
: [];
|
|
135
|
+
const parentConstraints = [
|
|
136
|
+
...(inheritedParentConstraints ?? []),
|
|
137
|
+
...hookConstraint,
|
|
138
|
+
...(ownCallerPolicy !== undefined
|
|
139
|
+
? [
|
|
140
|
+
{
|
|
141
|
+
policy: ownCallerPolicy,
|
|
142
|
+
...(frozenOnAsk !== undefined ? { onAsk: frozenOnAsk } : {}),
|
|
143
|
+
...(durableMandate ? { durableMandate: true } : {}),
|
|
144
|
+
...(contentMandate ? { contentMandate: true } : {}),
|
|
145
|
+
...(autoModeDecider !== undefined
|
|
146
|
+
? { autoMode: { decider: autoModeDecider, ...(autoModeDenialTracking !== undefined ? { denialTracking: autoModeDenialTracking } : {}), ...(autoModeArming !== undefined ? { arming: autoModeArming } : {}) } }
|
|
147
|
+
: {}),
|
|
148
|
+
},
|
|
149
|
+
]
|
|
150
|
+
: []),
|
|
151
|
+
];
|
|
152
|
+
return {
|
|
153
|
+
...(ancestorRules.length > 0 ? { ancestorRules } : {}),
|
|
154
|
+
...(effectiveShellGate !== "off" ? { shellGate: effectiveShellGate } : {}),
|
|
155
|
+
...(autoModeIntent ? { autoModeRequested: true } : {}),
|
|
156
|
+
...(parentConstraints.length > 0 ? { parentConstraints } : {}),
|
|
157
|
+
admittedOrgScopes: memoryAdmittedOrgScopesRef.current,
|
|
158
|
+
...(orgGovernedProvenance ? { orgAdmissionGoverned: true } : {}),
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
const carrierReadFace = () => input.resolvedReadFace() ?? input.handsLessResolvedFace();
|
|
162
|
+
const fullShellReachable = handsEnabled &&
|
|
163
|
+
!(executionEnv instanceof StubExecutionEnv) &&
|
|
164
|
+
spec.handsReadOnly !== true &&
|
|
165
|
+
!(toolFaceSnapshot.exclude?.includes("Bash") ?? false);
|
|
166
|
+
const { gateStopRef, stopForDenialLimit } = createDenialLimitStop({ sessionId, runId, onNotice: deps.onNotice, abort: abortRun });
|
|
167
|
+
const delegationEntryCapsResolved = resolveDelegationEntryCaps(deps.delegationEntryCaps);
|
|
168
|
+
const enrichSpecToolCtx = (ctx) => {
|
|
169
|
+
const agentForkDenial = input.agentForkDenial();
|
|
170
|
+
const observersActive = input.observersActive();
|
|
171
|
+
const readDenyAdditionsNormalized = input.readDenyAdditionsNormalized();
|
|
172
|
+
const autoModeDecider = input.autoModeDecider();
|
|
173
|
+
const centerAdoption = input.centerAdoption();
|
|
174
|
+
return {
|
|
175
|
+
...ctx,
|
|
176
|
+
delegationEntryCaps: delegationEntryCapsResolved,
|
|
177
|
+
reportUsage,
|
|
178
|
+
model: harnessRef.current?.getModel(),
|
|
179
|
+
thinkingLevel: harnessRef.current?.getThinkingLevel(),
|
|
180
|
+
principal: spec.principal,
|
|
181
|
+
...(frozenOnAsk !== undefined ? { onAsk: frozenOnAsk } : {}),
|
|
182
|
+
...(frozenOnQuestion !== undefined ? { onQuestion: frozenOnQuestion } : {}),
|
|
183
|
+
...(spec.handsReadOnly === true ? { handsReadOnly: true } : {}),
|
|
184
|
+
...(carrierReadFace() === "roots" ? { readFace: "roots" } : {}),
|
|
185
|
+
...(readDenyAdditionsNormalized.length > 0 ? { readDenyPatterns: Object.freeze(readDenyAdditionsNormalized.map((e) => ({ ...e }))) } : {}),
|
|
186
|
+
...(spec.interactiveTools === false ? { interactiveTools: false } : {}),
|
|
187
|
+
oneShot: spec.oneShot,
|
|
188
|
+
clientContext: spec.clientContext,
|
|
189
|
+
excludeTools: toolFaceSnapshot.exclude,
|
|
190
|
+
deferTools: toolFaceSnapshot.defer,
|
|
191
|
+
alwaysLoadTools: toolFaceSnapshot.alwaysLoad,
|
|
192
|
+
...(toolFaceSnapshot.restoreGated !== undefined ? { restoreGatedTools: toolFaceSnapshot.restoreGated } : {}),
|
|
193
|
+
promptProfile,
|
|
194
|
+
...(spec.additionalDirectories !== undefined ? { additionalDirectories: Object.freeze([...spec.additionalDirectories]) } : {}),
|
|
195
|
+
...(spec.additionalReadDirectories !== undefined ? { additionalReadDirectories: Object.freeze([...spec.additionalReadDirectories]) } : {}),
|
|
196
|
+
...(spec.envFacts !== undefined ? { envFacts: { ...spec.envFacts } } : {}),
|
|
197
|
+
...(spec.memoryPersistenceCapable !== undefined ? { memoryPersistenceCapable: spec.memoryPersistenceCapable } : {}),
|
|
198
|
+
get memoryCaptureOptedOut() {
|
|
199
|
+
return input.memoryEngineSession()?.captureOptOut?.optedOut() ?? false;
|
|
200
|
+
},
|
|
201
|
+
get memoryCaptureIndeterminate() {
|
|
202
|
+
return input.memoryEngineSession()?.captureOptOut?.indeterminate() ?? false;
|
|
203
|
+
},
|
|
204
|
+
get memoryCaptureControlDir() {
|
|
205
|
+
return input.memoryEngineSession()?.engine.controlPlaneDir;
|
|
206
|
+
},
|
|
207
|
+
get memoryCaptureAncestors() {
|
|
208
|
+
const ctl = input.memoryEngineSession()?.engine.controlPlaneDir;
|
|
209
|
+
return [...(internals?.memoryCaptureAncestors ?? []), { sessionId, ...(ctl !== undefined ? { controlDir: ctl } : {}) }];
|
|
210
|
+
},
|
|
211
|
+
getApiKeyAndHeaders: spec.getApiKeyAndHeaders,
|
|
212
|
+
parentCwd: taskRootFinal,
|
|
213
|
+
...(fileHistoryEnabled ? { fileHistoryLineage: { scope: historyScope, root: historyRoot, fs: historyFs } } : {}),
|
|
214
|
+
reminderMark,
|
|
215
|
+
reminderDisclosureCounts,
|
|
216
|
+
...(centerAdoption !== undefined ? { centerArtifactDigest: centerAdoption.artifact.artifactDigest } : {}),
|
|
217
|
+
...(centerAdoption?.sourceRevision !== undefined ? { centerSourceRevision: centerAdoption.sourceRevision } : {}),
|
|
218
|
+
activeSkillScope: () => skillScope.active(),
|
|
219
|
+
inheritedGateForChildren,
|
|
220
|
+
delegationProvenanceForChildren,
|
|
221
|
+
delegationSettlement: delegationSettlementForChildren,
|
|
222
|
+
...(autoModeDecider ? { autoModeReview: { decider: autoModeDecider } } : {}),
|
|
223
|
+
...(spec.durableApproval !== undefined ? { durableApprovalForChildren: { ...spec.durableApproval } } : {}),
|
|
224
|
+
...(spec.checkpointStore === null ? { checkpointStoreDisabledForChildren: true } : {}),
|
|
225
|
+
taskId: hostTaskId,
|
|
226
|
+
...(internals?.parentTaskId !== undefined ? { parentTaskId: internals.parentTaskId } : {}),
|
|
227
|
+
...(internals?.parentSessionId !== undefined ? { parentSessionId: internals.parentSessionId } : {}),
|
|
228
|
+
...(internals?.rootSessionId !== undefined ? { rootSessionId: internals.rootSessionId } : {}), ...(internals?.placementRoot !== undefined ? { placementRoot: internals.placementRoot } : {}),
|
|
229
|
+
...(internals?.explicitAgentName !== undefined ? { spawnedAgentName: internals.explicitAgentName } : {}),
|
|
230
|
+
...(internals?.peerSelfRef !== undefined ? { peerSelfRef: internals.peerSelfRef } : {}),
|
|
231
|
+
...(internals?.peerInboundChainRef !== undefined ? { peerInboundChainRef: internals.peerInboundChainRef } : {}),
|
|
232
|
+
...(deps.rosterStore !== undefined ? { roster: deps.rosterStore } : {}),
|
|
233
|
+
...(sessions.fork !== undefined
|
|
234
|
+
? {
|
|
235
|
+
hostSessionFork: async () => {
|
|
236
|
+
const forked = (await sessions.fork(sessionId, spec.principal ?? null)) ?? null;
|
|
237
|
+
if (forked === null)
|
|
238
|
+
return null;
|
|
239
|
+
return {
|
|
240
|
+
sessionId: forked,
|
|
241
|
+
release: async () => {
|
|
242
|
+
await sessions.release?.(forked);
|
|
243
|
+
},
|
|
244
|
+
};
|
|
245
|
+
},
|
|
246
|
+
}
|
|
247
|
+
: {}),
|
|
248
|
+
sessionId,
|
|
249
|
+
...(spec.backgroundScope !== undefined ? { backgroundScope: spec.backgroundScope } : {}),
|
|
250
|
+
...(resolvedInteractionPosture !== undefined ? { interactionPosture: resolvedInteractionPosture } : {}),
|
|
251
|
+
...(deps.onBackgroundChildEvent ? { onBackgroundChildEvent: deps.onBackgroundChildEvent } : {}),
|
|
252
|
+
...(internals?.onTaskNotification ? { onTaskNotification: internals.onTaskNotification } : {}),
|
|
253
|
+
...(forwardEvent ? { forwardEvent } : {}),
|
|
254
|
+
...(internals?.onSubagentSpawn ? { onSubagentSpawn: internals.onSubagentSpawn } : {}),
|
|
255
|
+
...(subagentRetain ? { subagentRetain } : {}),
|
|
256
|
+
...(worktreeIsolation ? { worktreeIsolation } : {}),
|
|
257
|
+
...(internals?.insideFork === true ? { insideFork: true } : {}),
|
|
258
|
+
...(agentForkDenial !== undefined ? { forkAccess: { denied: agentForkDenial } } : {}),
|
|
259
|
+
...(observersActive ? { observersAllowed: true } : {}),
|
|
260
|
+
requestReview,
|
|
261
|
+
requestStopAfterTurn,
|
|
262
|
+
...(spec.enablePlanMode === true ? { enterPlanMode } : {}),
|
|
263
|
+
};
|
|
264
|
+
};
|
|
265
|
+
return { liveInheritedGate, seedInheritedGate, inheritedAncestorRules, inheritedShellGate, inheritedParentConstraints, autoModeIntent, inheritedAdmittedOrgScopes, priorOwnOrgVerdict, orgGovernedProvenance, effectiveShellGate, ownSessionRulesRef, memoryAdmittedOrgScopesRef, ownOrgVerdictRef, orgAdmissionCheckpointState, faceCheckpointSection, faceCheckpointState, f012CheckpointState, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, frozenOnQuestion, provenanceForChildrenRef, delegationSettlementRef, inheritedGateForChildren, carrierReadFace, fullShellReachable, gateStopRef, stopForDenialLimit, enrichSpecToolCtx };
|
|
266
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* design/390 M15 — prepareTask's LISTINGS phase: the per-task agent definitions' tool-name audit
|
|
3
|
+
* (deny entries fail loud, allow entries advise), the agent-listing announce face read off the
|
|
4
|
+
* delegation tool's roster (with its deferred / excluded / removal-to-zero arms), the two listing
|
|
5
|
+
* opt-out advisories, the announced-listings mirror seeded from the once-per-session ledger, the
|
|
6
|
+
* deferred roster's ToolSearch ride, and the date_change seam. The body is the driver's stretch moved
|
|
7
|
+
* verbatim; the interface is the dependency list it had implicitly (design/238 R-1).
|
|
8
|
+
*
|
|
9
|
+
* SYNCHRONOUS FUNCTION, SYNCHRONOUS CALL: the stretch has no await, so the phase adds no yield between
|
|
10
|
+
* the disclosure mount before it and the context-lane seats after it (design/390 §1.5 S1: a stretch
|
|
11
|
+
* with no await is extracted as a sync function — an `async` wrapper would open a microtask window).
|
|
12
|
+
*
|
|
13
|
+
* Throws pass through unchanged: `config.agent.unknown_tool` (a deny entry naming a tool this
|
|
14
|
+
* deployment does not mount — a typo there would silently guard nothing).
|
|
15
|
+
*/
|
|
16
|
+
import type { AgentTool } from "../../internal/harness.js";
|
|
17
|
+
import type { TaskSpec } from "../types.js";
|
|
18
|
+
import type { AnnounceOnceSink, Prepared, PrepareResume, ToolFaceSnapshot } from "./contracts.js";
|
|
19
|
+
import type { AnnouncedListingSnapshot } from "../../internal/harness.js";
|
|
20
|
+
export interface PrepareListingsInput {
|
|
21
|
+
/** borrowed-readonly — the REBOUND spec (`spec′`). Read: `agents` (the audit's subject), `tools`
|
|
22
|
+
* (the roster-bearing delegation tool, by its `agentListing` marker), `sessionId` (continuation
|
|
23
|
+
* ⇒ seeded/removal projections), `attachments` (the two opt-outs). Never mutated. */
|
|
24
|
+
spec: Pick<TaskSpec, "agents" | "tools" | "sessionId" | "attachments">;
|
|
25
|
+
/** borrowed-readonly — the FULLY ASSEMBLED mount array (names + aliases = the audit's universe).
|
|
26
|
+
* Read only; this phase never mutates the roster. */
|
|
27
|
+
tools: ReadonlyArray<AgentTool>;
|
|
28
|
+
/** borrowed-readonly — the once-per-session ledger: its deduplicated operator sink (`onError`) and
|
|
29
|
+
* the whole announced snapshot (`arms()`) the mirror is seeded from. */
|
|
30
|
+
onceLedger: AnnounceOnceSink & {
|
|
31
|
+
arms(): AnnouncedListingSnapshot;
|
|
32
|
+
};
|
|
33
|
+
/** borrowed-readonly — the acquired session's id (operator-line context). */
|
|
34
|
+
sessionId: string;
|
|
35
|
+
/** borrowed-readonly — the frozen tool face: `exclude` / `defer` decide the roster face's arm. */
|
|
36
|
+
toolFaceSnapshot: Pick<ToolFaceSnapshot, "exclude" | "defer">;
|
|
37
|
+
/** borrowed-readonly — the activated deferred names as of prepare (transcript replay / checkpoint
|
|
38
|
+
* seed); only `has()` is read: an already-ACTIVE roster tool un-defers its listing face. The set
|
|
39
|
+
* keeps mutating mid-run (ToolSearch activations) — this phase reads it once, here. */
|
|
40
|
+
activeTools: ReadonlySet<string>;
|
|
41
|
+
/** borrowed-readonly — the durable-resume carrier: presence (seedAnnounced) and
|
|
42
|
+
* `seed.announcedListings.agents` (the removal-to-zero projection's gate). */
|
|
43
|
+
resume: Pick<PrepareResume, "seed"> | undefined;
|
|
44
|
+
/** borrowed-readonly — the project-context phase's skills-listing projection; read only for the
|
|
45
|
+
* skills opt-out advisory (entries.length). */
|
|
46
|
+
skillsListing: Prepared["skillsListing"];
|
|
47
|
+
/** borrowed-mutable — the deferred roster's ToolSearch RIDE seat (declared by the disclosure
|
|
48
|
+
* mount, read at activation time through `listingRideRef.current?.(newly)`). Written here, once,
|
|
49
|
+
* on a deferred roster face; no later writer. Identity is the contract (the mount's closures read
|
|
50
|
+
* this exact cell). */
|
|
51
|
+
listingRideRef: {
|
|
52
|
+
current?: (newly: readonly string[]) => string | undefined;
|
|
53
|
+
};
|
|
54
|
+
/** borrowed-readonly — the prompt assembly's date re-renderer; presence alone decides whether the
|
|
55
|
+
* date_change seam exists (a provider that owns the whole prompt has none). */
|
|
56
|
+
renderWithDate: ((date: string) => string) | undefined;
|
|
57
|
+
/** borrowed-readonly — the environment facts; only `date` is read (the leg's frozen date). */
|
|
58
|
+
envFacts: {
|
|
59
|
+
readonly date?: string;
|
|
60
|
+
};
|
|
61
|
+
/** borrowed-readonly — whether the client zone validated (the seam re-judges "today" in it). */
|
|
62
|
+
tzValid: boolean;
|
|
63
|
+
/** borrowed-readonly — the client's declared zone (used only when `tzValid`). */
|
|
64
|
+
userTz: string | undefined;
|
|
65
|
+
}
|
|
66
|
+
export interface PrepareListingsResult {
|
|
67
|
+
/** owned — the agent-listing announce projection (`Prepared.agentListing`): the roster off the
|
|
68
|
+
* delegation tool's effective face, the removal-to-zero projection, or undefined (silent). */
|
|
69
|
+
agentListing: Prepared["agentListing"];
|
|
70
|
+
/** owned — the announced-listings mirror seeded from the ledger's whole snapshot
|
|
71
|
+
* (`Prepared.announcedListingsRef`); the run loop and the checkpoint serializer write it from here on. */
|
|
72
|
+
announcedListingsRef: Prepared["announcedListingsRef"];
|
|
73
|
+
/** owned — the date_change seam (`Prepared.dateChange`), or undefined when the prompt has no date re-renderer. */
|
|
74
|
+
dateChange: Prepared["dateChange"];
|
|
75
|
+
}
|
|
76
|
+
/** The M15 phase body — prepareTask's listings stretch, verbatim (see the module header). */
|
|
77
|
+
export declare function prepareListings(input: PrepareListingsInput): PrepareListingsResult;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { formatLocalDate } from "../../prompts/default.js";
|
|
2
|
+
import { SKILL_TOOL_NAME } from "./synthetic-tools.js";
|
|
3
|
+
import { renderAgentListingDelta } from "./turn-attachments.js";
|
|
4
|
+
export function prepareListings(input) {
|
|
5
|
+
const { spec, tools, onceLedger, sessionId, toolFaceSnapshot, activeTools, resume, skillsListing, listingRideRef, renderWithDate, envFacts, tzValid, userTz } = input;
|
|
6
|
+
if (spec.agents !== undefined && spec.agents.length > 0) {
|
|
7
|
+
const known = new Set(tools.flatMap((t) => [t.name, ...(t.aliases ?? [])]));
|
|
8
|
+
for (const def of spec.agents) {
|
|
9
|
+
const unknownAllow = (def.allowTools ?? []).filter((n) => n !== "*" && !known.has(n));
|
|
10
|
+
if (unknownAllow.length > 0) {
|
|
11
|
+
try {
|
|
12
|
+
onceLedger.onError(new Error(`TaskSpec.agents: agent "${def.name}" allows tool(s) ${unknownAllow.join(", ")} not present in this task's assembled roster — likely a typo (the entry would be item-filtered at spawn; the agent stays usable). Advisory only: the delegation pool can differ from this roster, so a tool mounted only on the delegation tool or produced by per-spawn extraTools makes this spurious.`), { phase: "config", sessionId });
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
for (const n of def.denyTools ?? []) {
|
|
18
|
+
if (n === "*")
|
|
19
|
+
continue;
|
|
20
|
+
if (!known.has(n)) {
|
|
21
|
+
const e = new Error(`TaskSpec.agents: agent "${def.name}" declares tool "${n}" in its denied tools, but no such tool exists in this deployment — fix the agent's tools list or mount the tool.`);
|
|
22
|
+
e.code = "config.agent.unknown_tool";
|
|
23
|
+
throw e;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const rosterBearingSpec = (spec.tools ?? []).find((t) => t.agentListing !== undefined && t.agentListing.length > 0);
|
|
29
|
+
const rosterFaceDeferred = rosterBearingSpec !== undefined &&
|
|
30
|
+
!(toolFaceSnapshot.exclude?.includes(rosterBearingSpec.name) ?? false) &&
|
|
31
|
+
(toolFaceSnapshot.defer?.includes(rosterBearingSpec.name) ?? false) &&
|
|
32
|
+
!activeTools.has(rosterBearingSpec.name);
|
|
33
|
+
const agentListingSpec = rosterBearingSpec !== undefined &&
|
|
34
|
+
!rosterFaceDeferred &&
|
|
35
|
+
!(toolFaceSnapshot.exclude?.includes(rosterBearingSpec.name) ?? false)
|
|
36
|
+
? rosterBearingSpec
|
|
37
|
+
: undefined;
|
|
38
|
+
const agentListing = agentListingSpec
|
|
39
|
+
? {
|
|
40
|
+
entries: agentListingSpec.agentListing,
|
|
41
|
+
toolName: agentListingSpec.name,
|
|
42
|
+
seedAnnounced: resume !== undefined || spec.sessionId !== undefined,
|
|
43
|
+
...(agentListingSpec.agentModels !== undefined ? { models: agentListingSpec.agentModels } : {}),
|
|
44
|
+
}
|
|
45
|
+
:
|
|
46
|
+
!rosterFaceDeferred && ((resume?.seed.announcedListings?.agents?.length ?? 0) > 0 || spec.sessionId !== undefined)
|
|
47
|
+
?
|
|
48
|
+
{
|
|
49
|
+
entries: [],
|
|
50
|
+
toolName: (spec.tools ?? []).find((t) => t.agentListing !== undefined)?.name ?? "Agent",
|
|
51
|
+
seedAnnounced: true,
|
|
52
|
+
}
|
|
53
|
+
: undefined;
|
|
54
|
+
if (spec.attachments?.agentListing === false && agentListing !== undefined && agentListing.entries.length > 0) {
|
|
55
|
+
onceLedger.onError(new Error(`attachments.agentListing is explicitly false but the "${agentListing.toolName}" delegation tool mounts a ${agentListing.entries.length}-type roster — the model will never see the agent-type listing its tool description points to.`), { phase: "config", sessionId });
|
|
56
|
+
}
|
|
57
|
+
if (spec.attachments?.skillsListing === false && skillsListing !== undefined && skillsListing.entries.length > 0) {
|
|
58
|
+
onceLedger.onError(new Error(`attachments.skillsListing is explicitly false but ${skillsListing.entries.length} skill(s) are mounted — the model will never see the skills listing the ${SKILL_TOOL_NAME} tool description points to.`), { phase: "config", sessionId });
|
|
59
|
+
}
|
|
60
|
+
const announcedListingsRef = onceLedger.arms();
|
|
61
|
+
if (rosterFaceDeferred && rosterBearingSpec !== undefined) {
|
|
62
|
+
const rideEntries = rosterBearingSpec.agentListing;
|
|
63
|
+
const rideModels = rosterBearingSpec.agentModels;
|
|
64
|
+
listingRideRef.current = (newly) => {
|
|
65
|
+
if (!newly.includes(rosterBearingSpec.name))
|
|
66
|
+
return undefined;
|
|
67
|
+
if ((announcedListingsRef.agents?.length ?? 0) > 0)
|
|
68
|
+
return undefined;
|
|
69
|
+
return renderAgentListingDelta({ announcedAgentTypes: undefined }, rideEntries, rosterBearingSpec.name, rideModels);
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const dateChange = renderWithDate
|
|
73
|
+
? { legDate: envFacts.date, today: () => formatLocalDate(new Date(), tzValid ? userTz : undefined) }
|
|
74
|
+
: undefined;
|
|
75
|
+
return { agentListing, announcedListingsRef, dateChange };
|
|
76
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* design/390 §1.2 M8 — prepareTask's LSP phase, verbatim from the driver: the manager fold (spec > deps), the
|
|
3
|
+
* LSP tool mount over the per-task env with its git-ignore filter, the diagnostics lane behind its four
|
|
4
|
+
* preconditions (a manager whose sessions feed a registry, write-capable hands, not opted out), the run-scoped
|
|
5
|
+
* registry key, and the edit nudge (raw path → the SAME resolution the tool leg uses → registry reset +
|
|
6
|
+
* session didChange). No manager ⇒ nothing mounts and both lane seats are undefined. The interface is the
|
|
7
|
+
* dependency list the segment had implicitly (design/238 R-1).
|
|
8
|
+
*
|
|
9
|
+
* SYNCHRONOUS FUNCTION, SYNCHRONOUS CALL: the stretch has no await, so the phase adds no yield between the
|
|
10
|
+
* fork-governance note before it and the memory trio's occupancy read after it (design/390 §1.5 S1: a stretch
|
|
11
|
+
* with no await is extracted as a sync function — an `async` wrapper would open a microtask window).
|
|
12
|
+
* Read-stability of the host handles for the call: {@link RunInternals} (`@contract prepare.deps-read-stable`).
|
|
13
|
+
*/
|
|
14
|
+
import type { AgentTool, ExecutionEnv } from "../../internal/harness.js";
|
|
15
|
+
import type { LspDiagnosticsRegistry } from "../lsp-diagnostics.js";
|
|
16
|
+
import type { RunnerDeps, TaskSpec } from "../types.js";
|
|
17
|
+
import type { Prepared } from "./contracts.js";
|
|
18
|
+
export interface PrepareLspInput {
|
|
19
|
+
/** borrowed-readonly — the REBOUND spec. Read: `lspManager` (the per-task manager, outranks the deployment's),
|
|
20
|
+
* `lspDiagnostics` (the lane's opt-out), `handsReadOnly` (a read-only run has no lane). Never mutated. */
|
|
21
|
+
spec: Pick<TaskSpec, "lspManager" | "lspDiagnostics" | "handsReadOnly">;
|
|
22
|
+
/** borrowed-readonly — the deployment's manager seat (read only when the spec carries none). */
|
|
23
|
+
deps: Pick<RunnerDeps, "lspManager">;
|
|
24
|
+
/** borrowed-readonly — the run's resolved env: the tool's in-env server and git-ignore filter, and the
|
|
25
|
+
* session lookup the nudge performs. */
|
|
26
|
+
executionEnv: ExecutionEnv;
|
|
27
|
+
/** borrowed-readonly — the SETTLED task root: the tool's git-ignore root, and the nudge's resolution base when
|
|
28
|
+
* no cwd is tracked. */
|
|
29
|
+
taskRootFinal: string;
|
|
30
|
+
/** borrowed-readonly — whether a real fs env is present (the lane's hands precondition). */
|
|
31
|
+
handsEnabled: boolean;
|
|
32
|
+
/** borrowed-readonly — the acquired session id: the run's key into the deployment-shared registry. */
|
|
33
|
+
sessionId: string;
|
|
34
|
+
/** borrowed-readonly — the tracked-cwd cell the hands band writes; the nudge READS `current` per call as its
|
|
35
|
+
* resolution base (identity is the contract — the band's `cd` handling writes this exact cell). */
|
|
36
|
+
handsCwdRef: Prepared["cwdRef"];
|
|
37
|
+
/** borrowed-mutable — the run's shared roster (identity is the contract). Writer here: ONE push (the LSP tool)
|
|
38
|
+
* when a manager exists. */
|
|
39
|
+
tools: AgentTool[];
|
|
40
|
+
/** borrowed-mutable — the env-hand membership set the read-posture observer projects; writer here: `add("LSP")`
|
|
41
|
+
* on the mount. */
|
|
42
|
+
envHandToolNames: Set<string>;
|
|
43
|
+
}
|
|
44
|
+
export interface PrepareLspResult {
|
|
45
|
+
/** borrowed-readonly — the manager's diagnostics registry when the lane is live, else undefined (the
|
|
46
|
+
* registry is a DEPLOYMENT object shared by every task; this run reads and resets it under its own key). */
|
|
47
|
+
lspDiagnostics: LspDiagnosticsRegistry | undefined;
|
|
48
|
+
/** owned — the edit nudge (raw path in), or undefined when the lane is not live. */
|
|
49
|
+
nudgeLspOnEdit: ((rawPath: string) => void) | undefined;
|
|
50
|
+
/** borrowed-readonly — the run's registry key (= the session id): a session hosts one run at a time and the
|
|
51
|
+
* run loop releases the key at the terminal. */
|
|
52
|
+
lspRunIdent: string;
|
|
53
|
+
}
|
|
54
|
+
/** The M8 phase body — prepareTask's LSP stretch, verbatim (see the module header). */
|
|
55
|
+
export declare function prepareLsp(input: PrepareLspInput): PrepareLspResult;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { createLspTool, gitCheckIgnoreFilter, resolveLspPath } from "../lsp.js";
|
|
2
|
+
import { pathToUri } from "../lsp-protocol.js";
|
|
3
|
+
export function prepareLsp(input) {
|
|
4
|
+
const { spec, deps, executionEnv, taskRootFinal, handsEnabled, sessionId, handsCwdRef, tools, envHandToolNames } = input;
|
|
5
|
+
const lspManager = spec.lspManager ?? deps.lspManager;
|
|
6
|
+
if (lspManager) {
|
|
7
|
+
const lspRoot = taskRootFinal;
|
|
8
|
+
tools.push(createLspTool(lspManager, { isPathIgnored: gitCheckIgnoreFilter(executionEnv, lspRoot), env: executionEnv }));
|
|
9
|
+
envHandToolNames.add("LSP");
|
|
10
|
+
}
|
|
11
|
+
const lspDiagnostics = spec.lspDiagnostics !== false && lspManager?.diagnostics !== undefined && handsEnabled && spec.handsReadOnly !== true
|
|
12
|
+
? lspManager.diagnostics
|
|
13
|
+
: undefined;
|
|
14
|
+
const lspRunIdent = sessionId;
|
|
15
|
+
const nudgeLspOnEdit = lspDiagnostics
|
|
16
|
+
? (rawPath) => {
|
|
17
|
+
const baseDir = handsCwdRef?.current ?? taskRootFinal;
|
|
18
|
+
const filePath = resolveLspPath(rawPath, baseDir);
|
|
19
|
+
lspDiagnostics.fileEdited(lspRunIdent, pathToUri(filePath));
|
|
20
|
+
void lspManager
|
|
21
|
+
.sessionFor(filePath, undefined, executionEnv)
|
|
22
|
+
.then((session) => session?.notifyFileChanged?.(filePath))
|
|
23
|
+
.catch(() => undefined);
|
|
24
|
+
}
|
|
25
|
+
: undefined;
|
|
26
|
+
return { lspDiagnostics, nudgeLspOnEdit, lspRunIdent };
|
|
27
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* design/390 §1.2 M12 — prepareTask's MEMORY-ENGINE-SESSION phase, verbatim from the driver: the content-origin
|
|
3
|
+
* classification + one-way session pollution wrap section (design/178 §3 / design/180 half A / design/324 /
|
|
4
|
+
* design/336 §3.3 + §5.5 / design/378 D-4 / design/380 O9a). Its arming predicate (a mounted memory session OR an
|
|
5
|
+
* upstream recorder channel), the chain-narrowed classification config, the children's provenance seat, the
|
|
6
|
+
* declared-MCP-class announcement, the settlement seat, the per-tool wrap with its three record verbs (mark /
|
|
7
|
+
* recordExternal / recordIncomplete), the Read tool's recall-taint arm and the delegation arm's three-valued
|
|
8
|
+
* attestation judgment all live here; the announcement helper only this section called moved with it. The
|
|
9
|
+
* interface is the dependency list the segment had implicitly (design/238 R-1).
|
|
10
|
+
*
|
|
11
|
+
* SYNCHRONOUS FUNCTION, SYNCHRONOUS CALL: the stretch has no await of its own (the awaits sit inside the wrappers it
|
|
12
|
+
* installs, which run at tool-call time), so the phase adds no yield between the deferred classification before it
|
|
13
|
+
* and the prompt assembly after it (design/390 §1.5: a stretch with no await is extracted as a sync function).
|
|
14
|
+
* Read-stability of the host handles for the call: {@link RunInternals} (`@contract prepare.deps-read-stable`).
|
|
15
|
+
*
|
|
16
|
+
* One read changed spelling and nothing else: the declared-class announcement read `mcp?.statuses` while `mcp` had
|
|
17
|
+
* long been the protocol-tools phase's non-null handle; the optional chain was dead and is now the plain member read.
|
|
18
|
+
*/
|
|
19
|
+
import type { AgentTool } from "../../internal/harness.js";
|
|
20
|
+
import type { LockedPreflight } from "../locked-config.js";
|
|
21
|
+
import type { MaterializedMcp } from "../mcp.js";
|
|
22
|
+
import { type DelegationContentSafety } from "../memory-engine/delegation-provenance.js";
|
|
23
|
+
import type { RunnerDeps, TaskSpec } from "../types.js";
|
|
24
|
+
import type { Prepared, RunInternals } from "./contracts.js";
|
|
25
|
+
export interface PrepareMemoryEngineSessionInput {
|
|
26
|
+
/** borrowed-readonly — the mounted engine session, or undefined (the ARMING fact's first half). Read: `pollution`
|
|
27
|
+
* (the mark face), `contentSafety` (the own half of the narrowing), `settlement` (the seat + the receipt ledger),
|
|
28
|
+
* `recallTaint` (the Read arm's judge). Never mutated; the wrappers call `pollution.markPolluted` at tool-call time. */
|
|
29
|
+
memoryEngineSession: Prepared["memoryEngineSession"];
|
|
30
|
+
/** borrowed-mutable — the trusted spawn-side channel; only `delegationProvenance` (the ARMING fact's second half: the
|
|
31
|
+
* recorder channel with the chain's frozen `contentSafety`). Writers: the wrappers this phase installs set
|
|
32
|
+
* `delegationProvenance.ref.current.sawExternal` / `.incomplete` at tool-call time (monotonic, never cleared). */
|
|
33
|
+
internals: Pick<RunInternals, "delegationProvenance"> | undefined;
|
|
34
|
+
/** borrowed-readonly — the doors' per-leg SNAPSHOT of `RunnerDeps.memoryDelegationEvidence` (screened in the
|
|
35
|
+
* synchronous pre-await stretch; never a live deps re-read here). */
|
|
36
|
+
memoryDelegationEvidence: "static-face" | "attested-only";
|
|
37
|
+
/** borrowed-readonly — the run's external-content-target fold (live adapter declaration OR the persisted bit). */
|
|
38
|
+
externalContentTargetActive: boolean;
|
|
39
|
+
/** borrowed-readonly — the frozen preflight; only `mcp` (the declared entries the announcement walks). */
|
|
40
|
+
lockedPreflight: Pick<LockedPreflight, "mcp">;
|
|
41
|
+
/** borrowed-readonly — the materialized MCP handle; only `statuses` (the announcement's mounted-tool count). */
|
|
42
|
+
mcp: Pick<MaterializedMcp, "statuses">;
|
|
43
|
+
/** borrowed-readonly — the acquired session id (notice detail). */
|
|
44
|
+
sessionId: string;
|
|
45
|
+
/** borrowed-readonly — the run's invocation id (notice detail; the once-per-leg claims are per-RUN claims). */
|
|
46
|
+
runId: string;
|
|
47
|
+
/** borrowed-readonly — the deployment seats; only `onNotice` (the declared-class line and the waiver notice). */
|
|
48
|
+
deps: Pick<RunnerDeps, "onNotice">;
|
|
49
|
+
/** borrowed-mutable — the children's provenance seat (the inherited-gate phase mints it; `inheritedGateForChildren`
|
|
50
|
+
* reads it late). Writer: THIS phase, once at arming, to the effective (chain-narrowed) config. */
|
|
51
|
+
provenanceForChildrenRef: {
|
|
52
|
+
current?: DelegationContentSafety;
|
|
53
|
+
};
|
|
54
|
+
/** borrowed-mutable — the children's settlement seat (the inherited-gate phase mints it). Writer: THIS phase, once at
|
|
55
|
+
* arming, when the memory session mounted a settlement (memoryProvenance "carry"). */
|
|
56
|
+
delegationSettlementRef: {
|
|
57
|
+
current?: {
|
|
58
|
+
controlDir: string;
|
|
59
|
+
sessionId: string;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
/** borrowed-readonly — the REBOUND spec; only `tools` (the RAW caller specs: caller-tool names and the marker-bearing
|
|
63
|
+
* delegation entries — the assembled roster objects carry neither marker). Never mutated. */
|
|
64
|
+
spec: Pick<TaskSpec, "tools">;
|
|
65
|
+
/** borrowed-readonly — the env-hand roster (membership minted at the mount sites); read by the classification. */
|
|
66
|
+
envHandToolNames: ReadonlySet<string>;
|
|
67
|
+
/** borrowed-mutable — the run's ONE tool roster. Writer here: the wrap pass REPLACES entries in place
|
|
68
|
+
* (`tools[i] = wrapped`, identity-tracked so a re-run never stacks wrappers); see the roster's writer table on
|
|
69
|
+
* {@link Prepared.tools}. */
|
|
70
|
+
tools: AgentTool[];
|
|
71
|
+
/** borrowed-mutable — the re-runnable wrap pass's seat (the protocol-tools phase mints it; the rebuild seam re-runs it
|
|
72
|
+
* after a refresh re-splice). Writer: THIS phase installs the pass and runs it once. */
|
|
73
|
+
contentOriginWrapRef: {
|
|
74
|
+
current?: () => void;
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
export interface PrepareMemoryEngineSessionResult {
|
|
78
|
+
/** owned — whether the section ARMED on this leg (a memory session or a recorder channel existed): armed ⇒ every
|
|
79
|
+
* roster tool was classified and the polluting/delegation/Read-plane ones wrapped; not armed ⇒ zero wraps, zero
|
|
80
|
+
* announcements, both children's seats untouched. */
|
|
81
|
+
armed: boolean;
|
|
82
|
+
}
|
|
83
|
+
/** The M12 phase body — prepareTask's content-origin wrap stretch, verbatim (see the module header). */
|
|
84
|
+
export declare function prepareMemoryEngineSession(input: PrepareMemoryEngineSessionInput): PrepareMemoryEngineSessionResult;
|