@patronage/software-factory 1.0.0-alpha.29 → 1.0.0-alpha.30
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 +4 -2
- package/dist/index.d.ts +32 -130
- package/dist/index.js +54 -183
- package/dist/schemas.d.ts +5 -5
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -24,11 +24,13 @@ The package publishes to public npm as `@patronage/software-factory` under MIT.
|
|
|
24
24
|
|
|
25
25
|
Internal architectural packages live under `src/packages/`. Read the package root's `README.md` before editing one. Import only entry points explicitly declared by `dependency-cruiser.config.mjs`; package implementation and fixtures are private. See ADR 0007 (`docs/adr/0007-factory-internal-deep-packages-enforce-module-seams.md` in the source repository).
|
|
26
26
|
|
|
27
|
+
A public export leaves this package only with a named supported-consumer account, under the criteria in that ADR's 2026-09-04 amendment. `api:check` reports declaration drift, and it passes a breaking removal through whenever the version opens a break window, so it is a notice rather than the control. The control is that amendment plus `src/public-consumer-surface.test.ts`, which names every export the audited consumers import and fails when one goes. The amendment also lists the retained surface — the exports that stay without a current importer — and the reason each group stays.
|
|
28
|
+
|
|
27
29
|
## Releases
|
|
28
30
|
|
|
29
|
-
This is the release checklist. It lives here and nowhere else; the repository runbook links to it rather than restating it.
|
|
31
|
+
This is the release checklist. It lives here and nowhere else; the repository runbook links to it rather than restating it. Do not let merged work accumulate untagged: merged work that no release-owning boundary carries rides the next attended release.
|
|
30
32
|
|
|
31
|
-
Releases are attended and hand-cut. Nothing in the factory publishes, tags, or releases on its own, and no step below may be automated as a drive-by.
|
|
33
|
+
Releases are attended and hand-cut. Nothing in the factory publishes, tags, or releases on its own, and no step below may be automated as a drive-by. Delivery closeout (`boundary:check --final`, then `factory:closeout` on the epic) is a separate act with a separate owner: it closes the epic and releases nothing. Only a release-owning boundary carries a release, and one issue at a time holds that authority for a given version. A docs-only or non-release-owning runtime boundary closes without a bump and waits for the next attended cut. The admission skill's [closeout reference](../skills/patronage-software-factory-admission/references/epic-closeout.md#delivery-closeout-is-not-a-release) states the same split from the closeout side.
|
|
32
34
|
|
|
33
35
|
The factory family has one version posture (ADR 0026, `docs/adr/0026-factory-family-version-lines-move-in-lockstep.md` in the source repository): `@patronage/factory-ci` moves in lockstep majors with this CLI. From factory-ci's first release in the CLI's current series onward, majors and prerelease series move together while patch and prerelease increments stay independent per package. A consumer pins a factory-ci from the same major/prerelease series as its CLI; there is no compatibility matrix. Until that first lockstep release, factory-ci's published 0.x line is the named pre-adoption state and pairs with any CLI version. `@patronage/alchemy-d1-state` keeps independent SemVer. Lockstep is a rule the maintainer follows when cutting releases, never automation.
|
|
34
36
|
|
package/dist/index.d.ts
CHANGED
|
@@ -611,8 +611,6 @@ type PolicyResolution = z.infer<typeof policyResolutionSchema>;
|
|
|
611
611
|
type ReviewFindingSeverity = "critical" | "high" | "medium" | "low" | "unknown";
|
|
612
612
|
type ReviewFindingCategory = "correctness" | "safety" | "coordination" | "maintainability" | "unknown";
|
|
613
613
|
declare const REVIEW_SEVERITIES: readonly ["critical", "high", "medium", "low", "unknown"];
|
|
614
|
-
declare const resolveReviewFindingSeverity: (priority?: string) => ReviewFindingSeverity;
|
|
615
|
-
declare const resolveReviewFindingCategory: (category?: string) => ReviewFindingCategory;
|
|
616
614
|
declare const FINDING_DISPOSITIONS: readonly ["open", "fixed-in-thread", "follow-up-filed", "waived", "stale-repeat", "rerun-noise"];
|
|
617
615
|
type FindingDisposition = (typeof FINDING_DISPOSITIONS)[number];
|
|
618
616
|
interface ReviewFindingAttributes {
|
|
@@ -628,17 +626,11 @@ interface ReviewFindingAttributes {
|
|
|
628
626
|
};
|
|
629
627
|
title: string;
|
|
630
628
|
}
|
|
631
|
-
type BlockingResolvableFinding = Pick<ReviewFindingAttributes, "blockingAfterCap" | "category" | "priority">;
|
|
632
|
-
declare const resolveFindingBlocking: (finding: BlockingResolvableFinding, disposition?: FindingDisposition) => boolean;
|
|
633
629
|
interface ReviewLadderPolicy {
|
|
634
630
|
gate: {
|
|
635
631
|
cap: number;
|
|
636
632
|
};
|
|
637
|
-
interior: {
|
|
638
|
-
cap: number;
|
|
639
|
-
};
|
|
640
633
|
}
|
|
641
|
-
declare const resolveReviewLadderPolicy: () => ReviewLadderPolicy;
|
|
642
634
|
//#endregion
|
|
643
635
|
//#region src/review-ladder-ledger.d.ts
|
|
644
636
|
type LadderCycleStage = "interior" | "gate";
|
|
@@ -668,18 +660,6 @@ interface FindingLedgerEntry extends ReviewFindingAttributes {
|
|
|
668
660
|
reopenedCount: number;
|
|
669
661
|
staleRepeatCount: number;
|
|
670
662
|
}
|
|
671
|
-
declare const findingKey: (finding: {
|
|
672
|
-
citedSpan?: string;
|
|
673
|
-
file?: string;
|
|
674
|
-
prescribedAction?: string;
|
|
675
|
-
title?: string;
|
|
676
|
-
}) => string;
|
|
677
|
-
declare const openLadderFindings: (ledger: FindingLedgerEntry[]) => FindingLedgerEntry[];
|
|
678
|
-
declare const blockingLadderFindings: (ledger: FindingLedgerEntry[]) => FindingLedgerEntry[];
|
|
679
|
-
declare const staleRepeatLadderFindings: (ledger: FindingLedgerEntry[]) => FindingLedgerEntry[];
|
|
680
|
-
declare const inferFixedInThreadDispositions: (ledger: FindingLedgerEntry[], findings: readonly LadderFindingReport[], options?: {
|
|
681
|
-
sameHeadAsPriorCycle?: boolean;
|
|
682
|
-
}) => LadderDispositionDeclaration[];
|
|
683
663
|
//#endregion
|
|
684
664
|
//#region src/review-ladder.d.ts
|
|
685
665
|
type ReviewLadderExecutedStage = "interior" | "gate";
|
|
@@ -709,47 +689,29 @@ interface ReviewLadderCycle {
|
|
|
709
689
|
stage: LadderCycleStage;
|
|
710
690
|
usage?: LadderUsageReport;
|
|
711
691
|
}
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
interface LadderGateCapTransition {
|
|
692
|
+
type LadderNextActionKind = "run-interior-cycle" | "advance-to-gate" | "run-gate-cycle" | "accept-nonblocking-findings" | "escalate-to-triage" | "ready-for-human";
|
|
693
|
+
type ReviewLadderStage = "interior" | "interior-complete" | "gate";
|
|
694
|
+
type LadderForcedTransitionKind = "gate-cap-exhausted" | "interior-cap-reached";
|
|
695
|
+
interface LadderForcedTransition {
|
|
717
696
|
blockingFindings: string[];
|
|
718
697
|
cap: number;
|
|
719
|
-
kind: "gate-cap-exhausted"
|
|
698
|
+
kind: Extract<LadderForcedTransitionKind, "gate-cap-exhausted">;
|
|
720
699
|
}
|
|
721
|
-
type
|
|
722
|
-
interface LadderRunInteriorCycleAction {
|
|
700
|
+
type LadderNextAction = {
|
|
723
701
|
cycle: number;
|
|
724
|
-
kind: "run-
|
|
725
|
-
}
|
|
726
|
-
type LadderGateNextAction = {
|
|
727
|
-
cycle: number;
|
|
728
|
-
kind: "run-gate-cycle";
|
|
729
|
-
} | {
|
|
730
|
-
kind: "accept-nonblocking-findings";
|
|
731
|
-
} | {
|
|
732
|
-
kind: "escalate-to-triage";
|
|
702
|
+
kind: Extract<LadderNextActionKind, "run-gate-cycle">;
|
|
733
703
|
} | {
|
|
734
|
-
kind: "
|
|
735
|
-
};
|
|
736
|
-
type LadderPosition = {
|
|
737
|
-
forcedTransition?: LadderGateCapTransition;
|
|
738
|
-
nextAction: LadderGateNextAction;
|
|
739
|
-
stage: "gate";
|
|
704
|
+
kind: Extract<LadderNextActionKind, "accept-nonblocking-findings">;
|
|
740
705
|
} | {
|
|
741
|
-
|
|
742
|
-
nextAction: {
|
|
743
|
-
kind: "advance-to-gate";
|
|
744
|
-
};
|
|
745
|
-
stage: "interior-complete";
|
|
706
|
+
kind: Extract<LadderNextActionKind, "escalate-to-triage">;
|
|
746
707
|
} | {
|
|
747
|
-
|
|
748
|
-
nextAction: LadderRunInteriorCycleAction;
|
|
749
|
-
stage: "interior";
|
|
708
|
+
kind: Extract<LadderNextActionKind, "ready-for-human">;
|
|
750
709
|
};
|
|
751
|
-
|
|
752
|
-
|
|
710
|
+
interface LadderPosition {
|
|
711
|
+
forcedTransition?: LadderForcedTransition;
|
|
712
|
+
nextAction: LadderNextAction;
|
|
713
|
+
stage: Extract<ReviewLadderStage, "gate">;
|
|
714
|
+
}
|
|
753
715
|
interface ReviewLadderStageEvent {
|
|
754
716
|
cycle: number;
|
|
755
717
|
cyclesToClean?: number;
|
|
@@ -769,28 +731,15 @@ interface ReviewLadderStageEvent {
|
|
|
769
731
|
type: "review-ladder-stage";
|
|
770
732
|
usage?: LadderUsageReport;
|
|
771
733
|
}
|
|
772
|
-
interface LadderDiagnostic {
|
|
773
|
-
code: "interior-cycles-unrecorded";
|
|
774
|
-
message: string;
|
|
775
|
-
}
|
|
776
734
|
type ReviewLadderEvaluation = LadderPosition & {
|
|
777
735
|
cycleCounts: {
|
|
778
736
|
gate: number;
|
|
779
737
|
interior: number;
|
|
780
738
|
};
|
|
781
|
-
diagnostics: LadderDiagnostic[];
|
|
782
739
|
event?: ReviewLadderStageEvent;
|
|
783
740
|
ledger: FindingLedgerEntry[];
|
|
784
741
|
unmatchedDispositions: LadderDispositionDeclaration[];
|
|
785
742
|
};
|
|
786
|
-
interface EvaluateReviewLadderInput {
|
|
787
|
-
cycles: ReviewLadderCycle[];
|
|
788
|
-
policy: ReviewLadderPolicy;
|
|
789
|
-
}
|
|
790
|
-
declare const evaluateReviewLadder: ({
|
|
791
|
-
cycles,
|
|
792
|
-
policy
|
|
793
|
-
}: EvaluateReviewLadderInput) => ReviewLadderEvaluation;
|
|
794
743
|
//#endregion
|
|
795
744
|
//#region src/pr-readiness/ladder-proof-state.d.ts
|
|
796
745
|
interface PrReviewLadderState {
|
|
@@ -807,8 +756,8 @@ interface ReviewLadderSummaryState {
|
|
|
807
756
|
gate: number;
|
|
808
757
|
interior: number;
|
|
809
758
|
};
|
|
810
|
-
forcedTransition?:
|
|
811
|
-
nextAction:
|
|
759
|
+
forcedTransition?: LadderForcedTransitionKind;
|
|
760
|
+
nextAction: LadderNextActionKind;
|
|
812
761
|
stage: ReviewLadderStage;
|
|
813
762
|
}
|
|
814
763
|
interface ReviewLadderSnapshot {
|
|
@@ -1360,8 +1309,8 @@ declare const mergeFreezeStateSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
1360
1309
|
generationId: z.ZodNumber;
|
|
1361
1310
|
headSha: z.ZodString;
|
|
1362
1311
|
outcome: z.ZodEnum<{
|
|
1363
|
-
active: "active";
|
|
1364
1312
|
stale: "stale";
|
|
1313
|
+
active: "active";
|
|
1365
1314
|
}>;
|
|
1366
1315
|
reason: z.ZodString;
|
|
1367
1316
|
recordedAt: z.ZodISODateTime;
|
|
@@ -1583,12 +1532,12 @@ declare const managedReadinessLedgerSchema: z.ZodObject<{
|
|
|
1583
1532
|
"interior-cap-reached": "interior-cap-reached";
|
|
1584
1533
|
}>>;
|
|
1585
1534
|
nextAction: z.ZodEnum<{
|
|
1535
|
+
"run-interior-cycle": "run-interior-cycle";
|
|
1536
|
+
"advance-to-gate": "advance-to-gate";
|
|
1586
1537
|
"run-gate-cycle": "run-gate-cycle";
|
|
1587
1538
|
"accept-nonblocking-findings": "accept-nonblocking-findings";
|
|
1588
1539
|
"escalate-to-triage": "escalate-to-triage";
|
|
1589
1540
|
"ready-for-human": "ready-for-human";
|
|
1590
|
-
"advance-to-gate": "advance-to-gate";
|
|
1591
|
-
"run-interior-cycle": "run-interior-cycle";
|
|
1592
1541
|
}>;
|
|
1593
1542
|
stage: z.ZodEnum<{
|
|
1594
1543
|
interior: "interior";
|
|
@@ -1609,9 +1558,9 @@ declare const managedReadinessLedgerSchema: z.ZodObject<{
|
|
|
1609
1558
|
reviewedPatchId: z.ZodOptional<z.ZodString>;
|
|
1610
1559
|
status: z.ZodEnum<{
|
|
1611
1560
|
"not-required": "not-required";
|
|
1612
|
-
stale: "stale";
|
|
1613
1561
|
blocked: "blocked";
|
|
1614
1562
|
current: "current";
|
|
1563
|
+
stale: "stale";
|
|
1615
1564
|
missing: "missing";
|
|
1616
1565
|
}>;
|
|
1617
1566
|
}, z.core.$strip>;
|
|
@@ -1621,9 +1570,9 @@ declare const managedReadinessLedgerSchema: z.ZodObject<{
|
|
|
1621
1570
|
reviewedPatchId: z.ZodOptional<z.ZodString>;
|
|
1622
1571
|
status: z.ZodEnum<{
|
|
1623
1572
|
"not-required": "not-required";
|
|
1624
|
-
stale: "stale";
|
|
1625
1573
|
blocked: "blocked";
|
|
1626
1574
|
current: "current";
|
|
1575
|
+
stale: "stale";
|
|
1627
1576
|
missing: "missing";
|
|
1628
1577
|
}>;
|
|
1629
1578
|
}, z.core.$strip>>;
|
|
@@ -2732,9 +2681,9 @@ declare const loadEvidenceEnvelopes: (cwd: string) => LoadedEvidenceEnvelope[];
|
|
|
2732
2681
|
declare const REVIEW_STATUS_VALUES: readonly ["not-required", "current", "stale", "missing", "blocked"];
|
|
2733
2682
|
declare const reviewStatusSchema: z.ZodEnum<{
|
|
2734
2683
|
"not-required": "not-required";
|
|
2735
|
-
stale: "stale";
|
|
2736
2684
|
blocked: "blocked";
|
|
2737
2685
|
current: "current";
|
|
2686
|
+
stale: "stale";
|
|
2738
2687
|
missing: "missing";
|
|
2739
2688
|
}>;
|
|
2740
2689
|
type ReviewStatus = z.infer<typeof reviewStatusSchema>;
|
|
@@ -2818,7 +2767,7 @@ declare const reviewProofFor: (proof: PrReviewProof | undefined, kind: PrReviewK
|
|
|
2818
2767
|
patchId: string;
|
|
2819
2768
|
}) => ReviewProofClaim;
|
|
2820
2769
|
declare namespace review_proof_d_exports {
|
|
2821
|
-
export { DEFAULT_PR_REVIEW_MAX_CYCLES, DEFAULT_PR_REVIEW_PROOF_PATH, PR_REVIEW_FINAL_READINESS_NOTICE, PR_REVIEW_FINDING_PROVENANCE_VERSION, PR_REVIEW_PROOF_DESCRIPTOR, PR_REVIEW_SCHEMA_VERSION, PrReviewFinding, PrReviewKind, PrReviewLadderState, PrReviewMode, PrReviewOutcome, PrReviewProof, PrReviewResult, PrReviewStageResolution, REVIEW_SEVERITIES, ReviewAcceptance, ReviewCycleState, ReviewFindingCategory, ReviewFindingSeverity, ReviewTerminalState, prReviewFindingSchema, prReviewProofSchema, prReviewResultSchema,
|
|
2770
|
+
export { DEFAULT_PR_REVIEW_MAX_CYCLES, DEFAULT_PR_REVIEW_PROOF_PATH, PR_REVIEW_FINAL_READINESS_NOTICE, PR_REVIEW_FINDING_PROVENANCE_VERSION, PR_REVIEW_PROOF_DESCRIPTOR, PR_REVIEW_SCHEMA_VERSION, PrReviewFinding, PrReviewKind, PrReviewLadderState, PrReviewMode, PrReviewOutcome, PrReviewProof, PrReviewResult, PrReviewStageResolution, REVIEW_SEVERITIES, ReviewAcceptance, ReviewCycleState, ReviewFindingCategory, ReviewFindingSeverity, ReviewTerminalState, prReviewFindingSchema, prReviewProofSchema, prReviewResultSchema, resolveReviewAcceptance, resolveReviewTerminalState, resolveReviewTerminalStateAcrossReviews, resolveReviewTerminalStateAcrossReviewsForPolicy, resolveReviewTerminalStateForEpoch, reviewCycleStateFor, reviewProofFor, validatePrReviewProof, validatePrReviewResult };
|
|
2822
2771
|
}
|
|
2823
2772
|
declare const PR_REVIEW_SCHEMA_VERSION = 2;
|
|
2824
2773
|
declare const PR_REVIEW_FINDING_PROVENANCE_VERSION = 1;
|
|
@@ -2830,7 +2779,6 @@ declare const prReviewResultSchema: z.ZodType<PrReviewResult>;
|
|
|
2830
2779
|
declare const prReviewProofSchema: z.ZodType<PrReviewProof>;
|
|
2831
2780
|
declare const validatePrReviewResult: (value: unknown) => PrReviewResult;
|
|
2832
2781
|
declare const validatePrReviewProof: (value: unknown) => PrReviewProof;
|
|
2833
|
-
declare const readPrReviewProof: (filePath: string) => PrReviewProof;
|
|
2834
2782
|
declare const PR_REVIEW_PROOF_DESCRIPTOR: ProofDescriptor<PrReviewProof>;
|
|
2835
2783
|
//#endregion
|
|
2836
2784
|
//#region src/schemas.d.ts
|
|
@@ -3986,8 +3934,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
|
|
|
3986
3934
|
interiorCycle: z.ZodOptional<z.ZodNumber>;
|
|
3987
3935
|
observedAt: z.ZodString;
|
|
3988
3936
|
purpose: z.ZodEnum<{
|
|
3989
|
-
code: "code";
|
|
3990
3937
|
review: "review";
|
|
3938
|
+
code: "code";
|
|
3991
3939
|
}>;
|
|
3992
3940
|
slotResolution: z.ZodObject<{
|
|
3993
3941
|
effort: z.ZodEnum<{
|
|
@@ -4065,8 +4013,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
|
|
|
4065
4013
|
interiorCycle: z.ZodOptional<z.ZodNumber>;
|
|
4066
4014
|
observedAt: z.ZodString;
|
|
4067
4015
|
purpose: z.ZodEnum<{
|
|
4068
|
-
code: "code";
|
|
4069
4016
|
review: "review";
|
|
4017
|
+
code: "code";
|
|
4070
4018
|
}>;
|
|
4071
4019
|
slotResolution: z.ZodObject<{
|
|
4072
4020
|
effort: z.ZodEnum<{
|
|
@@ -4135,8 +4083,8 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
|
|
|
4135
4083
|
interiorCycle: z.ZodOptional<z.ZodNumber>;
|
|
4136
4084
|
observedAt: z.ZodString;
|
|
4137
4085
|
purpose: z.ZodEnum<{
|
|
4138
|
-
code: "code";
|
|
4139
4086
|
review: "review";
|
|
4087
|
+
code: "code";
|
|
4140
4088
|
}>;
|
|
4141
4089
|
slotResolution: z.ZodObject<{
|
|
4142
4090
|
effort: z.ZodEnum<{
|
|
@@ -4208,7 +4156,7 @@ declare const FACTORY_TRACE_EVENT_DEFINITIONS: readonly [DefinedTraceEvent<"revi
|
|
|
4208
4156
|
exitCode: number | null;
|
|
4209
4157
|
harness: string;
|
|
4210
4158
|
observedAt: string;
|
|
4211
|
-
purpose: "
|
|
4159
|
+
purpose: "review" | "code";
|
|
4212
4160
|
slotResolution: {
|
|
4213
4161
|
effort: "high" | "low" | "medium" | "xhigh";
|
|
4214
4162
|
engine: string;
|
|
@@ -4562,13 +4510,13 @@ declare const evaluateReadiness: (input: EvaluationInput) => {
|
|
|
4562
4510
|
reviews: {
|
|
4563
4511
|
correctness: {
|
|
4564
4512
|
required: boolean;
|
|
4565
|
-
status: "not-required" | "
|
|
4513
|
+
status: "not-required" | "blocked" | "current" | "stale" | "missing";
|
|
4566
4514
|
reviewedHeadSha?: string | undefined;
|
|
4567
4515
|
reviewedPatchId?: string | undefined;
|
|
4568
4516
|
};
|
|
4569
4517
|
security?: {
|
|
4570
4518
|
required: boolean;
|
|
4571
|
-
status: "not-required" | "
|
|
4519
|
+
status: "not-required" | "blocked" | "current" | "stale" | "missing";
|
|
4572
4520
|
reviewedHeadSha?: string | undefined;
|
|
4573
4521
|
reviewedPatchId?: string | undefined;
|
|
4574
4522
|
} | undefined;
|
|
@@ -4630,7 +4578,7 @@ declare const evaluateReadiness: (input: EvaluationInput) => {
|
|
|
4630
4578
|
gate: number;
|
|
4631
4579
|
interior: number;
|
|
4632
4580
|
};
|
|
4633
|
-
nextAction: "run-
|
|
4581
|
+
nextAction: "run-interior-cycle" | "advance-to-gate" | "run-gate-cycle" | "accept-nonblocking-findings" | "escalate-to-triage" | "ready-for-human";
|
|
4634
4582
|
stage: "interior" | "gate" | "interior-complete";
|
|
4635
4583
|
forcedTransition?: "gate-cap-exhausted" | "interior-cap-reached" | undefined;
|
|
4636
4584
|
} | undefined;
|
|
@@ -4921,52 +4869,6 @@ declare const assembleReviewPrompt: ({
|
|
|
4921
4869
|
waveRung
|
|
4922
4870
|
}: AssembleReviewPromptInput, dependencies?: AssembleReviewPromptDependencies) => AssembledReviewPrompt;
|
|
4923
4871
|
//#endregion
|
|
4924
|
-
//#region src/review-ladder-trace.d.ts
|
|
4925
|
-
interface ReviewLadderTraceIdentity {
|
|
4926
|
-
issue?: number;
|
|
4927
|
-
pr?: number;
|
|
4928
|
-
repo: string;
|
|
4929
|
-
threadId?: string;
|
|
4930
|
-
workerId?: string;
|
|
4931
|
-
}
|
|
4932
|
-
interface ReviewLadderStageTraceWriteResult {
|
|
4933
|
-
errorMessage?: string;
|
|
4934
|
-
filePath?: string;
|
|
4935
|
-
mirrorDiagnostics: TraceMirrorDiagnostic[];
|
|
4936
|
-
ok: boolean;
|
|
4937
|
-
}
|
|
4938
|
-
declare const buildReviewLadderStageTraceEvent: ({
|
|
4939
|
-
createdAt,
|
|
4940
|
-
event,
|
|
4941
|
-
headSha,
|
|
4942
|
-
identity,
|
|
4943
|
-
patchId
|
|
4944
|
-
}: {
|
|
4945
|
-
createdAt?: string;
|
|
4946
|
-
event: ReviewLadderStageEvent;
|
|
4947
|
-
headSha?: string;
|
|
4948
|
-
identity: ReviewLadderTraceIdentity;
|
|
4949
|
-
patchId?: string;
|
|
4950
|
-
}) => FactoryTraceEvent;
|
|
4951
|
-
declare const appendReviewLadderStageTraceEvent: ({
|
|
4952
|
-
createdAt,
|
|
4953
|
-
event,
|
|
4954
|
-
headSha,
|
|
4955
|
-
identity,
|
|
4956
|
-
mirror,
|
|
4957
|
-
patchId,
|
|
4958
|
-
repoRoot
|
|
4959
|
-
}: {
|
|
4960
|
-
createdAt?: string;
|
|
4961
|
-
event: ReviewLadderStageEvent;
|
|
4962
|
-
headSha?: string;
|
|
4963
|
-
identity: ReviewLadderTraceIdentity;
|
|
4964
|
-
mirror?: TraceSink;
|
|
4965
|
-
patchId?: string;
|
|
4966
|
-
repoRoot: string;
|
|
4967
|
-
}) => AppendFactoryTraceEventResult;
|
|
4968
|
-
declare const tryAppendReviewLadderStageTraceEvent: (input: Parameters<typeof appendReviewLadderStageTraceEvent>[0]) => ReviewLadderStageTraceWriteResult;
|
|
4969
|
-
//#endregion
|
|
4970
4872
|
//#region src/verification-run-context.d.ts
|
|
4971
4873
|
declare const FACTORY_BASE_REF_ENV = "FACTORY_BASE_REF";
|
|
4972
4874
|
declare const FACTORY_CHANGED_FILES_ENV = "FACTORY_CHANGED_FILES";
|
|
@@ -5112,4 +5014,4 @@ declare function createProgram(options?: CreateProgramOptions): Command;
|
|
|
5112
5014
|
*/
|
|
5113
5015
|
declare function run(argv?: string[], cliEntry?: string): Promise<void>;
|
|
5114
5016
|
//#endregion
|
|
5115
|
-
export { type AppendFactoryTraceEventResult, type AssembledReviewPrompt, type BatteryCommandDisposition, type BatteryDisposition, type BoundaryCheckArgs, type BoundaryCheckDependencies, type BoundaryCheckProofRecord, type BuildEpicStructureEventInput, type CloudflareAccessServiceToken, type CompletedFactoryCheckSnapshot, CreateProgramOptions, DEFAULT_DEMAND_WAIVER_PATH, DEFAULT_FACTORY_REPOSITORY, DEFAULT_ROOT_SHARED_GLOBS, type DagDocument, type DemandWaiveArgs, type DemandWaiveDependencies, DemandWaiveRefusalError, type DemandWaiver, type DemandWaiverStore, EMPTY_TREE_OBJECT_HASH, EPIC_STRUCTURE_NODE_STATUSES, EPIC_STRUCTURE_SCHEMA_VERSION, type EpicStructureEvent, type EpicStructureGraphPayload, type EpicStructureNodeStatus, EpicStructureValidationError, type EvidenceEmitArgs, type EvidenceEmitDependencies, type EvidenceEmitResult, FACTORY_BASE_REF_ENV, FACTORY_CHANGED_FILES_ENV, FACTORY_CHANGED_FILES_FILE_ENV, type FactoryCliInvocation, FactoryCliInvocationSchema, type FactoryPrStatusCheckName, type FactoryPrStatusSources, type FactoryProjectProfile, type FactoryTraceDiagnostic, type FactoryTraceEnvelope, type FactoryTraceEvent, type
|
|
5017
|
+
export { type AppendFactoryTraceEventResult, type AssembledReviewPrompt, type BatteryCommandDisposition, type BatteryDisposition, type BoundaryCheckArgs, type BoundaryCheckDependencies, type BoundaryCheckProofRecord, type BuildEpicStructureEventInput, type CloudflareAccessServiceToken, type CompletedFactoryCheckSnapshot, CreateProgramOptions, DEFAULT_DEMAND_WAIVER_PATH, DEFAULT_FACTORY_REPOSITORY, DEFAULT_ROOT_SHARED_GLOBS, type DagDocument, type DemandWaiveArgs, type DemandWaiveDependencies, DemandWaiveRefusalError, type DemandWaiver, type DemandWaiverStore, EMPTY_TREE_OBJECT_HASH, EPIC_STRUCTURE_NODE_STATUSES, EPIC_STRUCTURE_SCHEMA_VERSION, type EpicStructureEvent, type EpicStructureGraphPayload, type EpicStructureNodeStatus, EpicStructureValidationError, type EvidenceEmitArgs, type EvidenceEmitDependencies, type EvidenceEmitResult, FACTORY_BASE_REF_ENV, FACTORY_CHANGED_FILES_ENV, FACTORY_CHANGED_FILES_FILE_ENV, type FactoryCliInvocation, FactoryCliInvocationSchema, type FactoryPrStatusCheckName, type FactoryPrStatusSources, type FactoryProjectProfile, type FactoryTraceDiagnostic, type FactoryTraceEnvelope, type FactoryTraceEvent, type FollowUpAction, FollowUpActionSchema, type GitHubCheckRunMergeFreezeApi, type ImpactScopeDecision, type ImpactScopeSurface, type IssueReviewFocus, MERGE_FREEZE_APP_SLUG, MERGE_FREEZE_CHECK_NAME, type MergeFreezeAuthority, type MergeFreezeGeneration, type MergeFreezeState, type MergeFreezeStoreInput, type PlanFactoryPrStatusHudInput, type PrPublishArgs, type PrPublishDependencies, PrPublishFollowUpError, type PrPublishFollowUpOutcome, type PrPublishHandoff, type PrPublishResult, type PrReadyArgs, type PrReadyProof, type PrVerifyProof, type PresentFactoryPrStatusHudDependencies, type PresentFactoryPrStatusHudInput, type PreviewDisposition, type PreviewLifecyclePlan, type PreviewTargetPlan, type PublishEpicStructureArgs, type PublishEpicStructureResult, type PublishFollowUpPlan, REVIEW_FOCUS_SECTION, type ReadFactoryPrStatusSourcesDependencies, type ReadFactoryPrStatusSourcesInput, type RefreshFactoryPrStatusHudInput, type RenderFactoryPrStatusHudInput, type ReviewGateNotRequiredProof, type ReviewGateTraceIdentity, type ReviewPromptSection, type ReviewPromptSectionProvenance, type ScanFactoryTraceDiagnosticsOptions, type ScanFactoryTraceOptions, type ScanFactoryTraceResult, type ScopedOutCommand, type TraceMirrorDiagnostic, type TraceSink, type TraceWriteResult, type TraceWriteSinks, type VerificationBatteryPlan, type VerificationReuse, type VerificationRunContext, type VerificationRunContextInput, type WaivedDemand, WorkerCheckoutGuardError, type WorkerCloseoutLessonsTraceEvent, appendWithTraceSinks, applyDemandWaiver, assembleReviewPrompt, assertFactoryPrStatusIdentity, assertWorkerCheckoutAllowed, authorizeDemandWaiver, batteryScopeSummaryLines, boundary_manifest_d_exports as boundaryManifest, boundary_review_proof_d_exports as boundaryReviewProof, buildEpicStructureEvent, buildEpicStructurePayload, buildEvidenceEnvelope, buildReviewGateNotRequiredTraceEvent, comment_provenance_d_exports as commentProvenance, createGitHubCheckRunMergeFreezeStore, createLocalJsonlTraceSink, createProgram, createVerificationRunContext, doctorProjectProfile, epicStructureEventId, evidenceEnvelopeFilename, followUpFromArgv, impactStampScopeDecision, isProductionHqUrl, loadProjectProfile, normalizeIssueComments, planFactoryPrStatusHud, 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, presentFactoryPrStatusHud, previewLifecycleTargets, publishEpicStructure, readDemandWaivers, readFactoryPrStatusSources, readPrReadyProof, refreshFactoryPrStatusHud, refreshFactoryPrStatusHudSafely, renderFactoryPrStatusHud, resolveFactoryRepository, resolveTraceWriteSinks, reviewFocusFromIssueBody, reviewPromptSectionSchema, reviewPromptSectionsSchema, run, runBoundaryCheck, runDemandWaive, runEvidenceEmit, runPrPublish, runPrReady, runPrReview, runPrVerify, scanFactoryTraceDiagnostics, scanFactoryTraceEvents, selectWaiversForCandidate, toFactoryTraceEnvelope, tryAppendReviewGateNotRequiredTraceEvent, validateBoundaryCheckProof, validateDagDocument, validateDemandWaiverStore, validateFactoryTraceEvent, validateMergeFreezeState, validatePrReadyProof, validatePrVerifyProof, validatePreviewLifecyclePlan, waivedDemandNotice, waivedDemandSchema, worktree_scratch_files_d_exports as worktreeScratchFiles };
|
package/dist/index.js
CHANGED
|
@@ -18,7 +18,7 @@ import { FACTORY_APP_BROKER_ORIGIN, FACTORY_APP_BROKER_PATH, FACTORY_CURSOR_OIDC
|
|
|
18
18
|
import http from "node:http";
|
|
19
19
|
import { pathToFileURL } from "node:url";
|
|
20
20
|
//#region package.json
|
|
21
|
-
var version = "1.0.0-alpha.
|
|
21
|
+
var version = "1.0.0-alpha.30";
|
|
22
22
|
//#endregion
|
|
23
23
|
//#region src/cli-entry.ts
|
|
24
24
|
/**
|
|
@@ -1694,6 +1694,24 @@ function assertCleanWorktreeForProof({ changedFiles, cwd, dirtyMessage, statusPo
|
|
|
1694
1694
|
if (offendingLines.length > 0) throw new Error(`${dirtyMessage}\n${offendingLines.join("\n")}`);
|
|
1695
1695
|
}
|
|
1696
1696
|
//#endregion
|
|
1697
|
+
//#region src/battery-shell-command.ts
|
|
1698
|
+
/** Quotes one argument for a POSIX shell, including embedded single quotes. */
|
|
1699
|
+
function singleQuote(value) {
|
|
1700
|
+
return `'${value.replaceAll("'", String.raw`'\''`)}'`;
|
|
1701
|
+
}
|
|
1702
|
+
/**
|
|
1703
|
+
* Wraps a verification command so a login shell cannot demote the Node the
|
|
1704
|
+
* factory CLI is running on.
|
|
1705
|
+
*
|
|
1706
|
+
* `nodeBinDir` is the directory holding the running Node executable, so the
|
|
1707
|
+
* battery and the CLI always agree. The prefix is a separate line rather than a
|
|
1708
|
+
* `;` join: the command is profile-authored text that may already contain `&&`,
|
|
1709
|
+
* `;`, or a trailing comment, and a newline composes with all three.
|
|
1710
|
+
*/
|
|
1711
|
+
function withPinnedNodeOnPath(command, nodeBinDir) {
|
|
1712
|
+
return `export PATH=${singleQuote(nodeBinDir)}:"$PATH"\n${command}`;
|
|
1713
|
+
}
|
|
1714
|
+
//#endregion
|
|
1697
1715
|
//#region src/candidate-identity.ts
|
|
1698
1716
|
/**
|
|
1699
1717
|
* The same fallback for a patch id taken at an explicit ref rather than at
|
|
@@ -2459,12 +2477,8 @@ const resolveFindingBlocking = (finding, disposition = "open") => {
|
|
|
2459
2477
|
const severity = resolveReviewFindingSeverity(finding.priority);
|
|
2460
2478
|
return severity === "critical" || severity === "high" || severity === "unknown";
|
|
2461
2479
|
};
|
|
2462
|
-
const DEFAULT_INTERIOR_REVIEW_CAP = 0;
|
|
2463
2480
|
const FACTORY_REVIEW_CYCLE_CAP = 5;
|
|
2464
|
-
const resolveReviewLadderPolicy = () => ({
|
|
2465
|
-
gate: { cap: FACTORY_REVIEW_CYCLE_CAP },
|
|
2466
|
-
interior: { cap: DEFAULT_INTERIOR_REVIEW_CAP }
|
|
2467
|
-
});
|
|
2481
|
+
const resolveReviewLadderPolicy = () => ({ gate: { cap: FACTORY_REVIEW_CYCLE_CAP } });
|
|
2468
2482
|
//#endregion
|
|
2469
2483
|
//#region src/sha256-hex.ts
|
|
2470
2484
|
const ROUND_CONSTANTS = new Uint32Array([
|
|
@@ -3879,7 +3893,7 @@ const validatedIngestEndpoint = (value) => {
|
|
|
3879
3893
|
const origin = validatedEndpoint(value);
|
|
3880
3894
|
return origin === void 0 ? void 0 : new URL(HQ_INGEST_PATH, origin.origin);
|
|
3881
3895
|
};
|
|
3882
|
-
const retainRetryEntry = async (layout, entry, dependencies, deadline
|
|
3896
|
+
const retainRetryEntry = async (layout, entry, dependencies, deadline) => {
|
|
3883
3897
|
let customAppend;
|
|
3884
3898
|
try {
|
|
3885
3899
|
customAppend = dependencies.appendJournal;
|
|
@@ -3894,17 +3908,11 @@ const retainRetryEntry = async (layout, entry, dependencies, deadline, options =
|
|
|
3894
3908
|
return "failed";
|
|
3895
3909
|
}
|
|
3896
3910
|
const target = path.join(path.resolve(layout.root, ...layout.segments), `${randomUUID()}-${spoolFileName(entry)}`);
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
}).unref();
|
|
3903
|
-
return;
|
|
3904
|
-
}
|
|
3905
|
-
const outcome = await settleWithin((async () => customAppend(target, row))(), remainingMs(deadline));
|
|
3906
|
-
if (outcome.status === "fulfilled") return;
|
|
3907
|
-
return outcome.status === "timed-out" ? "timed-out" : "failed";
|
|
3911
|
+
setImmediate(async () => {
|
|
3912
|
+
try {
|
|
3913
|
+
await customAppend(target, row);
|
|
3914
|
+
} catch {}
|
|
3915
|
+
}).unref();
|
|
3908
3916
|
};
|
|
3909
3917
|
const projectInputForHqIngest = async (input, deadline) => {
|
|
3910
3918
|
let profilePath;
|
|
@@ -3927,94 +3935,6 @@ const projectInputForHqIngest = async (input, deadline) => {
|
|
|
3927
3935
|
...input.subject === void 0 ? {} : { subject: input.subject }
|
|
3928
3936
|
};
|
|
3929
3937
|
};
|
|
3930
|
-
async function handoffHqIngest(input, dependencies, setupDeadline) {
|
|
3931
|
-
let config;
|
|
3932
|
-
try {
|
|
3933
|
-
if (!input.profile.hq?.enabled) return "skipped";
|
|
3934
|
-
config = input.profile.hq;
|
|
3935
|
-
} catch {
|
|
3936
|
-
return "skipped";
|
|
3937
|
-
}
|
|
3938
|
-
const endpoint = validatedIngestEndpoint(config.endpoint);
|
|
3939
|
-
if (!endpoint) {
|
|
3940
|
-
await reportDiagnostic(dependencies, setupDeadline, "profile endpoint must be an HTTPS origin without embedded credentials", "HQ ingest skipped");
|
|
3941
|
-
return "skipped";
|
|
3942
|
-
}
|
|
3943
|
-
let env;
|
|
3944
|
-
try {
|
|
3945
|
-
env = dependencies.env ?? process.env;
|
|
3946
|
-
} catch {
|
|
3947
|
-
await reportDiagnostic(dependencies, setupDeadline, "operator configuration is unavailable", "HQ ingest skipped");
|
|
3948
|
-
return "skipped";
|
|
3949
|
-
}
|
|
3950
|
-
if (!(await loadAllowedOrigins(env, setupDeadline)).includes(endpoint.origin)) {
|
|
3951
|
-
await reportDiagnostic(dependencies, setupDeadline, `endpoint origin ${endpoint.origin} is not authorized by hqAllowedOrigins in the operator user config`, "HQ ingest skipped");
|
|
3952
|
-
return "skipped";
|
|
3953
|
-
}
|
|
3954
|
-
const flushDeadline = performance.now() + journalFlushBudgetFor(dependencies);
|
|
3955
|
-
const now = dependencies.now ?? (() => /* @__PURE__ */ new Date());
|
|
3956
|
-
const makeEventId = dependencies.randomUUID ?? randomUUID;
|
|
3957
|
-
let event;
|
|
3958
|
-
let dropped = false;
|
|
3959
|
-
let reason = "closeout-advisory-handoff";
|
|
3960
|
-
try {
|
|
3961
|
-
const projectedPayload = await loadBoundedPayload(input, setupDeadline);
|
|
3962
|
-
const eventId = makeEventId();
|
|
3963
|
-
const observedAt = now().toISOString();
|
|
3964
|
-
const repository = {
|
|
3965
|
-
owner: input.profile.repository.owner,
|
|
3966
|
-
repo: input.profile.repository.name
|
|
3967
|
-
};
|
|
3968
|
-
if (projectedPayload.status === "dropped") {
|
|
3969
|
-
dropped = true;
|
|
3970
|
-
const { reason: projectionReason } = projectedPayload;
|
|
3971
|
-
reason = projectionReason;
|
|
3972
|
-
const subject = inferredSubject(input, {});
|
|
3973
|
-
event = {
|
|
3974
|
-
eventId,
|
|
3975
|
-
kind: input.kind,
|
|
3976
|
-
observedAt,
|
|
3977
|
-
repository,
|
|
3978
|
-
schemaVersion: 1,
|
|
3979
|
-
...subject === void 0 ? {} : { subject }
|
|
3980
|
-
};
|
|
3981
|
-
} else {
|
|
3982
|
-
const subject = inferredSubject(input, projectedPayload.value);
|
|
3983
|
-
event = {
|
|
3984
|
-
eventId,
|
|
3985
|
-
kind: input.kind,
|
|
3986
|
-
observedAt,
|
|
3987
|
-
payload: projectedPayload.value,
|
|
3988
|
-
repository,
|
|
3989
|
-
schemaVersion: projectedPayload.value.schemaVersion,
|
|
3990
|
-
...subject === void 0 ? {} : { subject }
|
|
3991
|
-
};
|
|
3992
|
-
}
|
|
3993
|
-
} catch {
|
|
3994
|
-
await reportDiagnostic(dependencies, flushDeadline, "closeout advisory handoff could not construct an event");
|
|
3995
|
-
return "held";
|
|
3996
|
-
}
|
|
3997
|
-
if (dropped || event === void 0) return "held";
|
|
3998
|
-
let failedAt;
|
|
3999
|
-
try {
|
|
4000
|
-
failedAt = now().toISOString();
|
|
4001
|
-
} catch {
|
|
4002
|
-
failedAt = "unknown";
|
|
4003
|
-
}
|
|
4004
|
-
const retryEntry = {
|
|
4005
|
-
endpoint: endpoint.href,
|
|
4006
|
-
event,
|
|
4007
|
-
failedAt,
|
|
4008
|
-
reason
|
|
4009
|
-
};
|
|
4010
|
-
const writeLayout = repositorySpoolLayout({
|
|
4011
|
-
owner: input.profile.repository.owner,
|
|
4012
|
-
repo: input.profile.repository.name
|
|
4013
|
-
}, env);
|
|
4014
|
-
const journalFailure = dependencies.appendJournal === void 0 ? await appendCloseoutSpool(writeLayout, retryEntry, flushDeadline) : await retainRetryEntry(writeLayout, retryEntry, dependencies, flushDeadline, { awaitCustom: true });
|
|
4015
|
-
if (journalFailure) await reportDiagnostic(dependencies, flushDeadline, `closeout advisory handoff local spool ${journalFailure}`);
|
|
4016
|
-
return journalFailure === void 0 && !dropped ? "deferred" : "held";
|
|
4017
|
-
}
|
|
4018
3938
|
/**
|
|
4019
3939
|
* A bounded read of the ingest receipt body. Only the explicit drain asks for
|
|
4020
3940
|
* it: the gate path must not add a body read to its transport leg. Nothing but
|
|
@@ -4767,28 +4687,6 @@ function enqueueProjectHqIngest(input, dependencies = {}) {
|
|
|
4767
4687
|
return Promise.resolve("skipped");
|
|
4768
4688
|
}
|
|
4769
4689
|
}
|
|
4770
|
-
/**
|
|
4771
|
-
* Persists an advisory closeout event for a later normal HQ sink drain. Unlike
|
|
4772
|
-
* enqueueProjectHqIngest, this never starts a network request or enters the
|
|
4773
|
-
* process-exit lifecycle registry, so local closeout cannot wait on HQ.
|
|
4774
|
-
*/
|
|
4775
|
-
async function deferProjectHqIngestDirect(input, dependencies) {
|
|
4776
|
-
try {
|
|
4777
|
-
const setupDeadline = performance.now() + timeoutFor(dependencies);
|
|
4778
|
-
const projectInput = await projectInputForHqIngest(input, setupDeadline);
|
|
4779
|
-
if (projectInput === void 0) return "skipped";
|
|
4780
|
-
return await handoffHqIngest(projectInput, dependencies, setupDeadline);
|
|
4781
|
-
} catch {
|
|
4782
|
-
return "held";
|
|
4783
|
-
}
|
|
4784
|
-
}
|
|
4785
|
-
const hasCloseoutHandoffCustomization = (dependencies) => {
|
|
4786
|
-
try {
|
|
4787
|
-
return Reflect.ownKeys(dependencies).length > 0;
|
|
4788
|
-
} catch {
|
|
4789
|
-
return true;
|
|
4790
|
-
}
|
|
4791
|
-
};
|
|
4792
4690
|
const ISOLATED_CLOSEOUT_FS_WORKER_SOURCE = String.raw`
|
|
4793
4691
|
const crypto = require("node:crypto");
|
|
4794
4692
|
const fs = require("node:fs");
|
|
@@ -5045,8 +4943,8 @@ const runCloseoutFsWorker = async (data, budgetMs) => {
|
|
|
5045
4943
|
});
|
|
5046
4944
|
};
|
|
5047
4945
|
const isIsolatedReadResult = (value) => value !== null && typeof value === "object" && value.status === "read";
|
|
5048
|
-
const deferProjectHqIngestIsolated = async (input) => {
|
|
5049
|
-
const setupDeadline = performance.now() + timeoutFor({ env
|
|
4946
|
+
const deferProjectHqIngestIsolated = async (input, env) => {
|
|
4947
|
+
const setupDeadline = performance.now() + timeoutFor({ env });
|
|
5050
4948
|
let profilePath;
|
|
5051
4949
|
try {
|
|
5052
4950
|
profilePath = input.profilePath ? path.resolve(input.cwd, input.profilePath) : defaultProfilePath(input.cwd);
|
|
@@ -5071,7 +4969,7 @@ const deferProjectHqIngestIsolated = async (input) => {
|
|
|
5071
4969
|
let configPath;
|
|
5072
4970
|
let payloadPath;
|
|
5073
4971
|
try {
|
|
5074
|
-
configPath = defaultUserConfigPath(
|
|
4972
|
+
configPath = defaultUserConfigPath(env);
|
|
5075
4973
|
payloadPath = input.payloadJson === void 0 && input.payloadPath !== void 0 ? path.resolve(input.cwd, input.payloadPath) : void 0;
|
|
5076
4974
|
} catch {
|
|
5077
4975
|
return "skipped";
|
|
@@ -5131,19 +5029,34 @@ const deferProjectHqIngestIsolated = async (input) => {
|
|
|
5131
5029
|
const layout = repositorySpoolLayout({
|
|
5132
5030
|
owner: parsedProfile.repository.owner,
|
|
5133
5031
|
repo: parsedProfile.repository.name
|
|
5134
|
-
},
|
|
5032
|
+
}, env);
|
|
5135
5033
|
const persisted = await runCloseoutFsWorker({
|
|
5136
5034
|
body,
|
|
5137
5035
|
eventId,
|
|
5138
5036
|
root: layout.root,
|
|
5139
5037
|
segments: layout.segments,
|
|
5140
5038
|
type: "persist"
|
|
5141
|
-
}, journalFlushBudgetFor({ env
|
|
5039
|
+
}, journalFlushBudgetFor({ env }));
|
|
5142
5040
|
return persisted !== null && typeof persisted === "object" && persisted.status === "persisted" ? "deferred" : "held";
|
|
5143
5041
|
};
|
|
5042
|
+
/**
|
|
5043
|
+
* Persists an advisory closeout event for a later normal HQ sink drain. Unlike
|
|
5044
|
+
* enqueueProjectHqIngest, this never starts a network request or enters the
|
|
5045
|
+
* process-exit lifecycle registry, so local closeout cannot wait on HQ.
|
|
5046
|
+
*
|
|
5047
|
+
* There is one persistence implementation and it always runs in an unreferenced
|
|
5048
|
+
* worker, so no caller can select a main-thread variant whose durability and
|
|
5049
|
+
* confinement guarantees are proved separately. The only seam is the operator
|
|
5050
|
+
* environment the worker's budgets and spool location are read from.
|
|
5051
|
+
*/
|
|
5144
5052
|
async function deferProjectHqIngest(input, dependencies = {}) {
|
|
5145
|
-
|
|
5146
|
-
|
|
5053
|
+
let env;
|
|
5054
|
+
try {
|
|
5055
|
+
env = dependencies.env ?? process.env;
|
|
5056
|
+
} catch {
|
|
5057
|
+
return "skipped";
|
|
5058
|
+
}
|
|
5059
|
+
return deferProjectHqIngestIsolated(input, env);
|
|
5147
5060
|
}
|
|
5148
5061
|
//#endregion
|
|
5149
5062
|
//#region src/evidence-freshness.ts
|
|
@@ -8204,7 +8117,7 @@ function defaultPrVerifyGit() {
|
|
|
8204
8117
|
mergeBaseSha,
|
|
8205
8118
|
recognizeCatchUp: recognizeCatchUpCandidate,
|
|
8206
8119
|
runVerificationCommand(command, cwd, env) {
|
|
8207
|
-
return verificationOutcomeOf(runInheritedTee("bash", ["-lc", command], cwd, env));
|
|
8120
|
+
return verificationOutcomeOf(runInheritedTee("bash", ["-lc", withPinnedNodeOnPath(command, path.dirname(process.execPath))], cwd, env));
|
|
8208
8121
|
},
|
|
8209
8122
|
showFileAtRef,
|
|
8210
8123
|
stablePatchId: runStablePatchId,
|
|
@@ -9024,29 +8937,7 @@ const ladderCycleRefsFor = (cycles) => {
|
|
|
9024
8937
|
};
|
|
9025
8938
|
});
|
|
9026
8939
|
};
|
|
9027
|
-
const
|
|
9028
|
-
const { cap } = policy.interior;
|
|
9029
|
-
if (interiorCount > 0 && openFindings.length === 0) return {
|
|
9030
|
-
nextAction: { kind: "advance-to-gate" },
|
|
9031
|
-
stage: "interior-complete"
|
|
9032
|
-
};
|
|
9033
|
-
if (interiorCount >= cap) return {
|
|
9034
|
-
forcedTransition: {
|
|
9035
|
-
cap,
|
|
9036
|
-
kind: "interior-cap-reached"
|
|
9037
|
-
},
|
|
9038
|
-
nextAction: { kind: "advance-to-gate" },
|
|
9039
|
-
stage: "interior-complete"
|
|
9040
|
-
};
|
|
9041
|
-
return {
|
|
9042
|
-
nextAction: {
|
|
9043
|
-
cycle: interiorCount + 1,
|
|
9044
|
-
kind: "run-interior-cycle"
|
|
9045
|
-
},
|
|
9046
|
-
stage: "interior"
|
|
9047
|
-
};
|
|
9048
|
-
};
|
|
9049
|
-
const gatePosition = ({ blockingFindings, gateCount, openFindings, policy }) => {
|
|
8940
|
+
const resolveLadderPosition = ({ blockingFindings, gateCount, openFindings, policy }) => {
|
|
9050
8941
|
const { cap } = policy.gate;
|
|
9051
8942
|
if (gateCount === 0) return {
|
|
9052
8943
|
nextAction: {
|
|
@@ -9080,21 +8971,11 @@ const gatePosition = ({ blockingFindings, gateCount, openFindings, policy }) =>
|
|
|
9080
8971
|
stage: "gate"
|
|
9081
8972
|
};
|
|
9082
8973
|
};
|
|
9083
|
-
const
|
|
9084
|
-
blockingFindings,
|
|
9085
|
-
gateCount,
|
|
9086
|
-
openFindings,
|
|
9087
|
-
policy
|
|
9088
|
-
}) : interiorPosition({
|
|
9089
|
-
interiorCount,
|
|
9090
|
-
openFindings,
|
|
9091
|
-
policy
|
|
9092
|
-
});
|
|
9093
|
-
const executedStageFor = (ref, _policy) => {
|
|
8974
|
+
const executedStageFor = (ref) => {
|
|
9094
8975
|
if (ref.stage === "gate") return "gate";
|
|
9095
8976
|
return "interior";
|
|
9096
8977
|
};
|
|
9097
|
-
const eventFor = ({ cycles, openFindings, blockingFindings,
|
|
8978
|
+
const eventFor = ({ cycles, openFindings, blockingFindings, position, staleRepeats, refs }) => {
|
|
9098
8979
|
const latest = cycles.at(-1);
|
|
9099
8980
|
const latestRef = refs.at(-1);
|
|
9100
8981
|
if (!latest || !latestRef) return;
|
|
@@ -9113,7 +8994,7 @@ const eventFor = ({ cycles, openFindings, blockingFindings, policy, position, st
|
|
|
9113
8994
|
...latest.model === void 0 ? {} : { model: latest.model },
|
|
9114
8995
|
payloadVersion: 1,
|
|
9115
8996
|
...latest.session ? { session: latest.session } : {},
|
|
9116
|
-
stage: executedStageFor(latestRef
|
|
8997
|
+
stage: executedStageFor(latestRef),
|
|
9117
8998
|
type: "review-ladder-stage",
|
|
9118
8999
|
...latest.usage ? { usage: latest.usage } : {}
|
|
9119
9000
|
};
|
|
@@ -9130,26 +9011,19 @@ const evaluateReviewLadder = ({ cycles, policy }) => {
|
|
|
9130
9011
|
const position = resolveLadderPosition({
|
|
9131
9012
|
blockingFindings,
|
|
9132
9013
|
gateCount,
|
|
9133
|
-
interiorCount,
|
|
9134
9014
|
openFindings,
|
|
9135
9015
|
policy
|
|
9136
9016
|
});
|
|
9137
|
-
const diagnostics = policy.interior.cap > 0 && interiorCount === 0 && gateCount > 0 ? [{
|
|
9138
|
-
code: "interior-cycles-unrecorded",
|
|
9139
|
-
message: `Ladder policy configures an interior loop (cap ${policy.interior.cap}) but the history contains no interior cycles; the gate is proceeding without interior evidence.`
|
|
9140
|
-
}] : [];
|
|
9141
9017
|
return {
|
|
9142
9018
|
...position,
|
|
9143
9019
|
cycleCounts: {
|
|
9144
9020
|
gate: gateCount,
|
|
9145
9021
|
interior: interiorCount
|
|
9146
9022
|
},
|
|
9147
|
-
diagnostics,
|
|
9148
9023
|
event: eventFor({
|
|
9149
9024
|
blockingFindings,
|
|
9150
9025
|
cycles,
|
|
9151
9026
|
openFindings,
|
|
9152
|
-
policy,
|
|
9153
9027
|
position,
|
|
9154
9028
|
refs,
|
|
9155
9029
|
staleRepeats
|
|
@@ -9325,7 +9199,6 @@ var review_proof_exports = /* @__PURE__ */ __exportAll({
|
|
|
9325
9199
|
prReviewFindingSchema: () => prReviewFindingSchema,
|
|
9326
9200
|
prReviewProofSchema: () => prReviewProofSchema,
|
|
9327
9201
|
prReviewResultSchema: () => prReviewResultSchema,
|
|
9328
|
-
readPrReviewProof: () => readPrReviewProof,
|
|
9329
9202
|
resolveReviewAcceptance: () => resolveReviewAcceptance,
|
|
9330
9203
|
resolveReviewTerminalState: () => resolveReviewTerminalState,
|
|
9331
9204
|
resolveReviewTerminalStateAcrossReviews: () => resolveReviewTerminalStateAcrossReviews,
|
|
@@ -9451,7 +9324,6 @@ const validatePrReviewProof = (value) => {
|
|
|
9451
9324
|
}
|
|
9452
9325
|
return parsed.data;
|
|
9453
9326
|
};
|
|
9454
|
-
const readPrReviewProof = (filePath) => readProofFromPath(validatePrReviewProof, filePath);
|
|
9455
9327
|
const PR_REVIEW_PROOF_DESCRIPTOR = {
|
|
9456
9328
|
defaultPath: DEFAULT_PR_REVIEW_PROOF_PATH,
|
|
9457
9329
|
label: "pr:review proof",
|
|
@@ -17753,7 +17625,6 @@ function ladderStateForRun({ declaredDispositions, cycle, historical, identity,
|
|
|
17753
17625
|
policy
|
|
17754
17626
|
});
|
|
17755
17627
|
if (evaluation.unmatchedDispositions.length > 0) throw new Error(`Dispositions were dropped at fold time — they matched no flagged finding in the ladder history: ${evaluation.unmatchedDispositions.map((declaration) => declaration.finding.title).join("; ")}. The fold and the pre-run --dispositions validation disagree; nothing was persisted.`);
|
|
17756
|
-
for (const diagnostic of evaluation.diagnostics) console.error(`[${diagnostic.code}] ${diagnostic.message}`);
|
|
17757
17628
|
return {
|
|
17758
17629
|
evaluation,
|
|
17759
17630
|
ladder: { cycles }
|
|
@@ -20327,4 +20198,4 @@ async function run(argv = process.argv, cliEntry = factoryCliEntry()) {
|
|
|
20327
20198
|
}
|
|
20328
20199
|
}
|
|
20329
20200
|
//#endregion
|
|
20330
|
-
export { DEFAULT_DEMAND_WAIVER_PATH, DEFAULT_FACTORY_REPOSITORY, DEFAULT_ROOT_SHARED_GLOBS, DemandWaiveRefusalError, EMPTY_TREE_OBJECT_HASH, EPIC_STRUCTURE_NODE_STATUSES, EPIC_STRUCTURE_SCHEMA_VERSION, EpicStructureValidationError, FACTORY_BASE_REF_ENV, FACTORY_CHANGED_FILES_ENV, FACTORY_CHANGED_FILES_FILE_ENV, FactoryCliInvocationSchema, FollowUpActionSchema, MERGE_FREEZE_APP_SLUG, MERGE_FREEZE_CHECK_NAME, PrPublishFollowUpError, REVIEW_FOCUS_SECTION, WorkerCheckoutGuardError,
|
|
20201
|
+
export { DEFAULT_DEMAND_WAIVER_PATH, DEFAULT_FACTORY_REPOSITORY, DEFAULT_ROOT_SHARED_GLOBS, DemandWaiveRefusalError, EMPTY_TREE_OBJECT_HASH, EPIC_STRUCTURE_NODE_STATUSES, EPIC_STRUCTURE_SCHEMA_VERSION, EpicStructureValidationError, FACTORY_BASE_REF_ENV, FACTORY_CHANGED_FILES_ENV, FACTORY_CHANGED_FILES_FILE_ENV, FactoryCliInvocationSchema, FollowUpActionSchema, MERGE_FREEZE_APP_SLUG, MERGE_FREEZE_CHECK_NAME, PrPublishFollowUpError, REVIEW_FOCUS_SECTION, WorkerCheckoutGuardError, appendWithTraceSinks, applyDemandWaiver, assembleReviewPrompt, assertFactoryPrStatusIdentity, assertWorkerCheckoutAllowed, authorizeDemandWaiver, batteryScopeSummaryLines, boundary_manifest_exports as boundaryManifest, boundary_review_proof_exports as boundaryReviewProof, buildEpicStructureEvent, buildEpicStructurePayload, buildEvidenceEnvelope, buildReviewGateNotRequiredTraceEvent, comment_provenance_exports as commentProvenance, createGitHubCheckRunMergeFreezeStore, createLocalJsonlTraceSink, createProgram, createVerificationRunContext, doctorProjectProfile, epicStructureEventId, evidenceEnvelopeFilename, followUpFromArgv, impactStampScopeDecision, isProductionHqUrl, loadProjectProfile, normalizeIssueComments, planFactoryPrStatusHud, planPreviewLifecycle, planPublishFollowUp, planVerificationBattery, readiness_evaluation_exports as prReadinessEvaluation, external_evidence_exports as prReadinessExternalEvidence, pr_body_renderer_exports as prReadinessPrBodyRenderer, proof_identity_exports as prReadinessProofIdentity, review_proof_exports as prReadinessReviewProof, status_check_rollup_exports as prReadinessStatusChecks, verification_proof_exports as prReadinessVerificationProof, presentFactoryPrStatusHud, previewLifecycleTargets, publishEpicStructure, readDemandWaivers, readFactoryPrStatusSources, readPrReadyProof, refreshFactoryPrStatusHud, refreshFactoryPrStatusHudSafely, renderFactoryPrStatusHud, resolveFactoryRepository, resolveTraceWriteSinks, reviewFocusFromIssueBody, reviewPromptSectionSchema, reviewPromptSectionsSchema, run, runBoundaryCheck, runDemandWaive, runEvidenceEmit, runPrPublish, runPrReady, runPrReview, runPrVerify, scanFactoryTraceDiagnostics, scanFactoryTraceEvents, selectWaiversForCandidate, toFactoryTraceEnvelope, tryAppendReviewGateNotRequiredTraceEvent, validateBoundaryCheckProof, validateDagDocument, validateDemandWaiverStore, validateFactoryTraceEvent, validateMergeFreezeState, validatePrReadyProof, validatePrVerifyProof, validatePreviewLifecyclePlan, waivedDemandNotice, waivedDemandSchema, worktree_scratch_files_exports as worktreeScratchFiles };
|
package/dist/schemas.d.ts
CHANGED
|
@@ -432,12 +432,12 @@ declare const managedReadinessLedgerSchema: z.ZodObject<{
|
|
|
432
432
|
"interior-cap-reached": "interior-cap-reached";
|
|
433
433
|
}>>;
|
|
434
434
|
nextAction: z.ZodEnum<{
|
|
435
|
+
"run-interior-cycle": "run-interior-cycle";
|
|
436
|
+
"advance-to-gate": "advance-to-gate";
|
|
435
437
|
"run-gate-cycle": "run-gate-cycle";
|
|
436
438
|
"accept-nonblocking-findings": "accept-nonblocking-findings";
|
|
437
439
|
"escalate-to-triage": "escalate-to-triage";
|
|
438
440
|
"ready-for-human": "ready-for-human";
|
|
439
|
-
"advance-to-gate": "advance-to-gate";
|
|
440
|
-
"run-interior-cycle": "run-interior-cycle";
|
|
441
441
|
}>;
|
|
442
442
|
stage: z.ZodEnum<{
|
|
443
443
|
gate: "gate";
|
|
@@ -903,8 +903,8 @@ declare const closeoutArtifactSchema: z.ZodObject<{
|
|
|
903
903
|
}, z.core.$strict>;
|
|
904
904
|
unit: z.ZodEnum<{
|
|
905
905
|
boolean: "boolean";
|
|
906
|
-
text: "text";
|
|
907
906
|
count: "count";
|
|
907
|
+
text: "text";
|
|
908
908
|
tokens: "tokens";
|
|
909
909
|
usd: "usd";
|
|
910
910
|
}>;
|
|
@@ -1201,12 +1201,12 @@ declare const prReadyProofSchema: z.ZodObject<{
|
|
|
1201
1201
|
"interior-cap-reached": "interior-cap-reached";
|
|
1202
1202
|
}>>;
|
|
1203
1203
|
nextAction: z.ZodEnum<{
|
|
1204
|
+
"run-interior-cycle": "run-interior-cycle";
|
|
1205
|
+
"advance-to-gate": "advance-to-gate";
|
|
1204
1206
|
"run-gate-cycle": "run-gate-cycle";
|
|
1205
1207
|
"accept-nonblocking-findings": "accept-nonblocking-findings";
|
|
1206
1208
|
"escalate-to-triage": "escalate-to-triage";
|
|
1207
1209
|
"ready-for-human": "ready-for-human";
|
|
1208
|
-
"advance-to-gate": "advance-to-gate";
|
|
1209
|
-
"run-interior-cycle": "run-interior-cycle";
|
|
1210
1210
|
}>;
|
|
1211
1211
|
stage: z.ZodEnum<{
|
|
1212
1212
|
gate: "gate";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patronage/software-factory",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.30",
|
|
4
4
|
"description": "Shared Patronage software factory CLI and project-profile validation tools",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"picomatch": "^4.0.5",
|
|
38
38
|
"yaml": "^2.9.0",
|
|
39
39
|
"zod": "4.4.3",
|
|
40
|
-
"@patronage/factory-ci": "1.0.0-alpha.
|
|
40
|
+
"@patronage/factory-ci": "1.0.0-alpha.30"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/node": "24.13.3",
|