@telora/daemon 0.17.64 → 0.17.70
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 +7 -3
- package/dist/completion/review-exit-phase.d.ts.map +1 -1
- package/dist/completion/review-exit-phase.js +31 -5
- package/dist/completion/review-exit-phase.js.map +1 -1
- package/dist/completion/status-advance-phase.d.ts.map +1 -1
- package/dist/completion/status-advance-phase.js +46 -13
- package/dist/completion/status-advance-phase.js.map +1 -1
- package/dist/delivery-lifecycle.d.ts.map +1 -1
- package/dist/delivery-lifecycle.js +40 -0
- package/dist/delivery-lifecycle.js.map +1 -1
- package/dist/delivery-reconciler-apply.d.ts +85 -0
- package/dist/delivery-reconciler-apply.d.ts.map +1 -0
- package/dist/delivery-reconciler-apply.js +80 -0
- package/dist/delivery-reconciler-apply.js.map +1 -0
- package/dist/delivery-reconciler-shadow.d.ts +65 -0
- package/dist/delivery-reconciler-shadow.d.ts.map +1 -0
- package/dist/delivery-reconciler-shadow.js +127 -0
- package/dist/delivery-reconciler-shadow.js.map +1 -0
- package/dist/delivery-reconciler.d.ts +133 -0
- package/dist/delivery-reconciler.d.ts.map +1 -0
- package/dist/delivery-reconciler.js +160 -0
- package/dist/delivery-reconciler.js.map +1 -0
- package/dist/listener-auto-advance.d.ts.map +1 -1
- package/dist/listener-auto-advance.js +65 -31
- package/dist/listener-auto-advance.js.map +1 -1
- package/dist/listener.d.ts.map +1 -1
- package/dist/listener.js +6 -0
- package/dist/listener.js.map +1 -1
- package/dist/nexus-return.d.ts +52 -0
- package/dist/nexus-return.d.ts.map +1 -1
- package/dist/nexus-return.js +135 -2
- package/dist/nexus-return.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shadow harness for the single-writer delivery reconciler.
|
|
3
|
+
*
|
|
4
|
+
* Delivery 3 (single-writer reconciler, shadow mode) of the Delivery Execution
|
|
5
|
+
* Pathway Consolidation focus (reality-tree injection #10). De-risking method:
|
|
6
|
+
* characterize -> SHADOW -> flip one transition at a time. This is the shadow
|
|
7
|
+
* step.
|
|
8
|
+
*
|
|
9
|
+
* On each poll, for every active focus's deliveries, this gathers the live
|
|
10
|
+
* signal (issue rollup, worktree-committed flag), runs the PURE
|
|
11
|
+
* reconcileDeliveryStatus(), compares its computed target to the delivery's
|
|
12
|
+
* LIVE execution_status, and LOGS every divergence. It makes ZERO writes to
|
|
13
|
+
* execution_status -- there is no status writer in its dependency surface by
|
|
14
|
+
* construction. When divergence holds steady at zero, the reconciler is safe to
|
|
15
|
+
* flip into the write path one transition at a time (Delivery 4).
|
|
16
|
+
*
|
|
17
|
+
* Default-OFF: unlike the focus/verification loops (opt-OUT via shouldRunLoop),
|
|
18
|
+
* the shadow is opt-IN. It runs only when TELORA_RECONCILER_SHADOW is a truthy
|
|
19
|
+
* value ('1'/'true'/etc); unset / '' / '0' keep it a no-op, so wiring it into
|
|
20
|
+
* the live poll changes nothing until an operator deliberately enables it.
|
|
21
|
+
*
|
|
22
|
+
* Poll-time signal note: at poll time there is no exiting review session, so the
|
|
23
|
+
* harness supplies a conservative review state (a verify delivery with no open
|
|
24
|
+
* work stays in verify -- matching what the live poll does; verify->done is
|
|
25
|
+
* driven by the review-exit path, not the poll). The transitions the shadow
|
|
26
|
+
* meaningfully exercises at poll time are the issue-rollup-driven ones
|
|
27
|
+
* (queued/coding/verify_failed) and verify->verify_failed on open work.
|
|
28
|
+
*/
|
|
29
|
+
import type { DaemonConfig } from './types.js';
|
|
30
|
+
import { getActiveFocuses, getDeliveryIssues } from './supabase.js';
|
|
31
|
+
import { getFocusDeliveries } from './queries/focuses.js';
|
|
32
|
+
import { getFocusWorktree } from './focus-worktree-state.js';
|
|
33
|
+
import { worktreeHasUncommittedChanges } from './worktree-safety.js';
|
|
34
|
+
/** Opt-in flag name. Default-OFF (only a truthy value enables the shadow). */
|
|
35
|
+
export declare const RECONCILER_SHADOW_ENV = "TELORA_RECONCILER_SHADOW";
|
|
36
|
+
/** Default-off opt-in: only '1'/'true'/'yes'/'on' (case-insensitive) enable. */
|
|
37
|
+
export declare function reconcilerShadowEnabled(env?: NodeJS.ProcessEnv): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Injectable collaborators. The surface is READ-ONLY by design: there is NO
|
|
40
|
+
* status-writer dependency, which is the structural guarantee that the shadow
|
|
41
|
+
* cannot mutate execution_status.
|
|
42
|
+
*/
|
|
43
|
+
export interface ReconcilerShadowDeps {
|
|
44
|
+
isEnabled: () => boolean;
|
|
45
|
+
getActiveFocuses: typeof getActiveFocuses;
|
|
46
|
+
getFocusDeliveries: typeof getFocusDeliveries;
|
|
47
|
+
getDeliveryIssues: typeof getDeliveryIssues;
|
|
48
|
+
getFocusWorktree: typeof getFocusWorktree;
|
|
49
|
+
worktreeHasUncommittedChanges: typeof worktreeHasUncommittedChanges;
|
|
50
|
+
/** Divergence sink. Defaults to console.log; injected in tests for capture. */
|
|
51
|
+
log: (message: string) => void;
|
|
52
|
+
}
|
|
53
|
+
export interface ReconcilerShadowSummary {
|
|
54
|
+
/** Whether the shadow actually ran (false when the flag is off). */
|
|
55
|
+
ran: boolean;
|
|
56
|
+
/** Number of deliveries whose live status was compared. */
|
|
57
|
+
checked: number;
|
|
58
|
+
/** Number where the reconciled target differed from the live status. */
|
|
59
|
+
divergences: number;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Run one shadow pass for a (product-scoped) config. Reads only; never writes.
|
|
63
|
+
*/
|
|
64
|
+
export declare function runReconcilerShadow(config: DaemonConfig, deps?: ReconcilerShadowDeps): Promise<ReconcilerShadowSummary>;
|
|
65
|
+
//# sourceMappingURL=delivery-reconciler-shadow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delivery-reconciler-shadow.d.ts","sourceRoot":"","sources":["../src/delivery-reconciler-shadow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,6BAA6B,EAAE,MAAM,sBAAsB,CAAC;AAKrE,8EAA8E;AAC9E,eAAO,MAAM,qBAAqB,6BAA6B,CAAC;AAEhE,gFAAgF;AAChF,wBAAgB,uBAAuB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAIrF;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,gBAAgB,CAAC;IAC1C,kBAAkB,EAAE,OAAO,kBAAkB,CAAC;IAC9C,iBAAiB,EAAE,OAAO,iBAAiB,CAAC;IAC5C,gBAAgB,EAAE,OAAO,gBAAgB,CAAC;IAC1C,6BAA6B,EAAE,OAAO,6BAA6B,CAAC;IACpE,+EAA+E;IAC/E,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAYD,MAAM,WAAW,uBAAuB;IACtC,oEAAoE;IACpE,GAAG,EAAE,OAAO,CAAC;IACb,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,YAAY,EACpB,IAAI,GAAE,oBAAkC,GACvC,OAAO,CAAC,uBAAuB,CAAC,CA4ElC"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shadow harness for the single-writer delivery reconciler.
|
|
3
|
+
*
|
|
4
|
+
* Delivery 3 (single-writer reconciler, shadow mode) of the Delivery Execution
|
|
5
|
+
* Pathway Consolidation focus (reality-tree injection #10). De-risking method:
|
|
6
|
+
* characterize -> SHADOW -> flip one transition at a time. This is the shadow
|
|
7
|
+
* step.
|
|
8
|
+
*
|
|
9
|
+
* On each poll, for every active focus's deliveries, this gathers the live
|
|
10
|
+
* signal (issue rollup, worktree-committed flag), runs the PURE
|
|
11
|
+
* reconcileDeliveryStatus(), compares its computed target to the delivery's
|
|
12
|
+
* LIVE execution_status, and LOGS every divergence. It makes ZERO writes to
|
|
13
|
+
* execution_status -- there is no status writer in its dependency surface by
|
|
14
|
+
* construction. When divergence holds steady at zero, the reconciler is safe to
|
|
15
|
+
* flip into the write path one transition at a time (Delivery 4).
|
|
16
|
+
*
|
|
17
|
+
* Default-OFF: unlike the focus/verification loops (opt-OUT via shouldRunLoop),
|
|
18
|
+
* the shadow is opt-IN. It runs only when TELORA_RECONCILER_SHADOW is a truthy
|
|
19
|
+
* value ('1'/'true'/etc); unset / '' / '0' keep it a no-op, so wiring it into
|
|
20
|
+
* the live poll changes nothing until an operator deliberately enables it.
|
|
21
|
+
*
|
|
22
|
+
* Poll-time signal note: at poll time there is no exiting review session, so the
|
|
23
|
+
* harness supplies a conservative review state (a verify delivery with no open
|
|
24
|
+
* work stays in verify -- matching what the live poll does; verify->done is
|
|
25
|
+
* driven by the review-exit path, not the poll). The transitions the shadow
|
|
26
|
+
* meaningfully exercises at poll time are the issue-rollup-driven ones
|
|
27
|
+
* (queued/coding/verify_failed) and verify->verify_failed on open work.
|
|
28
|
+
*/
|
|
29
|
+
import { getActiveFocuses, getDeliveryIssues } from './supabase.js';
|
|
30
|
+
import { getFocusDeliveries } from './queries/focuses.js';
|
|
31
|
+
import { getFocusWorktree } from './focus-worktree-state.js';
|
|
32
|
+
import { worktreeHasUncommittedChanges } from './worktree-safety.js';
|
|
33
|
+
import { reconcileDeliveryStatus } from './delivery-reconciler.js';
|
|
34
|
+
import { isExecutionStatus } from '@telora/daemon-core';
|
|
35
|
+
/** Opt-in flag name. Default-OFF (only a truthy value enables the shadow). */
|
|
36
|
+
export const RECONCILER_SHADOW_ENV = 'TELORA_RECONCILER_SHADOW';
|
|
37
|
+
/** Default-off opt-in: only '1'/'true'/'yes'/'on' (case-insensitive) enable. */
|
|
38
|
+
export function reconcilerShadowEnabled(env = process.env) {
|
|
39
|
+
const raw = env[RECONCILER_SHADOW_ENV];
|
|
40
|
+
if (raw === undefined)
|
|
41
|
+
return false;
|
|
42
|
+
return ['1', 'true', 'yes', 'on'].includes(raw.trim().toLowerCase());
|
|
43
|
+
}
|
|
44
|
+
const defaultDeps = {
|
|
45
|
+
isEnabled: () => reconcilerShadowEnabled(),
|
|
46
|
+
getActiveFocuses,
|
|
47
|
+
getFocusDeliveries,
|
|
48
|
+
getDeliveryIssues,
|
|
49
|
+
getFocusWorktree,
|
|
50
|
+
worktreeHasUncommittedChanges,
|
|
51
|
+
log: (m) => console.log(m),
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Run one shadow pass for a (product-scoped) config. Reads only; never writes.
|
|
55
|
+
*/
|
|
56
|
+
export async function runReconcilerShadow(config, deps = defaultDeps) {
|
|
57
|
+
if (!deps.isEnabled()) {
|
|
58
|
+
return { ran: false, checked: 0, divergences: 0 };
|
|
59
|
+
}
|
|
60
|
+
let checked = 0;
|
|
61
|
+
let divergences = 0;
|
|
62
|
+
let focuses;
|
|
63
|
+
try {
|
|
64
|
+
focuses = await deps.getActiveFocuses(config.organizationId, config.productId);
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
deps.log(`[reconciler-shadow] failed to fetch active focuses: ${err.message}`);
|
|
68
|
+
return { ran: true, checked, divergences };
|
|
69
|
+
}
|
|
70
|
+
for (const focus of focuses) {
|
|
71
|
+
const reviewRequested = !!focus.review_requested_at;
|
|
72
|
+
let deliveries;
|
|
73
|
+
try {
|
|
74
|
+
deliveries = await deps.getFocusDeliveries(focus.focus_id);
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
deps.log(`[reconciler-shadow] failed to fetch deliveries for focus ${focus.focus_id}: ${err.message}`);
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
// Resolve the worktree-committed signal once per focus (one worktree per focus).
|
|
81
|
+
const worktree = deps.getFocusWorktree(focus.focus_id);
|
|
82
|
+
let worktreeCommitted = true; // no worktree => nothing uncommitted can block (matches the advance precheck)
|
|
83
|
+
if (worktree) {
|
|
84
|
+
try {
|
|
85
|
+
worktreeCommitted = !deps.worktreeHasUncommittedChanges(worktree.worktreePath);
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// Best-effort: a git failure should not break the shadow; assume committed.
|
|
89
|
+
worktreeCommitted = true;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
for (const delivery of deliveries) {
|
|
93
|
+
const liveStatus = delivery.executionStatus ?? '';
|
|
94
|
+
if (!isExecutionStatus(liveStatus))
|
|
95
|
+
continue;
|
|
96
|
+
let issues;
|
|
97
|
+
try {
|
|
98
|
+
issues = await deps.getDeliveryIssues(delivery.id);
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
deps.log(`[reconciler-shadow] failed to fetch issues for delivery ${delivery.id}: ${err.message}`);
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
const result = reconcileDeliveryStatus({
|
|
105
|
+
currentStatus: liveStatus,
|
|
106
|
+
issues: issues.map(i => ({ status: i.status, issueType: i.issueType })),
|
|
107
|
+
gitState: { worktreeCommitted },
|
|
108
|
+
guardVerdict: null,
|
|
109
|
+
// Poll-time review state: conservative. verify with no open work stays
|
|
110
|
+
// verify (verify->done is review-exit-driven, not poll-driven).
|
|
111
|
+
reviewState: { reviewRequested, reportExists: false, sessionType: 'coding', succeeded: false },
|
|
112
|
+
});
|
|
113
|
+
checked++;
|
|
114
|
+
if (result.changed) {
|
|
115
|
+
divergences++;
|
|
116
|
+
deps.log(`[reconciler-shadow] DIVERGENCE delivery=${delivery.id} ("${delivery.name}") ` +
|
|
117
|
+
`live=${liveStatus} reconciled=${result.target} ` +
|
|
118
|
+
`canonical=${result.canonical} reason="${result.reason}" (no write performed)`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (checked > 0) {
|
|
123
|
+
deps.log(`[reconciler-shadow] pass complete: ${checked} deliveries checked, ${divergences} divergence(s), 0 writes`);
|
|
124
|
+
}
|
|
125
|
+
return { ran: true, checked, divergences };
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=delivery-reconciler-shadow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delivery-reconciler-shadow.js","sourceRoot":"","sources":["../src/delivery-reconciler-shadow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single-writer delivery reconciler (PURE).
|
|
3
|
+
*
|
|
4
|
+
* Delivery 3 of the Delivery Execution Pathway Consolidation focus
|
|
5
|
+
* (reality-tree injection #10: "Delivery execution_status has exactly one
|
|
6
|
+
* writer -- the daemon reconciler; every transition flows through it").
|
|
7
|
+
*
|
|
8
|
+
* This module is the consolidation's center of gravity: ONE pure function that
|
|
9
|
+
* computes the single next execution_status the daemon should write, plus ONE
|
|
10
|
+
* shared "issues are done" predicate that replaces the divergent copies spread
|
|
11
|
+
* across the live writers (advanceDeliveryStage / advanceDeliveryStatuses /
|
|
12
|
+
* runReviewExitHandler / checkDeliveryAutoAdvance / checkVerifyDeliveriesForOpenIssues).
|
|
13
|
+
*
|
|
14
|
+
* It is deliberately PURE -- no I/O, no supabase, no git. Callers gather the
|
|
15
|
+
* signal (issues, worktree-committed flag, guard verdict, review state) and
|
|
16
|
+
* pass it in; the reconciler only computes. This is what makes it
|
|
17
|
+
* shadow-testable: run it alongside the live path, compare its target to the
|
|
18
|
+
* live status, log divergence, write nothing (see delivery-reconciler-shadow.ts).
|
|
19
|
+
*
|
|
20
|
+
* The behavior here MIRRORS the CURRENT live writers as pinned by the
|
|
21
|
+
* Delivery 2 characterization suite
|
|
22
|
+
* (__tests__/delivery-state-machine-characterization.test.ts). It characterizes
|
|
23
|
+
* what the system does today, not an idealized target -- the shadow phase exists
|
|
24
|
+
* precisely to prove parity before any cutover.
|
|
25
|
+
*
|
|
26
|
+
* The coding -> queued re-queue edge (open work at team exit -> re-queue) is
|
|
27
|
+
* present in EXECUTION_STATUS_TRANSITIONS as of the D5 cleanup. `result.canonical`
|
|
28
|
+
* flags transitions NOT in the canonical map; the coding -> queued edge now
|
|
29
|
+
* resolves to `canonical=true`.
|
|
30
|
+
*/
|
|
31
|
+
import type { ExecutionStatus } from '@telora/daemon-core';
|
|
32
|
+
/** Minimal issue shape the reconciler needs. */
|
|
33
|
+
export interface ReconcilerIssue {
|
|
34
|
+
status: string;
|
|
35
|
+
issueType: string;
|
|
36
|
+
}
|
|
37
|
+
/** Git-safety signal: the irreducible worktree-commit gate. */
|
|
38
|
+
export interface ReconcilerGitState {
|
|
39
|
+
/**
|
|
40
|
+
* Whether the focus worktree has NO uncommitted changes. The daemon is the
|
|
41
|
+
* only place this can be checked (Postgres has no git), which is the core
|
|
42
|
+
* reason the daemon -- not a PG trigger -- must own the coding -> verify write.
|
|
43
|
+
* When false, an otherwise-ready coding delivery is HELD in coding.
|
|
44
|
+
*/
|
|
45
|
+
worktreeCommitted: boolean;
|
|
46
|
+
}
|
|
47
|
+
/** Verify-gate verdict (from the guard engine). null = no guard evaluated. */
|
|
48
|
+
export interface ReconcilerGuardVerdict {
|
|
49
|
+
/** True when a hard guard blocked the transition -> delivery pauses. */
|
|
50
|
+
blocked: boolean;
|
|
51
|
+
}
|
|
52
|
+
/** Review-window signal used to route verify -> done. */
|
|
53
|
+
export interface ReconcilerReviewState {
|
|
54
|
+
/** Whether the focus currently has review_requested_at set. */
|
|
55
|
+
reviewRequested: boolean;
|
|
56
|
+
/** Whether an explicit focus_reviews report exists for the review session. */
|
|
57
|
+
reportExists: boolean;
|
|
58
|
+
/** The exiting session's type. */
|
|
59
|
+
sessionType: 'coding' | 'review';
|
|
60
|
+
/** Whether that session exited successfully. */
|
|
61
|
+
succeeded: boolean;
|
|
62
|
+
}
|
|
63
|
+
export interface ReconcileInput {
|
|
64
|
+
currentStatus: ExecutionStatus;
|
|
65
|
+
issues: ReadonlyArray<ReconcilerIssue>;
|
|
66
|
+
gitState: ReconcilerGitState;
|
|
67
|
+
guardVerdict?: ReconcilerGuardVerdict | null;
|
|
68
|
+
reviewState?: ReconcilerReviewState | null;
|
|
69
|
+
}
|
|
70
|
+
export interface ReconcileResult {
|
|
71
|
+
/** The execution_status the daemon should write (equal to currentStatus when no change). */
|
|
72
|
+
target: ExecutionStatus;
|
|
73
|
+
/** Whether target differs from currentStatus. */
|
|
74
|
+
changed: boolean;
|
|
75
|
+
/** Human-readable rationale (for shadow divergence logs + debugging). */
|
|
76
|
+
reason: string;
|
|
77
|
+
/**
|
|
78
|
+
* Whether (currentStatus -> target) is present in the canonical
|
|
79
|
+
* EXECUTION_STATUS_TRANSITIONS map. Always true for a no-op (stay). False
|
|
80
|
+
* flags a live-vs-canonical gap (notably coding -> queued); see the module
|
|
81
|
+
* header.
|
|
82
|
+
*/
|
|
83
|
+
canonical: boolean;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* THE shared "issues are done" predicate. A delivery's work is done when none
|
|
87
|
+
* of its work issues (Tasks/Bugs, excluding Context Groups) are in an OPEN
|
|
88
|
+
* status. OPEN = {To Do, In Progress, Blocked}; 'In Review' and 'Verified' are
|
|
89
|
+
* terminal here -- this is the daemon predicate, deliberately chosen as the
|
|
90
|
+
* single source of truth over the Postgres auto_close predicate (which requires
|
|
91
|
+
* every issue to be literally 'Done'). A delivery with zero work issues is
|
|
92
|
+
* vacuously done.
|
|
93
|
+
*
|
|
94
|
+
* Replaces the previously-divergent inline copies in advanceDeliveryStatuses
|
|
95
|
+
* (`!TERMINAL_ISSUE_STATUSES.has`), listener-auto-advance (`OPEN_ISSUE_STATUSES`),
|
|
96
|
+
* and review-exit (`ACTIVE_WORK_STATUSES`) -- all three sets have identical
|
|
97
|
+
* membership; this names the predicate once.
|
|
98
|
+
*/
|
|
99
|
+
export declare function areDeliveryIssuesDone(issues: ReadonlyArray<ReconcilerIssue>): boolean;
|
|
100
|
+
/** Whether the delivery has at least one work issue (Task/Bug). */
|
|
101
|
+
export declare function hasWorkIssues(issues: ReadonlyArray<ReconcilerIssue>): boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Whether any work issue is in an OPEN (active) status. This is the routing
|
|
104
|
+
* signal for verify -> verify_failed (open work on a verify delivery) and the
|
|
105
|
+
* coding/verify_failed re-queue (open work re-queues). Mirror image of
|
|
106
|
+
* areDeliveryIssuesDone for deliveries that have work.
|
|
107
|
+
*/
|
|
108
|
+
export declare function hasOpenWork(issues: ReadonlyArray<ReconcilerIssue>): boolean;
|
|
109
|
+
/** Whether any work issue is actively In Progress -- the queued -> coding driver. */
|
|
110
|
+
export declare function hasActiveWork(issues: ReadonlyArray<ReconcilerIssue>): boolean;
|
|
111
|
+
/**
|
|
112
|
+
* Compute the single next execution_status for a delivery from its full signal.
|
|
113
|
+
*
|
|
114
|
+
* Faithful to the current live writers (Delivery 2 characterization):
|
|
115
|
+
* - queued : has work + all done -> coding (step toward verify);
|
|
116
|
+
* has work + active -> coding (work started);
|
|
117
|
+
* otherwise -> stay (scoping gate / not started).
|
|
118
|
+
* - coding : open work -> queued (re-queue);
|
|
119
|
+
* all done + uncommitted worktree -> stay coding (git-safety gate);
|
|
120
|
+
* all done + committed + guard blocked -> paused;
|
|
121
|
+
* all done + committed -> verify.
|
|
122
|
+
* - verify : open work -> verify_failed;
|
|
123
|
+
* guard blocked -> paused;
|
|
124
|
+
* report exists -> done;
|
|
125
|
+
* clean review session -> done (auto-approve);
|
|
126
|
+
* otherwise -> stay verify (awaiting review outcome).
|
|
127
|
+
* - verify_failed : open work -> queued (re-queue);
|
|
128
|
+
* all done -> coding (re-iterate).
|
|
129
|
+
* - draft/planning/paused/done/cancelled : stay (out of reconciler scope;
|
|
130
|
+
* paused is cleared by a human re-queue, terminal states are final).
|
|
131
|
+
*/
|
|
132
|
+
export declare function reconcileDeliveryStatus(input: ReconcileInput): ReconcileResult;
|
|
133
|
+
//# sourceMappingURL=delivery-reconciler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delivery-reconciler.d.ts","sourceRoot":"","sources":["../src/delivery-reconciler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,gDAAgD;AAChD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,+DAA+D;AAC/D,MAAM,WAAW,kBAAkB;IACjC;;;;;OAKG;IACH,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,8EAA8E;AAC9E,MAAM,WAAW,sBAAsB;IACrC,wEAAwE;IACxE,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,yDAAyD;AACzD,MAAM,WAAW,qBAAqB;IACpC,+DAA+D;IAC/D,eAAe,EAAE,OAAO,CAAC;IACzB,8EAA8E;IAC9E,YAAY,EAAE,OAAO,CAAC;IACtB,kCAAkC;IAClC,WAAW,EAAE,QAAQ,GAAG,QAAQ,CAAC;IACjC,gDAAgD;IAChD,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,eAAe,CAAC;IAC/B,MAAM,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IACvC,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,YAAY,CAAC,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAC7C,WAAW,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;CAC5C;AAED,MAAM,WAAW,eAAe;IAC9B,4FAA4F;IAC5F,MAAM,EAAE,eAAe,CAAC;IACxB,iDAAiD;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,SAAS,EAAE,OAAO,CAAC;CACpB;AAID;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,CAAC,eAAe,CAAC,GAAG,OAAO,CAIrF;AAED,mEAAmE;AACnE,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,CAAC,eAAe,CAAC,GAAG,OAAO,CAE7E;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,eAAe,CAAC,GAAG,OAAO,CAE3E;AAED,qFAAqF;AACrF,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,CAAC,eAAe,CAAC,GAAG,OAAO,CAE7E;AAcD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,cAAc,GAAG,eAAe,CA8D9E"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single-writer delivery reconciler (PURE).
|
|
3
|
+
*
|
|
4
|
+
* Delivery 3 of the Delivery Execution Pathway Consolidation focus
|
|
5
|
+
* (reality-tree injection #10: "Delivery execution_status has exactly one
|
|
6
|
+
* writer -- the daemon reconciler; every transition flows through it").
|
|
7
|
+
*
|
|
8
|
+
* This module is the consolidation's center of gravity: ONE pure function that
|
|
9
|
+
* computes the single next execution_status the daemon should write, plus ONE
|
|
10
|
+
* shared "issues are done" predicate that replaces the divergent copies spread
|
|
11
|
+
* across the live writers (advanceDeliveryStage / advanceDeliveryStatuses /
|
|
12
|
+
* runReviewExitHandler / checkDeliveryAutoAdvance / checkVerifyDeliveriesForOpenIssues).
|
|
13
|
+
*
|
|
14
|
+
* It is deliberately PURE -- no I/O, no supabase, no git. Callers gather the
|
|
15
|
+
* signal (issues, worktree-committed flag, guard verdict, review state) and
|
|
16
|
+
* pass it in; the reconciler only computes. This is what makes it
|
|
17
|
+
* shadow-testable: run it alongside the live path, compare its target to the
|
|
18
|
+
* live status, log divergence, write nothing (see delivery-reconciler-shadow.ts).
|
|
19
|
+
*
|
|
20
|
+
* The behavior here MIRRORS the CURRENT live writers as pinned by the
|
|
21
|
+
* Delivery 2 characterization suite
|
|
22
|
+
* (__tests__/delivery-state-machine-characterization.test.ts). It characterizes
|
|
23
|
+
* what the system does today, not an idealized target -- the shadow phase exists
|
|
24
|
+
* precisely to prove parity before any cutover.
|
|
25
|
+
*
|
|
26
|
+
* The coding -> queued re-queue edge (open work at team exit -> re-queue) is
|
|
27
|
+
* present in EXECUTION_STATUS_TRANSITIONS as of the D5 cleanup. `result.canonical`
|
|
28
|
+
* flags transitions NOT in the canonical map; the coding -> queued edge now
|
|
29
|
+
* resolves to `canonical=true`.
|
|
30
|
+
*/
|
|
31
|
+
import { OPEN_ISSUE_STATUSES, filterWorkIssues } from './constants.js';
|
|
32
|
+
import { DELIVERY_STATUS, isValidTransition } from '@telora/daemon-core';
|
|
33
|
+
// ── Shared predicate (the single definition) ─────────────────────────
|
|
34
|
+
/**
|
|
35
|
+
* THE shared "issues are done" predicate. A delivery's work is done when none
|
|
36
|
+
* of its work issues (Tasks/Bugs, excluding Context Groups) are in an OPEN
|
|
37
|
+
* status. OPEN = {To Do, In Progress, Blocked}; 'In Review' and 'Verified' are
|
|
38
|
+
* terminal here -- this is the daemon predicate, deliberately chosen as the
|
|
39
|
+
* single source of truth over the Postgres auto_close predicate (which requires
|
|
40
|
+
* every issue to be literally 'Done'). A delivery with zero work issues is
|
|
41
|
+
* vacuously done.
|
|
42
|
+
*
|
|
43
|
+
* Replaces the previously-divergent inline copies in advanceDeliveryStatuses
|
|
44
|
+
* (`!TERMINAL_ISSUE_STATUSES.has`), listener-auto-advance (`OPEN_ISSUE_STATUSES`),
|
|
45
|
+
* and review-exit (`ACTIVE_WORK_STATUSES`) -- all three sets have identical
|
|
46
|
+
* membership; this names the predicate once.
|
|
47
|
+
*/
|
|
48
|
+
export function areDeliveryIssuesDone(issues) {
|
|
49
|
+
const work = filterWorkIssues([...issues]);
|
|
50
|
+
if (work.length === 0)
|
|
51
|
+
return true;
|
|
52
|
+
return work.every(i => !OPEN_ISSUE_STATUSES.has(i.status));
|
|
53
|
+
}
|
|
54
|
+
/** Whether the delivery has at least one work issue (Task/Bug). */
|
|
55
|
+
export function hasWorkIssues(issues) {
|
|
56
|
+
return filterWorkIssues([...issues]).length > 0;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Whether any work issue is in an OPEN (active) status. This is the routing
|
|
60
|
+
* signal for verify -> verify_failed (open work on a verify delivery) and the
|
|
61
|
+
* coding/verify_failed re-queue (open work re-queues). Mirror image of
|
|
62
|
+
* areDeliveryIssuesDone for deliveries that have work.
|
|
63
|
+
*/
|
|
64
|
+
export function hasOpenWork(issues) {
|
|
65
|
+
return filterWorkIssues([...issues]).some(i => OPEN_ISSUE_STATUSES.has(i.status));
|
|
66
|
+
}
|
|
67
|
+
/** Whether any work issue is actively In Progress -- the queued -> coding driver. */
|
|
68
|
+
export function hasActiveWork(issues) {
|
|
69
|
+
return filterWorkIssues([...issues]).some(i => i.status === 'In Progress');
|
|
70
|
+
}
|
|
71
|
+
// ── The reconciler ───────────────────────────────────────────────────
|
|
72
|
+
function result(currentStatus, target, reason) {
|
|
73
|
+
const changed = target !== currentStatus;
|
|
74
|
+
return {
|
|
75
|
+
target,
|
|
76
|
+
changed,
|
|
77
|
+
reason,
|
|
78
|
+
canonical: !changed || isValidTransition(currentStatus, target),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Compute the single next execution_status for a delivery from its full signal.
|
|
83
|
+
*
|
|
84
|
+
* Faithful to the current live writers (Delivery 2 characterization):
|
|
85
|
+
* - queued : has work + all done -> coding (step toward verify);
|
|
86
|
+
* has work + active -> coding (work started);
|
|
87
|
+
* otherwise -> stay (scoping gate / not started).
|
|
88
|
+
* - coding : open work -> queued (re-queue);
|
|
89
|
+
* all done + uncommitted worktree -> stay coding (git-safety gate);
|
|
90
|
+
* all done + committed + guard blocked -> paused;
|
|
91
|
+
* all done + committed -> verify.
|
|
92
|
+
* - verify : open work -> verify_failed;
|
|
93
|
+
* guard blocked -> paused;
|
|
94
|
+
* report exists -> done;
|
|
95
|
+
* clean review session -> done (auto-approve);
|
|
96
|
+
* otherwise -> stay verify (awaiting review outcome).
|
|
97
|
+
* - verify_failed : open work -> queued (re-queue);
|
|
98
|
+
* all done -> coding (re-iterate).
|
|
99
|
+
* - draft/planning/paused/done/cancelled : stay (out of reconciler scope;
|
|
100
|
+
* paused is cleared by a human re-queue, terminal states are final).
|
|
101
|
+
*/
|
|
102
|
+
export function reconcileDeliveryStatus(input) {
|
|
103
|
+
const { currentStatus, issues, gitState, guardVerdict, reviewState } = input;
|
|
104
|
+
const allDone = areDeliveryIssuesDone(issues);
|
|
105
|
+
const openWork = hasOpenWork(issues);
|
|
106
|
+
const hasWork = hasWorkIssues(issues);
|
|
107
|
+
switch (currentStatus) {
|
|
108
|
+
case DELIVERY_STATUS.QUEUED: {
|
|
109
|
+
if (!hasWork) {
|
|
110
|
+
return result(currentStatus, DELIVERY_STATUS.QUEUED, 'no work issues yet (scoping gate holds queued)');
|
|
111
|
+
}
|
|
112
|
+
if (allDone) {
|
|
113
|
+
return result(currentStatus, DELIVERY_STATUS.CODING, 'queued with all work terminal -> step to coding before advancing');
|
|
114
|
+
}
|
|
115
|
+
if (hasActiveWork(issues)) {
|
|
116
|
+
return result(currentStatus, DELIVERY_STATUS.CODING, 'work in progress -> coding');
|
|
117
|
+
}
|
|
118
|
+
return result(currentStatus, DELIVERY_STATUS.QUEUED, 'work not started -> stay queued');
|
|
119
|
+
}
|
|
120
|
+
case DELIVERY_STATUS.CODING: {
|
|
121
|
+
if (openWork) {
|
|
122
|
+
return result(currentStatus, DELIVERY_STATUS.QUEUED, 'open work remains -> re-queue');
|
|
123
|
+
}
|
|
124
|
+
if (!gitState.worktreeCommitted) {
|
|
125
|
+
return result(currentStatus, DELIVERY_STATUS.CODING, 'all work done but worktree has uncommitted changes -> git-safety gate holds in coding');
|
|
126
|
+
}
|
|
127
|
+
if (guardVerdict?.blocked) {
|
|
128
|
+
return result(currentStatus, DELIVERY_STATUS.PAUSED, 'guard blocked coding->verify -> paused');
|
|
129
|
+
}
|
|
130
|
+
return result(currentStatus, DELIVERY_STATUS.VERIFY, 'all work done + worktree committed -> verify');
|
|
131
|
+
}
|
|
132
|
+
case DELIVERY_STATUS.VERIFY: {
|
|
133
|
+
if (openWork) {
|
|
134
|
+
return result(currentStatus, DELIVERY_STATUS.VERIFY_FAILED, 'open work on a verify delivery -> verify_failed');
|
|
135
|
+
}
|
|
136
|
+
if (guardVerdict?.blocked) {
|
|
137
|
+
return result(currentStatus, DELIVERY_STATUS.PAUSED, 'verify->done gate blocked -> paused');
|
|
138
|
+
}
|
|
139
|
+
if (reviewState?.reportExists) {
|
|
140
|
+
return result(currentStatus, DELIVERY_STATUS.DONE, 'explicit review report present -> done');
|
|
141
|
+
}
|
|
142
|
+
if (reviewState?.sessionType === 'review' && reviewState.succeeded) {
|
|
143
|
+
return result(currentStatus, DELIVERY_STATUS.DONE, 'clean review session, no report -> done (auto-approve)');
|
|
144
|
+
}
|
|
145
|
+
return result(currentStatus, DELIVERY_STATUS.VERIFY, 'no open work, awaiting review outcome -> stay verify');
|
|
146
|
+
}
|
|
147
|
+
case DELIVERY_STATUS.VERIFY_FAILED: {
|
|
148
|
+
if (openWork) {
|
|
149
|
+
return result(currentStatus, DELIVERY_STATUS.QUEUED, 'verify_failed with open work -> re-queue');
|
|
150
|
+
}
|
|
151
|
+
return result(currentStatus, DELIVERY_STATUS.CODING, 'verify_failed, work done -> coding (re-iterate)');
|
|
152
|
+
}
|
|
153
|
+
// draft / planning / paused / done / cancelled: not driven by the
|
|
154
|
+
// issue-rollup reconciler. paused is cleared by a human re-queue;
|
|
155
|
+
// terminal states are final.
|
|
156
|
+
default:
|
|
157
|
+
return result(currentStatus, currentStatus, `status '${currentStatus}' is not reconciler-driven -> stay`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=delivery-reconciler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delivery-reconciler.js","sourceRoot":"","sources":["../src/delivery-reconciler.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listener-auto-advance.d.ts","sourceRoot":"","sources":["../src/listener-auto-advance.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"listener-auto-advance.d.ts","sourceRoot":"","sources":["../src/listener-auto-advance.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAS/C,OAAO,EAAE,gBAAgB,IAAI,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAwElF;;;GAGG;AACH,eAAO,MAAM,yBAAyB,yBAAyB,CAAC;AAQhE;;GAEG;AACH,wBAAgB,mCAAmC,IAAI,IAAI,CAE1D;AAED;;GAEG;AACH,wBAAgB,oCAAoC,IAAI,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAElF;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,wBAAwB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAqJlF;AAED;;;;;;;;;;GAUG;AACH;;;;;GAKG;AACH,MAAM,WAAW,yBAAyB;IACxC,gBAAgB,CAAC,EAAE,OAAO,uBAAuB,CAAC;CACnD;AAED,wBAAsB,kCAAkC,CACtD,MAAM,EAAE,YAAY,EACpB,IAAI,GAAE,yBAA8B,GACnC,OAAO,CAAC,IAAI,CAAC,CAsLf"}
|