@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/README.md +2 -0
- package/dist/index.d.ts +507 -296
- package/dist/index.js +12542 -10611
- package/dist/schemas.d.ts +104 -36
- package/dist/schemas.js +127 -51
- package/package.json +2 -2
package/dist/schemas.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { z } from "zod";
|
|
|
2
2
|
//#region src/packages/review-prompt-sections/schema.d.ts
|
|
3
3
|
declare const reviewPromptSectionSchema: z.ZodObject<{
|
|
4
4
|
provenance: z.ZodEnum<{
|
|
5
|
+
"coding-standards": "coding-standards";
|
|
5
6
|
"prior-review-ledger": "prior-review-ledger";
|
|
6
7
|
"issue-review-focus": "issue-review-focus";
|
|
7
8
|
}>;
|
|
@@ -12,6 +13,7 @@ type ReviewPromptSection = z.infer<typeof reviewPromptSectionSchema>;
|
|
|
12
13
|
type ReviewPromptSectionProvenance = ReviewPromptSection["provenance"];
|
|
13
14
|
declare const reviewPromptSectionsSchema: z.ZodArray<z.ZodObject<{
|
|
14
15
|
provenance: z.ZodEnum<{
|
|
16
|
+
"coding-standards": "coding-standards";
|
|
15
17
|
"prior-review-ledger": "prior-review-ledger";
|
|
16
18
|
"issue-review-focus": "issue-review-focus";
|
|
17
19
|
}>;
|
|
@@ -19,6 +21,23 @@ declare const reviewPromptSectionsSchema: z.ZodArray<z.ZodObject<{
|
|
|
19
21
|
text: z.ZodString;
|
|
20
22
|
}, z.core.$strict>>;
|
|
21
23
|
//#endregion
|
|
24
|
+
//#region src/policy-resolution.d.ts
|
|
25
|
+
/** How a gate resolved the review policy it evaluated a candidate under. */
|
|
26
|
+
declare const policyResolutionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
27
|
+
basePolicyDigest: z.ZodString;
|
|
28
|
+
baseRefName: z.ZodString;
|
|
29
|
+
candidatePolicyDigest: z.ZodString;
|
|
30
|
+
effectiveDigest: z.ZodString;
|
|
31
|
+
policyBaseSha: z.ZodString;
|
|
32
|
+
reviewPolicyChanged: z.ZodBoolean;
|
|
33
|
+
status: z.ZodLiteral<"authoritative">;
|
|
34
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
35
|
+
baseRefName: z.ZodString;
|
|
36
|
+
reason: z.ZodString;
|
|
37
|
+
status: z.ZodLiteral<"unresolved">;
|
|
38
|
+
}, z.core.$strict>], "status">;
|
|
39
|
+
type PolicyResolution = z.infer<typeof policyResolutionSchema>;
|
|
40
|
+
//#endregion
|
|
22
41
|
//#region src/review-ladder-policy.d.ts
|
|
23
42
|
type ReviewFindingCategory = "correctness" | "safety" | "coordination" | "maintainability" | "unknown";
|
|
24
43
|
declare const FINDING_DISPOSITIONS: readonly ["open", "fixed-in-thread", "follow-up-filed", "waived", "stale-repeat", "rerun-noise"];
|
|
@@ -75,6 +94,7 @@ interface ReviewLadderCycle {
|
|
|
75
94
|
headSha: string;
|
|
76
95
|
patchId: string;
|
|
77
96
|
};
|
|
97
|
+
historical?: true;
|
|
78
98
|
model?: string;
|
|
79
99
|
correlatedRerun?: boolean;
|
|
80
100
|
session?: LadderSessionAttribution;
|
|
@@ -126,6 +146,13 @@ interface PrReviewProof {
|
|
|
126
146
|
changedFiles: string[];
|
|
127
147
|
cleanedPaths: string[];
|
|
128
148
|
ladder?: PrReviewLadderState;
|
|
149
|
+
/**
|
|
150
|
+
* The policy identity this review run resolved its demanded kinds under
|
|
151
|
+
* (#922 Slice B). Optional: a run that could not reach the authority records
|
|
152
|
+
* the refusal instead, and `pr:ready` decides what an unresolved or
|
|
153
|
+
* disagreeing identity means for admission.
|
|
154
|
+
*/
|
|
155
|
+
policyResolution?: PolicyResolution;
|
|
129
156
|
reviewRequirement?: {
|
|
130
157
|
reason: "no-applicable-mode" | "faithful-merge";
|
|
131
158
|
status: "not-required";
|
|
@@ -225,21 +252,21 @@ declare const boundaryReviewProofBaseSchema: z.ZodObject<{
|
|
|
225
252
|
}, z.core.$loose>;
|
|
226
253
|
type BoundaryReviewProof = z.infer<typeof boundaryReviewProofBaseSchema>;
|
|
227
254
|
//#endregion
|
|
228
|
-
//#region src/
|
|
229
|
-
interface
|
|
230
|
-
/**
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
*/
|
|
237
|
-
argv: string[];
|
|
255
|
+
//#region src/catch-up-recognition-record.d.ts
|
|
256
|
+
interface CatchUpRecognition {
|
|
257
|
+
/** The ref the candidate targets, as the recognizing command resolved it. */
|
|
258
|
+
baseRef: string;
|
|
259
|
+
/** The live target tip at recognition time; the head's first parent. */
|
|
260
|
+
baseTipSha: string;
|
|
261
|
+
/** The head's second parent: the admitted base-side content merged in. */
|
|
262
|
+
mergedParentSha: string;
|
|
238
263
|
/**
|
|
239
|
-
*
|
|
240
|
-
*
|
|
264
|
+
* The tree `git merge-tree --write-tree` produced for the two parents. It
|
|
265
|
+
* equals the head's own tree; that equality is the faithfulness proof.
|
|
241
266
|
*/
|
|
242
|
-
|
|
267
|
+
mergedTreeSha: string;
|
|
268
|
+
/** The ref that proves the second parent is admitted content. */
|
|
269
|
+
upstreamRef: string;
|
|
243
270
|
}
|
|
244
271
|
//#endregion
|
|
245
272
|
//#region src/diff-classification.d.ts
|
|
@@ -274,6 +301,23 @@ declare const impactStampSchema: z.ZodObject<{
|
|
|
274
301
|
}, z.core.$strip>;
|
|
275
302
|
type ImpactStamp = z.infer<typeof impactStampSchema>;
|
|
276
303
|
//#endregion
|
|
304
|
+
//#region src/follow-up.d.ts
|
|
305
|
+
interface FollowUpAction {
|
|
306
|
+
/**
|
|
307
|
+
* Machine-safe argv-style array for the obvious next action, e.g.
|
|
308
|
+
* ["gh","pr","merge","513","--squash"]. Same shape and field name that
|
|
309
|
+
* `factory:delegate --print` emits, so an orchestrating agent can spawn the
|
|
310
|
+
* next command without reconstructing a shell string. argv[0] is the
|
|
311
|
+
* executable; the rest are literal, already-split arguments.
|
|
312
|
+
*/
|
|
313
|
+
argv: string[];
|
|
314
|
+
/**
|
|
315
|
+
* Human-readable rendering of {@link argv} for logs and operators. Additive
|
|
316
|
+
* to argv, never a substitute for it — argv is the source of truth.
|
|
317
|
+
*/
|
|
318
|
+
command: string;
|
|
319
|
+
}
|
|
320
|
+
//#endregion
|
|
277
321
|
//#region src/pr-verify-mode.d.ts
|
|
278
322
|
/**
|
|
279
323
|
* The verification mode `pr:verify` resolved for a run.
|
|
@@ -388,12 +432,12 @@ declare const managedReadinessLedgerSchema: z.ZodObject<{
|
|
|
388
432
|
"interior-cap-reached": "interior-cap-reached";
|
|
389
433
|
}>>;
|
|
390
434
|
nextAction: z.ZodEnum<{
|
|
391
|
-
"run-interior-cycle": "run-interior-cycle";
|
|
392
|
-
"advance-to-gate": "advance-to-gate";
|
|
393
435
|
"run-gate-cycle": "run-gate-cycle";
|
|
394
436
|
"accept-nonblocking-findings": "accept-nonblocking-findings";
|
|
395
437
|
"escalate-to-triage": "escalate-to-triage";
|
|
396
438
|
"ready-for-human": "ready-for-human";
|
|
439
|
+
"advance-to-gate": "advance-to-gate";
|
|
440
|
+
"run-interior-cycle": "run-interior-cycle";
|
|
397
441
|
}>;
|
|
398
442
|
stage: z.ZodEnum<{
|
|
399
443
|
gate: "gate";
|
|
@@ -461,23 +505,6 @@ type ReadinessRepair = z.infer<typeof readinessRepairSchema>;
|
|
|
461
505
|
type ReadinessStatus = "ready" | "blocked";
|
|
462
506
|
type ManagedReadinessLedger = z.infer<typeof managedReadinessLedgerSchema>;
|
|
463
507
|
//#endregion
|
|
464
|
-
//#region src/catch-up-recognition-record.d.ts
|
|
465
|
-
interface CatchUpRecognition {
|
|
466
|
-
/** The ref the candidate targets, as the recognizing command resolved it. */
|
|
467
|
-
baseRef: string;
|
|
468
|
-
/** The live target tip at recognition time; the head's first parent. */
|
|
469
|
-
baseTipSha: string;
|
|
470
|
-
/** The head's second parent: the admitted base-side content merged in. */
|
|
471
|
-
mergedParentSha: string;
|
|
472
|
-
/**
|
|
473
|
-
* The tree `git merge-tree --write-tree` produced for the two parents. It
|
|
474
|
-
* equals the head's own tree; that equality is the faithfulness proof.
|
|
475
|
-
*/
|
|
476
|
-
mergedTreeSha: string;
|
|
477
|
-
/** The ref that proves the second parent is admitted content. */
|
|
478
|
-
upstreamRef: string;
|
|
479
|
-
}
|
|
480
|
-
//#endregion
|
|
481
508
|
//#region src/pr-verify-proof-contract.d.ts
|
|
482
509
|
declare const SUPPORTED_PR_VERIFY_SCHEMA_VERSIONS: readonly [1, 2, 3, 4];
|
|
483
510
|
type PrVerifySchemaVersion = (typeof SUPPORTED_PR_VERIFY_SCHEMA_VERSIONS)[number];
|
|
@@ -560,6 +587,16 @@ interface PrVerifyProof {
|
|
|
560
587
|
notRequiredCommands?: PrVerifyNotRequiredCommand[];
|
|
561
588
|
outcome?: "aborted" | "passed";
|
|
562
589
|
patchId?: string;
|
|
590
|
+
/**
|
|
591
|
+
* The review policy identity this verification run resolved (#922 Slice B).
|
|
592
|
+
*
|
|
593
|
+
* Verification demands no review mode of its own. It records the identity so
|
|
594
|
+
* `pr:ready` can see whether the stage that produced this proof judged the
|
|
595
|
+
* candidate under the same policy readiness resolves. Optional, and normally
|
|
596
|
+
* `unresolved` on the first run of a branch: a candidate is verified before
|
|
597
|
+
* it has a pull request, and there is no authority to read without one.
|
|
598
|
+
*/
|
|
599
|
+
policyResolution?: PolicyResolution;
|
|
563
600
|
profilePath: string;
|
|
564
601
|
projectKey: string;
|
|
565
602
|
repository: string;
|
|
@@ -644,6 +681,19 @@ declare const prVerifyProofSchema: z.ZodObject<{
|
|
|
644
681
|
aborted: "aborted";
|
|
645
682
|
}>>;
|
|
646
683
|
patchId: z.ZodOptional<z.ZodString>;
|
|
684
|
+
policyResolution: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
685
|
+
basePolicyDigest: z.ZodString;
|
|
686
|
+
baseRefName: z.ZodString;
|
|
687
|
+
candidatePolicyDigest: z.ZodString;
|
|
688
|
+
effectiveDigest: z.ZodString;
|
|
689
|
+
policyBaseSha: z.ZodString;
|
|
690
|
+
reviewPolicyChanged: z.ZodBoolean;
|
|
691
|
+
status: z.ZodLiteral<"authoritative">;
|
|
692
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
693
|
+
baseRefName: z.ZodString;
|
|
694
|
+
reason: z.ZodString;
|
|
695
|
+
status: z.ZodLiteral<"unresolved">;
|
|
696
|
+
}, z.core.$strict>], "status">>;
|
|
647
697
|
profilePath: z.ZodString;
|
|
648
698
|
projectKey: z.ZodString;
|
|
649
699
|
repository: z.ZodString;
|
|
@@ -713,6 +763,13 @@ interface PrReadyProof {
|
|
|
713
763
|
* waived demand reads to a human. Absent when there are none.
|
|
714
764
|
*/
|
|
715
765
|
notices?: string[];
|
|
766
|
+
/**
|
|
767
|
+
* The policy identity readiness resolved review demand under (#922): the
|
|
768
|
+
* base ref, its live tip, and the digests of the base, candidate, and merged
|
|
769
|
+
* review policies. Optional on the wire and additive — this is a new record
|
|
770
|
+
* on an unchanged contract, so no schema version moves.
|
|
771
|
+
*/
|
|
772
|
+
policyResolution?: PolicyResolution;
|
|
716
773
|
/** Committed profile blob evaluated by readiness. Required for merge. */
|
|
717
774
|
profileBlobSha?: string;
|
|
718
775
|
/** Checkout-relative committed profile path evaluated by readiness. */
|
|
@@ -1086,20 +1143,18 @@ declare const prReadyProofSchema: z.ZodObject<{
|
|
|
1086
1143
|
forcedTransition: z.ZodOptional<z.ZodEnum<{
|
|
1087
1144
|
"gate-cap-exhausted": "gate-cap-exhausted";
|
|
1088
1145
|
"interior-cap-reached": "interior-cap-reached";
|
|
1089
|
-
"interior-takeover": "interior-takeover";
|
|
1090
1146
|
}>>;
|
|
1091
1147
|
nextAction: z.ZodEnum<{
|
|
1092
|
-
"run-interior-cycle": "run-interior-cycle";
|
|
1093
|
-
"advance-to-gate": "advance-to-gate";
|
|
1094
1148
|
"run-gate-cycle": "run-gate-cycle";
|
|
1095
1149
|
"accept-nonblocking-findings": "accept-nonblocking-findings";
|
|
1096
1150
|
"escalate-to-triage": "escalate-to-triage";
|
|
1097
1151
|
"ready-for-human": "ready-for-human";
|
|
1152
|
+
"advance-to-gate": "advance-to-gate";
|
|
1153
|
+
"run-interior-cycle": "run-interior-cycle";
|
|
1098
1154
|
}>;
|
|
1099
1155
|
stage: z.ZodEnum<{
|
|
1100
1156
|
gate: "gate";
|
|
1101
1157
|
interior: "interior";
|
|
1102
|
-
"interior-takeover": "interior-takeover";
|
|
1103
1158
|
"interior-complete": "interior-complete";
|
|
1104
1159
|
}>;
|
|
1105
1160
|
}, z.core.$strip>>;
|
|
@@ -1166,6 +1221,19 @@ declare const prReadyProofSchema: z.ZodObject<{
|
|
|
1166
1221
|
}, z.core.$strict>], "prVerify">;
|
|
1167
1222
|
}, z.core.$strip>;
|
|
1168
1223
|
notices: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1224
|
+
policyResolution: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
1225
|
+
basePolicyDigest: z.ZodString;
|
|
1226
|
+
baseRefName: z.ZodString;
|
|
1227
|
+
candidatePolicyDigest: z.ZodString;
|
|
1228
|
+
effectiveDigest: z.ZodString;
|
|
1229
|
+
policyBaseSha: z.ZodString;
|
|
1230
|
+
reviewPolicyChanged: z.ZodBoolean;
|
|
1231
|
+
status: z.ZodLiteral<"authoritative">;
|
|
1232
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1233
|
+
baseRefName: z.ZodString;
|
|
1234
|
+
reason: z.ZodString;
|
|
1235
|
+
status: z.ZodLiteral<"unresolved">;
|
|
1236
|
+
}, z.core.$strict>], "status">>;
|
|
1169
1237
|
profileBlobSha: z.ZodOptional<z.ZodString>;
|
|
1170
1238
|
profilePath: z.ZodOptional<z.ZodString>;
|
|
1171
1239
|
repairs: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
package/dist/schemas.js
CHANGED
|
@@ -2,12 +2,12 @@ import { z } from "zod";
|
|
|
2
2
|
import "yaml";
|
|
3
3
|
import "picomatch";
|
|
4
4
|
//#region src/review-rungs.ts
|
|
5
|
-
const EVIDENCE_REVIEW_RUNGS
|
|
5
|
+
const EVIDENCE_REVIEW_RUNGS = [
|
|
6
6
|
"independent-model",
|
|
7
7
|
"oracle",
|
|
8
8
|
"human"
|
|
9
9
|
];
|
|
10
|
-
Object.fromEntries(EVIDENCE_REVIEW_RUNGS
|
|
10
|
+
Object.fromEntries(EVIDENCE_REVIEW_RUNGS.map((rung, index) => [rung, index]));
|
|
11
11
|
//#endregion
|
|
12
12
|
//#region src/demand-keys.ts
|
|
13
13
|
/** The demands that exist at most once per candidate. */
|
|
@@ -19,6 +19,13 @@ const DEMAND_KEYS = {
|
|
|
19
19
|
* happen.
|
|
20
20
|
*/
|
|
21
21
|
boundaryWave: "boundary-wave",
|
|
22
|
+
/**
|
|
23
|
+
* Closeout pin (#901): a merged interior's declared child issue is still
|
|
24
|
+
* open. The factory does not close issues; the operator closes, or waives
|
|
25
|
+
* this demand for that interior PR. In force at `boundary:check --final`,
|
|
26
|
+
* not at interior `boundary:check` and not at `pr:ready`.
|
|
27
|
+
*/
|
|
28
|
+
childIssueOpen: "child-issue-open",
|
|
22
29
|
/** The PR is still a draft. */
|
|
23
30
|
draft: "draft",
|
|
24
31
|
/** GitHub's own check rollup for the candidate head. */
|
|
@@ -37,6 +44,13 @@ const DEMAND_KEYS = {
|
|
|
37
44
|
* neither a review-rung authority nor a scheduling requirement.
|
|
38
45
|
*/
|
|
39
46
|
nativeApproval: "native-approval",
|
|
47
|
+
/**
|
|
48
|
+
* The policy identity an earlier stage recorded must be the one readiness
|
|
49
|
+
* resolved (#922 Slice B). In force when a consumed `pr:verify` or
|
|
50
|
+
* `pr:review` proof judged this candidate under a different review policy,
|
|
51
|
+
* or recorded none where the resolved demand includes a security review.
|
|
52
|
+
*/
|
|
53
|
+
policyIdentity: "policy-identity",
|
|
40
54
|
/** A current, head-bound, passing typed `pr:verify` proof. */
|
|
41
55
|
prVerify: "pr-verify",
|
|
42
56
|
/** The profile-resolved review ladder policy. */
|
|
@@ -116,7 +130,7 @@ const qualifierIsMintable = (family, qualifier) => {
|
|
|
116
130
|
if (!QUALIFIER_PATTERN.test(qualifier)) return false;
|
|
117
131
|
const decoded = decodeQualifier(qualifier);
|
|
118
132
|
if (decoded === void 0 || demandQualifier(decoded) !== qualifier) return false;
|
|
119
|
-
if (family === "review-rung") return EVIDENCE_REVIEW_RUNGS
|
|
133
|
+
if (family === "review-rung") return EVIDENCE_REVIEW_RUNGS.includes(decoded);
|
|
120
134
|
if (family === "review-mode") return REVIEW_MODE_DEMAND_VALUES.includes(decoded);
|
|
121
135
|
return true;
|
|
122
136
|
};
|
|
@@ -234,8 +248,71 @@ const waivedDemandSchema = z.object({
|
|
|
234
248
|
unmetReasons: z.array(z.string().min(1)).min(1)
|
|
235
249
|
});
|
|
236
250
|
//#endregion
|
|
251
|
+
//#region src/diff-classification.ts
|
|
252
|
+
const DIFF_CLASSIFICATIONS = [
|
|
253
|
+
"docs/process-only",
|
|
254
|
+
"trivial",
|
|
255
|
+
"non-trivial"
|
|
256
|
+
];
|
|
257
|
+
//#endregion
|
|
258
|
+
//#region src/policy-resolution.ts
|
|
259
|
+
const COMMIT_SHA_PATTERN = /^[0-9a-f]{40}$/u;
|
|
260
|
+
const digestSchema = z.string().regex(/^[0-9a-f]{64}$/u);
|
|
261
|
+
/**
|
|
262
|
+
* The authority resolved: the live tip of the PR's own base ref served a
|
|
263
|
+
* parseable profile, and demand was resolved from the union of that policy and
|
|
264
|
+
* the candidate's.
|
|
265
|
+
*
|
|
266
|
+
* Every identity field is REQUIRED. A cross-stage reader compares these digests
|
|
267
|
+
* to decide whether two stages judged the same candidate under the same policy;
|
|
268
|
+
* an `authoritative` record with a digest missing would read to that reader as
|
|
269
|
+
* "nothing disagrees", which is a silent downgrade of exactly the demand this
|
|
270
|
+
* record exists to protect. `reason` is forbidden here — a resolved authority
|
|
271
|
+
* has nothing to explain.
|
|
272
|
+
*/
|
|
273
|
+
const authoritativePolicyResolutionSchema = z.object({
|
|
274
|
+
/** sha256 of the canonical base `review` subtree. */
|
|
275
|
+
basePolicyDigest: digestSchema,
|
|
276
|
+
/** The PR's own base ref, whose live tip is the authority. */
|
|
277
|
+
baseRefName: z.string().min(1),
|
|
278
|
+
/** sha256 of the canonical candidate `review` subtree. */
|
|
279
|
+
candidatePolicyDigest: digestSchema,
|
|
280
|
+
/** sha256 of the merged (base ∪ candidate) protected-path set. */
|
|
281
|
+
effectiveDigest: digestSchema,
|
|
282
|
+
/** The base-ref tip the base policy was read at. */
|
|
283
|
+
policyBaseSha: z.string().regex(COMMIT_SHA_PATTERN),
|
|
284
|
+
/**
|
|
285
|
+
* Whether the candidate's `review` subtree differs from the base's. The
|
|
286
|
+
* digests prove which policies were read; this says whether they agreed,
|
|
287
|
+
* which is the fact that explains a demand the candidate's own profile
|
|
288
|
+
* would not have produced.
|
|
289
|
+
*/
|
|
290
|
+
reviewPolicyChanged: z.boolean(),
|
|
291
|
+
status: z.literal("authoritative")
|
|
292
|
+
}).strict();
|
|
293
|
+
/**
|
|
294
|
+
* The authority could not be read, and `reason` says why — required, because an
|
|
295
|
+
* unresolved record with no reason is an unactionable refusal. `pr:ready`
|
|
296
|
+
* refuses before it writes a proof, so a Slice A ready proof never carries one;
|
|
297
|
+
* this member is the recorded form of that refusal for the stages that carry it
|
|
298
|
+
* forward.
|
|
299
|
+
*/
|
|
300
|
+
const unresolvedPolicyResolutionSchema = z.object({
|
|
301
|
+
/** The base ref whose policy could not be read. */
|
|
302
|
+
baseRefName: z.string().min(1),
|
|
303
|
+
/** Why the authority is unresolved. */
|
|
304
|
+
reason: z.string().min(1),
|
|
305
|
+
status: z.literal("unresolved")
|
|
306
|
+
}).strict();
|
|
307
|
+
/** How a gate resolved the review policy it evaluated a candidate under. */
|
|
308
|
+
const policyResolutionSchema = z.discriminatedUnion("status", [authoritativePolicyResolutionSchema, unresolvedPolicyResolutionSchema]);
|
|
309
|
+
//#endregion
|
|
237
310
|
//#region src/packages/review-prompt-sections/schema.ts
|
|
238
|
-
const REVIEW_PROMPT_SECTION_PROVENANCES = [
|
|
311
|
+
const REVIEW_PROMPT_SECTION_PROVENANCES = [
|
|
312
|
+
"coding-standards",
|
|
313
|
+
"prior-review-ledger",
|
|
314
|
+
"issue-review-focus"
|
|
315
|
+
];
|
|
239
316
|
const nonBlankString$1 = z.string().refine((value) => value.trim().length > 0, { message: "must not be blank" });
|
|
240
317
|
const reviewPromptSectionSchema = z.object({
|
|
241
318
|
provenance: z.enum(REVIEW_PROMPT_SECTION_PROVENANCES),
|
|
@@ -617,6 +694,20 @@ z.array(z.object({
|
|
|
617
694
|
}).strict());
|
|
618
695
|
//#endregion
|
|
619
696
|
//#region src/review-ladder.ts
|
|
697
|
+
const LADDER_NEXT_ACTION_KINDS = [
|
|
698
|
+
"run-interior-cycle",
|
|
699
|
+
"advance-to-gate",
|
|
700
|
+
"run-gate-cycle",
|
|
701
|
+
"accept-nonblocking-findings",
|
|
702
|
+
"escalate-to-triage",
|
|
703
|
+
"ready-for-human"
|
|
704
|
+
];
|
|
705
|
+
const LADDER_STAGES = [
|
|
706
|
+
"interior",
|
|
707
|
+
"interior-complete",
|
|
708
|
+
"gate"
|
|
709
|
+
];
|
|
710
|
+
const LADDER_FORCED_TRANSITION_KINDS = ["gate-cap-exhausted", "interior-cap-reached"];
|
|
620
711
|
const ladderCycleRefsFor = (cycles) => {
|
|
621
712
|
let interior = 0;
|
|
622
713
|
let gate = 0;
|
|
@@ -685,7 +776,7 @@ const prReviewResultSchema = z.object({
|
|
|
685
776
|
]),
|
|
686
777
|
producer: nonBlankString.optional(),
|
|
687
778
|
promptSections: reviewPromptSectionsSchema.optional(),
|
|
688
|
-
rung: z.enum(EVIDENCE_REVIEW_RUNGS
|
|
779
|
+
rung: z.enum(EVIDENCE_REVIEW_RUNGS).optional(),
|
|
689
780
|
sessionId: nonBlankString.optional(),
|
|
690
781
|
startedAt: parseableDateString,
|
|
691
782
|
summary: z.string().refine((value) => value.trim().length > 0 && value !== "<one sentence>", { message: "summary must not be blank or a placeholder" }),
|
|
@@ -731,6 +822,7 @@ const prReviewProofSchema = z.object({
|
|
|
731
822
|
ladder: prReviewLadderStateSchema.optional(),
|
|
732
823
|
maxReviewCycles: z.number().int().positive().optional(),
|
|
733
824
|
patchId: z.string().regex(/^[0-9a-f]{40,64}$/u),
|
|
825
|
+
policyResolution: policyResolutionSchema.optional(),
|
|
734
826
|
reviewCycle: z.number().int().positive().optional(),
|
|
735
827
|
reviewRequirement: z.object({
|
|
736
828
|
reason: z.enum(["no-applicable-mode", "faithful-merge"]),
|
|
@@ -751,6 +843,17 @@ const prReviewProofSchema = z.object({
|
|
|
751
843
|
});
|
|
752
844
|
});
|
|
753
845
|
//#endregion
|
|
846
|
+
//#region src/required-check-policy.ts
|
|
847
|
+
const EVIDENCE_CHECK_TYPES = ["review", "verify"];
|
|
848
|
+
const requiredCheckScopeSchema = z.object({ classifications: z.array(z.enum(DIFF_CLASSIFICATIONS)).min(1) }).strict();
|
|
849
|
+
const reviewStatusSchema = z.enum([
|
|
850
|
+
"not-required",
|
|
851
|
+
"current",
|
|
852
|
+
"stale",
|
|
853
|
+
"missing",
|
|
854
|
+
"blocked"
|
|
855
|
+
]);
|
|
856
|
+
//#endregion
|
|
754
857
|
//#region src/review-state.ts
|
|
755
858
|
const reviewStateIssue = (message, field) => [{
|
|
756
859
|
code: "custom",
|
|
@@ -1161,6 +1264,7 @@ const prVerifyProofSchema = z.object({
|
|
|
1161
1264
|
notRequiredCommands: z.array(notRequiredCommandSchema).min(1).optional(),
|
|
1162
1265
|
outcome: z.enum(["aborted", "passed"]).optional(),
|
|
1163
1266
|
patchId: z.string().regex(/^[0-9a-f]{40}$/u).optional(),
|
|
1267
|
+
policyResolution: policyResolutionSchema.optional(),
|
|
1164
1268
|
profilePath: z.string().min(1),
|
|
1165
1269
|
projectKey: z.string().min(1),
|
|
1166
1270
|
repository: z.string().min(1),
|
|
@@ -1228,24 +1332,12 @@ const closeoutArtifactSchema = z.object({
|
|
|
1228
1332
|
}).strict();
|
|
1229
1333
|
//#endregion
|
|
1230
1334
|
//#region src/schemas.ts
|
|
1231
|
-
const
|
|
1232
|
-
const
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
const DIFF_CLASSIFICATIONS = [
|
|
1238
|
-
"docs/process-only",
|
|
1239
|
-
"trivial",
|
|
1240
|
-
"non-trivial"
|
|
1241
|
-
];
|
|
1242
|
-
const REVIEW_STATUS_VALUES = [
|
|
1243
|
-
"not-required",
|
|
1244
|
-
"current",
|
|
1245
|
-
"stale",
|
|
1246
|
-
"missing",
|
|
1247
|
-
"blocked"
|
|
1248
|
-
];
|
|
1335
|
+
const evidenceCheckTypeSchema = z.enum(EVIDENCE_CHECK_TYPES);
|
|
1336
|
+
const evidenceReviewRungSchema = z.enum(EVIDENCE_REVIEW_RUNGS);
|
|
1337
|
+
const diffClassificationSchema = z.enum(DIFF_CLASSIFICATIONS);
|
|
1338
|
+
const ladderStageSchema = z.enum(LADDER_STAGES);
|
|
1339
|
+
const ladderNextActionSchema = z.enum(LADDER_NEXT_ACTION_KINDS);
|
|
1340
|
+
const ladderForcedTransitionSchema = z.enum(LADDER_FORCED_TRANSITION_KINDS);
|
|
1249
1341
|
const followUpActionSchema = z.object({
|
|
1250
1342
|
argv: z.array(z.string()),
|
|
1251
1343
|
command: z.string()
|
|
@@ -1254,7 +1346,7 @@ const EVIDENCE_ENVELOPE_SCHEMA_VERSION = 1;
|
|
|
1254
1346
|
const evidenceShaSchema = z.string().regex(/^[0-9a-f]{7,40}$/u, { message: "must be a 7-40 char lowercase hex git SHA" });
|
|
1255
1347
|
const evidenceEnvelopeSchema = z.object({
|
|
1256
1348
|
check: z.string().min(1),
|
|
1257
|
-
checkType:
|
|
1349
|
+
checkType: evidenceCheckTypeSchema,
|
|
1258
1350
|
findingsPointer: z.string().min(1).optional(),
|
|
1259
1351
|
headSha: evidenceShaSchema,
|
|
1260
1352
|
mergeBaseSha: evidenceShaSchema,
|
|
@@ -1264,7 +1356,7 @@ const evidenceEnvelopeSchema = z.object({
|
|
|
1264
1356
|
policyVersion: z.string().min(1).optional(),
|
|
1265
1357
|
producer: z.string().min(1),
|
|
1266
1358
|
requestId: z.string().min(1).optional(),
|
|
1267
|
-
rung:
|
|
1359
|
+
rung: evidenceReviewRungSchema.optional(),
|
|
1268
1360
|
schemaVersion: z.literal(1),
|
|
1269
1361
|
sessionId: z.string().trim().min(1).optional(),
|
|
1270
1362
|
timestamp: z.iso.datetime().optional()
|
|
@@ -1327,7 +1419,7 @@ const boundaryReviewProofSchema = z.object({
|
|
|
1327
1419
|
}).passthrough(),
|
|
1328
1420
|
outcome: z.enum(["pass", "fail"]),
|
|
1329
1421
|
producer: z.string().min(1),
|
|
1330
|
-
rung:
|
|
1422
|
+
rung: evidenceReviewRungSchema,
|
|
1331
1423
|
schemaVersion: z.literal(1),
|
|
1332
1424
|
sessionId: z.string().min(1).optional(),
|
|
1333
1425
|
specHash: z.object({
|
|
@@ -1348,7 +1440,7 @@ const boundaryCheckProofSchema = z.object({
|
|
|
1348
1440
|
state: z.enum(["merged", "open"]),
|
|
1349
1441
|
wave: z.string().min(1)
|
|
1350
1442
|
})),
|
|
1351
|
-
demandedRung:
|
|
1443
|
+
demandedRung: evidenceReviewRungSchema.optional(),
|
|
1352
1444
|
epicIssue: z.number().int().positive(),
|
|
1353
1445
|
manifestHash: z.object({
|
|
1354
1446
|
algo: z.literal("sha256"),
|
|
@@ -1360,7 +1452,7 @@ const boundaryCheckProofSchema = z.object({
|
|
|
1360
1452
|
commentId: z.union([z.string(), z.number()]).optional(),
|
|
1361
1453
|
commentUrl: z.string().optional(),
|
|
1362
1454
|
producer: z.string().min(1),
|
|
1363
|
-
rung:
|
|
1455
|
+
rung: evidenceReviewRungSchema,
|
|
1364
1456
|
sessionId: z.string().min(1).optional(),
|
|
1365
1457
|
specHash: z.object({
|
|
1366
1458
|
algo: z.literal("sha256"),
|
|
@@ -1375,7 +1467,6 @@ const boundaryCheckProofSchema = z.object({
|
|
|
1375
1467
|
}).optional(),
|
|
1376
1468
|
status: z.enum(["ready", "blocked"])
|
|
1377
1469
|
});
|
|
1378
|
-
const requiredCheckScopeSchema = z.object({ classifications: z.array(z.enum(DIFF_CLASSIFICATIONS)).min(1) }).strict();
|
|
1379
1470
|
const readinessRepairSchema = z.object({
|
|
1380
1471
|
action: z.string().min(1),
|
|
1381
1472
|
code: z.enum([
|
|
@@ -1389,7 +1480,7 @@ const reviewStateSchema = z.object({
|
|
|
1389
1480
|
required: z.boolean(),
|
|
1390
1481
|
reviewedHeadSha: z.string().optional(),
|
|
1391
1482
|
reviewedPatchId: z.string().optional(),
|
|
1392
|
-
status:
|
|
1483
|
+
status: reviewStatusSchema
|
|
1393
1484
|
}).strict().superRefine((state, context) => {
|
|
1394
1485
|
for (const issue of reviewStateIssues(state)) context.addIssue(issue);
|
|
1395
1486
|
});
|
|
@@ -1410,9 +1501,9 @@ const historicalHandledHumanCommentSchema = z.object({
|
|
|
1410
1501
|
const managedReadinessLedgerSchema = z.object({
|
|
1411
1502
|
baseSha: z.string().regex(/^[0-9a-f]{40}$/u),
|
|
1412
1503
|
blockingReasons: z.array(z.string()),
|
|
1413
|
-
classification:
|
|
1504
|
+
classification: diffClassificationSchema,
|
|
1414
1505
|
externalChecks: z.array(z.object({
|
|
1415
|
-
checkType:
|
|
1506
|
+
checkType: evidenceCheckTypeSchema,
|
|
1416
1507
|
name: z.string().min(1),
|
|
1417
1508
|
reason: z.string().optional(),
|
|
1418
1509
|
scope: requiredCheckScopeSchema.optional(),
|
|
@@ -1485,25 +1576,9 @@ const managedReadinessLedgerSchema = z.object({
|
|
|
1485
1576
|
gate: z.number().int().nonnegative(),
|
|
1486
1577
|
interior: z.number().int().nonnegative()
|
|
1487
1578
|
}),
|
|
1488
|
-
forcedTransition:
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
"interior-takeover"
|
|
1492
|
-
]).optional(),
|
|
1493
|
-
nextAction: z.enum([
|
|
1494
|
-
"run-interior-cycle",
|
|
1495
|
-
"advance-to-gate",
|
|
1496
|
-
"run-gate-cycle",
|
|
1497
|
-
"accept-nonblocking-findings",
|
|
1498
|
-
"escalate-to-triage",
|
|
1499
|
-
"ready-for-human"
|
|
1500
|
-
]),
|
|
1501
|
-
stage: z.enum([
|
|
1502
|
-
"interior",
|
|
1503
|
-
"interior-takeover",
|
|
1504
|
-
"interior-complete",
|
|
1505
|
-
"gate"
|
|
1506
|
-
])
|
|
1579
|
+
forcedTransition: ladderForcedTransitionSchema.optional(),
|
|
1580
|
+
nextAction: ladderNextActionSchema,
|
|
1581
|
+
stage: ladderStageSchema
|
|
1507
1582
|
}).optional(),
|
|
1508
1583
|
reviewRuns: z.array(prReviewResultSchema).optional(),
|
|
1509
1584
|
reviewTerminalState: z.enum([
|
|
@@ -1580,6 +1655,7 @@ const prReadyProofSchema = z.object({
|
|
|
1580
1655
|
humanBlockingReasons: z.array(z.string()).default([]),
|
|
1581
1656
|
ledger: managedReadinessLedgerSchema,
|
|
1582
1657
|
notices: z.array(z.string().min(1)).optional(),
|
|
1658
|
+
policyResolution: policyResolutionSchema.optional(),
|
|
1583
1659
|
profileBlobSha: z.string().regex(/^[0-9a-f]{40}$/u).optional(),
|
|
1584
1660
|
profilePath: z.string().min(1).optional(),
|
|
1585
1661
|
repairs: z.array(readinessRepairSchema).default([]),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patronage/software-factory",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.25",
|
|
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.
|
|
40
|
+
"@patronage/factory-ci": "1.0.0-alpha.25"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/node": "24.13.3",
|