@telora/daemon 0.22.239 → 0.22.245
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 +2 -2
- package/dist/ci/ci-red-attribution.js +1 -1
- package/dist/ci/ci-red-attribution.js.map +1 -1
- package/dist/ci/ci-status-git.js +1 -1
- package/dist/ci/ci-status-git.js.map +1 -1
- package/dist/completion/escalations.d.ts.map +1 -1
- package/dist/completion/escalations.js +1 -0
- package/dist/completion/escalations.js.map +1 -1
- package/dist/completion/merge-phase.d.ts +4 -4
- package/dist/completion/merge-phase.d.ts.map +1 -1
- package/dist/completion/merge-phase.js +10 -7
- package/dist/completion/merge-phase.js.map +1 -1
- package/dist/completion/review-breaker-hold.d.ts +107 -0
- package/dist/completion/review-breaker-hold.d.ts.map +1 -0
- package/dist/completion/review-breaker-hold.js +127 -0
- package/dist/completion/review-breaker-hold.js.map +1 -0
- package/dist/completion/review-exit-escalations.d.ts +9 -1
- package/dist/completion/review-exit-escalations.d.ts.map +1 -1
- package/dist/completion/review-exit-escalations.js +14 -3
- package/dist/completion/review-exit-escalations.js.map +1 -1
- package/dist/completion/review-exit-phase.d.ts.map +1 -1
- package/dist/completion/review-exit-phase.js +2 -2
- package/dist/completion/review-exit-phase.js.map +1 -1
- package/dist/completion/state-cascade.d.ts +14 -12
- package/dist/completion/state-cascade.d.ts.map +1 -1
- package/dist/completion/state-cascade.js +28 -19
- package/dist/completion/state-cascade.js.map +1 -1
- package/dist/completion/team-lifecycle.d.ts +3 -3
- package/dist/completion/team-lifecycle.d.ts.map +1 -1
- package/dist/completion/team-lifecycle.js +6 -5
- package/dist/completion/team-lifecycle.js.map +1 -1
- package/dist/merge/approval-gate-state.d.ts +24 -0
- package/dist/merge/approval-gate-state.d.ts.map +1 -0
- package/dist/merge/approval-gate-state.js +67 -0
- package/dist/merge/approval-gate-state.js.map +1 -0
- package/dist/merge/focus-merge.d.ts +3 -3
- package/dist/merge/focus-merge.d.ts.map +1 -1
- package/dist/merge/focus-merge.js +6 -6
- package/dist/merge/focus-merge.js.map +1 -1
- package/dist/merge/merge-back-loop.d.ts +3 -3
- package/dist/merge/merge-back-loop.d.ts.map +1 -1
- package/dist/merge/merge-back-loop.js +10 -10
- package/dist/merge/merge-back-loop.js.map +1 -1
- package/dist/merge/merge-gate-coverage.d.ts +32 -9
- package/dist/merge/merge-gate-coverage.d.ts.map +1 -1
- package/dist/merge/merge-gate-coverage.js +69 -18
- package/dist/merge/merge-gate-coverage.js.map +1 -1
- package/dist/queries/delivery-gate-state.d.ts +4 -2
- package/dist/queries/delivery-gate-state.d.ts.map +1 -1
- package/dist/queries/delivery-gate-state.js +8 -3
- package/dist/queries/delivery-gate-state.js.map +1 -1
- package/dist/queries/escalations.d.ts +2 -1
- package/dist/queries/escalations.d.ts.map +1 -1
- package/dist/queries/escalations.js +3 -3
- package/dist/queries/escalations.js.map +1 -1
- package/dist/queries/focus-criteria-standing.d.ts +2 -2
- package/dist/testing/fixtures/merge-log-capture.d.ts +5 -0
- package/dist/testing/fixtures/merge-log-capture.d.ts.map +1 -0
- package/dist/testing/fixtures/merge-log-capture.js +35 -0
- package/dist/testing/fixtures/merge-log-capture.js.map +1 -0
- package/dist/testing/fixtures/pending-spawn-world.js +1 -1
- package/dist/testing/fixtures/pending-spawn-world.js.map +1 -1
- package/dist/verify/commit-gate-configured.d.ts.map +1 -1
- package/dist/verify/commit-gate-configured.js +1 -0
- package/dist/verify/commit-gate-configured.js.map +1 -1
- package/dist/verify/gate-process-group.d.ts +40 -0
- package/dist/verify/gate-process-group.d.ts.map +1 -0
- package/dist/verify/gate-process-group.js +91 -0
- package/dist/verify/gate-process-group.js.map +1 -0
- package/dist/verify/no-verdict-record.d.ts +103 -0
- package/dist/verify/no-verdict-record.d.ts.map +1 -0
- package/dist/verify/no-verdict-record.js +218 -0
- package/dist/verify/no-verdict-record.js.map +1 -0
- package/dist/verify/timed-out-rendered-verdict.d.ts +40 -0
- package/dist/verify/timed-out-rendered-verdict.d.ts.map +1 -0
- package/dist/verify/timed-out-rendered-verdict.js +52 -0
- package/dist/verify/timed-out-rendered-verdict.js.map +1 -0
- package/dist/verify/verification-attribution-base.js +1 -1
- package/dist/verify/verification-attribution-base.js.map +1 -1
- package/dist/verify/verification-attribution.js +2 -2
- package/dist/verify/verification-attribution.js.map +1 -1
- package/dist/verify/verification-baseline-run.d.ts.map +1 -1
- package/dist/verify/verification-baseline-run.js +5 -7
- package/dist/verify/verification-baseline-run.js.map +1 -1
- package/dist/verify/verification-baseline.js +1 -1
- package/dist/verify/verification-baseline.js.map +1 -1
- package/dist/verify/verification-checkout.js +1 -1
- package/dist/verify/verification-checkout.js.map +1 -1
- package/dist/verify/verification-commit-sharing.d.ts.map +1 -1
- package/dist/verify/verification-commit-sharing.js +93 -10
- package/dist/verify/verification-commit-sharing.js.map +1 -1
- package/dist/verify/verification-default-on.js +1 -1
- package/dist/verify/verification-default-on.js.map +1 -1
- package/dist/verify/verification-deps-default.d.ts.map +1 -1
- package/dist/verify/verification-deps-default.js +2 -0
- package/dist/verify/verification-deps-default.js.map +1 -1
- package/dist/verify/verification-deps.d.ts +8 -0
- package/dist/verify/verification-deps.d.ts.map +1 -1
- package/dist/verify/verification-deterministic.d.ts +8 -0
- package/dist/verify/verification-deterministic.d.ts.map +1 -1
- package/dist/verify/verification-deterministic.js +3 -6
- package/dist/verify/verification-deterministic.js.map +1 -1
- package/dist/worktree/provision.d.ts +6 -5
- package/dist/worktree/provision.d.ts.map +1 -1
- package/dist/worktree/provision.js +13 -8
- package/dist/worktree/provision.js.map +1 -1
- package/dist/worktree/verify-interlock.d.ts.map +1 -1
- package/dist/worktree/verify-interlock.js +2 -0
- package/dist/worktree/verify-interlock.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commit-gate-configured.js","sourceRoot":"","sources":["../../src/verify/commit-gate-configured.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"commit-gate-configured.js","sourceRoot":"","sources":["../../src/verify/commit-gate-configured.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The gate command's process GROUP: spawn it as a group leader and end the
|
|
3
|
+
* whole group on timeout.
|
|
4
|
+
*
|
|
5
|
+
* The gate runs as `sh -c <command>`. Killing only that shell (the former
|
|
6
|
+
* `child.kill('SIGKILL')`) left its npm / vitest / node:test grandchildren
|
|
7
|
+
* running and holding the output pipes, so the run's 'close' -- and with it the
|
|
8
|
+
* verify interlock and the daemon-wide verification slot -- waited for the whole
|
|
9
|
+
* gate to finish: measured on mars 2026-09-18..25, up to 36 minutes past the
|
|
10
|
+
* timeout. Spawning `detached` makes the shell a process-group leader, so one
|
|
11
|
+
* signal to `-pid` reaches every descendant that did not leave the group.
|
|
12
|
+
*
|
|
13
|
+
* A descendant that DID leave the group (its own `setsid`) could still hold the
|
|
14
|
+
* pipes, so the kill also arms a backstop: after `STDIO_RELEASE_GRACE_MS` the
|
|
15
|
+
* child's stdio is destroyed, which lets 'close' fire regardless. A timed-out
|
|
16
|
+
* run therefore resolves within a small bound of its timeout, always.
|
|
17
|
+
*
|
|
18
|
+
* `detached` also means the gate no longer dies with the daemon's own group, so
|
|
19
|
+
* live groups are recorded and killed when the daemon process exits -- a run
|
|
20
|
+
* the daemon abandons must not keep running unobserved.
|
|
21
|
+
*
|
|
22
|
+
* @module verify/gate-process-group
|
|
23
|
+
*/
|
|
24
|
+
import { type ChildProcess, type SpawnOptions } from 'node:child_process';
|
|
25
|
+
/** How long after the group kill the child's stdio is forcibly released. */
|
|
26
|
+
export declare const STDIO_RELEASE_GRACE_MS = 2000;
|
|
27
|
+
/**
|
|
28
|
+
* Spawn `sh -c command` as the leader of its own process group. The group is
|
|
29
|
+
* tracked until the child closes so a daemon exit can end it.
|
|
30
|
+
*/
|
|
31
|
+
export declare function spawnGateGroup(command: string, options: SpawnOptions): ChildProcess;
|
|
32
|
+
/**
|
|
33
|
+
* End the child's whole process group (SIGKILL: a timed-out gate is abandoned,
|
|
34
|
+
* not asked to wind down), then release its stdio after a short grace so a
|
|
35
|
+
* descendant that escaped the group cannot hold the run open.
|
|
36
|
+
*/
|
|
37
|
+
export declare function killGateGroup(child: ChildProcess, graceMs?: number): void;
|
|
38
|
+
/** Test seam: the process groups currently tracked as live. */
|
|
39
|
+
export declare function liveGateGroupsForTest(): ReadonlySet<number>;
|
|
40
|
+
//# sourceMappingURL=gate-process-group.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-process-group.d.ts","sourceRoot":"","sources":["../../src/verify/gate-process-group.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAS,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEjF,4EAA4E;AAC5E,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAuB3C;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,YAAY,CAUnF;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,GAAE,MAA+B,GAAG,IAAI,CAWjG;AAED,+DAA+D;AAC/D,wBAAgB,qBAAqB,IAAI,WAAW,CAAC,MAAM,CAAC,CAE3D"}
|
|
@@ -0,0 +1,91 @@
|
|
|
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-deterministic.test.ts
|
|
3
|
+
// PINNED-BY-END
|
|
4
|
+
/**
|
|
5
|
+
* The gate command's process GROUP: spawn it as a group leader and end the
|
|
6
|
+
* whole group on timeout.
|
|
7
|
+
*
|
|
8
|
+
* The gate runs as `sh -c <command>`. Killing only that shell (the former
|
|
9
|
+
* `child.kill('SIGKILL')`) left its npm / vitest / node:test grandchildren
|
|
10
|
+
* running and holding the output pipes, so the run's 'close' -- and with it the
|
|
11
|
+
* verify interlock and the daemon-wide verification slot -- waited for the whole
|
|
12
|
+
* gate to finish: measured on mars 2026-09-18..25, up to 36 minutes past the
|
|
13
|
+
* timeout. Spawning `detached` makes the shell a process-group leader, so one
|
|
14
|
+
* signal to `-pid` reaches every descendant that did not leave the group.
|
|
15
|
+
*
|
|
16
|
+
* A descendant that DID leave the group (its own `setsid`) could still hold the
|
|
17
|
+
* pipes, so the kill also arms a backstop: after `STDIO_RELEASE_GRACE_MS` the
|
|
18
|
+
* child's stdio is destroyed, which lets 'close' fire regardless. A timed-out
|
|
19
|
+
* run therefore resolves within a small bound of its timeout, always.
|
|
20
|
+
*
|
|
21
|
+
* `detached` also means the gate no longer dies with the daemon's own group, so
|
|
22
|
+
* live groups are recorded and killed when the daemon process exits -- a run
|
|
23
|
+
* the daemon abandons must not keep running unobserved.
|
|
24
|
+
*
|
|
25
|
+
* @module verify/gate-process-group
|
|
26
|
+
*/
|
|
27
|
+
import { spawn } from 'node:child_process';
|
|
28
|
+
/** How long after the group kill the child's stdio is forcibly released. */
|
|
29
|
+
export const STDIO_RELEASE_GRACE_MS = 2000;
|
|
30
|
+
const liveGroups = new Set();
|
|
31
|
+
let exitHookInstalled = false;
|
|
32
|
+
/** Signal a whole process group, tolerating one that is already gone. */
|
|
33
|
+
function signalGroup(pid, signal) {
|
|
34
|
+
try {
|
|
35
|
+
process.kill(-pid, signal);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// ESRCH: the group already exited. EPERM cannot occur for our own child.
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function installExitHook() {
|
|
42
|
+
if (exitHookInstalled)
|
|
43
|
+
return;
|
|
44
|
+
exitHookInstalled = true;
|
|
45
|
+
process.on('exit', () => {
|
|
46
|
+
for (const pid of liveGroups)
|
|
47
|
+
signalGroup(pid, 'SIGKILL');
|
|
48
|
+
liveGroups.clear();
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Spawn `sh -c command` as the leader of its own process group. The group is
|
|
53
|
+
* tracked until the child closes so a daemon exit can end it.
|
|
54
|
+
*/
|
|
55
|
+
export function spawnGateGroup(command, options) {
|
|
56
|
+
const child = spawn('sh', ['-c', command], { ...options, detached: true });
|
|
57
|
+
const pid = child.pid;
|
|
58
|
+
if (typeof pid === 'number') {
|
|
59
|
+
installExitHook();
|
|
60
|
+
liveGroups.add(pid);
|
|
61
|
+
child.once('close', () => liveGroups.delete(pid));
|
|
62
|
+
child.once('error', () => liveGroups.delete(pid));
|
|
63
|
+
}
|
|
64
|
+
return child;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* End the child's whole process group (SIGKILL: a timed-out gate is abandoned,
|
|
68
|
+
* not asked to wind down), then release its stdio after a short grace so a
|
|
69
|
+
* descendant that escaped the group cannot hold the run open.
|
|
70
|
+
*/
|
|
71
|
+
export function killGateGroup(child, graceMs = STDIO_RELEASE_GRACE_MS) {
|
|
72
|
+
if (typeof child.pid === 'number')
|
|
73
|
+
signalGroup(child.pid, 'SIGKILL');
|
|
74
|
+
else {
|
|
75
|
+
try {
|
|
76
|
+
child.kill('SIGKILL');
|
|
77
|
+
}
|
|
78
|
+
catch { /* ignore */ }
|
|
79
|
+
}
|
|
80
|
+
const backstop = setTimeout(() => {
|
|
81
|
+
child.stdout?.destroy();
|
|
82
|
+
child.stderr?.destroy();
|
|
83
|
+
}, graceMs);
|
|
84
|
+
backstop.unref();
|
|
85
|
+
child.once('close', () => clearTimeout(backstop));
|
|
86
|
+
}
|
|
87
|
+
/** Test seam: the process groups currently tracked as live. */
|
|
88
|
+
export function liveGateGroupsForTest() {
|
|
89
|
+
return liveGroups;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=gate-process-group.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-process-group.js","sourceRoot":"","sources":["../../src/verify/gate-process-group.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,2EAA2E;AAC3E,gBAAgB;AAEhB;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,KAAK,EAAwC,MAAM,oBAAoB,CAAC;AAEjF,4EAA4E;AAC5E,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAE3C,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;AACrC,IAAI,iBAAiB,GAAG,KAAK,CAAC;AAE9B,yEAAyE;AACzE,SAAS,WAAW,CAAC,GAAW,EAAE,MAAsB;IACtD,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,yEAAyE;IAC3E,CAAC;AACH,CAAC;AAED,SAAS,eAAe;IACtB,IAAI,iBAAiB;QAAE,OAAO;IAC9B,iBAAiB,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;QACtB,KAAK,MAAM,GAAG,IAAI,UAAU;YAAE,WAAW,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAC1D,UAAU,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,OAAqB;IACnE,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3E,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;IACtB,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,eAAe,EAAE,CAAC;QAClB,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAClD,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,KAAmB,EAAE,UAAkB,sBAAsB;IACzF,IAAI,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ;QAAE,WAAW,CAAC,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;SAChE,CAAC;QACJ,IAAI,CAAC;YAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IACvD,CAAC;IACD,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,EAAE;QAC/B,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;QACxB,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;IAC1B,CAAC,EAAE,OAAO,CAAC,CAAC;IACZ,QAAQ,CAAC,KAAK,EAAE,CAAC;IACjB,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;AACpD,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,qBAAqB;IACnC,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { type CommitVerdictGate } from './commit-verdict-record.js';
|
|
2
|
+
import type { FileEscalationInput } from '../completion/escalations.js';
|
|
3
|
+
/** Backoff after the FIRST no-verdict run on a commit; doubles per further one. */
|
|
4
|
+
export declare const NO_VERDICT_BACKOFF_BASE_MS: number;
|
|
5
|
+
/** The longest a commit waits between no-verdict runs. */
|
|
6
|
+
export declare const NO_VERDICT_BACKOFF_MAX_MS: number;
|
|
7
|
+
/** No-verdict runs on one focus commit (any gate) that raise its one escalation. */
|
|
8
|
+
export declare const NO_VERDICT_ESCALATION_THRESHOLD = 3;
|
|
9
|
+
/** Machine kind the escalation carries (metadata discriminator). */
|
|
10
|
+
export declare const NO_VERDICT_ESCALATION_KIND = "verify_commit_no_verdict";
|
|
11
|
+
/** Why a run rendered no verdict. */
|
|
12
|
+
export type NoVerdictKind = 'timed_out' | 'instrument_fault';
|
|
13
|
+
/** What identifies one commit under one gate. */
|
|
14
|
+
export interface NoVerdictKey {
|
|
15
|
+
productId: string;
|
|
16
|
+
focusId: string;
|
|
17
|
+
sha: string;
|
|
18
|
+
gate: CommitVerdictGate;
|
|
19
|
+
}
|
|
20
|
+
/** One no-verdict run. */
|
|
21
|
+
export interface NoVerdictRun {
|
|
22
|
+
at: string;
|
|
23
|
+
deliveryId: string;
|
|
24
|
+
kind: NoVerdictKind;
|
|
25
|
+
}
|
|
26
|
+
/** A dispatch that ran the commit again after its backoff elapsed, and why. */
|
|
27
|
+
export interface NoVerdictRedispatch {
|
|
28
|
+
at: string;
|
|
29
|
+
deliveryId: string;
|
|
30
|
+
reason: string;
|
|
31
|
+
}
|
|
32
|
+
/** The durable backoff record for one (product, focus, sha, gate). */
|
|
33
|
+
export interface NoVerdictRecord extends NoVerdictKey {
|
|
34
|
+
runs: NoVerdictRun[];
|
|
35
|
+
redispatches: NoVerdictRedispatch[];
|
|
36
|
+
}
|
|
37
|
+
/** What identifies one focus commit, whatever gate judged it. */
|
|
38
|
+
export type NoVerdictCommitKey = Omit<NoVerdictKey, 'gate'>;
|
|
39
|
+
/** A no-verdict run in its commit's tally, with the gate it ran under. */
|
|
40
|
+
export interface NoVerdictTallyRun extends NoVerdictRun {
|
|
41
|
+
gate: CommitVerdictGate;
|
|
42
|
+
}
|
|
43
|
+
/** The durable escalation tally for one (product, focus, sha): every no-verdict run, under any gate. */
|
|
44
|
+
export interface NoVerdictCommitTally extends NoVerdictCommitKey {
|
|
45
|
+
runs: NoVerdictTallyRun[];
|
|
46
|
+
/** When the one escalation for this commit was filed; absent until it is. */
|
|
47
|
+
escalatedAt?: string;
|
|
48
|
+
}
|
|
49
|
+
/** The record for a key, or null when there is none (or it is unreadable / for another key). */
|
|
50
|
+
export declare function readNoVerdict(key: NoVerdictKey, dir?: string): NoVerdictRecord | null;
|
|
51
|
+
/** The commit's tally, or null when there is none (or it is unreadable / for another commit). */
|
|
52
|
+
export declare function readNoVerdictTally(key: NoVerdictCommitKey, dir?: string): NoVerdictCommitTally | null;
|
|
53
|
+
/** Append one no-verdict run to the key's record; returns the record as written. */
|
|
54
|
+
export declare function recordNoVerdictRun(key: NoVerdictKey, run: NoVerdictRun, dir?: string): NoVerdictRecord;
|
|
55
|
+
/** Append one no-verdict run, with its gate, to its commit's tally; returns the tally as written. */
|
|
56
|
+
export declare function recordNoVerdictTallyRun(key: NoVerdictKey, run: NoVerdictRun, dir?: string): NoVerdictCommitTally;
|
|
57
|
+
/** Append a re-dispatch after backoff, with why it ran. */
|
|
58
|
+
export declare function recordNoVerdictRedispatch(key: NoVerdictKey, redispatch: NoVerdictRedispatch, dir?: string): void;
|
|
59
|
+
/** Stamp that the commit's one escalation was filed. */
|
|
60
|
+
export declare function markNoVerdictEscalated(key: NoVerdictCommitKey, at: string, dir?: string): void;
|
|
61
|
+
/** The backoff a record imposes after its latest run: base * 2^(runs-1), capped. Pure. */
|
|
62
|
+
export declare function noVerdictBackoffMs(record: Pick<NoVerdictRecord, 'runs'>): number;
|
|
63
|
+
/** Whether a dispatch may run the commit now. Pure. */
|
|
64
|
+
export type NoVerdictGate = {
|
|
65
|
+
run: true;
|
|
66
|
+
redispatch: null;
|
|
67
|
+
} | {
|
|
68
|
+
run: true;
|
|
69
|
+
redispatch: string;
|
|
70
|
+
} | {
|
|
71
|
+
run: false;
|
|
72
|
+
until: string;
|
|
73
|
+
why: string;
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* What a record says about dispatching its commit at `now`: no record runs as
|
|
77
|
+
* before; inside the backoff nothing runs; past it the run goes ahead, and the
|
|
78
|
+
* reason it did is returned so it can be recorded. An unparseable run time holds
|
|
79
|
+
* nothing (fails toward judging). Pure.
|
|
80
|
+
*/
|
|
81
|
+
export declare function noVerdictDispatchGate(record: NoVerdictRecord | null, now: number): NoVerdictGate;
|
|
82
|
+
/** True exactly when the commit's tally reached the threshold and nothing was filed yet. Pure. */
|
|
83
|
+
export declare function noVerdictEscalationDue(tally: NoVerdictCommitTally): boolean;
|
|
84
|
+
/** The one escalation for a focus commit that keeps rendering no verdict, under whatever gates. Pure. */
|
|
85
|
+
export declare function buildNoVerdictEscalation(tally: NoVerdictCommitTally, organizationId: string): FileEscalationInput;
|
|
86
|
+
/** The record's IO as the verification path uses it (a seam: tests pin a clock). */
|
|
87
|
+
export interface NoVerdictStore {
|
|
88
|
+
read: (key: NoVerdictKey) => NoVerdictRecord | null;
|
|
89
|
+
/** Record one no-verdict run in its gate's backoff record AND its commit's escalation tally. */
|
|
90
|
+
recordRun: (key: NoVerdictKey, run: Omit<NoVerdictRun, 'at'>) => {
|
|
91
|
+
record: NoVerdictRecord;
|
|
92
|
+
tally: NoVerdictCommitTally;
|
|
93
|
+
};
|
|
94
|
+
recordRedispatch: (key: NoVerdictKey, redispatch: Omit<NoVerdictRedispatch, 'at'>) => void;
|
|
95
|
+
markEscalated: (key: NoVerdictCommitKey) => void;
|
|
96
|
+
now: () => number;
|
|
97
|
+
}
|
|
98
|
+
/** The durable store under the global state dir (resolved per call, so TELORA_STATE_DIR is honoured). */
|
|
99
|
+
export declare function durableNoVerdictStore(opts?: {
|
|
100
|
+
dir?: string;
|
|
101
|
+
now?: () => number;
|
|
102
|
+
}): NoVerdictStore;
|
|
103
|
+
//# sourceMappingURL=no-verdict-record.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-verdict-record.d.ts","sourceRoot":"","sources":["../../src/verify/no-verdict-record.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,218 @@
|
|
|
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/no-verdict-record.test.ts,
|
|
3
|
+
// packages/daemon/src/verify/verification-commit-sharing.test.ts
|
|
4
|
+
// PINNED-BY-END
|
|
5
|
+
/**
|
|
6
|
+
* A focus commit whose gate run rendered NO verdict is not run again blind.
|
|
7
|
+
*
|
|
8
|
+
* A run that renders a verdict is recorded per (product, focus, sha, gate)
|
|
9
|
+
* (verify/commit-verdict-record.ts) and every delivery judged on that commit
|
|
10
|
+
* takes it. A run that renders none -- killed by its timeout with nothing
|
|
11
|
+
* rendered (verify/timed-out-rendered-verdict.ts), or routed to instrument-fault
|
|
12
|
+
* re-work because the gate could not attribute it -- used to leave nothing
|
|
13
|
+
* behind at all. The re-run guards and the stall budget are keyed per DELIVERY
|
|
14
|
+
* and pruned on re-entry to verify, so the same commit was dispatched again by
|
|
15
|
+
* each sibling in turn (mars 2026-09-22: focus 63c8741f ran one commit seven
|
|
16
|
+
* times in 7.8h, rotating four deliveries), and nine such runs spread 3/2/2/3
|
|
17
|
+
* across four deliveries tripped no per-delivery cap and raised nothing.
|
|
18
|
+
*
|
|
19
|
+
* So the no-verdict outcome is recorded against the COMMIT, under the same key a
|
|
20
|
+
* verdict would be (the gate the run applied, at the sha it judged), durably
|
|
21
|
+
* beside the verdict records:
|
|
22
|
+
*
|
|
23
|
+
* - Dispatch reads it (verify/verification-commit-sharing.ts reuseOrRun) where
|
|
24
|
+
* it finds no verdict to take: while the backoff since the last no-verdict run
|
|
25
|
+
* has not elapsed, NO candidate -- a sibling delivery, a re-entry to verify, a
|
|
26
|
+
* restart -- starts that commit's gate. The backoff doubles per recorded
|
|
27
|
+
* no-verdict run (NO_VERDICT_BACKOFF_BASE_MS, capped at NO_VERDICT_BACKOFF_MAX_MS),
|
|
28
|
+
* and each dispatch that runs after it elapsed is appended to the record with
|
|
29
|
+
* why it ran.
|
|
30
|
+
* - The ESCALATION is counted per focus COMMIT, not per gate: every no-verdict
|
|
31
|
+
* run on a commit also lands in that commit's tally (product, focus, sha --
|
|
32
|
+
* no gate), whatever gate it ran under. At NO_VERDICT_ESCALATION_THRESHOLD
|
|
33
|
+
* runs in the tally ONE escalation is filed for that focus and commit,
|
|
34
|
+
* whichever deliveries and gates triggered the runs; the tally carries that it
|
|
35
|
+
* was filed, so neither a later run, a changed gate nor a restart files a
|
|
36
|
+
* second.
|
|
37
|
+
* - The BACKOFF stays keyed by gate: a different commit, or a changed gate
|
|
38
|
+
* identity (command or timeout), is a different backoff key, so an earlier
|
|
39
|
+
* commit's or gate's record blocks no run.
|
|
40
|
+
*
|
|
41
|
+
* Not recorded here: a run that never started the command (no checkout could be
|
|
42
|
+
* made, an unresolvable config) -- it spent no gate time, and the tick retries it.
|
|
43
|
+
*
|
|
44
|
+
* @module verify/no-verdict-record
|
|
45
|
+
*/
|
|
46
|
+
import { mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
47
|
+
import { resolve } from 'node:path';
|
|
48
|
+
import { ESCALATION_DISPOSITIONS, ESCALATION_REASONS } from '@telora/daemon-core';
|
|
49
|
+
import { resolveGlobalStateDir } from '../shell/daemon-process.js';
|
|
50
|
+
import { commitVerdictPath } from './commit-verdict-record.js';
|
|
51
|
+
import { createLogger } from '../shell/log.js';
|
|
52
|
+
const log = createLogger({ module: 'verification' });
|
|
53
|
+
/** Backoff after the FIRST no-verdict run on a commit; doubles per further one. */
|
|
54
|
+
export const NO_VERDICT_BACKOFF_BASE_MS = 15 * 60 * 1000;
|
|
55
|
+
/** The longest a commit waits between no-verdict runs. */
|
|
56
|
+
export const NO_VERDICT_BACKOFF_MAX_MS = 2 * 60 * 60 * 1000;
|
|
57
|
+
/** No-verdict runs on one focus commit (any gate) that raise its one escalation. */
|
|
58
|
+
export const NO_VERDICT_ESCALATION_THRESHOLD = 3;
|
|
59
|
+
/** Machine kind the escalation carries (metadata discriminator). */
|
|
60
|
+
export const NO_VERDICT_ESCALATION_KIND = 'verify_commit_no_verdict';
|
|
61
|
+
function noVerdictDir() {
|
|
62
|
+
return resolve(resolveGlobalStateDir(), 'verification-no-verdicts');
|
|
63
|
+
}
|
|
64
|
+
function recordPath(key, dir) {
|
|
65
|
+
return commitVerdictPath(key.productId, key.focusId, key.sha, dir, key.gate);
|
|
66
|
+
}
|
|
67
|
+
/** The tally's file: the gate-less name under the same dir, so no gate's backoff file is it. */
|
|
68
|
+
function tallyPath(key, dir) {
|
|
69
|
+
return commitVerdictPath(key.productId, key.focusId, key.sha, dir);
|
|
70
|
+
}
|
|
71
|
+
function sameKey(record, key) {
|
|
72
|
+
return record.productId === key.productId && record.focusId === key.focusId && record.sha === key.sha
|
|
73
|
+
&& record.gate?.command === key.gate.command && record.gate?.timeoutMs === key.gate.timeoutMs;
|
|
74
|
+
}
|
|
75
|
+
/** The record for a key, or null when there is none (or it is unreadable / for another key). */
|
|
76
|
+
export function readNoVerdict(key, dir = noVerdictDir()) {
|
|
77
|
+
try {
|
|
78
|
+
const parsed = JSON.parse(readFileSync(recordPath(key, dir), 'utf8'));
|
|
79
|
+
if (!sameKey(parsed, key) || !Array.isArray(parsed.runs))
|
|
80
|
+
return null;
|
|
81
|
+
return { ...parsed, redispatches: Array.isArray(parsed.redispatches) ? parsed.redispatches : [] };
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/** The commit's tally, or null when there is none (or it is unreadable / for another commit). */
|
|
88
|
+
export function readNoVerdictTally(key, dir = noVerdictDir()) {
|
|
89
|
+
try {
|
|
90
|
+
const parsed = JSON.parse(readFileSync(tallyPath(key, dir), 'utf8'));
|
|
91
|
+
const same = parsed.productId === key.productId && parsed.focusId === key.focusId && parsed.sha === key.sha;
|
|
92
|
+
return same && Array.isArray(parsed.runs) ? parsed : null;
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function writeRecord(record, dir) {
|
|
99
|
+
const path = 'gate' in record ? recordPath(record, dir) : tallyPath(record, dir);
|
|
100
|
+
const tmp = `${path}.${process.pid}.tmp`;
|
|
101
|
+
try {
|
|
102
|
+
mkdirSync(dir, { recursive: true });
|
|
103
|
+
writeFileSync(tmp, JSON.stringify(record, null, 2), { mode: 0o600 });
|
|
104
|
+
renameSync(tmp, path);
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
log.warn(`[verification] failed to record the no-verdict run for ${record.focusId}@${record.sha.slice(0, 8)}:`, err.message);
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/** Append one no-verdict run to the key's record; returns the record as written. */
|
|
113
|
+
export function recordNoVerdictRun(key, run, dir = noVerdictDir()) {
|
|
114
|
+
const prior = readNoVerdict(key, dir);
|
|
115
|
+
const record = {
|
|
116
|
+
productId: key.productId,
|
|
117
|
+
focusId: key.focusId,
|
|
118
|
+
sha: key.sha,
|
|
119
|
+
gate: { command: key.gate.command, timeoutMs: key.gate.timeoutMs },
|
|
120
|
+
runs: [...(prior?.runs ?? []), run],
|
|
121
|
+
redispatches: prior?.redispatches ?? [],
|
|
122
|
+
};
|
|
123
|
+
writeRecord(record, dir);
|
|
124
|
+
return record;
|
|
125
|
+
}
|
|
126
|
+
/** Append one no-verdict run, with its gate, to its commit's tally; returns the tally as written. */
|
|
127
|
+
export function recordNoVerdictTallyRun(key, run, dir = noVerdictDir()) {
|
|
128
|
+
const commit = { productId: key.productId, focusId: key.focusId, sha: key.sha };
|
|
129
|
+
const prior = readNoVerdictTally(commit, dir);
|
|
130
|
+
const tally = {
|
|
131
|
+
...commit,
|
|
132
|
+
runs: [...(prior?.runs ?? []), { ...run, gate: { command: key.gate.command, timeoutMs: key.gate.timeoutMs } }],
|
|
133
|
+
...(prior?.escalatedAt ? { escalatedAt: prior.escalatedAt } : {}),
|
|
134
|
+
};
|
|
135
|
+
writeRecord(tally, dir);
|
|
136
|
+
return tally;
|
|
137
|
+
}
|
|
138
|
+
/** Append a re-dispatch after backoff, with why it ran. */
|
|
139
|
+
export function recordNoVerdictRedispatch(key, redispatch, dir = noVerdictDir()) {
|
|
140
|
+
const prior = readNoVerdict(key, dir);
|
|
141
|
+
if (!prior)
|
|
142
|
+
return;
|
|
143
|
+
writeRecord({ ...prior, redispatches: [...prior.redispatches, redispatch] }, dir);
|
|
144
|
+
}
|
|
145
|
+
/** Stamp that the commit's one escalation was filed. */
|
|
146
|
+
export function markNoVerdictEscalated(key, at, dir = noVerdictDir()) {
|
|
147
|
+
const prior = readNoVerdictTally(key, dir);
|
|
148
|
+
if (!prior)
|
|
149
|
+
return;
|
|
150
|
+
writeRecord({ ...prior, escalatedAt: at }, dir);
|
|
151
|
+
}
|
|
152
|
+
/** The backoff a record imposes after its latest run: base * 2^(runs-1), capped. Pure. */
|
|
153
|
+
export function noVerdictBackoffMs(record) {
|
|
154
|
+
const n = Math.max(1, record.runs.length);
|
|
155
|
+
return Math.min(NO_VERDICT_BACKOFF_MAX_MS, NO_VERDICT_BACKOFF_BASE_MS * 2 ** (n - 1));
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* What a record says about dispatching its commit at `now`: no record runs as
|
|
159
|
+
* before; inside the backoff nothing runs; past it the run goes ahead, and the
|
|
160
|
+
* reason it did is returned so it can be recorded. An unparseable run time holds
|
|
161
|
+
* nothing (fails toward judging). Pure.
|
|
162
|
+
*/
|
|
163
|
+
export function noVerdictDispatchGate(record, now) {
|
|
164
|
+
const last = record?.runs[record.runs.length - 1];
|
|
165
|
+
if (!record || !last)
|
|
166
|
+
return { run: true, redispatch: null };
|
|
167
|
+
const lastAt = Date.parse(last.at);
|
|
168
|
+
if (Number.isNaN(lastAt))
|
|
169
|
+
return { run: true, redispatch: null };
|
|
170
|
+
const backoff = noVerdictBackoffMs(record);
|
|
171
|
+
const until = lastAt + backoff;
|
|
172
|
+
const tally = `${record.runs.length} run(s) on ${record.sha.slice(0, 8)} rendered no verdict (latest ${last.kind}, delivery ${last.deliveryId}, at ${last.at})`;
|
|
173
|
+
if (now < until)
|
|
174
|
+
return { run: false, until: new Date(until).toISOString(), why: `${tally}; backoff ${Math.round(backoff / 60000)} min` };
|
|
175
|
+
return { run: true, redispatch: `${tally}; the ${Math.round(backoff / 60000)}-min backoff elapsed, so the commit is judged again` };
|
|
176
|
+
}
|
|
177
|
+
/** True exactly when the commit's tally reached the threshold and nothing was filed yet. Pure. */
|
|
178
|
+
export function noVerdictEscalationDue(tally) {
|
|
179
|
+
return tally.escalatedAt === undefined && tally.runs.length >= NO_VERDICT_ESCALATION_THRESHOLD;
|
|
180
|
+
}
|
|
181
|
+
/** The one escalation for a focus commit that keeps rendering no verdict, under whatever gates. Pure. */
|
|
182
|
+
export function buildNoVerdictEscalation(tally, organizationId) {
|
|
183
|
+
const deliveries = [...new Set(tally.runs.map((r) => r.deliveryId))];
|
|
184
|
+
const kinds = [...new Set(tally.runs.map((r) => r.kind))];
|
|
185
|
+
const gates = [...new Set(tally.runs.map((r) => `\`${r.gate.command}\` (${r.gate.timeoutMs}ms timeout)`))];
|
|
186
|
+
return {
|
|
187
|
+
organizationId,
|
|
188
|
+
focusId: tally.focusId,
|
|
189
|
+
productId: tally.productId,
|
|
190
|
+
reason: `The deterministic gate has run ${tally.runs.length} times on focus commit ${tally.sha} and rendered no verdict `
|
|
191
|
+
+ `each time (${kinds.join(', ')}), across deliveries ${deliveries.join(', ')}. Dispatch backs off between runs `
|
|
192
|
+
+ `of this commit, but no run has judged it. Gate(s): ${gates.join(', ')}.`,
|
|
193
|
+
reasonType: ESCALATION_REASONS.ERROR_ENCOUNTERED,
|
|
194
|
+
disposition: ESCALATION_DISPOSITIONS.AGENT_RESOLVABLE,
|
|
195
|
+
kind: NO_VERDICT_ESCALATION_KIND,
|
|
196
|
+
details: {
|
|
197
|
+
sha: tally.sha,
|
|
198
|
+
runs: tally.runs,
|
|
199
|
+
},
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
/** The durable store under the global state dir (resolved per call, so TELORA_STATE_DIR is honoured). */
|
|
203
|
+
export function durableNoVerdictStore(opts = {}) {
|
|
204
|
+
const now = opts.now ?? Date.now;
|
|
205
|
+
const dir = () => opts.dir ?? noVerdictDir();
|
|
206
|
+
const at = () => new Date(now()).toISOString();
|
|
207
|
+
return {
|
|
208
|
+
read: (key) => readNoVerdict(key, dir()),
|
|
209
|
+
recordRun: (key, run) => {
|
|
210
|
+
const stamped = { ...run, at: at() };
|
|
211
|
+
return { record: recordNoVerdictRun(key, stamped, dir()), tally: recordNoVerdictTallyRun(key, stamped, dir()) };
|
|
212
|
+
},
|
|
213
|
+
recordRedispatch: (key, redispatch) => recordNoVerdictRedispatch(key, { ...redispatch, at: at() }, dir()),
|
|
214
|
+
markEscalated: (key) => markNoVerdictEscalated(key, at(), dir()),
|
|
215
|
+
now,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=no-verdict-record.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-verdict-record.js","sourceRoot":"","sources":["../../src/verify/no-verdict-record.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A gate run the timeout ended is judged from what it had already RENDERED.
|
|
3
|
+
*
|
|
4
|
+
* A timed-out run used to be routed straight to instrument-fault re-work and to
|
|
5
|
+
* record nothing for its commit -- no commit verdict, no failedAtSha, no failure
|
|
6
|
+
* signature -- whatever its log showed. Measured on mars 2026-09-18..25: of 34
|
|
7
|
+
* timed-out runs, 20 had printed the gate's completion sentinel (every stage
|
|
8
|
+
* passed: green, discarded) and 14 had named real failing tests (fed back as an
|
|
9
|
+
* "instrument fault" instead of the tests). With no verdict, the same commit was
|
|
10
|
+
* then run again, and again.
|
|
11
|
+
*
|
|
12
|
+
* The rule, read in this order:
|
|
13
|
+
* 1. PASSED -- the log carries the completion sentinel (TELORA_GATE_COMPLETE:*,
|
|
14
|
+
* the gate chain's final `&&` step, so it prints only when every stage before
|
|
15
|
+
* it passed) AND the gate's stage walk (verify/verification-gate-stages.ts)
|
|
16
|
+
* reads every chain as finished. The sentinel is the ONLY pass evidence: a
|
|
17
|
+
* log cut mid-stage has no sentinel and never reads as green, and a gate that
|
|
18
|
+
* is not a stage-walkable `npm run <gate>` chain can never be read as passed.
|
|
19
|
+
* 2. FAILED -- the log names failing tests (verify/verification-failure-parser.ts,
|
|
20
|
+
* which reads only explicit failure lines: a TAP `not ok`, a vitest FAIL /
|
|
21
|
+
* × line, a JSON report's failed assertion). A failure line printed before the
|
|
22
|
+
* kill is a real failure of that test, however much of the run was cut off.
|
|
23
|
+
* 3. Otherwise the run rendered NO verdict: it stays timed out, and the caller
|
|
24
|
+
* routes it to the bounded instrument-fault re-work as before.
|
|
25
|
+
*
|
|
26
|
+
* A run judged by (1) or (2) is no longer `timedOut`; it carries
|
|
27
|
+
* `renderedBeforeKill` instead, so it is recorded per commit, attributed against
|
|
28
|
+
* the base and fed back exactly as a run that exited on its own. Pure.
|
|
29
|
+
*
|
|
30
|
+
* @module verify/timed-out-rendered-verdict
|
|
31
|
+
*/
|
|
32
|
+
import type { StrategyResult } from './verification-deterministic.js';
|
|
33
|
+
/** True when the log proves the whole gate chain passed: sentinel printed and every stage finished. */
|
|
34
|
+
export declare function logShowsCompletedPass(logText: string, gateCommand: string | null): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Re-judge a timed-out result from its rendered log (module doc). A result the
|
|
37
|
+
* timeout did not end is returned unchanged; so is one that rendered no verdict.
|
|
38
|
+
*/
|
|
39
|
+
export declare function judgeTimedOutRun(result: StrategyResult, gateCommand: string | null, logText: string): StrategyResult;
|
|
40
|
+
//# sourceMappingURL=timed-out-rendered-verdict.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timed-out-rendered-verdict.d.ts","sourceRoot":"","sources":["../../src/verify/timed-out-rendered-verdict.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAStE,uGAAuG;AACvG,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAM1F;AAQD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,cAAc,CAqBpH"}
|
|
@@ -0,0 +1,52 @@
|
|
|
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/timed-out-rendered-verdict.test.ts
|
|
3
|
+
// PINNED-BY-END
|
|
4
|
+
import { parseFailingTests } from './verification-failure-parser.js';
|
|
5
|
+
import { parseGateRunStages } from './verification-gate-stages.js';
|
|
6
|
+
const ESC = String.fromCharCode(27);
|
|
7
|
+
const ANSI_RE = new RegExp(`${ESC}\\[[0-9;?]*[A-Za-z]`, 'g');
|
|
8
|
+
/** The completion sentinel line, alone on its line (as scripts/check-gate-sentinel.mjs reads it). */
|
|
9
|
+
const SENTINEL_LINE_RE = /^TELORA_GATE_COMPLETE:[A-Za-z0-9._-]+$/m;
|
|
10
|
+
/** True when the log proves the whole gate chain passed: sentinel printed and every stage finished. */
|
|
11
|
+
export function logShowsCompletedPass(logText, gateCommand) {
|
|
12
|
+
if (!gateCommand || typeof logText !== 'string')
|
|
13
|
+
return false;
|
|
14
|
+
const plain = logText.replace(ANSI_RE, '').replace(/[ \t]+$/gm, '');
|
|
15
|
+
if (!SENTINEL_LINE_RE.test(plain))
|
|
16
|
+
return false;
|
|
17
|
+
const run = parseGateRunStages(plain, 0, gateCommand);
|
|
18
|
+
return run !== null && run.failedStage === null;
|
|
19
|
+
}
|
|
20
|
+
function withoutTimeout(result) {
|
|
21
|
+
const next = { ...result };
|
|
22
|
+
delete next.timedOut;
|
|
23
|
+
return next;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Re-judge a timed-out result from its rendered log (module doc). A result the
|
|
27
|
+
* timeout did not end is returned unchanged; so is one that rendered no verdict.
|
|
28
|
+
*/
|
|
29
|
+
export function judgeTimedOutRun(result, gateCommand, logText) {
|
|
30
|
+
if (result.timedOut !== true)
|
|
31
|
+
return result;
|
|
32
|
+
if (logShowsCompletedPass(logText, gateCommand)) {
|
|
33
|
+
return {
|
|
34
|
+
...withoutTimeout(result),
|
|
35
|
+
outcome: 'passed',
|
|
36
|
+
renderedBeforeKill: 'passed',
|
|
37
|
+
rationale: 'deterministic check passed: the gate printed its completion sentinel with every stage passed '
|
|
38
|
+
+ 'before its timeout ended the run',
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const failing = parseFailingTests(logText);
|
|
42
|
+
if (failing.size > 0) {
|
|
43
|
+
return {
|
|
44
|
+
...withoutTimeout(result),
|
|
45
|
+
outcome: 'failed',
|
|
46
|
+
renderedBeforeKill: 'failed',
|
|
47
|
+
rationale: `deterministic check failed: the gate named ${failing.size} failing test(s) before its timeout ended the run`,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=timed-out-rendered-verdict.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timed-out-rendered-verdict.js","sourceRoot":"","sources":["../../src/verify/timed-out-rendered-verdict.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,2EAA2E;AAC3E,gBAAgB;AAmChB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEnE,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;AACpC,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,GAAG,GAAG,qBAAqB,EAAE,GAAG,CAAC,CAAC;AAC7D,qGAAqG;AACrG,MAAM,gBAAgB,GAAG,yCAAyC,CAAC;AAEnE,uGAAuG;AACvG,MAAM,UAAU,qBAAqB,CAAC,OAAe,EAAE,WAA0B;IAC/E,IAAI,CAAC,WAAW,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IACpE,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAChD,MAAM,GAAG,GAAG,kBAAkB,CAAC,KAAK,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC;IACtD,OAAO,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,WAAW,KAAK,IAAI,CAAC;AAClD,CAAC;AAED,SAAS,cAAc,CAAC,MAAsB;IAC5C,MAAM,IAAI,GAAmB,EAAE,GAAG,MAAM,EAAE,CAAC;IAC3C,OAAO,IAAI,CAAC,QAAQ,CAAC;IACrB,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAsB,EAAE,WAA0B,EAAE,OAAe;IAClG,IAAI,MAAM,CAAC,QAAQ,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC;IAC5C,IAAI,qBAAqB,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,CAAC;QAChD,OAAO;YACL,GAAG,cAAc,CAAC,MAAM,CAAC;YACzB,OAAO,EAAE,QAAQ;YACjB,kBAAkB,EAAE,QAAQ;YAC5B,SAAS,EAAE,+FAA+F;kBACtG,kCAAkC;SACvC,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAC3C,IAAI,OAAO,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO;YACL,GAAG,cAAc,CAAC,MAAM,CAAC;YACzB,OAAO,EAAE,QAAQ;YACjB,kBAAkB,EAAE,QAAQ;YAC5B,SAAS,EAAE,8CAA8C,OAAO,CAAC,IAAI,mDAAmD;SACzH,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
* @module verify/verification-attribution-base
|
|
30
30
|
*/
|
|
31
31
|
import { execFileSync } from 'node:child_process';
|
|
32
|
-
import { runGitSync } from '../git/
|
|
32
|
+
import { runGitSync } from '../git/types.js';
|
|
33
33
|
const FIXED_IDENTITY = {
|
|
34
34
|
GIT_AUTHOR_NAME: 'telora-verify',
|
|
35
35
|
GIT_AUTHOR_EMAIL: 'verify@telora.invalid',
|