@kirrosh/zond 0.26.1 → 0.27.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 (261) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/README.md +22 -21
  3. package/bin/zond.mjs +23 -0
  4. package/package.json +13 -16
  5. package/scripts/npm/postinstall.mjs +76 -0
  6. package/src/CLAUDE.md +0 -112
  7. package/src/bun-types.d.ts +0 -5
  8. package/src/cli/argv.ts +0 -122
  9. package/src/cli/commands/add-api.ts +0 -146
  10. package/src/cli/commands/api/annotate/idempotency.ts +0 -59
  11. package/src/cli/commands/api/annotate/index.ts +0 -880
  12. package/src/cli/commands/api/annotate/lifecycle.ts +0 -74
  13. package/src/cli/commands/api/annotate/overlay.ts +0 -206
  14. package/src/cli/commands/api/annotate/pagination.ts +0 -64
  15. package/src/cli/commands/api/annotate/prompts.ts +0 -220
  16. package/src/cli/commands/api/annotate/readback.ts +0 -58
  17. package/src/cli/commands/api/annotate/resources.ts +0 -91
  18. package/src/cli/commands/api/annotate/seed-bodies.ts +0 -61
  19. package/src/cli/commands/audit.ts +0 -786
  20. package/src/cli/commands/catalog.ts +0 -97
  21. package/src/cli/commands/check.ts +0 -361
  22. package/src/cli/commands/checks.ts +0 -1072
  23. package/src/cli/commands/ci-init.ts +0 -223
  24. package/src/cli/commands/clean.ts +0 -212
  25. package/src/cli/commands/cleanup.ts +0 -236
  26. package/src/cli/commands/completions.ts +0 -192
  27. package/src/cli/commands/coverage.ts +0 -872
  28. package/src/cli/commands/db.ts +0 -611
  29. package/src/cli/commands/describe.ts +0 -120
  30. package/src/cli/commands/discover.ts +0 -1356
  31. package/src/cli/commands/doctor.ts +0 -661
  32. package/src/cli/commands/fixtures.ts +0 -402
  33. package/src/cli/commands/generate.ts +0 -577
  34. package/src/cli/commands/init/agents-md.ts +0 -61
  35. package/src/cli/commands/init/bootstrap.ts +0 -111
  36. package/src/cli/commands/init/index.ts +0 -244
  37. package/src/cli/commands/init/skills.ts +0 -141
  38. package/src/cli/commands/init/templates/agents.md +0 -86
  39. package/src/cli/commands/init/templates/markdown.d.ts +0 -4
  40. package/src/cli/commands/init/templates/skills/warm-up-target.md +0 -122
  41. package/src/cli/commands/init/templates/skills/zond-checks.md +0 -621
  42. package/src/cli/commands/init/templates/skills/zond-seed.md +0 -114
  43. package/src/cli/commands/init/templates/skills/zond-triage.md +0 -272
  44. package/src/cli/commands/init/templates/skills/zond.md +0 -861
  45. package/src/cli/commands/init/templates/zond-config.yml +0 -14
  46. package/src/cli/commands/prepare-fixtures.ts +0 -97
  47. package/src/cli/commands/probe/_seed-bodies.ts +0 -52
  48. package/src/cli/commands/probe/mass-assignment.ts +0 -594
  49. package/src/cli/commands/probe/security.ts +0 -537
  50. package/src/cli/commands/probe/static.ts +0 -255
  51. package/src/cli/commands/probe/webhooks.ts +0 -163
  52. package/src/cli/commands/probe.ts +0 -535
  53. package/src/cli/commands/reference.ts +0 -87
  54. package/src/cli/commands/refresh-api.ts +0 -227
  55. package/src/cli/commands/remove-api.ts +0 -150
  56. package/src/cli/commands/report-bundle.ts +0 -310
  57. package/src/cli/commands/report.ts +0 -241
  58. package/src/cli/commands/request.ts +0 -548
  59. package/src/cli/commands/run.ts +0 -1162
  60. package/src/cli/commands/schema-from-runs.ts +0 -128
  61. package/src/cli/commands/secrets.ts +0 -133
  62. package/src/cli/commands/session.ts +0 -244
  63. package/src/cli/commands/use.ts +0 -74
  64. package/src/cli/index.ts +0 -55
  65. package/src/cli/json-envelope.ts +0 -108
  66. package/src/cli/json-schemas.ts +0 -314
  67. package/src/cli/output.ts +0 -40
  68. package/src/cli/program.ts +0 -219
  69. package/src/cli/resolve.ts +0 -105
  70. package/src/cli/runtime.ts +0 -7
  71. package/src/cli/safe-live.ts +0 -24
  72. package/src/cli/status-filter.ts +0 -114
  73. package/src/cli/util/api-context.ts +0 -85
  74. package/src/cli/version.ts +0 -8
  75. package/src/core/audit/persist.ts +0 -183
  76. package/src/core/checks/budget.ts +0 -59
  77. package/src/core/checks/checks/_crud-helpers.ts +0 -133
  78. package/src/core/checks/checks/_negative_mutator.ts +0 -133
  79. package/src/core/checks/checks/_readback-helpers.ts +0 -133
  80. package/src/core/checks/checks/content_type_conformance.ts +0 -39
  81. package/src/core/checks/checks/cross_call_references.ts +0 -147
  82. package/src/core/checks/checks/cursor_boundary_fuzzing.ts +0 -219
  83. package/src/core/checks/checks/ensure_resource_availability.ts +0 -62
  84. package/src/core/checks/checks/idempotency_replay.ts +0 -242
  85. package/src/core/checks/checks/ignored_auth.ts +0 -254
  86. package/src/core/checks/checks/index.ts +0 -68
  87. package/src/core/checks/checks/lifecycle_transitions.ts +0 -416
  88. package/src/core/checks/checks/missing_required_header.ts +0 -40
  89. package/src/core/checks/checks/negative_data_rejection.ts +0 -148
  90. package/src/core/checks/checks/not_a_server_error.ts +0 -35
  91. package/src/core/checks/checks/open_cors_on_sensitive.ts +0 -160
  92. package/src/core/checks/checks/pagination_invariants.ts +0 -419
  93. package/src/core/checks/checks/positive_data_acceptance.ts +0 -33
  94. package/src/core/checks/checks/rate_limit_headers_absent.ts +0 -77
  95. package/src/core/checks/checks/response_headers_conformance.ts +0 -74
  96. package/src/core/checks/checks/response_schema_conformance.ts +0 -30
  97. package/src/core/checks/checks/status_code_conformance.ts +0 -132
  98. package/src/core/checks/checks/unsupported_method.ts +0 -63
  99. package/src/core/checks/checks/use_after_free.ts +0 -78
  100. package/src/core/checks/index.ts +0 -30
  101. package/src/core/checks/mode.ts +0 -82
  102. package/src/core/checks/recommended-action.ts +0 -68
  103. package/src/core/checks/registry.ts +0 -78
  104. package/src/core/checks/runner.ts +0 -1461
  105. package/src/core/checks/sarif.ts +0 -230
  106. package/src/core/checks/spec-findings.ts +0 -308
  107. package/src/core/checks/stateful.ts +0 -121
  108. package/src/core/checks/types.ts +0 -305
  109. package/src/core/checks/zond-extensions.ts +0 -73
  110. package/src/core/classifier/recommended-action.ts +0 -251
  111. package/src/core/context/current.ts +0 -51
  112. package/src/core/context/session.ts +0 -78
  113. package/src/core/coverage/loader.ts +0 -216
  114. package/src/core/coverage/reasons.ts +0 -300
  115. package/src/core/diagnostics/db-analysis.ts +0 -666
  116. package/src/core/diagnostics/failure-class.ts +0 -140
  117. package/src/core/diagnostics/failure-hints.ts +0 -112
  118. package/src/core/diagnostics/spec-pointer.ts +0 -99
  119. package/src/core/diagnostics/suggested-fixes.ts +0 -155
  120. package/src/core/exporter/case-study/index.ts +0 -270
  121. package/src/core/exporter/curl.ts +0 -40
  122. package/src/core/exporter/exporter.ts +0 -48
  123. package/src/core/exporter/html-report/escape.ts +0 -24
  124. package/src/core/exporter/html-report/index.ts +0 -479
  125. package/src/core/exporter/html-report/script.ts +0 -100
  126. package/src/core/exporter/html-report/styles.ts +0 -408
  127. package/src/core/generator/catalog-builder.ts +0 -179
  128. package/src/core/generator/chunker.ts +0 -78
  129. package/src/core/generator/coverage-phase.ts +0 -0
  130. package/src/core/generator/coverage-scanner.ts +0 -87
  131. package/src/core/generator/data-factory.ts +0 -759
  132. package/src/core/generator/describe.ts +0 -302
  133. package/src/core/generator/endpoint-warnings.ts +0 -52
  134. package/src/core/generator/fixtures-builder.ts +0 -332
  135. package/src/core/generator/index.ts +0 -14
  136. package/src/core/generator/openapi-reader.ts +0 -297
  137. package/src/core/generator/path-param-disambig.ts +0 -140
  138. package/src/core/generator/resources-builder.ts +0 -898
  139. package/src/core/generator/schema-utils.ts +0 -112
  140. package/src/core/generator/serializer.ts +0 -343
  141. package/src/core/generator/suite-generator.ts +0 -1301
  142. package/src/core/generator/types.ts +0 -63
  143. package/src/core/identity/identity-file.ts +0 -0
  144. package/src/core/lint/affects.ts +0 -28
  145. package/src/core/lint/config.ts +0 -96
  146. package/src/core/lint/format.ts +0 -42
  147. package/src/core/lint/index.ts +0 -94
  148. package/src/core/lint/reporter.ts +0 -128
  149. package/src/core/lint/rules/consistency.ts +0 -158
  150. package/src/core/lint/rules/heuristics.ts +0 -97
  151. package/src/core/lint/rules/strictness.ts +0 -109
  152. package/src/core/lint/types.ts +0 -96
  153. package/src/core/lint/walker.ts +0 -248
  154. package/src/core/meta/meta-store.ts +0 -11
  155. package/src/core/output/README.md +0 -73
  156. package/src/core/output/index.ts +0 -13
  157. package/src/core/output/run.ts +0 -91
  158. package/src/core/output/types.ts +0 -122
  159. package/src/core/parser/dynamic-values.ts +0 -160
  160. package/src/core/parser/env-interpolation.ts +0 -104
  161. package/src/core/parser/filter.ts +0 -97
  162. package/src/core/parser/schema.ts +0 -359
  163. package/src/core/parser/types.ts +0 -117
  164. package/src/core/parser/variables.ts +0 -0
  165. package/src/core/parser/yaml-parser.ts +0 -181
  166. package/src/core/probe/bootstrap.ts +0 -34
  167. package/src/core/probe/dry-run-envelope.ts +0 -61
  168. package/src/core/probe/mass-assignment/classify.ts +0 -175
  169. package/src/core/probe/mass-assignment/cleanup.ts +0 -52
  170. package/src/core/probe/mass-assignment/digest.ts +0 -114
  171. package/src/core/probe/mass-assignment/orchestrator.ts +0 -459
  172. package/src/core/probe/mass-assignment/regression.ts +0 -141
  173. package/src/core/probe/mass-assignment/suspects.ts +0 -92
  174. package/src/core/probe/mass-assignment/types.ts +0 -135
  175. package/src/core/probe/mass-assignment-probe-class.ts +0 -198
  176. package/src/core/probe/mass-assignment-probe.ts +0 -27
  177. package/src/core/probe/mass-assignment-template.ts +0 -240
  178. package/src/core/probe/method-probe.ts +0 -164
  179. package/src/core/probe/method-shared.ts +0 -69
  180. package/src/core/probe/negative-probe.ts +0 -691
  181. package/src/core/probe/orphan-tracker.ts +0 -188
  182. package/src/core/probe/path-discovery.ts +0 -439
  183. package/src/core/probe/probe-harness.ts +0 -119
  184. package/src/core/probe/registry.ts +0 -89
  185. package/src/core/probe/runner.ts +0 -136
  186. package/src/core/probe/security/baseline.ts +0 -174
  187. package/src/core/probe/security/classify.ts +0 -341
  188. package/src/core/probe/security/cleanup.ts +0 -125
  189. package/src/core/probe/security/detectors.ts +0 -71
  190. package/src/core/probe/security/digest.ts +0 -104
  191. package/src/core/probe/security/orchestrator.ts +0 -398
  192. package/src/core/probe/security/regression.ts +0 -103
  193. package/src/core/probe/security/types.ts +0 -151
  194. package/src/core/probe/security-probe-class.ts +0 -207
  195. package/src/core/probe/security-probe.ts +0 -32
  196. package/src/core/probe/shared.ts +0 -531
  197. package/src/core/probe/static-probe-class.ts +0 -125
  198. package/src/core/probe/types.ts +0 -165
  199. package/src/core/probe/verdict-aggregator.ts +0 -33
  200. package/src/core/probe/webhooks-probe.ts +0 -282
  201. package/src/core/reporter/console.ts +0 -240
  202. package/src/core/reporter/index.ts +0 -22
  203. package/src/core/reporter/json.ts +0 -22
  204. package/src/core/reporter/junit.ts +0 -93
  205. package/src/core/reporter/ndjson.ts +0 -37
  206. package/src/core/reporter/types.ts +0 -15
  207. package/src/core/runner/assertions.ts +0 -383
  208. package/src/core/runner/async-pool.ts +0 -108
  209. package/src/core/runner/auth-path.ts +0 -8
  210. package/src/core/runner/ci-context.ts +0 -72
  211. package/src/core/runner/executor.ts +0 -652
  212. package/src/core/runner/expr-eval.ts +0 -41
  213. package/src/core/runner/form-encode.ts +0 -41
  214. package/src/core/runner/http-client.ts +0 -224
  215. package/src/core/runner/learn-drift.ts +0 -293
  216. package/src/core/runner/preflight-vars.ts +0 -153
  217. package/src/core/runner/progress-tracker.ts +0 -73
  218. package/src/core/runner/rate-limiter.ts +0 -185
  219. package/src/core/runner/run-kind.ts +0 -45
  220. package/src/core/runner/schema-validator.ts +0 -308
  221. package/src/core/runner/send-request.ts +0 -232
  222. package/src/core/runner/transforms.ts +0 -65
  223. package/src/core/runner/types.ts +0 -94
  224. package/src/core/secrets/registry.ts +0 -164
  225. package/src/core/secrets/secrets-file.ts +0 -115
  226. package/src/core/selectors/operation-filter.ts +0 -144
  227. package/src/core/setup-api.ts +0 -590
  228. package/src/core/severity/category.ts +0 -94
  229. package/src/core/severity/index.ts +0 -58
  230. package/src/core/spec/infer-schema.ts +0 -102
  231. package/src/core/spec/layers.ts +0 -154
  232. package/src/core/spec/merge-specs.ts +0 -156
  233. package/src/core/spec/schema-from-runs.ts +0 -117
  234. package/src/core/spec/schema-overlay.ts +0 -130
  235. package/src/core/util/ajv.ts +0 -13
  236. package/src/core/util/format-eta.ts +0 -21
  237. package/src/core/util/headers.ts +0 -9
  238. package/src/core/util/url.ts +0 -24
  239. package/src/core/utils.ts +0 -13
  240. package/src/core/workspace/config.ts +0 -129
  241. package/src/core/workspace/fixture-gap-report.ts +0 -84
  242. package/src/core/workspace/fixture-gaps.ts +0 -71
  243. package/src/core/workspace/manifest.ts +0 -283
  244. package/src/core/workspace/output-rotation.ts +0 -62
  245. package/src/core/workspace/root.ts +0 -96
  246. package/src/core/workspace/triage-path.ts +0 -87
  247. package/src/db/lint-runs.ts +0 -47
  248. package/src/db/migrate.ts +0 -128
  249. package/src/db/migrations/0001_run_kind.sql +0 -25
  250. package/src/db/migrations/0002_run_kind_request.sql +0 -59
  251. package/src/db/migrations/sql.d.ts +0 -4
  252. package/src/db/queries/collections.ts +0 -133
  253. package/src/db/queries/coverage.ts +0 -9
  254. package/src/db/queries/dashboard.ts +0 -59
  255. package/src/db/queries/results.ts +0 -216
  256. package/src/db/queries/runs.ts +0 -289
  257. package/src/db/queries/sessions.ts +0 -42
  258. package/src/db/queries/settings.ts +0 -28
  259. package/src/db/queries/types.ts +0 -172
  260. package/src/db/queries.ts +0 -75
  261. package/src/db/schema.ts +0 -298
package/src/db/schema.ts DELETED
@@ -1,298 +0,0 @@
1
- import { Database } from "bun:sqlite";
2
- import { dirname, resolve } from "path";
3
- import { existsSync, mkdirSync } from "fs";
4
- import { findWorkspaceRoot } from "../core/workspace/root.ts";
5
- import { applyMigrations } from "./migrate.ts";
6
-
7
- let _db: Database | null = null;
8
- let _dbPath: string | null = null;
9
-
10
- /**
11
- * Default DB path lives under `<workspace>/.zond/zond.db` to keep runtime
12
- * artifacts out of the project root. (The flat `<workspace>/zond.db` layout
13
- * was dropped in m-25 — pass an explicit `--db` to target a legacy file.)
14
- */
15
- function defaultDbPath(): string {
16
- const root = findWorkspaceRoot().root;
17
- return resolve(root, ".zond", "zond.db");
18
- }
19
-
20
- export function getDb(dbPath?: string): Database {
21
- const path = dbPath ? resolve(dbPath) : (_dbPath ?? defaultDbPath());
22
-
23
- // If cached connection exists, verify the file still exists
24
- if (_db && _dbPath === path && existsSync(path)) return _db;
25
-
26
- // Close stale connection if any
27
- if (_db) {
28
- try { _db.close(); } catch {}
29
- _db = null;
30
- _dbPath = null;
31
- }
32
- // SQLite won't auto-create parent dirs; ensure `.zond/` (or any custom
33
- // path's parent) exists before opening the file.
34
- const parent = dirname(path);
35
- if (!existsSync(parent)) mkdirSync(parent, { recursive: true });
36
-
37
- const db = new Database(path, { create: true });
38
-
39
- // Performance and integrity settings
40
- db.exec("PRAGMA journal_mode = WAL");
41
- db.exec("PRAGMA foreign_keys = ON");
42
- // ARV-163: concurrent zond processes (e.g. `probe security` in one terminal
43
- // + `checks run` in another) collide on the write-lock and surface as
44
- // "database is locked". Letting SQLite spin at the C-level for up to 5s
45
- // resolves the overwhelming majority without any per-call retry logic.
46
- // `synchronous=NORMAL` is safe under WAL and cuts fsync overhead in the
47
- // bulk-insert path (saveResults). withDbRetry() in this file remains the
48
- // belt-and-suspenders for the rare long-running transactions.
49
- db.exec("PRAGMA busy_timeout = 5000");
50
- db.exec("PRAGMA synchronous = NORMAL");
51
-
52
- runMigrations(db);
53
-
54
- // ARV-127: file-based migrations sit on top of the legacy PRAGMA
55
- // path. On an existing DB the runner pre-seeds `schema_migrations`
56
- // so the v9→v10 inline migration (now mirrored in
57
- // src/db/migrations/0001_run_kind.sql) is treated as applied.
58
- applyMigrations(db);
59
-
60
- _db = db;
61
- _dbPath = path;
62
- return db;
63
- }
64
-
65
- /**
66
- * ARV-163: retry wrapper for SQLite write paths that may collide with
67
- * concurrent zond processes. `PRAGMA busy_timeout` already absorbs short
68
- * contention at the C level — this wrapper only catches the residual cases
69
- * where the lock holder runs longer than the timeout (e.g. a big
70
- * `saveResults` bulk insert during a parallel `probe security` cleanup).
71
- *
72
- * Detects bun:sqlite's "database is locked" / "SQLITE_BUSY" message shapes;
73
- * other errors propagate immediately. Backoff: 100, 200, 400, 800ms capped at
74
- * 4 attempts (≈1.5s total) so we never silently stall a CLI command.
75
- */
76
- export function withDbRetry<T>(label: string, fn: () => T): T {
77
- const delaysMs = [100, 200, 400, 800];
78
- let lastError: unknown;
79
- for (let attempt = 0; attempt <= delaysMs.length; attempt++) {
80
- try {
81
- return fn();
82
- } catch (err) {
83
- const msg = err instanceof Error ? err.message : String(err);
84
- if (!/database is locked|SQLITE_BUSY/i.test(msg)) throw err;
85
- lastError = err;
86
- if (attempt === delaysMs.length) break;
87
- Bun.sleepSync(delaysMs[attempt]!);
88
- }
89
- }
90
- const msg = lastError instanceof Error ? lastError.message : String(lastError);
91
- throw new Error(`SQLite still locked after ${delaysMs.length + 1} attempts (${label}): ${msg}`);
92
- }
93
-
94
- export function closeDb(): void {
95
- if (_db) {
96
- try { _db.close(); } catch {}
97
- _db = null;
98
- _dbPath = null;
99
- }
100
- }
101
-
102
- function resetDb(): void {
103
- if (_db) { try { _db.close(); } catch {} }
104
- _db = null;
105
- _dbPath = null;
106
- }
107
-
108
- // ──────────────────────────────────────────────
109
- // Schema
110
- // ──────────────────────────────────────────────
111
-
112
- const SCHEMA_VERSION = 10;
113
-
114
- const SCHEMA = `
115
- CREATE TABLE IF NOT EXISTS runs (
116
- id INTEGER PRIMARY KEY AUTOINCREMENT,
117
- started_at TEXT NOT NULL,
118
- finished_at TEXT,
119
- total INTEGER NOT NULL DEFAULT 0,
120
- passed INTEGER NOT NULL DEFAULT 0,
121
- failed INTEGER NOT NULL DEFAULT 0,
122
- skipped INTEGER NOT NULL DEFAULT 0,
123
- trigger TEXT DEFAULT 'manual',
124
- commit_sha TEXT,
125
- branch TEXT,
126
- environment TEXT,
127
- duration_ms INTEGER,
128
- collection_id INTEGER REFERENCES collections(id),
129
- session_id TEXT,
130
- tags TEXT,
131
- -- ARV-55: classify a run once at INSERT time so coverage / diagnose
132
- -- queries don't have to re-derive "is this a probe-only run?" from
133
- -- the results' suite_file paths. ARV-265 extends the CHECK list with
134
- -- 'request' (zond request in-session) and 'fixture' (prepare-fixtures
135
- -- cascade list-calls) so audit-coverage can attribute HTTP touches
136
- -- back to the producer.
137
- run_kind TEXT NOT NULL DEFAULT 'regular' CHECK (run_kind IN ('regular','probe','check','request','fixture'))
138
- );
139
-
140
- CREATE TABLE IF NOT EXISTS results (
141
- id INTEGER PRIMARY KEY AUTOINCREMENT,
142
- run_id INTEGER NOT NULL REFERENCES runs(id),
143
- suite_name TEXT NOT NULL,
144
- test_name TEXT NOT NULL,
145
- status TEXT NOT NULL,
146
- duration_ms INTEGER NOT NULL,
147
- request_method TEXT,
148
- request_url TEXT,
149
- request_body TEXT,
150
- response_status INTEGER,
151
- response_body TEXT,
152
- error_message TEXT,
153
- assertions TEXT,
154
- captures TEXT,
155
- response_headers TEXT,
156
- suite_file TEXT,
157
- provenance TEXT,
158
- failure_class TEXT,
159
- failure_class_reason TEXT,
160
- spec_pointer TEXT,
161
- spec_excerpt TEXT
162
- );
163
-
164
- CREATE TABLE IF NOT EXISTS collections (
165
- id INTEGER PRIMARY KEY AUTOINCREMENT,
166
- name TEXT NOT NULL,
167
- test_path TEXT NOT NULL,
168
- openapi_spec TEXT,
169
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
170
- base_dir TEXT
171
- );
172
-
173
- CREATE TABLE IF NOT EXISTS settings (
174
- key TEXT PRIMARY KEY,
175
- value TEXT NOT NULL
176
- );
177
-
178
- CREATE INDEX IF NOT EXISTS idx_runs_started ON runs(started_at DESC);
179
- CREATE INDEX IF NOT EXISTS idx_runs_collection ON runs(collection_id);
180
- CREATE INDEX IF NOT EXISTS idx_runs_session ON runs(session_id, started_at DESC);
181
- CREATE INDEX IF NOT EXISTS idx_results_run ON results(run_id);
182
- CREATE INDEX IF NOT EXISTS idx_results_status ON results(status);
183
- CREATE INDEX IF NOT EXISTS idx_results_name ON results(suite_name, test_name);
184
- CREATE INDEX IF NOT EXISTS idx_collections_name ON collections(name);
185
-
186
- CREATE TABLE IF NOT EXISTS lint_runs (
187
- id INTEGER PRIMARY KEY AUTOINCREMENT,
188
- spec_path TEXT NOT NULL,
189
- started_at TEXT NOT NULL,
190
- finished_at TEXT,
191
- total INTEGER NOT NULL DEFAULT 0,
192
- high_count INTEGER NOT NULL DEFAULT 0,
193
- medium_count INTEGER NOT NULL DEFAULT 0,
194
- low_count INTEGER NOT NULL DEFAULT 0,
195
- endpoint_count INTEGER NOT NULL DEFAULT 0,
196
- config_json TEXT,
197
- issues_json TEXT
198
- );
199
-
200
- CREATE INDEX IF NOT EXISTS idx_lint_runs_spec ON lint_runs(spec_path, started_at DESC);
201
- `;
202
-
203
- function runMigrations(db: Database): void {
204
- const ver = (db.query("PRAGMA user_version").get() as { user_version: number }).user_version;
205
- if (ver >= SCHEMA_VERSION) return;
206
-
207
- db.transaction(() => {
208
- if (ver === 0) {
209
- // Fresh database — create all tables
210
- db.exec(SCHEMA);
211
- }
212
- if (ver >= 1 && ver < 2) {
213
- // Migration v1→v2: add suite_file column to results
214
- db.exec("ALTER TABLE results ADD COLUMN suite_file TEXT");
215
- }
216
- if (ver >= 2 && ver < 3) {
217
- // Migration v2→v3: add provenance column (test source metadata)
218
- db.exec("ALTER TABLE results ADD COLUMN provenance TEXT");
219
- }
220
- if (ver >= 3 && ver < 4) {
221
- // Migration v3→v4: add failure classification columns
222
- db.exec("ALTER TABLE results ADD COLUMN failure_class TEXT");
223
- db.exec("ALTER TABLE results ADD COLUMN failure_class_reason TEXT");
224
- }
225
- if (ver >= 4 && ver < 5) {
226
- // Migration v4→v5: add spec_pointer + spec_excerpt (frozen OpenAPI evidence)
227
- db.exec("ALTER TABLE results ADD COLUMN spec_pointer TEXT");
228
- db.exec("ALTER TABLE results ADD COLUMN spec_excerpt TEXT");
229
- }
230
- if (ver >= 5 && ver < 6) {
231
- // Migration v5→v6: add lint_runs table for `zond lint-spec` history.
232
- db.exec(`
233
- CREATE TABLE IF NOT EXISTS lint_runs (
234
- id INTEGER PRIMARY KEY AUTOINCREMENT,
235
- spec_path TEXT NOT NULL,
236
- started_at TEXT NOT NULL,
237
- finished_at TEXT,
238
- total INTEGER NOT NULL DEFAULT 0,
239
- high_count INTEGER NOT NULL DEFAULT 0,
240
- medium_count INTEGER NOT NULL DEFAULT 0,
241
- low_count INTEGER NOT NULL DEFAULT 0,
242
- endpoint_count INTEGER NOT NULL DEFAULT 0,
243
- config_json TEXT,
244
- issues_json TEXT
245
- );
246
- CREATE INDEX IF NOT EXISTS idx_lint_runs_spec ON lint_runs(spec_path, started_at DESC);
247
- `);
248
- }
249
- if (ver >= 6 && ver < 7) {
250
- // Migration v6→v7: add session_id column to runs for grouping CLI invocations
251
- // (e.g. `zond hunt`, scripted post-init runs) into one campaign.
252
- db.exec("ALTER TABLE runs ADD COLUMN session_id TEXT");
253
- db.exec("CREATE INDEX IF NOT EXISTS idx_runs_session ON runs(session_id, started_at DESC)");
254
- }
255
- if (ver >= 7 && ver < 8) {
256
- // Migration v7→v8: drop the unused AI/chat tables. They were a legacy
257
- // experiment (in-app chat-driven YAML generation) that never shipped a
258
- // user-facing surface and have no consumers in the codebase.
259
- db.exec("DROP TABLE IF EXISTS chat_messages");
260
- db.exec("DROP TABLE IF EXISTS chat_sessions");
261
- db.exec("DROP TABLE IF EXISTS ai_generations");
262
- }
263
- if (ver >= 8 && ver < 9) {
264
- // Migration v8→v9: tags column on runs (JSON array of strings — union
265
- // of suite-level tags actually executed in the run, plus any explicit
266
- // --tag filters). Powers `coverage --union tag:<name>` (TASK-274).
267
- db.exec("ALTER TABLE runs ADD COLUMN tags TEXT");
268
- }
269
- if (ver >= 9 && ver < 10) {
270
- // Migration v9→v10 (ARV-55): classify each historical run by suite
271
- // kind so coverage's default query becomes a column compare. The
272
- // CHECK constraint can't be added retroactively without a table
273
- // rebuild — accept the looser column for legacy rows; new INSERTs
274
- // go through `createRun()` which only emits known kinds.
275
- db.exec("ALTER TABLE runs ADD COLUMN run_kind TEXT NOT NULL DEFAULT 'regular'");
276
- // Backfill: derive kind per existing run from its stored results.
277
- // `every` semantics mirror the runtime `detectRunKind` helper —
278
- // pure-probe / pure-check vs anything else.
279
- db.exec(`
280
- UPDATE runs SET run_kind = 'probe'
281
- WHERE id IN (
282
- SELECT r.id FROM runs r
283
- WHERE EXISTS (SELECT 1 FROM results WHERE run_id = r.id AND suite_file IS NOT NULL AND suite_file LIKE '%probes/%')
284
- AND NOT EXISTS (SELECT 1 FROM results WHERE run_id = r.id AND suite_file IS NOT NULL AND suite_file NOT LIKE '%probes/%')
285
- )
286
- `);
287
- db.exec(`
288
- UPDATE runs SET run_kind = 'check'
289
- WHERE id IN (
290
- SELECT r.id FROM runs r
291
- WHERE EXISTS (SELECT 1 FROM results WHERE run_id = r.id AND suite_file IS NOT NULL AND suite_file LIKE '%checks/%')
292
- AND NOT EXISTS (SELECT 1 FROM results WHERE run_id = r.id AND suite_file IS NOT NULL AND suite_file NOT LIKE '%checks/%')
293
- )
294
- `);
295
- }
296
- db.exec(`PRAGMA user_version = ${SCHEMA_VERSION}`);
297
- })();
298
- }