@patronage/software-factory 1.0.0-alpha.19 → 1.0.0-alpha.20

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 CHANGED
@@ -927,8 +927,8 @@ declare const mergeFreezeStateSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
927
927
  generationId: z.ZodNumber;
928
928
  headSha: z.ZodString;
929
929
  outcome: z.ZodEnum<{
930
- stale: "stale";
931
930
  active: "active";
931
+ stale: "stale";
932
932
  }>;
933
933
  reason: z.ZodString;
934
934
  recordedAt: z.ZodISODateTime;
@@ -1336,9 +1336,9 @@ declare const managedReadinessLedgerSchema: z.ZodObject<{
1336
1336
  mergeable: z.ZodString;
1337
1337
  requiredChecks: z.ZodEnum<{
1338
1338
  unknown: "unknown";
1339
+ pending: "pending";
1339
1340
  passed: "passed";
1340
1341
  failed: "failed";
1341
- pending: "pending";
1342
1342
  none: "none";
1343
1343
  }>;
1344
1344
  reviewDecision: z.ZodOptional<z.ZodNullable<z.ZodString>>;
@@ -1404,8 +1404,8 @@ declare const managedReadinessLedgerSchema: z.ZodObject<{
1404
1404
  "run-interior-cycle": "run-interior-cycle";
1405
1405
  }>;
1406
1406
  stage: z.ZodEnum<{
1407
- gate: "gate";
1408
1407
  interior: "interior";
1408
+ gate: "gate";
1409
1409
  "interior-complete": "interior-complete";
1410
1410
  }>;
1411
1411
  }, z.core.$strip>>;
@@ -1421,10 +1421,10 @@ declare const managedReadinessLedgerSchema: z.ZodObject<{
1421
1421
  reviewedHeadSha: z.ZodOptional<z.ZodString>;
1422
1422
  reviewedPatchId: z.ZodOptional<z.ZodString>;
1423
1423
  status: z.ZodEnum<{
1424
- blocked: "blocked";
1425
1424
  "not-required": "not-required";
1426
- current: "current";
1427
1425
  stale: "stale";
1426
+ blocked: "blocked";
1427
+ current: "current";
1428
1428
  missing: "missing";
1429
1429
  }>;
1430
1430
  }, z.core.$strip>;
@@ -1433,10 +1433,10 @@ declare const managedReadinessLedgerSchema: z.ZodObject<{
1433
1433
  reviewedHeadSha: z.ZodOptional<z.ZodString>;
1434
1434
  reviewedPatchId: z.ZodOptional<z.ZodString>;
1435
1435
  status: z.ZodEnum<{
1436
- blocked: "blocked";
1437
1436
  "not-required": "not-required";
1438
- current: "current";
1439
1437
  stale: "stale";
1438
+ blocked: "blocked";
1439
+ current: "current";
1440
1440
  missing: "missing";
1441
1441
  }>;
1442
1442
  }, z.core.$strip>>;
@@ -1447,8 +1447,8 @@ declare const managedReadinessLedgerSchema: z.ZodObject<{
1447
1447
  docsOnlyDeltaAccepted: z.ZodOptional<z.ZodBoolean>;
1448
1448
  docsOnlyVerifiedHeadSha: z.ZodOptional<z.ZodString>;
1449
1449
  prVerify: z.ZodEnum<{
1450
- passed: "passed";
1451
1450
  stale: "stale";
1451
+ passed: "passed";
1452
1452
  missing: "missing";
1453
1453
  }>;
1454
1454
  trivialDeltaAccepted: z.ZodOptional<z.ZodBoolean>;
@@ -1934,6 +1934,13 @@ interface PresentFactoryPrStatusHudDependencies {
1934
1934
  }
1935
1935
  interface ReadFactoryPrStatusSourcesInput {
1936
1936
  readonly headSha: string;
1937
+ /**
1938
+ * Read token for `previewProofInventory.list`. The list walks the
1939
+ * force-push timeline, which needs commit (contents) read; the Factory App
1940
+ * token has no contents permission, so pass a workflow `GITHUB_TOKEN`
1941
+ * (#825). Falls back to `token`.
1942
+ */
1943
+ readonly inventoryToken?: string;
1937
1944
  readonly owner: string;
1938
1945
  readonly pr: number;
1939
1946
  /**
@@ -2369,10 +2376,10 @@ declare const loadEvidenceEnvelopes: (cwd: string) => LoadedEvidenceEnvelope[];
2369
2376
  //#region src/review-proof-applicability.d.ts
2370
2377
  declare const REVIEW_STATUS_VALUES: readonly ["not-required", "current", "stale", "missing", "blocked"];
2371
2378
  declare const reviewStatusSchema: z.ZodEnum<{
2372
- blocked: "blocked";
2373
2379
  "not-required": "not-required";
2374
- current: "current";
2375
2380
  stale: "stale";
2381
+ blocked: "blocked";
2382
+ current: "current";
2376
2383
  missing: "missing";
2377
2384
  }>;
2378
2385
  type ReviewStatus = z.infer<typeof reviewStatusSchema>;
@@ -2865,6 +2872,12 @@ type PrReviewAction = (args: PrReviewArgs) => Promise<unknown>;
2865
2872
  interface PrStatusHudArgs {
2866
2873
  readonly cwd: string;
2867
2874
  readonly headSha: string;
2875
+ /**
2876
+ * Read token for the preview-proof inventory list. The App token cannot
2877
+ * read the force-push timeline (no contents permission), so the workflow
2878
+ * `GITHUB_TOKEN` serves that read (#825).
2879
+ */
2880
+ readonly inventoryToken?: string;
2868
2881
  readonly owner: string;
2869
2882
  readonly planPath?: string;
2870
2883
  readonly pr: number;
@@ -2950,11 +2963,11 @@ declare const LegacyWorkerCloseoutStatusTraceEventSchema: z.ZodObject<{
2950
2963
  threadId: z.ZodOptional<z.ZodString>;
2951
2964
  workerId: z.ZodOptional<z.ZodString>;
2952
2965
  archiveStatus: z.ZodOptional<z.ZodEnum<{
2953
- pending: "pending";
2954
2966
  unavailable: "unavailable";
2955
2967
  archived: "archived";
2956
2968
  skipped: "skipped";
2957
2969
  "not-applicable": "not-applicable";
2970
+ pending: "pending";
2958
2971
  }>>;
2959
2972
  closeoutReason: z.ZodOptional<z.ZodString>;
2960
2973
  eventType: z.ZodLiteral<"worker-closeout-lessons">;
@@ -3124,8 +3137,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3124
3137
  sessionId: z.ZodOptional<z.ZodString>;
3125
3138
  }, z.core.$strict>>;
3126
3139
  stage: z.ZodEnum<{
3127
- gate: "gate";
3128
3140
  interior: "interior";
3141
+ gate: "gate";
3129
3142
  }>;
3130
3143
  usage: z.ZodOptional<z.ZodObject<{
3131
3144
  estimatedCostUsd: z.ZodOptional<z.ZodNumber>;
@@ -3177,8 +3190,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3177
3190
  sessionId: z.ZodOptional<z.ZodString>;
3178
3191
  }, z.core.$strict>>;
3179
3192
  stage: z.ZodEnum<{
3180
- gate: "gate";
3181
3193
  interior: "interior";
3194
+ gate: "gate";
3182
3195
  }>;
3183
3196
  usage: z.ZodOptional<z.ZodObject<{
3184
3197
  estimatedCostUsd: z.ZodOptional<z.ZodNumber>;
@@ -3221,8 +3234,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3221
3234
  sessionId: z.ZodOptional<z.ZodString>;
3222
3235
  }, z.core.$strict>>;
3223
3236
  stage: z.ZodEnum<{
3224
- gate: "gate";
3225
3237
  interior: "interior";
3238
+ gate: "gate";
3226
3239
  }>;
3227
3240
  usage: z.ZodOptional<z.ZodObject<{
3228
3241
  estimatedCostUsd: z.ZodOptional<z.ZodNumber>;
@@ -3252,7 +3265,7 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3252
3265
  staleRepeats: number;
3253
3266
  };
3254
3267
  observedAt: string;
3255
- stage: "gate" | "interior";
3268
+ stage: "interior" | "gate";
3256
3269
  issue?: number | undefined;
3257
3270
  pr?: number | undefined;
3258
3271
  threadId?: string | undefined;
@@ -3345,11 +3358,11 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3345
3358
  threadId: z.ZodOptional<z.ZodString>;
3346
3359
  workerId: z.ZodOptional<z.ZodString>;
3347
3360
  archiveStatus: z.ZodOptional<z.ZodEnum<{
3348
- pending: "pending";
3349
3361
  unavailable: "unavailable";
3350
3362
  archived: "archived";
3351
3363
  skipped: "skipped";
3352
3364
  "not-applicable": "not-applicable";
3365
+ pending: "pending";
3353
3366
  }>>;
3354
3367
  closeoutReason: z.ZodOptional<z.ZodString>;
3355
3368
  eventType: z.ZodLiteral<"worker-closeout-lessons">;
@@ -3386,11 +3399,11 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3386
3399
  }, z.core.$strict>], "lessonStatus">;
3387
3400
  readonly 2: z.ZodObject<{
3388
3401
  archiveStatus: z.ZodOptional<z.ZodEnum<{
3389
- pending: "pending";
3390
3402
  unavailable: "unavailable";
3391
3403
  archived: "archived";
3392
3404
  skipped: "skipped";
3393
3405
  "not-applicable": "not-applicable";
3406
+ pending: "pending";
3394
3407
  }>>;
3395
3408
  closeoutReason: z.ZodOptional<z.ZodString>;
3396
3409
  lessonStatus: z.ZodOptional<z.ZodEnum<{
@@ -3508,8 +3521,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3508
3521
  interiorCycle: z.ZodOptional<z.ZodNumber>;
3509
3522
  observedAt: z.ZodString;
3510
3523
  purpose: z.ZodEnum<{
3511
- code: "code";
3512
3524
  review: "review";
3525
+ code: "code";
3513
3526
  }>;
3514
3527
  slotResolution: z.ZodObject<{
3515
3528
  effort: z.ZodEnum<{
@@ -3587,8 +3600,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3587
3600
  interiorCycle: z.ZodOptional<z.ZodNumber>;
3588
3601
  observedAt: z.ZodString;
3589
3602
  purpose: z.ZodEnum<{
3590
- code: "code";
3591
3603
  review: "review";
3604
+ code: "code";
3592
3605
  }>;
3593
3606
  slotResolution: z.ZodObject<{
3594
3607
  effort: z.ZodEnum<{
@@ -3657,8 +3670,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3657
3670
  interiorCycle: z.ZodOptional<z.ZodNumber>;
3658
3671
  observedAt: z.ZodString;
3659
3672
  purpose: z.ZodEnum<{
3660
- code: "code";
3661
3673
  review: "review";
3674
+ code: "code";
3662
3675
  }>;
3663
3676
  slotResolution: z.ZodObject<{
3664
3677
  effort: z.ZodEnum<{
@@ -3730,7 +3743,7 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
3730
3743
  exitCode: number | null;
3731
3744
  harness: string;
3732
3745
  observedAt: string;
3733
- purpose: "code" | "review";
3746
+ purpose: "review" | "code";
3734
3747
  slotResolution: {
3735
3748
  effort: "high" | "low" | "medium" | "xhigh";
3736
3749
  engine: string;
@@ -4013,7 +4026,7 @@ declare const CORRECTNESS_UNTYPED_REVIEW_BLOCKER_REASON = "Correctness review pr
4013
4026
  declare const SECURITY_UNTYPED_REVIEW_BLOCKER_REASON = "Security review proof is not a head-bound typed findings verdict; re-run pr:review with a valid findings file.";
4014
4027
  declare const DRAFT_BLOCKER_REASON = "PR is still marked draft.";
4015
4028
  declare const PENDING_CHECKS_BLOCKER_REASON_PREFIX = "Required/current checks are";
4016
- declare const readinessExitCode: (status: ReadinessStatus) => 0 | 1;
4029
+ declare const readinessExitCode: (status: ReadinessStatus) => 1 | 0;
4017
4030
  interface EvaluationInput {
4018
4031
  pr: number;
4019
4032
  prTitle?: string;
@@ -4062,7 +4075,7 @@ declare const evaluateReadiness: (input: EvaluationInput) => {
4062
4075
  draft: boolean;
4063
4076
  mergeStateStatus: string;
4064
4077
  mergeable: string;
4065
- requiredChecks: "unknown" | "passed" | "failed" | "pending" | "none";
4078
+ requiredChecks: "unknown" | "pending" | "passed" | "failed" | "none";
4066
4079
  unresolvedReviewThreads: number;
4067
4080
  reviewDecision?: string | null | undefined;
4068
4081
  };
@@ -4077,13 +4090,13 @@ declare const evaluateReadiness: (input: EvaluationInput) => {
4077
4090
  reviews: {
4078
4091
  correctness: {
4079
4092
  required: boolean;
4080
- status: "blocked" | "not-required" | "current" | "stale" | "missing";
4093
+ status: "not-required" | "stale" | "blocked" | "current" | "missing";
4081
4094
  reviewedHeadSha?: string | undefined;
4082
4095
  reviewedPatchId?: string | undefined;
4083
4096
  };
4084
4097
  security?: {
4085
4098
  required: boolean;
4086
- status: "blocked" | "not-required" | "current" | "stale" | "missing";
4099
+ status: "not-required" | "stale" | "blocked" | "current" | "missing";
4087
4100
  reviewedHeadSha?: string | undefined;
4088
4101
  reviewedPatchId?: string | undefined;
4089
4102
  } | undefined;
@@ -4091,7 +4104,7 @@ declare const evaluateReadiness: (input: EvaluationInput) => {
4091
4104
  schemaVersion: 1;
4092
4105
  verification: {
4093
4106
  command: "patronage-factory pr:verify";
4094
- prVerify: "passed" | "stale" | "missing";
4107
+ prVerify: "stale" | "passed" | "missing";
4095
4108
  docsOnlyDeltaAccepted?: boolean | undefined;
4096
4109
  docsOnlyVerifiedHeadSha?: string | undefined;
4097
4110
  trivialDeltaAccepted?: boolean | undefined;
@@ -4134,7 +4147,7 @@ declare const evaluateReadiness: (input: EvaluationInput) => {
4134
4147
  interior: number;
4135
4148
  };
4136
4149
  nextAction: "run-gate-cycle" | "accept-nonblocking-findings" | "escalate-to-triage" | "ready-for-human" | "advance-to-gate" | "run-interior-cycle";
4137
- stage: "gate" | "interior" | "interior-complete";
4150
+ stage: "interior" | "gate" | "interior-complete";
4138
4151
  forcedTransition?: "gate-cap-exhausted" | "interior-cap-reached" | undefined;
4139
4152
  } | undefined;
4140
4153
  reviewRuns?: PrReviewResult[] | undefined;
package/dist/index.js CHANGED
@@ -17,7 +17,7 @@ import { parse } from "yaml";
17
17
  import { FACTORY_PROOF_GATE_APP_ID, FACTORY_PROOF_GATE_STEP_NAME, GitHubApiError, mintInstallationToken, previewProofInventory, productionImpactTargetOutput, readVitestProfileDocument } from "@patronage/factory-ci";
18
18
  import { promisify } from "node:util";
19
19
  //#region package.json
20
- var version = "1.0.0-alpha.19";
20
+ var version = "1.0.0-alpha.20";
21
21
  //#endregion
22
22
  //#region src/review-rungs.ts
23
23
  const EVIDENCE_REVIEW_RUNGS$1 = [
@@ -6038,7 +6038,7 @@ const renderReport = (record) => {
6038
6038
  return `${lines.join("\n")}\n`;
6039
6039
  };
6040
6040
  function createBoundaryCheckCommand(output, action) {
6041
- return markCwdOptionDefault(new Command("boundary:check").description("Boundary readiness gate (T8): require a membership-fresh boundary-review proof at the declared closeout rung. Blocks closeout/enablement, never merge.").requiredOption("--epic <number>", "epic issue number carrying the factory-boundary manifest", positiveInteger$1("--epic")).option("--repo <owner/name>", "GitHub repository (default: resolved from --cwd)").option("--cwd <path>", "repository working directory", collectCwdOption).option("--output <path>", "write an additional proof copy to this path").option("--profile <path>", "path to the project profile JSON file").option("--json", "print the full proof record as JSON").action(withGateTiming({
6041
+ return markCwdOptionDefault(new Command("boundary:check").description("Boundary readiness gate (T8): require a membership-fresh boundary-review proof at the declared closeout rung. Blocks closeout/enablement, never merge.").requiredOption("--epic <number>", "issue number carrying the factory-boundary manifest, which may be the work issue itself (#789)", positiveInteger$1("--epic")).option("--repo <owner/name>", "GitHub repository (default: resolved from --cwd)").option("--cwd <path>", "repository working directory", collectCwdOption).option("--output <path>", "write an additional proof copy to this path").option("--profile <path>", "path to the project profile JSON file").option("--json", "print the full proof record as JSON").action(withGateTiming({
6042
6042
  gate: "boundary:check",
6043
6043
  resolveLedgerRoot: (options) => resolveCwdOption(options.cwd),
6044
6044
  stderr: output.stderr
@@ -10885,9 +10885,20 @@ const defaultFetchIssueBody = ({ issue, owner, repo }) => runGhJson([
10885
10885
  "body"
10886
10886
  ]).body;
10887
10887
  /**
10888
- * Resolve the wave demand for a PR from an epic's boundary manifest, fail
10888
+ * The one-issue wrapper warning (#789). A boundary that declares exactly one
10889
+ * wave issue, and is not that issue, is a wrapper around a work issue that
10890
+ * could carry the fence itself. The factory never required a second issue, so
10891
+ * this is a notice and never a refusal.
10892
+ */
10893
+ const wrapperBoundaryNotices = ({ epic, manifest }) => {
10894
+ const issues = manifest.waves.flatMap((wave) => wave.issues);
10895
+ const [only] = issues;
10896
+ return issues.length === 1 && only !== void 0 && only !== epic ? [`Issue #${epic} declares one wave issue, #${only}, and is not that issue: this boundary wraps a single work issue. The factory-boundary fence can live on the work issue instead — move it to #${only} and run pr:ready --epic ${only}. A second "Boundary: admit ..." issue is not a factory requirement.`] : [];
10897
+ };
10898
+ /**
10899
+ * Resolve the wave demand for a PR from a boundary issue's manifest, fail
10889
10900
  * closed: an absent, unparseable, or unmatched manifest binds nothing and
10890
- * names its refusal.
10901
+ * names its refusal. The boundary issue may be the work issue itself (#789).
10891
10902
  */
10892
10903
  const resolveWaveDemand = ({ baseRefName, epic, fetchClosingPullRequests = defaultFetchClosingPullRequests, fetchIssueBody = defaultFetchIssueBody, headRefName, owner, pr, repo }) => {
10893
10904
  const parsed = parseBoundaryManifest(fetchIssueBody({
@@ -10896,6 +10907,10 @@ const resolveWaveDemand = ({ baseRefName, epic, fetchClosingPullRequests = defau
10896
10907
  repo
10897
10908
  }));
10898
10909
  if (!parsed.ok) return { reasons: [`Epic #${epic} boundary manifest refused: ${parsed.error}`] };
10910
+ const notices = wrapperBoundaryNotices({
10911
+ epic,
10912
+ manifest: parsed.manifest
10913
+ });
10899
10914
  const resolution = waveDemandForPullRequest({
10900
10915
  fetchClosingPullRequests,
10901
10916
  manifest: parsed.manifest,
@@ -10903,9 +10918,13 @@ const resolveWaveDemand = ({ baseRefName, epic, fetchClosingPullRequests = defau
10903
10918
  pr,
10904
10919
  repo
10905
10920
  });
10906
- if (!resolution.demand) return resolution;
10921
+ if (!resolution.demand) return {
10922
+ ...resolution,
10923
+ ...notices.length > 0 ? { notices } : {}
10924
+ };
10907
10925
  return {
10908
10926
  demand: resolution.demand,
10927
+ ...notices.length > 0 ? { notices } : {},
10909
10928
  reasons: pullRequestTopologyReasons({
10910
10929
  manifest: parsed.manifest,
10911
10930
  pullRequest: {
@@ -14841,7 +14860,12 @@ async function readFactoryPrStatusSources(input, dependencies = {}) {
14841
14860
  timeoutMs: dependencies.timeoutMs,
14842
14861
  token: identity.token
14843
14862
  }));
14844
- const [previewRegistrations, pullIdentity] = await Promise.all([listPreviews(input), readFactoryPrIdentity(input, dependencies)]);
14863
+ const [previewRegistrations, pullIdentity] = await Promise.all([listPreviews({
14864
+ owner: input.owner,
14865
+ pr: input.pr,
14866
+ repo: input.repo,
14867
+ token: input.inventoryToken ?? input.token
14868
+ }), readFactoryPrIdentity(input, dependencies)]);
14845
14869
  if (pullIdentity.head.sha !== input.headSha) throw new Error(`PR status HUD candidate head moved to ${pullIdentity.head.sha}; refusing stale presentation for ${input.headSha}.`);
14846
14870
  const baseSha = pullIdentity.base.sha;
14847
14871
  const checkTargets = [
@@ -15287,7 +15311,7 @@ async function runPrReady(args, dependencies = {}) {
15287
15311
  pr: args.pr,
15288
15312
  repo: repository.name
15289
15313
  });
15290
- if (waveDemand && waveDemand.reasons.length > 0) throw new Error(`pr:ready --epic ${args.epic} could not resolve this PR's wave demand: ${waveDemand.reasons.join(" ")}`);
15314
+ if (waveDemand && waveDemand.reasons.length > 0) throw new Error(`pr:ready --epic ${args.epic} could not resolve this PR's wave demand: ${[...waveDemand.reasons, ...waveDemand.notices ?? []].join(" ")}`);
15291
15315
  const reviewProof = readOptionalReviewProof(cwd, reviewProofPath);
15292
15316
  const docsOnlyDeltaAcceptedSince = (baselineHeadSha) => docsOnlyDeltaSinceHead({
15293
15317
  cwd,
@@ -15388,7 +15412,8 @@ async function runPrReady(args, dependencies = {}) {
15388
15412
  const notices = [
15389
15413
  ...evaluation.notices,
15390
15414
  ...arming ? [armingNotice(arming)] : [],
15391
- ...evaluation.status === "ready" && !boundary ? ["No boundary wave authorized this candidate, so nothing was armed: pr:ready admits it but schedules no merge. Re-run with --epic <issue> to resolve the wave demand and arm."] : [],
15415
+ ...waveDemand?.notices ?? [],
15416
+ ...evaluation.status === "ready" && !boundary ? ["No boundary wave authorized this candidate, so nothing was armed: pr:ready admits it but schedules no merge. Re-run with --epic <issue> to resolve the wave demand and arm. That issue can be the work issue itself, carrying its own fence; do not file a second boundary issue for one candidate."] : [],
15392
15417
  ...evaluation.status === "ready" && boundary?.autoMerge === false ? [`This candidate is admitted but unscheduled: boundary wave ${boundary.wave} does not authorize machine merge. GitHub auto-merge remains disabled; use the attended merge operation authorized for this wave.`] : []
15393
15418
  ];
15394
15419
  const proof = {
@@ -16610,7 +16635,7 @@ async function deliverSpooledEvidence({ awaitPending, cwd, flush, profilePath })
16610
16635
  //#endregion
16611
16636
  //#region src/commands/pr-publish.ts
16612
16637
  function createPrPublishCommand(_output, action = runPrPublish) {
16613
- return markCwdOptionDefault(new Command("pr:publish").description("Promote a proved draft, then evaluate Candidate demands; never launches review").option("--pr <number>", "pull request number", positiveInteger$1("--pr")).option("--base <ref>", "local base Git ref assertion; origin/<branch> creates against GitHub <branch>").option("--authoring-session <id>", "known authoring session identity for verification retries").option("--cwd <path>", "working directory to evaluate", collectCwdOption).option("--epic <number>", "epic issue containing the factory-boundary manifest; the composed readiness evaluation then applies the wave-demanded review rung (#351)", positiveInteger$1("--epic")).option("--findings <path>", "clean-session findings to validate when no current review proof is available").option("--json", "print the publish result as JSON").option("--output <path>", "write readiness proof JSON to a file").option("--profile <path>", "path to the project profile JSON file").option("--review-proof <path>", "pr:review proof JSON path").option("--verify-proof <path>", "pr:verify proof JSON path").action(async (options) => {
16638
+ return markCwdOptionDefault(new Command("pr:publish").description("Promote a proved draft, then evaluate Candidate demands; never launches review").option("--pr <number>", "pull request number", positiveInteger$1("--pr")).option("--base <ref>", "local base Git ref assertion; origin/<branch> creates against GitHub <branch>").option("--authoring-session <id>", "known authoring session identity for verification retries").option("--cwd <path>", "working directory to evaluate", collectCwdOption).option("--epic <number>", "issue carrying the factory-boundary manifest, which may be the work issue itself; the composed readiness evaluation then applies the wave-demanded review rung (#351, #789)", positiveInteger$1("--epic")).option("--findings <path>", "clean-session findings to validate when no current review proof is available").option("--json", "print the publish result as JSON").option("--output <path>", "write readiness proof JSON to a file").option("--profile <path>", "path to the project profile JSON file").option("--review-proof <path>", "pr:review proof JSON path").option("--verify-proof <path>", "pr:verify proof JSON path").action(async (options) => {
16614
16639
  await action({
16615
16640
  authoringSessionIds: options.authoringSession ? [options.authoringSession] : void 0,
16616
16641
  base: options.base ?? "",
@@ -16629,7 +16654,7 @@ function createPrPublishCommand(_output, action = runPrPublish) {
16629
16654
  //#endregion
16630
16655
  //#region src/commands/pr-ready.ts
16631
16656
  function createPrReadyCommand(output, action) {
16632
- return markCwdOptionDefault(new Command("pr:ready").description("Evaluate typed proof and GitHub state for final readiness").requiredOption("--pr <number>", "pull request number", positiveInteger$1("--pr")).option("--base <ref>", "explicit base branch or ref override").option("--authoring-session <id...>", "recorded authoring session id(s) for review-type requiredCheck independence (ADR 0014 §5)").option("--cwd <path>", "working directory to evaluate", collectCwdOption).option("--epic <number>", "epic issue containing the factory-boundary manifest; readiness then evaluates the wave-demanded review rung (#351)", positiveInteger$1("--epic")).option("--json", "print the readiness proof as JSON").option("--output <path>", "write proof JSON to a file").option("--profile <path>", "path to the project profile JSON file").option("--review-proof <path>", "pr:review proof JSON path").option("--verify-proof <path>", "pr:verify proof JSON path").action(withGateTiming({
16657
+ return markCwdOptionDefault(new Command("pr:ready").description("Evaluate typed proof and GitHub state for final readiness").requiredOption("--pr <number>", "pull request number", positiveInteger$1("--pr")).option("--base <ref>", "explicit base branch or ref override").option("--authoring-session <id...>", "recorded authoring session id(s) for review-type requiredCheck independence (ADR 0014 §5)").option("--cwd <path>", "working directory to evaluate", collectCwdOption).option("--epic <number>", "issue carrying the factory-boundary manifest, which may be the work issue itself; readiness then evaluates the wave-demanded review rung (#351, #789)", positiveInteger$1("--epic")).option("--json", "print the readiness proof as JSON").option("--output <path>", "write proof JSON to a file").option("--profile <path>", "path to the project profile JSON file").option("--review-proof <path>", "pr:review proof JSON path").option("--verify-proof <path>", "pr:verify proof JSON path").action(withGateTiming({
16633
16658
  gate: "pr:ready",
16634
16659
  resolveLedgerRoot: (options) => resolveCwdOption(options.cwd),
16635
16660
  stderr: output.stderr
@@ -16911,6 +16936,7 @@ async function runPrStatusHud(args) {
16911
16936
  }),
16912
16937
  readSources: (identity) => readFactoryPrStatusSources({
16913
16938
  ...identity,
16939
+ ...args.inventoryToken === void 0 ? {} : { inventoryToken: args.inventoryToken },
16914
16940
  token: args.token
16915
16941
  }),
16916
16942
  upsert: (input) => upsertFactoryPrStatusComment(input, { request: (request) => requestFactoryApp(request, { token: args.token }) })
@@ -16920,9 +16946,11 @@ function createPrStatusHudCommand(output, action = runPrStatusHud, env = process
16920
16946
  return markCwdOptionDefault(new Command("pr:status-hud").description("Present the App-owned PR status HUD from planPreviewLifecycle").requiredOption("--head <sha>", "candidate head commit SHA").requiredOption("--owner <owner>", "GitHub repository owner").requiredOption("--repo <repo>", "GitHub repository name").requiredOption("--pr <number>", "pull request number", positiveInteger$1("--pr")).option("--plan <path>", "optional candidate-bound JSON envelope; when omitted, planPreviewLifecycle is consumed from the checkout").option("--cwd <path>", "repository working directory", collectCwdOption).action(async (options) => {
16921
16947
  const token = env.FACTORY_GITHUB_APP_TOKEN;
16922
16948
  if (!token) throw new Error("pr:status-hud requires FACTORY_GITHUB_APP_TOKEN from actions/create-github-app-token; a workflow GITHUB_TOKEN cannot own the Factory App comment.");
16949
+ const inventoryToken = env.GITHUB_TOKEN;
16923
16950
  const result = await action({
16924
16951
  cwd: resolveCwdOption(options.cwd),
16925
16952
  headSha: shaSchema.parse(options.head),
16953
+ ...inventoryToken ? { inventoryToken } : {},
16926
16954
  owner: options.owner,
16927
16955
  ...options.plan === void 0 ? {} : { planPath: options.plan },
16928
16956
  pr: options.pr,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patronage/software-factory",
3
- "version": "1.0.0-alpha.19",
3
+ "version": "1.0.0-alpha.20",
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.19"
40
+ "@patronage/factory-ci": "1.0.0-alpha.20"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/node": "24.13.3",