ccqa 1.51.1 → 1.52.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.
@@ -0,0 +1,1376 @@
1
+ import { z } from "zod";
2
+
3
+ //#region src/hub/contract/schema.d.ts
4
+ /**
5
+ * The hub's public REST contract (docs/hub-api.md). These schemas are
6
+ * consumed on both sides of the wire: the hub validates request/response
7
+ * bodies against them, and `ccqa/hub-client` re-exports them so any HTTP
8
+ * client — the ccqa CLI, an intranet web app, the hub's own bundled UI —
9
+ * gets the same types.
10
+ */
11
+ /**
12
+ * A run's outcome. "running" is non-terminal/mutable — an opened run
13
+ * (`POST /runs/open`) sits in this state while it's patched incrementally.
14
+ * "passed"/"failed" are terminal/immutable: a pushed run (`POST /runs`)
15
+ * starts there directly, and an opened run ends there once done.
16
+ */
17
+ declare const RunStatusSchema: z.ZodEnum<{
18
+ passed: "passed";
19
+ failed: "failed";
20
+ running: "running";
21
+ }>;
22
+ type RunStatus = z.infer<typeof RunStatusSchema>;
23
+ /**
24
+ * A pushed run. All fields are derived server-side from the report the client
25
+ * pushed (`POST /runs`) — the run is immutable once created.
26
+ */
27
+ declare const RunSchema: z.ZodObject<{
28
+ id: z.ZodString;
29
+ project: z.ZodString;
30
+ profile: z.ZodNullable<z.ZodString>;
31
+ branch: z.ZodNullable<z.ZodString>;
32
+ status: z.ZodEnum<{
33
+ passed: "passed";
34
+ failed: "failed";
35
+ running: "running";
36
+ }>;
37
+ kind: z.ZodDefault<z.ZodEnum<{
38
+ run: "run";
39
+ drift: "drift";
40
+ record: "record";
41
+ }>>;
42
+ drift: z.ZodDefault<z.ZodNullable<z.ZodObject<{
43
+ specs: z.ZodNumber;
44
+ testDrift: z.ZodNumber;
45
+ specChange: z.ZodNumber;
46
+ productBug: z.ZodDefault<z.ZodNumber>;
47
+ environment: z.ZodDefault<z.ZodNumber>;
48
+ unknown: z.ZodNumber;
49
+ }, z.core.$strip>>>;
50
+ gradedDrift: z.ZodOptional<z.ZodObject<{
51
+ specs: z.ZodNumber;
52
+ testDrift: z.ZodNumber;
53
+ specChange: z.ZodNumber;
54
+ productBug: z.ZodDefault<z.ZodNumber>;
55
+ environment: z.ZodDefault<z.ZodNumber>;
56
+ unknown: z.ZodNumber;
57
+ noDrift: z.ZodNumber;
58
+ graded: z.ZodNumber;
59
+ }, z.core.$strip>>;
60
+ specs: z.ZodObject<{
61
+ total: z.ZodNumber;
62
+ passed: z.ZodNumber;
63
+ failed: z.ZodNumber;
64
+ }, z.core.$strip>;
65
+ gitHead: z.ZodNullable<z.ZodString>;
66
+ promptVersion: z.ZodString;
67
+ costUsd: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
68
+ ciRunId: z.ZodNullable<z.ZodString>;
69
+ runUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
70
+ reportCreatedAt: z.ZodString;
71
+ createdAt: z.ZodString;
72
+ deployedSha: z.ZodOptional<z.ZodNullable<z.ZodString>>;
73
+ deployedShaSource: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
74
+ "hub-deploy-log": "hub-deploy-log";
75
+ client: "client";
76
+ }>>>;
77
+ deployedShaAmbiguous: z.ZodOptional<z.ZodBoolean>;
78
+ }, z.core.$strip>;
79
+ type Run = z.infer<typeof RunSchema>;
80
+ /**
81
+ * One failing spec's triage: the AI's prediction (read-only, sourced from
82
+ * the run's report) paired with the human-recorded actual cause (write-only
83
+ * from the client's perspective — the API is how it gets in).
84
+ */
85
+ declare const TriageCaseSchema: z.ZodObject<{
86
+ feature: z.ZodString;
87
+ spec: z.ZodString;
88
+ target: z.ZodOptional<z.ZodString>;
89
+ predicted: z.ZodObject<{
90
+ label: z.ZodEnum<{
91
+ TEST_DRIFT: "TEST_DRIFT";
92
+ SPEC_CHANGE: "SPEC_CHANGE";
93
+ PRODUCT_BUG: "PRODUCT_BUG";
94
+ ENVIRONMENT: "ENVIRONMENT";
95
+ UNKNOWN: "UNKNOWN";
96
+ }>;
97
+ confidence: z.ZodNumber;
98
+ subDiagnosis: z.ZodOptional<z.ZodString>;
99
+ headline: z.ZodString;
100
+ }, z.core.$strip>;
101
+ actual: z.ZodNullable<z.ZodObject<{
102
+ cause: z.ZodEnum<{
103
+ TEST_DRIFT: "TEST_DRIFT";
104
+ SPEC_CHANGE: "SPEC_CHANGE";
105
+ PRODUCT_BUG: "PRODUCT_BUG";
106
+ ENVIRONMENT: "ENVIRONMENT";
107
+ NO_DRIFT: "NO_DRIFT";
108
+ }>;
109
+ note: z.ZodOptional<z.ZodString>;
110
+ recordedAt: z.ZodString;
111
+ invalidForKind: z.ZodOptional<z.ZodBoolean>;
112
+ }, z.core.$strip>>;
113
+ }, z.core.$strip>;
114
+ type TriageCase = z.infer<typeof TriageCaseSchema>;
115
+ declare const RunTriageSchema: z.ZodObject<{
116
+ runId: z.ZodString;
117
+ promptVersion: z.ZodString;
118
+ cases: z.ZodArray<z.ZodObject<{
119
+ feature: z.ZodString;
120
+ spec: z.ZodString;
121
+ target: z.ZodOptional<z.ZodString>;
122
+ predicted: z.ZodObject<{
123
+ label: z.ZodEnum<{
124
+ TEST_DRIFT: "TEST_DRIFT";
125
+ SPEC_CHANGE: "SPEC_CHANGE";
126
+ PRODUCT_BUG: "PRODUCT_BUG";
127
+ ENVIRONMENT: "ENVIRONMENT";
128
+ UNKNOWN: "UNKNOWN";
129
+ }>;
130
+ confidence: z.ZodNumber;
131
+ subDiagnosis: z.ZodOptional<z.ZodString>;
132
+ headline: z.ZodString;
133
+ }, z.core.$strip>;
134
+ actual: z.ZodNullable<z.ZodObject<{
135
+ cause: z.ZodEnum<{
136
+ TEST_DRIFT: "TEST_DRIFT";
137
+ SPEC_CHANGE: "SPEC_CHANGE";
138
+ PRODUCT_BUG: "PRODUCT_BUG";
139
+ ENVIRONMENT: "ENVIRONMENT";
140
+ NO_DRIFT: "NO_DRIFT";
141
+ }>;
142
+ note: z.ZodOptional<z.ZodString>;
143
+ recordedAt: z.ZodString;
144
+ invalidForKind: z.ZodOptional<z.ZodBoolean>;
145
+ }, z.core.$strip>>;
146
+ }, z.core.$strip>>;
147
+ recorded: z.ZodNumber;
148
+ recordedInvalidForKind: z.ZodNumber;
149
+ total: z.ZodNumber;
150
+ }, z.core.$strip>;
151
+ type RunTriage = z.infer<typeof RunTriageSchema>;
152
+ declare const PutActualCauseRequestSchema: z.ZodObject<{
153
+ cause: z.ZodEnum<{
154
+ TEST_DRIFT: "TEST_DRIFT";
155
+ SPEC_CHANGE: "SPEC_CHANGE";
156
+ PRODUCT_BUG: "PRODUCT_BUG";
157
+ ENVIRONMENT: "ENVIRONMENT";
158
+ NO_DRIFT: "NO_DRIFT";
159
+ }>;
160
+ note: z.ZodOptional<z.ZodString>;
161
+ }, z.core.$strip>;
162
+ type PutActualCauseRequest = z.infer<typeof PutActualCauseRequestSchema>;
163
+ /** Response of `PUT /runs/:id/triage/actual-causes`. */
164
+ declare const ImportActualCausesResponseSchema: z.ZodObject<{
165
+ imported: z.ZodNumber;
166
+ rejected: z.ZodArray<z.ZodObject<{
167
+ feature: z.ZodString;
168
+ spec: z.ZodString;
169
+ reason: z.ZodString;
170
+ }, z.core.$strip>>;
171
+ }, z.core.$strip>;
172
+ type ImportActualCausesResponse = z.infer<typeof ImportActualCausesResponseSchema>;
173
+ /**
174
+ * One spec's "last time it passed" record in the last-green ledger. The hub
175
+ * updates the ledger whenever a `kind: "run"` run reaches a terminal state:
176
+ * every spec that passed gets its entry advanced to that run's `gitHead`
177
+ * (newest `at` wins, so out-of-order finalizes can't move a baseline
178
+ * backwards). `ccqa run --on-fail-explain` reads it to diff each
179
+ * failing spec against the commit where that spec was last green.
180
+ */
181
+ declare const LastGreenEntrySchema: z.ZodObject<{
182
+ gitHead: z.ZodString;
183
+ runId: z.ZodString;
184
+ at: z.ZodString;
185
+ }, z.core.$strip>;
186
+ type LastGreenEntry = z.infer<typeof LastGreenEntrySchema>;
187
+ /** One deploy, as the consumer's deploy job reported it (ADR-0010). */
188
+ declare const DeployEntrySchema: z.ZodObject<{
189
+ index: z.ZodNumber;
190
+ sha: z.ZodString;
191
+ previousSha: z.ZodNullable<z.ZodString>;
192
+ at: z.ZodString;
193
+ ref: z.ZodOptional<z.ZodString>;
194
+ runUrl: z.ZodOptional<z.ZodString>;
195
+ changedPaths: z.ZodNullable<z.ZodArray<z.ZodString>>;
196
+ hasSelection: z.ZodDefault<z.ZodBoolean>;
197
+ gapBefore: z.ZodDefault<z.ZodBoolean>;
198
+ }, z.core.$strip>;
199
+ type DeployEntry = z.infer<typeof DeployEntrySchema>;
200
+ /** Body of `POST /projects/:project/locks?profile=`. */
201
+ declare const AcquireLocksRequestSchema: z.ZodObject<{
202
+ specs: z.ZodArray<z.ZodString>;
203
+ kind: z.ZodEnum<{
204
+ run: "run";
205
+ audit: "audit";
206
+ }>;
207
+ holder: z.ZodString;
208
+ ttlSeconds: z.ZodNumber;
209
+ }, z.core.$strip>;
210
+ type AcquireLocksRequest = z.infer<typeof AcquireLocksRequestSchema>;
211
+ /**
212
+ * Which specs the caller may work on. `denied` is not an error: another job got
213
+ * there first, and skipping those is the whole point.
214
+ */
215
+ declare const AcquireLocksResponseSchema: z.ZodObject<{
216
+ granted: z.ZodArray<z.ZodString>;
217
+ denied: z.ZodArray<z.ZodString>;
218
+ }, z.core.$strip>;
219
+ type AcquireLocksResponse = z.infer<typeof AcquireLocksResponseSchema>;
220
+ /** Answer of PUT (the attestation as stamped) and GET (the whole document). */
221
+ declare const AttestationResponseSchema: z.ZodObject<{
222
+ project: z.ZodString;
223
+ profile: z.ZodString;
224
+ spec: z.ZodString;
225
+ attestation: z.ZodObject<{
226
+ by: z.ZodString;
227
+ at: z.ZodString;
228
+ note: z.ZodOptional<z.ZodString>;
229
+ deployedSha: z.ZodNullable<z.ZodString>;
230
+ }, z.core.$strip>;
231
+ }, z.core.$strip>;
232
+ type AttestationResponse = z.infer<typeof AttestationResponseSchema>;
233
+ declare const AttestationsResponseSchema: z.ZodObject<{
234
+ project: z.ZodString;
235
+ profile: z.ZodString;
236
+ specs: z.ZodRecord<z.ZodString, z.ZodObject<{
237
+ by: z.ZodString;
238
+ at: z.ZodString;
239
+ note: z.ZodOptional<z.ZodString>;
240
+ deployedSha: z.ZodNullable<z.ZodString>;
241
+ }, z.core.$strip>>;
242
+ }, z.core.$strip>;
243
+ type AttestationsResponse = z.infer<typeof AttestationsResponseSchema>;
244
+ declare const AuditDismissalResponseSchema: z.ZodObject<{
245
+ project: z.ZodString;
246
+ spec: z.ZodString;
247
+ dismissal: z.ZodObject<{
248
+ by: z.ZodString;
249
+ at: z.ZodString;
250
+ note: z.ZodString;
251
+ auditRunId: z.ZodString;
252
+ label: z.ZodEnum<{
253
+ TEST_DRIFT: "TEST_DRIFT";
254
+ SPEC_CHANGE: "SPEC_CHANGE";
255
+ PRODUCT_BUG: "PRODUCT_BUG";
256
+ ENVIRONMENT: "ENVIRONMENT";
257
+ UNKNOWN: "UNKNOWN";
258
+ }>;
259
+ headline: z.ZodString;
260
+ }, z.core.$strip>;
261
+ }, z.core.$strip>;
262
+ type AuditDismissalResponse = z.infer<typeof AuditDismissalResponseSchema>;
263
+ declare const AuditDismissalsResponseSchema: z.ZodObject<{
264
+ project: z.ZodString;
265
+ specs: z.ZodRecord<z.ZodString, z.ZodObject<{
266
+ by: z.ZodString;
267
+ at: z.ZodString;
268
+ note: z.ZodString;
269
+ auditRunId: z.ZodString;
270
+ label: z.ZodEnum<{
271
+ TEST_DRIFT: "TEST_DRIFT";
272
+ SPEC_CHANGE: "SPEC_CHANGE";
273
+ PRODUCT_BUG: "PRODUCT_BUG";
274
+ ENVIRONMENT: "ENVIRONMENT";
275
+ UNKNOWN: "UNKNOWN";
276
+ }>;
277
+ headline: z.ZodString;
278
+ }, z.core.$strip>>;
279
+ }, z.core.$strip>;
280
+ type AuditDismissalsResponse = z.infer<typeof AuditDismissalsResponseSchema>;
281
+ /** Body of `GET /projects/:project/audit-needed?profile=`: one answer per spec. */
282
+ declare const AuditNeedReportSchema: z.ZodObject<{
283
+ project: z.ZodString;
284
+ profile: z.ZodString;
285
+ specs: z.ZodRecord<z.ZodString, z.ZodObject<{
286
+ because: z.ZodEnum<{
287
+ deployReached: "deployReached";
288
+ neverAudited: "neverAudited";
289
+ cannotTell: "cannotTell";
290
+ held: "held";
291
+ current: "current";
292
+ }>;
293
+ reason: z.ZodOptional<z.ZodEnum<{
294
+ noSelectionInRange: "noSelectionInRange";
295
+ selectionUnknown: "selectionUnknown";
296
+ noDeployLog: "noDeployLog";
297
+ unknownDeployedSha: "unknownDeployedSha";
298
+ ambiguousDeployedSha: "ambiguousDeployedSha";
299
+ deployedShaNotInLog: "deployedShaNotInLog";
300
+ gapInRange: "gapInRange";
301
+ }>>;
302
+ }, z.core.$strip>>;
303
+ }, z.core.$strip>;
304
+ type AuditNeedReport = z.infer<typeof AuditNeedReportSchema>;
305
+ /** Body of `GET /projects/:project/rerun?profile=`: one verdict per spec in the perspectives document. */
306
+ declare const RerunReportSchema: z.ZodObject<{
307
+ project: z.ZodString;
308
+ profile: z.ZodString;
309
+ deployHead: z.ZodNullable<z.ZodObject<{
310
+ index: z.ZodNumber;
311
+ sha: z.ZodString;
312
+ at: z.ZodString;
313
+ }, z.core.$strip>>;
314
+ specs: z.ZodRecord<z.ZodString, z.ZodObject<{
315
+ verdict: z.ZodEnum<{
316
+ inProgress: "inProgress";
317
+ needsRepair: "needsRepair";
318
+ rerunNeeded: "rerunNeeded";
319
+ verified: "verified";
320
+ manuallyVerified: "manuallyVerified";
321
+ }>;
322
+ audit: z.ZodEnum<{
323
+ due: "due";
324
+ clean: "clean";
325
+ drifted: "drifted";
326
+ undecided: "undecided";
327
+ }>;
328
+ execution: z.ZodEnum<{
329
+ passed: "passed";
330
+ failed: "failed";
331
+ stale: "stale";
332
+ neverRun: "neverRun";
333
+ }>;
334
+ driftLabel: z.ZodOptional<z.ZodEnum<{
335
+ TEST_DRIFT: "TEST_DRIFT";
336
+ SPEC_CHANGE: "SPEC_CHANGE";
337
+ }>>;
338
+ auditAssumedReached: z.ZodOptional<z.ZodEnum<{
339
+ noSelectionInRange: "noSelectionInRange";
340
+ selectionUnknown: "selectionUnknown";
341
+ noDeployLog: "noDeployLog";
342
+ unknownDeployedSha: "unknownDeployedSha";
343
+ ambiguousDeployedSha: "ambiguousDeployedSha";
344
+ deployedShaNotInLog: "deployedShaNotInLog";
345
+ gapInRange: "gapInRange";
346
+ }>>;
347
+ auditDismissed: z.ZodOptional<z.ZodObject<{
348
+ by: z.ZodString;
349
+ at: z.ZodString;
350
+ note: z.ZodString;
351
+ auditRunId: z.ZodString;
352
+ label: z.ZodEnum<{
353
+ TEST_DRIFT: "TEST_DRIFT";
354
+ SPEC_CHANGE: "SPEC_CHANGE";
355
+ PRODUCT_BUG: "PRODUCT_BUG";
356
+ ENVIRONMENT: "ENVIRONMENT";
357
+ UNKNOWN: "UNKNOWN";
358
+ }>;
359
+ headline: z.ZodString;
360
+ }, z.core.$strip>>;
361
+ auditDismissalApplied: z.ZodOptional<z.ZodBoolean>;
362
+ executionAssumedReached: z.ZodOptional<z.ZodEnum<{
363
+ noSelectionInRange: "noSelectionInRange";
364
+ selectionUnknown: "selectionUnknown";
365
+ noDeployLog: "noDeployLog";
366
+ unknownDeployedSha: "unknownDeployedSha";
367
+ ambiguousDeployedSha: "ambiguousDeployedSha";
368
+ deployedShaNotInLog: "deployedShaNotInLog";
369
+ gapInRange: "gapInRange";
370
+ }>>;
371
+ specChangedSince: z.ZodOptional<z.ZodString>;
372
+ manual: z.ZodOptional<z.ZodObject<{
373
+ by: z.ZodString;
374
+ at: z.ZodString;
375
+ note: z.ZodOptional<z.ZodString>;
376
+ deployedSha: z.ZodNullable<z.ZodString>;
377
+ }, z.core.$strip>>;
378
+ manualLapsed: z.ZodOptional<z.ZodObject<{
379
+ by: z.ZodString;
380
+ at: z.ZodString;
381
+ note: z.ZodOptional<z.ZodString>;
382
+ deployedSha: z.ZodNullable<z.ZodString>;
383
+ because: z.ZodEnum<{
384
+ deployReached: "deployReached";
385
+ cannotPlace: "cannotPlace";
386
+ specEdited: "specEdited";
387
+ newerRed: "newerRed";
388
+ }>;
389
+ }, z.core.$strip>>;
390
+ manualLapsedByDeploy: z.ZodOptional<z.ZodNullable<z.ZodObject<{
391
+ index: z.ZodNumber;
392
+ sha: z.ZodString;
393
+ at: z.ZodString;
394
+ }, z.core.$strip>>>;
395
+ manualLapsedReason: z.ZodOptional<z.ZodEnum<{
396
+ noSelectionInRange: "noSelectionInRange";
397
+ selectionUnknown: "selectionUnknown";
398
+ noDeployLog: "noDeployLog";
399
+ unknownDeployedSha: "unknownDeployedSha";
400
+ ambiguousDeployedSha: "ambiguousDeployedSha";
401
+ deployedShaNotInLog: "deployedShaNotInLog";
402
+ gapInRange: "gapInRange";
403
+ }>>;
404
+ heldBy: z.ZodNullable<z.ZodObject<{
405
+ kind: z.ZodEnum<{
406
+ run: "run";
407
+ audit: "audit";
408
+ }>;
409
+ holder: z.ZodString;
410
+ expiresAt: z.ZodString;
411
+ }, z.core.$strip>>;
412
+ lastRun: z.ZodNullable<z.ZodObject<{
413
+ gitHead: z.ZodString;
414
+ runId: z.ZodString;
415
+ at: z.ZodString;
416
+ deployedSha: z.ZodOptional<z.ZodNullable<z.ZodString>>;
417
+ deployedShaAmbiguous: z.ZodOptional<z.ZodBoolean>;
418
+ }, z.core.$strip>>;
419
+ lastGreen: z.ZodNullable<z.ZodObject<{
420
+ gitHead: z.ZodString;
421
+ runId: z.ZodString;
422
+ at: z.ZodString;
423
+ deployedSha: z.ZodOptional<z.ZodNullable<z.ZodString>>;
424
+ deployedShaAmbiguous: z.ZodOptional<z.ZodBoolean>;
425
+ }, z.core.$strip>>;
426
+ lastRed: z.ZodNullable<z.ZodObject<{
427
+ gitHead: z.ZodString;
428
+ runId: z.ZodString;
429
+ at: z.ZodString;
430
+ deployedSha: z.ZodOptional<z.ZodNullable<z.ZodString>>;
431
+ deployedShaAmbiguous: z.ZodOptional<z.ZodBoolean>;
432
+ label: z.ZodOptional<z.ZodEnum<{
433
+ TEST_DRIFT: "TEST_DRIFT";
434
+ SPEC_CHANGE: "SPEC_CHANGE";
435
+ PRODUCT_BUG: "PRODUCT_BUG";
436
+ ENVIRONMENT: "ENVIRONMENT";
437
+ UNKNOWN: "UNKNOWN";
438
+ }>>;
439
+ headline: z.ZodOptional<z.ZodString>;
440
+ }, z.core.$strip>>;
441
+ touchedBy: z.ZodOptional<z.ZodArray<z.ZodString>>;
442
+ touchedByDeploy: z.ZodOptional<z.ZodNullable<z.ZodObject<{
443
+ index: z.ZodNumber;
444
+ sha: z.ZodString;
445
+ at: z.ZodString;
446
+ }, z.core.$strip>>>;
447
+ }, z.core.$strip>>;
448
+ }, z.core.$strip>;
449
+ type RerunReport = z.infer<typeof RerunReportSchema>;
450
+ /** Body of `POST /projects/:project/deploys?profile=` — what the deploy job shipped. */
451
+ declare const RecordDeployRequestSchema: z.ZodObject<{
452
+ sha: z.ZodString;
453
+ previousSha: z.ZodOptional<z.ZodNullable<z.ZodString>>;
454
+ changedPaths: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
455
+ selection: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
456
+ verdict: z.ZodEnum<{
457
+ unknown: "unknown";
458
+ needed: "needed";
459
+ notNeeded: "notNeeded";
460
+ }>;
461
+ reason: z.ZodString;
462
+ touchedBy: z.ZodOptional<z.ZodArray<z.ZodString>>;
463
+ }, z.core.$strip>>>;
464
+ ref: z.ZodOptional<z.ZodString>;
465
+ runUrl: z.ZodOptional<z.ZodString>;
466
+ }, z.core.$strip>;
467
+ type RecordDeployRequest = z.infer<typeof RecordDeployRequestSchema>;
468
+ /** Body of `GET /projects/:project/deploys?profile=` — newest last, as stored. */
469
+ declare const DeployLogResponseSchema: z.ZodObject<{
470
+ entries: z.ZodArray<z.ZodObject<{
471
+ index: z.ZodNumber;
472
+ sha: z.ZodString;
473
+ previousSha: z.ZodNullable<z.ZodString>;
474
+ at: z.ZodString;
475
+ ref: z.ZodOptional<z.ZodString>;
476
+ runUrl: z.ZodOptional<z.ZodString>;
477
+ changedPaths: z.ZodNullable<z.ZodArray<z.ZodString>>;
478
+ hasSelection: z.ZodDefault<z.ZodBoolean>;
479
+ gapBefore: z.ZodDefault<z.ZodBoolean>;
480
+ }, z.core.$strip>>;
481
+ nextIndex: z.ZodNumber;
482
+ }, z.core.$strip>;
483
+ type DeployLogResponse = z.infer<typeof DeployLogResponseSchema>;
484
+ /**
485
+ * Body of `GET /projects/:project/drift`. No `?profile=` — see `SpecDriftEntrySchema`.
486
+ */
487
+ declare const DriftLedgerResponseSchema: z.ZodObject<{
488
+ project: z.ZodString;
489
+ specs: z.ZodRecord<z.ZodString, z.ZodObject<{
490
+ label: z.ZodNullable<z.ZodEnum<{
491
+ TEST_DRIFT: "TEST_DRIFT";
492
+ SPEC_CHANGE: "SPEC_CHANGE";
493
+ PRODUCT_BUG: "PRODUCT_BUG";
494
+ ENVIRONMENT: "ENVIRONMENT";
495
+ UNKNOWN: "UNKNOWN";
496
+ }>>;
497
+ surface: z.ZodOptional<z.ZodEnum<{
498
+ spec: "spec";
499
+ generated: "generated";
500
+ }>>;
501
+ subDiagnosis: z.ZodOptional<z.ZodEnum<{
502
+ OVER_ASSERTION: "OVER_ASSERTION";
503
+ SELECTOR_DRIFT: "SELECTOR_DRIFT";
504
+ NONE: "NONE";
505
+ }>>;
506
+ specChangeKind: z.ZodOptional<z.ZodEnum<{
507
+ FEATURE_REMOVED: "FEATURE_REMOVED";
508
+ BEHAVIOUR_CHANGED: "BEHAVIOUR_CHANGED";
509
+ }>>;
510
+ confidence: z.ZodOptional<z.ZodNumber>;
511
+ headline: z.ZodOptional<z.ZodString>;
512
+ gitHead: z.ZodString;
513
+ runId: z.ZodString;
514
+ at: z.ZodString;
515
+ graded: z.ZodOptional<z.ZodBoolean>;
516
+ }, z.core.$strip>>;
517
+ }, z.core.$strip>;
518
+ type DriftLedgerResponse = z.infer<typeof DriftLedgerResponseSchema>;
519
+ /**
520
+ * What one batch of ccqa invocations spent on Claude, as the job that ran them
521
+ * reported it (see `SpendStore`). `label` is the consumer's name for the batch
522
+ * — its job name — and the only thing that says where the money went.
523
+ */
524
+ declare const SpendEntrySchema: z.ZodObject<{
525
+ id: z.ZodString;
526
+ at: z.ZodString;
527
+ costUsd: z.ZodNumber;
528
+ label: z.ZodString;
529
+ ciRunId: z.ZodOptional<z.ZodString>;
530
+ runUrl: z.ZodOptional<z.ZodString>;
531
+ }, z.core.$strip>;
532
+ type SpendEntry = z.infer<typeof SpendEntrySchema>;
533
+ /** Body of `POST /projects/:project/spend` — one batch's total. `at` defaults to now. */
534
+ declare const RecordSpendRequestSchema: z.ZodObject<{
535
+ costUsd: z.ZodNumber;
536
+ label: z.ZodString;
537
+ at: z.ZodOptional<z.ZodString>;
538
+ ciRunId: z.ZodOptional<z.ZodString>;
539
+ runUrl: z.ZodOptional<z.ZodString>;
540
+ }, z.core.$strip>;
541
+ type RecordSpendRequest = z.infer<typeof RecordSpendRequestSchema>;
542
+ /**
543
+ * Body of `GET /projects/:project/spend?since=&until=`, newest first. `since`
544
+ * and `until` echo the window that was asked for (null for an open end), so a
545
+ * reader of `totalUsd` can tell what it totals.
546
+ */
547
+ declare const SpendLogResponseSchema: z.ZodObject<{
548
+ project: z.ZodString;
549
+ since: z.ZodNullable<z.ZodString>;
550
+ until: z.ZodNullable<z.ZodString>;
551
+ totalUsd: z.ZodNumber;
552
+ entries: z.ZodArray<z.ZodObject<{
553
+ id: z.ZodString;
554
+ at: z.ZodString;
555
+ costUsd: z.ZodNumber;
556
+ label: z.ZodString;
557
+ ciRunId: z.ZodOptional<z.ZodString>;
558
+ runUrl: z.ZodOptional<z.ZodString>;
559
+ }, z.core.$strip>>;
560
+ }, z.core.$strip>;
561
+ type SpendLogResponse = z.infer<typeof SpendLogResponseSchema>;
562
+ declare const CoverageEdgesDocSchema: z.ZodObject<{
563
+ specs: z.ZodRecord<z.ZodString, z.ZodObject<{
564
+ files: z.ZodArray<z.ZodString>;
565
+ measuredAt: z.ZodNumber;
566
+ runId: z.ZodOptional<z.ZodString>;
567
+ }, z.core.$strip>>;
568
+ }, z.core.$strip>;
569
+ type CoverageEdgesDoc = z.infer<typeof CoverageEdgesDocSchema>;
570
+ /**
571
+ * Body of `PUT /projects/:project/coverage-edges` — the specs one run
572
+ * measured. Merged into the stored document, never replacing other specs'
573
+ * entries; an empty file set is not a measurement and is rejected per entry.
574
+ */
575
+ declare const CoverageEdgesUpsertSchema: z.ZodObject<{
576
+ specs: z.ZodRecord<z.ZodString, z.ZodObject<{
577
+ files: z.ZodArray<z.ZodString>;
578
+ runId: z.ZodOptional<z.ZodString>;
579
+ }, z.core.$strip>>;
580
+ }, z.core.$strip>;
581
+ type CoverageEdgesUpsert = z.infer<typeof CoverageEdgesUpsertSchema>;
582
+ //#endregion
583
+ //#region src/coverage/resolve-stream.d.ts
584
+ /**
585
+ * What one run's slice of the stream resolves to. The shape is the read-out
586
+ * API of `CoverageResolver` written down: what the coverage page needs to
587
+ * draw, and nothing the stream cannot support.
588
+ */
589
+ declare const ResolvedCoverageSchema: z.ZodObject<{
590
+ runId: z.ZodString;
591
+ hubRunId: z.ZodOptional<z.ZodString>;
592
+ asOf: z.ZodNumber;
593
+ lastSeq: z.ZodNumber;
594
+ universe: z.ZodOptional<z.ZodObject<{
595
+ include: z.ZodArray<z.ZodString>;
596
+ files: z.ZodArray<z.ZodString>;
597
+ }, z.core.$strip>>;
598
+ specs: z.ZodArray<z.ZodObject<{
599
+ specId: z.ZodString;
600
+ files: z.ZodArray<z.ZodString>;
601
+ actorEvents: z.ZodRecord<z.ZodString, z.ZodNumber>;
602
+ }, z.core.$strip>>;
603
+ boot: z.ZodArray<z.ZodString>;
604
+ health: z.ZodObject<{
605
+ heardFromApplication: z.ZodBoolean;
606
+ pushesDuringRun: z.ZodNumber;
607
+ attributedSpecs: z.ZodNumber;
608
+ rejectedPushes: z.ZodNumber;
609
+ uninstrumentedFiles: z.ZodNumber;
610
+ uninstrumentedProcesses: z.ZodNumber;
611
+ droppedPushes: z.ZodNumber;
612
+ unmappedActorEvents: z.ZodNumber;
613
+ outsideWindowEvents: z.ZodRecord<z.ZodString, z.ZodNumber>;
614
+ specsMeasured: z.ZodNumber;
615
+ }, z.core.$strip>;
616
+ }, z.core.$strip>;
617
+ type ResolvedCoverage = z.infer<typeof ResolvedCoverageSchema>;
618
+ //#endregion
619
+ //#region src/prompts/prompt-names.d.ts
620
+ /**
621
+ * The fixed set of prompt assets the hub stores per project/profile, and which
622
+ * each is fetched at run time by the CLI. Kept as a tiny, dependency-free
623
+ * module so both the hub side (store/handlers) and the client/CLI can share
624
+ * the names without a circular import.
625
+ *
626
+ * Two kinds share one namespace:
627
+ * - "guidance": Markdown — every `.user.md` file, plus the record/live/
628
+ * playwright/runn `.agent.md` notes (despite the "agent" name, these are
629
+ * plain prose, not the learned JSON below).
630
+ * - "custom-prompt": JSON Claude writes — only `triage.agent` and
631
+ * `audit.agent`, calibration distilled from graded cases and injected at
632
+ * run time.
633
+ *
634
+ * `triage.*` belongs to `ccqa run`'s failure classification and `audit.*` to
635
+ * `ccqa audit`. They are two prompts because they answer two questions in one
636
+ * shared vocabulary: the audit decides whether a spec still describes the
637
+ * code (from the source alone), and the run decides why it failed, using the
638
+ * execution evidence — the two commands run independently, neither gating the
639
+ * other (ADR-0016).
640
+ *
641
+ * Hub names are extensionless (`record.agent`), local files keep their real
642
+ * extensions; `PROMPT_LOCAL_PATHS` is the single mapping every caller (push,
643
+ * pull, learn, UI) goes through so the two never drift.
644
+ */
645
+ declare const PROMPT_NAMES: readonly ["record.user", "record.agent", "live.user", "live.agent", "playwright.user", "playwright.agent", "runn.user", "runn.agent", "triage.user", "triage.agent", "audit.user", "audit.agent"];
646
+ type PromptName = (typeof PROMPT_NAMES)[number];
647
+ //#endregion
648
+ //#region src/report/schema.d.ts
649
+ declare const ReportSpecResultSchema: z.ZodObject<{
650
+ feature: z.ZodString;
651
+ spec: z.ZodString;
652
+ title: z.ZodNullable<z.ZodString>;
653
+ target: z.ZodOptional<z.ZodString>;
654
+ mode: z.ZodOptional<z.ZodEnum<{
655
+ live: "live";
656
+ deterministic: "deterministic";
657
+ }>>;
658
+ status: z.ZodEnum<{
659
+ passed: "passed";
660
+ failed: "failed";
661
+ skipped: "skipped";
662
+ }>;
663
+ skipReason: z.ZodOptional<z.ZodString>;
664
+ testCounts: z.ZodNullable<z.ZodObject<{
665
+ total: z.ZodNumber;
666
+ passed: z.ZodNumber;
667
+ failed: z.ZodNumber;
668
+ }, z.core.$strip>>;
669
+ durationMs: z.ZodNullable<z.ZodNumber>;
670
+ startedAt: z.ZodOptional<z.ZodString>;
671
+ finishedAt: z.ZodOptional<z.ZodString>;
672
+ assertions: z.ZodNullable<z.ZodArray<z.ZodObject<{
673
+ name: z.ZodString;
674
+ status: z.ZodEnum<{
675
+ passed: "passed";
676
+ failed: "failed";
677
+ skipped: "skipped";
678
+ }>;
679
+ durationMs: z.ZodNullable<z.ZodNumber>;
680
+ }, z.core.$strip>>>;
681
+ analysis: z.ZodNullable<z.ZodObject<{
682
+ label: z.ZodEnum<{
683
+ TEST_DRIFT: "TEST_DRIFT";
684
+ SPEC_CHANGE: "SPEC_CHANGE";
685
+ PRODUCT_BUG: "PRODUCT_BUG";
686
+ ENVIRONMENT: "ENVIRONMENT";
687
+ UNKNOWN: "UNKNOWN";
688
+ }>;
689
+ confidence: z.ZodNumber;
690
+ subDiagnosis: z.ZodOptional<z.ZodEnum<{
691
+ TIMING_ISSUE: "TIMING_ISSUE";
692
+ OVER_ASSERTION: "OVER_ASSERTION";
693
+ SELECTOR_DRIFT: "SELECTOR_DRIFT";
694
+ DATA_MISSING: "DATA_MISSING";
695
+ NONE: "NONE";
696
+ }>>;
697
+ headline: z.ZodDefault<z.ZodString>;
698
+ recommendation: z.ZodDefault<z.ZodString>;
699
+ evidence: z.ZodArray<z.ZodObject<{
700
+ file: z.ZodOptional<z.ZodString>;
701
+ detail: z.ZodString;
702
+ citation: z.ZodOptional<z.ZodEnum<{
703
+ corrected: "corrected";
704
+ unverified: "unverified";
705
+ }>>;
706
+ }, z.core.$strip>>;
707
+ reasoning: z.ZodString;
708
+ surface: z.ZodOptional<z.ZodEnum<{
709
+ spec: "spec";
710
+ generated: "generated";
711
+ }>>;
712
+ specChangeKind: z.ZodCatch<z.ZodOptional<z.ZodEnum<{
713
+ FEATURE_REMOVED: "FEATURE_REMOVED";
714
+ BEHAVIOUR_CHANGED: "BEHAVIOUR_CHANGED";
715
+ }>>>;
716
+ }, z.core.$strip>>;
717
+ analysisSkipped: z.ZodNullable<z.ZodString>;
718
+ rerun: z.ZodOptional<z.ZodObject<{
719
+ outcome: z.ZodEnum<{
720
+ passed: "passed";
721
+ failed: "failed";
722
+ }>;
723
+ }, z.core.$strip>>;
724
+ customPromptVersion: z.ZodOptional<z.ZodString>;
725
+ analysisBase: z.ZodOptional<z.ZodNullable<z.ZodObject<{
726
+ ref: z.ZodString;
727
+ sha: z.ZodString;
728
+ }, z.core.$strip>>>;
729
+ failureLogExcerpt: z.ZodNullable<z.ZodString>;
730
+ diffExcerpt: z.ZodNullable<z.ZodString>;
731
+ specYaml: z.ZodNullable<z.ZodString>;
732
+ evidence: z.ZodNullable<z.ZodArray<z.ZodObject<{
733
+ stepId: z.ZodString;
734
+ source: z.ZodString;
735
+ pngPath: z.ZodString;
736
+ beforePngPath: z.ZodOptional<z.ZodNullable<z.ZodString>>;
737
+ url: z.ZodNullable<z.ZodString>;
738
+ title: z.ZodNullable<z.ZodString>;
739
+ capturedAt: z.ZodNullable<z.ZodString>;
740
+ description: z.ZodNullable<z.ZodString>;
741
+ status: z.ZodDefault<z.ZodEnum<{
742
+ passed: "passed";
743
+ failed: "failed";
744
+ }>>;
745
+ failureSummary: z.ZodDefault<z.ZodNullable<z.ZodString>>;
746
+ }, z.core.$strip>>>;
747
+ evidenceUnavailable: z.ZodOptional<z.ZodString>;
748
+ artifacts: z.ZodOptional<z.ZodArray<z.ZodObject<{
749
+ name: z.ZodString;
750
+ path: z.ZodString;
751
+ kind: z.ZodEnum<{
752
+ image: "image";
753
+ text: "text";
754
+ json: "json";
755
+ binary: "binary";
756
+ }>;
757
+ sizeBytes: z.ZodNumber;
758
+ }, z.core.$strip>>>;
759
+ coverage: z.ZodOptional<z.ZodObject<{
760
+ files: z.ZodArray<z.ZodString>;
761
+ frontendFiles: z.ZodNumber;
762
+ backendFiles: z.ZodNumber;
763
+ backendReported: z.ZodBoolean;
764
+ frontendReported: z.ZodBoolean;
765
+ frontendStopped: z.ZodBoolean;
766
+ actorWindows: z.ZodDefault<z.ZodArray<z.ZodObject<{
767
+ key: z.ZodString;
768
+ events: z.ZodNumber;
769
+ }, z.core.$strip>>>;
770
+ excludedDependencies: z.ZodNumber;
771
+ gaps: z.ZodObject<{
772
+ unattributed: z.ZodNumber;
773
+ unmappedScripts: z.ZodNumber;
774
+ unmappedRanges: z.ZodNumber;
775
+ outsideProject: z.ZodNumber;
776
+ unresolvedSources: z.ZodNumber;
777
+ outsideProjectSamples: z.ZodDefault<z.ZodArray<z.ZodString>>;
778
+ unresolvedSamples: z.ZodDefault<z.ZodArray<z.ZodString>>;
779
+ uninstrumentedFiles: z.ZodNumber;
780
+ uninstrumentedProcesses: z.ZodNumber;
781
+ droppedPushes: z.ZodNumber;
782
+ unmappedActorEvents: z.ZodDefault<z.ZodNumber>;
783
+ outsideWindowEvents: z.ZodDefault<z.ZodNumber>;
784
+ }, z.core.$strip>;
785
+ }, z.core.$strip>>;
786
+ coverageUnavailable: z.ZodOptional<z.ZodString>;
787
+ liveRun: z.ZodNullable<z.ZodObject<{
788
+ runId: z.ZodString;
789
+ sessionName: z.ZodString;
790
+ startedAt: z.ZodString;
791
+ durationMs: z.ZodNumber;
792
+ steps: z.ZodArray<z.ZodObject<{
793
+ stepId: z.ZodString;
794
+ source: z.ZodString;
795
+ instruction: z.ZodString;
796
+ expected: z.ZodString;
797
+ status: z.ZodEnum<{
798
+ passed: "passed";
799
+ failed: "failed";
800
+ skipped: "skipped";
801
+ }>;
802
+ reasoning: z.ZodString;
803
+ beforePng: z.ZodNullable<z.ZodString>;
804
+ afterPng: z.ZodNullable<z.ZodString>;
805
+ durationMs: z.ZodNumber;
806
+ cost: z.ZodObject<{
807
+ totalCostUsd: z.ZodNullable<z.ZodNumber>;
808
+ durationApiMs: z.ZodNullable<z.ZodNumber>;
809
+ numTurns: z.ZodNullable<z.ZodNumber>;
810
+ inputTokens: z.ZodNullable<z.ZodNumber>;
811
+ cacheCreationInputTokens: z.ZodNullable<z.ZodNumber>;
812
+ cacheReadInputTokens: z.ZodNullable<z.ZodNumber>;
813
+ outputTokens: z.ZodNullable<z.ZodNumber>;
814
+ models: z.ZodArray<z.ZodString>;
815
+ }, z.core.$strip>;
816
+ commands: z.ZodOptional<z.ZodArray<z.ZodString>>;
817
+ }, z.core.$strip>>;
818
+ cost: z.ZodObject<{
819
+ totalCostUsd: z.ZodNullable<z.ZodNumber>;
820
+ durationApiMs: z.ZodNullable<z.ZodNumber>;
821
+ numTurns: z.ZodNullable<z.ZodNumber>;
822
+ inputTokens: z.ZodNullable<z.ZodNumber>;
823
+ cacheCreationInputTokens: z.ZodNullable<z.ZodNumber>;
824
+ cacheReadInputTokens: z.ZodNullable<z.ZodNumber>;
825
+ outputTokens: z.ZodNullable<z.ZodNumber>;
826
+ models: z.ZodArray<z.ZodString>;
827
+ }, z.core.$strip>;
828
+ }, z.core.$strip>>;
829
+ }, z.core.$strip>;
830
+ type ReportSpecResult = z.infer<typeof ReportSpecResultSchema>;
831
+ declare const RunReportDataSchema: z.ZodObject<{
832
+ schemaVersion: z.ZodLiteral<1>;
833
+ kind: z.ZodDefault<z.ZodEnum<{
834
+ run: "run";
835
+ drift: "drift";
836
+ record: "record";
837
+ }>>;
838
+ createdAt: z.ZodString;
839
+ runId: z.ZodNullable<z.ZodString>;
840
+ runUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
841
+ git: z.ZodObject<{
842
+ head: z.ZodNullable<z.ZodString>;
843
+ base: z.ZodNullable<z.ZodString>;
844
+ baseSha: z.ZodOptional<z.ZodNullable<z.ZodString>>;
845
+ baseSource: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
846
+ explicit: "explicit";
847
+ "github-base-ref": "github-base-ref";
848
+ "last-green": "last-green";
849
+ }>>>;
850
+ }, z.core.$strip>;
851
+ model: z.ZodNullable<z.ZodString>;
852
+ language: z.ZodDefault<z.ZodNullable<z.ZodString>>;
853
+ promptVersion: z.ZodString;
854
+ customPromptVersion: z.ZodDefault<z.ZodNullable<z.ZodString>>;
855
+ triageUserPromptHash: z.ZodOptional<z.ZodString>;
856
+ deployedSha: z.ZodOptional<z.ZodString>;
857
+ cost: z.ZodDefault<z.ZodNullable<z.ZodObject<{
858
+ totalCostUsd: z.ZodNullable<z.ZodNumber>;
859
+ durationApiMs: z.ZodNullable<z.ZodNumber>;
860
+ numTurns: z.ZodNullable<z.ZodNumber>;
861
+ inputTokens: z.ZodNullable<z.ZodNumber>;
862
+ cacheCreationInputTokens: z.ZodNullable<z.ZodNumber>;
863
+ cacheReadInputTokens: z.ZodNullable<z.ZodNumber>;
864
+ outputTokens: z.ZodNullable<z.ZodNumber>;
865
+ models: z.ZodArray<z.ZodString>;
866
+ }, z.core.$strip>>>;
867
+ coverageUniverse: z.ZodOptional<z.ZodObject<{
868
+ include: z.ZodArray<z.ZodString>;
869
+ files: z.ZodArray<z.ZodString>;
870
+ }, z.core.$strip>>;
871
+ results: z.ZodArray<z.ZodObject<{
872
+ feature: z.ZodString;
873
+ spec: z.ZodString;
874
+ title: z.ZodNullable<z.ZodString>;
875
+ target: z.ZodOptional<z.ZodString>;
876
+ mode: z.ZodOptional<z.ZodEnum<{
877
+ live: "live";
878
+ deterministic: "deterministic";
879
+ }>>;
880
+ status: z.ZodEnum<{
881
+ passed: "passed";
882
+ failed: "failed";
883
+ skipped: "skipped";
884
+ }>;
885
+ skipReason: z.ZodOptional<z.ZodString>;
886
+ testCounts: z.ZodNullable<z.ZodObject<{
887
+ total: z.ZodNumber;
888
+ passed: z.ZodNumber;
889
+ failed: z.ZodNumber;
890
+ }, z.core.$strip>>;
891
+ durationMs: z.ZodNullable<z.ZodNumber>;
892
+ startedAt: z.ZodOptional<z.ZodString>;
893
+ finishedAt: z.ZodOptional<z.ZodString>;
894
+ assertions: z.ZodNullable<z.ZodArray<z.ZodObject<{
895
+ name: z.ZodString;
896
+ status: z.ZodEnum<{
897
+ passed: "passed";
898
+ failed: "failed";
899
+ skipped: "skipped";
900
+ }>;
901
+ durationMs: z.ZodNullable<z.ZodNumber>;
902
+ }, z.core.$strip>>>;
903
+ analysis: z.ZodNullable<z.ZodObject<{
904
+ label: z.ZodEnum<{
905
+ TEST_DRIFT: "TEST_DRIFT";
906
+ SPEC_CHANGE: "SPEC_CHANGE";
907
+ PRODUCT_BUG: "PRODUCT_BUG";
908
+ ENVIRONMENT: "ENVIRONMENT";
909
+ UNKNOWN: "UNKNOWN";
910
+ }>;
911
+ confidence: z.ZodNumber;
912
+ subDiagnosis: z.ZodOptional<z.ZodEnum<{
913
+ TIMING_ISSUE: "TIMING_ISSUE";
914
+ OVER_ASSERTION: "OVER_ASSERTION";
915
+ SELECTOR_DRIFT: "SELECTOR_DRIFT";
916
+ DATA_MISSING: "DATA_MISSING";
917
+ NONE: "NONE";
918
+ }>>;
919
+ headline: z.ZodDefault<z.ZodString>;
920
+ recommendation: z.ZodDefault<z.ZodString>;
921
+ evidence: z.ZodArray<z.ZodObject<{
922
+ file: z.ZodOptional<z.ZodString>;
923
+ detail: z.ZodString;
924
+ citation: z.ZodOptional<z.ZodEnum<{
925
+ corrected: "corrected";
926
+ unverified: "unverified";
927
+ }>>;
928
+ }, z.core.$strip>>;
929
+ reasoning: z.ZodString;
930
+ surface: z.ZodOptional<z.ZodEnum<{
931
+ spec: "spec";
932
+ generated: "generated";
933
+ }>>;
934
+ specChangeKind: z.ZodCatch<z.ZodOptional<z.ZodEnum<{
935
+ FEATURE_REMOVED: "FEATURE_REMOVED";
936
+ BEHAVIOUR_CHANGED: "BEHAVIOUR_CHANGED";
937
+ }>>>;
938
+ }, z.core.$strip>>;
939
+ analysisSkipped: z.ZodNullable<z.ZodString>;
940
+ rerun: z.ZodOptional<z.ZodObject<{
941
+ outcome: z.ZodEnum<{
942
+ passed: "passed";
943
+ failed: "failed";
944
+ }>;
945
+ }, z.core.$strip>>;
946
+ customPromptVersion: z.ZodOptional<z.ZodString>;
947
+ analysisBase: z.ZodOptional<z.ZodNullable<z.ZodObject<{
948
+ ref: z.ZodString;
949
+ sha: z.ZodString;
950
+ }, z.core.$strip>>>;
951
+ failureLogExcerpt: z.ZodNullable<z.ZodString>;
952
+ diffExcerpt: z.ZodNullable<z.ZodString>;
953
+ specYaml: z.ZodNullable<z.ZodString>;
954
+ evidence: z.ZodNullable<z.ZodArray<z.ZodObject<{
955
+ stepId: z.ZodString;
956
+ source: z.ZodString;
957
+ pngPath: z.ZodString;
958
+ beforePngPath: z.ZodOptional<z.ZodNullable<z.ZodString>>;
959
+ url: z.ZodNullable<z.ZodString>;
960
+ title: z.ZodNullable<z.ZodString>;
961
+ capturedAt: z.ZodNullable<z.ZodString>;
962
+ description: z.ZodNullable<z.ZodString>;
963
+ status: z.ZodDefault<z.ZodEnum<{
964
+ passed: "passed";
965
+ failed: "failed";
966
+ }>>;
967
+ failureSummary: z.ZodDefault<z.ZodNullable<z.ZodString>>;
968
+ }, z.core.$strip>>>;
969
+ evidenceUnavailable: z.ZodOptional<z.ZodString>;
970
+ artifacts: z.ZodOptional<z.ZodArray<z.ZodObject<{
971
+ name: z.ZodString;
972
+ path: z.ZodString;
973
+ kind: z.ZodEnum<{
974
+ image: "image";
975
+ text: "text";
976
+ json: "json";
977
+ binary: "binary";
978
+ }>;
979
+ sizeBytes: z.ZodNumber;
980
+ }, z.core.$strip>>>;
981
+ coverage: z.ZodOptional<z.ZodObject<{
982
+ files: z.ZodArray<z.ZodString>;
983
+ frontendFiles: z.ZodNumber;
984
+ backendFiles: z.ZodNumber;
985
+ backendReported: z.ZodBoolean;
986
+ frontendReported: z.ZodBoolean;
987
+ frontendStopped: z.ZodBoolean;
988
+ actorWindows: z.ZodDefault<z.ZodArray<z.ZodObject<{
989
+ key: z.ZodString;
990
+ events: z.ZodNumber;
991
+ }, z.core.$strip>>>;
992
+ excludedDependencies: z.ZodNumber;
993
+ gaps: z.ZodObject<{
994
+ unattributed: z.ZodNumber;
995
+ unmappedScripts: z.ZodNumber;
996
+ unmappedRanges: z.ZodNumber;
997
+ outsideProject: z.ZodNumber;
998
+ unresolvedSources: z.ZodNumber;
999
+ outsideProjectSamples: z.ZodDefault<z.ZodArray<z.ZodString>>;
1000
+ unresolvedSamples: z.ZodDefault<z.ZodArray<z.ZodString>>;
1001
+ uninstrumentedFiles: z.ZodNumber;
1002
+ uninstrumentedProcesses: z.ZodNumber;
1003
+ droppedPushes: z.ZodNumber;
1004
+ unmappedActorEvents: z.ZodDefault<z.ZodNumber>;
1005
+ outsideWindowEvents: z.ZodDefault<z.ZodNumber>;
1006
+ }, z.core.$strip>;
1007
+ }, z.core.$strip>>;
1008
+ coverageUnavailable: z.ZodOptional<z.ZodString>;
1009
+ liveRun: z.ZodNullable<z.ZodObject<{
1010
+ runId: z.ZodString;
1011
+ sessionName: z.ZodString;
1012
+ startedAt: z.ZodString;
1013
+ durationMs: z.ZodNumber;
1014
+ steps: z.ZodArray<z.ZodObject<{
1015
+ stepId: z.ZodString;
1016
+ source: z.ZodString;
1017
+ instruction: z.ZodString;
1018
+ expected: z.ZodString;
1019
+ status: z.ZodEnum<{
1020
+ passed: "passed";
1021
+ failed: "failed";
1022
+ skipped: "skipped";
1023
+ }>;
1024
+ reasoning: z.ZodString;
1025
+ beforePng: z.ZodNullable<z.ZodString>;
1026
+ afterPng: z.ZodNullable<z.ZodString>;
1027
+ durationMs: z.ZodNumber;
1028
+ cost: z.ZodObject<{
1029
+ totalCostUsd: z.ZodNullable<z.ZodNumber>;
1030
+ durationApiMs: z.ZodNullable<z.ZodNumber>;
1031
+ numTurns: z.ZodNullable<z.ZodNumber>;
1032
+ inputTokens: z.ZodNullable<z.ZodNumber>;
1033
+ cacheCreationInputTokens: z.ZodNullable<z.ZodNumber>;
1034
+ cacheReadInputTokens: z.ZodNullable<z.ZodNumber>;
1035
+ outputTokens: z.ZodNullable<z.ZodNumber>;
1036
+ models: z.ZodArray<z.ZodString>;
1037
+ }, z.core.$strip>;
1038
+ commands: z.ZodOptional<z.ZodArray<z.ZodString>>;
1039
+ }, z.core.$strip>>;
1040
+ cost: z.ZodObject<{
1041
+ totalCostUsd: z.ZodNullable<z.ZodNumber>;
1042
+ durationApiMs: z.ZodNullable<z.ZodNumber>;
1043
+ numTurns: z.ZodNullable<z.ZodNumber>;
1044
+ inputTokens: z.ZodNullable<z.ZodNumber>;
1045
+ cacheCreationInputTokens: z.ZodNullable<z.ZodNumber>;
1046
+ cacheReadInputTokens: z.ZodNullable<z.ZodNumber>;
1047
+ outputTokens: z.ZodNullable<z.ZodNumber>;
1048
+ models: z.ZodArray<z.ZodString>;
1049
+ }, z.core.$strip>;
1050
+ }, z.core.$strip>>;
1051
+ }, z.core.$strip>>;
1052
+ }, z.core.$strip>;
1053
+ type RunReportData = z.infer<typeof RunReportDataSchema>;
1054
+ declare const LabelsExportSchema: z.ZodObject<{
1055
+ schemaVersion: z.ZodLiteral<1>;
1056
+ runId: z.ZodNullable<z.ZodString>;
1057
+ promptVersion: z.ZodString;
1058
+ exportedAt: z.ZodString;
1059
+ labels: z.ZodArray<z.ZodObject<{
1060
+ feature: z.ZodString;
1061
+ spec: z.ZodString;
1062
+ predicted: z.ZodEnum<{
1063
+ TEST_DRIFT: "TEST_DRIFT";
1064
+ SPEC_CHANGE: "SPEC_CHANGE";
1065
+ PRODUCT_BUG: "PRODUCT_BUG";
1066
+ ENVIRONMENT: "ENVIRONMENT";
1067
+ UNKNOWN: "UNKNOWN";
1068
+ }>;
1069
+ label: z.ZodEnum<{
1070
+ TEST_DRIFT: "TEST_DRIFT";
1071
+ SPEC_CHANGE: "SPEC_CHANGE";
1072
+ PRODUCT_BUG: "PRODUCT_BUG";
1073
+ ENVIRONMENT: "ENVIRONMENT";
1074
+ NO_DRIFT: "NO_DRIFT";
1075
+ }>;
1076
+ note: z.ZodOptional<z.ZodString>;
1077
+ }, z.core.$strip>>;
1078
+ }, z.core.$strip>;
1079
+ type LabelsExport = z.infer<typeof LabelsExportSchema>;
1080
+ //#endregion
1081
+ //#region src/run/incremental-report.d.ts
1082
+ /**
1083
+ * The report envelope fields that don't change spec-to-spec — everything in
1084
+ * `RunReportData` except `results`. Captured once when the writer is created
1085
+ * so each incremental flush produces the same envelope the final batch write
1086
+ * used to.
1087
+ */
1088
+ type ReportEnvelope = Omit<RunReportData, "results">;
1089
+ //#endregion
1090
+ //#region src/hub-client/index.d.ts
1091
+ /**
1092
+ * Body of a `PATCH /runs/:id` incremental push: the newly-finished spec rows,
1093
+ * their evidence PNGs (posix relPath → base64), the report envelope metadata
1094
+ * (filled once the real git diff is known), and — on the last patch — `done`
1095
+ * with the terminal status.
1096
+ */
1097
+ interface PatchRunRequest {
1098
+ rows: ReportSpecResult[];
1099
+ /** reportDir-relative posix path → base64 PNG bytes. */
1100
+ evidence?: Record<string, string>;
1101
+ done?: boolean;
1102
+ finalStatus?: "passed" | "failed";
1103
+ reportMeta?: Partial<ReportEnvelope>;
1104
+ }
1105
+ /**
1106
+ * TypeScript client for the ccqa hub's public REST API (docs/hub-api.md).
1107
+ * Uses the global `fetch` only — no `node:*` imports — so this same module
1108
+ * works unmodified as a browser bundle (an intranet dashboard) or in a
1109
+ * Node script (the `ccqa hub push/pull` CLI, which is itself just one more
1110
+ * consumer of this client).
1111
+ */
1112
+ interface HubClientOptions {
1113
+ baseUrl: string;
1114
+ token: string;
1115
+ /**
1116
+ * Extra headers sent on every request, ahead of any per-call headers and
1117
+ * the `Authorization` header (e.g. an infra gateway/ALB bypass header in
1118
+ * CI — never overrides `Authorization`).
1119
+ */
1120
+ headers?: Record<string, string>;
1121
+ /** Override for testing; defaults to the global `fetch`. */
1122
+ fetchImpl?: typeof fetch;
1123
+ }
1124
+ declare class HubApiError extends Error {
1125
+ readonly status: number;
1126
+ readonly code: string;
1127
+ constructor(status: number, code: string, message: string);
1128
+ }
1129
+ interface HubVariable {
1130
+ name: string;
1131
+ sensitive: boolean;
1132
+ updatedAt: string;
1133
+ value?: string;
1134
+ }
1135
+ interface HubPromptMeta {
1136
+ name: string;
1137
+ kind: "guidance" | "custom-prompt";
1138
+ updatedAt: string;
1139
+ meta: Record<string, unknown>;
1140
+ }
1141
+ /**
1142
+ * What `GET /api/v1/coverage` answers: one run's resolved view of the
1143
+ * project's coverage event stream, plus every run the stream retains (newest
1144
+ * first, bounded server-side). `resolved` is null when the stream holds no
1145
+ * measured run.
1146
+ */
1147
+ interface HubCoverageAnswer {
1148
+ resolved: ResolvedCoverage | null;
1149
+ runIds: string[];
1150
+ }
1151
+ interface HubClient {
1152
+ /**
1153
+ * Push a report directory (as a tar.gz) for an already-finished `ccqa run`.
1154
+ *
1155
+ * `deployedSha` asserts the commit the environment was running *when the run
1156
+ * started*. Without it the hub falls back to its deploy-log head, which by
1157
+ * push time is the head after the run — a deploy that landed mid-run would
1158
+ * then read as that run's baseline.
1159
+ */
1160
+ pushRun(archive: Uint8Array, meta: {
1161
+ project: string;
1162
+ branch?: string;
1163
+ profile?: string;
1164
+ kind?: Run["kind"];
1165
+ deployedSha?: string;
1166
+ }): Promise<Run>;
1167
+ /**
1168
+ * Open a `running` run to push results into incrementally. Returns the new
1169
+ * run's id. Non-retryable (a dropped response after the server committed
1170
+ * would leave a second open run); callers degrade to local-only on failure.
1171
+ * `gitHead` stamps the run's commit at open time, so even a run that dies
1172
+ * before its final reconcile patch is attributable to a commit.
1173
+ *
1174
+ * `deployedSha` does the same for the environment's commit: the baseline the
1175
+ * caller selected against, which a `--rerun` inherits from an earlier run.
1176
+ * Left unset the hub reads its own deploy-log head, which by the time this
1177
+ * call lands can already name a later deploy.
1178
+ */
1179
+ openRun(meta: {
1180
+ project: string;
1181
+ branch?: string;
1182
+ profile?: string;
1183
+ kind?: Run["kind"];
1184
+ gitHead?: string;
1185
+ deployedSha?: string;
1186
+ /** CI run id (GITHUB_RUN_ID) and its run URL, stamped at open time so an
1187
+ * interrupted incremental run still links back to its CI run. */
1188
+ ciRunId?: string;
1189
+ runUrl?: string;
1190
+ }): Promise<Run>;
1191
+ /** Add finished spec rows (+ evidence) to a running run; `done` closes it. */
1192
+ patchRun(id: string, body: PatchRunRequest): Promise<Run>;
1193
+ /** `ciRunId` answers "which runs did this CI job create", whatever the window. */
1194
+ listRuns(q?: {
1195
+ project?: string;
1196
+ branch?: string;
1197
+ status?: RunStatus;
1198
+ kind?: Run["kind"];
1199
+ ciRunId?: string;
1200
+ limit?: number;
1201
+ }): Promise<Run[]>;
1202
+ getRun(id: string): Promise<Run>;
1203
+ getReport(id: string): Promise<unknown>;
1204
+ downloadArtifacts(id: string): Promise<Uint8Array>;
1205
+ /**
1206
+ * The project's coverage event stream, resolved for one run — `runId`
1207
+ * omitted means the most recently measured run. Spec selection reads its
1208
+ * reach edges through this (ADR-0024).
1209
+ */
1210
+ getCoverage(project: string, q?: {
1211
+ runId?: string;
1212
+ }): Promise<HubCoverageAnswer>;
1213
+ /**
1214
+ * Merge one run's measured reach into the project's coverage-edge ledger
1215
+ * (ADR-0026). The hub stamps `measuredAt` with its own clock.
1216
+ */
1217
+ putCoverageEdges(project: string, upsert: CoverageEdgesUpsert): Promise<void>;
1218
+ /** The coverage-edge ledger, or `null` when nothing is stored (or the hub predates it). */
1219
+ getCoverageEdges(project: string): Promise<CoverageEdgesDoc | null>;
1220
+ /**
1221
+ * Source maps for what a commit deployed, addressed by the asset path the
1222
+ * browser requests. Coverage falls back to these when the build keeps its
1223
+ * maps out of the CDN, which is the usual choice — a map hands out source.
1224
+ */
1225
+ putSourceMap(project: string, commit: string, assetPath: string, map: Uint8Array): Promise<void>;
1226
+ getSourceMap(project: string, commit: string, assetPath: string): Promise<string | null>;
1227
+ listSourceMaps(project: string, commit: string): Promise<string[]>;
1228
+ /** Ends a push, letting the hub drop the commits it no longer keeps. */
1229
+ sweepSourceMaps(project: string): Promise<void>;
1230
+ getTriage(id: string): Promise<RunTriage>;
1231
+ putActualCause(id: string, c: {
1232
+ feature: string;
1233
+ spec: string;
1234
+ }, v: PutActualCauseRequest): Promise<TriageCase>;
1235
+ deleteActualCause(id: string, c: {
1236
+ feature: string;
1237
+ spec: string;
1238
+ }): Promise<void>;
1239
+ importActualCauses(id: string, labels: LabelsExport): Promise<ImportActualCausesResponse>;
1240
+ /** Every project the hub knows (from runs and stored secrets). */
1241
+ listProjects(): Promise<string[]>;
1242
+ /**
1243
+ * The last-green ledger for one project/profile: "feature/spec" → the run
1244
+ * head where that spec last passed. `branch` entries overlay
1245
+ * `fallbackBranch` (typically the default branch) entries server-side.
1246
+ */
1247
+ getLastGreen(project: string, q: {
1248
+ profile?: string;
1249
+ branch: string;
1250
+ fallbackBranch?: string;
1251
+ }): Promise<Record<string, LastGreenEntry>>;
1252
+ /**
1253
+ * Per spec of one project/profile: is its last result still trustworthy?
1254
+ * Answers `ccqa run --only-hub-rerun-needed`. 404 when the project has no
1255
+ * perspectives document — there is then no spec registered to compare
1256
+ * against a deploy, which the caller must report rather than read as
1257
+ * "nothing to run".
1258
+ */
1259
+ getRerun(project: string, q: {
1260
+ profile: string;
1261
+ }): Promise<RerunReport>;
1262
+ /**
1263
+ * Per spec of one project/profile: has a deploy landed on the code it covers
1264
+ * since the audit last read it? Answers `ccqa audit
1265
+ * --only-hub-audit-needed`. 404 on a project with no perspectives document,
1266
+ * for the same reason `getRerun` does.
1267
+ */
1268
+ getAuditNeed(project: string, q: {
1269
+ profile: string;
1270
+ }): Promise<AuditNeedReport>;
1271
+ /**
1272
+ * Take the specs that are free, so a second job does not start on one this
1273
+ * run is already working. `denied` is part of the answer, not an error.
1274
+ */
1275
+ acquireLocks(project: string, q: {
1276
+ profile: string;
1277
+ }, body: AcquireLocksRequest): Promise<AcquireLocksResponse>;
1278
+ /** Drop everything `runId` holds. Safe to call when it holds nothing. */
1279
+ releaseLocks(project: string, q: {
1280
+ profile: string;
1281
+ }, holder: string): Promise<void>;
1282
+ /** Every attestation for the profile, standing and lapsed alike. */
1283
+ getAttestations(project: string, q: {
1284
+ profile: string;
1285
+ }): Promise<AttestationsResponse>;
1286
+ /** Record that a person checked `spec` by hand. The hub stamps the time and deploy head. */
1287
+ putAttestation(project: string, q: {
1288
+ profile: string;
1289
+ }, body: {
1290
+ spec: string;
1291
+ by: string;
1292
+ note?: string;
1293
+ }): Promise<AttestationResponse>;
1294
+ /** Revoke a spec's attestation. Revoking one that does not exist succeeds. */
1295
+ deleteAttestation(project: string, q: {
1296
+ profile: string;
1297
+ }, spec: string): Promise<void>;
1298
+ /** Every dismissed audit finding for the project, current and superseded alike. No profile — findings are about the repository. */
1299
+ getAuditDismissals(project: string): Promise<AuditDismissalsResponse>;
1300
+ /**
1301
+ * Record that a person judged `spec`'s current audit finding wrong. The hub
1302
+ * reads which finding that is from the ledger and pins the dismissal to it;
1303
+ * a spec with no open finding is rejected.
1304
+ */
1305
+ putAuditDismissal(project: string, body: {
1306
+ spec: string;
1307
+ by: string;
1308
+ note: string;
1309
+ }): Promise<AuditDismissalResponse>;
1310
+ /** Withdraw a dismissal, putting the audit's finding back in force. */
1311
+ deleteAuditDismissal(project: string, spec: string): Promise<void>;
1312
+ /**
1313
+ * Every spec's last `ccqa audit --report-to-hub` result, keyed by "feature/spec". No
1314
+ * profile — drift asks whether a spec still describes the code, not
1315
+ * whether an environment is stale.
1316
+ */
1317
+ getDriftLedger(project: string): Promise<DriftLedgerResponse>;
1318
+ /** Tell the hub what a deploy shipped (`ccqa hub deploy record`). */
1319
+ recordDeploy(project: string, profile: string, body: RecordDeployRequest): Promise<DeployEntry>;
1320
+ /** The profile's retained deploy log, oldest first; `limit` keeps the newest N. */
1321
+ getDeployLog(project: string, q: {
1322
+ profile: string;
1323
+ limit?: number;
1324
+ }): Promise<DeployLogResponse>;
1325
+ /**
1326
+ * Report what one batch of ccqa invocations cost (`ccqa hub cost push`).
1327
+ * Read instead of a sum over runs, never alongside one (ADR-0017).
1328
+ */
1329
+ recordSpend(project: string, body: RecordSpendRequest): Promise<SpendEntry>;
1330
+ /** The project's spend over `[since, until)`, newest first, with the window's total. */
1331
+ getSpend(project: string, q?: {
1332
+ since?: string;
1333
+ until?: string;
1334
+ }): Promise<SpendLogResponse>;
1335
+ putSession(project: string, profile: string, name: string, storageState: unknown): Promise<void>;
1336
+ getSession(project: string, profile: string, name: string): Promise<unknown>;
1337
+ listSessions(project: string, profile: string): Promise<{
1338
+ name: string;
1339
+ updatedAt: string;
1340
+ }[]>;
1341
+ deleteSession(project: string, profile: string, name: string): Promise<void>;
1342
+ putVariable(project: string, profile: string, name: string, v: {
1343
+ value: string;
1344
+ sensitive: boolean;
1345
+ }): Promise<void>;
1346
+ listVariables(project: string, profile: string, opts?: {
1347
+ includeValues?: boolean;
1348
+ }): Promise<HubVariable[]>;
1349
+ deleteVariable(project: string, profile: string, name: string): Promise<void>;
1350
+ putPrompt(project: string, name: PromptName, body: string): Promise<void>;
1351
+ getPrompt(project: string, name: PromptName): Promise<string | null>;
1352
+ listPrompts(project: string): Promise<HubPromptMeta[]>;
1353
+ deletePrompt(project: string, name: PromptName): Promise<void>;
1354
+ /** The project's perspectives document (coverage inventory), stored hub-only. */
1355
+ putPerspectives(project: string, doc: unknown): Promise<void>;
1356
+ getPerspectives(project: string): Promise<unknown | null>;
1357
+ /** Set (or clear, with an empty string) the human note on one spec's entry. */
1358
+ patchPerspectivesNote(project: string, c: {
1359
+ feature: string;
1360
+ spec: string;
1361
+ note: string;
1362
+ }): Promise<void>;
1363
+ deletePerspectives(project: string): Promise<void>;
1364
+ }
1365
+ /**
1366
+ * One round trip against a hub, with the client's shared policy: bearer auth,
1367
+ * per-attempt timeout, retries for idempotent methods, `HubApiError` on the
1368
+ * final non-ok answer. Exported for the one caller outside the client
1369
+ * (`CoverageInbox`), whose POSTs are appends a duplicate cannot corrupt —
1370
+ * unlike the client's own POSTs — so it may opt into `retry: "post-once"`,
1371
+ * one extra attempt after a 5xx or network error.
1372
+ */
1373
+ declare function hubRequest(opts: HubClientOptions, path: string, init?: RequestInit, retry?: "post-once"): Promise<Response>;
1374
+ declare function createHubClient(opts: HubClientOptions): HubClient;
1375
+ //#endregion
1376
+ export { HubApiError, HubClient, HubClientOptions, HubCoverageAnswer, HubPromptMeta, HubVariable, PatchRunRequest, createHubClient, hubRequest };