@yagni-app/code-staging 1.2.10-staging.2105.1 → 1.2.10-staging.2111.1
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/extension/pipeline/checkAttribution.d.ts +85 -0
- package/dist/extension/pipeline/checkAttribution.js +131 -0
- package/dist/extension/pipeline/headlessGo.d.ts +5 -5
- package/dist/extension/pipeline/headlessGo.js +112 -87
- package/dist/extension/pipeline/missionChecks.d.ts +11 -1
- package/dist/extension/pipeline/missionChecks.js +24 -2
- package/dist/extension/pipeline/verify.d.ts +137 -138
- package/dist/extension/pipeline/verify.js +297 -372
- package/package.json +2 -2
|
@@ -36,8 +36,9 @@
|
|
|
36
36
|
* failures (connection refused, missing env, DB/auth, command not found) and
|
|
37
37
|
* anything UNCERTAIN fail OPEN with an honest note, never a never-clearable
|
|
38
38
|
* critical. A cloud session's gate (`unreadTestFailureIsFinding`) makes an
|
|
39
|
-
* UNCERTAIN failure a finding carrying the output tail
|
|
40
|
-
*
|
|
39
|
+
* UNCERTAIN failure a finding carrying the output tail: it names nothing the
|
|
40
|
+
* unchanged code could already have, so it is never excused. On a build that
|
|
41
|
+
* named the repository's toolchain
|
|
41
42
|
* (`YAGNI_TOOLCHAIN_FILE`, a sandbox) both halves run on it, as the model's
|
|
42
43
|
* shell and the approved checks do ({@link buildGateVerifyEnv},
|
|
43
44
|
* {@link buildGateTestEnv}).
|
|
@@ -52,6 +53,7 @@
|
|
|
52
53
|
* findings, handoffs, or run records (§0.9).
|
|
53
54
|
*/
|
|
54
55
|
import { type ToolchainFile } from "../toolchain/spawnHook.js";
|
|
56
|
+
import { canonicalCheckCommand, type BaseMeasurement, type FailureAttribution } from "./checkAttribution.js";
|
|
55
57
|
import { type FailedCheckResult, type MissionChecksFile } from "./missionChecks.js";
|
|
56
58
|
import type { Finding } from "./types.js";
|
|
57
59
|
/**
|
|
@@ -112,17 +114,13 @@ export interface VerifyOutcome {
|
|
|
112
114
|
/** An approved check's name on the report: its command, cut at 80 characters. */
|
|
113
115
|
export declare function checkLabel(command: string): string;
|
|
114
116
|
/**
|
|
115
|
-
* A command as the gate compares two
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
* suite three times). Only the leading form: a manager's flags before the
|
|
121
|
-
* script leave the command as it is. The same rule as
|
|
122
|
-
* `canonicalCheckCommand` in the backend's attempts/inputs.ts; both test
|
|
123
|
-
* files read one corpus, test/fixtures/equivalentCheckCommands.json. Pure.
|
|
117
|
+
* A command as the gate compares two (staging bench 2026-10-25: the gate's
|
|
118
|
+
* own `test` script and two approved twins ran one suite three times):
|
|
119
|
+
* `checkAttribution.ts`, the one rule the host's attempts/inputs.ts keeps
|
|
120
|
+
* too; both test files read one corpus,
|
|
121
|
+
* test/fixtures/equivalentCheckCommands.json.
|
|
124
122
|
*/
|
|
125
|
-
export
|
|
123
|
+
export { canonicalCheckCommand };
|
|
126
124
|
/**
|
|
127
125
|
* True when a command changes the checkout's git state: a commit, a branch
|
|
128
126
|
* created or switched, a reset, a stash, a push. `git branch`, `git remote`
|
|
@@ -367,7 +365,8 @@ export type TestFailureClassification = {
|
|
|
367
365
|
* prerequisite ({@link classifyMissingPrerequisite}, given the `env` the
|
|
368
366
|
* command ran under) is `infra` with `needs` and the cause "needs <it>".
|
|
369
367
|
* - recognisable failing-test lines (pnpm-wrapped vitest / jest / node:test
|
|
370
|
-
* TAP + spec reporters) → `failures` with
|
|
368
|
+
* TAP + spec reporters, pytest, Pest, PHPUnit, go test) → `failures` with
|
|
369
|
+
* located `critical` findings
|
|
371
370
|
* (capped at 25, deduped, locations attached when the runner printed them).
|
|
372
371
|
* - a failure summary with no parseable per-test lines → one capped tail
|
|
373
372
|
* finding (still real evidence tests ran and failed).
|
|
@@ -404,33 +403,36 @@ export declare function parseVerifyFailures(output: string, exitCode: number, la
|
|
|
404
403
|
*/
|
|
405
404
|
export declare function toRepoRelativePath(file: string, repoRoot: string, commandCwd: string): string;
|
|
406
405
|
/**
|
|
407
|
-
* What the gate's
|
|
408
|
-
* anything (YAG-1003)
|
|
409
|
-
*
|
|
410
|
-
*
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
*
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
*
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
|
|
431
|
-
|
|
406
|
+
* What the gate's checks did on the unchanged code before the build changed
|
|
407
|
+
* anything (YAG-1003), by check id (`checkId`: the command and the folder it
|
|
408
|
+
* runs in): each that passed there, and each that failed with its failure
|
|
409
|
+
* keys. A check with no entry was not measured there (or gave no verdict),
|
|
410
|
+
* and its failures all count. The session measures each check once per
|
|
411
|
+
* attempt and base commit ({@link makeMeasureOnBase}); `checks.json` carries
|
|
412
|
+
* what the attempt's earlier sessions measured.
|
|
413
|
+
*/
|
|
414
|
+
export type BaseMeasurements = ReadonlyMap<string, Omit<BaseMeasurement, "id">>;
|
|
415
|
+
/** A detected command's id, as the base measurement and the gate both key it. */
|
|
416
|
+
export declare function commandCheckId(repoRoot: string, command: Pick<VerifyCommand, "cwd" | "argv">): string;
|
|
417
|
+
/**
|
|
418
|
+
* One finding's failure key, in `checkAttribution.ts`'s shapes: a failing
|
|
419
|
+
* test's name, or a located diagnostic's repo-relative file and message,
|
|
420
|
+
* never its line, since a change above a failure moves it. A finding that is
|
|
421
|
+
* only the output's tail names nothing stable: null, and never excused. Read
|
|
422
|
+
* before the finding is prefixed with what ran. Pure.
|
|
423
|
+
*/
|
|
424
|
+
export declare function findingKey(finding: Finding): string | null;
|
|
425
|
+
/**
|
|
426
|
+
* The failures this change caused, by `attributeFailure`: each failure the
|
|
427
|
+
* unchanged code already had is excused once, so a second copy of an old
|
|
428
|
+
* error is new, and a failure that names nothing never is. No measurement on
|
|
429
|
+
* the base leaves every failure in place. `keys` is index for index with
|
|
430
|
+
* `findings`. Pure.
|
|
431
|
+
*/
|
|
432
|
+
export declare function attributeFindings(findings: readonly Finding[], keys: ReadonlyArray<string | null>, base: Omit<BaseMeasurement, "id"> | undefined): {
|
|
432
433
|
findings: Finding[];
|
|
433
434
|
excused: number;
|
|
435
|
+
verdict: FailureAttribution;
|
|
434
436
|
};
|
|
435
437
|
/** The note for failures the clean tree already had, by command label. Pure. */
|
|
436
438
|
export declare function preexistingNote(byLabel: ReadonlyMap<string, number>): string | null;
|
|
@@ -579,23 +581,18 @@ export interface MakeRunVerifyOpts {
|
|
|
579
581
|
/** Undo what the half wrote into the tree (default: `git clean` / `git checkout` of exactly those paths). */
|
|
580
582
|
undoTreeWrites?: (cwd: string, entries: TreeEntry[]) => Promise<void>;
|
|
581
583
|
/**
|
|
582
|
-
* What the
|
|
583
|
-
*
|
|
584
|
-
*
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
/**
|
|
588
|
-
* What the approved checks `checks.json` marks `measureOnBase` did on the
|
|
589
|
-
* unchanged code ({@link makeMeasureChecksOnBase}). It stands over each
|
|
590
|
-
* one's `status`: one that passed there must pass, and one that failed
|
|
591
|
-
* there is the change's only where it fails anew. Absent: `status` alone.
|
|
584
|
+
* What the gate's checks did on the unchanged code ({@link makeMeasureOnBase},
|
|
585
|
+
* and what `checks.json` carried from the attempt's earlier sessions). A
|
|
586
|
+
* failure is the change's unless `attributeFailure` finds the base already
|
|
587
|
+
* had it; a check with no measurement counts every failure, whatever label
|
|
588
|
+
* `checks.json` gave it. Absent: every failure is a finding.
|
|
592
589
|
*/
|
|
593
|
-
|
|
590
|
+
onBase?: BaseMeasurements | null;
|
|
594
591
|
/**
|
|
595
592
|
* The cloud session's rule (spec decision 3): a test run that exits
|
|
596
593
|
* non-zero with output no parser reads is a finding carrying its output
|
|
597
|
-
* tail
|
|
598
|
-
*
|
|
594
|
+
* tail. It names nothing the base could already have, so it is never
|
|
595
|
+
* excused. Absent (mission mode): it fails open with a note, as before.
|
|
599
596
|
*/
|
|
600
597
|
unreadTestFailureIsFinding?: boolean;
|
|
601
598
|
/**
|
|
@@ -646,8 +643,8 @@ export interface MakeWorkstreamCheckOpts {
|
|
|
646
643
|
detect?: (cwd: string, claimDirs: string[]) => VerifyCommand[];
|
|
647
644
|
exec?: VerifyExec;
|
|
648
645
|
timeoutMs?: number;
|
|
649
|
-
/** What the
|
|
650
|
-
|
|
646
|
+
/** What the unchanged code already failed on (YAG-1003): those failures are not a workstream's. */
|
|
647
|
+
onBase?: BaseMeasurements | null;
|
|
651
648
|
/**
|
|
652
649
|
* The toolchain the checks run on, as the full gate's do (default:
|
|
653
650
|
* `YAGNI_TOOLCHAIN_FILE`, when it reads).
|
|
@@ -680,6 +677,27 @@ export interface MakeWorkstreamCheckOpts {
|
|
|
680
677
|
* and produces no findings.
|
|
681
678
|
*/
|
|
682
679
|
export declare function makeWorkstreamCheck(opts?: MakeWorkstreamCheckOpts): (cwd: string, targets: WorkstreamCheckTarget[], signal?: AbortSignal) => Promise<WorkstreamCheckResult[]>;
|
|
680
|
+
/**
|
|
681
|
+
* A failing repository command's findings, located from the folder it ran in
|
|
682
|
+
* and prefixed with what ran, each with its failure key ({@link findingKey},
|
|
683
|
+
* index for index): the gate's on the build's tree, and the unchanged code's
|
|
684
|
+
* measurement ({@link makeMeasureOnBase}), so a failure keys the same on
|
|
685
|
+
* both. Pure.
|
|
686
|
+
*/
|
|
687
|
+
export declare function repoCommandFindings(failure: {
|
|
688
|
+
output: string;
|
|
689
|
+
code: number;
|
|
690
|
+
env?: NodeJS.ProcessEnv;
|
|
691
|
+
}, at: {
|
|
692
|
+
label: string;
|
|
693
|
+
prefix: string;
|
|
694
|
+
repoRoot: string;
|
|
695
|
+
dir: string;
|
|
696
|
+
limit?: number;
|
|
697
|
+
}): {
|
|
698
|
+
findings: Finding[];
|
|
699
|
+
keys: Array<string | null>;
|
|
700
|
+
};
|
|
683
701
|
/**
|
|
684
702
|
* Build the runVerify function injected into the orchestrator. It discovers the
|
|
685
703
|
* changed package(s) (scoped to this run's diff via `baselinePaths`), detects a
|
|
@@ -690,109 +708,90 @@ export declare function makeWorkstreamCheck(opts?: MakeWorkstreamCheckOpts): (cw
|
|
|
690
708
|
* blocks a real change on its own failure.
|
|
691
709
|
*/
|
|
692
710
|
export declare function makeRunVerify(opts?: MakeRunVerifyOpts): (cwd: string, signal?: AbortSignal, baselinePaths?: string[]) => Promise<VerifyOutcome>;
|
|
693
|
-
/** The whole
|
|
694
|
-
export declare const
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
711
|
+
/** The whole base measurement's cap, before the build starts: it costs minutes at most. */
|
|
712
|
+
export declare const BASE_MEASUREMENT_BUDGET_MS: number;
|
|
713
|
+
/**
|
|
714
|
+
* One check to run once on the unchanged code: an approved check from
|
|
715
|
+
* `checks.json` (at the repository root, as the gate runs it), or one of the
|
|
716
|
+
* gate's own typecheck and test commands in a package the build will
|
|
717
|
+
* change, keyed (`id`) as the gate keys its run.
|
|
718
|
+
*/
|
|
719
|
+
export interface BaseTarget {
|
|
720
|
+
id: string;
|
|
721
|
+
label: string;
|
|
722
|
+
kind: "check" | "typecheck" | "test";
|
|
723
|
+
/** The command line, as the stream hears it. */
|
|
724
|
+
command: string;
|
|
725
|
+
argv: string[];
|
|
726
|
+
/** Where it runs (absolute). */
|
|
727
|
+
dir: string;
|
|
728
|
+
}
|
|
729
|
+
/**
|
|
730
|
+
* What the gate will judge, in the order it is measured: the approved
|
|
731
|
+
* checks `checks.json` marks `measureOnBase` (every one it can run with
|
|
732
|
+
* `allChecks`, a resumed session's rule: the record's green is what went
|
|
733
|
+
* stale), then the gate's own typecheck and test commands in `dirs`, the
|
|
734
|
+
* packages the build will change. Each once, by id; a check that changes the
|
|
735
|
+
* checkout's git state or that the sandbox cannot run is never one. Read on
|
|
736
|
+
* the tree as it is: the gate detects its commands on the build's tree, so
|
|
737
|
+
* these are the ids it will look up.
|
|
738
|
+
*/
|
|
739
|
+
export declare function baseTargets(cwd: string, input: {
|
|
740
|
+
dirs: string[];
|
|
741
|
+
checks: MissionChecksFile | null;
|
|
742
|
+
allChecks?: boolean;
|
|
743
|
+
}, opts?: Pick<MakeRunVerifyOpts, "detect" | "detectTests">): BaseTarget[];
|
|
744
|
+
export interface MakeMeasureOnBaseOpts {
|
|
698
745
|
exec?: VerifyExec;
|
|
746
|
+
/** One typecheck's cap (default {@link VERIFY_TIMEOUT_MS}). */
|
|
699
747
|
timeoutMs?: number;
|
|
748
|
+
/** One test run's cap (default {@link VERIFY_TEST_TIMEOUT_MS}). */
|
|
700
749
|
testTimeoutMs?: number;
|
|
750
|
+
/** One approved check's cap (default {@link REPO_CHECK_TIMEOUT_MS}). */
|
|
751
|
+
repoCheckTimeoutMs?: number;
|
|
752
|
+
/** Env overrides for determinism in tests (default: the gate's own, per kind). */
|
|
701
753
|
testEnv?: NodeJS.ProcessEnv;
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
* `YAGNI_TOOLCHAIN_FILE`, when it reads).
|
|
705
|
-
*/
|
|
754
|
+
repoChecksEnv?: NodeJS.ProcessEnv;
|
|
755
|
+
/** The toolchain the commands run on, as the gate's do (default: `YAGNI_TOOLCHAIN_FILE`, when it reads). */
|
|
706
756
|
toolchain?: () => ToolchainFile | null;
|
|
707
757
|
budgetMs?: number;
|
|
708
758
|
now?: () => number;
|
|
709
759
|
treeStatus?: (cwd: string, signal?: AbortSignal) => Promise<string>;
|
|
710
760
|
undoTreeWrites?: (cwd: string, entries: TreeEntry[]) => Promise<void>;
|
|
711
|
-
/** Told as each command starts and ends on the
|
|
761
|
+
/** Told as each command starts and ends on the unchanged code (the session's stream). */
|
|
712
762
|
onCheck?: (event: VerifyCheckEvent) => void;
|
|
713
763
|
}
|
|
714
|
-
/** What
|
|
715
|
-
export interface
|
|
716
|
-
|
|
717
|
-
|
|
764
|
+
/** What one measurement found, for the gate and for the run's log. */
|
|
765
|
+
export interface BaseMeasurementResult {
|
|
766
|
+
/** Each target that gave a verdict, by id: it passed, or failed with these keys. */
|
|
767
|
+
measured: Map<string, Omit<BaseMeasurement, "id">>;
|
|
768
|
+
/** The labels of the targets that gave a verdict. */
|
|
718
769
|
ran: string[];
|
|
719
|
-
/** Keyed failures the
|
|
770
|
+
/** Keyed failures the unchanged code had, across them. */
|
|
720
771
|
failures: number;
|
|
721
|
-
/**
|
|
722
|
-
notes: string[];
|
|
723
|
-
}
|
|
724
|
-
/**
|
|
725
|
-
* Run the gate's own typecheck and test commands ONCE on the clean tree,
|
|
726
|
-
* before the build changes anything (YAG-1003), in the package dirs the
|
|
727
|
-
* approved plan names, and keep each command's failure keys. The build's gate
|
|
728
|
-
* then counts only the failures this change added ({@link subtractBaseline}).
|
|
729
|
-
*
|
|
730
|
-
* The same detection, exec seam and environments as {@link makeRunVerify}, so
|
|
731
|
-
* a command's key and its failures' keys match the build's runs. Fail-open per
|
|
732
|
-
* command: one that cannot run, times out, or is not reached in the budget
|
|
733
|
-
* has no baseline, and its failures all count, as before. What the commands
|
|
734
|
-
* write into the tree is undone, so none of it reaches the candidate.
|
|
735
|
-
*/
|
|
736
|
-
export declare function makeTakeVerifyBaseline(opts?: MakeTakeVerifyBaselineOpts): (cwd: string, dirs: string[], signal?: AbortSignal, budgetOverrideMs?: number) => Promise<VerifyBaselineResult>;
|
|
737
|
-
/**
|
|
738
|
-
* What the approved checks marked `measureOnBase` did on the unchanged code,
|
|
739
|
-
* by command (trimmed): each that passed there, and each that failed there
|
|
740
|
-
* with failures the gate reads, with how often each failure key was seen
|
|
741
|
-
* (none for a failure only a summary line names). A command in neither gave
|
|
742
|
-
* no verdict there, and keeps the status `checks.json` gave it.
|
|
743
|
-
*/
|
|
744
|
-
export interface ChecksOnBase {
|
|
745
|
-
passed: ReadonlySet<string>;
|
|
746
|
-
failed: ReadonlyMap<string, ReadonlyMap<string, number>>;
|
|
747
|
-
}
|
|
748
|
-
/** {@link ChecksOnBase}, with what ran and why the rest gave no verdict, for the run's log. */
|
|
749
|
-
export interface ChecksOnBaseResult extends ChecksOnBase {
|
|
750
|
-
ran: string[];
|
|
772
|
+
/** Targets that gave no verdict, and why: their failures all count later. */
|
|
751
773
|
notes: string[];
|
|
752
774
|
/**
|
|
753
|
-
* What the
|
|
754
|
-
* False when the tree could not be read before them or the undo
|
|
755
|
-
* the build then starts on a tree
|
|
775
|
+
* What the commands wrote into the tree was undone (or they wrote
|
|
776
|
+
* nothing). False when the tree could not be read before them or the undo
|
|
777
|
+
* failed: the build then starts on a tree they may have dirtied.
|
|
756
778
|
*/
|
|
757
779
|
treeUndone: boolean;
|
|
758
780
|
}
|
|
759
781
|
/**
|
|
760
|
-
*
|
|
761
|
-
*
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
export interface MakeMeasureChecksOnBaseOpts {
|
|
765
|
-
exec?: VerifyExec;
|
|
766
|
-
/** Repository-checks env override for determinism in tests (default: the gate's own). */
|
|
767
|
-
repoChecksEnv?: NodeJS.ProcessEnv;
|
|
768
|
-
toolchain?: () => ToolchainFile | null;
|
|
769
|
-
/** One check's cap (default {@link REPO_CHECK_TIMEOUT_MS}). */
|
|
770
|
-
timeoutMs?: number;
|
|
771
|
-
budgetMs?: number;
|
|
772
|
-
now?: () => number;
|
|
773
|
-
treeStatus?: (cwd: string, signal?: AbortSignal) => Promise<string>;
|
|
774
|
-
undoTreeWrites?: (cwd: string, entries: TreeEntry[]) => Promise<void>;
|
|
775
|
-
/** Told as each check starts and ends on the unchanged code (the session's stream). */
|
|
776
|
-
onCheck?: (event: VerifyCheckEvent) => void;
|
|
777
|
-
}
|
|
778
|
-
/**
|
|
779
|
-
* Run each approved check `checks.json` marks `measureOnBase` once on the
|
|
780
|
-
* unchanged code, before the build changes anything: a plan's check the
|
|
781
|
-
* host has not seen pass there (none of the record's, or a red one the
|
|
782
|
-
* record may hold from long ago), and a command the repository's CI runs
|
|
783
|
-
* when the record names no check of its own. A check the plan wrote for the
|
|
784
|
-
* change often fails there by design (its test file is not written yet), and a
|
|
785
|
-
* failure that says only that (a file not found, no tests to run, output no
|
|
786
|
-
* parser reads) is no verdict: its failures all count after the build, as
|
|
787
|
-
* before. A failure the gate reads (failing tests, located diagnostics, a
|
|
788
|
-
* test runner's failure summary) is one the unchanged code already has.
|
|
782
|
+
* Run each target ({@link baseTargets}) once on the unchanged code, before
|
|
783
|
+
* the build changes anything (YAG-1003), and keep what it did: passed, or
|
|
784
|
+
* failed with its failure keys ({@link findingKey}). The build's gate then
|
|
785
|
+
* counts only the failures the change added ({@link attributeFindings}).
|
|
789
786
|
*
|
|
790
|
-
*
|
|
791
|
-
*
|
|
792
|
-
*
|
|
793
|
-
*
|
|
794
|
-
*
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
787
|
+
* Each runs as the gate runs it, with the same command line, environment
|
|
788
|
+
* and toolchain, so a failure keys the same on both trees. A run that says
|
|
789
|
+
* only that it could not run (an infra failure, a path it reads not there,
|
|
790
|
+
* a command not found) gives no verdict, and its failures all count after
|
|
791
|
+
* the build. A test run or check whose output no parser reads failed there
|
|
792
|
+
* with no keys: nothing after the build is excused by it. Bounded: each by
|
|
793
|
+
* its cap, the whole by the budget, and a target not reached in it gives no
|
|
794
|
+
* verdict. What the commands write into the tree is undone.
|
|
795
|
+
*/
|
|
796
|
+
export declare function makeMeasureOnBase(opts?: MakeMeasureOnBaseOpts): (cwd: string, targets: readonly BaseTarget[], signal?: AbortSignal, budgetOverrideMs?: number) => Promise<BaseMeasurementResult>;
|
|
798
797
|
//# sourceMappingURL=verify.d.ts.map
|