@patronage/software-factory 1.0.0-alpha.26 → 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/cli.js +12 -0
- package/dist/index.d.ts +115 -55
- package/dist/index.js +685 -194
- package/dist/schemas.d.ts +17 -12
- package/dist/schemas.js +19 -53
- package/package.json +5 -5
package/dist/schemas.d.ts
CHANGED
|
@@ -506,7 +506,15 @@ type ReadinessStatus = "ready" | "blocked";
|
|
|
506
506
|
type ManagedReadinessLedger = z.infer<typeof managedReadinessLedgerSchema>;
|
|
507
507
|
//#endregion
|
|
508
508
|
//#region src/pr-verify-proof-contract.d.ts
|
|
509
|
-
|
|
509
|
+
/**
|
|
510
|
+
* The pr:verify proof versions a reader accepts: the current one only (#920
|
|
511
|
+
* item 1). #917 narrowed the pr:ready reader the same way. A pr:verify proof
|
|
512
|
+
* is per-candidate and short-lived — it is rewritten on every head — so no
|
|
513
|
+
* stored v1–v3 proof can outlive the release that drops it. Pre-1.0 posture
|
|
514
|
+
* applies: one current contract, no compat reader. A consumer on an older
|
|
515
|
+
* factory must adopt this release before HQ ingests its pr:verify proofs.
|
|
516
|
+
*/
|
|
517
|
+
declare const SUPPORTED_PR_VERIFY_SCHEMA_VERSIONS: readonly [4];
|
|
510
518
|
type PrVerifySchemaVersion = (typeof SUPPORTED_PR_VERIFY_SCHEMA_VERSIONS)[number];
|
|
511
519
|
interface PrVerifyCommandResult {
|
|
512
520
|
command: string;
|
|
@@ -517,11 +525,11 @@ interface PrVerifyCommandResult {
|
|
|
517
525
|
* mapping: a `notRequiredCommands` entry must name the target recorded HERE
|
|
518
526
|
* for the same command, so a withholding cannot point at whichever released
|
|
519
527
|
* target happens to be convenient. Absent for a command the profile does
|
|
520
|
-
* not scope
|
|
528
|
+
* not scope.
|
|
521
529
|
*/
|
|
522
530
|
impactTarget?: string;
|
|
523
531
|
name: string;
|
|
524
|
-
scope: "
|
|
532
|
+
scope: "docs-only" | "trivial" | "full";
|
|
525
533
|
}
|
|
526
534
|
interface PrVerifyExecutedCommand {
|
|
527
535
|
command: string;
|
|
@@ -532,7 +540,7 @@ interface PrVerifyExecutedCommand {
|
|
|
532
540
|
durationMs: number;
|
|
533
541
|
exitCode: number;
|
|
534
542
|
name: string;
|
|
535
|
-
scope: "
|
|
543
|
+
scope: "docs-only" | "trivial" | "full";
|
|
536
544
|
}
|
|
537
545
|
/**
|
|
538
546
|
* Epic #550 wave 3 (#430): a verification command the impact stamp proved this
|
|
@@ -551,8 +559,7 @@ interface PrVerifyNotRequiredCommand {
|
|
|
551
559
|
}
|
|
552
560
|
/**
|
|
553
561
|
* Epic #758 (#762): a consumer package a stamp-scoped selection skipped, and
|
|
554
|
-
* why. Bound to the proof's stamp identity —
|
|
555
|
-
* window that can carry `impactStamp`) and refused when the proof records no
|
|
562
|
+
* why. Bound to the proof's stamp identity — refused when the proof records no
|
|
556
563
|
* stamp. The factory does not write this list; consumers do.
|
|
557
564
|
*/
|
|
558
565
|
interface PrVerifyNotDemandedRecord {
|
|
@@ -561,7 +568,7 @@ interface PrVerifyNotDemandedRecord {
|
|
|
561
568
|
}
|
|
562
569
|
interface PrVerifyProof {
|
|
563
570
|
schemaVersion: PrVerifySchemaVersion;
|
|
564
|
-
authoringSession
|
|
571
|
+
authoringSession: string;
|
|
565
572
|
base: string;
|
|
566
573
|
baselineFullProofs?: {
|
|
567
574
|
base: string;
|
|
@@ -604,7 +611,7 @@ interface PrVerifyProof {
|
|
|
604
611
|
verificationCommands: PrVerifyCommandResult[];
|
|
605
612
|
}
|
|
606
613
|
declare const prVerifyProofSchema: z.ZodObject<{
|
|
607
|
-
authoringSession: z.
|
|
614
|
+
authoringSession: z.ZodString;
|
|
608
615
|
base: z.ZodString;
|
|
609
616
|
baselineFullProofs: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
610
617
|
base: z.ZodString;
|
|
@@ -636,7 +643,6 @@ declare const prVerifyProofSchema: z.ZodObject<{
|
|
|
636
643
|
name: z.ZodString;
|
|
637
644
|
scope: z.ZodEnum<{
|
|
638
645
|
trivial: "trivial";
|
|
639
|
-
always: "always";
|
|
640
646
|
"docs-only": "docs-only";
|
|
641
647
|
full: "full";
|
|
642
648
|
}>;
|
|
@@ -697,7 +703,7 @@ declare const prVerifyProofSchema: z.ZodObject<{
|
|
|
697
703
|
profilePath: z.ZodString;
|
|
698
704
|
projectKey: z.ZodString;
|
|
699
705
|
repository: z.ZodString;
|
|
700
|
-
schemaVersion: z.
|
|
706
|
+
schemaVersion: z.ZodLiteral<4>;
|
|
701
707
|
startedAt: z.ZodISODateTime;
|
|
702
708
|
verificationCommands: z.ZodArray<z.ZodObject<{
|
|
703
709
|
command: z.ZodString;
|
|
@@ -706,7 +712,6 @@ declare const prVerifyProofSchema: z.ZodObject<{
|
|
|
706
712
|
name: z.ZodString;
|
|
707
713
|
scope: z.ZodEnum<{
|
|
708
714
|
trivial: "trivial";
|
|
709
|
-
always: "always";
|
|
710
715
|
"docs-only": "docs-only";
|
|
711
716
|
full: "full";
|
|
712
717
|
}>;
|
|
@@ -848,8 +853,8 @@ declare const closeoutArtifactSchema: z.ZodObject<{
|
|
|
848
853
|
}, z.core.$strict>;
|
|
849
854
|
unit: z.ZodEnum<{
|
|
850
855
|
boolean: "boolean";
|
|
851
|
-
count: "count";
|
|
852
856
|
text: "text";
|
|
857
|
+
count: "count";
|
|
853
858
|
tokens: "tokens";
|
|
854
859
|
usd: "usd";
|
|
855
860
|
}>;
|
package/dist/schemas.js
CHANGED
|
@@ -1014,9 +1014,7 @@ z.looseObject({
|
|
|
1014
1014
|
* skip this epic forbids.
|
|
1015
1015
|
*
|
|
1016
1016
|
* Rule 4 is scoped to `outcome: "passed"` because an ABORTED proof legitimately
|
|
1017
|
-
* records partial execution — the run stopped at the failing command.
|
|
1018
|
-
* also scoped to schemaVersion >= 4: `executedCommands` postdates v1–v3, so a
|
|
1019
|
-
* legacy proof that never recorded it is not making a false completeness claim.
|
|
1017
|
+
* records partial execution — the run stopped at the failing command.
|
|
1020
1018
|
*
|
|
1021
1019
|
* The check is one-directional on purpose. Every SELECTED command must be
|
|
1022
1020
|
* accounted for, but `executedCommands` may legitimately carry MORE than the
|
|
@@ -1059,7 +1057,7 @@ const assertBatteryCompleteness = (proof, context) => {
|
|
|
1059
1057
|
});
|
|
1060
1058
|
seen.add(entry.name);
|
|
1061
1059
|
}
|
|
1062
|
-
if (proof.outcome !== "passed"
|
|
1060
|
+
if (proof.outcome !== "passed") return;
|
|
1063
1061
|
const disposed = new Set([...executed, ...seen]);
|
|
1064
1062
|
const undisposed = selected.filter((name) => !disposed.has(name));
|
|
1065
1063
|
if (undisposed.length > 0) context.addIssue({
|
|
@@ -1069,7 +1067,7 @@ const assertBatteryCompleteness = (proof, context) => {
|
|
|
1069
1067
|
});
|
|
1070
1068
|
};
|
|
1071
1069
|
/**
|
|
1072
|
-
* The stamp-authorization control: a passed
|
|
1070
|
+
* The stamp-authorization control: a passed proof may only claim a command
|
|
1073
1071
|
* was NOT REQUIRED if its own recorded stamp says so.
|
|
1074
1072
|
*
|
|
1075
1073
|
* `assertBatteryCompleteness` proves the two lists partition the selected
|
|
@@ -1092,8 +1090,8 @@ const assertBatteryCompleteness = (proof, context) => {
|
|
|
1092
1090
|
* provably released.
|
|
1093
1091
|
*
|
|
1094
1092
|
* The proof is one artifact and a determined forger controls all of it; this
|
|
1095
|
-
* is internal-coherence belt-and-braces in the same trust domain as the
|
|
1096
|
-
*
|
|
1093
|
+
* is internal-coherence belt-and-braces in the same trust domain as the rest
|
|
1094
|
+
* of the proof, and write-time truth stays `pr:verify`'s job.
|
|
1097
1095
|
*
|
|
1098
1096
|
* The authorizing evidence is the proof's OWN `impactStamp` — the same stamp
|
|
1099
1097
|
* `pr:verify` computed for this candidate's identity triple and recorded here,
|
|
@@ -1106,14 +1104,13 @@ const assertBatteryCompleteness = (proof, context) => {
|
|
|
1106
1104
|
* self-contradictory stamp, an unclassified name, or an `affected` verdict all
|
|
1107
1105
|
* fail the same way scoping itself would.
|
|
1108
1106
|
*
|
|
1109
|
-
* Scoped to `outcome: "passed"`
|
|
1110
|
-
*
|
|
1111
|
-
* legacy proof predates both fields, so neither is making a false completeness
|
|
1107
|
+
* Scoped to `outcome: "passed"` for the same reason as the completeness rule:
|
|
1108
|
+
* an aborted run records partial execution, so it makes no false completeness
|
|
1112
1109
|
* claim.
|
|
1113
1110
|
*/
|
|
1114
1111
|
const assertNotRequiredStampAuthorization = (proof, context) => {
|
|
1115
1112
|
const notRequired = proof.notRequiredCommands ?? [];
|
|
1116
|
-
if (proof.outcome !== "passed" ||
|
|
1113
|
+
if (proof.outcome !== "passed" || notRequired.length === 0) return;
|
|
1117
1114
|
const { impactStamp } = proof;
|
|
1118
1115
|
if (impactStamp === void 0) {
|
|
1119
1116
|
context.addIssue({
|
|
@@ -1157,36 +1154,6 @@ const assertNotRequiredStampAuthorization = (proof, context) => {
|
|
|
1157
1154
|
//#endregion
|
|
1158
1155
|
//#region src/pr-verify-proof-rules.ts
|
|
1159
1156
|
const assertPrVerifyProofRules = (proof, context) => {
|
|
1160
|
-
if (proof.schemaVersion >= 4 && proof.authoringSession === void 0) context.addIssue({
|
|
1161
|
-
code: "custom",
|
|
1162
|
-
message: "schemaVersion 4 pr:verify proof requires authoringSession (the recorded authoring identity, or the `unknown` sentinel).",
|
|
1163
|
-
path: ["authoringSession"]
|
|
1164
|
-
});
|
|
1165
|
-
if (proof.schemaVersion < 4 && proof.authoringSession !== void 0) context.addIssue({
|
|
1166
|
-
code: "custom",
|
|
1167
|
-
message: "authoringSession is a schemaVersion>=4 field; a v1–v3 pr:verify proof must not carry it.",
|
|
1168
|
-
path: ["authoringSession"]
|
|
1169
|
-
});
|
|
1170
|
-
if (proof.schemaVersion < 4 && proof.impactStamp !== void 0) context.addIssue({
|
|
1171
|
-
code: "custom",
|
|
1172
|
-
message: "impactStamp is a schemaVersion>=4 field; a v1–v3 pr:verify proof must not carry it.",
|
|
1173
|
-
path: ["impactStamp"]
|
|
1174
|
-
});
|
|
1175
|
-
if (proof.schemaVersion < 4 && proof.notRequiredCommands !== void 0) context.addIssue({
|
|
1176
|
-
code: "custom",
|
|
1177
|
-
message: "notRequiredCommands is a schemaVersion>=4 field; a v1–v3 pr:verify proof must not carry it.",
|
|
1178
|
-
path: ["notRequiredCommands"]
|
|
1179
|
-
});
|
|
1180
|
-
if (proof.schemaVersion < 4 && proof.catchUpRecognition !== void 0) context.addIssue({
|
|
1181
|
-
code: "custom",
|
|
1182
|
-
message: "catchUpRecognition is a schemaVersion>=4 field; a v1–v3 pr:verify proof must not carry it.",
|
|
1183
|
-
path: ["catchUpRecognition"]
|
|
1184
|
-
});
|
|
1185
|
-
if (proof.schemaVersion < 4 && proof.notDemandedRecords !== void 0) context.addIssue({
|
|
1186
|
-
code: "custom",
|
|
1187
|
-
message: "notDemandedRecords is a schemaVersion>=4 field; a v1–v3 pr:verify proof must not carry it.",
|
|
1188
|
-
path: ["notDemandedRecords"]
|
|
1189
|
-
});
|
|
1190
1157
|
if (proof.notDemandedRecords !== void 0 && proof.impactStamp === void 0) context.addIssue({
|
|
1191
1158
|
code: "custom",
|
|
1192
1159
|
message: "notDemandedRecords requires impactStamp; package-level not-demanded records are bound to the stamp identity.",
|
|
@@ -1195,14 +1162,15 @@ const assertPrVerifyProofRules = (proof, context) => {
|
|
|
1195
1162
|
assertBatteryCompleteness(proof, context);
|
|
1196
1163
|
assertNotRequiredStampAuthorization(proof, context);
|
|
1197
1164
|
};
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1165
|
+
/**
|
|
1166
|
+
* The pr:verify proof versions a reader accepts: the current one only (#920
|
|
1167
|
+
* item 1). #917 narrowed the pr:ready reader the same way. A pr:verify proof
|
|
1168
|
+
* is per-candidate and short-lived — it is rewritten on every head — so no
|
|
1169
|
+
* stored v1–v3 proof can outlive the release that drops it. Pre-1.0 posture
|
|
1170
|
+
* applies: one current contract, no compat reader. A consumer on an older
|
|
1171
|
+
* factory must adopt this release before HQ ingests its pr:verify proofs.
|
|
1172
|
+
*/
|
|
1173
|
+
const SUPPORTED_PR_VERIFY_SCHEMA_VERSIONS = [4];
|
|
1206
1174
|
const executedCommandSchema = z.object({
|
|
1207
1175
|
command: z.string().min(1),
|
|
1208
1176
|
counts: z.object({
|
|
@@ -1213,7 +1181,6 @@ const executedCommandSchema = z.object({
|
|
|
1213
1181
|
exitCode: z.number(),
|
|
1214
1182
|
name: z.string().min(1),
|
|
1215
1183
|
scope: z.enum([
|
|
1216
|
-
"always",
|
|
1217
1184
|
"docs-only",
|
|
1218
1185
|
"trivial",
|
|
1219
1186
|
"full"
|
|
@@ -1228,9 +1195,9 @@ const notDemandedRecordSchema = z.object({
|
|
|
1228
1195
|
basis: z.string().min(1),
|
|
1229
1196
|
name: z.string().min(1)
|
|
1230
1197
|
});
|
|
1231
|
-
const prVerifySchemaVersionSchema = z.
|
|
1198
|
+
const prVerifySchemaVersionSchema = z.literal(4);
|
|
1232
1199
|
const prVerifyProofSchema = z.object({
|
|
1233
|
-
authoringSession: z.string().trim().min(1)
|
|
1200
|
+
authoringSession: z.string().trim().min(1),
|
|
1234
1201
|
base: z.string().min(1),
|
|
1235
1202
|
baselineFullProofs: z.array(z.object({
|
|
1236
1203
|
base: z.string().min(1),
|
|
@@ -1276,7 +1243,6 @@ const prVerifyProofSchema = z.object({
|
|
|
1276
1243
|
impactTarget: z.string().min(1).optional(),
|
|
1277
1244
|
name: z.string().min(1),
|
|
1278
1245
|
scope: z.enum([
|
|
1279
|
-
"always",
|
|
1280
1246
|
"docs-only",
|
|
1281
1247
|
"trivial",
|
|
1282
1248
|
"full"
|
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.28",
|
|
4
4
|
"description": "Shared Patronage software factory CLI and project-profile validation tools",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
"directory": "software-factory"
|
|
10
10
|
},
|
|
11
11
|
"bin": {
|
|
12
|
-
"patronage-factory": "./dist/
|
|
13
|
-
"psf": "./dist/
|
|
12
|
+
"patronage-factory": "./dist/cli.js",
|
|
13
|
+
"psf": "./dist/cli.js"
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
16
16
|
"dist",
|
|
@@ -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.28"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/node": "24.13.3",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"api:check": "pnpm build && pnpm api:check:prepared",
|
|
65
65
|
"api:check:prepared": "node scripts/public-api-surface.mjs",
|
|
66
66
|
"precli": "bash ../scripts/ensure-worktree-bootstrap.sh",
|
|
67
|
-
"cli": "tsx src/
|
|
67
|
+
"cli": "tsx src/cli.ts",
|
|
68
68
|
"cleanup:check": "knip --files --dependencies --exports",
|
|
69
69
|
"precoverage": "bash ../scripts/ensure-worktree-bootstrap.sh",
|
|
70
70
|
"coverage": "vitest run --coverage",
|