@martinloop/mcp 0.3.9 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/README.md +82 -141
  2. package/dist/discovery-metadata.d.ts +1 -1
  3. package/dist/discovery-metadata.js +1 -1
  4. package/dist/resources.d.ts +1 -2
  5. package/dist/resources.js +47 -95
  6. package/dist/server-validation.d.ts +1 -1
  7. package/dist/server-validation.js +16 -11
  8. package/dist/server.d.ts +23 -0
  9. package/dist/server.js +152 -7
  10. package/dist/tools/preflight.d.ts +2 -0
  11. package/dist/tools/preflight.js +42 -2
  12. package/dist/tools/run-dossier.d.ts +3 -1
  13. package/dist/tools/run-dossier.js +40 -2
  14. package/dist/tools/run-loop.d.ts +1 -4
  15. package/dist/tools/run-loop.js +6 -15
  16. package/dist/tools/tool-support.d.ts +2 -1
  17. package/dist/tools/tool-support.js +1 -12
  18. package/dist/vendor/adapters/claude-cli.js +38 -35
  19. package/dist/vendor/adapters/cli-bridge.d.ts +9 -1
  20. package/dist/vendor/adapters/cli-bridge.js +54 -13
  21. package/dist/vendor/adapters/codex-launcher.d.ts +61 -1
  22. package/dist/vendor/adapters/codex-launcher.js +118 -19
  23. package/dist/vendor/adapters/index.d.ts +1 -3
  24. package/dist/vendor/adapters/index.js +1 -3
  25. package/dist/vendor/adapters/openai-compatible.js +51 -12
  26. package/dist/vendor/contracts/adapter-capabilities.d.ts +1 -1
  27. package/dist/vendor/contracts/context-handoff.d.ts +100 -0
  28. package/dist/vendor/contracts/context-handoff.js +11 -0
  29. package/dist/vendor/contracts/context-manifest.d.ts +195 -0
  30. package/dist/vendor/contracts/context-manifest.js +17 -0
  31. package/dist/vendor/contracts/context-shadow.d.ts +75 -0
  32. package/dist/vendor/contracts/context-shadow.js +8 -0
  33. package/dist/vendor/contracts/delivery.d.ts +47 -0
  34. package/dist/vendor/contracts/delivery.js +18 -0
  35. package/dist/vendor/contracts/exits.d.ts +126 -0
  36. package/dist/vendor/contracts/exits.js +32 -0
  37. package/dist/vendor/contracts/index.d.ts +41 -2
  38. package/dist/vendor/contracts/index.js +24 -0
  39. package/dist/vendor/contracts/mission.d.ts +102 -0
  40. package/dist/vendor/contracts/mission.js +64 -0
  41. package/dist/vendor/contracts/operator.d.ts +3 -1
  42. package/dist/vendor/contracts/operator.js +2 -1
  43. package/dist/vendor/contracts/verified-handoff.d.ts +100 -0
  44. package/dist/vendor/contracts/verified-handoff.js +35 -0
  45. package/dist/vendor/core/context-chain-gate.d.ts +89 -0
  46. package/dist/vendor/core/context-chain-gate.js +173 -0
  47. package/dist/vendor/core/context-compiler.d.ts +53 -0
  48. package/dist/vendor/core/context-compiler.js +261 -0
  49. package/dist/vendor/core/context-handoff.d.ts +42 -0
  50. package/dist/vendor/core/context-handoff.js +167 -0
  51. package/dist/vendor/core/context-shadow.d.ts +39 -0
  52. package/dist/vendor/core/context-shadow.js +200 -0
  53. package/dist/vendor/core/delivery/index.d.ts +6 -0
  54. package/dist/vendor/core/delivery/index.js +4 -0
  55. package/dist/vendor/core/delivery/message-client.d.ts +18 -0
  56. package/dist/vendor/core/delivery/message-client.js +38 -0
  57. package/dist/vendor/core/delivery/message-ledger.d.ts +35 -0
  58. package/dist/vendor/core/delivery/message-ledger.js +97 -0
  59. package/dist/vendor/core/delivery/message-schema.d.ts +16 -0
  60. package/dist/vendor/core/delivery/message-schema.js +111 -0
  61. package/dist/vendor/core/delivery/update-check.d.ts +19 -0
  62. package/dist/vendor/core/delivery/update-check.js +107 -0
  63. package/dist/vendor/core/exit-signal.d.ts +88 -0
  64. package/dist/vendor/core/exit-signal.js +339 -0
  65. package/dist/vendor/core/exits.d.ts +41 -0
  66. package/dist/vendor/core/exits.js +258 -0
  67. package/dist/vendor/core/index.d.ts +44 -1
  68. package/dist/vendor/core/index.js +1088 -662
  69. package/dist/vendor/core/mission/aggregate.d.ts +27 -0
  70. package/dist/vendor/core/mission/aggregate.js +42 -0
  71. package/dist/vendor/core/mission/index.d.ts +2 -0
  72. package/dist/vendor/core/mission/index.js +1 -0
  73. package/dist/vendor/core/persistence/compiler.d.ts +8 -0
  74. package/dist/vendor/core/persistence/compiler.js +156 -0
  75. package/dist/vendor/core/persistence/context-handoff-store.d.ts +68 -0
  76. package/dist/vendor/core/persistence/context-handoff-store.js +112 -0
  77. package/dist/vendor/core/persistence/index.d.ts +4 -0
  78. package/dist/vendor/core/persistence/index.js +2 -0
  79. package/dist/vendor/core/persistence/ledger.d.ts +1 -1
  80. package/dist/vendor/core/persistence/mission-store.d.ts +56 -0
  81. package/dist/vendor/core/persistence/mission-store.js +281 -0
  82. package/dist/vendor/core/policy.d.ts +2 -0
  83. package/dist/vendor/core/policy.js +5 -2
  84. package/dist/vendor/core/rollback.js +15 -1
  85. package/dist/vendor/core/savings.d.ts +13 -0
  86. package/dist/vendor/core/savings.js +22 -0
  87. package/dist/vendor/core/termination-store.d.ts +15 -0
  88. package/dist/vendor/core/termination-store.js +44 -0
  89. package/dist/vendor/core/verified-handoff.d.ts +67 -0
  90. package/dist/vendor/core/verified-handoff.js +210 -0
  91. package/package.json +3 -13
  92. package/server.json +3 -3
  93. package/dist/vendor/adapters/stub-agent-cli.d.ts +0 -8
  94. package/dist/vendor/adapters/stub-agent-cli.js +0 -40
  95. package/dist/vendor/adapters/verifier-only.d.ts +0 -9
  96. package/dist/vendor/adapters/verifier-only.js +0 -63
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Eight-Exit Runtime — pure deterministic evaluator.
3
+ *
4
+ * EXIT_PRECEDENCE rationale (product decision — see contracts/exits.ts for rationale;
5
+ * any change to this array requires updating that paragraph in the same commit):
6
+ * human_interrupt > external_event > wall_clock > budget_cap > turn_cap >
7
+ * goal_met > error_threshold > no_progress
8
+ */
9
+ import type { ExitEvaluationV1, ExitPolicyV1, ExitSnapshotV1, LoopBudget, LoopLifecycleState, LoopStatus } from "../contracts/index.js";
10
+ export interface LegacyExitDecision {
11
+ shouldExit: boolean;
12
+ lifecycleState: LoopLifecycleState;
13
+ status: LoopStatus;
14
+ reason: string;
15
+ reasonCode?: string;
16
+ failureClass?: string;
17
+ safetySurface?: string;
18
+ exitEvaluation: ExitEvaluationV1;
19
+ }
20
+ export interface ExitPolicyOverrides {
21
+ goal?: Partial<ExitPolicyV1["goal"]>;
22
+ turns?: Partial<ExitPolicyV1["turns"]>;
23
+ budget?: Partial<ExitPolicyV1["budget"]>;
24
+ wallClock?: Partial<ExitPolicyV1["wallClock"]>;
25
+ progress?: Partial<ExitPolicyV1["progress"]>;
26
+ errors?: Partial<ExitPolicyV1["errors"]>;
27
+ humanInterrupt?: Partial<ExitPolicyV1["humanInterrupt"]>;
28
+ externalEvent?: Partial<ExitPolicyV1["externalEvent"]>;
29
+ }
30
+ export declare function createDefaultExitPolicy(budget: LoopBudget, overrides?: ExitPolicyOverrides): ExitPolicyV1;
31
+ export declare function validateExitPolicy(policy: ExitPolicyV1): void;
32
+ export declare function evaluateExitPolicy(policy: ExitPolicyV1, snapshot: ExitSnapshotV1): ExitEvaluationV1;
33
+ export declare function toLegacyExitDecision(evaluation: ExitEvaluationV1, externalDisposition?: "satisfied" | "superseded" | "cancelled"): LegacyExitDecision;
34
+ /**
35
+ * Hash the meaningful workspace/verification state for no-progress detection.
36
+ * Excludes timestamps, cost counters, prose summaries — only structural changes count.
37
+ */
38
+ export declare function hashProgressState(value: unknown): string;
39
+ /** @deprecated Use evaluateExitPolicy instead. Retained for downstream compatibility. */
40
+ export { inferExitCompat as inferExitCompat };
41
+ declare function inferExitCompat(_unused: unknown): never;
@@ -0,0 +1,258 @@
1
+ /**
2
+ * Eight-Exit Runtime — pure deterministic evaluator.
3
+ *
4
+ * EXIT_PRECEDENCE rationale (product decision — see contracts/exits.ts for rationale;
5
+ * any change to this array requires updating that paragraph in the same commit):
6
+ * human_interrupt > external_event > wall_clock > budget_cap > turn_cap >
7
+ * goal_met > error_threshold > no_progress
8
+ */
9
+ import { createHash } from "node:crypto";
10
+ // Precedence: human authority first, resource limits before goal success,
11
+ // resource exits ranked by urgency (wall_clock > budget_cap > turn_cap).
12
+ // Note: turn_cap is suppressed at signal-generation time when goalMet is true
13
+ // so goal_met and turn_cap cannot co-occur in practice.
14
+ const EXIT_PRECEDENCE = [
15
+ "human_interrupt",
16
+ "external_event",
17
+ "wall_clock",
18
+ "budget_cap",
19
+ "turn_cap",
20
+ "goal_met",
21
+ "error_threshold",
22
+ "no_progress"
23
+ ];
24
+ export function createDefaultExitPolicy(budget, overrides = {}) {
25
+ const base = {
26
+ schemaVersion: "exit-policy/1",
27
+ goal: { verifierRequired: true, minimumScore: 1 },
28
+ turns: { max: budget.maxIterations },
29
+ budget: { maxUsd: budget.maxUsd, maxTokens: budget.maxTokens },
30
+ wallClock: { maxElapsedMs: 30 * 60 * 1000 },
31
+ progress: { windowSize: 3, unchangedStateLimit: 3 },
32
+ errors: { maxConsecutive: 3 },
33
+ humanInterrupt: { enabled: true },
34
+ externalEvent: { enabled: true }
35
+ };
36
+ return {
37
+ ...base,
38
+ ...overrides,
39
+ goal: { ...base.goal, ...overrides.goal },
40
+ turns: { ...base.turns, ...overrides.turns },
41
+ budget: { ...base.budget, ...overrides.budget },
42
+ wallClock: { ...base.wallClock, ...overrides.wallClock },
43
+ progress: { ...base.progress, ...overrides.progress },
44
+ errors: { ...base.errors, ...overrides.errors },
45
+ humanInterrupt: { ...base.humanInterrupt, ...overrides.humanInterrupt },
46
+ externalEvent: { ...base.externalEvent, ...overrides.externalEvent }
47
+ };
48
+ }
49
+ export function validateExitPolicy(policy) {
50
+ assertFinitePositive("turns.max", policy.turns.max);
51
+ assertFinitePositive("budget.maxUsd", policy.budget.maxUsd);
52
+ assertFinitePositive("budget.maxTokens", policy.budget.maxTokens);
53
+ assertFinitePositive("wallClock.maxElapsedMs", policy.wallClock.maxElapsedMs);
54
+ assertFinitePositive("progress.windowSize", policy.progress.windowSize);
55
+ assertFinitePositive("progress.unchangedStateLimit", policy.progress.unchangedStateLimit);
56
+ assertFinitePositive("errors.maxConsecutive", policy.errors.maxConsecutive);
57
+ if (policy.goal.minimumScore < 0 || policy.goal.minimumScore > 1) {
58
+ throw new RangeError("goal.minimumScore must be between 0 and 1");
59
+ }
60
+ if (policy.progress.unchangedStateLimit > policy.progress.windowSize) {
61
+ throw new RangeError("progress.unchangedStateLimit cannot exceed progress.windowSize");
62
+ }
63
+ if (policy.wallClock.deadlineAt !== undefined) {
64
+ const parsed = Date.parse(policy.wallClock.deadlineAt);
65
+ if (!Number.isFinite(parsed)) {
66
+ throw new RangeError("wallClock.deadlineAt must be an ISO timestamp");
67
+ }
68
+ }
69
+ }
70
+ export function evaluateExitPolicy(policy, snapshot) {
71
+ validateExitPolicy(policy);
72
+ const matches = [];
73
+ const push = (kind, reason, evidence) => {
74
+ matches.push({ kind, reason, evidence });
75
+ };
76
+ // 1. Human interrupt (highest authority — cannot be argued with)
77
+ if (policy.humanInterrupt.enabled && snapshot.humanInterrupt !== undefined) {
78
+ push("human_interrupt", snapshot.humanInterrupt.reason ?? "Human interrupt requested.", {
79
+ requestedAt: snapshot.humanInterrupt.requestedAt,
80
+ requestedBy: snapshot.humanInterrupt.requestedBy
81
+ });
82
+ }
83
+ // 2. External event
84
+ if (policy.externalEvent.enabled && snapshot.externalEvent !== undefined) {
85
+ push("external_event", snapshot.externalEvent.reason ?? "External terminal event observed.", {
86
+ source: snapshot.externalEvent.source,
87
+ event: snapshot.externalEvent.event,
88
+ disposition: snapshot.externalEvent.disposition,
89
+ subject: snapshot.externalEvent.subject,
90
+ evidenceUri: snapshot.externalEvent.evidenceUri
91
+ });
92
+ }
93
+ // 3. Goal met (verified success outranks resource exhaustion)
94
+ const result = snapshot.result;
95
+ const goalMet = result !== undefined &&
96
+ result.status === "completed" &&
97
+ (!policy.goal.verifierRequired || result.verificationPassed) &&
98
+ result.verifierScore >= policy.goal.minimumScore;
99
+ if (goalMet) {
100
+ push("goal_met", "Configured verification goal passed.", {
101
+ verifierScore: result.verifierScore,
102
+ minimumScore: policy.goal.minimumScore
103
+ });
104
+ }
105
+ // 4. Wall clock
106
+ const elapsedMs = Math.max(0, snapshot.nowMs - snapshot.runStartedAtMs);
107
+ const deadlineMs = policy.wallClock.deadlineAt === undefined
108
+ ? undefined
109
+ : Date.parse(policy.wallClock.deadlineAt);
110
+ if (elapsedMs >= policy.wallClock.maxElapsedMs ||
111
+ (deadlineMs !== undefined && snapshot.nowMs >= deadlineMs)) {
112
+ push("wall_clock", "Run wall-clock limit reached.", {
113
+ elapsedMs,
114
+ maxElapsedMs: policy.wallClock.maxElapsedMs,
115
+ deadlineAt: policy.wallClock.deadlineAt
116
+ });
117
+ }
118
+ // 5. Budget cap
119
+ const usdExceeded = snapshot.actualUsd >= policy.budget.maxUsd;
120
+ const tokensExceeded = snapshot.tokensUsed >= policy.budget.maxTokens;
121
+ if (usdExceeded || tokensExceeded) {
122
+ push("budget_cap", "Run token or dollar budget reached.", {
123
+ actualUsd: snapshot.actualUsd,
124
+ maxUsd: policy.budget.maxUsd,
125
+ tokensUsed: snapshot.tokensUsed,
126
+ maxTokens: policy.budget.maxTokens,
127
+ usdExceeded,
128
+ tokensExceeded
129
+ });
130
+ }
131
+ // 6. Turn cap — suppressed when goalMet: completing on the final allowed
132
+ // iteration is legitimate success, not an overrun. turn_cap fires only when
133
+ // iterations are exhausted without verified completion.
134
+ if (!goalMet && snapshot.turnsUsed >= policy.turns.max) {
135
+ push("turn_cap", "Run iteration limit reached.", {
136
+ turnsUsed: snapshot.turnsUsed,
137
+ maxTurns: policy.turns.max
138
+ });
139
+ }
140
+ // 7. Error threshold
141
+ if (snapshot.consecutiveErrors >= policy.errors.maxConsecutive) {
142
+ push("error_threshold", "Consecutive error threshold reached.", {
143
+ consecutiveErrors: snapshot.consecutiveErrors,
144
+ maxConsecutive: policy.errors.maxConsecutive
145
+ });
146
+ }
147
+ // 8. No progress — only fires when the window is FULL (A3 fix: sub-window must not fire)
148
+ const requiredHashes = policy.progress.unchangedStateLimit;
149
+ const recentHashes = snapshot.recentStateHashes.slice(-requiredHashes);
150
+ const hashStall = recentHashes.length === requiredHashes && new Set(recentHashes).size === 1;
151
+ if (hashStall || snapshot.trajectoryStop?.shouldStop === true) {
152
+ push("no_progress", snapshot.trajectoryStop?.reason ?? "Canonical run state stopped changing.", {
153
+ unchangedStateCount: hashStall ? recentHashes.length : 0,
154
+ stateHash: hashStall ? recentHashes[0] : undefined,
155
+ trajectoryStop: snapshot.trajectoryStop?.shouldStop ?? false
156
+ });
157
+ }
158
+ const matched = EXIT_PRECEDENCE.filter((kind) => matches.some((m) => m.kind === kind));
159
+ return {
160
+ schemaVersion: "exit-evaluation/1",
161
+ policyVersion: policy.schemaVersion,
162
+ shouldExit: matched.length > 0,
163
+ ...(matched[0] === undefined ? {} : { primary: matched[0] }),
164
+ matched,
165
+ phase: snapshot.phase,
166
+ evaluatedAt: snapshot.evaluatedAt,
167
+ matches
168
+ };
169
+ }
170
+ export function toLegacyExitDecision(evaluation, externalDisposition) {
171
+ const primary = evaluation.primary;
172
+ if (primary === undefined) {
173
+ return {
174
+ shouldExit: false,
175
+ lifecycleState: "running",
176
+ status: "running",
177
+ reason: "No exit condition matched.",
178
+ exitEvaluation: evaluation
179
+ };
180
+ }
181
+ const reason = evaluation.matches.find((m) => m.kind === primary)?.reason ??
182
+ `MartinLoop exited because ${primary} fired.`;
183
+ if (primary === "goal_met") {
184
+ return completed(reason, primary, evaluation);
185
+ }
186
+ if (primary === "external_event" && externalDisposition === "satisfied") {
187
+ return completed(reason, primary, evaluation);
188
+ }
189
+ if (primary === "human_interrupt") {
190
+ return exited("human_escalation", reason, primary, evaluation);
191
+ }
192
+ if (primary === "budget_cap" || primary === "turn_cap") {
193
+ return exited("budget_exit", reason, primary, evaluation);
194
+ }
195
+ if (primary === "no_progress") {
196
+ return exited("diminishing_returns", reason, primary, evaluation);
197
+ }
198
+ if (primary === "error_threshold") {
199
+ return exited("error_threshold", reason, primary, evaluation);
200
+ }
201
+ if (primary === "wall_clock") {
202
+ return exited("wall_clock", reason, primary, evaluation);
203
+ }
204
+ if (primary === "external_event") {
205
+ return exited("external_event", reason, primary, evaluation);
206
+ }
207
+ return exited("stuck_exit", reason, primary, evaluation);
208
+ }
209
+ /**
210
+ * Hash the meaningful workspace/verification state for no-progress detection.
211
+ * Excludes timestamps, cost counters, prose summaries — only structural changes count.
212
+ */
213
+ export function hashProgressState(value) {
214
+ return createHash("sha256").update(stableJson(value)).digest("hex");
215
+ }
216
+ function stableJson(value) {
217
+ if (value === null || typeof value !== "object") {
218
+ return JSON.stringify(value) ?? "null";
219
+ }
220
+ if (Array.isArray(value)) {
221
+ return `[${value.map(stableJson).join(",")}]`;
222
+ }
223
+ const obj = value;
224
+ return `{${Object.keys(obj)
225
+ .sort()
226
+ .map((k) => `${JSON.stringify(k)}:${stableJson(obj[k])}`)
227
+ .join(",")}}`;
228
+ }
229
+ function completed(reason, primary, evaluation) {
230
+ return {
231
+ shouldExit: true,
232
+ lifecycleState: "completed",
233
+ status: "completed",
234
+ reason,
235
+ reasonCode: primary,
236
+ exitEvaluation: evaluation
237
+ };
238
+ }
239
+ function exited(lifecycleState, reason, primary, evaluation) {
240
+ return {
241
+ shouldExit: true,
242
+ lifecycleState,
243
+ status: "exited",
244
+ reason,
245
+ reasonCode: primary,
246
+ exitEvaluation: evaluation
247
+ };
248
+ }
249
+ function assertFinitePositive(name, value) {
250
+ if (!Number.isFinite(value) || value <= 0) {
251
+ throw new RangeError(`${name} must be a finite number greater than zero`);
252
+ }
253
+ }
254
+ /** @deprecated Use evaluateExitPolicy instead. Retained for downstream compatibility. */
255
+ export { inferExitCompat as inferExitCompat };
256
+ function inferExitCompat(_unused) {
257
+ throw new Error("inferExitCompat is a compatibility stub — call evaluateExitPolicy directly");
258
+ }
@@ -1,9 +1,12 @@
1
- import { type ApprovalPolicy, type CostProvenance, type ExecutionProfile, type FailureClass, type InterventionType, type LoopArtifact, type LoopAttempt, type LoopBudget, type ProviderUsageSettlement, type MutationMode, type LoopRecord, type LoopTask, type ReceiptScope } from "../contracts/index.js";
1
+ import { type ApprovalPolicy, type ContextHandoffReceipt, type CostProvenance, type ExecutionProfile, type FailureClass, type InterventionType, type LoopArtifact, type LoopAttempt, type LoopBudget, type ProviderUsageSettlement, type MutationMode, type LoopRecord, type LoopTask, type ReceiptScope } from "../contracts/index.js";
2
2
  import { classifyFailure, computeEvidenceVector, evaluatePatchDecision, evaluateCostGovernor, evaluateBudgetPreflight, inferExit, nextPolicyPhase, policyPhaseToLifecycleState, scorePatchDecision, selectRecoveryRecipe, type ExitDecision } from "./policy.js";
3
3
  import { evaluateChangeApprovalLeash, evaluateFilesystemLeash, evaluateSecretLeash, redactSecretsFromText, resolveExecutionProfile, evaluateVerificationLeash } from "./leash.js";
4
4
  import { buildRepoGroundingIndex, loadOrBuildRepoGroundingIndex, queryRepoGroundingIndex, scanPatchForGroundingViolations } from "./grounding.js";
5
5
  import { captureRollbackBoundary, listAttemptChangedFilesSinceBoundary, restoreRollbackBoundary } from "./rollback.js";
6
6
  import { type RunStore } from "./persistence/index.js";
7
+ import { type ExitPolicyOverrides } from "./exits.js";
8
+ import { type ExitSignalSource } from "./exit-signal.js";
9
+ import { type VerifierExecutionBinding } from "./verified-handoff.js";
7
10
  export type { ApprovalPolicy, BudgetPreflightEstimate, BudgetSettlement, CostProvenance, EvidenceVector, ExecutionProfile, FailureClass, InterventionType, PatchDecision, PatchDecisionArtifact, PatchDecisionReasonCode, PatchScore, MutationMode, RollbackBoundaryArtifact, RollbackBoundaryStrategy, RollbackFileSnapshot, RollbackOutcomeArtifact, RollbackOutcomeStatus, PolicyPhase, CallStage, AgentRole, FirstDelta, RoutingEconomics } from "../contracts/index.js";
8
11
  export { classifyFailure, computeEvidenceVector, evaluatePatchDecision, evaluateCostGovernor, evaluateBudgetPreflight, inferExit, nextPolicyPhase, policyPhaseToLifecycleState, scorePatchDecision, selectRecoveryRecipe, evaluateVerificationLeash, evaluateFilesystemLeash, evaluateChangeApprovalLeash, evaluateSecretLeash, resolveExecutionProfile, redactSecretsFromText, buildRepoGroundingIndex, loadOrBuildRepoGroundingIndex, queryRepoGroundingIndex, scanPatchForGroundingViolations, captureRollbackBoundary, listAttemptChangedFilesSinceBoundary, restoreRollbackBoundary };
9
12
  export type { BudgetPreflightDecision, BudgetPreflightInput, CostGovernorState, EvidenceVectorInput, EvaluatedPatchDecision, ExitDecision, FailureAssessment, PatchDecisionInput, RecoveryDecision, RecoveryRecipe } from "./policy.js";
@@ -14,6 +17,8 @@ export { createLocalIdentityAuthority, hasIdentityScope, issueIdentityToken, ver
14
17
  export type { LocalIdentityAuthority } from "./identity.js";
15
18
  export { compileExecutionPolicy } from "./policy-compiler.js";
16
19
  export { assessTrajectory, decideCircuitBreak } from "./trajectory.js";
20
+ export { calculateAvoidedUsd, calculateLoopAvoidedUsd } from "./savings.js";
21
+ export type { AvoidedUsdInput } from "./savings.js";
17
22
  export { classifyRoute, evaluatePreworkBurnPolicy, resolveModelForTier, selectBestEngine } from "./routing.js";
18
23
  export type { RouteDecision, RouteClassificationInput, AvailableEngine } from "./routing.js";
19
24
  export { validateTestIntegrity, snapshotTestFiles, identifyNewTests, findTestFiles, isTestFile, extractImports, hasTrivialAssertionsOnly, importsPreExistingCode } from "./test-integrity.js";
@@ -24,16 +29,27 @@ export { runContextIntegrityPrecheck } from "./context-integrity.js";
24
29
  export type { ContextIntegrityPrecheck, ContextIntegrityVerdict } from "./context-integrity.js";
25
30
  export { compilePromptPacket } from "./compiler.js";
26
31
  export type { PromptPacket, CompilerAdapterRequest } from "./compiler.js";
32
+ export { buildVerifiedHandoff, resolveVerifiedHandoffOutcome, toTestIntegrityVerdict, verifierActuallyPassed, } from "./verified-handoff.js";
33
+ export type { BoundVerifierEvidence, BuildVerifiedHandoffInput, VerifierExecutionBinding, } from "./verified-handoff.js";
27
34
  export { createFileRunStore, makeLedgerEvent, readAllLoopRecords, readLatestLoopRecord, readLatestLoopRecordFromFile, readLoopRecordsFromFile, resolveRunsRoot, resolveReceiptIntegrityPath, verifyReceiptIntegrityFromFiles, writeReceiptIntegrityMaterial } from "./persistence/index.js";
28
35
  export type { AttemptArtifacts, LedgerEvent, LedgerEventKind, LoopAttemptRecord, LoopRunRecord, ReceiptIntegrityChainEntry, RunContract, RunStore, StoredReceiptIntegrityMaterial } from "./persistence/index.js";
29
36
  export { compileAndPersistContext } from "./persistence/index.js";
30
37
  export type { CompileResult } from "./persistence/index.js";
38
+ export { compileContextShadow, estimateContextTokens } from "./context-shadow.js";
39
+ export type { CompileContextShadowInput, CompileContextShadowResult, ContextShadowSegment } from "./context-shadow.js";
40
+ export { compileContext, HEURISTIC_ADAPTER, MAX_RENDER_PASSES } from "./context-compiler.js";
41
+ export type { CompileContextInput, CompileContextOutput, ContextAdapter } from "./context-compiler.js";
42
+ export { verifyContextHandoff, decideContextCircuitBreak } from "./context-handoff.js";
43
+ export type { VerifyContextHandoffInput } from "./context-handoff.js";
44
+ export { evaluateChainGate, renderGatePrComment } from "./context-chain-gate.js";
45
+ export type { ChainGateConfig, ChainGateCost, ChainGateConclusion, ChainGateInput, ChainGateResult, GatePrCommentOptions } from "./context-chain-gate.js";
31
46
  export { appendMemory, readMemoryEntries, getPreference, buildMemorySummary, recordPreference, recordConsent } from "./persistence/memory-store.js";
32
47
  export type { MemoryEntry, MemoryKind, MemorySummary } from "./persistence/memory-store.js";
33
48
  export { appendTraceEntry, readTraceEntries, aggregateTraces, getHistoricalDirectSuccessRate } from "./persistence/trace-store.js";
34
49
  export type { TraceEntry, TraceAggregation } from "./persistence/trace-store.js";
35
50
  export interface MartinAdapterRequest {
36
51
  loopId: string;
52
+ workspaceId: string;
37
53
  attemptId: string;
38
54
  context: {
39
55
  taskTitle: string;
@@ -41,6 +57,7 @@ export interface MartinAdapterRequest {
41
57
  verificationPlan: string[];
42
58
  verificationStack?: LoopTask["verificationStack"];
43
59
  mutationMode?: MutationMode;
60
+ definitionOfDonePreSatisfied?: boolean;
44
61
  /** Absolute path to the repository root. */
45
62
  repoRoot?: string;
46
63
  /** Glob patterns for files the agent may modify. Empty = no restriction. */
@@ -58,10 +75,14 @@ export interface MartinAdapterRequest {
58
75
  remainingTokens: number;
59
76
  };
60
77
  previousAttempts: LoopAttempt[];
78
+ /** Abort signal propagated from the harness — adapters should honour it. */
79
+ signal?: AbortSignal;
61
80
  }
62
81
  export interface MartinVerificationStep {
63
82
  command: string;
64
83
  launched: boolean;
84
+ completed?: boolean;
85
+ crashed?: boolean;
65
86
  exitCode?: number;
66
87
  timedOut: boolean;
67
88
  fastFail?: boolean;
@@ -72,6 +93,7 @@ export interface MartinVerificationOutcome {
72
93
  summary: string;
73
94
  steps?: MartinVerificationStep[];
74
95
  warnings?: string[];
96
+ binding?: VerifierExecutionBinding;
75
97
  }
76
98
  export interface MartinAdapterResult {
77
99
  status: "completed" | "failed";
@@ -91,6 +113,7 @@ export interface MartinAdapterResult {
91
113
  summary: string;
92
114
  steps?: MartinVerificationStep[];
93
115
  warnings?: string[];
116
+ binding?: VerifierExecutionBinding;
94
117
  };
95
118
  execution?: {
96
119
  changedFiles?: string[];
@@ -175,6 +198,20 @@ export interface RunMartinInput {
175
198
  receiptScope?: ReceiptScope;
176
199
  /** Optional persistence store. When provided, runMartin writes artifacts on each lifecycle event. */
177
200
  store?: RunStore;
201
+ /** Overrides for the default eight-exit policy derived from budget. */
202
+ exitPolicy?: ExitPolicyOverrides;
203
+ /** Source for durable cancellation/external-event signals. */
204
+ exitSignalSource?: ExitSignalSource;
205
+ /** Poll interval for the signal monitor in ms (default 250). */
206
+ exitSignalPollIntervalMs?: number;
207
+ /** Clock override for testing (default Date.now). */
208
+ nowMs?: () => number;
209
+ /** When provided, runMartin verifies the handoff before invoking the adapter. */
210
+ contextHandoff?: ContextHandoffReceipt;
211
+ /** true when the producer receipt file hash has been independently confirmed. */
212
+ producerReceiptVerified?: boolean;
213
+ /** Map of sha256 → true for every artifact available to the verifier. */
214
+ availableArtifacts?: ReadonlyMap<string, true>;
178
215
  }
179
216
  export interface RunMartinResult {
180
217
  loop: LoopRecord;
@@ -184,3 +221,9 @@ export declare function distillContext(loop: Pick<LoopRecord, "task" | "budget"
184
221
  maxRecentAttempts?: number;
185
222
  }): DistilledContext;
186
223
  export declare function runMartin(input: RunMartinInput): Promise<RunMartinResult>;
224
+ export { createDefaultExitPolicy, evaluateExitPolicy, hashProgressState, toLegacyExitDecision, validateExitPolicy } from "./exits.js";
225
+ export type { ExitPolicyOverrides, LegacyExitDecision } from "./exits.js";
226
+ export { SignalDiagnosticError, createFileExitSignalSource, exitSignalPath, readAllExitSignals, readExitSignal, startExitSignalMonitor, writeExitSignal } from "./exit-signal.js";
227
+ export type { ExitSignalSource, SignalDiagnostic, SignalReadResult } from "./exit-signal.js";
228
+ export { cacheMessage, fetchSelectedMessage, getCliInstalledVersion, getMcpInstalledVersion, isCooldownExpired, isDismissed, isNewerVersion, loadDeliveryRecord, parseMessageSelectionResponse, recordDismissed, recordShown, resolveDefaultLedgerPath, saveDeliveryRecord, } from "./delivery/index.js";
229
+ export type { MessageClientOptions, MessageSelectRequest, ParseFailure, ParseResult, ValidationError, } from "./delivery/index.js";