@patronage/software-factory 1.0.0-alpha.2 → 1.0.0-alpha.21

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
@@ -1,8 +1,98 @@
1
1
  import { existsSync, readFileSync, rmSync } from "node:fs";
2
2
  import { Command } from "commander";
3
3
  import { z } from "zod";
4
- import { readFile } from "node:fs/promises";
4
+ import { PreviewProofRegistration } from "@patronage/factory-ci";
5
5
 
6
+ //#region src/review-rungs.d.ts
7
+ declare const EVIDENCE_REVIEW_RUNGS: readonly ["independent-model", "oracle", "human"];
8
+ type EvidenceReviewRung = (typeof EVIDENCE_REVIEW_RUNGS)[number];
9
+ declare namespace boundary_manifest_d_exports {
10
+ export { BOUNDARY_CLOSEOUT_DEFAULT_RUNG, BOUNDARY_MANIFEST_SCHEMA_VERSION, BoundaryManifest, BoundaryManifestExtraction, BoundaryManifestParse, FACTORY_BOUNDARY_FENCE_LANG, boundaryManifestSchema, closeoutRungFor, extractBoundaryManifestBlock, manifestContentHash, parseBoundaryManifest, rungMeetsMinimum, specContentHash };
11
+ }
12
+ declare const FACTORY_BOUNDARY_FENCE_LANG = "factory-boundary";
13
+ declare const BOUNDARY_MANIFEST_SCHEMA_VERSION = 1;
14
+ declare const BOUNDARY_CLOSEOUT_DEFAULT_RUNG: EvidenceReviewRung;
15
+ declare const rungMeetsMinimum: (rung: EvidenceReviewRung, minimum: EvidenceReviewRung) => boolean;
16
+ declare const boundaryManifestBaseSchema: z.ZodObject<{
17
+ boundary: z.ZodString;
18
+ closeout: z.ZodOptional<z.ZodObject<{
19
+ review: z.ZodEnum<{
20
+ oracle: "oracle";
21
+ "independent-model": "independent-model";
22
+ human: "human";
23
+ }>;
24
+ }, z.core.$loose>>;
25
+ declaredBy: z.ZodString;
26
+ integrationBranch: z.ZodOptional<z.ZodString>;
27
+ schemaVersion: z.ZodLiteral<1>;
28
+ topology: z.ZodEnum<{
29
+ flagged: "flagged";
30
+ "each-to-main": "each-to-main";
31
+ stacked: "stacked";
32
+ "each-to-epic": "each-to-epic";
33
+ }>;
34
+ waves: z.ZodArray<z.ZodObject<{
35
+ autoMerge: z.ZodOptional<z.ZodBoolean>;
36
+ issues: z.ZodArray<z.ZodNumber>;
37
+ name: z.ZodString;
38
+ review: z.ZodEnum<{
39
+ oracle: "oracle";
40
+ "independent-model": "independent-model";
41
+ human: "human";
42
+ }>;
43
+ }, z.core.$loose>>;
44
+ }, z.core.$loose>;
45
+ declare const boundaryManifestSchema: z.ZodObject<{
46
+ boundary: z.ZodString;
47
+ closeout: z.ZodOptional<z.ZodObject<{
48
+ review: z.ZodEnum<{
49
+ oracle: "oracle";
50
+ "independent-model": "independent-model";
51
+ human: "human";
52
+ }>;
53
+ }, z.core.$loose>>;
54
+ declaredBy: z.ZodString;
55
+ integrationBranch: z.ZodOptional<z.ZodString>;
56
+ schemaVersion: z.ZodLiteral<1>;
57
+ topology: z.ZodEnum<{
58
+ flagged: "flagged";
59
+ "each-to-main": "each-to-main";
60
+ stacked: "stacked";
61
+ "each-to-epic": "each-to-epic";
62
+ }>;
63
+ waves: z.ZodArray<z.ZodObject<{
64
+ autoMerge: z.ZodOptional<z.ZodBoolean>;
65
+ issues: z.ZodArray<z.ZodNumber>;
66
+ name: z.ZodString;
67
+ review: z.ZodEnum<{
68
+ oracle: "oracle";
69
+ "independent-model": "independent-model";
70
+ human: "human";
71
+ }>;
72
+ }, z.core.$loose>>;
73
+ }, z.core.$loose>;
74
+ type BoundaryManifest = z.infer<typeof boundaryManifestBaseSchema>;
75
+ type BoundaryManifestExtraction = {
76
+ ok: true;
77
+ blockText: string;
78
+ } | {
79
+ ok: false;
80
+ error: string;
81
+ };
82
+ declare const extractBoundaryManifestBlock: (issueBody: string) => BoundaryManifestExtraction;
83
+ declare const manifestContentHash: (blockText: string) => string;
84
+ declare const specContentHash: (issueBody: string) => string;
85
+ type BoundaryManifestParse = {
86
+ ok: true;
87
+ manifest: BoundaryManifest;
88
+ manifestHash: string;
89
+ } | {
90
+ ok: false;
91
+ error: string;
92
+ };
93
+ declare const parseBoundaryManifest: (issueBody: string) => BoundaryManifestParse;
94
+ declare const closeoutRungFor: (manifest: BoundaryManifest) => EvidenceReviewRung;
95
+ //#endregion
6
96
  //#region src/github-issue-comments.d.ts
7
97
  interface GithubIssueCommentApi {
8
98
  body: string;
@@ -127,6 +217,24 @@ declare const selectBoundaryReviewProof: (comments: GithubIssueComment[], bounda
127
217
  declare const boundaryReviewProofAuthorsSeen: (comments: GithubIssueComment[], boundary: string) => string[];
128
218
  declare const undispositionedBlockingFindings: (proof: BoundaryReviewProof) => string[];
129
219
  //#endregion
220
+ //#region src/boundary-membership-graph.d.ts
221
+ /** The boundary-manifest wave demand that applies to one pull request. */
222
+ interface WaveReviewDemand {
223
+ autoMerge: boolean;
224
+ review: EvidenceReviewRung;
225
+ wave: string;
226
+ }
227
+ interface BoundaryPullRequestRef {
228
+ baseRefName?: string;
229
+ headRefOid?: string;
230
+ headRefName?: string;
231
+ mergeCommitOid?: string;
232
+ /** GitHub's merge timestamp; the merge-ordering fact topology reads (#821). */
233
+ mergedAt?: string;
234
+ number: number;
235
+ state: "OPEN" | "CLOSED" | "MERGED";
236
+ }
237
+ //#endregion
130
238
  //#region src/hq-ingest-sink.d.ts
131
239
  interface HqIngestDependencies {
132
240
  /**
@@ -145,8 +253,6 @@ interface HqIngestDependencies {
145
253
  * `timeoutMs`: see the note there.
146
254
  */
147
255
  journalFlushBudgetMs?: number;
148
- /** @deprecated Legacy sidecars are now streamed directly; retained for API compatibility. */
149
- sidecarReclaimMs?: number;
150
256
  /**
151
257
  * Setup budget for callers that own the process lifetime — honored AS GIVEN,
152
258
  * above the `DEFAULT_HQ_INGEST_TIMEOUT_MS` ceiling that clamps `timeoutMs`.
@@ -182,14 +288,17 @@ interface HqSpoolEntryOutcome {
182
288
  detail?: string;
183
289
  eventId: string;
184
290
  kind: string;
291
+ /**
292
+ * `true` when HQ refused the content as schema-invalid (HTTP 422, #739).
293
+ * The same bytes get the same verdict on every retry under the current
294
+ * ingest schema, so retrying without a schema change cannot succeed.
295
+ * Distinct from `undeliverable`: an HQ schema fix can still admit these
296
+ * bytes, so eviction is an operator decision (`hq:flush --evict-permanent`),
297
+ * never automatic.
298
+ */
299
+ permanent?: boolean;
185
300
  spool: string;
186
301
  /**
187
- * `migrated` belongs to the legacy JSONL journal only: the row was moved
188
- * into the current spool without being delivered. The spool pass that runs
189
- * after it in the same drain supersedes that line with a real outcome when
190
- * it gets to the row; a `migrated` line that survives the run means the row
191
- * is still waiting.
192
- *
193
302
  * `undeliverable` is the one terminal verdict (#445). Every other status
194
303
  * describes a moment: HQ was unreachable, HQ refused this content today, the
195
304
  * row moved. Retrying is meaningful for all of them. A wrong-origin entry is
@@ -198,15 +307,20 @@ interface HqSpoolEntryOutcome {
198
307
  * run. Leaving it spooled asks the operator to retry something that provably
199
308
  * cannot succeed, and the count it inflates is the one doctor goes red on.
200
309
  */
201
- status: "delivered" | "duplicate" | "migrated" | "rejected" | "undeliverable" | "unreachable";
310
+ status: "delivered" | "duplicate" | "rejected" | "undeliverable" | "unreachable";
202
311
  }
203
312
  interface HqSpoolFlushInput {
204
313
  clientId: string;
205
314
  clientSecret: string;
206
- /** Repository root whose legacy `.factory-memory` spool is also drained. */
207
- cwd: string;
208
315
  /** The profile's HQ origin; entries recorded against another are refused. */
209
316
  endpoint: string;
317
+ /**
318
+ * Disposition schema-permanent rejections (HTTP 422) in place with the
319
+ * `.undeliverable` suffix instead of retaining them (#739). Operator
320
+ * opt-in: a later HQ schema fix can still admit the same bytes, so the
321
+ * drain never evicts on its own.
322
+ */
323
+ evictPermanentRejections?: boolean;
210
324
  /** Operator-named spool directories; replaces the default two locations. */
211
325
  explicitDirectories?: string[];
212
326
  repository: HqSpoolRepository;
@@ -239,13 +353,13 @@ interface HqSpoolFlushSummary {
239
353
  interface HqSpoolWorkCount {
240
354
  /**
241
355
  * The earliest moment learned across pending spool files (their own write
242
- * time) and legacy journal rows (their own `failedAt`). Absent only when
356
+ * time). Absent only when
243
357
  * `pending` is `0`, or when every timestamp source was unreadable within
244
358
  * budget — an estimate for doctor's remediation message (#394), never a
245
359
  * precise audit trail.
246
360
  */
247
361
  oldestQueuedAt?: string;
248
- /** Spooled events and replayable journals waiting in the locations below. */
362
+ /** Spooled events waiting in the locations below. */
249
363
  pending: number;
250
364
  /** Locations that exist and hold spooled work. */
251
365
  spools: string[];
@@ -266,7 +380,7 @@ interface HqSpoolWorkCount {
266
380
  * same locations `flushHqSpool` drains are inspected here, read-only: no
267
381
  * directory is created, nothing is secured, and nothing is delivered.
268
382
  */
269
- declare function countHqSpoolWork(input: Pick<HqSpoolFlushInput, "cwd" | "explicitDirectories" | "repository">, dependencies?: {
383
+ declare function countHqSpoolWork(input: Pick<HqSpoolFlushInput, "explicitDirectories" | "repository">, dependencies?: {
270
384
  budgetMs?: number;
271
385
  env?: NodeJS.ProcessEnv;
272
386
  }): Promise<HqSpoolWorkCount>;
@@ -275,7 +389,7 @@ interface HqSpoolOrphan {
275
389
  /** The `hq-retry-spool` directory itself, ready to pass to `--dir`. */
276
390
  directory: string;
277
391
  oldestQueuedAt?: string;
278
- /** Spooled events and journal rows waiting there. */
392
+ /** Spooled events waiting there. */
279
393
  pending: number;
280
394
  /**
281
395
  * The location exists but could not be listed. As everywhere else in this
@@ -522,10 +636,82 @@ declare const FollowUpActionSchema: z.ZodType<FollowUpAction>;
522
636
  declare const DIFF_CLASSIFICATIONS: readonly ["docs/process-only", "trivial", "non-trivial"];
523
637
  type DiffClassification = (typeof DIFF_CLASSIFICATIONS)[number];
524
638
  //#endregion
639
+ //#region src/impact-stamp.d.ts
640
+ /**
641
+ * The recorded stamp. `targets` satisfies the completeness invariant: every
642
+ * target the profile declares is present, each with its exact basis — never
643
+ * silently absent. `basis: "conservative"` means an unmodelled or unprovable
644
+ * input widened every target to full impact.
645
+ */
646
+ declare const impactStampSchema: z.ZodObject<{
647
+ basis: z.ZodEnum<{
648
+ "target-scoped": "target-scoped";
649
+ conservative: "conservative";
650
+ }>;
651
+ inertPaths: z.ZodDefault<z.ZodArray<z.ZodString>>;
652
+ reasons: z.ZodArray<z.ZodString>;
653
+ stampVersion: z.ZodLiteral<3>;
654
+ targets: z.ZodArray<z.ZodObject<{
655
+ basis: z.ZodString;
656
+ impact: z.ZodEnum<{
657
+ affected: "affected";
658
+ "not-affected": "not-affected";
659
+ }>;
660
+ name: z.ZodString;
661
+ }, z.core.$strip>>;
662
+ unsubscribedPaths: z.ZodArray<z.ZodString>;
663
+ }, z.core.$strip>;
664
+ type ImpactStamp = z.infer<typeof impactStampSchema>;
665
+ /**
666
+ * The surfaces that consume the stamp. One classification, consumed
667
+ * everywhere (#430): every surface routes through
668
+ * {@link impactStampScopeDecision}, so no surface can be more trusting than
669
+ * another, and no surface re-derives path rules of its own. The value only
670
+ * selects the wording of the conservative floor a refusal falls back to.
671
+ */
672
+ declare const IMPACT_SCOPE_SURFACES: {
673
+ readonly demand: "full demand floor";
674
+ readonly "preview-lifecycle": "full preview-lifecycle floor";
675
+ readonly "verification-battery": "full verification-battery floor";
676
+ };
677
+ type ImpactScopeSurface = keyof typeof IMPACT_SCOPE_SURFACES;
678
+ interface ImpactScopeDecision {
679
+ reason: string;
680
+ /** True ⇒ this target's work is provably unreachable and may be released. */
681
+ scoped: boolean;
682
+ }
683
+ /**
684
+ * Whether a trusted stamp RELEASES one target-scoped unit of work — an
685
+ * external proof demand (#542 wave 2), a verification-battery command, or a
686
+ * preview (Alchemy) lifecycle stack (#430 wave 3).
687
+ *
688
+ * The only release path is a `target-scoped` stamp of exactly this build's
689
+ * stamp version whose target entry for exactly this name is provably
690
+ * `not-affected`. Every other input — no trusted stamp, an unknown stamp
691
+ * version, a conservative stamp, a name the stamp does not classify, or an
692
+ * `affected` verdict — keeps today's full-work floor. Work only ever gets
693
+ * released, never added or satisfied: this function can withdraw a demand, it
694
+ * can never certify one.
695
+ *
696
+ * Identity binding is the CALLER's precondition: pass only a stamp computed
697
+ * for, or read from a pr:verify proof bound to, the current candidate (see
698
+ * `trustedImpactStamp` in `pr-readiness/verification-proof.ts`); pass
699
+ * `undefined` otherwise.
700
+ */
701
+ declare const impactStampScopeDecision: ({
702
+ stamp,
703
+ surface,
704
+ targetName
705
+ }: {
706
+ stamp: ImpactStamp | undefined;
707
+ surface: ImpactScopeSurface;
708
+ targetName: string;
709
+ }) => ImpactScopeDecision;
710
+ //#endregion
525
711
  //#region src/profile.d.ts
526
712
  declare const DEFAULT_FACTORY_REPOSITORY = "unknown/unknown";
527
- /** The one profile shape this build accepts (ADR 0023, #318, #351). */
528
- declare const PROFILE_SCHEMA_VERSION = 5;
713
+ /** The one profile shape this build accepts (ADR 0023, #318, #351, #742). */
714
+ declare const PROFILE_SCHEMA_VERSION = 6;
529
715
  declare const factoryProjectProfileSchema: z.ZodObject<{
530
716
  $schema: z.ZodOptional<z.ZodString>;
531
717
  extensions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
@@ -534,18 +720,17 @@ declare const factoryProjectProfileSchema: z.ZodObject<{
534
720
  endpoint: z.ZodIntersection<z.ZodString, z.ZodString>;
535
721
  }, z.core.$strict>>;
536
722
  impact: z.ZodOptional<z.ZodObject<{
723
+ inert: z.ZodOptional<z.ZodArray<z.ZodString>>;
537
724
  targets: z.ZodArray<z.ZodObject<{
538
725
  importers: z.ZodArray<z.ZodString>;
539
726
  name: z.ZodString;
540
727
  paths: z.ZodOptional<z.ZodArray<z.ZodString>>;
541
728
  }, z.core.$strict>>;
542
729
  }, z.core.$strict>>;
543
- proof: z.ZodObject<{
544
- classificationPolicy: z.ZodObject<{
545
- docsOnly: z.ZodDefault<z.ZodArray<z.ZodString>>;
546
- trivial: z.ZodDefault<z.ZodArray<z.ZodString>>;
547
- }, z.core.$strict>;
548
- }, z.core.$strict>;
730
+ lifecycleContract: z.ZodOptional<z.ZodObject<{
731
+ command: z.ZodString;
732
+ jobName: z.ZodOptional<z.ZodString>;
733
+ }, z.core.$strict>>;
549
734
  repository: z.ZodObject<{
550
735
  name: z.ZodString;
551
736
  owner: z.ZodString;
@@ -554,7 +739,6 @@ declare const factoryProjectProfileSchema: z.ZodObject<{
554
739
  name: z.ZodString;
555
740
  scope: z.ZodOptional<z.ZodObject<{
556
741
  classifications: z.ZodArray<z.ZodEnum<{
557
- trivial: "trivial";
558
742
  "docs/process-only": "docs/process-only";
559
743
  "non-trivial": "non-trivial";
560
744
  }>>;
@@ -565,7 +749,7 @@ declare const factoryProjectProfileSchema: z.ZodObject<{
565
749
  paths: z.ZodArray<z.ZodString>;
566
750
  }, z.core.$strict>>;
567
751
  }, z.core.$strict>>;
568
- schemaVersion: z.ZodLiteral<5>;
752
+ schemaVersion: z.ZodLiteral<6>;
569
753
  verification: z.ZodObject<{
570
754
  commands: z.ZodArray<z.ZodObject<{
571
755
  command: z.ZodString;
@@ -658,9 +842,7 @@ interface LoadUserConfigResult {
658
842
  //#endregion
659
843
  //#region src/github-check-runs.d.ts
660
844
  declare const FACTORY_CHECK_NAMES: {
661
- readonly boundary: "patronage-factory/boundary";
662
845
  readonly "pr-ready": "patronage-factory/pr-ready";
663
- readonly "pr-review": "patronage-factory/pr-review";
664
846
  readonly "pr-verify": "patronage-factory/pr-verify";
665
847
  };
666
848
  type FactoryCheckGate = keyof typeof FACTORY_CHECK_NAMES;
@@ -675,12 +857,6 @@ interface PublishFactoryCheckInput {
675
857
  * `hqLaneRefBaseUrlFromProfile` — the same source as the HQ gate sink.
676
858
  */
677
859
  hqLaneBaseUrl?: string;
678
- /**
679
- * Explicit issue/PR number for the HQ lane ref, used when the check run is not
680
- * PR-scoped (e.g. an epic boundary check keyed by its epic issue). Falls back
681
- * to `pr`, then to the checkout's PR, when omitted.
682
- */
683
- laneRefNumber?: number;
684
860
  owner: string;
685
861
  pr?: number;
686
862
  proof: unknown;
@@ -753,8 +929,8 @@ declare const mergeFreezeStateSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
753
929
  generationId: z.ZodNumber;
754
930
  headSha: z.ZodString;
755
931
  outcome: z.ZodEnum<{
756
- stale: "stale";
757
932
  active: "active";
933
+ stale: "stale";
758
934
  }>;
759
935
  reason: z.ZodString;
760
936
  recordedAt: z.ZodISODateTime;
@@ -879,10 +1055,6 @@ interface ReviewLadderPolicy {
879
1055
  }
880
1056
  declare const resolveReviewLadderPolicy: () => ReviewLadderPolicy;
881
1057
  //#endregion
882
- //#region src/review-rungs.d.ts
883
- declare const EVIDENCE_REVIEW_RUNGS: readonly ["independent-model", "oracle", "human"];
884
- type EvidenceReviewRung = (typeof EVIDENCE_REVIEW_RUNGS)[number];
885
- //#endregion
886
1058
  //#region src/review-ladder-ledger.d.ts
887
1059
  type LadderCycleStage = "interior" | "gate";
888
1060
  interface LadderCycleRef {
@@ -1113,7 +1285,7 @@ interface PrReviewProof {
1113
1285
  cleanedPaths: string[];
1114
1286
  ladder?: PrReviewLadderState;
1115
1287
  reviewRequirement?: {
1116
- reason: "no-applicable-mode";
1288
+ reason: "no-applicable-mode" | "faithful-merge";
1117
1289
  status: "not-required";
1118
1290
  };
1119
1291
  reviews: PrReviewResult[];
@@ -1134,8 +1306,8 @@ declare const managedReadinessLedgerSchema: z.ZodObject<{
1134
1306
  baseSha: z.ZodString;
1135
1307
  blockingReasons: z.ZodArray<z.ZodString>;
1136
1308
  classification: z.ZodEnum<{
1137
- trivial: "trivial";
1138
1309
  "docs/process-only": "docs/process-only";
1310
+ trivial: "trivial";
1139
1311
  "non-trivial": "non-trivial";
1140
1312
  }>;
1141
1313
  externalChecks: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -1148,8 +1320,8 @@ declare const managedReadinessLedgerSchema: z.ZodObject<{
1148
1320
  reason: z.ZodOptional<z.ZodString>;
1149
1321
  scope: z.ZodOptional<z.ZodObject<{
1150
1322
  classifications: z.ZodArray<z.ZodEnum<{
1151
- trivial: "trivial";
1152
1323
  "docs/process-only": "docs/process-only";
1324
+ trivial: "trivial";
1153
1325
  "non-trivial": "non-trivial";
1154
1326
  }>>;
1155
1327
  }, z.core.$strict>>;
@@ -1252,9 +1424,9 @@ declare const managedReadinessLedgerSchema: z.ZodObject<{
1252
1424
  reviewedPatchId: z.ZodOptional<z.ZodString>;
1253
1425
  status: z.ZodEnum<{
1254
1426
  "not-required": "not-required";
1427
+ stale: "stale";
1255
1428
  blocked: "blocked";
1256
1429
  current: "current";
1257
- stale: "stale";
1258
1430
  missing: "missing";
1259
1431
  }>;
1260
1432
  }, z.core.$strip>;
@@ -1264,9 +1436,9 @@ declare const managedReadinessLedgerSchema: z.ZodObject<{
1264
1436
  reviewedPatchId: z.ZodOptional<z.ZodString>;
1265
1437
  status: z.ZodEnum<{
1266
1438
  "not-required": "not-required";
1439
+ stale: "stale";
1267
1440
  blocked: "blocked";
1268
1441
  current: "current";
1269
- stale: "stale";
1270
1442
  missing: "missing";
1271
1443
  }>;
1272
1444
  }, z.core.$strip>>;
@@ -1277,8 +1449,8 @@ declare const managedReadinessLedgerSchema: z.ZodObject<{
1277
1449
  docsOnlyDeltaAccepted: z.ZodOptional<z.ZodBoolean>;
1278
1450
  docsOnlyVerifiedHeadSha: z.ZodOptional<z.ZodString>;
1279
1451
  prVerify: z.ZodEnum<{
1280
- passed: "passed";
1281
1452
  stale: "stale";
1453
+ passed: "passed";
1282
1454
  missing: "missing";
1283
1455
  }>;
1284
1456
  trivialDeltaAccepted: z.ZodOptional<z.ZodBoolean>;
@@ -1340,659 +1512,203 @@ declare const isHostedVerifyCheck: (check: StatusCheckRollup) => boolean;
1340
1512
  declare const hostedVerifyCheckState: (rollup: StatusCheckRollup[] | undefined) => CheckState;
1341
1513
  declare const statusCheckState: (rollup: StatusCheckRollup[] | undefined, exclude?: (check: StatusCheckRollup) => boolean) => CheckState;
1342
1514
  //#endregion
1343
- //#region src/pr-ready.d.ts
1344
- interface PrReadyArgs extends LoadProjectProfileInput {
1345
- authoringSessionIds?: string[];
1346
- base: string;
1347
- epic?: number;
1348
- json?: boolean;
1349
- output?: string;
1350
- report?: boolean;
1351
- pr: number;
1352
- reviewProof?: string;
1353
- throwWhenBlocked?: boolean;
1354
- verifyProof?: string;
1515
+ //#region src/github-app-client.d.ts
1516
+ interface FactoryAppRequest {
1517
+ body?: unknown;
1518
+ headers?: Readonly<Record<string, string>>;
1519
+ method: "DELETE" | "GET" | "PATCH" | "POST";
1520
+ owner: string;
1521
+ path: string;
1522
+ repo: string;
1355
1523
  }
1356
- interface GitHubPullRequest {
1357
- /**
1358
- * GitHub's live auto-merge enablement, or `null` when nothing is scheduled.
1359
- *
1360
- * Required, not optional (#515 review). `gh pr view --json autoMergeRequest`
1361
- * always returns the key — explicitly `null` when nothing is scheduled — and
1362
- * errors loudly on a field name it does not know, so there is no shape where
1363
- * the real CLI omits it. But `fetchPullRequest` is injectable, and an
1364
- * implementation that left the field out would silently disable the
1365
- * `boundary-wave` refusal that stops an epicless run from greening a
1366
- * candidate GitHub is already scheduled to merge. Requiring it makes the
1367
- * compiler enforce what `gh` already promises.
1368
- */
1369
- autoMergeRequest: {
1370
- enabledAt?: string;
1371
- } | null;
1372
- baseRefName: string;
1373
- baseRefOid: string;
1524
+ interface FactoryAppExchange<T = unknown> {
1525
+ readonly etag?: string;
1526
+ readonly json: T;
1527
+ readonly status: number;
1528
+ }
1529
+ //#endregion
1530
+ //#region src/github-pr-status-comment.d.ts
1531
+ interface UpsertFactoryPrStatusCommentInput {
1374
1532
  body: string;
1375
- headRefOid: string;
1376
- isDraft: boolean;
1377
- mergeStateStatus: string;
1378
- mergeable: string;
1379
- number: number;
1380
- reviewDecision: string | null;
1381
- statusCheckRollup?: StatusCheckRollup[];
1382
- title: string;
1383
- unresolvedReviewThreads: number;
1533
+ /** ISO instant at which this presentation was observed. */
1534
+ observedAt?: string;
1535
+ owner: string;
1536
+ pr: number;
1537
+ repo: string;
1538
+ }
1539
+ interface UpsertFactoryPrStatusCommentDependencies {
1540
+ request?: (input: FactoryAppRequest) => Promise<FactoryAppExchange>;
1541
+ requestJson?: (input: FactoryAppRequest) => Promise<unknown>;
1542
+ }
1543
+ interface UpsertFactoryPrStatusCommentResult {
1544
+ action: "created" | "updated";
1545
+ commentId: number;
1384
1546
  url: string;
1385
1547
  }
1386
- interface PrReadyProof {
1387
- schemaVersion: 3;
1548
+ declare function upsertFactoryPrStatusComment(input: UpsertFactoryPrStatusCommentInput, dependencies?: UpsertFactoryPrStatusCommentDependencies): Promise<UpsertFactoryPrStatusCommentResult>;
1549
+ //#endregion
1550
+ //#region src/catch-up-recognition-record.d.ts
1551
+ interface CatchUpRecognition {
1552
+ /** The ref the candidate targets, as the recognizing command resolved it. */
1553
+ baseRef: string;
1554
+ /** The live target tip at recognition time; the head's first parent. */
1555
+ baseTipSha: string;
1556
+ /** The head's second parent: the admitted base-side content merged in. */
1557
+ mergedParentSha: string;
1388
1558
  /**
1389
- * What GitHub actually did when this run armed native auto-merge (#477).
1390
- * Present exactly when a ready wave authorizes machine merge and arming ran;
1391
- * read back from the PR rather than inferred from the invocation, because `gh pr merge
1392
- * --auto` arms, merges, or does nothing with the same exit code and the same
1393
- * empty output. `not-armed` means the candidate is admitted but nothing will
1394
- * merge it, and `followUp` carries the re-dispatch.
1559
+ * The tree `git merge-tree --write-tree` produced for the two parents. It
1560
+ * equals the head's own tree; that equality is the faithfulness proof.
1395
1561
  */
1396
- arming?: {
1397
- detail?: string;
1398
- headSha: string;
1399
- outcome: "armed" | "merged" | "not-armed";
1400
- };
1401
- /**
1402
- * Why this run blocked, one entry per refusing demand (#391): `code` is the
1403
- * demand key from the resolver's vocabulary, `detail` the one-sentence
1404
- * refusal. Same refusals as `blockingReasons`, in the same order — the
1405
- * analyzable projection of a flat string list, so a wall of blocked proofs
1406
- * on one PR can be counted by cause. Absent when nothing blocked.
1407
- */
1408
- blockedReasons?: BlockedReason[];
1409
- blockingReasons: string[];
1410
- humanBlockingReasons: string[];
1411
- command: "patronage-factory pr:ready";
1412
- /**
1413
- * Machine-safe arg array for the obvious next action (#523): when `ready`
1414
- * but arming did not take effect, a `pr:ready` re-dispatch (idempotent on
1415
- * an unchanged head); otherwise the `gh pr ready` undraft repair or the
1416
- * `pr:verify` re-run that the blocking reasons name (re-verify the head,
1417
- * then re-run pr:ready). Same `argv` shape `factory:delegate --print`
1418
- * emits. Optional and purely additive.
1419
- */
1420
- followUp?: FollowUpAction;
1421
- /**
1422
- * `ledger.headSha` is the evaluated head SHA: the GitHub `pr.headRefOid`
1423
- * captured at evaluation time (not a local git read), recorded explicitly
1424
- * so merge-time identity checks are a pure comparison against the live
1425
- * pushed HEAD, not a re-derivation. See the ledger schema.
1426
- */
1427
- ledger: ManagedReadinessLedger;
1428
- /**
1429
- * Actionable facts that did not block (#477): a settling merge-freeze
1430
- * generation that permitted readiness and any authorized arming with a
1431
- * notice, an admitted-but-unscheduled false boundary wave, and how each
1432
- * waived demand reads to a human. Absent when there are none.
1433
- */
1434
- notices?: string[];
1435
- /** Committed profile blob evaluated by readiness. Required for merge. */
1436
- profileBlobSha?: string;
1437
- /** Checkout-relative committed profile path evaluated by readiness. */
1438
- profilePath?: string;
1439
- repairs: ReadinessRepair[];
1440
- /** Trusted checkout repository used for all GitHub reads and writes. */
1441
- repository?: string;
1442
- status: ReadinessStatus;
1443
- /**
1444
- * Demands that were in force, were NOT met, and were waived by the operator
1445
- * (#354, moved here from the merge-time proof by #477). Each entry carries
1446
- * the demand's refusals verbatim, so a waived demand can never read as a met
1447
- * one; readiness proceeds on the recorded operator act, not on evidence.
1448
- */
1449
- waivedDemands?: WaivedDemand[];
1562
+ mergedTreeSha: string;
1563
+ /** The ref that proves the second parent is admitted content. */
1564
+ upstreamRef: string;
1450
1565
  }
1451
- interface PrReadyDependencies {
1452
- /**
1453
- * Arms GitHub native auto-merge only for a passing boundary wave that
1454
- * authorizes machine merge (#477). Defaults to the real `gh pr merge --auto`
1455
- * call plus the read-back that says what actually happened.
1456
- */
1457
- armAutoMerge?: (input: ArmAutoMergeInput) => ArmAutoMergeOutcome;
1458
- github?: {
1459
- fetchClosingPullRequests?: (input: {
1460
- issue: number;
1461
- owner: string;
1462
- repo: string;
1463
- }) => {
1464
- number: number;
1465
- }[];
1466
- fetchIssueBody?: (input: {
1467
- issue: number;
1468
- owner: string;
1469
- repo: string;
1470
- }) => string;
1471
- fetchPullRequest: (input: {
1472
- owner: string;
1473
- repo: string;
1474
- pr: number;
1475
- }) => GitHubPullRequest;
1476
- };
1477
- git?: PrReadyGitDependencies;
1478
- hq?: HqIngestDependencies;
1479
- /**
1480
- * The authoritative merge-freeze reader (#477). Defaults to the pinned-App
1481
- * GitHub check-run authority — readiness is a control, so an absent
1482
- * dependency must not mean an unread freeze.
1483
- */
1484
- mergeFreeze?: Pick<MergeFreezeAuthority, "readGeneration">;
1566
+ //#endregion
1567
+ //#region src/pr-verify-proof-contract.d.ts
1568
+ declare const SUPPORTED_PR_VERIFY_SCHEMA_VERSIONS: readonly [1, 2, 3, 4];
1569
+ type PrVerifySchemaVersion = (typeof SUPPORTED_PR_VERIFY_SCHEMA_VERSIONS)[number];
1570
+ interface PrVerifyCommandResult {
1571
+ command: string;
1572
+ description: string;
1485
1573
  /**
1486
- * Awaited publication of the branded check, which is a source-pinned
1487
- * required check rather than a mirror (#477). Returns true only when the
1488
- * App-owned run landed. Defaults to `ensureFactoryCheckRunPublished`.
1489
- *
1490
- * `pr:ready` has no other publication seam, and this one cannot express a
1491
- * non-terminal run (#526): `status` is omitted from the input, so every run
1492
- * readiness creates is completed with a conclusion. A `pr:ready` invocation
1493
- * therefore cannot leave a run holding the source-pinned required check
1494
- * open, which is a permanent block on the pull request (#524).
1574
+ * Epic #550 wave 3 (#430): the profile's declared impact target for this
1575
+ * command, recorded from v4 on. It is the proof's own command→target
1576
+ * mapping: a `notRequiredCommands` entry must name the target recorded HERE
1577
+ * for the same command, so a withholding cannot point at whichever released
1578
+ * target happens to be convenient. Absent for a command the profile does
1579
+ * not scope, and for v1–v3 proofs, which predate the field.
1495
1580
  */
1496
- publishFinalCheckRun?: (input: Omit<PublishFactoryCheckInput, "status"> & {
1497
- conclusion: "failure" | "success";
1498
- }) => Promise<boolean> | boolean;
1499
- /** Injectable delay for the UNKNOWN-mergeable brief poll (tests). */
1500
- sleep?: (ms: number) => Promise<void>;
1581
+ impactTarget?: string;
1582
+ name: string;
1583
+ scope: "always" | "docs-only" | "trivial" | "full";
1501
1584
  }
1502
- interface PrReadyGitDependencies {
1503
- canResolveCommit: (cwd: string, sha: string) => boolean;
1504
- changedFiles: (cwd: string, base: string, headSha?: string) => string[];
1505
- checkoutRepository: (cwd: string) => CheckoutRepository;
1506
- currentHeadSha: (cwd: string) => string;
1507
- mergeBaseSha: (cwd: string, base: string) => string;
1508
- objectIdAtRef: (cwd: string, ref: string, absolutePath: string) => string | undefined;
1509
- resolveCommitSha: (cwd: string, ref: string) => string | undefined;
1510
- showFileAtRef: (cwd: string, ref: string, absolutePath: string) => string | undefined;
1511
- stablePatchId: (cwd: string, base: string) => string;
1585
+ interface PrVerifyExecutedCommand {
1586
+ command: string;
1587
+ counts?: {
1588
+ testFiles?: number;
1589
+ tests?: number;
1590
+ };
1591
+ durationMs: number;
1592
+ exitCode: number;
1593
+ name: string;
1594
+ scope: "always" | "docs-only" | "trivial" | "full";
1512
1595
  }
1513
- declare function validatePrReadyProof(value: unknown): PrReadyProof;
1514
- declare function readPrReadyProof(filePath: string): PrReadyProof;
1515
- declare function runPrReady(args: PrReadyArgs, dependencies?: PrReadyDependencies): Promise<PrReadyProof>;
1516
- //#endregion
1517
- //#region src/impact-stamp.d.ts
1518
- /**
1519
- * The recorded stamp. `targets` satisfies the completeness invariant: every
1520
- * target the profile declares is present, each with its exact basis — never
1521
- * silently absent. `basis: "conservative"` means an unmodelled or unprovable
1522
- * input widened every target to full impact.
1523
- */
1524
- declare const impactStampSchema: z.ZodObject<{
1525
- basis: z.ZodEnum<{
1526
- "target-scoped": "target-scoped";
1527
- conservative: "conservative";
1528
- }>;
1529
- reasons: z.ZodArray<z.ZodString>;
1530
- stampVersion: z.ZodLiteral<2>;
1531
- targets: z.ZodArray<z.ZodObject<{
1532
- basis: z.ZodString;
1533
- impact: z.ZodEnum<{
1534
- affected: "affected";
1535
- "not-affected": "not-affected";
1536
- }>;
1537
- name: z.ZodString;
1538
- }, z.core.$strip>>;
1539
- }, z.core.$strip>;
1540
- type ImpactStamp = z.infer<typeof impactStampSchema>;
1541
1596
  /**
1542
- * The surfaces that consume the stamp. One classification, consumed
1543
- * everywhere (#430): every surface routes through
1544
- * {@link impactStampScopeDecision}, so no surface can be more trusting than
1545
- * another, and no surface re-derives path rules of its own. The value only
1546
- * selects the wording of the conservative floor a refusal falls back to.
1597
+ * Epic #550 wave 3 (#430): a verification command the impact stamp proved this
1598
+ * candidate cannot reach, so the battery did not run it.
1599
+ *
1600
+ * The completeness invariant lives in the pairing: `verificationCommands`
1601
+ * records every command the resolved mode selected, `executedCommands` records
1602
+ * what ran, and this list records the rest WITH the stamp's own basis. A
1603
+ * withheld stack is therefore never silently absent from the proof — it is
1604
+ * present, named, and explained.
1547
1605
  */
1548
- declare const IMPACT_SCOPE_SURFACES: {
1549
- readonly demand: "full demand floor";
1550
- readonly "preview-lifecycle": "full preview-lifecycle floor";
1551
- readonly "verification-battery": "full verification-battery floor";
1552
- };
1553
- type ImpactScopeSurface = keyof typeof IMPACT_SCOPE_SURFACES;
1554
- interface ImpactScopeDecision {
1555
- reason: string;
1556
- /** True ⇒ this target's work is provably unreachable and may be released. */
1557
- scoped: boolean;
1606
+ interface PrVerifyNotRequiredCommand {
1607
+ basis: string;
1608
+ impactTarget: string;
1609
+ name: string;
1558
1610
  }
1559
1611
  /**
1560
- * Whether a trusted stamp RELEASES one target-scoped unit of work — an
1561
- * external proof demand (#542 wave 2), a verification-battery command, or a
1562
- * preview (Alchemy) lifecycle stack (#430 wave 3).
1563
- *
1564
- * The only release path is a `target-scoped` stamp of exactly this build's
1565
- * stamp version whose target entry for exactly this name is provably
1566
- * `not-affected`. Every other input — no trusted stamp, an unknown stamp
1567
- * version, a conservative stamp, a name the stamp does not classify, or an
1568
- * `affected` verdict — keeps today's full-work floor. Work only ever gets
1569
- * released, never added or satisfied: this function can withdraw a demand, it
1570
- * can never certify one.
1571
- *
1572
- * Identity binding is the CALLER's precondition: pass only a stamp computed
1573
- * for, or read from a pr:verify proof bound to, the current candidate (see
1574
- * `trustedImpactStamp` in `pr-readiness/verification-proof.ts`); pass
1575
- * `undefined` otherwise.
1612
+ * Epic #758 (#762): a consumer package a stamp-scoped selection skipped, and
1613
+ * why. Bound to the proof's stamp identity the field is v4-only (the same
1614
+ * window that can carry `impactStamp`) and refused when the proof records no
1615
+ * stamp. The factory does not write this list; consumers do.
1576
1616
  */
1577
- declare const impactStampScopeDecision: ({
1578
- stamp,
1579
- surface,
1580
- targetName
1581
- }: {
1582
- stamp: ImpactStamp | undefined;
1583
- surface: ImpactScopeSurface;
1584
- targetName: string;
1585
- }) => ImpactScopeDecision;
1586
- //#endregion
1587
- //#region src/required-check-policy.d.ts
1588
- declare const EVIDENCE_CHECK_TYPES: readonly ["review", "verify"];
1589
- type EvidenceCheckType = (typeof EVIDENCE_CHECK_TYPES)[number];
1590
- declare const requiredCheckScopeSchema: z.ZodObject<{
1591
- classifications: z.ZodArray<z.ZodEnum<{
1592
- trivial: "trivial";
1593
- "docs/process-only": "docs/process-only";
1594
- "non-trivial": "non-trivial";
1595
- }>>;
1596
- }, z.core.$strict>;
1597
- type RequiredCheckScope = z.infer<typeof requiredCheckScopeSchema>;
1598
- interface RequiredCheckScopeContext {
1599
- classification: DiffClassification | undefined;
1600
- impactStamp?: ImpactStamp;
1601
- }
1602
- interface ScopeDecision {
1603
- inScope: boolean;
1604
- reason: string;
1605
- }
1606
- declare const requiredCheckInScope: ({
1607
- context,
1608
- scope
1609
- }: {
1610
- context: RequiredCheckScopeContext;
1611
- scope?: RequiredCheckScope;
1612
- }) => ScopeDecision;
1613
- interface RequiredCheck {
1617
+ interface PrVerifyNotDemandedRecord {
1618
+ basis: string;
1614
1619
  name: string;
1615
- checkType: EvidenceCheckType;
1616
- scope?: RequiredCheckScope;
1617
1620
  }
1618
- //#endregion
1619
- //#region src/factory-session.d.ts
1620
- declare const resolveAuthoringSessionIds: ({
1621
- override,
1622
- recorded
1623
- }: {
1624
- override?: string[];
1625
- recorded?: string;
1626
- }) => string[];
1627
- declare namespace external_evidence_d_exports {
1628
- export { EVIDENCE_CHECK_TYPES, EVIDENCE_DIR, EVIDENCE_ENVELOPE_SCHEMA_VERSION, EVIDENCE_REVIEW_RUNGS, EvidenceCandidateIdentity, EvidenceCheckType, EvidenceEnvelope, EvidenceEnvelopeParse, EvidenceReviewRung, IndependenceResult, LoadedEvidenceEnvelope, RequiredCheck, RequiredCheckEvaluation, RequiredCheckEvaluationInput, RequiredCheckOutcome, RequiredCheckScope, RequiredCheckScopeContext, ScopeDecision, boundFailingCheckNames, evaluateRequiredChecks, evidenceBindingFresh, evidenceEnvelopeSchema, evidenceReviewIndependence, loadEvidenceEnvelopes, parseEvidenceEnvelope, requiredCheckInScope, requiredCheckScopeSchema, resolveAuthoringSessionIds };
1629
- }
1630
- declare const EVIDENCE_ENVELOPE_SCHEMA_VERSION = 1;
1631
- declare const evidenceEnvelopeBaseSchema: z.ZodObject<{
1632
- check: z.ZodString;
1633
- checkType: z.ZodEnum<{
1634
- review: "review";
1635
- verify: "verify";
1636
- }>;
1637
- findingsPointer: z.ZodOptional<z.ZodString>;
1638
- headSha: z.ZodString;
1639
- mergeBaseSha: z.ZodString;
1640
- model: z.ZodOptional<z.ZodString>;
1641
- outcome: z.ZodEnum<{
1642
- pass: "pass";
1643
- fail: "fail";
1644
- }>;
1645
- patchId: z.ZodString;
1646
- policyVersion: z.ZodOptional<z.ZodString>;
1647
- producer: z.ZodString;
1648
- requestId: z.ZodOptional<z.ZodString>;
1649
- rung: z.ZodOptional<z.ZodEnum<{
1650
- oracle: "oracle";
1651
- "independent-model": "independent-model";
1652
- human: "human";
1653
- }>>;
1654
- schemaVersion: z.ZodLiteral<1>;
1655
- sessionId: z.ZodOptional<z.ZodString>;
1656
- timestamp: z.ZodOptional<z.ZodISODateTime>;
1657
- }, z.core.$loose>;
1658
- declare const evidenceEnvelopeSchema: z.ZodObject<{
1659
- check: z.ZodString;
1660
- checkType: z.ZodEnum<{
1661
- review: "review";
1662
- verify: "verify";
1663
- }>;
1664
- findingsPointer: z.ZodOptional<z.ZodString>;
1665
- headSha: z.ZodString;
1666
- mergeBaseSha: z.ZodString;
1667
- model: z.ZodOptional<z.ZodString>;
1668
- outcome: z.ZodEnum<{
1669
- pass: "pass";
1670
- fail: "fail";
1671
- }>;
1672
- patchId: z.ZodString;
1673
- policyVersion: z.ZodOptional<z.ZodString>;
1674
- producer: z.ZodString;
1675
- requestId: z.ZodOptional<z.ZodString>;
1676
- rung: z.ZodOptional<z.ZodEnum<{
1677
- oracle: "oracle";
1678
- "independent-model": "independent-model";
1679
- human: "human";
1680
- }>>;
1681
- schemaVersion: z.ZodLiteral<1>;
1682
- sessionId: z.ZodOptional<z.ZodString>;
1683
- timestamp: z.ZodOptional<z.ZodISODateTime>;
1684
- }, z.core.$loose>;
1685
- type EvidenceEnvelope = z.infer<typeof evidenceEnvelopeBaseSchema>;
1686
- type EvidenceEnvelopeParse = {
1687
- ok: true;
1688
- envelope: EvidenceEnvelope;
1689
- } | {
1690
- ok: false;
1691
- error: string;
1692
- };
1693
- declare const parseEvidenceEnvelope: (raw: unknown) => EvidenceEnvelopeParse;
1694
- interface EvidenceCandidateIdentity {
1621
+ interface PrVerifyProof {
1622
+ schemaVersion: PrVerifySchemaVersion;
1623
+ authoringSession?: string;
1624
+ base: string;
1625
+ baselineFullProofs?: {
1626
+ base: string;
1627
+ changedFiles: string[];
1628
+ headSha: string;
1629
+ profilePath: string;
1630
+ projectKey: string;
1631
+ repository: string;
1632
+ }[];
1633
+ catchUpRecognition?: CatchUpRecognition;
1634
+ changedFiles: string[];
1635
+ classification: DiffClassification;
1636
+ classificationReasons: string[];
1637
+ command: "patronage-factory pr:verify";
1638
+ durationMs: number;
1639
+ endedAt: string;
1640
+ executedCommands?: PrVerifyExecutedCommand[];
1695
1641
  headSha: string;
1696
- patchId: string;
1697
- mergeBaseSha: string;
1642
+ impactStamp?: ImpactStamp;
1643
+ mode: ResolvedPrVerifyMode;
1644
+ mergeBaseSha?: string;
1645
+ notDemandedRecords?: PrVerifyNotDemandedRecord[];
1646
+ notRequiredCommands?: PrVerifyNotRequiredCommand[];
1647
+ outcome?: "aborted" | "passed";
1648
+ patchId?: string;
1649
+ profilePath: string;
1650
+ projectKey: string;
1651
+ repository: string;
1652
+ startedAt: string;
1653
+ verificationCommands: PrVerifyCommandResult[];
1698
1654
  }
1699
- declare const evidenceBindingFresh: ({
1700
- candidate,
1701
- envelope
1702
- }: {
1703
- candidate: EvidenceCandidateIdentity;
1704
- envelope: EvidenceEnvelope;
1705
- }) => boolean;
1706
- interface IndependenceResult {
1707
- independent: boolean;
1708
- reason?: "no-session" | "unknown-authoring-identity" | "same-session";
1655
+ type PrVerifyBaselineFullProof = NonNullable<PrVerifyProof["baselineFullProofs"]>[number];
1656
+ declare function validatePrVerifyProof(value: unknown): PrVerifyProof;
1657
+ declare namespace verification_proof_d_exports {
1658
+ export { PrVerifyBaselineFullProof, PrVerifyCommandResult, PrVerifyExecutedCommand, PrVerifyNotDemandedRecord, PrVerifyNotRequiredCommand, PrVerifyProof, PrVerifySchemaVersion, ResolvedPrVerifyMode, SUPPORTED_PR_VERIFY_SCHEMA_VERSIONS, VerificationHeadShas, VerificationProofState, VerifiedHeadShas, prVerifyFullHeadShasForDiff, prVerifyProofHeadShas, readPrVerifyProof, resolveVerifyProofApplicability, trustedCatchUpRecognition, trustedImpactStamp, validatePrVerifyProof, verificationProofApplicabilityFor, verificationProofBlockingReason, verificationProofForReadiness, verificationProofStateFor, verifyProofIdentityMatches, verifyProofPassed };
1709
1659
  }
1710
- declare const evidenceReviewIndependence: ({
1711
- authoringSessionIds,
1712
- envelope
1660
+ interface VerifiedHeadShas {
1661
+ docsOnlyVerifiedHeadShas: string[];
1662
+ trivialVerifiedHeadShas: string[];
1663
+ verifiedHeadShas: string[];
1664
+ }
1665
+ type VerificationHeadShas = {
1666
+ explicitFailure: true;
1667
+ } | VerifiedHeadShas;
1668
+ declare function readPrVerifyProof(filePath: string): PrVerifyProof;
1669
+ declare const verifyProofPassed: (proof: PrVerifyProof) => boolean;
1670
+ declare const prVerifyProofHeadShas: (proof: PrVerifyProof | undefined, creditedHeadSha?: string) => VerifiedHeadShas;
1671
+ declare const verifyProofIdentityMatches: ({
1672
+ currentIdentity,
1673
+ proof
1713
1674
  }: {
1714
- authoringSessionIds: string[];
1715
- envelope: EvidenceEnvelope;
1716
- }) => IndependenceResult;
1717
- type LoadedEvidenceEnvelope = {
1718
- ok: true;
1719
- envelope: EvidenceEnvelope;
1720
- path: string;
1721
- } | {
1722
- check?: string;
1723
- error: string;
1724
- ok: false;
1725
- path: string;
1726
- };
1675
+ currentIdentity?: {
1676
+ patchId: string;
1677
+ mergeBaseSha?: string;
1678
+ };
1679
+ proof?: PrVerifyProof;
1680
+ }) => boolean;
1727
1681
  /**
1728
- * Every check name with a current, candidate-bound FAILING envelope on disk.
1729
- *
1730
- * The wave-3 scoping veto input. Callers pass the resolved set to
1731
- * `planVerificationBattery` / `planPreviewLifecycle`, which stay pure the
1732
- * planners decide, they never read the filesystem.
1682
+ * Wave-2 consumption (#542): the recorded impact stamp, released for demand
1683
+ * resolution ONLY when it is identity-bound to the current candidate — the
1684
+ * proof passed, and its recorded headSha AND patchId both name exactly this
1685
+ * candidate (the same identities the proof already binds). Everything else
1686
+ * no proof, an aborted run, a stale head, a moved patch id, a pre-stamp proof
1687
+ * — returns `undefined`, and the consumer keeps today's full-demand floor.
1733
1688
  *
1734
- * `checkType` is the caller's, not a guess: schema-v5 requiredChecks are
1735
- * verify-only (`resolveProfileRequiredChecks`), so a scoping caller passes
1736
- * `"verify"` and matches exactly the pair wave 2 evaluates.
1689
+ * Deliberately stricter than verify-once applicability (which tolerates a
1690
+ * head-only or patch-id-only match): a stamp narrows external demands, so it
1691
+ * is trusted only on an exact double binding, fail closed.
1737
1692
  */
1738
- declare const boundFailingCheckNames: ({
1693
+ declare const trustedImpactStamp: ({
1739
1694
  candidate,
1740
- checkType,
1741
- envelopes
1695
+ proof
1742
1696
  }: {
1743
- candidate: EvidenceCandidateIdentity;
1744
- checkType: EvidenceCheckType;
1745
- envelopes: LoadedEvidenceEnvelope[];
1746
- }) => string[];
1747
- interface RequiredCheckEvaluationInput {
1748
- authoringSessionIds: string[];
1749
- candidate: EvidenceCandidateIdentity;
1750
- envelopes: LoadedEvidenceEnvelope[];
1751
- requiredChecks: RequiredCheck[];
1752
- scopeContext: RequiredCheckScopeContext;
1753
- }
1754
- interface RequiredCheckOutcome {
1755
- name: string;
1756
- checkType: EvidenceCheckType;
1757
- status: "satisfied" | "unmet" | "out-of-scope";
1758
- inScope: boolean;
1759
- scopeReason: string;
1760
- scope?: RequiredCheckScope;
1761
- reason?: string;
1762
- matchedPath?: string;
1763
- }
1764
- interface RequiredCheckEvaluation {
1765
- outcomes: RequiredCheckOutcome[];
1766
- blockingReasons: string[];
1767
- }
1768
- declare const evaluateRequiredChecks: ({
1769
- authoringSessionIds,
1770
- candidate,
1771
- envelopes,
1772
- requiredChecks,
1773
- scopeContext
1774
- }: RequiredCheckEvaluationInput) => RequiredCheckEvaluation;
1775
- declare const EVIDENCE_DIR = ".factory-memory/evidence";
1776
- declare const loadEvidenceEnvelopes: (cwd: string) => LoadedEvidenceEnvelope[];
1777
- //#endregion
1778
- //#region src/review-proof-applicability.d.ts
1779
- declare const REVIEW_STATUS_VALUES: readonly ["not-required", "current", "stale", "missing", "blocked"];
1780
- declare const reviewStatusSchema: z.ZodEnum<{
1781
- "not-required": "not-required";
1782
- blocked: "blocked";
1783
- current: "current";
1784
- stale: "stale";
1785
- missing: "missing";
1786
- }>;
1787
- type ReviewStatus = z.infer<typeof reviewStatusSchema>;
1788
- interface CurrentReviewIdentity {
1789
- headSha: string;
1790
- patchId: string;
1791
- }
1792
- declare const reviewStatus: ({
1793
- blocked,
1794
- required,
1795
- reviewedHeadSha,
1796
- reviewedPatchId,
1797
- headSha,
1798
- patchId
1799
- }: CurrentReviewIdentity & {
1800
- blocked?: boolean;
1801
- required: boolean;
1802
- reviewedHeadSha?: string;
1803
- reviewedPatchId?: string;
1804
- }) => ReviewStatus;
1805
- declare namespace proof_identity_d_exports {
1806
- export { CurrentReviewIdentity, REVIEW_STATUS_VALUES, ReviewProofClaim, ReviewStatus, explicitFailureIdentity, isExplicitReviewFailure, isUntypedReviewProof, reviewStatus, reviewStatusSchema, selectReviewProof };
1807
- }
1808
- type ReviewProofClaim = {
1809
- reviewedHeadSha?: string;
1810
- reviewedPatchId?: string;
1811
- untypedVerdict?: boolean;
1812
- } | {
1813
- explicitFailure: true;
1814
- reviewedHeadSha?: string;
1815
- reviewedPatchId?: string;
1816
- untypedVerdict?: boolean;
1817
- };
1818
- declare const isExplicitReviewFailure: (proof: ReviewProofClaim) => proof is {
1819
- explicitFailure: true;
1820
- reviewedHeadSha?: string;
1821
- reviewedPatchId?: string;
1822
- untypedVerdict?: boolean;
1823
- };
1824
- declare const isUntypedReviewProof: (proof: ReviewProofClaim) => proof is {
1825
- untypedVerdict: true;
1826
- reviewedHeadSha?: string;
1827
- reviewedPatchId?: string;
1828
- };
1829
- declare const explicitFailureIdentity: (proof: ReviewProofClaim) => {
1830
- reviewedHeadSha?: string;
1831
- reviewedPatchId?: string;
1832
- };
1833
- declare const selectReviewProof: ({
1834
- reviewProof
1835
- }: {
1836
- reviewProof: ReviewProofClaim;
1837
- }) => {
1838
- reviewedHeadSha?: string;
1839
- reviewedPatchId?: string;
1840
- untypedVerdict?: boolean;
1841
- };
1842
- //#endregion
1843
- //#region src/pr-readiness/review-epoch.d.ts
1844
- interface ReviewCycleState {
1845
- autoBlockingFindings: number;
1846
- countsBySeverity: Record<ReviewFindingSeverity, number>;
1847
- highestBlockingSeverity?: ReviewFindingSeverity;
1848
- highestOpenSeverity?: ReviewFindingSeverity;
1849
- maxReviewCycles?: number;
1850
- nonBlockingFindings: number;
1851
- openFindings: number;
1852
- reviewCycle?: number;
1853
- staleRepeatFindings?: number;
1854
- windowExhausted: boolean;
1855
- }
1856
- declare const reviewCycleStateFor: (proof: Pick<PrReviewProof, "ladder" | "reviewCycle" | "maxReviewCycles" | "reviews">, policy?: ReviewLadderPolicy, adjudicatedLedger?: FindingLedgerEntry[]) => ReviewCycleState;
1857
- type ReviewAcceptance = "accepted-after-cap" | "accepted-clean" | "accepted-through-ladder" | "blocked";
1858
- declare const resolveReviewAcceptance: (proof: PrReviewProof, review: PrReviewResult, policy: ReviewLadderPolicy | undefined) => ReviewAcceptance;
1859
- type ReviewTerminalState = "accepted-with-findings" | "blocked" | "clean";
1860
- declare const resolveReviewTerminalStateForEpoch: (proof: PrReviewProof, review: PrReviewResult, epoch: ReviewEpochMode, adjudicatedLedger?: FindingLedgerEntry[]) => ReviewTerminalState;
1861
- declare const resolveReviewTerminalState: (proof: PrReviewProof, review: PrReviewResult, policy: ReviewLadderPolicy | undefined) => ReviewTerminalState;
1862
- declare const resolveReviewTerminalStateAcrossReviews: (proof: PrReviewProof, epoch: ReviewEpochMode, adjudicatedLedger?: FindingLedgerEntry[]) => ReviewTerminalState | undefined;
1863
- declare const resolveReviewTerminalStateAcrossReviewsForPolicy: (proof: PrReviewProof, policy: ReviewLadderPolicy) => ReviewTerminalState | undefined;
1864
- declare const reviewProofFor: (proof: PrReviewProof | undefined, kind: PrReviewKind, policy: ReviewLadderPolicy | undefined, current?: {
1865
- patchId: string;
1866
- }) => ReviewProofClaim;
1867
- declare namespace review_proof_d_exports {
1868
- export { DEFAULT_PR_REVIEW_MAX_CYCLES, DEFAULT_PR_REVIEW_PROOF_PATH, PR_REVIEW_FINAL_READINESS_NOTICE, PR_REVIEW_FINDING_PROVENANCE_VERSION, PR_REVIEW_PROOF_DESCRIPTOR, PR_REVIEW_SCHEMA_VERSION, PrReviewFinding, PrReviewKind, PrReviewLadderState, PrReviewMode, PrReviewOutcome, PrReviewProof, PrReviewResult, PrReviewStageResolution, REVIEW_SEVERITIES, ReviewAcceptance, ReviewCycleState, ReviewFindingCategory, ReviewFindingSeverity, ReviewTerminalState, prReviewFindingSchema, prReviewProofSchema, prReviewResultSchema, readPrReviewProof, resolveReviewAcceptance, resolveReviewTerminalState, resolveReviewTerminalStateAcrossReviews, resolveReviewTerminalStateAcrossReviewsForPolicy, resolveReviewTerminalStateForEpoch, reviewCycleStateFor, reviewProofFor, validatePrReviewProof, validatePrReviewResult };
1869
- }
1870
- declare const PR_REVIEW_SCHEMA_VERSION = 2;
1871
- declare const PR_REVIEW_FINDING_PROVENANCE_VERSION = 1;
1872
- declare const DEFAULT_PR_REVIEW_PROOF_PATH = ".factory-memory/pr-review.json";
1873
- declare const DEFAULT_PR_REVIEW_MAX_CYCLES = 5;
1874
- declare const PR_REVIEW_FINAL_READINESS_NOTICE = "pr:review is a final readiness proof gate. Run it after local verification and avoid repeated full runs unless the review proof records actionable findings. Default review window: 5 cycles.";
1875
- declare const prReviewFindingSchema: z.ZodType<PrReviewFinding>;
1876
- declare const prReviewResultSchema: z.ZodType<PrReviewResult>;
1877
- declare const prReviewProofSchema: z.ZodType<PrReviewProof>;
1878
- declare const validatePrReviewResult: (value: unknown) => PrReviewResult;
1879
- declare const validatePrReviewProof: (value: unknown) => PrReviewProof;
1880
- declare const readPrReviewProof: (filePath: string) => PrReviewProof;
1881
- declare const PR_REVIEW_PROOF_DESCRIPTOR: ProofDescriptor<PrReviewProof>;
1882
- declare namespace verification_proof_d_exports {
1883
- export { PrVerifyBaselineFullProof, PrVerifyCommandResult, PrVerifyExecutedCommand, PrVerifyNotRequiredCommand, PrVerifyProof, PrVerifySchemaVersion, ResolvedPrVerifyMode, SUPPORTED_PR_VERIFY_SCHEMA_VERSIONS, VerificationHeadShas, VerificationProofState, VerifiedHeadShas, prVerifyFullHeadShasForDiff, prVerifyProofHeadShas, readPrVerifyProof, resolveVerifyProofApplicability, trustedImpactStamp, validatePrVerifyProof, verificationProofApplicabilityFor, verificationProofBlockingReason, verificationProofForReadiness, verificationProofStateFor, verifyProofIdentityMatches, verifyProofPassed };
1884
- }
1885
- interface VerifiedHeadShas {
1886
- docsOnlyVerifiedHeadShas: string[];
1887
- trivialVerifiedHeadShas: string[];
1888
- verifiedHeadShas: string[];
1889
- }
1890
- type VerificationHeadShas = {
1891
- explicitFailure: true;
1892
- } | VerifiedHeadShas;
1893
- declare const SUPPORTED_PR_VERIFY_SCHEMA_VERSIONS: readonly [1, 2, 3, 4];
1894
- type PrVerifySchemaVersion = (typeof SUPPORTED_PR_VERIFY_SCHEMA_VERSIONS)[number];
1895
- interface PrVerifyCommandResult {
1896
- command: string;
1897
- description: string;
1898
- /**
1899
- * Epic #550 wave 3 (#430): the profile's declared impact target for this
1900
- * command, recorded from v4 on. It is the proof's own command→target
1901
- * mapping: a `notRequiredCommands` entry must name the target recorded HERE
1902
- * for the same command, so a withholding cannot point at whichever released
1903
- * target happens to be convenient. Absent for a command the profile does
1904
- * not scope, and for v1–v3 proofs, which predate the field.
1905
- */
1906
- impactTarget?: string;
1907
- name: string;
1908
- scope: "always" | "docs-only" | "trivial" | "full";
1909
- }
1910
- interface PrVerifyExecutedCommand {
1911
- command: string;
1912
- counts?: {
1913
- testFiles?: number;
1914
- tests?: number;
1915
- };
1916
- durationMs: number;
1917
- exitCode: number;
1918
- name: string;
1919
- scope: "always" | "docs-only" | "trivial" | "full";
1920
- }
1921
- /**
1922
- * Epic #550 wave 3 (#430): a verification command the impact stamp proved this
1923
- * candidate cannot reach, so the battery did not run it.
1924
- *
1925
- * The completeness invariant lives in the pairing: `verificationCommands`
1926
- * records every command the resolved mode selected, `executedCommands` records
1927
- * what ran, and this list records the rest WITH the stamp's own basis. A
1928
- * withheld stack is therefore never silently absent from the proof — it is
1929
- * present, named, and explained.
1930
- */
1931
- interface PrVerifyNotRequiredCommand {
1932
- basis: string;
1933
- impactTarget: string;
1934
- name: string;
1935
- }
1936
- interface PrVerifyProof {
1937
- schemaVersion: PrVerifySchemaVersion;
1938
- authoringSession?: string;
1939
- base: string;
1940
- baselineFullProofs?: {
1941
- base: string;
1942
- changedFiles: string[];
1943
- headSha: string;
1944
- profilePath: string;
1945
- projectKey: string;
1946
- repository: string;
1947
- }[];
1948
- changedFiles: string[];
1949
- classification: DiffClassification;
1950
- classificationReasons: string[];
1951
- command: "patronage-factory pr:verify";
1952
- durationMs: number;
1953
- endedAt: string;
1954
- executedCommands?: PrVerifyExecutedCommand[];
1955
- headSha: string;
1956
- impactStamp?: ImpactStamp;
1957
- mode: ResolvedPrVerifyMode;
1958
- mergeBaseSha?: string;
1959
- notRequiredCommands?: PrVerifyNotRequiredCommand[];
1960
- outcome?: "aborted" | "passed";
1961
- patchId?: string;
1962
- profilePath: string;
1963
- projectKey: string;
1964
- repository: string;
1965
- startedAt: string;
1966
- verificationCommands: PrVerifyCommandResult[];
1967
- }
1968
- type PrVerifyBaselineFullProof = NonNullable<PrVerifyProof["baselineFullProofs"]>[number];
1969
- declare function validatePrVerifyProof(value: unknown): PrVerifyProof;
1970
- declare function readPrVerifyProof(filePath: string): PrVerifyProof;
1971
- declare const verifyProofPassed: (proof: PrVerifyProof) => boolean;
1972
- declare const prVerifyProofHeadShas: (proof: PrVerifyProof | undefined, creditedHeadSha?: string) => VerifiedHeadShas;
1973
- declare const verifyProofIdentityMatches: ({
1974
- currentIdentity,
1975
- proof
1976
- }: {
1977
- currentIdentity?: {
1978
- patchId: string;
1979
- mergeBaseSha?: string;
1980
- };
1981
- proof?: PrVerifyProof;
1982
- }) => boolean;
1983
- /**
1984
- * Wave-2 consumption (#542): the recorded impact stamp, released for demand
1985
- * resolution ONLY when it is identity-bound to the current candidate — the
1986
- * proof passed, and its recorded headSha AND patchId both name exactly this
1987
- * candidate (the same identities the proof already binds). Everything else —
1988
- * no proof, an aborted run, a stale head, a moved patch id, a pre-stamp proof
1989
- * — returns `undefined`, and the consumer keeps today's full-demand floor.
1990
- *
1991
- * Deliberately stricter than verify-once applicability (which tolerates a
1992
- * head-only or patch-id-only match): a stamp narrows external demands, so it
1993
- * is trusted only on an exact double binding, fail closed.
1994
- */
1995
- declare const trustedImpactStamp: ({
1697
+ candidate: {
1698
+ headSha: string;
1699
+ patchId: string;
1700
+ };
1701
+ proof: PrVerifyProof | undefined;
1702
+ }) => ImpactStamp | undefined;
1703
+ /**
1704
+ * #833: the recorded catch-up recognition, consumed ONLY when it is
1705
+ * identity-bound to the current candidate under exactly the rules
1706
+ * `trustedImpactStamp` applies — the proof passed, is v4+, and its recorded
1707
+ * headSha AND patchId both name this candidate. The recognition withdraws
1708
+ * review and preview demands, so it earns the same strict double binding and
1709
+ * the same fail-closed answer (`undefined`) on every other state.
1710
+ */
1711
+ declare const trustedCatchUpRecognition: ({
1996
1712
  candidate,
1997
1713
  proof
1998
1714
  }: {
@@ -2001,7 +1717,7 @@ declare const trustedImpactStamp: ({
2001
1717
  patchId: string;
2002
1718
  };
2003
1719
  proof: PrVerifyProof | undefined;
2004
- }) => ImpactStamp | undefined;
1720
+ }) => CatchUpRecognition | undefined;
2005
1721
  declare const prVerifyFullHeadShasForDiff: ({
2006
1722
  docsOnlyDeltaAcceptedSince,
2007
1723
  files,
@@ -2024,260 +1740,782 @@ type VerificationProofState = {
2024
1740
  headShas: VerifiedHeadShas;
2025
1741
  proof: PrVerifyProof;
2026
1742
  } | {
2027
- kind: "typed-diff-mismatch";
2028
- mode: ResolvedPrVerifyMode;
1743
+ kind: "typed-diff-mismatch";
1744
+ mode: ResolvedPrVerifyMode;
1745
+ };
1746
+ declare const verificationProofStateFor: ({
1747
+ proof,
1748
+ proofMatchesCurrentDiff,
1749
+ proofPath
1750
+ }: {
1751
+ proof?: PrVerifyProof;
1752
+ proofMatchesCurrentDiff?: boolean;
1753
+ proofPath?: string;
1754
+ }) => VerificationProofState;
1755
+ declare const verificationProofApplicabilityFor: ({
1756
+ docsOnlyDeltaAcceptedSince,
1757
+ explicitProof,
1758
+ files,
1759
+ headSha,
1760
+ currentIdentity,
1761
+ proof,
1762
+ proofPath,
1763
+ proofReadError
1764
+ }: {
1765
+ docsOnlyDeltaAcceptedSince?: (baselineHeadSha: string) => boolean;
1766
+ explicitProof: boolean;
1767
+ files: string[];
1768
+ headSha: string;
1769
+ currentIdentity?: {
1770
+ patchId: string;
1771
+ mergeBaseSha?: string;
1772
+ };
1773
+ proof?: PrVerifyProof;
1774
+ proofPath?: string;
1775
+ proofReadError?: unknown;
1776
+ }) => {
1777
+ fullVerifiedHeadShas: never[];
1778
+ verificationProof: VerificationProofState;
1779
+ } | {
1780
+ fullVerifiedHeadShas: string[];
1781
+ verificationProof: {
1782
+ headShas: VerifiedHeadShas;
1783
+ kind: "typed";
1784
+ proof: PrVerifyProof;
1785
+ };
1786
+ };
1787
+ declare const resolveVerifyProofApplicability: ({
1788
+ proofPath,
1789
+ explicitProof,
1790
+ docsOnlyDeltaAcceptedSince,
1791
+ files,
1792
+ headSha,
1793
+ currentVerifyIdentityForBase,
1794
+ preread
1795
+ }: {
1796
+ proofPath: string;
1797
+ explicitProof: boolean;
1798
+ docsOnlyDeltaAcceptedSince?: (baselineHeadSha: string) => boolean;
1799
+ files: string[];
1800
+ headSha: string;
1801
+ currentVerifyIdentityForBase?: (base: string) => {
1802
+ patchId: string;
1803
+ mergeBaseSha?: string;
1804
+ };
1805
+ preread?: {
1806
+ proof?: PrVerifyProof;
1807
+ error?: unknown;
1808
+ };
1809
+ }) => {
1810
+ fullVerifiedHeadShas: never[];
1811
+ verificationProof: VerificationProofState;
1812
+ } | {
1813
+ fullVerifiedHeadShas: string[];
1814
+ verificationProof: {
1815
+ headShas: VerifiedHeadShas;
1816
+ kind: "typed";
1817
+ proof: PrVerifyProof;
1818
+ };
1819
+ };
1820
+ declare const verificationProofForReadiness: (state: VerificationProofState) => VerificationHeadShas;
1821
+ declare const verificationProofBlockingReason: (state: VerificationProofState) => string | undefined;
1822
+ //#endregion
1823
+ //#region src/preview-lifecycle.d.ts
1824
+ type PreviewDisposition = "deploy" | "not-required";
1825
+ interface PreviewTargetPlan {
1826
+ basis: string;
1827
+ disposition: PreviewDisposition;
1828
+ name: string;
1829
+ }
1830
+ interface PreviewLifecyclePlan {
1831
+ /** The declared preview stacks to deploy, in declaration order. */
1832
+ deploy: string[];
1833
+ /** The withheld stacks, in declaration order. */
1834
+ notRequired: PreviewTargetPlan[];
1835
+ /** Whether a trusted, identity-bound stamp was available at all. */
1836
+ stampTrusted: boolean;
1837
+ /** Every declared preview target with its disposition, in declaration order. */
1838
+ targets: PreviewTargetPlan[];
1839
+ }
1840
+ /** Validate a serialized plan without deriving or changing its dispositions. */
1841
+ declare const validatePreviewLifecyclePlan: (value: unknown) => PreviewLifecyclePlan;
1842
+ /**
1843
+ * Structural subset of the profile: the impact declarations plus the external
1844
+ * demand list. Structural rather than a `Pick` so this module does not import
1845
+ * `profile.ts`.
1846
+ */
1847
+ interface PreviewLifecycleProfile {
1848
+ impact?: {
1849
+ targets: {
1850
+ name: string;
1851
+ }[];
1852
+ };
1853
+ requiredChecks?: {
1854
+ name: string;
1855
+ }[];
1856
+ }
1857
+ /**
1858
+ * The declared preview stacks: impact targets that are ALSO declared required
1859
+ * checks — i.e. targets whose proof is produced externally, which is exactly
1860
+ * what a preview producer is.
1861
+ *
1862
+ * Deriving the list from the two existing declarations rather than adding a
1863
+ * third is what makes lifecycle and demand unable to disagree: the stacks this
1864
+ * plan can withhold are precisely the demands wave 2 can release, so a stack
1865
+ * can never be skipped while its proof stays demanded.
1866
+ */
1867
+ declare const previewLifecycleTargets: (profile: PreviewLifecycleProfile) => string[];
1868
+ /**
1869
+ * Plan the preview lifecycle for one candidate.
1870
+ *
1871
+ * Trust is resolved here through the SAME identity gate demand release uses
1872
+ * (`trustedImpactStamp`): the proof must have passed and must bind both the
1873
+ * candidate's headSha and its patchId. A stale, aborted, absent, or
1874
+ * differently-bound proof yields no stamp, and every declared stack is planned
1875
+ * for deploy. Total over its INPUTS — no proof, stamp, or profile can make it
1876
+ * throw. A malformed CALL is the deliberate exception: omitting
1877
+ * `vetoedTargets` is API misuse, not data doubt, and throws.
1878
+ */
1879
+ declare const planPreviewLifecycle: ({
1880
+ candidate,
1881
+ profile,
1882
+ proof,
1883
+ vetoedTargets
1884
+ }: {
1885
+ candidate: {
1886
+ headSha: string;
1887
+ patchId: string;
1888
+ };
1889
+ profile: PreviewLifecycleProfile;
1890
+ proof: PrVerifyProof | undefined;
1891
+ /**
1892
+ * Stack names with a current, candidate-bound FAILING envelope. Scoping is
1893
+ * withheld for these whatever the stamp says — the same veto demand release
1894
+ * applies, and for the same reason: a withheld stack is a stack that can
1895
+ * never re-emit the envelope its standing demand needs. Callers hold the
1896
+ * checkout context, so they resolve the set with `boundFailingCheckNames`
1897
+ * and pass it in; this module stays pure.
1898
+ *
1899
+ * REQUIRED, with no default, on purpose: a defaulted `[]` reads the same
1900
+ * whether the caller inspected the envelopes or never looked, and this seam
1901
+ * exists precisely for EXTERNAL preview producers — the callers most likely
1902
+ * to skip the lookup. Pass the result of `boundFailingCheckNames`; pass `[]`
1903
+ * only to mean "inspected the envelopes and found no bound failure".
1904
+ *
1905
+ * Deliberately visible to `api:check` as a breaking signature change
1906
+ * (pre-1.0, no external callers yet).
1907
+ */
1908
+ vetoedTargets: readonly string[];
1909
+ }) => PreviewLifecyclePlan;
1910
+ //#endregion
1911
+ //#region src/pr-status-hud.d.ts
1912
+ type FactoryPrStatusCheckName = "patronage-factory/merge-freeze" | "patronage-factory/pr-ready" | "patronage-factory/pr-verify";
1913
+ interface CompletedFactoryCheckSnapshot {
1914
+ readonly completedAt: string;
1915
+ readonly conclusion: string;
1916
+ readonly detailsUrl?: string;
1917
+ readonly headSha: string;
1918
+ readonly name: FactoryPrStatusCheckName;
1919
+ }
1920
+ interface FailedPreviewSnapshot {
1921
+ readonly completedAt: string;
1922
+ readonly conclusion: string;
1923
+ readonly detailsUrl?: string;
1924
+ readonly headSha: string;
1925
+ readonly name: string;
1926
+ }
1927
+ interface FactoryPrStatusSources {
1928
+ readonly baseSha: string;
1929
+ readonly checks: Readonly<Partial<Record<FactoryPrStatusCheckName, CompletedFactoryCheckSnapshot>>>;
1930
+ readonly previewFailures?: Readonly<Partial<Record<string, FailedPreviewSnapshot>>>;
1931
+ readonly previewRegistrations: readonly PreviewProofRegistration[];
1932
+ }
1933
+ interface RenderFactoryPrStatusHudInput extends FactoryPrStatusSources {
1934
+ readonly headSha: string;
1935
+ readonly plan: PreviewLifecyclePlan;
1936
+ readonly planHeadSha: string;
1937
+ readonly pr: number;
1938
+ /** ISO instant at which the presentation sources were observed. */
1939
+ readonly renderedAt: string;
1940
+ }
1941
+ interface PresentFactoryPrStatusHudInput {
1942
+ readonly headSha: string;
1943
+ readonly owner: string;
1944
+ readonly plan: PreviewLifecyclePlan;
1945
+ readonly planHeadSha: string;
1946
+ readonly pr: number;
1947
+ readonly renderedAt?: string;
1948
+ readonly repo: string;
1949
+ }
1950
+ interface PresentFactoryPrStatusHudDependencies {
1951
+ /**
1952
+ * Read only `previewProofInventory.list` registrations and completed,
1953
+ * Factory-App-owned check snapshots. PR comment bodies are not an evidence
1954
+ * source and are deliberately absent from this contract.
1955
+ */
1956
+ readonly readSources: (input: {
1957
+ headSha: string;
1958
+ owner: string;
1959
+ pr: number;
1960
+ previewTargets?: readonly string[];
1961
+ repo: string;
1962
+ }) => Promise<FactoryPrStatusSources>;
1963
+ /** Recheck both PR endpoints immediately before mutating the sticky HUD. */
1964
+ readonly assertCurrentIdentity: (input: {
1965
+ baseSha: string;
1966
+ headSha: string;
1967
+ owner: string;
1968
+ pr: number;
1969
+ repo: string;
1970
+ }) => Promise<void>;
1971
+ readonly upsert?: typeof upsertFactoryPrStatusComment;
1972
+ }
1973
+ interface ReadFactoryPrStatusSourcesInput {
1974
+ readonly headSha: string;
1975
+ /**
1976
+ * Read token for `previewProofInventory.list`. The list walks the
1977
+ * force-push timeline, which needs commit (contents) read; the Factory App
1978
+ * token has no contents permission, so pass a workflow `GITHUB_TOKEN`
1979
+ * (#825). Falls back to `token`.
1980
+ */
1981
+ readonly inventoryToken?: string;
1982
+ readonly owner: string;
1983
+ readonly pr: number;
1984
+ /**
1985
+ * Demanded preview stack names from the lifecycle plan. Used only to look up
1986
+ * a completed unsuccessful check run when inventory has no registration.
1987
+ */
1988
+ readonly previewTargets?: readonly string[];
1989
+ readonly repo: string;
1990
+ /** Factory App installation token, normally minted by the presentation job. */
1991
+ readonly token: string;
1992
+ }
1993
+ interface ReadFactoryPrStatusSourcesDependencies {
1994
+ readonly fetch?: typeof fetch;
1995
+ readonly listPreviewRegistrations?: (input: {
1996
+ owner: string;
1997
+ pr: number;
1998
+ repo: string;
1999
+ token: string;
2000
+ }) => Promise<readonly PreviewProofRegistration[]>;
2001
+ readonly timeoutMs?: number;
2002
+ }
2003
+ declare function renderFactoryPrStatusHud(input: RenderFactoryPrStatusHudInput): string;
2004
+ declare function presentFactoryPrStatusHud(input: PresentFactoryPrStatusHudInput, dependencies: PresentFactoryPrStatusHudDependencies): Promise<UpsertFactoryPrStatusCommentResult>;
2005
+ declare function assertFactoryPrStatusIdentity(input: ReadFactoryPrStatusSourcesInput & {
2006
+ readonly baseSha: string;
2007
+ }, dependencies?: ReadFactoryPrStatusSourcesDependencies): Promise<void>;
2008
+ declare function readFactoryPrStatusSources(input: ReadFactoryPrStatusSourcesInput, dependencies?: ReadFactoryPrStatusSourcesDependencies): Promise<FactoryPrStatusSources>;
2009
+ interface PlanFactoryPrStatusHudInput {
2010
+ readonly cwd: string;
2011
+ readonly headSha: string;
2012
+ readonly mergeBaseSha?: string;
2013
+ readonly patchId?: string;
2014
+ readonly profilePath?: string;
2015
+ }
2016
+ /**
2017
+ * Consume `planPreviewLifecycle` for the current checkout. No second plan is
2018
+ * invented: dispositions are Ready/Skipped from `deploy` vs `not-required`.
2019
+ * Candidate identity is never copied from the proof. Absent independent
2020
+ * identity or an unbound verify proof is the planner's conservative path.
2021
+ */
2022
+ declare function planFactoryPrStatusHud(input: PlanFactoryPrStatusHudInput): PreviewLifecyclePlan;
2023
+ interface RefreshFactoryPrStatusHudInput {
2024
+ readonly cwd: string;
2025
+ readonly headSha: string;
2026
+ readonly mergeBaseSha?: string;
2027
+ readonly owner: string;
2028
+ readonly patchId?: string;
2029
+ readonly pr: number;
2030
+ readonly profilePath?: string;
2031
+ readonly repo: string;
2032
+ readonly token?: string;
2033
+ }
2034
+ /** Plan from the checkout and present the App-owned HUD. */
2035
+ declare function refreshFactoryPrStatusHud(input: RefreshFactoryPrStatusHudInput): Promise<UpsertFactoryPrStatusCommentResult>;
2036
+ /**
2037
+ * Presentation must not fail an admission gate. Used after pr:ready publishes
2038
+ * its check so the table is not stuck at first-write.
2039
+ */
2040
+ declare function refreshFactoryPrStatusHudSafely(input: RefreshFactoryPrStatusHudInput, onNotice?: (message: string) => void): Promise<void>;
2041
+ //#endregion
2042
+ //#region src/pr-ready.d.ts
2043
+ interface PrReadyArgs extends LoadProjectProfileInput {
2044
+ authoringSessionIds?: string[];
2045
+ base: string;
2046
+ epic?: number;
2047
+ json?: boolean;
2048
+ output?: string;
2049
+ report?: boolean;
2050
+ pr: number;
2051
+ reviewProof?: string;
2052
+ throwWhenBlocked?: boolean;
2053
+ verifyProof?: string;
2054
+ }
2055
+ interface GitHubPullRequest {
2056
+ /**
2057
+ * GitHub's live auto-merge enablement, or `null` when nothing is scheduled.
2058
+ *
2059
+ * Required, not optional (#515 review). `gh pr view --json autoMergeRequest`
2060
+ * always returns the key — explicitly `null` when nothing is scheduled — and
2061
+ * errors loudly on a field name it does not know, so there is no shape where
2062
+ * the real CLI omits it. But `fetchPullRequest` is injectable, and an
2063
+ * implementation that left the field out would silently disable the
2064
+ * `boundary-wave` refusal that stops an epicless run from greening a
2065
+ * candidate GitHub is already scheduled to merge. Requiring it makes the
2066
+ * compiler enforce what `gh` already promises.
2067
+ */
2068
+ autoMergeRequest: {
2069
+ enabledAt?: string;
2070
+ } | null;
2071
+ baseRefName: string;
2072
+ baseRefOid: string;
2073
+ body: string;
2074
+ headRefName?: string;
2075
+ headRefOid: string;
2076
+ isDraft: boolean;
2077
+ mergeStateStatus: string;
2078
+ mergeable: string;
2079
+ number: number;
2080
+ reviewDecision: string | null;
2081
+ statusCheckRollup?: StatusCheckRollup[];
2082
+ title: string;
2083
+ unresolvedReviewThreads: number;
2084
+ url: string;
2085
+ }
2086
+ interface PrReadyProof {
2087
+ schemaVersion: 3;
2088
+ /**
2089
+ * What GitHub actually did when this run armed native auto-merge (#477).
2090
+ * Present exactly when a ready wave authorizes machine merge and arming ran;
2091
+ * read back from the PR rather than inferred from the invocation, because `gh pr merge
2092
+ * --auto` arms, merges, or does nothing with the same exit code and the same
2093
+ * empty output. `not-armed` means the candidate is admitted but nothing will
2094
+ * merge it, and `followUp` carries the re-dispatch.
2095
+ */
2096
+ arming?: {
2097
+ detail?: string;
2098
+ headSha: string;
2099
+ outcome: "armed" | "merged" | "not-armed";
2100
+ };
2101
+ /**
2102
+ * Why this run blocked, one entry per refusing demand (#391): `code` is the
2103
+ * demand key from the resolver's vocabulary, `detail` the one-sentence
2104
+ * refusal. Same refusals as `blockingReasons`, in the same order — the
2105
+ * analyzable projection of a flat string list, so a wall of blocked proofs
2106
+ * on one PR can be counted by cause. Absent when nothing blocked.
2107
+ */
2108
+ blockedReasons?: BlockedReason[];
2109
+ blockingReasons: string[];
2110
+ humanBlockingReasons: string[];
2111
+ command: "patronage-factory pr:ready";
2112
+ /**
2113
+ * Machine-safe arg array for the obvious next action (#523): when `ready`
2114
+ * but arming did not take effect, a `pr:ready` re-dispatch (idempotent on
2115
+ * an unchanged head); otherwise the `gh pr ready` undraft repair or the
2116
+ * `pr:verify` re-run that the blocking reasons name (re-verify the head,
2117
+ * then re-run pr:ready). Same `argv` shape `factory:delegate --print`
2118
+ * emits. Optional and purely additive.
2119
+ */
2120
+ followUp?: FollowUpAction;
2121
+ /**
2122
+ * `ledger.headSha` is the evaluated head SHA: the GitHub `pr.headRefOid`
2123
+ * captured at evaluation time (not a local git read), recorded explicitly
2124
+ * so merge-time identity checks are a pure comparison against the live
2125
+ * pushed HEAD, not a re-derivation. See the ledger schema.
2126
+ */
2127
+ ledger: ManagedReadinessLedger;
2128
+ /**
2129
+ * Actionable facts that did not block (#477): a settling merge-freeze
2130
+ * generation that permitted readiness and any authorized arming with a
2131
+ * notice, an admitted-but-unscheduled false boundary wave, and how each
2132
+ * waived demand reads to a human. Absent when there are none.
2133
+ */
2134
+ notices?: string[];
2135
+ /** Committed profile blob evaluated by readiness. Required for merge. */
2136
+ profileBlobSha?: string;
2137
+ /** Checkout-relative committed profile path evaluated by readiness. */
2138
+ profilePath?: string;
2139
+ repairs: ReadinessRepair[];
2140
+ /** Trusted checkout repository used for all GitHub reads and writes. */
2141
+ repository?: string;
2142
+ status: ReadinessStatus;
2143
+ /**
2144
+ * Demands that were in force, were NOT met, and were waived by the operator
2145
+ * (#354, moved here from the merge-time proof by #477). Each entry carries
2146
+ * the demand's refusals verbatim, so a waived demand can never read as a met
2147
+ * one; readiness proceeds on the recorded operator act, not on evidence.
2148
+ */
2149
+ waivedDemands?: WaivedDemand[];
2150
+ }
2151
+ interface PrReadyDependencies {
2152
+ /**
2153
+ * Arms GitHub native auto-merge only for a passing boundary wave that
2154
+ * authorizes machine merge (#477). Defaults to the real `gh pr merge --auto`
2155
+ * call plus the read-back that says what actually happened.
2156
+ */
2157
+ armAutoMerge?: (input: ArmAutoMergeInput) => ArmAutoMergeOutcome;
2158
+ github?: {
2159
+ fetchClosingPullRequests?: (input: {
2160
+ issue: number;
2161
+ owner: string;
2162
+ repo: string;
2163
+ }) => {
2164
+ number: number;
2165
+ }[];
2166
+ fetchIssueBody?: (input: {
2167
+ issue: number;
2168
+ owner: string;
2169
+ repo: string;
2170
+ }) => string;
2171
+ fetchPullRequest: (input: {
2172
+ owner: string;
2173
+ repo: string;
2174
+ pr: number;
2175
+ }) => GitHubPullRequest;
2176
+ };
2177
+ git?: PrReadyGitDependencies;
2178
+ hq?: HqIngestDependencies;
2179
+ /**
2180
+ * The authoritative merge-freeze reader (#477). Defaults to the pinned-App
2181
+ * GitHub check-run authority — readiness is a control, so an absent
2182
+ * dependency must not mean an unread freeze.
2183
+ */
2184
+ mergeFreeze?: Pick<MergeFreezeAuthority, "readGeneration">;
2185
+ /**
2186
+ * Awaited publication of the branded check, which is a source-pinned
2187
+ * required check rather than a mirror (#477). Returns true only when the
2188
+ * App-owned run landed. Defaults to `ensureFactoryCheckRunPublished`.
2189
+ *
2190
+ * `pr:ready` has no other publication seam, and this one cannot express a
2191
+ * non-terminal run (#526): `status` is omitted from the input, so every run
2192
+ * readiness creates is completed with a conclusion. A `pr:ready` invocation
2193
+ * therefore cannot leave a run holding the source-pinned required check
2194
+ * open, which is a permanent block on the pull request (#524).
2195
+ */
2196
+ publishFinalCheckRun?: (input: Omit<PublishFactoryCheckInput, "status"> & {
2197
+ conclusion: "failure" | "success";
2198
+ }) => Promise<boolean> | boolean;
2199
+ /**
2200
+ * Re-present the App-owned HUD after this run's ready check is published
2201
+ * so the table is not stuck at first-write. Defaults to a safe refresh
2202
+ * that never fails the gate.
2203
+ */
2204
+ presentStatusHud?: (input: RefreshFactoryPrStatusHudInput) => Promise<void> | void;
2205
+ /** Injectable delay for the UNKNOWN-mergeable brief poll (tests). */
2206
+ sleep?: (ms: number) => Promise<void>;
2207
+ }
2208
+ interface PrReadyGitDependencies {
2209
+ canResolveCommit: (cwd: string, sha: string) => boolean;
2210
+ changedFiles: (cwd: string, base: string, headSha?: string) => string[];
2211
+ checkoutRepository: (cwd: string) => CheckoutRepository;
2212
+ currentHeadSha: (cwd: string) => string;
2213
+ mergeBaseSha: (cwd: string, base: string) => string;
2214
+ objectIdAtRef: (cwd: string, ref: string, absolutePath: string) => string | undefined;
2215
+ resolveCommitSha: (cwd: string, ref: string) => string | undefined;
2216
+ showFileAtRef: (cwd: string, ref: string, absolutePath: string) => string | undefined;
2217
+ stablePatchId: (cwd: string, base: string) => string;
2218
+ }
2219
+ declare function validatePrReadyProof(value: unknown): PrReadyProof;
2220
+ declare function readPrReadyProof(filePath: string): PrReadyProof;
2221
+ declare function runPrReady(args: PrReadyArgs, dependencies?: PrReadyDependencies): Promise<PrReadyProof>;
2222
+ //#endregion
2223
+ //#region src/required-check-policy.d.ts
2224
+ declare const EVIDENCE_CHECK_TYPES: readonly ["review", "verify"];
2225
+ type EvidenceCheckType = (typeof EVIDENCE_CHECK_TYPES)[number];
2226
+ declare const requiredCheckScopeSchema: z.ZodObject<{
2227
+ classifications: z.ZodArray<z.ZodEnum<{
2228
+ "docs/process-only": "docs/process-only";
2229
+ trivial: "trivial";
2230
+ "non-trivial": "non-trivial";
2231
+ }>>;
2232
+ }, z.core.$strict>;
2233
+ type RequiredCheckScope = z.infer<typeof requiredCheckScopeSchema>;
2234
+ interface RequiredCheckScopeContext {
2235
+ catchUpRecognition?: CatchUpRecognition;
2236
+ classification: DiffClassification | undefined;
2237
+ impactStamp?: ImpactStamp;
2238
+ }
2239
+ interface ScopeDecision {
2240
+ inScope: boolean;
2241
+ reason: string;
2242
+ }
2243
+ declare const requiredCheckInScope: ({
2244
+ context,
2245
+ scope
2246
+ }: {
2247
+ context: RequiredCheckScopeContext;
2248
+ scope?: RequiredCheckScope;
2249
+ }) => ScopeDecision;
2250
+ interface RequiredCheck {
2251
+ name: string;
2252
+ checkType: EvidenceCheckType;
2253
+ scope?: RequiredCheckScope;
2254
+ }
2255
+ //#endregion
2256
+ //#region src/factory-session.d.ts
2257
+ declare const resolveAuthoringSessionIds: ({
2258
+ override,
2259
+ recorded
2260
+ }: {
2261
+ override?: string[];
2262
+ recorded?: string;
2263
+ }) => string[];
2264
+ declare namespace external_evidence_d_exports {
2265
+ export { EVIDENCE_CHECK_TYPES, EVIDENCE_DIR, EVIDENCE_ENVELOPE_SCHEMA_VERSION, EVIDENCE_REVIEW_RUNGS, EvidenceCandidateIdentity, EvidenceCheckType, EvidenceEnvelope, EvidenceEnvelopeParse, EvidenceReviewRung, IndependenceResult, LoadedEvidenceEnvelope, RequiredCheck, RequiredCheckEvaluation, RequiredCheckEvaluationInput, RequiredCheckOutcome, RequiredCheckScope, RequiredCheckScopeContext, ScopeDecision, boundFailingCheckNames, evaluateRequiredChecks, evidenceBindingFresh, evidenceEnvelopeSchema, evidenceReviewIndependence, loadEvidenceEnvelopes, parseEvidenceEnvelope, requiredCheckInScope, requiredCheckScopeSchema, resolveAuthoringSessionIds };
2266
+ }
2267
+ declare const EVIDENCE_ENVELOPE_SCHEMA_VERSION = 1;
2268
+ declare const evidenceEnvelopeBaseSchema: z.ZodObject<{
2269
+ check: z.ZodString;
2270
+ checkType: z.ZodEnum<{
2271
+ review: "review";
2272
+ verify: "verify";
2273
+ }>;
2274
+ findingsPointer: z.ZodOptional<z.ZodString>;
2275
+ headSha: z.ZodString;
2276
+ mergeBaseSha: z.ZodString;
2277
+ model: z.ZodOptional<z.ZodString>;
2278
+ outcome: z.ZodEnum<{
2279
+ pass: "pass";
2280
+ fail: "fail";
2281
+ }>;
2282
+ patchId: z.ZodString;
2283
+ policyVersion: z.ZodOptional<z.ZodString>;
2284
+ producer: z.ZodString;
2285
+ requestId: z.ZodOptional<z.ZodString>;
2286
+ rung: z.ZodOptional<z.ZodEnum<{
2287
+ oracle: "oracle";
2288
+ "independent-model": "independent-model";
2289
+ human: "human";
2290
+ }>>;
2291
+ schemaVersion: z.ZodLiteral<1>;
2292
+ sessionId: z.ZodOptional<z.ZodString>;
2293
+ timestamp: z.ZodOptional<z.ZodISODateTime>;
2294
+ }, z.core.$loose>;
2295
+ declare const evidenceEnvelopeSchema: z.ZodObject<{
2296
+ check: z.ZodString;
2297
+ checkType: z.ZodEnum<{
2298
+ review: "review";
2299
+ verify: "verify";
2300
+ }>;
2301
+ findingsPointer: z.ZodOptional<z.ZodString>;
2302
+ headSha: z.ZodString;
2303
+ mergeBaseSha: z.ZodString;
2304
+ model: z.ZodOptional<z.ZodString>;
2305
+ outcome: z.ZodEnum<{
2306
+ pass: "pass";
2307
+ fail: "fail";
2308
+ }>;
2309
+ patchId: z.ZodString;
2310
+ policyVersion: z.ZodOptional<z.ZodString>;
2311
+ producer: z.ZodString;
2312
+ requestId: z.ZodOptional<z.ZodString>;
2313
+ rung: z.ZodOptional<z.ZodEnum<{
2314
+ oracle: "oracle";
2315
+ "independent-model": "independent-model";
2316
+ human: "human";
2317
+ }>>;
2318
+ schemaVersion: z.ZodLiteral<1>;
2319
+ sessionId: z.ZodOptional<z.ZodString>;
2320
+ timestamp: z.ZodOptional<z.ZodISODateTime>;
2321
+ }, z.core.$loose>;
2322
+ type EvidenceEnvelope = z.infer<typeof evidenceEnvelopeBaseSchema>;
2323
+ type EvidenceEnvelopeParse = {
2324
+ ok: true;
2325
+ envelope: EvidenceEnvelope;
2326
+ } | {
2327
+ ok: false;
2328
+ error: string;
2029
2329
  };
2030
- declare const verificationProofStateFor: ({
2031
- proof,
2032
- proofMatchesCurrentDiff,
2033
- proofPath
2034
- }: {
2035
- proof?: PrVerifyProof;
2036
- proofMatchesCurrentDiff?: boolean;
2037
- proofPath?: string;
2038
- }) => VerificationProofState;
2039
- declare const verificationProofApplicabilityFor: ({
2040
- docsOnlyDeltaAcceptedSince,
2041
- explicitProof,
2042
- files,
2043
- headSha,
2044
- currentIdentity,
2045
- proof,
2046
- proofPath,
2047
- proofReadError
2048
- }: {
2049
- docsOnlyDeltaAcceptedSince?: (baselineHeadSha: string) => boolean;
2050
- explicitProof: boolean;
2051
- files: string[];
2330
+ declare const parseEvidenceEnvelope: (raw: unknown) => EvidenceEnvelopeParse;
2331
+ interface EvidenceCandidateIdentity {
2052
2332
  headSha: string;
2053
- currentIdentity?: {
2054
- patchId: string;
2055
- mergeBaseSha?: string;
2056
- };
2057
- proof?: PrVerifyProof;
2058
- proofPath?: string;
2059
- proofReadError?: unknown;
2060
- }) => {
2061
- fullVerifiedHeadShas: never[];
2062
- verificationProof: VerificationProofState;
2063
- } | {
2064
- fullVerifiedHeadShas: string[];
2065
- verificationProof: {
2066
- headShas: VerifiedHeadShas;
2067
- kind: "typed";
2068
- proof: PrVerifyProof;
2069
- };
2070
- };
2071
- declare const resolveVerifyProofApplicability: ({
2072
- proofPath,
2073
- explicitProof,
2074
- docsOnlyDeltaAcceptedSince,
2075
- files,
2076
- headSha,
2077
- currentVerifyIdentityForBase,
2078
- preread
2333
+ patchId: string;
2334
+ mergeBaseSha: string;
2335
+ }
2336
+ declare const evidenceBindingFresh: ({
2337
+ candidate,
2338
+ envelope
2079
2339
  }: {
2080
- proofPath: string;
2081
- explicitProof: boolean;
2082
- docsOnlyDeltaAcceptedSince?: (baselineHeadSha: string) => boolean;
2083
- files: string[];
2084
- headSha: string;
2085
- currentVerifyIdentityForBase?: (base: string) => {
2086
- patchId: string;
2087
- mergeBaseSha?: string;
2088
- };
2089
- preread?: {
2090
- proof?: PrVerifyProof;
2091
- error?: unknown;
2092
- };
2093
- }) => {
2094
- fullVerifiedHeadShas: never[];
2095
- verificationProof: VerificationProofState;
2340
+ candidate: EvidenceCandidateIdentity;
2341
+ envelope: EvidenceEnvelope;
2342
+ }) => boolean;
2343
+ interface IndependenceResult {
2344
+ independent: boolean;
2345
+ reason?: "no-session" | "unknown-authoring-identity" | "same-session";
2346
+ }
2347
+ declare const evidenceReviewIndependence: ({
2348
+ authoringSessionIds,
2349
+ envelope
2350
+ }: {
2351
+ authoringSessionIds: string[];
2352
+ envelope: EvidenceEnvelope;
2353
+ }) => IndependenceResult;
2354
+ type LoadedEvidenceEnvelope = {
2355
+ ok: true;
2356
+ envelope: EvidenceEnvelope;
2357
+ path: string;
2096
2358
  } | {
2097
- fullVerifiedHeadShas: string[];
2098
- verificationProof: {
2099
- headShas: VerifiedHeadShas;
2100
- kind: "typed";
2101
- proof: PrVerifyProof;
2102
- };
2359
+ check?: string;
2360
+ error: string;
2361
+ ok: false;
2362
+ path: string;
2103
2363
  };
2104
- declare const verificationProofForReadiness: (state: VerificationProofState) => VerificationHeadShas;
2105
- declare const verificationProofBlockingReason: (state: VerificationProofState) => string | undefined;
2106
- //#endregion
2107
- //#region src/retro-envelope.d.ts
2108
2364
  /**
2109
- * Versioned retro envelope schema (epic #27 wave 2, issue #34).
2110
- *
2111
- * One envelope per lane, built at `factory:closeout` and delivered through the
2112
- * typed gate-sink as the `retro-envelope` ingest kind. Re-derived in TypeScript
2113
- * from the `spike/telemetry-layer2` S5 scratch schema (reference-only, never
2114
- * merged). This module is the single source of truth for the v1 wire shape
2115
- * and its bounds ({@link RETRO_ENVELOPE_WIRE_BOUNDS}) — producer and consumer
2116
- * alike. HQ imports these exports directly from the Worker-safe
2117
- * `@patronage/software-factory/schemas` subpath
2118
- * (`software-factory-hq/src/contracts/retro-schemas.ts`) instead of
2119
- * maintaining a parallel hand-written copy, so there is exactly one wire
2120
- * contract and no drift-detection machinery is needed (issue #350; formerly
2121
- * a hand-written twin plus a 767-line parity test, #46).
2122
- *
2123
- * DESIGN INVARIANT: cross-family token sums must be UNREPRESENTABLE.
2124
- *
2125
- * The two model families use different tokenizers, prices, and accounting
2126
- * conventions, so any token total that spans Claude and GPT is a lie:
2127
- *
2128
- * 1. There is no combined/total token field anywhere in the envelope.
2129
- * 2. `tokenFamilies` is strict — its only keys are `claude` and `gpt`; data
2130
- * cannot smuggle in a third "all"/"combined" slot.
2131
- * 3. The family BLOCKS are structurally different shapes with DIFFERENT keys
2132
- * (claude is a single flat block keyed on freshInput/cacheReadInput/
2133
- * cacheCreationInput; gpt is `{ roles: [...] }`). The exclusive input-tier
2134
- * COUNTS share no key name across families. The residual names shared
2135
- * between the claude block and a gpt ROLE entry are pinned to exactly
2136
- * {costUsd, model, output} (PR #32 advisory): `costUsd` is deliberate —
2137
- * USD is the one cross-family summable unit (rule 4); `model` is an
2138
- * unsummable label; `output` is the same name at DIFFERENT depths (lane
2139
- * block vs per-role entry), frozen by a tripwire test in
2140
- * `retro-envelope.test.ts` so the overlap cannot grow. Renaming `output`
2141
- * is a schemaVersion-2 wire change, deliberately not spent in v1.
2142
- * 4. Cost is per-family USD and nullable. Combined totals are allowed in USD
2143
- * only, and only as a projection-time sum of per-family USD.
2365
+ * Every check name with a current, candidate-bound FAILING envelope on disk.
2144
2366
  *
2145
- * Field names also encode the S2/S3 reader lessons: Claude `freshInput` alone
2146
- * is not prompt size (true input context = freshInput + cacheReadInput +
2147
- * cacheCreationInput, requestId-deduped), and codex `inputInclusiveOfCache`
2148
- * already includes `cachedInput`, so `freshInputDerived` (inclusive − cached)
2149
- * is the only value safe to feed a per-token pricer.
2367
+ * The wave-3 scoping veto input. Callers pass the resolved set to
2368
+ * `planVerificationBattery` / `planPreviewLifecycle`, which stay pure the
2369
+ * planners decide, they never read the filesystem.
2150
2370
  *
2151
- * COMPLETENESS POSTURE: harvest may have no usable native log for a lane, so
2152
- * `tokenFamilies` may legitimately be absent. The closeout build gate demands
2153
- * a valid envelope, not available telemetry. A families-absent envelope keeps
2154
- * its operator-visible data gaps and is a replayable advisory HQ event, so it
2155
- * never substitutes unavailable usage with zero. The wire shape (field names,
2156
- * types, structure) stays byte-parity with HQ v1.
2157
- */
2158
- declare const RETRO_ENVELOPE_SCHEMA_VERSION = 1;
2159
- declare const retroEnvelopeV1Schema: z.ZodObject<{
2160
- agentRunId: z.ZodString;
2161
- archiveRef: z.ZodOptional<z.ZodString>;
2162
- cycles: z.ZodObject<{
2163
- gateRunsToFirstGreen: z.ZodNumber;
2164
- reviewerFixRounds: z.ZodNumber;
2165
- thermoFixRounds: z.ZodNumber;
2166
- }, z.core.$strict>;
2167
- dataGaps: z.ZodDefault<z.ZodArray<z.ZodString>>;
2168
- gates: z.ZodArray<z.ZodObject<{
2169
- cycle: z.ZodNumber;
2170
- duration: z.ZodNumber;
2171
- gate: z.ZodString;
2172
- outcome: z.ZodEnum<{
2173
- pass: "pass";
2174
- fail: "fail";
2175
- skip: "skip";
2176
- }>;
2177
- startedAt: z.ZodISODateTime;
2178
- }, z.core.$strict>>;
2179
- generatedAt: z.ZodISODateTime;
2180
- interventions: z.ZodObject<{
2181
- count: z.ZodNumber;
2182
- }, z.core.$strict>;
2183
- joinKeys: z.ZodObject<{
2184
- claudeSessionIds: z.ZodDefault<z.ZodArray<z.ZodString>>;
2185
- codexThreadIds: z.ZodDefault<z.ZodArray<z.ZodString>>;
2186
- }, z.core.$strict>;
2187
- kind: z.ZodLiteral<"retro-envelope">;
2188
- outcome: z.ZodOptional<z.ZodObject<{
2189
- status: z.ZodEnum<{
2190
- success: "success";
2191
- fail: "fail";
2192
- blocked: "blocked";
2193
- "ship-with-followups": "ship-with-followups";
2194
- }>;
2195
- verdict: z.ZodOptional<z.ZodString>;
2196
- }, z.core.$strict>>;
2197
- phases: z.ZodArray<z.ZodObject<{
2198
- at: z.ZodISODateTime;
2199
- deltaSec: z.ZodOptional<z.ZodNumber>;
2200
- name: z.ZodString;
2201
- }, z.core.$strict>>;
2202
- refs: z.ZodObject<{
2203
- branch: z.ZodOptional<z.ZodString>;
2204
- epic: z.ZodOptional<z.ZodString>;
2205
- headSha: z.ZodOptional<z.ZodString>;
2206
- issue: z.ZodOptional<z.ZodString>;
2207
- prNumber: z.ZodOptional<z.ZodNumber>;
2208
- }, z.core.$strict>;
2209
- repo: z.ZodObject<{
2210
- name: z.ZodString;
2211
- owner: z.ZodString;
2212
- }, z.core.$strict>;
2213
- schemaVersion: z.ZodLiteral<1>;
2214
- tokenFamilies: z.ZodObject<{
2215
- claude: z.ZodOptional<z.ZodObject<{
2216
- cacheCreationInput: z.ZodNumber;
2217
- cacheReadInput: z.ZodNumber;
2218
- costUsd: z.ZodNullable<z.ZodNumber>;
2219
- family: z.ZodLiteral<"claude">;
2220
- freshInput: z.ZodNumber;
2221
- model: z.ZodString;
2222
- output: z.ZodNumber;
2223
- requests: z.ZodNumber;
2224
- }, z.core.$strict>>;
2225
- gpt: z.ZodOptional<z.ZodObject<{
2226
- family: z.ZodLiteral<"gpt">;
2227
- roles: z.ZodArray<z.ZodObject<{
2228
- cachedInput: z.ZodNumber;
2229
- costUsd: z.ZodNullable<z.ZodNumber>;
2230
- freshInputDerived: z.ZodNumber;
2231
- inputInclusiveOfCache: z.ZodNumber;
2232
- model: z.ZodString;
2233
- output: z.ZodNumber;
2234
- reasoningOutput: z.ZodNumber;
2235
- role: z.ZodString;
2236
- threadId: z.ZodOptional<z.ZodString>;
2237
- }, z.core.$strict>>;
2238
- }, z.core.$strict>>;
2239
- }, z.core.$strict>;
2240
- wallClock: z.ZodObject<{
2241
- endTs: z.ZodISODateTime;
2242
- startTs: z.ZodISODateTime;
2243
- totalSec: z.ZodNumber;
2244
- }, z.core.$strict>;
2245
- }, z.core.$strict>;
2246
- type RetroEnvelope = z.infer<typeof retroEnvelopeV1Schema>;
2247
- /**
2248
- * Versioned payload validators, keyed by schema major. Unknown majors never
2249
- * reach these — {@link parseRetroEnvelope} returns them raw and marked
2250
- * degraded, mirroring HQ's ingest skew posture (stored raw, never dropped).
2371
+ * `checkType` is the caller's, not a guess: schema-v5 requiredChecks are
2372
+ * verify-only (`resolveProfileRequiredChecks`), so a scoping caller passes
2373
+ * `"verify"` and matches exactly the pair wave 2 evaluates.
2251
2374
  */
2252
- declare const RETRO_ENVELOPE_VALIDATORS: Record<number, z.ZodType<RetroEnvelope, unknown>>;
2253
- declare const SUPPORTED_RETRO_ENVELOPE_SCHEMA_VERSIONS: readonly number[];
2254
- /** The `schemaVersion` a candidate declares, or undefined when unreadable. */
2255
- declare const retroEnvelopeSchemaVersionOf: (candidate: unknown) => number | undefined;
2256
- type ParsedRetroEnvelope = {
2257
- disposition: "trusted";
2258
- envelope: RetroEnvelope;
2259
- schemaVersion: number;
2375
+ declare const boundFailingCheckNames: ({
2376
+ candidate,
2377
+ checkType,
2378
+ envelopes
2379
+ }: {
2380
+ candidate: EvidenceCandidateIdentity;
2381
+ checkType: EvidenceCheckType;
2382
+ envelopes: LoadedEvidenceEnvelope[];
2383
+ }) => string[];
2384
+ interface RequiredCheckEvaluationInput {
2385
+ authoringSessionIds: string[];
2386
+ candidate: EvidenceCandidateIdentity;
2387
+ envelopes: LoadedEvidenceEnvelope[];
2388
+ requiredChecks: RequiredCheck[];
2389
+ scopeContext: RequiredCheckScopeContext;
2390
+ }
2391
+ interface RequiredCheckOutcome {
2392
+ name: string;
2393
+ checkType: EvidenceCheckType;
2394
+ status: "satisfied" | "unmet" | "out-of-scope";
2395
+ inScope: boolean;
2396
+ scopeReason: string;
2397
+ scope?: RequiredCheckScope;
2398
+ reason?: string;
2399
+ matchedPath?: string;
2400
+ }
2401
+ interface RequiredCheckEvaluation {
2402
+ outcomes: RequiredCheckOutcome[];
2403
+ blockingReasons: string[];
2404
+ }
2405
+ declare const evaluateRequiredChecks: ({
2406
+ authoringSessionIds,
2407
+ candidate,
2408
+ envelopes,
2409
+ requiredChecks,
2410
+ scopeContext
2411
+ }: RequiredCheckEvaluationInput) => RequiredCheckEvaluation;
2412
+ declare const EVIDENCE_DIR = ".factory-memory/evidence";
2413
+ declare const loadEvidenceEnvelopes: (cwd: string) => LoadedEvidenceEnvelope[];
2414
+ //#endregion
2415
+ //#region src/review-proof-applicability.d.ts
2416
+ declare const REVIEW_STATUS_VALUES: readonly ["not-required", "current", "stale", "missing", "blocked"];
2417
+ declare const reviewStatusSchema: z.ZodEnum<{
2418
+ "not-required": "not-required";
2419
+ stale: "stale";
2420
+ blocked: "blocked";
2421
+ current: "current";
2422
+ missing: "missing";
2423
+ }>;
2424
+ type ReviewStatus = z.infer<typeof reviewStatusSchema>;
2425
+ interface CurrentReviewIdentity {
2426
+ headSha: string;
2427
+ patchId: string;
2428
+ }
2429
+ declare const reviewStatus: ({
2430
+ blocked,
2431
+ required,
2432
+ reviewedHeadSha,
2433
+ reviewedPatchId,
2434
+ headSha,
2435
+ patchId
2436
+ }: CurrentReviewIdentity & {
2437
+ blocked?: boolean;
2438
+ required: boolean;
2439
+ reviewedHeadSha?: string;
2440
+ reviewedPatchId?: string;
2441
+ }) => ReviewStatus;
2442
+ declare namespace proof_identity_d_exports {
2443
+ export { CurrentReviewIdentity, REVIEW_STATUS_VALUES, ReviewProofClaim, ReviewStatus, explicitFailureIdentity, isExplicitReviewFailure, isUntypedReviewProof, reviewStatus, reviewStatusSchema, selectReviewProof };
2444
+ }
2445
+ type ReviewProofClaim = {
2446
+ reviewedHeadSha?: string;
2447
+ reviewedPatchId?: string;
2448
+ untypedVerdict?: boolean;
2260
2449
  } | {
2261
- disposition: "degraded";
2262
- raw: unknown;
2263
- schemaVersion: number | undefined;
2450
+ explicitFailure: true;
2451
+ reviewedHeadSha?: string;
2452
+ reviewedPatchId?: string;
2453
+ untypedVerdict?: boolean;
2264
2454
  };
2265
- /**
2266
- * Parses a candidate against the versioned validators. A recognized major is
2267
- * validated typed-only (throws on an invalid known-version payload); an unknown
2268
- * major is round-tripped RAW and marked degraded — the retained payload is the
2269
- * exact input object, never a coerced projection. Mirrors the HQ ingest seam so
2270
- * the two sides agree on the skew posture.
2271
- */
2272
- declare const parseRetroEnvelope: (candidate: unknown) => ParsedRetroEnvelope;
2273
- /**
2274
- * Whether harvest recorded at least one token family. This is an operator
2275
- * summary predicate, not a delivery gate: a families-absent envelope remains
2276
- * valid and replayable when its data gaps explain why telemetry is unavailable.
2277
- */
2278
- declare const isRetroEnvelopeWireComplete: (envelope: Pick<RetroEnvelope, "tokenFamilies">) => boolean;
2279
- /** Epic anchor for an envelope: refs.epic, else refs.issue, else the PR. */
2280
- declare const retroEpicReference: (refs: RetroEnvelope["refs"]) => string | undefined;
2455
+ declare const isExplicitReviewFailure: (proof: ReviewProofClaim) => proof is {
2456
+ explicitFailure: true;
2457
+ reviewedHeadSha?: string;
2458
+ reviewedPatchId?: string;
2459
+ untypedVerdict?: boolean;
2460
+ };
2461
+ declare const isUntypedReviewProof: (proof: ReviewProofClaim) => proof is {
2462
+ untypedVerdict: true;
2463
+ reviewedHeadSha?: string;
2464
+ reviewedPatchId?: string;
2465
+ };
2466
+ declare const explicitFailureIdentity: (proof: ReviewProofClaim) => {
2467
+ reviewedHeadSha?: string;
2468
+ reviewedPatchId?: string;
2469
+ };
2470
+ declare const selectReviewProof: ({
2471
+ reviewProof
2472
+ }: {
2473
+ reviewProof: ReviewProofClaim;
2474
+ }) => {
2475
+ reviewedHeadSha?: string;
2476
+ reviewedPatchId?: string;
2477
+ untypedVerdict?: boolean;
2478
+ };
2479
+ //#endregion
2480
+ //#region src/pr-readiness/review-epoch.d.ts
2481
+ interface ReviewCycleState {
2482
+ autoBlockingFindings: number;
2483
+ countsBySeverity: Record<ReviewFindingSeverity, number>;
2484
+ highestBlockingSeverity?: ReviewFindingSeverity;
2485
+ highestOpenSeverity?: ReviewFindingSeverity;
2486
+ maxReviewCycles?: number;
2487
+ nonBlockingFindings: number;
2488
+ openFindings: number;
2489
+ reviewCycle?: number;
2490
+ staleRepeatFindings?: number;
2491
+ windowExhausted: boolean;
2492
+ }
2493
+ declare const reviewCycleStateFor: (proof: Pick<PrReviewProof, "ladder" | "reviewCycle" | "maxReviewCycles" | "reviews">, policy?: ReviewLadderPolicy, adjudicatedLedger?: FindingLedgerEntry[]) => ReviewCycleState;
2494
+ type ReviewAcceptance = "accepted-after-cap" | "accepted-clean" | "accepted-through-ladder" | "blocked";
2495
+ declare const resolveReviewAcceptance: (proof: PrReviewProof, review: PrReviewResult, policy: ReviewLadderPolicy | undefined) => ReviewAcceptance;
2496
+ type ReviewTerminalState = "accepted-with-findings" | "blocked" | "clean";
2497
+ declare const resolveReviewTerminalStateForEpoch: (proof: PrReviewProof, review: PrReviewResult, epoch: ReviewEpochMode, adjudicatedLedger?: FindingLedgerEntry[]) => ReviewTerminalState;
2498
+ declare const resolveReviewTerminalState: (proof: PrReviewProof, review: PrReviewResult, policy: ReviewLadderPolicy | undefined) => ReviewTerminalState;
2499
+ declare const resolveReviewTerminalStateAcrossReviews: (proof: PrReviewProof, epoch: ReviewEpochMode, adjudicatedLedger?: FindingLedgerEntry[]) => ReviewTerminalState | undefined;
2500
+ declare const resolveReviewTerminalStateAcrossReviewsForPolicy: (proof: PrReviewProof, policy: ReviewLadderPolicy) => ReviewTerminalState | undefined;
2501
+ declare const reviewProofFor: (proof: PrReviewProof | undefined, kind: PrReviewKind, policy: ReviewLadderPolicy | undefined, current?: {
2502
+ patchId: string;
2503
+ }) => ReviewProofClaim;
2504
+ declare namespace review_proof_d_exports {
2505
+ export { DEFAULT_PR_REVIEW_MAX_CYCLES, DEFAULT_PR_REVIEW_PROOF_PATH, PR_REVIEW_FINAL_READINESS_NOTICE, PR_REVIEW_FINDING_PROVENANCE_VERSION, PR_REVIEW_PROOF_DESCRIPTOR, PR_REVIEW_SCHEMA_VERSION, PrReviewFinding, PrReviewKind, PrReviewLadderState, PrReviewMode, PrReviewOutcome, PrReviewProof, PrReviewResult, PrReviewStageResolution, REVIEW_SEVERITIES, ReviewAcceptance, ReviewCycleState, ReviewFindingCategory, ReviewFindingSeverity, ReviewTerminalState, prReviewFindingSchema, prReviewProofSchema, prReviewResultSchema, readPrReviewProof, resolveReviewAcceptance, resolveReviewTerminalState, resolveReviewTerminalStateAcrossReviews, resolveReviewTerminalStateAcrossReviewsForPolicy, resolveReviewTerminalStateForEpoch, reviewCycleStateFor, reviewProofFor, validatePrReviewProof, validatePrReviewResult };
2506
+ }
2507
+ declare const PR_REVIEW_SCHEMA_VERSION = 2;
2508
+ declare const PR_REVIEW_FINDING_PROVENANCE_VERSION = 1;
2509
+ declare const DEFAULT_PR_REVIEW_PROOF_PATH = ".factory-memory/pr-review.json";
2510
+ declare const DEFAULT_PR_REVIEW_MAX_CYCLES = 5;
2511
+ declare const PR_REVIEW_FINAL_READINESS_NOTICE = "pr:review is a final readiness proof gate. Run it after local verification and avoid repeated full runs unless the review proof records actionable findings. Default review window: 5 cycles.";
2512
+ declare const prReviewFindingSchema: z.ZodType<PrReviewFinding>;
2513
+ declare const prReviewResultSchema: z.ZodType<PrReviewResult>;
2514
+ declare const prReviewProofSchema: z.ZodType<PrReviewProof>;
2515
+ declare const validatePrReviewResult: (value: unknown) => PrReviewResult;
2516
+ declare const validatePrReviewProof: (value: unknown) => PrReviewProof;
2517
+ declare const readPrReviewProof: (filePath: string) => PrReviewProof;
2518
+ declare const PR_REVIEW_PROOF_DESCRIPTOR: ProofDescriptor<PrReviewProof>;
2281
2519
  //#endregion
2282
2520
  //#region src/schemas.d.ts
2283
2521
  declare const boundaryCheckProofSchema: z.ZodObject<{
@@ -2328,24 +2566,18 @@ declare const boundaryCheckProofSchema: z.ZodObject<{
2328
2566
  value: z.ZodString;
2329
2567
  }, z.core.$strip>>;
2330
2568
  status: z.ZodEnum<{
2331
- blocked: "blocked";
2332
2569
  ready: "ready";
2570
+ blocked: "blocked";
2333
2571
  }>;
2334
2572
  }, z.core.$strip>;
2335
2573
  type BoundaryCheckProofRecord = z.infer<typeof boundaryCheckProofSchema>;
2336
2574
  //#endregion
2337
2575
  //#region src/boundary-check.d.ts
2338
- interface BoundaryPullRequestRef {
2339
- headRefOid?: string;
2340
- mergeCommitOid?: string;
2341
- number: number;
2342
- state: "OPEN" | "CLOSED" | "MERGED";
2343
- }
2344
2576
  interface BoundaryCheckGithub {
2345
2577
  fetchIssueBody: (repo: string, issue: number) => string;
2346
2578
  fetchIssueComments: (repo: string, issue: number) => GithubIssueComment[];
2347
2579
  fetchClosingPullRequests: (repo: string, issue: number) => BoundaryPullRequestRef[];
2348
- fetchPullRequest: (repo: string, pr: number) => BoundaryPullRequestRef;
2580
+ fetchPullRequest?: (repo: string, pr: number) => BoundaryPullRequestRef;
2349
2581
  }
2350
2582
  interface BoundaryCheckArgs {
2351
2583
  cwd?: string;
@@ -2362,7 +2594,7 @@ interface BoundaryCheckDependencies {
2362
2594
  declare function runBoundaryCheck(args: BoundaryCheckArgs, dependencies?: BoundaryCheckDependencies): BoundaryCheckProofRecord;
2363
2595
  declare function validateBoundaryCheckProof(value: unknown): BoundaryCheckProofRecord;
2364
2596
  //#endregion
2365
- //#region src/commands/doctor.d.ts
2597
+ //#region src/cli-output.d.ts
2366
2598
  interface CliOutput {
2367
2599
  stderr: Pick<NodeJS.WriteStream, "write">;
2368
2600
  stdout: Pick<NodeJS.WriteStream, "write">;
@@ -2410,32 +2642,6 @@ declare const runDemandWaive: (args: DemandWaiveArgs, dependencies?: DemandWaive
2410
2642
  //#region src/commands/demand-waive.d.ts
2411
2643
  type DemandWaiveAction = (args: DemandWaiveArgs) => DemandWaiver;
2412
2644
  //#endregion
2413
- //#region src/hq-credentials.d.ts
2414
- /**
2415
- * Why a reference did not resolve. Each value names a different remedy, and
2416
- * none of them can be inferred from a value-or-nothing result:
2417
- *
2418
- * - `resolver-missing` — no secret-manager binary on PATH.
2419
- * - `resolver-blocked` — a binary exists but this session may not execute it
2420
- * (a sandbox denying exec). The command belongs outside the sandbox.
2421
- * - `resolver-timeout` — the probe expired: a desktop agent waiting on an
2422
- * approval nobody can give here.
2423
- * - `resolver-refused` — the binary ran and produced no value. Its store is
2424
- * unreachable from this session (a sandbox with no keychain access) or the
2425
- * reference is not readable. These two stay one status on purpose: telling
2426
- * them apart would mean reading resolver output.
2427
- */
2428
- type SecretResolutionFailure = "resolver-blocked" | "resolver-missing" | "resolver-refused" | "resolver-timeout";
2429
- /** A structured resolution outcome. The value travels only when resolved. */
2430
- type SecretResolution = {
2431
- status: "resolved";
2432
- value: string;
2433
- } | {
2434
- status: SecretResolutionFailure;
2435
- };
2436
- /** Resolves a secret reference. Injected so tests stay offline. */
2437
- type SecretReferenceResolver = (reference: string) => SecretResolution;
2438
- //#endregion
2439
2645
  //#region src/hq-flush.d.ts
2440
2646
  /**
2441
2647
  * Spool locations this run did not drain because they sit under an earlier
@@ -2459,6 +2665,19 @@ type HqFlushResult = (HqFlushOrphans & {
2459
2665
  status: "flushed";
2460
2666
  });
2461
2667
  //#endregion
2668
+ //#region src/catch-up-recognition.d.ts
2669
+ type CatchUpRecognitionResult = {
2670
+ recognition: CatchUpRecognition;
2671
+ recognized: true;
2672
+ } | {
2673
+ reasons: string[];
2674
+ recognized: false;
2675
+ };
2676
+ type CatchUpRecognizer = (input: {
2677
+ base: string;
2678
+ cwd: string;
2679
+ }) => CatchUpRecognitionResult;
2680
+ //#endregion
2462
2681
  //#region src/pr-review.d.ts
2463
2682
  interface PrReviewArgs extends LoadProjectProfileInput {
2464
2683
  base: string;
@@ -2474,13 +2693,13 @@ interface PrReviewGitDependencies {
2474
2693
  changedFiles: (cwd: string, base: string) => string[];
2475
2694
  currentHeadSha: (cwd: string) => string;
2476
2695
  isAncestor: (cwd: string, ancestor: string, descendant: string) => boolean;
2696
+ recognizeCatchUp?: CatchUpRecognizer;
2477
2697
  stablePatchId: (cwd: string, base: string) => string;
2478
2698
  statusPorcelain: (cwd: string) => string;
2479
2699
  }
2480
2700
  interface PrReviewDependencies {
2481
2701
  git?: PrReviewGitDependencies;
2482
2702
  hq?: HqIngestDependencies;
2483
- publishCheckRun?: (input: PublishFactoryCheckInput) => void;
2484
2703
  }
2485
2704
  declare function runPrReview(args: PrReviewArgs, dependencies?: PrReviewDependencies): Promise<PrReviewProof>;
2486
2705
  //#endregion
@@ -2493,7 +2712,7 @@ interface CleanInstallResolutionDependencies {
2493
2712
  }
2494
2713
  //#endregion
2495
2714
  //#region src/pr-verify.d.ts
2496
- type PrVerifyMode = "auto" | "docs-only" | "trivial" | "full";
2715
+ type PrVerifyMode = "auto" | "docs-only" | "full";
2497
2716
  interface VerificationCommandOutcome {
2498
2717
  counts?: {
2499
2718
  testFiles?: number;
@@ -2514,6 +2733,7 @@ interface PrVerifyGitDependencies {
2514
2733
  currentHeadSha: (cwd: string) => string;
2515
2734
  emptyTreeHash: (cwd: string) => string;
2516
2735
  mergeBaseSha: (cwd: string, base: string) => string;
2736
+ recognizeCatchUp?: CatchUpRecognizer;
2517
2737
  runVerificationCommand: (command: string, cwd: string, env: Record<string, string>) => VerificationCommandOutcome;
2518
2738
  showFileAtRef?: (cwd: string, ref: string, absolutePath: string) => string | undefined;
2519
2739
  statusPorcelain: (cwd: string) => string;
@@ -2702,6 +2922,28 @@ type PrReadyAction = (args: PrReadyArgs) => Promise<unknown>;
2702
2922
  //#region src/commands/pr-review.d.ts
2703
2923
  type PrReviewAction = (args: PrReviewArgs) => Promise<unknown>;
2704
2924
  //#endregion
2925
+ //#region src/pr-status-hud-command.d.ts
2926
+ interface PrStatusHudArgs {
2927
+ readonly cwd: string;
2928
+ readonly headSha: string;
2929
+ /**
2930
+ * Read token for the preview-proof inventory list. The App token cannot
2931
+ * read the force-push timeline (no contents permission), so the workflow
2932
+ * `GITHUB_TOKEN` serves that read (#825).
2933
+ */
2934
+ readonly inventoryToken?: string;
2935
+ readonly owner: string;
2936
+ readonly planPath?: string;
2937
+ readonly pr: number;
2938
+ readonly repo: string;
2939
+ readonly token: string;
2940
+ }
2941
+ type PrStatusHudAction = (args: PrStatusHudArgs) => Promise<{
2942
+ action: string;
2943
+ commentId: number;
2944
+ url: string;
2945
+ }>;
2946
+ //#endregion
2705
2947
  //#region src/packages/trace/implementation/core.d.ts
2706
2948
  declare const FactoryTraceEnvelopeCoreSchema: z.ZodObject<{
2707
2949
  createdAt: z.ZodString;
@@ -2846,6 +3088,7 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
2846
3088
  patchId: z.ZodString;
2847
3089
  reason: z.ZodEnum<{
2848
3090
  "no-applicable-mode": "no-applicable-mode";
3091
+ "faithful-merge": "faithful-merge";
2849
3092
  }>;
2850
3093
  reviewCycle: z.ZodNumber;
2851
3094
  }, z.core.$strict>, readonly [z.ZodObject<{
@@ -2868,6 +3111,7 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
2868
3111
  patchId: z.ZodString;
2869
3112
  reason: z.ZodEnum<{
2870
3113
  "no-applicable-mode": "no-applicable-mode";
3114
+ "faithful-merge": "faithful-merge";
2871
3115
  }>;
2872
3116
  reviewCycle: z.ZodNumber;
2873
3117
  }, z.core.$strict>], {
@@ -2881,6 +3125,7 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
2881
3125
  patchId: z.ZodString;
2882
3126
  reason: z.ZodEnum<{
2883
3127
  "no-applicable-mode": "no-applicable-mode";
3128
+ "faithful-merge": "faithful-merge";
2884
3129
  }>;
2885
3130
  reviewCycle: z.ZodNumber;
2886
3131
  }, z.core.$strict>;
@@ -2898,7 +3143,7 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
2898
3143
  observedAt: string;
2899
3144
  outcome: "not-required";
2900
3145
  patchId: string;
2901
- reason: "no-applicable-mode";
3146
+ reason: "no-applicable-mode" | "faithful-merge";
2902
3147
  reviewCycle: number;
2903
3148
  issue?: number | undefined;
2904
3149
  pr?: number | undefined;
@@ -3699,74 +3944,6 @@ declare const scanFactoryTraceDiagnostics: ({
3699
3944
  repoRoot,
3700
3945
  to
3701
3946
  }: ScanFactoryTraceDiagnosticsOptions) => FactoryTraceDiagnostic[];
3702
- //#endregion
3703
- //#region src/interior-telemetry/gate-timing.d.ts
3704
- declare const GATE_TIMING_SCHEMA_VERSION = 1;
3705
- type FactoryGateName = "boundary:check" | "factory:closeout" | "pr:ready" | "pr:review" | "pr:verify";
3706
- type GateTimingOutcome = "fail" | "pass";
3707
- interface GateTimingRecord {
3708
- agentRunId: string;
3709
- cycle: number;
3710
- durationMs: number;
3711
- gate: FactoryGateName;
3712
- outcome: GateTimingOutcome;
3713
- schemaVersion: typeof GATE_TIMING_SCHEMA_VERSION;
3714
- startedAt: string;
3715
- startOffsetMs: number;
3716
- }
3717
- //#endregion
3718
- //#region src/retro-envelope-builder.d.ts
3719
- /**
3720
- * Folds a lane's gate-timing ledger (`.factory-memory/gate-timing/<id>.jsonl`,
3721
- * wave-1 PR #33) into a versioned retro envelope at `factory:closeout`.
3722
- *
3723
- * STRUCTURAL INVARIANT (#677 repeat-class rule; PR #35 review cycles 1-2):
3724
- * telemetry CONTENT can never fail the closeout build gate. Every value that
3725
- * reaches the envelope passes through one sanitization seam that makes the
3726
- * output valid BY CONSTRUCTION:
3727
- *
3728
- * - strings are clamped to their wire bounds (truncated, with a data gap when
3729
- * truncation lost information);
3730
- * - numbers must be finite and within plausibility bounds BEFORE any derived
3731
- * arithmetic; an absurd value (1e16 ms duration, year-9999 timestamp) SKIPS
3732
- * its record with a data gap rather than clamping, because clamping would
3733
- * assert a measurement that never happened;
3734
- * - arrays are bounded to their schema maxima (gates[] keeps the most recent);
3735
- * - derived computations (wall clock, cycles) consume only sanitized inputs,
3736
- * so no ledger content can push them outside Date/Number safe ranges.
3737
- *
3738
- * Terminal backstop: the assembled candidate goes through a final schema
3739
- * parse; if that still fails, a minimal-valid envelope (clamped identity,
3740
- * empty gates, a data gap naming the failure) is built and returned instead.
3741
- * `buildRetroEnvelope` therefore never throws for content — the closeout gate
3742
- * can only fail on filesystem errors when persisting.
3743
- */
3744
- interface BuildRetroEnvelopeInput {
3745
- agentRunId: string;
3746
- /** Optional pointer (key/URL) to #8's durable proof archive — never payload. */
3747
- archiveRef?: string;
3748
- dataGaps?: string[];
3749
- generatedAt: Date;
3750
- interventions?: number;
3751
- /** Per-family session identities the lane already records. */
3752
- joinKeys?: {
3753
- claudeSessionIds?: string[];
3754
- codexThreadIds?: string[];
3755
- };
3756
- /** The lane's gate-timing ledger records, in append order. */
3757
- ledger: GateTimingRecord[];
3758
- outcome?: RetroEnvelope["outcome"];
3759
- phases?: RetroEnvelope["phases"];
3760
- refs: RetroEnvelope["refs"];
3761
- repo: RetroEnvelope["repo"];
3762
- /**
3763
- * Token families. They may be absent when native session data is unavailable
3764
- * (valid does not imply available telemetry). When present they satisfy the
3765
- * family invariants.
3766
- */
3767
- tokenFamilies?: RetroEnvelope["tokenFamilies"];
3768
- }
3769
- declare const buildRetroEnvelope: (input: BuildRetroEnvelopeInput) => RetroEnvelope;
3770
3947
  declare namespace comment_provenance_d_exports {
3771
3948
  export { SHA_MATCH_MIN_LENGTH, isBotLogin, sameHeadSha };
3772
3949
  }
@@ -3776,18 +3953,12 @@ declare const sameHeadSha: (left: string, right: string) => boolean;
3776
3953
  //#endregion
3777
3954
  //#region src/doctor-hq-checks.d.ts
3778
3955
  /**
3779
- * Two `doctor` checks that make silent HQ delivery failure loud (#394,
3780
- * epic #389 wave 2).
3781
- *
3782
- * Both consume #414's structured credential resolution rather than inventing
3783
- * a second classification: a sandboxed session that cannot reach the
3784
- * keychain is reported as "cannot resolve credentials here", never as
3785
- * "credentials are wrong" or a silent pass. Both name `psf hq:flush` and
3786
- * `psf pr:publish` as the commands that need a trusted local session.
3956
+ * The `doctor` check that makes silent HQ delivery failure loud (#394,
3957
+ * epic #389 wave 2): the local spool is empty, and no stranded evidence is
3958
+ * waiting under the spool root.
3787
3959
  *
3788
- * Advisory stays advisory: neither check can block anything but doctor's own
3789
- * exit status (epic #389 design decision 4). Absent credentials make the
3790
- * remote check a skip with a printed reason, never a silent pass.
3960
+ * Advisory stays advisory: this check can block nothing but doctor's own exit
3961
+ * status (epic #389 design decision 4).
3791
3962
  */
3792
3963
  type DoctorCheckStatus = "error" | "ok" | "warning";
3793
3964
  interface DoctorCheck {
@@ -3799,12 +3970,6 @@ interface HqSpoolCheckDependencies {
3799
3970
  countSpool?: typeof countHqSpoolWork;
3800
3971
  sweepOrphans?: typeof sweepHqSpoolOrphans;
3801
3972
  }
3802
- interface HqRetroReadbackCheckDependencies {
3803
- fetch?: typeof fetch;
3804
- readFile?: typeof readFile;
3805
- resolve?: SecretReferenceResolver;
3806
- timeoutMs?: number;
3807
- }
3808
3973
  //#endregion
3809
3974
  //#region src/doctor.d.ts
3810
3975
  interface DoctorReport {
@@ -3823,8 +3988,6 @@ interface DoctorProjectProfileInput extends LoadProjectProfileInput {
3823
3988
  base?: string;
3824
3989
  env?: NodeJS.ProcessEnv;
3825
3990
  /** Test seam for the local HQ spool check (#394); production never sets this. */
3826
- hqRetroReadbackDependencies?: HqRetroReadbackCheckDependencies;
3827
- /** Test seam for the remote HQ retro-envelope read-back check (#394). */
3828
3991
  hqSpoolDependencies?: HqSpoolCheckDependencies;
3829
3992
  /**
3830
3993
  * Append the read-only admission checklist (#292): every requirement this
@@ -3913,98 +4076,6 @@ declare const renderPrBodySections: ({
3913
4076
  reviewProof?: PrReviewProof;
3914
4077
  verifyProof?: PrVerifyProof;
3915
4078
  }) => string;
3916
- declare namespace boundary_manifest_d_exports {
3917
- export { BOUNDARY_CLOSEOUT_DEFAULT_RUNG, BOUNDARY_MANIFEST_SCHEMA_VERSION, BoundaryManifest, BoundaryManifestExtraction, BoundaryManifestParse, FACTORY_BOUNDARY_FENCE_LANG, boundaryManifestSchema, closeoutRungFor, extractBoundaryManifestBlock, manifestContentHash, parseBoundaryManifest, rungMeetsMinimum, specContentHash };
3918
- }
3919
- declare const FACTORY_BOUNDARY_FENCE_LANG = "factory-boundary";
3920
- declare const BOUNDARY_MANIFEST_SCHEMA_VERSION = 1;
3921
- declare const BOUNDARY_CLOSEOUT_DEFAULT_RUNG: EvidenceReviewRung;
3922
- declare const rungMeetsMinimum: (rung: EvidenceReviewRung, minimum: EvidenceReviewRung) => boolean;
3923
- declare const boundaryManifestBaseSchema: 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
- declare const boundaryManifestSchema: z.ZodObject<{
3952
- boundary: z.ZodString;
3953
- closeout: z.ZodOptional<z.ZodObject<{
3954
- review: z.ZodEnum<{
3955
- oracle: "oracle";
3956
- "independent-model": "independent-model";
3957
- human: "human";
3958
- }>;
3959
- }, z.core.$loose>>;
3960
- declaredBy: z.ZodString;
3961
- prs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
3962
- schemaVersion: z.ZodLiteral<1>;
3963
- topology: z.ZodEnum<{
3964
- flagged: "flagged";
3965
- "each-to-main": "each-to-main";
3966
- stacked: "stacked";
3967
- }>;
3968
- waves: z.ZodArray<z.ZodObject<{
3969
- autoMerge: z.ZodOptional<z.ZodBoolean>;
3970
- issues: z.ZodArray<z.ZodNumber>;
3971
- name: z.ZodString;
3972
- review: z.ZodEnum<{
3973
- oracle: "oracle";
3974
- "independent-model": "independent-model";
3975
- human: "human";
3976
- }>;
3977
- }, z.core.$loose>>;
3978
- }, z.core.$loose>;
3979
- type BoundaryManifest = z.infer<typeof boundaryManifestBaseSchema>;
3980
- type BoundaryManifestExtraction = {
3981
- ok: true;
3982
- blockText: string;
3983
- } | {
3984
- ok: false;
3985
- error: string;
3986
- };
3987
- declare const extractBoundaryManifestBlock: (issueBody: string) => BoundaryManifestExtraction;
3988
- declare const manifestContentHash: (blockText: string) => string;
3989
- declare const specContentHash: (issueBody: string) => string;
3990
- type BoundaryManifestParse = {
3991
- ok: true;
3992
- manifest: BoundaryManifest;
3993
- manifestHash: string;
3994
- } | {
3995
- ok: false;
3996
- error: string;
3997
- };
3998
- declare const parseBoundaryManifest: (issueBody: string) => BoundaryManifestParse;
3999
- declare const closeoutRungFor: (manifest: BoundaryManifest) => EvidenceReviewRung;
4000
- //#endregion
4001
- //#region src/demand-resolution.d.ts
4002
- /** The boundary-manifest wave demand that applies to one pull request. */
4003
- interface WaveReviewDemand {
4004
- autoMerge: boolean;
4005
- review: EvidenceReviewRung;
4006
- wave: string;
4007
- }
4008
4079
  declare namespace readiness_evaluation_d_exports {
4009
4080
  export { CORRECTNESS_UNTYPED_REVIEW_BLOCKER_REASON, DRAFT_BLOCKER_REASON, EvaluationInput, ManagedReadinessLedger, PENDING_CHECKS_BLOCKER_REASON_PREFIX, READINESS_REPAIR_CODES, ReadinessRepair, ReadinessStatus, SCHEMA_VERSION, SECURITY_UNTYPED_REVIEW_BLOCKER_REASON, evaluateReadiness, managedReadinessLedgerSchema, readinessExitCode, readinessRepairSchema, validateManagedReadinessLedger };
4010
4081
  }
@@ -4056,7 +4127,7 @@ declare const evaluateReadiness: (input: EvaluationInput) => {
4056
4127
  ledger: {
4057
4128
  baseSha: string;
4058
4129
  blockingReasons: string[];
4059
- classification: "trivial" | "docs/process-only" | "non-trivial";
4130
+ classification: "docs/process-only" | "trivial" | "non-trivial";
4060
4131
  github: {
4061
4132
  draft: boolean;
4062
4133
  mergeStateStatus: string;
@@ -4076,13 +4147,13 @@ declare const evaluateReadiness: (input: EvaluationInput) => {
4076
4147
  reviews: {
4077
4148
  correctness: {
4078
4149
  required: boolean;
4079
- status: "not-required" | "blocked" | "current" | "stale" | "missing";
4150
+ status: "not-required" | "stale" | "blocked" | "current" | "missing";
4080
4151
  reviewedHeadSha?: string | undefined;
4081
4152
  reviewedPatchId?: string | undefined;
4082
4153
  };
4083
4154
  security?: {
4084
4155
  required: boolean;
4085
- status: "not-required" | "blocked" | "current" | "stale" | "missing";
4156
+ status: "not-required" | "stale" | "blocked" | "current" | "missing";
4086
4157
  reviewedHeadSha?: string | undefined;
4087
4158
  reviewedPatchId?: string | undefined;
4088
4159
  } | undefined;
@@ -4090,7 +4161,7 @@ declare const evaluateReadiness: (input: EvaluationInput) => {
4090
4161
  schemaVersion: 1;
4091
4162
  verification: {
4092
4163
  command: "patronage-factory pr:verify";
4093
- prVerify: "passed" | "stale" | "missing";
4164
+ prVerify: "stale" | "passed" | "missing";
4094
4165
  docsOnlyDeltaAccepted?: boolean | undefined;
4095
4166
  docsOnlyVerifiedHeadSha?: string | undefined;
4096
4167
  trivialDeltaAccepted?: boolean | undefined;
@@ -4105,7 +4176,7 @@ declare const evaluateReadiness: (input: EvaluationInput) => {
4105
4176
  status: "satisfied" | "unmet" | "out-of-scope";
4106
4177
  reason?: string | undefined;
4107
4178
  scope?: {
4108
- classifications: ("trivial" | "docs/process-only" | "non-trivial")[];
4179
+ classifications: ("docs/process-only" | "trivial" | "non-trivial")[];
4109
4180
  } | undefined;
4110
4181
  }[] | undefined;
4111
4182
  mergeBaseSha?: string | undefined;
@@ -4458,6 +4529,34 @@ declare const appendReviewLadderStageTraceEvent: ({
4458
4529
  }) => AppendFactoryTraceEventResult;
4459
4530
  declare const tryAppendReviewLadderStageTraceEvent: (input: Parameters<typeof appendReviewLadderStageTraceEvent>[0]) => ReviewLadderStageTraceWriteResult;
4460
4531
  //#endregion
4532
+ //#region src/verification-run-context.d.ts
4533
+ declare const FACTORY_BASE_REF_ENV = "FACTORY_BASE_REF";
4534
+ declare const FACTORY_CHANGED_FILES_ENV = "FACTORY_CHANGED_FILES";
4535
+ declare const FACTORY_CHANGED_FILES_FILE_ENV = "FACTORY_CHANGED_FILES_FILE";
4536
+ declare const EMPTY_TREE_OBJECT_HASH = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
4537
+ declare const DEFAULT_ROOT_SHARED_GLOBS: string[];
4538
+ interface VerificationRunContextInput {
4539
+ baseRef: string;
4540
+ changedFiles: string[];
4541
+ fullSuiteBaseRef?: string;
4542
+ rootSharedGlobs?: string[];
4543
+ inlineLimitBytes?: number;
4544
+ tmpDir?: string;
4545
+ }
4546
+ interface VerificationEnv {
4547
+ env: Record<string, string>;
4548
+ cleanup: () => void;
4549
+ }
4550
+ interface VerificationRunContext {
4551
+ readonly baseRef: string;
4552
+ readonly changedFiles: string[];
4553
+ readonly forcesFullSuite: boolean;
4554
+ readonly fullSuiteReasons: string[];
4555
+ buildEnv: () => VerificationEnv;
4556
+ runSummaryLines: () => string[];
4557
+ }
4558
+ declare function createVerificationRunContext(input: VerificationRunContextInput): VerificationRunContext;
4559
+ //#endregion
4461
4560
  //#region src/verification-battery.d.ts
4462
4561
  type BatteryDisposition = "executed" | "not-required";
4463
4562
  /**
@@ -4535,92 +4634,6 @@ declare const planVerificationBattery: <Command extends BatteryCandidateCommand>
4535
4634
  /** Console lines naming every withheld command and why. Never silent. */
4536
4635
  declare const batteryScopeSummaryLines: (plan: VerificationBatteryPlan<BatteryCandidateCommand>) => string[];
4537
4636
  //#endregion
4538
- //#region src/preview-lifecycle.d.ts
4539
- type PreviewDisposition = "deploy" | "not-required";
4540
- interface PreviewTargetPlan {
4541
- basis: string;
4542
- disposition: PreviewDisposition;
4543
- name: string;
4544
- }
4545
- interface PreviewLifecyclePlan {
4546
- /** The declared preview stacks to deploy, in declaration order. */
4547
- deploy: string[];
4548
- /** The withheld stacks, in declaration order. */
4549
- notRequired: PreviewTargetPlan[];
4550
- /** Whether a trusted, identity-bound stamp was available at all. */
4551
- stampTrusted: boolean;
4552
- /** Every declared preview target with its disposition, in declaration order. */
4553
- targets: PreviewTargetPlan[];
4554
- }
4555
- /**
4556
- * Structural subset of the profile: the impact declarations plus the external
4557
- * demand list. Structural rather than a `Pick` so this module does not import
4558
- * `profile.ts`.
4559
- */
4560
- interface PreviewLifecycleProfile {
4561
- impact?: {
4562
- targets: {
4563
- name: string;
4564
- }[];
4565
- };
4566
- requiredChecks?: {
4567
- name: string;
4568
- }[];
4569
- }
4570
- /**
4571
- * The declared preview stacks: impact targets that are ALSO declared required
4572
- * checks — i.e. targets whose proof is produced externally, which is exactly
4573
- * what a preview producer is.
4574
- *
4575
- * Deriving the list from the two existing declarations rather than adding a
4576
- * third is what makes lifecycle and demand unable to disagree: the stacks this
4577
- * plan can withhold are precisely the demands wave 2 can release, so a stack
4578
- * can never be skipped while its proof stays demanded.
4579
- */
4580
- declare const previewLifecycleTargets: (profile: PreviewLifecycleProfile) => string[];
4581
- /**
4582
- * Plan the preview lifecycle for one candidate.
4583
- *
4584
- * Trust is resolved here through the SAME identity gate demand release uses
4585
- * (`trustedImpactStamp`): the proof must have passed and must bind both the
4586
- * candidate's headSha and its patchId. A stale, aborted, absent, or
4587
- * differently-bound proof yields no stamp, and every declared stack is planned
4588
- * for deploy. Total over its INPUTS — no proof, stamp, or profile can make it
4589
- * throw. A malformed CALL is the deliberate exception: omitting
4590
- * `vetoedTargets` is API misuse, not data doubt, and throws.
4591
- */
4592
- declare const planPreviewLifecycle: ({
4593
- candidate,
4594
- profile,
4595
- proof,
4596
- vetoedTargets
4597
- }: {
4598
- candidate: {
4599
- headSha: string;
4600
- patchId: string;
4601
- };
4602
- profile: PreviewLifecycleProfile;
4603
- proof: PrVerifyProof | undefined;
4604
- /**
4605
- * Stack names with a current, candidate-bound FAILING envelope. Scoping is
4606
- * withheld for these whatever the stamp says — the same veto demand release
4607
- * applies, and for the same reason: a withheld stack is a stack that can
4608
- * never re-emit the envelope its standing demand needs. Callers hold the
4609
- * checkout context, so they resolve the set with `boundFailingCheckNames`
4610
- * and pass it in; this module stays pure.
4611
- *
4612
- * REQUIRED, with no default, on purpose: a defaulted `[]` reads the same
4613
- * whether the caller inspected the envelopes or never looked, and this seam
4614
- * exists precisely for EXTERNAL preview producers — the callers most likely
4615
- * to skip the lookup. Pass the result of `boundFailingCheckNames`; pass `[]`
4616
- * only to mean "inspected the envelopes and found no bound failure".
4617
- *
4618
- * Deliberately visible to `api:check` as a breaking signature change
4619
- * (pre-1.0, no external callers yet).
4620
- */
4621
- vetoedTargets: readonly string[];
4622
- }) => PreviewLifecyclePlan;
4623
- //#endregion
4624
4637
  //#region src/worker-checkout-guard.d.ts
4625
4638
  type CheckoutDirsProbe = (cwd: string) => {
4626
4639
  gitCommonDir: string;
@@ -4647,6 +4660,7 @@ interface CreateProgramOptions {
4647
4660
  prPublish?: PrPublishAction;
4648
4661
  prReady?: PrReadyAction;
4649
4662
  prReview?: PrReviewAction;
4663
+ prStatusHud?: PrStatusHudAction;
4650
4664
  };
4651
4665
  factoryCliInvocation?: FactoryCliInvocation;
4652
4666
  output?: CliOutput;
@@ -4654,4 +4668,4 @@ interface CreateProgramOptions {
4654
4668
  declare function createProgram(options?: CreateProgramOptions): Command;
4655
4669
  declare function run(argv?: string[]): Promise<void>;
4656
4670
  //#endregion
4657
- export { type AppendFactoryTraceEventResult, type AssembledReviewPrompt, type BatteryCommandDisposition, type BatteryDisposition, 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 ImpactScopeDecision, type ImpactScopeSurface, 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 PreviewDisposition, type PreviewLifecyclePlan, type PreviewTargetPlan, 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 ScopedOutCommand, type TraceMirrorDiagnostic, type TraceSink, type TraceWriteResult, type TraceWriteSinks, type VerificationBatteryPlan, type VerificationReuse, type WaivedDemand, WorkerCheckoutGuardError, type WorkerCloseoutLessonsTraceEvent, appendReviewLadderStageTraceEvent, appendWithTraceSinks, applyDemandWaiver, assembleReviewPrompt, assertWorkerCheckoutAllowed, authorizeDemandWaiver, batteryScopeSummaryLines, 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, impactStampScopeDecision, inferFixedInThreadDispositions, isProductionHqUrl, isRetroEnvelopeWireComplete, loadProjectProfile, normalizeIssueComments, openLadderFindings, parseRetroEnvelope, planPreviewLifecycle, planPublishFollowUp, planVerificationBattery, readiness_evaluation_d_exports as prReadinessEvaluation, external_evidence_d_exports as prReadinessExternalEvidence, 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, previewLifecycleTargets, publishEpicStructure, readDemandWaivers, readPrReadyProof, readPrReviewProof, resolveFactoryRepository, resolveFindingBlocking, resolveReviewFindingCategory, resolveReviewFindingSeverity, resolveReviewLadderPolicy, resolveTraceWriteSinks, retroEnvelopeSchemaVersionOf, retroEnvelopeV1Schema, retroEpicReference, reviewCycleStateFor, reviewFocusFromIssueBody, reviewPromptSectionSchema, reviewPromptSectionsSchema, run, runBoundaryCheck, runDemandWaive, runEvidenceEmit, runPrPublish, runPrReady, runPrReview, runPrVerify, scanFactoryTraceDiagnostics, scanFactoryTraceEvents, selectWaiversForCandidate, staleRepeatLadderFindings, toFactoryTraceEnvelope, tryAppendReviewGateNotRequiredTraceEvent, tryAppendReviewLadderStageTraceEvent, validateBoundaryCheckProof, validateDagDocument, validateDemandWaiverStore, validateFactoryTraceEvent, validateMergeFreezeState, validatePrReadyProof, validatePrReviewProof, validatePrVerifyProof, waivedDemandNotice, waivedDemandSchema, worktree_scratch_files_d_exports as worktreeScratchFiles };
4671
+ export { type AppendFactoryTraceEventResult, type AssembledReviewPrompt, type BatteryCommandDisposition, type BatteryDisposition, type BoundaryCheckArgs, type BoundaryCheckDependencies, type BoundaryCheckProofRecord, type BuildEpicStructureEventInput, type CloudflareAccessServiceToken, type CompletedFactoryCheckSnapshot, CreateProgramOptions, DEFAULT_DEMAND_WAIVER_PATH, DEFAULT_FACTORY_REPOSITORY, DEFAULT_ROOT_SHARED_GLOBS, type DagDocument, type DemandWaiveArgs, type DemandWaiveDependencies, DemandWaiveRefusalError, type DemandWaiver, type DemandWaiverStore, EMPTY_TREE_OBJECT_HASH, EPIC_STRUCTURE_NODE_STATUSES, EPIC_STRUCTURE_SCHEMA_VERSION, type EpicStructureEvent, type EpicStructureGraphPayload, type EpicStructureNodeStatus, EpicStructureValidationError, type EvidenceEmitArgs, type EvidenceEmitDependencies, type EvidenceEmitResult, FACTORY_BASE_REF_ENV, FACTORY_CHANGED_FILES_ENV, FACTORY_CHANGED_FILES_FILE_ENV, type FactoryCliInvocation, FactoryCliInvocationSchema, type FactoryPrStatusCheckName, type FactoryPrStatusSources, type FactoryProjectProfile, type FactoryTraceDiagnostic, type FactoryTraceEnvelope, type FactoryTraceEvent, type FindingDisposition, type FindingLedgerEntry, type FollowUpAction, FollowUpActionSchema, type ImpactScopeDecision, type ImpactScopeSurface, type IssueReviewFocus, type LadderDispositionDeclaration, MERGE_FREEZE_APP_SLUG, MERGE_FREEZE_CHECK_NAME, type MergeFreezeState, type PlanFactoryPrStatusHudInput, type PrPublishArgs, type PrPublishDependencies, PrPublishFollowUpError, type PrPublishFollowUpOutcome, type PrPublishHandoff, type PrPublishResult, type PrReadyArgs, type PrReadyProof, type PresentFactoryPrStatusHudDependencies, type PresentFactoryPrStatusHudInput, type PreviewDisposition, type PreviewLifecyclePlan, type PreviewTargetPlan, type PublishEpicStructureArgs, type PublishEpicStructureResult, type PublishFollowUpPlan, REVIEW_FOCUS_SECTION, type ReadFactoryPrStatusSourcesDependencies, type ReadFactoryPrStatusSourcesInput, type RefreshFactoryPrStatusHudInput, type RenderFactoryPrStatusHudInput, type ReviewGateNotRequiredProof, type ReviewGateTraceIdentity, type ReviewLadderCycle, type ReviewLadderEvaluation, type ReviewLadderPolicy, type ReviewLadderStageEvent, type ReviewLadderTraceIdentity, type ReviewPromptSection, type ReviewPromptSectionProvenance, type ScanFactoryTraceDiagnosticsOptions, type ScanFactoryTraceOptions, type ScanFactoryTraceResult, type ScopedOutCommand, type TraceMirrorDiagnostic, type TraceSink, type TraceWriteResult, type TraceWriteSinks, type VerificationBatteryPlan, type VerificationReuse, type VerificationRunContext, type VerificationRunContextInput, type WaivedDemand, WorkerCheckoutGuardError, type WorkerCloseoutLessonsTraceEvent, appendReviewLadderStageTraceEvent, appendWithTraceSinks, applyDemandWaiver, assembleReviewPrompt, assertFactoryPrStatusIdentity, assertWorkerCheckoutAllowed, authorizeDemandWaiver, batteryScopeSummaryLines, blockingLadderFindings, boundary_manifest_d_exports as boundaryManifest, boundary_review_proof_d_exports as boundaryReviewProof, buildEpicStructureEvent, buildEpicStructurePayload, buildEvidenceEnvelope, buildReviewGateNotRequiredTraceEvent, buildReviewLadderStageTraceEvent, comment_provenance_d_exports as commentProvenance, createLocalJsonlTraceSink, createProgram, createVerificationRunContext, doctorProjectProfile, epicStructureEventId, evaluateReviewLadder, evidenceEnvelopeFilename, findingKey, followUpFromArgv, impactStampScopeDecision, inferFixedInThreadDispositions, isProductionHqUrl, loadProjectProfile, normalizeIssueComments, openLadderFindings, planFactoryPrStatusHud, planPreviewLifecycle, planPublishFollowUp, planVerificationBattery, readiness_evaluation_d_exports as prReadinessEvaluation, external_evidence_d_exports as prReadinessExternalEvidence, 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, presentFactoryPrStatusHud, previewLifecycleTargets, publishEpicStructure, readDemandWaivers, readFactoryPrStatusSources, readPrReadyProof, readPrReviewProof, refreshFactoryPrStatusHud, refreshFactoryPrStatusHudSafely, renderFactoryPrStatusHud, resolveFactoryRepository, resolveFindingBlocking, resolveReviewFindingCategory, resolveReviewFindingSeverity, resolveReviewLadderPolicy, resolveTraceWriteSinks, reviewCycleStateFor, reviewFocusFromIssueBody, reviewPromptSectionSchema, reviewPromptSectionsSchema, run, runBoundaryCheck, runDemandWaive, runEvidenceEmit, runPrPublish, runPrReady, runPrReview, runPrVerify, scanFactoryTraceDiagnostics, scanFactoryTraceEvents, selectWaiversForCandidate, staleRepeatLadderFindings, toFactoryTraceEnvelope, tryAppendReviewGateNotRequiredTraceEvent, tryAppendReviewLadderStageTraceEvent, validateBoundaryCheckProof, validateDagDocument, validateDemandWaiverStore, validateFactoryTraceEvent, validateMergeFreezeState, validatePrReadyProof, validatePrReviewProof, validatePrVerifyProof, validatePreviewLifecyclePlan, waivedDemandNotice, waivedDemandSchema, worktree_scratch_files_d_exports as worktreeScratchFiles };