@martinloop/mcp 0.3.8 → 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.
- package/README.md +90 -106
- package/dist/discovery-metadata.d.ts +1 -1
- package/dist/discovery-metadata.js +1 -1
- package/dist/resources.d.ts +1 -2
- package/dist/resources.js +190 -238
- package/dist/server-validation.d.ts +1 -1
- package/dist/server-validation.js +16 -11
- package/dist/server.d.ts +23 -0
- package/dist/server.js +152 -7
- package/dist/tools/run-dossier.d.ts +3 -1
- package/dist/tools/run-dossier.js +40 -2
- package/dist/tools/run-loop.d.ts +1 -4
- package/dist/tools/run-loop.js +6 -15
- package/dist/tools/tool-support.d.ts +2 -1
- package/dist/tools/tool-support.js +1 -12
- package/dist/vendor/adapters/claude-cli.js +38 -35
- package/dist/vendor/adapters/cli-bridge.d.ts +9 -1
- package/dist/vendor/adapters/cli-bridge.js +54 -13
- package/dist/vendor/adapters/codex-launcher.d.ts +61 -1
- package/dist/vendor/adapters/codex-launcher.js +118 -19
- package/dist/vendor/adapters/index.d.ts +1 -3
- package/dist/vendor/adapters/index.js +1 -3
- package/dist/vendor/adapters/openai-compatible.js +57 -18
- package/dist/vendor/contracts/adapter-capabilities.d.ts +1 -1
- package/dist/vendor/contracts/context-handoff.d.ts +100 -0
- package/dist/vendor/contracts/context-handoff.js +11 -0
- package/dist/vendor/contracts/context-manifest.d.ts +195 -0
- package/dist/vendor/contracts/context-manifest.js +17 -0
- package/dist/vendor/contracts/context-shadow.d.ts +75 -0
- package/dist/vendor/contracts/context-shadow.js +8 -0
- package/dist/vendor/contracts/exits.d.ts +126 -0
- package/dist/vendor/contracts/exits.js +32 -0
- package/dist/vendor/contracts/index.d.ts +39 -2
- package/dist/vendor/contracts/index.js +22 -0
- package/dist/vendor/contracts/mission.d.ts +102 -0
- package/dist/vendor/contracts/mission.js +64 -0
- package/dist/vendor/contracts/operator.d.ts +3 -1
- package/dist/vendor/contracts/operator.js +2 -1
- package/dist/vendor/contracts/verified-handoff.d.ts +100 -0
- package/dist/vendor/contracts/verified-handoff.js +35 -0
- package/dist/vendor/core/context-chain-gate.d.ts +89 -0
- package/dist/vendor/core/context-chain-gate.js +173 -0
- package/dist/vendor/core/context-compiler.d.ts +53 -0
- package/dist/vendor/core/context-compiler.js +261 -0
- package/dist/vendor/core/context-handoff.d.ts +42 -0
- package/dist/vendor/core/context-handoff.js +167 -0
- package/dist/vendor/core/context-shadow.d.ts +39 -0
- package/dist/vendor/core/context-shadow.js +200 -0
- package/dist/vendor/core/exit-signal.d.ts +88 -0
- package/dist/vendor/core/exit-signal.js +339 -0
- package/dist/vendor/core/exits.d.ts +41 -0
- package/dist/vendor/core/exits.js +258 -0
- package/dist/vendor/core/index.d.ts +42 -1
- package/dist/vendor/core/index.js +1086 -662
- package/dist/vendor/core/mission/aggregate.d.ts +27 -0
- package/dist/vendor/core/mission/aggregate.js +42 -0
- package/dist/vendor/core/mission/index.d.ts +2 -0
- package/dist/vendor/core/mission/index.js +1 -0
- package/dist/vendor/core/persistence/compiler.d.ts +8 -0
- package/dist/vendor/core/persistence/compiler.js +156 -0
- package/dist/vendor/core/persistence/context-handoff-store.d.ts +68 -0
- package/dist/vendor/core/persistence/context-handoff-store.js +112 -0
- package/dist/vendor/core/persistence/index.d.ts +4 -0
- package/dist/vendor/core/persistence/index.js +2 -0
- package/dist/vendor/core/persistence/ledger.d.ts +1 -1
- package/dist/vendor/core/persistence/mission-store.d.ts +56 -0
- package/dist/vendor/core/persistence/mission-store.js +281 -0
- package/dist/vendor/core/policy.d.ts +2 -0
- package/dist/vendor/core/policy.js +5 -2
- package/dist/vendor/core/rollback.js +15 -1
- package/dist/vendor/core/savings.d.ts +13 -0
- package/dist/vendor/core/savings.js +22 -0
- package/dist/vendor/core/termination-store.d.ts +15 -0
- package/dist/vendor/core/termination-store.js +44 -0
- package/dist/vendor/core/verified-handoff.d.ts +67 -0
- package/dist/vendor/core/verified-handoff.js +210 -0
- package/package.json +76 -83
- package/server.json +21 -21
- package/LICENSE +0 -216
- package/dist/vendor/adapters/adapters/src/claude-cli.d.ts +0 -146
- package/dist/vendor/adapters/adapters/src/claude-cli.js +0 -1100
- package/dist/vendor/adapters/adapters/src/cli-bridge.d.ts +0 -103
- package/dist/vendor/adapters/adapters/src/cli-bridge.js +0 -569
- package/dist/vendor/adapters/adapters/src/codex-launcher.d.ts +0 -78
- package/dist/vendor/adapters/adapters/src/codex-launcher.js +0 -663
- package/dist/vendor/adapters/adapters/src/direct-provider.d.ts +0 -10
- package/dist/vendor/adapters/adapters/src/direct-provider.js +0 -40
- package/dist/vendor/adapters/adapters/src/index.d.ts +0 -8
- package/dist/vendor/adapters/adapters/src/index.js +0 -8
- package/dist/vendor/adapters/adapters/src/openai-compatible.d.ts +0 -62
- package/dist/vendor/adapters/adapters/src/openai-compatible.js +0 -306
- package/dist/vendor/adapters/adapters/src/runtime-support.d.ts +0 -17
- package/dist/vendor/adapters/adapters/src/runtime-support.js +0 -59
- package/dist/vendor/adapters/adapters/src/stub-agent-cli.d.ts +0 -8
- package/dist/vendor/adapters/adapters/src/stub-agent-cli.js +0 -40
- package/dist/vendor/adapters/adapters/src/stub-direct-provider.d.ts +0 -8
- package/dist/vendor/adapters/adapters/src/stub-direct-provider.js +0 -12
- package/dist/vendor/adapters/adapters/src/verifier-only.d.ts +0 -9
- package/dist/vendor/adapters/adapters/src/verifier-only.js +0 -63
- package/dist/vendor/adapters/contracts/src/context-graph.d.ts +0 -48
- package/dist/vendor/adapters/contracts/src/context-graph.js +0 -26
- package/dist/vendor/adapters/contracts/src/execution-policy.d.ts +0 -78
- package/dist/vendor/adapters/contracts/src/execution-policy.js +0 -43
- package/dist/vendor/adapters/contracts/src/governance.d.ts +0 -24
- package/dist/vendor/adapters/contracts/src/governance.js +0 -11
- package/dist/vendor/adapters/contracts/src/identity.d.ts +0 -29
- package/dist/vendor/adapters/contracts/src/identity.js +0 -30
- package/dist/vendor/adapters/contracts/src/index.d.ts +0 -412
- package/dist/vendor/adapters/contracts/src/index.js +0 -225
- package/dist/vendor/adapters/contracts/src/operator.d.ts +0 -19
- package/dist/vendor/adapters/contracts/src/operator.js +0 -11
- package/dist/vendor/adapters/contracts/src/trajectory.d.ts +0 -26
- package/dist/vendor/adapters/contracts/src/trajectory.js +0 -27
- package/dist/vendor/adapters/core/src/compiler.d.ts +0 -52
- package/dist/vendor/adapters/core/src/compiler.js +0 -52
- package/dist/vendor/adapters/core/src/context-graph.d.ts +0 -3
- package/dist/vendor/adapters/core/src/context-graph.js +0 -371
- package/dist/vendor/adapters/core/src/context-integrity.d.ts +0 -26
- package/dist/vendor/adapters/core/src/context-integrity.js +0 -80
- package/dist/vendor/adapters/core/src/grounding.d.ts +0 -38
- package/dist/vendor/adapters/core/src/grounding.js +0 -273
- package/dist/vendor/adapters/core/src/identity.d.ts +0 -20
- package/dist/vendor/adapters/core/src/identity.js +0 -86
- package/dist/vendor/adapters/core/src/index.d.ts +0 -186
- package/dist/vendor/adapters/core/src/index.js +0 -1495
- package/dist/vendor/adapters/core/src/leash.d.ts +0 -48
- package/dist/vendor/adapters/core/src/leash.js +0 -497
- package/dist/vendor/adapters/core/src/persistence/compiler.d.ts +0 -18
- package/dist/vendor/adapters/core/src/persistence/compiler.js +0 -34
- package/dist/vendor/adapters/core/src/persistence/index.d.ts +0 -10
- package/dist/vendor/adapters/core/src/persistence/index.js +0 -5
- package/dist/vendor/adapters/core/src/persistence/integrity.d.ts +0 -39
- package/dist/vendor/adapters/core/src/persistence/integrity.js +0 -252
- package/dist/vendor/adapters/core/src/persistence/ledger.d.ts +0 -23
- package/dist/vendor/adapters/core/src/persistence/ledger.js +0 -9
- package/dist/vendor/adapters/core/src/persistence/memory-store.d.ts +0 -63
- package/dist/vendor/adapters/core/src/persistence/memory-store.js +0 -115
- package/dist/vendor/adapters/core/src/persistence/runs-reader.d.ts +0 -66
- package/dist/vendor/adapters/core/src/persistence/runs-reader.js +0 -140
- package/dist/vendor/adapters/core/src/persistence/store.d.ts +0 -89
- package/dist/vendor/adapters/core/src/persistence/store.js +0 -125
- package/dist/vendor/adapters/core/src/persistence/trace-store.d.ts +0 -85
- package/dist/vendor/adapters/core/src/persistence/trace-store.js +0 -125
- package/dist/vendor/adapters/core/src/policy-compiler.d.ts +0 -2
- package/dist/vendor/adapters/core/src/policy-compiler.js +0 -195
- package/dist/vendor/adapters/core/src/policy.d.ts +0 -156
- package/dist/vendor/adapters/core/src/policy.js +0 -704
- package/dist/vendor/adapters/core/src/repo-analyzer.d.ts +0 -53
- package/dist/vendor/adapters/core/src/repo-analyzer.js +0 -263
- package/dist/vendor/adapters/core/src/rollback.d.ts +0 -15
- package/dist/vendor/adapters/core/src/rollback.js +0 -253
- package/dist/vendor/adapters/core/src/routing.d.ts +0 -82
- package/dist/vendor/adapters/core/src/routing.js +0 -336
- package/dist/vendor/adapters/core/src/test-integrity.d.ts +0 -64
- package/dist/vendor/adapters/core/src/test-integrity.js +0 -197
- package/dist/vendor/adapters/core/src/trajectory.d.ts +0 -18
- package/dist/vendor/adapters/core/src/trajectory.js +0 -295
- package/dist/vendor/adapters/stub-agent-cli.d.ts +0 -8
- package/dist/vendor/adapters/stub-agent-cli.js +0 -40
- package/dist/vendor/adapters/verifier-only.d.ts +0 -9
- package/dist/vendor/adapters/verifier-only.js +0 -63
|
@@ -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,5 +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";
|
|
187
228
|
export { cacheMessage, fetchSelectedMessage, getCliInstalledVersion, getMcpInstalledVersion, isCooldownExpired, isDismissed, isNewerVersion, loadDeliveryRecord, parseMessageSelectionResponse, recordDismissed, recordShown, resolveDefaultLedgerPath, saveDeliveryRecord, } from "./delivery/index.js";
|
|
188
229
|
export type { MessageClientOptions, MessageSelectRequest, ParseFailure, ParseResult, ValidationError, } from "./delivery/index.js";
|