@patronage/software-factory 0.30.0 → 1.0.0-alpha.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/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  The factory admits a pull request from evidence bound to its candidate. It validates policy and proof; it does not schedule workers, choose models, or run reviews. Those are jobs for the harness or operator.
6
6
 
7
- Admission is fail closed. A clean-session review and required verification produce typed proof, then readiness decides whether the candidate may proceed. Evidence stays current when the candidate patch is unchanged; the main-push verify workflow covers integration risk and freezes further merges when main goes red. Epic policy, including review minimums and auto-merge authority, lives in the boundary manifest. HQ observes this work; it never blocks a gate.
7
+ Admission is fail closed. A clean-session review and required verification produce typed proof, then readiness decides whether the candidate may proceed. Evidence stays current when the candidate patch is unchanged; the push-triggered Verify workflow covers integration risk on every factory merge target and freezes further merges into a target when that target goes red. Epic policy, including review minimums and auto-merge authority, lives in the boundary manifest. HQ observes this work; it never blocks a gate.
8
8
 
9
9
  ## Develop the package
10
10
 
package/dist/index.d.ts CHANGED
@@ -533,6 +533,12 @@ declare const factoryProjectProfileSchema: z.ZodObject<{
533
533
  enabled: z.ZodBoolean;
534
534
  endpoint: z.ZodIntersection<z.ZodString, z.ZodString>;
535
535
  }, z.core.$strict>>;
536
+ impact: z.ZodOptional<z.ZodObject<{
537
+ targets: z.ZodArray<z.ZodObject<{
538
+ importers: z.ZodArray<z.ZodString>;
539
+ name: z.ZodString;
540
+ }, z.core.$strict>>;
541
+ }, z.core.$strict>>;
536
542
  proof: z.ZodObject<{
537
543
  classificationPolicy: z.ZodObject<{
538
544
  docsOnly: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -563,6 +569,7 @@ declare const factoryProjectProfileSchema: z.ZodObject<{
563
569
  commands: z.ZodArray<z.ZodObject<{
564
570
  command: z.ZodString;
565
571
  description: z.ZodString;
572
+ impactTarget: z.ZodOptional<z.ZodString>;
566
573
  name: z.ZodString;
567
574
  requiredCheck: z.ZodOptional<z.ZodString>;
568
575
  scope: z.ZodDefault<z.ZodEnum<{
@@ -763,8 +770,8 @@ declare const mergeFreezeStateSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
763
770
  }, z.core.$strip>], "active">;
764
771
  type MergeFreezeState = z.infer<typeof mergeFreezeStateSchema>;
765
772
  /**
766
- * The write side of this contract lives in the generated main-push verify
767
- * workflow (#356, ADR 0016 as amended): it is the ONLY producer of
773
+ * The write side of this contract lives in the generated merge-target push
774
+ * Verify workflow (#356, ADR 0016 as amended; #429): it is the ONLY producer of
768
775
  * `patronage-factory/merge-freeze` generations. Its emitted `output.text`
769
776
  * payload must parse under this exact reader schema, which is what the
770
777
  * workflow's own tests assert through this export.
@@ -784,7 +791,7 @@ interface MergeFreezeStore {
784
791
  * `read` above collapses three different situations into one refusal, because
785
792
  * merge time treated all of them as "do not merge". Readiness distinguishes
786
793
  * them: a settled generation is the writer's verdict, a **settling** one is the
787
- * window between a merge landing and its main-push verify completing (a
794
+ * window between a merge landing and its merge-target Verify completing (a
788
795
  * running generation, or a missing generation proven by the immediately prior
789
796
  * settled tip plus a current source-pinned verify run), and an **unreadable**
790
797
  * one is ambiguous, malformed, foreign-App, or unavailable state. Same
@@ -1506,6 +1513,76 @@ declare function validatePrReadyProof(value: unknown): PrReadyProof;
1506
1513
  declare function readPrReadyProof(filePath: string): PrReadyProof;
1507
1514
  declare function runPrReady(args: PrReadyArgs, dependencies?: PrReadyDependencies): Promise<PrReadyProof>;
1508
1515
  //#endregion
1516
+ //#region src/impact-stamp.d.ts
1517
+ /**
1518
+ * The recorded stamp. `targets` satisfies the completeness invariant: every
1519
+ * target the profile declares is present, each with its exact basis — never
1520
+ * silently absent. `basis: "conservative"` means an unmodelled or unprovable
1521
+ * input widened every target to full impact.
1522
+ */
1523
+ declare const impactStampSchema: z.ZodObject<{
1524
+ basis: z.ZodEnum<{
1525
+ "lockfile-scoped": "lockfile-scoped";
1526
+ conservative: "conservative";
1527
+ }>;
1528
+ reasons: z.ZodArray<z.ZodString>;
1529
+ stampVersion: z.ZodLiteral<1>;
1530
+ targets: z.ZodArray<z.ZodObject<{
1531
+ basis: z.ZodString;
1532
+ impact: z.ZodEnum<{
1533
+ affected: "affected";
1534
+ "not-affected": "not-affected";
1535
+ }>;
1536
+ name: z.ZodString;
1537
+ }, z.core.$strip>>;
1538
+ }, z.core.$strip>;
1539
+ type ImpactStamp = z.infer<typeof impactStampSchema>;
1540
+ /**
1541
+ * The surfaces that consume the stamp. One classification, consumed
1542
+ * everywhere (#430): every surface routes through
1543
+ * {@link impactStampScopeDecision}, so no surface can be more trusting than
1544
+ * another, and no surface re-derives path rules of its own. The value only
1545
+ * selects the wording of the conservative floor a refusal falls back to.
1546
+ */
1547
+ declare const IMPACT_SCOPE_SURFACES: {
1548
+ readonly demand: "full demand floor";
1549
+ readonly "preview-lifecycle": "full preview-lifecycle floor";
1550
+ readonly "verification-battery": "full verification-battery floor";
1551
+ };
1552
+ type ImpactScopeSurface = keyof typeof IMPACT_SCOPE_SURFACES;
1553
+ interface ImpactScopeDecision {
1554
+ reason: string;
1555
+ /** True ⇒ this target's work is provably unreachable and may be released. */
1556
+ scoped: boolean;
1557
+ }
1558
+ /**
1559
+ * Whether a trusted stamp RELEASES one target-scoped unit of work — an
1560
+ * external proof demand (#542 wave 2), a verification-battery command, or a
1561
+ * preview (Alchemy) lifecycle stack (#430 wave 3).
1562
+ *
1563
+ * The only release path is a `lockfile-scoped` stamp of exactly this build's
1564
+ * stamp version whose target entry for exactly this name is provably
1565
+ * `not-affected`. Every other input — no trusted stamp, an unknown stamp
1566
+ * version, a conservative stamp, a name the stamp does not classify, or an
1567
+ * `affected` verdict — keeps today's full-work floor. Work only ever gets
1568
+ * released, never added or satisfied: this function can withdraw a demand, it
1569
+ * can never certify one.
1570
+ *
1571
+ * Identity binding is the CALLER's precondition: pass only a stamp computed
1572
+ * for, or read from a pr:verify proof bound to, the current candidate (see
1573
+ * `trustedImpactStamp` in `pr-readiness/verification-proof.ts`); pass
1574
+ * `undefined` otherwise.
1575
+ */
1576
+ declare const impactStampScopeDecision: ({
1577
+ stamp,
1578
+ surface,
1579
+ targetName
1580
+ }: {
1581
+ stamp: ImpactStamp | undefined;
1582
+ surface: ImpactScopeSurface;
1583
+ targetName: string;
1584
+ }) => ImpactScopeDecision;
1585
+ //#endregion
1509
1586
  //#region src/required-check-policy.d.ts
1510
1587
  declare const EVIDENCE_CHECK_TYPES: readonly ["review", "verify"];
1511
1588
  type EvidenceCheckType = (typeof EVIDENCE_CHECK_TYPES)[number];
@@ -1519,6 +1596,7 @@ declare const requiredCheckScopeSchema: z.ZodObject<{
1519
1596
  type RequiredCheckScope = z.infer<typeof requiredCheckScopeSchema>;
1520
1597
  interface RequiredCheckScopeContext {
1521
1598
  classification: DiffClassification | undefined;
1599
+ impactStamp?: ImpactStamp;
1522
1600
  }
1523
1601
  interface ScopeDecision {
1524
1602
  inScope: boolean;
@@ -1546,7 +1624,7 @@ declare const resolveAuthoringSessionIds: ({
1546
1624
  recorded?: string;
1547
1625
  }) => string[];
1548
1626
  declare namespace external_evidence_d_exports {
1549
- export { EVIDENCE_CHECK_TYPES, EVIDENCE_DIR, EVIDENCE_ENVELOPE_SCHEMA_VERSION, EVIDENCE_REVIEW_RUNGS, EvidenceCandidateIdentity, EvidenceCheckType, EvidenceEnvelope, EvidenceEnvelopeParse, EvidenceReviewRung, IndependenceResult, LoadedEvidenceEnvelope, RequiredCheck, RequiredCheckEvaluation, RequiredCheckEvaluationInput, RequiredCheckOutcome, RequiredCheckScope, RequiredCheckScopeContext, ScopeDecision, evaluateRequiredChecks, evidenceBindingFresh, evidenceEnvelopeSchema, evidenceReviewIndependence, loadEvidenceEnvelopes, parseEvidenceEnvelope, requiredCheckInScope, requiredCheckScopeSchema, resolveAuthoringSessionIds };
1627
+ export { EVIDENCE_CHECK_TYPES, EVIDENCE_DIR, EVIDENCE_ENVELOPE_SCHEMA_VERSION, EVIDENCE_REVIEW_RUNGS, EvidenceCandidateIdentity, EvidenceCheckType, EvidenceEnvelope, EvidenceEnvelopeParse, EvidenceReviewRung, IndependenceResult, LoadedEvidenceEnvelope, RequiredCheck, RequiredCheckEvaluation, RequiredCheckEvaluationInput, RequiredCheckOutcome, RequiredCheckScope, RequiredCheckScopeContext, ScopeDecision, boundFailingCheckNames, evaluateRequiredChecks, evidenceBindingFresh, evidenceEnvelopeSchema, evidenceReviewIndependence, loadEvidenceEnvelopes, parseEvidenceEnvelope, requiredCheckInScope, requiredCheckScopeSchema, resolveAuthoringSessionIds };
1550
1628
  }
1551
1629
  declare const EVIDENCE_ENVELOPE_SCHEMA_VERSION = 1;
1552
1630
  declare const evidenceEnvelopeBaseSchema: z.ZodObject<{
@@ -1645,6 +1723,26 @@ type LoadedEvidenceEnvelope = {
1645
1723
  ok: false;
1646
1724
  path: string;
1647
1725
  };
1726
+ /**
1727
+ * Every check name with a current, candidate-bound FAILING envelope on disk.
1728
+ *
1729
+ * The wave-3 scoping veto input. Callers pass the resolved set to
1730
+ * `planVerificationBattery` / `planPreviewLifecycle`, which stay pure — the
1731
+ * planners decide, they never read the filesystem.
1732
+ *
1733
+ * `checkType` is the caller's, not a guess: schema-v5 requiredChecks are
1734
+ * verify-only (`resolveProfileRequiredChecks`), so a scoping caller passes
1735
+ * `"verify"` and matches exactly the pair wave 2 evaluates.
1736
+ */
1737
+ declare const boundFailingCheckNames: ({
1738
+ candidate,
1739
+ checkType,
1740
+ envelopes
1741
+ }: {
1742
+ candidate: EvidenceCandidateIdentity;
1743
+ checkType: EvidenceCheckType;
1744
+ envelopes: LoadedEvidenceEnvelope[];
1745
+ }) => string[];
1648
1746
  interface RequiredCheckEvaluationInput {
1649
1747
  authoringSessionIds: string[];
1650
1748
  candidate: EvidenceCandidateIdentity;
@@ -1781,7 +1879,7 @@ declare const validatePrReviewProof: (value: unknown) => PrReviewProof;
1781
1879
  declare const readPrReviewProof: (filePath: string) => PrReviewProof;
1782
1880
  declare const PR_REVIEW_PROOF_DESCRIPTOR: ProofDescriptor<PrReviewProof>;
1783
1881
  declare namespace verification_proof_d_exports {
1784
- export { PrVerifyBaselineFullProof, PrVerifyCommandResult, PrVerifyExecutedCommand, PrVerifyProof, PrVerifySchemaVersion, ResolvedPrVerifyMode, SUPPORTED_PR_VERIFY_SCHEMA_VERSIONS, VerificationHeadShas, VerificationProofState, VerifiedHeadShas, prVerifyFullHeadShasForDiff, prVerifyProofHeadShas, readPrVerifyProof, resolveVerifyProofApplicability, validatePrVerifyProof, verificationProofApplicabilityFor, verificationProofBlockingReason, verificationProofForReadiness, verificationProofStateFor, verifyProofIdentityMatches, verifyProofPassed };
1882
+ export { PrVerifyBaselineFullProof, PrVerifyCommandResult, PrVerifyExecutedCommand, PrVerifyNotRequiredCommand, PrVerifyProof, PrVerifySchemaVersion, ResolvedPrVerifyMode, SUPPORTED_PR_VERIFY_SCHEMA_VERSIONS, VerificationHeadShas, VerificationProofState, VerifiedHeadShas, prVerifyFullHeadShasForDiff, prVerifyProofHeadShas, readPrVerifyProof, resolveVerifyProofApplicability, trustedImpactStamp, validatePrVerifyProof, verificationProofApplicabilityFor, verificationProofBlockingReason, verificationProofForReadiness, verificationProofStateFor, verifyProofIdentityMatches, verifyProofPassed };
1785
1883
  }
1786
1884
  interface VerifiedHeadShas {
1787
1885
  docsOnlyVerifiedHeadShas: string[];
@@ -1796,6 +1894,15 @@ type PrVerifySchemaVersion = (typeof SUPPORTED_PR_VERIFY_SCHEMA_VERSIONS)[number
1796
1894
  interface PrVerifyCommandResult {
1797
1895
  command: string;
1798
1896
  description: string;
1897
+ /**
1898
+ * Epic #550 wave 3 (#430): the profile's declared impact target for this
1899
+ * command, recorded from v4 on. It is the proof's own command→target
1900
+ * mapping: a `notRequiredCommands` entry must name the target recorded HERE
1901
+ * for the same command, so a withholding cannot point at whichever released
1902
+ * target happens to be convenient. Absent for a command the profile does
1903
+ * not scope, and for v1–v3 proofs, which predate the field.
1904
+ */
1905
+ impactTarget?: string;
1799
1906
  name: string;
1800
1907
  scope: "always" | "docs-only" | "trivial" | "full";
1801
1908
  }
@@ -1810,6 +1917,21 @@ interface PrVerifyExecutedCommand {
1810
1917
  name: string;
1811
1918
  scope: "always" | "docs-only" | "trivial" | "full";
1812
1919
  }
1920
+ /**
1921
+ * Epic #550 wave 3 (#430): a verification command the impact stamp proved this
1922
+ * candidate cannot reach, so the battery did not run it.
1923
+ *
1924
+ * The completeness invariant lives in the pairing: `verificationCommands`
1925
+ * records every command the resolved mode selected, `executedCommands` records
1926
+ * what ran, and this list records the rest WITH the stamp's own basis. A
1927
+ * withheld stack is therefore never silently absent from the proof — it is
1928
+ * present, named, and explained.
1929
+ */
1930
+ interface PrVerifyNotRequiredCommand {
1931
+ basis: string;
1932
+ impactTarget: string;
1933
+ name: string;
1934
+ }
1813
1935
  interface PrVerifyProof {
1814
1936
  schemaVersion: PrVerifySchemaVersion;
1815
1937
  authoringSession?: string;
@@ -1830,8 +1952,10 @@ interface PrVerifyProof {
1830
1952
  endedAt: string;
1831
1953
  executedCommands?: PrVerifyExecutedCommand[];
1832
1954
  headSha: string;
1955
+ impactStamp?: ImpactStamp;
1833
1956
  mode: ResolvedPrVerifyMode;
1834
1957
  mergeBaseSha?: string;
1958
+ notRequiredCommands?: PrVerifyNotRequiredCommand[];
1835
1959
  outcome?: "aborted" | "passed";
1836
1960
  patchId?: string;
1837
1961
  profilePath: string;
@@ -1855,6 +1979,28 @@ declare const verifyProofIdentityMatches: ({
1855
1979
  };
1856
1980
  proof?: PrVerifyProof;
1857
1981
  }) => boolean;
1982
+ /**
1983
+ * Wave-2 consumption (#542): the recorded impact stamp, released for demand
1984
+ * resolution ONLY when it is identity-bound to the current candidate — the
1985
+ * proof passed, and its recorded headSha AND patchId both name exactly this
1986
+ * candidate (the same identities the proof already binds). Everything else —
1987
+ * no proof, an aborted run, a stale head, a moved patch id, a pre-stamp proof
1988
+ * — returns `undefined`, and the consumer keeps today's full-demand floor.
1989
+ *
1990
+ * Deliberately stricter than verify-once applicability (which tolerates a
1991
+ * head-only or patch-id-only match): a stamp narrows external demands, so it
1992
+ * is trusted only on an exact double binding, fail closed.
1993
+ */
1994
+ declare const trustedImpactStamp: ({
1995
+ candidate,
1996
+ proof
1997
+ }: {
1998
+ candidate: {
1999
+ headSha: string;
2000
+ patchId: string;
2001
+ };
2002
+ proof: PrVerifyProof | undefined;
2003
+ }) => ImpactStamp | undefined;
1858
2004
  declare const prVerifyFullHeadShasForDiff: ({
1859
2005
  docsOnlyDeltaAcceptedSince,
1860
2006
  files,
@@ -2040,9 +2186,9 @@ declare const retroEnvelopeV1Schema: z.ZodObject<{
2040
2186
  kind: z.ZodLiteral<"retro-envelope">;
2041
2187
  outcome: z.ZodOptional<z.ZodObject<{
2042
2188
  status: z.ZodEnum<{
2189
+ blocked: "blocked";
2043
2190
  success: "success";
2044
2191
  fail: "fail";
2045
- blocked: "blocked";
2046
2192
  "ship-with-followups": "ship-with-followups";
2047
2193
  }>;
2048
2194
  verdict: z.ZodOptional<z.ZodString>;
@@ -2368,6 +2514,7 @@ interface PrVerifyGitDependencies {
2368
2514
  emptyTreeHash: (cwd: string) => string;
2369
2515
  mergeBaseSha: (cwd: string, base: string) => string;
2370
2516
  runVerificationCommand: (command: string, cwd: string, env: Record<string, string>) => VerificationCommandOutcome;
2517
+ showFileAtRef?: (cwd: string, ref: string, absolutePath: string) => string | undefined;
2371
2518
  statusPorcelain: (cwd: string) => string;
2372
2519
  stablePatchId: (cwd: string, base: string) => string;
2373
2520
  }
@@ -4310,6 +4457,169 @@ declare const appendReviewLadderStageTraceEvent: ({
4310
4457
  }) => AppendFactoryTraceEventResult;
4311
4458
  declare const tryAppendReviewLadderStageTraceEvent: (input: Parameters<typeof appendReviewLadderStageTraceEvent>[0]) => ReviewLadderStageTraceWriteResult;
4312
4459
  //#endregion
4460
+ //#region src/verification-battery.d.ts
4461
+ type BatteryDisposition = "executed" | "not-required";
4462
+ /**
4463
+ * The structural subset of a profile verification command this planner reads.
4464
+ * Kept structural — not a `Pick` of the profile type — so this leaf module
4465
+ * never imports `profile.ts` (which already depends on the impact modules).
4466
+ */
4467
+ interface BatteryCandidateCommand {
4468
+ impactTarget?: string;
4469
+ name: string;
4470
+ }
4471
+ interface BatteryCommandDisposition {
4472
+ /** Why this command runs or is withheld — the stamp's own words when scoped. */
4473
+ basis: string;
4474
+ disposition: BatteryDisposition;
4475
+ /** The declared impact target, when the command declares one. */
4476
+ impactTarget?: string;
4477
+ name: string;
4478
+ }
4479
+ /**
4480
+ * A withheld command. `impactTarget` is REQUIRED here, not optional: only a
4481
+ * command that declared a target can be released, so the proof record can
4482
+ * always name the target whose classification released it.
4483
+ */
4484
+ interface ScopedOutCommand {
4485
+ basis: string;
4486
+ impactTarget: string;
4487
+ name: string;
4488
+ }
4489
+ interface VerificationBatteryPlan<Command> {
4490
+ /** Every input command with its disposition, in input order. */
4491
+ dispositions: BatteryCommandDisposition[];
4492
+ /** The commands to run, in input order. */
4493
+ execute: Command[];
4494
+ /** The withheld commands, in input order. Recorded on the proof. */
4495
+ notRequired: ScopedOutCommand[];
4496
+ }
4497
+ /**
4498
+ * Plan one verification battery against the candidate's impact stamp.
4499
+ *
4500
+ * Pure and total: it makes a decision, it never reads a proof, a profile file,
4501
+ * or the filesystem, and no INPUT can make it throw — every doubt path is a
4502
+ * decision, not an exception. A malformed CALL is the one exception to that,
4503
+ * and deliberately so: omitting `vetoedTargets` is API misuse rather than data
4504
+ * doubt, and it throws (see {@link assertVetoedTargets}).
4505
+ *
4506
+ * `stamp` must already be trusted by
4507
+ * the caller — inside `pr:verify` that is the stamp just computed for this
4508
+ * candidate's own identity triple; anywhere else it is `trustedImpactStamp`'s
4509
+ * output or `undefined`.
4510
+ */
4511
+ declare const planVerificationBattery: <Command extends BatteryCandidateCommand>({
4512
+ commands,
4513
+ stamp,
4514
+ vetoedTargets
4515
+ }: {
4516
+ commands: readonly Command[];
4517
+ stamp: ImpactStamp | undefined;
4518
+ /**
4519
+ * Target names with a current, candidate-bound FAILING envelope. Scoping is
4520
+ * withheld for these whatever the stamp says.
4521
+ *
4522
+ * REQUIRED, with no default, on purpose: the veto is the rule that keeps a
4523
+ * scoped-away command from leaving a demand nothing on this head could meet,
4524
+ * and a defaulted `[]` cannot tell "I inspected the envelopes and found no
4525
+ * bound failure" apart from "I never looked". Pass the result of
4526
+ * `boundFailingCheckNames`; pass `[]` only to mean the former.
4527
+ *
4528
+ * This tightening is deliberately visible to `api:check` as a breaking
4529
+ * signature change (pre-1.0, no external callers yet): an external producer
4530
+ * must be made to state the veto set rather than silently skip it.
4531
+ */
4532
+ vetoedTargets: readonly string[];
4533
+ }) => VerificationBatteryPlan<Command>;
4534
+ /** Console lines naming every withheld command and why. Never silent. */
4535
+ declare const batteryScopeSummaryLines: (plan: VerificationBatteryPlan<BatteryCandidateCommand>) => string[];
4536
+ //#endregion
4537
+ //#region src/preview-lifecycle.d.ts
4538
+ type PreviewDisposition = "deploy" | "not-required";
4539
+ interface PreviewTargetPlan {
4540
+ basis: string;
4541
+ disposition: PreviewDisposition;
4542
+ name: string;
4543
+ }
4544
+ interface PreviewLifecyclePlan {
4545
+ /** The declared preview stacks to deploy, in declaration order. */
4546
+ deploy: string[];
4547
+ /** The withheld stacks, in declaration order. */
4548
+ notRequired: PreviewTargetPlan[];
4549
+ /** Whether a trusted, identity-bound stamp was available at all. */
4550
+ stampTrusted: boolean;
4551
+ /** Every declared preview target with its disposition, in declaration order. */
4552
+ targets: PreviewTargetPlan[];
4553
+ }
4554
+ /**
4555
+ * Structural subset of the profile: the impact declarations plus the external
4556
+ * demand list. Structural rather than a `Pick` so this module does not import
4557
+ * `profile.ts`.
4558
+ */
4559
+ interface PreviewLifecycleProfile {
4560
+ impact?: {
4561
+ targets: {
4562
+ name: string;
4563
+ }[];
4564
+ };
4565
+ requiredChecks?: {
4566
+ name: string;
4567
+ }[];
4568
+ }
4569
+ /**
4570
+ * The declared preview stacks: impact targets that are ALSO declared required
4571
+ * checks — i.e. targets whose proof is produced externally, which is exactly
4572
+ * what a preview producer is.
4573
+ *
4574
+ * Deriving the list from the two existing declarations rather than adding a
4575
+ * third is what makes lifecycle and demand unable to disagree: the stacks this
4576
+ * plan can withhold are precisely the demands wave 2 can release, so a stack
4577
+ * can never be skipped while its proof stays demanded.
4578
+ */
4579
+ declare const previewLifecycleTargets: (profile: PreviewLifecycleProfile) => string[];
4580
+ /**
4581
+ * Plan the preview lifecycle for one candidate.
4582
+ *
4583
+ * Trust is resolved here through the SAME identity gate demand release uses
4584
+ * (`trustedImpactStamp`): the proof must have passed and must bind both the
4585
+ * candidate's headSha and its patchId. A stale, aborted, absent, or
4586
+ * differently-bound proof yields no stamp, and every declared stack is planned
4587
+ * for deploy. Total over its INPUTS — no proof, stamp, or profile can make it
4588
+ * throw. A malformed CALL is the deliberate exception: omitting
4589
+ * `vetoedTargets` is API misuse, not data doubt, and throws.
4590
+ */
4591
+ declare const planPreviewLifecycle: ({
4592
+ candidate,
4593
+ profile,
4594
+ proof,
4595
+ vetoedTargets
4596
+ }: {
4597
+ candidate: {
4598
+ headSha: string;
4599
+ patchId: string;
4600
+ };
4601
+ profile: PreviewLifecycleProfile;
4602
+ proof: PrVerifyProof | undefined;
4603
+ /**
4604
+ * Stack names with a current, candidate-bound FAILING envelope. Scoping is
4605
+ * withheld for these whatever the stamp says — the same veto demand release
4606
+ * applies, and for the same reason: a withheld stack is a stack that can
4607
+ * never re-emit the envelope its standing demand needs. Callers hold the
4608
+ * checkout context, so they resolve the set with `boundFailingCheckNames`
4609
+ * and pass it in; this module stays pure.
4610
+ *
4611
+ * REQUIRED, with no default, on purpose: a defaulted `[]` reads the same
4612
+ * whether the caller inspected the envelopes or never looked, and this seam
4613
+ * exists precisely for EXTERNAL preview producers — the callers most likely
4614
+ * to skip the lookup. Pass the result of `boundFailingCheckNames`; pass `[]`
4615
+ * only to mean "inspected the envelopes and found no bound failure".
4616
+ *
4617
+ * Deliberately visible to `api:check` as a breaking signature change
4618
+ * (pre-1.0, no external callers yet).
4619
+ */
4620
+ vetoedTargets: readonly string[];
4621
+ }) => PreviewLifecyclePlan;
4622
+ //#endregion
4313
4623
  //#region src/worker-checkout-guard.d.ts
4314
4624
  type CheckoutDirsProbe = (cwd: string) => {
4315
4625
  gitCommonDir: string;
@@ -4343,4 +4653,4 @@ interface CreateProgramOptions {
4343
4653
  declare function createProgram(options?: CreateProgramOptions): Command;
4344
4654
  declare function run(argv?: string[]): Promise<void>;
4345
4655
  //#endregion
4346
- export { type AppendFactoryTraceEventResult, type AssembledReviewPrompt, type BoundaryCheckArgs, type BoundaryCheckDependencies, type BoundaryCheckProofRecord, type BuildEpicStructureEventInput, type BuildRetroEnvelopeInput, type CloudflareAccessServiceToken, CreateProgramOptions, DEFAULT_DEMAND_WAIVER_PATH, DEFAULT_FACTORY_REPOSITORY, type DagDocument, type DemandWaiveArgs, type DemandWaiveDependencies, DemandWaiveRefusalError, type DemandWaiver, type DemandWaiverStore, EPIC_STRUCTURE_NODE_STATUSES, EPIC_STRUCTURE_SCHEMA_VERSION, type EpicStructureEvent, type EpicStructureGraphPayload, type EpicStructureNodeStatus, EpicStructureValidationError, type EvidenceEmitArgs, type EvidenceEmitDependencies, type EvidenceEmitResult, type FactoryCliInvocation, FactoryCliInvocationSchema, type FactoryProjectProfile, type FactoryTraceDiagnostic, type FactoryTraceEnvelope, type FactoryTraceEvent, type FindingDisposition, type FindingLedgerEntry, type FollowUpAction, FollowUpActionSchema, type IssueReviewFocus, type LadderDispositionDeclaration, MERGE_FREEZE_APP_SLUG, MERGE_FREEZE_CHECK_NAME, type MergeFreezeState, type ParsedRetroEnvelope, type PrPublishArgs, type PrPublishDependencies, PrPublishFollowUpError, type PrPublishFollowUpOutcome, type PrPublishHandoff, type PrPublishResult, type PrReadyArgs, type PrReadyProof, type PublishEpicStructureArgs, type PublishEpicStructureResult, type PublishFollowUpPlan, RETRO_ENVELOPE_SCHEMA_VERSION, RETRO_ENVELOPE_VALIDATORS, REVIEW_FOCUS_SECTION, type RetroEnvelope, type ReviewGateNotRequiredProof, type ReviewGateTraceIdentity, type ReviewLadderCycle, type ReviewLadderEvaluation, type ReviewLadderPolicy, type ReviewLadderStageEvent, type ReviewLadderTraceIdentity, type ReviewPromptSection, type ReviewPromptSectionProvenance, SUPPORTED_RETRO_ENVELOPE_SCHEMA_VERSIONS, type ScanFactoryTraceDiagnosticsOptions, type ScanFactoryTraceOptions, type ScanFactoryTraceResult, type TraceMirrorDiagnostic, type TraceSink, type TraceWriteResult, type TraceWriteSinks, type VerificationReuse, type WaivedDemand, WorkerCheckoutGuardError, type WorkerCloseoutLessonsTraceEvent, appendReviewLadderStageTraceEvent, appendWithTraceSinks, applyDemandWaiver, assembleReviewPrompt, assertWorkerCheckoutAllowed, authorizeDemandWaiver, blockingLadderFindings, boundary_manifest_d_exports as boundaryManifest, boundary_review_proof_d_exports as boundaryReviewProof, buildEpicStructureEvent, buildEpicStructurePayload, buildEvidenceEnvelope, buildRetroEnvelope, buildReviewGateNotRequiredTraceEvent, buildReviewLadderStageTraceEvent, comment_provenance_d_exports as commentProvenance, createLocalJsonlTraceSink, createProgram, doctorProjectProfile, epicStructureEventId, evaluateReviewLadder, evidenceEnvelopeFilename, findingKey, followUpFromArgv, inferFixedInThreadDispositions, isProductionHqUrl, isRetroEnvelopeWireComplete, loadProjectProfile, normalizeIssueComments, openLadderFindings, parseRetroEnvelope, planPublishFollowUp, readiness_evaluation_d_exports as prReadinessEvaluation, external_evidence_d_exports as prReadinessExternalEvidence, pr_body_renderer_d_exports as prReadinessPrBodyRenderer, proof_identity_d_exports as prReadinessProofIdentity, review_proof_d_exports as prReadinessReviewProof, status_check_rollup_d_exports as prReadinessStatusChecks, verification_proof_d_exports as prReadinessVerificationProof, publishEpicStructure, readDemandWaivers, readPrReadyProof, readPrReviewProof, resolveFactoryRepository, resolveFindingBlocking, resolveReviewFindingCategory, resolveReviewFindingSeverity, resolveReviewLadderPolicy, resolveTraceWriteSinks, retroEnvelopeSchemaVersionOf, retroEnvelopeV1Schema, retroEpicReference, reviewCycleStateFor, reviewFocusFromIssueBody, reviewPromptSectionSchema, reviewPromptSectionsSchema, run, runBoundaryCheck, runDemandWaive, runEvidenceEmit, runPrPublish, runPrReady, runPrReview, runPrVerify, scanFactoryTraceDiagnostics, scanFactoryTraceEvents, selectWaiversForCandidate, staleRepeatLadderFindings, toFactoryTraceEnvelope, tryAppendReviewGateNotRequiredTraceEvent, tryAppendReviewLadderStageTraceEvent, validateBoundaryCheckProof, validateDagDocument, validateDemandWaiverStore, validateFactoryTraceEvent, validateMergeFreezeState, validatePrReadyProof, validatePrReviewProof, validatePrVerifyProof, waivedDemandNotice, waivedDemandSchema, worktree_scratch_files_d_exports as worktreeScratchFiles };
4656
+ export { type AppendFactoryTraceEventResult, type AssembledReviewPrompt, type BatteryCommandDisposition, type BatteryDisposition, type BoundaryCheckArgs, type BoundaryCheckDependencies, type BoundaryCheckProofRecord, type BuildEpicStructureEventInput, type BuildRetroEnvelopeInput, type CloudflareAccessServiceToken, CreateProgramOptions, DEFAULT_DEMAND_WAIVER_PATH, DEFAULT_FACTORY_REPOSITORY, type DagDocument, type DemandWaiveArgs, type DemandWaiveDependencies, DemandWaiveRefusalError, type DemandWaiver, type DemandWaiverStore, EPIC_STRUCTURE_NODE_STATUSES, EPIC_STRUCTURE_SCHEMA_VERSION, type EpicStructureEvent, type EpicStructureGraphPayload, type EpicStructureNodeStatus, EpicStructureValidationError, type EvidenceEmitArgs, type EvidenceEmitDependencies, type EvidenceEmitResult, type FactoryCliInvocation, FactoryCliInvocationSchema, type FactoryProjectProfile, type FactoryTraceDiagnostic, type FactoryTraceEnvelope, type FactoryTraceEvent, type FindingDisposition, type FindingLedgerEntry, type FollowUpAction, FollowUpActionSchema, type ImpactScopeDecision, type ImpactScopeSurface, type IssueReviewFocus, type LadderDispositionDeclaration, MERGE_FREEZE_APP_SLUG, MERGE_FREEZE_CHECK_NAME, type MergeFreezeState, type ParsedRetroEnvelope, type PrPublishArgs, type PrPublishDependencies, PrPublishFollowUpError, type PrPublishFollowUpOutcome, type PrPublishHandoff, type PrPublishResult, type PrReadyArgs, type PrReadyProof, type PreviewDisposition, type PreviewLifecyclePlan, type PreviewTargetPlan, type PublishEpicStructureArgs, type PublishEpicStructureResult, type PublishFollowUpPlan, RETRO_ENVELOPE_SCHEMA_VERSION, RETRO_ENVELOPE_VALIDATORS, REVIEW_FOCUS_SECTION, type RetroEnvelope, type ReviewGateNotRequiredProof, type ReviewGateTraceIdentity, type ReviewLadderCycle, type ReviewLadderEvaluation, type ReviewLadderPolicy, type ReviewLadderStageEvent, type ReviewLadderTraceIdentity, type ReviewPromptSection, type ReviewPromptSectionProvenance, SUPPORTED_RETRO_ENVELOPE_SCHEMA_VERSIONS, type ScanFactoryTraceDiagnosticsOptions, type ScanFactoryTraceOptions, type ScanFactoryTraceResult, type ScopedOutCommand, type TraceMirrorDiagnostic, type TraceSink, type TraceWriteResult, type TraceWriteSinks, type VerificationBatteryPlan, type VerificationReuse, type WaivedDemand, WorkerCheckoutGuardError, type WorkerCloseoutLessonsTraceEvent, appendReviewLadderStageTraceEvent, appendWithTraceSinks, applyDemandWaiver, assembleReviewPrompt, assertWorkerCheckoutAllowed, authorizeDemandWaiver, batteryScopeSummaryLines, blockingLadderFindings, boundary_manifest_d_exports as boundaryManifest, boundary_review_proof_d_exports as boundaryReviewProof, buildEpicStructureEvent, buildEpicStructurePayload, buildEvidenceEnvelope, buildRetroEnvelope, buildReviewGateNotRequiredTraceEvent, buildReviewLadderStageTraceEvent, comment_provenance_d_exports as commentProvenance, createLocalJsonlTraceSink, createProgram, doctorProjectProfile, epicStructureEventId, evaluateReviewLadder, evidenceEnvelopeFilename, findingKey, followUpFromArgv, impactStampScopeDecision, inferFixedInThreadDispositions, isProductionHqUrl, isRetroEnvelopeWireComplete, loadProjectProfile, normalizeIssueComments, openLadderFindings, parseRetroEnvelope, planPreviewLifecycle, planPublishFollowUp, planVerificationBattery, readiness_evaluation_d_exports as prReadinessEvaluation, external_evidence_d_exports as prReadinessExternalEvidence, pr_body_renderer_d_exports as prReadinessPrBodyRenderer, proof_identity_d_exports as prReadinessProofIdentity, review_proof_d_exports as prReadinessReviewProof, status_check_rollup_d_exports as prReadinessStatusChecks, verification_proof_d_exports as prReadinessVerificationProof, previewLifecycleTargets, publishEpicStructure, readDemandWaivers, readPrReadyProof, readPrReviewProof, resolveFactoryRepository, resolveFindingBlocking, resolveReviewFindingCategory, resolveReviewFindingSeverity, resolveReviewLadderPolicy, resolveTraceWriteSinks, retroEnvelopeSchemaVersionOf, retroEnvelopeV1Schema, retroEpicReference, reviewCycleStateFor, reviewFocusFromIssueBody, reviewPromptSectionSchema, reviewPromptSectionsSchema, run, runBoundaryCheck, runDemandWaive, runEvidenceEmit, runPrPublish, runPrReady, runPrReview, runPrVerify, scanFactoryTraceDiagnostics, scanFactoryTraceEvents, selectWaiversForCandidate, staleRepeatLadderFindings, toFactoryTraceEnvelope, tryAppendReviewGateNotRequiredTraceEvent, tryAppendReviewLadderStageTraceEvent, validateBoundaryCheckProof, validateDagDocument, validateDemandWaiverStore, validateFactoryTraceEvent, validateMergeFreezeState, validatePrReadyProof, validatePrReviewProof, validatePrVerifyProof, waivedDemandNotice, waivedDemandSchema, worktree_scratch_files_d_exports as worktreeScratchFiles };