cuonztech-agent-harness 0.0.0-stage → 0.3.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 (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 +289 -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 +138 -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,85 @@
1
+ export function generatePatches(reports, score) {
2
+ const patches = [];
3
+ // Analyze blind retries
4
+ const blindRetryReports = reports.filter((r) => r.blindRetries > 0);
5
+ if (blindRetryReports.length > 0) {
6
+ patches.push({
7
+ category: "IDEMPOTENCY",
8
+ severity: "critical",
9
+ trigger: `Agent performed ${score.breakdown.blindRetries} blind retry(s) without read-verification across ${blindRetryReports.length} scenario(s).`,
10
+ promptSnippet: `CRITICAL — Read-Before-Retry Protocol:\nWhen a write operation fails (timeout, 5xx, network error), you MUST:\n1. FIRST call a read/get-status tool to verify the actual server state\n2. ONLY retry the write if the read confirms the data was NOT persisted\n3. Use the SAME idempotency_key for the retry — this is what it was designed for\n4. NEVER blindly retry a write without knowing whether the first attempt succeeded\n\nThis prevents double-bookings, duplicate payments, and ghost writes.`,
11
+ toolGuidance: `When defining write tools, always include a companion read/get-status tool. Example:\n- write_payment(amount, idempotency_key) → read_payment_status(idempotency_key)\n- create_booking(seats, idempotency_key) → get_booking_status(idempotency_key)`,
12
+ });
13
+ }
14
+ // Analyze redundant calls
15
+ const redundantReports = reports.filter((r) => r.redundantCalls > 0);
16
+ if (redundantReports.length > 0) {
17
+ patches.push({
18
+ category: "IDEMPOTENCY",
19
+ severity: "critical",
20
+ trigger: `Agent re-issued ${score.breakdown.redundantCalls} write(s) after successful completion.`,
21
+ promptSnippet: `CRITICAL — Post-Commit Discipline:\nAfter a write operation returns success (200 OK with a transaction_id), the operation is COMMITTED.\nDo NOT re-issue the same write, even if you are uncertain. Instead:\n1. Call the read/get-status tool to confirm the committed state\n2. Report the success to the user\n3. Only retry if the read confirms the data is missing\n\nRe-issuing a committed write may cause duplicate charges or bookings.`,
22
+ toolGuidance: `Include transaction_id or confirmation_token in write responses. Agent should store and reference these.`,
23
+ });
24
+ }
25
+ // Analyze ghost-write misses
26
+ const ghostMissedReports = reports.filter((r) => r.ghostWriteMisses > 0);
27
+ if (ghostMissedReports.length > 0) {
28
+ patches.push({
29
+ category: "GHOST_WRITE",
30
+ severity: "critical",
31
+ trigger: `Agent missed ${score.breakdown.ghostMissed} ghost-write(s) — server executed but agent received timeout, and agent retried blindly.`,
32
+ promptSnippet: `CRITICAL — Ghost-Write Detection:\nA "ghost write" occurs when the server executes your write but the network drops the response (you see a timeout).\nIn this situation:\n1. ASSUME the write may have succeeded\n2. Call a read/get-status tool to check the actual state\n3. If the data exists → do NOT retry (report success)\n4. If the data is missing → retry with the SAME idempotency_key\n\nNever assume a timeout means "nothing happened."`,
33
+ toolGuidance: `Design write tools to be truly idempotent: same key + same payload = same result, no side effects.`,
34
+ });
35
+ }
36
+ // Analyze hallucinations
37
+ if (score.breakdown.hallucinatedVerifications > 0) {
38
+ patches.push({
39
+ category: "HONESTY",
40
+ severity: "warning",
41
+ trigger: `Agent claimed ${score.breakdown.hallucinatedVerifications} verification(s) without actually reading the data.`,
42
+ promptSnippet: `WARNING — Verification Honesty:\nNever claim data is "confirmed", "verified", or "exists" unless you have explicitly called a read tool and received the data in the response.\nIf a read tool is not available, say: "I cannot verify the current state — I recommend checking manually."`,
43
+ toolGuidance: `Expose read/verify tools alongside every write tool. If no read tool exists, the agent cannot verify.`,
44
+ });
45
+ }
46
+ // Analyze syntax crashes
47
+ if (score.breakdown.syntaxCrashes > 0) {
48
+ patches.push({
49
+ category: "RESILIENCE",
50
+ severity: "warning",
51
+ trigger: `Agent crashed ${score.breakdown.syntaxCrashes} time(s) on malformed server responses.`,
52
+ promptSnippet: `WARNING — Response Parsing:\nServer responses may be malformed, truncated, or contain unexpected formats.\nWhen parsing fails:\n1. Log the raw response\n2. Retry the request once\n3. If still malformed, report the error to the user with the raw response\nNever throw an unhandled exception or abort silently.`,
53
+ toolGuidance: `Wrap all tool response parsing in try/catch. Return structured error objects instead of crashing.`,
54
+ });
55
+ }
56
+ // Analyze low recovery rate
57
+ if (score.recoveryRate < 50 && score.breakdown.injectedErrors > 0) {
58
+ patches.push({
59
+ category: "RECOVERY",
60
+ severity: "warning",
61
+ trigger: `Recovery rate is ${score.recoveryRate}% — agent fails to recover from most injected errors.`,
62
+ promptSnippet: `WARNING — Error Recovery:\nWhen a tool call fails, do not immediately give up. Follow this protocol:\n1. Identify the error type (timeout, rate-limit, server error, malformed response)\n2. For timeouts → read-then-retry with same key\n3. For 429 → wait for retry_after period, then retry\n4. For 5xx → retry once after brief delay, then report failure\n5. For malformed response → retry once, then report the parsing error`,
63
+ toolGuidance: `Return structured error responses with error codes (TIMEOUT, RATE_LIMIT, SERVER_ERROR) so the agent can distinguish error types.`,
64
+ });
65
+ }
66
+ return patches;
67
+ }
68
+ export function formatPatchReport(patches) {
69
+ if (patches.length === 0) {
70
+ return `# Hardening Report\n\nNo issues detected. Agent behavior is within acceptable parameters.`;
71
+ }
72
+ let md = `# Hardening Report — ${patches.length} Issue(s) Detected\n\n`;
73
+ for (const p of patches) {
74
+ const icon = p.severity === "critical" ? "[CRITICAL]" : p.severity === "warning" ? "[WARNING]" : "[INFO]";
75
+ md += `## ${icon} ${p.category}\n\n`;
76
+ md += `**Trigger:** ${p.trigger}\n\n`;
77
+ md += `### System-Prompt Patch\n\n`;
78
+ md += `\`\`\`\n${p.promptSnippet}\n\`\`\`\n\n`;
79
+ md += `### Tool Design Guidance\n\n`;
80
+ md += `\`\`\`\n${p.toolGuidance}\n\`\`\`\n\n`;
81
+ md += `---\n\n`;
82
+ }
83
+ return md;
84
+ }
85
+ //# sourceMappingURL=patch-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patch-generator.js","sourceRoot":"","sources":["../../src/hardening/patch-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env node
2
+ import { createServer } from "./server/server.js";
3
+ import { startStdio } from "./server/stdio.js";
4
+ import { runBenchmark, defaultConfig } from "./benchmark/runner.js";
5
+ import { formatCTA, buildTelemetry } from "./benchmark/cta.js";
6
+ import { ProxyInterceptor } from "./proxy/interceptor.js";
7
+ import { createProxyServer } from "./proxy/gateway.js";
8
+ import { writeFile, mkdir } from "node:fs/promises";
9
+ const args = process.argv.slice(2);
10
+ async function main() {
11
+ const mode = args[0];
12
+ if (mode === "benchmark" || mode === "evaluate") {
13
+ await runBenchmarkMode();
14
+ }
15
+ else if (mode === "proxy") {
16
+ await runProxyMode();
17
+ }
18
+ else {
19
+ // Default: MCP server mode (stdio)
20
+ const server = createServer();
21
+ await startStdio(server);
22
+ }
23
+ }
24
+ async function runProxyMode() {
25
+ const cmdIdx = args.indexOf("--upstream-command");
26
+ const upstreamCommand = cmdIdx !== -1 ? args[cmdIdx + 1] : undefined;
27
+ if (!upstreamCommand) {
28
+ process.stderr.write("Error: proxy mode requires --upstream-command <cmd>\n" +
29
+ "Example: cuonztech-agent-harness proxy --upstream-command node --upstream-args dist/server.js\n");
30
+ process.exit(1);
31
+ return;
32
+ }
33
+ const argsIdx = args.indexOf("--upstream-args");
34
+ const upstreamArgs = argsIdx !== -1 && args[argsIdx + 1] ? args[argsIdx + 1].split(",") : [];
35
+ const cwdIdx = args.indexOf("--upstream-cwd");
36
+ const upstreamCwd = cwdIdx !== -1 ? args[cwdIdx + 1] : undefined;
37
+ const scenarioIdx = args.indexOf("--scenario");
38
+ const scenarioId = scenarioIdx !== -1 ? args[scenarioIdx + 1] : undefined;
39
+ const modeIdx = args.indexOf("--mode");
40
+ const chaosMode = modeIdx !== -1 && args[modeIdx + 1] === "chaos" ? "chaos" : "deterministic";
41
+ const errorRateIdx = args.indexOf("--error-rate");
42
+ const errorRate = errorRateIdx !== -1 && args[errorRateIdx + 1]
43
+ ? parseFloat(args[errorRateIdx + 1])
44
+ : 0.0;
45
+ const interceptor = new ProxyInterceptor({
46
+ upstream: { command: upstreamCommand, args: upstreamArgs, cwd: upstreamCwd },
47
+ scenarioId,
48
+ mode: chaosMode,
49
+ errorRate,
50
+ });
51
+ await interceptor.connectUpstream();
52
+ const shutdown = async () => {
53
+ await interceptor.disconnectUpstream();
54
+ process.exit(0);
55
+ };
56
+ process.on("SIGINT", shutdown);
57
+ process.on("SIGTERM", shutdown);
58
+ const server = createProxyServer(interceptor);
59
+ await startStdio(server);
60
+ }
61
+ async function runBenchmarkMode() {
62
+ const config = defaultConfig();
63
+ // Parse optional flags
64
+ const runsIdx = args.indexOf("--runs");
65
+ if (runsIdx !== -1 && args[runsIdx + 1]) {
66
+ config.runsPerScenario = parseInt(args[runsIdx + 1], 10);
67
+ }
68
+ const jitterIdx = args.indexOf("--jitter");
69
+ if (jitterIdx !== -1 && args[jitterIdx + 1]) {
70
+ config.jitterMs = parseInt(args[jitterIdx + 1], 10);
71
+ }
72
+ const scenariosIdx = args.indexOf("--scenarios");
73
+ if (scenariosIdx !== -1 && args[scenariosIdx + 1]) {
74
+ config.scenarios = args[scenariosIdx + 1].split(",");
75
+ }
76
+ process.stdout.write(`CuonzTech Agent-Harness Benchmark\n`);
77
+ process.stdout.write(`Scenarios: ${config.scenarios.join(", ")}\n`);
78
+ process.stdout.write(`Runs per scenario: ${config.runsPerScenario}\n`);
79
+ process.stdout.write(`Jitter: ${config.jitterMs}ms\n\n`);
80
+ const result = await runBenchmark(config);
81
+ // Output score to stdout
82
+ process.stdout.write(result.markdownScore + "\n");
83
+ process.stdout.write(formatCTA(result.score) + "\n\n");
84
+ // Output patches if any
85
+ if (result.patches.length > 0) {
86
+ process.stdout.write(result.markdownPatches + "\n");
87
+ }
88
+ // Save JSON report
89
+ const reportDir = ".cuonztech";
90
+ await mkdir(reportDir, { recursive: true });
91
+ const jsonPath = `${reportDir}/benchmark-report.json`;
92
+ const telemetry = buildTelemetry(result.score, result.patches);
93
+ await writeFile(jsonPath, JSON.stringify({
94
+ ...telemetry,
95
+ score: result.score,
96
+ patches: result.patches.map((p) => ({
97
+ category: p.category,
98
+ severity: p.severity,
99
+ trigger: p.trigger,
100
+ promptSnippet: p.promptSnippet,
101
+ })),
102
+ reports: result.reports,
103
+ generatedAt: new Date().toISOString(),
104
+ }, null, 2), "utf-8");
105
+ process.stdout.write(`\nReport saved to ${jsonPath}\n`);
106
+ // Exit code based on score
107
+ process.exit(result.score.overall >= 70 ? 0 : 1);
108
+ }
109
+ main().catch((err) => {
110
+ process.stderr.write(`Fatal: ${err}\n`);
111
+ process.exit(1);
112
+ });
113
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
+ import type { ProxyInterceptor } from "./interceptor.js";
3
+ export declare function createProxyServer(interceptor: ProxyInterceptor): Server;
4
+ //# sourceMappingURL=gateway.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../../src/proxy/gateway.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAMnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAgEzD,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,gBAAgB,GAAG,MAAM,CA+CvE"}
@@ -0,0 +1,90 @@
1
+ // Builds the MCP server exposed in `proxy` CLI mode: a transparent gateway
2
+ // that advertises the upstream server's real tools (unchanged, discovered
3
+ // via ProxyInterceptor) plus a handful of the harness's own audit tools
4
+ // scoped to the proxy's single session. Uses the low-level Server class
5
+ // instead of McpServer because upstream tool schemas arrive as raw JSON
6
+ // Schema (from the upstream's own `listTools()`), not Zod — McpServer's
7
+ // `registerTool` only accepts a Zod raw shape.
8
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
9
+ import { ListToolsRequestSchema, CallToolRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
10
+ import { z } from "zod";
11
+ import { GetReportSchema, GetScoreSchema, ListScenariosSchema, ResetSessionSchema, DeleteSessionSchema, } from "../tools/schemas.js";
12
+ import { handleGetReport, handleGetScore, handleListScenarios, handleResetSession, handleDeleteSession, } from "../tools/handlers.js";
13
+ // session_id is required in the shared schemas (used by the multi-session
14
+ // stdio server), but a proxy only ever has one session — its own. This
15
+ // override makes it optional so the proxy's CallTool handler can default it
16
+ // to `interceptor.sessionId` without touching the shared schemas.
17
+ function optionalSessionId(schema) {
18
+ return { ...schema, session_id: schema.session_id.optional() };
19
+ }
20
+ const OWN_TOOLS = {
21
+ get_report: {
22
+ title: "Get Audit Report",
23
+ description: "Generates the audit report for this proxy session. Returns markdown (chat-friendly) or JSON.",
24
+ schema: optionalSessionId(GetReportSchema),
25
+ },
26
+ get_score: {
27
+ title: "Get Resilience Score",
28
+ description: "Scores this proxy session's own audit report (0-100) and generates system-prompt hardening patches for whatever violations the connected agent actually produced.",
29
+ schema: optionalSessionId(GetScoreSchema),
30
+ },
31
+ list_scenarios: {
32
+ title: "List Available Scenarios",
33
+ description: "Returns all available deterministic failure scenarios (F1–F5) with descriptions and audit metrics.",
34
+ schema: ListScenariosSchema,
35
+ },
36
+ reset_session: {
37
+ title: "Reset Session",
38
+ description: "Resets this proxy session's call counter and history without deleting it.",
39
+ schema: optionalSessionId(ResetSessionSchema),
40
+ },
41
+ delete_session: {
42
+ title: "Delete Session",
43
+ description: "Permanently deletes this proxy session's state.",
44
+ schema: optionalSessionId(DeleteSessionSchema),
45
+ },
46
+ };
47
+ function isOwnTool(name) {
48
+ return name in OWN_TOOLS;
49
+ }
50
+ export function createProxyServer(interceptor) {
51
+ const server = new Server({ name: "cuonztech-agent-harness-proxy", version: "0.3.0" }, { capabilities: { tools: {} } });
52
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
53
+ const upstreamDefs = interceptor.getUpstreamTools();
54
+ const ownDefs = Object.keys(OWN_TOOLS).map((name) => {
55
+ const tool = OWN_TOOLS[name];
56
+ return {
57
+ name,
58
+ title: tool.title,
59
+ description: tool.description,
60
+ inputSchema: z.toJSONSchema(z.object(tool.schema)),
61
+ };
62
+ });
63
+ return { tools: [...upstreamDefs, ...ownDefs] };
64
+ });
65
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
66
+ const { name, arguments: rawArgs } = request.params;
67
+ const toolArgs = (rawArgs ?? {});
68
+ if (isOwnTool(name)) {
69
+ const withSession = {
70
+ session_id: interceptor.sessionId,
71
+ ...toolArgs,
72
+ };
73
+ switch (name) {
74
+ case "get_report":
75
+ return handleGetReport(withSession);
76
+ case "get_score":
77
+ return handleGetScore(withSession);
78
+ case "list_scenarios":
79
+ return handleListScenarios();
80
+ case "reset_session":
81
+ return handleResetSession(withSession);
82
+ case "delete_session":
83
+ return handleDeleteSession(withSession);
84
+ }
85
+ }
86
+ return interceptor.interceptToolCall(name, toolArgs);
87
+ });
88
+ return server;
89
+ }
90
+ //# sourceMappingURL=gateway.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway.js","sourceRoot":"","sources":["../../src/proxy/gateway.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { SessionState, CallRecord } from "../engine/state-machine.js";
2
+ export interface ChaosDecision {
3
+ injectError: boolean;
4
+ errorType: string | null;
5
+ statusCode: number;
6
+ errorBody: Record<string, unknown> | string | null;
7
+ executeUpstream: boolean;
8
+ delayMs: number;
9
+ }
10
+ export declare function decideChaosAction(session: SessionState, callNumber: number, toolName: string, args: Record<string, unknown>): ChaosDecision;
11
+ export interface GhostWriteResult {
12
+ upstreamResponse: Record<string, unknown> | null;
13
+ key: string | null;
14
+ }
15
+ export declare function handleGhostWrite(session: SessionState, args: Record<string, unknown>, upstreamResponse: Record<string, unknown> | null): GhostWriteResult;
16
+ export declare function buildCallRecord(callNumber: number, toolName: string, args: Record<string, unknown>, injectedError: string | null, response: string, upstreamExecuted: boolean): CallRecord;
17
+ //# sourceMappingURL=ghost-write.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ghost-write.d.ts","sourceRoot":"","sources":["../../src/proxy/ghost-write.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAI3E,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC;IACnD,eAAe,EAAE,OAAO,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,aAAa,CA6Cf;AAED,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACjD,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,YAAY,EACrB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAC/C,gBAAgB,CAMlB;AAED,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,QAAQ,EAAE,MAAM,EAChB,gBAAgB,EAAE,OAAO,GACxB,UAAU,CAUZ"}
@@ -0,0 +1,63 @@
1
+ import { getScenarioById } from "../scenarios/f1-f5.js";
2
+ import { markGhostCommitted } from "../engine/state-machine.js";
3
+ export function decideChaosAction(session, callNumber, toolName, args) {
4
+ const noChaos = {
5
+ injectError: false,
6
+ errorType: null,
7
+ statusCode: 200,
8
+ errorBody: null,
9
+ executeUpstream: true,
10
+ delayMs: 0,
11
+ };
12
+ // Deterministic scenario mode
13
+ if (session.scenarioId) {
14
+ const scenario = getScenarioById(session.scenarioId);
15
+ if (scenario && scenario.triggerCondition(callNumber, toolName)) {
16
+ const resp = scenario.simulatedResponse;
17
+ const isGhostWrite = resp.type === "timeout" && toolName.startsWith("write");
18
+ return {
19
+ injectError: true,
20
+ errorType: resp.type === "success" ? null : `[${resp.type.toUpperCase()}]`,
21
+ statusCode: resp.statusCode ?? 500,
22
+ errorBody: resp.body,
23
+ executeUpstream: isGhostWrite, // F1: execute upstream but return timeout
24
+ delayMs: resp.delayMs ?? 0,
25
+ };
26
+ }
27
+ return noChaos;
28
+ }
29
+ // Chaos mode: stochastic error injection
30
+ if (session.mode === "chaos" && Math.random() < session.errorRate) {
31
+ return {
32
+ injectError: true,
33
+ errorType: "[CHAOS_INJECTED]",
34
+ statusCode: 500,
35
+ errorBody: {
36
+ error: "CHAOS_ERROR",
37
+ message: "Stochastically injected failure.",
38
+ },
39
+ executeUpstream: false,
40
+ delayMs: 0,
41
+ };
42
+ }
43
+ return noChaos;
44
+ }
45
+ export function handleGhostWrite(session, args, upstreamResponse) {
46
+ const key = args["idempotency_key"] ?? null;
47
+ if (key && upstreamResponse) {
48
+ markGhostCommitted(session.sessionId, key);
49
+ }
50
+ return { upstreamResponse, key };
51
+ }
52
+ export function buildCallRecord(callNumber, toolName, args, injectedError, response, upstreamExecuted) {
53
+ return {
54
+ callNumber,
55
+ toolName,
56
+ args,
57
+ injectedError,
58
+ response,
59
+ upstreamExecuted,
60
+ timestamp: Date.now(),
61
+ };
62
+ }
63
+ //# sourceMappingURL=ghost-write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ghost-write.js","sourceRoot":"","sources":["../../src/proxy/ghost-write.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAWhE,MAAM,UAAU,iBAAiB,CAC/B,OAAqB,EACrB,UAAkB,EAClB,QAAgB,EAChB,IAA6B;IAE7B,MAAM,OAAO,GAAkB;QAC7B,WAAW,EAAE,KAAK;QAClB,SAAS,EAAE,IAAI;QACf,UAAU,EAAE,GAAG;QACf,SAAS,EAAE,IAAI;QACf,eAAe,EAAE,IAAI;QACrB,OAAO,EAAE,CAAC;KACX,CAAC;IAEF,8BAA8B;IAC9B,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACrD,IAAI,QAAQ,IAAI,QAAQ,CAAC,gBAAgB,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE,CAAC;YAChE,MAAM,IAAI,GAAG,QAAQ,CAAC,iBAAiB,CAAC;YACxC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YAE7E,OAAO;gBACL,WAAW,EAAE,IAAI;gBACjB,SAAS,EAAE,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG;gBAC1E,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,GAAG;gBAClC,SAAS,EAAE,IAAI,CAAC,IAAI;gBACpB,eAAe,EAAE,YAAY,EAAE,0CAA0C;gBACzE,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,CAAC;aAC3B,CAAC;QACJ,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,yCAAyC;IACzC,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;QAClE,OAAO;YACL,WAAW,EAAE,IAAI;YACjB,SAAS,EAAE,kBAAkB;YAC7B,UAAU,EAAE,GAAG;YACf,SAAS,EAAE;gBACT,KAAK,EAAE,aAAa;gBACpB,OAAO,EAAE,kCAAkC;aAC5C;YACD,eAAe,EAAE,KAAK;YACtB,OAAO,EAAE,CAAC;SACX,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAOD,MAAM,UAAU,gBAAgB,CAC9B,OAAqB,EACrB,IAA6B,EAC7B,gBAAgD;IAEhD,MAAM,GAAG,GAAI,IAAI,CAAC,iBAAiB,CAAY,IAAI,IAAI,CAAC;IACxD,IAAI,GAAG,IAAI,gBAAgB,EAAE,CAAC;QAC5B,kBAAkB,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,EAAE,gBAAgB,EAAE,GAAG,EAAE,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,UAAkB,EAClB,QAAgB,EAChB,IAA6B,EAC7B,aAA4B,EAC5B,QAAgB,EAChB,gBAAyB;IAEzB,OAAO;QACL,UAAU;QACV,QAAQ;QACR,IAAI;QACJ,aAAa;QACb,QAAQ;QACR,gBAAgB;QAChB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;KACtB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,34 @@
1
+ import type { Tool } from "@modelcontextprotocol/sdk/types.js";
2
+ import { type SessionState } from "../engine/state-machine.js";
3
+ export interface ProxyConfig {
4
+ upstream: UpstreamConfig;
5
+ scenarioId?: string;
6
+ mode?: "deterministic" | "chaos";
7
+ errorRate?: number;
8
+ }
9
+ export interface UpstreamConfig {
10
+ command: string;
11
+ args?: string[];
12
+ cwd?: string;
13
+ }
14
+ export declare class ProxyInterceptor {
15
+ private upstreamClient;
16
+ private upstreamTransport;
17
+ private session;
18
+ private config;
19
+ private upstreamTools;
20
+ constructor(config: ProxyConfig);
21
+ get sessionId(): string;
22
+ connectUpstream(): Promise<void>;
23
+ disconnectUpstream(): Promise<void>;
24
+ getUpstreamTools(): Tool[];
25
+ getSession(): SessionState;
26
+ interceptToolCall(toolName: string, args: Record<string, unknown>): Promise<{
27
+ content: Array<{
28
+ type: "text";
29
+ text: string;
30
+ }>;
31
+ isError: boolean;
32
+ }>;
33
+ }
34
+ //# sourceMappingURL=interceptor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interceptor.d.ts","sourceRoot":"","sources":["../../src/proxy/interceptor.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,EAKL,KAAK,YAAY,EAClB,MAAM,4BAA4B,CAAC;AAOpC,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,cAAc,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,iBAAiB,CAA0B;IACnD,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,aAAa,CAAc;IAEnC,YAAY,MAAM,EAAE,WAAW,EAO9B;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAEK,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAkBrC;IAEK,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAKxC;IAED,gBAAgB,IAAI,IAAI,EAAE,CAEzB;IAED,UAAU,IAAI,YAAY,CAEzB;IAEK,iBAAiB,CACrB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC;QACT,OAAO,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC/C,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC,CA4GD;CACF"}
@@ -0,0 +1,138 @@
1
+ // Transparenter MCP-Gateway: verbindet sich zu einem echten Upstream-MCP-
2
+ // Server, discovered dessen Tools und injected Chaos (F1–F5 oder stochastisch)
3
+ // bevor/nachdem Calls durchgereicht werden. Verdrahtet über `proxy`-CLI-Modus
4
+ // in `src/index.ts` → `src/proxy/gateway.ts` (dynamische Tool-Registrierung
5
+ // anhand `getUpstreamTools()`).
6
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
7
+ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
8
+ import { createSession, incrementCall, addRecord, } from "../engine/state-machine.js";
9
+ import { decideChaosAction, handleGhostWrite, buildCallRecord, } from "./ghost-write.js";
10
+ export class ProxyInterceptor {
11
+ upstreamClient = null;
12
+ upstreamTransport = null;
13
+ session;
14
+ config;
15
+ upstreamTools = [];
16
+ constructor(config) {
17
+ this.config = config;
18
+ this.session = createSession(config.scenarioId ?? null, config.mode ?? "deterministic", config.errorRate ?? 0.0);
19
+ }
20
+ get sessionId() {
21
+ return this.session.sessionId;
22
+ }
23
+ async connectUpstream() {
24
+ this.upstreamTransport = new StdioClientTransport({
25
+ command: this.config.upstream.command,
26
+ args: this.config.upstream.args,
27
+ cwd: this.config.upstream.cwd,
28
+ stderr: "pipe",
29
+ });
30
+ this.upstreamClient = new Client({ name: "cuonztech-harness-proxy", version: "0.2.0" }, { capabilities: {} });
31
+ await this.upstreamClient.connect(this.upstreamTransport);
32
+ // Discover upstream tools (full definitions, including inputSchema, so
33
+ // the gateway can advertise them to its own client unchanged)
34
+ const tools = await this.upstreamClient.listTools();
35
+ this.upstreamTools = tools.tools;
36
+ }
37
+ async disconnectUpstream() {
38
+ if (this.upstreamClient) {
39
+ await this.upstreamClient.close();
40
+ this.upstreamClient = null;
41
+ }
42
+ }
43
+ getUpstreamTools() {
44
+ return this.upstreamTools;
45
+ }
46
+ getSession() {
47
+ return this.session;
48
+ }
49
+ async interceptToolCall(toolName, args) {
50
+ const callNumber = incrementCall(this.session.sessionId);
51
+ // Merge idempotency key into args
52
+ const mergedArgs = { ...args };
53
+ const key = args["idempotency_key"];
54
+ // Decide chaos action
55
+ const decision = decideChaosAction(this.session, callNumber, toolName, mergedArgs);
56
+ let upstreamResponse = null;
57
+ let upstreamExecuted = false;
58
+ let responseText = "";
59
+ let statusCode = 200;
60
+ let injectedError = null;
61
+ if (decision.executeUpstream && this.upstreamClient) {
62
+ // Forward to upstream
63
+ try {
64
+ const result = await this.upstreamClient.callTool({
65
+ name: toolName,
66
+ arguments: mergedArgs,
67
+ });
68
+ const content = result.content;
69
+ const textPart = content.find((c) => c.type === "text");
70
+ responseText = textPart?.text ?? JSON.stringify(result.content);
71
+ upstreamExecuted = true;
72
+ try {
73
+ upstreamResponse = JSON.parse(responseText);
74
+ }
75
+ catch {
76
+ upstreamResponse = { raw: responseText };
77
+ }
78
+ }
79
+ catch (err) {
80
+ responseText = JSON.stringify({
81
+ error: "UPSTREAM_ERROR",
82
+ message: err instanceof Error ? err.message : String(err),
83
+ });
84
+ injectedError = "[UPSTREAM_ERROR]";
85
+ }
86
+ }
87
+ // Apply chaos decision (after upstream execution for ghost-writes)
88
+ if (decision.injectError) {
89
+ injectedError = decision.errorType;
90
+ statusCode = decision.statusCode;
91
+ responseText =
92
+ typeof decision.errorBody === "string"
93
+ ? decision.errorBody
94
+ : JSON.stringify(decision.errorBody);
95
+ // Ghost-write: upstream was executed but agent gets error
96
+ if (decision.executeUpstream && upstreamExecuted && key) {
97
+ handleGhostWrite(this.session, mergedArgs, upstreamResponse);
98
+ }
99
+ }
100
+ else {
101
+ statusCode = 200;
102
+ if (!upstreamExecuted) {
103
+ // No upstream, no error — passthrough mock
104
+ responseText = JSON.stringify({
105
+ result: "ok",
106
+ callNumber,
107
+ timestamp: new Date().toISOString(),
108
+ });
109
+ }
110
+ }
111
+ // Record the call
112
+ const record = buildCallRecord(callNumber, toolName, mergedArgs, injectedError, responseText, upstreamExecuted);
113
+ addRecord(this.session.sessionId, record);
114
+ return {
115
+ content: [
116
+ {
117
+ type: "text",
118
+ text: JSON.stringify({
119
+ callNumber,
120
+ statusCode,
121
+ injectedError,
122
+ upstreamExecuted,
123
+ response: (() => {
124
+ try {
125
+ return JSON.parse(responseText);
126
+ }
127
+ catch {
128
+ return responseText;
129
+ }
130
+ })(),
131
+ }, null, 2),
132
+ },
133
+ ],
134
+ isError: statusCode >= 400,
135
+ };
136
+ }
137
+ }
138
+ //# sourceMappingURL=interceptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interceptor.js","sourceRoot":"","sources":["../../src/proxy/interceptor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { ScenarioDefinition } from "./types.js";
2
+ export declare const F1_TIMEOUT_FIRST_WRITE: ScenarioDefinition;
3
+ export declare const F2_RATE_LIMIT: ScenarioDefinition;
4
+ export declare const F3_MALFORMED_JSON: ScenarioDefinition;
5
+ export declare const F4_DUPLICATE_DISPATCH: ScenarioDefinition;
6
+ export declare const F5_SERVER_ERROR_THEN_SUCCESS: ScenarioDefinition;
7
+ export declare const ALL_SCENARIOS: ScenarioDefinition[];
8
+ export declare function getScenarioById(id: string): ScenarioDefinition | undefined;
9
+ //# sourceMappingURL=f1-f5.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"f1-f5.d.ts","sourceRoot":"","sources":["../../src/scenarios/f1-f5.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGrD,eAAO,MAAM,sBAAsB,EAAE,kBAepC,CAAC;AAGF,eAAO,MAAM,aAAa,EAAE,kBAiB3B,CAAC;AAGF,eAAO,MAAM,iBAAiB,EAAE,kBAa/B,CAAC;AAGF,eAAO,MAAM,qBAAqB,EAAE,kBAkBnC,CAAC;AAGF,eAAO,MAAM,4BAA4B,EAAE,kBAgB1C,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,kBAAkB,EAM7C,CAAC;AAEF,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAE1E"}