@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.
- package/dist/index.d.ts +295 -164
- package/dist/index.js +12177 -10750
- package/dist/review-prompts/security/SKILL.md +1 -0
- package/dist/review-prompts/security/references/javascript-typescript.md +1 -0
- package/dist/schemas.d.ts +48 -17
- package/dist/schemas.js +16 -0
- package/package.json +2 -2
|
@@ -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.
|
|
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.
|
|
40
|
+
"@patronage/factory-ci": "1.0.0-alpha.26"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/node": "24.13.3",
|