@patronage/software-factory 1.0.0-alpha.23 → 1.0.0-alpha.25

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
@@ -17,8 +17,8 @@ declare const boundaryManifestBaseSchema: z.ZodObject<{
17
17
  boundary: z.ZodString;
18
18
  closeout: z.ZodOptional<z.ZodObject<{
19
19
  review: z.ZodEnum<{
20
- oracle: "oracle";
21
20
  "independent-model": "independent-model";
21
+ oracle: "oracle";
22
22
  human: "human";
23
23
  }>;
24
24
  }, z.core.$loose>>;
@@ -36,8 +36,8 @@ declare const boundaryManifestBaseSchema: z.ZodObject<{
36
36
  issues: z.ZodArray<z.ZodNumber>;
37
37
  name: z.ZodString;
38
38
  review: z.ZodEnum<{
39
- oracle: "oracle";
40
39
  "independent-model": "independent-model";
40
+ oracle: "oracle";
41
41
  human: "human";
42
42
  }>;
43
43
  }, z.core.$loose>>;
@@ -46,8 +46,8 @@ declare const boundaryManifestSchema: z.ZodObject<{
46
46
  boundary: z.ZodString;
47
47
  closeout: z.ZodOptional<z.ZodObject<{
48
48
  review: z.ZodEnum<{
49
- oracle: "oracle";
50
49
  "independent-model": "independent-model";
50
+ oracle: "oracle";
51
51
  human: "human";
52
52
  }>;
53
53
  }, z.core.$loose>>;
@@ -65,8 +65,8 @@ declare const boundaryManifestSchema: z.ZodObject<{
65
65
  issues: z.ZodArray<z.ZodNumber>;
66
66
  name: z.ZodString;
67
67
  review: z.ZodEnum<{
68
- oracle: "oracle";
69
68
  "independent-model": "independent-model";
69
+ oracle: "oracle";
70
70
  human: "human";
71
71
  }>;
72
72
  }, z.core.$loose>>;
@@ -151,8 +151,8 @@ declare const boundaryReviewProofBaseSchema: z.ZodObject<{
151
151
  }>;
152
152
  producer: z.ZodString;
153
153
  rung: z.ZodEnum<{
154
- oracle: "oracle";
155
154
  "independent-model": "independent-model";
155
+ oracle: "oracle";
156
156
  human: "human";
157
157
  }>;
158
158
  schemaVersion: z.ZodLiteral<1>;
@@ -195,8 +195,8 @@ declare const boundaryReviewProofSchema: z.ZodObject<{
195
195
  }>;
196
196
  producer: z.ZodString;
197
197
  rung: z.ZodEnum<{
198
- oracle: "oracle";
199
198
  "independent-model": "independent-model";
199
+ oracle: "oracle";
200
200
  human: "human";
201
201
  }>;
202
202
  schemaVersion: z.ZodLiteral<1>;
@@ -235,6 +235,102 @@ interface BoundaryPullRequestRef {
235
235
  state: "OPEN" | "CLOSED" | "MERGED";
236
236
  }
237
237
  //#endregion
238
+ //#region src/demand-waiver.d.ts
239
+ declare const DEFAULT_DEMAND_WAIVER_PATH = ".factory-memory/demand-waivers.json";
240
+ /** One recorded operator act: this demand, on this candidate, waived. */
241
+ interface DemandWaiver {
242
+ candidate: {
243
+ headSha: string;
244
+ pr: number;
245
+ };
246
+ demand: string;
247
+ /** The authenticated GitHub account that recorded the waiver. */
248
+ operator: string;
249
+ rationale: string;
250
+ recordedAt: string;
251
+ /** Optional audit metadata; never waiver authority. */
252
+ session?: string;
253
+ }
254
+ interface DemandWaiverStore {
255
+ command: "patronage-factory demand:waive";
256
+ schemaVersion: 1;
257
+ waivers: DemandWaiver[];
258
+ }
259
+ declare const validateDemandWaiverStore: (value: unknown) => DemandWaiverStore;
260
+ /**
261
+ * A demand that was in force, was NOT met, and was waived by the operator.
262
+ *
263
+ * `unmetReasons` is required and non-empty: every reason the demand refused is
264
+ * carried through verbatim. There is no field on this record that could say
265
+ * "satisfied", and no code path constructs one without a refusal to carry.
266
+ */
267
+ interface WaivedDemand {
268
+ demand: string;
269
+ operator: string;
270
+ rationale: string;
271
+ recordedAt: string;
272
+ session?: string;
273
+ /** The demand's refusals at evaluation time, preserved verbatim. */
274
+ unmetReasons: string[];
275
+ }
276
+ declare const waivedDemandSchema: z.ZodType<WaivedDemand>;
277
+ /** The waivers that bind one candidate: same PR, same head. */
278
+ declare const selectWaiversForCandidate: ({
279
+ headSha,
280
+ pr,
281
+ waivers
282
+ }: {
283
+ headSha: string | undefined;
284
+ pr: number;
285
+ waivers: readonly DemandWaiver[];
286
+ }) => DemandWaiver[];
287
+ interface DemandOutcome {
288
+ blockingReasons: string[];
289
+ waived?: WaivedDemand;
290
+ }
291
+ /**
292
+ * Fold one resolved demand's refusals through the operator's waivers.
293
+ *
294
+ * A satisfied demand (no refusals) stays satisfied and the waiver stays inert
295
+ * — a waiver can only ever move a demand from *unmet-and-blocking* to
296
+ * *unmet-and-waived*, never to met.
297
+ */
298
+ declare const applyDemandWaiver: ({
299
+ demand,
300
+ reasons,
301
+ waivers
302
+ }: {
303
+ demand: string;
304
+ reasons: readonly string[];
305
+ waivers: readonly DemandWaiver[];
306
+ }) => DemandOutcome;
307
+ /** How a waived demand reads to a human. Never the word "satisfied". */
308
+ declare const waivedDemandNotice: (waived: WaivedDemand) => string;
309
+ interface DemandWaiverAuthorization {
310
+ operator: string;
311
+ session?: string;
312
+ }
313
+ type AuthorizeDemandWaiverResult = {
314
+ authorization: DemandWaiverAuthorization;
315
+ refusals?: undefined;
316
+ } | {
317
+ authorization?: undefined;
318
+ refusals: string[];
319
+ };
320
+ /**
321
+ * Operator identity, `declaredBy`-style: a named human account, recorded on
322
+ * the waiver and enforced here. Session is optional audit metadata only: it is
323
+ * not credential-backed, so its absence or equality never authorizes or
324
+ * refuses an operator act.
325
+ */
326
+ declare const authorizeDemandWaiver: ({
327
+ authenticatedLogin,
328
+ session
329
+ }: {
330
+ authenticatedLogin: string | undefined;
331
+ session: string | undefined;
332
+ }) => AuthorizeDemandWaiverResult;
333
+ //#endregion
238
334
  //#region src/hq-ingest-sink.d.ts
239
335
  interface HqIngestDependencies {
240
336
  /**
@@ -475,6 +571,7 @@ declare function sweepHqSpoolOrphans(input: {
475
571
  //#region src/packages/review-prompt-sections/schema.d.ts
476
572
  declare const reviewPromptSectionSchema: z.ZodObject<{
477
573
  provenance: z.ZodEnum<{
574
+ "coding-standards": "coding-standards";
478
575
  "prior-review-ledger": "prior-review-ledger";
479
576
  "issue-review-focus": "issue-review-focus";
480
577
  }>;
@@ -485,6 +582,7 @@ type ReviewPromptSection = z.infer<typeof reviewPromptSectionSchema>;
485
582
  type ReviewPromptSectionProvenance = ReviewPromptSection["provenance"];
486
583
  declare const reviewPromptSectionsSchema: z.ZodArray<z.ZodObject<{
487
584
  provenance: z.ZodEnum<{
585
+ "coding-standards": "coding-standards";
488
586
  "prior-review-ledger": "prior-review-ledger";
489
587
  "issue-review-focus": "issue-review-focus";
490
588
  }>;
@@ -492,6 +590,23 @@ declare const reviewPromptSectionsSchema: z.ZodArray<z.ZodObject<{
492
590
  text: z.ZodString;
493
591
  }, z.core.$strict>>;
494
592
  //#endregion
593
+ //#region src/policy-resolution.d.ts
594
+ /** How a gate resolved the review policy it evaluated a candidate under. */
595
+ declare const policyResolutionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
596
+ basePolicyDigest: z.ZodString;
597
+ baseRefName: z.ZodString;
598
+ candidatePolicyDigest: z.ZodString;
599
+ effectiveDigest: z.ZodString;
600
+ policyBaseSha: z.ZodString;
601
+ reviewPolicyChanged: z.ZodBoolean;
602
+ status: z.ZodLiteral<"authoritative">;
603
+ }, z.core.$strict>, z.ZodObject<{
604
+ baseRefName: z.ZodString;
605
+ reason: z.ZodString;
606
+ status: z.ZodLiteral<"unresolved">;
607
+ }, z.core.$strict>], "status">;
608
+ type PolicyResolution = z.infer<typeof policyResolutionSchema>;
609
+ //#endregion
495
610
  //#region src/review-ladder-policy.d.ts
496
611
  type ReviewFindingSeverity = "critical" | "high" | "medium" | "low" | "unknown";
497
612
  type ReviewFindingCategory = "correctness" | "safety" | "coordination" | "maintainability" | "unknown";
@@ -587,6 +702,7 @@ interface ReviewLadderCycle {
587
702
  headSha: string;
588
703
  patchId: string;
589
704
  };
705
+ historical?: true;
590
706
  model?: string;
591
707
  correlatedRerun?: boolean;
592
708
  session?: LadderSessionAttribution;
@@ -754,6 +870,13 @@ interface PrReviewProof {
754
870
  changedFiles: string[];
755
871
  cleanedPaths: string[];
756
872
  ladder?: PrReviewLadderState;
873
+ /**
874
+ * The policy identity this review run resolved its demanded kinds under
875
+ * (#922 Slice B). Optional: a run that could not reach the authority records
876
+ * the refusal instead, and `pr:ready` decides what an unresolved or
877
+ * disagreeing identity means for admission.
878
+ */
879
+ policyResolution?: PolicyResolution;
757
880
  reviewRequirement?: {
758
881
  reason: "no-applicable-mode" | "faithful-merge";
759
882
  status: "not-required";
@@ -761,102 +884,6 @@ interface PrReviewProof {
761
884
  reviews: PrReviewResult[];
762
885
  }
763
886
  //#endregion
764
- //#region src/demand-waiver.d.ts
765
- declare const DEFAULT_DEMAND_WAIVER_PATH = ".factory-memory/demand-waivers.json";
766
- /** One recorded operator act: this demand, on this candidate, waived. */
767
- interface DemandWaiver {
768
- candidate: {
769
- headSha: string;
770
- pr: number;
771
- };
772
- demand: string;
773
- /** The authenticated GitHub account that recorded the waiver. */
774
- operator: string;
775
- rationale: string;
776
- recordedAt: string;
777
- /** Optional audit metadata; never waiver authority. */
778
- session?: string;
779
- }
780
- interface DemandWaiverStore {
781
- command: "patronage-factory demand:waive";
782
- schemaVersion: 1;
783
- waivers: DemandWaiver[];
784
- }
785
- declare const validateDemandWaiverStore: (value: unknown) => DemandWaiverStore;
786
- /**
787
- * A demand that was in force, was NOT met, and was waived by the operator.
788
- *
789
- * `unmetReasons` is required and non-empty: every reason the demand refused is
790
- * carried through verbatim. There is no field on this record that could say
791
- * "satisfied", and no code path constructs one without a refusal to carry.
792
- */
793
- interface WaivedDemand {
794
- demand: string;
795
- operator: string;
796
- rationale: string;
797
- recordedAt: string;
798
- session?: string;
799
- /** The demand's refusals at evaluation time, preserved verbatim. */
800
- unmetReasons: string[];
801
- }
802
- declare const waivedDemandSchema: z.ZodType<WaivedDemand>;
803
- /** The waivers that bind one candidate: same PR, same head. */
804
- declare const selectWaiversForCandidate: ({
805
- headSha,
806
- pr,
807
- waivers
808
- }: {
809
- headSha: string | undefined;
810
- pr: number;
811
- waivers: readonly DemandWaiver[];
812
- }) => DemandWaiver[];
813
- interface DemandOutcome {
814
- blockingReasons: string[];
815
- waived?: WaivedDemand;
816
- }
817
- /**
818
- * Fold one resolved demand's refusals through the operator's waivers.
819
- *
820
- * A satisfied demand (no refusals) stays satisfied and the waiver stays inert
821
- * — a waiver can only ever move a demand from *unmet-and-blocking* to
822
- * *unmet-and-waived*, never to met.
823
- */
824
- declare const applyDemandWaiver: ({
825
- demand,
826
- reasons,
827
- waivers
828
- }: {
829
- demand: string;
830
- reasons: readonly string[];
831
- waivers: readonly DemandWaiver[];
832
- }) => DemandOutcome;
833
- /** How a waived demand reads to a human. Never the word "satisfied". */
834
- declare const waivedDemandNotice: (waived: WaivedDemand) => string;
835
- interface DemandWaiverAuthorization {
836
- operator: string;
837
- session?: string;
838
- }
839
- type AuthorizeDemandWaiverResult = {
840
- authorization: DemandWaiverAuthorization;
841
- refusals?: undefined;
842
- } | {
843
- authorization?: undefined;
844
- refusals: string[];
845
- };
846
- /**
847
- * Operator identity, `declaredBy`-style: a named human account, recorded on
848
- * the waiver and enforced here. Session is optional audit metadata only: it is
849
- * not credential-backed, so its absence or equality never authorizes or
850
- * refuses an operator act.
851
- */
852
- declare const authorizeDemandWaiver: ({
853
- authenticatedLogin,
854
- session
855
- }: {
856
- authenticatedLogin: string | undefined;
857
- session: string | undefined;
858
- }) => AuthorizeDemandWaiverResult;
859
- //#endregion
860
887
  //#region src/blocked-reasons.d.ts
861
888
  declare const blockedReasonSchema: z.ZodObject<{
862
889
  code: z.ZodString;
@@ -891,35 +918,91 @@ interface CheckoutRepository {
891
918
  owner: string;
892
919
  }
893
920
  //#endregion
894
- //#region src/follow-up.d.ts
895
- interface FactoryCliInvocation {
896
- /** Runtime arguments ending with the factory CLI entry module. */
897
- argvPrefix: string[];
898
- executable: string;
921
+ //#region src/profile.d.ts
922
+ declare const DEFAULT_FACTORY_REPOSITORY = "unknown/unknown";
923
+ /** The one profile shape this build accepts (ADR 0023, #318, #351, #742). */
924
+ declare const PROFILE_SCHEMA_VERSION = 6;
925
+ declare const factoryProjectProfileSchema: z.ZodObject<{
926
+ $schema: z.ZodOptional<z.ZodString>;
927
+ extensions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
928
+ hq: z.ZodOptional<z.ZodObject<{
929
+ enabled: z.ZodBoolean;
930
+ endpoint: z.ZodIntersection<z.ZodString, z.ZodString>;
931
+ }, z.core.$strict>>;
932
+ impact: z.ZodOptional<z.ZodObject<{
933
+ inert: z.ZodOptional<z.ZodArray<z.ZodString>>;
934
+ targets: z.ZodArray<z.ZodObject<{
935
+ importers: z.ZodArray<z.ZodString>;
936
+ name: z.ZodString;
937
+ paths: z.ZodOptional<z.ZodArray<z.ZodString>>;
938
+ }, z.core.$strict>>;
939
+ }, z.core.$strict>>;
940
+ lifecycleContract: z.ZodOptional<z.ZodObject<{
941
+ command: z.ZodString;
942
+ jobName: z.ZodOptional<z.ZodString>;
943
+ }, z.core.$strict>>;
944
+ repository: z.ZodObject<{
945
+ name: z.ZodString;
946
+ owner: z.ZodString;
947
+ }, z.core.$strict>;
948
+ requiredChecks: z.ZodOptional<z.ZodArray<z.ZodObject<{
949
+ name: z.ZodString;
950
+ scope: z.ZodOptional<z.ZodObject<{
951
+ classifications: z.ZodArray<z.ZodEnum<{
952
+ "docs/process-only": "docs/process-only";
953
+ "non-trivial": "non-trivial";
954
+ }>>;
955
+ }, z.core.$strict>>;
956
+ }, z.core.$strict>>>;
957
+ review: z.ZodOptional<z.ZodObject<{
958
+ conditional: z.ZodArray<z.ZodObject<{
959
+ paths: z.ZodArray<z.ZodString>;
960
+ }, z.core.$strict>>;
961
+ }, z.core.$strict>>;
962
+ schemaVersion: z.ZodLiteral<6>;
963
+ verification: z.ZodObject<{
964
+ commands: z.ZodArray<z.ZodObject<{
965
+ command: z.ZodString;
966
+ description: z.ZodString;
967
+ impactTarget: z.ZodOptional<z.ZodString>;
968
+ name: z.ZodString;
969
+ requiredCheck: z.ZodOptional<z.ZodString>;
970
+ scope: z.ZodDefault<z.ZodEnum<{
971
+ trivial: "trivial";
972
+ "docs-only": "docs-only";
973
+ full: "full";
974
+ }>>;
975
+ }, z.core.$strip>>;
976
+ }, z.core.$strip>;
977
+ }, z.core.$strict>;
978
+ type FactoryProjectProfile = z.infer<typeof factoryProjectProfileSchema>;
979
+ declare const resolveFactoryRepository: (profile?: Pick<FactoryProjectProfile, "repository"> | undefined) => string;
980
+ interface LoadProjectProfileInput {
981
+ cwd?: string;
982
+ profilePath?: string;
899
983
  }
900
- declare const FactoryCliInvocationSchema: z.ZodType<FactoryCliInvocation>;
901
- interface FollowUpAction {
902
- /**
903
- * Machine-safe argv-style array for the obvious next action, e.g.
904
- * ["gh","pr","merge","513","--squash"]. Same shape and field name that
905
- * `factory:delegate --print` emits, so an orchestrating agent can spawn the
906
- * next command without reconstructing a shell string. argv[0] is the
907
- * executable; the rest are literal, already-split arguments.
908
- */
909
- argv: string[];
984
+ interface LoadProjectProfileResult {
985
+ path: string;
986
+ profile: FactoryProjectProfile;
987
+ }
988
+ declare function loadProjectProfile(input?: LoadProjectProfileInput): LoadProjectProfileResult;
989
+ //#endregion
990
+ //#region src/catch-up-recognition-record.d.ts
991
+ interface CatchUpRecognition {
992
+ /** The ref the candidate targets, as the recognizing command resolved it. */
993
+ baseRef: string;
994
+ /** The live target tip at recognition time; the head's first parent. */
995
+ baseTipSha: string;
996
+ /** The head's second parent: the admitted base-side content merged in. */
997
+ mergedParentSha: string;
910
998
  /**
911
- * Human-readable rendering of {@link argv} for logs and operators. Additive
912
- * to argv, never a substitute for it — argv is the source of truth.
999
+ * The tree `git merge-tree --write-tree` produced for the two parents. It
1000
+ * equals the head's own tree; that equality is the faithfulness proof.
913
1001
  */
914
- command: string;
1002
+ mergedTreeSha: string;
1003
+ /** The ref that proves the second parent is admitted content. */
1004
+ upstreamRef: string;
915
1005
  }
916
- /**
917
- * Build a {@link FollowUpAction} from a literal argv array. The `command`
918
- * string is derived from argv so the two never drift.
919
- */
920
- declare const followUpFromArgv: (argv: string[]) => FollowUpAction;
921
- /** Canonical zod schema for the optional follow-up field on JSON outputs. */
922
- declare const FollowUpActionSchema: z.ZodType<FollowUpAction>;
923
1006
  //#endregion
924
1007
  //#region src/diff-classification.d.ts
925
1008
  declare const DIFF_CLASSIFICATIONS: readonly ["docs/process-only", "trivial", "non-trivial"];
@@ -971,101 +1054,137 @@ interface ImpactScopeDecision {
971
1054
  scoped: boolean;
972
1055
  }
973
1056
  /**
974
- * Whether a trusted stamp RELEASES one target-scoped unit of work — an
975
- * external proof demand (#542 wave 2), a verification-battery command, or a
976
- * preview (Alchemy) lifecycle stack (#430 wave 3).
977
- *
978
- * The only release path is a `target-scoped` stamp of exactly this build's
979
- * stamp version whose target entry for exactly this name is provably
980
- * `not-affected`. Every other input — no trusted stamp, an unknown stamp
981
- * version, a conservative stamp, a name the stamp does not classify, or an
982
- * `affected` verdict — keeps today's full-work floor. Work only ever gets
983
- * released, never added or satisfied: this function can withdraw a demand, it
984
- * can never certify one.
1057
+ * Whether a trusted stamp RELEASES one target-scoped unit of work — an
1058
+ * external proof demand (#542 wave 2), a verification-battery command, or a
1059
+ * preview (Alchemy) lifecycle stack (#430 wave 3).
1060
+ *
1061
+ * The only release path is a `target-scoped` stamp of exactly this build's
1062
+ * stamp version whose target entry for exactly this name is provably
1063
+ * `not-affected`. Every other input — no trusted stamp, an unknown stamp
1064
+ * version, a conservative stamp, a name the stamp does not classify, or an
1065
+ * `affected` verdict — keeps today's full-work floor. Work only ever gets
1066
+ * released, never added or satisfied: this function can withdraw a demand, it
1067
+ * can never certify one.
1068
+ *
1069
+ * Identity binding is the CALLER's precondition: pass only a stamp computed
1070
+ * for, or read from a pr:verify proof bound to, the current candidate (see
1071
+ * `trustedImpactStamp` in `pr-readiness/verification-proof.ts`); pass
1072
+ * `undefined` otherwise.
1073
+ */
1074
+ declare const impactStampScopeDecision: ({
1075
+ stamp,
1076
+ surface,
1077
+ targetName
1078
+ }: {
1079
+ stamp: ImpactStamp | undefined;
1080
+ surface: ImpactScopeSurface;
1081
+ targetName: string;
1082
+ }) => ImpactScopeDecision;
1083
+ //#endregion
1084
+ //#region src/required-check-policy.d.ts
1085
+ declare const EVIDENCE_CHECK_TYPES: readonly ["review", "verify"];
1086
+ type EvidenceCheckType = (typeof EVIDENCE_CHECK_TYPES)[number];
1087
+ declare const requiredCheckScopeSchema: z.ZodObject<{
1088
+ classifications: z.ZodArray<z.ZodEnum<{
1089
+ "docs/process-only": "docs/process-only";
1090
+ trivial: "trivial";
1091
+ "non-trivial": "non-trivial";
1092
+ }>>;
1093
+ }, z.core.$strict>;
1094
+ type RequiredCheckScope = z.infer<typeof requiredCheckScopeSchema>;
1095
+ interface RequiredCheckScopeContext {
1096
+ catchUpRecognition?: CatchUpRecognition;
1097
+ classification: DiffClassification | undefined;
1098
+ impactStamp?: ImpactStamp;
1099
+ }
1100
+ interface ScopeDecision {
1101
+ inScope: boolean;
1102
+ reason: string;
1103
+ }
1104
+ declare const requiredCheckInScope: ({
1105
+ context,
1106
+ scope
1107
+ }: {
1108
+ context: RequiredCheckScopeContext;
1109
+ scope?: RequiredCheckScope;
1110
+ }) => ScopeDecision;
1111
+ interface RequiredCheck {
1112
+ name: string;
1113
+ checkType: EvidenceCheckType;
1114
+ scope?: RequiredCheckScope;
1115
+ }
1116
+ //#endregion
1117
+ //#region src/demand-resolution.d.ts
1118
+ /**
1119
+ * The two GitHub reads that make the base policy authoritative: the live tip of
1120
+ * a branch, and one file's content at an exact commit. Injectable so tests can
1121
+ * state what the authority says; an absent implementation is the real read, so
1122
+ * an unstated authority is a refusal rather than a silent pass.
1123
+ */
1124
+ interface BaseReviewPolicyAuthority {
1125
+ branchTipSha: (input: {
1126
+ branch: string;
1127
+ cwd: string;
1128
+ repository: CheckoutRepository;
1129
+ }) => string;
1130
+ profileContentAtRef: (input: {
1131
+ cwd: string;
1132
+ profilePath: string;
1133
+ ref: string;
1134
+ repository: CheckoutRepository;
1135
+ }) => string;
1136
+ }
1137
+ /**
1138
+ * The pull request whose base ref is the authority, as the resolving stage
1139
+ * knows it (#922 Slice B).
985
1140
  *
986
- * Identity binding is the CALLER's precondition: pass only a stamp computed
987
- * for, or read from a pr:verify proof bound to, the current candidate (see
988
- * `trustedImpactStamp` in `pr-readiness/verification-proof.ts`); pass
989
- * `undefined` otherwise.
1141
+ * `pr:ready` is handed a PR number and reads the record; `pr:verify` and
1142
+ * `pr:review` run in the authoring checkout and look the PR up from the branch,
1143
+ * which can legitimately find nothing. `isCrossRepository` stays `unknown` for
1144
+ * the reason the reader below states: an unstated fork answer is not a "no".
990
1145
  */
991
- declare const impactStampScopeDecision: ({
992
- stamp,
993
- surface,
994
- targetName
995
- }: {
996
- stamp: ImpactStamp | undefined;
997
- surface: ImpactScopeSurface;
998
- targetName: string;
999
- }) => ImpactScopeDecision;
1146
+ interface CandidatePullRequestPolicyContext {
1147
+ baseRefName: string;
1148
+ isCrossRepository: unknown;
1149
+ }
1150
+ /** What a stage found when it looked for the pull request that owns this branch. */
1151
+ type CandidatePullRequestLookup = {
1152
+ pullRequest: CandidatePullRequestPolicyContext;
1153
+ status: "found";
1154
+ } | {
1155
+ reason: string;
1156
+ status: "unavailable";
1157
+ };
1000
1158
  //#endregion
1001
- //#region src/profile.d.ts
1002
- declare const DEFAULT_FACTORY_REPOSITORY = "unknown/unknown";
1003
- /** The one profile shape this build accepts (ADR 0023, #318, #351, #742). */
1004
- declare const PROFILE_SCHEMA_VERSION = 6;
1005
- declare const factoryProjectProfileSchema: z.ZodObject<{
1006
- $schema: z.ZodOptional<z.ZodString>;
1007
- extensions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1008
- hq: z.ZodOptional<z.ZodObject<{
1009
- enabled: z.ZodBoolean;
1010
- endpoint: z.ZodIntersection<z.ZodString, z.ZodString>;
1011
- }, z.core.$strict>>;
1012
- impact: z.ZodOptional<z.ZodObject<{
1013
- inert: z.ZodOptional<z.ZodArray<z.ZodString>>;
1014
- targets: z.ZodArray<z.ZodObject<{
1015
- importers: z.ZodArray<z.ZodString>;
1016
- name: z.ZodString;
1017
- paths: z.ZodOptional<z.ZodArray<z.ZodString>>;
1018
- }, z.core.$strict>>;
1019
- }, z.core.$strict>>;
1020
- lifecycleContract: z.ZodOptional<z.ZodObject<{
1021
- command: z.ZodString;
1022
- jobName: z.ZodOptional<z.ZodString>;
1023
- }, z.core.$strict>>;
1024
- repository: z.ZodObject<{
1025
- name: z.ZodString;
1026
- owner: z.ZodString;
1027
- }, z.core.$strict>;
1028
- requiredChecks: z.ZodOptional<z.ZodArray<z.ZodObject<{
1029
- name: z.ZodString;
1030
- scope: z.ZodOptional<z.ZodObject<{
1031
- classifications: z.ZodArray<z.ZodEnum<{
1032
- "docs/process-only": "docs/process-only";
1033
- "non-trivial": "non-trivial";
1034
- }>>;
1035
- }, z.core.$strict>>;
1036
- }, z.core.$strict>>>;
1037
- review: z.ZodOptional<z.ZodObject<{
1038
- conditional: z.ZodArray<z.ZodObject<{
1039
- paths: z.ZodArray<z.ZodString>;
1040
- }, z.core.$strict>>;
1041
- }, z.core.$strict>>;
1042
- schemaVersion: z.ZodLiteral<6>;
1043
- verification: z.ZodObject<{
1044
- commands: z.ZodArray<z.ZodObject<{
1045
- command: z.ZodString;
1046
- description: z.ZodString;
1047
- impactTarget: z.ZodOptional<z.ZodString>;
1048
- name: z.ZodString;
1049
- requiredCheck: z.ZodOptional<z.ZodString>;
1050
- scope: z.ZodDefault<z.ZodEnum<{
1051
- trivial: "trivial";
1052
- "docs-only": "docs-only";
1053
- full: "full";
1054
- }>>;
1055
- }, z.core.$strip>>;
1056
- }, z.core.$strip>;
1057
- }, z.core.$strict>;
1058
- type FactoryProjectProfile = z.infer<typeof factoryProjectProfileSchema>;
1059
- declare const resolveFactoryRepository: (profile?: Pick<FactoryProjectProfile, "repository"> | undefined) => string;
1060
- interface LoadProjectProfileInput {
1061
- cwd?: string;
1062
- profilePath?: string;
1159
+ //#region src/follow-up.d.ts
1160
+ interface FactoryCliInvocation {
1161
+ /** Runtime arguments ending with the factory CLI entry module. */
1162
+ argvPrefix: string[];
1163
+ executable: string;
1063
1164
  }
1064
- interface LoadProjectProfileResult {
1065
- path: string;
1066
- profile: FactoryProjectProfile;
1165
+ declare const FactoryCliInvocationSchema: z.ZodType<FactoryCliInvocation>;
1166
+ interface FollowUpAction {
1167
+ /**
1168
+ * Machine-safe argv-style array for the obvious next action, e.g.
1169
+ * ["gh","pr","merge","513","--squash"]. Same shape and field name that
1170
+ * `factory:delegate --print` emits, so an orchestrating agent can spawn the
1171
+ * next command without reconstructing a shell string. argv[0] is the
1172
+ * executable; the rest are literal, already-split arguments.
1173
+ */
1174
+ argv: string[];
1175
+ /**
1176
+ * Human-readable rendering of {@link argv} for logs and operators. Additive
1177
+ * to argv, never a substitute for it — argv is the source of truth.
1178
+ */
1179
+ command: string;
1067
1180
  }
1068
- declare function loadProjectProfile(input?: LoadProjectProfileInput): LoadProjectProfileResult;
1181
+ /**
1182
+ * Build a {@link FollowUpAction} from a literal argv array. The `command`
1183
+ * string is derived from argv so the two never drift.
1184
+ */
1185
+ declare const followUpFromArgv: (argv: string[]) => FollowUpAction;
1186
+ /** Canonical zod schema for the optional follow-up field on JSON outputs. */
1187
+ declare const FollowUpActionSchema: z.ZodType<FollowUpAction>;
1069
1188
  //#endregion
1070
1189
  //#region src/pr-verify-mode.d.ts
1071
1190
  /**
@@ -1467,8 +1586,8 @@ declare const managedReadinessLedgerSchema: z.ZodObject<{
1467
1586
  reviewedHeadSha: z.ZodOptional<z.ZodString>;
1468
1587
  reviewedPatchId: z.ZodOptional<z.ZodString>;
1469
1588
  status: z.ZodEnum<{
1470
- "not-required": "not-required";
1471
1589
  stale: "stale";
1590
+ "not-required": "not-required";
1472
1591
  blocked: "blocked";
1473
1592
  current: "current";
1474
1593
  missing: "missing";
@@ -1479,8 +1598,8 @@ declare const managedReadinessLedgerSchema: z.ZodObject<{
1479
1598
  reviewedHeadSha: z.ZodOptional<z.ZodString>;
1480
1599
  reviewedPatchId: z.ZodOptional<z.ZodString>;
1481
1600
  status: z.ZodEnum<{
1482
- "not-required": "not-required";
1483
1601
  stale: "stale";
1602
+ "not-required": "not-required";
1484
1603
  blocked: "blocked";
1485
1604
  current: "current";
1486
1605
  missing: "missing";
@@ -1516,7 +1635,7 @@ type ReadinessStatus = "ready" | "blocked";
1516
1635
  type ManagedReadinessLedger = z.infer<typeof managedReadinessLedgerSchema>;
1517
1636
  declare function validateManagedReadinessLedger(value: unknown): ManagedReadinessLedger;
1518
1637
  declare namespace status_check_rollup_d_exports {
1519
- export { CheckState, HOSTED_VERIFY_CHECK_NAME, StatusCheckRollup, hostedVerifyCheckState, isFactoryReadyCheck, isHostedVerifyCheck, statusCheckState };
1638
+ export { CheckState, HOSTED_VERIFY_CHECK_NAME, StatusCheckRollup, hostedVerifyCheckState, isFactoryReadyCheck, isHostedVerifyCheck, pendingCheckNames, statusCheckState };
1520
1639
  }
1521
1640
  type CheckState = "passed" | "failed" | "pending" | "none" | "unknown";
1522
1641
  interface StatusCheckRollup {
@@ -1563,8 +1682,23 @@ declare const isHostedVerifyCheck: (check: StatusCheckRollup) => boolean;
1563
1682
  * nothing else in the rollup would have said so.
1564
1683
  */
1565
1684
  declare const hostedVerifyCheckState: (rollup: StatusCheckRollup[] | undefined) => CheckState;
1685
+ /**
1686
+ * The names of the runs `statusCheckState` would count as pending, in the
1687
+ * order the rollup reports them.
1688
+ *
1689
+ * Same reader, same collapsing of superseded generations — this only says
1690
+ * *which* runs hold the head open, so a caller that waits on them can name
1691
+ * them. A run with no context and no name is reported as `unnamed check`
1692
+ * rather than dropped: a wait must not look settled because one row was
1693
+ * unprintable.
1694
+ */
1695
+ declare const pendingCheckNames: (rollup: StatusCheckRollup[] | undefined, exclude?: (check: StatusCheckRollup) => boolean) => string[];
1566
1696
  declare const statusCheckState: (rollup: StatusCheckRollup[] | undefined, exclude?: (check: StatusCheckRollup) => boolean) => CheckState;
1567
1697
  //#endregion
1698
+ //#region src/github-client.d.ts
1699
+ /** Read a branch tip from GitHub rather than a checkout's cached remote ref. */
1700
+ declare const fetchGitHubBranchTipSha: (repository: CheckoutRepository, branch: string, cwd: string) => string;
1701
+ //#endregion
1568
1702
  //#region src/github-app-client.d.ts
1569
1703
  interface FactoryAppRequest {
1570
1704
  body?: unknown;
@@ -1600,23 +1734,6 @@ interface UpsertFactoryPrStatusCommentResult {
1600
1734
  }
1601
1735
  declare function upsertFactoryPrStatusComment(input: UpsertFactoryPrStatusCommentInput, dependencies?: UpsertFactoryPrStatusCommentDependencies): Promise<UpsertFactoryPrStatusCommentResult>;
1602
1736
  //#endregion
1603
- //#region src/catch-up-recognition-record.d.ts
1604
- interface CatchUpRecognition {
1605
- /** The ref the candidate targets, as the recognizing command resolved it. */
1606
- baseRef: string;
1607
- /** The live target tip at recognition time; the head's first parent. */
1608
- baseTipSha: string;
1609
- /** The head's second parent: the admitted base-side content merged in. */
1610
- mergedParentSha: string;
1611
- /**
1612
- * The tree `git merge-tree --write-tree` produced for the two parents. It
1613
- * equals the head's own tree; that equality is the faithfulness proof.
1614
- */
1615
- mergedTreeSha: string;
1616
- /** The ref that proves the second parent is admitted content. */
1617
- upstreamRef: string;
1618
- }
1619
- //#endregion
1620
1737
  //#region src/pr-verify-proof-contract.d.ts
1621
1738
  declare const SUPPORTED_PR_VERIFY_SCHEMA_VERSIONS: readonly [1, 2, 3, 4];
1622
1739
  type PrVerifySchemaVersion = (typeof SUPPORTED_PR_VERIFY_SCHEMA_VERSIONS)[number];
@@ -1699,6 +1816,16 @@ interface PrVerifyProof {
1699
1816
  notRequiredCommands?: PrVerifyNotRequiredCommand[];
1700
1817
  outcome?: "aborted" | "passed";
1701
1818
  patchId?: string;
1819
+ /**
1820
+ * The review policy identity this verification run resolved (#922 Slice B).
1821
+ *
1822
+ * Verification demands no review mode of its own. It records the identity so
1823
+ * `pr:ready` can see whether the stage that produced this proof judged the
1824
+ * candidate under the same policy readiness resolves. Optional, and normally
1825
+ * `unresolved` on the first run of a branch: a candidate is verified before
1826
+ * it has a pull request, and there is no authority to read without one.
1827
+ */
1828
+ policyResolution?: PolicyResolution;
1702
1829
  profilePath: string;
1703
1830
  projectKey: string;
1704
1831
  repository: string;
@@ -1978,6 +2105,8 @@ interface FailedPreviewSnapshot {
1978
2105
  readonly name: string;
1979
2106
  }
1980
2107
  interface FactoryPrStatusSources {
2108
+ /** Live PR base ref name observed with the sources. Identity, not a SHA. */
2109
+ readonly baseRefName?: string;
1981
2110
  readonly baseSha: string;
1982
2111
  readonly checks: Readonly<Partial<Record<FactoryPrStatusCheckName, CompletedFactoryCheckSnapshot>>>;
1983
2112
  readonly previewFailures?: Readonly<Partial<Record<string, FailedPreviewSnapshot>>>;
@@ -2013,9 +2142,14 @@ interface PresentFactoryPrStatusHudDependencies {
2013
2142
  previewTargets?: readonly string[];
2014
2143
  repo: string;
2015
2144
  }) => Promise<FactoryPrStatusSources>;
2016
- /** Recheck both PR endpoints immediately before mutating the sticky HUD. */
2145
+ /**
2146
+ * Recheck the pulls identity immediately before mutating the sticky HUD.
2147
+ * Happy path reads `/pulls/:n` only; git-ref is fetched to decorate a
2148
+ * head-moved error, not as a second identity endpoint.
2149
+ */
2017
2150
  readonly assertCurrentIdentity: (input: {
2018
- baseSha: string;
2151
+ baseRefName?: string; /** Retained for rendering/callers; identity compares base ref name. */
2152
+ baseSha?: string;
2019
2153
  headSha: string;
2020
2154
  owner: string;
2021
2155
  pr: number;
@@ -2026,10 +2160,11 @@ interface PresentFactoryPrStatusHudDependencies {
2026
2160
  interface ReadFactoryPrStatusSourcesInput {
2027
2161
  readonly headSha: string;
2028
2162
  /**
2029
- * Read token for `previewProofInventory.list`. The list walks the
2030
- * force-push timeline, which needs commit (contents) read; the Factory App
2031
- * token has no contents permission, so pass a workflow `GITHUB_TOKEN`
2032
- * (#825). Falls back to `token`.
2163
+ * Contents-read token for `previewProofInventory.list` and the live
2164
+ * `git/ref/heads/<base>` tip. Both need `contents: read`; the Factory App
2165
+ * token has none, so pass a workflow `GITHUB_TOKEN` (#825, #908). The
2166
+ * inventory list falls back to `token`. The base tip has no HTTP fallback:
2167
+ * without this token it is read through `gh`.
2033
2168
  */
2034
2169
  readonly inventoryToken?: string;
2035
2170
  readonly owner: string;
@@ -2045,6 +2180,11 @@ interface ReadFactoryPrStatusSourcesInput {
2045
2180
  }
2046
2181
  interface ReadFactoryPrStatusSourcesDependencies {
2047
2182
  readonly fetch?: typeof fetch;
2183
+ /**
2184
+ * Local base-tip reader used when no `inventoryToken` exists. Defaults to
2185
+ * the `gh`-backed reader `pr:ready` already uses.
2186
+ */
2187
+ readonly fetchBranchTipSha?: typeof fetchGitHubBranchTipSha;
2048
2188
  readonly listPreviewRegistrations?: (input: {
2049
2189
  owner: string;
2050
2190
  pr: number;
@@ -2056,7 +2196,8 @@ interface ReadFactoryPrStatusSourcesDependencies {
2056
2196
  declare function renderFactoryPrStatusHud(input: RenderFactoryPrStatusHudInput): string;
2057
2197
  declare function presentFactoryPrStatusHud(input: PresentFactoryPrStatusHudInput, dependencies: PresentFactoryPrStatusHudDependencies): Promise<UpsertFactoryPrStatusCommentResult>;
2058
2198
  declare function assertFactoryPrStatusIdentity(input: ReadFactoryPrStatusSourcesInput & {
2059
- readonly baseSha: string;
2199
+ readonly baseRefName?: string; /** Retained for rendering/callers; identity compares base ref name. */
2200
+ readonly baseSha?: string;
2060
2201
  }, dependencies?: ReadFactoryPrStatusSourcesDependencies): Promise<void>;
2061
2202
  declare function readFactoryPrStatusSources(input: ReadFactoryPrStatusSourcesInput, dependencies?: ReadFactoryPrStatusSourcesDependencies): Promise<FactoryPrStatusSources>;
2062
2203
  interface PlanFactoryPrStatusHudInput {
@@ -2076,6 +2217,11 @@ declare function planFactoryPrStatusHud(input: PlanFactoryPrStatusHudInput): Pre
2076
2217
  interface RefreshFactoryPrStatusHudInput {
2077
2218
  readonly cwd: string;
2078
2219
  readonly headSha: string;
2220
+ /**
2221
+ * Workflow `GITHUB_TOKEN` with `contents: read` for the live git-ref and
2222
+ * preview inventory. The Factory App token cannot read those (#825, #908).
2223
+ */
2224
+ readonly inventoryToken?: string;
2079
2225
  readonly mergeBaseSha?: string;
2080
2226
  readonly owner: string;
2081
2227
  readonly patchId?: string;
@@ -2126,6 +2272,14 @@ interface GitHubPullRequest {
2126
2272
  body: string;
2127
2273
  headRefName?: string;
2128
2274
  headRefOid: string;
2275
+ /**
2276
+ * Whether the head branch lives in a different repository from the base
2277
+ * (#922). Required, not optional, for the reason `autoMergeRequest` is: the
2278
+ * trusted checkout names ONE repository, and for a fork PR that is not the
2279
+ * base repository. An implementation that omitted the field would silently
2280
+ * resolve base policy from whichever repository the checkout points at.
2281
+ */
2282
+ isCrossRepository: boolean;
2129
2283
  isDraft: boolean;
2130
2284
  mergeStateStatus: string;
2131
2285
  mergeable: string;
@@ -2185,6 +2339,13 @@ interface PrReadyProof {
2185
2339
  * waived demand reads to a human. Absent when there are none.
2186
2340
  */
2187
2341
  notices?: string[];
2342
+ /**
2343
+ * The policy identity readiness resolved review demand under (#922): the
2344
+ * base ref, its live tip, and the digests of the base, candidate, and merged
2345
+ * review policies. Optional on the wire and additive — this is a new record
2346
+ * on an unchanged contract, so no schema version moves.
2347
+ */
2348
+ policyResolution?: PolicyResolution;
2188
2349
  /** Committed profile blob evaluated by readiness. Required for merge. */
2189
2350
  profileBlobSha?: string;
2190
2351
  /** Checkout-relative committed profile path evaluated by readiness. */
@@ -2208,6 +2369,13 @@ interface PrReadyDependencies {
2208
2369
  * call plus the read-back that says what actually happened.
2209
2370
  */
2210
2371
  armAutoMerge?: (input: ArmAutoMergeInput) => ArmAutoMergeOutcome;
2372
+ /**
2373
+ * Reads the authoritative base review policy (#922): the profile committed at
2374
+ * the live tip of the PR's own base ref. Defaults to the real GitHub reads,
2375
+ * so an unstated authority refuses rather than falling back to candidate
2376
+ * policy — unreadable authority is never absent authority.
2377
+ */
2378
+ basePolicy?: BaseReviewPolicyAuthority;
2211
2379
  github?: {
2212
2380
  fetchClosingPullRequests?: (input: {
2213
2381
  issue: number;
@@ -2262,6 +2430,12 @@ interface PrReadyGitDependencies {
2262
2430
  canResolveCommit: (cwd: string, sha: string) => boolean;
2263
2431
  changedFiles: (cwd: string, base: string, headSha?: string) => string[];
2264
2432
  checkoutRepository: (cwd: string) => CheckoutRepository;
2433
+ /**
2434
+ * Bring `refs/heads/<baseRefName>` into the checkout so the live tip
2435
+ * `pr.baseRefOid` can resolve. Optional so fixtures that already resolve
2436
+ * every SHA can omit it.
2437
+ */
2438
+ fetchOriginRef?: (cwd: string, refName: string) => void;
2265
2439
  currentHeadSha: (cwd: string) => string;
2266
2440
  mergeBaseSha: (cwd: string, base: string) => string;
2267
2441
  objectIdAtRef: (cwd: string, ref: string, absolutePath: string) => string | undefined;
@@ -2273,39 +2447,6 @@ declare function validatePrReadyProof(value: unknown): PrReadyProof;
2273
2447
  declare function readPrReadyProof(filePath: string): PrReadyProof;
2274
2448
  declare function runPrReady(args: PrReadyArgs, dependencies?: PrReadyDependencies): Promise<PrReadyProof>;
2275
2449
  //#endregion
2276
- //#region src/required-check-policy.d.ts
2277
- declare const EVIDENCE_CHECK_TYPES: readonly ["review", "verify"];
2278
- type EvidenceCheckType = (typeof EVIDENCE_CHECK_TYPES)[number];
2279
- declare const requiredCheckScopeSchema: z.ZodObject<{
2280
- classifications: z.ZodArray<z.ZodEnum<{
2281
- "docs/process-only": "docs/process-only";
2282
- trivial: "trivial";
2283
- "non-trivial": "non-trivial";
2284
- }>>;
2285
- }, z.core.$strict>;
2286
- type RequiredCheckScope = z.infer<typeof requiredCheckScopeSchema>;
2287
- interface RequiredCheckScopeContext {
2288
- catchUpRecognition?: CatchUpRecognition;
2289
- classification: DiffClassification | undefined;
2290
- impactStamp?: ImpactStamp;
2291
- }
2292
- interface ScopeDecision {
2293
- inScope: boolean;
2294
- reason: string;
2295
- }
2296
- declare const requiredCheckInScope: ({
2297
- context,
2298
- scope
2299
- }: {
2300
- context: RequiredCheckScopeContext;
2301
- scope?: RequiredCheckScope;
2302
- }) => ScopeDecision;
2303
- interface RequiredCheck {
2304
- name: string;
2305
- checkType: EvidenceCheckType;
2306
- scope?: RequiredCheckScope;
2307
- }
2308
- //#endregion
2309
2450
  //#region src/factory-session.d.ts
2310
2451
  declare const resolveAuthoringSessionIds: ({
2311
2452
  override,
@@ -2337,8 +2478,8 @@ declare const evidenceEnvelopeBaseSchema: z.ZodObject<{
2337
2478
  producer: z.ZodString;
2338
2479
  requestId: z.ZodOptional<z.ZodString>;
2339
2480
  rung: z.ZodOptional<z.ZodEnum<{
2340
- oracle: "oracle";
2341
2481
  "independent-model": "independent-model";
2482
+ oracle: "oracle";
2342
2483
  human: "human";
2343
2484
  }>>;
2344
2485
  schemaVersion: z.ZodLiteral<1>;
@@ -2364,8 +2505,8 @@ declare const evidenceEnvelopeSchema: z.ZodObject<{
2364
2505
  producer: z.ZodString;
2365
2506
  requestId: z.ZodOptional<z.ZodString>;
2366
2507
  rung: z.ZodOptional<z.ZodEnum<{
2367
- oracle: "oracle";
2368
2508
  "independent-model": "independent-model";
2509
+ oracle: "oracle";
2369
2510
  human: "human";
2370
2511
  }>>;
2371
2512
  schemaVersion: z.ZodLiteral<1>;
@@ -2467,8 +2608,8 @@ declare const loadEvidenceEnvelopes: (cwd: string) => LoadedEvidenceEnvelope[];
2467
2608
  //#region src/review-proof-applicability.d.ts
2468
2609
  declare const REVIEW_STATUS_VALUES: readonly ["not-required", "current", "stale", "missing", "blocked"];
2469
2610
  declare const reviewStatusSchema: z.ZodEnum<{
2470
- "not-required": "not-required";
2471
2611
  stale: "stale";
2612
+ "not-required": "not-required";
2472
2613
  blocked: "blocked";
2473
2614
  current: "current";
2474
2615
  missing: "missing";
@@ -2585,8 +2726,8 @@ declare const boundaryCheckProofSchema: z.ZodObject<{
2585
2726
  wave: z.ZodString;
2586
2727
  }, z.core.$strip>>;
2587
2728
  demandedRung: z.ZodOptional<z.ZodEnum<{
2588
- oracle: "oracle";
2589
2729
  "independent-model": "independent-model";
2730
+ oracle: "oracle";
2590
2731
  human: "human";
2591
2732
  }>>;
2592
2733
  epicIssue: z.ZodNumber;
@@ -2601,8 +2742,8 @@ declare const boundaryCheckProofSchema: z.ZodObject<{
2601
2742
  commentUrl: z.ZodOptional<z.ZodString>;
2602
2743
  producer: z.ZodString;
2603
2744
  rung: z.ZodEnum<{
2604
- oracle: "oracle";
2605
2745
  "independent-model": "independent-model";
2746
+ oracle: "oracle";
2606
2747
  human: "human";
2607
2748
  }>;
2608
2749
  sessionId: z.ZodOptional<z.ZodString>;
@@ -2630,6 +2771,22 @@ interface BoundaryCheckGithub {
2630
2771
  fetchIssueComments: (repo: string, issue: number) => GithubIssueComment[];
2631
2772
  fetchClosingPullRequests: (repo: string, issue: number) => BoundaryPullRequestRef[];
2632
2773
  fetchPullRequest?: (repo: string, pr: number) => BoundaryPullRequestRef;
2774
+ /**
2775
+ * Child issue state for the close-gate (#901). Required so a stub cannot
2776
+ * skip the gate and look like a pass.
2777
+ */
2778
+ fetchIssueState: (repo: string, issue: number) => "OPEN" | "CLOSED";
2779
+ /**
2780
+ * PRs whose bodies may contribute closing-keyword membership (#901). For
2781
+ * `each-to-epic`, production lists PRs targeting the integration branch.
2782
+ * Branch targeting never joins; only a keyword naming a declared child does.
2783
+ * Required so omitting the channel cannot silently drop it.
2784
+ */
2785
+ listCandidatePullRequests: (repo: string, input: {
2786
+ integrationBranch?: string;
2787
+ }) => (BoundaryPullRequestRef & {
2788
+ body?: string;
2789
+ })[];
2633
2790
  }
2634
2791
  interface BoundaryCheckArgs {
2635
2792
  cwd?: string;
@@ -2649,6 +2806,7 @@ interface BoundaryCheckArgs {
2649
2806
  interface BoundaryCheckDependencies {
2650
2807
  github?: BoundaryCheckGithub;
2651
2808
  hq?: HqIngestDependencies;
2809
+ readWaivers?: (cwd: string) => DemandWaiver[];
2652
2810
  resolveRepo?: (cwd: string) => string;
2653
2811
  }
2654
2812
  declare function runBoundaryCheck(args: BoundaryCheckArgs, dependencies?: BoundaryCheckDependencies): BoundaryCheckProofRecord;
@@ -2740,10 +2898,12 @@ type CatchUpRecognizer = (input: {
2740
2898
  //#endregion
2741
2899
  //#region src/pr-review.d.ts
2742
2900
  interface PrReviewArgs extends LoadProjectProfileInput {
2901
+ assemble?: boolean;
2743
2902
  base: string;
2744
2903
  cycle: number;
2745
2904
  dispositions?: string;
2746
2905
  findings?: string;
2906
+ historical?: boolean;
2747
2907
  issue?: number;
2748
2908
  mode: PrReviewMode;
2749
2909
  output?: string;
@@ -2751,15 +2911,37 @@ interface PrReviewArgs extends LoadProjectProfileInput {
2751
2911
  }
2752
2912
  interface PrReviewGitDependencies {
2753
2913
  changedFiles: (cwd: string, base: string) => string[];
2914
+ checkoutRepository?: (cwd: string) => CheckoutRepository;
2754
2915
  currentHeadSha: (cwd: string) => string;
2916
+ firstParentCommits?: (cwd: string, base: string) => string[];
2755
2917
  isAncestor: (cwd: string, ancestor: string, descendant: string) => boolean;
2756
2918
  recognizeCatchUp?: CatchUpRecognizer;
2919
+ repositoryRoot?: (cwd: string) => string;
2920
+ showFileAtRef?: (cwd: string, ref: string, absolutePath: string) => string | undefined;
2757
2921
  stablePatchId: (cwd: string, base: string) => string;
2922
+ stablePatchIdAtRef?: (cwd: string, base: string, ref: string) => string;
2758
2923
  statusPorcelain: (cwd: string) => string;
2759
2924
  }
2925
+ interface PrReviewIssueBodyInput {
2926
+ issue: number;
2927
+ owner: string;
2928
+ repo: string;
2929
+ }
2760
2930
  interface PrReviewDependencies {
2931
+ /**
2932
+ * The authoritative base-policy reader (#922). Injectable for the same
2933
+ * reason `pr:ready` injects it: an unstated authority must be a refusal a
2934
+ * test can state, never a silent pass.
2935
+ */
2936
+ basePolicy?: BaseReviewPolicyAuthority;
2937
+ fetchIssueBody?: (input: PrReviewIssueBodyInput) => string;
2761
2938
  git?: PrReviewGitDependencies;
2762
2939
  hq?: HqIngestDependencies;
2940
+ /**
2941
+ * How this run finds the pull request whose base ref is the policy authority
2942
+ * (#922 Slice B). Defaults to the GitHub lookup.
2943
+ */
2944
+ lookupPullRequest?: (cwd: string) => CandidatePullRequestLookup;
2763
2945
  }
2764
2946
  declare function runPrReview(args: PrReviewArgs, dependencies?: PrReviewDependencies): Promise<PrReviewProof>;
2765
2947
  //#endregion
@@ -2790,6 +2972,7 @@ interface PrVerifyArgs extends LoadProjectProfileInput {
2790
2972
  }
2791
2973
  interface PrVerifyGitDependencies {
2792
2974
  changedFiles: (cwd: string, base: string) => string[];
2975
+ checkoutRepository?: (cwd: string) => CheckoutRepository;
2793
2976
  currentHeadSha: (cwd: string) => string;
2794
2977
  emptyTreeHash: (cwd: string) => string;
2795
2978
  mergeBaseSha: (cwd: string, base: string) => string;
@@ -2800,7 +2983,19 @@ interface PrVerifyGitDependencies {
2800
2983
  stablePatchId: (cwd: string, base: string) => string;
2801
2984
  }
2802
2985
  interface PrVerifyDependencies {
2986
+ /**
2987
+ * The authoritative base-policy reader (#922). Injectable for the same
2988
+ * reason `pr:ready` injects it: an unstated authority must be a refusal a
2989
+ * test can state, never a silent pass.
2990
+ */
2991
+ basePolicy?: BaseReviewPolicyAuthority;
2803
2992
  cleanInstall?: CleanInstallResolutionDependencies | false;
2993
+ /**
2994
+ * How this run finds the pull request whose base ref is the policy authority
2995
+ * (#922 Slice B). Defaults to the GitHub lookup; a checkout with no pull
2996
+ * request resolves `unavailable`, which is normal before publication.
2997
+ */
2998
+ lookupPullRequest?: (cwd: string) => CandidatePullRequestLookup;
2804
2999
  env?: NodeJS.ProcessEnv;
2805
3000
  git?: PrVerifyGitDependencies;
2806
3001
  hq?: HqIngestDependencies;
@@ -2987,9 +3182,9 @@ interface PrStatusHudArgs {
2987
3182
  readonly cwd: string;
2988
3183
  readonly headSha: string;
2989
3184
  /**
2990
- * Read token for the preview-proof inventory list. The App token cannot
2991
- * read the force-push timeline (no contents permission), so the workflow
2992
- * `GITHUB_TOKEN` serves that read (#825).
3185
+ * Contents-read token for the preview-proof inventory list and the live
3186
+ * git-ref tip. The App token has no contents permission, so the workflow
3187
+ * `GITHUB_TOKEN` serves those reads (#825, #908).
2993
3188
  */
2994
3189
  readonly inventoryToken?: string;
2995
3190
  readonly owner: string;
@@ -3658,8 +3853,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3658
3853
  model: z.ZodString;
3659
3854
  tier: z.ZodEnum<{
3660
3855
  review: "review";
3661
- delegate: "delegate";
3662
3856
  oracle: "oracle";
3857
+ delegate: "delegate";
3663
3858
  workhorse: "workhorse";
3664
3859
  scout: "scout";
3665
3860
  }>;
@@ -3667,8 +3862,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3667
3862
  startedAt: z.ZodString;
3668
3863
  tier: z.ZodEnum<{
3669
3864
  review: "review";
3670
- delegate: "delegate";
3671
3865
  oracle: "oracle";
3866
+ delegate: "delegate";
3672
3867
  workhorse: "workhorse";
3673
3868
  scout: "scout";
3674
3869
  }>;
@@ -3737,8 +3932,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3737
3932
  model: z.ZodString;
3738
3933
  tier: z.ZodEnum<{
3739
3934
  review: "review";
3740
- delegate: "delegate";
3741
3935
  oracle: "oracle";
3936
+ delegate: "delegate";
3742
3937
  workhorse: "workhorse";
3743
3938
  scout: "scout";
3744
3939
  }>;
@@ -3746,8 +3941,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3746
3941
  startedAt: z.ZodString;
3747
3942
  tier: z.ZodEnum<{
3748
3943
  review: "review";
3749
- delegate: "delegate";
3750
3944
  oracle: "oracle";
3945
+ delegate: "delegate";
3751
3946
  workhorse: "workhorse";
3752
3947
  scout: "scout";
3753
3948
  }>;
@@ -3807,8 +4002,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3807
4002
  model: z.ZodString;
3808
4003
  tier: z.ZodEnum<{
3809
4004
  review: "review";
3810
- delegate: "delegate";
3811
4005
  oracle: "oracle";
4006
+ delegate: "delegate";
3812
4007
  workhorse: "workhorse";
3813
4008
  scout: "scout";
3814
4009
  }>;
@@ -3816,8 +4011,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3816
4011
  startedAt: z.ZodString;
3817
4012
  tier: z.ZodEnum<{
3818
4013
  review: "review";
3819
- delegate: "delegate";
3820
4014
  oracle: "oracle";
4015
+ delegate: "delegate";
3821
4016
  workhorse: "workhorse";
3822
4017
  scout: "scout";
3823
4018
  }>;
@@ -3866,11 +4061,11 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3866
4061
  engine: string;
3867
4062
  layerSource: "committedDefault" | "operatorSession" | "userConfig";
3868
4063
  model: string;
3869
- tier: "review" | "delegate" | "oracle" | "workhorse" | "scout";
4064
+ tier: "review" | "oracle" | "delegate" | "workhorse" | "scout";
3870
4065
  fallbackTier?: "delegate" | undefined;
3871
4066
  };
3872
4067
  startedAt: string;
3873
- tier: "review" | "delegate" | "oracle" | "workhorse" | "scout";
4068
+ tier: "review" | "oracle" | "delegate" | "workhorse" | "scout";
3874
4069
  tokenUsage: {
3875
4070
  source: "cursor-csv" | "codex-json" | "cursor-json" | "claude-json";
3876
4071
  status: "available";
@@ -4162,6 +4357,13 @@ interface EvaluationInput {
4162
4357
  mergeStateStatus: string;
4163
4358
  ladderPolicy?: ReviewLadderPolicy;
4164
4359
  reviewModes?: PrReviewKind[];
4360
+ /**
4361
+ * Cross-stage policy-identity refusals resolved at the command boundary
4362
+ * (#922 Slice B), already worded. Evaluation only decides whether they are
4363
+ * in force: a recognized catch-up withdraws every review demand, so it
4364
+ * withdraws these with them.
4365
+ */
4366
+ policyIdentityRefusals?: string[];
4165
4367
  reviewProof?: PrReviewProof;
4166
4368
  verificationProof?: VerificationProofState;
4167
4369
  docsOnlyVerifyBaselineHeadShas?: string[];
@@ -4207,13 +4409,13 @@ declare const evaluateReadiness: (input: EvaluationInput) => {
4207
4409
  reviews: {
4208
4410
  correctness: {
4209
4411
  required: boolean;
4210
- status: "not-required" | "stale" | "blocked" | "current" | "missing";
4412
+ status: "stale" | "not-required" | "blocked" | "current" | "missing";
4211
4413
  reviewedHeadSha?: string | undefined;
4212
4414
  reviewedPatchId?: string | undefined;
4213
4415
  };
4214
4416
  security?: {
4215
4417
  required: boolean;
4216
- status: "not-required" | "stale" | "blocked" | "current" | "missing";
4418
+ status: "stale" | "not-required" | "blocked" | "current" | "missing";
4217
4419
  reviewedHeadSha?: string | undefined;
4218
4420
  reviewedPatchId?: string | undefined;
4219
4421
  } | undefined;
@@ -4533,6 +4735,7 @@ declare const reviewFocusFromIssueBody: (body: string) => string | undefined;
4533
4735
  interface AssembleReviewPromptInput {
4534
4736
  base: string;
4535
4737
  changedFiles: string[];
4738
+ cwd?: string;
4536
4739
  headSha: string;
4537
4740
  issueFocus?: IssueReviewFocus;
4538
4741
  kind: PrReviewKind;
@@ -4540,6 +4743,13 @@ interface AssembleReviewPromptInput {
4540
4743
  priorLedgerEntries?: FindingLedgerEntry[];
4541
4744
  profile: FactoryProjectProfile;
4542
4745
  }
4746
+ interface AssembleReviewPromptGitDependencies {
4747
+ repositoryRoot: (cwd: string) => string;
4748
+ showFileAtRef: (cwd: string, ref: string, absolutePath: string) => string | undefined;
4749
+ }
4750
+ interface AssembleReviewPromptDependencies {
4751
+ git?: AssembleReviewPromptGitDependencies;
4752
+ }
4543
4753
  interface AssembledReviewPrompt {
4544
4754
  prompt: string;
4545
4755
  sections: ReviewPromptSection[];
@@ -4547,13 +4757,14 @@ interface AssembledReviewPrompt {
4547
4757
  declare const assembleReviewPrompt: ({
4548
4758
  base,
4549
4759
  changedFiles,
4760
+ cwd,
4550
4761
  headSha,
4551
4762
  issueFocus,
4552
4763
  kind,
4553
4764
  patchId,
4554
4765
  priorLedgerEntries,
4555
4766
  profile
4556
- }: AssembleReviewPromptInput) => AssembledReviewPrompt;
4767
+ }: AssembleReviewPromptInput, dependencies?: AssembleReviewPromptDependencies) => AssembledReviewPrompt;
4557
4768
  //#endregion
4558
4769
  //#region src/review-ladder-trace.d.ts
4559
4770
  interface ReviewLadderTraceIdentity {