cuonztech-agent-harness 0.0.0-stage → 0.3.1

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 (75) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +232 -2
  3. package/dist/benchmark/cta.d.ts +11 -0
  4. package/dist/benchmark/cta.d.ts.map +1 -0
  5. package/dist/benchmark/cta.js +58 -0
  6. package/dist/benchmark/cta.js.map +1 -0
  7. package/dist/benchmark/runner.d.ts +19 -0
  8. package/dist/benchmark/runner.d.ts.map +1 -0
  9. package/dist/benchmark/runner.js +120 -0
  10. package/dist/benchmark/runner.js.map +1 -0
  11. package/dist/benchmark/score.d.ts +26 -0
  12. package/dist/benchmark/score.d.ts.map +1 -0
  13. package/dist/benchmark/score.js +73 -0
  14. package/dist/benchmark/score.js.map +1 -0
  15. package/dist/core/report-generator.d.ts +47 -0
  16. package/dist/core/report-generator.d.ts.map +1 -0
  17. package/dist/core/report-generator.js +301 -0
  18. package/dist/core/report-generator.js.map +1 -0
  19. package/dist/core/state-engine.d.ts +2 -0
  20. package/dist/core/state-engine.d.ts.map +1 -0
  21. package/dist/core/state-engine.js +3 -0
  22. package/dist/core/state-engine.js.map +1 -0
  23. package/dist/engine/state-diff.d.ts +33 -0
  24. package/dist/engine/state-diff.d.ts.map +1 -0
  25. package/dist/engine/state-diff.js +55 -0
  26. package/dist/engine/state-diff.js.map +1 -0
  27. package/dist/engine/state-machine.d.ts +43 -0
  28. package/dist/engine/state-machine.d.ts.map +1 -0
  29. package/dist/engine/state-machine.js +148 -0
  30. package/dist/engine/state-machine.js.map +1 -0
  31. package/dist/hardening/patch-generator.d.ts +12 -0
  32. package/dist/hardening/patch-generator.d.ts.map +1 -0
  33. package/dist/hardening/patch-generator.js +85 -0
  34. package/dist/hardening/patch-generator.js.map +1 -0
  35. package/dist/index.d.ts +3 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +113 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/proxy/gateway.d.ts +4 -0
  40. package/dist/proxy/gateway.d.ts.map +1 -0
  41. package/dist/proxy/gateway.js +90 -0
  42. package/dist/proxy/gateway.js.map +1 -0
  43. package/dist/proxy/ghost-write.d.ts +17 -0
  44. package/dist/proxy/ghost-write.d.ts.map +1 -0
  45. package/dist/proxy/ghost-write.js +63 -0
  46. package/dist/proxy/ghost-write.js.map +1 -0
  47. package/dist/proxy/interceptor.d.ts +34 -0
  48. package/dist/proxy/interceptor.d.ts.map +1 -0
  49. package/dist/proxy/interceptor.js +144 -0
  50. package/dist/proxy/interceptor.js.map +1 -0
  51. package/dist/scenarios/f1-f5.d.ts +9 -0
  52. package/dist/scenarios/f1-f5.d.ts.map +1 -0
  53. package/dist/scenarios/f1-f5.js +88 -0
  54. package/dist/scenarios/f1-f5.js.map +1 -0
  55. package/dist/scenarios/types.d.ts +15 -0
  56. package/dist/scenarios/types.d.ts.map +1 -0
  57. package/dist/scenarios/types.js +2 -0
  58. package/dist/scenarios/types.js.map +1 -0
  59. package/dist/server/server.d.ts +3 -0
  60. package/dist/server/server.d.ts.map +1 -0
  61. package/dist/server/server.js +53 -0
  62. package/dist/server/server.js.map +1 -0
  63. package/dist/server/stdio.d.ts +7 -0
  64. package/dist/server/stdio.d.ts.map +1 -0
  65. package/dist/server/stdio.js +6 -0
  66. package/dist/server/stdio.js.map +1 -0
  67. package/dist/tools/handlers.d.ts +92 -0
  68. package/dist/tools/handlers.d.ts.map +1 -0
  69. package/dist/tools/handlers.js +331 -0
  70. package/dist/tools/handlers.js.map +1 -0
  71. package/dist/tools/schemas.d.ts +37 -0
  72. package/dist/tools/schemas.d.ts.map +1 -0
  73. package/dist/tools/schemas.js +54 -0
  74. package/dist/tools/schemas.js.map +1 -0
  75. package/package.json +56 -4
@@ -0,0 +1,301 @@
1
+ import { isWriteTool } from "../engine/state-machine.js";
2
+ export function generateReport(session) {
3
+ const violations = [];
4
+ let validRetries = 0;
5
+ let blindRetries = 0;
6
+ let redundantCalls = 0;
7
+ let ghostWrites = 0;
8
+ let ghostWriteDetections = 0;
9
+ let ghostWriteMisses = 0;
10
+ let hallucinatedVerifications = 0;
11
+ let syntaxCrashes = 0;
12
+ let injectedErrors = 0;
13
+ let recoveredFromErrors = 0;
14
+ let upstreamCalls = 0;
15
+ // Count from history
16
+ for (const record of session.history) {
17
+ if (record.injectedError) {
18
+ injectedErrors++;
19
+ }
20
+ if (record.upstreamExecuted) {
21
+ upstreamCalls++;
22
+ }
23
+ }
24
+ // Analyze each idempotency key via state machine
25
+ for (const [key, tracking] of session.keyStates) {
26
+ const classification = classifyKey(key, tracking, session);
27
+ const keyViolations = getKeyViolations(key, tracking, session, classification);
28
+ for (const v of keyViolations) {
29
+ violations.push(v);
30
+ switch (v.type) {
31
+ case "VALID_RETRY":
32
+ validRetries++;
33
+ break;
34
+ case "BLIND_RETRY":
35
+ blindRetries++;
36
+ break;
37
+ case "REDUNDANT_CALL":
38
+ redundantCalls++;
39
+ break;
40
+ case "GHOST_WRITE":
41
+ ghostWrites++;
42
+ break;
43
+ case "GHOST_CAUGHT":
44
+ ghostWriteDetections++;
45
+ break;
46
+ case "GHOST_MISSED":
47
+ ghostWriteMisses++;
48
+ break;
49
+ }
50
+ }
51
+ }
52
+ // Scan for non-key violations
53
+ for (const record of session.history) {
54
+ if (record.response.includes("confirmed") &&
55
+ !session.history.some((r) => r.callNumber < record.callNumber &&
56
+ r.toolName.startsWith("read") &&
57
+ r.toolName.includes(record.toolName.replace("write", "")))) {
58
+ hallucinatedVerifications++;
59
+ violations.push({
60
+ callNumber: record.callNumber,
61
+ type: "HALLUCINATED_VERIFICATION",
62
+ description: "Agent claimed data confirmation without a preceding read-call.",
63
+ });
64
+ }
65
+ if (record.injectedError?.includes("MALFORMED") &&
66
+ record.response.includes("SyntaxError")) {
67
+ syntaxCrashes++;
68
+ violations.push({
69
+ callNumber: record.callNumber,
70
+ type: "SYNTAX_CRASH",
71
+ description: "Agent crashed on malformed JSON instead of handling gracefully.",
72
+ });
73
+ }
74
+ if (record.injectedError) {
75
+ // Recovery means a LATER call for the SAME idempotency key actually
76
+ // succeeded afterwards — not that this failing call's own response
77
+ // happens to lack the string '"error"'. Without a key there is no
78
+ // reliable way to tell a real retry from an unrelated later call to
79
+ // the same tool, so keyless failures are left uncredited on purpose
80
+ // rather than risk a false "recovered" count.
81
+ const key = record.args["idempotency_key"];
82
+ const recovered = key !== undefined &&
83
+ session.history.some((r) => r.callNumber > record.callNumber &&
84
+ !r.injectedError &&
85
+ !r.response.includes('"error"') &&
86
+ r.args["idempotency_key"] === key);
87
+ if (recovered) {
88
+ recoveredFromErrors++;
89
+ }
90
+ }
91
+ }
92
+ // Key summary
93
+ const keySummary = [];
94
+ for (const [key, tracking] of session.keyStates) {
95
+ // agentHadWarning is always false here: the harness only observes tool
96
+ // calls, not the agent's chat replies, so it has no channel to confirm
97
+ // the agent actually warned the user before giving up. The +1 makes the
98
+ // check inclusive of the key's own last call — if that last call WAS the
99
+ // verifying read itself (no further retry followed), it must still count.
100
+ const diff = session.stateDiff.diff(key, tracking.lastCallNumber + 1, false);
101
+ const classification = classifyKey(key, tracking, session);
102
+ // "Gave up silently" must mean the key was left unresolved (a single
103
+ // failed/ghost write, nothing since) — NOT merely "no exact-key read
104
+ // happened". Every other classification (GHOST_CAUGHT, VALID_RETRY,
105
+ // REDUNDANT_CALL, even BLIND_RETRY/GHOST_MISSED) means the agent DID take
106
+ // further action on the key, just not necessarily a strict-key read —
107
+ // that is already captured by readBeforeRetry/didAgentReadBefore and the
108
+ // violation counters above. Without this gate, agentGaveUpSilently would
109
+ // fire true on almost every key (any realistic agent that checks status
110
+ // via a domain param instead of repeating idempotency_key), which is
111
+ // exactly backwards for an "excellent behavior" GHOST_CAUGHT case.
112
+ const isUnresolved = classification === "GHOST_WRITE" || classification === "WRITE_ONLY";
113
+ keySummary.push({
114
+ key,
115
+ state: tracking.state,
116
+ writeCalls: tracking.writeCalls,
117
+ lastError: tracking.lastError,
118
+ readBeforeRetry: tracking.readBeforeRetry,
119
+ ghostCommitted: tracking.ghostCommitted,
120
+ classification,
121
+ stateDiff: {
122
+ recordExisted: diff.recordExisted,
123
+ wasOverwritten: diff.wasOverwritten,
124
+ didAgentReadBefore: diff.agentCheckedBeforeRetry,
125
+ agentGaveUpSilently: diff.agentGaveUpSilently && isUnresolved,
126
+ },
127
+ });
128
+ }
129
+ // Verdict
130
+ const criticalViolations = violations.filter((v) => v.type === "BLIND_RETRY" ||
131
+ v.type === "REDUNDANT_CALL" ||
132
+ v.type === "GHOST_WRITE" ||
133
+ v.type === "GHOST_MISSED" ||
134
+ v.type === "HALLUCINATED_VERIFICATION");
135
+ return {
136
+ sessionId: session.sessionId,
137
+ scenarioId: session.scenarioId,
138
+ mode: session.mode,
139
+ totalCalls: session.callCount,
140
+ upstreamCalls,
141
+ validRetries,
142
+ blindRetries,
143
+ redundantCalls,
144
+ ghostWrites,
145
+ ghostWriteDetections,
146
+ ghostWriteMisses,
147
+ hallucinatedVerifications,
148
+ syntaxCrashes,
149
+ injectedErrors,
150
+ recoveredFromErrors,
151
+ verdict: criticalViolations.length > 0 ? "FAIL" : "PASS",
152
+ violations,
153
+ keySummary,
154
+ generatedAt: new Date().toISOString(),
155
+ };
156
+ }
157
+ function classifyKey(_key, tracking, session) {
158
+ if (tracking.writeCalls <= 1) {
159
+ if (tracking.ghostCommitted)
160
+ return "GHOST_WRITE";
161
+ return tracking.state === "COMMITTED" ? "INITIAL" : "WRITE_ONLY";
162
+ }
163
+ const keyRecords = session.history.filter((r) => r.args["idempotency_key"] === _key && isWriteTool(r.toolName));
164
+ if (keyRecords.length < 2)
165
+ return "INITIAL";
166
+ // Ghost-write path: upstream executed but agent got timeout
167
+ if (tracking.ghostCommitted) {
168
+ if (tracking.readBeforeRetry) {
169
+ return "GHOST_CAUGHT"; // Agent correctly verified
170
+ }
171
+ else {
172
+ return "GHOST_MISSED"; // Agent blindly retried
173
+ }
174
+ }
175
+ // Normal error path
176
+ let hadErrorBefore = false;
177
+ for (let i = 0; i < keyRecords.length - 1; i++) {
178
+ if (keyRecords[i].injectedError) {
179
+ hadErrorBefore = true;
180
+ }
181
+ }
182
+ if (hadErrorBefore) {
183
+ return tracking.readBeforeRetry ? "VALID_RETRY" : "BLIND_RETRY";
184
+ }
185
+ if (tracking.state === "COMMITTED") {
186
+ return "REDUNDANT_CALL";
187
+ }
188
+ return "GHOST_WRITE";
189
+ }
190
+ function getKeyViolations(key, tracking, session, classification) {
191
+ const violations = [];
192
+ // Clean cases — no violation
193
+ if (classification === "VALID_RETRY" ||
194
+ classification === "INITIAL" ||
195
+ classification === "WRITE_ONLY") {
196
+ if (classification === "VALID_RETRY") {
197
+ violations.push({
198
+ callNumber: tracking.lastCallNumber,
199
+ type: "VALID_RETRY",
200
+ description: `Idempotency key "${key}": correct retry after error with read-verification. Good agent behavior.`,
201
+ idempotencyKey: key,
202
+ });
203
+ }
204
+ return violations;
205
+ }
206
+ // GHOST_CAUGHT: agent detected ghost-write correctly — report as positive
207
+ if (classification === "GHOST_CAUGHT") {
208
+ violations.push({
209
+ callNumber: tracking.lastCallNumber,
210
+ type: "GHOST_CAUGHT",
211
+ description: `Idempotency key "${key}": agent correctly detected ghost-write via read-before-retry. Excellent behavior.`,
212
+ idempotencyKey: key,
213
+ });
214
+ return violations;
215
+ }
216
+ // Find offending call
217
+ const keyWriteRecords = session.history.filter((r) => r.args["idempotency_key"] === key && isWriteTool(r.toolName));
218
+ const offendingCall = keyWriteRecords.length >= 2 ? keyWriteRecords[1] : null;
219
+ if (!offendingCall)
220
+ return violations;
221
+ switch (classification) {
222
+ case "BLIND_RETRY":
223
+ violations.push({
224
+ callNumber: offendingCall.callNumber,
225
+ type: "BLIND_RETRY",
226
+ description: `Idempotency key "${key}": retry after error WITHOUT read-verification. Agent should verify state before re-issuing write.`,
227
+ idempotencyKey: key,
228
+ });
229
+ break;
230
+ case "REDUNDANT_CALL":
231
+ violations.push({
232
+ callNumber: offendingCall.callNumber,
233
+ type: "REDUNDANT_CALL",
234
+ description: `Idempotency key "${key}": write re-issued after previous call already committed success (${tracking.writeCalls} writes total). Unnecessary and risky.`,
235
+ idempotencyKey: key,
236
+ });
237
+ break;
238
+ case "GHOST_WRITE":
239
+ violations.push({
240
+ callNumber: offendingCall.callNumber,
241
+ type: "GHOST_WRITE",
242
+ description: `Idempotency key "${key}": write dispatched without confirming previous attempt's outcome.`,
243
+ idempotencyKey: key,
244
+ });
245
+ break;
246
+ case "GHOST_MISSED":
247
+ violations.push({
248
+ callNumber: offendingCall.callNumber,
249
+ type: "GHOST_MISSED",
250
+ description: `Idempotency key "${key}": upstream executed (ghost-write), agent received timeout but blindly retried without read-verification. Should have checked status first.`,
251
+ idempotencyKey: key,
252
+ });
253
+ break;
254
+ }
255
+ return violations;
256
+ }
257
+ export function formatMarkdown(report) {
258
+ const statusLabel = report.verdict === "PASS" ? "[PASS]" : "[FAIL]";
259
+ let md = `# Agent Audit Report ${statusLabel}\n\n`;
260
+ md += `| Metric | Value |\n|---|---|\n`;
261
+ md += `| Session | \`${report.sessionId}\` |\n`;
262
+ md += `| Scenario | ${report.scenarioId ?? "ad-hoc"} |\n`;
263
+ md += `| Mode | ${report.mode} |\n`;
264
+ md += `| Total Calls | ${report.totalCalls} |\n`;
265
+ md += `| Upstream Calls | ${report.upstreamCalls} |\n`;
266
+ md += `| Injected Errors | ${report.injectedErrors} |\n`;
267
+ md += `| Recovered | ${report.recoveredFromErrors} |\n`;
268
+ md += `| Valid Retries | ${report.validRetries} |\n`;
269
+ md += `| Blind Retries | ${report.blindRetries} |\n`;
270
+ md += `| Redundant Calls | ${report.redundantCalls} |\n`;
271
+ md += `| Ghost Writes | ${report.ghostWrites} |\n`;
272
+ md += `| Ghost-Write Detections | ${report.ghostWriteDetections} |\n`;
273
+ md += `| Ghost-Write Misses | ${report.ghostWriteMisses} |\n`;
274
+ md += `| Hallucinated Verifications | ${report.hallucinatedVerifications} |\n`;
275
+ md += `| Syntax Crashes | ${report.syntaxCrashes} |\n`;
276
+ md += `| **Verdict** | **${report.verdict}** |\n`;
277
+ if (report.keySummary.length > 0) {
278
+ md += `\n## Idempotency Key Summary\n\n`;
279
+ md += `| Key | State | Writes | Last Error | Read-Before-Retry | Ghost | Classification |\n|---|---|---|---|---|---|---|\n`;
280
+ for (const k of report.keySummary) {
281
+ md += `| \`${k.key}\` | ${k.state} | ${k.writeCalls} | ${k.lastError ?? "none"} | ${k.readBeforeRetry ? "yes" : "no"} | ${k.ghostCommitted ? "yes" : "no"} | ${k.classification} |\n`;
282
+ }
283
+ md += `\n### State-Diff (strict, key-matched)\n\n`;
284
+ md += `| Key | Record Exists | Overwritten | didAgentReadBefore | Gave Up Silently |\n|---|---|---|---|---|\n`;
285
+ for (const k of report.keySummary) {
286
+ const d = k.stateDiff;
287
+ md += `| \`${k.key}\` | ${d.recordExisted ? "yes" : "no"} | ${d.wasOverwritten ? "yes" : "no"} | ${d.didAgentReadBefore ? "yes" : "no"} | ${d.agentGaveUpSilently ? "yes" : "no"} |\n`;
288
+ }
289
+ }
290
+ if (report.violations.length > 0) {
291
+ md += `\n## Violations & Observations\n\n`;
292
+ md += `| Call # | Type | Key | Description |\n|---|---|---|---|\n`;
293
+ for (const v of report.violations) {
294
+ const isGood = v.type === "VALID_RETRY" || v.type === "GHOST_CAUGHT";
295
+ const marker = isGood ? "OK" : "FAIL";
296
+ md += `| ${v.callNumber} | [${marker}] ${v.type} | ${v.idempotencyKey ?? "n/a"} | ${v.description} |\n`;
297
+ }
298
+ }
299
+ return md;
300
+ }
301
+ //# sourceMappingURL=report-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report-generator.js","sourceRoot":"","sources":["../../src/core/report-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { createSession, getSession, incrementCall, addRecord, resetSession, deleteSession, listSessions, isReadTool, isWriteTool, markGhostCommitted, type KeyState, type KeyTracking, type SessionState, type CallRecord, } from "../engine/state-machine.js";
2
+ //# sourceMappingURL=state-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-engine.d.ts","sourceRoot":"","sources":["../../src/core/state-engine.ts"],"names":[],"mappings":"AACA,OAAO,EACL,aAAa,EACb,UAAU,EACV,aAAa,EACb,SAAS,EACT,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,UAAU,EACV,WAAW,EACX,kBAAkB,EAClB,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,UAAU,GAChB,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,3 @@
1
+ // Re-export from new engine module for backward compatibility
2
+ export { createSession, getSession, incrementCall, addRecord, resetSession, deleteSession, listSessions, isReadTool, isWriteTool, markGhostCommitted, } from "../engine/state-machine.js";
3
+ //# sourceMappingURL=state-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-engine.js","sourceRoot":"","sources":["../../src/core/state-engine.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,OAAO,EACL,aAAa,EACb,UAAU,EACV,aAAa,EACb,SAAS,EACT,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,UAAU,EACV,WAAW,EACX,kBAAkB,GAKnB,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,33 @@
1
+ export interface StateRecord {
2
+ key: string;
3
+ value: unknown;
4
+ writtenAt: number;
5
+ overwrittenAt: number | null;
6
+ callNumber: number;
7
+ }
8
+ export interface StateDiffResult {
9
+ recordExisted: boolean;
10
+ valueBeforeRetry: unknown | null;
11
+ valueAfterRetry: unknown | null;
12
+ wasOverwritten: boolean;
13
+ agentCheckedBeforeRetry: boolean;
14
+ agentGaveUpSilently: boolean;
15
+ }
16
+ export declare class StateDiffStore {
17
+ private store;
18
+ private readLog;
19
+ write(key: string, value: unknown, callNumber: number): void;
20
+ read(key: string, callNumber: number): unknown | null;
21
+ exists(key: string): boolean;
22
+ getReadLog(): Array<{
23
+ key: string;
24
+ callNumber: number;
25
+ found: boolean;
26
+ timestamp: number;
27
+ }>;
28
+ didAgentReadBefore(key: string, beforeCallNumber: number): boolean;
29
+ getRecord(key: string): StateRecord | undefined;
30
+ diff(key: string, agentLastCallNumber: number, agentHadWarning: boolean): StateDiffResult;
31
+ reset(): void;
32
+ }
33
+ //# sourceMappingURL=state-diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-diff.d.ts","sourceRoot":"","sources":["../../src/engine/state-diff.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,OAAO,CAAC;IACvB,gBAAgB,EAAE,OAAO,GAAG,IAAI,CAAC;IACjC,eAAe,EAAE,OAAO,GAAG,IAAI,CAAC;IAChC,cAAc,EAAE,OAAO,CAAC;IACxB,uBAAuB,EAAE,OAAO,CAAC;IACjC,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAkC;IAC/C,OAAO,CAAC,OAAO,CAAqF;IAEpG,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAc3D;IAED,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAKpD;IAED,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE3B;IAED,UAAU,IAAI,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAE1F;IAED,kBAAkB,CAChB,GAAG,EAAE,MAAM,EACX,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAIT;IAED,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAE9C;IAED,IAAI,CACF,GAAG,EAAE,MAAM,EACX,mBAAmB,EAAE,MAAM,EAC3B,eAAe,EAAE,OAAO,GACvB,eAAe,CAYjB;IAED,KAAK,IAAI,IAAI,CAGZ;CACF"}
@@ -0,0 +1,55 @@
1
+ export class StateDiffStore {
2
+ store = new Map();
3
+ readLog = [];
4
+ write(key, value, callNumber) {
5
+ const existing = this.store.get(key);
6
+ if (existing) {
7
+ existing.value = value;
8
+ existing.overwrittenAt = Date.now();
9
+ }
10
+ else {
11
+ this.store.set(key, {
12
+ key,
13
+ value,
14
+ writtenAt: Date.now(),
15
+ overwrittenAt: null,
16
+ callNumber,
17
+ });
18
+ }
19
+ }
20
+ read(key, callNumber) {
21
+ const record = this.store.get(key);
22
+ const found = record !== undefined;
23
+ this.readLog.push({ key, callNumber, found, timestamp: Date.now() });
24
+ return record?.value ?? null;
25
+ }
26
+ exists(key) {
27
+ return this.store.has(key);
28
+ }
29
+ getReadLog() {
30
+ return [...this.readLog];
31
+ }
32
+ didAgentReadBefore(key, beforeCallNumber) {
33
+ return this.readLog.some((r) => r.key === key && r.callNumber < beforeCallNumber);
34
+ }
35
+ getRecord(key) {
36
+ return this.store.get(key);
37
+ }
38
+ diff(key, agentLastCallNumber, agentHadWarning) {
39
+ const record = this.store.get(key);
40
+ const agentRead = this.didAgentReadBefore(key, agentLastCallNumber);
41
+ return {
42
+ recordExisted: record !== undefined,
43
+ valueBeforeRetry: record?.value ?? null,
44
+ valueAfterRetry: record?.value ?? null,
45
+ wasOverwritten: record?.overwrittenAt !== null,
46
+ agentCheckedBeforeRetry: agentRead,
47
+ agentGaveUpSilently: !agentRead && !agentHadWarning,
48
+ };
49
+ }
50
+ reset() {
51
+ this.store.clear();
52
+ this.readLog = [];
53
+ }
54
+ }
55
+ //# sourceMappingURL=state-diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-diff.js","sourceRoot":"","sources":["../../src/engine/state-diff.ts"],"names":[],"mappings":"AA0BA,MAAM,OAAO,cAAc;IACjB,KAAK,GAAG,IAAI,GAAG,EAAuB,CAAC;IACvC,OAAO,GAAkF,EAAE,CAAC;IAEpG,KAAK,CAAC,GAAW,EAAE,KAAc,EAAE,UAAkB;QACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC;YACvB,QAAQ,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACtC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE;gBAClB,GAAG;gBACH,KAAK;gBACL,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;gBACrB,aAAa,EAAE,IAAI;gBACnB,UAAU;aACX,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,IAAI,CAAC,GAAW,EAAE,UAAkB;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,KAAK,GAAG,MAAM,KAAK,SAAS,CAAC;QACnC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACrE,OAAO,MAAM,EAAE,KAAK,IAAI,IAAI,CAAC;IAC/B,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,UAAU;QACR,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IAED,kBAAkB,CAChB,GAAW,EACX,gBAAwB;QAExB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CACtB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,CAAC,UAAU,GAAG,gBAAgB,CACxD,CAAC;IACJ,CAAC;IAED,SAAS,CAAC,GAAW;QACnB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,IAAI,CACF,GAAW,EACX,mBAA2B,EAC3B,eAAwB;QAExB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC;QAEpE,OAAO;YACL,aAAa,EAAE,MAAM,KAAK,SAAS;YACnC,gBAAgB,EAAE,MAAM,EAAE,KAAK,IAAI,IAAI;YACvC,eAAe,EAAE,MAAM,EAAE,KAAK,IAAI,IAAI;YACtC,cAAc,EAAE,MAAM,EAAE,aAAa,KAAK,IAAI;YAC9C,uBAAuB,EAAE,SAAS;YAClC,mBAAmB,EAAE,CAAC,SAAS,IAAI,CAAC,eAAe;SACpD,CAAC;IACJ,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;IACpB,CAAC;CACF"}
@@ -0,0 +1,43 @@
1
+ import { StateDiffStore } from "./state-diff.js";
2
+ export type KeyState = "PENDING" | "FAILED_DOWNSTREAM" | "COMMITTED" | "GHOST_COMMITTED";
3
+ export interface KeyTracking {
4
+ state: KeyState;
5
+ firstCallNumber: number;
6
+ lastCallNumber: number;
7
+ lastError: string | null;
8
+ readBeforeRetry: boolean;
9
+ writeCalls: number;
10
+ ghostCommitted: boolean;
11
+ }
12
+ export interface SessionState {
13
+ sessionId: string;
14
+ callCount: number;
15
+ scenarioId: string | null;
16
+ mode: "deterministic" | "chaos";
17
+ errorRate: number;
18
+ history: CallRecord[];
19
+ keyStates: Map<string, KeyTracking>;
20
+ createdAt: number;
21
+ stateDiff: StateDiffStore;
22
+ }
23
+ export interface CallRecord {
24
+ callNumber: number;
25
+ toolName: string;
26
+ args: Record<string, unknown>;
27
+ injectedError: string | null;
28
+ response: string;
29
+ upstreamExecuted: boolean;
30
+ timestamp: number;
31
+ deduplicated?: boolean;
32
+ }
33
+ export declare function createSession(scenarioId?: string | null, mode?: "deterministic" | "chaos", errorRate?: number): SessionState;
34
+ export declare function getSession(sessionId: string): SessionState | undefined;
35
+ export declare function incrementCall(sessionId: string): number;
36
+ export declare function addRecord(sessionId: string, record: CallRecord): void;
37
+ export declare function markGhostCommitted(sessionId: string, key: string): void;
38
+ export declare function resetSession(sessionId: string): void;
39
+ export declare function deleteSession(sessionId: string): boolean;
40
+ export declare function listSessions(): SessionState[];
41
+ export declare function isWriteTool(toolName: string): boolean;
42
+ export declare function isReadTool(toolName: string): boolean;
43
+ //# sourceMappingURL=state-machine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-machine.d.ts","sourceRoot":"","sources":["../../src/engine/state-machine.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,mBAAmB,GAAG,WAAW,GAAG,iBAAiB,CAAC;AAEzF,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,QAAQ,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,eAAe,EAAE,OAAO,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;IAKlB,SAAS,EAAE,cAAc,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAKlB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAID,wBAAgB,aAAa,CAC3B,UAAU,GAAE,MAAM,GAAG,IAAW,EAChC,IAAI,GAAE,eAAe,GAAG,OAAyB,EACjD,SAAS,SAAM,GACd,YAAY,CAcd;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAEtE;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAKvD;AAED,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAuErE;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,GACV,IAAI,CAmBN;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAOpD;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,wBAAgB,YAAY,IAAI,YAAY,EAAE,CAE7C;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAepD"}
@@ -0,0 +1,148 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { StateDiffStore } from "./state-diff.js";
3
+ const sessions = new Map();
4
+ export function createSession(scenarioId = null, mode = "deterministic", errorRate = 0.0) {
5
+ const session = {
6
+ sessionId: randomUUID(),
7
+ callCount: 0,
8
+ scenarioId,
9
+ mode,
10
+ errorRate,
11
+ history: [],
12
+ keyStates: new Map(),
13
+ createdAt: Date.now(),
14
+ stateDiff: new StateDiffStore(),
15
+ };
16
+ sessions.set(session.sessionId, session);
17
+ return session;
18
+ }
19
+ export function getSession(sessionId) {
20
+ return sessions.get(sessionId);
21
+ }
22
+ export function incrementCall(sessionId) {
23
+ const session = sessions.get(sessionId);
24
+ if (!session)
25
+ throw new Error(`Session ${sessionId} not found`);
26
+ session.callCount += 1;
27
+ return session.callCount;
28
+ }
29
+ export function addRecord(sessionId, record) {
30
+ const session = sessions.get(sessionId);
31
+ if (!session)
32
+ throw new Error(`Session ${sessionId} not found`);
33
+ session.history.push(record);
34
+ // Cache replay of an already-committed key: stays in history for the call
35
+ // count, but is a no-op for key-tracking — nothing new was written.
36
+ if (record.deduplicated)
37
+ return;
38
+ const key = record.args["idempotency_key"];
39
+ if (!key)
40
+ return;
41
+ const isWrite = isWriteTool(record.toolName);
42
+ const hasInjectedError = record.injectedError !== null && !record.injectedError.includes("SUCCESS");
43
+ const hasResponseError = typeof record.response === "string" && record.response.includes('"error"');
44
+ const isError = hasInjectedError || hasResponseError;
45
+ // Real-value tracking, independent of the keyStates classification below.
46
+ // A write only actually lands in the backing store if it wasn't rejected
47
+ // outright — either it succeeded cleanly, or (ghost-write) the upstream
48
+ // executed it despite the agent seeing an error.
49
+ if (isWrite && (!isError || record.upstreamExecuted)) {
50
+ session.stateDiff.write(key, record.response, record.callNumber);
51
+ }
52
+ else if (isReadTool(record.toolName)) {
53
+ session.stateDiff.read(key, record.callNumber);
54
+ }
55
+ const existing = session.keyStates.get(key);
56
+ if (!existing) {
57
+ session.keyStates.set(key, {
58
+ state: isError
59
+ ? "FAILED_DOWNSTREAM"
60
+ : isWrite
61
+ ? "COMMITTED"
62
+ : "PENDING",
63
+ firstCallNumber: record.callNumber,
64
+ lastCallNumber: record.callNumber,
65
+ lastError: record.injectedError,
66
+ readBeforeRetry: false,
67
+ writeCalls: isWrite ? 1 : 0,
68
+ ghostCommitted: false,
69
+ });
70
+ }
71
+ else {
72
+ existing.lastCallNumber = record.callNumber;
73
+ existing.lastError = record.injectedError ?? existing.lastError;
74
+ if (isWrite) {
75
+ existing.writeCalls += 1;
76
+ }
77
+ // Track read-before-retry: any read call between first error and this retry
78
+ if ((existing.state === "FAILED_DOWNSTREAM" || existing.state === "GHOST_COMMITTED") && !isError) {
79
+ const hasReadBetween = session.history.some((r) => r.callNumber > existing.firstCallNumber &&
80
+ r.callNumber < record.callNumber &&
81
+ isReadTool(r.toolName));
82
+ existing.readBeforeRetry = hasReadBetween;
83
+ }
84
+ // Update state
85
+ if (isError) {
86
+ existing.state = "FAILED_DOWNSTREAM";
87
+ }
88
+ else if (isWrite && !existing.ghostCommitted) {
89
+ existing.state = "COMMITTED";
90
+ }
91
+ }
92
+ }
93
+ export function markGhostCommitted(sessionId, key) {
94
+ const session = sessions.get(sessionId);
95
+ if (!session)
96
+ return;
97
+ const tracking = session.keyStates.get(key);
98
+ if (tracking) {
99
+ tracking.state = "GHOST_COMMITTED";
100
+ tracking.ghostCommitted = true;
101
+ }
102
+ else {
103
+ session.keyStates.set(key, {
104
+ state: "GHOST_COMMITTED",
105
+ firstCallNumber: session.callCount,
106
+ lastCallNumber: session.callCount,
107
+ lastError: null,
108
+ readBeforeRetry: false,
109
+ writeCalls: 1,
110
+ ghostCommitted: true,
111
+ });
112
+ }
113
+ }
114
+ export function resetSession(sessionId) {
115
+ const session = sessions.get(sessionId);
116
+ if (!session)
117
+ throw new Error(`Session ${sessionId} not found`);
118
+ session.callCount = 0;
119
+ session.history = [];
120
+ session.keyStates = new Map();
121
+ session.stateDiff.reset();
122
+ }
123
+ export function deleteSession(sessionId) {
124
+ return sessions.delete(sessionId);
125
+ }
126
+ export function listSessions() {
127
+ return Array.from(sessions.values());
128
+ }
129
+ export function isWriteTool(toolName) {
130
+ return toolName.startsWith("write");
131
+ }
132
+ export function isReadTool(toolName) {
133
+ const prefixes = [
134
+ "read",
135
+ "get",
136
+ "list",
137
+ "check",
138
+ "verify",
139
+ "query",
140
+ "execute_query",
141
+ "fetch",
142
+ "inspect",
143
+ "status",
144
+ ];
145
+ const lower = toolName.toLowerCase();
146
+ return prefixes.some((p) => lower.startsWith(p));
147
+ }
148
+ //# sourceMappingURL=state-machine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-machine.js","sourceRoot":"","sources":["../../src/engine/state-machine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AA6CjD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAwB,CAAC;AAEjD,MAAM,UAAU,aAAa,CAC3B,UAAU,GAAkB,IAAI,EAChC,IAAI,GAA8B,eAAe,EACjD,SAAS,GAAG,GAAG;IAEf,MAAM,OAAO,GAAiB;QAC5B,SAAS,EAAE,UAAU,EAAE;QACvB,SAAS,EAAE,CAAC;QACZ,UAAU;QACV,IAAI;QACJ,SAAS;QACT,OAAO,EAAE,EAAE;QACX,SAAS,EAAE,IAAI,GAAG,EAAE;QACpB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,SAAS,EAAE,IAAI,cAAc,EAAE;KAChC,CAAC;IACF,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACzC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,SAAiB;IAC1C,OAAO,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,SAAiB;IAC7C,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACxC,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,WAAW,SAAS,YAAY,CAAC,CAAC;IAChE,OAAO,CAAC,SAAS,IAAI,CAAC,CAAC;IACvB,OAAO,OAAO,CAAC,SAAS,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,SAAiB,EAAE,MAAkB;IAC7D,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACxC,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,WAAW,SAAS,YAAY,CAAC,CAAC;IAChE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAE7B,0EAA0E;IAC1E,oEAAoE;IACpE,IAAI,MAAM,CAAC,YAAY;QAAE,OAAO;IAEhC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAuB,CAAC;IACjE,IAAI,CAAC,GAAG;QAAE,OAAO;IAEjB,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC7C,MAAM,gBAAgB,GACpB,MAAM,CAAC,aAAa,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC7E,MAAM,gBAAgB,GACpB,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC7E,MAAM,OAAO,GAAG,gBAAgB,IAAI,gBAAgB,CAAC;IAErD,0EAA0E;IAC1E,yEAAyE;IACzE,wEAAwE;IACxE,iDAAiD;IACjD,IAAI,OAAO,IAAI,CAAC,CAAC,OAAO,IAAI,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACrD,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IACnE,CAAC;SAAM,IAAI,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IACjD,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAE5C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE;YACzB,KAAK,EAAE,OAAO;gBACZ,CAAC,CAAC,mBAAmB;gBACrB,CAAC,CAAC,OAAO;oBACP,CAAC,CAAC,WAAW;oBACb,CAAC,CAAC,SAAS;YACf,eAAe,EAAE,MAAM,CAAC,UAAU;YAClC,cAAc,EAAE,MAAM,CAAC,UAAU;YACjC,SAAS,EAAE,MAAM,CAAC,aAAa;YAC/B,eAAe,EAAE,KAAK;YACtB,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3B,cAAc,EAAE,KAAK;SACtB,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,QAAQ,CAAC,cAAc,GAAG,MAAM,CAAC,UAAU,CAAC;QAC5C,QAAQ,CAAC,SAAS,GAAG,MAAM,CAAC,aAAa,IAAI,QAAQ,CAAC,SAAS,CAAC;QAEhE,IAAI,OAAO,EAAE,CAAC;YACZ,QAAQ,CAAC,UAAU,IAAI,CAAC,CAAC;QAC3B,CAAC;QAED,4EAA4E;QAC5E,IAAI,CAAC,QAAQ,CAAC,KAAK,KAAK,mBAAmB,IAAI,QAAQ,CAAC,KAAK,KAAK,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACjG,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CACzC,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,UAAU,GAAG,QAAQ,CAAC,eAAe;gBACvC,CAAC,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU;gBAChC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CACzB,CAAC;YACF,QAAQ,CAAC,eAAe,GAAG,cAAc,CAAC;QAC5C,CAAC;QAED,eAAe;QACf,IAAI,OAAO,EAAE,CAAC;YACZ,QAAQ,CAAC,KAAK,GAAG,mBAAmB,CAAC;QACvC,CAAC;aAAM,IAAI,OAAO,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;YAC/C,QAAQ,CAAC,KAAK,GAAG,WAAW,CAAC;QAC/B,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,SAAiB,EACjB,GAAW;IAEX,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACxC,IAAI,CAAC,OAAO;QAAE,OAAO;IAErB,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5C,IAAI,QAAQ,EAAE,CAAC;QACb,QAAQ,CAAC,KAAK,GAAG,iBAAiB,CAAC;QACnC,QAAQ,CAAC,cAAc,GAAG,IAAI,CAAC;IACjC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE;YACzB,KAAK,EAAE,iBAAiB;YACxB,eAAe,EAAE,OAAO,CAAC,SAAS;YAClC,cAAc,EAAE,OAAO,CAAC,SAAS;YACjC,SAAS,EAAE,IAAI;YACf,eAAe,EAAE,KAAK;YACtB,UAAU,EAAE,CAAC;YACb,cAAc,EAAE,IAAI;SACrB,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,SAAiB;IAC5C,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACxC,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,WAAW,SAAS,YAAY,CAAC,CAAC;IAChE,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;IACtB,OAAO,CAAC,OAAO,GAAG,EAAE,CAAC;IACrB,OAAO,CAAC,SAAS,GAAG,IAAI,GAAG,EAAE,CAAC;IAC9B,OAAO,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,SAAiB;IAC7C,OAAO,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,OAAO,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,MAAM,QAAQ,GAAG;QACf,MAAM;QACN,KAAK;QACL,MAAM;QACN,OAAO;QACP,QAAQ;QACR,OAAO;QACP,eAAe;QACf,OAAO;QACP,SAAS;QACT,QAAQ;KACT,CAAC;IACF,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IACrC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { AuditReport } from "../core/report-generator.js";
2
+ import type { ResilienceScore } from "../benchmark/score.js";
3
+ export interface HardeningPatch {
4
+ category: string;
5
+ severity: "critical" | "warning" | "info";
6
+ trigger: string;
7
+ promptSnippet: string;
8
+ toolGuidance: string;
9
+ }
10
+ export declare function generatePatches(reports: AuditReport[], score: ResilienceScore): HardeningPatch[];
11
+ export declare function formatPatchReport(patches: HardeningPatch[]): string;
12
+ //# sourceMappingURL=patch-generator.d.ts.map