@patronage/software-factory 1.0.0-alpha.37 → 1.0.0-alpha.38
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/README.md +1 -1
- package/dist/index.d.ts +302 -64
- package/dist/index.js +2977 -1152
- package/dist/oxlint-jev/{bridge-B4Sx95ZO.js → bridge-PMzq2gZh.js} +98 -37
- package/dist/oxlint-jev/index.js +1 -1
- package/dist/oxlint-jev/worker.js +1 -1
- package/dist/schemas.d.ts +24 -2
- package/dist/schemas.js +26 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -76,6 +76,6 @@ npx skills add https://github.com/patronage/software-factory -g --all
|
|
|
76
76
|
|
|
77
77
|
They provide procedure and link back to the documentation site; they are not a second command reference.
|
|
78
78
|
|
|
79
|
-
The package also exports an Oxlint plugin at `@patronage/software-factory/oxlint-jev`. It asks Jev questions that a project writes about its own code, through HQ, from a dedicated Oxlint config. It records by default and sends only with `PATRONAGE_JEV_MODE=live`. `psf jev:calibrate` scores those questions against the project's labeled cases. Both are session diagnostics, never gates. See [Ask Jev about code](https://factory.patronage.com/
|
|
79
|
+
The package also exports an Oxlint plugin at `@patronage/software-factory/oxlint-jev`. It asks Jev questions that a project writes about its own code, through HQ, from a dedicated Oxlint config. It records by default and sends only with `PATRONAGE_JEV_MODE=live`. `psf jev:calibrate` scores those questions against the project's labeled cases. Both are session diagnostics, never gates. See [Ask Jev about your code](https://factory.patronage.com/tutorials/ask-jev-about-code).
|
|
80
80
|
|
|
81
81
|
`assembleReviewPrompt` puts a repository-root `CODING_STANDARDS.md` into the correctness prompt when the file exists and is not blank. It reads the file at the candidate head, not from the working tree, and emits one `coding-standards` section that names the head SHA. A repository without the file gets an unchanged prompt. `pr:review --assemble` writes that factory-owned prompt under `.factory-memory/pr-review-prompt.json`. `pr:review --findings` copies the recorded sections onto the proof when the artifact's patch-id matches.
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,109 @@ import { z } from "zod";
|
|
|
4
4
|
import { PreviewProofRegistration } from "@patronage/factory-ci";
|
|
5
5
|
import { JsonValue, Questions, SystemOneRequest, choice, noul, score } from "@typesafe-ai/sdk";
|
|
6
6
|
|
|
7
|
+
//#region src/factory-app-broker-client.d.ts
|
|
8
|
+
/**
|
|
9
|
+
* The opt-in broker permission set (#1360): `pull_requests: write`,
|
|
10
|
+
* `issues: read`, and `contents: read` on the requesting repository. The
|
|
11
|
+
* read-only contents grant is there because GitHub's pull request create
|
|
12
|
+
* reads the head and base refs (#1327, #1375). The CLI asks for the scope by
|
|
13
|
+
* name and the broker decides its permissions. A request without a scope is
|
|
14
|
+
* the `checks: write` mint, unchanged.
|
|
15
|
+
*/
|
|
16
|
+
declare const FACTORY_APP_BROKER_ADMISSION_SCOPE = "admission";
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region src/user-config.d.ts
|
|
19
|
+
declare const githubAppConfigSchema: z.ZodObject<{
|
|
20
|
+
appId: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
21
|
+
installationId: z.ZodOptional<z.ZodNumber>;
|
|
22
|
+
privateKeyPath: z.ZodString;
|
|
23
|
+
}, z.core.$strip>;
|
|
24
|
+
type GithubAppConfig = z.infer<typeof githubAppConfigSchema>;
|
|
25
|
+
declare const factoryUserConfigSchema: z.ZodObject<{
|
|
26
|
+
githubApp: z.ZodOptional<z.ZodObject<{
|
|
27
|
+
appId: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
28
|
+
installationId: z.ZodOptional<z.ZodNumber>;
|
|
29
|
+
privateKeyPath: z.ZodString;
|
|
30
|
+
}, z.core.$strip>>;
|
|
31
|
+
hqAllowedOrigins: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
32
|
+
hqIngestCredentials: z.ZodOptional<z.ZodObject<{
|
|
33
|
+
clientIdRef: z.ZodString;
|
|
34
|
+
clientSecretRef: z.ZodString;
|
|
35
|
+
}, z.core.$strip>>;
|
|
36
|
+
schemaVersion: z.ZodLiteral<2>;
|
|
37
|
+
}, z.core.$strip>;
|
|
38
|
+
type FactoryUserConfig = z.infer<typeof factoryUserConfigSchema>;
|
|
39
|
+
interface LoadUserConfigResult {
|
|
40
|
+
path: string;
|
|
41
|
+
config: FactoryUserConfig;
|
|
42
|
+
ignoredKeys?: string[];
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/github-app-access.d.ts
|
|
46
|
+
interface FactoryAppAccessDependencies {
|
|
47
|
+
env?: NodeJS.ProcessEnv;
|
|
48
|
+
existsSync?: (path: string) => boolean;
|
|
49
|
+
exchangeBroker?: (input: {
|
|
50
|
+
fetch?: typeof fetch;
|
|
51
|
+
oidc: string;
|
|
52
|
+
owner: string;
|
|
53
|
+
repo: string;
|
|
54
|
+
scope?: typeof FACTORY_APP_BROKER_ADMISSION_SCOPE;
|
|
55
|
+
timeoutMs?: number;
|
|
56
|
+
url?: string;
|
|
57
|
+
}) => Promise<string>;
|
|
58
|
+
fetch?: typeof fetch;
|
|
59
|
+
githubApp?: GithubAppConfig;
|
|
60
|
+
mintCursorOidc?: (input: {
|
|
61
|
+
audience?: string;
|
|
62
|
+
signal?: AbortSignal;
|
|
63
|
+
socketPath?: string;
|
|
64
|
+
timeoutMs?: number;
|
|
65
|
+
}) => Promise<string>;
|
|
66
|
+
now?: () => number;
|
|
67
|
+
/**
|
|
68
|
+
* Cancels the Cursor OIDC mint (#1322). Fetch-based calls are cancelled
|
|
69
|
+
* through the `fetch` the caller passes, which joins its own signal.
|
|
70
|
+
*/
|
|
71
|
+
signal?: AbortSignal;
|
|
72
|
+
timeoutMs?: number;
|
|
73
|
+
token?: string;
|
|
74
|
+
transportAttempts?: number;
|
|
75
|
+
}
|
|
76
|
+
//#endregion
|
|
77
|
+
//#region src/admission-credential.d.ts
|
|
78
|
+
/**
|
|
79
|
+
* The GitHub calls a Cursor VM's own `gh` credential cannot make (#1327).
|
|
80
|
+
* Cursor mints the VM token without `pull_requests: write` or `issues`, so on
|
|
81
|
+
* a Cursor managed runtime these, and only these, run on the broker's
|
|
82
|
+
* `admission` token (#1360): `pull_requests: write`, `issues: read`, and
|
|
83
|
+
* `contents: read`, which creating a pull request needs because GitHub reads
|
|
84
|
+
* the head and base refs (#1375). Push,
|
|
85
|
+
* marking ready, arming auto-merge, check runs, and every other call keep
|
|
86
|
+
* their own credential.
|
|
87
|
+
*/
|
|
88
|
+
type AdmissionOperation = "create-pull-request" | "edit-pull-request-body" | "read-issue" | "read-pull-request-for-status-hud";
|
|
89
|
+
/** The one repository the admission token is minted for. */
|
|
90
|
+
interface AdmissionRepository {
|
|
91
|
+
owner: string;
|
|
92
|
+
repo: string;
|
|
93
|
+
}
|
|
94
|
+
interface AdmissionCredential {
|
|
95
|
+
/**
|
|
96
|
+
* The environment overlay for ONE `gh` subprocess that performs
|
|
97
|
+
* `operation`. `undefined` off a Cursor managed runtime: nothing is minted
|
|
98
|
+
* and the subprocess environment is untouched. On one, `{ GH_TOKEN }` with
|
|
99
|
+
* the admission token. Throws {@link AdmissionCredentialError} when the mint
|
|
100
|
+
* fails.
|
|
101
|
+
*/
|
|
102
|
+
ghEnv: (operation: AdmissionOperation, repository: AdmissionRepository) => Promise<Readonly<Record<string, string>> | undefined>;
|
|
103
|
+
/**
|
|
104
|
+
* The same token for one direct REST request, or `undefined` off a Cursor
|
|
105
|
+
* managed runtime.
|
|
106
|
+
*/
|
|
107
|
+
token: (operation: AdmissionOperation, repository: AdmissionRepository) => Promise<string | undefined>;
|
|
108
|
+
}
|
|
109
|
+
//#endregion
|
|
7
110
|
//#region src/review-rungs.d.ts
|
|
8
111
|
declare const EVIDENCE_REVIEW_RUNGS: readonly ["independent-model", "oracle", "human"];
|
|
9
112
|
type EvidenceReviewRung = (typeof EVIDENCE_REVIEW_RUNGS)[number];
|
|
@@ -332,6 +435,32 @@ declare const authorizeDemandWaiver: ({
|
|
|
332
435
|
session: string | undefined;
|
|
333
436
|
}) => AuthorizeDemandWaiverResult;
|
|
334
437
|
//#endregion
|
|
438
|
+
//#region src/hq-credentials.d.ts
|
|
439
|
+
/**
|
|
440
|
+
* Why a reference did not resolve. Each value names a different remedy, and
|
|
441
|
+
* none of them can be inferred from a value-or-nothing result:
|
|
442
|
+
*
|
|
443
|
+
* - `resolver-missing` — no secret-manager binary on PATH.
|
|
444
|
+
* - `resolver-blocked` — a binary exists but this session may not execute it
|
|
445
|
+
* (a sandbox denying exec). The command belongs outside the sandbox.
|
|
446
|
+
* - `resolver-timeout` — the probe expired: a desktop agent waiting on an
|
|
447
|
+
* approval nobody can give here.
|
|
448
|
+
* - `resolver-refused` — the binary ran and produced no value. Its store is
|
|
449
|
+
* unreachable from this session (a sandbox with no keychain access) or the
|
|
450
|
+
* reference is not readable. These two stay one status on purpose: telling
|
|
451
|
+
* them apart would mean reading resolver output.
|
|
452
|
+
*/
|
|
453
|
+
type SecretResolutionFailure = "resolver-blocked" | "resolver-missing" | "resolver-refused" | "resolver-timeout";
|
|
454
|
+
/** A structured resolution outcome. The value travels only when resolved. */
|
|
455
|
+
type SecretResolution = {
|
|
456
|
+
status: "resolved";
|
|
457
|
+
value: string;
|
|
458
|
+
} | {
|
|
459
|
+
status: SecretResolutionFailure;
|
|
460
|
+
};
|
|
461
|
+
/** Resolves a secret reference. Injected so tests stay offline. */
|
|
462
|
+
type SecretReferenceResolver = (reference: string) => SecretResolution;
|
|
463
|
+
//#endregion
|
|
335
464
|
//#region src/hq-ingest-sink.d.ts
|
|
336
465
|
interface HqIngestDependencies {
|
|
337
466
|
/**
|
|
@@ -344,6 +473,12 @@ interface HqIngestDependencies {
|
|
|
344
473
|
fetch?: typeof fetch;
|
|
345
474
|
now?: () => Date;
|
|
346
475
|
randomUUID?: () => string;
|
|
476
|
+
/**
|
|
477
|
+
* Resolves one `hqIngestCredentials` reference on an operator machine
|
|
478
|
+
* (#1313). Injected so tests stay offline; production asks `op-fast`, then
|
|
479
|
+
* `op`.
|
|
480
|
+
*/
|
|
481
|
+
resolveSecret?: SecretReferenceResolver;
|
|
347
482
|
/**
|
|
348
483
|
* Ceiling for persisting a failure after the transport leg (default
|
|
349
484
|
* `HQ_JOURNAL_FLUSH_BUDGET_MS`). Injectable for the same reason as
|
|
@@ -458,6 +593,12 @@ interface HqSpoolWorkCount {
|
|
|
458
593
|
oldestQueuedAt?: string;
|
|
459
594
|
/** Spooled events waiting in the locations below. */
|
|
460
595
|
pending: number;
|
|
596
|
+
/**
|
|
597
|
+
* How many pending events carry each recorded spool reason (#1317). Present
|
|
598
|
+
* only when the caller asked for `reasons`. An event whose file could not be
|
|
599
|
+
* read or parsed within budget is counted in `pending` and absent here.
|
|
600
|
+
*/
|
|
601
|
+
reasons?: Record<string, number>;
|
|
461
602
|
/** Locations that exist and hold spooled work. */
|
|
462
603
|
spools: string[];
|
|
463
604
|
/**
|
|
@@ -477,7 +618,9 @@ interface HqSpoolWorkCount {
|
|
|
477
618
|
* same locations `flushHqSpool` drains are inspected here, read-only: no
|
|
478
619
|
* directory is created, nothing is secured, and nothing is delivered.
|
|
479
620
|
*/
|
|
480
|
-
declare function countHqSpoolWork(input: Pick<HqSpoolFlushInput, "explicitDirectories" | "repository"
|
|
621
|
+
declare function countHqSpoolWork(input: Pick<HqSpoolFlushInput, "explicitDirectories" | "repository"> & {
|
|
622
|
+
/** Also read each pending event's recorded reason (#1317). */reasons?: boolean;
|
|
623
|
+
}, dependencies?: {
|
|
481
624
|
budgetMs?: number;
|
|
482
625
|
env?: NodeJS.ProcessEnv;
|
|
483
626
|
}): Promise<HqSpoolWorkCount>;
|
|
@@ -1250,58 +1393,6 @@ declare const followUpFromArgv: (argv: string[]) => FollowUpAction;
|
|
|
1250
1393
|
/** Canonical zod schema for the optional follow-up field on JSON outputs. */
|
|
1251
1394
|
declare const FollowUpActionSchema: z.ZodType<FollowUpAction>;
|
|
1252
1395
|
//#endregion
|
|
1253
|
-
//#region src/user-config.d.ts
|
|
1254
|
-
declare const githubAppConfigSchema: z.ZodObject<{
|
|
1255
|
-
appId: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
1256
|
-
installationId: z.ZodOptional<z.ZodNumber>;
|
|
1257
|
-
privateKeyPath: z.ZodString;
|
|
1258
|
-
}, z.core.$strip>;
|
|
1259
|
-
type GithubAppConfig = z.infer<typeof githubAppConfigSchema>;
|
|
1260
|
-
declare const factoryUserConfigSchema: z.ZodObject<{
|
|
1261
|
-
githubApp: z.ZodOptional<z.ZodObject<{
|
|
1262
|
-
appId: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
1263
|
-
installationId: z.ZodOptional<z.ZodNumber>;
|
|
1264
|
-
privateKeyPath: z.ZodString;
|
|
1265
|
-
}, z.core.$strip>>;
|
|
1266
|
-
hqAllowedOrigins: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1267
|
-
hqIngestCredentials: z.ZodOptional<z.ZodObject<{
|
|
1268
|
-
clientIdRef: z.ZodString;
|
|
1269
|
-
clientSecretRef: z.ZodString;
|
|
1270
|
-
}, z.core.$strip>>;
|
|
1271
|
-
schemaVersion: z.ZodLiteral<2>;
|
|
1272
|
-
}, z.core.$strip>;
|
|
1273
|
-
type FactoryUserConfig = z.infer<typeof factoryUserConfigSchema>;
|
|
1274
|
-
interface LoadUserConfigResult {
|
|
1275
|
-
path: string;
|
|
1276
|
-
config: FactoryUserConfig;
|
|
1277
|
-
ignoredKeys?: string[];
|
|
1278
|
-
}
|
|
1279
|
-
//#endregion
|
|
1280
|
-
//#region src/github-app-access.d.ts
|
|
1281
|
-
interface FactoryAppAccessDependencies {
|
|
1282
|
-
env?: NodeJS.ProcessEnv;
|
|
1283
|
-
existsSync?: (path: string) => boolean;
|
|
1284
|
-
exchangeBroker?: (input: {
|
|
1285
|
-
fetch?: typeof fetch;
|
|
1286
|
-
oidc: string;
|
|
1287
|
-
owner: string;
|
|
1288
|
-
repo: string;
|
|
1289
|
-
timeoutMs?: number;
|
|
1290
|
-
url?: string;
|
|
1291
|
-
}) => Promise<string>;
|
|
1292
|
-
fetch?: typeof fetch;
|
|
1293
|
-
githubApp?: GithubAppConfig;
|
|
1294
|
-
mintCursorOidc?: (input: {
|
|
1295
|
-
audience?: string;
|
|
1296
|
-
socketPath?: string;
|
|
1297
|
-
timeoutMs?: number;
|
|
1298
|
-
}) => Promise<string>;
|
|
1299
|
-
now?: () => number;
|
|
1300
|
-
timeoutMs?: number;
|
|
1301
|
-
token?: string;
|
|
1302
|
-
transportAttempts?: number;
|
|
1303
|
-
}
|
|
1304
|
-
//#endregion
|
|
1305
1396
|
//#region src/pr-verify-mode.d.ts
|
|
1306
1397
|
/**
|
|
1307
1398
|
* The verification mode `pr:verify` resolved for a run.
|
|
@@ -1547,6 +1638,7 @@ type PostCommitStatus = (input: PostCommitStatusInput) => void;
|
|
|
1547
1638
|
//#region src/github-check-runs.d.ts
|
|
1548
1639
|
declare const FACTORY_CHECK_NAMES: {
|
|
1549
1640
|
readonly "pr-ready": "patronage-factory/pr-ready";
|
|
1641
|
+
readonly "pr-review": "patronage-factory/pr-review";
|
|
1550
1642
|
readonly "pr-verify": "patronage-factory/pr-verify";
|
|
1551
1643
|
};
|
|
1552
1644
|
type FactoryCheckGate = keyof typeof FACTORY_CHECK_NAMES;
|
|
@@ -1570,11 +1662,12 @@ interface PublishFactoryCheckInput {
|
|
|
1570
1662
|
}
|
|
1571
1663
|
interface CheckRunDependencies extends FactoryAppAccessDependencies {
|
|
1572
1664
|
postCommitStatus?: PostCommitStatus;
|
|
1573
|
-
resolveDetailsUrl?: (input: PublishFactoryCheckInput) => Promise<string> | string;
|
|
1665
|
+
resolveDetailsUrl?: (input: PublishFactoryCheckInput, signal?: AbortSignal) => Promise<string> | string;
|
|
1574
1666
|
/**
|
|
1575
1667
|
* Bounded retry for the check-run POST. GitHub answers 422 for a head SHA it
|
|
1576
1668
|
* has not seen yet, which is the normal state when `pr:verify` runs before
|
|
1577
|
-
* the branch is pushed, and is also briefly true right after a push.
|
|
1669
|
+
* the branch is pushed, and is also briefly true right after a push. Only
|
|
1670
|
+
* that answer is retried (`isRetryableCheckRunFailure`).
|
|
1578
1671
|
*/
|
|
1579
1672
|
retry?: {
|
|
1580
1673
|
attempts: number;
|
|
@@ -1659,6 +1752,15 @@ declare function fetchPrVerifyProofBinding({
|
|
|
1659
1752
|
sha: string;
|
|
1660
1753
|
runJson?: GhJsonRunner;
|
|
1661
1754
|
}): PrVerifyProofBinding | undefined;
|
|
1755
|
+
/**
|
|
1756
|
+
* Where rules 2 and 4 read from: the App id to trust and the `gh api` runner.
|
|
1757
|
+
* Both default to production (the user config's App id else the pinned one,
|
|
1758
|
+
* and `runGhJson`); tests state them.
|
|
1759
|
+
*/
|
|
1760
|
+
interface ExactHeadRunSource {
|
|
1761
|
+
appId?: () => string;
|
|
1762
|
+
runJson?: GhJsonRunner;
|
|
1763
|
+
}
|
|
1662
1764
|
//#endregion
|
|
1663
1765
|
//#region src/merge-freeze.d.ts
|
|
1664
1766
|
declare const MERGE_FREEZE_CHECK_NAME = "patronage-factory/merge-freeze";
|
|
@@ -2499,6 +2601,12 @@ interface ReadFactoryPrStatusSourcesInput {
|
|
|
2499
2601
|
* a completed unsuccessful check run when inventory has no registration.
|
|
2500
2602
|
*/
|
|
2501
2603
|
readonly previewTargets?: readonly string[];
|
|
2604
|
+
/**
|
|
2605
|
+
* Token for the `/pulls/:n` identity read only. Defaults to `token`. On a
|
|
2606
|
+
* Cursor VM `token` is the broker's checks token, which cannot read pulls,
|
|
2607
|
+
* so this is the broker's admission token (#1327).
|
|
2608
|
+
*/
|
|
2609
|
+
readonly pullToken?: string;
|
|
2502
2610
|
readonly repo: string;
|
|
2503
2611
|
/** Factory App installation token, normally minted by the presentation job. */
|
|
2504
2612
|
readonly token: string;
|
|
@@ -2555,8 +2663,19 @@ interface RefreshFactoryPrStatusHudInput {
|
|
|
2555
2663
|
readonly repo: string;
|
|
2556
2664
|
readonly token?: string;
|
|
2557
2665
|
}
|
|
2666
|
+
/**
|
|
2667
|
+
* Where a local HUD refresh gets its credentials. Defaults to the process
|
|
2668
|
+
* environment, the user config, the real broker, and `fetch`.
|
|
2669
|
+
*/
|
|
2670
|
+
interface RefreshFactoryPrStatusHudDependencies {
|
|
2671
|
+
/** The broker's admission token on a Cursor VM, for the pull read (#1327). */
|
|
2672
|
+
readonly admission?: AdmissionCredential;
|
|
2673
|
+
/** The checks-scope broker mint on a Cursor VM, unchanged (#949). */
|
|
2674
|
+
readonly factoryApp?: FactoryAppAccessDependencies;
|
|
2675
|
+
readonly fetch?: typeof fetch;
|
|
2676
|
+
}
|
|
2558
2677
|
/** Plan from the checkout and present the App-owned HUD. */
|
|
2559
|
-
declare function refreshFactoryPrStatusHud(input: RefreshFactoryPrStatusHudInput): Promise<UpsertFactoryPrStatusCommentResult>;
|
|
2678
|
+
declare function refreshFactoryPrStatusHud(input: RefreshFactoryPrStatusHudInput, dependencies?: RefreshFactoryPrStatusHudDependencies): Promise<UpsertFactoryPrStatusCommentResult>;
|
|
2560
2679
|
/**
|
|
2561
2680
|
* Presentation must not fail an admission gate. Used after pr:ready publishes
|
|
2562
2681
|
* its check so the table is not stuck at first-write.
|
|
@@ -2728,19 +2847,34 @@ interface PullRequestArmingFacts {
|
|
|
2728
2847
|
* arm, and its notice says which read failed.
|
|
2729
2848
|
*/
|
|
2730
2849
|
interface ArmingPolicyReads {
|
|
2731
|
-
/**
|
|
2850
|
+
/**
|
|
2851
|
+
* One issue's sub-issue parent, or `null` when it has none. An issue read,
|
|
2852
|
+
* so on a Cursor VM the real one runs on the admission token (#1327).
|
|
2853
|
+
*/
|
|
2732
2854
|
readIssueParent: (input: {
|
|
2733
2855
|
issue: number;
|
|
2734
2856
|
owner: string;
|
|
2735
2857
|
repo: string;
|
|
2736
|
-
}) => IssueParent | null
|
|
2858
|
+
}) => IssueParent | null | Promise<IssueParent | null>;
|
|
2859
|
+
/**
|
|
2860
|
+
* The repository's auto-merge setting and this pull request's labels and
|
|
2861
|
+
* closing issues. The closing issues are issue data, which the VM's own
|
|
2862
|
+
* `gh` credential reads back as none rather than refusing, so on a Cursor
|
|
2863
|
+
* VM the real one also runs on the admission token (#1327).
|
|
2864
|
+
*/
|
|
2737
2865
|
readPullRequest: (input: {
|
|
2738
2866
|
owner: string;
|
|
2739
2867
|
pr: number;
|
|
2740
2868
|
repo: string;
|
|
2741
|
-
}) => PullRequestArmingFacts
|
|
2869
|
+
}) => PullRequestArmingFacts | Promise<PullRequestArmingFacts>;
|
|
2742
2870
|
}
|
|
2743
2871
|
interface PrReadyDependencies {
|
|
2872
|
+
/**
|
|
2873
|
+
* The broker's admission token on a Cursor VM (#1327), for issue reads the
|
|
2874
|
+
* VM's own `gh` credential cannot make. Defaults to the process-wide
|
|
2875
|
+
* credential, which mints nothing off a Cursor managed runtime.
|
|
2876
|
+
*/
|
|
2877
|
+
admission?: AdmissionCredential;
|
|
2744
2878
|
/**
|
|
2745
2879
|
* Arms GitHub native auto-merge for an admitted candidate (#477, #1299).
|
|
2746
2880
|
* Defaults to the real `gh pr merge --auto` call plus the read-back that
|
|
@@ -2759,6 +2893,16 @@ interface PrReadyDependencies {
|
|
|
2759
2893
|
* policy — unreadable authority is never absent authority.
|
|
2760
2894
|
*/
|
|
2761
2895
|
basePolicy?: BaseReviewPolicyAuthority;
|
|
2896
|
+
/**
|
|
2897
|
+
* #1323: where the exact-head rules read GitHub's App runs for `pr-verify`
|
|
2898
|
+
* and `pr-review` at one head. `pr:ready` refuses when any App run of
|
|
2899
|
+
* either gate at the PR head is not a completed pass (rule 4); `pr:publish`,
|
|
2900
|
+
* which inherits this, posts a gate's proof only when its head has no run
|
|
2901
|
+
* for that gate (rule 2). Defaults to the user config's App id, else the
|
|
2902
|
+
* pinned factory App id, and the real `gh api` read, since readiness is a
|
|
2903
|
+
* control and an absent dependency must not mean an unread veto.
|
|
2904
|
+
*/
|
|
2905
|
+
exactHeadRuns?: ExactHeadRunSource;
|
|
2762
2906
|
github?: {
|
|
2763
2907
|
fetchClosingPullRequests?: (input: {
|
|
2764
2908
|
issue: number;
|
|
@@ -3188,6 +3332,11 @@ interface BoundaryCheckArgs {
|
|
|
3188
3332
|
repo?: string;
|
|
3189
3333
|
}
|
|
3190
3334
|
interface BoundaryCheckDependencies {
|
|
3335
|
+
/**
|
|
3336
|
+
* The broker's admission token on a Cursor VM (#1327), for the issue reads.
|
|
3337
|
+
* Read by {@link runBoundaryCheckWithAdmission} only.
|
|
3338
|
+
*/
|
|
3339
|
+
admission?: AdmissionCredential;
|
|
3191
3340
|
github?: BoundaryCheckGithub;
|
|
3192
3341
|
hq?: HqIngestDependencies;
|
|
3193
3342
|
readWaivers?: (cwd: string) => DemandWaiver[];
|
|
@@ -3355,6 +3504,12 @@ interface PrReviewIssueBodyInput {
|
|
|
3355
3504
|
repo: string;
|
|
3356
3505
|
}
|
|
3357
3506
|
interface PrReviewDependencies {
|
|
3507
|
+
/**
|
|
3508
|
+
* The broker's admission token on a Cursor VM (#1327), for the issue reads
|
|
3509
|
+
* `--assemble` makes. Defaults to the process-wide credential, which mints
|
|
3510
|
+
* nothing off a Cursor managed runtime.
|
|
3511
|
+
*/
|
|
3512
|
+
admission?: AdmissionCredential;
|
|
3358
3513
|
/**
|
|
3359
3514
|
* Test-only seam (#1131): runs after the recording has read the proof
|
|
3360
3515
|
* state it is applied to and immediately before the compare-and-swap write,
|
|
@@ -3403,6 +3558,11 @@ interface PrReviewDependencies {
|
|
|
3403
3558
|
* measured against (#1131). Defaults to the GitHub lookup.
|
|
3404
3559
|
*/
|
|
3405
3560
|
lookupPullRequestBase?: (cwd: string) => LivePullRequestBaseLookup;
|
|
3561
|
+
/**
|
|
3562
|
+
* #1323: the detached `patronage-factory/pr-review` publisher, the same one
|
|
3563
|
+
* `pr:verify` uses. Injected by the CLI; absent, no check run is posted.
|
|
3564
|
+
*/
|
|
3565
|
+
publishCheckRun?: (input: PublishFactoryCheckInput) => void;
|
|
3406
3566
|
}
|
|
3407
3567
|
declare function runPrReview(args: PrReviewArgs, dependencies?: PrReviewDependencies): Promise<PrReviewProof>;
|
|
3408
3568
|
//#endregion
|
|
@@ -3554,6 +3714,12 @@ interface PrPublishResult {
|
|
|
3554
3714
|
* it stays an additive change to the published result contract.
|
|
3555
3715
|
*/
|
|
3556
3716
|
verificationReuse?: VerificationReuse;
|
|
3717
|
+
/**
|
|
3718
|
+
* Whether the conclusion-only pr:review check run landed for this head
|
|
3719
|
+
* (#1323). Optional so adding it stays an additive change to the published
|
|
3720
|
+
* result contract.
|
|
3721
|
+
*/
|
|
3722
|
+
reviewProofBinding?: ReviewProofBindingOutcome;
|
|
3557
3723
|
/**
|
|
3558
3724
|
* Whether the durable pr:verify check-run binding landed for this head (#247).
|
|
3559
3725
|
* Always populated from this version on; optional so adding it stays an
|
|
@@ -3568,8 +3734,17 @@ declare class PrPublishFollowUpError extends Error {
|
|
|
3568
3734
|
interface PrPublishDependencies extends PrReadyDependencies {
|
|
3569
3735
|
currentBranch?: (cwd: string) => string | undefined;
|
|
3570
3736
|
/**
|
|
3571
|
-
* Awaited
|
|
3572
|
-
*
|
|
3737
|
+
* Awaited publication of the conclusion-only `pr:review` check run for the
|
|
3738
|
+
* publish head (#1323). Returns whether the App-owned check run landed.
|
|
3739
|
+
* Injected by the CLI like the verify sink. A review cycle publish records
|
|
3740
|
+
* from `--findings` posts through it too, accepted or blocked.
|
|
3741
|
+
*/
|
|
3742
|
+
ensureReviewCheckRun?: typeof ensureFactoryCheckRunPublished;
|
|
3743
|
+
/**
|
|
3744
|
+
* Awaited post of the `pr:verify` check run once the head SHA is on GitHub
|
|
3745
|
+
* (#247), when the head has no run for it yet (#1323). Returns whether the
|
|
3746
|
+
* App-owned check run landed. A `pr:verify` publish runs fresh posts through
|
|
3747
|
+
* it too, pass or failure (#1323).
|
|
3573
3748
|
*/
|
|
3574
3749
|
ensureVerifyCheckRun?: typeof ensureFactoryCheckRunPublished;
|
|
3575
3750
|
factoryCliInvocation?: FactoryCliInvocation;
|
|
@@ -3584,7 +3759,11 @@ interface PrPublishDependencies extends PrReadyDependencies {
|
|
|
3584
3759
|
};
|
|
3585
3760
|
runFollowUp?: FollowUpRunner;
|
|
3586
3761
|
runPrReady?: typeof runPrReady;
|
|
3587
|
-
|
|
3762
|
+
/**
|
|
3763
|
+
* The review producer publish runs for `--findings`. Its second argument
|
|
3764
|
+
* carries the publisher for the verdict it records (#1323).
|
|
3765
|
+
*/
|
|
3766
|
+
runPrReview?: (args: PrReviewArgs, dependencies?: ProducerPublisher) => Promise<PrReviewProof>;
|
|
3588
3767
|
/** Settles asynchronously scheduled sink work before the handoff drain. */
|
|
3589
3768
|
awaitPendingIngest?: () => Promise<void>;
|
|
3590
3769
|
/**
|
|
@@ -3594,7 +3773,11 @@ interface PrPublishDependencies extends PrReadyDependencies {
|
|
|
3594
3773
|
flushHqSpool?: (args: {
|
|
3595
3774
|
cwd: string;
|
|
3596
3775
|
}) => Promise<HqFlushResult>;
|
|
3597
|
-
|
|
3776
|
+
/**
|
|
3777
|
+
* The verify producer publish runs when no proof applies. Its second
|
|
3778
|
+
* argument carries the publisher for the verdict it produces (#1323).
|
|
3779
|
+
*/
|
|
3780
|
+
runPrVerify?: (args: PrVerifyArgs, dependencies?: ProducerPublisher) => Promise<PrVerifyProof>;
|
|
3598
3781
|
/**
|
|
3599
3782
|
* Injectable clock for the promotion instant the hosted-run await measures
|
|
3600
3783
|
* `verify` staleness against (#1045; tests only — production reads the real
|
|
@@ -3612,13 +3795,19 @@ interface PrPublishDependencies extends PrReadyDependencies {
|
|
|
3612
3795
|
* the publish summary: a binding that silently failed to land is
|
|
3613
3796
|
* indistinguishable from verification that never happened, and the operator is
|
|
3614
3797
|
* the only one who can fix the cause (usually an unpushed head).
|
|
3798
|
+
*
|
|
3799
|
+
* #1323 (rule 2): `skipped-existing-run` means the head already has an App run
|
|
3800
|
+
* for the gate, so publish posted nothing; `skipped-unreadable` means GitHub's
|
|
3801
|
+
* runs at the head could not be read whole, so publish posted nothing either.
|
|
3615
3802
|
*/
|
|
3616
3803
|
type VerifyProofBindingOutcome = {
|
|
3617
3804
|
status: "not-attempted";
|
|
3618
3805
|
} | {
|
|
3619
3806
|
headSha: string;
|
|
3620
|
-
status:
|
|
3807
|
+
status: ExactHeadBindingStatus | "skipped-relabelled-head";
|
|
3621
3808
|
};
|
|
3809
|
+
/** What a gate's post at the publish head came to, once rule 2 has read. */
|
|
3810
|
+
type ExactHeadBindingStatus = "failed" | "published" | "skipped-existing-run" | "skipped-unreadable";
|
|
3622
3811
|
/**
|
|
3623
3812
|
* Whether publish reused the on-disk `pr:verify` proof, and the one-line reason
|
|
3624
3813
|
* (#291). Publish decides reuse silently today, which is what made the
|
|
@@ -3629,6 +3818,21 @@ interface VerificationReuse {
|
|
|
3629
3818
|
reason: string;
|
|
3630
3819
|
reused: boolean;
|
|
3631
3820
|
}
|
|
3821
|
+
/** The publisher a producer takes: `pr:verify`'s and `pr:review`'s own seam. */
|
|
3822
|
+
interface ProducerPublisher {
|
|
3823
|
+
publishCheckRun?: (input: PublishFactoryCheckInput) => void;
|
|
3824
|
+
}
|
|
3825
|
+
/**
|
|
3826
|
+
* What became of the conclusion-only `pr:review` check run for this publish
|
|
3827
|
+
* (#1323). A proof that records no review (`not-required`) has no verdict to
|
|
3828
|
+
* post.
|
|
3829
|
+
*/
|
|
3830
|
+
type ReviewProofBindingOutcome = {
|
|
3831
|
+
status: "not-attempted";
|
|
3832
|
+
} | {
|
|
3833
|
+
headSha: string;
|
|
3834
|
+
status: ExactHeadBindingStatus | "skipped-no-review" | "skipped-relabelled-head";
|
|
3835
|
+
};
|
|
3632
3836
|
/**
|
|
3633
3837
|
* Whether publish runs the follow-up `pr:ready` recommended, plus the one-line
|
|
3634
3838
|
* reason either way (#291).
|
|
@@ -4728,6 +4932,26 @@ interface HqSpoolCheckDependencies {
|
|
|
4728
4932
|
countSpool?: typeof countHqSpoolWork;
|
|
4729
4933
|
sweepOrphans?: typeof sweepHqSpoolOrphans;
|
|
4730
4934
|
}
|
|
4935
|
+
/** Test seams. Production never sets these. */
|
|
4936
|
+
interface HqReadinessCheckDependencies {
|
|
4937
|
+
fetch?: typeof fetch;
|
|
4938
|
+
resolveSecret?: SecretReferenceResolver;
|
|
4939
|
+
timeoutMs?: number;
|
|
4940
|
+
}
|
|
4941
|
+
//#endregion
|
|
4942
|
+
//#region src/doctor-machine-checks.d.ts
|
|
4943
|
+
/** Test seams. Production never sets these. */
|
|
4944
|
+
interface MachineCheckDependencies {
|
|
4945
|
+
cpuCount?: () => number;
|
|
4946
|
+
/** Whether an executable file with this name is on the PATH in `env`. */
|
|
4947
|
+
isOnPath?: (name: string, env: NodeJS.ProcessEnv) => boolean;
|
|
4948
|
+
nodeVersion?: string;
|
|
4949
|
+
platform?: NodeJS.Platform;
|
|
4950
|
+
/** A small text file's contents, or undefined when it cannot be read. */
|
|
4951
|
+
readText?: (filePath: string) => string | undefined;
|
|
4952
|
+
/** What `/bin/sh` resolves to, or undefined when it cannot be resolved. */
|
|
4953
|
+
resolveShell?: () => string | undefined;
|
|
4954
|
+
}
|
|
4731
4955
|
//#endregion
|
|
4732
4956
|
//#region src/doctor.d.ts
|
|
4733
4957
|
interface DoctorReport {
|
|
@@ -4745,8 +4969,12 @@ interface DoctorProjectProfileInput extends LoadProjectProfileInput {
|
|
|
4745
4969
|
/** Diff base for the admission preflight; ignored unless `preflight`. */
|
|
4746
4970
|
base?: string;
|
|
4747
4971
|
env?: NodeJS.ProcessEnv;
|
|
4972
|
+
/** Test seam for the HQ readiness rows (#1315); production never sets this. */
|
|
4973
|
+
hqReadinessDependencies?: HqReadinessCheckDependencies;
|
|
4748
4974
|
/** Test seam for the local HQ spool check (#394); production never sets this. */
|
|
4749
4975
|
hqSpoolDependencies?: HqSpoolCheckDependencies;
|
|
4976
|
+
/** Test seam for the machine readiness rows (#1315); production never sets this. */
|
|
4977
|
+
machineDependencies?: MachineCheckDependencies;
|
|
4750
4978
|
/**
|
|
4751
4979
|
* Append the read-only admission checklist (#292): every requirement this
|
|
4752
4980
|
* candidate must satisfy before merge, named in one pass. Preflight checks
|
|
@@ -4880,6 +5108,10 @@ interface EvaluationInput {
|
|
|
4880
5108
|
blockingReasons: string[];
|
|
4881
5109
|
notices: string[];
|
|
4882
5110
|
};
|
|
5111
|
+
exactHeadRunRefusals?: {
|
|
5112
|
+
prReview: string[];
|
|
5113
|
+
prVerify: string[];
|
|
5114
|
+
};
|
|
4883
5115
|
waivers?: DemandWaiver[];
|
|
4884
5116
|
}
|
|
4885
5117
|
declare const evaluateReadiness: (input: EvaluationInput) => {
|
|
@@ -5802,6 +6034,12 @@ declare function createProgram(options?: CreateProgramOptions): Command;
|
|
|
5802
6034
|
* runnable bin module, which follow-up commands spawn; the bin entry passes its
|
|
5803
6035
|
* own path. This function never runs itself — `./cli.js` is the only caller
|
|
5804
6036
|
* that does (#386).
|
|
6037
|
+
*
|
|
6038
|
+
* On the way out it waits for the command's own check-run publications
|
|
6039
|
+
* (bounded, #1322) and HQ emissions, then drains
|
|
6040
|
+
* the checkout's HQ spool once (#1313). This is the one place that drains on
|
|
6041
|
+
* exit. `pr:ready` then prints one line if events are still spooled (#1317).
|
|
6042
|
+
* None of these steps can throw or change the command's exit code.
|
|
5805
6043
|
*/
|
|
5806
6044
|
declare function run(argv?: string[], cliEntry?: string): Promise<void>;
|
|
5807
6045
|
//#endregion
|