@patronage/software-factory 1.0.0-alpha.24 → 1.0.0-alpha.26

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.
@@ -51,6 +51,7 @@ Load only matching references:
51
51
  | Crypto and randomness | Weak hashes, predictable random values, static IVs, ECB mode, timing-unsafe compares, unsigned tokens, or custom crypto protect security-sensitive data. |
52
52
  | Abuse controls | Sensitive or expensive operations such as login, MFA, invites, exports, password reset, billing, email, SMS, or paid API calls lack meaningful rate, quota, replay, or idempotency controls. |
53
53
  | CI and workflows | Workflow changes let untrusted or caller-controlled code, text, artifacts, caches, or actions reach privileged execution, secrets, write tokens, releases, packages, deployments, or sensitive runners. |
54
+ | Infrastructure exposure | An infrastructure declaration publishes a service to the internet without a declared authentication mechanism. In an Alchemy stack, a Worker declaring `workersDev: true`, a `domain`, or `routes` must also declare its guard — Cloudflare Access, an auth secret binding, or an equivalent check inside the Worker — or carry a written reason in the change for why it is public. |
54
55
 
55
56
  ## Severity
56
57
 
@@ -22,6 +22,7 @@ Use this when reviewing JavaScript, TypeScript, Node, React, Next.js, or browser
22
22
  | Path traversal | `path.join(root, userPath)` without realpath containment, archive extraction by entry name | Normalize and resolve real paths, verify containment, generate server-side filenames |
23
23
  | Webhook forgery | State-changing webhook parses JSON before verifying signature or skips timestamp/replay checks | Verify raw body signature, timestamp freshness, replay/idempotency, and provider secret before side effects |
24
24
  | Secrets exposure | Secrets in client components, `NEXT_PUBLIC_*`, serialized props, logs, or error responses | Server-only reads, redacted logs, safe error messages, no hardcoded production fallback |
25
+ | Public Worker without auth | Alchemy `Cloudflare.Worker` gains `workersDev: true`, a `domain`, or a `routes` entry while its handler enforces no identity check | Cloudflare Access on the Worker (`access` prop or an Access application destination), an auth secret binding the handler verifies, or a written reason in the change for why the Worker is public |
25
26
 
26
27
  ## False-Positive Controls
27
28
 
package/dist/schemas.d.ts CHANGED
@@ -21,6 +21,23 @@ declare const reviewPromptSectionsSchema: z.ZodArray<z.ZodObject<{
21
21
  text: z.ZodString;
22
22
  }, z.core.$strict>>;
23
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
24
41
  //#region src/review-ladder-policy.d.ts
25
42
  type ReviewFindingCategory = "correctness" | "safety" | "coordination" | "maintainability" | "unknown";
26
43
  declare const FINDING_DISPOSITIONS: readonly ["open", "fixed-in-thread", "follow-up-filed", "waived", "stale-repeat", "rerun-noise"];
@@ -77,6 +94,7 @@ interface ReviewLadderCycle {
77
94
  headSha: string;
78
95
  patchId: string;
79
96
  };
97
+ historical?: true;
80
98
  model?: string;
81
99
  correlatedRerun?: boolean;
82
100
  session?: LadderSessionAttribution;
@@ -128,6 +146,13 @@ interface PrReviewProof {
128
146
  changedFiles: string[];
129
147
  cleanedPaths: string[];
130
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;
131
156
  reviewRequirement?: {
132
157
  reason: "no-applicable-mode" | "faithful-merge";
133
158
  status: "not-required";
@@ -227,23 +252,6 @@ declare const boundaryReviewProofBaseSchema: z.ZodObject<{
227
252
  }, z.core.$loose>;
228
253
  type BoundaryReviewProof = z.infer<typeof boundaryReviewProofBaseSchema>;
229
254
  //#endregion
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
255
  //#region src/catch-up-recognition-record.d.ts
248
256
  interface CatchUpRecognition {
249
257
  /** The ref the candidate targets, as the recognizing command resolved it. */
@@ -579,6 +587,16 @@ interface PrVerifyProof {
579
587
  notRequiredCommands?: PrVerifyNotRequiredCommand[];
580
588
  outcome?: "aborted" | "passed";
581
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;
582
600
  profilePath: string;
583
601
  projectKey: string;
584
602
  repository: string;
@@ -663,6 +681,19 @@ declare const prVerifyProofSchema: z.ZodObject<{
663
681
  aborted: "aborted";
664
682
  }>>;
665
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">>;
666
697
  profilePath: z.ZodString;
667
698
  projectKey: z.ZodString;
668
699
  repository: z.ZodString;
package/dist/schemas.js CHANGED
@@ -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. */
@@ -808,6 +822,7 @@ const prReviewProofSchema = z.object({
808
822
  ladder: prReviewLadderStateSchema.optional(),
809
823
  maxReviewCycles: z.number().int().positive().optional(),
810
824
  patchId: z.string().regex(/^[0-9a-f]{40,64}$/u),
825
+ policyResolution: policyResolutionSchema.optional(),
811
826
  reviewCycle: z.number().int().positive().optional(),
812
827
  reviewRequirement: z.object({
813
828
  reason: z.enum(["no-applicable-mode", "faithful-merge"]),
@@ -1249,6 +1264,7 @@ const prVerifyProofSchema = z.object({
1249
1264
  notRequiredCommands: z.array(notRequiredCommandSchema).min(1).optional(),
1250
1265
  outcome: z.enum(["aborted", "passed"]).optional(),
1251
1266
  patchId: z.string().regex(/^[0-9a-f]{40}$/u).optional(),
1267
+ policyResolution: policyResolutionSchema.optional(),
1252
1268
  profilePath: z.string().min(1),
1253
1269
  projectKey: z.string().min(1),
1254
1270
  repository: z.string().min(1),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patronage/software-factory",
3
- "version": "1.0.0-alpha.24",
3
+ "version": "1.0.0-alpha.26",
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.24"
40
+ "@patronage/factory-ci": "1.0.0-alpha.26"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/node": "24.13.3",