@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
package/dist/ci/ci-status.d.ts
CHANGED
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
* @module ci-status
|
|
26
26
|
*/
|
|
27
27
|
import type { DaemonConfig } from '../types/index.js';
|
|
28
|
+
import { type WaitReachability } from '../delivery/wait-reachability.js';
|
|
28
29
|
/**
|
|
29
30
|
* Normalized CI run status for a SHA.
|
|
30
31
|
* - green -- a CI run for this SHA completed successfully.
|
|
@@ -43,6 +44,19 @@ export interface CiMergeGateDecision {
|
|
|
43
44
|
status: CiRunStatus;
|
|
44
45
|
/** Human-readable reason (logged; surfaced in the session exit suffix). */
|
|
45
46
|
reason: string;
|
|
47
|
+
/**
|
|
48
|
+
* Reachability of the HELD wait: can the awaited CI condition still fire?
|
|
49
|
+
* Populated only for a hold (proceed=false) that a caller has classified with
|
|
50
|
+
* the merged sha via {@link classifyCiMergeWait}; absent on the pure
|
|
51
|
+
* status-only decision from {@link resolveCiMergeGate}. `reachable:false` marks
|
|
52
|
+
* the incident's trap -- a settled non-green result on an UNCHANGED sha that
|
|
53
|
+
* cannot self-clear without a NEW commit, so holding for it is a stall, not
|
|
54
|
+
* patience. `reachable:true` marks a run still in flight (the CI runner can
|
|
55
|
+
* still finish it).
|
|
56
|
+
*/
|
|
57
|
+
reachable?: boolean;
|
|
58
|
+
/** The reachability reason (from the wait-reachability classifier), when set. */
|
|
59
|
+
reachabilityReason?: string;
|
|
46
60
|
}
|
|
47
61
|
/**
|
|
48
62
|
* Pure merge-gate decision: should integration->main proceed given the merged
|
|
@@ -62,28 +76,66 @@ export interface CiMergeGateDecision {
|
|
|
62
76
|
* a non-green (or absent) status for the merged SHA.
|
|
63
77
|
*/
|
|
64
78
|
export declare function resolveCiMergeGate(status: CiRunStatus): CiMergeGateDecision;
|
|
79
|
+
/**
|
|
80
|
+
* Classify whether a HELD CI merge wait can still fire, given the merged SHA.
|
|
81
|
+
* This is the reachability distinction the plain status-only gate cannot make:
|
|
82
|
+
* the merge gate correctly HOLDS on pending / red / unknown, but only some of
|
|
83
|
+
* those waits can still be satisfied without new input.
|
|
84
|
+
*
|
|
85
|
+
* - pending -> REACHABLE: a run is in flight; the CI runner (another actor)
|
|
86
|
+
* can still finish it and turn the SHA green.
|
|
87
|
+
* - red -> UNREACHABLE: a settled failure recorded for THIS sha. It never
|
|
88
|
+
* re-evaluates for the same commit (refs/ci-status/<sha> is immutable per
|
|
89
|
+
* sha), so waiting for it to "turn green" cannot succeed without a NEW
|
|
90
|
+
* commit. This is the 2026-08-17 "CI-red result auto-resolving" trap: a
|
|
91
|
+
* stall that reads as patience.
|
|
92
|
+
* - unknown -> REACHABLE (conservative): no status could be determined, so a
|
|
93
|
+
* run could still appear. We do NOT declare an unknown wait dead -- only a
|
|
94
|
+
* recorded non-green RESULT is a static fact.
|
|
95
|
+
* - green -> not held; classified REACHABLE for totality (never reached on a
|
|
96
|
+
* hold path).
|
|
97
|
+
*
|
|
98
|
+
* Pure. Reuses the shared wait-reachability classifier so the CI hold speaks the
|
|
99
|
+
* same vocabulary as every other wait.
|
|
100
|
+
*/
|
|
101
|
+
export declare function classifyCiMergeWait(status: CiRunStatus, sha: string): WaitReachability;
|
|
65
102
|
/**
|
|
66
103
|
* Classify a git-native CI status from the set of ci-status ref names published
|
|
67
104
|
* for a SHA. The STATE is encoded in the ref NAME (immutable per-SHA), so no
|
|
68
105
|
* object content read is needed. Pure -- the caller supplies the ref names from a
|
|
69
106
|
* scoped `git ls-remote` / fetch.
|
|
70
107
|
*
|
|
71
|
-
*
|
|
72
|
-
* (`refs/ci-status/<sha>/<runNumber>/<state>`)
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
108
|
+
* COMPLETED-GREEN-WINS across runs. The publisher encodes run order in the ref
|
|
109
|
+
* PATH (`refs/ci-status/<sha>/<runNumber>/<state>`) and publishes `success` ONLY
|
|
110
|
+
* when the whole suite (ci AND e2e) completed green. A completed green run is
|
|
111
|
+
* therefore unforgeable proof the SHA's tree is sound: a genuinely broken tree
|
|
112
|
+
* can never publish green, and a run destroyed mid-suite can never reach a green
|
|
113
|
+
* e2e result. So among the distinct runs of one sha, ANY completed green run
|
|
114
|
+
* outranks a red run of the same sha -- the red is the environmental casualty
|
|
115
|
+
* (an evicted run, or one whose Postgres another overlapping run force-removed
|
|
116
|
+
* mid-suite), not the tree.
|
|
117
|
+
*
|
|
118
|
+
* This REPLACES the earlier most-recent-run-wins rule, which the 2026-08-18
|
|
119
|
+
* shared-runner incident disproved: run 3838's live database was force-removed
|
|
120
|
+
* by an overlapping run 3837, so 3838 published a failure -- and because the
|
|
121
|
+
* DESTROYED run carried the HIGHER run number, "most recent wins" let its red
|
|
122
|
+
* pin a sound sha red. Run-id order did not even match start order there (3838
|
|
123
|
+
* started before 3837), so "most recent run" was never reliably most-recent.
|
|
124
|
+
* Completed-green does not depend on run-number order at all.
|
|
78
125
|
*
|
|
79
|
-
* FAIL-CLOSED throughout: an empty set / unrecognized suffix ->
|
|
80
|
-
* (holds
|
|
81
|
-
*
|
|
126
|
+
* FAIL-CLOSED throughout: an empty set / unrecognized suffix / only-pending ->
|
|
127
|
+
* 'unknown'/'pending' (holds -- absent or ambiguous-without-a-completed-green
|
|
128
|
+
* evidence never passes). Within a SINGLE run, RED still wins a green/red tie
|
|
129
|
+
* (the rare same-run re-run that published both states resolves that run to red,
|
|
130
|
+
* never a false green); a sha with NO green run anywhere resolves to red, so a
|
|
131
|
+
* truly broken tree is never masked. The order/verdict comes from the workflow,
|
|
132
|
+
* never inferred by this reader.
|
|
82
133
|
*
|
|
83
134
|
* LEGACY refs (`refs/ci-status/<sha>/<state>`, no run number) carry no order; if
|
|
84
135
|
* ONLY legacy refs exist we fall back to the original fail-closed precedence
|
|
85
136
|
* (failure outranks success outranks pending), preserving prior behavior for
|
|
86
|
-
* shas published before the run-ordered scheme deployed.
|
|
137
|
+
* shas published before the run-ordered scheme deployed. Any ordered ref takes
|
|
138
|
+
* precedence over legacy refs for the same sha.
|
|
87
139
|
*/
|
|
88
140
|
export declare function classifyGitNativeCiStatus(refNames: readonly string[]): CiRunStatus;
|
|
89
141
|
/** Parameters passed to a CI status reader. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ci-status.d.ts","sourceRoot":"","sources":["../../src/ci/ci-status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"ci-status.d.ts","sourceRoot":"","sources":["../../src/ci/ci-status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,kCAAkC,CAAC;AAE1C;;;;;;;;GAQG;AACH,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,SAAS,GAAG,KAAK,GAAG,SAAS,CAAC;AAElE,gFAAgF;AAChF,MAAM,WAAW,mBAAmB;IAClC,2DAA2D;IAC3D,OAAO,EAAE,OAAO,CAAC;IACjB,gDAAgD;IAChD,MAAM,EAAE,WAAW,CAAC;IACpB,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;;;;OASG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,mBAAmB,CAY3E;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAUtF;AA8BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,WAAW,CAuDlF;AAED,+CAA+C;AAC/C,MAAM,WAAW,kBAAkB;IACjC,gFAAgF;IAChF,GAAG,EAAE,MAAM,CAAC;IACZ,6DAA6D;IAC7D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,+EAA+E;IAC/E,MAAM,EAAE,YAAY,CAAC;CACtB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,kBAAkB,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;AAElF;;;;;;;;;GASG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,KAAK,MAAM,EAAE,CAAC;AAEhF;;;;GAIG;AACH,8EAA8E;AAC9E,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;AAEzD;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,oBAAoB,EAAE,OAAO,GAAG,cAAc,CAIvG;AAED,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,iBAAiB,GAAG,cAAc,CAWvF"}
|
package/dist/ci/ci-status.js
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
*
|
|
25
25
|
* @module ci-status
|
|
26
26
|
*/
|
|
27
|
+
import { classifyWaitReachability, ciRunPendingWait, recordedCiResultWait, } from '../delivery/wait-reachability.js';
|
|
27
28
|
/**
|
|
28
29
|
* Pure merge-gate decision: should integration->main proceed given the merged
|
|
29
30
|
* SHA's CI status? FAIL-CLOSED (Jeremy decision 2026-07-05): only an explicit
|
|
@@ -54,6 +55,39 @@ export function resolveCiMergeGate(status) {
|
|
|
54
55
|
return { proceed: false, status: 'unknown', reason: 'CI status unavailable for the merged SHA -- holding (fail-closed: unknown != green)' };
|
|
55
56
|
}
|
|
56
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Classify whether a HELD CI merge wait can still fire, given the merged SHA.
|
|
60
|
+
* This is the reachability distinction the plain status-only gate cannot make:
|
|
61
|
+
* the merge gate correctly HOLDS on pending / red / unknown, but only some of
|
|
62
|
+
* those waits can still be satisfied without new input.
|
|
63
|
+
*
|
|
64
|
+
* - pending -> REACHABLE: a run is in flight; the CI runner (another actor)
|
|
65
|
+
* can still finish it and turn the SHA green.
|
|
66
|
+
* - red -> UNREACHABLE: a settled failure recorded for THIS sha. It never
|
|
67
|
+
* re-evaluates for the same commit (refs/ci-status/<sha> is immutable per
|
|
68
|
+
* sha), so waiting for it to "turn green" cannot succeed without a NEW
|
|
69
|
+
* commit. This is the 2026-08-17 "CI-red result auto-resolving" trap: a
|
|
70
|
+
* stall that reads as patience.
|
|
71
|
+
* - unknown -> REACHABLE (conservative): no status could be determined, so a
|
|
72
|
+
* run could still appear. We do NOT declare an unknown wait dead -- only a
|
|
73
|
+
* recorded non-green RESULT is a static fact.
|
|
74
|
+
* - green -> not held; classified REACHABLE for totality (never reached on a
|
|
75
|
+
* hold path).
|
|
76
|
+
*
|
|
77
|
+
* Pure. Reuses the shared wait-reachability classifier so the CI hold speaks the
|
|
78
|
+
* same vocabulary as every other wait.
|
|
79
|
+
*/
|
|
80
|
+
export function classifyCiMergeWait(status, sha) {
|
|
81
|
+
switch (status) {
|
|
82
|
+
case 'red':
|
|
83
|
+
return classifyWaitReachability(recordedCiResultWait(sha, 'red'));
|
|
84
|
+
case 'pending':
|
|
85
|
+
case 'unknown':
|
|
86
|
+
case 'green':
|
|
87
|
+
default:
|
|
88
|
+
return classifyWaitReachability(ciRunPendingWait(sha));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
57
91
|
/** The recognized state a ci-status ref suffix encodes, or null if unrecognized. */
|
|
58
92
|
function ciStateFromRefSuffix(ref) {
|
|
59
93
|
if (ref.endsWith('/failure') || ref.endsWith('/error') || ref.endsWith('/red'))
|
|
@@ -89,26 +123,42 @@ function ciRunOrderFromRef(ref) {
|
|
|
89
123
|
* object content read is needed. Pure -- the caller supplies the ref names from a
|
|
90
124
|
* scoped `git ls-remote` / fetch.
|
|
91
125
|
*
|
|
92
|
-
*
|
|
93
|
-
* (`refs/ci-status/<sha>/<runNumber>/<state>`)
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
126
|
+
* COMPLETED-GREEN-WINS across runs. The publisher encodes run order in the ref
|
|
127
|
+
* PATH (`refs/ci-status/<sha>/<runNumber>/<state>`) and publishes `success` ONLY
|
|
128
|
+
* when the whole suite (ci AND e2e) completed green. A completed green run is
|
|
129
|
+
* therefore unforgeable proof the SHA's tree is sound: a genuinely broken tree
|
|
130
|
+
* can never publish green, and a run destroyed mid-suite can never reach a green
|
|
131
|
+
* e2e result. So among the distinct runs of one sha, ANY completed green run
|
|
132
|
+
* outranks a red run of the same sha -- the red is the environmental casualty
|
|
133
|
+
* (an evicted run, or one whose Postgres another overlapping run force-removed
|
|
134
|
+
* mid-suite), not the tree.
|
|
99
135
|
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
136
|
+
* This REPLACES the earlier most-recent-run-wins rule, which the 2026-08-18
|
|
137
|
+
* shared-runner incident disproved: run 3838's live database was force-removed
|
|
138
|
+
* by an overlapping run 3837, so 3838 published a failure -- and because the
|
|
139
|
+
* DESTROYED run carried the HIGHER run number, "most recent wins" let its red
|
|
140
|
+
* pin a sound sha red. Run-id order did not even match start order there (3838
|
|
141
|
+
* started before 3837), so "most recent run" was never reliably most-recent.
|
|
142
|
+
* Completed-green does not depend on run-number order at all.
|
|
143
|
+
*
|
|
144
|
+
* FAIL-CLOSED throughout: an empty set / unrecognized suffix / only-pending ->
|
|
145
|
+
* 'unknown'/'pending' (holds -- absent or ambiguous-without-a-completed-green
|
|
146
|
+
* evidence never passes). Within a SINGLE run, RED still wins a green/red tie
|
|
147
|
+
* (the rare same-run re-run that published both states resolves that run to red,
|
|
148
|
+
* never a false green); a sha with NO green run anywhere resolves to red, so a
|
|
149
|
+
* truly broken tree is never masked. The order/verdict comes from the workflow,
|
|
150
|
+
* never inferred by this reader.
|
|
103
151
|
*
|
|
104
152
|
* LEGACY refs (`refs/ci-status/<sha>/<state>`, no run number) carry no order; if
|
|
105
153
|
* ONLY legacy refs exist we fall back to the original fail-closed precedence
|
|
106
154
|
* (failure outranks success outranks pending), preserving prior behavior for
|
|
107
|
-
* shas published before the run-ordered scheme deployed.
|
|
155
|
+
* shas published before the run-ordered scheme deployed. Any ordered ref takes
|
|
156
|
+
* precedence over legacy refs for the same sha.
|
|
108
157
|
*/
|
|
109
158
|
export function classifyGitNativeCiStatus(refNames) {
|
|
110
|
-
|
|
111
|
-
|
|
159
|
+
// Collect the published states per run number so each run resolves to one
|
|
160
|
+
// verdict (red wins a same-run tie) before the cross-run comparison.
|
|
161
|
+
const statesByRun = new Map();
|
|
112
162
|
let sawLegacyRed = false;
|
|
113
163
|
let sawLegacyGreen = false;
|
|
114
164
|
let sawLegacyPending = false;
|
|
@@ -127,22 +177,39 @@ export function classifyGitNativeCiStatus(refNames) {
|
|
|
127
177
|
sawLegacyPending = true;
|
|
128
178
|
continue;
|
|
129
179
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
else if (order === bestOrder) {
|
|
136
|
-
statesAtBest.add(state);
|
|
180
|
+
let set = statesByRun.get(order);
|
|
181
|
+
if (!set) {
|
|
182
|
+
set = new Set();
|
|
183
|
+
statesByRun.set(order, set);
|
|
137
184
|
}
|
|
185
|
+
set.add(state);
|
|
138
186
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
187
|
+
if (statesByRun.size > 0) {
|
|
188
|
+
// Resolve each run to a single verdict (red wins a same-run tie, fail-closed),
|
|
189
|
+
// then apply completed-green-wins across runs.
|
|
190
|
+
let anyGreen = false;
|
|
191
|
+
let anyRed = false;
|
|
192
|
+
let anyPending = false;
|
|
193
|
+
for (const set of statesByRun.values()) {
|
|
194
|
+
const runVerdict = set.has('red')
|
|
195
|
+
? 'red'
|
|
196
|
+
: set.has('green')
|
|
197
|
+
? 'green'
|
|
198
|
+
: set.has('pending')
|
|
199
|
+
? 'pending'
|
|
200
|
+
: 'unknown';
|
|
201
|
+
if (runVerdict === 'green')
|
|
202
|
+
anyGreen = true;
|
|
203
|
+
else if (runVerdict === 'red')
|
|
204
|
+
anyRed = true;
|
|
205
|
+
else if (runVerdict === 'pending')
|
|
206
|
+
anyPending = true;
|
|
207
|
+
}
|
|
208
|
+
if (anyGreen)
|
|
209
|
+
return 'green'; // a completed green run proves the tree sound
|
|
210
|
+
if (anyRed)
|
|
211
|
+
return 'red'; // no green anywhere -> a real gate red holds
|
|
212
|
+
if (anyPending)
|
|
146
213
|
return 'pending';
|
|
147
214
|
return 'unknown';
|
|
148
215
|
}
|
package/dist/ci/ci-status.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ci-status.js","sourceRoot":"","sources":["../../src/ci/ci-status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;
|
|
1
|
+
{"version":3,"file":"ci-status.js","sourceRoot":"","sources":["../../src/ci/ci-status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAGH,OAAO,EACL,wBAAwB,EACxB,gBAAgB,EAChB,oBAAoB,GAErB,MAAM,kCAAkC,CAAC;AAoC1C;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAmB;IACpD,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,OAAO;YACV,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,6BAA6B,EAAE,CAAC;QAC1E,KAAK,SAAS;YACZ,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,4EAA4E,EAAE,CAAC;QAC1H,KAAK,KAAK;YACR,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,wFAAwF,EAAE,CAAC;QACtI,KAAK,SAAS,CAAC;QACf;YACE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,qFAAqF,EAAE,CAAC;IAChJ,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAmB,EAAE,GAAW;IAClE,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,KAAK;YACR,OAAO,wBAAwB,CAAC,oBAAoB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QACpE,KAAK,SAAS,CAAC;QACf,KAAK,SAAS,CAAC;QACf,KAAK,OAAO,CAAC;QACb;YACE,OAAO,wBAAwB,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC;AAED,oFAAoF;AACpF,SAAS,oBAAoB,CAAC,GAAW;IACvC,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7F,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC;QAAE,OAAO,OAAO,CAAC;IAClG,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC;QAAE,OAAO,SAAS,CAAC;IACtG,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,iBAAiB,CAAC,GAAW;IACpC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,WAAW,EAAE,CAAC;QACnD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACvB,IAAI,KAAK,KAAK,SAAS,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAClD,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YACxB,OAAO,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC5C,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,MAAM,UAAU,yBAAyB,CAAC,QAA2B;IACnE,0EAA0E;IAC1E,qEAAqE;IACrE,MAAM,WAAW,GAAG,IAAI,GAAG,EAA4B,CAAC;IACxD,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,IAAI,cAAc,GAAG,KAAK,CAAC;IAC3B,IAAI,gBAAgB,GAAG,KAAK,CAAC;IAE7B,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,MAAM,KAAK,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,IAAI,KAAK,KAAK,KAAK;gBAAE,YAAY,GAAG,IAAI,CAAC;iBACpC,IAAI,KAAK,KAAK,OAAO;gBAAE,cAAc,GAAG,IAAI,CAAC;;gBAC7C,gBAAgB,GAAG,IAAI,CAAC;YAC7B,SAAS;QACX,CAAC;QACD,IAAI,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACjC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,GAAG,GAAG,IAAI,GAAG,EAAe,CAAC;YAC7B,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC9B,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACjB,CAAC;IAED,IAAI,WAAW,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QACzB,+EAA+E;QAC/E,+CAA+C;QAC/C,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,IAAI,MAAM,GAAG,KAAK,CAAC;QACnB,IAAI,UAAU,GAAG,KAAK,CAAC;QACvB,KAAK,MAAM,GAAG,IAAI,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;YACvC,MAAM,UAAU,GAAgB,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC;gBAC5C,CAAC,CAAC,KAAK;gBACP,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC;oBAChB,CAAC,CAAC,OAAO;oBACT,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC;wBAClB,CAAC,CAAC,SAAS;wBACX,CAAC,CAAC,SAAS,CAAC;YAClB,IAAI,UAAU,KAAK,OAAO;gBAAE,QAAQ,GAAG,IAAI,CAAC;iBACvC,IAAI,UAAU,KAAK,KAAK;gBAAE,MAAM,GAAG,IAAI,CAAC;iBACxC,IAAI,UAAU,KAAK,SAAS;gBAAE,UAAU,GAAG,IAAI,CAAC;QACvD,CAAC;QACD,IAAI,QAAQ;YAAE,OAAO,OAAO,CAAC,CAAC,8CAA8C;QAC5E,IAAI,MAAM;YAAE,OAAO,KAAK,CAAC,CAAC,6CAA6C;QACvE,IAAI,UAAU;YAAE,OAAO,SAAS,CAAC;QACjC,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,yDAAyD;IACzD,IAAI,YAAY;QAAE,OAAO,KAAK,CAAC;IAC/B,IAAI,cAAc;QAAE,OAAO,OAAO,CAAC;IACnC,IAAI,gBAAgB;QAAE,OAAO,SAAS,CAAC;IACvC,OAAO,SAAS,CAAC;AACnB,CAAC;AAyCD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAmB,EAAE,oBAA6B;IACrF,IAAI,MAAM,KAAK,KAAK,IAAI,CAAC,oBAAoB;QAAE,OAAO,MAAM,CAAC;IAC7D,IAAI,MAAM,KAAK,OAAO,IAAI,oBAAoB;QAAE,OAAO,SAAS,CAAC;IACjE,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,MAAyB;IACrE,OAAO,KAAK,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE;QAC/B,IAAI,IAAI,GAAa,EAAE,CAAC;QACxB,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,qEAAqE;YACrE,IAAI,GAAG,EAAE,CAAC;QACZ,CAAC;QACD,OAAO,yBAAyB,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -14,10 +14,37 @@
|
|
|
14
14
|
* the exact state it would approve). First drift arms a full-pass re-review (no
|
|
15
15
|
* escalation); a second consecutive drift files ONE needs_operator escalation
|
|
16
16
|
* (deduped in the DB by kind+focus). Cleared on a coverage-complete exit and on
|
|
17
|
-
* the coverage-escalation re-arm edge.
|
|
18
|
-
*
|
|
17
|
+
* the coverage-escalation re-arm edge.
|
|
18
|
+
*
|
|
19
|
+
* DURABLE: the count is a spent budget toward the review_coverage_incomplete
|
|
20
|
+
* escalation, persisted to product_focuses.below_coverage_drift_count so the
|
|
21
|
+
* second drift is still reached when a daemon re-exec falls between the two --
|
|
22
|
+
* "a spent budget stays spent" (TEL-2). recordBelowCoverageDrift /
|
|
23
|
+
* resetCoverageDriftState write through; hydrateBelowCoverageDriftCount restores
|
|
24
|
+
* it on boot. (Mutate ONLY through those functions so the write-through holds --
|
|
25
|
+
* the raw Map export remains for the read/reset call sites.)
|
|
19
26
|
*/
|
|
20
27
|
export declare const belowCoverageDriftCounts: Map<string, number>;
|
|
28
|
+
/**
|
|
29
|
+
* Durable write-through seam for the below-coverage drift count. Registered once
|
|
30
|
+
* at boot (setCoverageDriftPersister); called best-effort (fire-and-forget).
|
|
31
|
+
* Unset in tests -> pure in-memory.
|
|
32
|
+
*/
|
|
33
|
+
export type CoverageDriftPersister = (focusId: string, count: number) => void;
|
|
34
|
+
/** Register (or clear, with null) the durable write-through persister at boot. */
|
|
35
|
+
export declare function setCoverageDriftPersister(fn: CoverageDriftPersister | null): void;
|
|
36
|
+
/**
|
|
37
|
+
* Increment a focus's consecutive below-coverage drift streak by one, write it
|
|
38
|
+
* through durably, and return the new streak. The single mutation path for the
|
|
39
|
+
* increment so the durable column cannot drift from the in-memory Map.
|
|
40
|
+
*/
|
|
41
|
+
export declare function recordBelowCoverageDrift(focusId: string): number;
|
|
42
|
+
/**
|
|
43
|
+
* Restore a focus's below-coverage drift count from its persisted column, the
|
|
44
|
+
* first time the daemon sees the focus after a (re-)start. Non-clobbering +
|
|
45
|
+
* first-sight-only; skips a focus with no persisted streak.
|
|
46
|
+
*/
|
|
47
|
+
export declare function hydrateBelowCoverageDriftCount(focusId: string, count: number): void;
|
|
21
48
|
/**
|
|
22
49
|
* Focuses whose NEXT review must be a full pass (drift was detected, so the
|
|
23
50
|
* prior coverage cannot be trusted incrementally). Consumed + cleared by the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coverage-drift-state.d.ts","sourceRoot":"","sources":["../../src/completion/coverage-drift-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH
|
|
1
|
+
{"version":3,"file":"coverage-drift-state.d.ts","sourceRoot":"","sources":["../../src/completion/coverage-drift-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,wBAAwB,qBAA4B,CAAC;AAElE;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;AAI9E,kFAAkF;AAClF,wBAAgB,yBAAyB,CAAC,EAAE,EAAE,sBAAsB,GAAG,IAAI,GAAG,IAAI,CAEjF;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKhE;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAInF;AAED;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,aAAoB,CAAC;AAE5D;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAO7D;AAED,wDAAwD;AACxD,wBAAgB,iCAAiC,IAAI,IAAI,CAGxD"}
|
|
@@ -14,10 +14,45 @@
|
|
|
14
14
|
* the exact state it would approve). First drift arms a full-pass re-review (no
|
|
15
15
|
* escalation); a second consecutive drift files ONE needs_operator escalation
|
|
16
16
|
* (deduped in the DB by kind+focus). Cleared on a coverage-complete exit and on
|
|
17
|
-
* the coverage-escalation re-arm edge.
|
|
18
|
-
*
|
|
17
|
+
* the coverage-escalation re-arm edge.
|
|
18
|
+
*
|
|
19
|
+
* DURABLE: the count is a spent budget toward the review_coverage_incomplete
|
|
20
|
+
* escalation, persisted to product_focuses.below_coverage_drift_count so the
|
|
21
|
+
* second drift is still reached when a daemon re-exec falls between the two --
|
|
22
|
+
* "a spent budget stays spent" (TEL-2). recordBelowCoverageDrift /
|
|
23
|
+
* resetCoverageDriftState write through; hydrateBelowCoverageDriftCount restores
|
|
24
|
+
* it on boot. (Mutate ONLY through those functions so the write-through holds --
|
|
25
|
+
* the raw Map export remains for the read/reset call sites.)
|
|
19
26
|
*/
|
|
20
27
|
export const belowCoverageDriftCounts = new Map();
|
|
28
|
+
let coveragePersister = null;
|
|
29
|
+
/** Register (or clear, with null) the durable write-through persister at boot. */
|
|
30
|
+
export function setCoverageDriftPersister(fn) {
|
|
31
|
+
coveragePersister = fn;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Increment a focus's consecutive below-coverage drift streak by one, write it
|
|
35
|
+
* through durably, and return the new streak. The single mutation path for the
|
|
36
|
+
* increment so the durable column cannot drift from the in-memory Map.
|
|
37
|
+
*/
|
|
38
|
+
export function recordBelowCoverageDrift(focusId) {
|
|
39
|
+
const streak = (belowCoverageDriftCounts.get(focusId) ?? 0) + 1;
|
|
40
|
+
belowCoverageDriftCounts.set(focusId, streak);
|
|
41
|
+
coveragePersister?.(focusId, streak);
|
|
42
|
+
return streak;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Restore a focus's below-coverage drift count from its persisted column, the
|
|
46
|
+
* first time the daemon sees the focus after a (re-)start. Non-clobbering +
|
|
47
|
+
* first-sight-only; skips a focus with no persisted streak.
|
|
48
|
+
*/
|
|
49
|
+
export function hydrateBelowCoverageDriftCount(focusId, count) {
|
|
50
|
+
if (belowCoverageDriftCounts.has(focusId))
|
|
51
|
+
return; // in-memory wins during a run
|
|
52
|
+
if (count <= 0)
|
|
53
|
+
return; // no streak to restore
|
|
54
|
+
belowCoverageDriftCounts.set(focusId, count);
|
|
55
|
+
}
|
|
21
56
|
/**
|
|
22
57
|
* Focuses whose NEXT review must be a full pass (drift was detected, so the
|
|
23
58
|
* prior coverage cannot be trusted incrementally). Consumed + cleared by the
|
|
@@ -35,8 +70,13 @@ export const forceFullPassReviewFocuses = new Set();
|
|
|
35
70
|
* mirrors resetDeliveryAdvancementGuard's role for the team_failure re-arm.
|
|
36
71
|
*/
|
|
37
72
|
export function resetCoverageDriftState(focusId) {
|
|
73
|
+
const hadStreak = (belowCoverageDriftCounts.get(focusId) ?? 0) > 0;
|
|
38
74
|
belowCoverageDriftCounts.delete(focusId);
|
|
39
75
|
forceFullPassReviewFocuses.delete(focusId);
|
|
76
|
+
// Write the cleared budget through -- but only when it stood above 0, to avoid
|
|
77
|
+
// a needless DB write on every routed exit / re-arm (the streak is usually 0).
|
|
78
|
+
if (hadStreak)
|
|
79
|
+
coveragePersister?.(focusId, 0);
|
|
40
80
|
}
|
|
41
81
|
/** Test reset hook for the in-memory drift trackers. */
|
|
42
82
|
export function __resetCoverageDriftStateForTests() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coverage-drift-state.js","sourceRoot":"","sources":["../../src/completion/coverage-drift-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH
|
|
1
|
+
{"version":3,"file":"coverage-drift-state.js","sourceRoot":"","sources":["../../src/completion/coverage-drift-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,GAAG,EAAkB,CAAC;AASlE,IAAI,iBAAiB,GAAkC,IAAI,CAAC;AAE5D,kFAAkF;AAClF,MAAM,UAAU,yBAAyB,CAAC,EAAiC;IACzE,iBAAiB,GAAG,EAAE,CAAC;AACzB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CAAC,OAAe;IACtD,MAAM,MAAM,GAAG,CAAC,wBAAwB,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAChE,wBAAwB,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC9C,iBAAiB,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACrC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,8BAA8B,CAAC,OAAe,EAAE,KAAa;IAC3E,IAAI,wBAAwB,CAAC,GAAG,CAAC,OAAO,CAAC;QAAE,OAAO,CAAC,8BAA8B;IACjF,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,CAAC,uBAAuB;IAC/C,wBAAwB,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,IAAI,GAAG,EAAU,CAAC;AAE5D;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAe;IACrD,MAAM,SAAS,GAAG,CAAC,wBAAwB,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACnE,wBAAwB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACzC,0BAA0B,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC3C,+EAA+E;IAC/E,+EAA+E;IAC/E,IAAI,SAAS;QAAE,iBAAiB,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,iCAAiC;IAC/C,wBAAwB,CAAC,KAAK,EAAE,CAAC;IACjC,0BAA0B,CAAC,KAAK,EAAE,CAAC;AACrC,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Close half for the review_coverage_incomplete spawn block (delivery 7, Task 2).
|
|
3
|
+
*
|
|
4
|
+
* applyRespawnGuard parks EVERY spawn (coding AND review) while a
|
|
5
|
+
* review_coverage_incomplete escalation is open. The drift-streak breaker files
|
|
6
|
+
* it precisely because the focus branch kept advancing DURING each review pass,
|
|
7
|
+
* so a clean review never covered the exact state it would approve. That creates
|
|
8
|
+
* a deadlock: with review spawns blocked, no review can run to complete coverage,
|
|
9
|
+
* so the escalation can never clear at the review-exit site.
|
|
10
|
+
*
|
|
11
|
+
* The clearing condition is SPAWN-INDEPENDENT and distinct from delivery
|
|
12
|
+
* advancement (Task 1's signal): the branch has STABILIZED. The escalation
|
|
13
|
+
* records the branch tip at filing (metadata.current_tip). When the focus branch
|
|
14
|
+
* tip has not moved since -- no new commits landed -- a re-review can now cover
|
|
15
|
+
* the exact state, so the daemon resolves the escalation itself. applyRespawnGuard
|
|
16
|
+
* then permits a review spawn; if the branch has in fact re-drifted, the next
|
|
17
|
+
* review re-files the escalation, and the whole cycle is bounded by the existing
|
|
18
|
+
* review_cycle_cap. No human act.
|
|
19
|
+
*
|
|
20
|
+
* Pure decision (isCoverageBranchStable) + a thin reconcile whose git read,
|
|
21
|
+
* escalation list, and resolve are injected so it is unit-testable with no real
|
|
22
|
+
* git or DB.
|
|
23
|
+
*/
|
|
24
|
+
import { listOpenFocusEscalationsOfKind, markEscalationResolved as defaultMarkEscalationResolved } from '../queries/issues.js';
|
|
25
|
+
import { resolveRef as defaultResolveRef } from '../git/index.js';
|
|
26
|
+
/**
|
|
27
|
+
* Pure decision: has the focus branch STABILIZED at the tip recorded when the
|
|
28
|
+
* coverage-incomplete escalation was filed? True only when BOTH tips are known
|
|
29
|
+
* and equal (no commits landed since filing). A missing recorded tip (a legacy
|
|
30
|
+
* filing, or a null live read) is NOT stable -- the hold is kept, so a re-review
|
|
31
|
+
* is never armed over an unknown/moving branch. Exported for direct unit testing.
|
|
32
|
+
*/
|
|
33
|
+
export declare function isCoverageBranchStable(recordedTip: string | null | undefined, liveTip: string | null): boolean;
|
|
34
|
+
export interface CoverageStabilizedDeps {
|
|
35
|
+
/** List the focus's open review_coverage_incomplete rows (id + metadata). */
|
|
36
|
+
listOpen: typeof listOpenFocusEscalationsOfKind;
|
|
37
|
+
/** Resolve the focus branch ref to its live tip SHA (null when unreadable). */
|
|
38
|
+
resolveRef: typeof defaultResolveRef;
|
|
39
|
+
/** Resolve a single escalation row (the close-half write). */
|
|
40
|
+
markEscalationResolved: typeof defaultMarkEscalationResolved;
|
|
41
|
+
}
|
|
42
|
+
export interface CoverageStabilizedContext {
|
|
43
|
+
focusId: string;
|
|
44
|
+
focusName: string;
|
|
45
|
+
/** Pinned focus branch identity (product_focuses.branch_name), or null. */
|
|
46
|
+
branchName: string | null;
|
|
47
|
+
/** Product repo path -- the branch ref lives in its git dir (worktrees share it). */
|
|
48
|
+
repoPath: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Reconcile ONE focus's open review_coverage_incomplete hold: resolve it iff the
|
|
52
|
+
* focus branch has stabilized at the tip recorded at filing. Best-effort: any
|
|
53
|
+
* failure is logged and swallowed so the caller's cascade pass is never blocked.
|
|
54
|
+
* Returns the number of holds resolved (0 or 1 in practice -- the kind is
|
|
55
|
+
* cause-key deduped to one open row per focus).
|
|
56
|
+
*/
|
|
57
|
+
export declare function reconcileCoverageIncompleteHold(ctx: CoverageStabilizedContext, deps?: CoverageStabilizedDeps): Promise<number>;
|
|
58
|
+
//# sourceMappingURL=coverage-stabilized.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage-stabilized.d.ts","sourceRoot":"","sources":["../../src/completion/coverage-stabilized.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,8BAA8B,EAAE,sBAAsB,IAAI,6BAA6B,EAA8C,MAAM,sBAAsB,CAAC;AAC3K,OAAO,EAAE,UAAU,IAAI,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAKlE;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACtC,OAAO,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO,CAET;AAED,MAAM,WAAW,sBAAsB;IACrC,6EAA6E;IAC7E,QAAQ,EAAE,OAAO,8BAA8B,CAAC;IAChD,+EAA+E;IAC/E,UAAU,EAAE,OAAO,iBAAiB,CAAC;IACrC,8DAA8D;IAC9D,sBAAsB,EAAE,OAAO,6BAA6B,CAAC;CAC9D;AAQD,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,qFAAqF;IACrF,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAsB,+BAA+B,CACnD,GAAG,EAAE,yBAAyB,EAC9B,IAAI,GAAE,sBAAoC,GACzC,OAAO,CAAC,MAAM,CAAC,CAkCjB"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Close half for the review_coverage_incomplete spawn block (delivery 7, Task 2).
|
|
3
|
+
*
|
|
4
|
+
* applyRespawnGuard parks EVERY spawn (coding AND review) while a
|
|
5
|
+
* review_coverage_incomplete escalation is open. The drift-streak breaker files
|
|
6
|
+
* it precisely because the focus branch kept advancing DURING each review pass,
|
|
7
|
+
* so a clean review never covered the exact state it would approve. That creates
|
|
8
|
+
* a deadlock: with review spawns blocked, no review can run to complete coverage,
|
|
9
|
+
* so the escalation can never clear at the review-exit site.
|
|
10
|
+
*
|
|
11
|
+
* The clearing condition is SPAWN-INDEPENDENT and distinct from delivery
|
|
12
|
+
* advancement (Task 1's signal): the branch has STABILIZED. The escalation
|
|
13
|
+
* records the branch tip at filing (metadata.current_tip). When the focus branch
|
|
14
|
+
* tip has not moved since -- no new commits landed -- a re-review can now cover
|
|
15
|
+
* the exact state, so the daemon resolves the escalation itself. applyRespawnGuard
|
|
16
|
+
* then permits a review spawn; if the branch has in fact re-drifted, the next
|
|
17
|
+
* review re-files the escalation, and the whole cycle is bounded by the existing
|
|
18
|
+
* review_cycle_cap. No human act.
|
|
19
|
+
*
|
|
20
|
+
* Pure decision (isCoverageBranchStable) + a thin reconcile whose git read,
|
|
21
|
+
* escalation list, and resolve are injected so it is unit-testable with no real
|
|
22
|
+
* git or DB.
|
|
23
|
+
*/
|
|
24
|
+
import { listOpenFocusEscalationsOfKind, markEscalationResolved as defaultMarkEscalationResolved, REVIEW_COVERAGE_INCOMPLETE_ESCALATION_KIND } from '../queries/issues.js';
|
|
25
|
+
import { resolveRef as defaultResolveRef } from '../git/index.js';
|
|
26
|
+
import { createLogger } from '../shell/log.js';
|
|
27
|
+
const log = createLogger({ module: 'focus-executor' });
|
|
28
|
+
/**
|
|
29
|
+
* Pure decision: has the focus branch STABILIZED at the tip recorded when the
|
|
30
|
+
* coverage-incomplete escalation was filed? True only when BOTH tips are known
|
|
31
|
+
* and equal (no commits landed since filing). A missing recorded tip (a legacy
|
|
32
|
+
* filing, or a null live read) is NOT stable -- the hold is kept, so a re-review
|
|
33
|
+
* is never armed over an unknown/moving branch. Exported for direct unit testing.
|
|
34
|
+
*/
|
|
35
|
+
export function isCoverageBranchStable(recordedTip, liveTip) {
|
|
36
|
+
return !!recordedTip && !!liveTip && recordedTip === liveTip;
|
|
37
|
+
}
|
|
38
|
+
const defaultDeps = {
|
|
39
|
+
listOpen: listOpenFocusEscalationsOfKind,
|
|
40
|
+
resolveRef: defaultResolveRef,
|
|
41
|
+
markEscalationResolved: defaultMarkEscalationResolved,
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Reconcile ONE focus's open review_coverage_incomplete hold: resolve it iff the
|
|
45
|
+
* focus branch has stabilized at the tip recorded at filing. Best-effort: any
|
|
46
|
+
* failure is logged and swallowed so the caller's cascade pass is never blocked.
|
|
47
|
+
* Returns the number of holds resolved (0 or 1 in practice -- the kind is
|
|
48
|
+
* cause-key deduped to one open row per focus).
|
|
49
|
+
*/
|
|
50
|
+
export async function reconcileCoverageIncompleteHold(ctx, deps = defaultDeps) {
|
|
51
|
+
if (!ctx.branchName)
|
|
52
|
+
return 0; // no pinned branch identity -> nothing to compare
|
|
53
|
+
let open;
|
|
54
|
+
try {
|
|
55
|
+
open = await deps.listOpen(ctx.focusId, REVIEW_COVERAGE_INCOMPLETE_ESCALATION_KIND);
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
log.warn(`[coverage-stabilized] list failed for "${ctx.focusName}": ${err.message}`);
|
|
59
|
+
return 0;
|
|
60
|
+
}
|
|
61
|
+
if (open.length === 0)
|
|
62
|
+
return 0;
|
|
63
|
+
const liveTip = deps.resolveRef(ctx.repoPath, ctx.branchName);
|
|
64
|
+
let resolved = 0;
|
|
65
|
+
for (const row of open) {
|
|
66
|
+
const recordedTip = row.metadata?.current_tip ?? null;
|
|
67
|
+
if (!isCoverageBranchStable(recordedTip, liveTip))
|
|
68
|
+
continue;
|
|
69
|
+
try {
|
|
70
|
+
await deps.markEscalationResolved(row.id, 'Auto-resolved by the daemon: the focus branch stabilized at the tip recorded when coverage-incomplete ' +
|
|
71
|
+
'was filed (no commits since), so a re-review can now complete coverage -- the spawn block cleared.');
|
|
72
|
+
resolved++;
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
log.warn(`[coverage-stabilized] resolve failed for escalation ${row.id} on "${ctx.focusName}": ${err.message}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (resolved > 0) {
|
|
79
|
+
log.info(`[coverage-stabilized] Resolved ${resolved} review_coverage_incomplete hold(s) for "${ctx.focusName}" ` +
|
|
80
|
+
`-- branch stabilized at ${liveTip?.slice(0, 12)}; review spawns unblocked with no human act.`);
|
|
81
|
+
}
|
|
82
|
+
return resolved;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=coverage-stabilized.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage-stabilized.js","sourceRoot":"","sources":["../../src/completion/coverage-stabilized.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,8BAA8B,EAAE,sBAAsB,IAAI,6BAA6B,EAAE,0CAA0C,EAAE,MAAM,sBAAsB,CAAC;AAC3K,OAAO,EAAE,UAAU,IAAI,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,MAAM,GAAG,GAAG,YAAY,CAAC,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;AAEvD;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CACpC,WAAsC,EACtC,OAAsB;IAEtB,OAAO,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,OAAO,IAAI,WAAW,KAAK,OAAO,CAAC;AAC/D,CAAC;AAWD,MAAM,WAAW,GAA2B;IAC1C,QAAQ,EAAE,8BAA8B;IACxC,UAAU,EAAE,iBAAiB;IAC7B,sBAAsB,EAAE,6BAA6B;CACtD,CAAC;AAWF;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,+BAA+B,CACnD,GAA8B,EAC9B,OAA+B,WAAW;IAE1C,IAAI,CAAC,GAAG,CAAC,UAAU;QAAE,OAAO,CAAC,CAAC,CAAC,kDAAkD;IACjF,IAAI,IAAqE,CAAC;IAC1E,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,0CAA0C,CAAC,CAAC;IACtF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,IAAI,CAAC,0CAA0C,GAAG,CAAC,SAAS,MAAO,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAChG,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAEhC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;IAC9D,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,WAAW,GAAI,GAAG,CAAC,QAAQ,EAAE,WAAyC,IAAI,IAAI,CAAC;QACrF,IAAI,CAAC,sBAAsB,CAAC,WAAW,EAAE,OAAO,CAAC;YAAE,SAAS;QAC5D,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,sBAAsB,CAC/B,GAAG,CAAC,EAAE,EACN,wGAAwG;gBACtG,oGAAoG,CACvG,CAAC;YACF,QAAQ,EAAE,CAAC;QACb,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,IAAI,CAAC,uDAAuD,GAAG,CAAC,EAAE,QAAQ,GAAG,CAAC,SAAS,MAAO,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7H,CAAC;IACH,CAAC;IACD,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;QACjB,GAAG,CAAC,IAAI,CACN,kCAAkC,QAAQ,4CAA4C,GAAG,CAAC,SAAS,IAAI;YACvG,2BAA2B,OAAO,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,8CAA8C,CAC/F,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -70,6 +70,27 @@ export interface DeliveryAdvancementDecision {
|
|
|
70
70
|
noAdvancementCycles: number;
|
|
71
71
|
thresholdReached: boolean;
|
|
72
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* Durable write-through seam for the cross-respawn no-progress state. Registered
|
|
75
|
+
* once at daemon boot (setDeliveryAdvancementPersister); called best-effort
|
|
76
|
+
* (fire-and-forget) whenever the state changes, and with null when the guard is
|
|
77
|
+
* reset for a focus. Unset in tests -> the guard stays pure in-memory. This is
|
|
78
|
+
* what makes a spent no-advancement budget survive the auto-updater's re-exec
|
|
79
|
+
* (module-scope state alone reset noAdvancementCycles to 0 every restart, handing
|
|
80
|
+
* a focus about to trip its team_failure halt a fresh budget).
|
|
81
|
+
*/
|
|
82
|
+
export type DeliveryAdvancementPersister = (focusId: string, state: DeliveryAdvancementState | null) => void;
|
|
83
|
+
/** Register (or clear, with null) the durable write-through persister at boot. */
|
|
84
|
+
export declare function setDeliveryAdvancementPersister(fn: DeliveryAdvancementPersister | null): void;
|
|
85
|
+
/**
|
|
86
|
+
* Restore a focus's no-progress watchdog state from its persisted column, the
|
|
87
|
+
* FIRST time the daemon sees the focus after a (re-)start. Non-clobbering: a
|
|
88
|
+
* state already tracked in memory this run wins (hydrate never overwrites a live
|
|
89
|
+
* cycle). Restoring the SNAPSHOT alongside the counter is essential -- a bare
|
|
90
|
+
* counter would rebase to 0 on the first post-restart cycle for lack of a prior
|
|
91
|
+
* to compare against, silently forgiving the streak.
|
|
92
|
+
*/
|
|
93
|
+
export declare function hydrateDeliveryAdvancementState(focusId: string, state: DeliveryAdvancementState | null): void;
|
|
73
94
|
export declare function takeDeliveryAdvancementSnapshot(deliveries: Pick<FocusDeliveryInfo, 'id' | 'executionStatus'>[], issues?: Pick<FocusIssueInfo, 'id' | 'status'>[], focusHeadSha?: string | null): DeliveryAdvancementSnapshot;
|
|
74
95
|
export declare function deliveryAdvancementSnapshotsEqual(a: DeliveryAdvancementSnapshot, b: DeliveryAdvancementSnapshot): boolean;
|
|
75
96
|
export declare function recordDeliveryAdvancementCycle(focusId: string, deliveries: Pick<FocusDeliveryInfo, 'id' | 'executionStatus'>[], issues: Pick<FocusIssueInfo, 'id' | 'status'>[], focusHeadSha: string | null, threshold: number,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delivery-advancement-guard.d.ts","sourceRoot":"","sources":["../../src/completion/delivery-advancement-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAE3E,MAAM,WAAW,2BAA2B;IAC1C;iFAC6E;IAC7E,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC;mEAC+D;IAC/D,gBAAgB,EAAE,MAAM,CAAC;IACzB;+DAC2D;IAC3D,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,2BAA2B,CAAC;IACtC,mBAAmB,EAAE,MAAM,CAAC;IAC5B;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,OAAO,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,EAAE,OAAO,CAAC;CAC3B;
|
|
1
|
+
{"version":3,"file":"delivery-advancement-guard.d.ts","sourceRoot":"","sources":["../../src/completion/delivery-advancement-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAE3E,MAAM,WAAW,2BAA2B;IAC1C;iFAC6E;IAC7E,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC;mEAC+D;IAC/D,gBAAgB,EAAE,MAAM,CAAC;IACzB;+DAC2D;IAC3D,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,2BAA2B,CAAC;IACtC,mBAAmB,EAAE,MAAM,CAAC;IAC5B;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,OAAO,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAID;;;;;;;;GAQG;AACH,MAAM,MAAM,4BAA4B,GAAG,CACzC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,wBAAwB,GAAG,IAAI,KACnC,IAAI,CAAC;AAIV,kFAAkF;AAClF,wBAAgB,+BAA+B,CAAC,EAAE,EAAE,4BAA4B,GAAG,IAAI,GAAG,IAAI,CAE7F;AAQD;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,wBAAwB,GAAG,IAAI,GACrC,IAAI,CAIN;AAeD,wBAAgB,+BAA+B,CAC7C,UAAU,EAAE,IAAI,CAAC,iBAAiB,EAAE,IAAI,GAAG,iBAAiB,CAAC,EAAE,EAC/D,MAAM,GAAE,IAAI,CAAC,cAAc,EAAE,IAAI,GAAG,QAAQ,CAAC,EAAO,EACpD,YAAY,GAAE,MAAM,GAAG,IAAW,GACjC,2BAA2B,CAU7B;AAED,wBAAgB,iCAAiC,CAC/C,CAAC,EAAE,2BAA2B,EAC9B,CAAC,EAAE,2BAA2B,GAC7B,OAAO,CAaT;AAED,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,IAAI,CAAC,iBAAiB,EAAE,IAAI,GAAG,iBAAiB,CAAC,EAAE,EAC/D,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,GAAG,QAAQ,CAAC,EAAE,EAC/C,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,SAAS,EAAE,MAAM;AACjB,+EAA+E;AAC/E,KAAK,GAAE,MAAmB;AAC1B;;;;;GAKG;AACH,OAAO,SAAI,GACV,2BAA2B,CAqC7B;AAED,wBAAgB,6BAA6B,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CASpE"}
|