@shield-agent/kya 0.22.0 → 0.23.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/.mcp.json +1 -1
- package/README.md +72 -30
- package/amp/settings.example.json +1 -1
- package/claude/claude_desktop_config.example.json +1 -1
- package/cline/cline_mcp_settings.example.json +1 -1
- package/copilot/mcp-config.example.json +1 -1
- package/dist/certify/attest.js +5 -5
- package/dist/certify/catalog.d.ts +1 -1
- package/dist/certify/catalog.js +3 -3
- package/dist/certify/context.js +1 -1
- package/dist/certify/evaluate.d.ts +2 -2
- package/dist/certify/evaluate.js +12 -12
- package/dist/certify/live.js +2 -2
- package/dist/certify/render.d.ts +1 -1
- package/dist/certify/render.js +10 -10
- package/dist/cli.d.ts +2 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +49 -16
- package/dist/cli.js.map +1 -1
- package/dist/commands/certify.d.ts +1 -1
- package/dist/commands/certify.js +3 -3
- package/dist/commands/connect.d.ts +2 -2
- package/dist/commands/connect.js +22 -22
- package/dist/commands/dash.js +4 -4
- package/dist/commands/gate-serve.js +3 -3
- package/dist/commands/gate.d.ts +1 -1
- package/dist/commands/gate.js +16 -16
- package/dist/commands/hook.d.ts +1 -1
- package/dist/commands/hook.d.ts.map +1 -1
- package/dist/commands/hook.js +55 -18
- package/dist/commands/hook.js.map +1 -1
- package/dist/commands/import-traces.d.ts +16 -0
- package/dist/commands/import-traces.d.ts.map +1 -0
- package/dist/commands/import-traces.js +18 -0
- package/dist/commands/import-traces.js.map +1 -0
- package/dist/commands/init.js +1 -1
- package/dist/commands/investigate.d.ts +13 -0
- package/dist/commands/investigate.d.ts.map +1 -0
- package/dist/commands/investigate.js +22 -0
- package/dist/commands/investigate.js.map +1 -0
- package/dist/commands/notify-flush.d.ts +2 -0
- package/dist/commands/notify-flush.d.ts.map +1 -0
- package/dist/commands/notify-flush.js +47 -0
- package/dist/commands/notify-flush.js.map +1 -0
- package/dist/commands/orr.d.ts +3 -3
- package/dist/commands/orr.js +5 -5
- package/dist/commands/receipt-serve.d.ts +1 -1
- package/dist/commands/receipt-serve.js +1 -1
- package/dist/commands/serve-mcp.js +1 -1
- package/dist/commands/start.d.ts +2 -2
- package/dist/commands/start.js +20 -20
- package/dist/commands/stop.d.ts +1 -1
- package/dist/commands/stop.js +6 -6
- package/dist/commands/update.d.ts +19 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +96 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/wire-hooks.d.ts +1 -1
- package/dist/commands/wire-hooks.js +14 -14
- package/dist/commands/wrap.d.ts.map +1 -1
- package/dist/commands/wrap.js +12 -7
- package/dist/commands/wrap.js.map +1 -1
- package/dist/config.d.ts +4 -4
- package/dist/config.js +5 -5
- package/dist/dash/dash.d.ts +1 -1
- package/dist/dash/dash.js +3 -3
- package/dist/dash/entitlement.d.ts +1 -1
- package/dist/dash/entitlement.js +1 -1
- package/dist/dash/render.js +2 -2
- package/dist/dash/screens/enterprise.js +9 -9
- package/dist/dash/screens/free.js +5 -5
- package/dist/diff-preview.d.ts +1 -1
- package/dist/diff-preview.js +2 -2
- package/dist/errors.d.ts +1 -1
- package/dist/errors.js +1 -1
- package/dist/fs-atomic.d.ts +1 -1
- package/dist/fs-atomic.js +2 -2
- package/dist/gate/binary.js +4 -4
- package/dist/gate/config-gen.d.ts +1 -1
- package/dist/gate/config-gen.js +7 -7
- package/dist/gate/config.d.ts +2 -2
- package/dist/gate/config.js +6 -6
- package/dist/gate/daemon.js +1 -1
- package/dist/gate/discover.d.ts +2 -2
- package/dist/gate/discover.js +7 -7
- package/dist/gate/hosted-sync.js +1 -1
- package/dist/gate/otlp-decode.d.ts +2 -2
- package/dist/gate/otlp-decode.js +2 -2
- package/dist/gate/otlp-receiver.d.ts +1 -1
- package/dist/gate/otlp-receiver.js +3 -3
- package/dist/host-reload.js +11 -11
- package/dist/host-tools.d.ts +1 -1
- package/dist/host-tools.js +1 -1
- package/dist/importers/formats.d.ts +26 -0
- package/dist/importers/formats.d.ts.map +1 -0
- package/dist/importers/formats.js +281 -0
- package/dist/importers/formats.js.map +1 -0
- package/dist/importers/index.d.ts +26 -0
- package/dist/importers/index.d.ts.map +1 -0
- package/dist/importers/index.js +122 -0
- package/dist/importers/index.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/investigate/detectors.d.ts +35 -0
- package/dist/investigate/detectors.d.ts.map +1 -0
- package/dist/investigate/detectors.js +277 -0
- package/dist/investigate/detectors.js.map +1 -0
- package/dist/investigate/fix-brief.d.ts +3 -0
- package/dist/investigate/fix-brief.d.ts.map +1 -0
- package/dist/investigate/fix-brief.js +88 -0
- package/dist/investigate/fix-brief.js.map +1 -0
- package/dist/investigate/incidents.d.ts +19 -0
- package/dist/investigate/incidents.d.ts.map +1 -0
- package/dist/investigate/incidents.js +84 -0
- package/dist/investigate/incidents.js.map +1 -0
- package/dist/investigate/index.d.ts +25 -0
- package/dist/investigate/index.d.ts.map +1 -0
- package/dist/investigate/index.js +46 -0
- package/dist/investigate/index.js.map +1 -0
- package/dist/mcp/protocol.d.ts +2 -2
- package/dist/mcp/protocol.d.ts.map +1 -1
- package/dist/mcp/protocol.js +39 -8
- package/dist/mcp/protocol.js.map +1 -1
- package/dist/mcp/stdio.d.ts +1 -1
- package/dist/mcp/stdio.js +2 -2
- package/dist/mcp-servers.d.ts +2 -2
- package/dist/mcp-servers.js +2 -2
- package/dist/node-upgrade.d.ts +2 -2
- package/dist/node-upgrade.js +9 -9
- package/dist/notify/dispatch.d.ts +20 -0
- package/dist/notify/dispatch.d.ts.map +1 -0
- package/dist/notify/dispatch.js +52 -0
- package/dist/notify/dispatch.js.map +1 -0
- package/dist/notify/index.d.ts +39 -0
- package/dist/notify/index.d.ts.map +1 -0
- package/dist/notify/index.js +119 -0
- package/dist/notify/index.js.map +1 -0
- package/dist/notify/sender.d.ts +56 -0
- package/dist/notify/sender.d.ts.map +1 -0
- package/dist/notify/sender.js +139 -0
- package/dist/notify/sender.js.map +1 -0
- package/dist/notify/templates.d.ts +33 -0
- package/dist/notify/templates.d.ts.map +1 -0
- package/dist/notify/templates.js +119 -0
- package/dist/notify/templates.js.map +1 -0
- package/dist/offline-evaluate.d.ts +2 -2
- package/dist/offline-evaluate.js +3 -3
- package/dist/orr/agentshield.d.ts +2 -2
- package/dist/orr/agentshield.js +4 -4
- package/dist/orr/scorecard.d.ts +1 -1
- package/dist/orr/scorecard.js +3 -3
- package/dist/otel/exporter.d.ts +64 -0
- package/dist/otel/exporter.d.ts.map +1 -0
- package/dist/otel/exporter.js +243 -0
- package/dist/otel/exporter.js.map +1 -0
- package/dist/parse-args.d.ts +1 -1
- package/dist/parse-args.js +1 -1
- package/dist/receipt/auto-open.d.ts +1 -1
- package/dist/receipt/auto-open.js +1 -1
- package/dist/receipt/daemon.d.ts +6 -6
- package/dist/receipt/daemon.js +15 -15
- package/dist/receipt/dashboard.d.ts +1 -1
- package/dist/receipt/dashboard.js +2 -2
- package/dist/receipt/embeddings.d.ts +15 -4
- package/dist/receipt/embeddings.d.ts.map +1 -1
- package/dist/receipt/embeddings.js +116 -35
- package/dist/receipt/embeddings.js.map +1 -1
- package/dist/receipt/enrich.d.ts +2 -2
- package/dist/receipt/enrich.js +5 -5
- package/dist/receipt/gate-card.d.ts +2 -2
- package/dist/receipt/gate-card.d.ts.map +1 -1
- package/dist/receipt/gate-card.js +3 -3
- package/dist/receipt/live-server.d.ts.map +1 -1
- package/dist/receipt/live-server.js +22 -8
- package/dist/receipt/live-server.js.map +1 -1
- package/dist/receipt/receipt-css.d.ts +1 -1
- package/dist/receipt/receipt-css.d.ts.map +1 -1
- package/dist/receipt/receipt-css.js +72 -11
- package/dist/receipt/receipt-css.js.map +1 -1
- package/dist/receipt/render-receipt.d.ts +1 -1
- package/dist/receipt/render-receipt.d.ts.map +1 -1
- package/dist/receipt/render-receipt.js +138 -87
- package/dist/receipt/render-receipt.js.map +1 -1
- package/dist/receipt/share.d.ts +2 -2
- package/dist/receipt/share.js +5 -5
- package/dist/sample-tools.d.ts +1 -1
- package/dist/sample-tools.js +1 -1
- package/dist/sandbox/mock-driver.d.ts +1 -1
- package/dist/sandbox/mock-driver.js +1 -1
- package/dist/sdk/a2a.d.ts +2 -2
- package/dist/sdk/a2a.js +1 -1
- package/dist/sdk/adapters/claude-agent.d.ts +1 -1
- package/dist/sdk/adapters/claude-agent.js +1 -1
- package/dist/sdk/adapters/langgraph.d.ts +1 -1
- package/dist/sdk/adapters/langgraph.js +1 -1
- package/dist/sdk/adapters/mastra.d.ts +1 -1
- package/dist/sdk/adapters/mastra.js +1 -1
- package/dist/sdk/adapters/openai-agents.d.ts +1 -1
- package/dist/sdk/adapters/openai-agents.js +1 -1
- package/dist/sdk/adapters/vercel-ai.d.ts +2 -2
- package/dist/sdk/adapters/vercel-ai.js +1 -1
- package/dist/sdk/govern.d.ts +2 -2
- package/dist/sdk/govern.js +3 -3
- package/dist/sdk/index.d.ts +1 -1
- package/dist/sdk/index.js +1 -1
- package/dist/showback/trail-usage.d.ts +30 -0
- package/dist/showback/trail-usage.d.ts.map +1 -0
- package/dist/showback/trail-usage.js +50 -0
- package/dist/showback/trail-usage.js.map +1 -0
- package/dist/sign/evidence-bundle.d.ts +6 -6
- package/dist/sign/evidence-bundle.js +5 -5
- package/dist/star-cta.d.ts +1 -1
- package/dist/star-cta.d.ts.map +1 -1
- package/dist/star-cta.js +3 -3
- package/dist/trail-summary.d.ts +1 -1
- package/dist/trail-summary.js +3 -3
- package/dist/trail.d.ts +8 -2
- package/dist/trail.d.ts.map +1 -1
- package/dist/trail.js +18 -5
- package/dist/trail.js.map +1 -1
- package/dist/update-check.d.ts +17 -0
- package/dist/update-check.d.ts.map +1 -0
- package/dist/update-check.js +134 -0
- package/dist/update-check.js.map +1 -0
- package/droid/README.md +1 -1
- package/droid/mcp.example.json +1 -1
- package/gemini/settings.example.json +1 -1
- package/grok/README.md +1 -1
- package/kilo/kilo.example.json +1 -1
- package/kimi/mcp.example.json +1 -1
- package/kiro/mcp.example.json +1 -1
- package/manifest.json +1 -1
- package/mastracode/mcp.example.json +1 -1
- package/mcp.json +1 -1
- package/openai/codex.config.example.toml +1 -1
- package/opencode/opencode.example.json +1 -1
- package/package.json +2 -2
- package/qwen/settings.example.json +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
/** deny-spike: more than this many DENY events inside the window. */
|
|
2
|
+
export const DENY_SPIKE_THRESHOLD = 3;
|
|
3
|
+
export const DENY_SPIKE_WINDOW_MS = 10 * 60_000;
|
|
4
|
+
/** approval-loop: consecutive REQUIRE_APPROVE on one session+tool. */
|
|
5
|
+
export const APPROVAL_LOOP_MIN = 3;
|
|
6
|
+
/** slow-calls: p95 above this with at least MIN_SAMPLES per tool. */
|
|
7
|
+
export const SLOW_CALL_P95_MS = 5000;
|
|
8
|
+
export const SLOW_CALL_MIN_SAMPLES = 5;
|
|
9
|
+
/** pii-in-summary: token candidates must clear this Shannon entropy (bits/char). */
|
|
10
|
+
const TOKEN_MIN_ENTROPY = 4.0;
|
|
11
|
+
const TOKEN_MIN_LEN = 32;
|
|
12
|
+
function parseTs(ts) {
|
|
13
|
+
const t = Date.parse(ts);
|
|
14
|
+
return Number.isNaN(t) ? undefined : t;
|
|
15
|
+
}
|
|
16
|
+
const EMAIL_RE = /[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}/g;
|
|
17
|
+
const CARD_RE = /(?:\d[ -]?){13,19}(?!\d)/g;
|
|
18
|
+
const TOKEN_RE = /[A-Za-z0-9+/=_-]{32,}/g;
|
|
19
|
+
/** Standard Luhn checksum for card-shaped digit strings. */
|
|
20
|
+
export function luhnValid(digits) {
|
|
21
|
+
let sum = 0;
|
|
22
|
+
let double = false;
|
|
23
|
+
for (let i = digits.length - 1; i >= 0; i--) {
|
|
24
|
+
let d = digits.charCodeAt(i) - 48;
|
|
25
|
+
if (d < 0 || d > 9)
|
|
26
|
+
return false;
|
|
27
|
+
if (double) {
|
|
28
|
+
d *= 2;
|
|
29
|
+
if (d > 9)
|
|
30
|
+
d -= 9;
|
|
31
|
+
}
|
|
32
|
+
sum += d;
|
|
33
|
+
double = !double;
|
|
34
|
+
}
|
|
35
|
+
return digits.length > 0 && sum % 10 === 0;
|
|
36
|
+
}
|
|
37
|
+
function shannonEntropy(s) {
|
|
38
|
+
const freq = new Map();
|
|
39
|
+
for (const ch of s)
|
|
40
|
+
freq.set(ch, (freq.get(ch) ?? 0) + 1);
|
|
41
|
+
let h = 0;
|
|
42
|
+
for (const n of freq.values()) {
|
|
43
|
+
const p = n / s.length;
|
|
44
|
+
h -= p * Math.log2(p);
|
|
45
|
+
}
|
|
46
|
+
return h;
|
|
47
|
+
}
|
|
48
|
+
/** Mask a leaked value for evidence: keep first 4 and last 2 chars. */
|
|
49
|
+
function mask(s) {
|
|
50
|
+
if (s.length <= 8)
|
|
51
|
+
return "***";
|
|
52
|
+
return `${s.slice(0, 4)}***${s.slice(-2)}`;
|
|
53
|
+
}
|
|
54
|
+
function scanPiiField(field, value, hits) {
|
|
55
|
+
if (!value)
|
|
56
|
+
return;
|
|
57
|
+
for (const m of value.matchAll(EMAIL_RE)) {
|
|
58
|
+
hits.push({ kind: "email", field, sample: mask(m[0]) });
|
|
59
|
+
}
|
|
60
|
+
for (const m of value.matchAll(CARD_RE)) {
|
|
61
|
+
const digits = m[0].replace(/\D/g, "");
|
|
62
|
+
if (digits.length >= 13 && digits.length <= 19 && luhnValid(digits)) {
|
|
63
|
+
hits.push({ kind: "credit-card", field, sample: mask(digits) });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
for (const m of value.matchAll(TOKEN_RE)) {
|
|
67
|
+
const tok = m[0];
|
|
68
|
+
if (tok.length >= TOKEN_MIN_LEN && shannonEntropy(tok) >= TOKEN_MIN_ENTROPY) {
|
|
69
|
+
hits.push({ kind: "high-entropy-token", field, sample: mask(tok) });
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function isNever(e) {
|
|
74
|
+
return e.neverEvent === true || e.reasonCode === "NEVER_EVENT";
|
|
75
|
+
}
|
|
76
|
+
function piiInSummary(events) {
|
|
77
|
+
const findings = [];
|
|
78
|
+
for (let i = 0; i < events.length; i++) {
|
|
79
|
+
const e = events[i];
|
|
80
|
+
const hits = [];
|
|
81
|
+
scanPiiField("summary", e.summary, hits);
|
|
82
|
+
scanPiiField("diffPreview", e.diffPreview, hits);
|
|
83
|
+
scanPiiField("targetPath", e.targetPath, hits);
|
|
84
|
+
if (hits.length === 0)
|
|
85
|
+
continue;
|
|
86
|
+
const kinds = [...new Set(hits.map((h) => h.kind))];
|
|
87
|
+
const severity = kinds.includes("credit-card") || kinds.includes("email")
|
|
88
|
+
? "critical"
|
|
89
|
+
: "high";
|
|
90
|
+
findings.push({
|
|
91
|
+
detectorId: "pii-in-summary",
|
|
92
|
+
severity,
|
|
93
|
+
eventIdx: [i],
|
|
94
|
+
summary: `${kinds.join(", ")} in ${hits[0].field} of ${e.toolId} event slipped past redaction`,
|
|
95
|
+
evidence: {
|
|
96
|
+
toolId: e.toolId,
|
|
97
|
+
sessionId: e.sessionId,
|
|
98
|
+
ts: e.ts,
|
|
99
|
+
kinds,
|
|
100
|
+
fields: [...new Set(hits.map((h) => h.field))],
|
|
101
|
+
samples: hits.slice(0, 5).map((h) => `${h.kind}:${h.sample}`),
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return findings;
|
|
106
|
+
}
|
|
107
|
+
function denySpike(events) {
|
|
108
|
+
const byTool = new Map();
|
|
109
|
+
for (let i = 0; i < events.length; i++) {
|
|
110
|
+
const e = events[i];
|
|
111
|
+
if (e.verdict !== "DENY")
|
|
112
|
+
continue;
|
|
113
|
+
const t = parseTs(e.ts);
|
|
114
|
+
if (t === undefined)
|
|
115
|
+
continue;
|
|
116
|
+
const list = byTool.get(e.toolId) ?? [];
|
|
117
|
+
list.push({ idx: i, t });
|
|
118
|
+
byTool.set(e.toolId, list);
|
|
119
|
+
}
|
|
120
|
+
const findings = [];
|
|
121
|
+
for (const [toolId, list] of byTool) {
|
|
122
|
+
list.sort((a, b) => a.t - b.t);
|
|
123
|
+
let emittedUntil = -1;
|
|
124
|
+
for (let i = 0; i < list.length; i++) {
|
|
125
|
+
const window = list.filter((x) => x.t >= list[i].t && x.t - list[i].t <= DENY_SPIKE_WINDOW_MS);
|
|
126
|
+
if (window.length <= DENY_SPIKE_THRESHOLD || list[i].t <= emittedUntil)
|
|
127
|
+
continue;
|
|
128
|
+
emittedUntil = list[i].t + DENY_SPIKE_WINDOW_MS;
|
|
129
|
+
findings.push({
|
|
130
|
+
detectorId: "deny-spike",
|
|
131
|
+
severity: "medium",
|
|
132
|
+
eventIdx: window.map((x) => x.idx),
|
|
133
|
+
summary: `${window.length} DENY events for ${toolId} within 10 minutes`,
|
|
134
|
+
evidence: {
|
|
135
|
+
toolId,
|
|
136
|
+
count: window.length,
|
|
137
|
+
windowStart: new Date(list[i].t).toISOString(),
|
|
138
|
+
windowEnd: new Date(list[i].t + DENY_SPIKE_WINDOW_MS).toISOString(),
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return findings;
|
|
144
|
+
}
|
|
145
|
+
function approvalLoop(events) {
|
|
146
|
+
const byKey = new Map();
|
|
147
|
+
for (let i = 0; i < events.length; i++) {
|
|
148
|
+
const e = events[i];
|
|
149
|
+
const key = `${e.sessionId}${e.toolId}`;
|
|
150
|
+
const list = byKey.get(key) ?? [];
|
|
151
|
+
list.push({ idx: i, t: parseTs(e.ts) ?? 0, e });
|
|
152
|
+
byKey.set(key, list);
|
|
153
|
+
}
|
|
154
|
+
const findings = [];
|
|
155
|
+
for (const list of byKey.values()) {
|
|
156
|
+
list.sort((a, b) => a.t - b.t || a.idx - b.idx);
|
|
157
|
+
let run = [];
|
|
158
|
+
const flush = () => {
|
|
159
|
+
if (run.length >= APPROVAL_LOOP_MIN) {
|
|
160
|
+
const first = run[0].e;
|
|
161
|
+
findings.push({
|
|
162
|
+
detectorId: "approval-loop",
|
|
163
|
+
severity: "medium",
|
|
164
|
+
eventIdx: run.map((x) => x.idx),
|
|
165
|
+
summary: `session ${first.sessionId} hit ${run.length} consecutive REQUIRE_APPROVE on ${first.toolId}`,
|
|
166
|
+
evidence: {
|
|
167
|
+
toolId: first.toolId,
|
|
168
|
+
sessionId: first.sessionId,
|
|
169
|
+
count: run.length,
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
run = [];
|
|
174
|
+
};
|
|
175
|
+
for (const item of list) {
|
|
176
|
+
if (item.e.verdict === "REQUIRE_APPROVE")
|
|
177
|
+
run.push(item);
|
|
178
|
+
else
|
|
179
|
+
flush();
|
|
180
|
+
}
|
|
181
|
+
flush();
|
|
182
|
+
}
|
|
183
|
+
return findings;
|
|
184
|
+
}
|
|
185
|
+
function neverRepeat(events) {
|
|
186
|
+
const byTool = new Map();
|
|
187
|
+
for (let i = 0; i < events.length; i++) {
|
|
188
|
+
const e = events[i];
|
|
189
|
+
if (!isNever(e))
|
|
190
|
+
continue;
|
|
191
|
+
const list = byTool.get(e.toolId) ?? [];
|
|
192
|
+
list.push(i);
|
|
193
|
+
byTool.set(e.toolId, list);
|
|
194
|
+
}
|
|
195
|
+
const findings = [];
|
|
196
|
+
for (const [toolId, idxs] of byTool) {
|
|
197
|
+
if (idxs.length <= 1)
|
|
198
|
+
continue;
|
|
199
|
+
findings.push({
|
|
200
|
+
detectorId: "never-repeat",
|
|
201
|
+
severity: "high",
|
|
202
|
+
eventIdx: idxs,
|
|
203
|
+
summary: `never-list tool ${toolId} attempted ${idxs.length} times`,
|
|
204
|
+
evidence: { toolId, count: idxs.length },
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
return findings;
|
|
208
|
+
}
|
|
209
|
+
function unknownToolHold(events) {
|
|
210
|
+
const byTool = new Map();
|
|
211
|
+
for (let i = 0; i < events.length; i++) {
|
|
212
|
+
const e = events[i];
|
|
213
|
+
if (e.reasonCode !== "UNKNOWN_TOOL" || e.mode !== "hold")
|
|
214
|
+
continue;
|
|
215
|
+
const list = byTool.get(e.toolId) ?? [];
|
|
216
|
+
list.push(i);
|
|
217
|
+
byTool.set(e.toolId, list);
|
|
218
|
+
}
|
|
219
|
+
const findings = [];
|
|
220
|
+
for (const [toolId, idxs] of byTool) {
|
|
221
|
+
findings.push({
|
|
222
|
+
detectorId: "unknown-tool-hold",
|
|
223
|
+
severity: "low",
|
|
224
|
+
eventIdx: idxs,
|
|
225
|
+
summary: `${toolId} evaluated as UNKNOWN_TOOL in hold mode (${idxs.length}x); enforce mode would block it`,
|
|
226
|
+
evidence: { toolId, count: idxs.length },
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
return findings;
|
|
230
|
+
}
|
|
231
|
+
function slowCalls(events) {
|
|
232
|
+
const byTool = new Map();
|
|
233
|
+
for (let i = 0; i < events.length; i++) {
|
|
234
|
+
const e = events[i];
|
|
235
|
+
if (typeof e.latencyMs !== "number")
|
|
236
|
+
continue;
|
|
237
|
+
const list = byTool.get(e.toolId) ?? [];
|
|
238
|
+
list.push({ idx: i, ms: e.latencyMs });
|
|
239
|
+
byTool.set(e.toolId, list);
|
|
240
|
+
}
|
|
241
|
+
const findings = [];
|
|
242
|
+
for (const [toolId, list] of byTool) {
|
|
243
|
+
if (list.length < SLOW_CALL_MIN_SAMPLES)
|
|
244
|
+
continue;
|
|
245
|
+
const sorted = list.map((x) => x.ms).sort((a, b) => a - b);
|
|
246
|
+
const p95 = sorted[Math.ceil(0.95 * sorted.length) - 1];
|
|
247
|
+
if (p95 <= SLOW_CALL_P95_MS)
|
|
248
|
+
continue;
|
|
249
|
+
const slowIdx = list.filter((x) => x.ms >= p95).map((x) => x.idx);
|
|
250
|
+
findings.push({
|
|
251
|
+
detectorId: "slow-calls",
|
|
252
|
+
severity: "low",
|
|
253
|
+
eventIdx: slowIdx,
|
|
254
|
+
summary: `${toolId} p95 latency ${Math.round(p95)}ms across ${list.length} calls (limit ${SLOW_CALL_P95_MS}ms)`,
|
|
255
|
+
evidence: {
|
|
256
|
+
toolId,
|
|
257
|
+
samples: list.length,
|
|
258
|
+
p95Ms: Math.round(p95),
|
|
259
|
+
thresholdMs: SLOW_CALL_P95_MS,
|
|
260
|
+
},
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
return findings;
|
|
264
|
+
}
|
|
265
|
+
export const DETECTORS = [
|
|
266
|
+
{ id: "pii-in-summary", run: piiInSummary },
|
|
267
|
+
{ id: "deny-spike", run: denySpike },
|
|
268
|
+
{ id: "approval-loop", run: approvalLoop },
|
|
269
|
+
{ id: "never-repeat", run: neverRepeat },
|
|
270
|
+
{ id: "unknown-tool-hold", run: unknownToolHold },
|
|
271
|
+
{ id: "slow-calls", run: slowCalls },
|
|
272
|
+
];
|
|
273
|
+
/** Run every detector over the same events array; findings keep input indices. */
|
|
274
|
+
export function runDetectors(events) {
|
|
275
|
+
return DETECTORS.flatMap((d) => d.run(events));
|
|
276
|
+
}
|
|
277
|
+
//# sourceMappingURL=detectors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detectors.js","sourceRoot":"","sources":["../../src/investigate/detectors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fix-brief.d.ts","sourceRoot":"","sources":["../../src/investigate/fix-brief.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAsE/C,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CA4BzD"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
const WHY = {
|
|
2
|
+
"pii-in-summary": "Trail fields are supposed to be redacted; a real email, card number, or token in the local trail means redaction has a hole and the value may also have reached the agent's context or upstream logs.",
|
|
3
|
+
"deny-spike": "Repeated DENY verdicts on one tool mean the agent keeps hitting a policy wall, burning tokens and time instead of changing approach.",
|
|
4
|
+
"approval-loop": "An agent retrying a held action stalls the session and can bury a human reviewer in duplicate approval prompts.",
|
|
5
|
+
"never-repeat": "A never-list rule exists because the action is unacceptable; repeated attempts suggest the agent is routing around an explicit boundary.",
|
|
6
|
+
"unknown-tool-hold": "In hold mode an unknown tool is only recorded; in enforce mode the same call would be blocked, so this is a latent breakage once the gate tightens.",
|
|
7
|
+
"slow-calls": "Gate evaluation latency is on the critical path of every tool call; a high p95 slows the whole agent loop even though latency never changes verdicts.",
|
|
8
|
+
};
|
|
9
|
+
const SUGGESTED_CHANGE = {
|
|
10
|
+
"pii-in-summary": [
|
|
11
|
+
"1. Rotate the leaked value immediately (password, token, or card) and treat it as compromised.",
|
|
12
|
+
"2. Tighten the redaction step that produces `summary` / `diffPreview` / `targetPath` so the leaked pattern is masked before it reaches the trail.",
|
|
13
|
+
"3. Add a regression fixture with the masked shape so the pattern cannot come back.",
|
|
14
|
+
].join("\n"),
|
|
15
|
+
"deny-spike": [
|
|
16
|
+
"1. If the tool should never run, add it to the never-list so attempts fail fast instead of spiking DENYs.",
|
|
17
|
+
"2. If the tool is legitimate, narrow its args in the gate policy so the intended calls pass and the rest still deny.",
|
|
18
|
+
"3. Re-check the live verdict for one call with `kya eval-tool`.",
|
|
19
|
+
].join("\n"),
|
|
20
|
+
"approval-loop": [
|
|
21
|
+
"1. Resolve the pending decision once with `kya approve` or `kya reject` instead of letting the agent retry.",
|
|
22
|
+
"2. If the action is routine, add a scoped allow rule so it stops prompting; if it is unwanted, deny it permanently.",
|
|
23
|
+
"3. Tell the agent not to retry a held call unchanged; it should wait or change approach.",
|
|
24
|
+
].join("\n"),
|
|
25
|
+
"never-repeat": [
|
|
26
|
+
"1. Keep the never rule; it held. Remove the tool from the agent's available toolset or prompt so it stops being proposed.",
|
|
27
|
+
"2. If a variant of the action is legitimately needed, define a narrower tool and allow that instead of loosening the never rule.",
|
|
28
|
+
].join("\n"),
|
|
29
|
+
"unknown-tool-hold": [
|
|
30
|
+
"1. Register the tool in the gate policy or tool pack so it gets a real verdict instead of UNKNOWN_TOOL.",
|
|
31
|
+
"2. If the tool should not exist, remove it from the agent's toolset before the gate moves to enforce mode.",
|
|
32
|
+
"3. Confirm the resolved verdict with `kya eval-tool`.",
|
|
33
|
+
].join("\n"),
|
|
34
|
+
"slow-calls": [
|
|
35
|
+
"1. Profile the evaluate path for the slow tool (local model load, network, or oversized args).",
|
|
36
|
+
"2. Cache stable verdicts or trim args sent to the evaluator; latency is observe-only but it taxes every call.",
|
|
37
|
+
"3. Re-measure after the change and confirm p95 drops below 5000ms.",
|
|
38
|
+
].join("\n"),
|
|
39
|
+
};
|
|
40
|
+
const VERIFY_COMMANDS = {
|
|
41
|
+
"pii-in-summary": ["kya receipt --open", "kya certify"],
|
|
42
|
+
"deny-spike": ["kya eval-tool", "kya certify"],
|
|
43
|
+
"approval-loop": ["kya approvals", "kya receipt --open"],
|
|
44
|
+
"never-repeat": ["kya receipt --open", "kya certify"],
|
|
45
|
+
"unknown-tool-hold": ["kya eval-tool", "kya receipt --open"],
|
|
46
|
+
"slow-calls": ["kya dash", "kya receipt --open"],
|
|
47
|
+
};
|
|
48
|
+
function evidenceLines(incident) {
|
|
49
|
+
const lines = [];
|
|
50
|
+
for (const f of incident.findings) {
|
|
51
|
+
lines.push(`- [${f.severity}] ${f.summary}`);
|
|
52
|
+
const samples = f.evidence.samples;
|
|
53
|
+
if (Array.isArray(samples) && samples.length > 0) {
|
|
54
|
+
lines.push(` - masked samples: ${samples.map(String).join(", ")}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return lines;
|
|
58
|
+
}
|
|
59
|
+
export function renderFixBrief(incident) {
|
|
60
|
+
const detectorId = incident.findings[0]?.detectorId;
|
|
61
|
+
if (!detectorId)
|
|
62
|
+
return `# ${incident.title}\n`;
|
|
63
|
+
const window = incident.firstTs && incident.lastTs
|
|
64
|
+
? `${incident.firstTs} to ${incident.lastTs}`
|
|
65
|
+
: "time unknown";
|
|
66
|
+
return [
|
|
67
|
+
`# Fix brief: ${incident.title}`,
|
|
68
|
+
"",
|
|
69
|
+
`- Incident id: ${incident.id}`,
|
|
70
|
+
`- Severity: ${incident.severity}`,
|
|
71
|
+
`- Findings: ${incident.findingCount}`,
|
|
72
|
+
`- Window: ${window}`,
|
|
73
|
+
"",
|
|
74
|
+
"## What happened",
|
|
75
|
+
...evidenceLines(incident),
|
|
76
|
+
"",
|
|
77
|
+
"## Why it matters",
|
|
78
|
+
WHY[detectorId],
|
|
79
|
+
"",
|
|
80
|
+
"## Suggested change",
|
|
81
|
+
SUGGESTED_CHANGE[detectorId],
|
|
82
|
+
"",
|
|
83
|
+
"## Verify",
|
|
84
|
+
...VERIFY_COMMANDS[detectorId].map((c) => `- \`${c}\``),
|
|
85
|
+
"",
|
|
86
|
+
].join("\n");
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=fix-brief.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fix-brief.js","sourceRoot":"","sources":["../../src/investigate/fix-brief.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Group findings into incidents by (detectorId, toolId-or-session key),
|
|
3
|
+
* sorted by severity rank (critical first) then recency (newest lastTs first).
|
|
4
|
+
*/
|
|
5
|
+
import type { TrailEvent } from "../trail.js";
|
|
6
|
+
import type { Finding, Severity } from "./detectors.js";
|
|
7
|
+
export interface Incident {
|
|
8
|
+
readonly id: string;
|
|
9
|
+
readonly title: string;
|
|
10
|
+
readonly severity: Severity;
|
|
11
|
+
readonly findingCount: number;
|
|
12
|
+
/** Earliest event ts (ISO) across grouped findings; "" when unparseable. */
|
|
13
|
+
readonly firstTs: string;
|
|
14
|
+
/** Latest event ts (ISO) across grouped findings. */
|
|
15
|
+
readonly lastTs: string;
|
|
16
|
+
readonly findings: readonly Finding[];
|
|
17
|
+
}
|
|
18
|
+
export declare function groupIncidents(findings: readonly Finding[], events: readonly TrailEvent[]): Incident[];
|
|
19
|
+
//# sourceMappingURL=incidents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"incidents.d.ts","sourceRoot":"","sources":["../../src/investigate/incidents.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAc,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAEpE,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,4EAA4E;IAC5E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,qDAAqD;IACrD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;CACvC;AA2CD,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,MAAM,EAAE,SAAS,UAAU,EAAE,GAC5B,QAAQ,EAAE,CAqCZ"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
const SEVERITY_RANK = {
|
|
2
|
+
low: 0,
|
|
3
|
+
medium: 1,
|
|
4
|
+
high: 2,
|
|
5
|
+
critical: 3,
|
|
6
|
+
};
|
|
7
|
+
const TITLES = {
|
|
8
|
+
"pii-in-summary": "PII or secret slipped past redaction",
|
|
9
|
+
"deny-spike": "DENY spike on a gated tool",
|
|
10
|
+
"approval-loop": "Agent stuck in an approval loop",
|
|
11
|
+
"never-repeat": "Never-list tool attempted repeatedly",
|
|
12
|
+
"unknown-tool-hold": "Unknown tool evaluated in hold mode",
|
|
13
|
+
"slow-calls": "Slow gate evaluations",
|
|
14
|
+
};
|
|
15
|
+
function findingKey(f) {
|
|
16
|
+
const toolId = f.evidence.toolId;
|
|
17
|
+
if (typeof toolId === "string" && toolId)
|
|
18
|
+
return `tool:${toolId}`;
|
|
19
|
+
const sessionId = f.evidence.sessionId;
|
|
20
|
+
if (typeof sessionId === "string" && sessionId)
|
|
21
|
+
return `session:${sessionId}`;
|
|
22
|
+
return "global";
|
|
23
|
+
}
|
|
24
|
+
function slug(s) {
|
|
25
|
+
const out = s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
26
|
+
return out.length > 48 ? out.slice(0, 48) : out;
|
|
27
|
+
}
|
|
28
|
+
function tsRange(finding, events) {
|
|
29
|
+
let min = Number.POSITIVE_INFINITY;
|
|
30
|
+
let max = Number.NEGATIVE_INFINITY;
|
|
31
|
+
for (const idx of finding.eventIdx) {
|
|
32
|
+
const t = Date.parse(events[idx]?.ts ?? "");
|
|
33
|
+
if (Number.isNaN(t))
|
|
34
|
+
continue;
|
|
35
|
+
if (t < min)
|
|
36
|
+
min = t;
|
|
37
|
+
if (t > max)
|
|
38
|
+
max = t;
|
|
39
|
+
}
|
|
40
|
+
return { min, max };
|
|
41
|
+
}
|
|
42
|
+
export function groupIncidents(findings, events) {
|
|
43
|
+
const groups = new Map();
|
|
44
|
+
for (const f of findings) {
|
|
45
|
+
const key = `${f.detectorId}:${findingKey(f)}`;
|
|
46
|
+
const list = groups.get(key) ?? [];
|
|
47
|
+
list.push(f);
|
|
48
|
+
groups.set(key, list);
|
|
49
|
+
}
|
|
50
|
+
const incidents = [];
|
|
51
|
+
for (const list of groups.values()) {
|
|
52
|
+
let severity = "low";
|
|
53
|
+
let min = Number.POSITIVE_INFINITY;
|
|
54
|
+
let max = Number.NEGATIVE_INFINITY;
|
|
55
|
+
for (const f of list) {
|
|
56
|
+
if (SEVERITY_RANK[f.severity] > SEVERITY_RANK[severity])
|
|
57
|
+
severity = f.severity;
|
|
58
|
+
const r = tsRange(f, events);
|
|
59
|
+
if (r.min < min)
|
|
60
|
+
min = r.min;
|
|
61
|
+
if (r.max > max)
|
|
62
|
+
max = r.max;
|
|
63
|
+
}
|
|
64
|
+
const detectorId = list[0].detectorId;
|
|
65
|
+
const groupKey = findingKey(list[0]);
|
|
66
|
+
incidents.push({
|
|
67
|
+
id: slug(`${detectorId}-${groupKey}`),
|
|
68
|
+
title: `${TITLES[detectorId]} (${groupKey.replace(/^(tool|session):/, "")})`,
|
|
69
|
+
severity,
|
|
70
|
+
findingCount: list.length,
|
|
71
|
+
firstTs: Number.isFinite(min) ? new Date(min).toISOString() : "",
|
|
72
|
+
lastTs: Number.isFinite(max) ? new Date(max).toISOString() : "",
|
|
73
|
+
findings: list,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
incidents.sort((a, b) => {
|
|
77
|
+
const rankDiff = SEVERITY_RANK[b.severity] - SEVERITY_RANK[a.severity];
|
|
78
|
+
if (rankDiff !== 0)
|
|
79
|
+
return rankDiff;
|
|
80
|
+
return Date.parse(b.lastTs) - Date.parse(a.lastTs);
|
|
81
|
+
});
|
|
82
|
+
return incidents;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=incidents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"incidents.js","sourceRoot":"","sources":["../../src/investigate/incidents.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `kya investigate` core: deterministic detectors + incident grouping +
|
|
3
|
+
* fix briefs over the local trail. Pure analysis, no LLM calls, no IO;
|
|
4
|
+
* the CLI wires readTrail() output into investigateTrail().
|
|
5
|
+
*/
|
|
6
|
+
import type { TrailEvent } from "../trail.js";
|
|
7
|
+
import { type Finding } from "./detectors.js";
|
|
8
|
+
import { type Incident } from "./incidents.js";
|
|
9
|
+
export type { DetectorId, Finding, Severity } from "./detectors.js";
|
|
10
|
+
export type { Incident } from "./incidents.js";
|
|
11
|
+
export { renderFixBrief } from "./fix-brief.js";
|
|
12
|
+
export interface InvestigateOptions {
|
|
13
|
+
/** Cap the number of incidents listed in the plain-text report. */
|
|
14
|
+
readonly topIncidents?: number;
|
|
15
|
+
}
|
|
16
|
+
export interface InvestigateResult {
|
|
17
|
+
readonly findings: readonly Finding[];
|
|
18
|
+
readonly incidents: readonly Incident[];
|
|
19
|
+
/** incidentId -> markdown fix brief. */
|
|
20
|
+
readonly briefs: ReadonlyMap<string, string>;
|
|
21
|
+
}
|
|
22
|
+
export declare function investigateTrail(events: readonly TrailEvent[], _opts?: InvestigateOptions): InvestigateResult;
|
|
23
|
+
/** Plain-text summary for the CLI: counts by severity, then top incidents. */
|
|
24
|
+
export declare function renderInvestigateReport(result: InvestigateResult, opts?: InvestigateOptions): string;
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/investigate/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAgB,KAAK,OAAO,EAAiB,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG/D,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACpE,YAAY,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,WAAW,kBAAkB;IACjC,mEAAmE;IACnE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;IACtC,QAAQ,CAAC,SAAS,EAAE,SAAS,QAAQ,EAAE,CAAC;IACxC,wCAAwC;IACxC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9C;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,UAAU,EAAE,EAC7B,KAAK,GAAE,kBAAuB,GAC7B,iBAAiB,CAQnB;AAID,8EAA8E;AAC9E,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,iBAAiB,EACzB,IAAI,GAAE,kBAAuB,GAC5B,MAAM,CAiCR"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { runDetectors } from "./detectors.js";
|
|
2
|
+
import { groupIncidents } from "./incidents.js";
|
|
3
|
+
import { renderFixBrief } from "./fix-brief.js";
|
|
4
|
+
export { renderFixBrief } from "./fix-brief.js";
|
|
5
|
+
export function investigateTrail(events, _opts = {}) {
|
|
6
|
+
const findings = runDetectors(events);
|
|
7
|
+
const incidents = groupIncidents(findings, events);
|
|
8
|
+
const briefs = new Map();
|
|
9
|
+
for (const incident of incidents) {
|
|
10
|
+
briefs.set(incident.id, renderFixBrief(incident));
|
|
11
|
+
}
|
|
12
|
+
return { findings, incidents, briefs };
|
|
13
|
+
}
|
|
14
|
+
const SEVERITY_ORDER = ["critical", "high", "medium", "low"];
|
|
15
|
+
/** Plain-text summary for the CLI: counts by severity, then top incidents. */
|
|
16
|
+
export function renderInvestigateReport(result, opts = {}) {
|
|
17
|
+
const top = opts.topIncidents ?? 10;
|
|
18
|
+
const lines = [];
|
|
19
|
+
lines.push("kya investigate - local trail analysis");
|
|
20
|
+
lines.push("");
|
|
21
|
+
if (result.findings.length === 0) {
|
|
22
|
+
lines.push("No findings. The trail looks clean for all detectors.");
|
|
23
|
+
return lines.join("\n");
|
|
24
|
+
}
|
|
25
|
+
const bySeverity = new Map();
|
|
26
|
+
for (const f of result.findings) {
|
|
27
|
+
bySeverity.set(f.severity, (bySeverity.get(f.severity) ?? 0) + 1);
|
|
28
|
+
}
|
|
29
|
+
lines.push(`Findings: ${result.findings.length} (${SEVERITY_ORDER
|
|
30
|
+
.filter((s) => bySeverity.has(s))
|
|
31
|
+
.map((s) => `${s}: ${bySeverity.get(s)}`)
|
|
32
|
+
.join(", ")})`);
|
|
33
|
+
lines.push(`Incidents: ${result.incidents.length}`);
|
|
34
|
+
lines.push("");
|
|
35
|
+
lines.push("Top incidents:");
|
|
36
|
+
for (const incident of result.incidents.slice(0, top)) {
|
|
37
|
+
lines.push(`- [${incident.severity}] ${incident.title} ` +
|
|
38
|
+
`(${incident.findingCount} finding${incident.findingCount === 1 ? "" : "s"}, ` +
|
|
39
|
+
`last ${incident.lastTs || "unknown"}, id ${incident.id})`);
|
|
40
|
+
}
|
|
41
|
+
if (result.incidents.length > top) {
|
|
42
|
+
lines.push(`- ... and ${result.incidents.length - top} more`);
|
|
43
|
+
}
|
|
44
|
+
return lines.join("\n");
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/investigate/index.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp/protocol.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* MCP tool surface for local gate
|
|
2
|
+
* MCP tool surface for local gate - proxies to Shield KYA (sole PEP).
|
|
3
3
|
* Does not execute irreversible side effects; only evaluate / ingest / request approval.
|
|
4
4
|
* Host-agnostic: stdio or HTTP transport.
|
|
5
5
|
*/
|
|
@@ -29,7 +29,7 @@ export interface McpHandlerContext {
|
|
|
29
29
|
readonly client: KyaHttpClient;
|
|
30
30
|
readonly host: Host;
|
|
31
31
|
readonly agentId?: string;
|
|
32
|
-
/** Offline sample evaluate (KYA_OFFLINE=1)
|
|
32
|
+
/** Offline sample evaluate (KYA_OFFLINE=1) - no HTTP, never fails on a dead plane. */
|
|
33
33
|
readonly offline?: boolean;
|
|
34
34
|
/** Trail recording target; absent in contexts that must not record. */
|
|
35
35
|
readonly trail?: McpTrailContext;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/mcp/protocol.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,aAAa,EAA0B,MAAM,cAAc,CAAC;AAC1E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/mcp/protocol.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,aAAa,EAA0B,MAAM,cAAc,CAAC;AAC1E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAczC,eAAO,MAAM,eAAe;;;;;CAMlB,CAAC;AAEX,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/C;AAED,eAAO,MAAM,SAAS,EAAE,SAAS,UAAU,EAsEjC,CAAC;AAEX,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,SAAS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5D,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;CACtC;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,sFAAsF;IACtF,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,uEAAuE;IACvE,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,CAAC;CAClC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CAC/B;AAwDD,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EACzC,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,aAAa,CAAC,CAgBxB;AA8MD,0CAA0C;AAC1C,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;AAE/C,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,KAAK,CAAC;IACf,EAAE,CAAC,EAAE,SAAS,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,KAAK,CAAC;IACf,EAAE,EAAE,SAAS,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CAC3D;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CA0EjC"}
|