@descryy/mcp 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/dist/action-handshake.d.ts +8 -75
  2. package/dist/action-handshake.d.ts.map +1 -1
  3. package/dist/action-handshake.js +9 -79
  4. package/dist/action-handshake.js.map +1 -1
  5. package/dist/bin/descry-mcp.d.ts +4 -15
  6. package/dist/bin/descry-mcp.d.ts.map +1 -1
  7. package/dist/bin/descry-mcp.js +12 -42
  8. package/dist/bin/descry-mcp.js.map +1 -1
  9. package/dist/browser/driver.d.ts +62 -178
  10. package/dist/browser/driver.d.ts.map +1 -1
  11. package/dist/browser/driver.js +14 -46
  12. package/dist/browser/driver.js.map +1 -1
  13. package/dist/browser/evidence.d.ts +11 -35
  14. package/dist/browser/evidence.d.ts.map +1 -1
  15. package/dist/browser/evidence.js +25 -51
  16. package/dist/browser/evidence.js.map +1 -1
  17. package/dist/browser/fake-driver.d.ts +12 -16
  18. package/dist/browser/fake-driver.d.ts.map +1 -1
  19. package/dist/browser/fake-driver.js +24 -17
  20. package/dist/browser/fake-driver.js.map +1 -1
  21. package/dist/browser/graph-write.d.ts +4 -45
  22. package/dist/browser/graph-write.d.ts.map +1 -1
  23. package/dist/browser/graph-write.js +8 -53
  24. package/dist/browser/graph-write.js.map +1 -1
  25. package/dist/browser/playwright-driver.d.ts +17 -67
  26. package/dist/browser/playwright-driver.d.ts.map +1 -1
  27. package/dist/browser/playwright-driver.js +169 -166
  28. package/dist/browser/playwright-driver.js.map +1 -1
  29. package/dist/browser/provider.d.ts +5 -34
  30. package/dist/browser/provider.d.ts.map +1 -1
  31. package/dist/browser/provider.js +4 -24
  32. package/dist/browser/provider.js.map +1 -1
  33. package/dist/browser/registry.d.ts +26 -106
  34. package/dist/browser/registry.d.ts.map +1 -1
  35. package/dist/browser/registry.js +20 -77
  36. package/dist/browser/registry.js.map +1 -1
  37. package/dist/browser/scenario-resolve.d.ts +10 -44
  38. package/dist/browser/scenario-resolve.d.ts.map +1 -1
  39. package/dist/browser/scenario-resolve.js +10 -41
  40. package/dist/browser/scenario-resolve.js.map +1 -1
  41. package/dist/browser/scenario-runner.d.ts +12 -70
  42. package/dist/browser/scenario-runner.d.ts.map +1 -1
  43. package/dist/browser/scenario-runner.js +33 -91
  44. package/dist/browser/scenario-runner.js.map +1 -1
  45. package/dist/browser/stack-parser.d.ts +4 -28
  46. package/dist/browser/stack-parser.d.ts.map +1 -1
  47. package/dist/browser/stack-parser.js +12 -39
  48. package/dist/browser/stack-parser.js.map +1 -1
  49. package/dist/browser/tool-support.d.ts +20 -67
  50. package/dist/browser/tool-support.d.ts.map +1 -1
  51. package/dist/browser/tool-support.js +22 -66
  52. package/dist/browser/tool-support.js.map +1 -1
  53. package/dist/browser/url-scheme.d.ts +14 -0
  54. package/dist/browser/url-scheme.d.ts.map +1 -0
  55. package/dist/browser/url-scheme.js +38 -0
  56. package/dist/browser/url-scheme.js.map +1 -0
  57. package/dist/cancellation.d.ts +11 -46
  58. package/dist/cancellation.d.ts.map +1 -1
  59. package/dist/cancellation.js +11 -46
  60. package/dist/cancellation.js.map +1 -1
  61. package/dist/capped.d.ts +17 -0
  62. package/dist/capped.d.ts.map +1 -0
  63. package/dist/capped.js +15 -0
  64. package/dist/capped.js.map +1 -0
  65. package/dist/disclosure-ledger.d.ts +6 -30
  66. package/dist/disclosure-ledger.d.ts.map +1 -1
  67. package/dist/disclosure-ledger.js +4 -26
  68. package/dist/disclosure-ledger.js.map +1 -1
  69. package/dist/index.d.ts +10 -26
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +7 -17
  72. package/dist/index.js.map +1 -1
  73. package/dist/module-trust.d.ts +24 -0
  74. package/dist/module-trust.d.ts.map +1 -0
  75. package/dist/module-trust.js +60 -0
  76. package/dist/module-trust.js.map +1 -0
  77. package/dist/path-confinement.d.ts +31 -0
  78. package/dist/path-confinement.d.ts.map +1 -0
  79. package/dist/path-confinement.js +44 -0
  80. package/dist/path-confinement.js.map +1 -0
  81. package/dist/protocol.d.ts +10 -53
  82. package/dist/protocol.d.ts.map +1 -1
  83. package/dist/protocol.js +14 -60
  84. package/dist/protocol.js.map +1 -1
  85. package/dist/registry.d.ts +10 -58
  86. package/dist/registry.d.ts.map +1 -1
  87. package/dist/registry.js +38 -90
  88. package/dist/registry.js.map +1 -1
  89. package/dist/render.d.ts +79 -11
  90. package/dist/render.d.ts.map +1 -1
  91. package/dist/render.js +126 -14
  92. package/dist/render.js.map +1 -1
  93. package/dist/runtime-registry.d.ts +8 -49
  94. package/dist/runtime-registry.d.ts.map +1 -1
  95. package/dist/runtime-registry.js +72 -63
  96. package/dist/runtime-registry.js.map +1 -1
  97. package/dist/scenarios/index.d.ts +1 -1
  98. package/dist/scenarios/index.d.ts.map +1 -1
  99. package/dist/scenarios/index.js +1 -1
  100. package/dist/scenarios/index.js.map +1 -1
  101. package/dist/scenarios/parse.d.ts +4 -18
  102. package/dist/scenarios/parse.d.ts.map +1 -1
  103. package/dist/scenarios/parse.js +14 -34
  104. package/dist/scenarios/parse.js.map +1 -1
  105. package/dist/scenarios/scenario.d.ts +18 -74
  106. package/dist/scenarios/scenario.d.ts.map +1 -1
  107. package/dist/scenarios/scenario.js +7 -34
  108. package/dist/scenarios/scenario.js.map +1 -1
  109. package/dist/scenarios/storage.d.ts +11 -41
  110. package/dist/scenarios/storage.d.ts.map +1 -1
  111. package/dist/scenarios/storage.js +57 -47
  112. package/dist/scenarios/storage.js.map +1 -1
  113. package/dist/server.d.ts.map +1 -1
  114. package/dist/server.js +55 -13
  115. package/dist/server.js.map +1 -1
  116. package/dist/session.d.ts +69 -239
  117. package/dist/session.d.ts.map +1 -1
  118. package/dist/session.js +76 -231
  119. package/dist/session.js.map +1 -1
  120. package/dist/tools/analyze.d.ts +27 -101
  121. package/dist/tools/analyze.d.ts.map +1 -1
  122. package/dist/tools/analyze.js +58 -148
  123. package/dist/tools/analyze.js.map +1 -1
  124. package/dist/tools/browser-click.d.ts +3 -21
  125. package/dist/tools/browser-click.d.ts.map +1 -1
  126. package/dist/tools/browser-click.js +10 -31
  127. package/dist/tools/browser-click.js.map +1 -1
  128. package/dist/tools/browser-close-session.d.ts +4 -13
  129. package/dist/tools/browser-close-session.d.ts.map +1 -1
  130. package/dist/tools/browser-close-session.js +4 -13
  131. package/dist/tools/browser-close-session.js.map +1 -1
  132. package/dist/tools/browser-fill.d.ts +5 -36
  133. package/dist/tools/browser-fill.d.ts.map +1 -1
  134. package/dist/tools/browser-fill.js +9 -44
  135. package/dist/tools/browser-fill.js.map +1 -1
  136. package/dist/tools/browser-navigate.d.ts +6 -27
  137. package/dist/tools/browser-navigate.d.ts.map +1 -1
  138. package/dist/tools/browser-navigate.js +6 -23
  139. package/dist/tools/browser-navigate.js.map +1 -1
  140. package/dist/tools/browser-run-scenario.d.ts +5 -31
  141. package/dist/tools/browser-run-scenario.d.ts.map +1 -1
  142. package/dist/tools/browser-run-scenario.js +10 -46
  143. package/dist/tools/browser-run-scenario.js.map +1 -1
  144. package/dist/tools/browser-save-scenario.d.ts +3 -28
  145. package/dist/tools/browser-save-scenario.d.ts.map +1 -1
  146. package/dist/tools/browser-save-scenario.js +102 -55
  147. package/dist/tools/browser-save-scenario.js.map +1 -1
  148. package/dist/tools/browser-snapshot.d.ts +6 -39
  149. package/dist/tools/browser-snapshot.d.ts.map +1 -1
  150. package/dist/tools/browser-snapshot.js +4 -31
  151. package/dist/tools/browser-snapshot.js.map +1 -1
  152. package/dist/tools/browser-start-session.d.ts +4 -23
  153. package/dist/tools/browser-start-session.d.ts.map +1 -1
  154. package/dist/tools/browser-start-session.js +38 -51
  155. package/dist/tools/browser-start-session.js.map +1 -1
  156. package/dist/tools/browser-type.d.ts +5 -35
  157. package/dist/tools/browser-type.d.ts.map +1 -1
  158. package/dist/tools/browser-type.js +10 -45
  159. package/dist/tools/browser-type.js.map +1 -1
  160. package/dist/tools/contracts.d.ts +17 -63
  161. package/dist/tools/contracts.d.ts.map +1 -1
  162. package/dist/tools/contracts.js +91 -47
  163. package/dist/tools/contracts.js.map +1 -1
  164. package/dist/tools/cross-pr.d.ts +56 -15
  165. package/dist/tools/cross-pr.d.ts.map +1 -1
  166. package/dist/tools/cross-pr.js +141 -38
  167. package/dist/tools/cross-pr.js.map +1 -1
  168. package/dist/tools/git-diff.d.ts +18 -2
  169. package/dist/tools/git-diff.d.ts.map +1 -1
  170. package/dist/tools/git-diff.js +143 -23
  171. package/dist/tools/git-diff.js.map +1 -1
  172. package/dist/tools/git-history.d.ts +5 -16
  173. package/dist/tools/git-history.d.ts.map +1 -1
  174. package/dist/tools/git-history.js +3 -10
  175. package/dist/tools/git-history.js.map +1 -1
  176. package/dist/tools/history.d.ts +4 -33
  177. package/dist/tools/history.d.ts.map +1 -1
  178. package/dist/tools/history.js +6 -31
  179. package/dist/tools/history.js.map +1 -1
  180. package/dist/tools/impact.d.ts +7 -51
  181. package/dist/tools/impact.d.ts.map +1 -1
  182. package/dist/tools/impact.js +15 -67
  183. package/dist/tools/impact.js.map +1 -1
  184. package/dist/tools/index.d.ts +3 -8
  185. package/dist/tools/index.d.ts.map +1 -1
  186. package/dist/tools/index.js +3 -8
  187. package/dist/tools/index.js.map +1 -1
  188. package/dist/tools/kit.d.ts +66 -113
  189. package/dist/tools/kit.d.ts.map +1 -1
  190. package/dist/tools/kit.js +60 -28
  191. package/dist/tools/kit.js.map +1 -1
  192. package/dist/tools/link-workspace.d.ts +7 -45
  193. package/dist/tools/link-workspace.d.ts.map +1 -1
  194. package/dist/tools/link-workspace.js +10 -48
  195. package/dist/tools/link-workspace.js.map +1 -1
  196. package/dist/tools/lookup.d.ts +4 -14
  197. package/dist/tools/lookup.d.ts.map +1 -1
  198. package/dist/tools/lookup.js +4 -14
  199. package/dist/tools/lookup.js.map +1 -1
  200. package/dist/tools/mark-incident.d.ts +7 -54
  201. package/dist/tools/mark-incident.d.ts.map +1 -1
  202. package/dist/tools/mark-incident.js +15 -68
  203. package/dist/tools/mark-incident.js.map +1 -1
  204. package/dist/tools/observe-runtime.d.ts +27 -210
  205. package/dist/tools/observe-runtime.d.ts.map +1 -1
  206. package/dist/tools/observe-runtime.js +258 -436
  207. package/dist/tools/observe-runtime.js.map +1 -1
  208. package/dist/tools/observe-tests.d.ts +9 -88
  209. package/dist/tools/observe-tests.d.ts.map +1 -1
  210. package/dist/tools/observe-tests.js +34 -108
  211. package/dist/tools/observe-tests.js.map +1 -1
  212. package/dist/tools/pr-analysis.d.ts +18 -2
  213. package/dist/tools/pr-analysis.d.ts.map +1 -1
  214. package/dist/tools/pr-analysis.js +73 -23
  215. package/dist/tools/pr-analysis.js.map +1 -1
  216. package/dist/tools/pre-push.d.ts +94 -9
  217. package/dist/tools/pre-push.d.ts.map +1 -1
  218. package/dist/tools/pre-push.js +139 -34
  219. package/dist/tools/pre-push.js.map +1 -1
  220. package/dist/tools/propagation.d.ts +11 -53
  221. package/dist/tools/propagation.d.ts.map +1 -1
  222. package/dist/tools/propagation.js +14 -57
  223. package/dist/tools/propagation.js.map +1 -1
  224. package/dist/tools/questions.d.ts +13 -63
  225. package/dist/tools/questions.d.ts.map +1 -1
  226. package/dist/tools/questions.js +33 -105
  227. package/dist/tools/questions.js.map +1 -1
  228. package/dist/tools/refusal-fetch.d.ts +4 -40
  229. package/dist/tools/refusal-fetch.d.ts.map +1 -1
  230. package/dist/tools/refusal-fetch.js +4 -40
  231. package/dist/tools/refusal-fetch.js.map +1 -1
  232. package/dist/tools/runtime-incident.d.ts +4 -63
  233. package/dist/tools/runtime-incident.d.ts.map +1 -1
  234. package/dist/tools/runtime-incident.js +10 -87
  235. package/dist/tools/runtime-incident.js.map +1 -1
  236. package/dist/tools/scope.d.ts +7 -25
  237. package/dist/tools/scope.d.ts.map +1 -1
  238. package/dist/tools/scope.js +17 -20
  239. package/dist/tools/scope.js.map +1 -1
  240. package/dist/tools/similar-incidents.d.ts +11 -86
  241. package/dist/tools/similar-incidents.d.ts.map +1 -1
  242. package/dist/tools/similar-incidents.js +7 -71
  243. package/dist/tools/similar-incidents.js.map +1 -1
  244. package/dist/tools/validate.d.ts +31 -47
  245. package/dist/tools/validate.d.ts.map +1 -1
  246. package/dist/tools/validate.js +133 -61
  247. package/dist/tools/validate.js.map +1 -1
  248. package/dist/tools/verification-status.d.ts +9 -64
  249. package/dist/tools/verification-status.d.ts.map +1 -1
  250. package/dist/tools/verification-status.js +9 -62
  251. package/dist/tools/verification-status.js.map +1 -1
  252. package/dist/tools/verify-claim.d.ts +5 -52
  253. package/dist/tools/verify-claim.d.ts.map +1 -1
  254. package/dist/tools/verify-claim.js +6 -56
  255. package/dist/tools/verify-claim.js.map +1 -1
  256. package/dist/transport.d.ts +15 -52
  257. package/dist/transport.d.ts.map +1 -1
  258. package/dist/transport.js +16 -60
  259. package/dist/transport.js.map +1 -1
  260. package/package.json +33 -16
@@ -1,68 +1,8 @@
1
- /**
2
- * `similar_incidents` — "have we seen this failure before?", asked about a
3
- * failure that is **not yet in the graph**.
4
- *
5
- * ## Why this is a separate tool from `impact`'s `related` field
6
- *
7
- * `rootCauseSearch` — the `related` list every `impact` reply carries — walks
8
- * `INCIDENT_CORRELATED`/`FIXED_BY` edges out of a node that already exists.
9
- * It cannot help with a failure observed a moment ago: a stack trace and a set
10
- * of touched files have no node, so there is nothing to walk from. This tool
11
- * is the other direction. It takes the failure as a description and ranks the
12
- * `INCIDENT` nodes the graph already holds against it, using the two signals
13
- * `similarIncidents` (`@descryy/core`, DEC-274 step 2) computes from data the
14
- * graph already has: file-set Jaccard over `INCIDENT_CORRELATED`, and
15
- * token-set Jaccard over the incident's own text. Deterministic, no vector
16
- * store, no model call.
17
- *
18
- * ## The disclosure this tool exists to carry, and it is not optional
19
- *
20
- * DEC-279 makes one sentence mandatory here, and DEC-274 is why. That
21
- * measurement ran the correlation machinery over `descry-core`,
22
- * `descry-runtime` and `descry-adapters` — 734, 459 and 203 commits — and
23
- * found **zero `INCIDENT` nodes in all three**. Not few: zero. Only an
24
- * explicit `git revert` mints an `INCIDENT` today; a fix-forward commit, which
25
- * is how almost every real bug is actually fixed, mints nothing at all.
26
- *
27
- * So this matcher's **recall is not computable — 0/0, not 0%**. It has never
28
- * been handed a real incident to find, and no number describes how many it
29
- * would miss. An empty result therefore means *"no linked incident in this
30
- * graph, and this graph has few or no incidents"* and must never be read as
31
- * *"no similar incident exists."* That is the same *absence is not evidence*
32
- * obligation `impact` already carries on every reply, and `similar-incidents.test.ts`
33
- * fails if it goes missing from either the empty or the non-empty branch.
34
- *
35
- * ## Two different absences, and they are not the same result
36
- *
37
- * `ai-tool-contract.md` §1.3a splits them, and the split is the whole reason
38
- * this endpoint is interesting:
39
- *
40
- * - **Incidents exist and none matched.** The denominator is real, the tool
41
- * looked completely, and the absence is a fact about the code. `state:
42
- * "empty"`, per §1.1's split.
43
- * - **The graph holds zero `INCIDENT` nodes.** There is no denominator.
44
- * Nothing was looked at, and the reason is Descry's producer coverage
45
- * rather than anything about this repository: only `git revert` mints an
46
- * `INCIDENT` and fix-forward mints nothing. Answering "empty" there would
47
- * say *"this code has no similar incidents"* when the true statement is
48
- * *"Descry cannot see most incidents in any codebase"* — the
49
- * empty-denominator defect inside the endpoint written to demonstrate the
50
- * rule against it. So it is a refusal, carried as `state: "refused"` (§1.1:
51
- * `refused` is a result state, and `not analysable` is a report category —
52
- * different axes, never this).
53
- *
54
- * §1.3a generalises it past this tool: **when a query's population is itself
55
- * zero, the answer is a refusal, never an empty result.** That puts this in
56
- * line with its siblings rather than apart from them — `contracts` refuses on
57
- * a graph with no endpoint, `propagation` when no walked edge type touches
58
- * the start node.
59
- *
60
- * The denominator travels in the payload either way. `incidentsInGraph` is
61
- * the population and `analysed` is false only when it is zero, so a caller
62
- * can tell the two absences apart **from the payload alone, with no string
63
- * matching on prose** — §1's distinguishability requirement, satisfied
64
- * without waiting for the wider envelope.
65
- */
1
+ /** `similar_incidents` ranks existing `INCIDENT` nodes against a failure with no graph node yet,
2
+ * deterministically (file/token Jaccard, no vector store). DEC-274 found zero `INCIDENT` nodes
3
+ * across three repos (734/459/203 commits): recall is 0/0, not 0% — an empty result never means
4
+ * "no similar incident exists" (DEC-279). §1.3a: a zero-incident graph is `refused`, never `empty`
5
+ * — the same split `contracts` and `propagation` apply to their own zero-population case. */
66
6
  import { type SimilarIncidentSignalKind } from "@descryy/core";
67
7
  import { type BriefNode, type ToolDefinition } from "./kit.ts";
68
8
  /** One signal that fired for a candidate — the "why", never a bare score. */
@@ -75,32 +15,17 @@ export interface SimilarIncidentReport {
75
15
  readonly incident: BriefNode;
76
16
  /** The `FIX_PATTERN` this incident resolved to, when a `FIXED_BY` edge exists. */
77
17
  readonly fix: BriefNode | null;
78
- /**
79
- * How this incident came to exist — the `INCIDENT` node's own
80
- * `attrs.detectedVia`.
81
- *
82
- * Reported per match rather than folded away, because the mechanisms are not
83
- * interchangeable and a ranked list that hides the difference is not
84
- * reportable. `explicit-revert` and `manual-revert` rest on a revert somebody
85
- * wrote; `issue-reference` on a developer's `Fixes #123`; `runtime-observed`
86
- * on a process that really died; `developer-confirmed` on a person saying so,
87
- * which is testimony and capped at reliability class B by DEC-223 wherever it
88
- * is used. `null` for an incident minted before this field existed.
89
- */
18
+ /** How this incident was detected (`attrs.detectedVia`) — reported per match since the
19
+ * mechanisms differ: revert, `Fixes #123`, a process dying at runtime, or `developer-confirmed`
20
+ * testimony (capped at reliability B, DEC-223). `null` for incidents minted before this field. */
90
21
  readonly detectedVia: string | null;
91
22
  readonly signals: readonly SimilarIncidentSignalReport[];
92
23
  /** Weighted combination of every signal the query attempted, 0..1. */
93
24
  readonly score: number;
94
25
  }
95
- /**
96
- * One shape, both branches.
97
- *
98
- * `analysed: false` with `incidentsInGraph: 0` is the zero-denominator case
99
- * and arrives with `state: "refused"`; every other reply is `ok`.
100
- * The two counts are in the payload rather than only in the prose because a
101
- * caller deciding what to say about an empty list needs the denominator, and
102
- * a sentence it has to parse is not a denominator.
103
- */
26
+ /** One shape, both branches: `analysed: false` with `incidentsInGraph: 0` is the zero-denominator
27
+ * case, `state: "refused"`. Counts live in the payload, not just prose, so a caller can read the
28
+ * denominator without parsing a sentence. */
104
29
  export interface SimilarIncidentsData {
105
30
  readonly query: {
106
31
  readonly touchedFiles: readonly string[];
@@ -1 +1 @@
1
- {"version":3,"file":"similar-incidents.d.ts","sourceRoot":"","sources":["../../src/tools/similar-incidents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgEG;AAEH,OAAO,EAAoB,KAAK,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAEjF,OAAO,EAOL,KAAK,SAAS,EAEd,KAAK,cAAc,EACpB,MAAM,UAAU,CAAC;AAiClB,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;;;;;;;;;;;OAWG;IACH,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;;;;;;;;GAQG;AACH,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;AA6JD,eAAO,MAAM,oBAAoB,EAAE,cAqBlC,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;AAiClB,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;AAyJD,eAAO,MAAM,oBAAoB,EAAE,cAqBlC,CAAC"}
@@ -1,68 +1,8 @@
1
- /**
2
- * `similar_incidents` — "have we seen this failure before?", asked about a
3
- * failure that is **not yet in the graph**.
4
- *
5
- * ## Why this is a separate tool from `impact`'s `related` field
6
- *
7
- * `rootCauseSearch` — the `related` list every `impact` reply carries — walks
8
- * `INCIDENT_CORRELATED`/`FIXED_BY` edges out of a node that already exists.
9
- * It cannot help with a failure observed a moment ago: a stack trace and a set
10
- * of touched files have no node, so there is nothing to walk from. This tool
11
- * is the other direction. It takes the failure as a description and ranks the
12
- * `INCIDENT` nodes the graph already holds against it, using the two signals
13
- * `similarIncidents` (`@descryy/core`, DEC-274 step 2) computes from data the
14
- * graph already has: file-set Jaccard over `INCIDENT_CORRELATED`, and
15
- * token-set Jaccard over the incident's own text. Deterministic, no vector
16
- * store, no model call.
17
- *
18
- * ## The disclosure this tool exists to carry, and it is not optional
19
- *
20
- * DEC-279 makes one sentence mandatory here, and DEC-274 is why. That
21
- * measurement ran the correlation machinery over `descry-core`,
22
- * `descry-runtime` and `descry-adapters` — 734, 459 and 203 commits — and
23
- * found **zero `INCIDENT` nodes in all three**. Not few: zero. Only an
24
- * explicit `git revert` mints an `INCIDENT` today; a fix-forward commit, which
25
- * is how almost every real bug is actually fixed, mints nothing at all.
26
- *
27
- * So this matcher's **recall is not computable — 0/0, not 0%**. It has never
28
- * been handed a real incident to find, and no number describes how many it
29
- * would miss. An empty result therefore means *"no linked incident in this
30
- * graph, and this graph has few or no incidents"* and must never be read as
31
- * *"no similar incident exists."* That is the same *absence is not evidence*
32
- * obligation `impact` already carries on every reply, and `similar-incidents.test.ts`
33
- * fails if it goes missing from either the empty or the non-empty branch.
34
- *
35
- * ## Two different absences, and they are not the same result
36
- *
37
- * `ai-tool-contract.md` §1.3a splits them, and the split is the whole reason
38
- * this endpoint is interesting:
39
- *
40
- * - **Incidents exist and none matched.** The denominator is real, the tool
41
- * looked completely, and the absence is a fact about the code. `state:
42
- * "empty"`, per §1.1's split.
43
- * - **The graph holds zero `INCIDENT` nodes.** There is no denominator.
44
- * Nothing was looked at, and the reason is Descry's producer coverage
45
- * rather than anything about this repository: only `git revert` mints an
46
- * `INCIDENT` and fix-forward mints nothing. Answering "empty" there would
47
- * say *"this code has no similar incidents"* when the true statement is
48
- * *"Descry cannot see most incidents in any codebase"* — the
49
- * empty-denominator defect inside the endpoint written to demonstrate the
50
- * rule against it. So it is a refusal, carried as `state: "refused"` (§1.1:
51
- * `refused` is a result state, and `not analysable` is a report category —
52
- * different axes, never this).
53
- *
54
- * §1.3a generalises it past this tool: **when a query's population is itself
55
- * zero, the answer is a refusal, never an empty result.** That puts this in
56
- * line with its siblings rather than apart from them — `contracts` refuses on
57
- * a graph with no endpoint, `propagation` when no walked edge type touches
58
- * the start node.
59
- *
60
- * The denominator travels in the payload either way. `incidentsInGraph` is
61
- * the population and `analysed` is false only when it is zero, so a caller
62
- * can tell the two absences apart **from the payload alone, with no string
63
- * matching on prose** — §1's distinguishability requirement, satisfied
64
- * without waiting for the wider envelope.
65
- */
1
+ /** `similar_incidents` ranks existing `INCIDENT` nodes against a failure with no graph node yet,
2
+ * deterministically (file/token Jaccard, no vector store). DEC-274 found zero `INCIDENT` nodes
3
+ * across three repos (734/459/203 commits): recall is 0/0, not 0% — an empty result never means
4
+ * "no similar incident exists" (DEC-279). §1.3a: a zero-incident graph is `refused`, never `empty`
5
+ * — the same split `contracts` and `propagation` apply to their own zero-population case. */
66
6
  import { similarIncidents } from "@descryy/core";
67
7
  import { answer, briefNode, optionalInteger, optionalString, optionalStringArray, ToolInputError, } from "./kit.js";
68
8
  const SCHEMA = {
@@ -91,12 +31,8 @@ const SCHEMA = {
91
31
  },
92
32
  additionalProperties: false,
93
33
  };
94
- /**
95
- * The mandatory sentence, in the form that fits each branch.
96
- *
97
- * Written once here rather than inline at three return sites, because the one
98
- * failure mode this tool has is a branch that forgets it.
99
- */
34
+ /** The mandatory disclosure sentence, shaped per branch. Written once here rather than inline at
35
+ * three return sites, so no branch can forget it. */
100
36
  function recallDisclosure(incidentsInGraph) {
101
37
  return ((incidentsInGraph === 0
102
38
  ? "This graph holds no INCIDENT node at all, so nothing was compared. "
@@ -1 +1 @@
1
- {"version":3,"file":"similar-incidents.js","sourceRoot":"","sources":["../../src/tools/similar-incidents.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"similar-incidents.js","sourceRoot":"","sources":["../../src/tools/similar-incidents.ts"],"names":[],"mappings":"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"}
@@ -1,39 +1,13 @@
1
1
  /**
2
- * `validate` — §15's static validation engine, currently its env/config check.
3
- *
4
- * The architecture calls this one *"cheapest and most reliable — ship first"*,
5
- * and it is the first tool here whose output is a statement about the user's
6
- * code rather than a measurement of the graph.
7
- *
8
- * ## Two things this tool refuses to do, and both are the point
9
- *
10
- * 1. **It does not report a variable that is read and never declared, by
11
- * default.** Measured on two real repositories, that rule produces 18 wrong
12
- * findings on one and 107 on the other. A finding needs a read that asserts
13
- * *requirement* — no fallback at the read site — and a declaration surface
14
- * complete enough for an absence to mean something. See `validation/env.ts`.
15
- *
16
- * 2. **It does not return `ok` with an empty list when no adapter supplied
17
- * reads.** That is `refused` with the reason and the exact `attrs` key
18
- * it needs, because "no missing variables" is a false statement when the code
19
- * was never read.
20
- *
21
- * The declaration half runs regardless: configuration files are read straight
22
- * from the repository, which needs no adapter and no resolution.
23
- */
24
- import type { ConfigGraph, ConfigReadSite, EnvClaim, EnvEvidence, EnvFindingKind, EnvReport, RollbackFinding, RollbackReport } from "@descryy/core";
2
+ * `validate` — §15 static validation: env/config checks.
3
+ * Omits a var unless its read fails-on-absence AND declaration surface is complete
4
+ * (18/107 wrong findings measured otherwise); refuses rather than `ok` when no reads
5
+ * exist. Pass `files` for NEW_READ_UNDECLARED — catches accessor-shape-independent reads. */
6
+ import type { AttributeFinding, AttributeReport, ConfigGraph, ConfigReadSite, EnvClaim, EnvEvidence, EnvFindingKind, EnvReport, MigrationIntegrityFinding, MigrationIntegrityReport, RollbackFinding, RollbackReport } from "@descryy/core";
25
7
  import type { ResolutionLevel } from "@descryy/ir";
26
8
  import { type ToolDefinition } from "./kit.ts";
27
- /**
28
- * One environment/configuration finding.
29
- *
30
- * `claim` is the axis that matters: a `defect` is a statement about the code, a
31
- * `lead` is something to look at. A variable read with no fallback and
32
- * declared nowhere is the first; a variable set in one file and documented in
33
- * no example file is the second, and reporting it as the first is how this
34
- * check produced 18 and 107 wrong findings on two real repositories before the
35
- * distinction existed.
36
- */
9
+ /** One env/config finding. `claim` distinguishes `defect` (code contradiction) from
10
+ * `lead` (worth a look) — conflating them caused 18/107 wrong findings on two repos. */
37
11
  export interface EnvFindingReport {
38
12
  readonly kind: EnvFindingKind;
39
13
  readonly name: string;
@@ -43,13 +17,8 @@ export interface EnvFindingReport {
43
17
  readonly evidence: readonly EnvEvidence[];
44
18
  readonly resolution: ResolutionLevel;
45
19
  }
46
- /**
47
- * A variable and how much of the repository stands behind it.
48
- *
49
- * Only variables whose dependent set could actually be computed appear —
50
- * §15.3's third check feeding the first. An unknown count is not a zero, so it
51
- * is left out rather than reported as none.
52
- */
20
+ /** A variable and how much of the repo depends on it (§15.3's third check feeding
21
+ * the first). Only variables with a computable dependent set appear — unknown ≠ zero. */
53
22
  export interface ConfigDependencyReport {
54
23
  readonly name: string;
55
24
  /** A lower bound, never a total. */
@@ -71,13 +40,8 @@ export interface ValidateData {
71
40
  readonly coverage: EnvReport["coverage"];
72
41
  /** Declared and read nowhere. A dead-configuration lead, not a finding. */
73
42
  readonly declaredNeverRead: number;
74
- /**
75
- * False when no adapter supplied environment reads.
76
- *
77
- * The whole point of the field: with it false, "no missing variables" would
78
- * be a statement about code that was never read, so the call is degraded
79
- * rather than clean.
80
- */
43
+ /** False when no adapter supplied environment reads — otherwise "no missing
44
+ * variables" would misstate code that was never read as clean. */
81
45
  readonly readsAvailable: boolean;
82
46
  readonly configGraph: {
83
47
  readonly counts: ConfigGraph["counts"];
@@ -98,6 +62,26 @@ export interface ValidateData {
98
62
  /** Named in plain words when `ran` is false. */
99
63
  readonly blockers: readonly string[];
100
64
  };
65
+ /** §"attribute read, type doesn't declare it" — always a defect (graph-provable
66
+ * contradiction between two producers), never a lead. */
67
+ readonly attributeExistence: {
68
+ readonly findings: readonly AttributeFinding[];
69
+ readonly findingsTotal: number;
70
+ readonly examined: AttributeReport["examined"];
71
+ /** False when no READS edge onto a type-like node carried field-existence info at all. */
72
+ readonly ran: boolean;
73
+ };
74
+ /** §"migration outside its directory, or broken revision chain" — both always
75
+ * defects, both graph-provable. */
76
+ readonly migrationIntegrity: {
77
+ readonly findings: readonly MigrationIntegrityFinding[];
78
+ readonly findingsTotal: number;
79
+ readonly examined: MigrationIntegrityReport["examined"];
80
+ readonly migrationsDirectory: string | null;
81
+ /** False when no module in the graph carried migration revision attrs. */
82
+ readonly ran: boolean;
83
+ readonly withheld: MigrationIntegrityReport["withheld"];
84
+ };
101
85
  }
102
86
  export declare const validateTool: ToolDefinition;
103
87
  //# sourceMappingURL=validate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/tools/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAUH,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,QAAQ,EACR,WAAW,EACX,cAAc,EACd,SAAS,EACT,eAAe,EACf,cAAc,EACf,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,EAA0D,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AAGvG;;;;;;;;;GASG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,wDAAwD;IACxD,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IAC1C,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;CACtC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oCAAoC;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,yDAAyD;IACzD,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,8BAA8B;IAC9B,QAAQ,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;IAC3C,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC/C,6FAA6F;IAC7F,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;IACzC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;IACnC,sFAAsF;IACtF,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;IACzC,2EAA2E;IAC3E,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,WAAW,EAAE;QACpB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;QACvC,qEAAqE;QACrE,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;QACnC,8EAA8E;QAC9E,QAAQ,CAAC,cAAc,EAAE,SAAS,sBAAsB,EAAE,CAAC;KAC5D,CAAC;IACF,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;QAC9C,6FAA6F;QAC7F,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;QAC/B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;QAC9C,4FAA4F;QAC5F,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;QAC9C,0DAA0D;QAC1D,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;QACtB,gDAAgD;QAChD,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;KACtC,CAAC;CACH;AA4JD,eAAO,MAAM,YAAY,EAAE,cAgB1B,CAAC"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/tools/validate.ts"],"names":[],"mappings":"AAAA;;;;6FAI6F;AAY7F,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,cAAc,EACd,QAAQ,EACR,WAAW,EACX,cAAc,EACd,SAAS,EACT,yBAAyB,EACzB,wBAAwB,EACxB,eAAe,EACf,cAAc,EACf,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,EAA0D,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AAGvG;yFACyF;AACzF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,wDAAwD;IACxD,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IAC1C,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;CACtC;AAED;0FAC0F;AAC1F,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oCAAoC;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,yDAAyD;IACzD,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,8BAA8B;IAC9B,QAAQ,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;IAC3C,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC/C,6FAA6F;IAC7F,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;IACzC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;IACnC,sFAAsF;IACtF,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;IACzC,2EAA2E;IAC3E,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC;uEACmE;IACnE,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,WAAW,EAAE;QACpB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;QACvC,qEAAqE;QACrE,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;QACnC,8EAA8E;QAC9E,QAAQ,CAAC,cAAc,EAAE,SAAS,sBAAsB,EAAE,CAAC;KAC5D,CAAC;IACF,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;QAC9C,6FAA6F;QAC7F,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;QAC/B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;QAC9C,4FAA4F;QAC5F,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;QAC9C,0DAA0D;QAC1D,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;QACtB,gDAAgD;QAChD,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;KACtC,CAAC;IACF;8DAC0D;IAC1D,QAAQ,CAAC,kBAAkB,EAAE;QAC3B,QAAQ,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAC;QAC/C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;QAC/B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC,UAAU,CAAC,CAAC;QAC/C,0FAA0F;QAC1F,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;KACvB,CAAC;IACF;wCACoC;IACpC,QAAQ,CAAC,kBAAkB,EAAE;QAC3B,QAAQ,CAAC,QAAQ,EAAE,SAAS,yBAAyB,EAAE,CAAC;QACxD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;QAC/B,QAAQ,CAAC,QAAQ,EAAE,wBAAwB,CAAC,UAAU,CAAC,CAAC;QACxD,QAAQ,CAAC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5C,0EAA0E;QAC1E,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;QACtB,QAAQ,CAAC,QAAQ,EAAE,wBAAwB,CAAC,UAAU,CAAC,CAAC;KACzD,CAAC;CACH;AAyPD,eAAO,MAAM,YAAY,EAAE,cAwB1B,CAAC"}
@@ -1,27 +1,9 @@
1
1
  /**
2
- * `validate` — §15's static validation engine, currently its env/config check.
3
- *
4
- * The architecture calls this one *"cheapest and most reliable — ship first"*,
5
- * and it is the first tool here whose output is a statement about the user's
6
- * code rather than a measurement of the graph.
7
- *
8
- * ## Two things this tool refuses to do, and both are the point
9
- *
10
- * 1. **It does not report a variable that is read and never declared, by
11
- * default.** Measured on two real repositories, that rule produces 18 wrong
12
- * findings on one and 107 on the other. A finding needs a read that asserts
13
- * *requirement* — no fallback at the read site — and a declaration surface
14
- * complete enough for an absence to mean something. See `validation/env.ts`.
15
- *
16
- * 2. **It does not return `ok` with an empty list when no adapter supplied
17
- * reads.** That is `refused` with the reason and the exact `attrs` key
18
- * it needs, because "no missing variables" is a false statement when the code
19
- * was never read.
20
- *
21
- * The declaration half runs regardless: configuration files are read straight
22
- * from the repository, which needs no adapter and no resolution.
23
- */
24
- import { buildConfigGraph, checkEnvironment, checkRollbackReadiness, scanConfigSurfaces, scanMigrations, } from "@descryy/core";
2
+ * `validate` — §15 static validation: env/config checks.
3
+ * Omits a var unless its read fails-on-absence AND declaration surface is complete
4
+ * (18/107 wrong findings measured otherwise); refuses rather than `ok` when no reads
5
+ * exist. Pass `files` for NEW_READ_UNDECLARED — catches accessor-shape-independent reads. */
6
+ import { buildConfigGraph, checkAttributeExistence, checkEnvironment, checkMigrationIntegrity, checkRollbackReadiness, scanConfigSurfaces, scanMigrations, } from "@descryy/core";
25
7
  import { optionalInteger, optionalStringArray } from "./kit.js";
26
8
  const SCHEMA = {
27
9
  type: "object",
@@ -30,7 +12,10 @@ const SCHEMA = {
30
12
  type: "array",
31
13
  items: { type: "string" },
32
14
  description: "Restrict the code side to these repo-relative files — the scoped-subgraph run. " +
33
- "Configuration files are always read in full, because a declaration is repository-wide.",
15
+ "Configuration files are always read in full, because a declaration is repository-wide. " +
16
+ "Also enables a second, stronger env-var rule (NEW_READ_UNDECLARED): a variable read in " +
17
+ "one of these files and declared nowhere is reported regardless of whether the accessor " +
18
+ "fails on absence, catching a case the default rule structurally cannot.",
34
19
  },
35
20
  coverageFloor: {
36
21
  type: "number",
@@ -69,22 +54,73 @@ async function run(args, ctx) {
69
54
  ...(files === undefined ? {} : { files }),
70
55
  ...(maxFindings === undefined ? {} : { maxFindings }),
71
56
  });
57
+ ctx.progress("Checking attribute reads against declared types");
58
+ const attributeExistence = checkAttributeExistence(provider, {
59
+ ...(files === undefined ? {} : { files }),
60
+ ...(maxFindings === undefined ? {} : { maxFindings }),
61
+ });
62
+ ctx.progress("Checking migration location and revision chain");
63
+ const migrationIntegrity = checkMigrationIntegrity(provider, {
64
+ ...(files === undefined ? {} : { files }),
65
+ ...(maxFindings === undefined ? {} : { maxFindings }),
66
+ });
72
67
  const report = checked.data;
73
- const defects = report.findings.filter((f) => f.claim === "defect").length;
74
- const leads = report.findings.length - defects;
75
- // Nothing was compared at all: no configuration files, no reads, and no
76
- // migration. Any one of them alone is a real answer; none of them is not.
77
- const nothingToCheck = report.surfaces.length === 0 && !report.readsAvailable && !rollback.data.ran;
78
- // MK-7: the leading clause a caller reads first, graded on the axis that
79
- // actually matters — `claim`. A lead or a rollback finding is worth a look;
80
- // a defect is the thing this tool exists to catch. Never blur the two into
81
- // one count, the exact failure `EnvFindingReport.claim`'s own doc names.
68
+ const defects = report.findings.filter((f) => f.claim === "defect").length +
69
+ attributeExistence.data.findings.length +
70
+ migrationIntegrity.data.findings.length;
71
+ const leads = report.findings.length - report.findings.filter((f) => f.claim === "defect").length;
72
+ // Nothing compared at all: no config files, reads, migrations, attribute reads,
73
+ // or migration revisions — any one alone is a real answer, none of them is not.
74
+ const nothingToCheck = report.surfaces.length === 0 &&
75
+ !report.readsAvailable &&
76
+ !rollback.data.ran &&
77
+ !attributeExistence.data.ran &&
78
+ !migrationIntegrity.data.ran;
79
+ // A `files` scope matching zero FILE nodes means those files were never read into
80
+ // the graph (bad path, or unparsed) — not "read and clean". Same collapse as
81
+ // `contracts(paths)`, one level down.
82
+ const filesMatchedNothing = files !== undefined && report.reads.filesWithReads + report.reads.filesWithoutReads === 0;
83
+ // Leads and rollback findings are worth a look; defects are what this tool exists
84
+ // to catch. Never blur the two into one count (see EnvFindingReport.claim).
82
85
  const otherFindings = leads + rollback.data.findings.length;
83
- const verdict = defects > 0
84
- ? `${defects} defect(s) found`
85
- : otherFindings > 0
86
- ? `No defects; ${otherFindings} lead(s)/rollback finding(s) to review`
87
- : "Clean";
86
+ // A "Clean" verdict from a files scope matching nothing would misreport "checked,
87
+ // fine" when nothing was read. Only pure-Clean is downgraded — real findings from
88
+ // unscoped checks still surface.
89
+ const falseClean = filesMatchedNothing && defects === 0 && otherFindings === 0;
90
+ const verdict = falseClean
91
+ ? "not checked"
92
+ : defects > 0
93
+ ? `${defects} defect(s) found`
94
+ : otherFindings > 0
95
+ ? `No defects; ${otherFindings} lead(s)/rollback finding(s) to review`
96
+ : "Clean";
97
+ const scopeNotes = filesMatchedNothing
98
+ ? [
99
+ `0 of the ${(files ?? []).length} named file(s) matched a FILE node this graph's read side ` +
100
+ "considered — either the path is wrong, or the file was never read into the graph. The " +
101
+ "environment-read half of this report has nothing to say about them; it is not evidence " +
102
+ "they are clean.",
103
+ ]
104
+ : [];
105
+ // render.ts requires truncatedDetail whenever truncated=true. `truncated` folds 5
106
+ // independently-truncatable sources; shown/total cover only the 4 finding lists a
107
+ // maxFindings cap acts on — configGraph's own truncation stays prose-only.
108
+ const shown = report.findings.length +
109
+ rollback.data.findings.length +
110
+ attributeExistence.data.findings.length +
111
+ migrationIntegrity.data.findings.length;
112
+ const total = report.findingsTotal +
113
+ rollback.data.findingsTotal +
114
+ attributeExistence.data.findingsTotal +
115
+ migrationIntegrity.data.findingsTotal;
116
+ const truncated = checked.truncated ||
117
+ rollback.truncated ||
118
+ attributeExistence.truncated ||
119
+ migrationIntegrity.truncated ||
120
+ configGraph.truncated;
121
+ const truncatedDetail = truncated
122
+ ? { shown, total: Math.max(total, shown), more: null }
123
+ : undefined;
88
124
  return {
89
125
  result: {
90
126
  ...checked,
@@ -103,10 +139,8 @@ async function run(args, ctx) {
103
139
  coverage: report.coverage,
104
140
  declaredNeverRead: report.declaredNeverRead,
105
141
  readsAvailable: report.readsAvailable,
106
- // §15.3's third check feeds the first: a variable read by a module forty
107
- // others import is a different sentence from one read by a single
108
- // script. Only variables whose dependent set could be computed are
109
- // carried — an unknown count is not a zero and is not worth a row.
142
+ // §15.3's third check feeds the first. Only variables with a computable
143
+ // dependent set are carried — unknown count is not a zero, not worth a row.
110
144
  configGraph: {
111
145
  counts: configGraph.data.counts,
112
146
  importsAvailable: configGraph.data.importsAvailable,
@@ -129,29 +163,59 @@ async function run(args, ctx) {
129
163
  ran: rollback.data.ran,
130
164
  blockers: rollback.data.blockers,
131
165
  },
166
+ attributeExistence: {
167
+ findings: attributeExistence.data.findings,
168
+ findingsTotal: attributeExistence.data.findingsTotal,
169
+ examined: attributeExistence.data.examined,
170
+ ran: attributeExistence.data.ran,
171
+ },
172
+ migrationIntegrity: {
173
+ findings: migrationIntegrity.data.findings,
174
+ findingsTotal: migrationIntegrity.data.findingsTotal,
175
+ examined: migrationIntegrity.data.examined,
176
+ migrationsDirectory: migrationIntegrity.data.migrationsDirectory,
177
+ ran: migrationIntegrity.data.ran,
178
+ withheld: migrationIntegrity.data.withheld,
179
+ },
132
180
  },
133
- // Both checks' disclosures reach the reader. Dropping one half's notes
134
- // because the other half had something to say is the silent-degradation
135
- // failure rule 7 exists to prevent.
136
- notes: [...checked.notes, ...rollback.notes, ...configGraph.notes],
137
- truncated: checked.truncated || rollback.truncated || configGraph.truncated,
181
+ // Every check's disclosures reach the reader — dropping one half silently
182
+ // is the degradation rule 7 exists to prevent.
183
+ notes: [
184
+ ...scopeNotes,
185
+ ...checked.notes,
186
+ ...rollback.notes,
187
+ ...attributeExistence.notes,
188
+ ...migrationIntegrity.notes,
189
+ ...configGraph.notes,
190
+ ],
191
+ truncated,
138
192
  stamp: {
139
193
  ...checked.stamp,
140
- resolutionFloor: Math.min(checked.stamp.resolutionFloor, rollback.stamp.resolutionFloor, configGraph.stamp.resolutionFloor),
194
+ resolutionFloor: Math.min(checked.stamp.resolutionFloor, rollback.stamp.resolutionFloor, attributeExistence.stamp.resolutionFloor, migrationIntegrity.stamp.resolutionFloor, configGraph.stamp.resolutionFloor),
141
195
  },
142
196
  },
143
- // A missing environment variable is §11A.5's canonical name-level fact —
144
- // the variable exists or it does not — which is the one claim R2 supports at
145
- // class A. The shape of its value is never asserted here.
197
+ // §11A.5's canonical name-level fact (exists or not) — the one claim R2 supports
198
+ // at class A. Value shape is never asserted here.
146
199
  nameLevel: true,
147
- ...(nothingToCheck ? { state: "refused" } : {}),
200
+ ...(truncatedDetail === undefined ? {} : { truncatedDetail }),
201
+ ...(nothingToCheck
202
+ ? { state: "refused" }
203
+ : falseClean
204
+ ? { state: "empty" }
205
+ : {}),
148
206
  headline: nothingToCheck
149
- ? "No configuration files, environment reads or migrations were found, so there was " +
150
- "nothing to check."
151
- : `${verdict}. ${report.surfaces.length} configuration file(s) declare ` +
152
- `${countDeclared(report.surfaces)} variable(s); ` +
153
- `${report.reads.required} variable(s) are read through an accessor that fails when unset; ` +
154
- `${rollback.data.examined.operations} destructive migration operation(s) examined.`,
207
+ ? "No configuration files, environment reads, migrations or attribute reads were found, so " +
208
+ "there was nothing to check."
209
+ : falseClean
210
+ ? `0 of the ${(files ?? []).length} named file(s) matched anything on the read side. Not ` +
211
+ "checked, not clean."
212
+ : `${verdict}. ${report.surfaces.length} configuration file(s) declare ` +
213
+ `${countDeclared(report.surfaces)} variable(s); ` +
214
+ `${report.reads.required} variable(s) are read through an accessor that fails when unset; ` +
215
+ `${rollback.data.examined.operations} destructive migration operation(s) examined; ` +
216
+ `${attributeExistence.data.examined.readEdgesExamined} attribute read(s) checked against ` +
217
+ `a declared type; ${migrationIntegrity.data.examined.modulesWithRevision} migration(s) ` +
218
+ "checked for location and revision-chain integrity.",
155
219
  };
156
220
  }
157
221
  function countDeclared(surfaces) {
@@ -167,9 +231,17 @@ export const validateTool = {
167
231
  "declares. Reports a variable only when the code reads it with no fallback and no " +
168
232
  "configuration file declares it, and only when the repository's declaration surface is " +
169
233
  "complete enough for that absence to mean something — a variable supplied by a secrets " +
170
- "manager or a platform is disclosed with a count, never reported as missing. Also reports " +
171
- "variables set in one configuration file and documented in no example file, stated as a lead " +
172
- "rather than a defect.",
234
+ "manager or a platform is disclosed with a count, never reported as missing. Pass \"files\" " +
235
+ "(the diff you are about to push) to also catch a variable your change reads that no " +
236
+ "declaration surface declares, regardless of whether the accessor fails on absence — the " +
237
+ "usual shape on a codebase where almost no read is required. Also reports variables set in " +
238
+ "one configuration file and documented in no example file, stated as a lead rather than a " +
239
+ "defect. Two further checks, both always defects because both are provable from the graph " +
240
+ "alone: an attribute read on a value whose declared type does not name it (from a READS " +
241
+ "edge's attrs.unresolvedFields), and a migration whose location or declared parent revision " +
242
+ "disagrees with the rest of the project's migrations (from attrs.migrationRevision, " +
243
+ "migrationDownRevision and migrationDir). Both are silent wherever the producer supplied no " +
244
+ "signal — absence of the attrs key is never read as a clean result.",
173
245
  inputSchema: SCHEMA,
174
246
  run,
175
247
  };