@descryy/mcp 0.11.2 → 0.11.4
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/dist/bin/descry-mcp.js +6 -0
- package/dist/bin/descry-mcp.js.map +1 -1
- package/dist/browser/auth.d.ts +8 -0
- package/dist/browser/auth.d.ts.map +1 -1
- package/dist/browser/auth.js +12 -2
- package/dist/browser/auth.js.map +1 -1
- package/dist/browser/driver.d.ts +21 -0
- package/dist/browser/driver.d.ts.map +1 -1
- package/dist/browser/playwright-driver.d.ts.map +1 -1
- package/dist/browser/playwright-driver.js +39 -0
- package/dist/browser/playwright-driver.js.map +1 -1
- package/dist/browser/reach-recording-session.d.ts.map +1 -1
- package/dist/browser/reach-recording-session.js +8 -0
- package/dist/browser/reach-recording-session.js.map +1 -1
- package/dist/capped.d.ts +22 -0
- package/dist/capped.d.ts.map +1 -1
- package/dist/capped.js +28 -0
- package/dist/capped.js.map +1 -1
- package/dist/credential-store.d.ts +22 -0
- package/dist/credential-store.d.ts.map +1 -0
- package/dist/credential-store.js +33 -0
- package/dist/credential-store.js.map +1 -0
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/planner/predict-then-propose.d.ts +34 -1
- package/dist/planner/predict-then-propose.d.ts.map +1 -1
- package/dist/planner/predict-then-propose.js +51 -1
- package/dist/planner/predict-then-propose.js.map +1 -1
- package/dist/planner/propose-journey.d.ts +15 -0
- package/dist/planner/propose-journey.d.ts.map +1 -1
- package/dist/planner/propose-journey.js.map +1 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +8 -0
- package/dist/registry.js.map +1 -1
- package/dist/render.d.ts +44 -1
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +104 -3
- package/dist/render.js.map +1 -1
- package/dist/scenarios/browser-run-plan-projection.d.ts +24 -6
- package/dist/scenarios/browser-run-plan-projection.d.ts.map +1 -1
- package/dist/scenarios/browser-run-plan-projection.js +45 -9
- package/dist/scenarios/browser-run-plan-projection.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +122 -12
- package/dist/server.js.map +1 -1
- package/dist/session.d.ts +114 -1
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +178 -1
- package/dist/session.js.map +1 -1
- package/dist/tools/browser-run-scenario.d.ts.map +1 -1
- package/dist/tools/browser-run-scenario.js +19 -0
- package/dist/tools/browser-run-scenario.js.map +1 -1
- package/dist/tools/browser-start-session.d.ts.map +1 -1
- package/dist/tools/browser-start-session.js +75 -11
- package/dist/tools/browser-start-session.js.map +1 -1
- package/dist/tools/browser.d.ts.map +1 -1
- package/dist/tools/browser.js +9 -0
- package/dist/tools/browser.js.map +1 -1
- package/dist/tools/code-context.d.ts.map +1 -1
- package/dist/tools/code-context.js +61 -33
- package/dist/tools/code-context.js.map +1 -1
- package/dist/tools/cross-pr.d.ts.map +1 -1
- package/dist/tools/cross-pr.js +85 -36
- package/dist/tools/cross-pr.js.map +1 -1
- package/dist/tools/disclosure.d.ts.map +1 -1
- package/dist/tools/disclosure.js +25 -6
- package/dist/tools/disclosure.js.map +1 -1
- package/dist/tools/git-context.d.ts.map +1 -1
- package/dist/tools/git-context.js +22 -1
- package/dist/tools/git-context.js.map +1 -1
- package/dist/tools/git-history.d.ts.map +1 -1
- package/dist/tools/git-history.js +20 -0
- package/dist/tools/git-history.js.map +1 -1
- package/dist/tools/index.d.ts +3 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +5 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/observe-runtime.d.ts +40 -1
- package/dist/tools/observe-runtime.d.ts.map +1 -1
- package/dist/tools/observe-runtime.js +389 -15
- package/dist/tools/observe-runtime.js.map +1 -1
- package/dist/tools/observe.d.ts.map +1 -1
- package/dist/tools/observe.js +45 -0
- package/dist/tools/observe.js.map +1 -1
- package/dist/tools/pr-analysis.d.ts.map +1 -1
- package/dist/tools/pr-analysis.js +86 -11
- package/dist/tools/pr-analysis.js.map +1 -1
- package/dist/tools/prove-reach.d.ts +74 -0
- package/dist/tools/prove-reach.d.ts.map +1 -0
- package/dist/tools/prove-reach.js +286 -0
- package/dist/tools/prove-reach.js.map +1 -0
- package/dist/tools/refusal-fetch.d.ts.map +1 -1
- package/dist/tools/refusal-fetch.js +31 -11
- package/dist/tools/refusal-fetch.js.map +1 -1
- package/dist/tools/scope.d.ts.map +1 -1
- package/dist/tools/scope.js +42 -11
- package/dist/tools/scope.js.map +1 -1
- package/dist/tools/similar-incidents.d.ts.map +1 -1
- package/dist/tools/similar-incidents.js +42 -18
- package/dist/tools/similar-incidents.js.map +1 -1
- package/dist/tools/validate.d.ts.map +1 -1
- package/dist/tools/validate.js +145 -67
- package/dist/tools/validate.js.map +1 -1
- package/package.json +30 -26
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prove-reach.d.ts","sourceRoot":"","sources":["../../src/tools/prove-reach.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAeH,OAAO,EAML,KAAK,WAAW,EACjB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAG1E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAML,KAAK,SAAS,EACd,KAAK,cAAc,EAEnB,KAAK,cAAc,EACpB,MAAM,UAAU,CAAC;AAIlB,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,QAAQ,GAAG,YAAY,GAAG,YAAY,CAAC;IACpE,QAAQ,CAAC,KAAK,EAAE,SAAS;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC7E,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACrC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,SAAS,SAAS,EAAE,CAAC;IAC5C,QAAQ,CAAC,QAAQ,EAAE;QAAE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;QAAC,QAAQ,CAAC,kBAAkB,EAAE,SAAS,oBAAoB,EAAE,CAAA;KAAE,GAAG,IAAI,CAAC;IACxH;+FAC2F;IAC3F,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IACnC;8EAC0E;IAC1E,QAAQ,CAAC,UAAU,EAAE;QACnB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;QAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;QAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAC5B,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;QACxC,QAAQ,CAAC,uBAAuB,EAAE,OAAO,CAAC;QAC1C,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;KACtC,GAAG,IAAI,CAAC;CACV;AAED,MAAM,MAAM,cAAc,GAAG,gBAAgB,GAAG,cAAc,CAAC;AA6Q/D,eAAO,MAAM,cAAc,EAAE,cAmB5B,CAAC"}
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `prove_reach` — closes RG-10's loop. "Rename that column and these screens go blank" is
|
|
3
|
+
* three claims, made in order, each on evidence the last one didn't have:
|
|
4
|
+
*
|
|
5
|
+
* 1. **Predict** — from a node (typically a `DATABASE_COLUMN`), walk `reachablePages`
|
|
6
|
+
* (`@descryy/core`) to whatever `PAGE`/`COMPONENT` nodes the data reaches, and propose a
|
|
7
|
+
* navigate-only journey to them, exactly as `predict_reach` already does — this tool calls
|
|
8
|
+
* the identical pure planner (`../planner/predict-then-propose.ts#predictThenPropose`), never
|
|
9
|
+
* a second implementation. Nothing runs yet: a caller who has not yet approved the drive gets
|
|
10
|
+
* back the prediction, the proposal and a confirmation token, and this tool's `describeAction`
|
|
11
|
+
* is what mints that token — the dispatcher (`../action-handshake.ts`) never calls `run` at
|
|
12
|
+
* all until the second call arrives, so "nothing runs" is structural, not a promise this file
|
|
13
|
+
* keeps by convention.
|
|
14
|
+
* 2. **Approve and drive** — a second call, `confirmToken` in hand, drives the exact proposed
|
|
15
|
+
* scenario for real via `../browser/scenario-runner.ts#replayScenario`, in a browser session
|
|
16
|
+
* the caller already started and consented (`browser({ verb: "start_session" })`). Never boots an app,
|
|
17
|
+
* never widens the journey beyond what was proposed: the scenario driven is the one frozen at
|
|
18
|
+
* mint time, byte for byte.
|
|
19
|
+
* 3. **Prove** — correlates which of the predicted pages the drive's own step results actually
|
|
20
|
+
* reached (`../planner/predict-then-propose.ts#visitedPageIds` + `#proveOrDisprove`) — a page
|
|
21
|
+
* counts as visited only when the exact navigate URL built from its own route name replayed
|
|
22
|
+
* as `"ran"`, never a guess from proximity.
|
|
23
|
+
* 4. **Conclude** — routes the real, walked graph path (`#combinedGraphPath`, never a synthesised
|
|
24
|
+
* one) and the runtime evidence the drive actually observed (console errors, failed requests)
|
|
25
|
+
* through the same finding funnel `draw_conclusion` uses — `reportCategory`, `@descryy/ir`,
|
|
26
|
+
* `packages/ir/src/finding.ts` — so the reply carries a governed category, not a raw tally the
|
|
27
|
+
* caller has to interpret. A drive that reached every predicted page cleanly, with nothing
|
|
28
|
+
* wrong observed, reports so honestly: `hasRuntimeEvidence` is false and the category is
|
|
29
|
+
* `unconfirmed` by G3's own precondition, not "confirmed" because the pages loaded.
|
|
30
|
+
*
|
|
31
|
+
* **class: "action"**, gated only when there is something to drive: a node that reaches nothing,
|
|
32
|
+
* or reaches only non-path-shaped pages/components with no navigate step to propose, has nothing
|
|
33
|
+
* to approve, so `describeAction` returns `undefined` and this reports the prediction immediately
|
|
34
|
+
* — same discipline as `predict_reach`'s own empty case, never a gate for its own sake.
|
|
35
|
+
*/
|
|
36
|
+
import { directMechanismEvidence, evidencePrecondition, humanAssertedOnPath, independentSignalTypes, minimumResolution, reportCategory, } from "@descryy/ir";
|
|
37
|
+
import { combinedGraphPath, predictThenPropose, proveOrDisprove, visitedPageIds, } from "../planner/predict-then-propose.js";
|
|
38
|
+
import { browserAnswer, mutationRefusal, useSession, withinConsent } from "../browser/tool-support.js";
|
|
39
|
+
import { mutates, replayScenario } from "../browser/scenario-runner.js";
|
|
40
|
+
import { answer, briefNode, requiredString, optionalString, ToolInputError, } from "./kit.js";
|
|
41
|
+
import { resolveOneNode } from "./lookup.js";
|
|
42
|
+
const SCHEMA = {
|
|
43
|
+
type: "object",
|
|
44
|
+
properties: {
|
|
45
|
+
nodeId: { type: "string", description: "Graph node id to predict reach from — typically a DATABASE_COLUMN." },
|
|
46
|
+
symbol: {
|
|
47
|
+
type: "string",
|
|
48
|
+
description: "Symbol name to start from, when you do not have a node id. Ambiguity is reported rather than guessed at — narrow it with \"file\".",
|
|
49
|
+
},
|
|
50
|
+
file: { type: "string", description: "Repository-relative path, to disambiguate \"symbol\" or to start from a file." },
|
|
51
|
+
targetUrl: {
|
|
52
|
+
type: "string",
|
|
53
|
+
description: "REQUIRED. The running application's base URL — the same origin the browser session named in \"sessionId\" was consented for.",
|
|
54
|
+
},
|
|
55
|
+
sessionId: {
|
|
56
|
+
type: "string",
|
|
57
|
+
description: "REQUIRED. A browser session id from browser({ verb: \"start_session\" }), already consented for targetUrl's origin. " +
|
|
58
|
+
"This tool never starts a browser itself and never widens consent beyond that session's own.",
|
|
59
|
+
},
|
|
60
|
+
name: { type: "string", description: "What to call the proposed scenario. Defaults to \"predicted-journey\"." },
|
|
61
|
+
confirmToken: {
|
|
62
|
+
type: "string",
|
|
63
|
+
description: "The token returned by a previous call. The first call predicts and proposes but drives nothing; call " +
|
|
64
|
+
"again with \"confirmToken\" to actually drive the proposed journey and correlate the result — with " +
|
|
65
|
+
"the arguments frozen when the token was minted, never whatever the confirming call supplies, so " +
|
|
66
|
+
"changing nodeId, targetUrl, sessionId or any other field on the confirming call is discarded rather " +
|
|
67
|
+
"than applied, and the reply discloses that it was; call again without confirmToken for a fresh token " +
|
|
68
|
+
"if something needs to change. A token is single-use, expires, and is only valid for this tool.",
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
required: ["targetUrl", "sessionId"],
|
|
72
|
+
additionalProperties: false,
|
|
73
|
+
};
|
|
74
|
+
/** Resolves the start node and computes the identical prediction `predict_reach` would, from the
|
|
75
|
+
* same pure planner. Shared by `describeAction` and `run` so the two can never compute two
|
|
76
|
+
* different predictions for what a caller reads as one call. */
|
|
77
|
+
function prepare(args, ctx) {
|
|
78
|
+
const nodeIdArg = optionalString(args, "nodeId");
|
|
79
|
+
const symbol = optionalString(args, "symbol");
|
|
80
|
+
const file = optionalString(args, "file");
|
|
81
|
+
const targetUrl = requiredString(args, "targetUrl");
|
|
82
|
+
const sessionId = requiredString(args, "sessionId");
|
|
83
|
+
const name = optionalString(args, "name") ?? "predicted-journey";
|
|
84
|
+
if (nodeIdArg === undefined && symbol === undefined && file === undefined) {
|
|
85
|
+
throw new ToolInputError('give one of "nodeId", "symbol" or "file"');
|
|
86
|
+
}
|
|
87
|
+
const found = resolveOneNode(ctx.session, { nodeId: nodeIdArg, symbol, file });
|
|
88
|
+
if (found.node === null) {
|
|
89
|
+
return { ok: false, candidates: found.candidates.map(briefNode), headline: found.headline, notes: found.notes };
|
|
90
|
+
}
|
|
91
|
+
const provider = ctx.session.provider();
|
|
92
|
+
const base = provider.baseStamp();
|
|
93
|
+
const predicted = predictThenPropose(provider, found.node.id, { targetUrl, name, savedAtCommit: base.commitSha ?? "" });
|
|
94
|
+
return { ok: true, value: { node: found.node, predicted, targetUrl, sessionId } };
|
|
95
|
+
}
|
|
96
|
+
function drivable(predicted) {
|
|
97
|
+
return predicted.proposal !== null && predicted.proposal.scenario.steps.length > 0;
|
|
98
|
+
}
|
|
99
|
+
function emptyReport(node, predicted) {
|
|
100
|
+
return {
|
|
101
|
+
from: node === null ? { id: "", type: "", name: "", resolution: 0 } : briefNode(node),
|
|
102
|
+
reachedPages: predicted === null ? [] : predicted.reachedPages.map((n) => ({ id: n.id, type: n.type, name: n.name, resolution: 0 })),
|
|
103
|
+
proposal: predicted?.proposal === null || predicted === null
|
|
104
|
+
? null
|
|
105
|
+
: { scenario: predicted.proposal.scenario, reachedNotProposed: predicted.proposal.reachedNotProposed },
|
|
106
|
+
drive: null,
|
|
107
|
+
proof: null,
|
|
108
|
+
conclusion: null,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
async function describeAction(args, ctx) {
|
|
112
|
+
const prep = prepare(args, ctx);
|
|
113
|
+
if (!prep.ok)
|
|
114
|
+
return undefined; // nothing resolvable — run() reports the refusal immediately, no gate
|
|
115
|
+
const { node, predicted, sessionId } = prep.value;
|
|
116
|
+
if (!drivable(predicted))
|
|
117
|
+
return undefined; // nothing to drive — run() reports the prediction alone
|
|
118
|
+
const steps = predicted.proposal.scenario.steps.length;
|
|
119
|
+
const pageNames = predicted.reachedPages.map((p) => p.name);
|
|
120
|
+
return (`drive ${steps} navigate step(s) in browser session "${sessionId}", toward ${predicted.reachedPages.length} ` +
|
|
121
|
+
`predicted page/component reached from ${node.name} (${pageNames.slice(0, 5).join(", ")}${pageNames.length > 5 ? ", …" : ""}), ` +
|
|
122
|
+
"then correlate what the drive actually reached — and any console error or failed request observed while " +
|
|
123
|
+
"it ran — into a governed finding via the same gate draw_conclusion uses.");
|
|
124
|
+
}
|
|
125
|
+
async function run(args, ctx) {
|
|
126
|
+
const prep = prepare(args, ctx);
|
|
127
|
+
const base = ctx.session.provider().baseStamp();
|
|
128
|
+
if (!prep.ok) {
|
|
129
|
+
return {
|
|
130
|
+
result: { data: { candidates: prep.candidates }, stamp: { ...base, resolutionFloor: 0 }, truncated: false, notes: prep.notes },
|
|
131
|
+
nameLevel: true,
|
|
132
|
+
state: "refused",
|
|
133
|
+
headline: prep.headline,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
const { node, predicted, targetUrl, sessionId } = prep.value;
|
|
137
|
+
const notes = [...predicted.notes];
|
|
138
|
+
if (!drivable(predicted)) {
|
|
139
|
+
return answer({
|
|
140
|
+
headline: predicted.proposal === null
|
|
141
|
+
? `${node.name} reaches no PAGE or COMPONENT this graph can walk to. Not a claim it reaches none in the running application — see notes.`
|
|
142
|
+
: `${node.name} reaches ${predicted.reachedPages.length} page/component, but none has a path-shaped route name — nothing to drive or prove.`,
|
|
143
|
+
state: "empty",
|
|
144
|
+
nameLevel: true,
|
|
145
|
+
resolutionFloor: 0,
|
|
146
|
+
commitSha: base.commitSha,
|
|
147
|
+
graphBuiltAt: base.graphBuiltAt,
|
|
148
|
+
irSchemaVersion: base.irSchemaVersion,
|
|
149
|
+
commitSpread: base.commitSpread,
|
|
150
|
+
repoCount: base.repoCount,
|
|
151
|
+
notes,
|
|
152
|
+
data: emptyReport(node, predicted),
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
// A non-empty proposal only reaches this line once the two-call handshake has already
|
|
156
|
+
// approved it — `describeAction` above gates every other case. Drive it, exactly as proposed.
|
|
157
|
+
const scenario = predicted.proposal.scenario;
|
|
158
|
+
const found = await useSession(ctx.session.browserSessions(), sessionId);
|
|
159
|
+
if (!found.ok) {
|
|
160
|
+
return browserAnswer({
|
|
161
|
+
ctx,
|
|
162
|
+
state: found.dead.state,
|
|
163
|
+
headline: found.dead.headline,
|
|
164
|
+
notes: [...notes, ...found.dead.notes],
|
|
165
|
+
data: emptyReport(node, predicted),
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
const { entry } = found;
|
|
169
|
+
if (!withinConsent(entry, targetUrl)) {
|
|
170
|
+
return browserAnswer({
|
|
171
|
+
ctx,
|
|
172
|
+
state: "refused",
|
|
173
|
+
headline: `The predicted journey targets ${targetUrl}, outside this session's consent.`,
|
|
174
|
+
notes: [
|
|
175
|
+
...notes,
|
|
176
|
+
`This session was consented for ${entry.consentedOrigin} only. Start a session against that origin to drive this prediction.`,
|
|
177
|
+
],
|
|
178
|
+
data: emptyReport(node, predicted),
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
const refusedForSafety = mutationRefusal(entry);
|
|
182
|
+
if (refusedForSafety !== null && mutates(scenario)) {
|
|
183
|
+
// Dead in practice — proposeJourney only ever emits navigate steps — kept for the day a
|
|
184
|
+
// future planner proposes more, so a readOnly profile still refuses rather than driving.
|
|
185
|
+
return browserAnswer({
|
|
186
|
+
ctx,
|
|
187
|
+
state: "refused",
|
|
188
|
+
headline: `${entry.profile?.name ?? "This environment"} is read-only.`,
|
|
189
|
+
notes: [...notes, refusedForSafety],
|
|
190
|
+
data: emptyReport(node, predicted),
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
if (entry.page.currentUrl() !== scenario.targetUrl) {
|
|
194
|
+
await entry.page.navigate(scenario.targetUrl);
|
|
195
|
+
}
|
|
196
|
+
ctx.progress(`Driving the predicted journey from ${node.name}`);
|
|
197
|
+
const replay = await replayScenario(ctx, ctx.session.browserSessions(), sessionId, scenario, process.env, ctx.session.credentialStore);
|
|
198
|
+
const visited = visitedPageIds(predicted, targetUrl, replay.steps.map((s) => ({ url: s.url, status: s.status })));
|
|
199
|
+
const proof = proveOrDisprove(predicted, { visitedNodeIds: visited });
|
|
200
|
+
// The hypothesis's own structural mechanism — every page the walk predicted, not only the ones
|
|
201
|
+
// this one drive happened to confirm — so the finding's graphPath describes what the graph
|
|
202
|
+
// claims propagates, and the runtime evidence below is what says whether it broke anything.
|
|
203
|
+
const graphPath = combinedGraphPath(predicted, predicted.reachedPages.map((p) => p.id));
|
|
204
|
+
const runtimeEvidence = [
|
|
205
|
+
...replay.evidence.consoleErrors.map((e) => ({ signal: "browser-console", detail: e.text, directMechanism: false })),
|
|
206
|
+
...replay.evidence.failedRequests.map((r) => {
|
|
207
|
+
const reached = replay.graph.reached.find((n) => n.via.method === r.method && n.via.url === r.url);
|
|
208
|
+
return {
|
|
209
|
+
signal: "network",
|
|
210
|
+
detail: `${r.method} ${r.url} failed${r.status === null ? "" : ` (status ${r.status})`}`,
|
|
211
|
+
...(reached === undefined ? {} : { nodeId: reached.nodeId, directMechanism: reached.nodeId === node.id }),
|
|
212
|
+
};
|
|
213
|
+
}),
|
|
214
|
+
];
|
|
215
|
+
const hasRuntimeEvidence = evidencePrecondition(runtimeEvidence);
|
|
216
|
+
const resolution = minimumResolution(graphPath);
|
|
217
|
+
const humanAsserted = humanAssertedOnPath(graphPath);
|
|
218
|
+
const eSignals = independentSignalTypes(runtimeEvidence);
|
|
219
|
+
const mMechanism = directMechanismEvidence(runtimeEvidence, node.id);
|
|
220
|
+
const gated = reportCategory({
|
|
221
|
+
hasRuntimeEvidence,
|
|
222
|
+
independentSignalTypes: eSignals,
|
|
223
|
+
directMechanismEvidence: mMechanism,
|
|
224
|
+
resolution,
|
|
225
|
+
// Name-level throughout — a route path is read off a node's qualified name, same as
|
|
226
|
+
// predict_reach's own cap, never a type-checked shape.
|
|
227
|
+
nameLevel: true,
|
|
228
|
+
humanAsserted,
|
|
229
|
+
});
|
|
230
|
+
const proofNotes = [
|
|
231
|
+
`Drove the proposed journey for real: ${proof.proven.length} of ${predicted.reachedPages.length} predicted ` +
|
|
232
|
+
`page(s)/component(s) confirmed reached, ${proof.disproven.length} not reached by this drive.`,
|
|
233
|
+
hasRuntimeEvidence
|
|
234
|
+
? `${runtimeEvidence.length} runtime observation(s) fed the gate — ${replay.evidence.consoleErrors.length} console error(s), ` +
|
|
235
|
+
`${replay.evidence.failedRequests.length} failed request(s).`
|
|
236
|
+
: "No console error or failed request was observed during this drive, so G3's evidence precondition fails " +
|
|
237
|
+
"and this reports unconfirmed regardless of the graph path — reaching a page cleanly is not evidence it broke.",
|
|
238
|
+
];
|
|
239
|
+
return browserAnswer({
|
|
240
|
+
ctx,
|
|
241
|
+
headline: `"${node.name}": ${gated.category} (reliability ${gated.reliabilityClass}). Drove ${scenario.steps.length} step(s), ` +
|
|
242
|
+
`${proof.proven.length} predicted page(s) confirmed reached, ${proof.disproven.length} not.`,
|
|
243
|
+
notes: [...notes, ...proofNotes, ...replay.notes],
|
|
244
|
+
data: {
|
|
245
|
+
from: briefNode(node),
|
|
246
|
+
reachedPages: predicted.reachedPages.map((n) => ({ id: n.id, type: n.type, name: n.name, resolution: 0 })),
|
|
247
|
+
proposal: { scenario: predicted.proposal.scenario, reachedNotProposed: predicted.proposal.reachedNotProposed },
|
|
248
|
+
drive: {
|
|
249
|
+
outcome: replay.outcome,
|
|
250
|
+
steps: replay.steps.map((s) => ({ url: s.url, status: s.status })),
|
|
251
|
+
consoleErrorCount: replay.evidence.consoleErrors.length,
|
|
252
|
+
failedRequestCount: replay.evidence.failedRequests.length,
|
|
253
|
+
},
|
|
254
|
+
proof,
|
|
255
|
+
conclusion: {
|
|
256
|
+
failurePoint: node.id,
|
|
257
|
+
category: gated.category,
|
|
258
|
+
reliabilityClass: gated.reliabilityClass,
|
|
259
|
+
resolution,
|
|
260
|
+
independentSignalTypes: eSignals,
|
|
261
|
+
directMechanismEvidence: mMechanism,
|
|
262
|
+
hasRuntimeEvidence,
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
export const proveReachTool = {
|
|
268
|
+
name: "prove_reach",
|
|
269
|
+
class: "action",
|
|
270
|
+
tier: "conclusion",
|
|
271
|
+
version: "1.0.0",
|
|
272
|
+
title: "Predict which pages a data change reaches, then drive a real browser to prove or disprove it",
|
|
273
|
+
description: "RG-10's full loop: predicts which PAGE/COMPONENT nodes a node (typically a DATABASE_COLUMN) reaches, " +
|
|
274
|
+
"exactly as predict_reach does, and proposes a navigate-only journey. The first call performs nothing " +
|
|
275
|
+
"and returns a confirmation token; call again with confirmToken to drive that exact proposed journey for " +
|
|
276
|
+
"real, in an already-consented browser session (sessionId, from browser({ verb: \"start_session\" })), then correlate " +
|
|
277
|
+
"which predicted pages the drive actually reached and route the graph path plus whatever the drive " +
|
|
278
|
+
"observed (console errors, failed requests) through the same governed gate draw_conclusion uses. Never " +
|
|
279
|
+
"boots an app, never clicks or types beyond the navigate-only proposal, and never widens the journey the " +
|
|
280
|
+
"first call showed you. A drive that reaches every predicted page with nothing wrong observed reports " +
|
|
281
|
+
"unconfirmed, honestly — a clean page load is not evidence of breakage.",
|
|
282
|
+
inputSchema: SCHEMA,
|
|
283
|
+
run,
|
|
284
|
+
describeAction,
|
|
285
|
+
};
|
|
286
|
+
//# sourceMappingURL=prove-reach.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prove-reach.js","sourceRoot":"","sources":["../../src/tools/prove-reach.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refusal-fetch.d.ts","sourceRoot":"","sources":["../../src/tools/refusal-fetch.ts"],"names":[],"mappings":"AAAA;;;;6FAI6F;AAI7F,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"refusal-fetch.d.ts","sourceRoot":"","sources":["../../src/tools/refusal-fetch.ts"],"names":[],"mappings":"AAAA;;;;6FAI6F;AAI7F,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,UAAU,CAAC;AAsBlB,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,qGAAqG;IACrG,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,uGAAuG;IACvG,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,6FAA6F;IAC7F,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,uBAAuB,EAAE,CAAC;IACnD,iFAAiF;IACjF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,yDAAyD;IACzD,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED,MAAM,MAAM,gBAAgB,GAAG,uBAAuB,GAAG,oBAAoB,CAAC;AA2G9E,eAAO,MAAM,gBAAgB,EAAE,cAe9B,CAAC"}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* silently drop unclassified rows (DEC-243). No `limit`: the population must stay stable. */
|
|
6
6
|
import { fetchRefusalPage, summariseRefusals } from "@descryy/core";
|
|
7
7
|
import { answer, optionalInteger, optionalString, } from "./kit.js";
|
|
8
|
+
import { capBySize, sizeCapNote } from "../capped.js";
|
|
8
9
|
const SCHEMA = {
|
|
9
10
|
type: "object",
|
|
10
11
|
properties: {
|
|
@@ -32,6 +33,25 @@ function brief(ref) {
|
|
|
32
33
|
reason: ref.reason,
|
|
33
34
|
};
|
|
34
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* `pageSize` has no upper bound (schema only enforces `minimum: 1`), and each
|
|
38
|
+
* row carries a free-text `reason` and `rawTarget` — so a page can overflow
|
|
39
|
+
* either by row count or by row size. Rows are self-contained; shrinking
|
|
40
|
+
* means dropping trailing rows of this page (the next page still starts
|
|
41
|
+
* where this one's own `nextHandle` says, unaffected by this drop).
|
|
42
|
+
*/
|
|
43
|
+
function fitRefusalPage(rest, shownItems, budgetBytes) {
|
|
44
|
+
const scaffoldBytes = Buffer.byteLength(JSON.stringify({ ...rest, items: [] }), "utf8");
|
|
45
|
+
const fit = capBySize(shownItems, budgetBytes, scaffoldBytes);
|
|
46
|
+
const notes = fit.droppedForSize === 0 ? [] : [sizeCapNote("row", fit.shown.length, shownItems.length, fit.droppedForSize)];
|
|
47
|
+
return {
|
|
48
|
+
data: { ...rest, items: fit.shown },
|
|
49
|
+
notes,
|
|
50
|
+
...(fit.droppedForSize === 0
|
|
51
|
+
? {}
|
|
52
|
+
: { truncatedDetail: { shown: fit.shown.length, total: rest.total, more: null } }),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
35
55
|
async function run(args, ctx) {
|
|
36
56
|
const handle = optionalString(args, "handle");
|
|
37
57
|
const pageSize = optionalInteger(args, "pageSize", 1);
|
|
@@ -73,17 +93,17 @@ async function run(args, ctx) {
|
|
|
73
93
|
data: { kind: "page", items: [], total: 0, nextHandle: null },
|
|
74
94
|
});
|
|
75
95
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
96
|
+
const restOfPageData = { kind: "page", total: page.total, nextHandle: page.nextHandle };
|
|
97
|
+
const shapedItems = page.items.map(brief);
|
|
98
|
+
return {
|
|
99
|
+
...answer({
|
|
100
|
+
...envelopeBase,
|
|
101
|
+
headline: `Page of ${page.items.length} unresolved reference(s), of ${page.total} total.`,
|
|
102
|
+
notes: [],
|
|
103
|
+
data: { ...restOfPageData, items: shapedItems },
|
|
104
|
+
}),
|
|
105
|
+
fitToBudget: (budgetBytes) => fitRefusalPage(restOfPageData, shapedItems, budgetBytes),
|
|
106
|
+
};
|
|
87
107
|
}
|
|
88
108
|
export const refusalFetchTool = {
|
|
89
109
|
name: "refusal_fetch",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refusal-fetch.js","sourceRoot":"","sources":["../../src/tools/refusal-fetch.ts"],"names":[],"mappings":"AAAA;;;;6FAI6F;AAE7F,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEpE,OAAO,EACL,MAAM,EACN,eAAe,EACf,cAAc,GAGf,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"refusal-fetch.js","sourceRoot":"","sources":["../../src/tools/refusal-fetch.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../src/tools/scope.ts"],"names":[],"mappings":"AAAA;;;;0FAI0F;AAE1F,OAAO,EAA8C,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAC3F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAOL,KAAK,SAAS,EAEd,KAAK,cAAc,EACpB,MAAM,UAAU,CAAC;AAIlB,iDAAiD;AACjD,MAAM,WAAW,gBAAiB,SAAQ,SAAS;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,sEAAsE;IACtE,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC;CACzB;AAED,8EAA8E;AAC9E,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B;iFAC6E;IAC7E,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC9C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC/C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;CAC5C;AAED;;mCAEmC;AACnC,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC9C,QAAQ,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC/C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,SAAS,GAAG,WAAW,GAAG,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../src/tools/scope.ts"],"names":[],"mappings":"AAAA;;;;0FAI0F;AAE1F,OAAO,EAA8C,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAC3F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAOL,KAAK,SAAS,EAEd,KAAK,cAAc,EACpB,MAAM,UAAU,CAAC;AAIlB,iDAAiD;AACjD,MAAM,WAAW,gBAAiB,SAAQ,SAAS;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,sEAAsE;IACtE,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC;CACzB;AAED,8EAA8E;AAC9E,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B;iFAC6E;IAC7E,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC9C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC/C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;CAC5C;AAED;;mCAEmC;AACnC,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC9C,QAAQ,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC/C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,SAAS,GAAG,WAAW,GAAG,cAAc,CAAC;AA8OrD,eAAO,MAAM,SAAS,EAAE,cAavB,CAAC"}
|
package/dist/tools/scope.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* or stale graph) — both disclosed, never reported as "0 affected" (§20.2's collapse). */
|
|
6
6
|
import { nodesInFiles, scopeChange } from "@descryy/core";
|
|
7
7
|
import { answer, briefNode, optionalEnum, optionalInteger, optionalStringArray, ToolInputError, } from "./kit.js";
|
|
8
|
-
import { capped } from "../capped.js";
|
|
8
|
+
import { capBySize, capped, sizeCapNote } from "../capped.js";
|
|
9
9
|
const TRIGGERS = ["pre-push", "pr", "nightly"];
|
|
10
10
|
const SCHEMA = {
|
|
11
11
|
type: "object",
|
|
@@ -43,6 +43,35 @@ const SCHEMA = {
|
|
|
43
43
|
},
|
|
44
44
|
additionalProperties: false,
|
|
45
45
|
};
|
|
46
|
+
/**
|
|
47
|
+
* `fitToBudget` for `ScopeReport` — a scaffold of scalars plus two lists,
|
|
48
|
+
* `changed` and `affected`, already cut once by `limit`. Neither row carries
|
|
49
|
+
* a droppable payload, so shrinking further means only dropping trailing
|
|
50
|
+
* rows from each, `changed` first: every seed still seeded the traversal
|
|
51
|
+
* either way, but it is the caller's own named files, the more load-bearing
|
|
52
|
+
* of the two lists to keep whole.
|
|
53
|
+
*/
|
|
54
|
+
function fitScope(rest, shapedChanged, shapedAffected, totalRows, budgetBytes) {
|
|
55
|
+
const scaffoldBytes = Buffer.byteLength(JSON.stringify({ ...rest, changed: [], affected: [] }), "utf8");
|
|
56
|
+
const changedFit = capBySize(shapedChanged, budgetBytes, scaffoldBytes);
|
|
57
|
+
const spentOnChanged = Buffer.byteLength(JSON.stringify(changedFit.shown), "utf8");
|
|
58
|
+
const affectedFit = capBySize(shapedAffected, Math.max(budgetBytes - scaffoldBytes - spentOnChanged, 0), 0);
|
|
59
|
+
const notes = [];
|
|
60
|
+
if (changedFit.droppedForSize > 0) {
|
|
61
|
+
notes.push(sizeCapNote("changed symbol", changedFit.shown.length, shapedChanged.length, changedFit.droppedForSize));
|
|
62
|
+
}
|
|
63
|
+
if (affectedFit.droppedForSize > 0) {
|
|
64
|
+
notes.push(sizeCapNote("affected node", affectedFit.shown.length, shapedAffected.length, affectedFit.droppedForSize));
|
|
65
|
+
}
|
|
66
|
+
const droppedNow = changedFit.droppedForSize + affectedFit.droppedForSize;
|
|
67
|
+
return {
|
|
68
|
+
data: { ...rest, changed: changedFit.shown, affected: affectedFit.shown },
|
|
69
|
+
notes,
|
|
70
|
+
...(droppedNow === 0
|
|
71
|
+
? {}
|
|
72
|
+
: { truncatedDetail: { shown: changedFit.shown.length + affectedFit.shown.length, total: totalRows, more: null } }),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
46
75
|
function shape(entry) {
|
|
47
76
|
return {
|
|
48
77
|
...briefNode(entry.node),
|
|
@@ -144,19 +173,20 @@ async function run(args, ctx) {
|
|
|
144
173
|
const truncatedDetail = changedCap.detail === null && cap.detail === null
|
|
145
174
|
? null
|
|
146
175
|
: { shown: shownRows, total: totalRows, more: null };
|
|
176
|
+
const shapedChanged = changedCap.shown.map(shape);
|
|
177
|
+
const shapedAffected = cap.shown.map(shape);
|
|
178
|
+
const restOfData = {
|
|
179
|
+
changedTotal: scoped.data.changed.length,
|
|
180
|
+
affectedTotal: affected.length,
|
|
181
|
+
droppedForBudget: scoped.data.dropped.length,
|
|
182
|
+
budget: scoped.data.budget,
|
|
183
|
+
budgetUsed: scoped.data.budgetUsed,
|
|
184
|
+
byTier,
|
|
185
|
+
};
|
|
147
186
|
return {
|
|
148
187
|
result: {
|
|
149
188
|
...scoped,
|
|
150
|
-
data: {
|
|
151
|
-
changed: changedCap.shown.map(shape),
|
|
152
|
-
changedTotal: scoped.data.changed.length,
|
|
153
|
-
affected: cap.shown.map(shape),
|
|
154
|
-
affectedTotal: affected.length,
|
|
155
|
-
droppedForBudget: scoped.data.dropped.length,
|
|
156
|
-
budget: scoped.data.budget,
|
|
157
|
-
budgetUsed: scoped.data.budgetUsed,
|
|
158
|
-
byTier,
|
|
159
|
-
},
|
|
189
|
+
data: { ...restOfData, changed: shapedChanged, affected: shapedAffected },
|
|
160
190
|
// Deliberately not `scoped.truncated` (the node *budget*'s own drop flag,
|
|
161
191
|
// disclosed separately via `droppedForBudget`) — this `truncated` means "this
|
|
162
192
|
// reply is shorter than the scope computed," a different fact from that.
|
|
@@ -168,6 +198,7 @@ async function run(args, ctx) {
|
|
|
168
198
|
nameLevel: true,
|
|
169
199
|
headline: `${scoped.data.changed.length} changed symbol(s) reach ${affected.length} other node(s) ` +
|
|
170
200
|
`above the impact threshold, under the ${trigger} budget of ${scoped.data.budget}.`,
|
|
201
|
+
fitToBudget: (budgetBytes) => fitScope(restOfData, shapedChanged, shapedAffected, totalRows, budgetBytes),
|
|
171
202
|
};
|
|
172
203
|
}
|
|
173
204
|
export const scopeTool = {
|
package/dist/tools/scope.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/tools/scope.ts"],"names":[],"mappings":"AAAA;;;;0FAI0F;AAE1F,OAAO,EAAE,YAAY,EAAE,WAAW,EAAmC,MAAM,eAAe,CAAC;AAG3F,OAAO,EACL,MAAM,EACN,SAAS,EACT,YAAY,EACZ,eAAe,EACf,mBAAmB,EACnB,cAAc,GAIf,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/tools/scope.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"similar-incidents.d.ts","sourceRoot":"","sources":["../../src/tools/similar-incidents.ts"],"names":[],"mappings":"AAAA;;;;8FAI8F;AAE9F,OAAO,EAAoB,KAAK,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAEjF,OAAO,EAOL,KAAK,SAAS,EAEd,KAAK,cAAc,EACpB,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"similar-incidents.d.ts","sourceRoot":"","sources":["../../src/tools/similar-incidents.ts"],"names":[],"mappings":"AAAA;;;;8FAI8F;AAE9F,OAAO,EAAoB,KAAK,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAEjF,OAAO,EAOL,KAAK,SAAS,EAEd,KAAK,cAAc,EACpB,MAAM,UAAU,CAAC;AAkClB,6EAA6E;AAC7E,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,IAAI,EAAE,yBAAyB,CAAC;IACzC,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B,kFAAkF;IAClF,QAAQ,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IAC/B;;uGAEmG;IACnG,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,SAAS,2BAA2B,EAAE,CAAC;IACzD,sEAAsE;IACtE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;8CAE8C;AAC9C,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE;QACd,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;QACzC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;KACtC,CAAC;IACF,QAAQ,CAAC,OAAO,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACnD,2DAA2D;IAC3D,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,8FAA8F;IAC9F,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,kFAAkF;IAClF,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAwLD,eAAO,MAAM,oBAAoB,EAAE,cAqBlC,CAAC"}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* — the same split `contracts` and `propagation` apply to their own zero-population case. */
|
|
6
6
|
import { similarIncidents } from "@descryy/core";
|
|
7
7
|
import { answer, briefNode, optionalInteger, optionalString, optionalStringArray, ToolInputError, } from "./kit.js";
|
|
8
|
+
import { capBySize, sizeCapNote } from "../capped.js";
|
|
8
9
|
const SCHEMA = {
|
|
9
10
|
type: "object",
|
|
10
11
|
properties: {
|
|
@@ -48,6 +49,27 @@ function recallDisclosure(incidentsInGraph) {
|
|
|
48
49
|
"these results entirely. The corpus grows fastest through \"mark_incident\": one call, at the " +
|
|
49
50
|
"moment you already know the answer.");
|
|
50
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* `fitToBudget` — `matches` grows with how many incidents the graph holds and
|
|
54
|
+
* how much text each one's signals carry, unbounded by `limit` alone (a
|
|
55
|
+
* caller may raise it, and even at the default a graph with thousands of
|
|
56
|
+
* revert-derived incidents can still overflow). Every match row is already
|
|
57
|
+
* self-contained, so shrinking means dropping trailing rows only.
|
|
58
|
+
*/
|
|
59
|
+
function fitSimilarIncidents(rest, shownMatches, budgetBytes) {
|
|
60
|
+
const scaffoldBytes = Buffer.byteLength(JSON.stringify({ ...rest, matches: [] }), "utf8");
|
|
61
|
+
const fit = capBySize(shownMatches, budgetBytes, scaffoldBytes);
|
|
62
|
+
const notes = fit.droppedForSize === 0
|
|
63
|
+
? []
|
|
64
|
+
: [sizeCapNote("match", fit.shown.length, shownMatches.length, fit.droppedForSize)];
|
|
65
|
+
return {
|
|
66
|
+
data: { ...rest, matches: fit.shown },
|
|
67
|
+
notes,
|
|
68
|
+
...(fit.droppedForSize === 0
|
|
69
|
+
? {}
|
|
70
|
+
: { truncatedDetail: { shown: fit.shown.length, total: rest.matchesTotal, more: null } }),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
51
73
|
async function run(args, ctx) {
|
|
52
74
|
const touchedFiles = optionalStringArray(args, "touchedFiles") ?? [];
|
|
53
75
|
const errorMessage = optionalString(args, "errorMessage");
|
|
@@ -117,26 +139,27 @@ async function run(args, ctx) {
|
|
|
117
139
|
notes.push("The incident read was capped, so some INCIDENT nodes were never scored. The counts here " +
|
|
118
140
|
"are a lower bound.");
|
|
119
141
|
}
|
|
142
|
+
const shapedMatches = shown.map((match) => ({
|
|
143
|
+
incident: briefNode(match.incident),
|
|
144
|
+
fix: match.fix === null ? null : briefNode(match.fix),
|
|
145
|
+
// Read off the node rather than inferred from anything about the
|
|
146
|
+
// match: which mechanism minted an incident is a fact about the
|
|
147
|
+
// incident, not about how well it scored.
|
|
148
|
+
detectedVia: typeof match.incident.attrs?.["detectedVia"] === "string"
|
|
149
|
+
? match.incident.attrs["detectedVia"]
|
|
150
|
+
: null,
|
|
151
|
+
signals: match.signals.map((s) => ({ kind: s.kind, score: Number(s.score.toFixed(4)) })),
|
|
152
|
+
score: Number(match.combinedScore.toFixed(4)),
|
|
153
|
+
}));
|
|
154
|
+
const restOfData = {
|
|
155
|
+
query: { touchedFiles, errorMessage: errorMessage ?? null },
|
|
156
|
+
matchesTotal: ranked.data.length,
|
|
157
|
+
incidentsInGraph,
|
|
158
|
+
analysed: true,
|
|
159
|
+
};
|
|
120
160
|
return {
|
|
121
161
|
result: {
|
|
122
|
-
data: {
|
|
123
|
-
query: { touchedFiles, errorMessage: errorMessage ?? null },
|
|
124
|
-
matches: shown.map((match) => ({
|
|
125
|
-
incident: briefNode(match.incident),
|
|
126
|
-
fix: match.fix === null ? null : briefNode(match.fix),
|
|
127
|
-
// Read off the node rather than inferred from anything about the
|
|
128
|
-
// match: which mechanism minted an incident is a fact about the
|
|
129
|
-
// incident, not about how well it scored.
|
|
130
|
-
detectedVia: typeof match.incident.attrs?.["detectedVia"] === "string"
|
|
131
|
-
? match.incident.attrs["detectedVia"]
|
|
132
|
-
: null,
|
|
133
|
-
signals: match.signals.map((s) => ({ kind: s.kind, score: Number(s.score.toFixed(4)) })),
|
|
134
|
-
score: Number(match.combinedScore.toFixed(4)),
|
|
135
|
-
})),
|
|
136
|
-
matchesTotal: ranked.data.length,
|
|
137
|
-
incidentsInGraph,
|
|
138
|
-
analysed: true,
|
|
139
|
-
},
|
|
162
|
+
data: { ...restOfData, matches: shapedMatches },
|
|
140
163
|
stamp: ranked.stamp,
|
|
141
164
|
truncated: ranked.truncated || shown.length < ranked.data.length || population.truncated,
|
|
142
165
|
notes,
|
|
@@ -146,6 +169,7 @@ async function run(args, ctx) {
|
|
|
146
169
|
? { truncatedDetail: { shown: shown.length, total: ranked.data.length, more: null } }
|
|
147
170
|
: {}),
|
|
148
171
|
nameLevel: true,
|
|
172
|
+
fitToBudget: (budgetBytes) => fitSimilarIncidents(restOfData, shapedMatches, budgetBytes),
|
|
149
173
|
headline: ranked.data.length === 0
|
|
150
174
|
? `None of the ${incidentsInGraph} incident(s) in this graph share a file or a phrase with ` +
|
|
151
175
|
"the failure you described. That is a statement about this graph's incident record, not " +
|