dsh-plugin-coding-delegate 0.0.0-stage → 0.2.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.
Files changed (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +920 -2
  3. package/cordis.patch.example.yml +48 -0
  4. package/cordis.patch.yml +13 -0
  5. package/dist/attestation.d.ts +25 -0
  6. package/dist/attestation.js +44 -0
  7. package/dist/containment.d.ts +33 -0
  8. package/dist/containment.js +63 -0
  9. package/dist/context-quality.d.ts +79 -0
  10. package/dist/context-quality.js +181 -0
  11. package/dist/context.d.ts +39 -0
  12. package/dist/context.js +136 -0
  13. package/dist/contracts.d.ts +174 -0
  14. package/dist/contracts.js +415 -0
  15. package/dist/declaration-egress-hook.d.ts +45 -0
  16. package/dist/declaration-egress-hook.js +125 -0
  17. package/dist/declaration-egress.d.ts +37 -0
  18. package/dist/declaration-egress.js +169 -0
  19. package/dist/delegation.d.ts +339 -0
  20. package/dist/delegation.js +933 -0
  21. package/dist/emission.d.ts +70 -0
  22. package/dist/emission.js +310 -0
  23. package/dist/guard.d.ts +162 -0
  24. package/dist/guard.js +873 -0
  25. package/dist/host-events.d.ts +15 -0
  26. package/dist/host-events.js +27 -0
  27. package/dist/index.d.ts +560 -0
  28. package/dist/index.js +1398 -0
  29. package/dist/local-classifier.d.ts +52 -0
  30. package/dist/local-classifier.js +159 -0
  31. package/dist/logging.d.ts +21 -0
  32. package/dist/logging.js +90 -0
  33. package/dist/paths.d.ts +10 -0
  34. package/dist/paths.js +83 -0
  35. package/dist/profiles.d.ts +35 -0
  36. package/dist/profiles.js +95 -0
  37. package/dist/retry-context.d.ts +52 -0
  38. package/dist/retry-context.js +97 -0
  39. package/dist/roles.d.ts +129 -0
  40. package/dist/roles.js +363 -0
  41. package/dist/routing.d.ts +35 -0
  42. package/dist/routing.js +88 -0
  43. package/dist/savings-tracker.d.ts +128 -0
  44. package/dist/savings-tracker.js +340 -0
  45. package/dist/session-events.d.ts +17 -0
  46. package/dist/session-events.js +31 -0
  47. package/dist/verification.d.ts +104 -0
  48. package/dist/verification.js +560 -0
  49. package/package.json +66 -4
@@ -0,0 +1,15 @@
1
+ import type { Events } from '@deepseek-ai/cordis';
2
+ /**
3
+ * Subscribe to a host event, with the event NAME and the handler's SHAPE both taken from the host.
4
+ *
5
+ * `OmitThisParameter` is load-bearing rather than cosmetic. Several host events declare `this:
6
+ * Scoped<Agent>` or `this: Scoped<Session>`, and Cordis binds that itself; a plain arrow function has
7
+ * `this: void` and would be rejected for a `this` it never uses. Stripping the parameter keeps the real
8
+ * arguments and the return type, which are the parts a handler can get wrong.
9
+ *
10
+ * Declaring the handler this way is what makes the payloads checked: a handler written as
11
+ * `(payload, next) => …` with no annotations now has both parameters inferred from the host's own
12
+ * signature, so reading a field the host does not send is a compile error. Handlers that still annotate
13
+ * `any` compile as before -- the check is available, not enforced by force.
14
+ */
15
+ export declare function onHost<K extends keyof Events>(ctx: any, event: K, handler: OmitThisParameter<Events[K]>, options?: any): void;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.onHost = onHost;
4
+ /**
5
+ * Subscribe to a host event, with the event NAME and the handler's SHAPE both taken from the host.
6
+ *
7
+ * `OmitThisParameter` is load-bearing rather than cosmetic. Several host events declare `this:
8
+ * Scoped<Agent>` or `this: Scoped<Session>`, and Cordis binds that itself; a plain arrow function has
9
+ * `this: void` and would be rejected for a `this` it never uses. Stripping the parameter keeps the real
10
+ * arguments and the return type, which are the parts a handler can get wrong.
11
+ *
12
+ * Declaring the handler this way is what makes the payloads checked: a handler written as
13
+ * `(payload, next) => …` with no annotations now has both parameters inferred from the host's own
14
+ * signature, so reading a field the host does not send is a compile error. Handlers that still annotate
15
+ * `any` compile as before -- the check is available, not enforced by force.
16
+ */
17
+ function onHost(ctx, event, handler, options) {
18
+ if (typeof ctx?.on !== 'function')
19
+ return;
20
+ // The optional third argument is Cordis's own listener options (`{ prepend: true }` is used by the DLP
21
+ // and routing hooks, which must see a request before anything else does). Passed through rather than
22
+ // dropped: a wrapper that silently changes dispatch order is a worse bug than the one it is preventing.
23
+ if (options === undefined)
24
+ ctx.on(event, handler);
25
+ else
26
+ ctx.on(event, handler, options);
27
+ }
@@ -0,0 +1,560 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import { SavingsTracker, RouteType, StepUsage } from './savings-tracker';
3
+ import { PROFILES, ProfileConfig } from './profiles';
4
+ import { extractAndEmitFiles } from './emission';
5
+ import { VerificationPolicy, parseTestOutput, runSandboxVerification } from './verification';
6
+ import { resolveContextFiles } from './context';
7
+ import { DelegateReadPolicy, GuardVerdict, evaluateDelegatedReadPolicy } from './guard';
8
+ import { SourceEgressPolicy, applyAgentRole, applyArchitectConfig, describeSourceRead, detectSourceEgress, evaluateSourceEgress, rememberAgentRole, resetAgentRoles, resolveAgentRole, resolveLeadProviders, roleForAgent } from './roles';
9
+ import { applySearchReplaceBlocks, delegateWorker, parseSearchReplaceBlocks, resolveDelegateStatus, resolveVerificationRepeats } from './delegation';
10
+ import { contractFileHashes, contractViolations, loadDelegatedRegistry, mergeDelegatedRecords, parseDelegatedRegistry, pruneDelegatedRecords, rememberDelegated, resolveContractFiles, resolveDelegatedRegistryPath, saveDelegatedRegistry, sha256File } from './contracts';
11
+ export { PROFILES, ProfileConfig, SavingsTracker, RouteType, StepUsage };
12
+ export { resolveDataDir, trace } from './logging';
13
+ export { isPathWithin } from './paths';
14
+ export { evaluateEmissionPath, evaluateUnitScope, extractAndEmitFiles } from './emission';
15
+ export { DELETE_PRIMITIVES, evaluateCodeWriteGuard, evaluateDelegatedReadPolicy, hasCommandDeleteSignal, hasCommandWriteSignal, } from './guard';
16
+ export { AGENT_ROLE_LIMIT, DEFAULT_SOURCE_EGRESS_MIN_LINES, agentLineageRole, applyAgentRole, applyArchitectConfig, describeSourceRead, detectSourceEgress, evaluateSourceEgress, rememberAgentRole, resetAgentRoles, resolveAgentRole, resolveLeadProviders, roleForAgent, roleFromLineage, } from './roles';
17
+ export { ContextInjection, ContextRequest, ContextResolution, DEFAULT_CONTEXT_MAX_BYTES, resolveContextFiles, } from './context';
18
+ export { contractFileHashes, contractViolations, loadDelegatedRegistry, mergeDelegatedRecords, parseDelegatedRegistry, pruneDelegatedRecords, rememberDelegated, recordOperatorAttestation, resolveContractFiles, resolveDelegatedRegistryPath, saveDelegatedRegistry, sha256File, } from './contracts';
19
+ export { DEFAULT_VERIFICATION_POLICY, DEFAULT_VERIFICATION_TIMEOUT_MS, commandProgram, describeFailures, evaluateVerificationPolicy, parseTestOutput, redactVerificationOutput, resolveVerificationTimeoutMs, runInProcessFallback, runSandboxVerification, } from './verification';
20
+ export { ContextQuality, EMPTY_CONTEXT_QUALITY, describeContextQuality, foldContextQuality, } from './context-quality';
21
+ export { DELEGATE_WORKER_OPENAI_SCHEMA, DELEGATE_WORKER_SCHEMA, DELEGATE_WORKER_SCHEMA_COVERS_EVERY_PARAMETER, DEFAULT_LOCAL_ENDPOINT, MIN_SEARCH_CHARS, applySearchReplaceBlocks, delegateWorker, estimateTokenCount, extractPromptText, parseSearchReplaceBlocks, resolveChatCompletionsUrl, resolveDelegateStatus, resolveVerificationRepeats, } from './delegation';
22
+ export { FailureLocation, RETRY_CONTEXT_WINDOW_LINES, parseFailureLocations, retryContextRequests, } from './retry-context';
23
+ export declare const inject: string[];
24
+ export declare const using: readonly ["tools"];
25
+ export interface PluginConfig {
26
+ localProvider?: string;
27
+ cloudProvider?: string;
28
+ localModel?: string;
29
+ cloudModel?: string;
30
+ contextTokenThreshold?: number;
31
+ contextThreshold?: number;
32
+ timeoutMs?: number;
33
+ enforceDLP?: boolean;
34
+ /**
35
+ * What a tripped DLP firewall does with an outbound request: `'block'`
36
+ * (default) refuses to transmit it, `'local'` reroutes it to the local worker.
37
+ * Either way the credential never reaches the cloud.
38
+ */
39
+ dlpAction?: 'block' | 'local';
40
+ /** Enable the high-entropy backstop (default true). */
41
+ entropyCheck?: boolean;
42
+ /** Bits per character above which a token counts as suspiciously random (default 4.5). */
43
+ entropyMinBitsPerChar?: number;
44
+ /** Minimum token length before entropy is scored (default 20). */
45
+ entropyMinLength?: number;
46
+ /** Refuse cloud-authored writes to source files (default: true). */
47
+ /**
48
+ * What a read of source code returns to the architect.
49
+ *
50
+ * `'source'` (the default) is the historical behaviour: the file's contents are served unchanged.
51
+ *
52
+ * `'declarations'` serves the compiled TYPE SKELETON instead -- declarations, signatures and doc
53
+ * comments, with every function body stripped -- computed by the same `tsc` build that produces `dist/`.
54
+ * This is the mechanical form of "inverted ingestion": what crosses to the model is whatever the
55
+ * declaration emitter produced, so implementation bodies cannot leave the machine because of the shape of
56
+ * the egress rather than because the model chose not to ask for them. Measured on this repository, the
57
+ * skeleton is 3.3x smaller than the source with doc comments and 7.8x smaller without.
58
+ *
59
+ * A source file with no corresponding declaration is REFUSED rather than served as source. Failing closed
60
+ * is the point: an unimplemented mapping must not silently become the hole it was built to close.
61
+ * Requires `declarationRoot`.
62
+ *
63
+ * The limit worth knowing before turning this on: doc comments and signatures are preserved, not
64
+ * summarised, so an implementation whose behaviour lives in its body is still invisible. This removes
65
+ * bodies, not the need to read them when a defect has no structural signature.
66
+ *
67
+ * NOT the same option as `sourceEgress`, which is rule 8 and governs source inside a prompt payload.
68
+ * This one governs file reads by a tool call. They are different leaks and they fail differently, so
69
+ * they are named differently on purpose.
70
+ */
71
+ sourceReadEgress?: 'source' | 'declarations';
72
+ /**
73
+ * Directory holding emitted `.d.ts` files, used when `sourceReadEgress` is `'declarations'`. A source
74
+ * path's tree below `src/` is preserved, so `src/guard.ts` resolves under this root as `guard.d.ts`.
75
+ */
76
+ declarationRoot?: string;
77
+ /**
78
+ * Who to name as the operator when an attestation is recorded through `delegate_worker`.
79
+ *
80
+ * An attestation is a HUMAN claim about content, so it needs a human to name. There is deliberately no
81
+ * fallback to the calling agent's id: an autonomous session identifier cannot stand in for a person, and
82
+ * stamping one into the registry would produce a record LESS attributable than a typed name while looking
83
+ * like more. A delegation that asks for an attestation with no identity available is refused, with the
84
+ * unit's own verdict left intact -- the delegation succeeded, and only the attestation did not.
85
+ *
86
+ * Set once per environment or developer seat. A call may override it with `attestOperator`, which is the
87
+ * explicit-over-ambient precedence.
88
+ */
89
+ operatorIdentity?: string;
90
+ localCodeGuard?: boolean;
91
+ /** Force every guard hit to an approval prompt instead of a hard deny. */
92
+ guardMode?: 'deny' | 'ask';
93
+ /** Path fragments that downgrade a deny to an approval prompt. */
94
+ guardAskPaths?: string[];
95
+ /**
96
+ * What happens to `delegate_worker`'s model-supplied `runVerification` command.
97
+ * `'ask'` (default) routes it through the approval seam before anything executes;
98
+ * `'allow'` restores the pre-hardening unattended behaviour; `'deny'` never runs it.
99
+ */
100
+ verificationApproval?: 'ask' | 'allow' | 'deny';
101
+ /**
102
+ * Verification programs (the command's first token) that skip the prompt under
103
+ * `verificationApproval: 'ask'`. Weak by construction: it constrains the program,
104
+ * not its arguments, so listing `node` also permits `node -e "<anything>"`.
105
+ */
106
+ verificationAllowlist?: string[];
107
+ /**
108
+ * How long `delegate_worker`'s verification command may run before it is killed, in milliseconds.
109
+ * Defaults to 30,000 — the value this used to be hardcoded to — so configuring nothing changes
110
+ * nothing. Raise it for a contract whose command legitimately needs longer: a full suite, a build,
111
+ * an install.
112
+ *
113
+ * A value that is not a positive finite number falls back to the default rather than removing the
114
+ * bound. An unbounded command that is model-selected and runs with the DSH process's authority is a
115
+ * hang, not a permission.
116
+ */
117
+ verificationTimeoutMs?: number;
118
+ /**
119
+ * The project's own check — a build, a full suite — run after each unit's contract, with the power to
120
+ * void an otherwise passing unit. This is what catches two units disagreeing: a unit can pass the tests
121
+ * written for it and still break every caller of what it changed.
122
+ *
123
+ * Operator configuration, not model input, which is why it is absent from the tool schema and not
124
+ * approval-gated — the operator wrote this string here, exactly as they would in CI. It runs as an
125
+ * ordinary subprocess under `verificationTimeoutMs`, and a denied spawn is a failure rather than a
126
+ * pass. It is skipped when the unit wrote no files, since a delegation that changed nothing cannot
127
+ * have broken coherence.
128
+ *
129
+ * A failure is reported as `INCOHERENT` rather than `VERIFICATION_FAILED`: the unit is fine and the
130
+ * project is not, which is a different instruction to the architect.
131
+ */
132
+ coherenceVerification?: string;
133
+ /**
134
+ * Whether a unit's declared `targetFiles` is a boundary. `'enforce'` (the default) refuses a write to
135
+ * any path the unit did not declare; `'off'` restores the behaviour before the boundary existed.
136
+ *
137
+ * This is what makes the coherence check above attributable. A unit that sprawls can break the tree in
138
+ * a way no record can assign to a unit, so `coherenceVerification` can say *that* something broke but
139
+ * not *what*. Declared targets, enforced, are the other half of that pair.
140
+ */
141
+ unitScope?: 'enforce' | 'off';
142
+ /**
143
+ * Whether a unit that failed has its failure locations read back and offered to the next attempt in
144
+ * the same workspace as context. `'auto'` (the default) does this once per failure; `'off'` disables it.
145
+ *
146
+ * This is the loop closing on itself. The ordinary cause of a unit that failed "for no visible reason"
147
+ * is that the worker was never shown the code it had to change, and the failure already names the file.
148
+ * The plugin reads that file into the WORKER's prompt while the architect is handed metadata only, so a
149
+ * retry can widen the worker's view without widening the architect's window. It is best-effort by
150
+ * construction: it is dropped rather than allowed to turn a runnable delegation into a refusal.
151
+ */
152
+ retryContext?: 'auto' | 'off';
153
+ /**
154
+ * Extra directories a delegated worker may write into besides the resolved session
155
+ * workspace. Absolute worker paths and `..` escapes outside every allowed root are
156
+ * refused and reported rather than written.
157
+ */
158
+ emitAllowlist?: string[];
159
+ /**
160
+ * Run the verification module inside the DSH server process when the sandbox denies
161
+ * a piped spawn (default false). That fallback executes model-influenced code with
162
+ * full host authority and can kill the server, so it is opt-in only.
163
+ */
164
+ allowInProcessFallback?: boolean;
165
+ /**
166
+ * Base URL of the local OpenAI-compatible server that `delegate_worker` posts to — for
167
+ * example `http://127.0.0.1:11434/v1` for Ollama, or a vLLM/llama.cpp port. A full
168
+ * `/chat/completions` URL is also accepted. Defaults to `http://127.0.0.1:1234/v1`.
169
+ *
170
+ * This is operator configuration, deliberately separate from the tool's arguments: a
171
+ * caller-supplied `endpoint` is ignored, because honouring it would let the model redirect
172
+ * a task — and the file contents it carries — to any address.
173
+ */
174
+ localEndpoint?: string;
175
+ /**
176
+ * Provider ids whose requests are NOT the architect — the lead tier. A request the host has already
177
+ * resolved to one of these is left exactly as configured: not repinned to the cloud, not given the
178
+ * architect's instruction, and not offered `delegate_worker`. The DLP gate still runs.
179
+ *
180
+ * Empty by default, which means every request is the architect — the behaviour before this option
181
+ * existed. An allowlist rather than an inference on purpose: guessing the role from "the provider is
182
+ * not the architect's" would stop pinning the architect as soon as a profile named its provider
183
+ * something else, and the failure would be silent and in the direction of the cloud.
184
+ */
185
+ leadProviders?: string[];
186
+ /**
187
+ * Convenience switch for the lead tier: derives `leadProviders` from the LEAD profile, so the
188
+ * provider id is declared in exactly one place. An explicit `leadProviders` list wins over it.
189
+ *
190
+ * Do not point this at the provider your architect session uses — the hook would stop pinning it,
191
+ * which is the one failure direction that costs you source leaving the machine.
192
+ */
193
+ leadTier?: boolean;
194
+ /**
195
+ * What happens when an agent reads a file a delegated worker wrote. `ask` (default) prompts,
196
+ * `deny` refuses, and `allow` permits it.
197
+ *
198
+ * `allow` exists for a lead tier that must read the code it writes contracts about, and it is an
199
+ * honest weakening of rule 3 rather than a fix — the fix is the host exposing agent lineage. The
200
+ * guard cannot yet tell the architect from a lead, so `allow` relaxes the rule for every agent.
201
+ */
202
+ delegateReadPolicy?: DelegateReadPolicy;
203
+ /**
204
+ * Paths whose source the architect may author, because a contract test is the specification rather
205
+ * than the implementation. Rule 2 forbids the architect writing source and rule 7 needs the architect
206
+ * to own the tests, which conflict for exactly this case, so this is the declared exception.
207
+ * Defaults to `['tests/']`; an empty list disables the carve-out.
208
+ */
209
+ contractPaths?: string[];
210
+ /**
211
+ * What a write to a contract path does: `ask` (default), `allow`, or `deny`. Deliberately separate
212
+ * from `guardAskPaths`, which decides what may be written at all; this decides what the architect is
213
+ * allowed to specify. Setting `allow` is the opt-in that makes contract authoring frictionless.
214
+ */
215
+ contractWriteMode?: 'allow' | 'ask' | 'deny';
216
+ /**
217
+ * Rule 8: what happens when a cloud-bound request carries source code in its own payload.
218
+ *
219
+ * `deny` (default) refuses the request, `ask` puts it to the operator, `allow` transmits it. A
220
+ * request bound for the local worker is not egress and is never affected.
221
+ *
222
+ * This is the one rule here that can refuse a request the operator typed themselves, so it is worth
223
+ * knowing the detector: fenced blocks with a source language tag, at least
224
+ * `sourceEgressMinLines` lines long. Prose about code does not trip it, and neither does an
225
+ * untagged block — a real false negative, documented rather than hidden.
226
+ */
227
+ sourceEgress?: SourceEgressPolicy;
228
+ /** Lines a fenced source block needs before it counts (default 3). Lower is more false positives. */
229
+ sourceEgressMinLines?: number;
230
+ }
231
+ export interface RouterMetadata {
232
+ provider: string;
233
+ model?: string;
234
+ route: RouteType;
235
+ gate: string;
236
+ rationale: string;
237
+ tier: string;
238
+ estimatedTokens: number;
239
+ dlpViolations?: string[];
240
+ scores?: {
241
+ is_private: number;
242
+ complexity: number;
243
+ target: string;
244
+ };
245
+ latencyMs?: number;
246
+ failover?: boolean;
247
+ previousProvider?: string;
248
+ }
249
+ export interface LLMSession {
250
+ provider?: string;
251
+ model?: string;
252
+ prompt?: string;
253
+ input?: string;
254
+ apiKey?: string;
255
+ reasoningEffort?: string;
256
+ messages?: Array<{
257
+ role: string;
258
+ content: any;
259
+ }>;
260
+ options?: {
261
+ provider?: string;
262
+ model?: string;
263
+ apiKey?: string;
264
+ reasoningEffort?: string;
265
+ [key: string]: any;
266
+ };
267
+ metadata?: {
268
+ router?: RouterMetadata;
269
+ [key: string]: any;
270
+ };
271
+ redispatch?: () => Promise<any>;
272
+ retry?: () => Promise<any>;
273
+ [key: string]: any;
274
+ }
275
+ export declare const name = "dsh-plugin-coding-delegate";
276
+ export declare function scanDLP(text: string, options?: {
277
+ entropyCheck?: boolean;
278
+ entropyMinBitsPerChar?: number;
279
+ entropyMinLength?: number;
280
+ }): {
281
+ hasSensitiveData: boolean;
282
+ violations: string[];
283
+ highConfidence: boolean;
284
+ };
285
+ interface EffectiveConfig {
286
+ localProvider: string;
287
+ cloudProvider: string;
288
+ localModel: string;
289
+ cloudModel: string;
290
+ contextThreshold: number;
291
+ timeoutMs: number;
292
+ enforceDLP: boolean;
293
+ }
294
+ export declare class LocalRouter {
295
+ private config;
296
+ constructor(config?: PluginConfig);
297
+ getConfig(): EffectiveConfig;
298
+ predictRoute(promptText: string): Promise<{
299
+ provider: string;
300
+ model: string;
301
+ route: RouteType;
302
+ gate: string;
303
+ rationale: string;
304
+ scores: any;
305
+ latencyMs: number;
306
+ dlpViolations?: string[];
307
+ }>;
308
+ handleBeforeRequest(session: LLMSession): Promise<LLMSession>;
309
+ handleError(session: LLMSession, error: any): Promise<LLMSession>;
310
+ }
311
+ /**
312
+ * Commands that READ a file named on the command line rather than executing it.
313
+ *
314
+ * Without this list, `Select-String -Path some.js` was treated as an invocation of
315
+ * `some.js`: the guard read the whole file and, since any sizeable program contains a write
316
+ * primitive, asked for approval to *read* it. Reading a file is not running it.
317
+
318
+ }
319
+
320
+
321
+
322
+
323
+
324
+ /** Closed approval vocabulary; only 'allowed-once' is a grant. */
325
+ export type ApprovalOutcome = 'allowed-once' | 'rejected' | 'cancelled' | 'unavailable';
326
+ /**
327
+ * Route an `ask` guard decision through the real approval seam.
328
+ *
329
+ * Returning `{ kind: 'ask' }` from a tools/pre-execute listener prompts nobody: the
330
+ * pipeline understands only `deny`, so every other kind is an allow. The seam that
331
+ * actually asks is `dsh-user-approval` (ctx.approval), and it fails closed — a
332
+ * missing service, a missing agent, an idle turn or a throwing answerer all resolve
333
+ * to 'unavailable', which this treats as a refusal.
334
+ */
335
+ export declare function requestApprovalForWrite(ctx: any, exec: any, verdict: GuardVerdict): Promise<ApprovalOutcome>;
336
+ export declare function resolveVerificationPolicy(options?: PluginConfig): VerificationPolicy;
337
+ /**
338
+ * Ask the operator to approve one model-selected verification command. Unlike the write
339
+ * guard this is not a `tools/pre-execute` decision, because the command runs after the
340
+ * worker responds; it is asked before dispatch so the operator sees it up front.
341
+ * Fails closed on every error path.
342
+ */
343
+ export declare function requestApprovalForVerification(ctx: any, exec: any, command: string): Promise<boolean>;
344
+ /**
345
+ * Ask the operator before a delegation writes into a directory that is neither the session workspace
346
+ * nor an allowlisted root. Same seam as the verification prompt above, and the same fail-closed rule:
347
+ * no approval service, no agent, or a thrown request all resolve to refusal rather than to consent.
348
+ */
349
+ export declare function requestApprovalForWorkspace(ctx: any, exec: any, dir: string, reason: string): Promise<boolean>;
350
+ export declare function apply(ctx: Context, options?: PluginConfig): void;
351
+ declare const pluginExport: {
352
+ name: string;
353
+ inject: string[];
354
+ using: readonly ["tools"];
355
+ apply: typeof apply;
356
+ LocalRouter: typeof LocalRouter;
357
+ SavingsTracker: typeof SavingsTracker;
358
+ scanDLP: typeof scanDLP;
359
+ delegateWorker: typeof delegateWorker;
360
+ extractAndEmitFiles: typeof extractAndEmitFiles;
361
+ runSandboxVerification: typeof runSandboxVerification;
362
+ parseTestOutput: typeof parseTestOutput;
363
+ sha256File: typeof sha256File;
364
+ resolveContextFiles: typeof resolveContextFiles;
365
+ parseSearchReplaceBlocks: typeof parseSearchReplaceBlocks;
366
+ applySearchReplaceBlocks: typeof applySearchReplaceBlocks;
367
+ MIN_SEARCH_CHARS: number;
368
+ DEFAULT_CONTEXT_MAX_BYTES: number;
369
+ resolveContractFiles: typeof resolveContractFiles;
370
+ contractFileHashes: typeof contractFileHashes;
371
+ contractViolations: typeof contractViolations;
372
+ resolveDelegateStatus: typeof resolveDelegateStatus;
373
+ resolveVerificationRepeats: typeof resolveVerificationRepeats;
374
+ MAX_VERIFICATION_REPEATS: number;
375
+ resolveLeadProviders: typeof resolveLeadProviders;
376
+ evaluateDelegatedReadPolicy: typeof evaluateDelegatedReadPolicy;
377
+ rememberAgentRole: typeof rememberAgentRole;
378
+ roleForAgent: typeof roleForAgent;
379
+ resetAgentRoles: typeof resetAgentRoles;
380
+ describeSourceRead: typeof describeSourceRead;
381
+ AGENT_ROLE_LIMIT: number;
382
+ detectSourceEgress: typeof detectSourceEgress;
383
+ evaluateSourceEgress: typeof evaluateSourceEgress;
384
+ DEFAULT_SOURCE_EGRESS_MIN_LINES: number;
385
+ resolveDelegatedRegistryPath: typeof resolveDelegatedRegistryPath;
386
+ parseDelegatedRegistry: typeof parseDelegatedRegistry;
387
+ mergeDelegatedRecords: typeof mergeDelegatedRecords;
388
+ pruneDelegatedRecords: typeof pruneDelegatedRecords;
389
+ saveDelegatedRegistry: typeof saveDelegatedRegistry;
390
+ loadDelegatedRegistry: typeof loadDelegatedRegistry;
391
+ rememberDelegated: typeof rememberDelegated;
392
+ resolveAgentRole: typeof resolveAgentRole;
393
+ applyArchitectConfig: typeof applyArchitectConfig;
394
+ applyAgentRole: typeof applyAgentRole;
395
+ DELEGATE_WORKER_SCHEMA: {
396
+ type: string;
397
+ function: {
398
+ name: string;
399
+ description: string;
400
+ parameters: {
401
+ type: string;
402
+ properties: {
403
+ taskName: {
404
+ type: string;
405
+ description: string;
406
+ };
407
+ instruction: {
408
+ type: string;
409
+ description: string;
410
+ };
411
+ targetFiles: {
412
+ type: string;
413
+ items: {
414
+ type: string;
415
+ };
416
+ description: string;
417
+ };
418
+ runVerification: {
419
+ type: string;
420
+ description: string;
421
+ };
422
+ verificationRepeats: {
423
+ type: string;
424
+ description: string;
425
+ };
426
+ attestTargets: {
427
+ type: string;
428
+ items: {
429
+ type: string;
430
+ };
431
+ description: string;
432
+ };
433
+ attestEvidence: {
434
+ type: string;
435
+ description: string;
436
+ };
437
+ attestOperator: {
438
+ type: string;
439
+ description: string;
440
+ };
441
+ contractFiles: {
442
+ type: string;
443
+ items: {
444
+ type: string;
445
+ };
446
+ description: string;
447
+ };
448
+ contextFiles: {
449
+ type: string;
450
+ description: string;
451
+ items: {
452
+ type: string;
453
+ properties: {
454
+ path: {
455
+ type: string;
456
+ };
457
+ startLine: {
458
+ type: string;
459
+ };
460
+ endLine: {
461
+ type: string;
462
+ };
463
+ };
464
+ required: string[];
465
+ };
466
+ };
467
+ workspaceDir: {
468
+ type: string;
469
+ description: string;
470
+ };
471
+ };
472
+ required: string[];
473
+ };
474
+ };
475
+ };
476
+ DELEGATE_WORKER_OPENAI_SCHEMA: {
477
+ type: string;
478
+ function: {
479
+ name: string;
480
+ description: string;
481
+ parameters: {
482
+ type: string;
483
+ properties: {
484
+ taskName: {
485
+ type: string;
486
+ description: string;
487
+ };
488
+ instruction: {
489
+ type: string;
490
+ description: string;
491
+ };
492
+ targetFiles: {
493
+ type: string;
494
+ items: {
495
+ type: string;
496
+ };
497
+ description: string;
498
+ };
499
+ runVerification: {
500
+ type: string;
501
+ description: string;
502
+ };
503
+ verificationRepeats: {
504
+ type: string;
505
+ description: string;
506
+ };
507
+ attestTargets: {
508
+ type: string;
509
+ items: {
510
+ type: string;
511
+ };
512
+ description: string;
513
+ };
514
+ attestEvidence: {
515
+ type: string;
516
+ description: string;
517
+ };
518
+ attestOperator: {
519
+ type: string;
520
+ description: string;
521
+ };
522
+ contractFiles: {
523
+ type: string;
524
+ items: {
525
+ type: string;
526
+ };
527
+ description: string;
528
+ };
529
+ contextFiles: {
530
+ type: string;
531
+ description: string;
532
+ items: {
533
+ type: string;
534
+ properties: {
535
+ path: {
536
+ type: string;
537
+ };
538
+ startLine: {
539
+ type: string;
540
+ };
541
+ endLine: {
542
+ type: string;
543
+ };
544
+ };
545
+ required: string[];
546
+ };
547
+ };
548
+ workspaceDir: {
549
+ type: string;
550
+ description: string;
551
+ };
552
+ };
553
+ required: string[];
554
+ };
555
+ };
556
+ };
557
+ PROFILES: import("./profiles").Profiles;
558
+ default: typeof apply;
559
+ };
560
+ export default pluginExport;