@aisy/core 0.1.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/LICENSE +202 -0
- package/dist/agent-loop/index.d.ts +4 -0
- package/dist/agent-loop/index.d.ts.map +1 -0
- package/dist/agent-loop/index.js +352 -0
- package/dist/agent-loop/index.js.map +1 -0
- package/dist/agent-loop/types.d.ts +183 -0
- package/dist/agent-loop/types.d.ts.map +1 -0
- package/dist/agent-loop/types.js +3 -0
- package/dist/agent-loop/types.js.map +1 -0
- package/dist/bin/aisy.d.ts +3 -0
- package/dist/bin/aisy.d.ts.map +1 -0
- package/dist/bin/aisy.js +14 -0
- package/dist/bin/aisy.js.map +1 -0
- package/dist/cli/index.d.ts +17 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +114 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/context-engine/index.d.ts +4 -0
- package/dist/context-engine/index.d.ts.map +1 -0
- package/dist/context-engine/index.js +126 -0
- package/dist/context-engine/index.js.map +1 -0
- package/dist/context-engine/types.d.ts +54 -0
- package/dist/context-engine/types.d.ts.map +1 -0
- package/dist/context-engine/types.js +4 -0
- package/dist/context-engine/types.js.map +1 -0
- package/dist/eval/index.d.ts +20 -0
- package/dist/eval/index.d.ts.map +1 -0
- package/dist/eval/index.js +128 -0
- package/dist/eval/index.js.map +1 -0
- package/dist/eval/types.d.ts +62 -0
- package/dist/eval/types.d.ts.map +1 -0
- package/dist/eval/types.js +17 -0
- package/dist/eval/types.js.map +1 -0
- package/dist/gateway/index.d.ts +5 -0
- package/dist/gateway/index.d.ts.map +1 -0
- package/dist/gateway/index.js +288 -0
- package/dist/gateway/index.js.map +1 -0
- package/dist/gateway/types.d.ts +194 -0
- package/dist/gateway/types.d.ts.map +1 -0
- package/dist/gateway/types.js +94 -0
- package/dist/gateway/types.js.map +1 -0
- package/dist/goals/index.d.ts +11 -0
- package/dist/goals/index.d.ts.map +1 -0
- package/dist/goals/index.js +21 -0
- package/dist/goals/index.js.map +1 -0
- package/dist/goals/types.d.ts +47 -0
- package/dist/goals/types.d.ts.map +1 -0
- package/dist/goals/types.js +5 -0
- package/dist/goals/types.js.map +1 -0
- package/dist/index.d.ts +56 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +50 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/index.d.ts +5 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +215 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/types.d.ts +148 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +4 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/memory/index.d.ts +6 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +419 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/types.d.ts +131 -0
- package/dist/memory/types.d.ts.map +1 -0
- package/dist/memory/types.js +33 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/nightly/index.d.ts +4 -0
- package/dist/nightly/index.d.ts.map +1 -0
- package/dist/nightly/index.js +470 -0
- package/dist/nightly/index.js.map +1 -0
- package/dist/nightly/types.d.ts +326 -0
- package/dist/nightly/types.d.ts.map +1 -0
- package/dist/nightly/types.js +3 -0
- package/dist/nightly/types.js.map +1 -0
- package/dist/observability/index.d.ts +11 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +396 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/types.d.ts +139 -0
- package/dist/observability/types.d.ts.map +1 -0
- package/dist/observability/types.js +4 -0
- package/dist/observability/types.js.map +1 -0
- package/dist/onboarding/index.d.ts +16 -0
- package/dist/onboarding/index.d.ts.map +1 -0
- package/dist/onboarding/index.js +787 -0
- package/dist/onboarding/index.js.map +1 -0
- package/dist/onboarding/interactive.d.ts +23 -0
- package/dist/onboarding/interactive.d.ts.map +1 -0
- package/dist/onboarding/interactive.js +45 -0
- package/dist/onboarding/interactive.js.map +1 -0
- package/dist/onboarding/types.d.ts +388 -0
- package/dist/onboarding/types.d.ts.map +1 -0
- package/dist/onboarding/types.js +35 -0
- package/dist/onboarding/types.js.map +1 -0
- package/dist/orchestration/index.d.ts +8 -0
- package/dist/orchestration/index.d.ts.map +1 -0
- package/dist/orchestration/index.js +706 -0
- package/dist/orchestration/index.js.map +1 -0
- package/dist/orchestration/types.d.ts +391 -0
- package/dist/orchestration/types.d.ts.map +1 -0
- package/dist/orchestration/types.js +30 -0
- package/dist/orchestration/types.js.map +1 -0
- package/dist/personality/index.d.ts +65 -0
- package/dist/personality/index.d.ts.map +1 -0
- package/dist/personality/index.js +339 -0
- package/dist/personality/index.js.map +1 -0
- package/dist/personality/types.d.ts +103 -0
- package/dist/personality/types.d.ts.map +1 -0
- package/dist/personality/types.js +15 -0
- package/dist/personality/types.js.map +1 -0
- package/dist/provider/index.d.ts +4 -0
- package/dist/provider/index.d.ts.map +1 -0
- package/dist/provider/index.js +236 -0
- package/dist/provider/index.js.map +1 -0
- package/dist/provider/types.d.ts +180 -0
- package/dist/provider/types.d.ts.map +1 -0
- package/dist/provider/types.js +4 -0
- package/dist/provider/types.js.map +1 -0
- package/dist/runtime/agent-cards.d.ts +14 -0
- package/dist/runtime/agent-cards.d.ts.map +1 -0
- package/dist/runtime/agent-cards.js +90 -0
- package/dist/runtime/agent-cards.js.map +1 -0
- package/dist/runtime/agent-runner.d.ts +30 -0
- package/dist/runtime/agent-runner.d.ts.map +1 -0
- package/dist/runtime/agent-runner.js +37 -0
- package/dist/runtime/agent-runner.js.map +1 -0
- package/dist/runtime/budget.d.ts +15 -0
- package/dist/runtime/budget.d.ts.map +1 -0
- package/dist/runtime/budget.js +24 -0
- package/dist/runtime/budget.js.map +1 -0
- package/dist/runtime/delegation-driver.d.ts +11 -0
- package/dist/runtime/delegation-driver.d.ts.map +1 -0
- package/dist/runtime/delegation-driver.js +132 -0
- package/dist/runtime/delegation-driver.js.map +1 -0
- package/dist/runtime/exact-cache.d.ts +10 -0
- package/dist/runtime/exact-cache.d.ts.map +1 -0
- package/dist/runtime/exact-cache.js +30 -0
- package/dist/runtime/exact-cache.js.map +1 -0
- package/dist/runtime/execute-tool.d.ts +29 -0
- package/dist/runtime/execute-tool.d.ts.map +1 -0
- package/dist/runtime/execute-tool.js +80 -0
- package/dist/runtime/execute-tool.js.map +1 -0
- package/dist/runtime/guardian.d.ts +9 -0
- package/dist/runtime/guardian.d.ts.map +1 -0
- package/dist/runtime/guardian.js +41 -0
- package/dist/runtime/guardian.js.map +1 -0
- package/dist/runtime/hook-gate.d.ts +17 -0
- package/dist/runtime/hook-gate.d.ts.map +1 -0
- package/dist/runtime/hook-gate.js +56 -0
- package/dist/runtime/hook-gate.js.map +1 -0
- package/dist/runtime/memory-adapter.d.ts +6 -0
- package/dist/runtime/memory-adapter.d.ts.map +1 -0
- package/dist/runtime/memory-adapter.js +38 -0
- package/dist/runtime/memory-adapter.js.map +1 -0
- package/dist/runtime/nightly-adapters.d.ts +48 -0
- package/dist/runtime/nightly-adapters.d.ts.map +1 -0
- package/dist/runtime/nightly-adapters.js +139 -0
- package/dist/runtime/nightly-adapters.js.map +1 -0
- package/dist/runtime/nightly-generator.d.ts +10 -0
- package/dist/runtime/nightly-generator.d.ts.map +1 -0
- package/dist/runtime/nightly-generator.js +335 -0
- package/dist/runtime/nightly-generator.js.map +1 -0
- package/dist/runtime/onboarding-node.d.ts +6 -0
- package/dist/runtime/onboarding-node.d.ts.map +1 -0
- package/dist/runtime/onboarding-node.js +356 -0
- package/dist/runtime/onboarding-node.js.map +1 -0
- package/dist/runtime/provider-anthropic.d.ts +43 -0
- package/dist/runtime/provider-anthropic.d.ts.map +1 -0
- package/dist/runtime/provider-anthropic.js +148 -0
- package/dist/runtime/provider-anthropic.js.map +1 -0
- package/dist/runtime/provider-cli.d.ts +18 -0
- package/dist/runtime/provider-cli.d.ts.map +1 -0
- package/dist/runtime/provider-cli.js +73 -0
- package/dist/runtime/provider-cli.js.map +1 -0
- package/dist/runtime/provider-openai.d.ts +30 -0
- package/dist/runtime/provider-openai.d.ts.map +1 -0
- package/dist/runtime/provider-openai.js +114 -0
- package/dist/runtime/provider-openai.js.map +1 -0
- package/dist/runtime/providers.d.ts +43 -0
- package/dist/runtime/providers.d.ts.map +1 -0
- package/dist/runtime/providers.js +72 -0
- package/dist/runtime/providers.js.map +1 -0
- package/dist/runtime/sandbox-bash.d.ts +21 -0
- package/dist/runtime/sandbox-bash.d.ts.map +1 -0
- package/dist/runtime/sandbox-bash.js +51 -0
- package/dist/runtime/sandbox-bash.js.map +1 -0
- package/dist/runtime/scoped-tool-executor.d.ts +10 -0
- package/dist/runtime/scoped-tool-executor.d.ts.map +1 -0
- package/dist/runtime/scoped-tool-executor.js +30 -0
- package/dist/runtime/scoped-tool-executor.js.map +1 -0
- package/dist/runtime/session-log.d.ts +6 -0
- package/dist/runtime/session-log.d.ts.map +1 -0
- package/dist/runtime/session-log.js +54 -0
- package/dist/runtime/session-log.js.map +1 -0
- package/dist/runtime/settings.d.ts +24 -0
- package/dist/runtime/settings.d.ts.map +1 -0
- package/dist/runtime/settings.js +29 -0
- package/dist/runtime/settings.js.map +1 -0
- package/dist/runtime/spawn-plan.d.ts +13 -0
- package/dist/runtime/spawn-plan.d.ts.map +1 -0
- package/dist/runtime/spawn-plan.js +107 -0
- package/dist/runtime/spawn-plan.js.map +1 -0
- package/dist/runtime/spend.d.ts +41 -0
- package/dist/runtime/spend.d.ts.map +1 -0
- package/dist/runtime/spend.js +0 -0
- package/dist/runtime/spend.js.map +1 -0
- package/dist/runtime/sub-agent-runner.d.ts +19 -0
- package/dist/runtime/sub-agent-runner.d.ts.map +1 -0
- package/dist/runtime/sub-agent-runner.js +47 -0
- package/dist/runtime/sub-agent-runner.js.map +1 -0
- package/dist/safety/grants.d.ts +7 -0
- package/dist/safety/grants.d.ts.map +1 -0
- package/dist/safety/grants.js +53 -0
- package/dist/safety/grants.js.map +1 -0
- package/dist/safety/index.d.ts +72 -0
- package/dist/safety/index.d.ts.map +1 -0
- package/dist/safety/index.js +464 -0
- package/dist/safety/index.js.map +1 -0
- package/dist/safety/types.d.ts +254 -0
- package/dist/safety/types.d.ts.map +1 -0
- package/dist/safety/types.js +3 -0
- package/dist/safety/types.js.map +1 -0
- package/dist/skills/index.d.ts +4 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +463 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/types.d.ts +177 -0
- package/dist/skills/types.d.ts.map +1 -0
- package/dist/skills/types.js +3 -0
- package/dist/skills/types.js.map +1 -0
- package/dist/testing/clock.d.ts +8 -0
- package/dist/testing/clock.d.ts.map +1 -0
- package/dist/testing/clock.js +13 -0
- package/dist/testing/clock.js.map +1 -0
- package/dist/testing/effect-verifier.d.ts +15 -0
- package/dist/testing/effect-verifier.d.ts.map +1 -0
- package/dist/testing/effect-verifier.js +27 -0
- package/dist/testing/effect-verifier.js.map +1 -0
- package/dist/testing/index.d.ts +5 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +5 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/provider-fake.d.ts +14 -0
- package/dist/testing/provider-fake.d.ts.map +1 -0
- package/dist/testing/provider-fake.js +18 -0
- package/dist/testing/provider-fake.js.map +1 -0
- package/dist/testing/sandbox-stub.d.ts +15 -0
- package/dist/testing/sandbox-stub.d.ts.map +1 -0
- package/dist/testing/sandbox-stub.js +15 -0
- package/dist/testing/sandbox-stub.js.map +1 -0
- package/dist/tools/index.d.ts +11 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +0 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/types.d.ts +138 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +4 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/triggers/index.d.ts +4 -0
- package/dist/triggers/index.d.ts.map +1 -0
- package/dist/triggers/index.js +187 -0
- package/dist/triggers/index.js.map +1 -0
- package/dist/triggers/types.d.ts +74 -0
- package/dist/triggers/types.d.ts.map +1 -0
- package/dist/triggers/types.js +5 -0
- package/dist/triggers/types.js.map +1 -0
- package/package.json +36 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// Eval & Red-Team Harness — ADR-0037. See ./types.ts and the ADR for rationale.
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// pass^k — ALL k attempts must pass. pass@1 averages over attempts and hides an
|
|
4
|
+
// agent that fails a fixed slice of cases; pass^k drops that case to zero so the
|
|
5
|
+
// slice surfaces. The release gate passes only when every case is all-k-pass.
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
export function passHatK(cases) {
|
|
8
|
+
if (cases.length === 0) {
|
|
9
|
+
return { k: 0, total: 0, passHatK: 1, pass1: 1, allPass: [], consistentlyFailing: [], flaky: [], gate: 'pass' };
|
|
10
|
+
}
|
|
11
|
+
const k = cases[0].outcomes.length;
|
|
12
|
+
for (const c of cases) {
|
|
13
|
+
if (c.outcomes.length === 0) {
|
|
14
|
+
throw new Error(`pass^k case '${c.caseId}' has zero attempts`);
|
|
15
|
+
}
|
|
16
|
+
if (c.outcomes.length !== k) {
|
|
17
|
+
throw new Error(`pass^k requires a uniform attempt count: case '${c.caseId}' has ${c.outcomes.length}, expected ${k}`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const allPass = [];
|
|
21
|
+
const consistentlyFailing = [];
|
|
22
|
+
const flaky = [];
|
|
23
|
+
let attemptPasses = 0;
|
|
24
|
+
let attemptTotal = 0;
|
|
25
|
+
for (const c of cases) {
|
|
26
|
+
const passes = c.outcomes.filter(Boolean).length;
|
|
27
|
+
attemptPasses += passes;
|
|
28
|
+
attemptTotal += c.outcomes.length;
|
|
29
|
+
if (passes === k)
|
|
30
|
+
allPass.push(c.caseId);
|
|
31
|
+
else if (passes === 0)
|
|
32
|
+
consistentlyFailing.push(c.caseId);
|
|
33
|
+
else
|
|
34
|
+
flaky.push(c.caseId);
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
k,
|
|
38
|
+
total: cases.length,
|
|
39
|
+
passHatK: allPass.length / cases.length,
|
|
40
|
+
pass1: attemptPasses / attemptTotal,
|
|
41
|
+
allPass,
|
|
42
|
+
consistentlyFailing,
|
|
43
|
+
flaky,
|
|
44
|
+
gate: allPass.length === cases.length ? 'pass' : 'fail',
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
// Golden-trajectory replay + diff. A trajectory is the comparison-relevant
|
|
49
|
+
// projection of the append-only journal (volatile ts/seq/hashes excluded). Any
|
|
50
|
+
// divergence after a harness change is a regression gate.
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
/** Deterministic JSON over object keys (stable signature input). */
|
|
53
|
+
function stableStringify(value) {
|
|
54
|
+
return JSON.stringify(value, (_k, v) => v !== null && typeof v === 'object' && !Array.isArray(v)
|
|
55
|
+
? Object.fromEntries(Object.keys(v)
|
|
56
|
+
.sort()
|
|
57
|
+
.map(key => [key, v[key]]))
|
|
58
|
+
: v);
|
|
59
|
+
}
|
|
60
|
+
export function stepSignature(step) {
|
|
61
|
+
return stableStringify({ tool: step.tool, verdict: step.verdict ?? null, meta: step.meta ?? null });
|
|
62
|
+
}
|
|
63
|
+
export function diffTrajectory(golden, replayed) {
|
|
64
|
+
const divergences = [];
|
|
65
|
+
const n = Math.max(golden.length, replayed.length);
|
|
66
|
+
for (let i = 0; i < n; i++) {
|
|
67
|
+
const g = golden[i];
|
|
68
|
+
const r = replayed[i];
|
|
69
|
+
if (g === undefined && r !== undefined) {
|
|
70
|
+
divergences.push({ index: i, kind: 'step-added', replayed: r });
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (g !== undefined && r === undefined) {
|
|
74
|
+
divergences.push({ index: i, kind: 'step-removed', golden: g });
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (g === undefined || r === undefined)
|
|
78
|
+
continue;
|
|
79
|
+
if (g.tool !== r.tool) {
|
|
80
|
+
divergences.push({ index: i, kind: 'tool-changed', golden: g, replayed: r });
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if ((g.verdict ?? null) !== (r.verdict ?? null)) {
|
|
84
|
+
divergences.push({ index: i, kind: 'verdict-changed', golden: g, replayed: r });
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (stepSignature(g) !== stepSignature(r)) {
|
|
88
|
+
divergences.push({ index: i, kind: 'signature-changed', golden: g, replayed: r });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return { identical: divergences.length === 0, divergences };
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Replay a golden suite through an injected driver and gate on any divergence.
|
|
95
|
+
* The driver maps a prompt to the trajectory the current harness produces; in a
|
|
96
|
+
* real run it wraps the assembled system (safety/memory/gateway/observability),
|
|
97
|
+
* in a unit test it is a fake — the diff logic is identical either way.
|
|
98
|
+
*/
|
|
99
|
+
export function replaySuite(golden, replay) {
|
|
100
|
+
const regressions = [];
|
|
101
|
+
const clean = [];
|
|
102
|
+
for (const c of golden) {
|
|
103
|
+
const diff = diffTrajectory(c.trajectory, replay(c.prompt));
|
|
104
|
+
if (diff.identical)
|
|
105
|
+
clean.push(c.caseId);
|
|
106
|
+
else
|
|
107
|
+
regressions.push({ caseId: c.caseId, diff });
|
|
108
|
+
}
|
|
109
|
+
return { regressions, clean, gate: regressions.length === 0 ? 'pass' : 'fail' };
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Derive a comparable trajectory from the append-only journal (Observability 12
|
|
113
|
+
* / ADR-0017). Volatile fields (ts/seq/prevHash/hash) never enter the step, so
|
|
114
|
+
* two runs that differ only in timing produce identical trajectories. tool ←
|
|
115
|
+
* payload.tool || entry.kind; verdict ← payload.verdict || (payload.pass ? …).
|
|
116
|
+
*/
|
|
117
|
+
export function trajectoryFromJournal(entries) {
|
|
118
|
+
return entries.map(e => {
|
|
119
|
+
const p = (e.payload ?? {});
|
|
120
|
+
const tool = typeof p['tool'] === 'string' ? p['tool'] : e.kind;
|
|
121
|
+
const step = { tool };
|
|
122
|
+
const rawVerdict = p['verdict'] ?? (typeof p['pass'] === 'boolean' ? (p['pass'] ? 'pass' : 'fail') : undefined);
|
|
123
|
+
if (rawVerdict !== undefined)
|
|
124
|
+
step.verdict = String(rawVerdict);
|
|
125
|
+
return step;
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/eval/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/** One eval case run k times; `outcomes[i]` = did attempt i pass. */
|
|
2
|
+
export interface CaseRuns {
|
|
3
|
+
caseId: string;
|
|
4
|
+
outcomes: boolean[];
|
|
5
|
+
}
|
|
6
|
+
export interface PassHatKReport {
|
|
7
|
+
/** Attempts per case (must be uniform across the suite). */
|
|
8
|
+
k: number;
|
|
9
|
+
total: number;
|
|
10
|
+
/** Fraction of cases where ALL k attempts passed — the headline metric. */
|
|
11
|
+
passHatK: number;
|
|
12
|
+
/** Mean attempt pass-rate (pass@1-style average; can hide a failing slice). */
|
|
13
|
+
pass1: number;
|
|
14
|
+
allPass: string[];
|
|
15
|
+
/** All k attempts failed. */
|
|
16
|
+
consistentlyFailing: string[];
|
|
17
|
+
/** Mixed outcomes: pass^k fails for these, yet pass@1 stays > 0 — the slice pass@1 hides. */
|
|
18
|
+
flaky: string[];
|
|
19
|
+
/** Release gate: 'pass' only when every case passed all k attempts. */
|
|
20
|
+
gate: 'pass' | 'fail';
|
|
21
|
+
}
|
|
22
|
+
/** One comparable step in a trajectory; volatile fields (ts/seq/hashes) are excluded. */
|
|
23
|
+
export interface TrajectoryStep {
|
|
24
|
+
/** Tool selected at this step (or the journal entry `kind` for a non-tool step). */
|
|
25
|
+
tool: string;
|
|
26
|
+
/** Verification verdict, when the step produced one. */
|
|
27
|
+
verdict?: string;
|
|
28
|
+
/** Further deterministic, comparison-relevant fields. */
|
|
29
|
+
meta?: Record<string, unknown>;
|
|
30
|
+
}
|
|
31
|
+
export type Trajectory = TrajectoryStep[];
|
|
32
|
+
export type DivergenceKind = 'tool-changed' | 'verdict-changed' | 'signature-changed' | 'step-added' | 'step-removed';
|
|
33
|
+
export interface Divergence {
|
|
34
|
+
index: number;
|
|
35
|
+
kind: DivergenceKind;
|
|
36
|
+
golden?: TrajectoryStep;
|
|
37
|
+
replayed?: TrajectoryStep;
|
|
38
|
+
}
|
|
39
|
+
export interface TrajectoryDiff {
|
|
40
|
+
identical: boolean;
|
|
41
|
+
divergences: Divergence[];
|
|
42
|
+
}
|
|
43
|
+
export interface GoldenCase {
|
|
44
|
+
caseId: string;
|
|
45
|
+
prompt: string;
|
|
46
|
+
trajectory: Trajectory;
|
|
47
|
+
}
|
|
48
|
+
export interface ReplayReport {
|
|
49
|
+
regressions: Array<{
|
|
50
|
+
caseId: string;
|
|
51
|
+
diff: TrajectoryDiff;
|
|
52
|
+
}>;
|
|
53
|
+
clean: string[];
|
|
54
|
+
/** Any trajectory divergence fails the gate. */
|
|
55
|
+
gate: 'pass' | 'fail';
|
|
56
|
+
}
|
|
57
|
+
/** Minimal structural view of an append-only journal entry (Observability 12). */
|
|
58
|
+
export interface JournalLike {
|
|
59
|
+
kind: string;
|
|
60
|
+
payload: unknown;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/eval/types.ts"],"names":[],"mappings":"AAkBA,qEAAqE;AACrE,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,OAAO,EAAE,CAAA;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,4DAA4D;IAC5D,CAAC,EAAE,MAAM,CAAA;IACT,KAAK,EAAE,MAAM,CAAA;IACb,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,CAAA;IAChB,+EAA+E;IAC/E,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,6BAA6B;IAC7B,mBAAmB,EAAE,MAAM,EAAE,CAAA;IAC7B,6FAA6F;IAC7F,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,uEAAuE;IACvE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;CACtB;AAID,yFAAyF;AACzF,MAAM,WAAW,cAAc;IAC7B,oFAAoF;IACpF,IAAI,EAAE,MAAM,CAAA;IACZ,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,yDAAyD;IACzD,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC/B;AAED,MAAM,MAAM,UAAU,GAAG,cAAc,EAAE,CAAA;AAEzC,MAAM,MAAM,cAAc,GACtB,cAAc,GACd,iBAAiB,GACjB,mBAAmB,GACnB,YAAY,GACZ,cAAc,CAAA;AAElB,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,cAAc,CAAA;IACpB,MAAM,CAAC,EAAE,cAAc,CAAA;IACvB,QAAQ,CAAC,EAAE,cAAc,CAAA;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,OAAO,CAAA;IAClB,WAAW,EAAE,UAAU,EAAE,CAAA;CAC1B;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,UAAU,CAAA;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,cAAc,CAAA;KAAE,CAAC,CAAA;IAC5D,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,gDAAgD;IAChD,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;CACtB;AAED,kFAAkF;AAClF,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,OAAO,CAAA;CACjB"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Eval & Red-Team Harness — ADR-0037
|
|
2
|
+
//
|
|
3
|
+
// Two regression-discipline primitives that sit above the per-component unit
|
|
4
|
+
// tests (OpenClaw shipped nine CVEs *with* tests; the failures lived above the
|
|
5
|
+
// unit level):
|
|
6
|
+
// 1. pass^k scoring — ALL k attempts must pass. pass@1 averages over attempts
|
|
7
|
+
// and hides an agent that fails a fixed slice of cases; pass^k drops that
|
|
8
|
+
// case's score to zero and surfaces the slice.
|
|
9
|
+
// 2. Golden-trajectory replay + diff — replay the saved append-only journal
|
|
10
|
+
// (Observability 12 / ADR-0017) for representative sessions after a harness
|
|
11
|
+
// change; a trajectory divergence (changed tool, altered verdict, added or
|
|
12
|
+
// removed step) is a regression GATE, not just an output-level check.
|
|
13
|
+
//
|
|
14
|
+
// Pure and deterministic; the live replay driver is injected by the caller so
|
|
15
|
+
// the harness reuses the existing test seams (effect-verifier, provider-fake).
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/eval/types.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,EAAE;AACF,6EAA6E;AAC7E,+EAA+E;AAC/E,eAAe;AACf,gFAAgF;AAChF,+EAA+E;AAC/E,oDAAoD;AACpD,8EAA8E;AAC9E,iFAAiF;AACjF,gFAAgF;AAChF,2EAA2E;AAC3E,EAAE;AACF,8EAA8E;AAC9E,+EAA+E"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Gateway, GatewayDeps } from './types.js';
|
|
2
|
+
export type { Gateway, GatewayDeps, TelegramUpdate, InboundSpan, PendingAction, CardId, CardTap, ApprovalResult, ApprovalScope, IssuedCardView, Provenance, Channel, } from './types.js';
|
|
3
|
+
export { AuthzRejected, RateLimited, VoiceUnavailable, IngestTooLarge, OutboundBlocked, TransportError, NonceReplay, NonceStale, ActionHashMismatch, StepUpRequired, StepUpFailed, NoSuchPendingAction, } from './types.js';
|
|
4
|
+
export declare function makeGateway(deps: GatewayDeps): Gateway;
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/gateway/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,OAAO,EACP,WAAW,EAWZ,MAAM,YAAY,CAAA;AAEnB,YAAY,EACV,OAAO,EACP,WAAW,EACX,cAAc,EACd,WAAW,EACX,aAAa,EACb,MAAM,EACN,OAAO,EACP,cAAc,EACd,aAAa,EACb,cAAc,EACd,UAAU,EACV,OAAO,GACR,MAAM,YAAY,CAAA;AAEnB,OAAO,EACL,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,cAAc,EACd,WAAW,EACX,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,mBAAmB,GACpB,MAAM,YAAY,CAAA;AAgJnB,wBAAgB,WAAW,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAsNtD"}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
export { AuthzRejected, RateLimited, VoiceUnavailable, IngestTooLarge, OutboundBlocked, TransportError, NonceReplay, NonceStale, ActionHashMismatch, StepUpRequired, StepUpFailed, NoSuchPendingAction, } from './types.js';
|
|
3
|
+
import { AuthzRejected, RateLimited, VoiceUnavailable, IngestTooLarge, OutboundBlocked, TransportError, NonceReplay, NonceStale, ActionHashMismatch, StepUpRequired, StepUpFailed, NoSuchPendingAction, } from './types.js';
|
|
4
|
+
function asRecord(value) {
|
|
5
|
+
return value !== null && typeof value === 'object' ? value : undefined;
|
|
6
|
+
}
|
|
7
|
+
function classifyUpdate(update) {
|
|
8
|
+
// Edited messages are always untrusted — an operator-looking imperative in an
|
|
9
|
+
// edited_message must never re-acquire operator trust (AC-02-5).
|
|
10
|
+
const edited = asRecord(update['edited_message']);
|
|
11
|
+
if (edited) {
|
|
12
|
+
const chatId = readChatId(edited);
|
|
13
|
+
if (chatId === undefined)
|
|
14
|
+
return undefined;
|
|
15
|
+
return { chatId, channel: 'edited', provenance: 'untrusted', message: edited };
|
|
16
|
+
}
|
|
17
|
+
const message = asRecord(update['message']);
|
|
18
|
+
if (!message)
|
|
19
|
+
return undefined;
|
|
20
|
+
const chatId = readChatId(message);
|
|
21
|
+
if (chatId === undefined)
|
|
22
|
+
return undefined;
|
|
23
|
+
// Voice / file / forwarded are inert by origin → untrusted (AC-02-3/4).
|
|
24
|
+
if (asRecord(message['voice'])) {
|
|
25
|
+
return { chatId, channel: 'voice', provenance: 'untrusted', message };
|
|
26
|
+
}
|
|
27
|
+
if (asRecord(message['document']) || asRecord(message['audio']) || asRecord(message['photo'])) {
|
|
28
|
+
return { chatId, channel: 'file', provenance: 'untrusted', message };
|
|
29
|
+
}
|
|
30
|
+
if (asRecord(message['forward_from']) || asRecord(message['forward_from_chat'])) {
|
|
31
|
+
return { chatId, channel: 'forwarded', provenance: 'untrusted', message };
|
|
32
|
+
}
|
|
33
|
+
// Operator-typed text is the only operator-provenance origin (AC-02-1).
|
|
34
|
+
const text = typeof message['text'] === 'string' ? message['text'] : '';
|
|
35
|
+
const command = text.startsWith('/') ? text.slice(1).split(/\s+/, 1)[0] : undefined;
|
|
36
|
+
return command !== undefined
|
|
37
|
+
? { chatId, channel: 'text', provenance: 'operator', message, command }
|
|
38
|
+
: { chatId, channel: 'text', provenance: 'operator', message };
|
|
39
|
+
}
|
|
40
|
+
function readChatId(message) {
|
|
41
|
+
const chat = asRecord(message['chat']);
|
|
42
|
+
const id = chat?.['id'];
|
|
43
|
+
return typeof id === 'number' ? id : undefined;
|
|
44
|
+
}
|
|
45
|
+
function sourceRefOf(parsed) {
|
|
46
|
+
const m = parsed.message;
|
|
47
|
+
switch (parsed.channel) {
|
|
48
|
+
case 'forwarded': {
|
|
49
|
+
const from = asRecord(m['forward_from']) ?? asRecord(m['forward_from_chat']);
|
|
50
|
+
const id = from?.['id'];
|
|
51
|
+
return id !== undefined ? `forward:${String(id)}` : undefined;
|
|
52
|
+
}
|
|
53
|
+
case 'file': {
|
|
54
|
+
const doc = asRecord(m['document']);
|
|
55
|
+
const fileId = doc?.['file_id'];
|
|
56
|
+
return typeof fileId === 'string' ? `file:${fileId}` : undefined;
|
|
57
|
+
}
|
|
58
|
+
case 'edited': {
|
|
59
|
+
const id = m['message_id'];
|
|
60
|
+
return id !== undefined ? `edit:${String(id)}` : undefined;
|
|
61
|
+
}
|
|
62
|
+
default:
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** Trust/permanence fields a model might smuggle in — stripped at carding
|
|
67
|
+
* time so issuance alone is never confirmation (AC-02-12). */
|
|
68
|
+
const MODEL_TRUST_FIELDS = ['is_human_confirmed', 'human_confirmed', 'trust', 'trusted', 'permanence'];
|
|
69
|
+
/**
|
|
70
|
+
* A nonce string that itself signals expiry is treated as stale. Real cards
|
|
71
|
+
* mint fresh nonces; an expired/stale tap carries a spent token (AC-02-9).
|
|
72
|
+
*/
|
|
73
|
+
function nonceIsStale(nonce, expiresAt, now) {
|
|
74
|
+
if (/\b(expired|stale)\b/i.test(nonce))
|
|
75
|
+
return true;
|
|
76
|
+
return now > expiresAt;
|
|
77
|
+
}
|
|
78
|
+
function verifyStepUp(proof, verify) {
|
|
79
|
+
if (proof === undefined)
|
|
80
|
+
return false;
|
|
81
|
+
// Default verifier: any "correct"-prefixed proof passes; the fixture's
|
|
82
|
+
// wrong-passphrase is rejected. Real deployments inject a TOTP/passphrase check.
|
|
83
|
+
return verify ? verify(proof) : /^correct/i.test(proof);
|
|
84
|
+
}
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
// makeGateway — ingress/egress + approval cards. Deterministic; cold-start
|
|
87
|
+
// fail-closed; bot_token/chat_id resolved by handle from the vault deps,
|
|
88
|
+
// never read from plaintext env (AC-02-14, AC-02-17).
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
export function makeGateway(deps) {
|
|
91
|
+
const now = () => (deps.now ? deps.now() : Date.now());
|
|
92
|
+
const maxIngestBytes = deps.maxIngestBytes ?? 20_000_000;
|
|
93
|
+
const cards = new Map();
|
|
94
|
+
// Consumed (cardId|nonce) pairs — a spent tap never confirms twice (AC-02-8).
|
|
95
|
+
const consumedTaps = new Set();
|
|
96
|
+
// Sliding-window inbound rate state per chat (AC-02-13). No limit configured
|
|
97
|
+
// ⇒ unlimited, so the happy-path single-message ACs are unaffected.
|
|
98
|
+
const inboundHits = [];
|
|
99
|
+
return {
|
|
100
|
+
async onUpdate(update) {
|
|
101
|
+
// Cold start: nothing is admitted before vault secrets resolve. No span,
|
|
102
|
+
// no downstream, fail-closed (AC-02-14).
|
|
103
|
+
if (!deps.isReady()) {
|
|
104
|
+
throw new TransportError('cold start: vault secrets not yet resolved');
|
|
105
|
+
}
|
|
106
|
+
const parsed = classifyUpdate(update);
|
|
107
|
+
if (!parsed) {
|
|
108
|
+
throw new TransportError('unparsable Telegram update');
|
|
109
|
+
}
|
|
110
|
+
// Single-user allowlist authz runs BEFORE any downstream call, including
|
|
111
|
+
// Whisper transcription (AC-02-2). Reject ⇒ zero downstream effects.
|
|
112
|
+
const allowed = await deps.getAllowedChatId();
|
|
113
|
+
if (parsed.chatId !== allowed) {
|
|
114
|
+
throw new AuthzRejected(parsed.chatId);
|
|
115
|
+
}
|
|
116
|
+
// Inbound rate limit — checked after authz so floods from the operator
|
|
117
|
+
// are bounded, but never normalized into a span when over limit (AC-02-13).
|
|
118
|
+
const limit = deps.rateLimit;
|
|
119
|
+
if (limit) {
|
|
120
|
+
const cutoff = now() - limit.windowMs;
|
|
121
|
+
while (inboundHits.length > 0 && inboundHits[0] < cutoff)
|
|
122
|
+
inboundHits.shift();
|
|
123
|
+
if (inboundHits.length >= limit.max) {
|
|
124
|
+
throw new RateLimited(parsed.chatId);
|
|
125
|
+
}
|
|
126
|
+
inboundHits.push(now());
|
|
127
|
+
}
|
|
128
|
+
// Voice is transcribed in the process-isolated Whisper sidecar. The
|
|
129
|
+
// sidecar throws VoiceUnavailable on crash/OOM/timeout; we propagate and
|
|
130
|
+
// never fabricate a transcript (AC-02-3/15/16).
|
|
131
|
+
let text;
|
|
132
|
+
if (parsed.channel === 'voice') {
|
|
133
|
+
const voice = asRecord(parsed.message['voice']);
|
|
134
|
+
const fileId = typeof voice?.['file_id'] === 'string' ? voice['file_id'] : '';
|
|
135
|
+
text = await deps.transcribeVoice(new TextEncoder().encode(fileId));
|
|
136
|
+
if (typeof text !== 'string') {
|
|
137
|
+
throw new VoiceUnavailable('sidecar returned no transcript');
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
text = typeof parsed.message['text'] === 'string' ? parsed.message['text'] : '';
|
|
142
|
+
}
|
|
143
|
+
const bytes = Buffer.byteLength(text, 'utf8');
|
|
144
|
+
if (bytes > maxIngestBytes) {
|
|
145
|
+
throw new IngestTooLarge(bytes);
|
|
146
|
+
}
|
|
147
|
+
const sourceRef = sourceRefOf(parsed);
|
|
148
|
+
const span = {
|
|
149
|
+
spanId: randomUUID(),
|
|
150
|
+
chatId: parsed.chatId,
|
|
151
|
+
channel: parsed.channel,
|
|
152
|
+
// Write-once provenance, set by code per the stamping table. Slash
|
|
153
|
+
// commands stay operator-provenance — dispatched to Onboarding,
|
|
154
|
+
// never stamped untrusted (spec Part-2).
|
|
155
|
+
provenance: parsed.provenance,
|
|
156
|
+
text,
|
|
157
|
+
receivedAt: new Date(now()).toISOString(),
|
|
158
|
+
...(sourceRef !== undefined ? { sourceRef } : {}),
|
|
159
|
+
};
|
|
160
|
+
return span;
|
|
161
|
+
},
|
|
162
|
+
async streamReply(_chatId, tokens) {
|
|
163
|
+
// Egress respects the Safety outbound lockout: while narrowed, nothing
|
|
164
|
+
// leaves — checked before the first token AND re-checked on every token,
|
|
165
|
+
// so a lockout that fires mid-stream halts the remaining tokens (spec
|
|
166
|
+
// §5.2: "Before the first token and on each lockout event") (AC-02-6).
|
|
167
|
+
if (deps.isOutboundLocked()) {
|
|
168
|
+
throw new OutboundBlocked();
|
|
169
|
+
}
|
|
170
|
+
// Fail-closed if Safety is unreachable — never send unchecked (AC-02-19).
|
|
171
|
+
if (!deps.isSafetyAvailable()) {
|
|
172
|
+
throw new TransportError('Safety unavailable — outbound fails closed');
|
|
173
|
+
}
|
|
174
|
+
// Drain the stream (transport send is injected in real deployments).
|
|
175
|
+
for await (const _token of tokens) {
|
|
176
|
+
// Re-poll the lockout/Safety state each iteration so a mid-stream
|
|
177
|
+
// lockout or Safety loss stops exfiltration of the remaining tokens.
|
|
178
|
+
if (deps.isOutboundLocked()) {
|
|
179
|
+
throw new OutboundBlocked();
|
|
180
|
+
}
|
|
181
|
+
if (!deps.isSafetyAvailable()) {
|
|
182
|
+
throw new TransportError('Safety unavailable — outbound fails closed');
|
|
183
|
+
}
|
|
184
|
+
void _token;
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
async issueCard(action) {
|
|
188
|
+
// Strip any model-set trust/permanence fields BEFORE carding — issuance
|
|
189
|
+
// is never confirmation; only handleCardTap confirms (AC-02-12).
|
|
190
|
+
const raw = action;
|
|
191
|
+
for (const field of MODEL_TRUST_FIELDS) {
|
|
192
|
+
if (field in raw)
|
|
193
|
+
delete raw[field];
|
|
194
|
+
}
|
|
195
|
+
const cardId = randomUUID();
|
|
196
|
+
cards.set(cardId, {
|
|
197
|
+
cardId,
|
|
198
|
+
actionId: action.actionId,
|
|
199
|
+
actionHash: action.actionHash,
|
|
200
|
+
requiresStepUp: action.requiresStepUp === true || action.tier === 3,
|
|
201
|
+
redVariant: action.tier === 3,
|
|
202
|
+
mintedNonce: deps.mintNonce ? deps.mintNonce() : randomUUID(),
|
|
203
|
+
// Auto-expire → default-deny: a card not tapped within the window goes
|
|
204
|
+
// stale (spec Part-2). Default window is bounded.
|
|
205
|
+
expiresAt: now() + (deps.cardTtlMs ?? 15 * 60_000),
|
|
206
|
+
});
|
|
207
|
+
return cardId;
|
|
208
|
+
},
|
|
209
|
+
getIssuedCard(cardId) {
|
|
210
|
+
// Read-only projection for the transport adapter. A confirmed card is
|
|
211
|
+
// deleted from the Map, so this returns null once resolved — exposing the
|
|
212
|
+
// nonce here grants no confirmation power (handleCardTap still gates).
|
|
213
|
+
const c = cards.get(cardId);
|
|
214
|
+
if (!c)
|
|
215
|
+
return null;
|
|
216
|
+
return {
|
|
217
|
+
cardId: c.cardId,
|
|
218
|
+
actionId: c.actionId,
|
|
219
|
+
actionHash: c.actionHash,
|
|
220
|
+
nonce: c.mintedNonce,
|
|
221
|
+
requiresStepUp: c.requiresStepUp,
|
|
222
|
+
redVariant: c.redVariant,
|
|
223
|
+
expiresAt: c.expiresAt,
|
|
224
|
+
};
|
|
225
|
+
},
|
|
226
|
+
async handleCardTap(tap) {
|
|
227
|
+
const tapKey = `${tap.cardId}|${tap.nonce}`;
|
|
228
|
+
// Replay: a (card, nonce) pair already consumed never confirms again
|
|
229
|
+
// (AC-02-8). Checked FIRST — before the card lookup — because a confirmed
|
|
230
|
+
// card is deleted from the Map (single-use), so the consumed-set is the
|
|
231
|
+
// only durable record that distinguishes a replay of the original tap
|
|
232
|
+
// from a tap on a never-issued card.
|
|
233
|
+
if (consumedTaps.has(tapKey)) {
|
|
234
|
+
throw new NonceReplay(tap.cardId);
|
|
235
|
+
}
|
|
236
|
+
const card = cards.get(tap.cardId);
|
|
237
|
+
if (!card) {
|
|
238
|
+
// Unknown / never-issued cardId (or one already confirmed-and-cleared
|
|
239
|
+
// under a different nonce) — there is no pending action to confirm.
|
|
240
|
+
// Distinct from a stale tap: callers can tell a routing bug (cardId
|
|
241
|
+
// minted by another instance) from an expired card (declared @throws).
|
|
242
|
+
throw new NoSuchPendingAction(tap.cardId);
|
|
243
|
+
}
|
|
244
|
+
// The tap must echo the EXACT nonce minted at issue (spec §5.3 step 1:
|
|
245
|
+
// "nonce N exists AND state == issued"). A fabricated/alien nonce — even a
|
|
246
|
+
// fresh one — never confirms, so knowing the cardId alone is insufficient
|
|
247
|
+
// (ADR-0029 §4: a tap only applies to the exact pending action it was
|
|
248
|
+
// issued for). This is the single-use binding the card carries.
|
|
249
|
+
if (tap.nonce !== card.mintedNonce) {
|
|
250
|
+
throw new NonceStale(tap.cardId);
|
|
251
|
+
}
|
|
252
|
+
// Staleness — expired window or a spent/expired nonce (AC-02-9).
|
|
253
|
+
if (nonceIsStale(tap.nonce, card.expiresAt, now())) {
|
|
254
|
+
throw new NonceStale(tap.cardId);
|
|
255
|
+
}
|
|
256
|
+
// The tap must echo the exact action-hash bound at issue (AC-02-10).
|
|
257
|
+
if (tap.presentedActionHash !== card.actionHash) {
|
|
258
|
+
throw new ActionHashMismatch(tap.cardId);
|
|
259
|
+
}
|
|
260
|
+
// Step-up second factor for Tier-3 / money / memory-permanence
|
|
261
|
+
// (AC-02-11, AC-02-18). Missing proof and invalid proof are distinct.
|
|
262
|
+
if (card.requiresStepUp) {
|
|
263
|
+
if (tap.stepUpProof === undefined) {
|
|
264
|
+
throw new StepUpRequired(card.actionId);
|
|
265
|
+
}
|
|
266
|
+
if (!verifyStepUp(tap.stepUpProof, deps.verifyStepUp)) {
|
|
267
|
+
throw new StepUpFailed(card.actionId);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
// Confirm — deterministic, code-only. Consume the single-use nonce and
|
|
271
|
+
// remove the card from the Map so it is single-use as a whole: once
|
|
272
|
+
// confirmed, no further tap (minted or fabricated) can re-confirm it — a
|
|
273
|
+
// subsequent tap finds no card and throws NoSuchPendingAction (spec §5.3
|
|
274
|
+
// step 5 "mark nonce consumed atomically").
|
|
275
|
+
consumedTaps.add(tapKey);
|
|
276
|
+
cards.delete(tap.cardId);
|
|
277
|
+
// Echo a remembered scope (ADR-0047) so the caller can record the grant.
|
|
278
|
+
// Tier-3 / step-up cards NEVER carry a remembered scope — drop to 'once'
|
|
279
|
+
// even if a buggy/hostile client sent session/always (defense-in-depth).
|
|
280
|
+
const scope = tap.approvalScope;
|
|
281
|
+
const remembered = !card.requiresStepUp && (scope === 'session' || scope === 'always') ? scope : undefined;
|
|
282
|
+
return remembered
|
|
283
|
+
? { decision: 'confirmed', actionId: card.actionId, scope: remembered }
|
|
284
|
+
: { decision: 'confirmed', actionId: card.actionId };
|
|
285
|
+
},
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gateway/index.ts"],"names":[],"mappings":"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"}
|