@telora/daemon 0.21.83 → 0.21.134
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 +10 -3
- package/dist/audit/audit-hooks.d.ts +106 -0
- package/dist/audit/audit-hooks.d.ts.map +1 -1
- package/dist/audit/audit-hooks.js +149 -17
- package/dist/audit/audit-hooks.js.map +1 -1
- package/dist/ci/ci-sensor-loop.d.ts +6 -0
- package/dist/ci/ci-sensor-loop.d.ts.map +1 -1
- package/dist/ci/ci-sensor-loop.js +50 -3
- package/dist/ci/ci-sensor-loop.js.map +1 -1
- package/dist/ci/ci-status.d.ts +63 -11
- package/dist/ci/ci-status.d.ts.map +1 -1
- package/dist/ci/ci-status.js +94 -27
- package/dist/ci/ci-status.js.map +1 -1
- package/dist/completion/coverage-drift-state.d.ts +29 -2
- package/dist/completion/coverage-drift-state.d.ts.map +1 -1
- package/dist/completion/coverage-drift-state.js +42 -2
- package/dist/completion/coverage-drift-state.js.map +1 -1
- package/dist/completion/coverage-stabilized.d.ts +58 -0
- package/dist/completion/coverage-stabilized.d.ts.map +1 -0
- package/dist/completion/coverage-stabilized.js +84 -0
- package/dist/completion/coverage-stabilized.js.map +1 -0
- package/dist/completion/delivery-advancement-guard.d.ts +21 -0
- package/dist/completion/delivery-advancement-guard.d.ts.map +1 -1
- package/dist/completion/delivery-advancement-guard.js +31 -3
- package/dist/completion/delivery-advancement-guard.js.map +1 -1
- package/dist/completion/event-escalations.d.ts +15 -0
- package/dist/completion/event-escalations.d.ts.map +1 -1
- package/dist/completion/event-escalations.js +42 -4
- package/dist/completion/event-escalations.js.map +1 -1
- package/dist/completion/event-phases.d.ts.map +1 -1
- package/dist/completion/event-phases.js +10 -5
- package/dist/completion/event-phases.js.map +1 -1
- package/dist/completion/machine-remediable-demotion.d.ts +74 -0
- package/dist/completion/machine-remediable-demotion.d.ts.map +1 -0
- package/dist/completion/machine-remediable-demotion.js +147 -0
- package/dist/completion/machine-remediable-demotion.js.map +1 -0
- package/dist/completion/review-exit-escalations.d.ts +36 -1
- package/dist/completion/review-exit-escalations.d.ts.map +1 -1
- package/dist/completion/review-exit-escalations.js +81 -0
- package/dist/completion/review-exit-escalations.js.map +1 -1
- package/dist/completion/review-exit-phase.d.ts +4 -2
- package/dist/completion/review-exit-phase.d.ts.map +1 -1
- package/dist/completion/review-exit-phase.js +49 -54
- package/dist/completion/review-exit-phase.js.map +1 -1
- package/dist/completion/settle-injection-sweep.d.ts +55 -0
- package/dist/completion/settle-injection-sweep.d.ts.map +1 -0
- package/dist/completion/settle-injection-sweep.js +88 -0
- package/dist/completion/settle-injection-sweep.js.map +1 -0
- package/dist/completion/state-cascade.d.ts.map +1 -1
- package/dist/completion/state-cascade.js +41 -0
- package/dist/completion/state-cascade.js.map +1 -1
- package/dist/completion/status-advance-phase.d.ts.map +1 -1
- package/dist/completion/status-advance-phase.js +28 -30
- package/dist/completion/status-advance-phase.js.map +1 -1
- package/dist/completion/team-lifecycle.d.ts +42 -0
- package/dist/completion/team-lifecycle.d.ts.map +1 -1
- package/dist/completion/team-lifecycle.js +79 -2
- package/dist/completion/team-lifecycle.js.map +1 -1
- package/dist/delivery/delivery-lifecycle.d.ts +19 -33
- package/dist/delivery/delivery-lifecycle.d.ts.map +1 -1
- package/dist/delivery/delivery-lifecycle.js +26 -160
- package/dist/delivery/delivery-lifecycle.js.map +1 -1
- package/dist/delivery/delivery-merge-ops.d.ts +46 -0
- package/dist/delivery/delivery-merge-ops.d.ts.map +1 -0
- package/dist/delivery/delivery-merge-ops.js +154 -0
- package/dist/delivery/delivery-merge-ops.js.map +1 -0
- package/dist/delivery/delivery-reconciler-apply.d.ts +108 -66
- package/dist/delivery/delivery-reconciler-apply.d.ts.map +1 -1
- package/dist/delivery/delivery-reconciler-apply.js +87 -61
- package/dist/delivery/delivery-reconciler-apply.js.map +1 -1
- package/dist/delivery/delivery-reconciler.d.ts +7 -2
- package/dist/delivery/delivery-reconciler.d.ts.map +1 -1
- package/dist/delivery/delivery-reconciler.js +34 -5
- package/dist/delivery/delivery-reconciler.js.map +1 -1
- package/dist/delivery/external-hold-surface.d.ts +32 -0
- package/dist/delivery/external-hold-surface.d.ts.map +1 -0
- package/dist/delivery/external-hold-surface.js +67 -0
- package/dist/delivery/external-hold-surface.js.map +1 -0
- package/dist/delivery/external-hold.d.ts +38 -0
- package/dist/delivery/external-hold.d.ts.map +1 -1
- package/dist/delivery/external-hold.js +69 -6
- package/dist/delivery/external-hold.js.map +1 -1
- package/dist/delivery/operator-hold.d.ts +1 -2
- package/dist/delivery/operator-hold.d.ts.map +1 -1
- package/dist/delivery/operator-hold.js +1 -2
- package/dist/delivery/operator-hold.js.map +1 -1
- package/dist/delivery/paused-revival.d.ts +140 -0
- package/dist/delivery/paused-revival.d.ts.map +1 -0
- package/dist/delivery/paused-revival.js +229 -0
- package/dist/delivery/paused-revival.js.map +1 -0
- package/dist/delivery/wait-reachability.d.ts +149 -0
- package/dist/delivery/wait-reachability.d.ts.map +1 -0
- package/dist/delivery/wait-reachability.js +193 -0
- package/dist/delivery/wait-reachability.js.map +1 -0
- package/dist/directive/close-loop-dispatcher.d.ts +16 -263
- package/dist/directive/close-loop-dispatcher.d.ts.map +1 -1
- package/dist/directive/close-loop-dispatcher.js +21 -259
- package/dist/directive/close-loop-dispatcher.js.map +1 -1
- package/dist/directive/directive-dispatch.d.ts +19 -0
- package/dist/directive/directive-dispatch.d.ts.map +1 -1
- package/dist/directive/directive-dispatch.js +18 -0
- package/dist/directive/directive-dispatch.js.map +1 -1
- package/dist/directive/directive-executor.d.ts +1 -3
- package/dist/directive/directive-executor.d.ts.map +1 -1
- package/dist/directive/directive-executor.js +23 -21
- package/dist/directive/directive-executor.js.map +1 -1
- package/dist/directive/phase-sync.d.ts +28 -15
- package/dist/directive/phase-sync.d.ts.map +1 -1
- package/dist/directive/phase-sync.js +28 -36
- package/dist/directive/phase-sync.js.map +1 -1
- package/dist/directive/resolver-dispatch.d.ts +19 -92
- package/dist/directive/resolver-dispatch.d.ts.map +1 -1
- package/dist/directive/resolver-dispatch.js +19 -65
- package/dist/directive/resolver-dispatch.js.map +1 -1
- package/dist/focus/focus-engine.d.ts.map +1 -1
- package/dist/focus/focus-engine.js +26 -0
- package/dist/focus/focus-engine.js.map +1 -1
- package/dist/focus/focus-executor.d.ts.map +1 -1
- package/dist/focus/focus-executor.js +290 -256
- package/dist/focus/focus-executor.js.map +1 -1
- package/dist/focus/focus-loop-registry.d.ts.map +1 -1
- package/dist/focus/focus-loop-registry.js +43 -1
- package/dist/focus/focus-loop-registry.js.map +1 -1
- package/dist/focus/focus-respawn-guard.d.ts.map +1 -1
- package/dist/focus/focus-respawn-guard.js +11 -2
- package/dist/focus/focus-respawn-guard.js.map +1 -1
- package/dist/focus/focus-team-state.d.ts +11 -0
- package/dist/focus/focus-team-state.d.ts.map +1 -1
- package/dist/focus/focus-team-state.js +17 -0
- package/dist/focus/focus-team-state.js.map +1 -1
- package/dist/focus/listener-auto-advance.d.ts +13 -1
- package/dist/focus/listener-auto-advance.d.ts.map +1 -1
- package/dist/focus/listener-auto-advance.js +112 -76
- package/dist/focus/listener-auto-advance.js.map +1 -1
- package/dist/focus/listener.d.ts.map +1 -1
- package/dist/focus/listener.js +141 -75
- package/dist/focus/listener.js.map +1 -1
- package/dist/focus/tick-deadline.d.ts +55 -0
- package/dist/focus/tick-deadline.d.ts.map +1 -0
- package/dist/focus/tick-deadline.js +91 -0
- package/dist/focus/tick-deadline.js.map +1 -0
- package/dist/focus-stage-lifecycle/index.d.ts +18 -25
- package/dist/focus-stage-lifecycle/index.d.ts.map +1 -1
- package/dist/focus-stage-lifecycle/index.js +26 -38
- package/dist/focus-stage-lifecycle/index.js.map +1 -1
- package/dist/focus-stage-lifecycle/wedge-cause-arbiter.d.ts +52 -0
- package/dist/focus-stage-lifecycle/wedge-cause-arbiter.d.ts.map +1 -0
- package/dist/focus-stage-lifecycle/wedge-cause-arbiter.js +94 -0
- package/dist/focus-stage-lifecycle/wedge-cause-arbiter.js.map +1 -0
- package/dist/focus-stage-lifecycle/wedge-watchdog.d.ts +18 -1
- package/dist/focus-stage-lifecycle/wedge-watchdog.d.ts.map +1 -1
- package/dist/focus-stage-lifecycle/wedge-watchdog.js +57 -7
- package/dist/focus-stage-lifecycle/wedge-watchdog.js.map +1 -1
- package/dist/git/merge.d.ts.map +1 -1
- package/dist/git/merge.js +12 -3
- package/dist/git/merge.js.map +1 -1
- package/dist/guard/condition-evaluators.d.ts +9 -0
- package/dist/guard/condition-evaluators.d.ts.map +1 -1
- package/dist/guard/condition-evaluators.js +15 -0
- package/dist/guard/condition-evaluators.js.map +1 -1
- package/dist/guard/guard-evaluator.d.ts +17 -1
- package/dist/guard/guard-evaluator.d.ts.map +1 -1
- package/dist/guard/guard-evaluator.js +61 -2
- package/dist/guard/guard-evaluator.js.map +1 -1
- package/dist/guard/trigger-executor.d.ts +30 -18
- package/dist/guard/trigger-executor.d.ts.map +1 -1
- package/dist/guard/trigger-executor.js +55 -31
- package/dist/guard/trigger-executor.js.map +1 -1
- package/dist/prompt/team-prompt-base.d.ts +1 -1
- package/dist/prompt/team-prompt-base.d.ts.map +1 -1
- package/dist/prompt/team-prompt-base.js +1 -1
- package/dist/prompt/team-prompt-base.js.map +1 -1
- package/dist/prompt-sections/persona-sections.d.ts +0 -32
- package/dist/prompt-sections/persona-sections.d.ts.map +1 -1
- package/dist/prompt-sections/persona-sections.js +19 -88
- package/dist/prompt-sections/persona-sections.js.map +1 -1
- package/dist/queries/deliveries.d.ts +33 -0
- package/dist/queries/deliveries.d.ts.map +1 -1
- package/dist/queries/deliveries.js +7 -0
- package/dist/queries/deliveries.js.map +1 -1
- package/dist/queries/focuses.d.ts +46 -0
- package/dist/queries/focuses.d.ts.map +1 -1
- package/dist/queries/focuses.js +60 -0
- package/dist/queries/focuses.js.map +1 -1
- package/dist/queries/guards.d.ts +10 -0
- package/dist/queries/guards.d.ts.map +1 -1
- package/dist/queries/guards.js +14 -1
- package/dist/queries/guards.js.map +1 -1
- package/dist/queries/issues.d.ts +65 -1
- package/dist/queries/issues.d.ts.map +1 -1
- package/dist/queries/issues.js +135 -2
- package/dist/queries/issues.js.map +1 -1
- package/dist/queries/schemas.d.ts +53 -0
- package/dist/queries/schemas.d.ts.map +1 -1
- package/dist/queries/schemas.js +38 -0
- package/dist/queries/schemas.js.map +1 -1
- package/dist/queries/verification.d.ts +5 -6
- package/dist/queries/verification.d.ts.map +1 -1
- package/dist/queries/verification.js +5 -6
- package/dist/queries/verification.js.map +1 -1
- package/dist/resolvers/loop-persona.d.ts +1 -11
- package/dist/resolvers/loop-persona.d.ts.map +1 -1
- package/dist/resolvers/loop-persona.js +2 -16
- package/dist/resolvers/loop-persona.js.map +1 -1
- package/dist/shell/heartbeat.d.ts +7 -0
- package/dist/shell/heartbeat.d.ts.map +1 -1
- package/dist/shell/heartbeat.js +1 -1
- package/dist/shell/heartbeat.js.map +1 -1
- package/dist/shell/unified-shell-provisioning.d.ts +40 -0
- package/dist/shell/unified-shell-provisioning.d.ts.map +1 -1
- package/dist/shell/unified-shell-provisioning.js +72 -0
- package/dist/shell/unified-shell-provisioning.js.map +1 -1
- package/dist/shell/unified-shell.d.ts.map +1 -1
- package/dist/shell/unified-shell.js +18 -1
- package/dist/shell/unified-shell.js.map +1 -1
- package/dist/spawn/helpers.d.ts.map +1 -1
- package/dist/spawn/helpers.js +6 -1
- package/dist/spawn/helpers.js.map +1 -1
- package/dist/spawn/process-spawn.d.ts.map +1 -1
- package/dist/spawn/process-spawn.js +7 -0
- package/dist/spawn/process-spawn.js.map +1 -1
- package/dist/spawn/respawn-cycle-escalation.d.ts +41 -0
- package/dist/spawn/respawn-cycle-escalation.d.ts.map +1 -0
- package/dist/spawn/respawn-cycle-escalation.js +83 -0
- package/dist/spawn/respawn-cycle-escalation.js.map +1 -0
- package/dist/spawn/spawn-cooldown.d.ts +119 -2
- package/dist/spawn/spawn-cooldown.d.ts.map +1 -1
- package/dist/spawn/spawn-cooldown.js +120 -10
- package/dist/spawn/spawn-cooldown.js.map +1 -1
- package/dist/spawn/spawn-decision.d.ts.map +1 -1
- package/dist/spawn/spawn-decision.js +33 -1
- package/dist/spawn/spawn-decision.js.map +1 -1
- package/dist/testing/fixtures/index.d.ts +64 -0
- package/dist/testing/fixtures/index.d.ts.map +1 -0
- package/dist/testing/fixtures/index.js +220 -0
- package/dist/testing/fixtures/index.js.map +1 -0
- package/dist/update/build-info.d.ts +1 -0
- package/dist/update/build-info.d.ts.map +1 -1
- package/dist/update/build-info.js +1 -1
- package/dist/update/build-info.js.map +1 -1
- package/dist/verify/stall-detector-config.d.ts +8 -0
- package/dist/verify/stall-detector-config.d.ts.map +1 -1
- package/dist/verify/stall-detector-config.js +40 -0
- package/dist/verify/stall-detector-config.js.map +1 -1
- package/dist/verify/stall-detectors.d.ts +57 -14
- package/dist/verify/stall-detectors.d.ts.map +1 -1
- package/dist/verify/stall-detectors.js +72 -55
- package/dist/verify/stall-detectors.js.map +1 -1
- package/dist/verify/verification-feedback.d.ts +3 -4
- package/dist/verify/verification-feedback.d.ts.map +1 -1
- package/dist/verify/verification-feedback.js +3 -12
- package/dist/verify/verification-feedback.js.map +1 -1
- package/dist/workflow/gate-failure-policy.d.ts +48 -0
- package/dist/workflow/gate-failure-policy.d.ts.map +1 -0
- package/dist/workflow/gate-failure-policy.js +57 -0
- package/dist/workflow/gate-failure-policy.js.map +1 -0
- package/dist/workflow/pipeline-config.d.ts +2 -2
- package/dist/workflow/pipeline-config.js +2 -2
- package/package.json +3 -3
- package/dist/directive/close-loop-stage.d.ts +0 -50
- package/dist/directive/close-loop-stage.d.ts.map +0 -1
- package/dist/directive/close-loop-stage.js +0 -210
- package/dist/directive/close-loop-stage.js.map +0 -1
- package/dist/focus-stage-lifecycle/review-convergence.d.ts +0 -133
- package/dist/focus-stage-lifecycle/review-convergence.d.ts.map +0 -1
- package/dist/focus-stage-lifecycle/review-convergence.js +0 -237
- package/dist/focus-stage-lifecycle/review-convergence.js.map +0 -1
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Paused-delivery revival -- the daemon-traversable EXIT from `paused` (TEL-1:
|
|
3
|
+
* "Every path into `paused` has a daemon-traversable exit or a named human-act
|
|
4
|
+
* hold").
|
|
5
|
+
*
|
|
6
|
+
* A `paused` delivery is a guard BLOCK on a transition (coding->verify or
|
|
7
|
+
* verify->done), written with an open `transition_blocks` row carrying the
|
|
8
|
+
* blocked transition and its human decision_paths (retry / override). Before
|
|
9
|
+
* this consumer, that block row was written but "nothing read it back": a paused
|
|
10
|
+
* delivery was skipped by every actionable-status pass, never re-evaluated, and
|
|
11
|
+
* -- because paused BLOCKS lower-ranked deliveries -- it wedged the whole ranked
|
|
12
|
+
* queue until a human re-queued it. On an ARMED focus that human never comes
|
|
13
|
+
* (2026-07-28 ruling: an armed focus reaches its terminal without a human;
|
|
14
|
+
* decide-and-record, reversibility as tiebreaker).
|
|
15
|
+
*
|
|
16
|
+
* This module reads the block row back. Each sweep, for every paused delivery it
|
|
17
|
+
* re-evaluates the SAME blocked transition's guards and routes the fresh verdict
|
|
18
|
+
* through the single-writer reconciler (delivery-reconciler `paused` case):
|
|
19
|
+
* - guard CLEARED -> revive `paused` -> `queued` (the canonical revival edge);
|
|
20
|
+
* the normal walk re-drives and re-hits the gate. This is
|
|
21
|
+
* the daemon-traversable exit.
|
|
22
|
+
* - guard STILL blocks -> hold. The pause stays a NAMED human-act hold (its
|
|
23
|
+
* gate_state blocking conditions + the block's `override`
|
|
24
|
+
* decision path name the act only a human can perform), and
|
|
25
|
+
* the wedge watchdog surfaces it. The daemon never OVERRIDES
|
|
26
|
+
* an unclear gate -- that irreversible act is the human's.
|
|
27
|
+
*
|
|
28
|
+
* A paused delivery with NO open block row is NOT abandoned: the blocked FORWARD
|
|
29
|
+
* transition (coding->verify / verify->done) is recovered from the delivery's
|
|
30
|
+
* preserved source stage and re-evaluated the same way -- so a hard-guard pause
|
|
31
|
+
* that wrote no block_transition row still gets a daemon-traversable exit. Only a
|
|
32
|
+
* pause whose stage yields no recoverable forward transition (unknown/ambiguous)
|
|
33
|
+
* stays `no-block` for the watchdog.
|
|
34
|
+
*
|
|
35
|
+
* DI-first: `reconcilePausedDelivery` + `checkPausedDeliveriesForRevival` take a
|
|
36
|
+
* deps object so they unit-test with plain stubs (no `mock.module`, which would
|
|
37
|
+
* poison the daemon-core bare-import loader). `buildDefaultPausedRevivalDeps`
|
|
38
|
+
* wires the real query/guard functions for the listener.
|
|
39
|
+
*/
|
|
40
|
+
import { DELIVERY_STATUS } from '@telora/daemon-core';
|
|
41
|
+
import { resolveReconciledWrite } from './delivery-reconciler-apply.js';
|
|
42
|
+
import { getActiveTransitionBlock, resolveTransitionBlock } from '../queries/guards.js';
|
|
43
|
+
import { evaluateGuardsAtTransition } from '../guard/guard-evaluator.js';
|
|
44
|
+
import { fetchEffectiveWorkflow } from '../queries/workflows.js';
|
|
45
|
+
import { updateDeliveryStatus, getActiveFocuses } from '../queries/deliveries.js';
|
|
46
|
+
import { getFocusDeliveries } from '../queries/focuses.js';
|
|
47
|
+
import { createLogger } from '../shell/log.js';
|
|
48
|
+
const log = createLogger({ module: 'paused-revival' });
|
|
49
|
+
/**
|
|
50
|
+
* The canonical FORWARD delivery-stage a pause blocks. A `paused` delivery was
|
|
51
|
+
* blocked advancing coding->verify or verify->done (the only two guard-block
|
|
52
|
+
* pause producers, delivery-reconciler.ts:314/329); the blocked transition is the
|
|
53
|
+
* one FROM the source stage TO this forward stage. Used to recover the transition
|
|
54
|
+
* for re-evaluation when there is no transition_blocks row to read it from.
|
|
55
|
+
*/
|
|
56
|
+
const FORWARD_DELIVERY_STAGE = {
|
|
57
|
+
[DELIVERY_STATUS.CODING]: DELIVERY_STATUS.VERIFY,
|
|
58
|
+
[DELIVERY_STATUS.VERIFY]: DELIVERY_STATUS.DONE,
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* The `decision_path` stamped on a block the daemon closes on auto-revival. The
|
|
62
|
+
* block leaves `decided_by` NULL (a machine action has no auth.users id), which
|
|
63
|
+
* is what keeps it OUT of the human-routing resolved-block query (that path
|
|
64
|
+
* requires decided_by IS NOT NULL). This value is the audit marker for "the
|
|
65
|
+
* daemon revived past this block because its guard cleared", never a human's
|
|
66
|
+
* retry/override choice.
|
|
67
|
+
*/
|
|
68
|
+
const AUTO_REVIVAL_DECISION_PATH = 'daemon_auto_revival';
|
|
69
|
+
/**
|
|
70
|
+
* Re-evaluate one paused delivery's blocking guard and, if it has cleared,
|
|
71
|
+
* traverse it out of paused via the single-writer reconciler. Returns the
|
|
72
|
+
* outcome for sweep accounting. Never throws for an expected I/O failure -- a
|
|
73
|
+
* guard-reeval failure holds the delivery (safe: stays paused) rather than
|
|
74
|
+
* risking a wrong revival.
|
|
75
|
+
*/
|
|
76
|
+
export async function reconcilePausedDelivery(delivery, organizationId, deps) {
|
|
77
|
+
// Recover the blocked transition: prefer the open block row (the block_transition
|
|
78
|
+
// producer), else derive the forward transition from the preserved source stage
|
|
79
|
+
// (a hard-guard pause with no block row). Either yields the transition whose
|
|
80
|
+
// guards we re-evaluate; neither => nothing recoverable, leave for the watchdog.
|
|
81
|
+
const block = await deps.getActiveTransitionBlock(delivery.id);
|
|
82
|
+
const transitionId = block?.transitionId ??
|
|
83
|
+
(await deps.resolveForwardTransitionId(delivery.id, delivery.currentWorkflowStageId));
|
|
84
|
+
if (!transitionId)
|
|
85
|
+
return 'no-block';
|
|
86
|
+
let stillBlocked;
|
|
87
|
+
try {
|
|
88
|
+
stillBlocked = await deps.reEvaluateGuardBlocked(delivery.id, organizationId, transitionId);
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
log.warn(`[paused-revival] guard re-eval failed for "${delivery.name}" (${delivery.id.slice(0, 8)}): ` +
|
|
92
|
+
`${err.message} -- holding paused this tick`);
|
|
93
|
+
return 'held';
|
|
94
|
+
}
|
|
95
|
+
// Route the fresh verdict through the single reconciler computation. The
|
|
96
|
+
// paused case revives to `queued` only when the guard has cleared; otherwise
|
|
97
|
+
// it stays paused.
|
|
98
|
+
const decision = resolveReconciledWrite({
|
|
99
|
+
input: {
|
|
100
|
+
currentStatus: DELIVERY_STATUS.PAUSED,
|
|
101
|
+
issues: [],
|
|
102
|
+
gitState: { worktreeCommitted: true },
|
|
103
|
+
guardVerdict: { blocked: stillBlocked },
|
|
104
|
+
reviewState: null,
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
if (decision.target === DELIVERY_STATUS.PAUSED)
|
|
108
|
+
return 'held';
|
|
109
|
+
// Close out the block this revival acted on BEFORE the status write, so even a
|
|
110
|
+
// crash between the two leaves the block resolved (the next sweep then derives
|
|
111
|
+
// the forward transition from the preserved stage rather than re-reading a
|
|
112
|
+
// stale row). A derived-forward revival (block === null) has nothing to close.
|
|
113
|
+
// Best-effort: a close failure never blocks the already-decided revival.
|
|
114
|
+
if (block) {
|
|
115
|
+
try {
|
|
116
|
+
await deps.resolveTransitionBlock(block.id, AUTO_REVIVAL_DECISION_PATH);
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
log.warn(`[paused-revival] failed to close block ${block.id.slice(0, 8)} for ` +
|
|
120
|
+
`"${delivery.name}" (${delivery.id.slice(0, 8)}): ${err.message} -- ` +
|
|
121
|
+
`revival proceeds; a stale-open block may be re-read on a later pause episode`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const stageId = await deps.resolveStageId(delivery.id, decision.target);
|
|
125
|
+
// Clear gate_state + completion_artifacts explicitly (null, not undefined): the
|
|
126
|
+
// block that held this delivery no longer applies once it leaves paused, so the
|
|
127
|
+
// row must carry no gate state describing the block it has left. queries/
|
|
128
|
+
// deliveries.ts only clears the column on null; undefined would leave it stale.
|
|
129
|
+
await deps.updateDeliveryStatus(delivery.id, decision.target, stageId, null, null, { organizationId, fromStatus: DELIVERY_STATUS.PAUSED });
|
|
130
|
+
log.info(`[paused-revival] revived "${delivery.name}" (${delivery.id.slice(0, 8)}) ` +
|
|
131
|
+
`paused -> ${decision.target}: blocking guard cleared on re-eval`);
|
|
132
|
+
return 'revived';
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Sweep every active focus's paused deliveries and revive the ones whose
|
|
136
|
+
* blocking guard has cleared. Runs on TEAMLESS focuses too (a paused delivery
|
|
137
|
+
* wedges the queue so no team spawns) -- hence it iterates active focuses, not
|
|
138
|
+
* activeTeams. Best-effort per focus/delivery: one failure never aborts the
|
|
139
|
+
* sweep.
|
|
140
|
+
*/
|
|
141
|
+
export async function checkPausedDeliveriesForRevival(config, deps) {
|
|
142
|
+
let revived = 0;
|
|
143
|
+
let held = 0;
|
|
144
|
+
let noBlock = 0;
|
|
145
|
+
let focuses;
|
|
146
|
+
try {
|
|
147
|
+
focuses = await deps.getActiveFocuses(config.organizationId, config.productId);
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
log.warn(`[paused-revival] failed to fetch active focuses: ${err.message}`);
|
|
151
|
+
return { revived, held, noBlock };
|
|
152
|
+
}
|
|
153
|
+
for (const focus of focuses) {
|
|
154
|
+
let deliveries;
|
|
155
|
+
try {
|
|
156
|
+
deliveries = await deps.getFocusDeliveries(focus.focus_id);
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
log.warn(`[paused-revival] failed to fetch deliveries for focus ${focus.focus_id.slice(0, 8)}: ${err.message}`);
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
for (const delivery of deliveries) {
|
|
163
|
+
if ((delivery.executionStatus ?? '') !== DELIVERY_STATUS.PAUSED)
|
|
164
|
+
continue;
|
|
165
|
+
try {
|
|
166
|
+
const outcome = await reconcilePausedDelivery(delivery, config.organizationId, deps);
|
|
167
|
+
if (outcome === 'revived')
|
|
168
|
+
revived++;
|
|
169
|
+
else if (outcome === 'held')
|
|
170
|
+
held++;
|
|
171
|
+
else
|
|
172
|
+
noBlock++;
|
|
173
|
+
}
|
|
174
|
+
catch (err) {
|
|
175
|
+
log.warn(`[paused-revival] revival check failed for "${delivery.name}" (${delivery.id.slice(0, 8)}): ${err.message}`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return { revived, held, noBlock };
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Wire the real query + guard functions into a sweep-deps object for the
|
|
183
|
+
* listener. Kept as thin adapters (not direct assignments) so the wide,
|
|
184
|
+
* strictly-typed writer/query signatures reduce to this consumer's narrow seam.
|
|
185
|
+
* `reEvaluateGuardBlocked` is PURE measurement: evaluateGuardsAtTransition
|
|
186
|
+
* fetches guards + builds context and returns a verdict; it does NOT write the
|
|
187
|
+
* delivery's execution_status (that stays the reconciler's job here).
|
|
188
|
+
*/
|
|
189
|
+
export function buildDefaultPausedRevivalDeps() {
|
|
190
|
+
return {
|
|
191
|
+
getActiveTransitionBlock: async (deliveryId) => {
|
|
192
|
+
const block = await getActiveTransitionBlock(deliveryId);
|
|
193
|
+
return block ? { id: block.id, transitionId: block.transition_id } : null;
|
|
194
|
+
},
|
|
195
|
+
resolveForwardTransitionId: async (deliveryId, currentStageId) => {
|
|
196
|
+
if (!currentStageId)
|
|
197
|
+
return null;
|
|
198
|
+
const workflow = await fetchEffectiveWorkflow(deliveryId);
|
|
199
|
+
const sourceStage = workflow.stages.find((s) => s.id === currentStageId);
|
|
200
|
+
if (!sourceStage)
|
|
201
|
+
return null;
|
|
202
|
+
const forwardName = FORWARD_DELIVERY_STAGE[sourceStage.name];
|
|
203
|
+
if (!forwardName)
|
|
204
|
+
return null;
|
|
205
|
+
const forwardStage = workflow.stages.find((s) => s.name === forwardName);
|
|
206
|
+
if (!forwardStage)
|
|
207
|
+
return null;
|
|
208
|
+
const transition = (workflow.transitions ?? []).find((t) => t.from_stage_id === currentStageId && t.to_stage_id === forwardStage.id);
|
|
209
|
+
return transition?.id ?? null;
|
|
210
|
+
},
|
|
211
|
+
reEvaluateGuardBlocked: async (deliveryId, organizationId, transitionId) => {
|
|
212
|
+
const result = await evaluateGuardsAtTransition(deliveryId, organizationId, transitionId, 0);
|
|
213
|
+
return !result.should_proceed;
|
|
214
|
+
},
|
|
215
|
+
resolveStageId: async (deliveryId, statusName) => {
|
|
216
|
+
const workflow = await fetchEffectiveWorkflow(deliveryId);
|
|
217
|
+
return workflow.stages.find((s) => s.name === statusName)?.id;
|
|
218
|
+
},
|
|
219
|
+
updateDeliveryStatus: (deliveryId, status, stageId, gateState, completionArtifacts, transition) =>
|
|
220
|
+
// Pass the caller's gate_state + completion_artifacts THROUGH (reconcile-
|
|
221
|
+
// PausedDelivery clears them with null on the way out of paused) instead of
|
|
222
|
+
// hardcoding, so the clear is driven by -- and testable at -- the caller.
|
|
223
|
+
updateDeliveryStatus(deliveryId, status, stageId, gateState, completionArtifacts, transition),
|
|
224
|
+
resolveTransitionBlock: (blockId, decisionPath) => resolveTransitionBlock(blockId, decisionPath),
|
|
225
|
+
getActiveFocuses: (organizationId, productId) => getActiveFocuses(organizationId, productId),
|
|
226
|
+
getFocusDeliveries: (focusId) => getFocusDeliveries(focusId),
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=paused-revival.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paused-revival.js","sourceRoot":"","sources":["../../src/delivery/paused-revival.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wait reachability: can the condition a wait is blocked on still fire?
|
|
3
|
+
*
|
|
4
|
+
* The daemon waits in several places (an external hold, a stall-cycle counter, a
|
|
5
|
+
* mid-focus handoff, a CI merge gate). Every one of them holds against some
|
|
6
|
+
* awaited condition, but none of them ask the one question that tells patience
|
|
7
|
+
* from a stall: CAN THE THING BEING WAITED FOR STILL ARRIVE? A wait blocked on
|
|
8
|
+
* another actor (that actor can still act) and a wait blocked on itself -- or on
|
|
9
|
+
* a recorded fact that never re-evaluates -- look identical from the outside.
|
|
10
|
+
*
|
|
11
|
+
* This module is the shared answer. It classifies an awaited condition by WHAT
|
|
12
|
+
* it is blocked on, and derives reachability from that:
|
|
13
|
+
* - other_actor -> REACHABLE (another actor can still satisfy it)
|
|
14
|
+
* - self -> UNREACHABLE (only the waiter can produce it -> deadlock)
|
|
15
|
+
* - static_fact -> UNREACHABLE (a recorded fact that never re-evaluates
|
|
16
|
+
* without new input, e.g. a CI result on an
|
|
17
|
+
* unchanged sha)
|
|
18
|
+
*
|
|
19
|
+
* It is PURE and dependency-free so the decision is unit-testable without a live
|
|
20
|
+
* daemon, and so the hold sites (next task) and the shared wait descriptor
|
|
21
|
+
* (delivery 2) can both reuse the same classification.
|
|
22
|
+
*
|
|
23
|
+
* Reference incident (2026-08-17, f1): the lead held on three triggers, none of
|
|
24
|
+
* which could fire -- integration advancing (blocked by the very guard failure it
|
|
25
|
+
* was waiting out -> `self`), a CI-red result "auto-resolving" (a recorded fact
|
|
26
|
+
* on a sha that never re-evaluates -> `static_fact`), and a re-verify only that
|
|
27
|
+
* lead could initiate (-> `self`). The named constructors below encode exactly
|
|
28
|
+
* those classes so a caller states its wait's KIND, not a raw blocker enum.
|
|
29
|
+
*
|
|
30
|
+
* This GENERALIZES the reachability notion external-hold.ts already carries: a
|
|
31
|
+
* hold with no machine-readable clearing reference ("will not self-clear") is a
|
|
32
|
+
* hold whose condition cannot fire. Cross-product request holds are the live
|
|
33
|
+
* `other_actor` case -- an OPEN request the peer product can still close.
|
|
34
|
+
*
|
|
35
|
+
* @module wait-reachability
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* What a wait is blocked on -- the single axis that decides reachability.
|
|
39
|
+
* - other_actor: another actor (a peer product, a CI runner, integration
|
|
40
|
+
* merge-back) can still act, so the wait can still be satisfied.
|
|
41
|
+
* - self: only the waiter itself could produce what it waits for -- waiting is
|
|
42
|
+
* a deadlock (e.g. a re-verify only the holding lead could initiate).
|
|
43
|
+
* - static_fact: a recorded fact that never re-evaluates without new input
|
|
44
|
+
* (e.g. a CI result on an unchanged sha; it cannot change without a NEW
|
|
45
|
+
* commit, so waiting for it to change cannot succeed).
|
|
46
|
+
*/
|
|
47
|
+
export type WaitBlocker = 'other_actor' | 'self' | 'static_fact';
|
|
48
|
+
/** A described awaited condition: what is being waited for, and what blocks it. */
|
|
49
|
+
export interface AwaitedCondition {
|
|
50
|
+
/** Human-readable statement of what is being waited for (for logs/records). */
|
|
51
|
+
condition: string;
|
|
52
|
+
/** What the wait is blocked on -- decides whether it can still fire. */
|
|
53
|
+
blockedOn: WaitBlocker;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The shared form EVERY place the daemon waits describes itself in: the awaited
|
|
57
|
+
* condition plus what it is blocked on. A `WaitDescriptor` IS an
|
|
58
|
+
* {@link AwaitedCondition} -- the alias names its role as the one shared wait
|
|
59
|
+
* vocabulary the independent waiting sites (external hold, CI merge gate, the
|
|
60
|
+
* no-progress counters, the handoff loop, the verify_failed cap) all speak, so a
|
|
61
|
+
* wait blocked on another actor is tellable from a wait blocked on itself
|
|
62
|
+
* WITHOUT reconstructing daemon state. Render it with {@link renderWait}.
|
|
63
|
+
*/
|
|
64
|
+
export type WaitDescriptor = AwaitedCondition;
|
|
65
|
+
/** The reachability verdict for an awaited condition. */
|
|
66
|
+
export interface WaitReachability {
|
|
67
|
+
/** True when the condition can still fire (blocked on another actor). */
|
|
68
|
+
reachable: boolean;
|
|
69
|
+
/** The blocker the verdict was derived from (echoed for logs/records). */
|
|
70
|
+
blockedOn: WaitBlocker;
|
|
71
|
+
/** Human-readable reason, suitable for a daemon log line or a hold record. */
|
|
72
|
+
reason: string;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Classify whether an awaited condition can still fire. Pure and total: the
|
|
76
|
+
* verdict depends ONLY on `blockedOn`, so the same condition always classifies
|
|
77
|
+
* the same way regardless of who asks.
|
|
78
|
+
*/
|
|
79
|
+
export declare function classifyWaitReachability(c: AwaitedCondition): WaitReachability;
|
|
80
|
+
/** Convenience predicate: can this awaited condition still fire? */
|
|
81
|
+
export declare function canStillFire(c: AwaitedCondition): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* A stable, machine-checkable marker naming what a wait is blocked on, so a
|
|
84
|
+
* daemon log line lets a reader tell a wait blocked on ANOTHER ACTOR (can still
|
|
85
|
+
* arrive) from one blocked on ITSELF or on a RECORDED FACT (cannot arrive)
|
|
86
|
+
* WITHOUT reconstructing daemon state from git + DB. The three markers are
|
|
87
|
+
* disjoint substrings by construction. This is the shared vocabulary the hold
|
|
88
|
+
* log sites emit; delivery 2 folds it into the single wait-descriptor render.
|
|
89
|
+
*/
|
|
90
|
+
export declare function describeWaitReachability(r: WaitReachability): string;
|
|
91
|
+
/**
|
|
92
|
+
* The ONE canonical render of a wait for the daemon log: states WHAT is awaited
|
|
93
|
+
* and WHETHER it can still arrive, on one line, so a stall is legible from the
|
|
94
|
+
* log alone. Every waiting site routes its wait through this single function, so
|
|
95
|
+
* a future change to how a wait reads -- or a new fact to surface about every
|
|
96
|
+
* wait -- is made here, once, rather than in each component that waits.
|
|
97
|
+
*/
|
|
98
|
+
export declare function renderWait(wait: WaitDescriptor): string;
|
|
99
|
+
/**
|
|
100
|
+
* A cross-product request the peer product can still close. REACHABLE: the peer
|
|
101
|
+
* is another actor and an OPEN request can still reach closure. Mirrors
|
|
102
|
+
* external-hold.ts `clearsWhenRequestsClosed`.
|
|
103
|
+
*/
|
|
104
|
+
export declare function crossProductRequestWait(requestIds: readonly string[]): AwaitedCondition;
|
|
105
|
+
/**
|
|
106
|
+
* A recorded CI-status result on an UNCHANGED sha. A `red` (or otherwise
|
|
107
|
+
* non-green) result at refs/ci-status/<sha> never re-evaluates for the same
|
|
108
|
+
* commit -- it can only change with a NEW commit -- so waiting for it to turn
|
|
109
|
+
* green is waiting on a static fact. UNREACHABLE.
|
|
110
|
+
*
|
|
111
|
+
* A `pending` run is NOT this: the CI runner is still an active other actor, so
|
|
112
|
+
* that is a `ciRunPendingWait` (reachable). Only a settled, non-green result on
|
|
113
|
+
* a sha that will not change is the static-fact trap.
|
|
114
|
+
*/
|
|
115
|
+
export declare function recordedCiResultWait(sha: string, ciStatus: string): AwaitedCondition;
|
|
116
|
+
/**
|
|
117
|
+
* A CI run still in progress for a sha. REACHABLE: the CI runner (another actor)
|
|
118
|
+
* has not finished, so a result can still arrive. Distinct from
|
|
119
|
+
* `recordedCiResultWait`, which is a SETTLED result on a sha that will not change.
|
|
120
|
+
*/
|
|
121
|
+
export declare function ciRunPendingWait(sha: string): AwaitedCondition;
|
|
122
|
+
/**
|
|
123
|
+
* A re-verify (or any re-run) that only the holding lead itself could initiate.
|
|
124
|
+
* UNREACHABLE: the awaited event can only be produced by the waiter, so waiting
|
|
125
|
+
* for it is a deadlock.
|
|
126
|
+
*/
|
|
127
|
+
export declare function selfInitiatedReverifyWait(detail: string): AwaitedCondition;
|
|
128
|
+
/**
|
|
129
|
+
* The daemon awaiting a team's own progress on its non-terminal deliveries.
|
|
130
|
+
* From the daemon's vantage the TEAM is another actor that can still act, so
|
|
131
|
+
* this is REACHABLE -- the daemon legitimately waits on it. The bound on how
|
|
132
|
+
* long it waits is the no-progress / scope-coverage guard (the stall counters),
|
|
133
|
+
* NOT unreachability: a stall here is "the actor has not acted for N cycles",
|
|
134
|
+
* surfaced by the guard tripping, not "the wait can never be satisfied".
|
|
135
|
+
*/
|
|
136
|
+
export declare function teamProgressWait(nonTerminalCount: number): AwaitedCondition;
|
|
137
|
+
/**
|
|
138
|
+
* An integration branch advancing (merge-back). REACHABLE by default -- merge-back
|
|
139
|
+
* is driven by another actor (the daemon merge loop). But when the advance is
|
|
140
|
+
* blocked by the very condition this wait is itself waiting out (a circular
|
|
141
|
+
* wait, as in the 2026-08-17 incident where merge-back skipped the lead's branch
|
|
142
|
+
* as active_team because the lead was still executing), it is UNREACHABLE:
|
|
143
|
+
* nothing external can clear it while the wait persists.
|
|
144
|
+
*/
|
|
145
|
+
export declare function integrationAdvanceWait(opts: {
|
|
146
|
+
circular: boolean;
|
|
147
|
+
detail: string;
|
|
148
|
+
}): AwaitedCondition;
|
|
149
|
+
//# sourceMappingURL=wait-reachability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wait-reachability.d.ts","sourceRoot":"","sources":["../../src/delivery/wait-reachability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH;;;;;;;;;GASG;AACH,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,MAAM,GAAG,aAAa,CAAC;AAEjE,mFAAmF;AACnF,MAAM,WAAW,gBAAgB;IAC/B,+EAA+E;IAC/E,SAAS,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,SAAS,EAAE,WAAW,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAE9C,yDAAyD;AACzD,MAAM,WAAW,gBAAgB;IAC/B,yEAAyE;IACzE,SAAS,EAAE,OAAO,CAAC;IACnB,0EAA0E;IAC1E,SAAS,EAAE,WAAW,CAAC;IACvB,8EAA8E;IAC9E,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,gBAAgB,GAAG,gBAAgB,CAqB9E;AAED,oEAAoE;AACpE,wBAAgB,YAAY,CAAC,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAEzD;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,gBAAgB,GAAG,MAAM,CASpE;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAEvD;AAOD;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,gBAAgB,CAgBvF;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CAKpF;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAK9D;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAK1E;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,gBAAgB,EAAE,MAAM,GAAG,gBAAgB,CAK3E;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,gBAAgB,CAUpG"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wait reachability: can the condition a wait is blocked on still fire?
|
|
3
|
+
*
|
|
4
|
+
* The daemon waits in several places (an external hold, a stall-cycle counter, a
|
|
5
|
+
* mid-focus handoff, a CI merge gate). Every one of them holds against some
|
|
6
|
+
* awaited condition, but none of them ask the one question that tells patience
|
|
7
|
+
* from a stall: CAN THE THING BEING WAITED FOR STILL ARRIVE? A wait blocked on
|
|
8
|
+
* another actor (that actor can still act) and a wait blocked on itself -- or on
|
|
9
|
+
* a recorded fact that never re-evaluates -- look identical from the outside.
|
|
10
|
+
*
|
|
11
|
+
* This module is the shared answer. It classifies an awaited condition by WHAT
|
|
12
|
+
* it is blocked on, and derives reachability from that:
|
|
13
|
+
* - other_actor -> REACHABLE (another actor can still satisfy it)
|
|
14
|
+
* - self -> UNREACHABLE (only the waiter can produce it -> deadlock)
|
|
15
|
+
* - static_fact -> UNREACHABLE (a recorded fact that never re-evaluates
|
|
16
|
+
* without new input, e.g. a CI result on an
|
|
17
|
+
* unchanged sha)
|
|
18
|
+
*
|
|
19
|
+
* It is PURE and dependency-free so the decision is unit-testable without a live
|
|
20
|
+
* daemon, and so the hold sites (next task) and the shared wait descriptor
|
|
21
|
+
* (delivery 2) can both reuse the same classification.
|
|
22
|
+
*
|
|
23
|
+
* Reference incident (2026-08-17, f1): the lead held on three triggers, none of
|
|
24
|
+
* which could fire -- integration advancing (blocked by the very guard failure it
|
|
25
|
+
* was waiting out -> `self`), a CI-red result "auto-resolving" (a recorded fact
|
|
26
|
+
* on a sha that never re-evaluates -> `static_fact`), and a re-verify only that
|
|
27
|
+
* lead could initiate (-> `self`). The named constructors below encode exactly
|
|
28
|
+
* those classes so a caller states its wait's KIND, not a raw blocker enum.
|
|
29
|
+
*
|
|
30
|
+
* This GENERALIZES the reachability notion external-hold.ts already carries: a
|
|
31
|
+
* hold with no machine-readable clearing reference ("will not self-clear") is a
|
|
32
|
+
* hold whose condition cannot fire. Cross-product request holds are the live
|
|
33
|
+
* `other_actor` case -- an OPEN request the peer product can still close.
|
|
34
|
+
*
|
|
35
|
+
* @module wait-reachability
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* Classify whether an awaited condition can still fire. Pure and total: the
|
|
39
|
+
* verdict depends ONLY on `blockedOn`, so the same condition always classifies
|
|
40
|
+
* the same way regardless of who asks.
|
|
41
|
+
*/
|
|
42
|
+
export function classifyWaitReachability(c) {
|
|
43
|
+
switch (c.blockedOn) {
|
|
44
|
+
case 'other_actor':
|
|
45
|
+
return {
|
|
46
|
+
reachable: true,
|
|
47
|
+
blockedOn: 'other_actor',
|
|
48
|
+
reason: `blocked on another actor (can still arrive): ${c.condition}`,
|
|
49
|
+
};
|
|
50
|
+
case 'self':
|
|
51
|
+
return {
|
|
52
|
+
reachable: false,
|
|
53
|
+
blockedOn: 'self',
|
|
54
|
+
reason: `blocked on itself -- only the waiter could produce this, so it cannot arrive: ${c.condition}`,
|
|
55
|
+
};
|
|
56
|
+
case 'static_fact':
|
|
57
|
+
return {
|
|
58
|
+
reachable: false,
|
|
59
|
+
blockedOn: 'static_fact',
|
|
60
|
+
reason: `blocked on a recorded fact that never re-evaluates without new input, so it cannot arrive: ${c.condition}`,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/** Convenience predicate: can this awaited condition still fire? */
|
|
65
|
+
export function canStillFire(c) {
|
|
66
|
+
return classifyWaitReachability(c).reachable;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* A stable, machine-checkable marker naming what a wait is blocked on, so a
|
|
70
|
+
* daemon log line lets a reader tell a wait blocked on ANOTHER ACTOR (can still
|
|
71
|
+
* arrive) from one blocked on ITSELF or on a RECORDED FACT (cannot arrive)
|
|
72
|
+
* WITHOUT reconstructing daemon state from git + DB. The three markers are
|
|
73
|
+
* disjoint substrings by construction. This is the shared vocabulary the hold
|
|
74
|
+
* log sites emit; delivery 2 folds it into the single wait-descriptor render.
|
|
75
|
+
*/
|
|
76
|
+
export function describeWaitReachability(r) {
|
|
77
|
+
switch (r.blockedOn) {
|
|
78
|
+
case 'other_actor':
|
|
79
|
+
return 'wait: blocked on ANOTHER ACTOR (can still arrive)';
|
|
80
|
+
case 'self':
|
|
81
|
+
return 'wait: blocked on ITSELF (cannot arrive -- only the waiter could produce it)';
|
|
82
|
+
case 'static_fact':
|
|
83
|
+
return 'wait: blocked on a RECORDED FACT (cannot arrive without new input)';
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* The ONE canonical render of a wait for the daemon log: states WHAT is awaited
|
|
88
|
+
* and WHETHER it can still arrive, on one line, so a stall is legible from the
|
|
89
|
+
* log alone. Every waiting site routes its wait through this single function, so
|
|
90
|
+
* a future change to how a wait reads -- or a new fact to surface about every
|
|
91
|
+
* wait -- is made here, once, rather than in each component that waits.
|
|
92
|
+
*/
|
|
93
|
+
export function renderWait(wait) {
|
|
94
|
+
return `${wait.condition} [${describeWaitReachability(classifyWaitReachability(wait))}]`;
|
|
95
|
+
}
|
|
96
|
+
// ── Named constructors for the recognized wait kinds ────────────────────────
|
|
97
|
+
// Callers state their wait's KIND; the constructor sets the correct blocker so
|
|
98
|
+
// the incident's three unreachable classes cannot be mis-classified at a call
|
|
99
|
+
// site. These are the vocabulary delivery 2's shared descriptor builds on.
|
|
100
|
+
/**
|
|
101
|
+
* A cross-product request the peer product can still close. REACHABLE: the peer
|
|
102
|
+
* is another actor and an OPEN request can still reach closure. Mirrors
|
|
103
|
+
* external-hold.ts `clearsWhenRequestsClosed`.
|
|
104
|
+
*/
|
|
105
|
+
export function crossProductRequestWait(requestIds) {
|
|
106
|
+
if (requestIds.length === 0) {
|
|
107
|
+
// No request reference: nothing names an actor that could ever close this, so
|
|
108
|
+
// it cannot arrive -- the REFERENCE-LESS external hold. Classifying it as a
|
|
109
|
+
// recorded fact (UNREACHABLE) rather than other_actor is what lets a caller
|
|
110
|
+
// branch on the reachability verdict (e.g. isReferenceLessHoldStale) instead
|
|
111
|
+
// of mistaking a hold with nothing to re-read for one a peer will close.
|
|
112
|
+
return {
|
|
113
|
+
condition: 'cross-product hold with NO request reference to close (nothing to re-read)',
|
|
114
|
+
blockedOn: 'static_fact',
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
condition: `cross-product request(s) to close: ${requestIds.join(', ')}`,
|
|
119
|
+
blockedOn: 'other_actor',
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* A recorded CI-status result on an UNCHANGED sha. A `red` (or otherwise
|
|
124
|
+
* non-green) result at refs/ci-status/<sha> never re-evaluates for the same
|
|
125
|
+
* commit -- it can only change with a NEW commit -- so waiting for it to turn
|
|
126
|
+
* green is waiting on a static fact. UNREACHABLE.
|
|
127
|
+
*
|
|
128
|
+
* A `pending` run is NOT this: the CI runner is still an active other actor, so
|
|
129
|
+
* that is a `ciRunPendingWait` (reachable). Only a settled, non-green result on
|
|
130
|
+
* a sha that will not change is the static-fact trap.
|
|
131
|
+
*/
|
|
132
|
+
export function recordedCiResultWait(sha, ciStatus) {
|
|
133
|
+
return {
|
|
134
|
+
condition: `CI status '${ciStatus}' recorded for unchanged sha ${sha} to change (needs a new commit)`,
|
|
135
|
+
blockedOn: 'static_fact',
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* A CI run still in progress for a sha. REACHABLE: the CI runner (another actor)
|
|
140
|
+
* has not finished, so a result can still arrive. Distinct from
|
|
141
|
+
* `recordedCiResultWait`, which is a SETTLED result on a sha that will not change.
|
|
142
|
+
*/
|
|
143
|
+
export function ciRunPendingWait(sha) {
|
|
144
|
+
return {
|
|
145
|
+
condition: `CI run to finish for sha ${sha}`,
|
|
146
|
+
blockedOn: 'other_actor',
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* A re-verify (or any re-run) that only the holding lead itself could initiate.
|
|
151
|
+
* UNREACHABLE: the awaited event can only be produced by the waiter, so waiting
|
|
152
|
+
* for it is a deadlock.
|
|
153
|
+
*/
|
|
154
|
+
export function selfInitiatedReverifyWait(detail) {
|
|
155
|
+
return {
|
|
156
|
+
condition: `a re-verify only this lead could initiate: ${detail}`,
|
|
157
|
+
blockedOn: 'self',
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* The daemon awaiting a team's own progress on its non-terminal deliveries.
|
|
162
|
+
* From the daemon's vantage the TEAM is another actor that can still act, so
|
|
163
|
+
* this is REACHABLE -- the daemon legitimately waits on it. The bound on how
|
|
164
|
+
* long it waits is the no-progress / scope-coverage guard (the stall counters),
|
|
165
|
+
* NOT unreachability: a stall here is "the actor has not acted for N cycles",
|
|
166
|
+
* surfaced by the guard tripping, not "the wait can never be satisfied".
|
|
167
|
+
*/
|
|
168
|
+
export function teamProgressWait(nonTerminalCount) {
|
|
169
|
+
return {
|
|
170
|
+
condition: `progress from the team on ${nonTerminalCount} non-terminal delivery(ies)`,
|
|
171
|
+
blockedOn: 'other_actor',
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* An integration branch advancing (merge-back). REACHABLE by default -- merge-back
|
|
176
|
+
* is driven by another actor (the daemon merge loop). But when the advance is
|
|
177
|
+
* blocked by the very condition this wait is itself waiting out (a circular
|
|
178
|
+
* wait, as in the 2026-08-17 incident where merge-back skipped the lead's branch
|
|
179
|
+
* as active_team because the lead was still executing), it is UNREACHABLE:
|
|
180
|
+
* nothing external can clear it while the wait persists.
|
|
181
|
+
*/
|
|
182
|
+
export function integrationAdvanceWait(opts) {
|
|
183
|
+
return opts.circular
|
|
184
|
+
? {
|
|
185
|
+
condition: `integration to advance, blocked by the condition this wait is itself holding out: ${opts.detail}`,
|
|
186
|
+
blockedOn: 'self',
|
|
187
|
+
}
|
|
188
|
+
: {
|
|
189
|
+
condition: `integration to advance (merge-back): ${opts.detail}`,
|
|
190
|
+
blockedOn: 'other_actor',
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=wait-reachability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wait-reachability.js","sourceRoot":"","sources":["../../src/delivery/wait-reachability.ts"],"names":[],"mappings":"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"}
|