@patronage/software-factory 0.20.0 → 0.23.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.
package/dist/index.d.ts CHANGED
@@ -4,7 +4,6 @@ import { z } from "zod";
4
4
 
5
5
  //#region src/github-issue-comments.d.ts
6
6
  interface GithubIssueCommentApi {
7
- author_association?: string;
8
7
  body: string;
9
8
  created_at: string;
10
9
  html_url: string;
@@ -18,7 +17,6 @@ interface GithubIssueComment {
18
17
  author: {
19
18
  login?: string;
20
19
  };
21
- authorAssociation?: string;
22
20
  body: string;
23
21
  createdAt: string;
24
22
  id: string;
@@ -169,6 +167,103 @@ interface HqIngestDependencies {
169
167
  transportTimeoutMs?: number;
170
168
  }
171
169
  //#endregion
170
+ //#region src/demand-waiver.d.ts
171
+ declare const DEFAULT_DEMAND_WAIVER_PATH = ".factory-memory/demand-waivers.json";
172
+ /** One recorded operator act: this demand, on this candidate, waived. */
173
+ interface DemandWaiver {
174
+ candidate: {
175
+ headSha: string;
176
+ pr: number;
177
+ };
178
+ demand: string;
179
+ /** The authenticated GitHub account that recorded the waiver. */
180
+ operator: string;
181
+ rationale: string;
182
+ recordedAt: string;
183
+ /** The operator session the waiver was recorded in. */
184
+ session: string;
185
+ }
186
+ interface DemandWaiverStore {
187
+ command: "patronage-factory demand:waive";
188
+ schemaVersion: 1;
189
+ waivers: DemandWaiver[];
190
+ }
191
+ declare const validateDemandWaiverStore: (value: unknown) => DemandWaiverStore;
192
+ /**
193
+ * A demand that was in force, was NOT met, and was waived by the operator.
194
+ *
195
+ * `unmetReasons` is required and non-empty: every reason the demand refused is
196
+ * carried through verbatim. There is no field on this record that could say
197
+ * "satisfied", and no code path constructs one without a refusal to carry.
198
+ */
199
+ interface WaivedDemand {
200
+ demand: string;
201
+ operator: string;
202
+ rationale: string;
203
+ recordedAt: string;
204
+ session: string;
205
+ /** The demand's refusals at evaluation time, preserved verbatim. */
206
+ unmetReasons: string[];
207
+ }
208
+ declare const waivedDemandSchema: z.ZodType<WaivedDemand>;
209
+ /** The waivers that bind one candidate: same PR, same head. */
210
+ declare const selectWaiversForCandidate: ({
211
+ headSha,
212
+ pr,
213
+ waivers
214
+ }: {
215
+ headSha: string | undefined;
216
+ pr: number;
217
+ waivers: readonly DemandWaiver[];
218
+ }) => DemandWaiver[];
219
+ interface DemandOutcome {
220
+ blockingReasons: string[];
221
+ waived?: WaivedDemand;
222
+ }
223
+ /**
224
+ * Fold one resolved demand's refusals through the operator's waivers.
225
+ *
226
+ * A satisfied demand (no refusals) stays satisfied and the waiver stays inert
227
+ * — a waiver can only ever move a demand from *unmet-and-blocking* to
228
+ * *unmet-and-waived*, never to met.
229
+ */
230
+ declare const applyDemandWaiver: ({
231
+ demand,
232
+ reasons,
233
+ waivers
234
+ }: {
235
+ demand: string;
236
+ reasons: readonly string[];
237
+ waivers: readonly DemandWaiver[];
238
+ }) => DemandOutcome;
239
+ /** How a waived demand reads to a human. Never the word "satisfied". */
240
+ declare const waivedDemandNotice: (waived: WaivedDemand) => string;
241
+ interface DemandWaiverAuthorization {
242
+ operator: string;
243
+ session: string;
244
+ }
245
+ type AuthorizeDemandWaiverResult = {
246
+ authorization: DemandWaiverAuthorization;
247
+ refusals?: undefined;
248
+ } | {
249
+ authorization?: undefined;
250
+ refusals: string[];
251
+ };
252
+ /**
253
+ * Operator identity, `declaredBy`-style: a named human account, recorded on
254
+ * the waiver and enforced here — plus session distinctness from the candidate
255
+ * the waiver applies to. Every refusal is named; nothing falls open.
256
+ */
257
+ declare const authorizeDemandWaiver: ({
258
+ authenticatedLogin,
259
+ authoringSession,
260
+ session
261
+ }: {
262
+ authenticatedLogin: string | undefined;
263
+ authoringSession: string | undefined;
264
+ session: string | undefined;
265
+ }) => AuthorizeDemandWaiverResult;
266
+ //#endregion
172
267
  //#region src/checkout-repository.d.ts
173
268
  interface CheckoutRepository {
174
269
  name: string;
@@ -218,35 +313,227 @@ interface GithubPullRequestReview {
218
313
  url: string;
219
314
  }
220
315
  //#endregion
221
- //#region src/pr-readiness/handled-human-comments.d.ts
222
- declare const HANDLED_COMMENTS_PAYLOAD_KIND: "handled-human-comments";
316
+ //#region src/merge-freeze.d.ts
317
+ declare const MERGE_FREEZE_CHECK_NAME = "patronage-factory/merge-freeze";
318
+ declare const MERGE_FREEZE_APP_SLUG = "patronage-factory";
319
+ declare const mergeFreezeStateSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
320
+ active: z.ZodLiteral<true>;
321
+ generationId: z.ZodNumber;
322
+ headSha: z.ZodString;
323
+ outcome: z.ZodEnum<{
324
+ stale: "stale";
325
+ active: "active";
326
+ }>;
327
+ reason: z.ZodString;
328
+ recordedAt: z.ZodISODateTime;
329
+ schemaVersion: z.ZodLiteral<1>;
330
+ }, z.core.$strip>, z.ZodObject<{
331
+ active: z.ZodLiteral<false>;
332
+ clearRationale: z.ZodOptional<z.ZodString>;
333
+ generationId: z.ZodNumber;
334
+ headSha: z.ZodString;
335
+ outcome: z.ZodLiteral<"inactive">;
336
+ reason: z.ZodString;
337
+ recordedAt: z.ZodISODateTime;
338
+ schemaVersion: z.ZodLiteral<1>;
339
+ }, z.core.$strip>], "active">;
340
+ type MergeFreezeState = z.infer<typeof mergeFreezeStateSchema>;
223
341
  /**
224
- * Authenticated producer of the durable handled set. Recorded on the readiness
225
- * ledger; unverifiable producers are ignored on read (fail closed).
342
+ * The write side of this contract lives in the generated main-push verify
343
+ * workflow (#356, ADR 0016 as amended): it is the ONLY producer of
344
+ * `patronage-factory/merge-freeze` generations. Its emitted `output.text`
345
+ * payload must parse under this exact reader schema, which is what the
346
+ * workflow's own tests assert through this export.
226
347
  */
227
- type HandledCommentsProducerMode = "app" | "commit-status";
228
- interface HandledCommentsProducer {
229
- /** App id (stringified) or GitHub login, depending on mode. */
230
- identity: string;
231
- mode: HandledCommentsProducerMode;
348
+ declare function validateMergeFreezeState(value: unknown): MergeFreezeState;
349
+ interface MergeFreezeStoreInput {
350
+ cwd: string;
351
+ headSha: string;
352
+ repository: CheckoutRepository;
232
353
  }
233
- interface HandledCommentsCheckPayload {
234
- clearedAt?: string;
235
- handledCommentUrls: string[];
236
- kind: typeof HANDLED_COMMENTS_PAYLOAD_KIND;
237
- pr: number;
238
- schemaVersion: 1;
239
- sessionId?: string;
354
+ interface MergeFreezeStore {
355
+ read: (input: MergeFreezeStoreInput) => unknown;
240
356
  }
241
- //#endregion
242
- //#region src/diff-classification.d.ts
243
- declare const DIFF_CLASSIFICATIONS: readonly ["docs/process-only", "trivial", "non-trivial"];
244
- type DiffClassification = (typeof DIFF_CLASSIFICATIONS)[number];
357
+ declare namespace worktree_held_branch_d_exports {
358
+ export { MergeOperationalNotices, WorktreeHeldBranch, WorktreeHeldBranchCheck, WorktreeListEntry, checkWorktreeHeldBranch, findWorktreeHeldBranch, formatHeldBranchCloseoutSummary, listWorktreesPorcelain, parseGitWorktreeList, resolveMergeOperationalNotices, worktreeHeldBranchNotice };
359
+ }
360
+ /**
361
+ * Detects when a PR head branch is checked out in a local git worktree.
362
+ *
363
+ * `gh pr merge --delete-branch` fails when the local branch is held by a
364
+ * worktree (git refuses to delete a checked-out branch), which previously
365
+ * broke the auto-merge lane mid-merge (patronage/internal#284). The merge
366
+ * preflight surfaces this as an actionable notice — not a hard fail — so the
367
+ * operator merges without `--delete-branch` (or prunes the worktree first)
368
+ * and defers local branch cleanup to closeout.
369
+ */
370
+ interface WorktreeHeldBranch {
371
+ branch: string;
372
+ worktreePath: string;
373
+ }
374
+ interface WorktreeListEntry {
375
+ branch?: string;
376
+ path: string;
377
+ }
378
+ /**
379
+ * Parses `git worktree list --porcelain` output. Entries are separated by
380
+ * blank lines; each starts with `worktree <path>` and carries an optional
381
+ * `branch refs/heads/<name>` attribute (detached worktrees have none).
382
+ */
383
+ declare function parseGitWorktreeList(porcelain: string): WorktreeListEntry[];
384
+ /**
385
+ * Returns the worktree holding `branch`, or undefined when no local worktree
386
+ * has it checked out (or the porcelain listing was unavailable).
387
+ */
388
+ declare function findWorktreeHeldBranch({
389
+ branch,
390
+ worktreeListPorcelain
391
+ }: {
392
+ branch: string;
393
+ worktreeListPorcelain: string | undefined;
394
+ }): undefined | WorktreeHeldBranch;
395
+ declare function worktreeHeldBranchNotice(held: WorktreeHeldBranch): string;
396
+ interface MergeOperationalNotices {
397
+ notices: string[];
398
+ worktreeHeldBranch?: WorktreeHeldBranch;
399
+ worktreeHeldBranches?: WorktreeHeldBranch[];
400
+ }
401
+ /**
402
+ * Single entry point for non-blocking merge preflight notices, mirroring
403
+ * `resolveMergeGuardIdentity`/`mergeGuardBlockingReasons` in
404
+ * merge-identity.ts: adding a notice kind never requires coordinated edits
405
+ * in the command runner, and persisted notice strings cannot drift from the
406
+ * structured detection result.
407
+ */
408
+ declare function resolveMergeOperationalNotices({
409
+ headRefName,
410
+ worktreeListPorcelain
411
+ }: {
412
+ headRefName: string | undefined;
413
+ worktreeListPorcelain: string | undefined;
414
+ }): MergeOperationalNotices;
415
+ /**
416
+ * Shared `git worktree list --porcelain` reader for merge preflight and
417
+ * closeout. Returns undefined when the directory is missing, not a git
418
+ * repository, or git is unavailable — detection is best-effort and callers
419
+ * report "skipped" rather than fabricating a result.
420
+ */
421
+ declare function listWorktreesPorcelain(cwd: string): string | undefined;
422
+ interface WorktreeHeldBranchCheck {
423
+ held?: WorktreeHeldBranch;
424
+ /** "skipped" means no branch was recorded or worktrees were unlistable. */
425
+ status: "clean" | "held" | "skipped";
426
+ }
427
+ /**
428
+ * Closeout-side counterpart to the merge-preflight notice: the merge step
429
+ * defers local branch cleanup to closeout, so closeout planning checks
430
+ * whether the worker branch is still held by a worktree (#284).
431
+ */
432
+ declare function checkWorktreeHeldBranch({
433
+ branch,
434
+ worktreeListPorcelain
435
+ }: {
436
+ branch: string | undefined;
437
+ worktreeListPorcelain: string | undefined;
438
+ }): WorktreeHeldBranchCheck;
439
+ /** One-line closeout summary, owned beside the detection logic. */
440
+ declare function formatHeldBranchCloseoutSummary(check: WorktreeHeldBranchCheck): string;
441
+ declare namespace merge_identity_d_exports {
442
+ export { LiveHeadInput, MergeGuardIdentity, MergeIdentityResult, PostProofCommit, ReadyProofForMergeIdentity, evaluateMergeIdentity, mergeGuardBlockingReasons, mergeGuardIdentitySchema, resolveMergeGuardIdentity };
443
+ }
444
+ interface PostProofCommit {
445
+ sha: string;
446
+ subject: string;
447
+ }
448
+ /**
449
+ * The slice of the pr:ready proof the merge guard actually consumes, so this
450
+ * module does not depend on the parent proof envelope. `PrReadyProof` is
451
+ * structurally assignable to this type.
452
+ */
453
+ interface ReadyProofForMergeIdentity {
454
+ blockingReasons: string[];
455
+ ledger: {
456
+ /**
457
+ * The evaluated head SHA recorded by pr:ready: `pr.headRefOid` captured
458
+ * at evaluation time. The merge guard compares it to the live pushed
459
+ * HEAD with exact equality.
460
+ */
461
+ headSha: string;
462
+ pr: number;
463
+ };
464
+ status: string;
465
+ }
466
+ type MergeIdentityResult = {
467
+ kind: "match";
468
+ headSha: string;
469
+ } | {
470
+ kind: "diverged";
471
+ liveHeadSha: string;
472
+ postProofCommits?: PostProofCommit[];
473
+ proofHeadSha: string;
474
+ };
475
+ type MergeGuardIdentity = MergeIdentityResult | {
476
+ kind: "live-head-invalid";
477
+ pr: number;
478
+ received: string;
479
+ } | {
480
+ kind: "ready-proof-missing";
481
+ errorDetail?: string;
482
+ readyProofPath: string;
483
+ } | {
484
+ kind: "ready-proof-pr-mismatch";
485
+ proofPr: number;
486
+ requestedPr: number;
487
+ } | {
488
+ kind: "ready-proof-not-ready";
489
+ blockingReasons: string[];
490
+ status: string;
491
+ };
492
+ declare const evaluateMergeIdentity: ({
493
+ liveHeadSha,
494
+ postProofCommits,
495
+ proofHeadSha
496
+ }: {
497
+ liveHeadSha: string;
498
+ postProofCommits?: PostProofCommit[];
499
+ proofHeadSha: string;
500
+ }) => MergeIdentityResult;
501
+ /**
502
+ * The live PR head as fetched from GitHub: either a validated 40-hex SHA or
503
+ * the raw (stringified) response that failed validation.
504
+ */
505
+ type LiveHeadInput = {
506
+ headSha: string;
507
+ } | {
508
+ invalidResponse: string;
509
+ };
510
+ /**
511
+ * Single entry point that owns construction of every MergeGuardIdentity
512
+ * kind, so adding or changing a kind never requires coordinated edits in the
513
+ * command runner.
514
+ */
515
+ declare const resolveMergeGuardIdentity: ({
516
+ commitsBetween,
517
+ liveHead,
518
+ pr,
519
+ readyProof,
520
+ readyProofError,
521
+ readyProofPath
522
+ }: {
523
+ commitsBetween?: (fromSha: string, toSha: string) => PostProofCommit[] | undefined;
524
+ liveHead: LiveHeadInput;
525
+ pr: number;
526
+ readyProof: ReadyProofForMergeIdentity | undefined;
527
+ readyProofError?: unknown;
528
+ readyProofPath: string;
529
+ }) => MergeGuardIdentity;
530
+ declare const mergeGuardIdentitySchema: z.ZodType<MergeGuardIdentity>;
531
+ declare const mergeGuardBlockingReasons: (identity: MergeGuardIdentity) => string[];
245
532
  //#endregion
246
533
  //#region src/profile.d.ts
247
534
  declare const DEFAULT_FACTORY_REPOSITORY = "unknown/unknown";
248
- /** The one profile shape this build accepts (ADR 0023, #318). */
249
- declare const PROFILE_SCHEMA_VERSION = 3;
535
+ /** The one profile shape this build accepts (ADR 0023, #318, #351). */
536
+ declare const PROFILE_SCHEMA_VERSION = 4;
250
537
  declare const factoryProjectProfileSchema: z.ZodObject<{
251
538
  $schema: z.ZodOptional<z.ZodString>;
252
539
  env: z.ZodOptional<z.ZodObject<{
@@ -295,7 +582,6 @@ declare const factoryProjectProfileSchema: z.ZodObject<{
295
582
  paths: z.ZodArray<z.ZodString>;
296
583
  }, z.core.$strict>>>;
297
584
  defaultMaxCycles: z.ZodNumber;
298
- docsOnlyBypass: z.ZodOptional<z.ZodBoolean>;
299
585
  ladder: z.ZodOptional<z.ZodObject<{
300
586
  gate: z.ZodOptional<z.ZodObject<{
301
587
  cap: z.ZodNumber;
@@ -307,7 +593,7 @@ declare const factoryProjectProfileSchema: z.ZodObject<{
307
593
  }>>;
308
594
  standingChecklist: z.ZodOptional<z.ZodArray<z.ZodString>>;
309
595
  }, z.core.$strict>;
310
- schemaVersion: z.ZodLiteral<3>;
596
+ schemaVersion: z.ZodLiteral<4>;
311
597
  verification: z.ZodObject<{
312
598
  commands: z.ZodArray<z.ZodObject<{
313
599
  command: z.ZodString;
@@ -324,11 +610,6 @@ declare const factoryProjectProfileSchema: z.ZodObject<{
324
610
  }, z.core.$strict>;
325
611
  type FactoryProjectProfile = z.infer<typeof factoryProjectProfileSchema>;
326
612
  declare const resolveFactoryRepository: (profile?: Pick<FactoryProjectProfile, "repository"> | undefined) => string;
327
- /**
328
- * Whether a pure docs/process diff may skip independent review. Opt-in: absent
329
- * config means review is required (#318, ADR 0023).
330
- */
331
- declare const resolveDocsOnlyReviewBypass: (profile: Pick<FactoryProjectProfile, "review">) => boolean;
332
613
  interface LoadProjectProfileInput {
333
614
  cwd?: string;
334
615
  profilePath?: string;
@@ -339,26 +620,158 @@ interface LoadProjectProfileResult {
339
620
  }
340
621
  declare function loadProjectProfile(input?: LoadProjectProfileInput): LoadProjectProfileResult;
341
622
  //#endregion
342
- //#region src/pr-verify-mode.d.ts
343
- /**
344
- * The verification mode `pr:verify` resolved for a run.
345
- *
346
- * Canonically declared here rather than inside `pr-readiness/` so that modules
347
- * on either side of that boundary — the readiness proof shape and the durable
348
- * check-run payload — can name the same union without importing each other.
349
- */
350
- type ResolvedPrVerifyMode = "docs-only" | "trivial" | "full";
623
+ //#region src/review-rungs.d.ts
624
+ declare const EVIDENCE_REVIEW_RUNGS: readonly ["independent-model", "oracle", "human"];
625
+ type EvidenceReviewRung = (typeof EVIDENCE_REVIEW_RUNGS)[number];
351
626
  //#endregion
352
- //#region src/pr-verify-status.d.ts
353
- type CommitStatusState = "failure" | "pending" | "success";
354
- interface PostCommitStatusInput {
355
- context?: string;
356
- cwd: string;
357
- description: string;
358
- owner: string;
359
- repo: string;
360
- sha: string;
361
- state: CommitStatusState;
627
+ //#region src/pr-merge-check.d.ts
628
+ interface PrMergeCheckArgs extends LoadProjectProfileInput {
629
+ epic?: number;
630
+ json?: boolean;
631
+ output?: string;
632
+ pr: number;
633
+ readyProof?: string;
634
+ }
635
+ interface PrMergeCheckProof {
636
+ schemaVersion: 1;
637
+ blockingReasons: string[];
638
+ boundary?: {
639
+ autoMerge: boolean;
640
+ epic: number;
641
+ review: EvidenceReviewRung;
642
+ wave: string;
643
+ };
644
+ command: "patronage-factory pr:merge-check";
645
+ /**
646
+ * Machine-safe arg array for the obvious next action (#523): on `pass`, the
647
+ * remote-only GitHub merge API invocation for this PR; on `fail`, the re-run that clears the
648
+ * block (`pr:ready`, or `pr:verify` then `pr:ready` after a head
649
+ * divergence). Same `argv` shape `factory:delegate --print` emits. Optional
650
+ * and purely additive — existing consumers ignore it.
651
+ */
652
+ followUp?: FollowUpAction;
653
+ identity: MergeGuardIdentity;
654
+ /**
655
+ * The pushed PR head SHA fetched from GitHub at check time. Absent only
656
+ * when GitHub returned no usable 40-hex head (identity kind
657
+ * "live-head-invalid"), which is itself a fail-closed blocking state.
658
+ */
659
+ liveHeadSha?: string;
660
+ /**
661
+ * Actionable operational notices that do not block the merge, e.g. a PR
662
+ * head branch held by a local worktree, which makes
663
+ * `gh pr merge --delete-branch` fail (patronage/internal#284).
664
+ */
665
+ notices?: string[];
666
+ pr: number;
667
+ status: "pass" | "fail";
668
+ /**
669
+ * Demands that were in force, were NOT met, and were waived by the operator
670
+ * (#354). Each entry carries the demand's refusals verbatim, so a waived
671
+ * demand can never read as a met one; the merge proceeds on the recorded
672
+ * operator act, not on evidence.
673
+ */
674
+ waivedDemands?: WaivedDemand[];
675
+ /** Present when the PR head branch is checked out in a local worktree. */
676
+ worktreeHeldBranch?: WorktreeHeldBranch;
677
+ /** All merge-relevant branches held by local worktrees (head and default). */
678
+ worktreeHeldBranches?: WorktreeHeldBranch[];
679
+ }
680
+ interface PrMergeCheckGitDependencies {
681
+ checkoutRepository: (cwd: string) => CheckoutRepository;
682
+ commitsBetween: (cwd: string, fromSha: string, toSha: string) => PostProofCommit[] | undefined;
683
+ worktreeListPorcelain: (cwd: string) => string | undefined;
684
+ showFileAtRef: (cwd: string, ref: string, absolutePath: string) => string | undefined;
685
+ objectIdAtRef: (cwd: string, ref: string, absolutePath: string) => string | undefined;
686
+ }
687
+ interface PrMergeCheckDependencies {
688
+ git?: Partial<PrMergeCheckGitDependencies>;
689
+ github?: {
690
+ fetchClosingPullRequests?: (input: {
691
+ issue: number;
692
+ owner: string;
693
+ repo: string;
694
+ }) => {
695
+ number: number;
696
+ }[];
697
+ fetchIssueBody?: (input: {
698
+ issue: number;
699
+ owner: string;
700
+ repo: string;
701
+ }) => string;
702
+ fetchPullRequestHead: (input: {
703
+ cwd: string;
704
+ owner: string;
705
+ pr: number;
706
+ repo: string;
707
+ }) => {
708
+ headRefName?: string;
709
+ headRefOid: string;
710
+ baseRefName?: string;
711
+ baseRefOid?: string;
712
+ mergedAt?: string | null;
713
+ remoteHeadRefExists?: boolean;
714
+ labels?: {
715
+ name: string;
716
+ }[];
717
+ };
718
+ fetchPullRequestReviews?: (input: {
719
+ owner: string;
720
+ pr: number;
721
+ repo: string;
722
+ }) => GithubPullRequestReview[];
723
+ };
724
+ mergeFreeze?: MergeFreezeStore;
725
+ }
726
+ declare function validatePrMergeCheckProof(value: unknown): PrMergeCheckProof;
727
+ declare function readPrMergeCheckProof(filePath: string): PrMergeCheckProof;
728
+ declare function runPrMergeCheck(args: PrMergeCheckArgs, dependencies?: PrMergeCheckDependencies): PrMergeCheckProof;
729
+ //#endregion
730
+ //#region src/pr-readiness/handled-human-comments.d.ts
731
+ declare const HANDLED_COMMENTS_PAYLOAD_KIND: "handled-human-comments";
732
+ /**
733
+ * Authenticated producer of the durable handled set. Recorded on the readiness
734
+ * ledger; unverifiable producers are ignored on read (fail closed).
735
+ */
736
+ type HandledCommentsProducerMode = "app" | "commit-status";
737
+ interface HandledCommentsProducer {
738
+ /** App id (stringified) or GitHub login, depending on mode. */
739
+ identity: string;
740
+ mode: HandledCommentsProducerMode;
741
+ }
742
+ interface HandledCommentsCheckPayload {
743
+ clearedAt?: string;
744
+ handledCommentUrls: string[];
745
+ kind: typeof HANDLED_COMMENTS_PAYLOAD_KIND;
746
+ pr: number;
747
+ schemaVersion: 1;
748
+ sessionId?: string;
749
+ }
750
+ //#endregion
751
+ //#region src/diff-classification.d.ts
752
+ declare const DIFF_CLASSIFICATIONS: readonly ["docs/process-only", "trivial", "non-trivial"];
753
+ type DiffClassification = (typeof DIFF_CLASSIFICATIONS)[number];
754
+ //#endregion
755
+ //#region src/pr-verify-mode.d.ts
756
+ /**
757
+ * The verification mode `pr:verify` resolved for a run.
758
+ *
759
+ * Canonically declared here rather than inside `pr-readiness/` so that modules
760
+ * on either side of that boundary — the readiness proof shape and the durable
761
+ * check-run payload — can name the same union without importing each other.
762
+ */
763
+ type ResolvedPrVerifyMode = "docs-only" | "trivial" | "full";
764
+ //#endregion
765
+ //#region src/pr-verify-status.d.ts
766
+ type CommitStatusState = "failure" | "pending" | "success";
767
+ interface PostCommitStatusInput {
768
+ context?: string;
769
+ cwd: string;
770
+ description: string;
771
+ owner: string;
772
+ repo: string;
773
+ sha: string;
774
+ state: CommitStatusState;
362
775
  /**
363
776
  * Drop this mirror's own failure diagnostic because the caller has already
364
777
  * reported the same cause. Set only on the pre-push path, where the status
@@ -389,6 +802,10 @@ declare const factoryUserConfigSchema: z.ZodObject<{
389
802
  privateKeyPath: z.ZodString;
390
803
  }, z.core.$strip>>;
391
804
  hqAllowedOrigins: z.ZodOptional<z.ZodArray<z.ZodString>>;
805
+ hqIngestCredentials: z.ZodOptional<z.ZodObject<{
806
+ clientIdRef: z.ZodString;
807
+ clientSecretRef: z.ZodString;
808
+ }, z.core.$strip>>;
392
809
  schemaVersion: z.ZodLiteral<2>;
393
810
  }, z.core.$strip>;
394
811
  type FactoryUserConfig = z.infer<typeof factoryUserConfigSchema>;
@@ -473,304 +890,6 @@ interface PublishHandledCommentsCheckInput {
473
890
  sha: string;
474
891
  }
475
892
  //#endregion
476
- //#region src/merge-freeze.d.ts
477
- interface MergeFreezeGeneration {
478
- headSha: string;
479
- id: number;
480
- startedAt: string;
481
- }
482
- interface MergeFreezeStoreInput {
483
- cwd: string;
484
- headSha: string;
485
- repository: CheckoutRepository;
486
- }
487
- interface MergeFreezeStore {
488
- complete: (input: MergeFreezeStoreInput & {
489
- clearRationale?: string;
490
- generation: MergeFreezeGeneration;
491
- outcome: "active" | "inactive" | "stale";
492
- reason: string;
493
- }) => Promise<void>;
494
- read: (input: MergeFreezeStoreInput) => unknown;
495
- start: (input: MergeFreezeStoreInput) => Promise<MergeFreezeGeneration>;
496
- }
497
- declare namespace worktree_held_branch_d_exports {
498
- export { MergeOperationalNotices, WorktreeHeldBranch, WorktreeHeldBranchCheck, WorktreeListEntry, checkWorktreeHeldBranch, findWorktreeHeldBranch, formatHeldBranchCloseoutSummary, listWorktreesPorcelain, parseGitWorktreeList, resolveMergeOperationalNotices, worktreeHeldBranchNotice };
499
- }
500
- /**
501
- * Detects when a PR head branch is checked out in a local git worktree.
502
- *
503
- * `gh pr merge --delete-branch` fails when the local branch is held by a
504
- * worktree (git refuses to delete a checked-out branch), which previously
505
- * broke the auto-merge lane mid-merge (patronage/internal#284). The merge
506
- * preflight surfaces this as an actionable notice — not a hard fail — so the
507
- * operator merges without `--delete-branch` (or prunes the worktree first)
508
- * and defers local branch cleanup to closeout.
509
- */
510
- interface WorktreeHeldBranch {
511
- branch: string;
512
- worktreePath: string;
513
- }
514
- interface WorktreeListEntry {
515
- branch?: string;
516
- path: string;
517
- }
518
- /**
519
- * Parses `git worktree list --porcelain` output. Entries are separated by
520
- * blank lines; each starts with `worktree <path>` and carries an optional
521
- * `branch refs/heads/<name>` attribute (detached worktrees have none).
522
- */
523
- declare function parseGitWorktreeList(porcelain: string): WorktreeListEntry[];
524
- /**
525
- * Returns the worktree holding `branch`, or undefined when no local worktree
526
- * has it checked out (or the porcelain listing was unavailable).
527
- */
528
- declare function findWorktreeHeldBranch({
529
- branch,
530
- worktreeListPorcelain
531
- }: {
532
- branch: string;
533
- worktreeListPorcelain: string | undefined;
534
- }): undefined | WorktreeHeldBranch;
535
- declare function worktreeHeldBranchNotice(held: WorktreeHeldBranch): string;
536
- interface MergeOperationalNotices {
537
- notices: string[];
538
- worktreeHeldBranch?: WorktreeHeldBranch;
539
- worktreeHeldBranches?: WorktreeHeldBranch[];
540
- }
541
- /**
542
- * Single entry point for non-blocking merge preflight notices, mirroring
543
- * `resolveMergeGuardIdentity`/`mergeGuardBlockingReasons` in
544
- * merge-identity.ts: adding a notice kind never requires coordinated edits
545
- * in the command runner, and persisted notice strings cannot drift from the
546
- * structured detection result.
547
- */
548
- declare function resolveMergeOperationalNotices({
549
- headRefName,
550
- worktreeListPorcelain
551
- }: {
552
- headRefName: string | undefined;
553
- worktreeListPorcelain: string | undefined;
554
- }): MergeOperationalNotices;
555
- /**
556
- * Shared `git worktree list --porcelain` reader for merge preflight and
557
- * closeout. Returns undefined when the directory is missing, not a git
558
- * repository, or git is unavailable — detection is best-effort and callers
559
- * report "skipped" rather than fabricating a result.
560
- */
561
- declare function listWorktreesPorcelain(cwd: string): string | undefined;
562
- interface WorktreeHeldBranchCheck {
563
- held?: WorktreeHeldBranch;
564
- /** "skipped" means no branch was recorded or worktrees were unlistable. */
565
- status: "clean" | "held" | "skipped";
566
- }
567
- /**
568
- * Closeout-side counterpart to the merge-preflight notice: the merge step
569
- * defers local branch cleanup to closeout, so closeout planning checks
570
- * whether the worker branch is still held by a worktree (#284).
571
- */
572
- declare function checkWorktreeHeldBranch({
573
- branch,
574
- worktreeListPorcelain
575
- }: {
576
- branch: string | undefined;
577
- worktreeListPorcelain: string | undefined;
578
- }): WorktreeHeldBranchCheck;
579
- /** One-line closeout summary, owned beside the detection logic. */
580
- declare function formatHeldBranchCloseoutSummary(check: WorktreeHeldBranchCheck): string;
581
- declare namespace merge_identity_d_exports {
582
- export { LiveHeadInput, MergeGuardIdentity, MergeIdentityResult, PostProofCommit, ReadyProofForMergeIdentity, evaluateMergeIdentity, mergeGuardBlockingReasons, mergeGuardIdentitySchema, resolveMergeGuardIdentity };
583
- }
584
- interface PostProofCommit {
585
- sha: string;
586
- subject: string;
587
- }
588
- /**
589
- * The slice of the pr:ready proof the merge guard actually consumes, so this
590
- * module does not depend on the parent proof envelope. `PrReadyProof` is
591
- * structurally assignable to this type.
592
- */
593
- interface ReadyProofForMergeIdentity {
594
- blockingReasons: string[];
595
- ledger: {
596
- /**
597
- * The evaluated head SHA recorded by pr:ready: `pr.headRefOid` captured
598
- * at evaluation time. The merge guard compares it to the live pushed
599
- * HEAD with exact equality.
600
- */
601
- headSha: string;
602
- pr: number;
603
- };
604
- status: string;
605
- }
606
- type MergeIdentityResult = {
607
- kind: "match";
608
- headSha: string;
609
- } | {
610
- kind: "diverged";
611
- liveHeadSha: string;
612
- postProofCommits?: PostProofCommit[];
613
- proofHeadSha: string;
614
- };
615
- type MergeGuardIdentity = MergeIdentityResult | {
616
- kind: "live-head-invalid";
617
- pr: number;
618
- received: string;
619
- } | {
620
- kind: "ready-proof-missing";
621
- errorDetail?: string;
622
- readyProofPath: string;
623
- } | {
624
- kind: "ready-proof-pr-mismatch";
625
- proofPr: number;
626
- requestedPr: number;
627
- } | {
628
- kind: "ready-proof-not-ready";
629
- blockingReasons: string[];
630
- status: string;
631
- };
632
- declare const evaluateMergeIdentity: ({
633
- liveHeadSha,
634
- postProofCommits,
635
- proofHeadSha
636
- }: {
637
- liveHeadSha: string;
638
- postProofCommits?: PostProofCommit[];
639
- proofHeadSha: string;
640
- }) => MergeIdentityResult;
641
- /**
642
- * The live PR head as fetched from GitHub: either a validated 40-hex SHA or
643
- * the raw (stringified) response that failed validation.
644
- */
645
- type LiveHeadInput = {
646
- headSha: string;
647
- } | {
648
- invalidResponse: string;
649
- };
650
- /**
651
- * Single entry point that owns construction of every MergeGuardIdentity
652
- * kind, so adding or changing a kind never requires coordinated edits in the
653
- * command runner.
654
- */
655
- declare const resolveMergeGuardIdentity: ({
656
- commitsBetween,
657
- liveHead,
658
- pr,
659
- readyProof,
660
- readyProofError,
661
- readyProofPath
662
- }: {
663
- commitsBetween?: (fromSha: string, toSha: string) => PostProofCommit[] | undefined;
664
- liveHead: LiveHeadInput;
665
- pr: number;
666
- readyProof: ReadyProofForMergeIdentity | undefined;
667
- readyProofError?: unknown;
668
- readyProofPath: string;
669
- }) => MergeGuardIdentity;
670
- declare const mergeGuardIdentitySchema: z.ZodType<MergeGuardIdentity>;
671
- declare const mergeGuardBlockingReasons: (identity: MergeGuardIdentity) => string[];
672
- //#endregion
673
- //#region src/review-rungs.d.ts
674
- declare const EVIDENCE_REVIEW_RUNGS: readonly ["independent-model", "oracle", "human"];
675
- type EvidenceReviewRung = (typeof EVIDENCE_REVIEW_RUNGS)[number];
676
- //#endregion
677
- //#region src/pr-merge-check.d.ts
678
- interface PrMergeCheckArgs extends LoadProjectProfileInput {
679
- epic?: number;
680
- json?: boolean;
681
- output?: string;
682
- pr: number;
683
- readyProof?: string;
684
- }
685
- interface PrMergeCheckProof {
686
- schemaVersion: 1;
687
- blockingReasons: string[];
688
- boundary?: {
689
- autoMerge: boolean;
690
- epic: number;
691
- review: EvidenceReviewRung;
692
- wave: string;
693
- };
694
- command: "patronage-factory pr:merge-check";
695
- /**
696
- * Machine-safe arg array for the obvious next action (#523): on `pass`, the
697
- * remote-only GitHub merge API invocation for this PR; on `fail`, the re-run that clears the
698
- * block (`pr:ready`, or `pr:verify` then `pr:ready` after a head
699
- * divergence). Same `argv` shape `factory:delegate --print` emits. Optional
700
- * and purely additive — existing consumers ignore it.
701
- */
702
- followUp?: FollowUpAction;
703
- identity: MergeGuardIdentity;
704
- /**
705
- * The pushed PR head SHA fetched from GitHub at check time. Absent only
706
- * when GitHub returned no usable 40-hex head (identity kind
707
- * "live-head-invalid"), which is itself a fail-closed blocking state.
708
- */
709
- liveHeadSha?: string;
710
- /**
711
- * Actionable operational notices that do not block the merge, e.g. a PR
712
- * head branch held by a local worktree, which makes
713
- * `gh pr merge --delete-branch` fail (patronage/internal#284).
714
- */
715
- notices?: string[];
716
- pr: number;
717
- status: "pass" | "fail";
718
- /** Present when the PR head branch is checked out in a local worktree. */
719
- worktreeHeldBranch?: WorktreeHeldBranch;
720
- /** All merge-relevant branches held by local worktrees (head and default). */
721
- worktreeHeldBranches?: WorktreeHeldBranch[];
722
- }
723
- interface PrMergeCheckGitDependencies {
724
- changedFilesBetween: (cwd: string, baseSha: string, headSha: string) => string[] | undefined;
725
- checkoutRepository: (cwd: string) => CheckoutRepository;
726
- commitsBetween: (cwd: string, fromSha: string, toSha: string) => PostProofCommit[] | undefined;
727
- worktreeListPorcelain: (cwd: string) => string | undefined;
728
- showFileAtRef: (cwd: string, ref: string, absolutePath: string) => string | undefined;
729
- objectIdAtRef: (cwd: string, ref: string, absolutePath: string) => string | undefined;
730
- }
731
- interface PrMergeCheckDependencies {
732
- git?: Partial<PrMergeCheckGitDependencies>;
733
- github?: {
734
- fetchClosingPullRequests?: (input: {
735
- issue: number;
736
- owner: string;
737
- repo: string;
738
- }) => {
739
- number: number;
740
- }[];
741
- fetchIssueBody?: (input: {
742
- issue: number;
743
- owner: string;
744
- repo: string;
745
- }) => string;
746
- fetchPullRequestHead: (input: {
747
- cwd: string;
748
- owner: string;
749
- pr: number;
750
- repo: string;
751
- }) => {
752
- headRefName?: string;
753
- headRefOid: string;
754
- baseRefName?: string;
755
- baseRefOid?: string;
756
- mergedAt?: string | null;
757
- remoteHeadRefExists?: boolean;
758
- labels?: {
759
- name: string;
760
- }[];
761
- };
762
- fetchPullRequestReviews?: (input: {
763
- owner: string;
764
- pr: number;
765
- repo: string;
766
- }) => GithubPullRequestReview[];
767
- };
768
- mergeFreeze?: MergeFreezeStore;
769
- }
770
- declare function validatePrMergeCheckProof(value: unknown): PrMergeCheckProof;
771
- declare function readPrMergeCheckProof(filePath: string): PrMergeCheckProof;
772
- declare function runPrMergeCheck(args: PrMergeCheckArgs, dependencies?: PrMergeCheckDependencies): PrMergeCheckProof;
773
- //#endregion
774
893
  //#region src/pr-proof-io.d.ts
775
894
  interface ProofDescriptor<T> {
776
895
  label: string;
@@ -1064,7 +1183,7 @@ interface PrReviewProof {
1064
1183
  cleanedPaths: string[];
1065
1184
  ladder?: PrReviewLadderState;
1066
1185
  reviewRequirement?: {
1067
- reason: "docs-only-profile-bypass";
1186
+ reason: "no-applicable-mode";
1068
1187
  status: "not-required";
1069
1188
  };
1070
1189
  reviews: PrReviewResult[];
@@ -1349,6 +1468,7 @@ interface PrReadyArgs extends LoadProjectProfileInput {
1349
1468
  authoringSessionIds?: string[];
1350
1469
  base: string;
1351
1470
  bodyForEvaluation?: string;
1471
+ epic?: number;
1352
1472
  handledCommentUrls?: string[];
1353
1473
  json?: boolean;
1354
1474
  output?: string;
@@ -1427,6 +1547,18 @@ interface PrReadyProof {
1427
1547
  type PublishHandledCommentsResult = HandledCommentsProducer | Promise<HandledCommentsProducer | undefined> | undefined;
1428
1548
  interface PrReadyDependencies {
1429
1549
  github?: {
1550
+ fetchClosingPullRequests?: (input: {
1551
+ issue: number;
1552
+ owner: string;
1553
+ repo: string;
1554
+ }) => {
1555
+ number: number;
1556
+ }[];
1557
+ fetchIssueBody?: (input: {
1558
+ issue: number;
1559
+ owner: string;
1560
+ repo: string;
1561
+ }) => string;
1430
1562
  fetchHandledComments?: (input: {
1431
1563
  owner: string;
1432
1564
  pr: number;
@@ -1484,7 +1616,7 @@ declare const requiredCheckScopeSchema: z.ZodObject<{
1484
1616
  type RequiredCheckScope = z.infer<typeof requiredCheckScopeSchema>;
1485
1617
  interface RequiredCheckScopeContext {
1486
1618
  labels: string[] | undefined;
1487
- classification: DiffClassification;
1619
+ classification: DiffClassification | undefined;
1488
1620
  }
1489
1621
  interface ScopeDecision {
1490
1622
  inScope: boolean;
@@ -1913,15 +2045,195 @@ declare const resolveVerifyProofApplicability: ({
1913
2045
  fullVerifiedHeadShas: never[];
1914
2046
  verificationProof: VerificationProofState;
1915
2047
  } | {
1916
- fullVerifiedHeadShas: string[];
1917
- verificationProof: {
1918
- headShas: VerifiedHeadShas;
1919
- kind: "typed";
1920
- proof: PrVerifyProof;
1921
- };
2048
+ fullVerifiedHeadShas: string[];
2049
+ verificationProof: {
2050
+ headShas: VerifiedHeadShas;
2051
+ kind: "typed";
2052
+ proof: PrVerifyProof;
2053
+ };
2054
+ };
2055
+ declare const verificationProofForReadiness: (state: VerificationProofState) => VerificationHeadShas;
2056
+ declare const verificationProofBlockingReason: (state: VerificationProofState) => string | undefined;
2057
+ //#endregion
2058
+ //#region src/retro-envelope.d.ts
2059
+ /**
2060
+ * Versioned retro envelope schema (epic #27 wave 2, issue #34).
2061
+ *
2062
+ * One envelope per lane, built at `factory:closeout` and delivered through the
2063
+ * typed gate-sink as the `retro-envelope` ingest kind. Re-derived in TypeScript
2064
+ * from the `spike/telemetry-layer2` S5 scratch schema (reference-only, never
2065
+ * merged). This module is the single source of truth for the v1 wire shape
2066
+ * and its bounds ({@link RETRO_ENVELOPE_WIRE_BOUNDS}) — producer and consumer
2067
+ * alike. HQ imports these exports directly from the Worker-safe
2068
+ * `@patronage/software-factory/schemas` subpath
2069
+ * (`software-factory-hq/src/contracts/retro-schemas.ts`) instead of
2070
+ * maintaining a parallel hand-written copy, so there is exactly one wire
2071
+ * contract and no drift-detection machinery is needed (issue #350; formerly
2072
+ * a hand-written twin plus a 767-line parity test, #46).
2073
+ *
2074
+ * DESIGN INVARIANT: cross-family token sums must be UNREPRESENTABLE.
2075
+ *
2076
+ * The two model families use different tokenizers, prices, and accounting
2077
+ * conventions, so any token total that spans Claude and GPT is a lie:
2078
+ *
2079
+ * 1. There is no combined/total token field anywhere in the envelope.
2080
+ * 2. `tokenFamilies` is strict — its only keys are `claude` and `gpt`; data
2081
+ * cannot smuggle in a third "all"/"combined" slot.
2082
+ * 3. The family BLOCKS are structurally different shapes with DIFFERENT keys
2083
+ * (claude is a single flat block keyed on freshInput/cacheReadInput/
2084
+ * cacheCreationInput; gpt is `{ roles: [...] }`). The exclusive input-tier
2085
+ * COUNTS share no key name across families. The residual names shared
2086
+ * between the claude block and a gpt ROLE entry are pinned to exactly
2087
+ * {costUsd, model, output} (PR #32 advisory): `costUsd` is deliberate —
2088
+ * USD is the one cross-family summable unit (rule 4); `model` is an
2089
+ * unsummable label; `output` is the same name at DIFFERENT depths (lane
2090
+ * block vs per-role entry), frozen by a tripwire test in
2091
+ * `retro-envelope.test.ts` so the overlap cannot grow. Renaming `output`
2092
+ * is a schemaVersion-2 wire change, deliberately not spent in v1.
2093
+ * 4. Cost is per-family USD and nullable. Combined totals are allowed in USD
2094
+ * only, and only as a projection-time sum of per-family USD.
2095
+ *
2096
+ * Field names also encode the S2/S3 reader lessons: Claude `freshInput` alone
2097
+ * is not prompt size (true input context = freshInput + cacheReadInput +
2098
+ * cacheCreationInput, requestId-deduped), and codex `inputInclusiveOfCache`
2099
+ * already includes `cachedInput`, so `freshInputDerived` (inclusive − cached)
2100
+ * is the only value safe to feed a per-token pricer.
2101
+ *
2102
+ * COMPLETENESS POSTURE: harvest may have no usable native log for a lane, so
2103
+ * `tokenFamilies` may legitimately be absent. The closeout build gate demands
2104
+ * a valid envelope, not available telemetry. A families-absent envelope keeps
2105
+ * its operator-visible data gaps and is a replayable advisory HQ event, so it
2106
+ * never substitutes unavailable usage with zero. The wire shape (field names,
2107
+ * types, structure) stays byte-parity with HQ v1.
2108
+ */
2109
+ declare const RETRO_ENVELOPE_SCHEMA_VERSION = 1;
2110
+ declare const retroEnvelopeV1Schema: z.ZodObject<{
2111
+ agentRunId: z.ZodString;
2112
+ archiveRef: z.ZodOptional<z.ZodString>;
2113
+ cycles: z.ZodObject<{
2114
+ gateRunsToFirstGreen: z.ZodNumber;
2115
+ reviewerFixRounds: z.ZodNumber;
2116
+ thermoFixRounds: z.ZodNumber;
2117
+ }, z.core.$strict>;
2118
+ dataGaps: z.ZodDefault<z.ZodArray<z.ZodString>>;
2119
+ gates: z.ZodArray<z.ZodObject<{
2120
+ cycle: z.ZodNumber;
2121
+ duration: z.ZodNumber;
2122
+ gate: z.ZodString;
2123
+ outcome: z.ZodEnum<{
2124
+ pass: "pass";
2125
+ fail: "fail";
2126
+ skip: "skip";
2127
+ }>;
2128
+ startedAt: z.ZodISODateTime;
2129
+ }, z.core.$strict>>;
2130
+ generatedAt: z.ZodISODateTime;
2131
+ interventions: z.ZodObject<{
2132
+ count: z.ZodNumber;
2133
+ }, z.core.$strict>;
2134
+ joinKeys: z.ZodObject<{
2135
+ claudeSessionIds: z.ZodDefault<z.ZodArray<z.ZodString>>;
2136
+ codexThreadIds: z.ZodDefault<z.ZodArray<z.ZodString>>;
2137
+ }, z.core.$strict>;
2138
+ kind: z.ZodLiteral<"retro-envelope">;
2139
+ outcome: z.ZodOptional<z.ZodObject<{
2140
+ mergeCheck: z.ZodOptional<z.ZodEnum<{
2141
+ pass: "pass";
2142
+ fail: "fail";
2143
+ "not-run": "not-run";
2144
+ }>>;
2145
+ status: z.ZodEnum<{
2146
+ success: "success";
2147
+ fail: "fail";
2148
+ blocked: "blocked";
2149
+ "ship-with-followups": "ship-with-followups";
2150
+ }>;
2151
+ verdict: z.ZodOptional<z.ZodString>;
2152
+ }, z.core.$strict>>;
2153
+ phases: z.ZodArray<z.ZodObject<{
2154
+ at: z.ZodISODateTime;
2155
+ deltaSec: z.ZodOptional<z.ZodNumber>;
2156
+ name: z.ZodString;
2157
+ }, z.core.$strict>>;
2158
+ refs: z.ZodObject<{
2159
+ branch: z.ZodOptional<z.ZodString>;
2160
+ epic: z.ZodOptional<z.ZodString>;
2161
+ headSha: z.ZodOptional<z.ZodString>;
2162
+ issue: z.ZodOptional<z.ZodString>;
2163
+ prNumber: z.ZodOptional<z.ZodNumber>;
2164
+ }, z.core.$strict>;
2165
+ repo: z.ZodObject<{
2166
+ name: z.ZodString;
2167
+ owner: z.ZodString;
2168
+ }, z.core.$strict>;
2169
+ schemaVersion: z.ZodLiteral<1>;
2170
+ tokenFamilies: z.ZodObject<{
2171
+ claude: z.ZodOptional<z.ZodObject<{
2172
+ cacheCreationInput: z.ZodNumber;
2173
+ cacheReadInput: z.ZodNumber;
2174
+ costUsd: z.ZodNullable<z.ZodNumber>;
2175
+ family: z.ZodLiteral<"claude">;
2176
+ freshInput: z.ZodNumber;
2177
+ model: z.ZodString;
2178
+ output: z.ZodNumber;
2179
+ requests: z.ZodNumber;
2180
+ }, z.core.$strict>>;
2181
+ gpt: z.ZodOptional<z.ZodObject<{
2182
+ family: z.ZodLiteral<"gpt">;
2183
+ roles: z.ZodArray<z.ZodObject<{
2184
+ cachedInput: z.ZodNumber;
2185
+ costUsd: z.ZodNullable<z.ZodNumber>;
2186
+ freshInputDerived: z.ZodNumber;
2187
+ inputInclusiveOfCache: z.ZodNumber;
2188
+ model: z.ZodString;
2189
+ output: z.ZodNumber;
2190
+ reasoningOutput: z.ZodNumber;
2191
+ role: z.ZodString;
2192
+ threadId: z.ZodOptional<z.ZodString>;
2193
+ }, z.core.$strict>>;
2194
+ }, z.core.$strict>>;
2195
+ }, z.core.$strict>;
2196
+ wallClock: z.ZodObject<{
2197
+ endTs: z.ZodISODateTime;
2198
+ startTs: z.ZodISODateTime;
2199
+ totalSec: z.ZodNumber;
2200
+ }, z.core.$strict>;
2201
+ }, z.core.$strict>;
2202
+ type RetroEnvelope = z.infer<typeof retroEnvelopeV1Schema>;
2203
+ /**
2204
+ * Versioned payload validators, keyed by schema major. Unknown majors never
2205
+ * reach these — {@link parseRetroEnvelope} returns them raw and marked
2206
+ * degraded, mirroring HQ's ingest skew posture (stored raw, never dropped).
2207
+ */
2208
+ declare const RETRO_ENVELOPE_VALIDATORS: Record<number, z.ZodType<RetroEnvelope, unknown>>;
2209
+ declare const SUPPORTED_RETRO_ENVELOPE_SCHEMA_VERSIONS: readonly number[];
2210
+ /** The `schemaVersion` a candidate declares, or undefined when unreadable. */
2211
+ declare const retroEnvelopeSchemaVersionOf: (candidate: unknown) => number | undefined;
2212
+ type ParsedRetroEnvelope = {
2213
+ disposition: "trusted";
2214
+ envelope: RetroEnvelope;
2215
+ schemaVersion: number;
2216
+ } | {
2217
+ disposition: "degraded";
2218
+ raw: unknown;
2219
+ schemaVersion: number | undefined;
1922
2220
  };
1923
- declare const verificationProofForReadiness: (state: VerificationProofState) => VerificationHeadShas;
1924
- declare const verificationProofBlockingReason: (state: VerificationProofState) => string | undefined;
2221
+ /**
2222
+ * Parses a candidate against the versioned validators. A recognized major is
2223
+ * validated typed-only (throws on an invalid known-version payload); an unknown
2224
+ * major is round-tripped RAW and marked degraded — the retained payload is the
2225
+ * exact input object, never a coerced projection. Mirrors the HQ ingest seam so
2226
+ * the two sides agree on the skew posture.
2227
+ */
2228
+ declare const parseRetroEnvelope: (candidate: unknown) => ParsedRetroEnvelope;
2229
+ /**
2230
+ * Whether harvest recorded at least one token family. This is an operator
2231
+ * summary predicate, not a delivery gate: a families-absent envelope remains
2232
+ * valid and replayable when its data gaps explain why telemetry is unavailable.
2233
+ */
2234
+ declare const isRetroEnvelopeWireComplete: (envelope: Pick<RetroEnvelope, "tokenFamilies">) => boolean;
2235
+ /** Epic anchor for an envelope: refs.epic, else refs.issue, else the PR. */
2236
+ declare const retroEpicReference: (refs: RetroEnvelope["refs"]) => string | undefined;
1925
2237
  //#endregion
1926
2238
  //#region src/schemas.d.ts
1927
2239
  declare const boundaryCheckProofSchema: z.ZodObject<{
@@ -2015,6 +2327,74 @@ interface CliOutput {
2015
2327
  //#region src/commands/boundary-check.d.ts
2016
2328
  type BoundaryCheckAction = (args: BoundaryCheckArgs) => BoundaryCheckProofRecord;
2017
2329
  //#endregion
2330
+ //#region src/demand-waive.d.ts
2331
+ /** Every waiver recorded in this checkout; an absent or unreadable store is
2332
+ * no waivers, so a damaged file can only ever block, never permit. */
2333
+ declare const readDemandWaivers: (cwd: string, filePath?: string) => DemandWaiver[];
2334
+ interface DemandWaiveArgs {
2335
+ cwd?: string;
2336
+ demand: string;
2337
+ json?: boolean;
2338
+ output?: string;
2339
+ pr: number;
2340
+ rationale: string;
2341
+ }
2342
+ interface DemandWaiveDependencies {
2343
+ checkoutRepository?: (cwd: string) => CheckoutRepository;
2344
+ env?: NodeJS.ProcessEnv;
2345
+ fetchAuthenticatedLogin?: (cwd: string) => string | undefined;
2346
+ fetchPullRequestHeadSha?: (input: {
2347
+ cwd: string;
2348
+ owner: string;
2349
+ pr: number;
2350
+ repo: string;
2351
+ }) => string | undefined;
2352
+ now?: () => Date;
2353
+ }
2354
+ declare class DemandWaiveRefusalError extends Error {
2355
+ readonly refusals: string[];
2356
+ constructor(refusals: string[]);
2357
+ }
2358
+ /**
2359
+ * Record one waiver. One step: the operator names the demand, the candidate,
2360
+ * and why. No confirmation, no second approval, no cooldown — the trust model
2361
+ * puts the bar at operator identity, not at ceremony aimed at the operator
2362
+ * (ADR 0025).
2363
+ */
2364
+ declare const runDemandWaive: (args: DemandWaiveArgs, dependencies?: DemandWaiveDependencies) => DemandWaiver;
2365
+ //#endregion
2366
+ //#region src/commands/demand-waive.d.ts
2367
+ type DemandWaiveAction = (args: DemandWaiveArgs) => DemandWaiver;
2368
+ //#endregion
2369
+ //#region src/commands/pr-merge-check.d.ts
2370
+ type PrMergeCheckAction = (args: PrMergeCheckArgs) => PrMergeCheckProof;
2371
+ //#endregion
2372
+ //#region src/pr-review.d.ts
2373
+ interface PrReviewArgs extends LoadProjectProfileInput {
2374
+ base: string;
2375
+ cycle: number;
2376
+ dispositions?: string;
2377
+ findings?: string;
2378
+ issue?: number;
2379
+ maxCycles?: number;
2380
+ mode: PrReviewMode;
2381
+ output?: string;
2382
+ verifyProof?: string;
2383
+ }
2384
+ interface PrReviewGitDependencies {
2385
+ changedFiles: (cwd: string, base: string) => string[];
2386
+ currentHeadSha: (cwd: string) => string;
2387
+ isAncestor: (cwd: string, ancestor: string, descendant: string) => boolean;
2388
+ stablePatchId: (cwd: string, base: string) => string;
2389
+ statusPorcelain: (cwd: string) => string;
2390
+ }
2391
+ interface PrReviewDependencies {
2392
+ git?: PrReviewGitDependencies;
2393
+ hq?: HqIngestDependencies;
2394
+ publishCheckRun?: (input: PublishFactoryCheckInput) => void;
2395
+ }
2396
+ declare function runPrReview(args: PrReviewArgs, dependencies?: PrReviewDependencies): Promise<PrReviewProof>;
2397
+ //#endregion
2018
2398
  //#region src/workspace-install-resolution.d.ts
2019
2399
  interface CleanInstallResolutionDependencies {
2020
2400
  existsSync?: typeof existsSync;
@@ -2043,62 +2423,21 @@ interface PrVerifyArgs extends LoadProjectProfileInput {
2043
2423
  interface PrVerifyGitDependencies {
2044
2424
  changedFiles: (cwd: string, base: string) => string[];
2045
2425
  currentHeadSha: (cwd: string) => string;
2046
- emptyTreeHash: (cwd: string) => string;
2047
- mergeBaseSha: (cwd: string, base: string) => string;
2048
- runVerificationCommand: (command: string, cwd: string, env: Record<string, string>) => VerificationCommandOutcome;
2049
- statusPorcelain: (cwd: string) => string;
2050
- stablePatchId: (cwd: string, base: string) => string;
2051
- }
2052
- interface PrVerifyDependencies {
2053
- cleanInstall?: CleanInstallResolutionDependencies | false;
2054
- env?: NodeJS.ProcessEnv;
2055
- git?: PrVerifyGitDependencies;
2056
- hq?: HqIngestDependencies;
2057
- postCommitStatus?: PostCommitStatus;
2058
- publishCheckRun?: (input: PublishFactoryCheckInput) => void;
2059
- }
2060
- declare function runPrVerify(args: PrVerifyArgs, dependencies?: PrVerifyDependencies): PrVerifyProof;
2061
- //#endregion
2062
- //#region src/canary-verify.d.ts
2063
- interface CanaryVerifyArgs extends LoadProjectProfileInput {
2064
- /** Lift an active merge freeze without running verification. */
2065
- clear?: boolean;
2066
- output?: string;
2067
- /** Required with --clear; recorded on the canary proof. */
2068
- rationale?: string;
2069
- }
2070
- //#endregion
2071
- //#region src/commands/canary-verify.d.ts
2072
- type CanaryVerifyAction = (args: CanaryVerifyArgs) => Promise<unknown> | unknown;
2073
- //#endregion
2074
- //#region src/commands/pr-merge-check.d.ts
2075
- type PrMergeCheckAction = (args: PrMergeCheckArgs) => PrMergeCheckProof;
2076
- //#endregion
2077
- //#region src/pr-review.d.ts
2078
- interface PrReviewArgs extends LoadProjectProfileInput {
2079
- base: string;
2080
- cycle: number;
2081
- dispositions?: string;
2082
- findings?: string;
2083
- issue?: number;
2084
- maxCycles?: number;
2085
- mode: PrReviewMode;
2086
- output?: string;
2087
- verifyProof?: string;
2088
- }
2089
- interface PrReviewGitDependencies {
2090
- changedFiles: (cwd: string, base: string) => string[];
2091
- currentHeadSha: (cwd: string) => string;
2092
- isAncestor: (cwd: string, ancestor: string, descendant: string) => boolean;
2093
- stablePatchId: (cwd: string, base: string) => string;
2426
+ emptyTreeHash: (cwd: string) => string;
2427
+ mergeBaseSha: (cwd: string, base: string) => string;
2428
+ runVerificationCommand: (command: string, cwd: string, env: Record<string, string>) => VerificationCommandOutcome;
2094
2429
  statusPorcelain: (cwd: string) => string;
2430
+ stablePatchId: (cwd: string, base: string) => string;
2095
2431
  }
2096
- interface PrReviewDependencies {
2097
- git?: PrReviewGitDependencies;
2432
+ interface PrVerifyDependencies {
2433
+ cleanInstall?: CleanInstallResolutionDependencies | false;
2434
+ env?: NodeJS.ProcessEnv;
2435
+ git?: PrVerifyGitDependencies;
2098
2436
  hq?: HqIngestDependencies;
2437
+ postCommitStatus?: PostCommitStatus;
2099
2438
  publishCheckRun?: (input: PublishFactoryCheckInput) => void;
2100
2439
  }
2101
- declare function runPrReview(args: PrReviewArgs, dependencies?: PrReviewDependencies): Promise<PrReviewProof>;
2440
+ declare function runPrVerify(args: PrVerifyArgs, dependencies?: PrVerifyDependencies): PrVerifyProof;
2102
2441
  //#endregion
2103
2442
  //#region src/pr-publish.d.ts
2104
2443
  type PrPublishArgs = Omit<PrReadyArgs, "pr" | "throwWhenBlocked"> & {
@@ -2176,6 +2515,11 @@ interface PrPublishDependencies extends PrReadyDependencies {
2176
2515
  runPrReady?: typeof runPrReady;
2177
2516
  runPrReview?: (args: PrReviewArgs) => Promise<PrReviewProof>;
2178
2517
  runPrVerify?: (args: PrVerifyArgs) => Promise<PrVerifyProof>;
2518
+ /**
2519
+ * Injectable delay for the bounded hosted-run await (#348; tests only —
2520
+ * production always waits the real interval).
2521
+ */
2522
+ sleep?: (ms: number) => Promise<void>;
2179
2523
  }
2180
2524
  /**
2181
2525
  * What became of the durable `pr:verify` binding for this publish. Reported in
@@ -2392,7 +2736,9 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
2392
2736
  observedAt: z.ZodString;
2393
2737
  outcome: z.ZodLiteral<"not-required">;
2394
2738
  patchId: z.ZodString;
2395
- reason: z.ZodLiteral<"docs-only-profile-bypass">;
2739
+ reason: z.ZodEnum<{
2740
+ "no-applicable-mode": "no-applicable-mode";
2741
+ }>;
2396
2742
  reviewCycle: z.ZodNumber;
2397
2743
  }, z.core.$strict>, readonly [z.ZodObject<{
2398
2744
  createdAt: z.ZodString;
@@ -2412,7 +2758,9 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
2412
2758
  observedAt: z.ZodString;
2413
2759
  outcome: z.ZodLiteral<"not-required">;
2414
2760
  patchId: z.ZodString;
2415
- reason: z.ZodLiteral<"docs-only-profile-bypass">;
2761
+ reason: z.ZodEnum<{
2762
+ "no-applicable-mode": "no-applicable-mode";
2763
+ }>;
2416
2764
  reviewCycle: z.ZodNumber;
2417
2765
  }, z.core.$strict>], {
2418
2766
  readonly 1: z.ZodObject<{
@@ -2423,7 +2771,9 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
2423
2771
  observedAt: z.ZodString;
2424
2772
  outcome: z.ZodLiteral<"not-required">;
2425
2773
  patchId: z.ZodString;
2426
- reason: z.ZodLiteral<"docs-only-profile-bypass">;
2774
+ reason: z.ZodEnum<{
2775
+ "no-applicable-mode": "no-applicable-mode";
2776
+ }>;
2427
2777
  reviewCycle: z.ZodNumber;
2428
2778
  }, z.core.$strict>;
2429
2779
  }, {
@@ -2440,7 +2790,7 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
2440
2790
  observedAt: string;
2441
2791
  outcome: "not-required";
2442
2792
  patchId: string;
2443
- reason: "docs-only-profile-bypass";
2793
+ reason: "no-applicable-mode";
2444
2794
  reviewCycle: number;
2445
2795
  issue?: number | undefined;
2446
2796
  pr?: number | undefined;
@@ -2875,8 +3225,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
2875
3225
  interiorCycle: z.ZodOptional<z.ZodNumber>;
2876
3226
  observedAt: z.ZodString;
2877
3227
  purpose: z.ZodEnum<{
2878
- review: "review";
2879
3228
  code: "code";
3229
+ review: "review";
2880
3230
  }>;
2881
3231
  slotResolution: z.ZodObject<{
2882
3232
  effort: z.ZodEnum<{
@@ -2954,8 +3304,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
2954
3304
  interiorCycle: z.ZodOptional<z.ZodNumber>;
2955
3305
  observedAt: z.ZodString;
2956
3306
  purpose: z.ZodEnum<{
2957
- review: "review";
2958
3307
  code: "code";
3308
+ review: "review";
2959
3309
  }>;
2960
3310
  slotResolution: z.ZodObject<{
2961
3311
  effort: z.ZodEnum<{
@@ -3024,8 +3374,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3024
3374
  interiorCycle: z.ZodOptional<z.ZodNumber>;
3025
3375
  observedAt: z.ZodString;
3026
3376
  purpose: z.ZodEnum<{
3027
- review: "review";
3028
3377
  code: "code";
3378
+ review: "review";
3029
3379
  }>;
3030
3380
  slotResolution: z.ZodObject<{
3031
3381
  effort: z.ZodEnum<{
@@ -3097,7 +3447,7 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3097
3447
  exitCode: number | null;
3098
3448
  harness: string;
3099
3449
  observedAt: string;
3100
- purpose: "review" | "code";
3450
+ purpose: "code" | "review";
3101
3451
  slotResolution: {
3102
3452
  effort: "high" | "low" | "medium" | "xhigh";
3103
3453
  engine: string;
@@ -3165,263 +3515,82 @@ interface FactoryTraceFilters {
3165
3515
  pr?: number | readonly number[];
3166
3516
  repo?: string | readonly string[];
3167
3517
  threadId?: string | readonly string[];
3168
- workerId?: string | readonly string[];
3169
- }
3170
- interface FactoryTraceDiagnostic {
3171
- code: "malformed-json" | "invalid-event" | "unknown-event-type" | "unknown-event-version";
3172
- event?: {
3173
- eventId: string;
3174
- eventType: string;
3175
- issue?: number;
3176
- pr?: number;
3177
- repo: string;
3178
- threadId?: string;
3179
- workerId?: string;
3180
- };
3181
- file: string;
3182
- line: number;
3183
- message: string;
3184
- }
3185
- interface ScanFactoryTraceOptions {
3186
- diagnosticsOnly?: boolean;
3187
- filters?: FactoryTraceFilters;
3188
- from: string;
3189
- malformed?: "diagnostic" | "throw";
3190
- repoRoot: string;
3191
- to: string;
3192
- }
3193
- interface ScanFactoryTraceResult {
3194
- diagnostics: FactoryTraceDiagnostic[];
3195
- events: ReadableFactoryTraceEvent[];
3196
- }
3197
- interface ScanFactoryTraceDiagnosticsOptions {
3198
- filters?: FactoryTraceFilters;
3199
- from: string;
3200
- repoRoot: string;
3201
- to: string;
3202
- }
3203
- declare const validateFactoryTraceEvent: (event: unknown) => FactoryTraceEvent;
3204
- declare const toFactoryTraceEnvelope: (event: FactoryTraceEvent) => {
3205
- createdAt: string;
3206
- envelope: 1;
3207
- eventId: string;
3208
- payload: unknown;
3209
- repo: string;
3210
- type: string;
3211
- typeVersion: number;
3212
- issue?: number | undefined;
3213
- pr?: number | undefined;
3214
- thread?: string | undefined;
3215
- worker?: string | undefined;
3216
- };
3217
- interface AppendFactoryTraceEventResult {
3218
- event: FactoryTraceEvent;
3219
- filePath: string;
3220
- mirrorDiagnostics: TraceMirrorDiagnostic[];
3221
- }
3222
- declare const scanFactoryTraceEvents: ({
3223
- diagnosticsOnly,
3224
- filters,
3225
- from,
3226
- malformed,
3227
- repoRoot,
3228
- to
3229
- }: ScanFactoryTraceOptions) => ScanFactoryTraceResult;
3230
- /**
3231
- * Diagnostics-only trace read (#707). Scans the shard window purely to surface
3232
- * malformed / unknown-record diagnostics, without materializing (and then
3233
- * discarding) every well-formed event. Malformed shards are always collected as
3234
- * diagnostics, never thrown. Use when a consumer wants shard-corruption signal
3235
- * but no event payloads — e.g. epic closeout after the orchestrator-metrics
3236
- * removal.
3237
- */
3238
- declare const scanFactoryTraceDiagnostics: ({
3239
- filters,
3240
- from,
3241
- repoRoot,
3242
- to
3243
- }: ScanFactoryTraceDiagnosticsOptions) => FactoryTraceDiagnostic[];
3244
- //#endregion
3245
- //#region src/retro-envelope.d.ts
3246
- /**
3247
- * Versioned retro envelope schema (epic #27 wave 2, issue #34).
3248
- *
3249
- * One envelope per lane, built at `factory:closeout` and delivered through the
3250
- * typed gate-sink as the `retro-envelope` ingest kind. Re-derived in TypeScript
3251
- * from the `spike/telemetry-layer2` S5 scratch schema (reference-only, never
3252
- * merged) and kept structurally parity-compatible with HQ's v1 wire validator
3253
- * (`software-factory-hq/src/contracts/retro-schemas.ts`, PR #32): a complete
3254
- * envelope emitted by this package validates verbatim against HQ's payload
3255
- * validator. This module is the producer-side single source of truth for the
3256
- * v1 wire shape and its bounds ({@link RETRO_ENVELOPE_WIRE_BOUNDS}); the
3257
- * exhaustive per-field/bound parity test in
3258
- * `software-factory-hq/src/retro-envelope-parity.test.ts` (#46) walks this
3259
- * schema against HQ's actual validator so ANY drift — field, type, bound,
3260
- * enum, strictness — fails CI, not just drift a fixture happens to exercise.
3261
- *
3262
- * DESIGN INVARIANT: cross-family token sums must be UNREPRESENTABLE.
3263
- *
3264
- * The two model families use different tokenizers, prices, and accounting
3265
- * conventions, so any token total that spans Claude and GPT is a lie:
3266
- *
3267
- * 1. There is no combined/total token field anywhere in the envelope.
3268
- * 2. `tokenFamilies` is strict — its only keys are `claude` and `gpt`; data
3269
- * cannot smuggle in a third "all"/"combined" slot.
3270
- * 3. The family BLOCKS are structurally different shapes with DIFFERENT keys
3271
- * (claude is a single flat block keyed on freshInput/cacheReadInput/
3272
- * cacheCreationInput; gpt is `{ roles: [...] }`). The exclusive input-tier
3273
- * COUNTS share no key name across families. The residual names shared
3274
- * between the claude block and a gpt ROLE entry are pinned to exactly
3275
- * {costUsd, model, output} (PR #32 advisory): `costUsd` is deliberate —
3276
- * USD is the one cross-family summable unit (rule 4); `model` is an
3277
- * unsummable label; `output` is the same name at DIFFERENT depths (lane
3278
- * block vs per-role entry), frozen by a tripwire test in
3279
- * `retro-envelope.test.ts` so the overlap cannot grow. Renaming `output`
3280
- * is a schemaVersion-2 wire change, deliberately not spent in v1.
3281
- * 4. Cost is per-family USD and nullable. Combined totals are allowed in USD
3282
- * only, and only as a projection-time sum of per-family USD.
3283
- *
3284
- * Field names also encode the S2/S3 reader lessons: Claude `freshInput` alone
3285
- * is not prompt size (true input context = freshInput + cacheReadInput +
3286
- * cacheCreationInput, requestId-deduped), and codex `inputInclusiveOfCache`
3287
- * already includes `cachedInput`, so `freshInputDerived` (inclusive − cached)
3288
- * is the only value safe to feed a per-token pricer.
3289
- *
3290
- * COMPLETENESS POSTURE: harvest may have no usable native log for a lane, so
3291
- * `tokenFamilies` may legitimately be absent. The closeout build gate demands
3292
- * a valid envelope, not available telemetry. A families-absent envelope keeps
3293
- * its operator-visible data gaps and is a replayable advisory HQ event, so it
3294
- * never substitutes unavailable usage with zero. The wire shape (field names,
3295
- * types, structure) stays byte-parity with HQ v1.
3296
- */
3297
- declare const RETRO_ENVELOPE_SCHEMA_VERSION = 1;
3298
- declare const retroEnvelopeV1Schema: z.ZodObject<{
3299
- agentRunId: z.ZodString;
3300
- archiveRef: z.ZodOptional<z.ZodString>;
3301
- cycles: z.ZodObject<{
3302
- gateRunsToFirstGreen: z.ZodNumber;
3303
- reviewerFixRounds: z.ZodNumber;
3304
- thermoFixRounds: z.ZodNumber;
3305
- }, z.core.$strict>;
3306
- dataGaps: z.ZodDefault<z.ZodArray<z.ZodString>>;
3307
- gates: z.ZodArray<z.ZodObject<{
3308
- cycle: z.ZodNumber;
3309
- duration: z.ZodNumber;
3310
- gate: z.ZodString;
3311
- outcome: z.ZodEnum<{
3312
- pass: "pass";
3313
- fail: "fail";
3314
- skip: "skip";
3315
- }>;
3316
- startedAt: z.ZodISODateTime;
3317
- }, z.core.$strict>>;
3318
- generatedAt: z.ZodISODateTime;
3319
- interventions: z.ZodObject<{
3320
- count: z.ZodNumber;
3321
- }, z.core.$strict>;
3322
- joinKeys: z.ZodObject<{
3323
- claudeSessionIds: z.ZodDefault<z.ZodArray<z.ZodString>>;
3324
- codexThreadIds: z.ZodDefault<z.ZodArray<z.ZodString>>;
3325
- }, z.core.$strict>;
3326
- kind: z.ZodLiteral<"retro-envelope">;
3327
- outcome: z.ZodOptional<z.ZodObject<{
3328
- mergeCheck: z.ZodOptional<z.ZodEnum<{
3329
- pass: "pass";
3330
- fail: "fail";
3331
- "not-run": "not-run";
3332
- }>>;
3333
- status: z.ZodEnum<{
3334
- success: "success";
3335
- fail: "fail";
3336
- blocked: "blocked";
3337
- "ship-with-followups": "ship-with-followups";
3338
- }>;
3339
- verdict: z.ZodOptional<z.ZodString>;
3340
- }, z.core.$strict>>;
3341
- phases: z.ZodArray<z.ZodObject<{
3342
- at: z.ZodISODateTime;
3343
- deltaSec: z.ZodOptional<z.ZodNumber>;
3344
- name: z.ZodString;
3345
- }, z.core.$strict>>;
3346
- refs: z.ZodObject<{
3347
- branch: z.ZodOptional<z.ZodString>;
3348
- epic: z.ZodOptional<z.ZodString>;
3349
- headSha: z.ZodOptional<z.ZodString>;
3350
- issue: z.ZodOptional<z.ZodString>;
3351
- prNumber: z.ZodOptional<z.ZodNumber>;
3352
- }, z.core.$strict>;
3353
- repo: z.ZodObject<{
3354
- name: z.ZodString;
3355
- owner: z.ZodString;
3356
- }, z.core.$strict>;
3357
- schemaVersion: z.ZodLiteral<1>;
3358
- tokenFamilies: z.ZodObject<{
3359
- claude: z.ZodOptional<z.ZodObject<{
3360
- cacheCreationInput: z.ZodNumber;
3361
- cacheReadInput: z.ZodNumber;
3362
- costUsd: z.ZodNullable<z.ZodNumber>;
3363
- family: z.ZodLiteral<"claude">;
3364
- freshInput: z.ZodNumber;
3365
- model: z.ZodString;
3366
- output: z.ZodNumber;
3367
- requests: z.ZodNumber;
3368
- }, z.core.$strict>>;
3369
- gpt: z.ZodOptional<z.ZodObject<{
3370
- family: z.ZodLiteral<"gpt">;
3371
- roles: z.ZodArray<z.ZodObject<{
3372
- cachedInput: z.ZodNumber;
3373
- costUsd: z.ZodNullable<z.ZodNumber>;
3374
- freshInputDerived: z.ZodNumber;
3375
- inputInclusiveOfCache: z.ZodNumber;
3376
- model: z.ZodString;
3377
- output: z.ZodNumber;
3378
- reasoningOutput: z.ZodNumber;
3379
- role: z.ZodString;
3380
- threadId: z.ZodOptional<z.ZodString>;
3381
- }, z.core.$strict>>;
3382
- }, z.core.$strict>>;
3383
- }, z.core.$strict>;
3384
- wallClock: z.ZodObject<{
3385
- endTs: z.ZodISODateTime;
3386
- startTs: z.ZodISODateTime;
3387
- totalSec: z.ZodNumber;
3388
- }, z.core.$strict>;
3389
- }, z.core.$strict>;
3390
- type RetroEnvelope = z.infer<typeof retroEnvelopeV1Schema>;
3391
- /**
3392
- * Versioned payload validators, keyed by schema major. Unknown majors never
3393
- * reach these — {@link parseRetroEnvelope} returns them raw and marked
3394
- * degraded, mirroring HQ's ingest skew posture (stored raw, never dropped).
3395
- */
3396
- declare const RETRO_ENVELOPE_VALIDATORS: Record<number, z.ZodType<RetroEnvelope, unknown>>;
3397
- declare const SUPPORTED_RETRO_ENVELOPE_SCHEMA_VERSIONS: readonly number[];
3398
- /** The `schemaVersion` a candidate declares, or undefined when unreadable. */
3399
- declare const retroEnvelopeSchemaVersionOf: (candidate: unknown) => number | undefined;
3400
- type ParsedRetroEnvelope = {
3401
- disposition: "trusted";
3402
- envelope: RetroEnvelope;
3403
- schemaVersion: number;
3404
- } | {
3405
- disposition: "degraded";
3406
- raw: unknown;
3407
- schemaVersion: number | undefined;
3518
+ workerId?: string | readonly string[];
3519
+ }
3520
+ interface FactoryTraceDiagnostic {
3521
+ code: "malformed-json" | "invalid-event" | "unknown-event-type" | "unknown-event-version";
3522
+ event?: {
3523
+ eventId: string;
3524
+ eventType: string;
3525
+ issue?: number;
3526
+ pr?: number;
3527
+ repo: string;
3528
+ threadId?: string;
3529
+ workerId?: string;
3530
+ };
3531
+ file: string;
3532
+ line: number;
3533
+ message: string;
3534
+ }
3535
+ interface ScanFactoryTraceOptions {
3536
+ diagnosticsOnly?: boolean;
3537
+ filters?: FactoryTraceFilters;
3538
+ from: string;
3539
+ malformed?: "diagnostic" | "throw";
3540
+ repoRoot: string;
3541
+ to: string;
3542
+ }
3543
+ interface ScanFactoryTraceResult {
3544
+ diagnostics: FactoryTraceDiagnostic[];
3545
+ events: ReadableFactoryTraceEvent[];
3546
+ }
3547
+ interface ScanFactoryTraceDiagnosticsOptions {
3548
+ filters?: FactoryTraceFilters;
3549
+ from: string;
3550
+ repoRoot: string;
3551
+ to: string;
3552
+ }
3553
+ declare const validateFactoryTraceEvent: (event: unknown) => FactoryTraceEvent;
3554
+ declare const toFactoryTraceEnvelope: (event: FactoryTraceEvent) => {
3555
+ createdAt: string;
3556
+ envelope: 1;
3557
+ eventId: string;
3558
+ payload: unknown;
3559
+ repo: string;
3560
+ type: string;
3561
+ typeVersion: number;
3562
+ issue?: number | undefined;
3563
+ pr?: number | undefined;
3564
+ thread?: string | undefined;
3565
+ worker?: string | undefined;
3408
3566
  };
3567
+ interface AppendFactoryTraceEventResult {
3568
+ event: FactoryTraceEvent;
3569
+ filePath: string;
3570
+ mirrorDiagnostics: TraceMirrorDiagnostic[];
3571
+ }
3572
+ declare const scanFactoryTraceEvents: ({
3573
+ diagnosticsOnly,
3574
+ filters,
3575
+ from,
3576
+ malformed,
3577
+ repoRoot,
3578
+ to
3579
+ }: ScanFactoryTraceOptions) => ScanFactoryTraceResult;
3409
3580
  /**
3410
- * Parses a candidate against the versioned validators. A recognized major is
3411
- * validated typed-only (throws on an invalid known-version payload); an unknown
3412
- * major is round-tripped RAW and marked degraded the retained payload is the
3413
- * exact input object, never a coerced projection. Mirrors the HQ ingest seam so
3414
- * the two sides agree on the skew posture.
3415
- */
3416
- declare const parseRetroEnvelope: (candidate: unknown) => ParsedRetroEnvelope;
3417
- /**
3418
- * Whether harvest recorded at least one token family. This is an operator
3419
- * summary predicate, not a delivery gate: a families-absent envelope remains
3420
- * valid and replayable when its data gaps explain why telemetry is unavailable.
3581
+ * Diagnostics-only trace read (#707). Scans the shard window purely to surface
3582
+ * malformed / unknown-record diagnostics, without materializing (and then
3583
+ * discarding) every well-formed event. Malformed shards are always collected as
3584
+ * diagnostics, never thrown. Use when a consumer wants shard-corruption signal
3585
+ * but no event payloads e.g. epic closeout after the orchestrator-metrics
3586
+ * removal.
3421
3587
  */
3422
- declare const isRetroEnvelopeWireComplete: (envelope: Pick<RetroEnvelope, "tokenFamilies">) => boolean;
3423
- /** Epic anchor for an envelope: refs.epic, else refs.issue, else the PR. */
3424
- declare const retroEpicReference: (refs: RetroEnvelope["refs"]) => string | undefined;
3588
+ declare const scanFactoryTraceDiagnostics: ({
3589
+ filters,
3590
+ from,
3591
+ repoRoot,
3592
+ to
3593
+ }: ScanFactoryTraceDiagnosticsOptions) => FactoryTraceDiagnostic[];
3425
3594
  //#endregion
3426
3595
  //#region src/interior-telemetry/gate-timing.d.ts
3427
3596
  declare const GATE_TIMING_SCHEMA_VERSION = 1;
@@ -3716,17 +3885,100 @@ declare const renderPrBodySections: ({
3716
3885
  reviewProof?: PrReviewProof;
3717
3886
  verifyProof?: PrVerifyProof;
3718
3887
  }) => string;
3888
+ declare namespace boundary_manifest_d_exports {
3889
+ export { BOUNDARY_CLOSEOUT_DEFAULT_RUNG, BOUNDARY_MANIFEST_SCHEMA_VERSION, BoundaryManifest, BoundaryManifestExtraction, BoundaryManifestParse, FACTORY_BOUNDARY_FENCE_LANG, boundaryManifestSchema, closeoutRungFor, extractBoundaryManifestBlock, manifestContentHash, parseBoundaryManifest, rungMeetsMinimum, specContentHash };
3890
+ }
3891
+ declare const FACTORY_BOUNDARY_FENCE_LANG = "factory-boundary";
3892
+ declare const BOUNDARY_MANIFEST_SCHEMA_VERSION = 1;
3893
+ declare const BOUNDARY_CLOSEOUT_DEFAULT_RUNG: EvidenceReviewRung;
3894
+ declare const rungMeetsMinimum: (rung: EvidenceReviewRung, minimum: EvidenceReviewRung) => boolean;
3895
+ declare const boundaryManifestBaseSchema: z.ZodObject<{
3896
+ boundary: z.ZodString;
3897
+ closeout: z.ZodOptional<z.ZodObject<{
3898
+ review: z.ZodEnum<{
3899
+ oracle: "oracle";
3900
+ "independent-model": "independent-model";
3901
+ human: "human";
3902
+ }>;
3903
+ }, z.core.$loose>>;
3904
+ declaredBy: z.ZodString;
3905
+ prs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
3906
+ schemaVersion: z.ZodLiteral<1>;
3907
+ topology: z.ZodEnum<{
3908
+ flagged: "flagged";
3909
+ "each-to-main": "each-to-main";
3910
+ stacked: "stacked";
3911
+ }>;
3912
+ waves: z.ZodArray<z.ZodObject<{
3913
+ autoMerge: z.ZodOptional<z.ZodBoolean>;
3914
+ issues: z.ZodArray<z.ZodNumber>;
3915
+ name: z.ZodString;
3916
+ review: z.ZodEnum<{
3917
+ oracle: "oracle";
3918
+ "independent-model": "independent-model";
3919
+ human: "human";
3920
+ }>;
3921
+ }, z.core.$loose>>;
3922
+ }, z.core.$loose>;
3923
+ declare const boundaryManifestSchema: z.ZodObject<{
3924
+ boundary: z.ZodString;
3925
+ closeout: z.ZodOptional<z.ZodObject<{
3926
+ review: z.ZodEnum<{
3927
+ oracle: "oracle";
3928
+ "independent-model": "independent-model";
3929
+ human: "human";
3930
+ }>;
3931
+ }, z.core.$loose>>;
3932
+ declaredBy: z.ZodString;
3933
+ prs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
3934
+ schemaVersion: z.ZodLiteral<1>;
3935
+ topology: z.ZodEnum<{
3936
+ flagged: "flagged";
3937
+ "each-to-main": "each-to-main";
3938
+ stacked: "stacked";
3939
+ }>;
3940
+ waves: z.ZodArray<z.ZodObject<{
3941
+ autoMerge: z.ZodOptional<z.ZodBoolean>;
3942
+ issues: z.ZodArray<z.ZodNumber>;
3943
+ name: z.ZodString;
3944
+ review: z.ZodEnum<{
3945
+ oracle: "oracle";
3946
+ "independent-model": "independent-model";
3947
+ human: "human";
3948
+ }>;
3949
+ }, z.core.$loose>>;
3950
+ }, z.core.$loose>;
3951
+ type BoundaryManifest = z.infer<typeof boundaryManifestBaseSchema>;
3952
+ type BoundaryManifestExtraction = {
3953
+ ok: true;
3954
+ blockText: string;
3955
+ } | {
3956
+ ok: false;
3957
+ error: string;
3958
+ };
3959
+ declare const extractBoundaryManifestBlock: (issueBody: string) => BoundaryManifestExtraction;
3960
+ declare const manifestContentHash: (blockText: string) => string;
3961
+ declare const specContentHash: (issueBody: string) => string;
3962
+ type BoundaryManifestParse = {
3963
+ ok: true;
3964
+ manifest: BoundaryManifest;
3965
+ manifestHash: string;
3966
+ } | {
3967
+ ok: false;
3968
+ error: string;
3969
+ };
3970
+ declare const parseBoundaryManifest: (issueBody: string) => BoundaryManifestParse;
3971
+ declare const closeoutRungFor: (manifest: BoundaryManifest) => EvidenceReviewRung;
3719
3972
  //#endregion
3720
- //#region src/pr-readiness/review-requiredness.d.ts
3721
- interface DocsOnlyReviewBypassState {
3722
- applies: boolean;
3973
+ //#region src/demand-resolution.d.ts
3974
+ /** The boundary-manifest wave demand that applies to one pull request. */
3975
+ interface WaveReviewDemand {
3976
+ autoMerge: boolean;
3977
+ review: EvidenceReviewRung;
3978
+ wave: string;
3723
3979
  }
3724
- declare const resolveDocsOnlyReviewBypassState: (input: {
3725
- classification: DiffClassification;
3726
- docsOnlyReviewBypass?: boolean;
3727
- }) => DocsOnlyReviewBypassState;
3728
3980
  declare namespace readiness_evaluation_d_exports {
3729
- export { CORRECTNESS_UNTYPED_REVIEW_BLOCKER_REASON, DRAFT_BLOCKER_REASON, DocsOnlyReviewBypassState, EvaluationInput, ManagedReadinessLedger, PENDING_CHECKS_BLOCKER_REASON_PREFIX, PreviewDeployProof, PreviewSeedStatus, READINESS_REPAIR_CODES, RENDER_PR_BODY_SECTIONS_BLOCKER_REASON, ReadinessRepair, ReadinessStatus, SCHEMA_VERSION, SECURITY_UNTYPED_REVIEW_BLOCKER_REASON, evaluateReadiness, managedReadinessLedgerSchema, readinessExitCode, readinessRepairSchema, resolveDocsOnlyReviewBypassState, validateManagedReadinessLedger };
3981
+ export { CORRECTNESS_UNTYPED_REVIEW_BLOCKER_REASON, DRAFT_BLOCKER_REASON, EvaluationInput, ManagedReadinessLedger, PENDING_CHECKS_BLOCKER_REASON_PREFIX, PreviewDeployProof, PreviewSeedStatus, READINESS_REPAIR_CODES, RENDER_PR_BODY_SECTIONS_BLOCKER_REASON, ReadinessRepair, ReadinessStatus, SCHEMA_VERSION, SECURITY_UNTYPED_REVIEW_BLOCKER_REASON, evaluateReadiness, managedReadinessLedgerSchema, readinessExitCode, readinessRepairSchema, validateManagedReadinessLedger };
3730
3982
  }
3731
3983
  declare const CORRECTNESS_UNTYPED_REVIEW_BLOCKER_REASON = "Correctness review proof is not a head-bound typed findings verdict; re-run pr:review with a valid findings file.";
3732
3984
  declare const SECURITY_UNTYPED_REVIEW_BLOCKER_REASON = "Security review proof is not a head-bound typed findings verdict; re-run pr:review with a valid findings file.";
@@ -3757,7 +4009,6 @@ interface EvaluationInput {
3757
4009
  verificationProof?: VerificationProofState;
3758
4010
  docsOnlyVerifyBaselineHeadShas?: string[];
3759
4011
  docsOnlySinceReviewProof?: boolean;
3760
- docsOnlyReviewBypass?: boolean;
3761
4012
  externalRequiredChecks?: RequiredCheck[];
3762
4013
  evidenceEnvelopes?: LoadedEvidenceEnvelope[];
3763
4014
  mergeBaseSha?: string;
@@ -3772,6 +4023,7 @@ interface EvaluationInput {
3772
4023
  };
3773
4024
  handledCommentSessionId?: string;
3774
4025
  handledCommentClearedAt?: string;
4026
+ waveReviewDemand?: Pick<WaveReviewDemand, "review" | "wave">;
3775
4027
  }
3776
4028
  declare const evaluateReadiness: (input: EvaluationInput) => {
3777
4029
  blockingReasons: string[];
@@ -4134,90 +4386,6 @@ declare const isProductionHqUrl: (url: string) => boolean;
4134
4386
  * surfaced with actionable guidance; any non-2xx throws.
4135
4387
  */
4136
4388
  declare const publishEpicStructure: (args: PublishEpicStructureArgs) => Promise<PublishEpicStructureResult>;
4137
- declare namespace boundary_manifest_d_exports {
4138
- export { BOUNDARY_CLOSEOUT_DEFAULT_RUNG, BOUNDARY_MANIFEST_SCHEMA_VERSION, BoundaryManifest, BoundaryManifestExtraction, BoundaryManifestParse, FACTORY_BOUNDARY_FENCE_LANG, boundaryManifestSchema, closeoutRungFor, extractBoundaryManifestBlock, manifestContentHash, parseBoundaryManifest, rungMeetsMinimum, specContentHash };
4139
- }
4140
- declare const FACTORY_BOUNDARY_FENCE_LANG = "factory-boundary";
4141
- declare const BOUNDARY_MANIFEST_SCHEMA_VERSION = 1;
4142
- declare const BOUNDARY_CLOSEOUT_DEFAULT_RUNG: EvidenceReviewRung;
4143
- declare const rungMeetsMinimum: (rung: EvidenceReviewRung, minimum: EvidenceReviewRung) => boolean;
4144
- declare const boundaryManifestBaseSchema: z.ZodObject<{
4145
- boundary: z.ZodString;
4146
- closeout: z.ZodOptional<z.ZodObject<{
4147
- review: z.ZodEnum<{
4148
- oracle: "oracle";
4149
- "independent-model": "independent-model";
4150
- human: "human";
4151
- }>;
4152
- }, z.core.$loose>>;
4153
- declaredBy: z.ZodString;
4154
- prs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
4155
- schemaVersion: z.ZodLiteral<1>;
4156
- topology: z.ZodEnum<{
4157
- flagged: "flagged";
4158
- "each-to-main": "each-to-main";
4159
- stacked: "stacked";
4160
- }>;
4161
- waves: z.ZodArray<z.ZodObject<{
4162
- autoMerge: z.ZodOptional<z.ZodBoolean>;
4163
- issues: z.ZodArray<z.ZodNumber>;
4164
- name: z.ZodString;
4165
- review: z.ZodEnum<{
4166
- oracle: "oracle";
4167
- "independent-model": "independent-model";
4168
- human: "human";
4169
- }>;
4170
- }, z.core.$loose>>;
4171
- }, z.core.$loose>;
4172
- declare const boundaryManifestSchema: z.ZodObject<{
4173
- boundary: z.ZodString;
4174
- closeout: z.ZodOptional<z.ZodObject<{
4175
- review: z.ZodEnum<{
4176
- oracle: "oracle";
4177
- "independent-model": "independent-model";
4178
- human: "human";
4179
- }>;
4180
- }, z.core.$loose>>;
4181
- declaredBy: z.ZodString;
4182
- prs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
4183
- schemaVersion: z.ZodLiteral<1>;
4184
- topology: z.ZodEnum<{
4185
- flagged: "flagged";
4186
- "each-to-main": "each-to-main";
4187
- stacked: "stacked";
4188
- }>;
4189
- waves: z.ZodArray<z.ZodObject<{
4190
- autoMerge: z.ZodOptional<z.ZodBoolean>;
4191
- issues: z.ZodArray<z.ZodNumber>;
4192
- name: z.ZodString;
4193
- review: z.ZodEnum<{
4194
- oracle: "oracle";
4195
- "independent-model": "independent-model";
4196
- human: "human";
4197
- }>;
4198
- }, z.core.$loose>>;
4199
- }, z.core.$loose>;
4200
- type BoundaryManifest = z.infer<typeof boundaryManifestBaseSchema>;
4201
- type BoundaryManifestExtraction = {
4202
- ok: true;
4203
- blockText: string;
4204
- } | {
4205
- ok: false;
4206
- error: string;
4207
- };
4208
- declare const extractBoundaryManifestBlock: (issueBody: string) => BoundaryManifestExtraction;
4209
- declare const manifestContentHash: (blockText: string) => string;
4210
- declare const specContentHash: (issueBody: string) => string;
4211
- type BoundaryManifestParse = {
4212
- ok: true;
4213
- manifest: BoundaryManifest;
4214
- manifestHash: string;
4215
- } | {
4216
- ok: false;
4217
- error: string;
4218
- };
4219
- declare const parseBoundaryManifest: (issueBody: string) => BoundaryManifestParse;
4220
- declare const closeoutRungFor: (manifest: BoundaryManifest) => EvidenceReviewRung;
4221
4389
  //#endregion
4222
4390
  //#region src/review-focus.d.ts
4223
4391
  declare const REVIEW_FOCUS_SECTION = "Review focus";
@@ -4323,7 +4491,7 @@ declare function assertWorkerCheckoutAllowed({
4323
4491
  interface CreateProgramOptions {
4324
4492
  actions?: {
4325
4493
  boundaryCheck?: BoundaryCheckAction;
4326
- canaryVerify?: CanaryVerifyAction;
4494
+ demandWaive?: DemandWaiveAction;
4327
4495
  prMergeCheck?: PrMergeCheckAction;
4328
4496
  prPublish?: PrPublishAction;
4329
4497
  prReady?: PrReadyAction;
@@ -4335,4 +4503,4 @@ interface CreateProgramOptions {
4335
4503
  declare function createProgram(options?: CreateProgramOptions): Command;
4336
4504
  declare function run(argv?: string[]): Promise<void>;
4337
4505
  //#endregion
4338
- export { type AppendFactoryTraceEventResult, type AssembledReviewPrompt, type BoundaryCheckArgs, type BoundaryCheckDependencies, type BoundaryCheckProofRecord, type BuildEpicStructureEventInput, type BuildRetroEnvelopeInput, type CloudflareAccessServiceToken, CreateProgramOptions, DEFAULT_FACTORY_REPOSITORY, type DagDocument, EPIC_STRUCTURE_NODE_STATUSES, EPIC_STRUCTURE_SCHEMA_VERSION, type EpicStructureEvent, type EpicStructureGraphPayload, type EpicStructureNodeStatus, EpicStructureValidationError, type EvidenceEmitArgs, type EvidenceEmitDependencies, type EvidenceEmitResult, type FactoryCliInvocation, FactoryCliInvocationSchema, type FactoryProjectProfile, type FactoryTraceDiagnostic, type FactoryTraceEnvelope, type FactoryTraceEvent, type FindingDisposition, type FindingLedgerEntry, type FollowUpAction, FollowUpActionSchema, type IssueReviewFocus, type LadderDispositionDeclaration, type ParsedRetroEnvelope, type PrPublishArgs, type PrPublishDependencies, PrPublishFollowUpError, type PrPublishFollowUpOutcome, type PrPublishHandoff, type PrPublishResult, type PrReadyArgs, type PrReadyProof, type PublishEpicStructureArgs, type PublishEpicStructureResult, type PublishFollowUpPlan, RETRO_ENVELOPE_SCHEMA_VERSION, RETRO_ENVELOPE_VALIDATORS, REVIEW_FOCUS_SECTION, type RetroEnvelope, type ReviewGateNotRequiredProof, type ReviewGateTraceIdentity, type ReviewLadderCycle, type ReviewLadderEvaluation, type ReviewLadderPolicy, type ReviewLadderStageEvent, type ReviewLadderTraceIdentity, type ReviewPromptSection, type ReviewPromptSectionProvenance, SUPPORTED_RETRO_ENVELOPE_SCHEMA_VERSIONS, type ScanFactoryTraceDiagnosticsOptions, type ScanFactoryTraceOptions, type ScanFactoryTraceResult, type TraceMirrorDiagnostic, type TraceSink, type TraceWriteResult, type TraceWriteSinks, type VerificationReuse, WorkerCheckoutGuardError, type WorkerCloseoutLessonsTraceEvent, appendReviewLadderStageTraceEvent, appendWithTraceSinks, assembleReviewPrompt, assertWorkerCheckoutAllowed, blockingLadderFindings, boundary_manifest_d_exports as boundaryManifest, boundary_review_proof_d_exports as boundaryReviewProof, buildEpicStructureEvent, buildEpicStructurePayload, buildEvidenceEnvelope, buildRetroEnvelope, buildReviewGateNotRequiredTraceEvent, buildReviewLadderStageTraceEvent, comment_provenance_d_exports as commentProvenance, createLocalJsonlTraceSink, createProgram, doctorProjectProfile, epicStructureEventId, evaluateReviewLadder, evidenceEnvelopeFilename, findingKey, followUpFromArgv, inferFixedInThreadDispositions, isProductionHqUrl, isRetroEnvelopeWireComplete, loadProjectProfile, normalizeIssueComments, openLadderFindings, parseRetroEnvelope, planPublishFollowUp, worktree_held_branch_d_exports as prMergePreflight, pr_body_metadata_d_exports as prReadinessBodyMetadata, readiness_evaluation_d_exports as prReadinessEvaluation, external_evidence_d_exports as prReadinessExternalEvidence, merge_identity_d_exports as prReadinessMergeIdentity, post_readiness_comments_d_exports as prReadinessPostComments, pr_body_renderer_d_exports as prReadinessPrBodyRenderer, proof_identity_d_exports as prReadinessProofIdentity, review_proof_d_exports as prReadinessReviewProof, status_check_rollup_d_exports as prReadinessStatusChecks, verification_proof_d_exports as prReadinessVerificationProof, publishEpicStructure, readPrMergeCheckProof, readPrReadyProof, readPrReviewProof, resolveDocsOnlyReviewBypass, resolveFactoryRepository, resolveFindingBlocking, resolveReviewFindingCategory, resolveReviewFindingSeverity, resolveReviewLadderPolicy, resolveTraceWriteSinks, retroEnvelopeSchemaVersionOf, retroEnvelopeV1Schema, retroEpicReference, reviewCycleStateFor, reviewFocusFromIssueBody, reviewPromptSectionSchema, reviewPromptSectionsSchema, run, runBoundaryCheck, runEvidenceEmit, runPrMergeCheck, runPrPublish, runPrReady, runPrReview, runPrVerify, scanFactoryTraceDiagnostics, scanFactoryTraceEvents, staleRepeatLadderFindings, toFactoryTraceEnvelope, tryAppendReviewGateNotRequiredTraceEvent, tryAppendReviewLadderStageTraceEvent, validateBoundaryCheckProof, validateDagDocument, validateFactoryTraceEvent, validatePrMergeCheckProof, validatePrReadyProof, validatePrReviewProof, validatePrVerifyProof, worktree_scratch_files_d_exports as worktreeScratchFiles };
4506
+ export { type AppendFactoryTraceEventResult, type AssembledReviewPrompt, type BoundaryCheckArgs, type BoundaryCheckDependencies, type BoundaryCheckProofRecord, type BuildEpicStructureEventInput, type BuildRetroEnvelopeInput, type CloudflareAccessServiceToken, CreateProgramOptions, DEFAULT_DEMAND_WAIVER_PATH, DEFAULT_FACTORY_REPOSITORY, type DagDocument, type DemandWaiveArgs, type DemandWaiveDependencies, DemandWaiveRefusalError, type DemandWaiver, type DemandWaiverStore, EPIC_STRUCTURE_NODE_STATUSES, EPIC_STRUCTURE_SCHEMA_VERSION, type EpicStructureEvent, type EpicStructureGraphPayload, type EpicStructureNodeStatus, EpicStructureValidationError, type EvidenceEmitArgs, type EvidenceEmitDependencies, type EvidenceEmitResult, type FactoryCliInvocation, FactoryCliInvocationSchema, type FactoryProjectProfile, type FactoryTraceDiagnostic, type FactoryTraceEnvelope, type FactoryTraceEvent, type FindingDisposition, type FindingLedgerEntry, type FollowUpAction, FollowUpActionSchema, type IssueReviewFocus, type LadderDispositionDeclaration, MERGE_FREEZE_APP_SLUG, MERGE_FREEZE_CHECK_NAME, type MergeFreezeState, type ParsedRetroEnvelope, type PrPublishArgs, type PrPublishDependencies, PrPublishFollowUpError, type PrPublishFollowUpOutcome, type PrPublishHandoff, type PrPublishResult, type PrReadyArgs, type PrReadyProof, type PublishEpicStructureArgs, type PublishEpicStructureResult, type PublishFollowUpPlan, RETRO_ENVELOPE_SCHEMA_VERSION, RETRO_ENVELOPE_VALIDATORS, REVIEW_FOCUS_SECTION, type RetroEnvelope, type ReviewGateNotRequiredProof, type ReviewGateTraceIdentity, type ReviewLadderCycle, type ReviewLadderEvaluation, type ReviewLadderPolicy, type ReviewLadderStageEvent, type ReviewLadderTraceIdentity, type ReviewPromptSection, type ReviewPromptSectionProvenance, SUPPORTED_RETRO_ENVELOPE_SCHEMA_VERSIONS, type ScanFactoryTraceDiagnosticsOptions, type ScanFactoryTraceOptions, type ScanFactoryTraceResult, type TraceMirrorDiagnostic, type TraceSink, type TraceWriteResult, type TraceWriteSinks, type VerificationReuse, type WaivedDemand, WorkerCheckoutGuardError, type WorkerCloseoutLessonsTraceEvent, appendReviewLadderStageTraceEvent, appendWithTraceSinks, applyDemandWaiver, assembleReviewPrompt, assertWorkerCheckoutAllowed, authorizeDemandWaiver, blockingLadderFindings, boundary_manifest_d_exports as boundaryManifest, boundary_review_proof_d_exports as boundaryReviewProof, buildEpicStructureEvent, buildEpicStructurePayload, buildEvidenceEnvelope, buildRetroEnvelope, buildReviewGateNotRequiredTraceEvent, buildReviewLadderStageTraceEvent, comment_provenance_d_exports as commentProvenance, createLocalJsonlTraceSink, createProgram, doctorProjectProfile, epicStructureEventId, evaluateReviewLadder, evidenceEnvelopeFilename, findingKey, followUpFromArgv, inferFixedInThreadDispositions, isProductionHqUrl, isRetroEnvelopeWireComplete, loadProjectProfile, normalizeIssueComments, openLadderFindings, parseRetroEnvelope, planPublishFollowUp, worktree_held_branch_d_exports as prMergePreflight, pr_body_metadata_d_exports as prReadinessBodyMetadata, readiness_evaluation_d_exports as prReadinessEvaluation, external_evidence_d_exports as prReadinessExternalEvidence, merge_identity_d_exports as prReadinessMergeIdentity, post_readiness_comments_d_exports as prReadinessPostComments, pr_body_renderer_d_exports as prReadinessPrBodyRenderer, proof_identity_d_exports as prReadinessProofIdentity, review_proof_d_exports as prReadinessReviewProof, status_check_rollup_d_exports as prReadinessStatusChecks, verification_proof_d_exports as prReadinessVerificationProof, publishEpicStructure, readDemandWaivers, readPrMergeCheckProof, readPrReadyProof, readPrReviewProof, resolveFactoryRepository, resolveFindingBlocking, resolveReviewFindingCategory, resolveReviewFindingSeverity, resolveReviewLadderPolicy, resolveTraceWriteSinks, retroEnvelopeSchemaVersionOf, retroEnvelopeV1Schema, retroEpicReference, reviewCycleStateFor, reviewFocusFromIssueBody, reviewPromptSectionSchema, reviewPromptSectionsSchema, run, runBoundaryCheck, runDemandWaive, runEvidenceEmit, runPrMergeCheck, runPrPublish, runPrReady, runPrReview, runPrVerify, scanFactoryTraceDiagnostics, scanFactoryTraceEvents, selectWaiversForCandidate, staleRepeatLadderFindings, toFactoryTraceEnvelope, tryAppendReviewGateNotRequiredTraceEvent, tryAppendReviewLadderStageTraceEvent, validateBoundaryCheckProof, validateDagDocument, validateDemandWaiverStore, validateFactoryTraceEvent, validateMergeFreezeState, validatePrMergeCheckProof, validatePrReadyProof, validatePrReviewProof, validatePrVerifyProof, waivedDemandNotice, waivedDemandSchema, worktree_scratch_files_d_exports as worktreeScratchFiles };