@khoavu882/doflow 2.0.0-beta.3 → 2.0.0-beta.5

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 (236) hide show
  1. package/bin/doflow.js +2 -2
  2. package/core/.antigravity-plugin/plugin.json +0 -1
  3. package/core/.claude-plugin/plugin.json +1 -1
  4. package/core/.codex-plugin/plugin.json +1 -1
  5. package/core/.plugin/plugin.json +1 -1
  6. package/core/harnesses/claude/hooks/mcp-tool-guard.sh +7 -17
  7. package/core/harnesses/claude/hooks/pre-bash-guard.sh +7 -17
  8. package/core/harnesses/claude/hooks/pre-implement-gate.sh +7 -18
  9. package/core/harnesses/claude/hooks/session-start.sh +5 -3
  10. package/core/harnesses/claude/hooks/stop-check.sh +5 -3
  11. package/core/harnesses/claude/hooks/subagent-audit.sh +5 -5
  12. package/core/harnesses/claude/hooks/user-prompt-submit.sh +5 -3
  13. package/core/harnesses/codex/hooks/mcp-tool-guard.sh +7 -15
  14. package/core/harnesses/codex/hooks/pre-bash-guard.sh +7 -15
  15. package/core/harnesses/codex/hooks/pre-implement-gate.sh +7 -16
  16. package/core/harnesses/codex/hooks/session-start.sh +5 -3
  17. package/core/harnesses/codex/hooks/stop-check.sh +6 -5
  18. package/core/harnesses/codex/hooks/subagent-audit.sh +17 -6
  19. package/core/harnesses/codex/hooks/user-prompt-submit.sh +5 -4
  20. package/core/harnesses/gemini/hooks/mcp-tool-guard.sh +7 -18
  21. package/core/harnesses/gemini/hooks/pre-bash-guard.sh +7 -18
  22. package/core/harnesses/gemini/hooks/pre-implement-gate.sh +7 -19
  23. package/core/harnesses/gemini/hooks/session-start.sh +5 -3
  24. package/core/harnesses/kiro/hooks/mcp-tool-guard.sh +20 -5
  25. package/core/harnesses/kiro/hooks/pre-bash-guard.sh +20 -5
  26. package/core/harnesses/kiro/hooks/pre-implement-gate.sh +20 -5
  27. package/core/harnesses/kiro/hooks/session-start.sh +11 -5
  28. package/core/harnesses/kiro/hooks/stop-check.sh +21 -30
  29. package/core/harnesses/pi/extensions/doflow-guard.js +159 -0
  30. package/core/harnesses/shared/hooks/ENVELOPE_MIGRATION.md +27 -11
  31. package/core/harnesses/shared/hooks/adapters/antigravity.js +14 -57
  32. package/core/harnesses/shared/hooks/bridge/bridge.sh +184 -0
  33. package/core/harnesses/shared/hooks/bridge/envelope.jq +60 -0
  34. package/core/harnesses/shared/hooks/bridge/respond.sh +62 -0
  35. package/core/harnesses/shared/hooks/policies/capture-failure.sh +4 -2
  36. package/core/harnesses/shared/hooks/policies/contract.sh +75 -0
  37. package/core/harnesses/shared/hooks/policies/deny-json.sh +39 -4
  38. package/core/harnesses/shared/hooks/policies/lib.sh +4 -2
  39. package/core/harnesses/shared/hooks/policies/mcp-tool-guard.sh +46 -34
  40. package/core/harnesses/shared/hooks/policies/pre-bash-guard.sh +75 -25
  41. package/core/harnesses/shared/hooks/policies/pre-implementation-gate.sh +67 -73
  42. package/core/harnesses/shared/hooks/policies/session-context.sh +37 -7
  43. package/core/harnesses/shared/hooks/policies/stop-check.sh +42 -15
  44. package/core/harnesses/shared/hooks/policies/subagent-audit.sh +35 -5
  45. package/core/harnesses/shared/hooks/policies/user-prompt-submit.sh +40 -7
  46. package/core/harnesses/shared/hooks/stream-hook-runner.js +69 -181
  47. package/core/registry/assets.json +19 -0
  48. package/core/registry/contracts.json +2 -2
  49. package/core/registry/harnesses.json +196 -10
  50. package/core/registry/lifecycle.json +2626 -7
  51. package/core/registry/storage.json +110 -83
  52. package/core/registry/verification.json +1 -1
  53. package/core/shared/scripts/doflow/bash/render-puml.sh +2 -2
  54. package/core/shared/scripts/doflow/bin/doflow-run +10 -6
  55. package/core/shared/skills/do-design/SKILL.md +6 -6
  56. package/core/shared/skills/do-execute-plan/SKILL.md +11 -10
  57. package/core/shared/skills/do-execute-plan/references/readiness_gate.md +2 -0
  58. package/core/shared/skills/do-execute-plan/references/scaffold.md +2 -2
  59. package/core/shared/skills/do-implement/SKILL.md +3 -2
  60. package/core/shared/skills/do-plan/SKILL.md +7 -8
  61. package/package.json +4 -2
  62. package/src/adapters/antigravity/{index.ts → index.js} +141 -105
  63. package/src/adapters/claude/{index.ts → index.js} +63 -49
  64. package/src/adapters/claude/{mcp.ts → mcp.js} +16 -16
  65. package/src/adapters/codex/{agents.ts → agents.js} +24 -24
  66. package/src/adapters/codex/{config.ts → config.js} +49 -49
  67. package/src/adapters/codex/{hooks.ts → hooks.js} +62 -27
  68. package/src/adapters/codex/{index.ts → index.js} +148 -105
  69. package/src/adapters/codex/{mcp.ts → mcp.js} +38 -38
  70. package/src/adapters/codex/{native-projection.ts → native-projection.js} +5 -5
  71. package/src/adapters/copilot/{index.ts → index.js} +42 -42
  72. package/src/adapters/{copy-tree.ts → copy-tree.js} +74 -74
  73. package/src/adapters/gemini/{hooks.ts → hooks.js} +78 -37
  74. package/src/adapters/gemini/{index.ts → index.js} +96 -57
  75. package/src/adapters/{hook-commands.ts → hook-commands.js} +8 -8
  76. package/src/adapters/{index.ts → index.js} +13 -13
  77. package/src/adapters/kiro/{index.ts → index.js} +49 -35
  78. package/src/adapters/{mcp-entries.ts → mcp-entries.js} +55 -55
  79. package/src/adapters/opencode/{index.ts → index.js} +52 -52
  80. package/src/adapters/pi/hooks.js +119 -0
  81. package/src/adapters/pi/{index.ts → index.js} +64 -39
  82. package/src/adapters/pi/{json-members.ts → json-members.js} +23 -23
  83. package/src/adapters/pi/{mcp.ts → mcp.js} +70 -70
  84. package/src/adapters/{resolve-source.ts → resolve-source.js} +1 -1
  85. package/src/cli/commands/{install.ts → install.js} +25 -25
  86. package/src/cli/commands/{list-backups.ts → list-backups.js} +4 -4
  87. package/src/cli/commands/{reconcile.ts → reconcile.js} +19 -19
  88. package/src/cli/commands/{remove.ts → remove.js} +10 -10
  89. package/src/cli/commands/{rollback.ts → rollback.js} +17 -17
  90. package/src/cli/commands/{self-update.ts → self-update.js} +3 -3
  91. package/src/cli/commands/{status.ts → status.js} +24 -24
  92. package/src/cli/commands/{tools.ts → tools.js} +16 -16
  93. package/src/cli/commands/{update.ts → update.js} +20 -20
  94. package/src/cli/{index.ts → index.js} +43 -31
  95. package/src/cli/{runtime-commands.ts → runtime-commands.js} +97 -58
  96. package/src/cli/{shared.ts → shared.js} +40 -40
  97. package/src/helper/{bash-helper.ts → bash-helper.js} +7 -7
  98. package/src/helper/{git.ts → git.js} +2 -2
  99. package/src/helper/{guardrails.ts → guardrails.js} +10 -10
  100. package/src/helper/{harness-paths.ts → harness-paths.js} +24 -24
  101. package/src/helper/{marker-merge.ts → marker-merge.js} +4 -4
  102. package/src/helper/{prompt.ts → prompt.js} +5 -5
  103. package/src/helper/{repo-root.ts → repo-root.js} +2 -2
  104. package/src/helper/{settings-merge.ts → settings-merge.js} +27 -27
  105. package/src/helper/{settings-scope.ts → settings-scope.js} +3 -3
  106. package/src/helper/{toml.ts → toml.js} +48 -48
  107. package/src/install/{backup-set.ts → backup-set.js} +16 -16
  108. package/src/install/{backup.ts → backup.js} +65 -65
  109. package/src/install/{context.ts → context.js} +15 -15
  110. package/src/install/{manifest.ts → manifest.js} +27 -27
  111. package/src/install/{mcp.ts → mcp.js} +30 -30
  112. package/src/install/{paths.ts → paths.js} +15 -15
  113. package/src/install/{targets.ts → targets.js} +10 -10
  114. package/src/install/{tool-lifecycle.ts → tool-lifecycle.js} +20 -20
  115. package/src/lifecycle/{bash-availability.ts → bash-availability.js} +1 -1
  116. package/src/lifecycle/coverage.js +57 -0
  117. package/src/lifecycle/hook-step.js +61 -0
  118. package/src/lifecycle/{index.ts → index.js} +160 -146
  119. package/src/lifecycle/{mcp-index.ts → mcp-index.js} +1 -1
  120. package/src/lifecycle/{policies.ts → policies.js} +11 -11
  121. package/src/lifecycle/{view.ts → view.js} +28 -28
  122. package/src/registry/{index.ts → index.js} +195 -66
  123. package/src/release/build-package.js +91 -0
  124. package/src/release/changelog-section.js +70 -0
  125. package/src/release/{sync-plugin-versions.ts → sync-plugin-versions.js} +4 -4
  126. package/src/runtime/advice/{cli.ts → cli.js} +31 -31
  127. package/src/runtime/advice/{client.ts → client.js} +44 -44
  128. package/src/runtime/advice/{config.ts → config.js} +16 -16
  129. package/src/runtime/advice/{doctor.ts → doctor.js} +32 -32
  130. package/src/runtime/advice/{endpoint-guard.ts → endpoint-guard.js} +20 -20
  131. package/src/runtime/advice/{kinds.ts → kinds.js} +16 -16
  132. package/src/runtime/advice/providers/{ollama-systemone.ts → ollama-systemone.js} +21 -21
  133. package/src/runtime/advice/{record.ts → record.js} +19 -19
  134. package/src/runtime/advice/{registry.ts → registry.js} +16 -16
  135. package/src/runtime/advice/{strength.ts → strength.js} +7 -7
  136. package/src/runtime/{brief-tools.ts → brief-tools.js} +50 -50
  137. package/src/runtime/{c4-project.ts → c4-project.js} +27 -27
  138. package/src/runtime/candidate.js +505 -0
  139. package/src/runtime/{capability-router.ts → capability-router.js} +39 -39
  140. package/src/runtime/{checkouts.ts → checkouts.js} +21 -21
  141. package/src/runtime/{claims.ts → claims.js} +44 -35
  142. package/src/runtime/{cli-result.ts → cli-result.js} +15 -8
  143. package/src/runtime/{cli.ts → cli.js} +59 -292
  144. package/src/runtime/{command-detect.ts → command-detect.js} +47 -47
  145. package/src/runtime/context/budget.js +203 -0
  146. package/src/runtime/context/compose.js +1367 -0
  147. package/src/runtime/context/delivery-store.js +102 -0
  148. package/src/runtime/context/mandatory.js +594 -0
  149. package/src/runtime/context/pointer.js +142 -0
  150. package/src/runtime/context-pack.js +1277 -0
  151. package/src/runtime/{decision-register.ts → decision-register.js} +67 -67
  152. package/src/runtime/evidence-fields.js +39 -0
  153. package/src/runtime/{evidence-ledger.ts → evidence-ledger.js} +32 -25
  154. package/src/runtime/failure/{capture.ts → capture.js} +29 -29
  155. package/src/runtime/failure/{classifier.ts → classifier.js} +4 -4
  156. package/src/runtime/failure/{cli.ts → cli.js} +30 -30
  157. package/src/runtime/failure/{home.ts → home.js} +6 -6
  158. package/src/runtime/failure/{store.ts → store.js} +32 -32
  159. package/src/runtime/{feature-resolve.ts → feature-resolve.js} +6 -6
  160. package/src/runtime/{freshness.ts → freshness.js} +59 -22
  161. package/src/runtime/{health.ts → health.js} +72 -72
  162. package/src/runtime/{history-compactor.ts → history-compactor.js} +25 -25
  163. package/src/runtime/{implementation-gate.ts → implementation-gate.js} +30 -30
  164. package/src/runtime/inventory/{coverage.ts → coverage.js} +10 -10
  165. package/src/runtime/inventory/{identity.ts → identity.js} +2 -2
  166. package/src/runtime/inventory/{index.ts → index.js} +36 -36
  167. package/src/runtime/inventory/{precedence.ts → precedence.js} +2 -2
  168. package/src/runtime/inventory/{read-scopes.ts → read-scopes.js} +9 -9
  169. package/src/runtime/inventory/{siblings.ts → siblings.js} +15 -15
  170. package/src/runtime/knowledge/{chunker.ts → chunker.js} +12 -12
  171. package/src/runtime/knowledge/{hybrid.ts → hybrid.js} +17 -17
  172. package/src/runtime/knowledge/{index-store.ts → index-store.js} +23 -23
  173. package/src/runtime/knowledge/{retrieval.ts → retrieval.js} +27 -27
  174. package/src/runtime/{leak-scan.ts → leak-scan.js} +12 -12
  175. package/src/runtime/lifecycle/{cli.ts → cli.js} +32 -32
  176. package/src/runtime/lifecycle/{event-store.ts → event-store.js} +48 -48
  177. package/src/runtime/lifecycle/{fold.ts → fold.js} +41 -41
  178. package/src/runtime/lifecycle/{followup.ts → followup.js} +54 -54
  179. package/src/runtime/lifecycle/{goal.ts → goal.js} +50 -50
  180. package/src/runtime/lifecycle/{intent-writer.ts → intent-writer.js} +5 -5
  181. package/src/runtime/lifecycle/{overview.ts → overview.js} +47 -47
  182. package/src/runtime/lifecycle/{release.ts → release.js} +29 -29
  183. package/src/runtime/lifecycle/{report-store.ts → report-store.js} +25 -25
  184. package/src/runtime/lifecycle/{retention.ts → retention.js} +37 -37
  185. package/src/runtime/lifecycle/{root.ts → root.js} +9 -9
  186. package/src/runtime/lifecycle/{status.ts → status.js} +64 -64
  187. package/src/runtime/lifecycle/{store-upkeep.ts → store-upkeep.js} +46 -46
  188. package/src/runtime/{locator-resolve.ts → locator-resolve.js} +7 -7
  189. package/src/runtime/{mask.ts → mask.js} +22 -22
  190. package/src/runtime/{mcp-consultations.ts → mcp-consultations.js} +54 -54
  191. package/src/runtime/{mcp-reach.ts → mcp-reach.js} +24 -24
  192. package/src/runtime/{model-router.ts → model-router.js} +20 -20
  193. package/src/runtime/{outcome.ts → outcome.js} +27 -27
  194. package/src/runtime/{reach.ts → reach.js} +21 -21
  195. package/src/runtime/{readiness-record.ts → readiness-record.js} +12 -12
  196. package/src/runtime/{readiness.ts → readiness.js} +113 -43
  197. package/src/runtime/{recovery.ts → recovery.js} +15 -15
  198. package/src/runtime/{research-request.ts → research-request.js} +34 -34
  199. package/src/runtime/{retrieval-plan.ts → retrieval-plan.js} +453 -104
  200. package/src/runtime/retrieval-record.js +223 -0
  201. package/src/runtime/scaffold/{artifacts.ts → artifacts.js} +22 -19
  202. package/src/runtime/scaffold/{fingerprint.ts → fingerprint.js} +3 -3
  203. package/src/runtime/scaffold/{generate.ts → generate.js} +109 -109
  204. package/src/runtime/scaffold/{languages.ts → languages.js} +34 -34
  205. package/src/runtime/source-version.js +289 -0
  206. package/src/runtime/storage/{cli.ts → cli.js} +9 -9
  207. package/src/runtime/storage/{engine.ts → engine.js} +37 -37
  208. package/src/runtime/storage/{registry.ts → registry.js} +19 -19
  209. package/src/runtime/storage/{roots.ts → roots.js} +8 -8
  210. package/src/runtime/storage/{rules.ts → rules.js} +26 -26
  211. package/src/runtime/storage/{upkeep.ts → upkeep.js} +35 -35
  212. package/src/runtime/storage/{work-status.ts → work-status.js} +39 -39
  213. package/src/runtime/{task-attempts.ts → task-attempts.js} +62 -62
  214. package/src/runtime/{task-classifier.ts → task-classifier.js} +34 -34
  215. package/src/runtime/{task-scope.ts → task-scope.js} +40 -15
  216. package/src/runtime/{task-state.ts → task-state.js} +86 -21
  217. package/src/runtime/trace/{indicators.ts → indicators.js} +22 -22
  218. package/src/runtime/trace/{ledger.ts → ledger.js} +42 -42
  219. package/src/runtime/trace/{render.ts → render.js} +7 -7
  220. package/src/runtime/trace/{views.ts → views.js} +40 -40
  221. package/src/runtime/verification/{contract-runner.ts → contract-runner.js} +23 -23
  222. package/src/runtime/verification/{engine.ts → engine.js} +143 -143
  223. package/src/runtime/verification/{registry.ts → registry.js} +6 -6
  224. package/src/runtime/verification/{scope-bound.ts → scope-bound.js} +50 -50
  225. package/src/runtime/verification/{test-selection.ts → test-selection.js} +28 -28
  226. package/src/runtime/{workflow-engine.ts → workflow-engine.js} +50 -50
  227. package/src/runtime/{workflow-orchestrator.ts → workflow-orchestrator.js} +91 -91
  228. package/src/runtime/{worktree.ts → worktree.js} +31 -31
  229. package/src/state/{index.ts → index.js} +26 -26
  230. package/src/state/{lockfile.ts → lockfile.js} +20 -20
  231. package/src/state/{run-lock.ts → run-lock.js} +44 -44
  232. package/core/.antigravity-plugin/hooks.json +0 -39
  233. package/core/harnesses/shared/hooks/adapters/arg-fields.js +0 -19
  234. package/core/harnesses/shared/hooks/adapters/gemini.js +0 -114
  235. package/core/harnesses/shared/hooks/hooks.json +0 -47
  236. package/src/runtime/context-pack.ts +0 -492
@@ -12,7 +12,7 @@ const {
12
12
  buildStats,
13
13
  buildDiscover,
14
14
  PROVIDER,
15
- } = require('./views.ts');
15
+ } = require('./views.js');
16
16
  const {
17
17
  shortTime,
18
18
  formatMs,
@@ -20,7 +20,7 @@ const {
20
20
  integrityNote,
21
21
  printEmptyLedgerNotice,
22
22
  DISCOVER_MARK,
23
- } = require('./render.ts');
23
+ } = require('./render.js');
24
24
 
25
25
  /**
26
26
  * Task-run telemetry — the JavaScript port of
@@ -49,7 +49,7 @@ const {
49
49
  * They price one specific model; a trace naming a different one gets a cost only if the caller
50
50
  * supplies its rates, because inventing a price for an unpriced model is inventing a metric.
51
51
  */
52
- const DEFAULT_TOKEN_RATES: Readonly<{ inputPerToken: number; outputPerToken: number }> = Object.freeze({
52
+ const DEFAULT_TOKEN_RATES = Object.freeze({
53
53
  inputPerToken: 0.000003,
54
54
  outputPerToken: 0.000015,
55
55
  });
@@ -60,20 +60,20 @@ const COST_DECIMALS = 6;
60
60
  * @param {number} value
61
61
  * @returns {number} rounded to six decimals, matching the Python's `round(x, 6)`
62
62
  */
63
- function roundCost(value: number): number {
63
+ function roundCost(value ) {
64
64
  const factor = 10 ** COST_DECIMALS;
65
65
  return Math.round(value * factor) / factor;
66
66
  }
67
67
 
68
68
  class TaskRunTelemetry {
69
- taskId: string;
70
- agent: string;
71
- model: string;
72
- rates: { inputPerToken: number; outputPerToken: number } | null;
73
- events: any[];
74
- clock: () => number;
75
- startedAtMs: number;
76
- startedAt: string;
69
+ taskId ;
70
+ agent ;
71
+ model ;
72
+ rates ;
73
+ events ;
74
+ clock ;
75
+ startedAtMs ;
76
+ startedAt ;
77
77
 
78
78
  /**
79
79
  * @param {string} taskId
@@ -84,7 +84,7 @@ class TaskRunTelemetry {
84
84
  * @param {{inputPerToken: number, outputPerToken: number}|null} [options.rates]
85
85
  * @param {Function} [options.clock] injection seam for tests; returns elapsed milliseconds
86
86
  */
87
- constructor(taskId: string, options: any = {}) {
87
+ constructor(taskId , options = {}) {
88
88
  const opts = typeof options === 'string' ? { agent: options } : options;
89
89
  this.taskId = taskId;
90
90
  this.agent = opts.agent || 'codex';
@@ -105,7 +105,7 @@ class TaskRunTelemetry {
105
105
  * @param {Object} [details={}]
106
106
  * @returns {Object} the recorded event
107
107
  */
108
- recordEvent(eventType: string, details: any = {}): any {
108
+ recordEvent(eventType , details = {}) {
109
109
  const event = {
110
110
  timestamp: new Date().toISOString(),
111
111
  type: eventType,
@@ -119,7 +119,7 @@ class TaskRunTelemetry {
119
119
  * Milliseconds elapsed since the recorder was constructed.
120
120
  * @returns {number}
121
121
  */
122
- elapsedMs(): number {
122
+ elapsedMs() {
123
123
  return Math.max(0, this.clock() - this.startedAtMs);
124
124
  }
125
125
 
@@ -130,7 +130,7 @@ class TaskRunTelemetry {
130
130
  * @param {number} [outputTokens=0]
131
131
  * @returns {Object} trace record
132
132
  */
133
- exportTrace(success: boolean, inputTokens: number = 0, outputTokens: number = 0): any {
133
+ exportTrace(success , inputTokens = 0, outputTokens = 0) {
134
134
  // Defect fix (2): cost is only reported when rates are known for this run. The default rates
135
135
  // reproduce the Python's number exactly; a caller that clears them (`rates: null`) gets `null`
136
136
  // rather than a confident figure derived from another model's price list.
@@ -180,7 +180,7 @@ const LEDGER_FILE_RE = /^\d{4}-\d{2}-\d{2}\.jsonl$/;
180
180
  * `wire` is the on-disk key: snake_case, matching the five fields `doflow-run` already writes, so
181
181
  * one file never mixes two naming conventions.
182
182
  */
183
- const RUN_FIELDS: Readonly<Array<{ key: string; wire: string; type: string }>> = Object.freeze([
183
+ const RUN_FIELDS = Object.freeze([
184
184
  { key: 'verb', wire: 'verb', type: 'token' },
185
185
  { key: 'kind', wire: 'kind', type: 'token' },
186
186
  { key: 'capability', wire: 'capability', type: 'token' },
@@ -215,7 +215,7 @@ const ISO_TIMESTAMP = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z?$/;
215
215
  * @param {string} configDir an install root, e.g. `<project>/.doflow` or `~/.doflow`
216
216
  * @returns {string}
217
217
  */
218
- function runsDir(configDir: string): string {
218
+ function runsDir(configDir ) {
219
219
  return path.join(configDir, 'state', RUNS_DIRNAME);
220
220
  }
221
221
 
@@ -234,8 +234,8 @@ function runsDir(configDir: string): string {
234
234
  * subdirectory, so a project with state but no guidance tree falls through to the home install
235
235
  * @returns {{dir: string, configDir: string, origin: string, searched: string[]}}
236
236
  */
237
- function resolveRunsLocation({ start, global: forceGlobal = false, env = process.env, homeDir = os.homedir(), fsImpl = fs, containing = '' }: any = {}): any {
238
- const searched: string[] = [];
237
+ function resolveRunsLocation({ start, global: forceGlobal = false, env = process.env, homeDir = os.homedir(), fsImpl = fs, containing = '' } = {}) {
238
+ const searched = [];
239
239
  const home = path.resolve(homeDir || '.');
240
240
  if (forceGlobal) {
241
241
  const configDir = path.join(home, '.doflow');
@@ -274,14 +274,14 @@ function resolveRunsLocation({ start, global: forceGlobal = false, env = process
274
274
  * fields and never carries their values — a rejection report that echoed the value would leak
275
275
  * exactly the content the rejection exists to keep out.
276
276
  */
277
- function sanitizeRunEvent(input: any, { now = new Date() } = {}): any {
277
+ function sanitizeRunEvent(input , { now = new Date() } = {}) {
278
278
  if (!input || typeof input !== 'object' || Array.isArray(input)) {
279
279
  return { record: null, dropped: [], reason: 'event must be an object' };
280
280
  }
281
281
  const byKey = new Map(RUN_FIELDS.map((field) => [field.key, field]));
282
282
  const byWire = new Map(RUN_FIELDS.map((field) => [field.wire, field]));
283
- const record: any = {};
284
- const dropped: string[] = [];
283
+ const record = {};
284
+ const dropped = [];
285
285
 
286
286
  const timestamp = typeof input.timestamp === 'string' && ISO_TIMESTAMP.test(input.timestamp)
287
287
  ? input.timestamp
@@ -317,9 +317,9 @@ function sanitizeRunEvent(input: any, { now = new Date() } = {}): any {
317
317
  * @param {*} raw parsed JSON value
318
318
  * @returns {Object|null} null when the line is not a usable record
319
319
  */
320
- function normalizeRunRecord(raw: any): any | null {
320
+ function normalizeRunRecord(raw ) {
321
321
  if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return null;
322
- const out: any = { timestamp: typeof raw.timestamp === 'string' ? raw.timestamp : null };
322
+ const out = { timestamp: typeof raw.timestamp === 'string' ? raw.timestamp : null };
323
323
  for (const field of RUN_FIELDS) {
324
324
  const value = raw[field.wire] !== undefined ? raw[field.wire] : raw[field.key];
325
325
  if (value === undefined || value === null) continue;
@@ -337,9 +337,9 @@ function normalizeRunRecord(raw: any): any | null {
337
337
  }
338
338
 
339
339
  class RunLedger {
340
- fsImpl: any;
341
- clock: () => Date;
342
- dir: string;
340
+ fsImpl ;
341
+ clock ;
342
+ dir ;
343
343
 
344
344
  /**
345
345
  * @param {Object} [options]
@@ -348,7 +348,7 @@ class RunLedger {
348
348
  * @param {Object} [options.fsImpl=fs]
349
349
  * @param {Function} [options.clock] returns the current Date; injection seam for tests
350
350
  */
351
- constructor({ dir, configDir, fsImpl = fs, clock = () => new Date() }: any = {}) {
351
+ constructor({ dir, configDir, fsImpl = fs, clock = () => new Date() } = {}) {
352
352
  this.fsImpl = fsImpl;
353
353
  this.clock = clock;
354
354
  if (dir) this.dir = path.resolve(dir);
@@ -362,7 +362,7 @@ class RunLedger {
362
362
  * @param {Object} event
363
363
  * @returns {{written: boolean, file?: string, record?: Object, dropped: string[], reason?: string}}
364
364
  */
365
- append(event: any): any {
365
+ append(event ) {
366
366
  const { record, dropped, reason } = sanitizeRunEvent(event, { now: this.clock() });
367
367
  if (!record) return { written: false, dropped, reason };
368
368
  try {
@@ -370,7 +370,7 @@ class RunLedger {
370
370
  const file = path.join(this.dir, `${record.timestamp.slice(0, 10)}.jsonl`);
371
371
  this.fsImpl.appendFileSync(file, `${JSON.stringify(record)}\n`, 'utf8');
372
372
  return { written: true, file, record, dropped };
373
- } catch (error: any) {
373
+ } catch (error ) {
374
374
  return { written: false, record, dropped, reason: error.message };
375
375
  }
376
376
  }
@@ -383,8 +383,8 @@ class RunLedger {
383
383
  * @param {number} [options.days] keep only partitions dated within the last N calendar days
384
384
  * @returns {{dir: string, exists: boolean, files: string[], records: Object[], malformedLines: number, unreadableFiles: string[], days: number|null}}
385
385
  */
386
- read({ days = null }: any = {}): any {
387
- const result: any = {
386
+ read({ days = null } = {}) {
387
+ const result = {
388
388
  dir: this.dir,
389
389
  exists: false,
390
390
  files: [],
@@ -394,7 +394,7 @@ class RunLedger {
394
394
  days: days && days > 0 ? days : null,
395
395
  };
396
396
 
397
- let entries: string[];
397
+ let entries ;
398
398
  try {
399
399
  entries = this.fsImpl.readdirSync(this.dir);
400
400
  } catch {
@@ -402,7 +402,7 @@ class RunLedger {
402
402
  }
403
403
  result.exists = true;
404
404
 
405
- let names: string[] = entries.filter((name) => LEDGER_FILE_RE.test(name)).sort();
405
+ let names = entries.filter((name) => LEDGER_FILE_RE.test(name)).sort();
406
406
  if (result.days) {
407
407
  // Calendar days, not "the last N files": a quiet week must not silently widen the window.
408
408
  const cutoff = new Date(this.clock().getTime() - (result.days - 1) * 24 * 60 * 60 * 1000)
@@ -412,7 +412,7 @@ class RunLedger {
412
412
  result.files = names;
413
413
 
414
414
  for (const name of names) {
415
- let text: string;
415
+ let text ;
416
416
  try {
417
417
  text = this.fsImpl.readFileSync(path.join(this.dir, name), 'utf8');
418
418
  } catch {
@@ -421,7 +421,7 @@ class RunLedger {
421
421
  }
422
422
  for (const line of text.split('\n')) {
423
423
  if (line.trim() === '') continue;
424
- let parsed: any;
424
+ let parsed ;
425
425
  try {
426
426
  parsed = JSON.parse(line);
427
427
  } catch {
@@ -436,7 +436,7 @@ class RunLedger {
436
436
  }
437
437
 
438
438
  // Undated records sort last rather than being dropped: they still count toward usage.
439
- result.records.sort((a: any, b: any) => (a.at ?? Number.MAX_SAFE_INTEGER) - (b.at ?? Number.MAX_SAFE_INTEGER));
439
+ result.records.sort((a , b ) => (a.at ?? Number.MAX_SAFE_INTEGER) - (b.at ?? Number.MAX_SAFE_INTEGER));
440
440
  return result;
441
441
  }
442
442
  }
@@ -455,7 +455,7 @@ class RunLedger {
455
455
  * @param {string} [options.projectRoot]
456
456
  * @returns {number} process exit code
457
457
  */
458
- function handleTraceCommand({ json = false, days = null, global: useGlobal = false, projectRoot }: any = {}): number {
458
+ function handleTraceCommand({ json = false, days = null, global: useGlobal = false, projectRoot } = {}) {
459
459
  const location = resolveRunsLocation({ start: projectRoot, global: useGlobal });
460
460
  const view = buildTrace(new RunLedger({ dir: location.dir }).read({ days }));
461
461
  view.origin = location.origin;
@@ -503,7 +503,7 @@ function handleTraceCommand({ json = false, days = null, global: useGlobal = fal
503
503
  * @param {Object} options
504
504
  * @returns {number} process exit code
505
505
  */
506
- function handleStatsCommand({ json = false, days = null, global: useGlobal = false, projectRoot }: any = {}): number {
506
+ function handleStatsCommand({ json = false, days = null, global: useGlobal = false, projectRoot } = {}) {
507
507
  const location = resolveRunsLocation({ start: projectRoot, global: useGlobal });
508
508
  const view = buildStats(new RunLedger({ dir: location.dir }).read({ days }));
509
509
  view.origin = location.origin;
@@ -556,7 +556,7 @@ function handleStatsCommand({ json = false, days = null, global: useGlobal = fal
556
556
  * @param {Object} [options.providerHealth] injected for tests; probed from `health.ts` otherwise
557
557
  * @returns {number} process exit code — 1 when there is a finding to act on
558
558
  */
559
- function handleDiscoverCommand({ json = false, days = null, global: useGlobal = false, projectRoot, providerHealth }: any = {}): number {
559
+ function handleDiscoverCommand({ json = false, days = null, global: useGlobal = false, projectRoot, providerHealth } = {}) {
560
560
  const location = resolveRunsLocation({ start: projectRoot, global: useGlobal });
561
561
  const read = new RunLedger({ dir: location.dir }).read({ days });
562
562
 
@@ -565,7 +565,7 @@ function handleDiscoverCommand({ json = false, days = null, global: useGlobal =
565
565
  let health = providerHealth;
566
566
  if (health === undefined) {
567
567
  try {
568
- health = require('../health.ts').probeProviders({ ids: Object.values(PROVIDER) });
568
+ health = require('../health.js').probeProviders({ ids: Object.values(PROVIDER) });
569
569
  } catch {
570
570
  health = null;
571
571
  }
@@ -12,12 +12,12 @@
12
12
 
13
13
  /** ISO timestamp to a compact local-independent `MM-DD HH:MM:SS`. Keeps columns narrow without
14
14
  * inventing a timezone the record does not carry. */
15
- function shortTime(timestamp: any): string {
15
+ function shortTime(timestamp ) {
16
16
  if (typeof timestamp !== 'string' || timestamp.length < 19) return '(undated)';
17
17
  return `${timestamp.slice(5, 10)} ${timestamp.slice(11, 19)}`;
18
18
  }
19
19
 
20
- function formatMs(value: any): string {
20
+ function formatMs(value ) {
21
21
  if (typeof value !== 'number') return '-';
22
22
  if (value < 1000) return `${value}ms`;
23
23
  return `${(value / 1000).toFixed(1)}s`;
@@ -33,7 +33,7 @@ function formatMs(value: any): string {
33
33
  * @param {number} code
34
34
  * @returns {number}
35
35
  */
36
- function finish(code: number): number {
36
+ function finish(code ) {
37
37
  process.exitCode = code;
38
38
  return code;
39
39
  }
@@ -44,22 +44,22 @@ function finish(code: number): number {
44
44
  * @param {Object} ledger
45
45
  * @returns {string|null}
46
46
  */
47
- function integrityNote(ledger: any): string | null {
48
- const parts: string[] = [];
47
+ function integrityNote(ledger ) {
48
+ const parts = [];
49
49
  if (ledger.malformedLines) parts.push(`${ledger.malformedLines} unreadable ledger line(s) skipped`);
50
50
  if (ledger.unreadableFiles.length) parts.push(`${ledger.unreadableFiles.length} unreadable partition(s): ${ledger.unreadableFiles.join(', ')}`);
51
51
  return parts.length ? `Note: ${parts.join('; ')}.` : null;
52
52
  }
53
53
 
54
54
  /** One place that turns a resolved location into the sentence an empty ledger deserves. */
55
- function printEmptyLedgerNotice(ledger: any, reason: any): void {
55
+ function printEmptyLedgerNotice(ledger , reason ) {
56
56
  console.log(` ${reason}`);
57
57
  console.log(` Location: ${ledger.dir}`);
58
58
  console.log(' An empty ledger is a normal state for a fresh install. It is not evidence that');
59
59
  console.log(' nothing ran, and no conclusion about usage can be drawn from it.');
60
60
  }
61
61
 
62
- const DISCOVER_MARK: Record<string, string> = Object.freeze({
62
+ const DISCOVER_MARK = Object.freeze({
63
63
  FINDING: '! FINDING',
64
64
  CLEAR: '✓ CLEAR',
65
65
  NOT_DETERMINED: '? UNKNOWN',
@@ -20,7 +20,7 @@
20
20
  const SESSION_GAP_MS = 30 * 60 * 1000;
21
21
 
22
22
  /** Nearest-rank percentile over an unsorted numeric array. */
23
- function percentile(values: number[], fraction: number): number | null {
23
+ function percentile(values , fraction ) {
24
24
  if (!values.length) return null;
25
25
  const sorted = [...values].sort((a, b) => a - b);
26
26
  const rank = Math.max(1, Math.ceil(fraction * sorted.length));
@@ -34,31 +34,31 @@ function percentile(values: number[], fraction: number): number | null {
34
34
  * @param {number} [options.gapMs=SESSION_GAP_MS]
35
35
  * @returns {{grouping: 'session-field'|'idle-gap', sessions: Array<{id: string, startedAt: string|null, endedAt: string|null, records: Object[]}>}}
36
36
  */
37
- function groupSessions(records: any[], { gapMs = SESSION_GAP_MS } = {}): any {
37
+ function groupSessions(records , { gapMs = SESSION_GAP_MS } = {}) {
38
38
  if (!records.length) return { grouping: 'idle-gap', sessions: [] };
39
39
 
40
40
  // An explicit session id is a recorded fact; an idle gap is an inference. Prefer the fact, and
41
41
  // only when every record carries one — a half-labelled history would mix the two silently.
42
42
  if (records.every((record) => record.session)) {
43
- const order: string[] = [];
44
- const byId = new Map<string, any[]>();
43
+ const order = [];
44
+ const byId = new Map ();
45
45
  for (const record of records) {
46
46
  if (!byId.has(record.session)) { byId.set(record.session, []); order.push(record.session); }
47
- byId.get(record.session)!.push(record);
47
+ byId.get(record.session) .push(record);
48
48
  }
49
49
  return {
50
50
  grouping: 'session-field',
51
51
  sessions: order.map((id) => ({
52
52
  id,
53
- startedAt: byId.get(id)![0].timestamp,
54
- endedAt: byId.get(id)![byId.get(id)!.length - 1].timestamp,
55
- records: byId.get(id)!,
53
+ startedAt: byId.get(id) [0].timestamp,
54
+ endedAt: byId.get(id) [byId.get(id) .length - 1].timestamp,
55
+ records: byId.get(id) ,
56
56
  })),
57
57
  };
58
58
  }
59
59
 
60
- const sessions: any[] = [];
61
- let current: any = null;
60
+ const sessions = [];
61
+ let current = null;
62
62
  for (const record of records) {
63
63
  const previous = current && current.records[current.records.length - 1];
64
64
  const contiguous = previous && record.at !== null && previous.at !== null && record.at - previous.at <= gapMs;
@@ -73,7 +73,7 @@ function groupSessions(records: any[], { gapMs = SESSION_GAP_MS } = {}): any {
73
73
  }
74
74
 
75
75
  /** The ledger provenance every view carries, so a reader can always tell what was actually read. */
76
- function ledgerSummary(read: any): any {
76
+ function ledgerSummary(read ) {
77
77
  return {
78
78
  dir: read.dir,
79
79
  exists: read.exists,
@@ -87,8 +87,8 @@ function ledgerSummary(read: any): any {
87
87
 
88
88
  /** How many records carry each optional field. Every view reports this, because the difference
89
89
  * between "no missed opportunities" and "no data to look for them in" is exactly this table. */
90
- function fieldCoverage(records: any[]): any {
91
- const count = (predicate: (r: any) => boolean) => records.filter(predicate).length;
90
+ function fieldCoverage(records ) {
91
+ const count = (predicate ) => records.filter(predicate).length;
92
92
  return {
93
93
  capability: count((r) => Boolean(r.capability)),
94
94
  provider: count((r) => Boolean(r.provider)),
@@ -108,7 +108,7 @@ function fieldCoverage(records: any[]): any {
108
108
  * @param {number} [options.gapMs]
109
109
  * @returns {Object} view model
110
110
  */
111
- function buildTrace(read: any, { gapMs = SESSION_GAP_MS } = {}): any {
111
+ function buildTrace(read , { gapMs = SESSION_GAP_MS } = {}) {
112
112
  const ledger = ledgerSummary(read);
113
113
  const { grouping, sessions } = groupSessions(read.records, { gapMs });
114
114
  if (!sessions.length) {
@@ -126,7 +126,7 @@ function buildTrace(read: any, { gapMs = SESSION_GAP_MS } = {}): any {
126
126
  }
127
127
 
128
128
  const session = sessions[sessions.length - 1];
129
- const steps = session.records.map((record: any, index: number) => ({
129
+ const steps = session.records.map((record , index ) => ({
130
130
  n: index + 1,
131
131
  timestamp: record.timestamp,
132
132
  verb: record.verb,
@@ -151,9 +151,9 @@ function buildTrace(read: any, { gapMs = SESSION_GAP_MS } = {}): any {
151
151
  startedAt: session.startedAt,
152
152
  endedAt: session.endedAt,
153
153
  wallDurationMs: start !== null && end !== null ? Math.max(0, end - start) : null,
154
- dispatchedMs: steps.reduce((total: number, step: any) => total + (step.durationMs ?? 0), 0),
154
+ dispatchedMs: steps.reduce((total , step ) => total + (step.durationMs ?? 0), 0),
155
155
  stepCount: steps.length,
156
- failedSteps: steps.filter((step: any) => step.exitCode !== null && step.exitCode !== 0).length,
156
+ failedSteps: steps.filter((step ) => step.exitCode !== null && step.exitCode !== 0).length,
157
157
  steps,
158
158
  },
159
159
  };
@@ -166,13 +166,13 @@ function buildTrace(read: any, { gapMs = SESSION_GAP_MS } = {}): any {
166
166
  * @param {Object} read result of `RunLedger#read`
167
167
  * @returns {Object} view model
168
168
  */
169
- function buildStats(read: any): any {
170
- const records: any[] = read.records;
169
+ function buildStats(read ) {
170
+ const records = read.records;
171
171
  const ledger = ledgerSummary(read);
172
172
  const durations = records.map((r) => r.durationMs).filter((value) => typeof value === 'number');
173
173
 
174
- const tally = (keyOf: (r: any) => any) => {
175
- const map = new Map<string, any>();
174
+ const tally = (keyOf ) => {
175
+ const map = new Map ();
176
176
  for (const record of records) {
177
177
  const key = keyOf(record);
178
178
  if (!key) continue;
@@ -221,7 +221,7 @@ function buildStats(read: any): any {
221
221
  byVerb: tally((r) => r.verb),
222
222
  byCapability: tally((r) => r.capability),
223
223
  byProvider: tally((r) => r.provider),
224
- byDay: tally((r) => (r.timestamp ? r.timestamp.slice(0, 10) : null)).sort((a: any, b: any) => a.key.localeCompare(b.key)),
224
+ byDay: tally((r) => (r.timestamp ? r.timestamp.slice(0, 10) : null)).sort((a , b ) => a.key.localeCompare(b.key)),
225
225
  coverage: fieldCoverage(records),
226
226
  };
227
227
  }
@@ -230,7 +230,7 @@ function buildStats(read: any): any {
230
230
 
231
231
  /** Capability ids the opportunity analyses reason about, kept in one place so a registry rename
232
232
  * shows up as one edit rather than four scattered string literals. */
233
- const CAPABILITY: Record<string, string> = Object.freeze({
233
+ const CAPABILITY = Object.freeze({
234
234
  exactSearch: 'code.exact-search',
235
235
  semanticSearch: 'code.semantic-search',
236
236
  relationships: 'code.relationships',
@@ -238,7 +238,7 @@ const CAPABILITY: Record<string, string> = Object.freeze({
238
238
  compress: 'command.compress',
239
239
  });
240
240
 
241
- const PROVIDER: Record<string, string> = Object.freeze({
241
+ const PROVIDER = Object.freeze({
242
242
  semantic: 'semble.search',
243
243
  structural: 'graphify.query',
244
244
  compressor: 'rtk',
@@ -260,7 +260,7 @@ const FINDING = 'FINDING';
260
260
  const CLEAR = 'CLEAR';
261
261
 
262
262
  /** Health of a provider as this analysis needs it: only `HEALTHY` counts as "was available". */
263
- function providerAvailable(providerHealth: any, id: string): boolean | null {
263
+ function providerAvailable(providerHealth , id ) {
264
264
  const entry = providerHealth ? providerHealth[id] : undefined;
265
265
  if (!entry) return null; // unknown — not the same as unavailable
266
266
  return entry.status === 'HEALTHY';
@@ -281,8 +281,8 @@ function providerAvailable(providerHealth: any, id: string): boolean | null {
281
281
  * @param {number} [options.gapMs]
282
282
  * @returns {Object} view model
283
283
  */
284
- function buildDiscover(read: any, { providerHealth = null, gapMs = SESSION_GAP_MS } = {}): any {
285
- const records: any[] = read.records;
284
+ function buildDiscover(read , { providerHealth = null, gapMs = SESSION_GAP_MS } = {}) {
285
+ const records = read.records;
286
286
  const ledger = ledgerSummary(read);
287
287
  const coverage = fieldCoverage(records);
288
288
  const { grouping, sessions } = groupSessions(records, { gapMs });
@@ -296,7 +296,7 @@ function buildDiscover(read: any, { providerHealth = null, gapMs = SESSION_GAP_M
296
296
  + 'Capability-level records are written by runtime calls that resolve a capability to a provider.',
297
297
  };
298
298
 
299
- const analyses: any[] = [];
299
+ const analyses = [];
300
300
 
301
301
  // 1. A broad search that was really a semantic question.
302
302
  analyses.push((() => {
@@ -332,13 +332,13 @@ function buildDiscover(read: any, { providerHealth = null, gapMs = SESSION_GAP_M
332
332
  if (!available) return { ...base, status: NOT_APPLICABLE, detail: `\`${PROVIDER.structural}\` is not answering on this machine, so structural queries were not an available alternative.` };
333
333
 
334
334
  const offenders = sessions
335
- .map((session: any) => ({
335
+ .map((session ) => ({
336
336
  id: session.id,
337
337
  startedAt: session.startedAt,
338
- searches: session.records.filter((r: any) => r.capability === CAPABILITY.exactSearch).length,
339
- structural: session.records.filter((r: any) => r.capability === CAPABILITY.relationships || r.capability === CAPABILITY.impact).length,
338
+ searches: session.records.filter((r ) => r.capability === CAPABILITY.exactSearch).length,
339
+ structural: session.records.filter((r ) => r.capability === CAPABILITY.relationships || r.capability === CAPABILITY.impact).length,
340
340
  }))
341
- .filter((session: any) => session.searches >= REPEATED_SEARCHES && session.structural === 0);
341
+ .filter((session ) => session.searches >= REPEATED_SEARCHES && session.structural === 0);
342
342
  if (!offenders.length) return { ...base, status: CLEAR, detail: `no session ran ${REPEATED_SEARCHES}+ exact searches without also querying the code graph.` };
343
343
  return {
344
344
  ...base,
@@ -362,7 +362,7 @@ function buildDiscover(read: any, { providerHealth = null, gapMs = SESSION_GAP_M
362
362
 
363
363
  const bulky = records.filter((r) => (r.outputBytes ?? 0) >= LARGE_OUTPUT_BYTES && r.provider !== PROVIDER.compressor);
364
364
  if (!bulky.length) return { ...base, status: CLEAR, detail: `no uncompressed run returned ${LARGE_OUTPUT_BYTES} bytes or more.` };
365
- const wasted = bulky.reduce((total: number, r: any) => total + r.outputBytes, 0);
365
+ const wasted = bulky.reduce((total , r ) => total + r.outputBytes, 0);
366
366
  return {
367
367
  ...base,
368
368
  status: FINDING,
@@ -379,14 +379,14 @@ function buildDiscover(read: any, { providerHealth = null, gapMs = SESSION_GAP_M
379
379
  const base = { id: 'retries-without-readiness', title: 'Implementation retries with no readiness check beforehand' };
380
380
  if (!records.length) return { ...base, status: NOT_DETERMINED, detail: 'the ledger holds no runs to analyse.' };
381
381
  const retrying = sessions
382
- .map((session: any) => ({
382
+ .map((session ) => ({
383
383
  id: session.id,
384
384
  startedAt: session.startedAt,
385
- failedVerifications: session.records.filter((r: any) => r.verb === 'verify' && r.exitCode !== undefined && r.exitCode !== 0).length,
386
- recoveries: session.records.filter((r: any) => r.verb === 'recover').length,
387
- readinessCalls: session.records.filter((r: any) => r.verb === 'readiness').length,
385
+ failedVerifications: session.records.filter((r ) => r.verb === 'verify' && r.exitCode !== undefined && r.exitCode !== 0).length,
386
+ recoveries: session.records.filter((r ) => r.verb === 'recover').length,
387
+ readinessCalls: session.records.filter((r ) => r.verb === 'readiness').length,
388
388
  }))
389
- .filter((session: any) => session.failedVerifications >= RETRY_THRESHOLD || session.recoveries >= 1);
389
+ .filter((session ) => session.failedVerifications >= RETRY_THRESHOLD || session.recoveries >= 1);
390
390
  if (!retrying.length) {
391
391
  // The retry signal is a `verify` that FAILED (non-zero exit_code) or a `recover` run. A
392
392
  // `verify` record with no exit_code carries neither, and that is the shape the shell
@@ -408,7 +408,7 @@ function buildDiscover(read: any, { providerHealth = null, gapMs = SESSION_GAP_M
408
408
  : 'no `verify` with a recorded exit code and no `recover` run appears in this window, so there is no retry behaviour to judge.',
409
409
  };
410
410
  }
411
- const unguarded = retrying.filter((session: any) => session.readinessCalls === 0);
411
+ const unguarded = retrying.filter((session ) => session.readinessCalls === 0);
412
412
  if (!unguarded.length) {
413
413
  return {
414
414
  ...base,
@@ -430,7 +430,7 @@ function buildDiscover(read: any, { providerHealth = null, gapMs = SESSION_GAP_M
430
430
  const undetermined = analyses.filter((analysis) => analysis.status === NOT_DETERMINED);
431
431
 
432
432
  // The verdict never claims a clean bill of health over data that could not answer the question.
433
- let verdict: string;
433
+ let verdict ;
434
434
  if (findings.length) verdict = 'findings';
435
435
  else if (undetermined.length === analyses.length) verdict = 'insufficient-data';
436
436
  else if (undetermined.length) verdict = 'no-findings-in-the-analyses-that-could-run';