@telora/daemon 0.24.58 → 0.24.64
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/ci/ci-run-spans.d.ts +140 -0
- package/dist/ci/ci-run-spans.d.ts.map +1 -0
- package/dist/ci/ci-run-spans.js +147 -0
- package/dist/ci/ci-run-spans.js.map +1 -0
- package/dist/ci/ci-sensor-loop.d.ts +8 -0
- package/dist/ci/ci-sensor-loop.d.ts.map +1 -1
- package/dist/ci/ci-sensor-loop.js +4 -0
- package/dist/ci/ci-sensor-loop.js.map +1 -1
- package/dist/ci/ci-status.d.ts +15 -0
- package/dist/ci/ci-status.d.ts.map +1 -1
- package/dist/ci/ci-status.js +43 -8
- package/dist/ci/ci-status.js.map +1 -1
- package/dist/composition/engine-start-context.d.ts.map +1 -1
- package/dist/composition/engine-start-context.js +8 -1
- package/dist/composition/engine-start-context.js.map +1 -1
- package/dist/composition/execution-ci-context.d.ts +3 -0
- package/dist/composition/execution-ci-context.d.ts.map +1 -1
- package/dist/composition/execution-ci-context.js +37 -1
- package/dist/composition/execution-ci-context.js.map +1 -1
- package/dist/composition/focus-activity-live-sources.d.ts.map +1 -1
- package/dist/composition/focus-activity-live-sources.js +5 -1
- package/dist/composition/focus-activity-live-sources.js.map +1 -1
- package/dist/composition/verification-context.d.ts.map +1 -1
- package/dist/composition/verification-context.js +5 -1
- package/dist/composition/verification-context.js.map +1 -1
- package/dist/delivery/delivery-reconciler-apply.d.ts.map +1 -1
- package/dist/delivery/delivery-reconciler-apply.js +7 -2
- package/dist/delivery/delivery-reconciler-apply.js.map +1 -1
- package/dist/delivery/delivery-reconciler.d.ts +8 -0
- package/dist/delivery/delivery-reconciler.d.ts.map +1 -1
- package/dist/delivery/delivery-reconciler.js +7 -5
- package/dist/delivery/delivery-reconciler.js.map +1 -1
- package/dist/focus/daemon-contexts.d.ts +6 -0
- package/dist/focus/daemon-contexts.d.ts.map +1 -1
- package/dist/focus/daemon-contexts.js.map +1 -1
- package/dist/focus/focus-activity-poll-facts.d.ts +13 -0
- package/dist/focus/focus-activity-poll-facts.d.ts.map +1 -1
- package/dist/focus/focus-activity-poll-facts.js +6 -0
- package/dist/focus/focus-activity-poll-facts.js.map +1 -1
- package/dist/focus/focus-activity-producers.d.ts +38 -1
- package/dist/focus/focus-activity-producers.d.ts.map +1 -1
- package/dist/focus/focus-activity-producers.js +52 -4
- package/dist/focus/focus-activity-producers.js.map +1 -1
- package/dist/focus/focus-activity-record.d.ts +2 -2
- package/dist/focus/focus-activity-record.d.ts.map +1 -1
- package/dist/focus/focus-activity-record.js +4 -3
- package/dist/focus/focus-activity-record.js.map +1 -1
- package/dist/focus/focus-activity-sources.d.ts +8 -0
- package/dist/focus/focus-activity-sources.d.ts.map +1 -1
- package/dist/focus/focus-activity-sources.js.map +1 -1
- package/dist/focus/focus-engine.d.ts.map +1 -1
- package/dist/focus/focus-engine.js +3 -1
- package/dist/focus/focus-engine.js.map +1 -1
- package/dist/merge/candidate-rework.d.ts +2 -0
- package/dist/merge/candidate-rework.d.ts.map +1 -1
- package/dist/merge/candidate-rework.js +2 -0
- package/dist/merge/candidate-rework.js.map +1 -1
- package/dist/queries/api-client/shared.d.ts +1 -0
- package/dist/queries/api-client/shared.d.ts.map +1 -1
- package/dist/queries/api-client/shared.js +30 -2
- package/dist/queries/api-client/shared.js.map +1 -1
- package/dist/queries/deliveries/deliveries.d.ts +14 -4
- package/dist/queries/deliveries/deliveries.d.ts.map +1 -1
- package/dist/queries/deliveries/deliveries.js +12 -6
- package/dist/queries/deliveries/deliveries.js.map +1 -1
- package/dist/queries/deliveries/delivery-transition-cause.d.ts +39 -0
- package/dist/queries/deliveries/delivery-transition-cause.d.ts.map +1 -0
- package/dist/queries/deliveries/delivery-transition-cause.js +41 -0
- package/dist/queries/deliveries/delivery-transition-cause.js.map +1 -0
- package/dist/queries/phase-spans/phase-spans.d.ts +59 -0
- package/dist/queries/phase-spans/phase-spans.d.ts.map +1 -0
- package/dist/queries/phase-spans/phase-spans.js +90 -0
- package/dist/queries/phase-spans/phase-spans.js.map +1 -0
- package/dist/queries/verification/verification.js +1 -1
- package/dist/testing/fixtures/api-client.js +1 -1
- package/dist/testing/fixtures/recording-api-client.js +1 -1
- package/dist/testing/fixtures/verification-deps.d.ts +7 -0
- package/dist/testing/fixtures/verification-deps.d.ts.map +1 -1
- package/dist/testing/fixtures/verification-deps.js +12 -1
- package/dist/testing/fixtures/verification-deps.js.map +1 -1
- package/dist/tower/tower-admission.d.ts +3 -1
- package/dist/tower/tower-admission.d.ts.map +1 -1
- package/dist/tower/tower-admission.js +3 -1
- package/dist/tower/tower-admission.js.map +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/issue-status.d.ts.map +1 -1
- package/dist/types/issue-status.js +1 -0
- package/dist/types/issue-status.js.map +1 -1
- package/dist/verify/deterministic-gate/verification-deterministic.js +1 -1
- package/dist/verify/engine/verification-commit-sharing.d.ts +18 -3
- package/dist/verify/engine/verification-commit-sharing.d.ts.map +1 -1
- package/dist/verify/engine/verification-commit-sharing.js +73 -13
- package/dist/verify/engine/verification-commit-sharing.js.map +1 -1
- package/dist/verify/engine/verification-deps.d.ts +11 -0
- package/dist/verify/engine/verification-deps.d.ts.map +1 -1
- package/dist/verify/engine/verification-deps.js +1 -1
- package/dist/verify/engine/verification-engine.js +1 -1
- package/dist/verify/engine/verification-engine.js.map +1 -1
- package/dist/verify/gate-verdicts/gate-phase-span.d.ts +137 -0
- package/dist/verify/gate-verdicts/gate-phase-span.d.ts.map +1 -0
- package/dist/verify/gate-verdicts/gate-phase-span.js +190 -0
- package/dist/verify/gate-verdicts/gate-phase-span.js.map +1 -0
- package/dist/verify/outcome-routing/falsified-effect-reopen.d.ts.map +1 -1
- package/dist/verify/outcome-routing/falsified-effect-reopen.js +6 -1
- package/dist/verify/outcome-routing/falsified-effect-reopen.js.map +1 -1
- package/dist/verify/outcome-routing/gate-rework-reopen.d.ts +2 -0
- package/dist/verify/outcome-routing/gate-rework-reopen.d.ts.map +1 -1
- package/dist/verify/outcome-routing/gate-rework-reopen.js +5 -2
- package/dist/verify/outcome-routing/gate-rework-reopen.js.map +1 -1
- package/docs/runbook-tower.md +6 -6
- package/package.json +3 -3
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every deterministic gate run this daemon performs is recorded as ONE timed
|
|
3
|
+
* execution-phase span (phase 'gate'; supabase migration
|
|
4
|
+
* 20261029133000_execution_phase_spans.sql), so the database holds when each run
|
|
5
|
+
* started, when it ended and what it rendered -- facts the per-commit verdict
|
|
6
|
+
* files under the state dir (verify/gate-verdicts/commit-verdict-record.ts) keep
|
|
7
|
+
* only on this host, and only for runs that rendered a verdict.
|
|
8
|
+
*
|
|
9
|
+
* WHAT IS SPANNED. A local gate run: judgeDelivery's run of a deterministic
|
|
10
|
+
* candidate (verify/engine/verification-commit-sharing.ts) -- from the moment the
|
|
11
|
+
* run path is entered, before the rework re-check or the checkout, until its
|
|
12
|
+
* verdict is attributed and recorded. A delivery that takes a verdict already
|
|
13
|
+
* recorded for its commit runs no gate and opens no span; a gate CI runs is
|
|
14
|
+
* recorded by the CI sensor as a 'ci' span, not here.
|
|
15
|
+
*
|
|
16
|
+
* THE GUARANTEE: NO CONFIRMED ROW, NO RUN. `run` -- the gate command and
|
|
17
|
+
* everything judging it -- is called only after the database open has answered
|
|
18
|
+
* the span's id, i.e. the row (organization, product, focus, the commit the
|
|
19
|
+
* dispatch read as the one it would judge, phase 'gate', started_at, this host)
|
|
20
|
+
* EXISTS. Every path that reaches `run` has that row. When the open fails, throws,
|
|
21
|
+
* answers no id, or does not answer within {@link GATE_SPAN_OPEN_WAIT_MS}, the
|
|
22
|
+
* attempt is DEFERRED, not failed: `run` is not called, so no command runs, no
|
|
23
|
+
* verdict and no no-verdict record is written, no re-work is routed and no rework
|
|
24
|
+
* re-check, failed-HEAD re-run or explicit run is spent. spanGateRun answers
|
|
25
|
+
* `{ ran: false }` with the reason, logged at warn; judgeDelivery turns it into a
|
|
26
|
+
* result that routes nothing (rationale "gate span not recorded: ..."), and the
|
|
27
|
+
* dispatch drops its selection exactly as it does for a status it could not
|
|
28
|
+
* re-read, so the next verification tick tries again. An open that answers an id
|
|
29
|
+
* AFTER the bound opened a row no command ran under: it is closed at once,
|
|
30
|
+
* 'not_a_verdict' with metadata.reason 'deferred_unconfirmed_open'. The open rides
|
|
31
|
+
* the control-plane breaker the verification writes ride
|
|
32
|
+
* (queries/api-client/shared.ts), so a tripped measurement breaker cannot defer
|
|
33
|
+
* every gate while the control plane is healthy. A gate run takes minutes and the
|
|
34
|
+
* open is one insert, so the bound is spent only on a hung write; a refused or
|
|
35
|
+
* throwing open answers at once.
|
|
36
|
+
*
|
|
37
|
+
* A gate judges a focus HEAD, not one delivery, so delivery_id is set only for a
|
|
38
|
+
* run with no focus; the delivery whose dispatch ran it is in metadata. A
|
|
39
|
+
* candidate with no product has nothing to key a span by, so it is deferred too.
|
|
40
|
+
*
|
|
41
|
+
* CLOSE, on EVERY exit of a run: the outcome is 'passed' or 'failed' for a
|
|
42
|
+
* verdict, and 'not_a_verdict' for every run the verdict record refuses to write
|
|
43
|
+
* (commit-verdict-record.ts buildCommitVerdict) -- metadata.reason names which:
|
|
44
|
+
* checkout_unavailable (no checkout, an unprovisioned worktree, installs that
|
|
45
|
+
* moved mid-run), config_unresolved, timed_out, killed / unreadable_red (a red
|
|
46
|
+
* with no code evidence), instrument_fault (attribution could not attribute it),
|
|
47
|
+
* no_verdict (a pending or escalated result), or threw. The close carries the
|
|
48
|
+
* commit the run actually judged (its checkout's sha) when it names one. It is
|
|
49
|
+
* not awaited, so the gate's result or throw is handed back unchanged, at the
|
|
50
|
+
* moment the run rendered it; a close that fails is logged and leaves the row
|
|
51
|
+
* open for the next start (below).
|
|
52
|
+
*
|
|
53
|
+
* A DAEMON START closes, as 'abandoned', every gate span THIS host still has open
|
|
54
|
+
* from before that start ({@link abandonCrashedGateSpans}, called from
|
|
55
|
+
* FocusEngine.start through composition/engine-start-context.ts): its previous
|
|
56
|
+
* process died mid-run, or a close did not land. A row the new process opens
|
|
57
|
+
* meanwhile is never touched.
|
|
58
|
+
*
|
|
59
|
+
* Known edge: an open whose response is lost after the row was inserted reads as
|
|
60
|
+
* "not opened"; the attempt is deferred and that row stays open until a start
|
|
61
|
+
* closes it 'abandoned'.
|
|
62
|
+
*
|
|
63
|
+
* @module verify/gate-verdicts/gate-phase-span
|
|
64
|
+
*/
|
|
65
|
+
import type { PendingVerification } from '../../queries/verification/verification.js';
|
|
66
|
+
import type { AbandonOpenPhaseSpansRequest, ClosePhaseSpanRequest, OpenPhaseSpanRequest } from '../../queries/phase-spans/phase-spans.js';
|
|
67
|
+
import type { StrategyResult } from '../deterministic-gate/verification-deterministic.js';
|
|
68
|
+
/** The span writes and the facts a span is stamped with. Production binds queries/phase-spans and this host. */
|
|
69
|
+
export interface GatePhaseSpanDeps {
|
|
70
|
+
/** Open a span; the id, or null when it could not be recorded. */
|
|
71
|
+
open: (request: OpenPhaseSpanRequest) => Promise<string | null>;
|
|
72
|
+
/** Close an open span. */
|
|
73
|
+
close: (request: ClosePhaseSpanRequest) => Promise<boolean>;
|
|
74
|
+
/** This daemon's host (the identity daemon_connections and agent sessions carry). */
|
|
75
|
+
host: () => string;
|
|
76
|
+
now: () => Date;
|
|
77
|
+
/** How long a run waits for its database open (default {@link GATE_SPAN_OPEN_WAIT_MS}); tests shorten it. */
|
|
78
|
+
openWaitMs?: number;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* The most a gate attempt waits for its span's database open before it is
|
|
82
|
+
* deferred. A normal insert answers in well under a second; a gate run takes
|
|
83
|
+
* minutes, so 10s is a small fraction of even a fast green run, and it is spent
|
|
84
|
+
* only on an open that is hung.
|
|
85
|
+
*/
|
|
86
|
+
export declare const GATE_SPAN_OPEN_WAIT_MS = 10000;
|
|
87
|
+
/** Why a run rendered no verdict, or why a row closed with no run under it (metadata.reason of a not_a_verdict span). */
|
|
88
|
+
export type GateNoVerdictReason = 'checkout_unavailable' | 'config_unresolved' | 'timed_out' | 'killed' | 'unreadable_red' | 'instrument_fault' | 'no_verdict' | 'threw' | 'deferred_unconfirmed_open';
|
|
89
|
+
/** How a gate run's span closes. */
|
|
90
|
+
export type GateSpanClose = {
|
|
91
|
+
outcome: 'passed' | 'failed';
|
|
92
|
+
} | {
|
|
93
|
+
outcome: 'not_a_verdict';
|
|
94
|
+
reason: GateNoVerdictReason;
|
|
95
|
+
};
|
|
96
|
+
/** What judging a run produced, as the span reads it. */
|
|
97
|
+
export interface JudgedGateRun {
|
|
98
|
+
result: StrategyResult;
|
|
99
|
+
/** Non-null when attribution routed the run to instrument-fault re-work. */
|
|
100
|
+
evidenceUnavailableHold: unknown;
|
|
101
|
+
}
|
|
102
|
+
/** A gate attempt inside its span: the run's own result, or why it was deferred without running (module header). */
|
|
103
|
+
export type SpannedGateRun<T> = {
|
|
104
|
+
ran: true;
|
|
105
|
+
judged: T;
|
|
106
|
+
} | {
|
|
107
|
+
ran: false;
|
|
108
|
+
deferredBecause: string;
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* The span close a judged run renders: the same verdict / no-verdict rule the
|
|
112
|
+
* per-commit verdict record applies (commit-verdict-record.ts buildCommitVerdict),
|
|
113
|
+
* with the reason named. Pure.
|
|
114
|
+
*/
|
|
115
|
+
export declare function gateSpanCloseOf(result: StrategyResult, instrumentFault: boolean): GateSpanClose;
|
|
116
|
+
/**
|
|
117
|
+
* Run a local gate attempt inside its span (module header): open the row and wait
|
|
118
|
+
* for it (bounded); with no confirmed row, defer -- `run` is never called; with
|
|
119
|
+
* one, call `run`, close the row on its result or its throw, and hand back
|
|
120
|
+
* exactly what `run` returned or threw. `onSettled`, for tests, sees the close
|
|
121
|
+
* write's promise (a deferral's: the close of a row its late open inserts) once it
|
|
122
|
+
* is started.
|
|
123
|
+
*/
|
|
124
|
+
export declare function spanGateRun<T extends JudgedGateRun>(deps: GatePhaseSpanDeps, v: PendingVerification, judgedHead: string | null, run: () => Promise<T>, onSettled?: (written: Promise<void>) => void): Promise<SpannedGateRun<T>>;
|
|
125
|
+
/** The start-time recovery's write and this host. */
|
|
126
|
+
export interface AbandonGateSpansDeps {
|
|
127
|
+
abandon: (request: AbandonOpenPhaseSpansRequest) => Promise<number>;
|
|
128
|
+
host: () => string;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* At daemon start: close, as 'abandoned', every gate span THIS host left open
|
|
132
|
+
* (its previous process died mid-run, or a close did not land) that was opened
|
|
133
|
+
* before `startedBefore`. Best-effort: answers how many closed, 0 when the write
|
|
134
|
+
* failed; never throws, so a boot is never held by it.
|
|
135
|
+
*/
|
|
136
|
+
export declare function abandonCrashedGateSpans(deps: AbandonGateSpansDeps, startedBefore: Date): Promise<number>;
|
|
137
|
+
//# sourceMappingURL=gate-phase-span.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-phase-span.d.ts","sourceRoot":"","sources":["../../../src/verify/gate-verdicts/gate-phase-span.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+DG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAC;AACtF,OAAO,KAAK,EACV,4BAA4B,EAC5B,qBAAqB,EACrB,oBAAoB,EAErB,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qDAAqD,CAAC;AAK1F,gHAAgH;AAChH,MAAM,WAAW,iBAAiB;IAChC,kEAAkE;IAClE,IAAI,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAChE,0BAA0B;IAC1B,KAAK,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5D,qFAAqF;IACrF,IAAI,EAAE,MAAM,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,IAAI,CAAC;IAChB,6GAA6G;IAC7G,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,QAAS,CAAC;AAE7C,yHAAyH;AACzH,MAAM,MAAM,mBAAmB,GAC3B,sBAAsB,GACtB,mBAAmB,GACnB,WAAW,GACX,QAAQ,GACR,gBAAgB,GAChB,kBAAkB,GAClB,YAAY,GACZ,OAAO,GACP,2BAA2B,CAAC;AAEhC,oCAAoC;AACpC,MAAM,MAAM,aAAa,GACrB;IAAE,OAAO,EAAE,QAAQ,GAAG,QAAQ,CAAA;CAAE,GAChC;IAAE,OAAO,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAA;CAAE,CAAC;AAE9D,yDAAyD;AACzD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,cAAc,CAAC;IACvB,4EAA4E;IAC5E,uBAAuB,EAAE,OAAO,CAAC;CAClC;AAED,oHAAoH;AACpH,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAAE,GAAG,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,CAAC,CAAA;CAAE,GAAG;IAAE,GAAG,EAAE,KAAK,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,CAAC;AAKnG;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,EAAE,eAAe,EAAE,OAAO,GAAG,aAAa,CAU/F;AAkHD;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAAC,CAAC,SAAS,aAAa,EACvD,IAAI,EAAE,iBAAiB,EACvB,CAAC,EAAE,mBAAmB,EACtB,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACrB,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,GAC3C,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAoB5B;AAED,qDAAqD;AACrD,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,CAAC,OAAO,EAAE,4BAA4B,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACpE,IAAI,EAAE,MAAM,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,oBAAoB,EAAE,aAAa,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAS9G"}
|
|
@@ -0,0 +1,190 @@
|
|
|
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/engine/judge-delivery-gate-span.test.ts,
|
|
3
|
+
// packages/daemon/src/verify/gate-verdicts/gate-phase-span.test.ts
|
|
4
|
+
// PINNED-BY-END
|
|
5
|
+
import { createLogger } from '../../log/daemon-log.js';
|
|
6
|
+
const log = createLogger({ module: 'verification' });
|
|
7
|
+
/**
|
|
8
|
+
* The most a gate attempt waits for its span's database open before it is
|
|
9
|
+
* deferred. A normal insert answers in well under a second; a gate run takes
|
|
10
|
+
* minutes, so 10s is a small fraction of even a fast green run, and it is spent
|
|
11
|
+
* only on an open that is hung.
|
|
12
|
+
*/
|
|
13
|
+
export const GATE_SPAN_OPEN_WAIT_MS = 10_000;
|
|
14
|
+
const SHA_RE = /^[0-9a-f]{7,64}$/i;
|
|
15
|
+
const MAX_RATIONALE_CHARS = 500;
|
|
16
|
+
/**
|
|
17
|
+
* The span close a judged run renders: the same verdict / no-verdict rule the
|
|
18
|
+
* per-commit verdict record applies (commit-verdict-record.ts buildCommitVerdict),
|
|
19
|
+
* with the reason named. Pure.
|
|
20
|
+
*/
|
|
21
|
+
export function gateSpanCloseOf(result, instrumentFault) {
|
|
22
|
+
if (result.checkoutUnavailable)
|
|
23
|
+
return { outcome: 'not_a_verdict', reason: 'checkout_unavailable' };
|
|
24
|
+
if (result.configUnresolved)
|
|
25
|
+
return { outcome: 'not_a_verdict', reason: 'config_unresolved' };
|
|
26
|
+
if (result.timedOut)
|
|
27
|
+
return { outcome: 'not_a_verdict', reason: 'timed_out' };
|
|
28
|
+
if (result.noCodeEvidence) {
|
|
29
|
+
return { outcome: 'not_a_verdict', reason: result.noCodeEvidence.reason === 'killed' ? 'killed' : 'unreadable_red' };
|
|
30
|
+
}
|
|
31
|
+
if (instrumentFault)
|
|
32
|
+
return { outcome: 'not_a_verdict', reason: 'instrument_fault' };
|
|
33
|
+
if (result.outcome === 'passed' || result.outcome === 'failed')
|
|
34
|
+
return { outcome: result.outcome };
|
|
35
|
+
return { outcome: 'not_a_verdict', reason: 'no_verdict' };
|
|
36
|
+
}
|
|
37
|
+
function openRequestOf(v, productId, judgedHead, deps) {
|
|
38
|
+
return {
|
|
39
|
+
productId,
|
|
40
|
+
focusId: v.focusId,
|
|
41
|
+
deliveryId: v.focusId === null ? v.deliveryId : null,
|
|
42
|
+
phase: 'gate',
|
|
43
|
+
commitSha: judgedHead !== null && SHA_RE.test(judgedHead) ? judgedHead : null,
|
|
44
|
+
recordedByHost: deps.host(),
|
|
45
|
+
startedAt: deps.now().toISOString(),
|
|
46
|
+
metadata: { judgedDeliveryId: v.deliveryId, verificationMethod: v.verificationMethod },
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function closeMetadataOf(close, result, err) {
|
|
50
|
+
const metadata = {};
|
|
51
|
+
if (close.outcome === 'not_a_verdict')
|
|
52
|
+
metadata.reason = close.reason;
|
|
53
|
+
if (result && typeof result.exitCode === 'number')
|
|
54
|
+
metadata.exitCode = result.exitCode;
|
|
55
|
+
const why = err !== undefined ? (err instanceof Error ? err.message : String(err)) : close.outcome === 'not_a_verdict' ? result?.rationale : undefined;
|
|
56
|
+
if (why)
|
|
57
|
+
metadata.rationale = why.slice(0, MAX_RATIONALE_CHARS);
|
|
58
|
+
return metadata;
|
|
59
|
+
}
|
|
60
|
+
const message = (err) => (err instanceof Error ? err.message : String(err));
|
|
61
|
+
/**
|
|
62
|
+
* Send an open and answer its id without ever rejecting: a write that fails or
|
|
63
|
+
* throws (even synchronously) is logged and answers null.
|
|
64
|
+
*/
|
|
65
|
+
function openSpan(deps, v, request) {
|
|
66
|
+
const notOpened = (err) => {
|
|
67
|
+
log.warn(`[verification] gate span for delivery ${v.deliveryId} not opened: ${message(err)}`);
|
|
68
|
+
return null;
|
|
69
|
+
};
|
|
70
|
+
try {
|
|
71
|
+
return deps.open(request).catch(notOpened);
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
return Promise.resolve(notOpened(err));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const BOUND_PASSED = Symbol('gate-span-open-bound-passed');
|
|
78
|
+
/** Wait for the database open, at most `waitMs`: its answer, or BOUND_PASSED. Never rejects. */
|
|
79
|
+
async function awaitOpenBounded(opened, waitMs) {
|
|
80
|
+
let timer;
|
|
81
|
+
const boundPassed = new Promise((resolve) => { timer = setTimeout(() => resolve(BOUND_PASSED), waitMs); });
|
|
82
|
+
try {
|
|
83
|
+
return await Promise.race([opened, boundPassed]);
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
clearTimeout(timer);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/** Close a span; never rejects (a failure is logged and leaves the row for the next start's abandon). */
|
|
90
|
+
async function closeSpan(deps, v, request) {
|
|
91
|
+
try {
|
|
92
|
+
await deps.close(request);
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
log.warn(`[verification] gate span ${request.spanId} for delivery ${v.deliveryId} not closed: ${message(err)}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Defer the attempt (module header): log it at warn, and close -- as
|
|
100
|
+
* not_a_verdict / deferred_unconfirmed_open -- a row the open still in flight
|
|
101
|
+
* inserts later, since no command runs under it. `opened` is null when no open
|
|
102
|
+
* was sent. Answers the deferral and the late close write.
|
|
103
|
+
*/
|
|
104
|
+
function deferAttempt(deps, v, judgedHead, opened, reason) {
|
|
105
|
+
log.warn(`[verification] gate span not recorded -- the gate is NOT run for delivery ${v.deliveryId} `
|
|
106
|
+
+ `(product ${v.productId ?? 'none'}, focus ${v.focusId ?? 'none'}, commit ${judgedHead?.slice(0, 12) ?? 'unread'}): `
|
|
107
|
+
+ `${reason}; no verdict is recorded and the next tick tries again`);
|
|
108
|
+
const written = (opened ?? Promise.resolve(null)).then(async (late) => {
|
|
109
|
+
if (late === null)
|
|
110
|
+
return;
|
|
111
|
+
log.warn(`[verification] gate span ${late} for delivery ${v.deliveryId} opened after its gate was deferred; closing it (no command ran under it)`);
|
|
112
|
+
await closeSpan(deps, v, {
|
|
113
|
+
spanId: late, outcome: 'not_a_verdict', endedAt: deps.now().toISOString(), metadata: { reason: 'deferred_unconfirmed_open' },
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
return { deferral: { ran: false, deferredBecause: reason }, written };
|
|
117
|
+
}
|
|
118
|
+
/** Open the span and wait for its row, bounded: the confirmed id, or the deferral (module header). */
|
|
119
|
+
async function openConfirmed(deps, v, judgedHead) {
|
|
120
|
+
if (!v.productId)
|
|
121
|
+
return deferAttempt(deps, v, judgedHead, null, 'the candidate names no product to key its span by');
|
|
122
|
+
const opened = openSpan(deps, v, openRequestOf(v, v.productId, judgedHead, deps));
|
|
123
|
+
const waitMs = deps.openWaitMs ?? GATE_SPAN_OPEN_WAIT_MS;
|
|
124
|
+
const answered = await awaitOpenBounded(opened, waitMs);
|
|
125
|
+
if (answered === BOUND_PASSED)
|
|
126
|
+
return deferAttempt(deps, v, judgedHead, opened, `the span open was not confirmed within ${waitMs}ms`);
|
|
127
|
+
if (answered === null)
|
|
128
|
+
return deferAttempt(deps, v, judgedHead, null, 'the span open failed (no row was confirmed)');
|
|
129
|
+
return { spanId: answered };
|
|
130
|
+
}
|
|
131
|
+
/** The close request a run renders. */
|
|
132
|
+
function closeOf(spanId, close, result, err, endedAt) {
|
|
133
|
+
const sha = result?.verifiedSha;
|
|
134
|
+
return {
|
|
135
|
+
spanId,
|
|
136
|
+
outcome: close.outcome,
|
|
137
|
+
endedAt,
|
|
138
|
+
...(typeof sha === 'string' && SHA_RE.test(sha) ? { commitSha: sha } : {}),
|
|
139
|
+
metadata: closeMetadataOf(close, result, err),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Run a local gate attempt inside its span (module header): open the row and wait
|
|
144
|
+
* for it (bounded); with no confirmed row, defer -- `run` is never called; with
|
|
145
|
+
* one, call `run`, close the row on its result or its throw, and hand back
|
|
146
|
+
* exactly what `run` returned or threw. `onSettled`, for tests, sees the close
|
|
147
|
+
* write's promise (a deferral's: the close of a row its late open inserts) once it
|
|
148
|
+
* is started.
|
|
149
|
+
*/
|
|
150
|
+
export async function spanGateRun(deps, v, judgedHead, run, onSettled) {
|
|
151
|
+
const confirmed = await openConfirmed(deps, v, judgedHead);
|
|
152
|
+
if (!('spanId' in confirmed)) {
|
|
153
|
+
onSettled?.(confirmed.written);
|
|
154
|
+
return confirmed.deferral;
|
|
155
|
+
}
|
|
156
|
+
const finish = (close, result, err) => {
|
|
157
|
+
// Sent before onSettled is consulted: `onSettled?.(write())` would skip the write when no caller observes it.
|
|
158
|
+
const written = closeSpan(deps, v, closeOf(confirmed.spanId, close, result, err, deps.now().toISOString()));
|
|
159
|
+
onSettled?.(written);
|
|
160
|
+
};
|
|
161
|
+
let judged;
|
|
162
|
+
try {
|
|
163
|
+
judged = await run();
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
finish({ outcome: 'not_a_verdict', reason: 'threw' }, null, err);
|
|
167
|
+
throw err;
|
|
168
|
+
}
|
|
169
|
+
finish(gateSpanCloseOf(judged.result, judged.evidenceUnavailableHold !== null), judged.result);
|
|
170
|
+
return { ran: true, judged };
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* At daemon start: close, as 'abandoned', every gate span THIS host left open
|
|
174
|
+
* (its previous process died mid-run, or a close did not land) that was opened
|
|
175
|
+
* before `startedBefore`. Best-effort: answers how many closed, 0 when the write
|
|
176
|
+
* failed; never throws, so a boot is never held by it.
|
|
177
|
+
*/
|
|
178
|
+
export async function abandonCrashedGateSpans(deps, startedBefore) {
|
|
179
|
+
try {
|
|
180
|
+
const closed = await deps.abandon({ recordedByHost: deps.host(), phase: 'gate', startedBefore: startedBefore.toISOString() });
|
|
181
|
+
if (closed > 0)
|
|
182
|
+
log.info(`[verification] closed ${closed} gate span(s) a previous daemon on this host left open, as abandoned`);
|
|
183
|
+
return closed;
|
|
184
|
+
}
|
|
185
|
+
catch (err) {
|
|
186
|
+
log.warn(`[verification] abandoned gate spans not closed at start: ${message(err)}`);
|
|
187
|
+
return 0;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=gate-phase-span.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-phase-span.js","sourceRoot":"","sources":["../../../src/verify/gate-verdicts/gate-phase-span.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"falsified-effect-reopen.d.ts","sourceRoot":"","sources":["../../../src/verify/outcome-routing/falsified-effect-reopen.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,sDAAsD,CAAC;AAE3G,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAIrE,uDAAuD;AACvD,MAAM,WAAW,yBAAyB;IACxC,qEAAqE;IACrE,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,8BAA8B,CAAC,CAAC,CAAC;IAC9F,cAAc,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACxF,2GAA2G;IAC3G,oBAAoB,EAAE,qBAAqB,CAAC;CAC7C;AAED;;;GAGG;AACH,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,yBAAyB,GAC9B,OAAO,CAAC,MAAM,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"falsified-effect-reopen.d.ts","sourceRoot":"","sources":["../../../src/verify/outcome-routing/falsified-effect-reopen.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,sDAAsD,CAAC;AAE3G,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAIrE,uDAAuD;AACvD,MAAM,WAAW,yBAAyB;IACxC,qEAAqE;IACrE,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,8BAA8B,CAAC,CAAC,CAAC;IAC9F,cAAc,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACxF,2GAA2G;IAC3G,oBAAoB,EAAE,qBAAqB,CAAC;CAC7C;AAED;;;GAGG;AACH,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,yBAAyB,GAC9B,OAAO,CAAC,MAAM,EAAE,CAAC,CAyCnB"}
|
|
@@ -63,7 +63,12 @@ export async function reopenFalsifiedDoneDeliveries(config, deps) {
|
|
|
63
63
|
continue;
|
|
64
64
|
try {
|
|
65
65
|
const stageId = await deps.resolveStageId(c.deliveryId, decision.target);
|
|
66
|
-
await deps.updateDeliveryStatus(c.deliveryId, decision.target, stageId, undefined, undefined, {
|
|
66
|
+
await deps.updateDeliveryStatus(c.deliveryId, decision.target, stageId, undefined, undefined, {
|
|
67
|
+
organizationId: config.organizationId,
|
|
68
|
+
fromStatus: c.executionStatus,
|
|
69
|
+
// falsified_effect: the reconciler's named re-open, recorded on the move.
|
|
70
|
+
...(decision.result.cause ? { cause: decision.result.cause } : {}),
|
|
71
|
+
});
|
|
67
72
|
reopened.push(c.deliveryId);
|
|
68
73
|
log.info(`[verification] falsified-effect reopen: re-opened done delivery "${c.deliveryName}" (${c.deliveryId}) to ${decision.target} -- an open Bug falsifies a met effect`);
|
|
69
74
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"falsified-effect-reopen.js","sourceRoot":"","sources":["../../../src/verify/outcome-routing/falsified-effect-reopen.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,wFAAwF;AACxF,gBAAgB;AAEhB;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,eAAe,EAAwB,MAAM,qBAAqB,CAAC;AAE5E,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AAErF,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAGvD,MAAM,GAAG,GAAG,YAAY,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;AAWrD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,MAAoB,EACpB,IAA+B;IAE/B,IAAI,CAAC,MAAM,CAAC,SAAS;QAAE,OAAO,EAAE,CAAC;IACjC,IAAI,UAAyD,CAAC;IAC9D,IAAI,CAAC;QACH,UAAU,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC3D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,IAAI,CAAC,qFAAqF,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7G,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,eAAe,KAAK,eAAe,CAAC,IAAI;YAAE,SAAS;QACzD,MAAM,QAAQ,GAAG,sBAAsB,CAAC;YACtC,KAAK,EAAE;gBACL,aAAa,EAAE,CAAC,CAAC,eAAkC;gBACnD,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;gBACzE,QAAQ,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE;gBACrC,YAAY,EAAE,IAAI;gBAClB,WAAW,EAAE,IAAI;gBACjB,sBAAsB,EAAE,IAAI;aAC7B;SACF,CAAC,CAAC;QACH,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,eAAe;YAAE,SAAS;QACpD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;YACzE,MAAM,IAAI,CAAC,oBAAoB,CAC7B,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAC5D,EAAE,cAAc,EAAE,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"falsified-effect-reopen.js","sourceRoot":"","sources":["../../../src/verify/outcome-routing/falsified-effect-reopen.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,wFAAwF;AACxF,gBAAgB;AAEhB;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,eAAe,EAAwB,MAAM,qBAAqB,CAAC;AAE5E,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AAErF,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAGvD,MAAM,GAAG,GAAG,YAAY,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;AAWrD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,MAAoB,EACpB,IAA+B;IAE/B,IAAI,CAAC,MAAM,CAAC,SAAS;QAAE,OAAO,EAAE,CAAC;IACjC,IAAI,UAAyD,CAAC;IAC9D,IAAI,CAAC;QACH,UAAU,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC3D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,IAAI,CAAC,qFAAqF,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7G,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,eAAe,KAAK,eAAe,CAAC,IAAI;YAAE,SAAS;QACzD,MAAM,QAAQ,GAAG,sBAAsB,CAAC;YACtC,KAAK,EAAE;gBACL,aAAa,EAAE,CAAC,CAAC,eAAkC;gBACnD,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;gBACzE,QAAQ,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE;gBACrC,YAAY,EAAE,IAAI;gBAClB,WAAW,EAAE,IAAI;gBACjB,sBAAsB,EAAE,IAAI;aAC7B;SACF,CAAC,CAAC;QACH,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,eAAe;YAAE,SAAS;QACpD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;YACzE,MAAM,IAAI,CAAC,oBAAoB,CAC7B,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAC5D;gBACE,cAAc,EAAE,MAAM,CAAC,cAAc;gBACrC,UAAU,EAAE,CAAC,CAAC,eAAe;gBAC7B,0EAA0E;gBAC1E,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACnE,CACF,CAAC;YACF,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;YAC5B,GAAG,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAC,YAAY,MAAM,CAAC,CAAC,UAAU,QAAQ,QAAQ,CAAC,MAAM,wCAAwC,CAAC,CAAC;QAChL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,IAAI,CAAC,4DAA4D,CAAC,CAAC,UAAU,wBAAwB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC1H,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import type { DeliveryTransitionCause } from '../../queries/deliveries/delivery-transition-cause.js';
|
|
1
2
|
/** The status write the re-open runs through: (id, status, stageId, gateState, completionArtifacts, transition). */
|
|
2
3
|
export type GateReworkStatusWrite = (deliveryId: string, executionStatus: string, currentWorkflowStageId?: string | null, gateState?: undefined, completionArtifacts?: undefined, transition?: {
|
|
3
4
|
organizationId: string;
|
|
4
5
|
fromStatus: string;
|
|
6
|
+
cause?: DeliveryTransitionCause;
|
|
5
7
|
}) => Promise<void>;
|
|
6
8
|
/** The re-open's collaborators, every one required. */
|
|
7
9
|
export interface GateReworkReopenDeps {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate-rework-reopen.d.ts","sourceRoot":"","sources":["../../../src/verify/outcome-routing/gate-rework-reopen.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"gate-rework-reopen.d.ts","sourceRoot":"","sources":["../../../src/verify/outcome-routing/gate-rework-reopen.ts"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uDAAuD,CAAC;AAIrG,oHAAoH;AACpH,MAAM,MAAM,qBAAqB,GAAG,CAClC,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,EACvB,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,EACtC,SAAS,CAAC,EAAE,SAAS,EACrB,mBAAmB,CAAC,EAAE,SAAS,EAC/B,UAAU,CAAC,EAAE;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,uBAAuB,CAAA;CAAE,KACzF,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,uDAAuD;AACvD,MAAM,WAAW,oBAAoB;IACnC,iBAAiB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IACxH,cAAc,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACxF,2GAA2G;IAC3G,oBAAoB,EAAE,qBAAqB,CAAC;IAC5C,oGAAoG;IACpG,cAAc,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;CACrC;AAED,4BAA4B;AAC5B,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG,UAAU,GAAG,OAAO,CAAC;AAEnE;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EACzD,IAAI,EAAE,oBAAoB,GACzB,OAAO,CAAC,gBAAgB,CAAC,CAyB3B"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
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/red-head-integration-merge-rework-regression.test.ts
|
|
2
|
+
// Pinned by: packages/daemon/src/integration/red-head-integration-merge-rework-regression.test.ts,
|
|
3
|
+
// packages/daemon/src/verify/outcome-routing/gate-rework-reopen.test.ts
|
|
3
4
|
// PINNED-BY-END
|
|
4
5
|
import { resolveReconciledWrite } from '../../delivery/delivery-reconciler-apply.js';
|
|
5
6
|
import { isGateReworkIssue } from '../../types/issue-status.js';
|
|
@@ -30,7 +31,9 @@ export async function reopenForGateRework(delivery, deps) {
|
|
|
30
31
|
return 'stays';
|
|
31
32
|
const stageId = await deps.resolveStageId(delivery.id, decision.target);
|
|
32
33
|
const organizationId = deps.organizationId();
|
|
33
|
-
await deps.updateDeliveryStatus(delivery.id, decision.target, stageId, undefined, undefined, ...(organizationId
|
|
34
|
+
await deps.updateDeliveryStatus(delivery.id, decision.target, stageId, undefined, undefined, ...(organizationId
|
|
35
|
+
? [{ organizationId, fromStatus: from, ...(decision.result.cause ? { cause: decision.result.cause } : {}) }]
|
|
36
|
+
: []));
|
|
34
37
|
log.info(`[verification] rework issue: re-opened ${from} delivery ${delivery.id} to ${decision.target} -- it carries the red gate's rework Bug`);
|
|
35
38
|
return 'reopened';
|
|
36
39
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate-rework-reopen.js","sourceRoot":"","sources":["../../../src/verify/outcome-routing/gate-rework-reopen.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,
|
|
1
|
+
{"version":3,"file":"gate-rework-reopen.js","sourceRoot":"","sources":["../../../src/verify/outcome-routing/gate-rework-reopen.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,mGAAmG;AACnG,0EAA0E;AAC1E,gBAAgB;AA2BhB,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AACrF,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAGvD,MAAM,GAAG,GAAG,YAAY,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;AAyBrD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,QAAyD,EACzD,IAA0B;IAE1B,MAAM,IAAI,GAAG,QAAQ,CAAC,eAAe,IAAI,EAAE,CAAC;IAC5C,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC;QAAE,OAAO,YAAY,CAAC;IACjD,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IACrF,MAAM,QAAQ,GAAG,sBAAsB,CAAC;QACtC,KAAK,EAAE;YACL,aAAa,EAAE,IAAuB;YACtC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;YACzE,QAAQ,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE;YACrC,YAAY,EAAE,IAAI;YAClB,WAAW,EAAE,IAAI;YACjB,cAAc,EAAE,IAAI;SACrB;KACF,CAAC,CAAC;IACH,IAAI,QAAQ,CAAC,MAAM,KAAK,IAAI;QAAE,OAAO,OAAO,CAAC;IAC7C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACxE,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;IAC7C,MAAM,IAAI,CAAC,oBAAoB,CAC7B,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAC3D,GAAG,CAAC,cAAc;QAChB,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAU;QACrH,CAAC,CAAC,EAAE,CAAC,CACR,CAAC;IACF,GAAG,CAAC,IAAI,CAAC,0CAA0C,IAAI,aAAa,QAAQ,CAAC,EAAE,OAAO,QAAQ,CAAC,MAAM,0CAA0C,CAAC,CAAC;IACjJ,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
package/docs/runbook-tower.md
CHANGED
|
@@ -38,9 +38,9 @@ The reasons, and what the dashboard says for each:
|
|
|
38
38
|
|
|
39
39
|
| Reason | Dashboard | Means |
|
|
40
40
|
|---|---|---|
|
|
41
|
-
| `product_limit_reached` | Held by tower: product limit reached (N of L running) | The product's free slots went to foci ahead of this one. |
|
|
42
|
-
| `waits_on` | Held by tower: waits on <focus> | A `depends_on` predecessor has not landed (tower graph). |
|
|
43
|
-
| `excluded_by` | Held by tower: excluded by <focus> on <evidence> | An `excludes` edge joins it to a focus that is running or cleared ahead of it (tower graph). |
|
|
41
|
+
| `product_limit_reached` | Held by the tower: product limit reached (N of L running) | The product's free slots went to foci ahead of this one. |
|
|
42
|
+
| `waits_on` | Held by the tower: waits on <focus> | A `depends_on` predecessor has not landed (tower graph). |
|
|
43
|
+
| `excluded_by` | Held by the tower: excluded by <focus> on <evidence> | An `excludes` edge joins it to a focus that is running or cleared ahead of it (tower graph). |
|
|
44
44
|
|
|
45
45
|
## The graph
|
|
46
46
|
|
|
@@ -266,13 +266,13 @@ spawn, so it must never be able to cause that silently.
|
|
|
266
266
|
|
|
267
267
|
## Reading a stuck focus
|
|
268
268
|
|
|
269
|
-
- **"Held by tower: product limit reached"** -- look at which foci are running
|
|
269
|
+
- **"Held by the tower: product limit reached"** -- look at which foci are running
|
|
270
270
|
(they hold the slots) and their rank; raise the limit or re-rank if the
|
|
271
271
|
order is wrong.
|
|
272
|
-
- **"Held by tower: waits on <focus>"** -- the predecessor has not landed: it
|
|
272
|
+
- **"Held by the tower: waits on <focus>"** -- the predecessor has not landed: it
|
|
273
273
|
still has open deliveries, or its branch is not yet merged into integration.
|
|
274
274
|
If the dependency is wrong, delete the edge (`edge_delete`).
|
|
275
|
-
- **"Held by tower: excluded by <focus> on <evidence>"** -- the other focus is
|
|
275
|
+
- **"Held by the tower: excluded by <focus> on <evidence>"** -- the other focus is
|
|
276
276
|
running (or was cleared ahead of this one); this one clears when it stops.
|
|
277
277
|
- **"Tower verdict unavailable"** -- the focus will spawn anyway. Check the
|
|
278
278
|
daemon log for `[tower] pass failed for product ...`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@telora/daemon",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.64",
|
|
4
4
|
"description": "Agent orchestration daemon for Telora - spawns and manages Claude Code instances",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
},
|
|
41
41
|
"//testRunner": "Uses Node.js built-in test runner (node:test) via tsx for TypeScript support. The root package uses Vitest; this is a deliberate choice for the daemon package to avoid framework dependencies. Test files live beside the modules they exercise (owner-directory layout); the runner discovers them recursively.",
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@telora/daemon-core": "^0.3.
|
|
44
|
-
"@telora/mcp-products": "^0.23.
|
|
43
|
+
"@telora/daemon-core": "^0.3.4",
|
|
44
|
+
"@telora/mcp-products": "^0.23.22",
|
|
45
45
|
"commander": "^14.0.3",
|
|
46
46
|
"yaml": "^2.4.0",
|
|
47
47
|
"zod": "^4.3.6"
|