@patronage/software-factory 1.0.0-alpha.27 → 1.0.0-alpha.28

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
- "independent-model": "independent-model";
21
20
  oracle: "oracle";
21
+ "independent-model": "independent-model";
22
22
  human: "human";
23
23
  }>;
24
24
  }, z.core.$loose>>;
@@ -26,8 +26,8 @@ declare const boundaryManifestBaseSchema: z.ZodObject<{
26
26
  integrationBranch: z.ZodOptional<z.ZodString>;
27
27
  schemaVersion: z.ZodLiteral<1>;
28
28
  topology: z.ZodEnum<{
29
- "each-to-main": "each-to-main";
30
29
  flagged: "flagged";
30
+ "each-to-main": "each-to-main";
31
31
  stacked: "stacked";
32
32
  "each-to-epic": "each-to-epic";
33
33
  }>;
@@ -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
- "independent-model": "independent-model";
40
39
  oracle: "oracle";
40
+ "independent-model": "independent-model";
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
- "independent-model": "independent-model";
50
49
  oracle: "oracle";
50
+ "independent-model": "independent-model";
51
51
  human: "human";
52
52
  }>;
53
53
  }, z.core.$loose>>;
@@ -55,8 +55,8 @@ declare const boundaryManifestSchema: z.ZodObject<{
55
55
  integrationBranch: z.ZodOptional<z.ZodString>;
56
56
  schemaVersion: z.ZodLiteral<1>;
57
57
  topology: z.ZodEnum<{
58
- "each-to-main": "each-to-main";
59
58
  flagged: "flagged";
59
+ "each-to-main": "each-to-main";
60
60
  stacked: "stacked";
61
61
  "each-to-epic": "each-to-epic";
62
62
  }>;
@@ -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
- "independent-model": "independent-model";
69
68
  oracle: "oracle";
69
+ "independent-model": "independent-model";
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
- "independent-model": "independent-model";
155
154
  oracle: "oracle";
155
+ "independent-model": "independent-model";
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
- "independent-model": "independent-model";
199
198
  oracle: "oracle";
199
+ "independent-model": "independent-model";
200
200
  human: "human";
201
201
  }>;
202
202
  schemaVersion: z.ZodLiteral<1>;
@@ -1523,9 +1523,9 @@ declare const managedReadinessLedgerSchema: z.ZodObject<{
1523
1523
  mergeable: z.ZodString;
1524
1524
  requiredChecks: z.ZodEnum<{
1525
1525
  unknown: "unknown";
1526
+ pending: "pending";
1526
1527
  passed: "passed";
1527
1528
  failed: "failed";
1528
- pending: "pending";
1529
1529
  none: "none";
1530
1530
  }>;
1531
1531
  reviewDecision: z.ZodOptional<z.ZodNullable<z.ZodString>>;
@@ -1591,8 +1591,8 @@ declare const managedReadinessLedgerSchema: z.ZodObject<{
1591
1591
  "run-interior-cycle": "run-interior-cycle";
1592
1592
  }>;
1593
1593
  stage: z.ZodEnum<{
1594
- gate: "gate";
1595
1594
  interior: "interior";
1595
+ gate: "gate";
1596
1596
  "interior-complete": "interior-complete";
1597
1597
  }>;
1598
1598
  }, z.core.$strip>>;
@@ -1608,8 +1608,8 @@ declare const managedReadinessLedgerSchema: z.ZodObject<{
1608
1608
  reviewedHeadSha: z.ZodOptional<z.ZodString>;
1609
1609
  reviewedPatchId: z.ZodOptional<z.ZodString>;
1610
1610
  status: z.ZodEnum<{
1611
- blocked: "blocked";
1612
1611
  "not-required": "not-required";
1612
+ blocked: "blocked";
1613
1613
  current: "current";
1614
1614
  stale: "stale";
1615
1615
  missing: "missing";
@@ -1620,8 +1620,8 @@ declare const managedReadinessLedgerSchema: z.ZodObject<{
1620
1620
  reviewedHeadSha: z.ZodOptional<z.ZodString>;
1621
1621
  reviewedPatchId: z.ZodOptional<z.ZodString>;
1622
1622
  status: z.ZodEnum<{
1623
- blocked: "blocked";
1624
1623
  "not-required": "not-required";
1624
+ blocked: "blocked";
1625
1625
  current: "current";
1626
1626
  stale: "stale";
1627
1627
  missing: "missing";
@@ -2508,8 +2508,8 @@ declare const evidenceEnvelopeBaseSchema: z.ZodObject<{
2508
2508
  producer: z.ZodString;
2509
2509
  requestId: z.ZodOptional<z.ZodString>;
2510
2510
  rung: z.ZodOptional<z.ZodEnum<{
2511
- "independent-model": "independent-model";
2512
2511
  oracle: "oracle";
2512
+ "independent-model": "independent-model";
2513
2513
  human: "human";
2514
2514
  }>>;
2515
2515
  schemaVersion: z.ZodLiteral<1>;
@@ -2535,8 +2535,8 @@ declare const evidenceEnvelopeSchema: z.ZodObject<{
2535
2535
  producer: z.ZodString;
2536
2536
  requestId: z.ZodOptional<z.ZodString>;
2537
2537
  rung: z.ZodOptional<z.ZodEnum<{
2538
- "independent-model": "independent-model";
2539
2538
  oracle: "oracle";
2539
+ "independent-model": "independent-model";
2540
2540
  human: "human";
2541
2541
  }>>;
2542
2542
  schemaVersion: z.ZodLiteral<1>;
@@ -2638,8 +2638,8 @@ declare const loadEvidenceEnvelopes: (cwd: string) => LoadedEvidenceEnvelope[];
2638
2638
  //#region src/review-proof-applicability.d.ts
2639
2639
  declare const REVIEW_STATUS_VALUES: readonly ["not-required", "current", "stale", "missing", "blocked"];
2640
2640
  declare const reviewStatusSchema: z.ZodEnum<{
2641
- blocked: "blocked";
2642
2641
  "not-required": "not-required";
2642
+ blocked: "blocked";
2643
2643
  current: "current";
2644
2644
  stale: "stale";
2645
2645
  missing: "missing";
@@ -2756,8 +2756,8 @@ declare const boundaryCheckProofSchema: z.ZodObject<{
2756
2756
  wave: z.ZodString;
2757
2757
  }, z.core.$strip>>;
2758
2758
  demandedRung: z.ZodOptional<z.ZodEnum<{
2759
- "independent-model": "independent-model";
2760
2759
  oracle: "oracle";
2760
+ "independent-model": "independent-model";
2761
2761
  human: "human";
2762
2762
  }>>;
2763
2763
  epicIssue: z.ZodNumber;
@@ -2772,8 +2772,8 @@ declare const boundaryCheckProofSchema: z.ZodObject<{
2772
2772
  commentUrl: z.ZodOptional<z.ZodString>;
2773
2773
  producer: z.ZodString;
2774
2774
  rung: z.ZodEnum<{
2775
- "independent-model": "independent-model";
2776
2775
  oracle: "oracle";
2776
+ "independent-model": "independent-model";
2777
2777
  human: "human";
2778
2778
  }>;
2779
2779
  sessionId: z.ZodOptional<z.ZodString>;
@@ -2789,8 +2789,8 @@ declare const boundaryCheckProofSchema: z.ZodObject<{
2789
2789
  value: z.ZodString;
2790
2790
  }, z.core.$strip>>;
2791
2791
  status: z.ZodEnum<{
2792
- blocked: "blocked";
2793
2792
  ready: "ready";
2793
+ blocked: "blocked";
2794
2794
  }>;
2795
2795
  }, z.core.$strip>;
2796
2796
  type BoundaryCheckProofRecord = z.infer<typeof boundaryCheckProofSchema>;
@@ -2931,6 +2931,13 @@ interface PrReviewArgs extends LoadProjectProfileInput {
2931
2931
  assemble?: boolean;
2932
2932
  base: string;
2933
2933
  cycle: number;
2934
+ /**
2935
+ * Issue carrying the factory-boundary manifest, which may be the work issue
2936
+ * itself. `--assemble` uses it to name the review rung the candidate's wave
2937
+ * demands, so the prompt asks for the findings schema the gate accepts
2938
+ * (#1001). It is the same handle `pr:publish` and `pr:ready` take.
2939
+ */
2940
+ epic?: number;
2934
2941
  dispositions?: string;
2935
2942
  findings?: string;
2936
2943
  historical?: boolean;
@@ -2964,7 +2971,22 @@ interface PrReviewDependencies {
2964
2971
  * test can state, never a silent pass.
2965
2972
  */
2966
2973
  basePolicy?: BaseReviewPolicyAuthority;
2974
+ /**
2975
+ * How the wave resolver reads an issue's closing pull requests (#1001).
2976
+ * Injected for the same reason `fetchIssueBody` is: the wave demand must be
2977
+ * statable in a test without a live repository.
2978
+ */
2979
+ fetchClosingPullRequests?: (input: PrReviewIssueBodyInput) => {
2980
+ number: number;
2981
+ state?: "OPEN" | "CLOSED" | "MERGED";
2982
+ }[];
2967
2983
  fetchIssueBody?: (input: PrReviewIssueBodyInput) => string;
2984
+ /**
2985
+ * How `--assemble` reads the pull request whose wave demand names the review
2986
+ * rung (#1001). Defaults to the GitHub lookup, and its result is validated
2987
+ * before use, so an injected stub is held to the same shape.
2988
+ */
2989
+ fetchWavePullRequest?: (cwd: string) => unknown;
2968
2990
  git?: PrReviewGitDependencies;
2969
2991
  hq?: HqIngestDependencies;
2970
2992
  /**
@@ -3302,11 +3324,11 @@ declare const LegacyWorkerCloseoutStatusTraceEventSchema: z.ZodObject<{
3302
3324
  threadId: z.ZodOptional<z.ZodString>;
3303
3325
  workerId: z.ZodOptional<z.ZodString>;
3304
3326
  archiveStatus: z.ZodOptional<z.ZodEnum<{
3305
- pending: "pending";
3306
3327
  unavailable: "unavailable";
3307
3328
  archived: "archived";
3308
3329
  skipped: "skipped";
3309
3330
  "not-applicable": "not-applicable";
3331
+ pending: "pending";
3310
3332
  }>>;
3311
3333
  closeoutReason: z.ZodOptional<z.ZodString>;
3312
3334
  eventType: z.ZodLiteral<"worker-closeout-lessons">;
@@ -3479,8 +3501,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3479
3501
  sessionId: z.ZodOptional<z.ZodString>;
3480
3502
  }, z.core.$strict>>;
3481
3503
  stage: z.ZodEnum<{
3482
- gate: "gate";
3483
3504
  interior: "interior";
3505
+ gate: "gate";
3484
3506
  }>;
3485
3507
  usage: z.ZodOptional<z.ZodObject<{
3486
3508
  estimatedCostUsd: z.ZodOptional<z.ZodNumber>;
@@ -3532,8 +3554,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3532
3554
  sessionId: z.ZodOptional<z.ZodString>;
3533
3555
  }, z.core.$strict>>;
3534
3556
  stage: z.ZodEnum<{
3535
- gate: "gate";
3536
3557
  interior: "interior";
3558
+ gate: "gate";
3537
3559
  }>;
3538
3560
  usage: z.ZodOptional<z.ZodObject<{
3539
3561
  estimatedCostUsd: z.ZodOptional<z.ZodNumber>;
@@ -3576,8 +3598,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3576
3598
  sessionId: z.ZodOptional<z.ZodString>;
3577
3599
  }, z.core.$strict>>;
3578
3600
  stage: z.ZodEnum<{
3579
- gate: "gate";
3580
3601
  interior: "interior";
3602
+ gate: "gate";
3581
3603
  }>;
3582
3604
  usage: z.ZodOptional<z.ZodObject<{
3583
3605
  estimatedCostUsd: z.ZodOptional<z.ZodNumber>;
@@ -3607,7 +3629,7 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3607
3629
  staleRepeats: number;
3608
3630
  };
3609
3631
  observedAt: string;
3610
- stage: "gate" | "interior";
3632
+ stage: "interior" | "gate";
3611
3633
  issue?: number | undefined;
3612
3634
  pr?: number | undefined;
3613
3635
  threadId?: string | undefined;
@@ -3700,11 +3722,11 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3700
3722
  threadId: z.ZodOptional<z.ZodString>;
3701
3723
  workerId: z.ZodOptional<z.ZodString>;
3702
3724
  archiveStatus: z.ZodOptional<z.ZodEnum<{
3703
- pending: "pending";
3704
3725
  unavailable: "unavailable";
3705
3726
  archived: "archived";
3706
3727
  skipped: "skipped";
3707
3728
  "not-applicable": "not-applicable";
3729
+ pending: "pending";
3708
3730
  }>>;
3709
3731
  closeoutReason: z.ZodOptional<z.ZodString>;
3710
3732
  eventType: z.ZodLiteral<"worker-closeout-lessons">;
@@ -3741,11 +3763,11 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3741
3763
  }, z.core.$strict>], "lessonStatus">;
3742
3764
  readonly 2: z.ZodObject<{
3743
3765
  archiveStatus: z.ZodOptional<z.ZodEnum<{
3744
- pending: "pending";
3745
3766
  unavailable: "unavailable";
3746
3767
  archived: "archived";
3747
3768
  skipped: "skipped";
3748
3769
  "not-applicable": "not-applicable";
3770
+ pending: "pending";
3749
3771
  }>>;
3750
3772
  closeoutReason: z.ZodOptional<z.ZodString>;
3751
3773
  lessonStatus: z.ZodOptional<z.ZodEnum<{
@@ -3863,8 +3885,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3863
3885
  interiorCycle: z.ZodOptional<z.ZodNumber>;
3864
3886
  observedAt: z.ZodString;
3865
3887
  purpose: z.ZodEnum<{
3866
- code: "code";
3867
3888
  review: "review";
3889
+ code: "code";
3868
3890
  }>;
3869
3891
  slotResolution: z.ZodObject<{
3870
3892
  effort: z.ZodEnum<{
@@ -3883,8 +3905,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3883
3905
  model: z.ZodString;
3884
3906
  tier: z.ZodEnum<{
3885
3907
  review: "review";
3886
- oracle: "oracle";
3887
3908
  delegate: "delegate";
3909
+ oracle: "oracle";
3888
3910
  workhorse: "workhorse";
3889
3911
  scout: "scout";
3890
3912
  }>;
@@ -3892,8 +3914,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3892
3914
  startedAt: z.ZodString;
3893
3915
  tier: z.ZodEnum<{
3894
3916
  review: "review";
3895
- oracle: "oracle";
3896
3917
  delegate: "delegate";
3918
+ oracle: "oracle";
3897
3919
  workhorse: "workhorse";
3898
3920
  scout: "scout";
3899
3921
  }>;
@@ -3942,8 +3964,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3942
3964
  interiorCycle: z.ZodOptional<z.ZodNumber>;
3943
3965
  observedAt: z.ZodString;
3944
3966
  purpose: z.ZodEnum<{
3945
- code: "code";
3946
3967
  review: "review";
3968
+ code: "code";
3947
3969
  }>;
3948
3970
  slotResolution: z.ZodObject<{
3949
3971
  effort: z.ZodEnum<{
@@ -3962,8 +3984,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3962
3984
  model: z.ZodString;
3963
3985
  tier: z.ZodEnum<{
3964
3986
  review: "review";
3965
- oracle: "oracle";
3966
3987
  delegate: "delegate";
3988
+ oracle: "oracle";
3967
3989
  workhorse: "workhorse";
3968
3990
  scout: "scout";
3969
3991
  }>;
@@ -3971,8 +3993,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3971
3993
  startedAt: z.ZodString;
3972
3994
  tier: z.ZodEnum<{
3973
3995
  review: "review";
3974
- oracle: "oracle";
3975
3996
  delegate: "delegate";
3997
+ oracle: "oracle";
3976
3998
  workhorse: "workhorse";
3977
3999
  scout: "scout";
3978
4000
  }>;
@@ -4012,8 +4034,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
4012
4034
  interiorCycle: z.ZodOptional<z.ZodNumber>;
4013
4035
  observedAt: z.ZodString;
4014
4036
  purpose: z.ZodEnum<{
4015
- code: "code";
4016
4037
  review: "review";
4038
+ code: "code";
4017
4039
  }>;
4018
4040
  slotResolution: z.ZodObject<{
4019
4041
  effort: z.ZodEnum<{
@@ -4032,8 +4054,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
4032
4054
  model: z.ZodString;
4033
4055
  tier: z.ZodEnum<{
4034
4056
  review: "review";
4035
- oracle: "oracle";
4036
4057
  delegate: "delegate";
4058
+ oracle: "oracle";
4037
4059
  workhorse: "workhorse";
4038
4060
  scout: "scout";
4039
4061
  }>;
@@ -4041,8 +4063,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
4041
4063
  startedAt: z.ZodString;
4042
4064
  tier: z.ZodEnum<{
4043
4065
  review: "review";
4044
- oracle: "oracle";
4045
4066
  delegate: "delegate";
4067
+ oracle: "oracle";
4046
4068
  workhorse: "workhorse";
4047
4069
  scout: "scout";
4048
4070
  }>;
@@ -4085,17 +4107,17 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
4085
4107
  exitCode: number | null;
4086
4108
  harness: string;
4087
4109
  observedAt: string;
4088
- purpose: "code" | "review";
4110
+ purpose: "review" | "code";
4089
4111
  slotResolution: {
4090
4112
  effort: "high" | "low" | "medium" | "xhigh";
4091
4113
  engine: string;
4092
4114
  layerSource: "committedDefault" | "operatorSession" | "userConfig";
4093
4115
  model: string;
4094
- tier: "review" | "oracle" | "delegate" | "workhorse" | "scout";
4116
+ tier: "review" | "delegate" | "oracle" | "workhorse" | "scout";
4095
4117
  fallbackTier?: "delegate" | undefined;
4096
4118
  };
4097
4119
  startedAt: string;
4098
- tier: "review" | "oracle" | "delegate" | "workhorse" | "scout";
4120
+ tier: "review" | "delegate" | "oracle" | "workhorse" | "scout";
4099
4121
  tokenUsage: {
4100
4122
  source: "cursor-csv" | "codex-json" | "cursor-json" | "claude-json";
4101
4123
  status: "available";
@@ -4424,7 +4446,7 @@ declare const evaluateReadiness: (input: EvaluationInput) => {
4424
4446
  draft: boolean;
4425
4447
  mergeStateStatus: string;
4426
4448
  mergeable: string;
4427
- requiredChecks: "unknown" | "passed" | "failed" | "pending" | "none";
4449
+ requiredChecks: "unknown" | "pending" | "passed" | "failed" | "none";
4428
4450
  unresolvedReviewThreads: number;
4429
4451
  reviewDecision?: string | null | undefined;
4430
4452
  };
@@ -4439,13 +4461,13 @@ declare const evaluateReadiness: (input: EvaluationInput) => {
4439
4461
  reviews: {
4440
4462
  correctness: {
4441
4463
  required: boolean;
4442
- status: "blocked" | "not-required" | "current" | "stale" | "missing";
4464
+ status: "not-required" | "blocked" | "current" | "stale" | "missing";
4443
4465
  reviewedHeadSha?: string | undefined;
4444
4466
  reviewedPatchId?: string | undefined;
4445
4467
  };
4446
4468
  security?: {
4447
4469
  required: boolean;
4448
- status: "blocked" | "not-required" | "current" | "stale" | "missing";
4470
+ status: "not-required" | "blocked" | "current" | "stale" | "missing";
4449
4471
  reviewedHeadSha?: string | undefined;
4450
4472
  reviewedPatchId?: string | undefined;
4451
4473
  } | undefined;
@@ -4508,7 +4530,7 @@ declare const evaluateReadiness: (input: EvaluationInput) => {
4508
4530
  interior: number;
4509
4531
  };
4510
4532
  nextAction: "run-gate-cycle" | "accept-nonblocking-findings" | "escalate-to-triage" | "ready-for-human" | "advance-to-gate" | "run-interior-cycle";
4511
- stage: "gate" | "interior" | "interior-complete";
4533
+ stage: "interior" | "gate" | "interior-complete";
4512
4534
  forcedTransition?: "gate-cap-exhausted" | "interior-cap-reached" | undefined;
4513
4535
  } | undefined;
4514
4536
  reviewRuns?: PrReviewResult[] | undefined;
@@ -4772,6 +4794,7 @@ interface AssembleReviewPromptInput {
4772
4794
  patchId: string;
4773
4795
  priorLedgerEntries?: FindingLedgerEntry[];
4774
4796
  profile: FactoryProjectProfile;
4797
+ waveRung?: EvidenceReviewRung;
4775
4798
  }
4776
4799
  interface AssembleReviewPromptGitDependencies {
4777
4800
  repositoryRoot: (cwd: string) => string;
@@ -4793,7 +4816,8 @@ declare const assembleReviewPrompt: ({
4793
4816
  kind,
4794
4817
  patchId,
4795
4818
  priorLedgerEntries,
4796
- profile
4819
+ profile,
4820
+ waveRung
4797
4821
  }: AssembleReviewPromptInput, dependencies?: AssembleReviewPromptDependencies) => AssembledReviewPrompt;
4798
4822
  //#endregion
4799
4823
  //#region src/review-ladder-trace.d.ts
package/dist/index.js CHANGED
@@ -18,7 +18,7 @@ import { FACTORY_APP_BROKER_ORIGIN, FACTORY_APP_BROKER_PATH, FACTORY_CURSOR_OIDC
18
18
  import http from "node:http";
19
19
  import { pathToFileURL } from "node:url";
20
20
  //#region package.json
21
- var version = "1.0.0-alpha.27";
21
+ var version = "1.0.0-alpha.28";
22
22
  //#endregion
23
23
  //#region src/cli-entry.ts
24
24
  /**
@@ -17504,10 +17504,20 @@ function emitLadderStageTrace({ cwd, evaluation, headSha, issue, patchId, profil
17504
17504
  }
17505
17505
  //#endregion
17506
17506
  //#region src/review-contract.ts
17507
- const REVIEW_FOOTER_INSTRUCTIONS = `Do not print a machine-readable footer in your chat response. Instead, write your findings to the typed findings file at the path given in your dispatch/task instructions (the file pr:review reads via --findings <path>). The file must be valid JSON matching review-findings-file.ts's schema (schemaVersion 1):
17507
+ const SESSION_ID_RULE = `"sessionId" is this review session's own id. It must differ from the authoring session id the candidate was verified under (FACTORY_SESSION_ID): pr:review --findings refuses a findings file whose sessionId equals the authoring session.`;
17508
+ const authorityRule = (waveRung) => waveRung === void 0 ? `Emit schemaVersion 1 and omit "producer" and "rung": this candidate resolves no boundary-wave review rung. If your dispatch instructions do name a rung, emit schemaVersion 2 with that rung and with "producer" instead.` : `This candidate belongs to a boundary wave that demands the ${waveRung} review rung, so schemaVersion 2 is required. Record "rung": "${waveRung}" exactly as shown, and set "producer" to the engine and model that ran this review (for example "codex-cli/gpt-5.6-sol"). Findings without both fields are recorded without authority, and pr:publish then refuses with "no passing review at that authority".`;
17509
+ /**
17510
+ * The findings-file instructions for one candidate.
17511
+ *
17512
+ * `waveRung` is the review rung the candidate's boundary wave demands, when it
17513
+ * resolves one. It selects the findings schema version the gate will accept.
17514
+ */
17515
+ const reviewFooterInstructions = (waveRung) => {
17516
+ const schemaVersion = waveRung === void 0 ? 1 : 2;
17517
+ return `Do not print a machine-readable footer in your chat response. Instead, write your findings to the typed findings file at the path given in your dispatch/task instructions (the file pr:review reads via --findings <path>). The file must be valid JSON matching review-findings-file.ts's schema (schemaVersion ${schemaVersion}):
17508
17518
  {
17509
- "schemaVersion": 1,
17510
- "model": "<your model identifier>",
17519
+ "schemaVersion": ${schemaVersion},
17520
+ ${waveRung === void 0 ? "" : ` "producer": "<the engine and model that ran this review, for example codex-cli/gpt-5.6-sol>",\n "rung": "${waveRung}",\n`} "model": "<your model identifier>",
17511
17521
  "sessionId": "<this session's id>",
17512
17522
  "patchId": "<the stable patch-id from Review scope above>",
17513
17523
  "reviews": [
@@ -17520,10 +17530,13 @@ const REVIEW_FOOTER_INSTRUCTIONS = `Do not print a machine-readable footer in yo
17520
17530
  }
17521
17531
  ]
17522
17532
  }
17533
+ ${authorityRule(waveRung)}
17534
+ ${SESSION_ID_RULE}
17523
17535
  Use category "correctness", "safety", "coordination", or "maintainability"; set blockingAfterCap true for correctness, safety, or coordination findings. citedSpan must be the exact code text the finding is about, quoted verbatim from the diff (identity is derived from this, not from the title, so quote precisely). prescribedAction must be a concise, standalone statement of the required fix (identity is derived from this text too). If this finding is a restatement of a prior finding shown in the prior review ledger below, set supersedes to {"title": "<exact prior title>", "file": "<its file>"} instead of minting a new title for the same theme.`;
17536
+ };
17524
17537
  //#endregion
17525
17538
  //#region src/review-prompt.ts
17526
- const reviewScope = ({ base, changedFiles: files, headSha, patchId, profile }) => `Review scope:
17539
+ const reviewScope = ({ base, changedFiles: files, headSha, patchId, profile, waveRung }) => `Review scope:
17527
17540
  - Repository: ${profile.repository.owner}/${profile.repository.name}
17528
17541
  - Base ref: ${base}
17529
17542
  - Head SHA: ${headSha}
@@ -17539,7 +17552,7 @@ Required constraints:
17539
17552
  - Do not request elevated or unsandboxed approvals.
17540
17553
  - When you flag a finding, report every other instance of the same class in this diff in the same response, and include a one-line coverage note.
17541
17554
 
17542
- ${REVIEW_FOOTER_INSTRUCTIONS}`;
17555
+ ${reviewFooterInstructions(waveRung)}`;
17543
17556
  const MODE_FLOOR_FILES = {
17544
17557
  correctness: "correctness.md",
17545
17558
  security: "security/SKILL.md"
@@ -17613,7 +17626,7 @@ ${entries.map(priorLedgerEntryLine).join("\n")}
17613
17626
 
17614
17627
  Do not re-raise any of the findings above under a new title: they are already adjudicated (waived, filed as a follow-up, or fixed in this thread). If new evidence genuinely supersedes one of them, say so explicitly and name the exact prior finding (its title and file) that it supersedes, rather than minting an unrelated title for the same underlying theme.`
17615
17628
  });
17616
- const assembleReviewPrompt = ({ base, changedFiles, cwd = process.cwd(), headSha, issueFocus, kind, patchId, priorLedgerEntries, profile }, dependencies = {}) => {
17629
+ const assembleReviewPrompt = ({ base, changedFiles, cwd = process.cwd(), headSha, issueFocus, kind, patchId, priorLedgerEntries, profile, waveRung }, dependencies = {}) => {
17617
17630
  const priorLedger = priorLedgerEntries ? nonOpenLadderFindings(priorLedgerEntries) : [];
17618
17631
  const optionalSegments = {
17619
17632
  "coding-standards": codingStandardsSegment({
@@ -17633,7 +17646,8 @@ const assembleReviewPrompt = ({ base, changedFiles, cwd = process.cwd(), headSha
17633
17646
  changedFiles,
17634
17647
  headSha,
17635
17648
  patchId,
17636
- profile
17649
+ profile,
17650
+ waveRung
17637
17651
  }) },
17638
17652
  { text: modeFloorInstructions(kind, changedFiles) },
17639
17653
  ...REVIEW_PROMPT_SECTION_PROVENANCES.flatMap((provenance) => {
@@ -17658,7 +17672,8 @@ const ASSEMBLED_REVIEW_PROMPT_SCHEMA_VERSION = 1;
17658
17672
  const assembledReviewPromptKindSchema = z.object({
17659
17673
  kind: z.enum(["correctness", "security"]),
17660
17674
  prompt: z.string().min(1),
17661
- sections: z.array(reviewPromptSectionSchema)
17675
+ sections: z.array(reviewPromptSectionSchema),
17676
+ waveRung: z.enum(EVIDENCE_REVIEW_RUNGS).optional()
17662
17677
  });
17663
17678
  const assembledReviewPromptArtifactSchema = z.object({
17664
17679
  headSha: z.string().regex(/^[0-9a-f]{40}$/u),
@@ -17687,6 +17702,51 @@ const defaultFetchIssueBody = ({ issue, owner, repo }) => runGhJson([
17687
17702
  "--json",
17688
17703
  "body"
17689
17704
  ]).body;
17705
+ const candidateWavePullRequestSchema = z.object({
17706
+ baseRefName: z.string().min(1),
17707
+ body: z.string(),
17708
+ headRefName: z.string().min(1),
17709
+ number: z.number().int().positive()
17710
+ });
17711
+ const defaultFetchWavePullRequest = (cwd) => runGhJsonAt([
17712
+ "pr",
17713
+ "view",
17714
+ "--json",
17715
+ "baseRefName,body,headRefName,number"
17716
+ ], cwd);
17717
+ /**
17718
+ * The review rung this candidate's boundary wave demands (#1001).
17719
+ *
17720
+ * The assembled prompt tells the reviewer which findings schema the gate will
17721
+ * accept. A wave that demands a rung needs schemaVersion 2 with `producer` and
17722
+ * `rung`; the v1 shape is recorded without authority, and `pr:publish` then
17723
+ * refuses it with "no passing review at that authority".
17724
+ *
17725
+ * This is prompt enrichment and fails open, like the coding-standards read:
17726
+ * every unreadable step returns undefined and the prompt keeps the v1 shape.
17727
+ * It decides no authority — `pr:ready` resolves the same wave demand again and
17728
+ * is the stage that refuses on it.
17729
+ */
17730
+ const assembleWaveRung = ({ args, cwd, dependencies, fetchIssueBody, fetchWavePullRequest, profile }) => {
17731
+ if (args.epic === void 0) return;
17732
+ try {
17733
+ const pullRequest = candidateWavePullRequestSchema.parse(fetchWavePullRequest(cwd));
17734
+ const demand = resolveWaveDemand({
17735
+ baseRefName: pullRequest.baseRefName,
17736
+ epic: args.epic,
17737
+ ...dependencies.fetchClosingPullRequests === void 0 ? {} : { fetchClosingPullRequests: dependencies.fetchClosingPullRequests },
17738
+ fetchIssueBody,
17739
+ headRefName: pullRequest.headRefName,
17740
+ owner: profile.repository.owner,
17741
+ pr: pullRequest.number,
17742
+ prBody: pullRequest.body,
17743
+ repo: profile.repository.name
17744
+ });
17745
+ return demand.kind === "demanded" ? demand.demand.review : void 0;
17746
+ } catch {
17747
+ return;
17748
+ }
17749
+ };
17690
17750
  const assertReviewCycleInWindow = (cycle, maxCycles) => {
17691
17751
  if (cycle < 1 || cycle > maxCycles) throw new Error(`--cycle must be between 1 and ${maxCycles}.`);
17692
17752
  };
@@ -17806,7 +17866,7 @@ const assembleGitDependencies = (git) => git.repositoryRoot !== void 0 && git.sh
17806
17866
  repositoryRoot: git.repositoryRoot,
17807
17867
  showFileAtRef: git.showFileAtRef
17808
17868
  } : void 0;
17809
- const writeAssembledReviewPrompt = ({ args, cwd, fetchIssueBody, files, git, headSha, kinds, output, patchId, profile }) => {
17869
+ const writeAssembledReviewPrompt = ({ args, cwd, fetchIssueBody, files, git, headSha, kinds, output, patchId, profile, waveRung }) => {
17810
17870
  const priorLedger = priorLedgerFor(priorLadderStateFor({
17811
17871
  base: args.base,
17812
17872
  cwd,
@@ -17826,12 +17886,14 @@ const writeAssembledReviewPrompt = ({ args, cwd, fetchIssueBody, files, git, hea
17826
17886
  kind,
17827
17887
  patchId,
17828
17888
  priorLedgerEntries: priorLedger,
17829
- profile
17889
+ profile,
17890
+ ...waveRung === void 0 ? {} : { waveRung }
17830
17891
  }, assembleGit === void 0 ? {} : { git: assembleGit });
17831
17892
  return {
17832
17893
  kind,
17833
17894
  prompt: assembled.prompt,
17834
- sections: assembled.sections
17895
+ sections: assembled.sections,
17896
+ ...waveRung === void 0 ? {} : { waveRung }
17835
17897
  };
17836
17898
  });
17837
17899
  const artifactPath = path.resolve(cwd, DEFAULT_ASSEMBLED_REVIEW_PROMPT_PATH);
@@ -17839,7 +17901,7 @@ const writeAssembledReviewPrompt = ({ args, cwd, fetchIssueBody, files, git, hea
17839
17901
  writeProofJson({
17840
17902
  headSha,
17841
17903
  patchId,
17842
- reviews: existing.status === "ok" && existing.artifact.patchId === patchId && existing.artifact.headSha === headSha ? [...new Map([...existing.artifact.reviews, ...assembledReviews].map((review) => [review.kind, review])).values()] : assembledReviews,
17904
+ reviews: existing.status === "ok" && existing.artifact.patchId === patchId && existing.artifact.headSha === headSha ? [...new Map([...existing.artifact.reviews.filter((review) => review.waveRung === waveRung), ...assembledReviews].map((review) => [review.kind, review])).values()] : assembledReviews,
17843
17905
  schemaVersion: ASSEMBLED_REVIEW_PROMPT_SCHEMA_VERSION
17844
17906
  }, artifactPath);
17845
17907
  console.log(`pr:review assembled prompt written to ${artifactPath}`);
@@ -18068,17 +18130,26 @@ async function runPrReview(args, dependencies = {}) {
18068
18130
  console.log(ASSEMBLE_FAITHFUL_MERGE_NOTICE);
18069
18131
  return assembleProof();
18070
18132
  }
18133
+ const fetchIssueBody = dependencies.fetchIssueBody ?? defaultFetchIssueBody;
18071
18134
  writeAssembledReviewPrompt({
18072
18135
  args,
18073
18136
  cwd,
18074
- fetchIssueBody: dependencies.fetchIssueBody ?? defaultFetchIssueBody,
18137
+ fetchIssueBody,
18075
18138
  files,
18076
18139
  git,
18077
18140
  headSha,
18078
18141
  kinds,
18079
18142
  output,
18080
18143
  patchId,
18081
- profile
18144
+ profile,
18145
+ waveRung: assembleWaveRung({
18146
+ args,
18147
+ cwd,
18148
+ dependencies,
18149
+ fetchIssueBody,
18150
+ fetchWavePullRequest: dependencies.fetchWavePullRequest ?? defaultFetchWavePullRequest,
18151
+ profile
18152
+ })
18082
18153
  });
18083
18154
  return assembleProof();
18084
18155
  }
@@ -18980,7 +19051,7 @@ function assertForegroundGate({ gate, env = process.env }) {
18980
19051
  //#endregion
18981
19052
  //#region src/commands/pr-review.ts
18982
19053
  function createPrReviewCommand(output, action) {
18983
- return markCwdOptionDefault(new Command("pr:review").description("Assemble a factory-owned review prompt, or validate clean-session findings and write typed review proof").option("--base <ref>", "base branch or ref", "origin/main").option("--cwd <path>", "working directory to review", collectCwdOption).option("--cycle <number>", "review cycle number", positiveInteger$1("--cycle"), 1).option("--mode <mode>", "correctness, security, or all", "all").option("--assemble", "write the factory-owned review prompt for a clean session; do not validate findings").option("--findings <path>", "typed clean-session findings JSON file").option("--historical", "record findings that read an earlier commit on this branch: the cycle joins the ladder as prior history and renders no verdict of its own, so it never admits. It leaves the candidate's recorded verdict untouched. Use --dispositions for the findings its fixes answered").option("--dispositions <path>", "JSON file of ladder disposition declarations (waived / follow-up-filed / fixed-in-thread) for previously flagged findings").option("--issue <number>", "issue number recorded on the review ladder trace; --assemble also loads Review focus from this issue", positiveInteger$1("--issue")).option("--output <path>", "write proof JSON to a file").option("--profile <path>", "path to the project profile JSON file").option("--verify-proof <path>", "pr:verify proof JSON path").action(withGateTiming({
19054
+ return markCwdOptionDefault(new Command("pr:review").description("Assemble a factory-owned review prompt, or validate clean-session findings and write typed review proof").option("--base <ref>", "base branch or ref", "origin/main").option("--cwd <path>", "working directory to review", collectCwdOption).option("--cycle <number>", "review cycle number", positiveInteger$1("--cycle"), 1).option("--mode <mode>", "correctness, security, or all", "all").option("--assemble", "write the factory-owned review prompt for a clean session; do not validate findings").option("--epic <number>", "issue carrying the factory-boundary manifest, which may be the work issue itself; --assemble then asks the reviewer for the findings schema the wave-demanded review rung accepts (#1001)", positiveInteger$1("--epic")).option("--findings <path>", "typed clean-session findings JSON file").option("--historical", "record findings that read an earlier commit on this branch: the cycle joins the ladder as prior history and renders no verdict of its own, so it never admits. It leaves the candidate's recorded verdict untouched. Use --dispositions for the findings its fixes answered").option("--dispositions <path>", "JSON file of ladder disposition declarations (waived / follow-up-filed / fixed-in-thread) for previously flagged findings").option("--issue <number>", "issue number recorded on the review ladder trace; --assemble also loads Review focus from this issue", positiveInteger$1("--issue")).option("--output <path>", "write proof JSON to a file").option("--profile <path>", "path to the project profile JSON file").option("--verify-proof <path>", "pr:verify proof JSON path").action(withGateTiming({
18984
19055
  gate: "pr:review",
18985
19056
  resolveCycle: (options) => options.cycle,
18986
19057
  resolveLedgerRoot: (options) => resolveCwdOption(options.cwd),
@@ -18998,6 +19069,7 @@ function createPrReviewCommand(output, action) {
18998
19069
  cwd: resolveCwdOption(options.cwd),
18999
19070
  cycle: options.cycle,
19000
19071
  dispositions: options.dispositions,
19072
+ epic: options.epic,
19001
19073
  findings: options.findings,
19002
19074
  ...options.historical === true ? { historical: true } : {},
19003
19075
  issue: options.issue,
package/dist/schemas.d.ts CHANGED
@@ -853,8 +853,8 @@ declare const closeoutArtifactSchema: z.ZodObject<{
853
853
  }, z.core.$strict>;
854
854
  unit: z.ZodEnum<{
855
855
  boolean: "boolean";
856
- count: "count";
857
856
  text: "text";
857
+ count: "count";
858
858
  tokens: "tokens";
859
859
  usd: "usd";
860
860
  }>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patronage/software-factory",
3
- "version": "1.0.0-alpha.27",
3
+ "version": "1.0.0-alpha.28",
4
4
  "description": "Shared Patronage software factory CLI and project-profile validation tools",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -37,7 +37,7 @@
37
37
  "picomatch": "^4.0.5",
38
38
  "yaml": "^2.9.0",
39
39
  "zod": "4.4.3",
40
- "@patronage/factory-ci": "1.0.0-alpha.27"
40
+ "@patronage/factory-ci": "1.0.0-alpha.28"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/node": "24.13.3",