@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/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
- declare const SUPPORTED_PR_VERIFY_SCHEMA_VERSIONS: readonly [1, 2, 3, 4];
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, and for v1–v3 proofs, which predate the field.
528
+ * not scope.
521
529
  */
522
530
  impactTarget?: string;
523
531
  name: string;
524
- scope: "always" | "docs-only" | "trivial" | "full";
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: "always" | "docs-only" | "trivial" | "full";
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 — the field is v4-only (the same
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?: string;
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.ZodOptional<z.ZodString>;
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.ZodNumber & z.ZodType<1 | 2 | 3 | 4, number, z.core.$ZodTypeInternals<1 | 2 | 3 | 4, number>>;
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. It is
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" || proof.schemaVersion < 4) return;
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 v4 proof may only claim a command
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
- * version guards, and write-time truth stays `pr:verify`'s job.
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"` and schemaVersion >= 4 for the same reasons as
1110
- * the completeness rule: an aborted run records partial execution, and a
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" || proof.schemaVersion < 4 || notRequired.length === 0) return;
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
- //#endregion
1199
- //#region src/pr-verify-proof-contract.ts
1200
- const SUPPORTED_PR_VERIFY_SCHEMA_VERSIONS = [
1201
- 1,
1202
- 2,
1203
- 3,
1204
- 4
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.number().refine((value) => SUPPORTED_PR_VERIFY_SCHEMA_VERSIONS.includes(value), { message: `schemaVersion must be one of: ${SUPPORTED_PR_VERIFY_SCHEMA_VERSIONS.join(", ")}` });
1198
+ const prVerifySchemaVersionSchema = z.literal(4);
1232
1199
  const prVerifyProofSchema = z.object({
1233
- authoringSession: z.string().trim().min(1).optional(),
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.26",
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/index.js",
13
- "psf": "./dist/index.js"
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.26"
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/index.ts",
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",