@yagni-app/code-staging 1.2.6-staging.1951.1 → 1.2.6-staging.1956.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.
Files changed (30) hide show
  1. package/dist/extension/branding.d.ts +20 -0
  2. package/dist/extension/branding.js +49 -8
  3. package/dist/extension/index.js +5 -0
  4. package/dist/extension/pipeline/changeScan.d.ts +62 -0
  5. package/dist/extension/pipeline/changeScan.js +307 -0
  6. package/dist/extension/pipeline/cloud.d.ts +205 -0
  7. package/dist/extension/pipeline/cloud.js +382 -0
  8. package/dist/extension/pipeline/continuation.d.ts +7 -3
  9. package/dist/extension/pipeline/continuation.js +29 -13
  10. package/dist/extension/pipeline/findings.d.ts +9 -4
  11. package/dist/extension/pipeline/findings.js +25 -10
  12. package/dist/extension/pipeline/finish.d.ts +11 -1
  13. package/dist/extension/pipeline/finish.js +51 -5
  14. package/dist/extension/pipeline/headlessGo.d.ts +30 -3
  15. package/dist/extension/pipeline/headlessGo.js +253 -29
  16. package/dist/extension/pipeline/orchestrator.d.ts +8 -2
  17. package/dist/extension/pipeline/orchestrator.js +249 -68
  18. package/dist/extension/pipeline/personas.d.ts +8 -3
  19. package/dist/extension/pipeline/personas.js +42 -7
  20. package/dist/extension/pipeline/planOutput.d.ts +42 -0
  21. package/dist/extension/pipeline/planOutput.js +94 -0
  22. package/dist/extension/pipeline/stages.d.ts +34 -5
  23. package/dist/extension/pipeline/stages.js +136 -7
  24. package/dist/extension/pipeline/tierCap.d.ts +22 -1
  25. package/dist/extension/pipeline/tierCap.js +48 -1
  26. package/dist/extension/pipeline/types.d.ts +31 -0
  27. package/dist/extension/pipeline/types.js +2 -0
  28. package/dist/extension/pipeline/verify.d.ts +128 -4
  29. package/dist/extension/pipeline/verify.js +356 -31
  30. package/package.json +2 -2
@@ -67,6 +67,33 @@ export interface PipelineStage {
67
67
  * claimed files, sibling claims, and the shared-worktree discipline rules.
68
68
  */
69
69
  personaClause?: string;
70
+ /**
71
+ * The persona body this stage runs with, in place of its agent's. The cloud
72
+ * plan stage takes the host's `plan-persona.md` (Reeve's persona) here.
73
+ */
74
+ persona?: string;
75
+ }
76
+ /**
77
+ * A stage list and the loop rules that go with it. The `full` lane is what
78
+ * interactive /go and mission builds run; the `cloud` lane is the one-attempt
79
+ * session (`yagni go --headless --cloud`).
80
+ */
81
+ export interface PipelineLane {
82
+ stages: PipelineStage[];
83
+ /** The review angles fanned out each round; empty is one reviewer covering every angle. */
84
+ reviewLenses: readonly ReviewLens[];
85
+ /** Review rounds before the loop stops `round_cap`. */
86
+ maxReviewRounds: number;
87
+ /** Whether implement may fan out into parallel builders (the diamond). */
88
+ fanout: boolean;
89
+ /** The plan stage ends the run: the plan goes to its gate before anything is built. */
90
+ stopAfterPlan: boolean;
91
+ /**
92
+ * Every stage loads the Team's skills (the launcher's `--skill` /
93
+ * `--prompt-template` flags), not only the ones that write code: the
94
+ * cloud session plans and reviews with them too (spec decision 4).
95
+ */
96
+ skillsEveryStage: boolean;
70
97
  }
71
98
  /** A single structured review finding parsed from a reviewer's output. */
72
99
  export interface Finding {
@@ -210,6 +237,8 @@ export interface PipelineResult {
210
237
  * orchestrator never sets it — commit/push live outside the LLM pipeline).
211
238
  */
212
239
  finish?: FinishInfo;
240
+ /** The plan the run wrote, on a lane whose plan stage ends the run (`stopAfterPlan`). */
241
+ plan?: string;
213
242
  }
214
243
  /**
215
244
  * The append-only resilience journal (spec: 2026-06-29-yagni-code-go-resilience).
@@ -512,6 +541,8 @@ export type PipelineProgress = {
512
541
  * - Round two runs only when round one found a blocker (`shouldStop`); what is
513
542
  * still open after the cap is written into the pull request body under
514
543
  * "Left for review" for Proctor, never a third round.
544
+ * This is the `full` lane's cap. The cloud lane carries its own
545
+ * (`PipelineLane.maxReviewRounds`): one reviewer per round, so four rounds.
515
546
  */
516
547
  export declare const MAX_REVIEW_ROUNDS = 2;
517
548
  /**
@@ -17,6 +17,8 @@
17
17
  * - Round two runs only when round one found a blocker (`shouldStop`); what is
18
18
  * still open after the cap is written into the pull request body under
19
19
  * "Left for review" for Proctor, never a third round.
20
+ * This is the `full` lane's cap. The cloud lane carries its own
21
+ * (`PipelineLane.maxReviewRounds`): one reviewer per round, so four rounds.
20
22
  */
21
23
  export const MAX_REVIEW_ROUNDS = 2;
22
24
  /**
@@ -94,7 +94,35 @@ export interface VerifyOutcome {
94
94
  reason?: string;
95
95
  /** Critical findings parsed from a failing run; empty otherwise. */
96
96
  findings: Finding[];
97
+ /** Failures the clean tree already had (YAG-1003): named in `reason`, never findings. */
98
+ preexisting?: number;
99
+ /** Every command the gate ran, with how it exited (the cloud session's `result.json` checks). */
100
+ checks?: VerifyCheckRun[];
97
101
  }
102
+ /** One command the gate ran, and how it went. */
103
+ export interface VerifyCheckRun {
104
+ name: string;
105
+ command: string;
106
+ /** Where it ran, repo-relative ("." for the root). */
107
+ cwd: string;
108
+ /** Null when the command never exited: it timed out, was aborted, or was not found. */
109
+ exitCode: number | null;
110
+ durationMs: number;
111
+ /**
112
+ * How the check stands on the unchanged code: it already failed there
113
+ * (the YAG-1003 baseline, or `checks.json`), the sandbox cannot run it, or
114
+ * neither.
115
+ */
116
+ baseline: "runnable" | "fails_on_base" | "cannot_run";
117
+ /** Why it has no exit code: "timed out", "aborted", "not found" or "could not run". */
118
+ note?: string;
119
+ }
120
+ /**
121
+ * Why a command threw instead of exiting, as its check record says it. `run`
122
+ * is the run's own signal (a /stop or the run's end); `capped` is the one
123
+ * the command ran under, which also carries its time cap.
124
+ */
125
+ export declare function unexitedNote(err: unknown, run?: AbortSignal, capped?: AbortSignal): string;
98
126
  /** Injectable fs seam so detection is unit-testable without a real repo. */
99
127
  export interface DetectOpts {
100
128
  readFile?: (path: string) => string;
@@ -228,15 +256,16 @@ export type TestFailureClassification = {
228
256
  * Callers scrub the output through {@link scrubSecrets} BEFORE classification
229
257
  * so findings/notes never carry secrets (§0.9).
230
258
  */
231
- export declare function classifyTestFailure(output: string, exitCode: number): TestFailureClassification;
259
+ export declare function classifyTestFailure(output: string, exitCode: number, limit?: number): TestFailureClassification;
232
260
  /**
233
261
  * Turn a failing verify run into `critical` Findings. A clean (exit 0) run yields
234
- * none. Located diagnostics (TypeScript first, then a generic file:line form) are
235
- * parsed into per-error findings; if none parse, a single capped finding carries
262
+ * none. Located diagnostics (TypeScript first, then a generic file:line form, then
263
+ * ESLint's stylish error rows under their file header) are parsed into per-error
264
+ * findings, at most `limit` of them; if none parse, a single capped finding carries
236
265
  * the tail of the output so the fix stage still gets actionable signal. Never
237
266
  * throws; always emits at least one finding on a non-zero exit.
238
267
  */
239
- export declare function parseVerifyFailures(output: string, exitCode: number, label: string): Finding[];
268
+ export declare function parseVerifyFailures(output: string, exitCode: number, label: string, limit?: number): Finding[];
240
269
  /**
241
270
  * One finding's file as the REPO ROOT sees it.
242
271
  *
@@ -253,6 +282,49 @@ export declare function parseVerifyFailures(output: string, exitCode: number, la
253
282
  * so a finding that passes through twice is not double-prefixed.
254
283
  */
255
284
  export declare function toRepoRelativePath(file: string, repoRoot: string, commandCwd: string): string;
285
+ /**
286
+ * What the gate's own checks already failed on before the build changed
287
+ * anything (YAG-1003): per command, how many times each failure key was seen
288
+ * on the clean tree. A command with no entry was not run there (or could not
289
+ * run), and its failures all count, as before.
290
+ */
291
+ export type VerifyBaseline = ReadonlyMap<string, ReadonlyMap<string, number>>;
292
+ /** One command's identity across the baseline run and the build's runs: where it runs and what it runs. */
293
+ export declare function verifyCommandKey(command: Pick<VerifyCommand, "cwd" | "argv">): string;
294
+ /**
295
+ * One failure's key, the shape #2601's `failureKeyOf` gives a CI failure: the
296
+ * repo-relative file and the message, never the line, since a change above a
297
+ * failure moves it. A failure that is only the output's tail names nothing
298
+ * stable, so it has no key and is never excused. Pure.
299
+ */
300
+ export declare function verifyFailureKey(finding: Finding): string | null;
301
+ /** How many times each failure key occurs. Pure. */
302
+ export declare function failureKeyCounts(findings: readonly Finding[]): Map<string, number>;
303
+ /**
304
+ * The failures this change caused: each failure key is excused at most as many
305
+ * times as the clean tree had it, so a second copy of an old error is new. A
306
+ * failure in a file the build did not touch still counts when the baseline did
307
+ * not have it, since a change can break another file's types. No baseline for
308
+ * the command leaves every failure in place. Pure.
309
+ */
310
+ export declare function subtractBaseline(findings: readonly Finding[], baseline: ReadonlyMap<string, number> | undefined): {
311
+ findings: Finding[];
312
+ excused: number;
313
+ };
314
+ /** The note for failures the clean tree already had, by command label. Pure. */
315
+ export declare function preexistingNote(byLabel: ReadonlyMap<string, number>): string | null;
316
+ /**
317
+ * The repo-relative paths an approved plan names (`src/flows/a.tsx`,
318
+ * `packages/web/`), which say which packages the build will change before it
319
+ * has changed anything. URLs and paths that leave the tree are dropped. Pure.
320
+ */
321
+ export declare function planPaths(plan: string): string[];
322
+ /**
323
+ * The package dirs the baseline runs in: those the plan's paths fall in. The
324
+ * repo root drops out when a package below it was named, since its check is
325
+ * not one the build's gate would run then. Pure (the `readFile` seam).
326
+ */
327
+ export declare function baselineDirs(repoRoot: string, paths: string[], readFile: (path: string) => string): string[];
256
328
  /** Result of actually executing the resolved command. */
257
329
  export interface VerifyExecResult {
258
330
  code: number;
@@ -352,6 +424,19 @@ export interface MakeRunVerifyOpts {
352
424
  treeStatus?: (cwd: string, signal?: AbortSignal) => Promise<string>;
353
425
  /** Undo what the half wrote into the tree (default: `git clean` / `git checkout` of exactly those paths). */
354
426
  undoTreeWrites?: (cwd: string, entries: TreeEntry[]) => Promise<void>;
427
+ /**
428
+ * What the typecheck and test halves already failed on before the build
429
+ * (YAG-1003, {@link makeTakeVerifyBaseline}). Those failures are a note, not
430
+ * findings. Absent: every failure is a finding, as before.
431
+ */
432
+ baseline?: VerifyBaseline | null;
433
+ /**
434
+ * The host's secret and binary scans over what this run added
435
+ * (changeScan.ts, YAG-1000), given the tree's pre-run dirt to leave out;
436
+ * null when git could not say what changed. A hit is a finding the fix turn
437
+ * removes. Absent: no scan half, as before (the cloud session sets it).
438
+ */
439
+ scanChange?: (cwd: string, signal?: AbortSignal, baselinePaths?: string[]) => Promise<Finding[] | null>;
355
440
  }
356
441
  /**
357
442
  * One workstream as the scoped checker sees it: the name its findings are
@@ -391,6 +476,8 @@ export interface MakeWorkstreamCheckOpts {
391
476
  detect?: (cwd: string, claimDirs: string[]) => VerifyCommand[];
392
477
  exec?: VerifyExec;
393
478
  timeoutMs?: number;
479
+ /** What the clean tree already failed on (YAG-1003): those failures are not a workstream's. */
480
+ baseline?: VerifyBaseline | null;
394
481
  }
395
482
  /**
396
483
  * The per-workstream scoped check the implement diamond runs right after the fan
@@ -428,5 +515,42 @@ export declare function makeWorkstreamCheck(opts?: MakeWorkstreamCheckOpts): (cw
428
515
  * blocks a real change on its own failure.
429
516
  */
430
517
  export declare function makeRunVerify(opts?: MakeRunVerifyOpts): (cwd: string, signal?: AbortSignal, baselinePaths?: string[]) => Promise<VerifyOutcome>;
518
+ /** The whole baseline run's cap, before the build starts: it costs minutes at most. */
519
+ export declare const VERIFY_BASELINE_BUDGET_MS: number;
520
+ export interface MakeTakeVerifyBaselineOpts {
521
+ detect?: (cwd: string, dirs: string[]) => VerifyCommand[];
522
+ detectTests?: (cwd: string, dirs: string[]) => VerifyCommand[];
523
+ exec?: VerifyExec;
524
+ timeoutMs?: number;
525
+ testTimeoutMs?: number;
526
+ testEnv?: NodeJS.ProcessEnv;
527
+ budgetMs?: number;
528
+ now?: () => number;
529
+ treeStatus?: (cwd: string, signal?: AbortSignal) => Promise<string>;
530
+ undoTreeWrites?: (cwd: string, entries: TreeEntry[]) => Promise<void>;
531
+ }
532
+ /** What the baseline run found, for the gate and for the run's log. */
533
+ export interface VerifyBaselineResult {
534
+ baseline: VerifyBaseline;
535
+ /** Commands that gave a verdict on the clean tree, by label. */
536
+ ran: string[];
537
+ /** Keyed failures the clean tree already had, across those commands. */
538
+ failures: number;
539
+ /** Commands that gave no verdict, and why: their failures all count later. */
540
+ notes: string[];
541
+ }
542
+ /**
543
+ * Run the gate's own typecheck and test commands ONCE on the clean tree,
544
+ * before the build changes anything (YAG-1003), in the package dirs the
545
+ * approved plan names, and keep each command's failure keys. The build's gate
546
+ * then counts only the failures this change added ({@link subtractBaseline}).
547
+ *
548
+ * The same detection, exec seam and environments as {@link makeRunVerify}, so
549
+ * a command's key and its failures' keys match the build's runs. Fail-open per
550
+ * command: one that cannot run, times out, or is not reached in the budget
551
+ * has no baseline, and its failures all count, as before. What the commands
552
+ * write into the tree is undone, so none of it reaches the candidate.
553
+ */
554
+ export declare function makeTakeVerifyBaseline(opts?: MakeTakeVerifyBaselineOpts): (cwd: string, dirs: string[], signal?: AbortSignal, budgetOverrideMs?: number) => Promise<VerifyBaselineResult>;
431
555
  export {};
432
556
  //# sourceMappingURL=verify.d.ts.map