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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/bin/doflow.js +2 -2
  2. package/core/.claude-plugin/plugin.json +1 -1
  3. package/core/.codex-plugin/plugin.json +1 -1
  4. package/core/.plugin/plugin.json +1 -1
  5. package/core/registry/storage.json +87 -83
  6. package/core/registry/verification.json +1 -1
  7. package/core/shared/scripts/doflow/bash/render-puml.sh +2 -2
  8. package/core/shared/skills/do-execute-plan/references/scaffold.md +2 -2
  9. package/package.json +4 -2
  10. package/src/adapters/antigravity/{index.ts → index.js} +60 -60
  11. package/src/adapters/claude/{index.ts → index.js} +48 -48
  12. package/src/adapters/claude/{mcp.ts → mcp.js} +16 -16
  13. package/src/adapters/codex/{agents.ts → agents.js} +24 -24
  14. package/src/adapters/codex/{config.ts → config.js} +49 -49
  15. package/src/adapters/codex/{hooks.ts → hooks.js} +23 -23
  16. package/src/adapters/codex/{index.ts → index.js} +98 -98
  17. package/src/adapters/codex/{mcp.ts → mcp.js} +38 -38
  18. package/src/adapters/codex/{native-projection.ts → native-projection.js} +5 -5
  19. package/src/adapters/copilot/{index.ts → index.js} +42 -42
  20. package/src/adapters/{copy-tree.ts → copy-tree.js} +70 -70
  21. package/src/adapters/gemini/{hooks.ts → hooks.js} +24 -24
  22. package/src/adapters/gemini/{index.ts → index.js} +41 -41
  23. package/src/adapters/{hook-commands.ts → hook-commands.js} +8 -8
  24. package/src/adapters/{index.ts → index.js} +13 -13
  25. package/src/adapters/kiro/{index.ts → index.js} +34 -34
  26. package/src/adapters/{mcp-entries.ts → mcp-entries.js} +55 -55
  27. package/src/adapters/opencode/{index.ts → index.js} +52 -52
  28. package/src/adapters/pi/{index.ts → index.js} +30 -30
  29. package/src/adapters/pi/{json-members.ts → json-members.js} +23 -23
  30. package/src/adapters/pi/{mcp.ts → mcp.js} +70 -70
  31. package/src/adapters/{resolve-source.ts → resolve-source.js} +1 -1
  32. package/src/cli/commands/{install.ts → install.js} +24 -24
  33. package/src/cli/commands/{list-backups.ts → list-backups.js} +4 -4
  34. package/src/cli/commands/{reconcile.ts → reconcile.js} +19 -19
  35. package/src/cli/commands/{remove.ts → remove.js} +10 -10
  36. package/src/cli/commands/{rollback.ts → rollback.js} +17 -17
  37. package/src/cli/commands/{self-update.ts → self-update.js} +3 -3
  38. package/src/cli/commands/{status.ts → status.js} +24 -24
  39. package/src/cli/commands/{tools.ts → tools.js} +16 -16
  40. package/src/cli/commands/{update.ts → update.js} +19 -19
  41. package/src/cli/{index.ts → index.js} +26 -26
  42. package/src/cli/{runtime-commands.ts → runtime-commands.js} +48 -48
  43. package/src/cli/{shared.ts → shared.js} +40 -40
  44. package/src/helper/{bash-helper.ts → bash-helper.js} +7 -7
  45. package/src/helper/{git.ts → git.js} +2 -2
  46. package/src/helper/{guardrails.ts → guardrails.js} +10 -10
  47. package/src/helper/{harness-paths.ts → harness-paths.js} +24 -24
  48. package/src/helper/{marker-merge.ts → marker-merge.js} +4 -4
  49. package/src/helper/{prompt.ts → prompt.js} +5 -5
  50. package/src/helper/{repo-root.ts → repo-root.js} +2 -2
  51. package/src/helper/{settings-merge.ts → settings-merge.js} +27 -27
  52. package/src/helper/{settings-scope.ts → settings-scope.js} +3 -3
  53. package/src/helper/{toml.ts → toml.js} +48 -48
  54. package/src/install/{backup-set.ts → backup-set.js} +16 -16
  55. package/src/install/{backup.ts → backup.js} +65 -65
  56. package/src/install/{context.ts → context.js} +15 -15
  57. package/src/install/{manifest.ts → manifest.js} +27 -27
  58. package/src/install/{mcp.ts → mcp.js} +30 -30
  59. package/src/install/{paths.ts → paths.js} +15 -15
  60. package/src/install/{targets.ts → targets.js} +10 -10
  61. package/src/install/{tool-lifecycle.ts → tool-lifecycle.js} +20 -20
  62. package/src/lifecycle/{bash-availability.ts → bash-availability.js} +1 -1
  63. package/src/lifecycle/{index.ts → index.js} +140 -140
  64. package/src/lifecycle/{mcp-index.ts → mcp-index.js} +1 -1
  65. package/src/lifecycle/{policies.ts → policies.js} +11 -11
  66. package/src/lifecycle/{view.ts → view.js} +28 -28
  67. package/src/registry/{index.ts → index.js} +60 -60
  68. package/src/release/build-package.js +91 -0
  69. package/src/release/changelog-section.js +70 -0
  70. package/src/release/{sync-plugin-versions.ts → sync-plugin-versions.js} +4 -4
  71. package/src/runtime/advice/{cli.ts → cli.js} +31 -31
  72. package/src/runtime/advice/{client.ts → client.js} +44 -44
  73. package/src/runtime/advice/{config.ts → config.js} +16 -16
  74. package/src/runtime/advice/{doctor.ts → doctor.js} +32 -32
  75. package/src/runtime/advice/{endpoint-guard.ts → endpoint-guard.js} +20 -20
  76. package/src/runtime/advice/{kinds.ts → kinds.js} +16 -16
  77. package/src/runtime/advice/providers/{ollama-systemone.ts → ollama-systemone.js} +21 -21
  78. package/src/runtime/advice/{record.ts → record.js} +19 -19
  79. package/src/runtime/advice/{registry.ts → registry.js} +16 -16
  80. package/src/runtime/advice/{strength.ts → strength.js} +7 -7
  81. package/src/runtime/{brief-tools.ts → brief-tools.js} +50 -50
  82. package/src/runtime/{c4-project.ts → c4-project.js} +27 -27
  83. package/src/runtime/{capability-router.ts → capability-router.js} +39 -39
  84. package/src/runtime/{checkouts.ts → checkouts.js} +21 -21
  85. package/src/runtime/{claims.ts → claims.js} +30 -30
  86. package/src/runtime/{cli-result.ts → cli-result.js} +4 -4
  87. package/src/runtime/{cli.ts → cli.js} +37 -37
  88. package/src/runtime/{command-detect.ts → command-detect.js} +47 -47
  89. package/src/runtime/{context-pack.ts → context-pack.js} +20 -20
  90. package/src/runtime/{decision-register.ts → decision-register.js} +67 -67
  91. package/src/runtime/{evidence-ledger.ts → evidence-ledger.js} +25 -25
  92. package/src/runtime/failure/{capture.ts → capture.js} +29 -29
  93. package/src/runtime/failure/{classifier.ts → classifier.js} +4 -4
  94. package/src/runtime/failure/{cli.ts → cli.js} +30 -30
  95. package/src/runtime/failure/{home.ts → home.js} +6 -6
  96. package/src/runtime/failure/{store.ts → store.js} +32 -32
  97. package/src/runtime/{feature-resolve.ts → feature-resolve.js} +6 -6
  98. package/src/runtime/{freshness.ts → freshness.js} +15 -15
  99. package/src/runtime/{health.ts → health.js} +72 -72
  100. package/src/runtime/{history-compactor.ts → history-compactor.js} +25 -25
  101. package/src/runtime/{implementation-gate.ts → implementation-gate.js} +30 -30
  102. package/src/runtime/inventory/{coverage.ts → coverage.js} +10 -10
  103. package/src/runtime/inventory/{identity.ts → identity.js} +2 -2
  104. package/src/runtime/inventory/{index.ts → index.js} +36 -36
  105. package/src/runtime/inventory/{precedence.ts → precedence.js} +2 -2
  106. package/src/runtime/inventory/{read-scopes.ts → read-scopes.js} +9 -9
  107. package/src/runtime/inventory/{siblings.ts → siblings.js} +15 -15
  108. package/src/runtime/knowledge/{chunker.ts → chunker.js} +12 -12
  109. package/src/runtime/knowledge/{hybrid.ts → hybrid.js} +17 -17
  110. package/src/runtime/knowledge/{index-store.ts → index-store.js} +23 -23
  111. package/src/runtime/knowledge/{retrieval.ts → retrieval.js} +27 -27
  112. package/src/runtime/{leak-scan.ts → leak-scan.js} +12 -12
  113. package/src/runtime/lifecycle/{cli.ts → cli.js} +32 -32
  114. package/src/runtime/lifecycle/{event-store.ts → event-store.js} +48 -48
  115. package/src/runtime/lifecycle/{fold.ts → fold.js} +41 -41
  116. package/src/runtime/lifecycle/{followup.ts → followup.js} +54 -54
  117. package/src/runtime/lifecycle/{goal.ts → goal.js} +50 -50
  118. package/src/runtime/lifecycle/{intent-writer.ts → intent-writer.js} +5 -5
  119. package/src/runtime/lifecycle/{overview.ts → overview.js} +47 -47
  120. package/src/runtime/lifecycle/{release.ts → release.js} +29 -29
  121. package/src/runtime/lifecycle/{report-store.ts → report-store.js} +25 -25
  122. package/src/runtime/lifecycle/{retention.ts → retention.js} +37 -37
  123. package/src/runtime/lifecycle/{root.ts → root.js} +9 -9
  124. package/src/runtime/lifecycle/{status.ts → status.js} +64 -64
  125. package/src/runtime/lifecycle/{store-upkeep.ts → store-upkeep.js} +46 -46
  126. package/src/runtime/{locator-resolve.ts → locator-resolve.js} +7 -7
  127. package/src/runtime/{mask.ts → mask.js} +22 -22
  128. package/src/runtime/{mcp-consultations.ts → mcp-consultations.js} +54 -54
  129. package/src/runtime/{mcp-reach.ts → mcp-reach.js} +24 -24
  130. package/src/runtime/{model-router.ts → model-router.js} +20 -20
  131. package/src/runtime/{outcome.ts → outcome.js} +27 -27
  132. package/src/runtime/{reach.ts → reach.js} +21 -21
  133. package/src/runtime/{readiness-record.ts → readiness-record.js} +12 -12
  134. package/src/runtime/{readiness.ts → readiness.js} +35 -35
  135. package/src/runtime/{recovery.ts → recovery.js} +15 -15
  136. package/src/runtime/{research-request.ts → research-request.js} +34 -34
  137. package/src/runtime/{retrieval-plan.ts → retrieval-plan.js} +40 -40
  138. package/src/runtime/scaffold/{artifacts.ts → artifacts.js} +19 -19
  139. package/src/runtime/scaffold/{fingerprint.ts → fingerprint.js} +3 -3
  140. package/src/runtime/scaffold/{generate.ts → generate.js} +109 -109
  141. package/src/runtime/scaffold/{languages.ts → languages.js} +34 -34
  142. package/src/runtime/storage/{cli.ts → cli.js} +9 -9
  143. package/src/runtime/storage/{engine.ts → engine.js} +37 -37
  144. package/src/runtime/storage/{registry.ts → registry.js} +19 -19
  145. package/src/runtime/storage/{roots.ts → roots.js} +8 -8
  146. package/src/runtime/storage/{rules.ts → rules.js} +26 -26
  147. package/src/runtime/storage/{upkeep.ts → upkeep.js} +35 -35
  148. package/src/runtime/storage/{work-status.ts → work-status.js} +39 -39
  149. package/src/runtime/{task-attempts.ts → task-attempts.js} +61 -61
  150. package/src/runtime/{task-classifier.ts → task-classifier.js} +34 -34
  151. package/src/runtime/{task-scope.ts → task-scope.js} +13 -13
  152. package/src/runtime/{task-state.ts → task-state.js} +15 -15
  153. package/src/runtime/trace/{indicators.ts → indicators.js} +22 -22
  154. package/src/runtime/trace/{ledger.ts → ledger.js} +42 -42
  155. package/src/runtime/trace/{render.ts → render.js} +7 -7
  156. package/src/runtime/trace/{views.ts → views.js} +40 -40
  157. package/src/runtime/verification/{contract-runner.ts → contract-runner.js} +23 -23
  158. package/src/runtime/verification/{engine.ts → engine.js} +143 -143
  159. package/src/runtime/verification/{registry.ts → registry.js} +6 -6
  160. package/src/runtime/verification/{scope-bound.ts → scope-bound.js} +50 -50
  161. package/src/runtime/verification/{test-selection.ts → test-selection.js} +28 -28
  162. package/src/runtime/{workflow-engine.ts → workflow-engine.js} +50 -50
  163. package/src/runtime/{workflow-orchestrator.ts → workflow-orchestrator.js} +91 -91
  164. package/src/runtime/{worktree.ts → worktree.js} +31 -31
  165. package/src/state/{index.ts → index.js} +26 -26
  166. package/src/state/{lockfile.ts → lockfile.js} +20 -20
  167. package/src/state/{run-lock.ts → run-lock.js} +44 -44
@@ -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';
@@ -46,7 +46,7 @@ const TIMEOUT_EXIT_CODE = 124;
46
46
  * @param {*} value
47
47
  * @returns {string}
48
48
  */
49
- function truncate(value: any): string {
49
+ function truncate(value ) {
50
50
  if (typeof value !== 'string') return '';
51
51
  if (value.length <= MAX_STREAM_CHARS) return value;
52
52
  // Keep the TAIL, not the head, and say so.
@@ -77,8 +77,8 @@ const TAP_NOT_OK = /^\s*not ok\b(?:\s+\d+)?(?:\s*-\s*)?(.*)$/gm;
77
77
  * @param {string} text
78
78
  * @returns {Array<string>} unique identifiers, bounded by MAX_FAILED_TESTS
79
79
  */
80
- function extractFailedTests(text: string): string[] {
81
- const seen = new Set<string>();
80
+ function extractFailedTests(text ) {
81
+ const seen = new Set ();
82
82
  for (const match of text.matchAll(TAP_NOT_OK)) {
83
83
  const name = match[1].trim();
84
84
  if (name === '' || /#\s*(?:SKIP|TODO)\b/i.test(name)) continue;
@@ -89,12 +89,12 @@ function extractFailedTests(text: string): string[] {
89
89
  }
90
90
 
91
91
  class VerificationContractRunner {
92
- cwd: string;
93
- defaultTimeoutMs: number;
94
- exec: any;
95
- fsImpl: any;
96
- logDir: string;
97
- logWriteWarned?: boolean;
92
+ cwd ;
93
+ defaultTimeoutMs ;
94
+ exec ;
95
+ fsImpl ;
96
+ logDir ;
97
+ logWriteWarned ;
98
98
 
99
99
  /**
100
100
  * @param {Object|string} [options] a string is accepted for parity with the Python's positional
@@ -103,7 +103,7 @@ class VerificationContractRunner {
103
103
  * @param {number} [options.defaultTimeoutMs=60000]
104
104
  * @param {Function} [options.exec] injection seam for tests; same contract as `spawnSync`
105
105
  */
106
- constructor(options: any = {}) {
106
+ constructor(options = {}) {
107
107
  const opts = typeof options === 'string' ? { cwd: options } : options;
108
108
  this.cwd = opts.cwd || process.cwd();
109
109
  this.defaultTimeoutMs = opts.defaultTimeoutMs || DEFAULT_TIMEOUT_MS;
@@ -123,7 +123,7 @@ class VerificationContractRunner {
123
123
  * @param {string} stderr
124
124
  * @returns {string|null} the log path, or null when the log could not be written
125
125
  */
126
- persistLog(name: string, command: string, stdout: string, stderr: string): string | null {
126
+ persistLog(name , command , stdout , stderr ) {
127
127
  try {
128
128
  this.fsImpl.mkdirSync(this.logDir, { recursive: true });
129
129
  const safe = name.replace(/[^A-Za-z0-9._-]+/g, '_');
@@ -132,7 +132,7 @@ class VerificationContractRunner {
132
132
  `# check: ${name}\n# command: ${command}\n--- stdout ---\n${stdout || ''}\n--- stderr ---\n${stderr || ''}\n`,
133
133
  'utf8');
134
134
  return file;
135
- } catch (error: any) {
135
+ } catch (error ) {
136
136
  // An unwritable log directory must not turn a completed check into an error — the check's
137
137
  // verdict stands; only the pointer is missing, and its null says so. But a chronic
138
138
  // permissions problem should not be invisible either: say so once per runner, on stderr so
@@ -154,7 +154,7 @@ class VerificationContractRunner {
154
154
  * @param {string} [stdout]
155
155
  * @param {string} [stderr]
156
156
  */
157
- decorate(result: any, command: string, stdout?: string, stderr?: string): void {
157
+ decorate(result , command , stdout , stderr ) {
158
158
  const full = `${stdout || ''}\n${stderr || ''}`;
159
159
  if (result.status === 'FAIL') {
160
160
  const failedTests = extractFailedTests(full);
@@ -162,7 +162,7 @@ class VerificationContractRunner {
162
162
  }
163
163
  const truncated = (stdout || '').length > MAX_STREAM_CHARS || (stderr || '').length > MAX_STREAM_CHARS;
164
164
  if ((result.status === 'FAIL' || truncated) && full.trim() !== '') {
165
- result.logPath = this.persistLog(result.name, command, stdout as string, stderr as string);
165
+ result.logPath = this.persistLog(result.name, command, stdout , stderr );
166
166
  }
167
167
  }
168
168
 
@@ -177,7 +177,7 @@ class VerificationContractRunner {
177
177
  * evaluations — a recovery retry must observe live behaviour, so each pass passes a fresh map.
178
178
  * @returns {Object} check result
179
179
  */
180
- runCheck(name: string, command: any, timeoutMs: number = this.defaultTimeoutMs, dedupeCache: Map<string, any> | null = null): any {
180
+ runCheck(name , command , timeoutMs = this.defaultTimeoutMs, dedupeCache = null) {
181
181
  const checkName = name || 'unnamed_check';
182
182
 
183
183
  // Defect fix (1): the Python defaulted a missing command to `true`, so a typo in a contract
@@ -196,12 +196,12 @@ class VerificationContractRunner {
196
196
  if (dedupeCache && dedupeCache.has(dedupeKey)) {
197
197
  return { ...dedupeCache.get(dedupeKey), name: checkName, deduplicated: true };
198
198
  }
199
- const remember = (result: any) => {
199
+ const remember = (result ) => {
200
200
  if (dedupeCache) dedupeCache.set(dedupeKey, result);
201
201
  return result;
202
202
  };
203
203
 
204
- let res: any;
204
+ let res ;
205
205
  try {
206
206
  res = this.exec(command, {
207
207
  shell: true,
@@ -214,7 +214,7 @@ class VerificationContractRunner {
214
214
  // past anything a check legitimately prints. Only the first 2,000 chars are ever kept.
215
215
  maxBuffer: 64 * 1024 * 1024,
216
216
  });
217
- } catch (error: any) {
217
+ } catch (error ) {
218
218
  // Mirrors the Python's bare `except Exception` arm: an unspawnable command is a FAIL, not a
219
219
  // thrown error that aborts the whole contract.
220
220
  return remember({
@@ -263,7 +263,7 @@ class VerificationContractRunner {
263
263
  const exitCode = res.status === null || res.status === undefined ? 1 : res.status;
264
264
  const passed = res.status === 0;
265
265
 
266
- const result: any = {
266
+ const result = {
267
267
  name: checkName,
268
268
  command,
269
269
  status: passed ? 'PASS' : 'FAIL',
@@ -283,7 +283,7 @@ class VerificationContractRunner {
283
283
  * @param {Array<{name?: string, command?: string, timeoutMs?: number}>} checks
284
284
  * @returns {{ status: string, checks: Array<Object>, failedChecks: Array<string>, timestamp: string, reason?: string }}
285
285
  */
286
- evaluateContract(checks: any[]): any {
286
+ evaluateContract(checks ) {
287
287
  if (!Array.isArray(checks)) {
288
288
  throw new Error('evaluateContract expects an array of checks');
289
289
  }
@@ -303,10 +303,10 @@ class VerificationContractRunner {
303
303
  };
304
304
  }
305
305
 
306
- const results: any[] = [];
307
- const failedChecks: string[] = [];
306
+ const results = [];
307
+ const failedChecks = [];
308
308
  let overallStatus = 'PASS';
309
- const dedupeCache = new Map<string, any>(); // one evaluation, one cache — a retry pass starts fresh
309
+ const dedupeCache = new Map (); // one evaluation, one cache — a retry pass starts fresh
310
310
 
311
311
  for (const chk of checks) {
312
312
  const name = (chk && chk.name) || 'unnamed_check';