@telora/daemon 0.15.31 → 0.15.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build-info.json +2 -2
- package/dist/assembly-resolvers.d.ts.map +1 -1
- package/dist/assembly-resolvers.js +170 -2
- package/dist/assembly-resolvers.js.map +1 -1
- package/dist/close-loop-dispatcher.d.ts +218 -0
- package/dist/close-loop-dispatcher.d.ts.map +1 -0
- package/dist/close-loop-dispatcher.js +207 -0
- package/dist/close-loop-dispatcher.js.map +1 -0
- package/dist/directive-executor.d.ts +70 -3
- package/dist/directive-executor.d.ts.map +1 -1
- package/dist/directive-executor.js +233 -8
- package/dist/directive-executor.js.map +1 -1
- package/dist/focus-executor.d.ts.map +1 -1
- package/dist/focus-executor.js +3 -0
- package/dist/focus-executor.js.map +1 -1
- package/dist/focus-stage-lifecycle.d.ts +158 -0
- package/dist/focus-stage-lifecycle.d.ts.map +1 -0
- package/dist/focus-stage-lifecycle.js +293 -0
- package/dist/focus-stage-lifecycle.js.map +1 -0
- package/dist/heartbeat.d.ts.map +1 -1
- package/dist/heartbeat.js +1 -0
- package/dist/heartbeat.js.map +1 -1
- package/dist/listener.d.ts.map +1 -1
- package/dist/listener.js +8 -0
- package/dist/listener.js.map +1 -1
- package/dist/queries/deliveries.d.ts +14 -0
- package/dist/queries/deliveries.d.ts.map +1 -1
- package/dist/queries/deliveries.js +2 -0
- package/dist/queries/deliveries.js.map +1 -1
- package/dist/queries/focuses.d.ts +24 -0
- package/dist/queries/focuses.d.ts.map +1 -1
- package/dist/queries/focuses.js +35 -0
- package/dist/queries/focuses.js.map +1 -1
- package/dist/queries/schemas.d.ts +13 -0
- package/dist/queries/schemas.d.ts.map +1 -1
- package/dist/queries/schemas.js +15 -0
- package/dist/queries/schemas.js.map +1 -1
- package/dist/queries/shared.d.ts.map +1 -1
- package/dist/queries/shared.js +2 -0
- package/dist/queries/shared.js.map +1 -1
- package/dist/team-prompt-base.d.ts +65 -0
- package/dist/team-prompt-base.d.ts.map +1 -1
- package/dist/team-prompt-base.js +152 -0
- package/dist/team-prompt-base.js.map +1 -1
- package/dist/trigger-executor.d.ts +9 -15
- package/dist/trigger-executor.d.ts.map +1 -1
- package/dist/trigger-executor.js +15 -38
- package/dist/trigger-executor.js.map +1 -1
- package/dist/types/focus.d.ts +12 -0
- package/dist/types/focus.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Close-loop stage dispatcher.
|
|
3
|
+
*
|
|
4
|
+
* Handles focuses entering the `close_loop` workflow stage. Three asymmetric
|
|
5
|
+
* checks are delegated to the spawned bookkeeper team via the assembled
|
|
6
|
+
* directive; the dispatcher itself is responsible for the deterministic
|
|
7
|
+
* pre- and post-conditions:
|
|
8
|
+
*
|
|
9
|
+
* - **Short-circuit on no anchors.** If the focus has no anchoring
|
|
10
|
+
* injections, close_loop is a no-op: the dispatcher advances the focus
|
|
11
|
+
* directly to `done`. No team is spawned. This matches the
|
|
12
|
+
* `no_anchoring_injections_short_circuit` soft guard on
|
|
13
|
+
* `verify -> close_loop` in the focus workflow.
|
|
14
|
+
*
|
|
15
|
+
* - **Otherwise, spawn a fresh bookkeeper team** (Sonnet model, fresh
|
|
16
|
+
* session) with the close_loop assembly recipe:
|
|
17
|
+
* loop.persona(variant=close_loop)
|
|
18
|
+
* focus.context
|
|
19
|
+
* focus.anchoring_injections
|
|
20
|
+
* git.diff_against_base
|
|
21
|
+
* delivery.acceptance_criteria
|
|
22
|
+
* review.outcomes
|
|
23
|
+
* The team handles the per-injection sweep (verified | escalated, no
|
|
24
|
+
* third option), the incomplete-planning check, and the tree-drift
|
|
25
|
+
* check skeleton (D5 wires `focus.description` through into the
|
|
26
|
+
* drift-check prompt section).
|
|
27
|
+
*
|
|
28
|
+
* - **Monitor termination.** Once every anchored injection has reached a
|
|
29
|
+
* terminal state (`verified` or has an open `injection_unverified`
|
|
30
|
+
* escalation), the dispatcher advances the focus to `done`. While any
|
|
31
|
+
* injection is still non-terminal, the focus stays at `close_loop`.
|
|
32
|
+
*
|
|
33
|
+
* The dispatcher is intentionally split into small pure helpers so each
|
|
34
|
+
* deterministic check (terminal classification, short-circuit detection,
|
|
35
|
+
* directive composition) is unit-testable without DB or process spawning.
|
|
36
|
+
*/
|
|
37
|
+
import type { DaemonConfig, StageDirective } from './types.js';
|
|
38
|
+
import type { FocusDeliveryInfo } from './types.js';
|
|
39
|
+
/**
|
|
40
|
+
* Model used by close_loop bookkeeper teams. Sonnet because the bookkeeper
|
|
41
|
+
* is a careful, deterministic role (sweep injections, file escalations);
|
|
42
|
+
* Opus would be overkill and slower.
|
|
43
|
+
*/
|
|
44
|
+
export declare const CLOSE_LOOP_MODEL = "claude-sonnet-4-6";
|
|
45
|
+
/**
|
|
46
|
+
* Assembly recipe for the close_loop stage. Composed in dispatcher when
|
|
47
|
+
* the close_loop directive is synthesized. Persisted nowhere -- the
|
|
48
|
+
* stage's stored `agent_directive` (if any) is ignored in favor of this
|
|
49
|
+
* canonical recipe so the bookkeeper framing is deterministic regardless
|
|
50
|
+
* of how the workflow stage row was seeded.
|
|
51
|
+
*/
|
|
52
|
+
export declare const CLOSE_LOOP_ASSEMBLY_RECIPE: readonly string[];
|
|
53
|
+
/**
|
|
54
|
+
* Terminal injection statuses for close_loop. An injection is considered
|
|
55
|
+
* terminal when it is either verified (the bookkeeper called
|
|
56
|
+
* reality_tree_injection_verify) or has an `injection_unverified`
|
|
57
|
+
* escalation filed against it. The first is detected by `injectionStatus`;
|
|
58
|
+
* the second is detected by walking the agent_escalations table -- see
|
|
59
|
+
* `isInjectionEscalated`.
|
|
60
|
+
*/
|
|
61
|
+
export declare const TERMINAL_INJECTION_STATUSES: readonly string[];
|
|
62
|
+
/**
|
|
63
|
+
* Return the deliveries in the focus that anchor an injection.
|
|
64
|
+
*
|
|
65
|
+
* A delivery anchors an injection when `injection_id` (a column on
|
|
66
|
+
* org_nodes rows of type='delivery', see migration
|
|
67
|
+
* 20260510152110_add_injection_id_to_product_deliveries.sql) points at a
|
|
68
|
+
* reality_tree_nodes row.
|
|
69
|
+
*/
|
|
70
|
+
export declare function getAnchoringDeliveries(deliveries: FocusDeliveryInfo[]): FocusDeliveryInfo[];
|
|
71
|
+
/**
|
|
72
|
+
* Pure short-circuit predicate -- "does this focus have any anchoring
|
|
73
|
+
* injections?". If false, close_loop is a no-op and the focus can advance
|
|
74
|
+
* directly to `done`.
|
|
75
|
+
*/
|
|
76
|
+
export declare function shouldShortCircuitToDone(deliveries: FocusDeliveryInfo[]): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Per-injection summary used by termination checks. The dispatcher composes
|
|
79
|
+
* one of these per anchored injection from a snapshot of:
|
|
80
|
+
*
|
|
81
|
+
* - the injection node's `injectionStatus` (from reality_tree_nodes)
|
|
82
|
+
* - whether there is an open `injection_unverified` escalation with
|
|
83
|
+
* metadata.injection_id == this injection id (from agent_escalations)
|
|
84
|
+
*/
|
|
85
|
+
export interface InjectionTerminalState {
|
|
86
|
+
injectionId: string;
|
|
87
|
+
/** From reality_tree_nodes.injection_status (or null for non-injection nodes). */
|
|
88
|
+
injectionStatus: string | null;
|
|
89
|
+
/** Whether an open injection_unverified escalation targets this injection. */
|
|
90
|
+
hasOpenUnverifiedEscalation: boolean;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Pure classifier. An injection is terminal for close_loop when:
|
|
94
|
+
*
|
|
95
|
+
* - injectionStatus is `verified`, OR
|
|
96
|
+
* - there is an open `injection_unverified` escalation for it
|
|
97
|
+
* (this is the "escalated" outcome -- the bookkeeper filed the
|
|
98
|
+
* escalation and the focus is now blocked on a human).
|
|
99
|
+
*
|
|
100
|
+
* The "open escalation" case keeps the focus at close_loop (status='pending'
|
|
101
|
+
* or 'in_review') -- this function classifies the escalation as terminal
|
|
102
|
+
* for the dispatcher's perspective so the daemon does not loop forever
|
|
103
|
+
* re-spawning the bookkeeper. A human must resolve or dismiss the
|
|
104
|
+
* escalation; once resolved, the bookkeeper can be re-triggered.
|
|
105
|
+
*/
|
|
106
|
+
export declare function isInjectionTerminal(state: InjectionTerminalState): boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Pure aggregate predicate -- "are ALL anchored injections terminal?".
|
|
109
|
+
* Returns true on an empty list (the short-circuit branch handles the
|
|
110
|
+
* empty case separately, but this is safe to call after the short-circuit
|
|
111
|
+
* filter).
|
|
112
|
+
*/
|
|
113
|
+
export declare function allInjectionsTerminal(states: InjectionTerminalState[]): boolean;
|
|
114
|
+
/**
|
|
115
|
+
* Compose the synthetic close_loop StageDirective. Used by the dispatcher
|
|
116
|
+
* to seed the pending spawn directive map; pure for testability.
|
|
117
|
+
*/
|
|
118
|
+
export declare function buildCloseLoopDirective(): StageDirective;
|
|
119
|
+
/**
|
|
120
|
+
* Query: are there any pending or in_review injection_unverified escalations
|
|
121
|
+
* for the given injection ids? Returns the set of injection ids that have
|
|
122
|
+
* an open escalation.
|
|
123
|
+
*
|
|
124
|
+
* Looks at agent_escalations with:
|
|
125
|
+
* - escalation_kind = 'injection_unverified'
|
|
126
|
+
* - status IN ('pending', 'in_review')
|
|
127
|
+
* - metadata->>'injection_id' IN (...)
|
|
128
|
+
*
|
|
129
|
+
* The dispatcher uses this to classify "escalated" injections as terminal
|
|
130
|
+
* for advancement purposes.
|
|
131
|
+
*/
|
|
132
|
+
export interface OpenInjectionEscalationLookup {
|
|
133
|
+
(params: {
|
|
134
|
+
organizationId: string;
|
|
135
|
+
injectionIds: string[];
|
|
136
|
+
}): Promise<Set<string>>;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Top-level result of inspecting a focus for close_loop termination.
|
|
140
|
+
* Tells the caller exactly what to do: short-circuit, spawn, advance to
|
|
141
|
+
* done, or hold.
|
|
142
|
+
*/
|
|
143
|
+
export type CloseLoopDecision = {
|
|
144
|
+
kind: 'short_circuit_to_done';
|
|
145
|
+
} | {
|
|
146
|
+
kind: 'spawn_bookkeeper';
|
|
147
|
+
directive: StageDirective;
|
|
148
|
+
} | {
|
|
149
|
+
kind: 'advance_to_done';
|
|
150
|
+
} | {
|
|
151
|
+
kind: 'hold';
|
|
152
|
+
reason: string;
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* Compute the close_loop decision for a focus given a snapshot of its
|
|
156
|
+
* deliveries and the terminal state of each anchored injection.
|
|
157
|
+
*
|
|
158
|
+
* Pure -- no DB access. Tests pass snapshots in.
|
|
159
|
+
*
|
|
160
|
+
* Semantics:
|
|
161
|
+
*
|
|
162
|
+
* - No anchored injections -> short_circuit_to_done
|
|
163
|
+
* - Anchored injections, none yet sweeped -> spawn_bookkeeper
|
|
164
|
+
* - All anchored injections terminal -> advance_to_done
|
|
165
|
+
* - Some terminal, some not -> hold (waiting on bookkeeper)
|
|
166
|
+
*
|
|
167
|
+
* The "spawn_bookkeeper" branch is gated on "no sweep has happened yet"
|
|
168
|
+
* which the caller communicates via `bookkeeperHasRun`. Without this gate
|
|
169
|
+
* every poll cycle would respawn the bookkeeper while it's still working
|
|
170
|
+
* (or before a stuck injection's escalation is filed).
|
|
171
|
+
*/
|
|
172
|
+
export declare function decideCloseLoop(deliveries: FocusDeliveryInfo[], injectionStates: InjectionTerminalState[], bookkeeperHasRun: boolean): CloseLoopDecision;
|
|
173
|
+
/**
|
|
174
|
+
* Sentinel returned by the dispatcher when no action was taken (focus is
|
|
175
|
+
* not in close_loop stage, or already processed this cycle). Caller can
|
|
176
|
+
* log it but should not act on it.
|
|
177
|
+
*/
|
|
178
|
+
export interface CloseLoopDispatchOutcome {
|
|
179
|
+
decision: CloseLoopDecision;
|
|
180
|
+
/** Anchored injection ids that were inspected (empty on short-circuit). */
|
|
181
|
+
anchoredInjectionIds: string[];
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Re-exported constant set so tests can assert the kind names used by the
|
|
185
|
+
* dispatcher in the agent_escalations rows. Keeps the kind string under
|
|
186
|
+
* a single source of truth in daemon-core.
|
|
187
|
+
*/
|
|
188
|
+
export declare const CLOSE_LOOP_ESCALATION_KINDS: {
|
|
189
|
+
readonly INJECTION_UNVERIFIED: "injection_unverified";
|
|
190
|
+
readonly TREE_DRIFT: "tree_drift";
|
|
191
|
+
readonly INCOMPLETE_PLANNING: "incomplete_planning";
|
|
192
|
+
};
|
|
193
|
+
/**
|
|
194
|
+
* Configuration knobs accepted by the dispatcher entry point. Exposed so
|
|
195
|
+
* tests can inject a no-op spawner.
|
|
196
|
+
*/
|
|
197
|
+
export interface CloseLoopDispatcherDeps {
|
|
198
|
+
/**
|
|
199
|
+
* Set the pending spawn directive for the focus so the next spawn cycle
|
|
200
|
+
* delivers the close_loop directive. In production this is the export
|
|
201
|
+
* from directive-executor; in tests this is a stub.
|
|
202
|
+
*/
|
|
203
|
+
setPendingSpawnDirective: (focusId: string, directive: {
|
|
204
|
+
message: string;
|
|
205
|
+
model: string | null;
|
|
206
|
+
sessionType: 'coding' | 'review';
|
|
207
|
+
contentHash: string;
|
|
208
|
+
}) => void;
|
|
209
|
+
/** Advance the focus stage on product_focuses.stage. */
|
|
210
|
+
updateFocusStage: (focusId: string, stage: string) => Promise<void>;
|
|
211
|
+
/** Lookup open injection_unverified escalations. */
|
|
212
|
+
lookupOpenInjectionEscalations: OpenInjectionEscalationLookup;
|
|
213
|
+
/** Build the directive content (assembly resolution + prompt). */
|
|
214
|
+
assembleDirectiveContent: (config: DaemonConfig, focusId: string, directive: StageDirective, worktreePath: string | null) => Promise<string>;
|
|
215
|
+
/** Compute the content hash for the synthesized directive. */
|
|
216
|
+
computeDirectiveHash: (directive: StageDirective) => string;
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=close-loop-dispatcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"close-loop-dispatcher.d.ts","sourceRoot":"","sources":["../src/close-loop-dispatcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Close-loop stage dispatcher.
|
|
3
|
+
*
|
|
4
|
+
* Handles focuses entering the `close_loop` workflow stage. Three asymmetric
|
|
5
|
+
* checks are delegated to the spawned bookkeeper team via the assembled
|
|
6
|
+
* directive; the dispatcher itself is responsible for the deterministic
|
|
7
|
+
* pre- and post-conditions:
|
|
8
|
+
*
|
|
9
|
+
* - **Short-circuit on no anchors.** If the focus has no anchoring
|
|
10
|
+
* injections, close_loop is a no-op: the dispatcher advances the focus
|
|
11
|
+
* directly to `done`. No team is spawned. This matches the
|
|
12
|
+
* `no_anchoring_injections_short_circuit` soft guard on
|
|
13
|
+
* `verify -> close_loop` in the focus workflow.
|
|
14
|
+
*
|
|
15
|
+
* - **Otherwise, spawn a fresh bookkeeper team** (Sonnet model, fresh
|
|
16
|
+
* session) with the close_loop assembly recipe:
|
|
17
|
+
* loop.persona(variant=close_loop)
|
|
18
|
+
* focus.context
|
|
19
|
+
* focus.anchoring_injections
|
|
20
|
+
* git.diff_against_base
|
|
21
|
+
* delivery.acceptance_criteria
|
|
22
|
+
* review.outcomes
|
|
23
|
+
* The team handles the per-injection sweep (verified | escalated, no
|
|
24
|
+
* third option), the incomplete-planning check, and the tree-drift
|
|
25
|
+
* check skeleton (D5 wires `focus.description` through into the
|
|
26
|
+
* drift-check prompt section).
|
|
27
|
+
*
|
|
28
|
+
* - **Monitor termination.** Once every anchored injection has reached a
|
|
29
|
+
* terminal state (`verified` or has an open `injection_unverified`
|
|
30
|
+
* escalation), the dispatcher advances the focus to `done`. While any
|
|
31
|
+
* injection is still non-terminal, the focus stays at `close_loop`.
|
|
32
|
+
*
|
|
33
|
+
* The dispatcher is intentionally split into small pure helpers so each
|
|
34
|
+
* deterministic check (terminal classification, short-circuit detection,
|
|
35
|
+
* directive composition) is unit-testable without DB or process spawning.
|
|
36
|
+
*/
|
|
37
|
+
import { ESCALATION_KINDS } from '@telora/daemon-core';
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
// Constants
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
/**
|
|
42
|
+
* Model used by close_loop bookkeeper teams. Sonnet because the bookkeeper
|
|
43
|
+
* is a careful, deterministic role (sweep injections, file escalations);
|
|
44
|
+
* Opus would be overkill and slower.
|
|
45
|
+
*/
|
|
46
|
+
export const CLOSE_LOOP_MODEL = 'claude-sonnet-4-6';
|
|
47
|
+
/**
|
|
48
|
+
* Assembly recipe for the close_loop stage. Composed in dispatcher when
|
|
49
|
+
* the close_loop directive is synthesized. Persisted nowhere -- the
|
|
50
|
+
* stage's stored `agent_directive` (if any) is ignored in favor of this
|
|
51
|
+
* canonical recipe so the bookkeeper framing is deterministic regardless
|
|
52
|
+
* of how the workflow stage row was seeded.
|
|
53
|
+
*/
|
|
54
|
+
export const CLOSE_LOOP_ASSEMBLY_RECIPE = [
|
|
55
|
+
'loop.persona(variant=close_loop)',
|
|
56
|
+
'focus.context',
|
|
57
|
+
'focus.anchoring_injections',
|
|
58
|
+
'git.diff_against_base',
|
|
59
|
+
'delivery.acceptance_criteria',
|
|
60
|
+
'review.outcomes',
|
|
61
|
+
];
|
|
62
|
+
/**
|
|
63
|
+
* Terminal injection statuses for close_loop. An injection is considered
|
|
64
|
+
* terminal when it is either verified (the bookkeeper called
|
|
65
|
+
* reality_tree_injection_verify) or has an `injection_unverified`
|
|
66
|
+
* escalation filed against it. The first is detected by `injectionStatus`;
|
|
67
|
+
* the second is detected by walking the agent_escalations table -- see
|
|
68
|
+
* `isInjectionEscalated`.
|
|
69
|
+
*/
|
|
70
|
+
export const TERMINAL_INJECTION_STATUSES = ['verified'];
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
// Helpers (pure)
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
/**
|
|
75
|
+
* Return the deliveries in the focus that anchor an injection.
|
|
76
|
+
*
|
|
77
|
+
* A delivery anchors an injection when `injection_id` (a column on
|
|
78
|
+
* org_nodes rows of type='delivery', see migration
|
|
79
|
+
* 20260510152110_add_injection_id_to_product_deliveries.sql) points at a
|
|
80
|
+
* reality_tree_nodes row.
|
|
81
|
+
*/
|
|
82
|
+
export function getAnchoringDeliveries(deliveries) {
|
|
83
|
+
return deliveries.filter((d) => typeof d.injectionId === 'string' && d.injectionId.length > 0);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Pure short-circuit predicate -- "does this focus have any anchoring
|
|
87
|
+
* injections?". If false, close_loop is a no-op and the focus can advance
|
|
88
|
+
* directly to `done`.
|
|
89
|
+
*/
|
|
90
|
+
export function shouldShortCircuitToDone(deliveries) {
|
|
91
|
+
return getAnchoringDeliveries(deliveries).length === 0;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Pure classifier. An injection is terminal for close_loop when:
|
|
95
|
+
*
|
|
96
|
+
* - injectionStatus is `verified`, OR
|
|
97
|
+
* - there is an open `injection_unverified` escalation for it
|
|
98
|
+
* (this is the "escalated" outcome -- the bookkeeper filed the
|
|
99
|
+
* escalation and the focus is now blocked on a human).
|
|
100
|
+
*
|
|
101
|
+
* The "open escalation" case keeps the focus at close_loop (status='pending'
|
|
102
|
+
* or 'in_review') -- this function classifies the escalation as terminal
|
|
103
|
+
* for the dispatcher's perspective so the daemon does not loop forever
|
|
104
|
+
* re-spawning the bookkeeper. A human must resolve or dismiss the
|
|
105
|
+
* escalation; once resolved, the bookkeeper can be re-triggered.
|
|
106
|
+
*/
|
|
107
|
+
export function isInjectionTerminal(state) {
|
|
108
|
+
if (state.injectionStatus && TERMINAL_INJECTION_STATUSES.includes(state.injectionStatus)) {
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
if (state.hasOpenUnverifiedEscalation) {
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Pure aggregate predicate -- "are ALL anchored injections terminal?".
|
|
118
|
+
* Returns true on an empty list (the short-circuit branch handles the
|
|
119
|
+
* empty case separately, but this is safe to call after the short-circuit
|
|
120
|
+
* filter).
|
|
121
|
+
*/
|
|
122
|
+
export function allInjectionsTerminal(states) {
|
|
123
|
+
return states.every(isInjectionTerminal);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Compose the synthetic close_loop StageDirective. Used by the dispatcher
|
|
127
|
+
* to seed the pending spawn directive map; pure for testability.
|
|
128
|
+
*/
|
|
129
|
+
export function buildCloseLoopDirective() {
|
|
130
|
+
return {
|
|
131
|
+
execution: 'spawn',
|
|
132
|
+
compact: null,
|
|
133
|
+
assembly: [...CLOSE_LOOP_ASSEMBLY_RECIPE],
|
|
134
|
+
tools: null,
|
|
135
|
+
prompt: [
|
|
136
|
+
'You are the close-loop bookkeeper for this focus. Run the three',
|
|
137
|
+
'asymmetric checks in order:',
|
|
138
|
+
'',
|
|
139
|
+
'1. **Per-injection sweep.** For each anchored injection, decide:',
|
|
140
|
+
' verified or escalated. No third option. Use',
|
|
141
|
+
' telora_reality_tree_injection_verify(injectionId, evidence) for',
|
|
142
|
+
' verified; file an `injection_unverified` escalation otherwise.',
|
|
143
|
+
'',
|
|
144
|
+
'2. **incomplete_planning check.** Walk the focus deliveries and the',
|
|
145
|
+
' git diff. Any delivery that shipped without an anchoring injection,',
|
|
146
|
+
' or any "injection-shaped" residual work the focus did not declare,',
|
|
147
|
+
' gets one `incomplete_planning` escalation per gap.',
|
|
148
|
+
'',
|
|
149
|
+
'3. **tree_drift check.** Compare residual UDEs in the focus tree to',
|
|
150
|
+
' the focus.description (the implicit apex). Drift gets a `tree_drift`',
|
|
151
|
+
' escalation; in-scope but unresolved UDEs do too. See the',
|
|
152
|
+
' "Tree-Focus Apex Drift Check" section of the role framework for',
|
|
153
|
+
' the procedure.',
|
|
154
|
+
'',
|
|
155
|
+
'You do not advance the focus stage. The daemon advances close_loop',
|
|
156
|
+
'to done automatically once every anchored injection is terminal',
|
|
157
|
+
'(verified or has an open injection_unverified escalation).',
|
|
158
|
+
].join('\n'),
|
|
159
|
+
model: CLOSE_LOOP_MODEL,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Compute the close_loop decision for a focus given a snapshot of its
|
|
164
|
+
* deliveries and the terminal state of each anchored injection.
|
|
165
|
+
*
|
|
166
|
+
* Pure -- no DB access. Tests pass snapshots in.
|
|
167
|
+
*
|
|
168
|
+
* Semantics:
|
|
169
|
+
*
|
|
170
|
+
* - No anchored injections -> short_circuit_to_done
|
|
171
|
+
* - Anchored injections, none yet sweeped -> spawn_bookkeeper
|
|
172
|
+
* - All anchored injections terminal -> advance_to_done
|
|
173
|
+
* - Some terminal, some not -> hold (waiting on bookkeeper)
|
|
174
|
+
*
|
|
175
|
+
* The "spawn_bookkeeper" branch is gated on "no sweep has happened yet"
|
|
176
|
+
* which the caller communicates via `bookkeeperHasRun`. Without this gate
|
|
177
|
+
* every poll cycle would respawn the bookkeeper while it's still working
|
|
178
|
+
* (or before a stuck injection's escalation is filed).
|
|
179
|
+
*/
|
|
180
|
+
export function decideCloseLoop(deliveries, injectionStates, bookkeeperHasRun) {
|
|
181
|
+
if (shouldShortCircuitToDone(deliveries)) {
|
|
182
|
+
return { kind: 'short_circuit_to_done' };
|
|
183
|
+
}
|
|
184
|
+
if (allInjectionsTerminal(injectionStates)) {
|
|
185
|
+
return { kind: 'advance_to_done' };
|
|
186
|
+
}
|
|
187
|
+
if (!bookkeeperHasRun) {
|
|
188
|
+
return { kind: 'spawn_bookkeeper', directive: buildCloseLoopDirective() };
|
|
189
|
+
}
|
|
190
|
+
const total = injectionStates.length;
|
|
191
|
+
const terminal = injectionStates.filter(isInjectionTerminal).length;
|
|
192
|
+
return {
|
|
193
|
+
kind: 'hold',
|
|
194
|
+
reason: `${terminal}/${total} anchored injections terminal (verified or escalated); waiting on bookkeeper`,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Re-exported constant set so tests can assert the kind names used by the
|
|
199
|
+
* dispatcher in the agent_escalations rows. Keeps the kind string under
|
|
200
|
+
* a single source of truth in daemon-core.
|
|
201
|
+
*/
|
|
202
|
+
export const CLOSE_LOOP_ESCALATION_KINDS = {
|
|
203
|
+
INJECTION_UNVERIFIED: ESCALATION_KINDS.INJECTION_UNVERIFIED,
|
|
204
|
+
TREE_DRIFT: ESCALATION_KINDS.TREE_DRIFT,
|
|
205
|
+
INCOMPLETE_PLANNING: ESCALATION_KINDS.INCOMPLETE_PLANNING,
|
|
206
|
+
};
|
|
207
|
+
//# sourceMappingURL=close-loop-dispatcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"close-loop-dispatcher.js","sourceRoot":"","sources":["../src/close-loop-dispatcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import type { DaemonConfig, StageDirective } from './types.js';
|
|
10
10
|
import './assembly-resolvers.js';
|
|
11
|
+
import { type CloseLoopDecision } from './close-loop-dispatcher.js';
|
|
11
12
|
import { createEscalation } from './queries/issues.js';
|
|
12
13
|
/** Seed the last-processed stage for a focus (used on daemon startup). */
|
|
13
14
|
export declare function seedLastProcessedStage(focusId: string, stageId: string): void;
|
|
@@ -83,9 +84,33 @@ export declare function getPendingSpawnFocusIds(): string[];
|
|
|
83
84
|
*/
|
|
84
85
|
export declare function assembleDirectiveContent(config: DaemonConfig, focusId: string, directive: StageDirective, worktreePath: string | null): Promise<string>;
|
|
85
86
|
/**
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
87
|
+
* Decide which workflow stage name a focus should be in.
|
|
88
|
+
*
|
|
89
|
+
* Pure helper, exported for testing. The selection rule is:
|
|
90
|
+
* 1. If `focus.stage` is one of the new lifecycle stage names
|
|
91
|
+
* (`queued`/`verify`/`review`/`close_loop`/`done`), use it directly.
|
|
92
|
+
* The denormalized stage is the authoritative signal under the new
|
|
93
|
+
* workflow.
|
|
94
|
+
* 2. Otherwise, fall back to the legacy phase derived from the delivery
|
|
95
|
+
* aggregate (kickoff/coding/verifying/reviewing/winding_down/blocked).
|
|
96
|
+
*
|
|
97
|
+
* Note: `review_requested_at` is still read by the legacy derivation for
|
|
98
|
+
* back-compat -- but on the new lifecycle path the `review` stage transition
|
|
99
|
+
* is driven by writes to `product_focuses.stage`, not by writes to
|
|
100
|
+
* `review_requested_at`. This is the Issue 1 contract.
|
|
101
|
+
*/
|
|
102
|
+
export declare function resolveFocusStageName(input: {
|
|
103
|
+
focusStage: string | null | undefined;
|
|
104
|
+
deliveries: Array<{
|
|
105
|
+
executionStatus: string | null;
|
|
106
|
+
}>;
|
|
107
|
+
reviewRequestedAt: string | null;
|
|
108
|
+
}): string;
|
|
109
|
+
/**
|
|
110
|
+
* Synchronize `product_focuses.current_workflow_stage_id` with the focus's
|
|
111
|
+
* authoritative stage. The authoritative stage is taken from `focus.stage`
|
|
112
|
+
* when it names one of the new lifecycle stages (Issue 1); otherwise the
|
|
113
|
+
* legacy delivery-aggregate phase derivation applies.
|
|
89
114
|
*
|
|
90
115
|
* Returns the stage ID the focus should be in (post-sync). Falls back to
|
|
91
116
|
* the recorded stage id on error so callers don't have to handle a third
|
|
@@ -95,6 +120,12 @@ export declare function syncFocusPhase(focus: {
|
|
|
95
120
|
focus_id: string;
|
|
96
121
|
current_workflow_stage_id: string | null;
|
|
97
122
|
review_requested_at: string | null;
|
|
123
|
+
/**
|
|
124
|
+
* Denormalized lifecycle stage from product_focuses.stage. Optional for
|
|
125
|
+
* back-compat with old API responses; absence is treated as "fall back to
|
|
126
|
+
* the legacy phase derivation".
|
|
127
|
+
*/
|
|
128
|
+
stage?: string | null;
|
|
98
129
|
}): Promise<string | null>;
|
|
99
130
|
/**
|
|
100
131
|
* Result of a bounded-retry attempt to run a directive. The retry is on
|
|
@@ -145,6 +176,42 @@ export declare function escalateDirectiveFailure(params: {
|
|
|
145
176
|
}, deps?: {
|
|
146
177
|
createEscalation: typeof createEscalation;
|
|
147
178
|
}): Promise<void>;
|
|
179
|
+
/** Test helper: clear the bookkeeper-spawned set. */
|
|
180
|
+
export declare function __resetCloseLoopStateForTesting(): void;
|
|
181
|
+
/**
|
|
182
|
+
* Inspect open escalations and return the set of injection ids that have
|
|
183
|
+
* an active `injection_unverified` escalation (status pending or
|
|
184
|
+
* in_review). Used by the close_loop dispatcher to classify "escalated"
|
|
185
|
+
* injections as terminal.
|
|
186
|
+
*
|
|
187
|
+
* The `metadata.injection_id` field is set by the bookkeeper persona when
|
|
188
|
+
* filing the escalation -- see the close_loop directive prompt.
|
|
189
|
+
*/
|
|
190
|
+
export declare function getOpenInjectionUnverifiedEscalationIds(): Promise<Set<string>>;
|
|
191
|
+
/**
|
|
192
|
+
* Dispatch the close_loop stage for one focus.
|
|
193
|
+
*
|
|
194
|
+
* Reads the focus's anchored deliveries + injection statuses + open
|
|
195
|
+
* escalations, then runs the pure `decideCloseLoop` to determine whether
|
|
196
|
+
* to short-circuit, spawn a bookkeeper, advance to done, or hold.
|
|
197
|
+
*
|
|
198
|
+
* Returns the decision so the caller (or a test) can log/assert.
|
|
199
|
+
*
|
|
200
|
+
* Idempotent across poll cycles -- the `closeLoopBookkeeperSpawned` set
|
|
201
|
+
* ensures the bookkeeper is spawned at most once per focus visit to
|
|
202
|
+
* close_loop. Tests reset this via `__resetCloseLoopStateForTesting`.
|
|
203
|
+
*/
|
|
204
|
+
export declare function dispatchCloseLoopStage(config: DaemonConfig, focus: {
|
|
205
|
+
focus_id: string;
|
|
206
|
+
focus_name: string;
|
|
207
|
+
}): Promise<CloseLoopDecision>;
|
|
208
|
+
/**
|
|
209
|
+
* Pure helper exported for tests: build the close_loop directive and verify
|
|
210
|
+
* it carries the expected assembly + model. The buildCloseLoopDirective
|
|
211
|
+
* function in close-loop-dispatcher.ts already does this; this is a
|
|
212
|
+
* dispatcher-side smoke export so the tests can grep through it.
|
|
213
|
+
*/
|
|
214
|
+
export declare function getCloseLoopDirectiveForTesting(): StageDirective;
|
|
148
215
|
/**
|
|
149
216
|
* Check all active focuses for stage changes with directives.
|
|
150
217
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"directive-executor.d.ts","sourceRoot":"","sources":["../src/directive-executor.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAI/D,OAAO,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"directive-executor.d.ts","sourceRoot":"","sources":["../src/directive-executor.ts"],"names":[],"mappings":"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"}
|