@telora/daemon 0.17.59 → 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 +19 -3
- package/dist/cascade-restatement.d.ts +10 -0
- package/dist/cascade-restatement.d.ts.map +1 -1
- package/dist/cascade-restatement.js +107 -37
- package/dist/cascade-restatement.js.map +1 -1
- package/dist/ci-escalation.d.ts.map +1 -1
- package/dist/ci-escalation.js +5 -3
- package/dist/ci-escalation.js.map +1 -1
- package/dist/cli/backfill-frt-prose.d.ts +101 -0
- package/dist/cli/backfill-frt-prose.d.ts.map +1 -0
- package/dist/cli/backfill-frt-prose.js +195 -0
- package/dist/cli/backfill-frt-prose.js.map +1 -0
- package/dist/completion/event-escalations.d.ts +4 -11
- package/dist/completion/event-escalations.d.ts.map +1 -1
- package/dist/completion/event-escalations.js +21 -5
- package/dist/completion/event-escalations.js.map +1 -1
- package/dist/completion/event.d.ts +4 -11
- package/dist/completion/event.d.ts.map +1 -1
- package/dist/completion/event.js.map +1 -1
- package/dist/completion/review-exit-phase.d.ts.map +1 -1
- package/dist/completion/review-exit-phase.js +37 -7
- 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/crash-recovery-cleanup.d.ts.map +1 -1
- package/dist/crash-recovery-cleanup.js +7 -1
- package/dist/crash-recovery-cleanup.js.map +1 -1
- package/dist/crash-recovery-types.d.ts +4 -9
- package/dist/crash-recovery-types.d.ts.map +1 -1
- package/dist/crash-recovery-types.js.map +1 -1
- package/dist/crash-recovery.d.ts +4 -9
- package/dist/crash-recovery.d.ts.map +1 -1
- package/dist/crash-recovery.js +5 -1
- package/dist/crash-recovery.js.map +1 -1
- package/dist/delivery-advance-block.d.ts +8 -6
- package/dist/delivery-advance-block.d.ts.map +1 -1
- package/dist/delivery-advance-block.js +14 -12
- package/dist/delivery-advance-block.js.map +1 -1
- package/dist/delivery-guards.d.ts.map +1 -1
- package/dist/delivery-guards.js +4 -1
- package/dist/delivery-guards.js.map +1 -1
- package/dist/delivery-lifecycle.d.ts.map +1 -1
- package/dist/delivery-lifecycle.js +47 -1
- package/dist/delivery-lifecycle.js.map +1 -1
- package/dist/delivery-merge.d.ts.map +1 -1
- package/dist/delivery-merge.js +5 -1
- package/dist/delivery-merge.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/directive/directive-dispatch.d.ts.map +1 -1
- package/dist/directive/directive-dispatch.js +4 -1
- package/dist/directive/directive-dispatch.js.map +1 -1
- package/dist/escalation-provenance.d.ts +60 -0
- package/dist/escalation-provenance.d.ts.map +1 -0
- package/dist/escalation-provenance.js +153 -0
- package/dist/escalation-provenance.js.map +1 -0
- package/dist/escalations.d.ts +33 -3
- package/dist/escalations.d.ts.map +1 -1
- package/dist/escalations.js +58 -12
- package/dist/escalations.js.map +1 -1
- package/dist/focus-executor.js +1 -1
- package/dist/focus-executor.js.map +1 -1
- package/dist/focus-merge.d.ts.map +1 -1
- package/dist/focus-merge.js +3 -1
- package/dist/focus-merge.js.map +1 -1
- package/dist/focus-stage-lifecycle.d.ts.map +1 -1
- package/dist/focus-stage-lifecycle.js +5 -2
- package/dist/focus-stage-lifecycle.js.map +1 -1
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -1
- package/dist/listener-auto-advance.d.ts.map +1 -1
- package/dist/listener-auto-advance.js +73 -34
- package/dist/listener-auto-advance.js.map +1 -1
- package/dist/listener.d.ts.map +1 -1
- package/dist/listener.js +12 -0
- package/dist/listener.js.map +1 -1
- package/dist/merge-back-loop.d.ts.map +1 -1
- package/dist/merge-back-loop.js +7 -2
- package/dist/merge-back-loop.js.map +1 -1
- package/dist/nexus-escalation-bridge.d.ts +92 -0
- package/dist/nexus-escalation-bridge.d.ts.map +1 -0
- package/dist/nexus-escalation-bridge.js +109 -0
- package/dist/nexus-escalation-bridge.js.map +1 -0
- package/dist/nexus-incoming.d.ts +47 -0
- package/dist/nexus-incoming.d.ts.map +1 -0
- package/dist/nexus-incoming.js +93 -0
- package/dist/nexus-incoming.js.map +1 -0
- package/dist/nexus-return.d.ts +131 -0
- package/dist/nexus-return.d.ts.map +1 -0
- package/dist/nexus-return.js +326 -0
- package/dist/nexus-return.js.map +1 -0
- package/dist/queries/deliveries.d.ts +12 -0
- package/dist/queries/deliveries.d.ts.map +1 -1
- package/dist/queries/deliveries.js +17 -0
- package/dist/queries/deliveries.js.map +1 -1
- package/dist/queries/issues.d.ts +62 -12
- package/dist/queries/issues.d.ts.map +1 -1
- package/dist/queries/issues.js +46 -13
- package/dist/queries/issues.js.map +1 -1
- package/dist/resolvers/escalation-answers.d.ts +22 -0
- package/dist/resolvers/escalation-answers.d.ts.map +1 -0
- package/dist/resolvers/escalation-answers.js +98 -0
- package/dist/resolvers/escalation-answers.js.map +1 -0
- package/dist/resolvers/index.d.ts.map +1 -1
- package/dist/resolvers/index.js +2 -0
- package/dist/resolvers/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -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":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AA8DzE,wEAAwE;AAExE;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAAsC;IAC1E,MAAM,IAAI,GAAG,gBAAgB,CAAC,CAAC,GAAG,MAAM,CAAsB,CAAC,CAAC;IAChE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAC7D,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,aAAa,CAAC,MAAsC;IAClE,OAAO,gBAAgB,CAAC,CAAC,GAAG,MAAM,CAAsB,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;AACvE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,MAAsC;IAChE,OAAO,gBAAgB,CAAC,CAAC,GAAG,MAAM,CAAsB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AACzG,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,aAAa,CAAC,MAAsC;IAClE,OAAO,gBAAgB,CAAC,CAAC,GAAG,MAAM,CAAsB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC;AAClG,CAAC;AAED,wEAAwE;AAExE,SAAS,MAAM,CAAC,aAA8B,EAAE,MAAuB,EAAE,MAAc;IACrF,MAAM,OAAO,GAAG,MAAM,KAAK,aAAa,CAAC;IACzC,OAAO;QACL,MAAM;QACN,OAAO;QACP,MAAM;QACN,SAAS,EAAE,CAAC,OAAO,IAAI,iBAAiB,CAAC,aAAa,EAAE,MAAM,CAAC;KAChE,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAqB;IAC3D,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC;IAC7E,MAAM,OAAO,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAEtC,QAAQ,aAAa,EAAE,CAAC;QACtB,KAAK,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;YAC5B,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC,MAAM,EAAE,gDAAgD,CAAC,CAAC;YACzG,CAAC;YACD,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC,MAAM,EAAE,kEAAkE,CAAC,CAAC;YAC3H,CAAC;YACD,IAAI,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC1B,OAAO,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC,MAAM,EAAE,4BAA4B,CAAC,CAAC;YACrF,CAAC;YACD,OAAO,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC,MAAM,EAAE,iCAAiC,CAAC,CAAC;QAC1F,CAAC;QAED,KAAK,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;YAC5B,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC,MAAM,EAAE,+BAA+B,CAAC,CAAC;YACxF,CAAC;YACD,IAAI,CAAC,QAAQ,CAAC,iBAAiB,EAAE,CAAC;gBAChC,OAAO,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC,MAAM,EAAE,uFAAuF,CAAC,CAAC;YAChJ,CAAC;YACD,IAAI,YAAY,EAAE,OAAO,EAAE,CAAC;gBAC1B,OAAO,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC,MAAM,EAAE,wCAAwC,CAAC,CAAC;YACjG,CAAC;YACD,OAAO,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC,MAAM,EAAE,8CAA8C,CAAC,CAAC;QACvG,CAAC;QAED,KAAK,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;YAC5B,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC,aAAa,EAAE,iDAAiD,CAAC,CAAC;YACjH,CAAC;YACD,IAAI,YAAY,EAAE,OAAO,EAAE,CAAC;gBAC1B,OAAO,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC,MAAM,EAAE,qCAAqC,CAAC,CAAC;YAC9F,CAAC;YACD,IAAI,WAAW,EAAE,YAAY,EAAE,CAAC;gBAC9B,OAAO,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC,IAAI,EAAE,wCAAwC,CAAC,CAAC;YAC/F,CAAC;YACD,IAAI,WAAW,EAAE,WAAW,KAAK,QAAQ,IAAI,WAAW,CAAC,SAAS,EAAE,CAAC;gBACnE,OAAO,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC,IAAI,EAAE,wDAAwD,CAAC,CAAC;YAC/G,CAAC;YACD,OAAO,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC,MAAM,EAAE,sDAAsD,CAAC,CAAC;QAC/G,CAAC;QAED,KAAK,eAAe,CAAC,aAAa,CAAC,CAAC,CAAC;YACnC,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC,MAAM,EAAE,0CAA0C,CAAC,CAAC;YACnG,CAAC;YACD,OAAO,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC,MAAM,EAAE,iDAAiD,CAAC,CAAC;QAC1G,CAAC;QAED,kEAAkE;QAClE,kEAAkE;QAClE,6BAA6B;QAC7B;YACE,OAAO,MAAM,CAAC,aAAa,EAAE,aAAa,EAAE,WAAW,aAAa,oCAAoC,CAAC,CAAC;IAC9G,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"directive-dispatch.d.ts","sourceRoot":"","sources":["../../src/directive/directive-dispatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAExF,OAAO,EAAsB,KAAK,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAG7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAWxD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,OAAO,EAAE,MAAM,GACd,sBAAsB,GAAG,IAAI,CAI/B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,cAAc,EACzB,oBAAoB,EAAE,MAAM,EAC5B,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAiCf;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,cAAc,EACzB,WAAW,GAAE,QAAQ,GAAG,QAAmB,EAC3C,IAAI,GAAE,WAA+E,GACpF,OAAO,CAAC,IAAI,CAAC,CAyEf;AA8ED;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IACjC,sEAAsE;IACtE,EAAE,EAAE,OAAO,CAAC;IACZ,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,+DAA+D;IAC/D,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC3D;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EACvB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,CAuB7B;AAED;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE;IACN,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,EACD,IAAI,GAAE;IAAE,gBAAgB,EAAE,OAAO,gBAAgB,CAAA;CAAyB,GACzE,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"directive-dispatch.d.ts","sourceRoot":"","sources":["../../src/directive/directive-dispatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAExF,OAAO,EAAsB,KAAK,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAG7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAWxD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,OAAO,EAAE,MAAM,GACd,sBAAsB,GAAG,IAAI,CAI/B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,cAAc,EACzB,oBAAoB,EAAE,MAAM,EAC5B,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAiCf;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,cAAc,EACzB,WAAW,GAAE,QAAQ,GAAG,QAAmB,EAC3C,IAAI,GAAE,WAA+E,GACpF,OAAO,CAAC,IAAI,CAAC,CAyEf;AA8ED;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IACjC,sEAAsE;IACtE,EAAE,EAAE,OAAO,CAAC;IACZ,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,+DAA+D;IAC/D,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC3D;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EACvB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,CAuB7B;AAED;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE;IACN,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,EACD,IAAI,GAAE;IAAE,gBAAgB,EAAE,OAAO,gBAAgB,CAAA;CAAyB,GACzE,OAAO,CAAC,IAAI,CAAC,CAyCf"}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { getActiveTeams } from '../focus-team-state.js';
|
|
13
13
|
import { resolveLineageSpec } from '../session-lineage.js';
|
|
14
|
-
import { sendMessage, ESCALATION_REASONS } from '@telora/daemon-core';
|
|
14
|
+
import { sendMessage, ESCALATION_REASONS, ESCALATION_DISPOSITIONS } from '@telora/daemon-core';
|
|
15
15
|
import { terminateTeam, waitForTeamExit } from '../completion/index.js';
|
|
16
16
|
import { createEscalation } from '../queries/issues.js';
|
|
17
17
|
import { pendingSpawnDirectives, computeDirectiveHash, SPAWN_GUARD_WINDOW_MS, shouldSkipSpawnDirective, } from './directive-queue.js';
|
|
@@ -251,6 +251,9 @@ export async function escalateDirectiveFailure(params, deps = { createEscalation
|
|
|
251
251
|
sessionId: params.sessionId,
|
|
252
252
|
issueId: null,
|
|
253
253
|
reasonType: ESCALATION_REASONS.ERROR_ENCOUNTERED,
|
|
254
|
+
// Operator triage: a broken assembly resolver / malformed directive.
|
|
255
|
+
disposition: ESCALATION_DISPOSITIONS.NEEDS_OPERATOR,
|
|
256
|
+
anchor: { focusId: params.focusId, sessionId: params.sessionId },
|
|
254
257
|
description: `Stage directive execution for focus "${params.focusName}" failed after ` +
|
|
255
258
|
`${params.attempts} attempts on stage "${stageLabel}".\n\n` +
|
|
256
259
|
`**Focus:** ${params.focusName}\n` +
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"directive-dispatch.js","sourceRoot":"","sources":["../../src/directive/directive-dispatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAoB,MAAM,uBAAuB,CAAC;AAC7E,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"directive-dispatch.js","sourceRoot":"","sources":["../../src/directive/directive-dispatch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Central escalation-provenance resolver.
|
|
3
|
+
*
|
|
4
|
+
* Delivery C (injection #11): ONE helper derives {productId, focusId,
|
|
5
|
+
* deliveryId} from whatever anchor a creation site holds, so the shared
|
|
6
|
+
* createEscalation path can stamp the first-class provenance columns on
|
|
7
|
+
* agent_escalations. No site can file an anonymous escalation by
|
|
8
|
+
* construction -- it passes whatever anchor it has and the resolver fills
|
|
9
|
+
* in the rest.
|
|
10
|
+
*
|
|
11
|
+
* Derivation facts (the schema this depends on):
|
|
12
|
+
* - A delivery IS an org_node carrying product_id + focus_id.
|
|
13
|
+
* - A focus carries product_id.
|
|
14
|
+
* So:
|
|
15
|
+
* - deliveryId -> resolve the delivery context to get focusId + productId.
|
|
16
|
+
* - focusId -> resolve focus to productId (best-effort via the
|
|
17
|
+
* active-focus listing; the focusId is always set verbatim).
|
|
18
|
+
* - issueId -> resolve issue.deliveryId, then treat as a delivery.
|
|
19
|
+
* - sessionId -> resolve the session row to its deliveryId/focusId.
|
|
20
|
+
* - branch -> best-effort via the session row carrying that branch.
|
|
21
|
+
*
|
|
22
|
+
* INVARIANT: resolveProvenance NEVER throws. A missing/unresolvable anchor
|
|
23
|
+
* returns {} (or whatever partial provenance it could derive). Provenance is
|
|
24
|
+
* signal enrichment, not control flow -- a lookup failure must never abort
|
|
25
|
+
* the escalation it accompanies.
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* Whatever a creation site holds when it files an escalation. Every field is
|
|
29
|
+
* optional; a site passes the subset it knows. The resolver derives the rest.
|
|
30
|
+
*/
|
|
31
|
+
export interface EscalationAnchor {
|
|
32
|
+
/** A delivery id (org_node, type='delivery'). The richest anchor. */
|
|
33
|
+
deliveryId?: string;
|
|
34
|
+
/** A focus id (product_focuses). */
|
|
35
|
+
focusId?: string;
|
|
36
|
+
/** An issue id (resolved to its delivery, then as a delivery). */
|
|
37
|
+
issueId?: string;
|
|
38
|
+
/** An agent session id (resolved to its delivery/focus). */
|
|
39
|
+
sessionId?: string;
|
|
40
|
+
/** A git branch name (best-effort: resolved via a session carrying it). */
|
|
41
|
+
branch?: string;
|
|
42
|
+
}
|
|
43
|
+
/** First-class provenance derived from an anchor. */
|
|
44
|
+
export interface ResolvedProvenance {
|
|
45
|
+
productId?: string;
|
|
46
|
+
focusId?: string;
|
|
47
|
+
deliveryId?: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Derive first-class provenance from whatever anchor a creation site holds.
|
|
51
|
+
*
|
|
52
|
+
* Resolution precedence (richest first): deliveryId > issueId > sessionId >
|
|
53
|
+
* branch > focusId. A more specific anchor implies the broader scopes, so the
|
|
54
|
+
* first resolvable anchor wins and we stop. focusId, when also supplied, is
|
|
55
|
+
* merged in as a floor (it never gets clobbered to a worse value).
|
|
56
|
+
*
|
|
57
|
+
* NEVER throws -- returns {} when nothing resolves.
|
|
58
|
+
*/
|
|
59
|
+
export declare function resolveProvenance(anchor: EscalationAnchor): Promise<ResolvedProvenance>;
|
|
60
|
+
//# sourceMappingURL=escalation-provenance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escalation-provenance.d.ts","sourceRoot":"","sources":["../src/escalation-provenance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAKH;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qDAAqD;AACrD,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAyED;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA0C7F"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Central escalation-provenance resolver.
|
|
3
|
+
*
|
|
4
|
+
* Delivery C (injection #11): ONE helper derives {productId, focusId,
|
|
5
|
+
* deliveryId} from whatever anchor a creation site holds, so the shared
|
|
6
|
+
* createEscalation path can stamp the first-class provenance columns on
|
|
7
|
+
* agent_escalations. No site can file an anonymous escalation by
|
|
8
|
+
* construction -- it passes whatever anchor it has and the resolver fills
|
|
9
|
+
* in the rest.
|
|
10
|
+
*
|
|
11
|
+
* Derivation facts (the schema this depends on):
|
|
12
|
+
* - A delivery IS an org_node carrying product_id + focus_id.
|
|
13
|
+
* - A focus carries product_id.
|
|
14
|
+
* So:
|
|
15
|
+
* - deliveryId -> resolve the delivery context to get focusId + productId.
|
|
16
|
+
* - focusId -> resolve focus to productId (best-effort via the
|
|
17
|
+
* active-focus listing; the focusId is always set verbatim).
|
|
18
|
+
* - issueId -> resolve issue.deliveryId, then treat as a delivery.
|
|
19
|
+
* - sessionId -> resolve the session row to its deliveryId/focusId.
|
|
20
|
+
* - branch -> best-effort via the session row carrying that branch.
|
|
21
|
+
*
|
|
22
|
+
* INVARIANT: resolveProvenance NEVER throws. A missing/unresolvable anchor
|
|
23
|
+
* returns {} (or whatever partial provenance it could derive). Provenance is
|
|
24
|
+
* signal enrichment, not control flow -- a lookup failure must never abort
|
|
25
|
+
* the escalation it accompanies.
|
|
26
|
+
*/
|
|
27
|
+
import { getDeliveryContext, getActiveFocuses, getIssueDelivery } from './queries/deliveries.js';
|
|
28
|
+
import { getActiveSessions } from './queries/sessions.js';
|
|
29
|
+
/**
|
|
30
|
+
* Resolve a delivery id to {productId, focusId, deliveryId}. Best-effort:
|
|
31
|
+
* returns at least { deliveryId } even when the context lookup fails.
|
|
32
|
+
*/
|
|
33
|
+
async function fromDelivery(deliveryId) {
|
|
34
|
+
const out = { deliveryId };
|
|
35
|
+
try {
|
|
36
|
+
const ctx = await getDeliveryContext(deliveryId);
|
|
37
|
+
if (ctx) {
|
|
38
|
+
// Delivery is transformed to the snake_case Delivery domain type
|
|
39
|
+
// (product_id); focus is the camelCase API shape (id).
|
|
40
|
+
if (ctx.delivery?.product_id)
|
|
41
|
+
out.productId = ctx.delivery.product_id ?? undefined;
|
|
42
|
+
const focusId = ctx.focus?.id;
|
|
43
|
+
if (focusId)
|
|
44
|
+
out.focusId = focusId;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// Best-effort: keep the delivery id; leave focus/product unset.
|
|
49
|
+
}
|
|
50
|
+
return out;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Resolve a focus id to {productId, focusId}. Best-effort: the focusId is
|
|
54
|
+
* always returned; productId is filled when the active-focus listing carries
|
|
55
|
+
* it. (There is no single-focus getter in the query layer; this derives the
|
|
56
|
+
* product from the focuses the daemon already enumerates.)
|
|
57
|
+
*/
|
|
58
|
+
async function fromFocus(focusId) {
|
|
59
|
+
const out = { focusId };
|
|
60
|
+
try {
|
|
61
|
+
const focuses = await getActiveFocuses('');
|
|
62
|
+
const match = focuses.find((f) => f.focus_id === focusId);
|
|
63
|
+
if (match?.product_id)
|
|
64
|
+
out.productId = match.product_id;
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
// Best-effort: keep the focus id; leave product unset.
|
|
68
|
+
}
|
|
69
|
+
return out;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Resolve a session id (or a branch name) to its delivery/focus via the
|
|
73
|
+
* active-session listing, then enrich from the delivery. Best-effort.
|
|
74
|
+
*/
|
|
75
|
+
async function fromSessionOrBranch(anchor) {
|
|
76
|
+
try {
|
|
77
|
+
const sessions = await getActiveSessions();
|
|
78
|
+
const match = sessions.find((s) => (anchor.sessionId && s.id === anchor.sessionId) ||
|
|
79
|
+
(anchor.branch && s.branch_name === anchor.branch));
|
|
80
|
+
if (!match)
|
|
81
|
+
return {};
|
|
82
|
+
if (match.delivery_id) {
|
|
83
|
+
// Delivery anchor is richest -- derive product/focus from it.
|
|
84
|
+
const fromDel = await fromDelivery(match.delivery_id);
|
|
85
|
+
// The session may carry a focus id even when the delivery context omits one.
|
|
86
|
+
if (!fromDel.focusId && match.focus_id)
|
|
87
|
+
fromDel.focusId = match.focus_id;
|
|
88
|
+
return fromDel;
|
|
89
|
+
}
|
|
90
|
+
const out = {};
|
|
91
|
+
if (match.focus_id) {
|
|
92
|
+
return { ...out, ...(await fromFocus(match.focus_id)) };
|
|
93
|
+
}
|
|
94
|
+
return out;
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return {};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Derive first-class provenance from whatever anchor a creation site holds.
|
|
102
|
+
*
|
|
103
|
+
* Resolution precedence (richest first): deliveryId > issueId > sessionId >
|
|
104
|
+
* branch > focusId. A more specific anchor implies the broader scopes, so the
|
|
105
|
+
* first resolvable anchor wins and we stop. focusId, when also supplied, is
|
|
106
|
+
* merged in as a floor (it never gets clobbered to a worse value).
|
|
107
|
+
*
|
|
108
|
+
* NEVER throws -- returns {} when nothing resolves.
|
|
109
|
+
*/
|
|
110
|
+
export async function resolveProvenance(anchor) {
|
|
111
|
+
if (!anchor)
|
|
112
|
+
return {};
|
|
113
|
+
let resolved = {};
|
|
114
|
+
if (anchor.deliveryId) {
|
|
115
|
+
resolved = await fromDelivery(anchor.deliveryId);
|
|
116
|
+
}
|
|
117
|
+
else if (anchor.issueId) {
|
|
118
|
+
// Resolve issue -> delivery -> focus/product via the daemon_get_issue_delivery
|
|
119
|
+
// edge action. Best-effort: returns {} when the issue is not found.
|
|
120
|
+
try {
|
|
121
|
+
const issueDelivery = await getIssueDelivery(anchor.issueId);
|
|
122
|
+
if (issueDelivery) {
|
|
123
|
+
resolved = {
|
|
124
|
+
deliveryId: issueDelivery.deliveryId,
|
|
125
|
+
...(issueDelivery.focusId ? { focusId: issueDelivery.focusId } : {}),
|
|
126
|
+
...(issueDelivery.productId ? { productId: issueDelivery.productId } : {}),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
// Best-effort: fall through with empty resolved.
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
else if (anchor.sessionId || anchor.branch) {
|
|
135
|
+
resolved = await fromSessionOrBranch({ sessionId: anchor.sessionId, branch: anchor.branch });
|
|
136
|
+
}
|
|
137
|
+
// A directly supplied focusId is a floor: merge it in if resolution did not
|
|
138
|
+
// already produce one, and use it to backfill productId when missing.
|
|
139
|
+
if (!resolved.focusId && anchor.focusId) {
|
|
140
|
+
const fromF = await fromFocus(anchor.focusId);
|
|
141
|
+
// Prefer a resolved productId; otherwise take the focus-derived one. Build
|
|
142
|
+
// the result without ever introducing an explicit `productId: undefined`
|
|
143
|
+
// key (callers/tests treat absence and undefined differently).
|
|
144
|
+
const productId = resolved.productId ?? fromF.productId;
|
|
145
|
+
resolved = {
|
|
146
|
+
...fromF,
|
|
147
|
+
...resolved,
|
|
148
|
+
...(productId !== undefined ? { productId } : {}),
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
return resolved;
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=escalation-provenance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escalation-provenance.js","sourceRoot":"","sources":["../src/escalation-provenance.ts"],"names":[],"mappings":"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"}
|
package/dist/escalations.d.ts
CHANGED
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
* config at the wiring site) and folds focus/product/details into the
|
|
14
14
|
* escalation metadata. No business logic lives here.
|
|
15
15
|
*/
|
|
16
|
-
import { type EscalationReasonType } from '@telora/daemon-core';
|
|
16
|
+
import { type EscalationReasonType, type EscalationDisposition } from '@telora/daemon-core';
|
|
17
|
+
import { type NexusEscalationBridgeDeps } from './nexus-escalation-bridge.js';
|
|
17
18
|
/** Controller-facing escalation input (narrow; tests inject a fake). */
|
|
18
19
|
export interface FileEscalationInput {
|
|
19
20
|
/** Org scope; required by the underlying transport. */
|
|
@@ -35,10 +36,39 @@ export interface FileEscalationInput {
|
|
|
35
36
|
* 'decision_needed' -- a stalled/diverged PRD needs a human decision.
|
|
36
37
|
*/
|
|
37
38
|
reasonType?: EscalationReasonType;
|
|
38
|
-
/**
|
|
39
|
+
/**
|
|
40
|
+
* Resolution routing axis. Defaults to 'needs_intent' -- a stalled/diverged
|
|
41
|
+
* PRD is an intent-owner decision (Play the PRD, commit a pathway, retire it).
|
|
42
|
+
*/
|
|
43
|
+
disposition?: EscalationDisposition;
|
|
44
|
+
/**
|
|
45
|
+
* Optional machine discriminator for grouping. Carried in metadata under
|
|
46
|
+
* `machine_discriminator` (NOT the DB escalation_kind enum -- PRD machine
|
|
47
|
+
* kinds like 'prd_frontier_blocked_no_role' are not CHECK-valid values).
|
|
48
|
+
*/
|
|
39
49
|
kind?: string;
|
|
40
50
|
/** Arbitrary structured context (prd id, signals, etc.). */
|
|
41
51
|
details?: Record<string, unknown>;
|
|
52
|
+
/**
|
|
53
|
+
* The product this escalation is a blocker AGAINST -- the lateral target. When
|
|
54
|
+
* present alongside sourceProductId and a cross-product reasonType, the
|
|
55
|
+
* escalation is routed to a Nexus request.
|
|
56
|
+
*/
|
|
57
|
+
targetProductId?: string;
|
|
58
|
+
/**
|
|
59
|
+
* The product the blocked agent is working in (the request's source). Distinct
|
|
60
|
+
* from `productId` semantically but typically the same value; kept separate so
|
|
61
|
+
* the routing predicate is explicit about both ends of the lateral channel.
|
|
62
|
+
*/
|
|
63
|
+
sourceProductId?: string;
|
|
64
|
+
/** Source-side focus provenance, passed through to the Nexus request. */
|
|
65
|
+
sourceFocusId?: string;
|
|
66
|
+
/** Source-side delivery provenance, passed through to the Nexus request. */
|
|
67
|
+
sourceDeliveryId?: string;
|
|
68
|
+
/** Title for the Nexus request (falls back to `reason` when omitted). */
|
|
69
|
+
title?: string;
|
|
70
|
+
/** Optional acceptance contract carried onto the Nexus request. */
|
|
71
|
+
acceptanceContract?: string;
|
|
42
72
|
}
|
|
43
73
|
/**
|
|
44
74
|
* File a human escalation from the PRD realign core. Best-effort wrapper over
|
|
@@ -51,5 +81,5 @@ export interface FileEscalationInput {
|
|
|
51
81
|
* in metadata so they survive without tripping the enum/CHECK validation that
|
|
52
82
|
* `reason_type` and `escalation_kind` enforce server-side.
|
|
53
83
|
*/
|
|
54
|
-
export declare function fileEscalation(input: FileEscalationInput): Promise<void>;
|
|
84
|
+
export declare function fileEscalation(input: FileEscalationInput, nexusDeps?: NexusEscalationBridgeDeps): Promise<void>;
|
|
55
85
|
//# sourceMappingURL=escalations.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"escalations.d.ts","sourceRoot":"","sources":["../src/escalations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,
|
|
1
|
+
{"version":3,"file":"escalations.d.ts","sourceRoot":"","sources":["../src/escalations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,8BAA8B,CAAC;AAEtC,wEAAwE;AACxE,MAAM,WAAW,mBAAmB;IAClC,uDAAuD;IACvD,cAAc,EAAE,MAAM,CAAC;IACvB,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,UAAU,CAAC,EAAE,oBAAoB,CAAC;IAClC;;;OAGG;IACH,WAAW,CAAC,EAAE,qBAAqB,CAAC;IACpC;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAOlC;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yEAAyE;IACzE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,mBAAmB,EAC1B,SAAS,CAAC,EAAE,yBAAyB,GACpC,OAAO,CAAC,IAAI,CAAC,CAoEf"}
|
package/dist/escalations.js
CHANGED
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
* config at the wiring site) and folds focus/product/details into the
|
|
14
14
|
* escalation metadata. No business logic lives here.
|
|
15
15
|
*/
|
|
16
|
-
import { createEscalation } from './queries/issues.js';
|
|
17
|
-
import { ESCALATION_REASONS } from '@telora/daemon-core';
|
|
16
|
+
import { createEscalation, markEscalationResolved } from './queries/issues.js';
|
|
17
|
+
import { ESCALATION_REASONS, ESCALATION_DISPOSITIONS, } from '@telora/daemon-core';
|
|
18
|
+
import { maybeRouteToNexus, } from './nexus-escalation-bridge.js';
|
|
18
19
|
/**
|
|
19
20
|
* File a human escalation from the PRD realign core. Best-effort wrapper over
|
|
20
21
|
* `createEscalation`. The transport requires a session id; PRD-controller ticks
|
|
@@ -26,20 +27,65 @@ import { ESCALATION_REASONS } from '@telora/daemon-core';
|
|
|
26
27
|
* in metadata so they survive without tripping the enum/CHECK validation that
|
|
27
28
|
* `reason_type` and `escalation_kind` enforce server-side.
|
|
28
29
|
*/
|
|
29
|
-
export async function fileEscalation(input) {
|
|
30
|
-
|
|
30
|
+
export async function fileEscalation(input, nexusDeps) {
|
|
31
|
+
// ---- Escalation -> Nexus bridge (cross-product blockers) ----
|
|
32
|
+
// BEFORE filing the human escalation: if this is a cross-product blocker that
|
|
33
|
+
// names a target + source product, try to route it into a Nexus request. The
|
|
34
|
+
// disposition router lives in nexus-escalation-bridge.routeEscalation; here we
|
|
35
|
+
// just attempt the route and record whether it landed. Non-cross-product
|
|
36
|
+
// escalations skip this entirely and behave exactly as before.
|
|
37
|
+
const reasonType = input.reasonType ?? ESCALATION_REASONS.DECISION_NEEDED;
|
|
38
|
+
const nexusResult = await maybeRouteToNexus({
|
|
39
|
+
reasonType,
|
|
40
|
+
targetProductId: input.targetProductId,
|
|
41
|
+
sourceProductId: input.sourceProductId,
|
|
42
|
+
sourceFocusId: input.sourceFocusId,
|
|
43
|
+
sourceDeliveryId: input.sourceDeliveryId,
|
|
44
|
+
title: input.title ?? input.reason,
|
|
45
|
+
description: input.reason,
|
|
46
|
+
...(input.acceptanceContract ? { acceptanceContract: input.acceptanceContract } : {}),
|
|
47
|
+
}, nexusDeps);
|
|
48
|
+
// Metadata hygiene (Delivery B): the bag carries EVIDENCE/PAYLOAD only.
|
|
49
|
+
// - machine_reason DROPPED -- it duplicated `description` (= input.reason).
|
|
50
|
+
// - focus_id/product_id DROPPED from metadata -- provenance now lives on the
|
|
51
|
+
// first-class columns, stamped via the anchor below.
|
|
52
|
+
// - machine `kind` is a non-CHECK-valid PRD discriminator, kept as evidence
|
|
53
|
+
// under `machine_discriminator` (it is NOT the DB escalation_kind).
|
|
54
|
+
// When routed to Nexus we ALSO carry the target in metadata so the audit row
|
|
55
|
+
// records the lateral target even if the edge has not yet promoted the
|
|
56
|
+
// target_product_id column write end-to-end.
|
|
57
|
+
const metadata = {
|
|
58
|
+
...(input.kind ? { machine_discriminator: input.kind } : {}),
|
|
59
|
+
...(nexusResult.routed && input.targetProductId
|
|
60
|
+
? { target_product_id: input.targetProductId, nexus_request_id: nexusResult.requestId }
|
|
61
|
+
: {}),
|
|
62
|
+
...(input.details ?? {}),
|
|
63
|
+
};
|
|
64
|
+
const { escalationId } = await createEscalation({
|
|
31
65
|
organizationId: input.organizationId,
|
|
32
66
|
sessionId: '',
|
|
33
67
|
issueId: null,
|
|
34
|
-
reasonType
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
...(input.focusId ? {
|
|
40
|
-
...(input.productId ? { product_id: input.productId } : {}),
|
|
41
|
-
...(input.details ?? {}),
|
|
68
|
+
reasonType,
|
|
69
|
+
disposition: input.disposition ?? ESCALATION_DISPOSITIONS.NEEDS_INTENT,
|
|
70
|
+
// Provenance via the anchor -- focus carries product; the resolver fills
|
|
71
|
+
// any gaps and never throws.
|
|
72
|
+
anchor: {
|
|
73
|
+
...(input.focusId ? { focusId: input.focusId } : {}),
|
|
42
74
|
},
|
|
75
|
+
// A directly-supplied productId still wins (explicit beats derived).
|
|
76
|
+
...(input.productId ? { productId: input.productId } : {}),
|
|
77
|
+
// First-class cross-product target (best-effort column write; the edge may
|
|
78
|
+
// ignore it today, the metadata copy above is the durable carrier).
|
|
79
|
+
...(input.targetProductId ? { targetProductId: input.targetProductId } : {}),
|
|
80
|
+
description: input.reason,
|
|
81
|
+
...(Object.keys(metadata).length > 0 ? { metadata } : {}),
|
|
43
82
|
});
|
|
83
|
+
// When routed to Nexus, the audit escalation must NOT linger in the human
|
|
84
|
+
// pending inbox -- the blocker is now owned by the other product's team. Mark
|
|
85
|
+
// it resolved with a note pointing at the Nexus request. Best-effort: a missing
|
|
86
|
+
// id (older edge build) just leaves the row pending, which is the safe default.
|
|
87
|
+
if (nexusResult.routed && escalationId) {
|
|
88
|
+
await markEscalationResolved(escalationId, `Routed to Nexus request ${nexusResult.requestId}`);
|
|
89
|
+
}
|
|
44
90
|
}
|
|
45
91
|
//# sourceMappingURL=escalations.js.map
|
package/dist/escalations.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"escalations.js","sourceRoot":"","sources":["../src/escalations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"escalations.js","sourceRoot":"","sources":["../src/escalations.ts"],"names":[],"mappings":"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"}
|
package/dist/focus-executor.js
CHANGED
|
@@ -289,7 +289,7 @@ export async function spawnFocusTeam(params) {
|
|
|
289
289
|
organizationId: config.organizationId,
|
|
290
290
|
productId: config.productId,
|
|
291
291
|
};
|
|
292
|
-
return await resolveAssemblyRecipeWithManifest(['loop.context', 'focus.injections'], assemblyCtx);
|
|
292
|
+
return await resolveAssemblyRecipeWithManifest(['loop.context', 'focus.injections', 'escalation.answers'], assemblyCtx);
|
|
293
293
|
}
|
|
294
294
|
catch (err) {
|
|
295
295
|
console.debug(`[focus-executor] Could not fetch loop context (non-fatal):`, err.message);
|