@descryy/mcp 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/descry-mcp.js +6 -1
- package/dist/bin/descry-mcp.js.map +1 -1
- package/dist/browser/driver.d.ts +236 -0
- package/dist/browser/driver.d.ts.map +1 -0
- package/dist/browser/driver.js +70 -0
- package/dist/browser/driver.js.map +1 -0
- package/dist/browser/evidence.d.ts +47 -0
- package/dist/browser/evidence.d.ts.map +1 -0
- package/dist/browser/evidence.js +55 -0
- package/dist/browser/evidence.js.map +1 -0
- package/dist/browser/fake-driver.d.ts +58 -0
- package/dist/browser/fake-driver.d.ts.map +1 -0
- package/dist/browser/fake-driver.js +161 -0
- package/dist/browser/fake-driver.js.map +1 -0
- package/dist/browser/graph-write.d.ts +86 -0
- package/dist/browser/graph-write.d.ts.map +1 -0
- package/dist/browser/graph-write.js +135 -0
- package/dist/browser/graph-write.js.map +1 -0
- package/dist/browser/playwright-driver.d.ts +65 -0
- package/dist/browser/playwright-driver.d.ts.map +1 -0
- package/dist/browser/playwright-driver.js +359 -0
- package/dist/browser/playwright-driver.js.map +1 -0
- package/dist/browser/provider.d.ts +49 -0
- package/dist/browser/provider.d.ts.map +1 -0
- package/dist/browser/provider.js +28 -0
- package/dist/browser/provider.js.map +1 -0
- package/dist/browser/registry.d.ts +182 -0
- package/dist/browser/registry.d.ts.map +1 -0
- package/dist/browser/registry.js +215 -0
- package/dist/browser/registry.js.map +1 -0
- package/dist/browser/scenario-resolve.d.ts +62 -0
- package/dist/browser/scenario-resolve.d.ts.map +1 -0
- package/dist/browser/scenario-resolve.js +127 -0
- package/dist/browser/scenario-resolve.js.map +1 -0
- package/dist/browser/scenario-runner.d.ts +113 -0
- package/dist/browser/scenario-runner.d.ts.map +1 -0
- package/dist/browser/scenario-runner.js +315 -0
- package/dist/browser/scenario-runner.js.map +1 -0
- package/dist/browser/stack-parser.d.ts +43 -0
- package/dist/browser/stack-parser.d.ts.map +1 -0
- package/dist/browser/stack-parser.js +112 -0
- package/dist/browser/stack-parser.js.map +1 -0
- package/dist/browser/tool-support.d.ts +113 -0
- package/dist/browser/tool-support.d.ts.map +1 -0
- package/dist/browser/tool-support.js +181 -0
- package/dist/browser/tool-support.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/render.d.ts +112 -10
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +79 -13
- package/dist/render.js.map +1 -1
- package/dist/scenarios/index.d.ts +4 -0
- package/dist/scenarios/index.d.ts.map +1 -0
- package/dist/scenarios/index.js +4 -0
- package/dist/scenarios/index.js.map +1 -0
- package/dist/scenarios/parse.d.ts +32 -0
- package/dist/scenarios/parse.d.ts.map +1 -0
- package/dist/scenarios/parse.js +199 -0
- package/dist/scenarios/parse.js.map +1 -0
- package/dist/scenarios/scenario.d.ts +115 -0
- package/dist/scenarios/scenario.d.ts.map +1 -0
- package/dist/scenarios/scenario.js +41 -0
- package/dist/scenarios/scenario.js.map +1 -0
- package/dist/scenarios/storage.d.ts +51 -0
- package/dist/scenarios/storage.d.ts.map +1 -0
- package/dist/scenarios/storage.js +93 -0
- package/dist/scenarios/storage.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +6 -3
- package/dist/server.js.map +1 -1
- package/dist/session.d.ts +68 -0
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +89 -0
- package/dist/session.js.map +1 -1
- package/dist/tools/analyze.d.ts +41 -1
- package/dist/tools/analyze.d.ts.map +1 -1
- package/dist/tools/analyze.js +81 -8
- package/dist/tools/analyze.js.map +1 -1
- package/dist/tools/browser-click.d.ts +36 -0
- package/dist/tools/browser-click.d.ts.map +1 -0
- package/dist/tools/browser-click.js +117 -0
- package/dist/tools/browser-click.js.map +1 -0
- package/dist/tools/browser-close-session.d.ts +24 -0
- package/dist/tools/browser-close-session.d.ts.map +1 -0
- package/dist/tools/browser-close-session.js +63 -0
- package/dist/tools/browser-close-session.js.map +1 -0
- package/dist/tools/browser-fill.d.ts +49 -0
- package/dist/tools/browser-fill.d.ts.map +1 -0
- package/dist/tools/browser-fill.js +138 -0
- package/dist/tools/browser-fill.js.map +1 -0
- package/dist/tools/browser-navigate.d.ts +32 -0
- package/dist/tools/browser-navigate.d.ts.map +1 -0
- package/dist/tools/browser-navigate.js +103 -0
- package/dist/tools/browser-navigate.js.map +1 -0
- package/dist/tools/browser-run-scenario.d.ts +54 -0
- package/dist/tools/browser-run-scenario.d.ts.map +1 -0
- package/dist/tools/browser-run-scenario.js +228 -0
- package/dist/tools/browser-run-scenario.js.map +1 -0
- package/dist/tools/browser-save-scenario.d.ts +44 -0
- package/dist/tools/browser-save-scenario.d.ts.map +1 -0
- package/dist/tools/browser-save-scenario.js +298 -0
- package/dist/tools/browser-save-scenario.js.map +1 -0
- package/dist/tools/browser-snapshot.d.ts +60 -0
- package/dist/tools/browser-snapshot.d.ts.map +1 -0
- package/dist/tools/browser-snapshot.js +139 -0
- package/dist/tools/browser-snapshot.js.map +1 -0
- package/dist/tools/browser-start-session.d.ts +43 -0
- package/dist/tools/browser-start-session.d.ts.map +1 -0
- package/dist/tools/browser-start-session.js +272 -0
- package/dist/tools/browser-start-session.js.map +1 -0
- package/dist/tools/browser-type.d.ts +48 -0
- package/dist/tools/browser-type.d.ts.map +1 -0
- package/dist/tools/browser-type.js +136 -0
- package/dist/tools/browser-type.js.map +1 -0
- package/dist/tools/contracts.d.ts +15 -0
- package/dist/tools/contracts.d.ts.map +1 -1
- package/dist/tools/contracts.js +14 -3
- package/dist/tools/contracts.js.map +1 -1
- package/dist/tools/git-diff.d.ts.map +1 -1
- package/dist/tools/git-diff.js +85 -6
- package/dist/tools/git-diff.js.map +1 -1
- package/dist/tools/impact.d.ts +9 -0
- package/dist/tools/impact.d.ts.map +1 -1
- package/dist/tools/impact.js +3 -3
- package/dist/tools/impact.js.map +1 -1
- package/dist/tools/index.d.ts +9 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +27 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/kit.d.ts +10 -1
- package/dist/tools/kit.d.ts.map +1 -1
- package/dist/tools/kit.js +2 -0
- package/dist/tools/kit.js.map +1 -1
- package/dist/tools/observe-runtime.d.ts +113 -19
- package/dist/tools/observe-runtime.d.ts.map +1 -1
- package/dist/tools/observe-runtime.js +293 -52
- package/dist/tools/observe-runtime.js.map +1 -1
- package/dist/tools/observe-tests.d.ts +125 -0
- package/dist/tools/observe-tests.d.ts.map +1 -0
- package/dist/tools/observe-tests.js +313 -0
- package/dist/tools/observe-tests.js.map +1 -0
- package/dist/tools/pr-analysis.d.ts +11 -0
- package/dist/tools/pr-analysis.d.ts.map +1 -1
- package/dist/tools/pr-analysis.js +3 -3
- package/dist/tools/pr-analysis.js.map +1 -1
- package/dist/tools/pre-push.d.ts +77 -0
- package/dist/tools/pre-push.d.ts.map +1 -0
- package/dist/tools/pre-push.js +250 -0
- package/dist/tools/pre-push.js.map +1 -0
- package/dist/tools/questions.d.ts.map +1 -1
- package/dist/tools/questions.js +41 -16
- package/dist/tools/questions.js.map +1 -1
- package/dist/tools/verification-status.d.ts +22 -0
- package/dist/tools/verification-status.d.ts.map +1 -1
- package/dist/tools/verification-status.js +51 -5
- package/dist/tools/verification-status.js.map +1 -1
- package/package.json +14 -13
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `observe_tests` — run the project's suite and record which tests actually ran.
|
|
3
|
+
*
|
|
4
|
+
* This is the coverage axis, and it is the one runtime signal in this server
|
|
5
|
+
* that needs **no application booted**: a suite runs, and what it exercised
|
|
6
|
+
* becomes a durable fact. `observe_runtime`'s standing complaint from the UAT
|
|
7
|
+
* was that it "assumes local setup is already solved"; this dissolves that for
|
|
8
|
+
* the coverage half rather than documenting around it.
|
|
9
|
+
*
|
|
10
|
+
* ## What it writes, and what it deliberately does not
|
|
11
|
+
*
|
|
12
|
+
* It writes `observed_tests` rows through `applyObservedTests` — the EARNED
|
|
13
|
+
* carrier. It does **not** promote any edge to R4, and the distinction is the
|
|
14
|
+
* whole reason that table exists.
|
|
15
|
+
*
|
|
16
|
+
* An edge needs two endpoints and a witnessed relationship between them. The
|
|
17
|
+
* test-runner collector's evidence carries no stack — every item it emits has
|
|
18
|
+
* `stackTrace: null` — so an observed test names exactly one node, its own
|
|
19
|
+
* `TEST_CASE`. Nothing here witnesses which function that test reached, and
|
|
20
|
+
* pairing the test with a function that merely co-occurred in the same run
|
|
21
|
+
* would mint an edge from temporal coincidence. That is the wrong-direction
|
|
22
|
+
* failure rule 2 exists to prevent, and `observe-runtime.ts`'s own header
|
|
23
|
+
* already refuses it by name for the same reason.
|
|
24
|
+
*
|
|
25
|
+
* So: "this test executed and passed" is a fact about one node, recorded as
|
|
26
|
+
* one. "This test covers that function" remains whatever the static graph
|
|
27
|
+
* already claimed, at whatever resolution it claimed it.
|
|
28
|
+
*
|
|
29
|
+
* ## Why the denominators are reported and not just the successes
|
|
30
|
+
*
|
|
31
|
+
* `TraceCoverage` carries `testsObserved` and `notRun` because the collector
|
|
32
|
+
* learned the hard way that "12 passed" must never silently be "9 passed and 3
|
|
33
|
+
* that never ran". The same discipline applies one layer up: this reply reports
|
|
34
|
+
* how many results the runner produced, how many resolved to a graph node, and
|
|
35
|
+
* how many did not — because `recorded: 3` against a 40-test suite reads as
|
|
36
|
+
* full coverage to anyone who is not shown the denominator.
|
|
37
|
+
*
|
|
38
|
+
* ## Class and tier
|
|
39
|
+
*
|
|
40
|
+
* `action` — it spawns a process that executes the repository's own code, and
|
|
41
|
+
* it writes EARNED rows that a later `verification_status` will read. Gated by
|
|
42
|
+
* the same two-call `confirmToken` handshake `observe_runtime` and `questions`
|
|
43
|
+
* use.
|
|
44
|
+
*
|
|
45
|
+
* `evidence` — it reports what ran. It draws no conclusion about the code and
|
|
46
|
+
* writes no finding or hypothesis.
|
|
47
|
+
*
|
|
48
|
+
* It does carry a `reportCategory`, and it used to read oddly:
|
|
49
|
+
* `deriveEnvelopeCategory` hardcoded `hasRuntimeEvidence: false`, so a reply
|
|
50
|
+
* whose `resolutionFloor` was 4 and whose `reliabilityCap` was A still
|
|
51
|
+
* rendered as `unconfirmed` — the envelope contradicting itself. The flag is
|
|
52
|
+
* now *declared* rather than inferred: this tool runs the repository's own
|
|
53
|
+
* test suite, so it hands the render layer a {@link WitnessedEvidence} count
|
|
54
|
+
* of the channels its run actually saw, and an answer resting on edges it
|
|
55
|
+
* witnessed renders `strongly supported`. Declaring it is what makes the
|
|
56
|
+
* promotion true rather than assumed — a resolution floor of 4 can be reached
|
|
57
|
+
* without anything having been watched, which is why the floor is no longer
|
|
58
|
+
* what the category reads.
|
|
59
|
+
*
|
|
60
|
+
* The count comes from `observe_runtime`'s `witnessedSignalTypes`, not from a
|
|
61
|
+
* tally here. The clamp to the six declared channels and the drop of signals
|
|
62
|
+
* Descry does not count are that function's rules, and a second
|
|
63
|
+
* implementation of them is a second place for the vocabulary to drift.
|
|
64
|
+
*
|
|
65
|
+
* `confirmed` is still unreachable from this surface, and deliberately: it
|
|
66
|
+
* needs direct mechanism evidence, which no graph query produces. Shared
|
|
67
|
+
* render-layer behaviour, identical for `observe_runtime`, and still not this
|
|
68
|
+
* tool's to override.
|
|
69
|
+
*/
|
|
70
|
+
import { type ObservedTestObservation, type ObservedTestOutcome, type SqlDriver } from "@descryy/core";
|
|
71
|
+
import type { Evidence } from "@descryy/runtime-contracts";
|
|
72
|
+
import { type ToolDefinition } from "./kit.ts";
|
|
73
|
+
/**
|
|
74
|
+
* What a collector hands to `emit`: an evidence item before the store has
|
|
75
|
+
* assigned it an id or tied it to an execution. Those two fields exist only
|
|
76
|
+
* after `EvidenceStore.write()` returns, and nothing here needs them — the
|
|
77
|
+
* resolver reads `eventType`, `payload` and `sourceLocation` and nothing else.
|
|
78
|
+
*/
|
|
79
|
+
type EmittedEvidence = Omit<Evidence, "evidenceId" | "executionId">;
|
|
80
|
+
/** One test the runner reported that could not be tied to a node in this graph. */
|
|
81
|
+
export interface UnresolvedObservedTest {
|
|
82
|
+
readonly qualifiedName: string;
|
|
83
|
+
readonly outcome: ObservedTestOutcome;
|
|
84
|
+
/** The resolver's own words — never summarised into "not found". */
|
|
85
|
+
readonly reason: string;
|
|
86
|
+
}
|
|
87
|
+
export interface ObserveTestsData {
|
|
88
|
+
readonly runId: string | null;
|
|
89
|
+
/** How many results the runner actually produced. The denominator — read every other count against this. */
|
|
90
|
+
readonly testsReported: number;
|
|
91
|
+
/** Tests the runner said did not run (`.skip`/`.todo`). Reported separately so a pass count is never inflated by them. */
|
|
92
|
+
readonly notRun: number;
|
|
93
|
+
/** Node ids written to the EARNED ledger. */
|
|
94
|
+
readonly recorded: readonly string[];
|
|
95
|
+
/** Results that reached no node in this graph, with the resolver's reason for each. */
|
|
96
|
+
readonly unresolved: readonly UnresolvedObservedTest[];
|
|
97
|
+
/** Observations the write path itself declined, with its reason. Distinct from `unresolved`: these named a node. */
|
|
98
|
+
readonly refused: readonly {
|
|
99
|
+
readonly nodeId: string;
|
|
100
|
+
readonly reason: string;
|
|
101
|
+
}[];
|
|
102
|
+
readonly outcomes: Readonly<Record<string, number>>;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Turn a run's evidence into observations this graph can hold.
|
|
106
|
+
*
|
|
107
|
+
* Separated from {@link run} because it is the part with a decision in it, and
|
|
108
|
+
* a decision that is only reachable by spawning a real test runner is a
|
|
109
|
+
* decision that does not get tested. Every result lands in `observations` or
|
|
110
|
+
* `unresolved`, so the caller can report a denominator rather than a success
|
|
111
|
+
* count on its own.
|
|
112
|
+
*
|
|
113
|
+
* `TEST_STARTED` is deliberately ignored: it is announced before the runner
|
|
114
|
+
* knows the outcome, so counting it would double every test and count a
|
|
115
|
+
* skipped one as having run.
|
|
116
|
+
*/
|
|
117
|
+
export declare function observationsFromEvidence(driver: SqlDriver, evidence: readonly EmittedEvidence[], repo: string, options?: {
|
|
118
|
+
readonly repoRoot?: string;
|
|
119
|
+
}): {
|
|
120
|
+
readonly observations: readonly ObservedTestObservation[];
|
|
121
|
+
readonly unresolved: readonly UnresolvedObservedTest[];
|
|
122
|
+
};
|
|
123
|
+
export declare const observeTestsTool: ToolDefinition;
|
|
124
|
+
export {};
|
|
125
|
+
//# sourceMappingURL=observe-tests.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observe-tests.d.ts","sourceRoot":"","sources":["../../src/tools/observe-tests.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AAKH,OAAO,EAA8B,KAAK,uBAAuB,EAAE,KAAK,mBAAmB,EAAE,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AACnI,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAM3D,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,UAAU,CAAC;AAKlB;;;;;GAKG;AACH,KAAK,eAAe,GAAG,IAAI,CAAC,QAAQ,EAAE,YAAY,GAAG,aAAa,CAAC,CAAC;AAmCpE,mFAAmF;AACnF,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;IACtC,oEAAoE;IACpE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,4GAA4G;IAC5G,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,0HAA0H;IAC1H,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,6CAA6C;IAC7C,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,uFAAuF;IACvF,QAAQ,CAAC,UAAU,EAAE,SAAS,sBAAsB,EAAE,CAAC;IACvD,oHAAoH;IACpH,QAAQ,CAAC,OAAO,EAAE,SAAS;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAClF,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACrD;AAiBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,SAAS,eAAe,EAAE,EACpC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAC3C;IAAE,QAAQ,CAAC,YAAY,EAAE,SAAS,uBAAuB,EAAE,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,SAAS,sBAAsB,EAAE,CAAA;CAAE,CA0BvH;AAqKD,eAAO,MAAM,gBAAgB,EAAE,cAgB9B,CAAC"}
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `observe_tests` — run the project's suite and record which tests actually ran.
|
|
3
|
+
*
|
|
4
|
+
* This is the coverage axis, and it is the one runtime signal in this server
|
|
5
|
+
* that needs **no application booted**: a suite runs, and what it exercised
|
|
6
|
+
* becomes a durable fact. `observe_runtime`'s standing complaint from the UAT
|
|
7
|
+
* was that it "assumes local setup is already solved"; this dissolves that for
|
|
8
|
+
* the coverage half rather than documenting around it.
|
|
9
|
+
*
|
|
10
|
+
* ## What it writes, and what it deliberately does not
|
|
11
|
+
*
|
|
12
|
+
* It writes `observed_tests` rows through `applyObservedTests` — the EARNED
|
|
13
|
+
* carrier. It does **not** promote any edge to R4, and the distinction is the
|
|
14
|
+
* whole reason that table exists.
|
|
15
|
+
*
|
|
16
|
+
* An edge needs two endpoints and a witnessed relationship between them. The
|
|
17
|
+
* test-runner collector's evidence carries no stack — every item it emits has
|
|
18
|
+
* `stackTrace: null` — so an observed test names exactly one node, its own
|
|
19
|
+
* `TEST_CASE`. Nothing here witnesses which function that test reached, and
|
|
20
|
+
* pairing the test with a function that merely co-occurred in the same run
|
|
21
|
+
* would mint an edge from temporal coincidence. That is the wrong-direction
|
|
22
|
+
* failure rule 2 exists to prevent, and `observe-runtime.ts`'s own header
|
|
23
|
+
* already refuses it by name for the same reason.
|
|
24
|
+
*
|
|
25
|
+
* So: "this test executed and passed" is a fact about one node, recorded as
|
|
26
|
+
* one. "This test covers that function" remains whatever the static graph
|
|
27
|
+
* already claimed, at whatever resolution it claimed it.
|
|
28
|
+
*
|
|
29
|
+
* ## Why the denominators are reported and not just the successes
|
|
30
|
+
*
|
|
31
|
+
* `TraceCoverage` carries `testsObserved` and `notRun` because the collector
|
|
32
|
+
* learned the hard way that "12 passed" must never silently be "9 passed and 3
|
|
33
|
+
* that never ran". The same discipline applies one layer up: this reply reports
|
|
34
|
+
* how many results the runner produced, how many resolved to a graph node, and
|
|
35
|
+
* how many did not — because `recorded: 3` against a 40-test suite reads as
|
|
36
|
+
* full coverage to anyone who is not shown the denominator.
|
|
37
|
+
*
|
|
38
|
+
* ## Class and tier
|
|
39
|
+
*
|
|
40
|
+
* `action` — it spawns a process that executes the repository's own code, and
|
|
41
|
+
* it writes EARNED rows that a later `verification_status` will read. Gated by
|
|
42
|
+
* the same two-call `confirmToken` handshake `observe_runtime` and `questions`
|
|
43
|
+
* use.
|
|
44
|
+
*
|
|
45
|
+
* `evidence` — it reports what ran. It draws no conclusion about the code and
|
|
46
|
+
* writes no finding or hypothesis.
|
|
47
|
+
*
|
|
48
|
+
* It does carry a `reportCategory`, and it used to read oddly:
|
|
49
|
+
* `deriveEnvelopeCategory` hardcoded `hasRuntimeEvidence: false`, so a reply
|
|
50
|
+
* whose `resolutionFloor` was 4 and whose `reliabilityCap` was A still
|
|
51
|
+
* rendered as `unconfirmed` — the envelope contradicting itself. The flag is
|
|
52
|
+
* now *declared* rather than inferred: this tool runs the repository's own
|
|
53
|
+
* test suite, so it hands the render layer a {@link WitnessedEvidence} count
|
|
54
|
+
* of the channels its run actually saw, and an answer resting on edges it
|
|
55
|
+
* witnessed renders `strongly supported`. Declaring it is what makes the
|
|
56
|
+
* promotion true rather than assumed — a resolution floor of 4 can be reached
|
|
57
|
+
* without anything having been watched, which is why the floor is no longer
|
|
58
|
+
* what the category reads.
|
|
59
|
+
*
|
|
60
|
+
* The count comes from `observe_runtime`'s `witnessedSignalTypes`, not from a
|
|
61
|
+
* tally here. The clamp to the six declared channels and the drop of signals
|
|
62
|
+
* Descry does not count are that function's rules, and a second
|
|
63
|
+
* implementation of them is a second place for the vocabulary to drift.
|
|
64
|
+
*
|
|
65
|
+
* `confirmed` is still unreachable from this surface, and deliberately: it
|
|
66
|
+
* needs direct mechanism evidence, which no graph query produces. Shared
|
|
67
|
+
* render-layer behaviour, identical for `observe_runtime`, and still not this
|
|
68
|
+
* tool's to override.
|
|
69
|
+
*/
|
|
70
|
+
import { isAbsolute, join } from "node:path";
|
|
71
|
+
import { randomBytes } from "node:crypto";
|
|
72
|
+
import { applyObservedTests, counts } from "@descryy/core";
|
|
73
|
+
import { witnessedSignalTypes } from "./observe-runtime.js";
|
|
74
|
+
import { createTestRunnerCollector } from "@descryy/runtime-test-runner";
|
|
75
|
+
import { resolveObservedTestCase } from "@descryy/runtime-test-runner";
|
|
76
|
+
import { answer, optionalInteger, optionalString, requiredString, ToolInputError, } from "./kit.js";
|
|
77
|
+
const DEFAULT_TIMEOUT_MS = 600_000;
|
|
78
|
+
const SCHEMA = {
|
|
79
|
+
type: "object",
|
|
80
|
+
properties: {
|
|
81
|
+
command: {
|
|
82
|
+
type: "string",
|
|
83
|
+
description: "The command that runs this project's test suite, exactly as you would type it in a terminal, " +
|
|
84
|
+
"whatever this project's runner happens to be. It is run in the repository and it executes your " +
|
|
85
|
+
"code, which is why the call takes a two-step confirmation. The runner is identified from the " +
|
|
86
|
+
"command itself; a runner Descry has no reporter for is refused by name rather than run blind.",
|
|
87
|
+
},
|
|
88
|
+
cwd: {
|
|
89
|
+
type: "string",
|
|
90
|
+
description: "Where to run it. Relative paths resolve against the repository root; absent means the " +
|
|
91
|
+
"repository root itself.",
|
|
92
|
+
},
|
|
93
|
+
timeoutMs: {
|
|
94
|
+
type: "integer",
|
|
95
|
+
minimum: 1,
|
|
96
|
+
description: "How long to let the suite run before giving up on it. Default 600000 (10 minutes).",
|
|
97
|
+
},
|
|
98
|
+
confirmToken: {
|
|
99
|
+
type: "string",
|
|
100
|
+
description: "The token returned by an unconfirmed call. This tool runs nothing without it: the first " +
|
|
101
|
+
"call describes what it would do and mints a token, the second performs it.",
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
required: ["command"],
|
|
105
|
+
additionalProperties: false,
|
|
106
|
+
};
|
|
107
|
+
const TEST_RESULT_EVENT_TYPES = new Set(["TEST_PASSED", "TEST_FAILED", "TEST_SKIPPED"]);
|
|
108
|
+
function outcomeOf(eventType) {
|
|
109
|
+
if (eventType === "TEST_PASSED")
|
|
110
|
+
return "passed";
|
|
111
|
+
if (eventType === "TEST_FAILED")
|
|
112
|
+
return "failed";
|
|
113
|
+
return "skipped";
|
|
114
|
+
}
|
|
115
|
+
function nameOf(evidence) {
|
|
116
|
+
const payload = evidence.payload;
|
|
117
|
+
if (typeof payload.qualifiedName === "string")
|
|
118
|
+
return payload.qualifiedName;
|
|
119
|
+
if (typeof payload.name === "string")
|
|
120
|
+
return payload.name;
|
|
121
|
+
return "(unnamed test)";
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Turn a run's evidence into observations this graph can hold.
|
|
125
|
+
*
|
|
126
|
+
* Separated from {@link run} because it is the part with a decision in it, and
|
|
127
|
+
* a decision that is only reachable by spawning a real test runner is a
|
|
128
|
+
* decision that does not get tested. Every result lands in `observations` or
|
|
129
|
+
* `unresolved`, so the caller can report a denominator rather than a success
|
|
130
|
+
* count on its own.
|
|
131
|
+
*
|
|
132
|
+
* `TEST_STARTED` is deliberately ignored: it is announced before the runner
|
|
133
|
+
* knows the outcome, so counting it would double every test and count a
|
|
134
|
+
* skipped one as having run.
|
|
135
|
+
*/
|
|
136
|
+
export function observationsFromEvidence(driver, evidence, repo, options = {}) {
|
|
137
|
+
const observations = [];
|
|
138
|
+
const unresolved = [];
|
|
139
|
+
for (const item of evidence) {
|
|
140
|
+
if (!TEST_RESULT_EVENT_TYPES.has(item.eventType))
|
|
141
|
+
continue;
|
|
142
|
+
const outcome = outcomeOf(item.eventType);
|
|
143
|
+
const qualifiedName = nameOf(item);
|
|
144
|
+
const resolution = resolveObservedTestCase(driver, item, repo, options);
|
|
145
|
+
if (resolution.outcome !== "resolved") {
|
|
146
|
+
unresolved.push({ qualifiedName, outcome, reason: resolution.reason });
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
const payload = item.payload;
|
|
150
|
+
observations.push({
|
|
151
|
+
nodeId: resolution.node.id,
|
|
152
|
+
qualifiedName,
|
|
153
|
+
outcome,
|
|
154
|
+
durationMs: typeof payload.durationMs === "number" ? payload.durationMs : null,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
return { observations, unresolved };
|
|
158
|
+
}
|
|
159
|
+
async function run(args, ctx) {
|
|
160
|
+
const session = ctx.session;
|
|
161
|
+
const command = requiredString(args, "command");
|
|
162
|
+
const cwdArg = optionalString(args, "cwd");
|
|
163
|
+
const timeoutMs = optionalInteger(args, "timeoutMs", 1) ?? DEFAULT_TIMEOUT_MS;
|
|
164
|
+
const base = session.provider().baseStamp();
|
|
165
|
+
const notes = [
|
|
166
|
+
"This records which tests ran, not what they covered. A test that executed is a fact about one " +
|
|
167
|
+
"node — its own TEST_CASE. Nothing here witnesses which functions a test reached, so no edge is " +
|
|
168
|
+
"promoted and any TESTS edge keeps whatever resolution the static graph gave it.",
|
|
169
|
+
"Read every count against testsReported. A recorded count on its own cannot distinguish a fully " +
|
|
170
|
+
"mapped suite from a mostly unmapped one.",
|
|
171
|
+
];
|
|
172
|
+
const refuse = (headline, data = {}) => answer({
|
|
173
|
+
headline,
|
|
174
|
+
state: "refused",
|
|
175
|
+
nameLevel: true,
|
|
176
|
+
// Nothing ran, so nothing was observed. A refusal reporting the tier its
|
|
177
|
+
// successful path would have reached is indistinguishable from a real
|
|
178
|
+
// answer, which is the failure this repository's own UAT already caught.
|
|
179
|
+
resolutionFloor: 0,
|
|
180
|
+
commitSha: base.commitSha,
|
|
181
|
+
graphBuiltAt: base.graphBuiltAt,
|
|
182
|
+
irSchemaVersion: base.irSchemaVersion,
|
|
183
|
+
commitSpread: base.commitSpread,
|
|
184
|
+
notes,
|
|
185
|
+
data: {
|
|
186
|
+
runId: null,
|
|
187
|
+
testsReported: 0,
|
|
188
|
+
notRun: 0,
|
|
189
|
+
recorded: [],
|
|
190
|
+
unresolved: [],
|
|
191
|
+
refused: [],
|
|
192
|
+
outcomes: {},
|
|
193
|
+
...data,
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
// Correlation resolves each result against this graph. Against an empty one
|
|
197
|
+
// it resolves nothing, and reporting that as a clean run would be the exact
|
|
198
|
+
// "empty means broken" collapse the five states exist to stop.
|
|
199
|
+
const driver = session.store().driver;
|
|
200
|
+
if (counts(driver).nodes === 0) {
|
|
201
|
+
return refuse("This repository has no graph yet, so a test result has nothing to be resolved against. Run " +
|
|
202
|
+
"analyze first — an observation that cannot name a node cannot become a fact.");
|
|
203
|
+
}
|
|
204
|
+
const root = await session.root();
|
|
205
|
+
const cwd = cwdArg === undefined ? session.repoPath : isAbsolute(cwdArg) ? cwdArg : join(session.repoPath, cwdArg);
|
|
206
|
+
const collected = [];
|
|
207
|
+
const collector = createTestRunnerCollector({
|
|
208
|
+
configuration: { command, cwd },
|
|
209
|
+
});
|
|
210
|
+
ctx.progress(`Running ${command}`);
|
|
211
|
+
const started = await collector.start({
|
|
212
|
+
executionId: `observe-tests-${Date.now()}`,
|
|
213
|
+
configuration: {
|
|
214
|
+
environmentTier: "tier-0-ci-attached",
|
|
215
|
+
fidelityLevel: 1,
|
|
216
|
+
timeoutMs,
|
|
217
|
+
services: {},
|
|
218
|
+
testRunner: { command, cwd },
|
|
219
|
+
},
|
|
220
|
+
emit: (item) => {
|
|
221
|
+
collected.push(item);
|
|
222
|
+
},
|
|
223
|
+
});
|
|
224
|
+
if (!started.available) {
|
|
225
|
+
return refuse(`The test command could not be run: ${started.reason} Nothing was started and nothing was written.`);
|
|
226
|
+
}
|
|
227
|
+
await collector.waitForCompletion();
|
|
228
|
+
await collector.stop();
|
|
229
|
+
const coverage = collector.traceCoverage();
|
|
230
|
+
const { observations, unresolved } = observationsFromEvidence(driver, collected, root.repo, {
|
|
231
|
+
repoRoot: root.absolutePath,
|
|
232
|
+
});
|
|
233
|
+
const runId = `tests-${randomBytes(6).toString("hex")}`;
|
|
234
|
+
const written = applyObservedTests(driver, {
|
|
235
|
+
runId,
|
|
236
|
+
commitSha: root.commitSha,
|
|
237
|
+
observations,
|
|
238
|
+
});
|
|
239
|
+
const outcomes = {};
|
|
240
|
+
for (const observation of observations) {
|
|
241
|
+
outcomes[observation.outcome] = (outcomes[observation.outcome] ?? 0) + 1;
|
|
242
|
+
}
|
|
243
|
+
if (unresolved.length > 0) {
|
|
244
|
+
notes.push(`${unresolved.length} of ${coverage.testsObserved} results reached no node in this graph and were ` +
|
|
245
|
+
"not recorded. Each carries the resolver's own reason — a test file the graph never indexed and " +
|
|
246
|
+
"a name the graph spells differently are different problems.");
|
|
247
|
+
}
|
|
248
|
+
return answer({
|
|
249
|
+
headline: `${command} produced ${coverage.testsObserved} result${coverage.testsObserved === 1 ? "" : "s"}; ` +
|
|
250
|
+
`${written.recorded.length} recorded against graph nodes` +
|
|
251
|
+
(coverage.notRun > 0 ? `, ${coverage.notRun} did not run` : "") +
|
|
252
|
+
".",
|
|
253
|
+
state: written.recorded.length > 0 ? "ok" : "empty",
|
|
254
|
+
data: {
|
|
255
|
+
runId,
|
|
256
|
+
testsReported: coverage.testsObserved,
|
|
257
|
+
notRun: coverage.notRun,
|
|
258
|
+
recorded: written.recorded,
|
|
259
|
+
unresolved,
|
|
260
|
+
refused: written.refused.map((r) => ({ nodeId: r.nodeId, reason: r.reason })),
|
|
261
|
+
outcomes,
|
|
262
|
+
},
|
|
263
|
+
// G3's precondition, declared rather than inferred, on the same guard
|
|
264
|
+
// `observe_runtime` uses: a completed run that collected nothing witnessed
|
|
265
|
+
// nothing, and claiming otherwise would assert a precondition on an empty
|
|
266
|
+
// array.
|
|
267
|
+
//
|
|
268
|
+
// Gated on evidence, not on `written.recorded.length`. Whether a result
|
|
269
|
+
// could be recorded against a graph node is a fact about the graph, and
|
|
270
|
+
// `resolutionFloor` below already caps the category for a run that
|
|
271
|
+
// recorded none — a suite that ran and resolved to nothing reports
|
|
272
|
+
// `unconfirmed` through the cap, not by pretending it watched nothing.
|
|
273
|
+
...(collected.length === 0
|
|
274
|
+
? {}
|
|
275
|
+
: { runtimeEvidence: { independentSignalTypes: witnessedSignalTypes(collected) } }),
|
|
276
|
+
// Witnessed by running it. R4 is what "observed at runtime" means, and that
|
|
277
|
+
// is exactly what happened to every recorded row — regardless of the
|
|
278
|
+
// resolution the static graph holds for the same node.
|
|
279
|
+
resolutionFloor: written.recorded.length > 0 ? 4 : 0,
|
|
280
|
+
nameLevel: true,
|
|
281
|
+
commitSha: base.commitSha,
|
|
282
|
+
graphBuiltAt: base.graphBuiltAt,
|
|
283
|
+
irSchemaVersion: base.irSchemaVersion,
|
|
284
|
+
commitSpread: base.commitSpread,
|
|
285
|
+
notes,
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
function describeAction(args) {
|
|
289
|
+
const command = args["command"];
|
|
290
|
+
if (typeof command !== "string")
|
|
291
|
+
throw new ToolInputError('"command" must be a string');
|
|
292
|
+
const cwd = args["cwd"];
|
|
293
|
+
return (`Run "${command}"${typeof cwd === "string" ? ` in ${cwd}` : ""} and record which tests executed. ` +
|
|
294
|
+
"This executes your repository's own code. It writes to the graph's earned ledger; it changes no " +
|
|
295
|
+
"source file and promotes no edge.");
|
|
296
|
+
}
|
|
297
|
+
export const observeTestsTool = {
|
|
298
|
+
name: "observe_tests",
|
|
299
|
+
class: "action",
|
|
300
|
+
tier: "evidence",
|
|
301
|
+
version: "1.0.0",
|
|
302
|
+
title: "Run the test suite and record what actually executed",
|
|
303
|
+
description: "Runs this project's test suite and records which test cases actually ran, and how they finished, " +
|
|
304
|
+
"against the graph's own TEST_CASE nodes. This is the coverage axis — what was actually verified — " +
|
|
305
|
+
"which is a separate question from any finding's confidence, and it is the one runtime signal that " +
|
|
306
|
+
"needs no application booted. It records that a test executed; it does not witness which functions " +
|
|
307
|
+
"the test reached, so it promotes no edge. Running takes a two-call confirmation: the first call " +
|
|
308
|
+
"describes what it would run and returns a token, the second sends \"confirmToken\" to actually run it.",
|
|
309
|
+
inputSchema: SCHEMA,
|
|
310
|
+
describeAction,
|
|
311
|
+
run,
|
|
312
|
+
};
|
|
313
|
+
//# sourceMappingURL=observe-tests.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observe-tests.js","sourceRoot":"","sources":["../../src/tools/observe-tests.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AAEH,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,EAA0E,MAAM,eAAe,CAAC;AAGnI,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAEvE,OAAO,EACL,MAAM,EACN,eAAe,EACf,cAAc,EACd,cAAc,EACd,cAAc,GAGf,MAAM,UAAU,CAAC;AAGlB,MAAM,kBAAkB,GAAG,OAAO,CAAC;AAUnC,MAAM,MAAM,GAAG;IACb,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,OAAO,EAAE;YACP,IAAI,EAAE,QAAQ;YACd,WAAW,EACT,+FAA+F;gBAC/F,iGAAiG;gBACjG,+FAA+F;gBAC/F,+FAA+F;SAClG;QACD,GAAG,EAAE;YACH,IAAI,EAAE,QAAQ;YACd,WAAW,EACT,wFAAwF;gBACxF,yBAAyB;SAC5B;QACD,SAAS,EAAE;YACT,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,CAAC;YACV,WAAW,EAAE,oFAAoF;SAClG;QACD,YAAY,EAAE;YACZ,IAAI,EAAE,QAAQ;YACd,WAAW,EACT,0FAA0F;gBAC1F,4EAA4E;SAC/E;KACF;IACD,QAAQ,EAAE,CAAC,SAAS,CAAC;IACrB,oBAAoB,EAAE,KAAK;CACnB,CAAC;AAyBX,MAAM,uBAAuB,GAAwB,IAAI,GAAG,CAAC,CAAC,aAAa,EAAE,aAAa,EAAE,cAAc,CAAC,CAAC,CAAC;AAE7G,SAAS,SAAS,CAAC,SAAiB;IAClC,IAAI,SAAS,KAAK,aAAa;QAAE,OAAO,QAAQ,CAAC;IACjD,IAAI,SAAS,KAAK,aAAa;QAAE,OAAO,QAAQ,CAAC;IACjD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,MAAM,CAAC,QAAmC;IACjD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAwE,CAAC;IAClG,IAAI,OAAO,OAAO,CAAC,aAAa,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC,aAAa,CAAC;IAC5E,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC,IAAI,CAAC;IAC1D,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,wBAAwB,CACtC,MAAiB,EACjB,QAAoC,EACpC,IAAY,EACZ,UAA0C,EAAE;IAE5C,MAAM,YAAY,GAA8B,EAAE,CAAC;IACnD,MAAM,UAAU,GAA6B,EAAE,CAAC;IAEhD,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;YAAE,SAAS;QAE3D,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC1C,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,UAAU,GAAG,uBAAuB,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAExE,IAAI,UAAU,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;YACtC,UAAU,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;YACvE,SAAS;QACX,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,OAA4C,CAAC;QAClE,YAAY,CAAC,IAAI,CAAC;YAChB,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,EAAE;YAC1B,aAAa;YACb,OAAO;YACP,UAAU,EAAE,OAAO,OAAO,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI;SAC/E,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC;AACtC,CAAC;AAED,KAAK,UAAU,GAAG,CAAC,IAA6B,EAAE,GAAgB;IAChE,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;IAC5B,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,eAAe,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,IAAI,kBAAkB,CAAC;IAE9E,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,CAAC;IAC5C,MAAM,KAAK,GAAa;QACtB,gGAAgG;YAC9F,iGAAiG;YACjG,iFAAiF;QACnF,iGAAiG;YAC/F,0CAA0C;KAC7C,CAAC;IAEF,MAAM,MAAM,GAAG,CAAC,QAAgB,EAAE,OAAkC,EAAE,EAAgC,EAAE,CACtG,MAAM,CAAmB;QACvB,QAAQ;QACR,KAAK,EAAE,SAAS;QAChB,SAAS,EAAE,IAAI;QACf,yEAAyE;QACzE,sEAAsE;QACtE,yEAAyE;QACzE,eAAe,EAAE,CAAC;QAClB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,eAAe,EAAE,IAAI,CAAC,eAAe;QACrC,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,KAAK;QACL,IAAI,EAAE;YACJ,KAAK,EAAE,IAAI;YACX,aAAa,EAAE,CAAC;YAChB,MAAM,EAAE,CAAC;YACT,QAAQ,EAAE,EAAE;YACZ,UAAU,EAAE,EAAE;YACd,OAAO,EAAE,EAAE;YACX,QAAQ,EAAE,EAAE;YACZ,GAAG,IAAI;SACR;KACF,CAAC,CAAC;IAEL,4EAA4E;IAC5E,4EAA4E;IAC5E,+DAA+D;IAC/D,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC;IACtC,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,MAAM,CACX,6FAA6F;YAC3F,8EAA8E,CACjF,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;IAClC,MAAM,GAAG,GACP,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAEzG,MAAM,SAAS,GAAsB,EAAE,CAAC;IACxC,MAAM,SAAS,GAAG,yBAAyB,CAAC;QAC1C,aAAa,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE;KAChC,CAAC,CAAC;IAEH,GAAG,CAAC,QAAQ,CAAC,WAAW,OAAO,EAAE,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC;QACpC,WAAW,EAAE,iBAAiB,IAAI,CAAC,GAAG,EAAE,EAAE;QAC1C,aAAa,EAAE;YACb,eAAe,EAAE,oBAAoB;YACrC,aAAa,EAAE,CAAC;YAChB,SAAS;YACT,QAAQ,EAAE,EAAE;YACZ,UAAU,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE;SAC7B;QACD,IAAI,EAAE,CAAC,IAAqB,EAAE,EAAE;YAC9B,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;KACF,CAAC,CAAC;IAEH,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QACvB,OAAO,MAAM,CACX,sCAAsC,OAAO,CAAC,MAAM,+CAA+C,CACpG,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,CAAC,iBAAiB,EAAE,CAAC;IACpC,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;IAEvB,MAAM,QAAQ,GAAG,SAAS,CAAC,aAAa,EAAE,CAAC;IAC3C,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,wBAAwB,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE;QAC1F,QAAQ,EAAE,IAAI,CAAC,YAAY;KAC5B,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,SAAS,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;IACxD,MAAM,OAAO,GAAG,kBAAkB,CAAC,MAAM,EAAE;QACzC,KAAK;QACL,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,YAAY;KACb,CAAC,CAAC;IAEH,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;QACvC,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAC3E,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,KAAK,CAAC,IAAI,CACR,GAAG,UAAU,CAAC,MAAM,OAAO,QAAQ,CAAC,aAAa,kDAAkD;YACjG,iGAAiG;YACjG,6DAA6D,CAChE,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAmB;QAC9B,QAAQ,EACN,GAAG,OAAO,aAAa,QAAQ,CAAC,aAAa,UAAU,QAAQ,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI;YAClG,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,+BAA+B;YACzD,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,MAAM,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/D,GAAG;QACL,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO;QACnD,IAAI,EAAE;YACJ,KAAK;YACL,aAAa,EAAE,QAAQ,CAAC,aAAa;YACrC,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,UAAU;YACV,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;YAC7E,QAAQ;SACT;QACD,sEAAsE;QACtE,2EAA2E;QAC3E,0EAA0E;QAC1E,SAAS;QACT,EAAE;QACF,wEAAwE;QACxE,wEAAwE;QACxE,mEAAmE;QACnE,mEAAmE;QACnE,uEAAuE;QACvE,GAAG,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;YACxB,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,eAAe,EAAE,EAAE,sBAAsB,EAAE,oBAAoB,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC;QACrF,4EAA4E;QAC5E,qEAAqE;QACrE,uDAAuD;QACvD,eAAe,EAAE,OAAO,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACpD,SAAS,EAAE,IAAI;QACf,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,eAAe,EAAE,IAAI,CAAC,eAAe;QACrC,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,KAAK;KACN,CAAC,CAAC;AACL,CAAC;AAED,SAAS,cAAc,CAAC,IAA6B;IACnD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;IAChC,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,MAAM,IAAI,cAAc,CAAC,4BAA4B,CAAC,CAAC;IACxF,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;IACxB,OAAO,CACL,QAAQ,OAAO,IAAI,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,oCAAoC;QAClG,kGAAkG;QAClG,mCAAmC,CACpC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAmB;IAC9C,IAAI,EAAE,eAAe;IACrB,KAAK,EAAE,QAAQ;IACf,IAAI,EAAE,UAAU;IAChB,OAAO,EAAE,OAAO;IAChB,KAAK,EAAE,sDAAsD;IAC7D,WAAW,EACT,mGAAmG;QACnG,oGAAoG;QACpG,oGAAoG;QACpG,oGAAoG;QACpG,kGAAkG;QAClG,wGAAwG;IAC1G,WAAW,EAAE,MAA4C;IACzD,cAAc;IACd,GAAG;CACJ,CAAC"}
|
|
@@ -45,6 +45,17 @@ export interface AffectedRef {
|
|
|
45
45
|
readonly id: string;
|
|
46
46
|
readonly score: number;
|
|
47
47
|
readonly depth: number;
|
|
48
|
+
/** 1-based position in this answer, highest score first. */
|
|
49
|
+
readonly rank: number;
|
|
50
|
+
/**
|
|
51
|
+
* `top` / `notable` / `rest` by rank, never by an absolute score threshold.
|
|
52
|
+
* This score is `weightedBfs`'s confidence decay — `changeRisk` passes only a
|
|
53
|
+
* budget, so it takes the default `weightFor` — and §12.7's tiers were
|
|
54
|
+
* calibrated against `scoping/`'s designed weights instead. See
|
|
55
|
+
* `prominence.ts`'s header for why reusing them here would be a calibrated
|
|
56
|
+
* label on an uncalibrated number.
|
|
57
|
+
*/
|
|
58
|
+
readonly prominence: "top" | "notable" | "rest";
|
|
48
59
|
}
|
|
49
60
|
/**
|
|
50
61
|
* The three lists and the one node map they name into.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pr-analysis.d.ts","sourceRoot":"","sources":["../../src/tools/pr-analysis.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAIH,OAAO,EAOL,KAAK,SAAS,EAEd,KAAK,cAAc,EACpB,MAAM,UAAU,CAAC;AAGlB;;;;;;;;;GASG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"pr-analysis.d.ts","sourceRoot":"","sources":["../../src/tools/pr-analysis.ts"],"names":[],"mappings":"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"}
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
* times in one reply. `indexPrAnalysisNodes` collapses that: the lists name
|
|
31
31
|
* ids, `nodes` holds each node once. Tool version 2.0.0 for it.
|
|
32
32
|
*/
|
|
33
|
-
import { changedFiles, changeRisk, NODE_BUDGETS, nodesInFiles } from "@descryy/core";
|
|
33
|
+
import { changedFiles, changeRisk, NODE_BUDGETS, nodesInFiles, withProminence } from "@descryy/core";
|
|
34
34
|
import { answer, briefNode, optionalEnum, optionalInteger, optionalString, requiredString, } from "./kit.js";
|
|
35
35
|
/**
|
|
36
36
|
* Collapse three overlapping node lists into one map plus three id lists.
|
|
@@ -47,11 +47,11 @@ export function indexPrAnalysisNodes(affected, untested, tests) {
|
|
|
47
47
|
return node.id;
|
|
48
48
|
};
|
|
49
49
|
return {
|
|
50
|
-
affected: affected.map((entry) => ({
|
|
50
|
+
affected: withProminence(affected.map((entry) => ({
|
|
51
51
|
id: remember(entry.node),
|
|
52
52
|
score: Number(entry.score.toFixed(4)),
|
|
53
53
|
depth: entry.depth,
|
|
54
|
-
})),
|
|
54
|
+
}))),
|
|
55
55
|
untested: untested.map(remember),
|
|
56
56
|
tests: tests.map(remember),
|
|
57
57
|
nodes,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pr-analysis.js","sourceRoot":"","sources":["../../src/tools/pr-analysis.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"pr-analysis.js","sourceRoot":"","sources":["../../src/tools/pr-analysis.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `pre_push` — one call where a developer about to push would otherwise make four.
|
|
3
|
+
*
|
|
4
|
+
* The UAT's own verdict was that in agentic use the gap is composition, not
|
|
5
|
+
* correctness: `scope`, `pr_analysis`, `contracts` and `validate` each answer
|
|
6
|
+
* well, and nothing puts them together at the moment someone actually wants
|
|
7
|
+
* them together. This is that composition, under the tightest budget the
|
|
8
|
+
* scoping tiers define.
|
|
9
|
+
*
|
|
10
|
+
* ## What "under the pre-push tier" actually means, per constituent
|
|
11
|
+
*
|
|
12
|
+
* The plan this comes from said the tier was "honoured by `scope`, `pr_analysis`
|
|
13
|
+
* and `contracts`". Two of those are true and the third is not, and the
|
|
14
|
+
* difference decides what this tool can pass down:
|
|
15
|
+
*
|
|
16
|
+
* - `scope` and `pr_analysis` take a `trigger`, and apply
|
|
17
|
+
* `NODE_BUDGETS["pre-push"]` (200 nodes) to their traversal. Passed straight
|
|
18
|
+
* through.
|
|
19
|
+
* - `contracts` has **no `trigger` and no node budget**, because it does not
|
|
20
|
+
* traverse — it compares every endpoint in the graph. Its expensive half is
|
|
21
|
+
* the shape comparison, and its own schema already names the answer:
|
|
22
|
+
* `pathsOnly` is "the honest choice for a pre-push run". So that is what the
|
|
23
|
+
* tier means here, and this tool sets it.
|
|
24
|
+
* - `validate` has no traversal budget either; it is bounded by `maxFindings`,
|
|
25
|
+
* which this tool tightens rather than leaving at its default 25.
|
|
26
|
+
*
|
|
27
|
+
* ## Why findings are grouped by source and not merged into one ranking
|
|
28
|
+
*
|
|
29
|
+
* A single global ranking would need to say that a contract mismatch outranks
|
|
30
|
+
* an unset environment variable, or the reverse. Descry has no model that
|
|
31
|
+
* supports either claim, and inventing one would be a judgement presented as a
|
|
32
|
+
* measurement — the same reason `contracts` ranks by evidence strength rather
|
|
33
|
+
* than severity. So each source contributes its own top few, and the envelope
|
|
34
|
+
* says plainly that the sources are not ranked against each other.
|
|
35
|
+
*
|
|
36
|
+
* That is still one call, one envelope, and a short read. It just does not
|
|
37
|
+
* pretend to a comparison nobody has made.
|
|
38
|
+
*
|
|
39
|
+
* ## Blocking versus informational
|
|
40
|
+
*
|
|
41
|
+
* `blockingTotal` counts `contracts` and `validate` findings only. Those are
|
|
42
|
+
* claims that something is *wrong*. `scope` and `pr_analysis` answer "what does
|
|
43
|
+
* this change touch" — real, useful, and not a defect, so counting them would
|
|
44
|
+
* make every change with a blast radius look like a failure. `descry check`
|
|
45
|
+
* exits non-zero on `blockingTotal`, which is why the line has to be drawn
|
|
46
|
+
* here rather than left to the caller.
|
|
47
|
+
*
|
|
48
|
+
* ## Class and tier
|
|
49
|
+
*
|
|
50
|
+
* `read` — it runs four read tools and writes nothing. `evidence` — it reports
|
|
51
|
+
* what those four found and draws no conclusion of its own.
|
|
52
|
+
*/
|
|
53
|
+
import { type ToolDefinition } from "./kit.ts";
|
|
54
|
+
export type PrePushSource = "scope" | "pr_analysis" | "contracts" | "validate";
|
|
55
|
+
export interface PrePushSection {
|
|
56
|
+
readonly source: PrePushSource;
|
|
57
|
+
/** `ok`, `empty`, `refused`, `failed` — this constituent's own state, never flattened away. */
|
|
58
|
+
readonly state: string;
|
|
59
|
+
/** How many items this source found in total, before this tool took its top few. */
|
|
60
|
+
readonly total: number;
|
|
61
|
+
/** The top few, in the order that source reported them. */
|
|
62
|
+
readonly shown: readonly unknown[];
|
|
63
|
+
/** True when this source's findings count toward `blockingTotal`. */
|
|
64
|
+
readonly blocking: boolean;
|
|
65
|
+
/** This source's own headline, kept verbatim. */
|
|
66
|
+
readonly headline: string;
|
|
67
|
+
}
|
|
68
|
+
export interface PrePushData {
|
|
69
|
+
readonly files: readonly string[];
|
|
70
|
+
readonly sections: readonly PrePushSection[];
|
|
71
|
+
/** Contract and environment findings only — see the module header on why scope is not counted. */
|
|
72
|
+
readonly blockingTotal: number;
|
|
73
|
+
/** The node budget actually applied to the traversing constituents. */
|
|
74
|
+
readonly nodeBudget: number;
|
|
75
|
+
}
|
|
76
|
+
export declare const prePushTool: ToolDefinition;
|
|
77
|
+
//# sourceMappingURL=pre-push.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pre-push.d.ts","sourceRoot":"","sources":["../../src/tools/pre-push.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAKH,OAAO,EAML,KAAK,cAAc,EACpB,MAAM,UAAU,CAAC;AAuClB,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,aAAa,GAAG,WAAW,GAAG,UAAU,CAAC;AAE/E,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,+FAA+F;IAC/F,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,oFAAoF;IACpF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,2DAA2D;IAC3D,QAAQ,CAAC,KAAK,EAAE,SAAS,OAAO,EAAE,CAAC;IACnC,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAC;IAC7C,kGAAkG;IAClG,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,uEAAuE;IACvE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAgND,eAAO,MAAM,WAAW,EAAE,cAezB,CAAC"}
|