@telora/daemon 0.22.58 → 0.22.72
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 +4 -3
- package/dist/completion/settle-injection-sweep.d.ts +7 -2
- package/dist/completion/settle-injection-sweep.d.ts.map +1 -1
- package/dist/completion/settle-injection-sweep.js +32 -2
- package/dist/completion/settle-injection-sweep.js.map +1 -1
- package/dist/completion/state-cascade.d.ts.map +1 -1
- package/dist/completion/state-cascade.js +35 -4
- package/dist/completion/state-cascade.js.map +1 -1
- package/dist/directive/directive-executor.d.ts.map +1 -1
- package/dist/directive/directive-executor.js +1 -0
- package/dist/directive/directive-executor.js.map +1 -1
- package/dist/focus/focus-executor.d.ts.map +1 -1
- package/dist/focus/focus-executor.js +41 -23
- package/dist/focus/focus-executor.js.map +1 -1
- package/dist/focus/focus-phase.d.ts.map +1 -1
- package/dist/focus/focus-phase.js +2 -1
- package/dist/focus/focus-phase.js.map +1 -1
- package/dist/focus/listener-spawn.d.ts +0 -44
- package/dist/focus/listener-spawn.d.ts.map +1 -1
- package/dist/focus/listener-spawn.js +61 -146
- package/dist/focus/listener-spawn.js.map +1 -1
- package/dist/focus-stage-lifecycle/planning-release.d.ts +3 -2
- package/dist/focus-stage-lifecycle/planning-release.d.ts.map +1 -1
- package/dist/focus-stage-lifecycle/planning-release.js +3 -2
- package/dist/focus-stage-lifecycle/planning-release.js.map +1 -1
- package/dist/focus-stage-lifecycle/wedge-watchdog.d.ts +5 -3
- package/dist/focus-stage-lifecycle/wedge-watchdog.d.ts.map +1 -1
- package/dist/focus-stage-lifecycle/wedge-watchdog.js +8 -5
- package/dist/focus-stage-lifecycle/wedge-watchdog.js.map +1 -1
- package/dist/queries/escalation-suppression.d.ts.map +1 -1
- package/dist/queries/escalation-suppression.js +2 -1
- package/dist/queries/escalation-suppression.js.map +1 -1
- package/dist/queries/focuses.d.ts +26 -0
- package/dist/queries/focuses.d.ts.map +1 -1
- package/dist/queries/focuses.js +36 -0
- package/dist/queries/focuses.js.map +1 -1
- package/dist/queries/shared.js +1 -1
- package/dist/queries/verification.d.ts +14 -2
- package/dist/queries/verification.d.ts.map +1 -1
- package/dist/queries/verification.js +43 -6
- package/dist/queries/verification.js.map +1 -1
- package/dist/reality/reality-writeback.d.ts +28 -0
- package/dist/reality/reality-writeback.d.ts.map +1 -1
- package/dist/reality/reality-writeback.js +30 -0
- package/dist/reality/reality-writeback.js.map +1 -1
- package/dist/shell/control-state.d.ts +6 -5
- package/dist/shell/control-state.d.ts.map +1 -1
- package/dist/shell/control-state.js +6 -5
- package/dist/shell/control-state.js.map +1 -1
- package/dist/spawn/null-role-spawn.d.ts +109 -0
- package/dist/spawn/null-role-spawn.d.ts.map +1 -0
- package/dist/spawn/null-role-spawn.js +94 -0
- package/dist/spawn/null-role-spawn.js.map +1 -0
- package/dist/spawn/worktree-session.d.ts +16 -10
- package/dist/spawn/worktree-session.d.ts.map +1 -1
- package/dist/spawn/worktree-session.js +52 -35
- package/dist/spawn/worktree-session.js.map +1 -1
- package/dist/testing/fixtures/index.js +1 -1
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types/session.js +1 -2
- package/dist/types/session.js.map +1 -1
- package/dist/verify/stall-detectors.d.ts.map +1 -1
- package/dist/verify/stall-detectors.js +3 -1
- package/dist/verify/stall-detectors.js.map +1 -1
- package/dist/verify/unreviewed-settle-detector.d.ts +108 -0
- package/dist/verify/unreviewed-settle-detector.d.ts.map +1 -0
- package/dist/verify/unreviewed-settle-detector.js +213 -0
- package/dist/verify/unreviewed-settle-detector.js.map +1 -0
- package/dist/verify/verification-boundary-env.d.ts +51 -0
- package/dist/verify/verification-boundary-env.d.ts.map +1 -0
- package/dist/verify/verification-boundary-env.js +63 -0
- package/dist/verify/verification-boundary-env.js.map +1 -0
- package/dist/verify/verification-deps-default.js +2 -1
- package/dist/verify/verification-deps-default.js.map +1 -1
- package/dist/verify/verification-deps.js +1 -1
- package/dist/verify/verification-deps.js.map +1 -1
- package/dist/verify/verification-deterministic.d.ts +11 -1
- package/dist/verify/verification-deterministic.d.ts.map +1 -1
- package/dist/verify/verification-deterministic.js +26 -5
- package/dist/verify/verification-deterministic.js.map +1 -1
- package/dist/verify/verification-engine.d.ts +1 -0
- package/dist/verify/verification-engine.d.ts.map +1 -1
- package/dist/verify/verification-engine.js +28 -4
- package/dist/verify/verification-engine.js.map +1 -1
- package/dist/verify/verification-evidence-unavailable-feedback.d.ts +52 -0
- package/dist/verify/verification-evidence-unavailable-feedback.d.ts.map +1 -0
- package/dist/verify/verification-evidence-unavailable-feedback.js +178 -0
- package/dist/verify/verification-evidence-unavailable-feedback.js.map +1 -0
- package/dist/verify/verification-feedback.d.ts +34 -59
- package/dist/verify/verification-feedback.d.ts.map +1 -1
- package/dist/verify/verification-feedback.js +64 -172
- package/dist/verify/verification-feedback.js.map +1 -1
- package/dist/verify/verify-restatement.d.ts.map +1 -1
- package/dist/verify/verify-restatement.js +2 -1
- package/dist/verify/verify-restatement.js.map +1 -1
- package/package.json +2 -2
- package/dist/spawn/review-role-fallback.d.ts +0 -141
- package/dist/spawn/review-role-fallback.d.ts.map +0 -1
- package/dist/spawn/review-role-fallback.js +0 -114
- package/dist/spawn/review-role-fallback.js.map +0 -1
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { FocusDeliveryInfo } from '../types/index.js';
|
|
2
|
+
import { type FileEscalationIdempotentParams, type FileEscalationIdempotentResult } from '../queries/escalation-suppression.js';
|
|
3
|
+
import { type FocusExecutionPhase } from '../focus/focus-phase.js';
|
|
4
|
+
import { type FocusStallContext } from './stall-detectors.js';
|
|
5
|
+
/**
|
|
6
|
+
* The set of inputs that decide an UNREVIEWED SETTLE. Kept as a small named
|
|
7
|
+
* shape so the pure predicate below can be truth-tabled directly.
|
|
8
|
+
*/
|
|
9
|
+
export interface UnreviewedSettleInputs {
|
|
10
|
+
/** The focus's derived execution phase (from deriveFocusPhase). */
|
|
11
|
+
phase: FocusExecutionPhase;
|
|
12
|
+
/** product_focuses.review_requested_at. */
|
|
13
|
+
reviewRequestedAt: string | null;
|
|
14
|
+
/** product_focuses.reviewed_through_sha (the rendered-verdict watermark). */
|
|
15
|
+
reviewedThroughSha: string | null;
|
|
16
|
+
/** product_focuses.assigned_agent_role_id (the stranded arm, when non-null). */
|
|
17
|
+
assignedAgentRoleId: string | null;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Pure decision: is this focus a SETTLED focus holding an UNRENDERED review
|
|
21
|
+
* verdict with its arm still stranded?
|
|
22
|
+
*
|
|
23
|
+
* True iff ALL hold:
|
|
24
|
+
* - phase === 'winding_down' -- every executable delivery is terminal and
|
|
25
|
+
* verify === 0 (deriveFocusPhase). This is the settle the reviewing-gated
|
|
26
|
+
* staleness detector can never reach.
|
|
27
|
+
* - review_requested_at is set -- a review window was opened,
|
|
28
|
+
* - reviewed_through_sha === null -- but NO verdict was ever rendered
|
|
29
|
+
* (review-exit stamps the watermark only on a routed completion), and
|
|
30
|
+
* - assigned_agent_role_id !== null -- an arm is still held.
|
|
31
|
+
*
|
|
32
|
+
* The role-still-assigned clause is what makes the whole detector idempotent
|
|
33
|
+
* (once released it is null, so a repeated poll is a no-op) and skips the cases
|
|
34
|
+
* that need no action: an operator-stopped focus (role already null) and a focus
|
|
35
|
+
* that settled with a rendered verdict (which clearStaleReviewRequest disarms via
|
|
36
|
+
* the window close). Exported for direct unit testing.
|
|
37
|
+
*/
|
|
38
|
+
export declare function isUnreviewedSettle(inputs: UnreviewedSettleInputs): boolean;
|
|
39
|
+
export interface UnreviewedSettleDeps {
|
|
40
|
+
/**
|
|
41
|
+
* File the review_window_stalled escalation through the cause-keyed idempotent
|
|
42
|
+
* gate: at most one open row per focus, so a repeated poll files no second one.
|
|
43
|
+
*/
|
|
44
|
+
fileEscalation: (params: FileEscalationIdempotentParams) => Promise<FileEscalationIdempotentResult>;
|
|
45
|
+
/**
|
|
46
|
+
* Release the settled focus's stranded arm (assigned_agent_role_id ->
|
|
47
|
+
* null) WITHOUT closing the review window. Defaults to releaseFocusArm.
|
|
48
|
+
*/
|
|
49
|
+
releaseArm: (focusId: string) => Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* Whether a review session for this focus is still running. While it is, the
|
|
52
|
+
* detector must NOT announce a missing verdict nor release the arm -- the
|
|
53
|
+
* verdict is being rendered right now. Same liveness signal the sibling
|
|
54
|
+
* clearStaleReviewRequest uses (an active team whose sessionType is 'review').
|
|
55
|
+
* Optional so a test may omit it (the gate then no-ops, the pre-gate
|
|
56
|
+
* behavior); the default deps always supply it, so production always gates.
|
|
57
|
+
*/
|
|
58
|
+
isReviewSessionActive?: (focusId: string) => boolean;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Check ONE focus's ALREADY-FETCHED settle state for an unreviewed settle and,
|
|
62
|
+
* when found, ANNOUNCE it and RELEASE the stranded arm -- keeping the review
|
|
63
|
+
* window OPEN (the deliberate null-watermark hold that surfaces the missing
|
|
64
|
+
* verdict; clearStaleReviewRequest leaves it set on a null watermark).
|
|
65
|
+
*
|
|
66
|
+
* SILENT while a review session is still live (a verdict may still land) -- see
|
|
67
|
+
* the liveness gate below. On an unreviewed settle with no live review, in order:
|
|
68
|
+
* 1. LOG the settle at the moment it occurs (so it is not readable only from
|
|
69
|
+
* the focus row).
|
|
70
|
+
* 2. File EXACTLY ONE review_window_stalled escalation naming the focus, its
|
|
71
|
+
* settled deliveries, and the verdict that was never rendered. Idempotent
|
|
72
|
+
* by cause key, so a repeated poll files no second one.
|
|
73
|
+
* 3. RELEASE the arm (daemon-owned, window stays open). Done last so a release
|
|
74
|
+
* failure still leaves the escalation filed and retries next poll (the
|
|
75
|
+
* role is still set, so the predicate still holds).
|
|
76
|
+
*
|
|
77
|
+
* Rides the same per-focus cascade seam as the sibling detectors; operates on
|
|
78
|
+
* state the caller (runCascadeChecks) already loaded.
|
|
79
|
+
*/
|
|
80
|
+
export declare function checkUnreviewedSettleForFocus(ctx: FocusStallContext, inputs: UnreviewedSettleInputs & {
|
|
81
|
+
deliveries: FocusDeliveryInfo[];
|
|
82
|
+
}, deps?: UnreviewedSettleDeps): Promise<void>;
|
|
83
|
+
export interface SupersedeUnreviewedSettleDeps {
|
|
84
|
+
/**
|
|
85
|
+
* Resolve every open escalation of a kind for a focus, stamping the note.
|
|
86
|
+
* Idempotent: resolves 0 when none are open. Defaults to
|
|
87
|
+
* resolveOpenFocusEscalationsOfKind.
|
|
88
|
+
*/
|
|
89
|
+
resolveStaleAnnouncement: (focusId: string, escalationKind: string, notes: string) => Promise<number>;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Retract/supersede a stale unreviewed-settle announcement once a verdict lands.
|
|
93
|
+
*
|
|
94
|
+
* Even with the liveness gate, an announcement can legitimately fire (a review
|
|
95
|
+
* that appeared dead without a verdict) and THEN a verdict lands -- e.g. the
|
|
96
|
+
* review-exit stamp or the edge review_complete promotes reviewed_through_sha
|
|
97
|
+
* afterward. Left alone, the record would keep telling a human the OPPOSITE of
|
|
98
|
+
* what happened ("no verdict was ever rendered"). This resolves any open
|
|
99
|
+
* review_window_stalled escalation for the focus with a superseding note, so the
|
|
100
|
+
* record reflects that a verdict did land.
|
|
101
|
+
*
|
|
102
|
+
* Self-gating: a no-op unless a window was opened (reviewRequestedAt set) AND a
|
|
103
|
+
* verdict has landed (reviewedThroughSha non-null). Idempotent and best-effort;
|
|
104
|
+
* a resolve failure is logged, never thrown. Runs in the same winding_down
|
|
105
|
+
* cascade branch as the announcer, so it reads state the caller already loaded.
|
|
106
|
+
*/
|
|
107
|
+
export declare function supersedeStaleUnreviewedSettleForFocus(ctx: FocusStallContext, reviewRequestedAt: string | null, reviewedThroughSha: string | null, deps?: SupersedeUnreviewedSettleDeps): Promise<void>;
|
|
108
|
+
//# sourceMappingURL=unreviewed-settle-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unreviewed-settle-detector.d.ts","sourceRoot":"","sources":["../../src/verify/unreviewed-settle-detector.ts"],"names":[],"mappings":"AAoCA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAEL,KAAK,8BAA8B,EACnC,KAAK,8BAA8B,EACpC,MAAM,sCAAsC,CAAC;AAK9C,OAAO,EAAE,KAAK,mBAAmB,EAAsB,MAAM,yBAAyB,CAAC;AAEvF,OAAO,EAA8B,KAAK,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAI1F;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,mEAAmE;IACnE,KAAK,EAAE,mBAAmB,CAAC;IAC3B,2CAA2C;IAC3C,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,6EAA6E;IAC7E,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,gFAAgF;IAChF,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAO1E;AAED,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,cAAc,EAAE,CAAC,MAAM,EAAE,8BAA8B,KAAK,OAAO,CAAC,8BAA8B,CAAC,CAAC;IACpG;;;OAGG;IACH,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C;;;;;;;OAOG;IACH,qBAAqB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;CACtD;AAsED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,6BAA6B,CACjD,GAAG,EAAE,iBAAiB,EACtB,MAAM,EAAE,sBAAsB,GAAG;IAAE,UAAU,EAAE,iBAAiB,EAAE,CAAA;CAAE,EACpE,IAAI,GAAE,oBAAkD,GACvD,OAAO,CAAC,IAAI,CAAC,CAqDf;AAED,MAAM,WAAW,6BAA6B;IAC5C;;;;OAIG;IACH,wBAAwB,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACvG;AAOD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,sCAAsC,CAC1D,GAAG,EAAE,iBAAiB,EACtB,iBAAiB,EAAE,MAAM,GAAG,IAAI,EAChC,kBAAkB,EAAE,MAAM,GAAG,IAAI,EACjC,IAAI,GAAE,6BAAoD,GACzD,OAAO,CAAC,IAAI,CAAC,CAwBf"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
// PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
|
|
2
|
+
// Pinned by: packages/daemon/src/integration/unreviewed-settle-live-review-repro.test.ts,
|
|
3
|
+
// packages/daemon/src/verify/unreviewed-settle-detector.test.ts
|
|
4
|
+
// PINNED-BY-END
|
|
5
|
+
/**
|
|
6
|
+
* Unreviewed-settle detector.
|
|
7
|
+
*
|
|
8
|
+
* The residual path of the "verification outruns the review window" defect: a
|
|
9
|
+
* review-enabled focus whose LAST delivery leaves verify before any review
|
|
10
|
+
* renders a verdict settles with review_requested_at set and
|
|
11
|
+
* reviewed_through_sha null. clearStaleReviewRequest (completion/state-cascade.ts)
|
|
12
|
+
* DELIBERATELY keeps that null-watermark window OPEN -- surfacing the missing
|
|
13
|
+
* verdict rather than silently clearing it -- but migration 20260830204654
|
|
14
|
+
* deferred the focus-team arm clear to a trigger that fires only on the window
|
|
15
|
+
* closing (review_requested_at NOT NULL -> NULL). A window that never closes
|
|
16
|
+
* therefore holds the arm forever, an operator view reads "running", and a
|
|
17
|
+
* paid-for review verdict is discarded. And because a settled focus derives
|
|
18
|
+
* winding_down (verify === 0), the reviewing-gated staleness detector in
|
|
19
|
+
* stall-detectors.ts can never reach it.
|
|
20
|
+
*
|
|
21
|
+
* This detector supplies the annunciator that hold always lacked and releases
|
|
22
|
+
* the arm the deferred trigger can no longer reach, WITHOUT closing the window
|
|
23
|
+
* (keeping the hold honest -- announce it, release the arm, do not revert to the
|
|
24
|
+
* census-keyed clear delivery 2 of this focus removed). It rides the same
|
|
25
|
+
* per-focus cascade seam as the sibling stall detectors (runCascadeChecks),
|
|
26
|
+
* operating on state the caller already loaded, and files at most one open
|
|
27
|
+
* escalation per focus (the idempotent cause-keyed gate survives a restart).
|
|
28
|
+
* Pure over injected deps so the cases unit-test without Supabase/MCP.
|
|
29
|
+
*/
|
|
30
|
+
import { ESCALATION_REASONS, ESCALATION_DISPOSITIONS, withRetry, } from '@telora/daemon-core';
|
|
31
|
+
import { fileEscalationIdempotent as defaultFileEscalationIdempotent, } from '../queries/escalation-suppression.js';
|
|
32
|
+
import { focusBlockageCauseKey } from '../queries/cause-key.js';
|
|
33
|
+
import { releaseFocusArm } from '../queries/focuses.js';
|
|
34
|
+
import { resolveOpenFocusEscalationsOfKind } from '../queries/escalations.js';
|
|
35
|
+
import { getActiveTeams } from '../focus/focus-team-state.js';
|
|
36
|
+
import { isDeliveryTerminal } from '../focus/focus-phase.js';
|
|
37
|
+
import { createLogger } from '../shell/log.js';
|
|
38
|
+
import { REVIEW_WINDOW_STALLED_KIND } from './stall-detectors.js';
|
|
39
|
+
const log = createLogger({ module: 'unreviewed-settle-detector' });
|
|
40
|
+
/**
|
|
41
|
+
* Pure decision: is this focus a SETTLED focus holding an UNRENDERED review
|
|
42
|
+
* verdict with its arm still stranded?
|
|
43
|
+
*
|
|
44
|
+
* True iff ALL hold:
|
|
45
|
+
* - phase === 'winding_down' -- every executable delivery is terminal and
|
|
46
|
+
* verify === 0 (deriveFocusPhase). This is the settle the reviewing-gated
|
|
47
|
+
* staleness detector can never reach.
|
|
48
|
+
* - review_requested_at is set -- a review window was opened,
|
|
49
|
+
* - reviewed_through_sha === null -- but NO verdict was ever rendered
|
|
50
|
+
* (review-exit stamps the watermark only on a routed completion), and
|
|
51
|
+
* - assigned_agent_role_id !== null -- an arm is still held.
|
|
52
|
+
*
|
|
53
|
+
* The role-still-assigned clause is what makes the whole detector idempotent
|
|
54
|
+
* (once released it is null, so a repeated poll is a no-op) and skips the cases
|
|
55
|
+
* that need no action: an operator-stopped focus (role already null) and a focus
|
|
56
|
+
* that settled with a rendered verdict (which clearStaleReviewRequest disarms via
|
|
57
|
+
* the window close). Exported for direct unit testing.
|
|
58
|
+
*/
|
|
59
|
+
export function isUnreviewedSettle(inputs) {
|
|
60
|
+
return (inputs.phase === 'winding_down' &&
|
|
61
|
+
inputs.reviewRequestedAt !== null &&
|
|
62
|
+
inputs.reviewedThroughSha === null &&
|
|
63
|
+
inputs.assignedAgentRoleId !== null);
|
|
64
|
+
}
|
|
65
|
+
const defaultUnreviewedSettleDeps = {
|
|
66
|
+
fileEscalation: defaultFileEscalationIdempotent,
|
|
67
|
+
releaseArm: releaseFocusArm,
|
|
68
|
+
isReviewSessionActive: (focusId) => getActiveTeams().get(focusId)?.sessionType === 'review',
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* File the ONE idempotent review_window_stalled escalation for an unreviewed
|
|
72
|
+
* settle (cause-keyed, so a repeated poll files no second one). Best-effort: a
|
|
73
|
+
* filing failure is logged and swallowed so the caller still releases the arm.
|
|
74
|
+
* Extracted from checkUnreviewedSettleForFocus to keep it under the
|
|
75
|
+
* function-size limit.
|
|
76
|
+
*/
|
|
77
|
+
async function fileUnreviewedSettleEscalation(ctx, inputs, settled, settledList, deps) {
|
|
78
|
+
const causeKey = focusBlockageCauseKey(REVIEW_WINDOW_STALLED_KIND, ctx.focusId, 'unreviewed_settle');
|
|
79
|
+
try {
|
|
80
|
+
await withRetry(() => deps.fileEscalation({
|
|
81
|
+
causeKey,
|
|
82
|
+
organizationId: ctx.organizationId,
|
|
83
|
+
sessionId: '',
|
|
84
|
+
issueId: null,
|
|
85
|
+
reasonType: ESCALATION_REASONS.ERROR_ENCOUNTERED,
|
|
86
|
+
disposition: ESCALATION_DISPOSITIONS.NEEDS_OPERATOR,
|
|
87
|
+
anchor: { focusId: ctx.focusId },
|
|
88
|
+
escalationKind: REVIEW_WINDOW_STALLED_KIND,
|
|
89
|
+
description: `Focus "${ctx.focusName}" settled with every delivery terminal, but its review ` +
|
|
90
|
+
`window opened and NO verdict was ever rendered (reviewed_through_sha is null). ` +
|
|
91
|
+
`The review either never spawned or exited without stamping a verdict, so the ` +
|
|
92
|
+
`deliveries reached done unjudged and the focus-team arm was stranded.\n\n` +
|
|
93
|
+
`**Focus:** ${ctx.focusName}\n` +
|
|
94
|
+
`**Focus ID:** ${ctx.focusId}\n` +
|
|
95
|
+
`**Settled deliveries:** ${settledList}\n` +
|
|
96
|
+
`**Verdict:** none rendered (reviewed_through_sha null while review_requested_at was set)\n\n` +
|
|
97
|
+
`The daemon has released the stranded arm and kept the review window open to ` +
|
|
98
|
+
`surface this. If these deliveries should have been reviewed, request a fresh ` +
|
|
99
|
+
`review; otherwise this focus completed without a review verdict.`,
|
|
100
|
+
whatWasTried: `A review window was opened (review_requested_at set) but the last delivery left ` +
|
|
101
|
+
`verify before any review rendered a verdict; the settled focus derives ` +
|
|
102
|
+
`winding_down, which the reviewing-gated staleness detector never reaches.`,
|
|
103
|
+
helpNeeded: `Decide whether the settled deliveries need a fresh review pass; the arm has ` +
|
|
104
|
+
`already been released so the focus is no longer falsely "running".`,
|
|
105
|
+
metadata: {
|
|
106
|
+
cause: REVIEW_WINDOW_STALLED_KIND,
|
|
107
|
+
subKind: 'unreviewed_settle',
|
|
108
|
+
settledDeliveryIds: settled.map((d) => d.id),
|
|
109
|
+
reviewRequestedAt: inputs.reviewRequestedAt,
|
|
110
|
+
},
|
|
111
|
+
}), { maxAttempts: 3, label: `escalation-unreviewed-settle-${ctx.focusId}` });
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
log.warn(`[unreviewed-settle] failed to file escalation for focus "${ctx.focusName}":`, err.message);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Check ONE focus's ALREADY-FETCHED settle state for an unreviewed settle and,
|
|
119
|
+
* when found, ANNOUNCE it and RELEASE the stranded arm -- keeping the review
|
|
120
|
+
* window OPEN (the deliberate null-watermark hold that surfaces the missing
|
|
121
|
+
* verdict; clearStaleReviewRequest leaves it set on a null watermark).
|
|
122
|
+
*
|
|
123
|
+
* SILENT while a review session is still live (a verdict may still land) -- see
|
|
124
|
+
* the liveness gate below. On an unreviewed settle with no live review, in order:
|
|
125
|
+
* 1. LOG the settle at the moment it occurs (so it is not readable only from
|
|
126
|
+
* the focus row).
|
|
127
|
+
* 2. File EXACTLY ONE review_window_stalled escalation naming the focus, its
|
|
128
|
+
* settled deliveries, and the verdict that was never rendered. Idempotent
|
|
129
|
+
* by cause key, so a repeated poll files no second one.
|
|
130
|
+
* 3. RELEASE the arm (daemon-owned, window stays open). Done last so a release
|
|
131
|
+
* failure still leaves the escalation filed and retries next poll (the
|
|
132
|
+
* role is still set, so the predicate still holds).
|
|
133
|
+
*
|
|
134
|
+
* Rides the same per-focus cascade seam as the sibling detectors; operates on
|
|
135
|
+
* state the caller (runCascadeChecks) already loaded.
|
|
136
|
+
*/
|
|
137
|
+
export async function checkUnreviewedSettleForFocus(ctx, inputs, deps = defaultUnreviewedSettleDeps) {
|
|
138
|
+
if (!isUnreviewedSettle(inputs))
|
|
139
|
+
return;
|
|
140
|
+
// A live review still OWNS its window. Do NOT announce a missing verdict --
|
|
141
|
+
// nor release the arm -- while a review session for this focus is running:
|
|
142
|
+
// the verdict is being rendered right now (the 2026-09-09 incident fired this
|
|
143
|
+
// ~90s before an approving verdict landed). Reuse the same liveness signal the
|
|
144
|
+
// sibling clearStaleReviewRequest uses. REVERSE-WEDGE SAFE: a review that DIED
|
|
145
|
+
// without a verdict is reaped from activeTeams by the outcome / stalled-team
|
|
146
|
+
// backstops later in this same cascade (checkTeamOutcomeStallForFocus /
|
|
147
|
+
// checkStalledTeamBackstopForFocus), after which this fires on the next tick --
|
|
148
|
+
// so an abandoned review never holds the arm forever.
|
|
149
|
+
if (deps.isReviewSessionActive?.(ctx.focusId)) {
|
|
150
|
+
log.debug(`[unreviewed-settle] Deferring unreviewed-settle on focus "${ctx.focusName}" ` +
|
|
151
|
+
`(${ctx.focusId}): a review session still owns the window; a verdict may still land.`);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
const settled = inputs.deliveries.filter((d) => isDeliveryTerminal(d.executionStatus));
|
|
155
|
+
const settledList = settled.length
|
|
156
|
+
? settled.map((d) => `"${d.name}" (${d.executionStatus})`).join(', ')
|
|
157
|
+
: '(none listed)';
|
|
158
|
+
// (1) Name the unreviewed settle in the log at the moment it occurs.
|
|
159
|
+
log.warn(`[unreviewed-settle] Unreviewed settle on focus "${ctx.focusName}" (${ctx.focusId}): ` +
|
|
160
|
+
`all deliveries terminal with review_requested_at set and reviewed_through_sha null -- ` +
|
|
161
|
+
`a review verdict was never rendered. Announcing and releasing the stranded arm ` +
|
|
162
|
+
`(review window kept open).`);
|
|
163
|
+
// (2) One idempotent review_window_stalled escalation naming the focus, its
|
|
164
|
+
// settled deliveries, and the verdict that was never rendered.
|
|
165
|
+
await fileUnreviewedSettleEscalation(ctx, inputs, settled, settledList, deps);
|
|
166
|
+
// (3) Release the stranded arm -- daemon-owned, review window stays open.
|
|
167
|
+
try {
|
|
168
|
+
await withRetry(() => deps.releaseArm(ctx.focusId), { maxAttempts: 3, label: `release-unreviewed-settle-arm-${ctx.focusId}` });
|
|
169
|
+
log.info(`[unreviewed-settle] Released the stranded arm for focus "${ctx.focusName}" ` +
|
|
170
|
+
`-- the consented go-signal no longer outlives the work (review window left open).`);
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
log.warn(`[unreviewed-settle] failed to release the arm for focus "${ctx.focusName}":`, err.message);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
const defaultSupersedeDeps = {
|
|
177
|
+
resolveStaleAnnouncement: (focusId, kind, notes) => resolveOpenFocusEscalationsOfKind(focusId, kind, notes),
|
|
178
|
+
};
|
|
179
|
+
/**
|
|
180
|
+
* Retract/supersede a stale unreviewed-settle announcement once a verdict lands.
|
|
181
|
+
*
|
|
182
|
+
* Even with the liveness gate, an announcement can legitimately fire (a review
|
|
183
|
+
* that appeared dead without a verdict) and THEN a verdict lands -- e.g. the
|
|
184
|
+
* review-exit stamp or the edge review_complete promotes reviewed_through_sha
|
|
185
|
+
* afterward. Left alone, the record would keep telling a human the OPPOSITE of
|
|
186
|
+
* what happened ("no verdict was ever rendered"). This resolves any open
|
|
187
|
+
* review_window_stalled escalation for the focus with a superseding note, so the
|
|
188
|
+
* record reflects that a verdict did land.
|
|
189
|
+
*
|
|
190
|
+
* Self-gating: a no-op unless a window was opened (reviewRequestedAt set) AND a
|
|
191
|
+
* verdict has landed (reviewedThroughSha non-null). Idempotent and best-effort;
|
|
192
|
+
* a resolve failure is logged, never thrown. Runs in the same winding_down
|
|
193
|
+
* cascade branch as the announcer, so it reads state the caller already loaded.
|
|
194
|
+
*/
|
|
195
|
+
export async function supersedeStaleUnreviewedSettleForFocus(ctx, reviewRequestedAt, reviewedThroughSha, deps = defaultSupersedeDeps) {
|
|
196
|
+
if (!reviewRequestedAt || reviewedThroughSha === null)
|
|
197
|
+
return;
|
|
198
|
+
try {
|
|
199
|
+
const resolved = await deps.resolveStaleAnnouncement(ctx.focusId, REVIEW_WINDOW_STALLED_KIND, `Superseded by the daemon: a review verdict subsequently landed for focus ` +
|
|
200
|
+
`"${ctx.focusName}" (reviewed_through_sha=${reviewedThroughSha}). The earlier ` +
|
|
201
|
+
`unreviewed-settle announcement -- that no verdict was ever rendered -- is no ` +
|
|
202
|
+
`longer true and is retracted.`);
|
|
203
|
+
if (resolved > 0) {
|
|
204
|
+
log.info(`[unreviewed-settle] Superseded ${resolved} stale review_window_stalled ` +
|
|
205
|
+
`announcement(s) for focus "${ctx.focusName}" -- a verdict landed ` +
|
|
206
|
+
`(reviewed_through_sha=${reviewedThroughSha}).`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
catch (err) {
|
|
210
|
+
log.warn(`[unreviewed-settle] failed to supersede a stale announcement for focus "${ctx.focusName}":`, err.message);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=unreviewed-settle-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unreviewed-settle-detector.js","sourceRoot":"","sources":["../../src/verify/unreviewed-settle-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The verify BOUNDARY the daemon resolves before a deterministic run and hands
|
|
3
|
+
* to the command as environment, so the command's targeted-test selector diffs
|
|
4
|
+
* against the delivery's recorded PRE-MERGE BOUNDARY rather than
|
|
5
|
+
* merge-base(HEAD, integration).
|
|
6
|
+
*
|
|
7
|
+
* On a merged-back delivery that merge-base equals HEAD: the changed-file set is
|
|
8
|
+
* empty and the gate passes as a "clean no-op" having run none of the delivery's
|
|
9
|
+
* own tests. Handing the recorded boundary makes the selection see the
|
|
10
|
+
* delivery's real changes. A delivery still on its branch has no recorded
|
|
11
|
+
* boundary, so nothing is handed and the selector's merge-base auto-derivation
|
|
12
|
+
* is used unchanged.
|
|
13
|
+
*
|
|
14
|
+
* Sliced out of verification-engine.ts to keep that file under the daemon
|
|
15
|
+
* 800-line limit; the engine's STRATEGIES dispatch calls resolveVerifyBoundaryEnv
|
|
16
|
+
* before running the deterministic strategy.
|
|
17
|
+
*
|
|
18
|
+
* @module verification-boundary-env
|
|
19
|
+
*/
|
|
20
|
+
import type { PendingVerification } from '../queries/verification.js';
|
|
21
|
+
import type { VerificationDeps } from './verification-deps.js';
|
|
22
|
+
/**
|
|
23
|
+
* Env vars handed to the deterministic verify command:
|
|
24
|
+
*
|
|
25
|
+
* TELORA_VERIFY_BASE_REF the recorded pre-merge boundary ref.
|
|
26
|
+
* TELORA_VERIFY_RECORDED_COMMIT_COUNT the delivery's own recorded commit count,
|
|
27
|
+
* so the selector can FAIL (never no-op)
|
|
28
|
+
* when the diff against the handed base is
|
|
29
|
+
* empty yet the delivery recorded commits.
|
|
30
|
+
*
|
|
31
|
+
* Consumed by scripts/select-targeted-tests.mjs (mirrored there by string, as
|
|
32
|
+
* that script cannot import this TS); pinned together by
|
|
33
|
+
* scripts/verify-gate.test.mjs.
|
|
34
|
+
*/
|
|
35
|
+
export declare const VERIFY_BASE_REF_ENV = "TELORA_VERIFY_BASE_REF";
|
|
36
|
+
export declare const VERIFY_RECORDED_COMMIT_COUNT_ENV = "TELORA_VERIFY_RECORDED_COMMIT_COUNT";
|
|
37
|
+
/**
|
|
38
|
+
* Resolve the verify boundary env for the deterministic command, BEFORE the run.
|
|
39
|
+
* Best-effort: a resolution failure or an unmerged delivery (no recorded
|
|
40
|
+
* boundary) yields {} so the command inherits the process env and the selector's
|
|
41
|
+
* merge-base auto-derivation is used unchanged. Only when a recorded pre-merge
|
|
42
|
+
* boundary exists is a base handed -- alongside the delivery's own recorded
|
|
43
|
+
* commit count, so the selector can distinguish an honest empty diff (no
|
|
44
|
+
* recorded commits) from a laundered no-op (recorded commits, empty diff).
|
|
45
|
+
*
|
|
46
|
+
* The FAST-FORWARD merge-back case (no merge commit) resolves its boundary from
|
|
47
|
+
* the recorded pre-merge ref (deps.resolveRecordedPreMergeRef is the
|
|
48
|
+
* fast-forward-safe source), never from a merge commit's parent.
|
|
49
|
+
*/
|
|
50
|
+
export declare function resolveVerifyBoundaryEnv(deps: VerificationDeps, v: PendingVerification): Promise<Record<string, string>>;
|
|
51
|
+
//# sourceMappingURL=verification-boundary-env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verification-boundary-env.d.ts","sourceRoot":"","sources":["../../src/verify/verification-boundary-env.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAK/D;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mBAAmB,2BAA2B,CAAC;AAC5D,eAAO,MAAM,gCAAgC,wCAAwC,CAAC;AAEtF;;;;;;;;;;;;GAYG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,gBAAgB,EACtB,CAAC,EAAE,mBAAmB,GACrB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAgCjC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
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-boundary-env.test.ts
|
|
3
|
+
// PINNED-BY-END
|
|
4
|
+
import { createLogger } from '../shell/log.js';
|
|
5
|
+
const log = createLogger({ module: 'verification' });
|
|
6
|
+
/**
|
|
7
|
+
* Env vars handed to the deterministic verify command:
|
|
8
|
+
*
|
|
9
|
+
* TELORA_VERIFY_BASE_REF the recorded pre-merge boundary ref.
|
|
10
|
+
* TELORA_VERIFY_RECORDED_COMMIT_COUNT the delivery's own recorded commit count,
|
|
11
|
+
* so the selector can FAIL (never no-op)
|
|
12
|
+
* when the diff against the handed base is
|
|
13
|
+
* empty yet the delivery recorded commits.
|
|
14
|
+
*
|
|
15
|
+
* Consumed by scripts/select-targeted-tests.mjs (mirrored there by string, as
|
|
16
|
+
* that script cannot import this TS); pinned together by
|
|
17
|
+
* scripts/verify-gate.test.mjs.
|
|
18
|
+
*/
|
|
19
|
+
export const VERIFY_BASE_REF_ENV = 'TELORA_VERIFY_BASE_REF';
|
|
20
|
+
export const VERIFY_RECORDED_COMMIT_COUNT_ENV = 'TELORA_VERIFY_RECORDED_COMMIT_COUNT';
|
|
21
|
+
/**
|
|
22
|
+
* Resolve the verify boundary env for the deterministic command, BEFORE the run.
|
|
23
|
+
* Best-effort: a resolution failure or an unmerged delivery (no recorded
|
|
24
|
+
* boundary) yields {} so the command inherits the process env and the selector's
|
|
25
|
+
* merge-base auto-derivation is used unchanged. Only when a recorded pre-merge
|
|
26
|
+
* boundary exists is a base handed -- alongside the delivery's own recorded
|
|
27
|
+
* commit count, so the selector can distinguish an honest empty diff (no
|
|
28
|
+
* recorded commits) from a laundered no-op (recorded commits, empty diff).
|
|
29
|
+
*
|
|
30
|
+
* The FAST-FORWARD merge-back case (no merge commit) resolves its boundary from
|
|
31
|
+
* the recorded pre-merge ref (deps.resolveRecordedPreMergeRef is the
|
|
32
|
+
* fast-forward-safe source), never from a merge commit's parent.
|
|
33
|
+
*/
|
|
34
|
+
export async function resolveVerifyBoundaryEnv(deps, v) {
|
|
35
|
+
let preMergeRef = null;
|
|
36
|
+
if (deps.resolveRecordedPreMergeRef) {
|
|
37
|
+
try {
|
|
38
|
+
preMergeRef = await deps.resolveRecordedPreMergeRef(v);
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
log.debug(`[verification] pre-merge boundary lookup failed for ${v.deliveryId}:`, err.message);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// No recorded boundary (a delivery still on its branch, or a merged-back row
|
|
45
|
+
// whose boundary the resolver suppressed to stay honestly blind): hand nothing,
|
|
46
|
+
// so the selector diffs against merge-base(HEAD, integration) as today.
|
|
47
|
+
if (!preMergeRef)
|
|
48
|
+
return {};
|
|
49
|
+
let recordedCommitCount = 0;
|
|
50
|
+
if (deps.resolveRecordedCommitShas) {
|
|
51
|
+
try {
|
|
52
|
+
recordedCommitCount = (await deps.resolveRecordedCommitShas(v)).length;
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
log.debug(`[verification] recorded commit-set lookup failed for ${v.deliveryId}:`, err.message);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
[VERIFY_BASE_REF_ENV]: preMergeRef,
|
|
60
|
+
[VERIFY_RECORDED_COMMIT_COUNT_ENV]: String(recordedCommitCount),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=verification-boundary-env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verification-boundary-env.js","sourceRoot":"","sources":["../../src/verify/verification-boundary-env.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,0EAA0E;AAC1E,gBAAgB;AAwBhB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,MAAM,GAAG,GAAG,YAAY,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;AAErD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,wBAAwB,CAAC;AAC5D,MAAM,CAAC,MAAM,gCAAgC,GAAG,qCAAqC,CAAC;AAEtF;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,IAAsB,EACtB,CAAsB;IAEtB,IAAI,WAAW,GAAkB,IAAI,CAAC;IACtC,IAAI,IAAI,CAAC,0BAA0B,EAAE,CAAC;QACpC,IAAI,CAAC;YACH,WAAW,GAAG,MAAM,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAC;QACzD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,KAAK,CACP,uDAAuD,CAAC,CAAC,UAAU,GAAG,EACrE,GAAa,CAAC,OAAO,CACvB,CAAC;QACJ,CAAC;IACH,CAAC;IACD,6EAA6E;IAC7E,gFAAgF;IAChF,wEAAwE;IACxE,IAAI,CAAC,WAAW;QAAE,OAAO,EAAE,CAAC;IAE5B,IAAI,mBAAmB,GAAG,CAAC,CAAC;IAC5B,IAAI,IAAI,CAAC,yBAAyB,EAAE,CAAC;QACnC,IAAI,CAAC;YACH,mBAAmB,GAAG,CAAC,MAAM,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QACzE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,KAAK,CACP,wDAAwD,CAAC,CAAC,UAAU,GAAG,EACtE,GAAa,CAAC,OAAO,CACvB,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO;QACL,CAAC,mBAAmB,CAAC,EAAE,WAAW;QAClC,CAAC,gCAAgC,CAAC,EAAE,MAAM,CAAC,mBAAmB,CAAC;KAChE,CAAC;AACJ,CAAC"}
|
|
@@ -30,7 +30,8 @@ import { getCommitsAhead, filterCommitsByDelivery, selectDeliveryCommitsAcrossBa
|
|
|
30
30
|
import { getActiveFocuses } from '../queries/focus-discovery.js';
|
|
31
31
|
import { resolveDefaultVerification as defaultResolveDefaultVerification } from './verification-config.js';
|
|
32
32
|
import { getFocusDeliveries } from '../queries/focuses.js';
|
|
33
|
-
import { deliverVerificationFailureFeedback, routeShortfallOutcome,
|
|
33
|
+
import { deliverVerificationFailureFeedback, routeShortfallOutcome, } from './verification-feedback.js';
|
|
34
|
+
import { requeueEvidenceUnavailableAsRework } from './verification-evidence-unavailable-feedback.js';
|
|
34
35
|
import { buildDefaultAttributeFailures, buildResolveVerificationCwd } from './verification-baseline.js';
|
|
35
36
|
import { resolveAiInspectionInputs as defaultResolveAiInspectionInputs } from './ai-inspection-context.js';
|
|
36
37
|
import { runAiInspection as defaultRunAiInspection } from './ai-inspection-runner.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verification-deps-default.js","sourceRoot":"","sources":["../../src/verify/verification-deps-default.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,0FAA0F;AAC1F,gBAAgB;AAEhB;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,EACL,uBAAuB,EACvB,iCAAiC,EACjC,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,wBAAwB,IAAI,+BAA+B,EAAE,MAAM,yBAAyB,CAAC;AACtG,OAAO,EAAE,cAAc,IAAI,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACvF,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,kCAAkC,EAClC,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEjE,OAAO,EAAE,0BAA0B,IAAI,iCAAiC,EAAE,MAAM,0BAA0B,CAAC;AAC3G,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EACL,kCAAkC,EAClC,qBAAqB,
|
|
1
|
+
{"version":3,"file":"verification-deps-default.js","sourceRoot":"","sources":["../../src/verify/verification-deps-default.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-boundary-env.test.ts
|
|
3
3
|
// PINNED-BY-END
|
|
4
4
|
export {};
|
|
5
5
|
//# sourceMappingURL=verification-deps.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verification-deps.js","sourceRoot":"","sources":["../../src/verify/verification-deps.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,
|
|
1
|
+
{"version":3,"file":"verification-deps.js","sourceRoot":"","sources":["../../src/verify/verification-deps.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,0EAA0E;AAC1E,gBAAgB"}
|
|
@@ -65,6 +65,16 @@ export interface DeterministicLogContext {
|
|
|
65
65
|
/**
|
|
66
66
|
* Run a configured shell command in the focus's worktree (or the product
|
|
67
67
|
* repo path as fallback). Pass = exit 0.
|
|
68
|
+
*
|
|
69
|
+
* `extraEnv` is merged over the inherited process env into the spawned command.
|
|
70
|
+
* It carries the verify BOUNDARY the daemon resolved before the run
|
|
71
|
+
* (TELORA_VERIFY_BASE_REF + TELORA_VERIFY_RECORDED_COMMIT_COUNT): on a
|
|
72
|
+
* merged-back delivery the command's targeted-test selector must diff against
|
|
73
|
+
* the delivery's recorded pre-merge boundary, not merge-base(HEAD, integration)
|
|
74
|
+
* (which equals HEAD once the branch merged back, selecting nothing and passing
|
|
75
|
+
* as a no-op). Empty / undefined => the process env is inherited unchanged (the
|
|
76
|
+
* still-on-branch delivery path, where the selector's merge-base auto-derivation
|
|
77
|
+
* is correct).
|
|
68
78
|
*/
|
|
69
|
-
export declare function runDeterministicStrategy(config: Record<string, unknown> | null, cwd: string, logContext?: DeterministicLogContext): Promise<StrategyResult>;
|
|
79
|
+
export declare function runDeterministicStrategy(config: Record<string, unknown> | null, cwd: string, logContext?: DeterministicLogContext, extraEnv?: Record<string, string>): Promise<StrategyResult>;
|
|
70
80
|
//# sourceMappingURL=verification-deterministic.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verification-deterministic.d.ts","sourceRoot":"","sources":["../../src/verify/verification-deterministic.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAOtE;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,+BAA+B,QAAiB,CAAC;AAE9D,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,mBAAmB,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yFAAyF;IACzF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,sFAAsF;IACtF,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,kFAAkF;IAClF,WAAW,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;
|
|
1
|
+
{"version":3,"file":"verification-deterministic.d.ts","sourceRoot":"","sources":["../../src/verify/verification-deterministic.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAOtE;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,+BAA+B,QAAiB,CAAC;AAE9D,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,mBAAmB,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yFAAyF;IACzF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,sFAAsF;IACtF,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,kFAAkF;IAClF,WAAW,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAiBD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,EACtC,GAAG,EAAE,MAAM,EACX,UAAU,CAAC,EAAE,uBAAuB,EACpC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,OAAO,CAAC,cAAc,CAAC,CA8IzB"}
|
|
@@ -41,11 +41,35 @@ const log = createLogger({ module: 'verification' });
|
|
|
41
41
|
* authoritative.
|
|
42
42
|
*/
|
|
43
43
|
export const DEFAULT_VERIFICATION_TIMEOUT_MS = 30 * 60 * 1000;
|
|
44
|
+
/**
|
|
45
|
+
* Spawn options for the deterministic verify child. Merges the resolved verify
|
|
46
|
+
* boundary env (extraEnv) over the inherited process env; when there is nothing
|
|
47
|
+
* to add, the process env is inherited unchanged (the still-on-branch path,
|
|
48
|
+
* where the selector's merge-base auto-derivation is correct). Extracted so the
|
|
49
|
+
* strategy function stays under the daemon per-function line limit.
|
|
50
|
+
*/
|
|
51
|
+
function verifySpawnOptions(cwd, extraEnv) {
|
|
52
|
+
const opts = { cwd, stdio: ['ignore', 'pipe', 'pipe'] };
|
|
53
|
+
if (extraEnv && Object.keys(extraEnv).length > 0) {
|
|
54
|
+
opts.env = { ...process.env, ...extraEnv };
|
|
55
|
+
}
|
|
56
|
+
return opts;
|
|
57
|
+
}
|
|
44
58
|
/**
|
|
45
59
|
* Run a configured shell command in the focus's worktree (or the product
|
|
46
60
|
* repo path as fallback). Pass = exit 0.
|
|
61
|
+
*
|
|
62
|
+
* `extraEnv` is merged over the inherited process env into the spawned command.
|
|
63
|
+
* It carries the verify BOUNDARY the daemon resolved before the run
|
|
64
|
+
* (TELORA_VERIFY_BASE_REF + TELORA_VERIFY_RECORDED_COMMIT_COUNT): on a
|
|
65
|
+
* merged-back delivery the command's targeted-test selector must diff against
|
|
66
|
+
* the delivery's recorded pre-merge boundary, not merge-base(HEAD, integration)
|
|
67
|
+
* (which equals HEAD once the branch merged back, selecting nothing and passing
|
|
68
|
+
* as a no-op). Empty / undefined => the process env is inherited unchanged (the
|
|
69
|
+
* still-on-branch delivery path, where the selector's merge-base auto-derivation
|
|
70
|
+
* is correct).
|
|
47
71
|
*/
|
|
48
|
-
export async function runDeterministicStrategy(config, cwd, logContext) {
|
|
72
|
+
export async function runDeterministicStrategy(config, cwd, logContext, extraEnv) {
|
|
49
73
|
const command = config?.command;
|
|
50
74
|
if (typeof command !== 'string' || command.length === 0 || !config) {
|
|
51
75
|
return {
|
|
@@ -89,10 +113,7 @@ export async function runDeterministicStrategy(config, cwd, logContext) {
|
|
|
89
113
|
return new Promise((resolve) => {
|
|
90
114
|
let child;
|
|
91
115
|
try {
|
|
92
|
-
child = spawn('sh', ['-c', command],
|
|
93
|
-
cwd,
|
|
94
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
95
|
-
});
|
|
116
|
+
child = spawn('sh', ['-c', command], verifySpawnOptions(cwd, extraEnv));
|
|
96
117
|
}
|
|
97
118
|
catch (err) {
|
|
98
119
|
// Synchronous spawn failure: release the hold and fail the run rather than
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verification-deterministic.js","sourceRoot":"","sources":["../../src/verify/verification-deterministic.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,4EAA4E;AAC5E,0DAA0D;AAC1D,gBAAgB;AAEhB;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"verification-deterministic.js","sourceRoot":"","sources":["../../src/verify/verification-deterministic.ts"],"names":[],"mappings":"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"}
|