@patronage/software-factory 0.20.0 → 0.25.0

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
@@ -1,5 +1,50 @@
1
1
  import { z } from "zod";
2
2
 
3
+ //#region src/demand-waiver.d.ts
4
+ /**
5
+ * A demand that was in force, was NOT met, and was waived by the operator.
6
+ *
7
+ * `unmetReasons` is required and non-empty: every reason the demand refused is
8
+ * carried through verbatim. There is no field on this record that could say
9
+ * "satisfied", and no code path constructs one without a refusal to carry.
10
+ */
11
+ interface WaivedDemand {
12
+ demand: string;
13
+ operator: string;
14
+ rationale: string;
15
+ recordedAt: string;
16
+ session: string;
17
+ /** The demand's refusals at evaluation time, preserved verbatim. */
18
+ unmetReasons: string[];
19
+ }
20
+ declare const waivedDemandSchema: z.ZodType<WaivedDemand>;
21
+ //#endregion
22
+ //#region src/blocked-reasons.d.ts
23
+ /**
24
+ * The wire bound on one `detail`. A blocked proof carries one short sentence
25
+ * per demand, never a transcript: HQ's ingest cap is 256 KB and this field
26
+ * must stay far under it even when a candidate blocks on every gate at once.
27
+ */
28
+ declare const BLOCKED_REASON_DETAIL_MAX = 280;
29
+ /**
30
+ * The wire bound on how many demands one proof may name. Well past any real
31
+ * candidate (there are a dozen fixed demands plus the profile's checks and the
32
+ * live human blockers) and, with the detail bound, keeps the whole field two
33
+ * orders of magnitude under the ingest cap. Bounded here rather than trimmed
34
+ * downstream: HQ rejects an over-long list loudly instead of storing a quietly
35
+ * truncated one.
36
+ */
37
+ declare const BLOCKED_REASONS_MAX = 100;
38
+ declare const blockedReasonSchema: z.ZodObject<{
39
+ code: z.ZodString;
40
+ detail: z.ZodString;
41
+ }, z.core.$strip>;
42
+ declare const blockedReasonsSchema: z.ZodArray<z.ZodObject<{
43
+ code: z.ZodString;
44
+ detail: z.ZodString;
45
+ }, z.core.$strip>>;
46
+ type BlockedReason = z.infer<typeof blockedReasonSchema>;
47
+ //#endregion
3
48
  //#region src/boundary-review-proof.d.ts
4
49
  declare const boundaryReviewProofBaseSchema: z.ZodObject<{
5
50
  boundary: z.ZodString;
@@ -64,20 +109,6 @@ interface FollowUpAction {
64
109
  command: string;
65
110
  }
66
111
  //#endregion
67
- //#region src/diff-classification.d.ts
68
- declare const DIFF_CLASSIFICATIONS: readonly ["docs/process-only", "trivial", "non-trivial"];
69
- type DiffClassification = (typeof DIFF_CLASSIFICATIONS)[number];
70
- //#endregion
71
- //#region src/pr-verify-mode.d.ts
72
- /**
73
- * The verification mode `pr:verify` resolved for a run.
74
- *
75
- * Canonically declared here rather than inside `pr-readiness/` so that modules
76
- * on either side of that boundary — the readiness proof shape and the durable
77
- * check-run payload — can name the same union without importing each other.
78
- */
79
- type ResolvedPrVerifyMode = "docs-only" | "trivial" | "full";
80
- //#endregion
81
112
  //#region src/merge-preflight/worktree-held-branch.d.ts
82
113
  /**
83
114
  * Detects when a PR head branch is checked out in a local git worktree.
@@ -164,12 +195,33 @@ interface PrMergeCheckProof {
164
195
  notices?: string[];
165
196
  pr: number;
166
197
  status: "pass" | "fail";
198
+ /**
199
+ * Demands that were in force, were NOT met, and were waived by the operator
200
+ * (#354). Each entry carries the demand's refusals verbatim, so a waived
201
+ * demand can never read as a met one; the merge proceeds on the recorded
202
+ * operator act, not on evidence.
203
+ */
204
+ waivedDemands?: WaivedDemand[];
167
205
  /** Present when the PR head branch is checked out in a local worktree. */
168
206
  worktreeHeldBranch?: WorktreeHeldBranch;
169
207
  /** All merge-relevant branches held by local worktrees (head and default). */
170
208
  worktreeHeldBranches?: WorktreeHeldBranch[];
171
209
  }
172
210
  //#endregion
211
+ //#region src/diff-classification.d.ts
212
+ declare const DIFF_CLASSIFICATIONS: readonly ["docs/process-only", "trivial", "non-trivial"];
213
+ type DiffClassification = (typeof DIFF_CLASSIFICATIONS)[number];
214
+ //#endregion
215
+ //#region src/pr-verify-mode.d.ts
216
+ /**
217
+ * The verification mode `pr:verify` resolved for a run.
218
+ *
219
+ * Canonically declared here rather than inside `pr-readiness/` so that modules
220
+ * on either side of that boundary — the readiness proof shape and the durable
221
+ * check-run payload — can name the same union without importing each other.
222
+ */
223
+ type ResolvedPrVerifyMode = "docs-only" | "trivial" | "full";
224
+ //#endregion
173
225
  //#region src/packages/review-prompt-sections/schema.d.ts
174
226
  declare const reviewPromptSectionSchema: z.ZodObject<{
175
227
  provenance: z.ZodEnum<{
@@ -286,7 +338,7 @@ interface PrReviewProof {
286
338
  cleanedPaths: string[];
287
339
  ladder?: PrReviewLadderState;
288
340
  reviewRequirement?: {
289
- reason: "docs-only-profile-bypass";
341
+ reason: "no-applicable-mode";
290
342
  status: "not-required";
291
343
  };
292
344
  reviews: PrReviewResult[];
@@ -525,7 +577,15 @@ type ManagedReadinessLedger = z.infer<typeof managedReadinessLedgerSchema>;
525
577
  //#endregion
526
578
  //#region src/pr-ready.d.ts
527
579
  interface PrReadyProof {
528
- schemaVersion: 1;
580
+ schemaVersion: 2;
581
+ /**
582
+ * Why this run blocked, one entry per refusing demand (#391): `code` is the
583
+ * demand key from the resolver's vocabulary, `detail` the one-sentence
584
+ * refusal. Same refusals as `blockingReasons`, in the same order — the
585
+ * analyzable projection of a flat string list, so a wall of blocked proofs
586
+ * on one PR can be counted by cause. Absent when nothing blocked.
587
+ */
588
+ blockedReasons?: BlockedReason[];
529
589
  blockingReasons: string[];
530
590
  humanBlockingReasons: string[];
531
591
  command: "patronage-factory pr:ready";
@@ -720,9 +780,9 @@ declare const closeoutArtifactSchema: z.ZodObject<{
720
780
  unit: z.ZodEnum<{
721
781
  boolean: "boolean";
722
782
  text: "text";
783
+ count: "count";
723
784
  tokens: "tokens";
724
785
  usd: "usd";
725
- count: "count";
726
786
  ratio: "ratio";
727
787
  }>;
728
788
  value: z.ZodUnion<readonly [z.ZodNumber, z.ZodString, z.ZodBoolean, z.ZodNull]>;
@@ -732,6 +792,187 @@ declare const closeoutArtifactSchema: z.ZodObject<{
732
792
  }, z.core.$strict>;
733
793
  type CloseoutArtifact = z.infer<typeof closeoutArtifactSchema>;
734
794
  //#endregion
795
+ //#region src/retro-envelope.d.ts
796
+ /**
797
+ * Versioned retro envelope schema (epic #27 wave 2, issue #34).
798
+ *
799
+ * One envelope per lane, built at `factory:closeout` and delivered through the
800
+ * typed gate-sink as the `retro-envelope` ingest kind. Re-derived in TypeScript
801
+ * from the `spike/telemetry-layer2` S5 scratch schema (reference-only, never
802
+ * merged). This module is the single source of truth for the v1 wire shape
803
+ * and its bounds ({@link RETRO_ENVELOPE_WIRE_BOUNDS}) — producer and consumer
804
+ * alike. HQ imports these exports directly from the Worker-safe
805
+ * `@patronage/software-factory/schemas` subpath
806
+ * (`software-factory-hq/src/contracts/retro-schemas.ts`) instead of
807
+ * maintaining a parallel hand-written copy, so there is exactly one wire
808
+ * contract and no drift-detection machinery is needed (issue #350; formerly
809
+ * a hand-written twin plus a 767-line parity test, #46).
810
+ *
811
+ * DESIGN INVARIANT: cross-family token sums must be UNREPRESENTABLE.
812
+ *
813
+ * The two model families use different tokenizers, prices, and accounting
814
+ * conventions, so any token total that spans Claude and GPT is a lie:
815
+ *
816
+ * 1. There is no combined/total token field anywhere in the envelope.
817
+ * 2. `tokenFamilies` is strict — its only keys are `claude` and `gpt`; data
818
+ * cannot smuggle in a third "all"/"combined" slot.
819
+ * 3. The family BLOCKS are structurally different shapes with DIFFERENT keys
820
+ * (claude is a single flat block keyed on freshInput/cacheReadInput/
821
+ * cacheCreationInput; gpt is `{ roles: [...] }`). The exclusive input-tier
822
+ * COUNTS share no key name across families. The residual names shared
823
+ * between the claude block and a gpt ROLE entry are pinned to exactly
824
+ * {costUsd, model, output} (PR #32 advisory): `costUsd` is deliberate —
825
+ * USD is the one cross-family summable unit (rule 4); `model` is an
826
+ * unsummable label; `output` is the same name at DIFFERENT depths (lane
827
+ * block vs per-role entry), frozen by a tripwire test in
828
+ * `retro-envelope.test.ts` so the overlap cannot grow. Renaming `output`
829
+ * is a schemaVersion-2 wire change, deliberately not spent in v1.
830
+ * 4. Cost is per-family USD and nullable. Combined totals are allowed in USD
831
+ * only, and only as a projection-time sum of per-family USD.
832
+ *
833
+ * Field names also encode the S2/S3 reader lessons: Claude `freshInput` alone
834
+ * is not prompt size (true input context = freshInput + cacheReadInput +
835
+ * cacheCreationInput, requestId-deduped), and codex `inputInclusiveOfCache`
836
+ * already includes `cachedInput`, so `freshInputDerived` (inclusive − cached)
837
+ * is the only value safe to feed a per-token pricer.
838
+ *
839
+ * COMPLETENESS POSTURE: harvest may have no usable native log for a lane, so
840
+ * `tokenFamilies` may legitimately be absent. The closeout build gate demands
841
+ * a valid envelope, not available telemetry. A families-absent envelope keeps
842
+ * its operator-visible data gaps and is a replayable advisory HQ event, so it
843
+ * never substitutes unavailable usage with zero. The wire shape (field names,
844
+ * types, structure) stays byte-parity with HQ v1.
845
+ */
846
+ declare const RETRO_ENVELOPE_SCHEMA_VERSION = 1;
847
+ /**
848
+ * v1 wire bounds — the single source the schemas below are built from and the
849
+ * builder's sanitization seam clamps to (`retro-envelope-builder.ts` imports
850
+ * these; it keeps no bound constants of its own). HQ imports this module
851
+ * directly (issue #350), so there is one set of bounds, not a second copy to
852
+ * keep in sync.
853
+ */
854
+ declare const RETRO_ENVELOPE_WIRE_BOUNDS: {
855
+ /** archiveRef pointer (key/URL) max characters. */readonly archiveRefMaxChars: 2048; /** refs.branch max characters (git ref length ceiling). */
856
+ readonly branchMaxChars: 255; /** gates[] wire cap — the builder keeps the most recent records. */
857
+ readonly gatesMax: 500; /** gpt roles[] cap (delegated roles per lane). */
858
+ readonly gptRolesMax: 20; /** Cap for list fields: joinKeys id arrays, phases, dataGaps. */
859
+ readonly listMax: 100; /** Bounded name fields: agentRunId, gate, phase name, refs, join-key ids. */
860
+ readonly nameMaxChars: 200; /** Short identifier fields: repo name/owner, model, role. */
861
+ readonly shortMaxChars: 100; /** Free-text fields: dataGaps entries, outcome.verdict. */
862
+ readonly textMaxChars: 500;
863
+ };
864
+ declare const retroEnvelopeV1Schema: z.ZodObject<{
865
+ agentRunId: z.ZodString;
866
+ archiveRef: z.ZodOptional<z.ZodString>;
867
+ cycles: z.ZodObject<{
868
+ gateRunsToFirstGreen: z.ZodNumber;
869
+ reviewerFixRounds: z.ZodNumber;
870
+ thermoFixRounds: z.ZodNumber;
871
+ }, z.core.$strict>;
872
+ dataGaps: z.ZodDefault<z.ZodArray<z.ZodString>>;
873
+ gates: z.ZodArray<z.ZodObject<{
874
+ cycle: z.ZodNumber;
875
+ duration: z.ZodNumber;
876
+ gate: z.ZodString;
877
+ outcome: z.ZodEnum<{
878
+ pass: "pass";
879
+ fail: "fail";
880
+ skip: "skip";
881
+ }>;
882
+ startedAt: z.ZodISODateTime;
883
+ }, z.core.$strict>>;
884
+ generatedAt: z.ZodISODateTime;
885
+ interventions: z.ZodObject<{
886
+ count: z.ZodNumber;
887
+ }, z.core.$strict>;
888
+ joinKeys: z.ZodObject<{
889
+ claudeSessionIds: z.ZodDefault<z.ZodArray<z.ZodString>>;
890
+ codexThreadIds: z.ZodDefault<z.ZodArray<z.ZodString>>;
891
+ }, z.core.$strict>;
892
+ kind: z.ZodLiteral<"retro-envelope">;
893
+ outcome: z.ZodOptional<z.ZodObject<{
894
+ mergeCheck: z.ZodOptional<z.ZodEnum<{
895
+ pass: "pass";
896
+ fail: "fail";
897
+ "not-run": "not-run";
898
+ }>>;
899
+ status: z.ZodEnum<{
900
+ fail: "fail";
901
+ success: "success";
902
+ blocked: "blocked";
903
+ "ship-with-followups": "ship-with-followups";
904
+ }>;
905
+ verdict: z.ZodOptional<z.ZodString>;
906
+ }, z.core.$strict>>;
907
+ phases: z.ZodArray<z.ZodObject<{
908
+ at: z.ZodISODateTime;
909
+ deltaSec: z.ZodOptional<z.ZodNumber>;
910
+ name: z.ZodString;
911
+ }, z.core.$strict>>;
912
+ refs: z.ZodObject<{
913
+ branch: z.ZodOptional<z.ZodString>;
914
+ epic: z.ZodOptional<z.ZodString>;
915
+ headSha: z.ZodOptional<z.ZodString>;
916
+ issue: z.ZodOptional<z.ZodString>;
917
+ prNumber: z.ZodOptional<z.ZodNumber>;
918
+ }, z.core.$strict>;
919
+ repo: z.ZodObject<{
920
+ name: z.ZodString;
921
+ owner: z.ZodString;
922
+ }, z.core.$strict>;
923
+ schemaVersion: z.ZodLiteral<1>;
924
+ tokenFamilies: z.ZodObject<{
925
+ claude: z.ZodOptional<z.ZodObject<{
926
+ cacheCreationInput: z.ZodNumber;
927
+ cacheReadInput: z.ZodNumber;
928
+ costUsd: z.ZodNullable<z.ZodNumber>;
929
+ family: z.ZodLiteral<"claude">;
930
+ freshInput: z.ZodNumber;
931
+ model: z.ZodString;
932
+ output: z.ZodNumber;
933
+ requests: z.ZodNumber;
934
+ }, z.core.$strict>>;
935
+ gpt: z.ZodOptional<z.ZodObject<{
936
+ family: z.ZodLiteral<"gpt">;
937
+ roles: z.ZodArray<z.ZodObject<{
938
+ cachedInput: z.ZodNumber;
939
+ costUsd: z.ZodNullable<z.ZodNumber>;
940
+ freshInputDerived: z.ZodNumber;
941
+ inputInclusiveOfCache: z.ZodNumber;
942
+ model: z.ZodString;
943
+ output: z.ZodNumber;
944
+ reasoningOutput: z.ZodNumber;
945
+ role: z.ZodString;
946
+ threadId: z.ZodOptional<z.ZodString>;
947
+ }, z.core.$strict>>;
948
+ }, z.core.$strict>>;
949
+ }, z.core.$strict>;
950
+ wallClock: z.ZodObject<{
951
+ endTs: z.ZodISODateTime;
952
+ startTs: z.ZodISODateTime;
953
+ totalSec: z.ZodNumber;
954
+ }, z.core.$strict>;
955
+ }, z.core.$strict>;
956
+ type RetroEnvelope = z.infer<typeof retroEnvelopeV1Schema>;
957
+ /**
958
+ * Versioned payload validators, keyed by schema major. Unknown majors never
959
+ * reach these — {@link parseRetroEnvelope} returns them raw and marked
960
+ * degraded, mirroring HQ's ingest skew posture (stored raw, never dropped).
961
+ */
962
+ declare const RETRO_ENVELOPE_VALIDATORS: Record<number, z.ZodType<RetroEnvelope, unknown>>;
963
+ declare const SUPPORTED_RETRO_ENVELOPE_SCHEMA_VERSIONS: readonly number[];
964
+ type ParsedRetroEnvelope = {
965
+ disposition: "trusted";
966
+ envelope: RetroEnvelope;
967
+ schemaVersion: number;
968
+ } | {
969
+ disposition: "degraded";
970
+ raw: unknown;
971
+ schemaVersion: number | undefined;
972
+ };
973
+ /** Epic anchor for an envelope: refs.epic, else refs.issue, else the PR. */
974
+ declare const retroEpicReference: (refs: RetroEnvelope["refs"]) => string | undefined;
975
+ //#endregion
735
976
  //#region src/schemas.d.ts
736
977
  declare const EVIDENCE_ENVELOPE_SCHEMA_VERSION = 1;
737
978
  declare const evidenceEnvelopeSchema: z.ZodObject<{
@@ -865,7 +1106,9 @@ declare const prReviewProofSchema: z.ZodObject<{
865
1106
  patchId: z.ZodString;
866
1107
  reviewCycle: z.ZodOptional<z.ZodNumber>;
867
1108
  reviewRequirement: z.ZodOptional<z.ZodObject<{
868
- reason: z.ZodLiteral<"docs-only-profile-bypass">;
1109
+ reason: z.ZodEnum<{
1110
+ "no-applicable-mode": "no-applicable-mode";
1111
+ }>;
869
1112
  status: z.ZodLiteral<"not-required">;
870
1113
  }, z.core.$strict>>;
871
1114
  reviews: z.ZodArray<z.ZodObject<{
@@ -1097,13 +1340,24 @@ declare const prMergeCheckProofSchema: z.ZodObject<{
1097
1340
  pass: "pass";
1098
1341
  fail: "fail";
1099
1342
  }>;
1343
+ waivedDemands: z.ZodOptional<z.ZodArray<z.ZodType<WaivedDemand, unknown, z.core.$ZodTypeInternals<WaivedDemand, unknown>>>>;
1100
1344
  worktreeHeldBranch: z.ZodOptional<z.ZodObject<{
1101
1345
  branch: z.ZodString;
1102
1346
  worktreePath: z.ZodString;
1103
1347
  }, z.core.$strip>>;
1104
1348
  }, z.core.$strip>;
1105
- declare const PR_READY_SCHEMA_VERSION = 1;
1349
+ declare const PR_READY_SCHEMA_VERSION = 2;
1350
+ /**
1351
+ * The pr:ready proof versions a reader still accepts. `pr:ready` emits v2 only
1352
+ * (#391) — one current contract — but v1 events were spooled before the bump
1353
+ * and HQ must ingest them without degrading, so the wire schema parses both.
1354
+ */
1355
+ declare const SUPPORTED_PR_READY_SCHEMA_VERSIONS: readonly [1, 2];
1106
1356
  declare const prReadyProofSchema: z.ZodObject<{
1357
+ blockedReasons: z.ZodOptional<z.ZodArray<z.ZodObject<{
1358
+ code: z.ZodString;
1359
+ detail: z.ZodString;
1360
+ }, z.core.$strip>>>;
1107
1361
  blockingReasons: z.ZodArray<z.ZodString>;
1108
1362
  command: z.ZodLiteral<"patronage-factory pr:ready">;
1109
1363
  followUp: z.ZodOptional<z.ZodObject<{
@@ -1419,7 +1673,7 @@ declare const prReadyProofSchema: z.ZodObject<{
1419
1673
  command: z.ZodString;
1420
1674
  }, z.core.$strip>>>;
1421
1675
  repository: z.ZodOptional<z.ZodString>;
1422
- schemaVersion: z.ZodLiteral<1>;
1676
+ schemaVersion: z.ZodNumber & z.ZodType<1 | 2, number, z.core.$ZodTypeInternals<1 | 2, number>>;
1423
1677
  status: z.ZodEnum<{
1424
1678
  ready: "ready";
1425
1679
  blocked: "blocked";
@@ -1427,4 +1681,4 @@ declare const prReadyProofSchema: z.ZodObject<{
1427
1681
  }>;
1428
1682
  }, z.core.$strip>;
1429
1683
  //#endregion
1430
- export { BOUNDARY_CHECK_SCHEMA_VERSION, BOUNDARY_REVIEW_PROOF_KIND, BoundaryCheckProofRecord, type BoundaryReviewProof, type CloseoutArtifact, EVIDENCE_ENVELOPE_SCHEMA_VERSION, type EvidenceEnvelope, PR_MERGE_CHECK_SCHEMA_VERSION, PR_READY_SCHEMA_VERSION, PR_REVIEW_SCHEMA_VERSION, type PrMergeCheckProof, type PrReadyProof, type PrReviewProof, type PrVerifyProof, SUPPORTED_PR_VERIFY_SCHEMA_VERSIONS, boundaryCheckProofSchema, boundaryReviewProofSchema, closeoutArtifactSchema, evidenceEnvelopeSchema, prMergeCheckProofSchema, prReadyProofSchema, prReviewProofSchema, prVerifyProofSchema };
1684
+ export { BLOCKED_REASONS_MAX, BLOCKED_REASON_DETAIL_MAX, BOUNDARY_CHECK_SCHEMA_VERSION, BOUNDARY_REVIEW_PROOF_KIND, type BlockedReason, BoundaryCheckProofRecord, type BoundaryReviewProof, type CloseoutArtifact, EVIDENCE_ENVELOPE_SCHEMA_VERSION, type EvidenceEnvelope, PR_MERGE_CHECK_SCHEMA_VERSION, PR_READY_SCHEMA_VERSION, PR_REVIEW_SCHEMA_VERSION, type ParsedRetroEnvelope, type PrMergeCheckProof, type PrReadyProof, type PrReviewProof, type PrVerifyProof, RETRO_ENVELOPE_SCHEMA_VERSION, RETRO_ENVELOPE_VALIDATORS, RETRO_ENVELOPE_WIRE_BOUNDS, type RetroEnvelope, SUPPORTED_PR_READY_SCHEMA_VERSIONS, SUPPORTED_PR_VERIFY_SCHEMA_VERSIONS, SUPPORTED_RETRO_ENVELOPE_SCHEMA_VERSIONS, type WaivedDemand, blockedReasonSchema, blockedReasonsSchema, boundaryCheckProofSchema, boundaryReviewProofSchema, closeoutArtifactSchema, evidenceEnvelopeSchema, prMergeCheckProofSchema, prReadyProofSchema, prReviewProofSchema, prVerifyProofSchema, retroEnvelopeV1Schema, retroEpicReference, waivedDemandSchema };