@telora/daemon 0.22.91 → 0.22.97
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/build-info.json +6 -3
- package/dist/completion/event-phases.js +5 -5
- package/dist/completion/event-phases.js.map +1 -1
- package/dist/completion/event.d.ts +7 -0
- package/dist/completion/event.d.ts.map +1 -1
- package/dist/completion/event.js.map +1 -1
- package/dist/completion/review-exit-phase.d.ts.map +1 -1
- package/dist/completion/review-exit-phase.js +2 -1
- package/dist/completion/review-exit-phase.js.map +1 -1
- package/dist/delivery/external-hold.js +1 -1
- package/dist/delivery/external-hold.js.map +1 -1
- package/dist/delivery/operator-hold.d.ts +14 -0
- package/dist/delivery/operator-hold.d.ts.map +1 -1
- package/dist/delivery/operator-hold.js +31 -1
- package/dist/delivery/operator-hold.js.map +1 -1
- package/dist/directive/directive-dispatch.js +2 -2
- package/dist/directive/directive-dispatch.js.map +1 -1
- package/dist/directive/directive-executor.d.ts.map +1 -1
- package/dist/directive/directive-executor.js +2 -1
- package/dist/directive/directive-executor.js.map +1 -1
- package/dist/directive/directive-verify-hold-gate.d.ts +32 -8
- package/dist/directive/directive-verify-hold-gate.d.ts.map +1 -1
- package/dist/directive/directive-verify-hold-gate.js +20 -21
- package/dist/directive/directive-verify-hold-gate.js.map +1 -1
- package/dist/focus/focus-engine.d.ts.map +1 -1
- package/dist/focus/focus-engine.js +6 -9
- package/dist/focus/focus-engine.js.map +1 -1
- package/dist/focus/listener-spawn.d.ts +31 -0
- package/dist/focus/listener-spawn.d.ts.map +1 -1
- package/dist/focus/listener-spawn.js +44 -22
- package/dist/focus/listener-spawn.js.map +1 -1
- package/dist/focus/listener.d.ts.map +1 -1
- package/dist/focus/listener.js +4 -0
- package/dist/focus/listener.js.map +1 -1
- package/dist/focus/team-actionable-work.d.ts +76 -20
- package/dist/focus/team-actionable-work.d.ts.map +1 -1
- package/dist/focus/team-actionable-work.js +85 -20
- package/dist/focus/team-actionable-work.js.map +1 -1
- package/dist/nexus/incoming.js +1 -1
- package/dist/nexus/incoming.js.map +1 -1
- package/dist/nexus/pending-returns.d.ts +124 -0
- package/dist/nexus/pending-returns.d.ts.map +1 -0
- package/dist/nexus/pending-returns.js +194 -0
- package/dist/nexus/pending-returns.js.map +1 -0
- package/dist/nexus/return-routing.d.ts +89 -0
- package/dist/nexus/return-routing.d.ts.map +1 -0
- package/dist/nexus/return-routing.js +148 -0
- package/dist/nexus/return-routing.js.map +1 -0
- package/dist/nexus/return.d.ts +66 -89
- package/dist/nexus/return.d.ts.map +1 -1
- package/dist/nexus/return.js +116 -279
- package/dist/nexus/return.js.map +1 -1
- package/dist/prompt/focus-prompt-builder.d.ts.map +1 -1
- package/dist/prompt/focus-prompt-builder.js +1 -0
- package/dist/prompt/focus-prompt-builder.js.map +1 -1
- package/dist/queries/delivery-gate-state.d.ts +23 -0
- package/dist/queries/delivery-gate-state.d.ts.map +1 -1
- package/dist/queries/delivery-gate-state.js +31 -4
- package/dist/queries/delivery-gate-state.js.map +1 -1
- package/dist/queries/focus-discovery.d.ts +7 -1
- package/dist/queries/focus-discovery.d.ts.map +1 -1
- package/dist/queries/focus-discovery.js +9 -3
- package/dist/queries/focus-discovery.js.map +1 -1
- package/dist/queries/requests.d.ts +51 -3
- package/dist/queries/requests.d.ts.map +1 -1
- package/dist/queries/requests.js +63 -10
- package/dist/queries/requests.js.map +1 -1
- package/dist/queries/shared.js +1 -1
- package/dist/queries/verification.d.ts.map +1 -1
- package/dist/queries/verification.js +1 -0
- package/dist/queries/verification.js.map +1 -1
- package/dist/spawn/prompt-assembly.js +1 -1
- package/dist/spawn/prompt-assembly.js.map +1 -1
- package/dist/spawn/respawn-cycle-escalation.d.ts.map +1 -1
- package/dist/spawn/respawn-cycle-escalation.js +11 -3
- package/dist/spawn/respawn-cycle-escalation.js.map +1 -1
- package/dist/spawn/review-hold-park.d.ts +31 -0
- package/dist/spawn/review-hold-park.d.ts.map +1 -0
- package/dist/spawn/review-hold-park.js +120 -0
- package/dist/spawn/review-hold-park.js.map +1 -0
- package/dist/spawn/spawn-cooldown.d.ts +27 -4
- package/dist/spawn/spawn-cooldown.d.ts.map +1 -1
- package/dist/spawn/spawn-cooldown.js +88 -3
- package/dist/spawn/spawn-cooldown.js.map +1 -1
- package/dist/spawn/spawn-decision.d.ts.map +1 -1
- package/dist/spawn/spawn-decision.js +6 -0
- package/dist/spawn/spawn-decision.js.map +1 -1
- package/dist/types/index.js +1 -1
- package/dist/update/auto-update-idle.d.ts.map +1 -1
- package/dist/update/auto-update-idle.js +2 -1
- package/dist/update/auto-update-idle.js.map +1 -1
- package/dist/verify/failure-signature.d.ts.map +1 -1
- package/dist/verify/failure-signature.js +1 -0
- package/dist/verify/failure-signature.js.map +1 -1
- package/dist/verify/verification-checkout.d.ts +58 -0
- package/dist/verify/verification-checkout.d.ts.map +1 -0
- package/dist/verify/verification-checkout.js +266 -0
- package/dist/verify/verification-checkout.js.map +1 -0
- package/dist/verify/verification-default-on.d.ts +27 -3
- package/dist/verify/verification-default-on.d.ts.map +1 -1
- package/dist/verify/verification-default-on.js +98 -5
- package/dist/verify/verification-default-on.js.map +1 -1
- package/dist/verify/verification-deps.d.ts +11 -0
- package/dist/verify/verification-deps.d.ts.map +1 -1
- package/dist/verify/verification-deterministic.d.ts +22 -1
- package/dist/verify/verification-deterministic.d.ts.map +1 -1
- package/dist/verify/verification-deterministic.js +6 -7
- package/dist/verify/verification-deterministic.js.map +1 -1
- package/dist/verify/verification-engine.d.ts.map +1 -1
- package/dist/verify/verification-engine.js +10 -8
- package/dist/verify/verification-engine.js.map +1 -1
- package/dist/verify/verification-feedback.d.ts +3 -0
- package/dist/verify/verification-feedback.d.ts.map +1 -1
- package/dist/verify/verification-feedback.js +5 -2
- package/dist/verify/verification-feedback.js.map +1 -1
- package/dist/worktree/verify-interlock.d.ts +9 -1
- package/dist/worktree/verify-interlock.d.ts.map +1 -1
- package/dist/worktree/verify-interlock.js +40 -3
- package/dist/worktree/verify-interlock.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { PendingVerification } from '../queries/verification.js';
|
|
2
|
+
import type { StrategyResult } from './verification-deterministic.js';
|
|
3
|
+
import type { VerificationDeps } from './verification-deps.js';
|
|
4
|
+
/** A detached checkout of one commit, owned by the verify that made it. */
|
|
5
|
+
export interface VerifyCheckout {
|
|
6
|
+
/** Absolute checkout path the verify command runs in. */
|
|
7
|
+
path: string;
|
|
8
|
+
/** The commit the checkout holds -- the sha the verdict is about. */
|
|
9
|
+
sha: string;
|
|
10
|
+
/** True when an install moved the linked dependency trees since the checkout was made. */
|
|
11
|
+
dependenciesMoved: () => boolean;
|
|
12
|
+
/** Remove the checkout (links unlinked, never followed) and its git registration. Idempotent. */
|
|
13
|
+
dispose: () => void;
|
|
14
|
+
}
|
|
15
|
+
/** Git result slice the checkout reads (structural over runGitSync). */
|
|
16
|
+
type GitRun = (args: string[], cwd: string) => {
|
|
17
|
+
success: boolean;
|
|
18
|
+
output: string;
|
|
19
|
+
error?: string;
|
|
20
|
+
};
|
|
21
|
+
/** Injectable seams (tests point the root at a temp dir). */
|
|
22
|
+
export interface VerifyCheckoutDeps {
|
|
23
|
+
runGit?: GitRun;
|
|
24
|
+
/** Parent directory checkouts are created under. */
|
|
25
|
+
checkoutRoot?: () => string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Repo-relative ignored node_modules dirs of the focus worktree (never one nested
|
|
29
|
+
* inside another node_modules). `--directory` keeps git from walking into a
|
|
30
|
+
* wholly-ignored tree. Build output is deliberately not listed (module doc).
|
|
31
|
+
*/
|
|
32
|
+
export declare function listMirroredDirs(focusWorktreePath: string, runGit?: GitRun): string[];
|
|
33
|
+
/**
|
|
34
|
+
* Create a detached checkout of the focus worktree's HEAD for one verify run.
|
|
35
|
+
* `checkoutKey` names the checkout directory (the delivery id -- a delivery
|
|
36
|
+
* never verifies twice at once, so concurrent verifies never share a path). A
|
|
37
|
+
* leftover from a crashed run at the same path is removed first. Returns null
|
|
38
|
+
* when HEAD cannot be read or the checkout cannot be created.
|
|
39
|
+
*/
|
|
40
|
+
export declare function createVerifyCheckout(focusWorktreePath: string, checkoutKey: string, deps?: VerifyCheckoutDeps): VerifyCheckout | null;
|
|
41
|
+
/** The deps slice {@link runDeterministicAtFixedCommit} reads. */
|
|
42
|
+
export type FixedCommitVerifyDeps = Pick<VerificationDeps, 'runDeterministic' | 'resolveCwd' | 'resolveVerificationCwd' | 'resolveRecordedPreMergeRef' | 'resolveRecordedCommitShas'> & {
|
|
43
|
+
/** The focus worktree a delivery's verify judges; null when the focus has none. */
|
|
44
|
+
resolveFocusWorktreePath?: (v: PendingVerification) => string | null;
|
|
45
|
+
createVerifyCheckout?: (focusWorktreePath: string, checkoutKey: string) => VerifyCheckout | null;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* The deterministic strategy: resolve the verify boundary env, then run the
|
|
49
|
+
* configured command against a detached checkout of the focus HEAD (holding the
|
|
50
|
+
* FOCUS worktree's interlock for the judged delivery), stamping the verdict with
|
|
51
|
+
* the sha it judged. A verdict rendered while an install moved the linked
|
|
52
|
+
* dependencies is discarded (pending, retried). A delivery with no focus worktree
|
|
53
|
+
* runs in place, as before: no team works in the product repo path the fallback
|
|
54
|
+
* cwd names.
|
|
55
|
+
*/
|
|
56
|
+
export declare function runDeterministicAtFixedCommit(deps: FixedCommitVerifyDeps, v: PendingVerification): Promise<StrategyResult>;
|
|
57
|
+
export {};
|
|
58
|
+
//# sourceMappingURL=verification-checkout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verification-checkout.d.ts","sourceRoot":"","sources":["../../src/verify/verification-checkout.ts"],"names":[],"mappings":"AAoDA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAM/D,2EAA2E;AAC3E,MAAM,WAAW,cAAc;IAC7B,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,GAAG,EAAE,MAAM,CAAC;IACZ,0FAA0F;IAC1F,iBAAiB,EAAE,MAAM,OAAO,CAAC;IACjC,iGAAiG;IACjG,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wEAAwE;AACxE,KAAK,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,KAAK;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpG,6DAA6D;AAC7D,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,MAAM,CAAC;CAC7B;AAOD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,iBAAiB,EAAE,MAAM,EAAE,MAAM,GAAE,MAAmB,GAAG,MAAM,EAAE,CASjG;AAgGD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,iBAAiB,EAAE,MAAM,EACzB,WAAW,EAAE,MAAM,EACnB,IAAI,GAAE,kBAAuB,GAC5B,cAAc,GAAG,IAAI,CAsCvB;AAED,kEAAkE;AAClE,MAAM,MAAM,qBAAqB,GAAG,IAAI,CACtC,gBAAgB,EAChB,kBAAkB,GAAG,YAAY,GAAG,wBAAwB,GAAG,4BAA4B,GAAG,2BAA2B,CAC1H,GAAG;IACF,mFAAmF;IACnF,wBAAwB,CAAC,EAAE,CAAC,CAAC,EAAE,mBAAmB,KAAK,MAAM,GAAG,IAAI,CAAC;IACrE,oBAAoB,CAAC,EAAE,CAAC,iBAAiB,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,cAAc,GAAG,IAAI,CAAC;CAClG,CAAC;AAKF;;;;;;;;GAQG;AACH,wBAAsB,6BAA6B,CACjD,IAAI,EAAE,qBAAqB,EAC3B,CAAC,EAAE,mBAAmB,GACrB,OAAO,CAAC,cAAc,CAAC,CAwCzB"}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
// PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
|
|
2
|
+
// Pinned by: packages/daemon/src/verify/verification-checkout.test.ts
|
|
3
|
+
// PINNED-BY-END
|
|
4
|
+
/**
|
|
5
|
+
* A deterministic verify judges a FIXED commit, never the live focus worktree.
|
|
6
|
+
*
|
|
7
|
+
* Every delivery of a focus shares one worktree, and the verify hold now
|
|
8
|
+
* withholds only the delivery under verify (focus/team-actionable-work.ts) -- so
|
|
9
|
+
* a coding team can be alive in that worktree, editing and committing a sibling
|
|
10
|
+
* delivery's fix, while a verify runs (f1, 2026-09-13). A verify run IN that
|
|
11
|
+
* worktree would judge a tree the team moved mid-run: a verdict about no commit
|
|
12
|
+
* at all. So the run happens in a detached checkout of the focus HEAD sha taken
|
|
13
|
+
* at dispatch, under the daemon state dir (the same shape as the baseline runner
|
|
14
|
+
* in verification-baseline.ts), and the verdict carries that sha.
|
|
15
|
+
*
|
|
16
|
+
* The verify interlock hold is still acquired on the FOCUS worktree (with the
|
|
17
|
+
* judged delivery id): daemon-authored commits and the coding->verify advance keep
|
|
18
|
+
* deferring exactly as before, so a team alive during a verify tears neither.
|
|
19
|
+
*
|
|
20
|
+
* Environment parity WITHOUT shared mutable state. A fresh checkout has no
|
|
21
|
+
* installed dependencies; the focus worktree resolves them from its own ignored
|
|
22
|
+
* node_modules dirs and by Node's walk-up to ancestor node_modules (the main
|
|
23
|
+
* checkout's, for a worktree nested under it -- often its ONLY real package tree).
|
|
24
|
+
* The checkout rebuilds that resolution as REAL node_modules directories whose
|
|
25
|
+
* package entries are symlinks: the root one merges the worktree's root
|
|
26
|
+
* node_modules with every ancestor node_modules in walk-up order (the first
|
|
27
|
+
* source naming a package wins, as resolution does), and `.bin` / `@scope` dirs
|
|
28
|
+
* merge one level down. Two things are deliberately NOT carried:
|
|
29
|
+
* - dot-entries other than `.bin` (`.vite`, `.cache`, ...): tool caches both
|
|
30
|
+
* sides write, which the verify recreates inside its own directories;
|
|
31
|
+
* - build output (`dist`): it is whatever tree the team last built, not the
|
|
32
|
+
* judged commit, so the gate builds what it needs inside the checkout.
|
|
33
|
+
* So no team write to caches or build output reaches the verify, and no verify
|
|
34
|
+
* write reaches the team. The linked package trees are read, never written; the
|
|
35
|
+
* one way they move is a dependency install, which the checkout DETECTS: a
|
|
36
|
+
* fingerprint of each source's package set and npm's hidden lockfile is taken at
|
|
37
|
+
* setup and re-read after the run, and a verdict rendered while the dependencies
|
|
38
|
+
* moved is discarded as `pending` (re-run next tick). The checkout is removed by
|
|
39
|
+
* lstat-based removal, which unlinks a link and never follows it into its target.
|
|
40
|
+
*
|
|
41
|
+
* Fail-closed: when no checkout can be made the run is NOT performed in the live
|
|
42
|
+
* worktree; it reports `pending` with checkoutUnavailable so the tick retries.
|
|
43
|
+
*
|
|
44
|
+
* @module verify/verification-checkout
|
|
45
|
+
*/
|
|
46
|
+
import { existsSync, mkdirSync, readdirSync, rmSync, statSync, symlinkSync } from 'node:fs';
|
|
47
|
+
import { basename, dirname, join, resolve } from 'node:path';
|
|
48
|
+
import { resolveGlobalStateDir } from '../shell/daemon-process.js';
|
|
49
|
+
import { runGitSync } from '../git/exec.js';
|
|
50
|
+
import { getFocusWorktree } from '../focus/focus-worktree-state.js';
|
|
51
|
+
import { resolveVerifyBoundaryEnv } from './verification-boundary-env.js';
|
|
52
|
+
import { createLogger } from '../shell/log.js';
|
|
53
|
+
const log = createLogger({ module: 'verification' });
|
|
54
|
+
/** The ignored directory name a checkout rebuilds from the focus worktree. */
|
|
55
|
+
const DEPENDENCY_DIR = 'node_modules';
|
|
56
|
+
const defaultCheckoutRoot = () => resolve(resolveGlobalStateDir(), 'verification-checkout');
|
|
57
|
+
/**
|
|
58
|
+
* Repo-relative ignored node_modules dirs of the focus worktree (never one nested
|
|
59
|
+
* inside another node_modules). `--directory` keeps git from walking into a
|
|
60
|
+
* wholly-ignored tree. Build output is deliberately not listed (module doc).
|
|
61
|
+
*/
|
|
62
|
+
export function listMirroredDirs(focusWorktreePath, runGit = runGitSync) {
|
|
63
|
+
const listed = runGit(['ls-files', '--others', '--ignored', '--exclude-standard', '--directory'], focusWorktreePath);
|
|
64
|
+
if (!listed.success)
|
|
65
|
+
return [];
|
|
66
|
+
return listed.output
|
|
67
|
+
.split('\n')
|
|
68
|
+
.map((line) => line.trim().replace(/\/$/, ''))
|
|
69
|
+
.filter((rel) => rel.length > 0
|
|
70
|
+
&& basename(rel) === DEPENDENCY_DIR
|
|
71
|
+
&& !rel.split('/').slice(0, -1).includes(DEPENDENCY_DIR));
|
|
72
|
+
}
|
|
73
|
+
/** Every node_modules Node's walk-up reaches from `dir` upward, nearest first. */
|
|
74
|
+
function ancestorNodeModules(dir) {
|
|
75
|
+
const found = [];
|
|
76
|
+
let current = resolve(dir);
|
|
77
|
+
for (;;) {
|
|
78
|
+
const candidate = join(current, DEPENDENCY_DIR);
|
|
79
|
+
if (existsSync(candidate))
|
|
80
|
+
found.push(candidate);
|
|
81
|
+
const parent = dirname(current);
|
|
82
|
+
if (parent === current)
|
|
83
|
+
return found;
|
|
84
|
+
current = parent;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/** A directory's entry names, or [] when it cannot be read. */
|
|
88
|
+
function entriesOf(dir) {
|
|
89
|
+
try {
|
|
90
|
+
return readdirSync(dir);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Build `at` as a REAL directory whose entries link into `sources` (nearest
|
|
98
|
+
* first; the first source naming an entry wins). At the top level a `.bin` or
|
|
99
|
+
* `@scope` entry is merged one level down the same way, and every other
|
|
100
|
+
* dot-entry (a tool cache) is skipped.
|
|
101
|
+
*/
|
|
102
|
+
function buildMergedModulesDir(sources, at, depth = 0) {
|
|
103
|
+
mkdirSync(at, { recursive: true });
|
|
104
|
+
const seen = new Set();
|
|
105
|
+
for (const source of sources) {
|
|
106
|
+
for (const name of entriesOf(source)) {
|
|
107
|
+
if (seen.has(name))
|
|
108
|
+
continue;
|
|
109
|
+
const merged = depth === 0 && (name === '.bin' || name.startsWith('@'));
|
|
110
|
+
if (depth === 0 && name.startsWith('.') && !merged)
|
|
111
|
+
continue;
|
|
112
|
+
seen.add(name);
|
|
113
|
+
if (merged) {
|
|
114
|
+
buildMergedModulesDir(sources.map((s) => join(s, name)), join(at, name), depth + 1);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
symlinkSync(join(source, name), join(at, name));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* A fingerprint of the dependency trees a checkout links into: each source's
|
|
124
|
+
* package set (top-level and `@scope` entry names; tool caches excluded) and
|
|
125
|
+
* npm's hidden lockfile (`.package-lock.json`, rewritten by every install). Equal
|
|
126
|
+
* before and after a run => no install moved the linked packages mid-run.
|
|
127
|
+
*/
|
|
128
|
+
function dependencyFingerprint(sources) {
|
|
129
|
+
return JSON.stringify(sources.map((source) => {
|
|
130
|
+
const names = entriesOf(source).filter((name) => !name.startsWith('.')).sort();
|
|
131
|
+
const scoped = names.filter((name) => name.startsWith('@')).map((name) => [name, entriesOf(join(source, name)).sort()]);
|
|
132
|
+
let lockfile = 'none';
|
|
133
|
+
try {
|
|
134
|
+
const stat = statSync(join(source, '.package-lock.json'));
|
|
135
|
+
lockfile = `${stat.mtimeMs}:${stat.size}`;
|
|
136
|
+
}
|
|
137
|
+
catch { /* no hidden lockfile */ }
|
|
138
|
+
return [source, names, scoped, lockfile];
|
|
139
|
+
}));
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Rebuild the focus worktree's dependency resolution inside the checkout (module
|
|
143
|
+
* doc). Returns every source node_modules the checkout links into.
|
|
144
|
+
*/
|
|
145
|
+
function mirrorDependencyDirs(focusWorktreePath, checkoutPath, runGit) {
|
|
146
|
+
const plans = listMirroredDirs(focusWorktreePath, runGit)
|
|
147
|
+
.filter((rel) => rel !== DEPENDENCY_DIR)
|
|
148
|
+
.map((rel) => ({ rel, sources: [join(focusWorktreePath, rel)] }));
|
|
149
|
+
const ownRoot = join(focusWorktreePath, DEPENDENCY_DIR);
|
|
150
|
+
const rootSources = [...(existsSync(ownRoot) ? [ownRoot] : []), ...ancestorNodeModules(dirname(focusWorktreePath))];
|
|
151
|
+
if (rootSources.length > 0)
|
|
152
|
+
plans.push({ rel: DEPENDENCY_DIR, sources: rootSources });
|
|
153
|
+
for (const plan of plans)
|
|
154
|
+
buildMergedModulesDir(plan.sources, join(checkoutPath, plan.rel));
|
|
155
|
+
return plans.flatMap((plan) => plan.sources);
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Remove a checkout directory and its registration. rmSync removes by lstat, so
|
|
159
|
+
* a linked package entry is unlinked, never followed into its target; `git
|
|
160
|
+
* worktree prune` then drops the registration of the now-missing directory.
|
|
161
|
+
*/
|
|
162
|
+
function removeCheckout(checkoutPath, focusWorktreePath, runGit) {
|
|
163
|
+
try {
|
|
164
|
+
rmSync(checkoutPath, { recursive: true, force: true });
|
|
165
|
+
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
log.warn(`verify checkout removal failed at ${checkoutPath}: ${err.message}`);
|
|
168
|
+
}
|
|
169
|
+
runGit(['worktree', 'prune'], focusWorktreePath);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Create a detached checkout of the focus worktree's HEAD for one verify run.
|
|
173
|
+
* `checkoutKey` names the checkout directory (the delivery id -- a delivery
|
|
174
|
+
* never verifies twice at once, so concurrent verifies never share a path). A
|
|
175
|
+
* leftover from a crashed run at the same path is removed first. Returns null
|
|
176
|
+
* when HEAD cannot be read or the checkout cannot be created.
|
|
177
|
+
*/
|
|
178
|
+
export function createVerifyCheckout(focusWorktreePath, checkoutKey, deps = {}) {
|
|
179
|
+
const runGit = deps.runGit ?? runGitSync;
|
|
180
|
+
const head = runGit(['rev-parse', 'HEAD'], focusWorktreePath);
|
|
181
|
+
const sha = head.success ? head.output.trim() : '';
|
|
182
|
+
if (sha.length === 0) {
|
|
183
|
+
log.warn(`verify checkout: cannot read HEAD of ${focusWorktreePath}: ${head.error ?? 'empty output'}`);
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
const root = (deps.checkoutRoot ?? defaultCheckoutRoot)();
|
|
187
|
+
const checkoutPath = resolve(root, checkoutKey.replace(/[^a-zA-Z0-9._-]/g, '_'));
|
|
188
|
+
let sources;
|
|
189
|
+
try {
|
|
190
|
+
mkdirSync(root, { recursive: true });
|
|
191
|
+
if (existsSync(checkoutPath))
|
|
192
|
+
removeCheckout(checkoutPath, focusWorktreePath, runGit);
|
|
193
|
+
const added = runGit(['worktree', 'add', '--detach', checkoutPath, sha], focusWorktreePath);
|
|
194
|
+
if (!added.success) {
|
|
195
|
+
log.warn(`verify checkout: worktree add at ${sha.slice(0, 8)} failed: ${added.error ?? added.output}`);
|
|
196
|
+
removeCheckout(checkoutPath, focusWorktreePath, runGit);
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
sources = mirrorDependencyDirs(focusWorktreePath, checkoutPath, runGit);
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
log.warn(`verify checkout: setup failed at ${checkoutPath}: ${err.message}`);
|
|
203
|
+
removeCheckout(checkoutPath, focusWorktreePath, runGit);
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
const fingerprint = dependencyFingerprint(sources);
|
|
207
|
+
let disposed = false;
|
|
208
|
+
return {
|
|
209
|
+
path: checkoutPath,
|
|
210
|
+
sha,
|
|
211
|
+
dependenciesMoved: () => dependencyFingerprint(sources) !== fingerprint,
|
|
212
|
+
dispose: () => {
|
|
213
|
+
if (disposed)
|
|
214
|
+
return;
|
|
215
|
+
disposed = true;
|
|
216
|
+
removeCheckout(checkoutPath, focusWorktreePath, runGit);
|
|
217
|
+
},
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
const defaultResolveFocusWorktreePath = (v) => (v.focusId ? getFocusWorktree(v.focusId)?.worktreePath ?? null : null);
|
|
221
|
+
/**
|
|
222
|
+
* The deterministic strategy: resolve the verify boundary env, then run the
|
|
223
|
+
* configured command against a detached checkout of the focus HEAD (holding the
|
|
224
|
+
* FOCUS worktree's interlock for the judged delivery), stamping the verdict with
|
|
225
|
+
* the sha it judged. A verdict rendered while an install moved the linked
|
|
226
|
+
* dependencies is discarded (pending, retried). A delivery with no focus worktree
|
|
227
|
+
* runs in place, as before: no team works in the product repo path the fallback
|
|
228
|
+
* cwd names.
|
|
229
|
+
*/
|
|
230
|
+
export async function runDeterministicAtFixedCommit(deps, v) {
|
|
231
|
+
// Hoist the boundary resolution BEFORE the run so the command's targeted-test
|
|
232
|
+
// selector diffs against the delivery's recorded pre-merge boundary.
|
|
233
|
+
const extraEnv = await resolveVerifyBoundaryEnv(deps, v);
|
|
234
|
+
const logContext = { deliveryId: v.deliveryId, startedAtMs: Date.now() };
|
|
235
|
+
const focusWorktreePath = (deps.resolveFocusWorktreePath ?? defaultResolveFocusWorktreePath)(v);
|
|
236
|
+
if (focusWorktreePath === null) {
|
|
237
|
+
const cwd = (deps.resolveVerificationCwd ?? ((pv) => deps.resolveCwd(pv.productId)))(v);
|
|
238
|
+
return deps.runDeterministic(v.verificationConfig, cwd, logContext, extraEnv);
|
|
239
|
+
}
|
|
240
|
+
const checkout = (deps.createVerifyCheckout ?? createVerifyCheckout)(focusWorktreePath, v.deliveryId);
|
|
241
|
+
if (!checkout) {
|
|
242
|
+
return {
|
|
243
|
+
outcome: 'pending',
|
|
244
|
+
rationale: 'verify checkout unavailable: no detached checkout of the focus HEAD could be made; '
|
|
245
|
+
+ 'the verify is not run in the live focus worktree (a team may be moving it) -- retried next tick',
|
|
246
|
+
checkoutUnavailable: true,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
try {
|
|
250
|
+
const result = await deps.runDeterministic(v.verificationConfig, checkout.path, logContext, extraEnv, { worktreePath: focusWorktreePath, deliveryId: v.deliveryId });
|
|
251
|
+
if (checkout.dependenciesMoved()) {
|
|
252
|
+
log.warn(`verify checkout: dependencies moved during the run for delivery ${v.deliveryId}; verdict discarded`);
|
|
253
|
+
return {
|
|
254
|
+
outcome: 'pending',
|
|
255
|
+
rationale: 'verify discarded: a dependency install moved the node_modules trees the checkout links into '
|
|
256
|
+
+ 'while the run was in flight, so the verdict judged no fixed environment -- retried next tick',
|
|
257
|
+
checkoutUnavailable: true,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
return { ...result, verifiedSha: checkout.sha };
|
|
261
|
+
}
|
|
262
|
+
finally {
|
|
263
|
+
checkout.dispose();
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=verification-checkout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verification-checkout.js","sourceRoot":"","sources":["../../src/verify/verification-checkout.ts"],"names":[],"mappings":"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"}
|
|
@@ -28,6 +28,12 @@ import type { getFocusDeliveries } from '../queries/focuses.js';
|
|
|
28
28
|
export interface DefaultOnScanDeps {
|
|
29
29
|
getActiveFocuses: typeof getActiveFocuses;
|
|
30
30
|
getFocusDeliveries: typeof getFocusDeliveries;
|
|
31
|
+
/**
|
|
32
|
+
* The focus worktree's current HEAD sha, read to keep a delivery whose verify
|
|
33
|
+
* FAILED from re-running on the same unchanged commit. A null read keeps a
|
|
34
|
+
* recorded failure suppressed: only a KNOWN different commit re-arms it.
|
|
35
|
+
*/
|
|
36
|
+
resolveFocusHeadSha?: (focusId: string) => string | null;
|
|
31
37
|
}
|
|
32
38
|
/**
|
|
33
39
|
* Counting semaphore capping concurrent daemon-side verification runs.
|
|
@@ -135,7 +141,7 @@ export declare function resolveProductVerificationScopes(config: DaemonConfig, r
|
|
|
135
141
|
* conservative floor, not a stale limit from a previous tick.
|
|
136
142
|
*/
|
|
137
143
|
export declare function resolveDaemonWideVerifyCap(scopes: readonly ProductVerificationScope[]): number;
|
|
138
|
-
/** Test-only: reset the default-on re-run
|
|
144
|
+
/** Test-only: reset the default-on re-run guards (status- and HEAD-keyed). */
|
|
139
145
|
export declare function __resetDefaultOnGuardForTests(): void;
|
|
140
146
|
/** Test-only: snapshot of the default-on re-run guard. */
|
|
141
147
|
export declare function __getDefaultOnGuardForTests(): ReadonlySet<string>;
|
|
@@ -143,12 +149,30 @@ export declare function __getDefaultOnGuardForTests(): ReadonlySet<string>;
|
|
|
143
149
|
export declare function markDefaultOnRan(deliveryId: string): void;
|
|
144
150
|
/** Test-only alias for markDefaultOnRan. */
|
|
145
151
|
export declare function __markDefaultOnRanForTests(deliveryId: string): void;
|
|
152
|
+
/** The slice of a verification result {@link noteDefaultOnResult} reads. */
|
|
153
|
+
export interface DefaultOnResultFacts {
|
|
154
|
+
outcome: string;
|
|
155
|
+
exitCode?: number | null;
|
|
156
|
+
timedOut?: boolean;
|
|
157
|
+
verifiedSha?: string;
|
|
158
|
+
checkoutUnavailable?: boolean;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Dispatch-result bookkeeping for a default-on run:
|
|
162
|
+
* - no checkout could be made -> un-mark, so the next tick retries (the run
|
|
163
|
+
* never happened; no verdict exists to guard);
|
|
164
|
+
* - the gate command FAILED at a known sha (non-zero exit, not a timeout, final
|
|
165
|
+
* outcome failed) -> record the sha so that commit is not re-verified;
|
|
166
|
+
* - a pass -> forget any recorded failure.
|
|
167
|
+
*/
|
|
168
|
+
export declare function noteDefaultOnResult(deliveryId: string, result: DefaultOnResultFacts): void;
|
|
146
169
|
/**
|
|
147
170
|
* Discover deliveries that should receive a DEFAULT-ON deterministic run: in
|
|
148
171
|
* `verify` status, anchored to an injection, with no explicit verification
|
|
149
172
|
* method (so not already returned by getPendingVerifications), not in a
|
|
150
|
-
* read-only audit focus (those are discovery-only and never run a suite),
|
|
151
|
-
*
|
|
173
|
+
* read-only audit focus (those are discovery-only and never run a suite), not
|
|
174
|
+
* already run this verify-entry (steady-state guard), and not failed on the
|
|
175
|
+
* focus's unchanged HEAD (HEAD-keyed guard).
|
|
152
176
|
*
|
|
153
177
|
* Synthesizes a `deterministic` PendingVerification carrying the resolved
|
|
154
178
|
* config-default command + timeout. Returns [] when the default-on path is
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verification-default-on.d.ts","sourceRoot":"","sources":["../../src/verify/verification-default-on.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAiC,KAAK,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAG3G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"verification-default-on.d.ts","sourceRoot":"","sources":["../../src/verify/verification-default-on.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
|
|
2
|
-
// Pinned by:
|
|
2
|
+
// Pinned by: packages/daemon/src/verify/verification-default-on.test.ts
|
|
3
3
|
// PINNED-BY-END
|
|
4
4
|
/**
|
|
5
5
|
* Default-on deterministic verification: selection + concurrency cap.
|
|
@@ -21,8 +21,16 @@ import { DELIVERY_STATUS } from '@telora/daemon-core';
|
|
|
21
21
|
import { DEFAULT_VERIFY_MAX_CONCURRENT } from './verification-config.js';
|
|
22
22
|
import { resolveVerifyManifestPath } from './verification-manifest.js';
|
|
23
23
|
import { configForProduct } from '../shell/config.js';
|
|
24
|
+
import { getFocusWorktree } from '../focus/focus-worktree-state.js';
|
|
25
|
+
import { resolveHeadSha } from './verification-baseline.js';
|
|
26
|
+
import { judgedFailedSha, readVerificationHistory } from '../queries/delivery-gate-state.js';
|
|
24
27
|
import { createLogger } from '../shell/log.js';
|
|
25
28
|
const log = createLogger({ module: 'verification' });
|
|
29
|
+
/** Default HEAD reader: the registered focus worktree's HEAD, or null when unreadable. */
|
|
30
|
+
function defaultResolveFocusHeadSha(focusId) {
|
|
31
|
+
const worktree = getFocusWorktree(focusId);
|
|
32
|
+
return worktree ? resolveHeadSha(worktree.worktreePath) : null;
|
|
33
|
+
}
|
|
26
34
|
// ---------------------------------------------------------------------------
|
|
27
35
|
// Concurrency cap
|
|
28
36
|
// ---------------------------------------------------------------------------
|
|
@@ -182,9 +190,43 @@ export function resolveDaemonWideVerifyCap(scopes) {
|
|
|
182
190
|
* delivery -- bounded and idempotent.
|
|
183
191
|
*/
|
|
184
192
|
const defaultOnRan = new Set();
|
|
185
|
-
/**
|
|
193
|
+
/**
|
|
194
|
+
* HEAD-keyed re-verify guard: delivery id -> the commit its last default-on
|
|
195
|
+
* verify FAILED on (the gate command exited non-zero at that sha).
|
|
196
|
+
*
|
|
197
|
+
* The steady-state guard above is keyed on STATUS re-entry, and a failed verify
|
|
198
|
+
* with every issue Done steps verify -> verify_failed -> coding -> verify within
|
|
199
|
+
* ~60s -- so the same unchanged commit re-ran the whole gate (one delivery
|
|
200
|
+
* re-verified 5x on one sha, f1 2026-09-13), and each run re-took the verify hold.
|
|
201
|
+
* A gate on an unchanged tree renders the same verdict; only a NEW commit on the
|
|
202
|
+
* focus branch can change it. So an entry here suppresses selection while the
|
|
203
|
+
* focus HEAD still equals the failed sha, survives the status round trip, and is
|
|
204
|
+
* dropped (re-armed) the first time a readable HEAD differs; an unreadable HEAD
|
|
205
|
+
* keeps it (fail closed). A pass clears it. A timed-out run records nothing (a
|
|
206
|
+
* kill is not a verdict about the tree; judgedFailedSha).
|
|
207
|
+
*
|
|
208
|
+
* This map is only the hot copy. The DURABLE record is gate_state
|
|
209
|
+
* `verificationHistory.failedAtSha`: the failure feedback stamps it on the
|
|
210
|
+
* rejection, every clearing writer carries it (carryVerificationHistory), and a
|
|
211
|
+
* pass resets it -- so a daemon restart does not re-arm the unchanged commit.
|
|
212
|
+
* Selection reads the map first, then that record; the map covers a rejection
|
|
213
|
+
* write that did not land.
|
|
214
|
+
*/
|
|
215
|
+
const failedAtSha = new Map();
|
|
216
|
+
/** `${deliveryId}@${sha}` pairs whose suppression was already logged. */
|
|
217
|
+
const loggedShaSkips = new Set();
|
|
218
|
+
function forgetFailedSha(deliveryId, durableSha) {
|
|
219
|
+
for (const sha of [failedAtSha.get(deliveryId), durableSha]) {
|
|
220
|
+
if (sha !== undefined)
|
|
221
|
+
loggedShaSkips.delete(`${deliveryId}@${sha}`);
|
|
222
|
+
}
|
|
223
|
+
failedAtSha.delete(deliveryId);
|
|
224
|
+
}
|
|
225
|
+
/** Test-only: reset the default-on re-run guards (status- and HEAD-keyed). */
|
|
186
226
|
export function __resetDefaultOnGuardForTests() {
|
|
187
227
|
defaultOnRan.clear();
|
|
228
|
+
failedAtSha.clear();
|
|
229
|
+
loggedShaSkips.clear();
|
|
188
230
|
}
|
|
189
231
|
/** Test-only: snapshot of the default-on re-run guard. */
|
|
190
232
|
export function __getDefaultOnGuardForTests() {
|
|
@@ -198,6 +240,53 @@ export function markDefaultOnRan(deliveryId) {
|
|
|
198
240
|
export function __markDefaultOnRanForTests(deliveryId) {
|
|
199
241
|
defaultOnRan.add(deliveryId);
|
|
200
242
|
}
|
|
243
|
+
/**
|
|
244
|
+
* Dispatch-result bookkeeping for a default-on run:
|
|
245
|
+
* - no checkout could be made -> un-mark, so the next tick retries (the run
|
|
246
|
+
* never happened; no verdict exists to guard);
|
|
247
|
+
* - the gate command FAILED at a known sha (non-zero exit, not a timeout, final
|
|
248
|
+
* outcome failed) -> record the sha so that commit is not re-verified;
|
|
249
|
+
* - a pass -> forget any recorded failure.
|
|
250
|
+
*/
|
|
251
|
+
export function noteDefaultOnResult(deliveryId, result) {
|
|
252
|
+
if (result.checkoutUnavailable) {
|
|
253
|
+
defaultOnRan.delete(deliveryId);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
const failedSha = judgedFailedSha(result);
|
|
257
|
+
if (result.outcome === 'failed' && failedSha) {
|
|
258
|
+
failedAtSha.set(deliveryId, failedSha);
|
|
259
|
+
}
|
|
260
|
+
else if (result.outcome === 'passed') {
|
|
261
|
+
forgetFailedSha(deliveryId);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* True when the delivery's last default-on verify failed on the focus's CURRENT
|
|
266
|
+
* HEAD (skip it). The failed sha is the in-memory copy, else the durable
|
|
267
|
+
* gate_state record. Only a readable HEAD that DIFFERS re-arms the delivery; an
|
|
268
|
+
* unreadable HEAD keeps it suppressed.
|
|
269
|
+
*/
|
|
270
|
+
function failedOnCurrentHead(delivery, focusId, deps) {
|
|
271
|
+
const failedSha = failedAtSha.get(delivery.id) ?? readVerificationHistory(delivery.gateState).failedAtSha;
|
|
272
|
+
if (failedSha === undefined)
|
|
273
|
+
return false;
|
|
274
|
+
const head = (deps.resolveFocusHeadSha ?? defaultResolveFocusHeadSha)(focusId);
|
|
275
|
+
if (head !== null && head !== failedSha) {
|
|
276
|
+
forgetFailedSha(delivery.id, failedSha);
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
const key = `${delivery.id}@${failedSha}`;
|
|
280
|
+
if (!loggedShaSkips.has(key)) {
|
|
281
|
+
loggedShaSkips.add(key);
|
|
282
|
+
const why = head === null
|
|
283
|
+
? `its last verify failed on ${failedSha.slice(0, 8)} and the focus HEAD is unreadable`
|
|
284
|
+
: `focus HEAD ${failedSha.slice(0, 8)} is the commit its last verify failed on`;
|
|
285
|
+
log.info(`[verification] default-on: not re-verifying delivery ${delivery.id} -- ${why}; `
|
|
286
|
+
+ `a new commit on the focus branch re-arms it`);
|
|
287
|
+
}
|
|
288
|
+
return true;
|
|
289
|
+
}
|
|
201
290
|
// ---------------------------------------------------------------------------
|
|
202
291
|
// Selection
|
|
203
292
|
// ---------------------------------------------------------------------------
|
|
@@ -205,8 +294,9 @@ export function __markDefaultOnRanForTests(deliveryId) {
|
|
|
205
294
|
* Discover deliveries that should receive a DEFAULT-ON deterministic run: in
|
|
206
295
|
* `verify` status, anchored to an injection, with no explicit verification
|
|
207
296
|
* method (so not already returned by getPendingVerifications), not in a
|
|
208
|
-
* read-only audit focus (those are discovery-only and never run a suite),
|
|
209
|
-
*
|
|
297
|
+
* read-only audit focus (those are discovery-only and never run a suite), not
|
|
298
|
+
* already run this verify-entry (steady-state guard), and not failed on the
|
|
299
|
+
* focus's unchanged HEAD (HEAD-keyed guard).
|
|
210
300
|
*
|
|
211
301
|
* Synthesizes a `deterministic` PendingVerification carrying the resolved
|
|
212
302
|
* config-default command + timeout. Returns [] when the default-on path is
|
|
@@ -246,6 +336,8 @@ export async function collectDefaultOnVerifications(config, resolved, explicitDe
|
|
|
246
336
|
observedInVerify.add(d.id);
|
|
247
337
|
if (defaultOnRan.has(d.id))
|
|
248
338
|
continue; // already ran this verify-entry
|
|
339
|
+
if (failedOnCurrentHead(d, focus.focus_id, deps))
|
|
340
|
+
continue; // unchanged commit already failed
|
|
249
341
|
candidates.push({
|
|
250
342
|
deliveryId: d.id,
|
|
251
343
|
deliveryName: d.name,
|
|
@@ -265,7 +357,8 @@ export async function collectDefaultOnVerifications(config, resolved, explicitDe
|
|
|
265
357
|
}
|
|
266
358
|
}
|
|
267
359
|
// Prune guard entries for deliveries no longer sitting in verify, so a
|
|
268
|
-
// genuine re-entry (verify_failed -> coding -> verify) runs again
|
|
360
|
+
// genuine re-entry (verify_failed -> coding -> verify) runs again -- unless its
|
|
361
|
+
// HEAD-keyed failure still stands (failedAtSha is deliberately NOT pruned here).
|
|
269
362
|
for (const id of [...defaultOnRan]) {
|
|
270
363
|
if (!observedInVerify.has(id))
|
|
271
364
|
defaultOnRan.delete(id);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verification-default-on.js","sourceRoot":"","sources":["../../src/verify/verification-default-on.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,
|
|
1
|
+
{"version":3,"file":"verification-default-on.js","sourceRoot":"","sources":["../../src/verify/verification-default-on.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import type { StrategyResult } from './verification-deterministic.js';
|
|
19
19
|
import type { runDeterministicStrategy } from './verification-deterministic.js';
|
|
20
|
+
import type { VerifyCheckout } from './verification-checkout.js';
|
|
20
21
|
import type { getPendingVerifications, PendingVerification, VerificationOutcome } from '../queries/verification.js';
|
|
21
22
|
import type { NodeWriteback } from '../reality/reality-writeback.js';
|
|
22
23
|
import type { ReconcileTargetsResult, TargetRestatement, TargetShortfall, VerifyEvidence } from './verify-restatement.js';
|
|
@@ -135,6 +136,16 @@ export interface VerificationDeps {
|
|
|
135
136
|
requeueEvidenceUnavailableAsRework?: (v: PendingVerification, fault: Omit<EvidenceUnavailableDetail, 'heldAt'>) => Promise<void>;
|
|
136
137
|
/** cwd for the HEAD run -- the focus worktree. Optional; dispatch falls back to resolveCwd. */
|
|
137
138
|
resolveVerificationCwd?: (v: PendingVerification) => string;
|
|
139
|
+
/**
|
|
140
|
+
* The focus worktree a deterministic verify judges (its HEAD is checked out
|
|
141
|
+
* detached for the run); null when the focus has none. Optional; defaults to
|
|
142
|
+
* the registered focus worktree (verify/verification-checkout.ts).
|
|
143
|
+
*/
|
|
144
|
+
resolveFocusWorktreePath?: (v: PendingVerification) => string | null;
|
|
145
|
+
/** Detached-checkout factory for a deterministic run. Optional; defaults to createVerifyCheckout. */
|
|
146
|
+
createVerifyCheckout?: (focusWorktreePath: string, checkoutKey: string) => VerifyCheckout | null;
|
|
147
|
+
/** Focus worktree HEAD sha (default-on HEAD re-verify guard). Optional; null never suppresses. */
|
|
148
|
+
resolveFocusHeadSha?: (focusId: string) => string | null;
|
|
138
149
|
/**
|
|
139
150
|
* Count of commits the delivery branch is ahead of the integration base.
|
|
140
151
|
* Used by the evidence-integrity guard to tell a broken diff MEASUREMENT
|