@patronage/software-factory 1.0.0-alpha.23 → 1.0.0-alpha.24
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 +262 -182
- package/dist/index.js +828 -324
- package/dist/schemas.d.ts +73 -36
- package/dist/schemas.js +111 -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
|
}>;
|
|
@@ -225,21 +227,38 @@ declare const boundaryReviewProofBaseSchema: z.ZodObject<{
|
|
|
225
227
|
}, z.core.$loose>;
|
|
226
228
|
type BoundaryReviewProof = z.infer<typeof boundaryReviewProofBaseSchema>;
|
|
227
229
|
//#endregion
|
|
228
|
-
//#region src/
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
230
|
+
//#region src/policy-resolution.d.ts
|
|
231
|
+
/** How a gate resolved the review policy it evaluated a candidate under. */
|
|
232
|
+
declare const policyResolutionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
233
|
+
basePolicyDigest: z.ZodString;
|
|
234
|
+
baseRefName: z.ZodString;
|
|
235
|
+
candidatePolicyDigest: z.ZodString;
|
|
236
|
+
effectiveDigest: z.ZodString;
|
|
237
|
+
policyBaseSha: z.ZodString;
|
|
238
|
+
reviewPolicyChanged: z.ZodBoolean;
|
|
239
|
+
status: z.ZodLiteral<"authoritative">;
|
|
240
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
241
|
+
baseRefName: z.ZodString;
|
|
242
|
+
reason: z.ZodString;
|
|
243
|
+
status: z.ZodLiteral<"unresolved">;
|
|
244
|
+
}, z.core.$strict>], "status">;
|
|
245
|
+
type PolicyResolution = z.infer<typeof policyResolutionSchema>;
|
|
246
|
+
//#endregion
|
|
247
|
+
//#region src/catch-up-recognition-record.d.ts
|
|
248
|
+
interface CatchUpRecognition {
|
|
249
|
+
/** The ref the candidate targets, as the recognizing command resolved it. */
|
|
250
|
+
baseRef: string;
|
|
251
|
+
/** The live target tip at recognition time; the head's first parent. */
|
|
252
|
+
baseTipSha: string;
|
|
253
|
+
/** The head's second parent: the admitted base-side content merged in. */
|
|
254
|
+
mergedParentSha: string;
|
|
238
255
|
/**
|
|
239
|
-
*
|
|
240
|
-
*
|
|
256
|
+
* The tree `git merge-tree --write-tree` produced for the two parents. It
|
|
257
|
+
* equals the head's own tree; that equality is the faithfulness proof.
|
|
241
258
|
*/
|
|
242
|
-
|
|
259
|
+
mergedTreeSha: string;
|
|
260
|
+
/** The ref that proves the second parent is admitted content. */
|
|
261
|
+
upstreamRef: string;
|
|
243
262
|
}
|
|
244
263
|
//#endregion
|
|
245
264
|
//#region src/diff-classification.d.ts
|
|
@@ -274,6 +293,23 @@ declare const impactStampSchema: z.ZodObject<{
|
|
|
274
293
|
}, z.core.$strip>;
|
|
275
294
|
type ImpactStamp = z.infer<typeof impactStampSchema>;
|
|
276
295
|
//#endregion
|
|
296
|
+
//#region src/follow-up.d.ts
|
|
297
|
+
interface FollowUpAction {
|
|
298
|
+
/**
|
|
299
|
+
* Machine-safe argv-style array for the obvious next action, e.g.
|
|
300
|
+
* ["gh","pr","merge","513","--squash"]. Same shape and field name that
|
|
301
|
+
* `factory:delegate --print` emits, so an orchestrating agent can spawn the
|
|
302
|
+
* next command without reconstructing a shell string. argv[0] is the
|
|
303
|
+
* executable; the rest are literal, already-split arguments.
|
|
304
|
+
*/
|
|
305
|
+
argv: string[];
|
|
306
|
+
/**
|
|
307
|
+
* Human-readable rendering of {@link argv} for logs and operators. Additive
|
|
308
|
+
* to argv, never a substitute for it — argv is the source of truth.
|
|
309
|
+
*/
|
|
310
|
+
command: string;
|
|
311
|
+
}
|
|
312
|
+
//#endregion
|
|
277
313
|
//#region src/pr-verify-mode.d.ts
|
|
278
314
|
/**
|
|
279
315
|
* The verification mode `pr:verify` resolved for a run.
|
|
@@ -388,12 +424,12 @@ declare const managedReadinessLedgerSchema: z.ZodObject<{
|
|
|
388
424
|
"interior-cap-reached": "interior-cap-reached";
|
|
389
425
|
}>>;
|
|
390
426
|
nextAction: z.ZodEnum<{
|
|
391
|
-
"run-interior-cycle": "run-interior-cycle";
|
|
392
|
-
"advance-to-gate": "advance-to-gate";
|
|
393
427
|
"run-gate-cycle": "run-gate-cycle";
|
|
394
428
|
"accept-nonblocking-findings": "accept-nonblocking-findings";
|
|
395
429
|
"escalate-to-triage": "escalate-to-triage";
|
|
396
430
|
"ready-for-human": "ready-for-human";
|
|
431
|
+
"advance-to-gate": "advance-to-gate";
|
|
432
|
+
"run-interior-cycle": "run-interior-cycle";
|
|
397
433
|
}>;
|
|
398
434
|
stage: z.ZodEnum<{
|
|
399
435
|
gate: "gate";
|
|
@@ -461,23 +497,6 @@ type ReadinessRepair = z.infer<typeof readinessRepairSchema>;
|
|
|
461
497
|
type ReadinessStatus = "ready" | "blocked";
|
|
462
498
|
type ManagedReadinessLedger = z.infer<typeof managedReadinessLedgerSchema>;
|
|
463
499
|
//#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
500
|
//#region src/pr-verify-proof-contract.d.ts
|
|
482
501
|
declare const SUPPORTED_PR_VERIFY_SCHEMA_VERSIONS: readonly [1, 2, 3, 4];
|
|
483
502
|
type PrVerifySchemaVersion = (typeof SUPPORTED_PR_VERIFY_SCHEMA_VERSIONS)[number];
|
|
@@ -713,6 +732,13 @@ interface PrReadyProof {
|
|
|
713
732
|
* waived demand reads to a human. Absent when there are none.
|
|
714
733
|
*/
|
|
715
734
|
notices?: string[];
|
|
735
|
+
/**
|
|
736
|
+
* The policy identity readiness resolved review demand under (#922): the
|
|
737
|
+
* base ref, its live tip, and the digests of the base, candidate, and merged
|
|
738
|
+
* review policies. Optional on the wire and additive — this is a new record
|
|
739
|
+
* on an unchanged contract, so no schema version moves.
|
|
740
|
+
*/
|
|
741
|
+
policyResolution?: PolicyResolution;
|
|
716
742
|
/** Committed profile blob evaluated by readiness. Required for merge. */
|
|
717
743
|
profileBlobSha?: string;
|
|
718
744
|
/** Checkout-relative committed profile path evaluated by readiness. */
|
|
@@ -1086,20 +1112,18 @@ declare const prReadyProofSchema: z.ZodObject<{
|
|
|
1086
1112
|
forcedTransition: z.ZodOptional<z.ZodEnum<{
|
|
1087
1113
|
"gate-cap-exhausted": "gate-cap-exhausted";
|
|
1088
1114
|
"interior-cap-reached": "interior-cap-reached";
|
|
1089
|
-
"interior-takeover": "interior-takeover";
|
|
1090
1115
|
}>>;
|
|
1091
1116
|
nextAction: z.ZodEnum<{
|
|
1092
|
-
"run-interior-cycle": "run-interior-cycle";
|
|
1093
|
-
"advance-to-gate": "advance-to-gate";
|
|
1094
1117
|
"run-gate-cycle": "run-gate-cycle";
|
|
1095
1118
|
"accept-nonblocking-findings": "accept-nonblocking-findings";
|
|
1096
1119
|
"escalate-to-triage": "escalate-to-triage";
|
|
1097
1120
|
"ready-for-human": "ready-for-human";
|
|
1121
|
+
"advance-to-gate": "advance-to-gate";
|
|
1122
|
+
"run-interior-cycle": "run-interior-cycle";
|
|
1098
1123
|
}>;
|
|
1099
1124
|
stage: z.ZodEnum<{
|
|
1100
1125
|
gate: "gate";
|
|
1101
1126
|
interior: "interior";
|
|
1102
|
-
"interior-takeover": "interior-takeover";
|
|
1103
1127
|
"interior-complete": "interior-complete";
|
|
1104
1128
|
}>;
|
|
1105
1129
|
}, z.core.$strip>>;
|
|
@@ -1166,6 +1190,19 @@ declare const prReadyProofSchema: z.ZodObject<{
|
|
|
1166
1190
|
}, z.core.$strict>], "prVerify">;
|
|
1167
1191
|
}, z.core.$strip>;
|
|
1168
1192
|
notices: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1193
|
+
policyResolution: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
1194
|
+
basePolicyDigest: z.ZodString;
|
|
1195
|
+
baseRefName: z.ZodString;
|
|
1196
|
+
candidatePolicyDigest: z.ZodString;
|
|
1197
|
+
effectiveDigest: z.ZodString;
|
|
1198
|
+
policyBaseSha: z.ZodString;
|
|
1199
|
+
reviewPolicyChanged: z.ZodBoolean;
|
|
1200
|
+
status: z.ZodLiteral<"authoritative">;
|
|
1201
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1202
|
+
baseRefName: z.ZodString;
|
|
1203
|
+
reason: z.ZodString;
|
|
1204
|
+
status: z.ZodLiteral<"unresolved">;
|
|
1205
|
+
}, z.core.$strict>], "status">>;
|
|
1169
1206
|
profileBlobSha: z.ZodOptional<z.ZodString>;
|
|
1170
1207
|
profilePath: z.ZodOptional<z.ZodString>;
|
|
1171
1208
|
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. */
|
|
@@ -116,7 +116,7 @@ const qualifierIsMintable = (family, qualifier) => {
|
|
|
116
116
|
if (!QUALIFIER_PATTERN.test(qualifier)) return false;
|
|
117
117
|
const decoded = decodeQualifier(qualifier);
|
|
118
118
|
if (decoded === void 0 || demandQualifier(decoded) !== qualifier) return false;
|
|
119
|
-
if (family === "review-rung") return EVIDENCE_REVIEW_RUNGS
|
|
119
|
+
if (family === "review-rung") return EVIDENCE_REVIEW_RUNGS.includes(decoded);
|
|
120
120
|
if (family === "review-mode") return REVIEW_MODE_DEMAND_VALUES.includes(decoded);
|
|
121
121
|
return true;
|
|
122
122
|
};
|
|
@@ -234,8 +234,71 @@ const waivedDemandSchema = z.object({
|
|
|
234
234
|
unmetReasons: z.array(z.string().min(1)).min(1)
|
|
235
235
|
});
|
|
236
236
|
//#endregion
|
|
237
|
+
//#region src/diff-classification.ts
|
|
238
|
+
const DIFF_CLASSIFICATIONS = [
|
|
239
|
+
"docs/process-only",
|
|
240
|
+
"trivial",
|
|
241
|
+
"non-trivial"
|
|
242
|
+
];
|
|
243
|
+
//#endregion
|
|
244
|
+
//#region src/policy-resolution.ts
|
|
245
|
+
const COMMIT_SHA_PATTERN = /^[0-9a-f]{40}$/u;
|
|
246
|
+
const digestSchema = z.string().regex(/^[0-9a-f]{64}$/u);
|
|
247
|
+
/**
|
|
248
|
+
* The authority resolved: the live tip of the PR's own base ref served a
|
|
249
|
+
* parseable profile, and demand was resolved from the union of that policy and
|
|
250
|
+
* the candidate's.
|
|
251
|
+
*
|
|
252
|
+
* Every identity field is REQUIRED. A cross-stage reader compares these digests
|
|
253
|
+
* to decide whether two stages judged the same candidate under the same policy;
|
|
254
|
+
* an `authoritative` record with a digest missing would read to that reader as
|
|
255
|
+
* "nothing disagrees", which is a silent downgrade of exactly the demand this
|
|
256
|
+
* record exists to protect. `reason` is forbidden here — a resolved authority
|
|
257
|
+
* has nothing to explain.
|
|
258
|
+
*/
|
|
259
|
+
const authoritativePolicyResolutionSchema = z.object({
|
|
260
|
+
/** sha256 of the canonical base `review` subtree. */
|
|
261
|
+
basePolicyDigest: digestSchema,
|
|
262
|
+
/** The PR's own base ref, whose live tip is the authority. */
|
|
263
|
+
baseRefName: z.string().min(1),
|
|
264
|
+
/** sha256 of the canonical candidate `review` subtree. */
|
|
265
|
+
candidatePolicyDigest: digestSchema,
|
|
266
|
+
/** sha256 of the merged (base ∪ candidate) protected-path set. */
|
|
267
|
+
effectiveDigest: digestSchema,
|
|
268
|
+
/** The base-ref tip the base policy was read at. */
|
|
269
|
+
policyBaseSha: z.string().regex(COMMIT_SHA_PATTERN),
|
|
270
|
+
/**
|
|
271
|
+
* Whether the candidate's `review` subtree differs from the base's. The
|
|
272
|
+
* digests prove which policies were read; this says whether they agreed,
|
|
273
|
+
* which is the fact that explains a demand the candidate's own profile
|
|
274
|
+
* would not have produced.
|
|
275
|
+
*/
|
|
276
|
+
reviewPolicyChanged: z.boolean(),
|
|
277
|
+
status: z.literal("authoritative")
|
|
278
|
+
}).strict();
|
|
279
|
+
/**
|
|
280
|
+
* The authority could not be read, and `reason` says why — required, because an
|
|
281
|
+
* unresolved record with no reason is an unactionable refusal. `pr:ready`
|
|
282
|
+
* refuses before it writes a proof, so a Slice A ready proof never carries one;
|
|
283
|
+
* this member is the recorded form of that refusal for the stages that carry it
|
|
284
|
+
* forward.
|
|
285
|
+
*/
|
|
286
|
+
const unresolvedPolicyResolutionSchema = z.object({
|
|
287
|
+
/** The base ref whose policy could not be read. */
|
|
288
|
+
baseRefName: z.string().min(1),
|
|
289
|
+
/** Why the authority is unresolved. */
|
|
290
|
+
reason: z.string().min(1),
|
|
291
|
+
status: z.literal("unresolved")
|
|
292
|
+
}).strict();
|
|
293
|
+
/** How a gate resolved the review policy it evaluated a candidate under. */
|
|
294
|
+
const policyResolutionSchema = z.discriminatedUnion("status", [authoritativePolicyResolutionSchema, unresolvedPolicyResolutionSchema]);
|
|
295
|
+
//#endregion
|
|
237
296
|
//#region src/packages/review-prompt-sections/schema.ts
|
|
238
|
-
const REVIEW_PROMPT_SECTION_PROVENANCES = [
|
|
297
|
+
const REVIEW_PROMPT_SECTION_PROVENANCES = [
|
|
298
|
+
"coding-standards",
|
|
299
|
+
"prior-review-ledger",
|
|
300
|
+
"issue-review-focus"
|
|
301
|
+
];
|
|
239
302
|
const nonBlankString$1 = z.string().refine((value) => value.trim().length > 0, { message: "must not be blank" });
|
|
240
303
|
const reviewPromptSectionSchema = z.object({
|
|
241
304
|
provenance: z.enum(REVIEW_PROMPT_SECTION_PROVENANCES),
|
|
@@ -617,6 +680,20 @@ z.array(z.object({
|
|
|
617
680
|
}).strict());
|
|
618
681
|
//#endregion
|
|
619
682
|
//#region src/review-ladder.ts
|
|
683
|
+
const LADDER_NEXT_ACTION_KINDS = [
|
|
684
|
+
"run-interior-cycle",
|
|
685
|
+
"advance-to-gate",
|
|
686
|
+
"run-gate-cycle",
|
|
687
|
+
"accept-nonblocking-findings",
|
|
688
|
+
"escalate-to-triage",
|
|
689
|
+
"ready-for-human"
|
|
690
|
+
];
|
|
691
|
+
const LADDER_STAGES = [
|
|
692
|
+
"interior",
|
|
693
|
+
"interior-complete",
|
|
694
|
+
"gate"
|
|
695
|
+
];
|
|
696
|
+
const LADDER_FORCED_TRANSITION_KINDS = ["gate-cap-exhausted", "interior-cap-reached"];
|
|
620
697
|
const ladderCycleRefsFor = (cycles) => {
|
|
621
698
|
let interior = 0;
|
|
622
699
|
let gate = 0;
|
|
@@ -685,7 +762,7 @@ const prReviewResultSchema = z.object({
|
|
|
685
762
|
]),
|
|
686
763
|
producer: nonBlankString.optional(),
|
|
687
764
|
promptSections: reviewPromptSectionsSchema.optional(),
|
|
688
|
-
rung: z.enum(EVIDENCE_REVIEW_RUNGS
|
|
765
|
+
rung: z.enum(EVIDENCE_REVIEW_RUNGS).optional(),
|
|
689
766
|
sessionId: nonBlankString.optional(),
|
|
690
767
|
startedAt: parseableDateString,
|
|
691
768
|
summary: z.string().refine((value) => value.trim().length > 0 && value !== "<one sentence>", { message: "summary must not be blank or a placeholder" }),
|
|
@@ -751,6 +828,17 @@ const prReviewProofSchema = z.object({
|
|
|
751
828
|
});
|
|
752
829
|
});
|
|
753
830
|
//#endregion
|
|
831
|
+
//#region src/required-check-policy.ts
|
|
832
|
+
const EVIDENCE_CHECK_TYPES = ["review", "verify"];
|
|
833
|
+
const requiredCheckScopeSchema = z.object({ classifications: z.array(z.enum(DIFF_CLASSIFICATIONS)).min(1) }).strict();
|
|
834
|
+
const reviewStatusSchema = z.enum([
|
|
835
|
+
"not-required",
|
|
836
|
+
"current",
|
|
837
|
+
"stale",
|
|
838
|
+
"missing",
|
|
839
|
+
"blocked"
|
|
840
|
+
]);
|
|
841
|
+
//#endregion
|
|
754
842
|
//#region src/review-state.ts
|
|
755
843
|
const reviewStateIssue = (message, field) => [{
|
|
756
844
|
code: "custom",
|
|
@@ -1228,24 +1316,12 @@ const closeoutArtifactSchema = z.object({
|
|
|
1228
1316
|
}).strict();
|
|
1229
1317
|
//#endregion
|
|
1230
1318
|
//#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
|
-
];
|
|
1319
|
+
const evidenceCheckTypeSchema = z.enum(EVIDENCE_CHECK_TYPES);
|
|
1320
|
+
const evidenceReviewRungSchema = z.enum(EVIDENCE_REVIEW_RUNGS);
|
|
1321
|
+
const diffClassificationSchema = z.enum(DIFF_CLASSIFICATIONS);
|
|
1322
|
+
const ladderStageSchema = z.enum(LADDER_STAGES);
|
|
1323
|
+
const ladderNextActionSchema = z.enum(LADDER_NEXT_ACTION_KINDS);
|
|
1324
|
+
const ladderForcedTransitionSchema = z.enum(LADDER_FORCED_TRANSITION_KINDS);
|
|
1249
1325
|
const followUpActionSchema = z.object({
|
|
1250
1326
|
argv: z.array(z.string()),
|
|
1251
1327
|
command: z.string()
|
|
@@ -1254,7 +1330,7 @@ const EVIDENCE_ENVELOPE_SCHEMA_VERSION = 1;
|
|
|
1254
1330
|
const evidenceShaSchema = z.string().regex(/^[0-9a-f]{7,40}$/u, { message: "must be a 7-40 char lowercase hex git SHA" });
|
|
1255
1331
|
const evidenceEnvelopeSchema = z.object({
|
|
1256
1332
|
check: z.string().min(1),
|
|
1257
|
-
checkType:
|
|
1333
|
+
checkType: evidenceCheckTypeSchema,
|
|
1258
1334
|
findingsPointer: z.string().min(1).optional(),
|
|
1259
1335
|
headSha: evidenceShaSchema,
|
|
1260
1336
|
mergeBaseSha: evidenceShaSchema,
|
|
@@ -1264,7 +1340,7 @@ const evidenceEnvelopeSchema = z.object({
|
|
|
1264
1340
|
policyVersion: z.string().min(1).optional(),
|
|
1265
1341
|
producer: z.string().min(1),
|
|
1266
1342
|
requestId: z.string().min(1).optional(),
|
|
1267
|
-
rung:
|
|
1343
|
+
rung: evidenceReviewRungSchema.optional(),
|
|
1268
1344
|
schemaVersion: z.literal(1),
|
|
1269
1345
|
sessionId: z.string().trim().min(1).optional(),
|
|
1270
1346
|
timestamp: z.iso.datetime().optional()
|
|
@@ -1327,7 +1403,7 @@ const boundaryReviewProofSchema = z.object({
|
|
|
1327
1403
|
}).passthrough(),
|
|
1328
1404
|
outcome: z.enum(["pass", "fail"]),
|
|
1329
1405
|
producer: z.string().min(1),
|
|
1330
|
-
rung:
|
|
1406
|
+
rung: evidenceReviewRungSchema,
|
|
1331
1407
|
schemaVersion: z.literal(1),
|
|
1332
1408
|
sessionId: z.string().min(1).optional(),
|
|
1333
1409
|
specHash: z.object({
|
|
@@ -1348,7 +1424,7 @@ const boundaryCheckProofSchema = z.object({
|
|
|
1348
1424
|
state: z.enum(["merged", "open"]),
|
|
1349
1425
|
wave: z.string().min(1)
|
|
1350
1426
|
})),
|
|
1351
|
-
demandedRung:
|
|
1427
|
+
demandedRung: evidenceReviewRungSchema.optional(),
|
|
1352
1428
|
epicIssue: z.number().int().positive(),
|
|
1353
1429
|
manifestHash: z.object({
|
|
1354
1430
|
algo: z.literal("sha256"),
|
|
@@ -1360,7 +1436,7 @@ const boundaryCheckProofSchema = z.object({
|
|
|
1360
1436
|
commentId: z.union([z.string(), z.number()]).optional(),
|
|
1361
1437
|
commentUrl: z.string().optional(),
|
|
1362
1438
|
producer: z.string().min(1),
|
|
1363
|
-
rung:
|
|
1439
|
+
rung: evidenceReviewRungSchema,
|
|
1364
1440
|
sessionId: z.string().min(1).optional(),
|
|
1365
1441
|
specHash: z.object({
|
|
1366
1442
|
algo: z.literal("sha256"),
|
|
@@ -1375,7 +1451,6 @@ const boundaryCheckProofSchema = z.object({
|
|
|
1375
1451
|
}).optional(),
|
|
1376
1452
|
status: z.enum(["ready", "blocked"])
|
|
1377
1453
|
});
|
|
1378
|
-
const requiredCheckScopeSchema = z.object({ classifications: z.array(z.enum(DIFF_CLASSIFICATIONS)).min(1) }).strict();
|
|
1379
1454
|
const readinessRepairSchema = z.object({
|
|
1380
1455
|
action: z.string().min(1),
|
|
1381
1456
|
code: z.enum([
|
|
@@ -1389,7 +1464,7 @@ const reviewStateSchema = z.object({
|
|
|
1389
1464
|
required: z.boolean(),
|
|
1390
1465
|
reviewedHeadSha: z.string().optional(),
|
|
1391
1466
|
reviewedPatchId: z.string().optional(),
|
|
1392
|
-
status:
|
|
1467
|
+
status: reviewStatusSchema
|
|
1393
1468
|
}).strict().superRefine((state, context) => {
|
|
1394
1469
|
for (const issue of reviewStateIssues(state)) context.addIssue(issue);
|
|
1395
1470
|
});
|
|
@@ -1410,9 +1485,9 @@ const historicalHandledHumanCommentSchema = z.object({
|
|
|
1410
1485
|
const managedReadinessLedgerSchema = z.object({
|
|
1411
1486
|
baseSha: z.string().regex(/^[0-9a-f]{40}$/u),
|
|
1412
1487
|
blockingReasons: z.array(z.string()),
|
|
1413
|
-
classification:
|
|
1488
|
+
classification: diffClassificationSchema,
|
|
1414
1489
|
externalChecks: z.array(z.object({
|
|
1415
|
-
checkType:
|
|
1490
|
+
checkType: evidenceCheckTypeSchema,
|
|
1416
1491
|
name: z.string().min(1),
|
|
1417
1492
|
reason: z.string().optional(),
|
|
1418
1493
|
scope: requiredCheckScopeSchema.optional(),
|
|
@@ -1485,25 +1560,9 @@ const managedReadinessLedgerSchema = z.object({
|
|
|
1485
1560
|
gate: z.number().int().nonnegative(),
|
|
1486
1561
|
interior: z.number().int().nonnegative()
|
|
1487
1562
|
}),
|
|
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
|
-
])
|
|
1563
|
+
forcedTransition: ladderForcedTransitionSchema.optional(),
|
|
1564
|
+
nextAction: ladderNextActionSchema,
|
|
1565
|
+
stage: ladderStageSchema
|
|
1507
1566
|
}).optional(),
|
|
1508
1567
|
reviewRuns: z.array(prReviewResultSchema).optional(),
|
|
1509
1568
|
reviewTerminalState: z.enum([
|
|
@@ -1580,6 +1639,7 @@ const prReadyProofSchema = z.object({
|
|
|
1580
1639
|
humanBlockingReasons: z.array(z.string()).default([]),
|
|
1581
1640
|
ledger: managedReadinessLedgerSchema,
|
|
1582
1641
|
notices: z.array(z.string().min(1)).optional(),
|
|
1642
|
+
policyResolution: policyResolutionSchema.optional(),
|
|
1583
1643
|
profileBlobSha: z.string().regex(/^[0-9a-f]{40}$/u).optional(),
|
|
1584
1644
|
profilePath: z.string().min(1).optional(),
|
|
1585
1645
|
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.24",
|
|
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.24"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/node": "24.13.3",
|