@telora/daemon 0.22.144 → 0.22.160
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 +8 -3
- package/dist/audit/audit-phase.d.ts +34 -1
- package/dist/audit/audit-phase.d.ts.map +1 -1
- package/dist/audit/audit-phase.js +77 -9
- package/dist/audit/audit-phase.js.map +1 -1
- package/dist/backends/codex/codex-mcp-proxy.d.ts +4 -6
- package/dist/backends/codex/codex-mcp-proxy.d.ts.map +1 -1
- package/dist/backends/codex/codex-mcp-proxy.js.map +1 -1
- package/dist/backends/codex/mcp-preflight.d.ts +2 -2
- package/dist/backends/codex/mcp-preflight.d.ts.map +1 -1
- package/dist/backends/codex/mcp-preflight.js.map +1 -1
- package/dist/completion/completion-phase-registry.d.ts +1 -0
- package/dist/completion/completion-phase-registry.d.ts.map +1 -1
- package/dist/completion/completion-phase-registry.js +7 -5
- package/dist/completion/completion-phase-registry.js.map +1 -1
- package/dist/completion/escalation-provenance.d.ts.map +1 -1
- package/dist/completion/escalation-provenance.js +5 -2
- package/dist/completion/escalation-provenance.js.map +1 -1
- package/dist/completion/exit-classification.d.ts +1 -1
- package/dist/completion/exit-classification.d.ts.map +1 -1
- package/dist/completion/exit-classification.js +7 -1
- package/dist/completion/exit-classification.js.map +1 -1
- package/dist/completion/review-cycle-cap.d.ts +81 -35
- package/dist/completion/review-cycle-cap.d.ts.map +1 -1
- package/dist/completion/review-cycle-cap.js +60 -132
- package/dist/completion/review-cycle-cap.js.map +1 -1
- package/dist/completion/review-exit-deps.d.ts +3 -1
- package/dist/completion/review-exit-deps.d.ts.map +1 -1
- package/dist/completion/review-exit-deps.js +3 -1
- package/dist/completion/review-exit-deps.js.map +1 -1
- package/dist/completion/review-exit-phase.d.ts.map +1 -1
- package/dist/completion/review-exit-phase.js +5 -4
- package/dist/completion/review-exit-phase.js.map +1 -1
- package/dist/completion/state-cascade.d.ts.map +1 -1
- package/dist/completion/state-cascade.js +3 -7
- package/dist/completion/state-cascade.js.map +1 -1
- package/dist/delivery/delivery-review-coverage.d.ts +16 -0
- package/dist/delivery/delivery-review-coverage.d.ts.map +1 -1
- package/dist/delivery/delivery-review-coverage.js +16 -0
- package/dist/delivery/delivery-review-coverage.js.map +1 -1
- package/dist/focus/focus-engine.d.ts +16 -0
- package/dist/focus/focus-engine.d.ts.map +1 -1
- package/dist/focus/focus-engine.js +37 -17
- 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 +7 -0
- package/dist/focus/focus-executor.js.map +1 -1
- package/dist/focus/focus-spawn-decision.d.ts +5 -3
- package/dist/focus/focus-spawn-decision.d.ts.map +1 -1
- package/dist/focus/focus-spawn-decision.js.map +1 -1
- package/dist/focus/listener-spawn.d.ts.map +1 -1
- package/dist/focus/listener-spawn.js +4 -3
- package/dist/focus/listener-spawn.js.map +1 -1
- package/dist/focus/listener.d.ts +15 -0
- package/dist/focus/listener.d.ts.map +1 -1
- package/dist/focus/listener.js +58 -9
- package/dist/focus/listener.js.map +1 -1
- package/dist/focus/review-cycle-cap-hold.d.ts +15 -94
- package/dist/focus/review-cycle-cap-hold.d.ts.map +1 -1
- package/dist/focus/review-cycle-cap-hold.js +54 -112
- package/dist/focus/review-cycle-cap-hold.js.map +1 -1
- package/dist/focus/session-health.d.ts +22 -1
- package/dist/focus/session-health.d.ts.map +1 -1
- package/dist/focus/session-health.js +28 -3
- package/dist/focus/session-health.js.map +1 -1
- package/dist/focus/session-process-reap.d.ts +3 -1
- package/dist/focus/session-process-reap.d.ts.map +1 -1
- package/dist/focus/session-process-reap.js +20 -0
- package/dist/focus/session-process-reap.js.map +1 -1
- package/dist/focus-stage-lifecycle/index.d.ts.map +1 -1
- package/dist/focus-stage-lifecycle/index.js +1 -0
- package/dist/focus-stage-lifecycle/index.js.map +1 -1
- package/dist/focus-stage-lifecycle/wedge-watchdog.d.ts +10 -0
- package/dist/focus-stage-lifecycle/wedge-watchdog.d.ts.map +1 -1
- package/dist/focus-stage-lifecycle/wedge-watchdog.js +27 -3
- package/dist/focus-stage-lifecycle/wedge-watchdog.js.map +1 -1
- package/dist/git/focus-integration-sync.d.ts +42 -3
- package/dist/git/focus-integration-sync.d.ts.map +1 -1
- package/dist/git/focus-integration-sync.js +38 -2
- package/dist/git/focus-integration-sync.js.map +1 -1
- package/dist/merge/abandoned-merge-recovery.d.ts.map +1 -1
- package/dist/merge/abandoned-merge-recovery.js +10 -0
- package/dist/merge/abandoned-merge-recovery.js.map +1 -1
- package/dist/merge/merge-back-loop.d.ts +1 -0
- package/dist/merge/merge-back-loop.d.ts.map +1 -1
- package/dist/merge/merge-back-loop.js +3 -3
- package/dist/merge/merge-back-loop.js.map +1 -1
- package/dist/prompt/team-prompt-base.d.ts +2 -1
- package/dist/prompt/team-prompt-base.d.ts.map +1 -1
- package/dist/prompt/team-prompt-base.js +5 -19
- package/dist/prompt/team-prompt-base.js.map +1 -1
- package/dist/prompt-sections/integration-reconcile-section.d.ts +45 -0
- package/dist/prompt-sections/integration-reconcile-section.d.ts.map +1 -0
- package/dist/prompt-sections/integration-reconcile-section.js +69 -0
- package/dist/prompt-sections/integration-reconcile-section.js.map +1 -0
- package/dist/prompt-sections/persona-sections.d.ts +0 -20
- package/dist/prompt-sections/persona-sections.d.ts.map +1 -1
- package/dist/prompt-sections/persona-sections.js +4 -49
- package/dist/prompt-sections/persona-sections.js.map +1 -1
- package/dist/prompt-sections/testing-standard.d.ts +51 -0
- package/dist/prompt-sections/testing-standard.d.ts.map +1 -0
- package/dist/prompt-sections/testing-standard.js +132 -0
- package/dist/prompt-sections/testing-standard.js.map +1 -0
- package/dist/queries/agent-resolvable-promotion.d.ts.map +1 -1
- package/dist/queries/agent-resolvable-promotion.js +7 -5
- package/dist/queries/agent-resolvable-promotion.js.map +1 -1
- package/dist/queries/ended-arm.d.ts +47 -0
- package/dist/queries/ended-arm.d.ts.map +1 -0
- package/dist/queries/ended-arm.js +35 -0
- package/dist/queries/ended-arm.js.map +1 -0
- package/dist/queries/escalation-consumption.d.ts.map +1 -1
- package/dist/queries/escalation-consumption.js +0 -1
- package/dist/queries/escalation-consumption.js.map +1 -1
- package/dist/queries/focus-discovery.d.ts +14 -0
- package/dist/queries/focus-discovery.d.ts.map +1 -1
- package/dist/queries/focus-discovery.js +1 -0
- package/dist/queries/focus-discovery.js.map +1 -1
- package/dist/queries/focus-integration-conflict.d.ts +78 -0
- package/dist/queries/focus-integration-conflict.d.ts.map +1 -0
- package/dist/queries/focus-integration-conflict.js +136 -0
- package/dist/queries/focus-integration-conflict.js.map +1 -0
- package/dist/queries/focuses.d.ts +6 -3
- package/dist/queries/focuses.d.ts.map +1 -1
- package/dist/queries/focuses.js +13 -5
- package/dist/queries/focuses.js.map +1 -1
- package/dist/queries/incident-correlation.d.ts +1 -2
- package/dist/queries/incident-correlation.d.ts.map +1 -1
- package/dist/queries/incident-correlation.js +1 -3
- package/dist/queries/incident-correlation.js.map +1 -1
- package/dist/queries/local-models.js +1 -1
- package/dist/queries/local-models.js.map +1 -1
- package/dist/queries/schemas-local-model.d.ts +47 -0
- package/dist/queries/schemas-local-model.d.ts.map +1 -0
- package/dist/queries/schemas-local-model.js +57 -0
- package/dist/queries/schemas-local-model.js.map +1 -0
- package/dist/queries/schemas.d.ts +10 -32
- package/dist/queries/schemas.d.ts.map +1 -1
- package/dist/queries/schemas.js +10 -41
- package/dist/queries/schemas.js.map +1 -1
- package/dist/queries/sessions.d.ts +120 -12
- package/dist/queries/sessions.d.ts.map +1 -1
- package/dist/queries/sessions.js +104 -11
- package/dist/queries/sessions.js.map +1 -1
- package/dist/queries/shared.d.ts +1 -0
- package/dist/queries/shared.d.ts.map +1 -1
- package/dist/queries/shared.js +1 -1
- package/dist/queries/shared.js.map +1 -1
- package/dist/queries/system-session.d.ts.map +1 -1
- package/dist/queries/system-session.js +3 -1
- package/dist/queries/system-session.js.map +1 -1
- package/dist/resolvers/assembly-engine.d.ts +71 -1
- package/dist/resolvers/assembly-engine.d.ts.map +1 -1
- package/dist/resolvers/assembly-engine.js +82 -43
- package/dist/resolvers/assembly-engine.js.map +1 -1
- package/dist/resolvers/branch-work-arming.d.ts +133 -0
- package/dist/resolvers/branch-work-arming.d.ts.map +1 -0
- package/dist/resolvers/branch-work-arming.js +67 -0
- package/dist/resolvers/branch-work-arming.js.map +1 -0
- package/dist/resolvers/focus-review-coverage.d.ts.map +1 -1
- package/dist/resolvers/focus-review-coverage.js +31 -2
- package/dist/resolvers/focus-review-coverage.js.map +1 -1
- package/dist/resolvers/wiki-topic.d.ts +6 -5
- package/dist/resolvers/wiki-topic.d.ts.map +1 -1
- package/dist/resolvers/wiki-topic.js +43 -27
- package/dist/resolvers/wiki-topic.js.map +1 -1
- package/dist/session/session-lineage.d.ts.map +1 -1
- package/dist/session/session-lineage.js +1 -0
- package/dist/session/session-lineage.js.map +1 -1
- package/dist/shell/crash-recovery.d.ts +4 -2
- package/dist/shell/crash-recovery.d.ts.map +1 -1
- package/dist/shell/crash-recovery.js +15 -14
- package/dist/shell/crash-recovery.js.map +1 -1
- package/dist/shell/daemon-instance.d.ts +176 -0
- package/dist/shell/daemon-instance.d.ts.map +1 -0
- package/dist/shell/daemon-instance.js +281 -0
- package/dist/shell/daemon-instance.js.map +1 -0
- package/dist/shell/graceful-shutdown.d.ts +12 -1
- package/dist/shell/graceful-shutdown.d.ts.map +1 -1
- package/dist/shell/graceful-shutdown.js +7 -4
- package/dist/shell/graceful-shutdown.js.map +1 -1
- package/dist/shell/shutdown-ownership.d.ts +34 -0
- package/dist/shell/shutdown-ownership.d.ts.map +1 -0
- package/dist/shell/shutdown-ownership.js +51 -0
- package/dist/shell/shutdown-ownership.js.map +1 -0
- package/dist/shell/unified-shell.d.ts.map +1 -1
- package/dist/shell/unified-shell.js +12 -5
- package/dist/shell/unified-shell.js.map +1 -1
- package/dist/shell/worker-pidfile.d.ts +127 -11
- package/dist/shell/worker-pidfile.d.ts.map +1 -1
- package/dist/shell/worker-pidfile.js +349 -58
- package/dist/shell/worker-pidfile.js.map +1 -1
- package/dist/spawn/lead-launch.d.ts +17 -1
- package/dist/spawn/lead-launch.d.ts.map +1 -1
- package/dist/spawn/lead-launch.js +56 -7
- package/dist/spawn/lead-launch.js.map +1 -1
- package/dist/spawn/lead-process-ownership.d.ts +5 -4
- package/dist/spawn/lead-process-ownership.d.ts.map +1 -1
- package/dist/spawn/lead-process-ownership.js +7 -4
- package/dist/spawn/lead-process-ownership.js.map +1 -1
- package/dist/spawn/lifecycle.d.ts +0 -12
- package/dist/spawn/lifecycle.d.ts.map +1 -1
- package/dist/spawn/lifecycle.js +76 -19
- package/dist/spawn/lifecycle.js.map +1 -1
- package/dist/spawn/liveness.d.ts.map +1 -1
- package/dist/spawn/liveness.js +3 -1
- package/dist/spawn/liveness.js.map +1 -1
- package/dist/spawn/one-shot-process-ownership.d.ts +46 -2
- package/dist/spawn/one-shot-process-ownership.d.ts.map +1 -1
- package/dist/spawn/one-shot-process-ownership.js +78 -3
- package/dist/spawn/one-shot-process-ownership.js.map +1 -1
- package/dist/spawn/process-group-kill.d.ts.map +1 -1
- package/dist/spawn/process-group-kill.js +3 -1
- package/dist/spawn/process-group-kill.js.map +1 -1
- package/dist/spawn/process-spawn.d.ts +5 -15
- package/dist/spawn/process-spawn.d.ts.map +1 -1
- package/dist/spawn/process-spawn.js +2 -1
- package/dist/spawn/process-spawn.js.map +1 -1
- package/dist/spawn/prompt-assembly.d.ts +27 -2
- package/dist/spawn/prompt-assembly.d.ts.map +1 -1
- package/dist/spawn/prompt-assembly.js +65 -43
- package/dist/spawn/prompt-assembly.js.map +1 -1
- package/dist/spawn/worktree-session.d.ts +46 -2
- package/dist/spawn/worktree-session.d.ts.map +1 -1
- package/dist/spawn/worktree-session.js +57 -4
- package/dist/spawn/worktree-session.js.map +1 -1
- package/dist/testing/fixtures/conflicting-repo.d.ts +30 -0
- package/dist/testing/fixtures/conflicting-repo.d.ts.map +1 -0
- package/dist/testing/fixtures/conflicting-repo.js +89 -0
- package/dist/testing/fixtures/conflicting-repo.js.map +1 -0
- package/dist/testing/fixtures/index.d.ts.map +1 -1
- package/dist/testing/fixtures/index.js +2 -1
- package/dist/testing/fixtures/index.js.map +1 -1
- package/dist/testing/fixtures/pending-spawn-world.js +2 -2
- package/dist/testing/fixtures/pending-spawn-world.js.map +1 -1
- package/dist/types/exit-category.d.ts +59 -0
- package/dist/types/exit-category.d.ts.map +1 -0
- package/dist/types/exit-category.js +133 -0
- package/dist/types/exit-category.js.map +1 -0
- package/dist/types/index.js +1 -1
- package/dist/types/session.d.ts +5 -1
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types/session.js +1 -1
- package/dist/types/session.js.map +1 -1
- package/dist/verify/stall-detector-config.d.ts +5 -1
- package/dist/verify/stall-detector-config.d.ts.map +1 -1
- package/dist/verify/stall-detector-config.js +5 -1
- package/dist/verify/stall-detector-config.js.map +1 -1
- package/dist/worktree/state.d.ts +75 -1
- package/dist/worktree/state.d.ts.map +1 -1
- package/dist/worktree/state.js +89 -17
- package/dist/worktree/state.js.map +1 -1
- package/package.json +3 -3
|
@@ -3,122 +3,65 @@
|
|
|
3
3
|
// packages/daemon/src/focus/review-cycle-cap-hold.test.ts
|
|
4
4
|
// PINNED-BY-END
|
|
5
5
|
/**
|
|
6
|
-
* The review-
|
|
7
|
-
* TELORA_REVIEW_CYCLE_CAP
|
|
8
|
-
* pass.
|
|
6
|
+
* The review-budget BACKSTOP: a focus whose review_cycle_count stands at
|
|
7
|
+
* TELORA_REVIEW_CYCLE_CAP spawns no further coding or review pass.
|
|
9
8
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* (completion/review-
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* (
|
|
9
|
+
* THIS IS NOT THE STOP. The stop is the un-arm: when the budget is spent the
|
|
10
|
+
* daemon releases the focus's assigned agent role
|
|
11
|
+
* (completion/review-cycle-cap.ts), and a null role is inert for every spawn
|
|
12
|
+
* path whatever the arm history (spawn/null-role-spawn.ts focusMayRunTeam).
|
|
13
|
+
* This module exists for the one case that leaves: the un-arm WRITE FAILED. The
|
|
14
|
+
* count is written before the release, so a failed release still leaves
|
|
15
|
+
* `count >= cap` standing, and that alone holds every gate until a later
|
|
16
|
+
* crossing lands the release or a human re-arms (which resets the count to 0 in
|
|
17
|
+
* the database, migration 20260920140801).
|
|
18
18
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
19
|
+
* WHAT WAS DELETED AND WHY. The crossing used to file a
|
|
20
|
+
* review_cycle_cap_exceeded observation, and this hold stood while that
|
|
21
|
+
* observation -- or a human-facing filing a routing decider made from it -- was
|
|
22
|
+
* open. That made the stop answerable from inside the loop it stopped: on
|
|
23
|
+
* 2026-09-19/20 a routing decider granted three capped foci eight more cycles
|
|
24
|
+
* each within minutes. No observation is filed any more, so the two clauses that
|
|
25
|
+
* read one (the open observation, and its lineage carrier) had nothing left to
|
|
26
|
+
* read and are gone, along with the cascade pass that re-filed a failed filing.
|
|
27
|
+
* ONE clause remains, and it is the fail-closed one.
|
|
28
|
+
*
|
|
29
|
+
* Read identically by every gate that can spawn a pass for a focus or open the
|
|
30
|
+
* window that spawns one:
|
|
21
31
|
* - the ready-focus spawn gate (focus/focus-spawn-decision.ts decideFocusSpawn)
|
|
22
32
|
* - the pending-directive spawn pass (focus/listener-spawn.ts processPendingSpawnFocuses)
|
|
23
33
|
* - the auto-review window (completion/state-cascade.ts checkAutoReview)
|
|
24
|
-
* spawnFocusTeam has exactly those two callers, and a stage directive never
|
|
25
|
-
* on its own (directive/directive-dispatch.ts stashes it for the pending
|
|
26
|
-
* these gates are the whole spawn surface.
|
|
27
|
-
*
|
|
28
|
-
* The hold is standing while ANY of three facts holds (isReviewCycleCapHeld):
|
|
29
|
-
* - an OPEN review_cycle_cap_exceeded observation for the focus. The crossing
|
|
30
|
-
* resets review_cycle_count to 0 once that observation is filed
|
|
31
|
-
* (completion/review-cycle-cap.ts), so a fresh cap of cycles is needed to
|
|
32
|
-
* re-cross. The hold is keyed on the machine-lane observation's KIND, never on
|
|
33
|
-
* a human act: the daemon has no human-facing route, and the promotion sweep
|
|
34
|
-
* hands a held focus's observations to the routing decider
|
|
35
|
-
* (queries/agent-resolvable-promotion.ts).
|
|
36
|
-
* - an OPEN lineage CARRIER naming one of the focus's review_cycle_cap_exceeded
|
|
37
|
-
* observations, open or resolved: a human-lane row whose
|
|
38
|
-
* metadata.originalEscalationId names it (queries/escalation-consumption.ts
|
|
39
|
-
* LineageCarrier -- what a routing decider files through telora_agent escalate
|
|
40
|
-
* with sourceEscalationId). The sweep closes the observation auto_swept the
|
|
41
|
-
* moment such a row exists, so without this fact the hold would lift -- and the
|
|
42
|
-
* focus bill another full cap of cycles -- while the human-facing filing still
|
|
43
|
-
* sits unacted. A carrier has its own close-half (its resolution), unlike a
|
|
44
|
-
* correlated or absorbed symptom, which is why carriers are matched by lineage
|
|
45
|
-
* here and hasOpenFocusEscalation's matchCorrelated is not used as the hold.
|
|
46
|
-
* Carriers carry no kind marker (no originalKind; original_cause_key only when
|
|
47
|
-
* the source had a cause_key, which this observation does not), so the match
|
|
48
|
-
* is by source id against the focus's own rows of the kind, any status.
|
|
49
|
-
* - review_cycle_count >= cap: the count is written before the filing, so a
|
|
50
|
-
* filing that fails still holds; the cascade re-files it every poll until it
|
|
51
|
-
* lands (reconcileReviewCycleCapFiling).
|
|
52
|
-
* Resolving the observation with no carrier, or resolving the carrier, lifts the
|
|
53
|
-
* hold (the count is already 0).
|
|
34
|
+
* spawnFocusTeam has exactly those two callers, and a stage directive never
|
|
35
|
+
* spawns on its own (directive/directive-dispatch.ts stashes it for the pending
|
|
36
|
+
* pass), so these gates are the whole spawn surface.
|
|
54
37
|
*
|
|
55
|
-
* Fails CLOSED: an unreadable count
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
38
|
+
* Fails CLOSED: an unreadable count holds. This is a stop gate
|
|
39
|
+
* (workflow/gate-failure-policy.ts, safety class) and the read repeats each
|
|
40
|
+
* poll, so a transient failure delays one poll instead of billing a pass the
|
|
41
|
+
* budget exists to prevent.
|
|
59
42
|
*
|
|
60
43
|
* @module focus/review-cycle-cap-hold
|
|
61
44
|
*/
|
|
62
|
-
import { listFocusEscalationsOfKind, listOpenLineageCarriersForOrg, } from '../queries/escalation-consumption.js';
|
|
63
|
-
import { isOpenFocusKindRow } from '../queries/incident-correlation.js';
|
|
64
45
|
import { getActiveFocuses } from '../queries/focus-discovery.js';
|
|
65
46
|
import { resolveReviewCycleCap } from '../verify/stall-detector-config.js';
|
|
66
47
|
import { safetyGateFailsClosed } from '../workflow/gate-failure-policy.js';
|
|
67
48
|
import { createLogger } from '../shell/log.js';
|
|
68
49
|
const log = createLogger({ module: 'focus' });
|
|
69
|
-
/**
|
|
70
|
-
export const REVIEW_CYCLE_CAP_EXCEEDED_KIND = 'review_cycle_cap_exceeded';
|
|
71
|
-
/** Pure: whether the review-cycle cap holds the focus. An unreadable fact holds. */
|
|
50
|
+
/** Pure: whether the spent review budget holds the focus. An unreadable count holds. */
|
|
72
51
|
export function isReviewCycleCapHeld(facts) {
|
|
73
|
-
if (facts.reviewCycleCount === null
|
|
52
|
+
if (facts.reviewCycleCount === null)
|
|
74
53
|
return true;
|
|
75
|
-
return facts.
|
|
76
|
-
}
|
|
77
|
-
/** Pure: whether an open carrier names one of the given cap observations (matched by source id). */
|
|
78
|
-
export function capCarrierNamesObservation(carriers, capObservationIds) {
|
|
79
|
-
return carriers.some((c) => capObservationIds.has(c.sourceEscalationId));
|
|
54
|
+
return facts.reviewCycleCount >= facts.cap;
|
|
80
55
|
}
|
|
81
56
|
/** Pure: why a held focus is held, for the one log line per episode. */
|
|
82
57
|
function describeHold(facts) {
|
|
83
|
-
if (facts.reviewCycleCount === null
|
|
84
|
-
return '
|
|
85
|
-
}
|
|
86
|
-
if (facts.capObservationOpen)
|
|
87
|
-
return 'its review_cycle_cap_exceeded observation is open';
|
|
88
|
-
if (facts.capCarrierOpen)
|
|
89
|
-
return 'a human-facing filing made from its review_cycle_cap_exceeded observation is open';
|
|
58
|
+
if (facts.reviewCycleCount === null)
|
|
59
|
+
return 'its review-cycle count could not be read (fail closed)';
|
|
90
60
|
return `cycles=${facts.reviewCycleCount} >= cap=${facts.cap}`;
|
|
91
61
|
}
|
|
92
|
-
/**
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
* the decision: skipped (false) when the focus has no cap observation for a
|
|
96
|
-
* carrier to name, or when the other facts already hold.
|
|
97
|
-
*/
|
|
98
|
-
export async function readReviewCycleCapFacts(focus, deps = {}) {
|
|
99
|
-
const base = { reviewCycleCount: focus.reviewCycleCount, cap: (deps.resolveReviewCycleCap ?? resolveReviewCycleCap)() };
|
|
100
|
-
const site = `review-cycle-cap-hold "${focus.focusName}"`;
|
|
101
|
-
const listRows = deps.listCapObservations
|
|
102
|
-
?? ((focusId) => listFocusEscalationsOfKind(focusId, REVIEW_CYCLE_CAP_EXCEEDED_KIND));
|
|
103
|
-
let rows;
|
|
104
|
-
try {
|
|
105
|
-
rows = await listRows(focus.focusId);
|
|
106
|
-
}
|
|
107
|
-
catch (err) {
|
|
108
|
-
return { ...base, capObservationOpen: safetyGateFailsClosed(`${site} observation read`, err, null), capCarrierOpen: null };
|
|
109
|
-
}
|
|
110
|
-
const own = rows.filter((r) => r.focusId === focus.focusId && r.escalationKind === REVIEW_CYCLE_CAP_EXCEEDED_KIND);
|
|
111
|
-
const capObservationOpen = own.some((r) => isOpenFocusKindRow(r, focus.focusId, REVIEW_CYCLE_CAP_EXCEEDED_KIND));
|
|
112
|
-
const unread = { ...base, capObservationOpen, capCarrierOpen: false };
|
|
113
|
-
if (own.length === 0 || isReviewCycleCapHeld(unread))
|
|
114
|
-
return unread;
|
|
115
|
-
try {
|
|
116
|
-
const carriers = await (deps.listOpenLineageCarriers ?? (() => listOpenLineageCarriersForOrg()))();
|
|
117
|
-
return { ...unread, capCarrierOpen: capCarrierNamesObservation(carriers, new Set(own.map((r) => r.id))) };
|
|
118
|
-
}
|
|
119
|
-
catch (err) {
|
|
120
|
-
return { ...unread, capCarrierOpen: safetyGateFailsClosed(`${site} lineage-carrier read`, err, null) };
|
|
121
|
-
}
|
|
62
|
+
/** Read the backstop's facts for a focus whose review_cycle_count the caller already read. */
|
|
63
|
+
export function readReviewCycleCapFacts(focus, deps = {}) {
|
|
64
|
+
return { reviewCycleCount: focus.reviewCycleCount, cap: (deps.resolveReviewCycleCap ?? resolveReviewCycleCap)() };
|
|
122
65
|
}
|
|
123
66
|
/** Focuses whose held episode was already logged (one line per episode, not per poll). */
|
|
124
67
|
const heldLoggedFocuses = new Set();
|
|
@@ -127,31 +70,33 @@ export function __resetReviewCycleCapHoldLog() {
|
|
|
127
70
|
heldLoggedFocuses.clear();
|
|
128
71
|
}
|
|
129
72
|
/**
|
|
130
|
-
* Resolve the
|
|
131
|
-
* (null when it could not)
|
|
132
|
-
*
|
|
73
|
+
* Resolve the backstop for a focus whose review_cycle_count the caller already
|
|
74
|
+
* read (null when it could not), and log the held edge once per episode.
|
|
75
|
+
*
|
|
76
|
+
* Async because every gate calls it in an await position and the un-arm that
|
|
77
|
+
* normally precedes it is the asynchronous half of the same decision; keeping
|
|
78
|
+
* the signature lets a future read rejoin here without touching four gates.
|
|
133
79
|
*/
|
|
134
80
|
export async function resolveReviewCycleCapHold(focus, deps = {}) {
|
|
135
|
-
const facts =
|
|
81
|
+
const facts = readReviewCycleCapFacts(focus, deps);
|
|
136
82
|
const held = isReviewCycleCapHeld(facts);
|
|
137
83
|
if (!held) {
|
|
138
84
|
heldLoggedFocuses.delete(focus.focusId);
|
|
139
85
|
}
|
|
140
86
|
else if (!heldLoggedFocuses.has(focus.focusId)) {
|
|
141
87
|
heldLoggedFocuses.add(focus.focusId);
|
|
142
|
-
log.info(`[review-cycle-cap-hold] "${focus.focusName}" is held
|
|
143
|
-
`
|
|
144
|
-
`
|
|
88
|
+
log.info(`[review-cycle-cap-hold] "${focus.focusName}" is held by its spent review budget: ${describeHold(facts)}. ` +
|
|
89
|
+
`The un-arm that normally accompanies a spent budget did not land (or its count has not been cleared), ` +
|
|
90
|
+
`so no coding or review pass spawns until the focus is armed again.`);
|
|
145
91
|
}
|
|
146
92
|
return held;
|
|
147
93
|
}
|
|
148
94
|
/**
|
|
149
|
-
* A
|
|
150
|
-
* review_cycle_count, so the count comes from the active-focus read --
|
|
151
|
-
* product for the reader's lifetime (create one per poll). A failed
|
|
152
|
-
* ready focus absent from the active read (both filter
|
|
153
|
-
* same-poll race), leaves the count unreadable: held.
|
|
154
|
-
* likewise made at most once per reader, however many focuses need it.
|
|
95
|
+
* A backstop reader for the ready-focus spawn gate. getReadyFocuses rows do not
|
|
96
|
+
* carry review_cycle_count, so the count comes from the active-focus read --
|
|
97
|
+
* once per product for the reader's lifetime (create one per poll). A failed
|
|
98
|
+
* read, or a ready focus absent from the active read (both filter
|
|
99
|
+
* status='active', so only a same-poll race), leaves the count unreadable: held.
|
|
155
100
|
*/
|
|
156
101
|
export function createReadyFocusCapHoldReader(organizationId, deps = {}) {
|
|
157
102
|
const countsByProduct = new Map();
|
|
@@ -166,13 +111,10 @@ export function createReadyFocusCapHoldReader(organizationId, deps = {}) {
|
|
|
166
111
|
}
|
|
167
112
|
return counts;
|
|
168
113
|
};
|
|
169
|
-
let carriers;
|
|
170
|
-
const readCarriers = deps.listOpenLineageCarriers ?? (() => listOpenLineageCarriersForOrg());
|
|
171
|
-
const holdDeps = { ...deps, listOpenLineageCarriers: () => (carriers ??= readCarriers()) };
|
|
172
114
|
return async (focus) => {
|
|
173
115
|
const counts = await readCounts(focus.product_id);
|
|
174
116
|
const reviewCycleCount = counts?.get(focus.focus_id) ?? null;
|
|
175
|
-
return resolveReviewCycleCapHold({ focusId: focus.focus_id, focusName: focus.focus_name, reviewCycleCount },
|
|
117
|
+
return resolveReviewCycleCapHold({ focusId: focus.focus_id, focusName: focus.focus_name, reviewCycleCount }, deps);
|
|
176
118
|
};
|
|
177
119
|
}
|
|
178
120
|
//# sourceMappingURL=review-cycle-cap-hold.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review-cycle-cap-hold.js","sourceRoot":"","sources":["../../src/focus/review-cycle-cap-hold.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,iFAAiF;AACjF,4DAA4D;AAC5D,gBAAgB;AAEhB
|
|
1
|
+
{"version":3,"file":"review-cycle-cap-hold.js","sourceRoot":"","sources":["../../src/focus/review-cycle-cap-hold.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
* from ordinary scope-time audit work.
|
|
28
28
|
*/
|
|
29
29
|
import type { AgentSession } from '../types/index.js';
|
|
30
|
+
import type { SessionProcessLiveness } from '../shell/daemon-instance.js';
|
|
30
31
|
/**
|
|
31
32
|
* Grace period: a session started within this window is left alone even if it
|
|
32
33
|
* has no matching team yet (it may still be initializing / the one-shot is still
|
|
@@ -53,6 +54,20 @@ export interface SessionHealthContext {
|
|
|
53
54
|
graceMs?: number;
|
|
54
55
|
/** Liveness probe: true when the pid is a live process. */
|
|
55
56
|
isProcessAlive: (pid: number) => boolean;
|
|
57
|
+
/**
|
|
58
|
+
* What the session's OWN team process is doing, read from the host's durable
|
|
59
|
+
* lead record (shell/daemon-instance.ts `classifySessionProcess`) rather than
|
|
60
|
+
* from the row's `pid`.
|
|
61
|
+
*
|
|
62
|
+
* The row's pid cannot answer it. It is written AFTER the detached lead is
|
|
63
|
+
* spawned, so a row still in `starting` with a null pid -- the pre-stamp
|
|
64
|
+
* window -- looked processless to this sweep and was closed while its team ran.
|
|
65
|
+
* It also names no identity, so a recycled number read as the team. The record
|
|
66
|
+
* is reserved before the process exists and carries its start identity, so
|
|
67
|
+
* both cases are decidable; where they are not, the verdict is `unprovable`
|
|
68
|
+
* and this sweep closes nothing.
|
|
69
|
+
*/
|
|
70
|
+
sessionProcessLiveness: (sessionId: string) => SessionProcessLiveness;
|
|
56
71
|
/**
|
|
57
72
|
* Silence window in ms for the CALL-ACTIVITY abandonment check. When set, a
|
|
58
73
|
* non-tracked session whose process is ALIVE but whose durable last-activity
|
|
@@ -64,7 +79,13 @@ export interface SessionHealthContext {
|
|
|
64
79
|
*/
|
|
65
80
|
silenceThresholdMs?: number;
|
|
66
81
|
}
|
|
67
|
-
export type SessionHealthSkipReason = 'tracked_team' | 'no_started_at' | 'within_grace' | 'live_process'
|
|
82
|
+
export type SessionHealthSkipReason = 'tracked_team' | 'no_started_at' | 'within_grace' | 'live_process'
|
|
83
|
+
/** The team's process could not be shown either running or stopped. */
|
|
84
|
+
| 'unprovable_process'
|
|
85
|
+
/** The durable record says stopped, but the row's own (unverified) pid is alive. */
|
|
86
|
+
| 'unverified_live_pid'
|
|
87
|
+
/** A close was decided, but the session's process was not confirmed gone. */
|
|
88
|
+
| 'unreaped_process';
|
|
68
89
|
export interface SessionHealthDecision {
|
|
69
90
|
sessionId: string;
|
|
70
91
|
focusId: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-health.d.ts","sourceRoot":"","sources":["../../src/focus/session-health.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"session-health.d.ts","sourceRoot":"","sources":["../../src/focus/session-health.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAE1E;;;;GAIG;AACH,eAAO,MAAM,8BAA8B,QAAgB,CAAC;AAE5D,kGAAkG;AAClG,wBAAgB,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,OAAO,CAErF;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,kBAAkB,CAAC,GAAG,MAAM,GAAG,IAAI,CAKlG;AAED,MAAM,WAAW,oBAAoB;IACnC,oDAAoD;IACpD,qBAAqB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3C,yCAAyC;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2DAA2D;IAC3D,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACzC;;;;;;;;;;;;OAYG;IACH,sBAAsB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,sBAAsB,CAAC;IACtE;;;;;;;;OAQG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,MAAM,uBAAuB,GAC/B,cAAc,GACd,eAAe,GACf,cAAc,GACd,cAAc;AAChB,uEAAuE;GACrE,oBAAoB;AACtB,oFAAoF;GAClF,qBAAqB;AACvB,6EAA6E;GAC3E,kBAAkB,CAAC;AAEvB,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1B,uCAAuC;IACvC,UAAU,CAAC,EAAE,uBAAuB,CAAC;IACrC;;;;;;;;;;OAUG;IACH,IAAI,CAAC,EAAE,aAAa,GAAG,kBAAkB,GAAG,kBAAkB,GAAG,mBAAmB,CAAC;CACtF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,YAAY,EACrB,GAAG,EAAE,oBAAoB,GACxB,qBAAqB,CAiFvB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,SAAS,YAAY,EAAE,EACjC,GAAG,EAAE,oBAAoB,GACxB,qBAAqB,EAAE,CAEzB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
|
|
2
|
-
// Pinned by: packages/daemon/src/focus/session-
|
|
3
|
-
// packages/daemon/src/focus/session-process-reap.test.ts
|
|
2
|
+
// Pinned by: packages/daemon/src/focus/session-close-producers.test.ts,
|
|
3
|
+
// packages/daemon/src/focus/session-health.test.ts, packages/daemon/src/focus/session-process-reap.test.ts
|
|
4
4
|
// PINNED-BY-END
|
|
5
5
|
/**
|
|
6
6
|
* Grace period: a session started within this window is left alone even if it
|
|
@@ -60,7 +60,13 @@ export function classifySessionHealth(session, ctx) {
|
|
|
60
60
|
// silence threshold, classify the session abandoned rather than skipping it
|
|
61
61
|
// forever. Applies only here -- a tracked team returned above, so a legitimately
|
|
62
62
|
// parked live team (owned by the outcome/idle stall detectors) is never touched.
|
|
63
|
-
|
|
63
|
+
const liveness = ctx.sessionProcessLiveness(session.id);
|
|
64
|
+
// A VERIFIED live process is the only thing that may be judged abandoned. The
|
|
65
|
+
// silence check is a CLOSE, and it must rest on the same identified process the
|
|
66
|
+
// rest of this module requires: an unverified raw pid reading alive plus a stale
|
|
67
|
+
// activity clock would close the row of a team that is running (or of a stranger
|
|
68
|
+
// whose pid we happened to probe), which is the falsification either way.
|
|
69
|
+
if (liveness === 'alive') {
|
|
64
70
|
const lastActivityMs = parseLastActivityMs(session);
|
|
65
71
|
if (ctx.silenceThresholdMs !== undefined &&
|
|
66
72
|
lastActivityMs !== null &&
|
|
@@ -72,6 +78,25 @@ export function classifySessionHealth(session, ctx) {
|
|
|
72
78
|
// before. Conservative: absence of a signal is never treated as abandonment.
|
|
73
79
|
return { ...base, verdict: 'skip', skipReason: 'live_process' };
|
|
74
80
|
}
|
|
81
|
+
// Not provably running -- but "not provably running" is not "stopped". An
|
|
82
|
+
// unreadable lead record, a reservation whose spawn is in flight, or a live pid
|
|
83
|
+
// whose identity cannot be verified all land here, and closing the row on any
|
|
84
|
+
// of them is the falsification this sweep must not make: a `failed` row tells
|
|
85
|
+
// the dashboard AND isWorktreeBeingWritten that a running team is not there.
|
|
86
|
+
if (liveness === 'unprovable') {
|
|
87
|
+
return { ...base, verdict: 'skip', skipReason: 'unprovable_process' };
|
|
88
|
+
}
|
|
89
|
+
// The durable record says stopped or names no lead -- but the row's own pid may
|
|
90
|
+
// still be alive (a legacy row the record never named, a one-shot recorded
|
|
91
|
+
// elsewhere). That pid is UNVERIFIED, so it is not grounds to close and not
|
|
92
|
+
// grounds to claim a live team either: skip, and let the reap that can verify
|
|
93
|
+
// it decide. This is the case that must not become a close.
|
|
94
|
+
if (session.pid != null && ctx.isProcessAlive(session.pid)) {
|
|
95
|
+
return { ...base, verdict: 'skip', skipReason: 'unverified_live_pid' };
|
|
96
|
+
}
|
|
97
|
+
// `stopped` (the recorded process is gone, or its pid was recycled) or
|
|
98
|
+
// `no_process_recorded` (the record is readable and names no lead for this
|
|
99
|
+
// session, and its own pid is not alive either) -- the team really has stopped.
|
|
75
100
|
return {
|
|
76
101
|
...base,
|
|
77
102
|
verdict: 'close',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-health.js","sourceRoot":"","sources":["../../src/focus/session-health.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F
|
|
1
|
+
{"version":3,"file":"session-health.js","sourceRoot":"","sources":["../../src/focus/session-health.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
* why it did not:
|
|
10
10
|
*
|
|
11
11
|
* - a CLOSE decision (team_orphan / system_straggler / silent_abandoned) ends
|
|
12
|
-
* the session's process group
|
|
12
|
+
* the session's process group, and the close is WITHHELD when that group
|
|
13
|
+
* survives -- a row marked failed while its process runs is the same
|
|
14
|
+
* falsification from the other direction;
|
|
13
15
|
* - a `live_process` SKIP whose process is a verified daemon-spawned lead no
|
|
14
16
|
* team tracks is ended too, and turned into an `untracked_process` close so
|
|
15
17
|
* its row is marked failed.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-process-reap.d.ts","sourceRoot":"","sources":["../../src/focus/session-process-reap.ts"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"session-process-reap.d.ts","sourceRoot":"","sources":["../../src/focus/session-process-reap.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAIL,KAAK,sBAAsB,EAC5B,MAAM,gCAAgC,CAAC;AAKxC,8CAA8C;AAC9C,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,oEAAoE;IACpE,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAAC;IACtC,0DAA0D;IAC1D,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,kEAAkE;AAClE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAEpE;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,GAAG,KAAK,CAAC,EACzC,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,iBAAsB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,CAqB7B;AAWD;;;;;;GAMG;AACH,wBAAsB,0BAA0B,CAC9C,QAAQ,EAAE,SAAS,YAAY,EAAE,EACjC,SAAS,EAAE,SAAS,qBAAqB,EAAE,EAC3C,IAAI,GAAE,iBAAsB,GAC3B,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAuClC"}
|
|
@@ -67,6 +67,26 @@ export async function reapSessionHealthProcesses(sessions, decisions, deps = {})
|
|
|
67
67
|
const context = d.verdict === 'close' ? `session reap (${d.kind ?? 'stale'})` : 'untracked live session';
|
|
68
68
|
const reap = await reapSessionProcess(session, context, deps);
|
|
69
69
|
logReap(reap, d);
|
|
70
|
+
// A CLOSE writes `failed`, which tells the dashboard AND isWorktreeBeingWritten
|
|
71
|
+
// that nothing is running. If we signalled this session's group and it did NOT
|
|
72
|
+
// end, something IS running -- and writing the row anyway is the exact
|
|
73
|
+
// falsification this module exists to prevent. Withhold the close; the next
|
|
74
|
+
// sweep re-examines it (a stale `running` row is visible and self-correcting,
|
|
75
|
+
// a live session marked failed is neither).
|
|
76
|
+
if (d.verdict === 'close' && reap.result !== null && !sessionProcessGone(reap)) {
|
|
77
|
+
log.warn(`[health] Session ${d.sessionId} (${d.kind ?? 'stale'}): its process group survived termination ` +
|
|
78
|
+
`(${reap.result.outcome}) -- NOT marking the row failed`);
|
|
79
|
+
return { ...d, verdict: 'skip', kind: undefined, skipReason: 'unreaped_process' };
|
|
80
|
+
}
|
|
81
|
+
// `silent_abandoned` is the one close decided on a process that is ALIVE: the
|
|
82
|
+
// team is judged wedged, not stopped. Its row may only be closed once that
|
|
83
|
+
// process is confirmed gone, so a termination we could not even attempt
|
|
84
|
+
// (unverifiable pid, an owner we must not signal) withholds it too.
|
|
85
|
+
if (d.verdict === 'close' && d.kind === 'silent_abandoned' && !sessionProcessGone(reap)) {
|
|
86
|
+
log.warn(`[health] Session ${d.sessionId} (silent_abandoned): its process was not confirmed gone ` +
|
|
87
|
+
`(${reap.notSignalledReason ?? 'no result'}) -- NOT marking the row failed`);
|
|
88
|
+
return { ...d, verdict: 'skip', kind: undefined, skipReason: 'unreaped_process' };
|
|
89
|
+
}
|
|
70
90
|
if (d.verdict === 'skip' && reap.result !== null && sessionProcessGone(reap)) {
|
|
71
91
|
log.warn(`[health] Session ${d.sessionId} had a live process no team tracks -- terminated it (focus=${d.focusId ?? 'none'})`);
|
|
72
92
|
return { sessionId: d.sessionId, focusId: d.focusId, deliveryId: d.deliveryId, status: d.status, verdict: 'close', kind: 'untracked_process' };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-process-reap.js","sourceRoot":"","sources":["../../src/focus/session-process-reap.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,oEAAoE;AACpE,gBAAgB;
|
|
1
|
+
{"version":3,"file":"session-process-reap.js","sourceRoot":"","sources":["../../src/focus/session-process-reap.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/focus-stage-lifecycle/index.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEzE,OAAO,EAAE,gBAAgB,IAAI,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAC5F,OAAO,EAAE,kBAAkB,IAAI,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACxF,OAAO,EACL,4BAA4B,EAC5B,sCAAsC,EACvC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,kBAAkB,EAElB,KAAK,YAAY,EAClB,MAAM,qBAAqB,CAAC;AAQ7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AAIpC,gFAAgF;AAChF,MAAM,WAAW,kBAAkB;IACjC,gBAAgB,EAAE,OAAO,uBAAuB,CAAC;IACjD,kBAAkB,EAAE,OAAO,yBAAyB,CAAC;IACrD,uBAAuB,EAAE,CACvB,KAAK,EAAE,UAAU,CAAC,OAAO,4BAA4B,CAAC,CAAC,CAAC,CAAC,KACtD,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,uBAAuB,EAAE,CACvB,KAAK,EAAE,UAAU,CAAC,OAAO,sCAAsC,CAAC,CAAC,CAAC,CAAC,KAChE,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,aAAa,EAAE,CACb,KAAK,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,CAAC,CAAC,KAC5C,OAAO,CAAC,YAAY,CAAC,CAAC;CAC5B;AAED,mDAAmD;AACnD,wBAAgB,yBAAyB,IAAI,kBAAkB,CAQ9D;AAED;;;GAGG;AACH,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,YAAY,EACpB,IAAI,GAAE,kBAAgD,GACrD,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/focus-stage-lifecycle/index.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEzE,OAAO,EAAE,gBAAgB,IAAI,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAC5F,OAAO,EAAE,kBAAkB,IAAI,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACxF,OAAO,EACL,4BAA4B,EAC5B,sCAAsC,EACvC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,kBAAkB,EAElB,KAAK,YAAY,EAClB,MAAM,qBAAqB,CAAC;AAQ7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AAIpC,gFAAgF;AAChF,MAAM,WAAW,kBAAkB;IACjC,gBAAgB,EAAE,OAAO,uBAAuB,CAAC;IACjD,kBAAkB,EAAE,OAAO,yBAAyB,CAAC;IACrD,uBAAuB,EAAE,CACvB,KAAK,EAAE,UAAU,CAAC,OAAO,4BAA4B,CAAC,CAAC,CAAC,CAAC,KACtD,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,uBAAuB,EAAE,CACvB,KAAK,EAAE,UAAU,CAAC,OAAO,sCAAsC,CAAC,CAAC,CAAC,CAAC,KAChE,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,aAAa,EAAE,CACb,KAAK,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,CAAC,CAAC,KAC5C,OAAO,CAAC,YAAY,CAAC,CAAC;CAC5B;AAED,mDAAmD;AACnD,wBAAgB,yBAAyB,IAAI,kBAAkB,CAQ9D;AAED;;;GAGG;AACH,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,YAAY,EACpB,IAAI,GAAE,kBAAgD,GACrD,OAAO,CAAC,IAAI,CAAC,CA4Hf;AAGD,YAAY,EAAE,iBAAiB,EAAE,CAAC"}
|
|
@@ -118,6 +118,7 @@ export async function runStageLifecycleTransitions(config, deps = defaultStageLi
|
|
|
118
118
|
status: focus.status,
|
|
119
119
|
assignedAgentRoleId: focus.assigned_agent_role_id,
|
|
120
120
|
operatorStopped: focus.operator_stopped_at != null,
|
|
121
|
+
armEndedReason: focus.arm_ended_reason,
|
|
121
122
|
everArmed: focus.first_armed_at != null,
|
|
122
123
|
readOnly: focus.read_only,
|
|
123
124
|
stage: baseArgs.stage, // display-only
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/focus-stage-lifecycle/index.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,sFAAsF;AACtF,sEAAsE;AACtE,sEAAsE;AACtE,uEAAuE;AACvE,gBAAgB;AAwChB,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,gBAAgB,IAAI,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAC5F,OAAO,EAAE,kBAAkB,IAAI,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACxF,OAAO,EACL,4BAA4B,EAC5B,sCAAsC,GACvC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,kBAAkB,EAClB,uBAAuB,GAExB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,MAAM,GAAG,GAAG,YAAY,CAAC,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC,CAAC;AAG9D,4EAA4E;AAC5E,2CAA2C;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AAmBpC,mDAAmD;AACnD,MAAM,UAAU,yBAAyB;IACvC,OAAO;QACL,gBAAgB,EAAE,uBAAuB;QACzC,kBAAkB,EAAE,yBAAyB;QAC7C,uBAAuB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,4BAA4B,CAAC,CAAC,CAAC;QAC/D,uBAAuB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,sCAAsC,CAAC,CAAC,CAAC;QACzE,aAAa,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC;KAC5C,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,MAAoB,EACpB,OAA2B,yBAAyB,EAAE;IAEtD,yEAAyE;IACzE,2EAA2E;IAC3E,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IAEvC,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACtC,MAAM,EAAE,GAAG,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAE7C,IAAI,OAA4D,CAAC;QACjE,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,cAAc,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;QACvE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,IAAI,CACN,qEAAqE;gBACrE,GAAG,OAAO,CAAC,EAAE,KAAM,GAAa,CAAC,OAAO,EAAE,CAC3C,CAAC;YACF,SAAS;QACX,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,iEAAiE;YACjE,yCAAyC;YACzC,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ;gBAAE,SAAS;YACxC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAEjC,MAAM,QAAQ,GAAG;gBACf,OAAO,EAAE,KAAK,CAAC,QAAQ;gBACvB,SAAS,EAAE,KAAK,CAAC,UAAU;gBAC3B,cAAc,EAAE,EAAE,CAAC,cAAc;gBACjC,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,UAAU;gBAChC,cAAc,EAAE,KAAK,CAAC,eAAe;aACtC,CAAC;YAEF,qEAAqE;YACrE,0EAA0E;YAC1E,0EAA0E;YAC1E,0EAA0E;YAC1E,8DAA8D;YAC9D,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,uBAAuB,CAAC;oBACjC,OAAO,EAAE,KAAK,CAAC,QAAQ;oBACvB,SAAS,EAAE,KAAK,CAAC,UAAU;oBAC3B,cAAc,EAAE,EAAE,CAAC,cAAc;oBACjC,QAAQ,EAAE,KAAK,CAAC,SAAS;oBACzB,UAAU,EAAE,KAAK,CAAC,WAAW;iBAC9B,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,GAAG,CAAC,IAAI,CACN,yDAAyD;oBACzD,IAAI,KAAK,CAAC,UAAU,MAAO,GAAa,CAAC,OAAO,EAAE,CACnD,CAAC;YACJ,CAAC;YAED,0EAA0E;YAC1E,uEAAuE;YACvE,4EAA4E;YAC5E,gEAAgE;YAChE,oEAAoE;YACpE,0EAA0E;YAC1E,wEAAwE;YACxE,2EAA2E;YAC3E,2EAA2E;YAC3E,iDAAiD;YACjD,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,uBAAuB,CAAC;oBACjC,OAAO,EAAE,KAAK,CAAC,QAAQ;oBACvB,SAAS,EAAE,KAAK,CAAC,UAAU;oBAC3B,cAAc,EAAE,EAAE,CAAC,cAAc;oBACjC,QAAQ,EAAE,KAAK,CAAC,SAAS;oBACzB,WAAW,EAAE,KAAK,CAAC,YAAY;oBAC/B,UAAU,EAAE,KAAK,CAAC,WAAW;oBAC7B,0FAA0F;oBAC1F,SAAS,EAAE,KAAK,CAAC,cAAc,IAAI,IAAI;oBACvC,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,eAAe;oBACtC,iBAAiB,EAAE,KAAK,CAAC,mBAAmB;iBAC7C,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,GAAG,CAAC,IAAI,CACN,2DAA2D;oBAC3D,IAAI,KAAK,CAAC,UAAU,MAAO,GAAa,CAAC,OAAO,EAAE,CACnD,CAAC;YACJ,CAAC;YAED,0EAA0E;YAC1E,0EAA0E;YAC1E,oEAAoE;YACpE,6EAA6E;YAC7E,0EAA0E;YAC1E,8EAA8E;YAC9E,yEAAyE;YACzE,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,aAAa,CAAC;oBACvB,OAAO,EAAE,KAAK,CAAC,QAAQ;oBACvB,SAAS,EAAE,KAAK,CAAC,UAAU;oBAC3B,cAAc,EAAE,EAAE,CAAC,cAAc;oBACjC,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,mBAAmB,EAAE,KAAK,CAAC,sBAAsB;oBACjD,eAAe,EAAE,KAAK,CAAC,mBAAmB,IAAI,IAAI;oBAClD,SAAS,EAAE,KAAK,CAAC,cAAc,IAAI,IAAI;oBACvC,QAAQ,EAAE,KAAK,CAAC,SAAS;oBACzB,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,eAAe;iBACvC,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,GAAG,CAAC,IAAI,CACN,yDAAyD;oBACzD,IAAI,KAAK,CAAC,UAAU,MAAO,GAAa,CAAC,OAAO,EAAE,CACnD,CAAC;YACJ,CAAC;YAED,uEAAuE;YACvE,yEAAyE;YACzE,2EAA2E;YAC3E,yEAAyE;YACzE,yEAAyE;YACzE,4EAA4E;YAC5E,0EAA0E;YAC1E,uEAAuE;QACzE,CAAC;IACH,CAAC;IAED,2EAA2E;IAC3E,2DAA2D;IAC3D,uBAAuB,CAAC,YAAY,CAAC,CAAC;AACxC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/focus-stage-lifecycle/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -183,6 +183,16 @@ export interface WedgeFocusInput {
|
|
|
183
183
|
* stop from a lifecycle role-clear when assignedAgentRoleId is null.
|
|
184
184
|
*/
|
|
185
185
|
operatorStopped?: boolean;
|
|
186
|
+
/**
|
|
187
|
+
* WHY the arm ended, when the daemon ended it deliberately
|
|
188
|
+
* (product_focuses.arm_ended_reason). 'review_budget_spent' => the review loop
|
|
189
|
+
* reached its cycle budget without converging and the daemon released the arm;
|
|
190
|
+
* the focus is correctly un-armed with work still open and is NOT a strand, so
|
|
191
|
+
* it is reported as ended rather than escalated as a wedge. Null/undefined =>
|
|
192
|
+
* no machine end recorded (a live arm, a never-armed focus, a lifecycle clear
|
|
193
|
+
* or an operator stop), which reads exactly as it did before this column.
|
|
194
|
+
*/
|
|
195
|
+
armEndedReason?: string | null;
|
|
186
196
|
/**
|
|
187
197
|
* Durable ever-armed marker (product_focuses.first_armed_at non-null). Splits a
|
|
188
198
|
* role-less-with-work focus into its two causes: true => the focus was armed
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wedge-watchdog.d.ts","sourceRoot":"","sources":["../../src/focus-stage-lifecycle/wedge-watchdog.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,kBAAkB,IAAI,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACxF,OAAO,EAAE,gBAAgB,IAAI,uBAAuB,EAAE,4BAA4B,IAAI,mCAAmC,EAAE,4BAA4B,IAAI,mCAAmC,EAAgC,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"wedge-watchdog.d.ts","sourceRoot":"","sources":["../../src/focus-stage-lifecycle/wedge-watchdog.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,6 +20,7 @@ import { DISPOSITION_AGENT_RESOLVABLE } from '../queries/escalation-dispositions
|
|
|
20
20
|
import { ESCALATION_REASONS, ESCALATION_DISPOSITIONS, DELIVERY_STATUS, loadEnvConfig, } from '@telora/daemon-core';
|
|
21
21
|
import { hasActiveTeam as defaultHasActiveTeam } from '../focus/focus-team-state.js';
|
|
22
22
|
import { focusMayRunTeam } from '../spawn/null-role-spawn.js';
|
|
23
|
+
import { ARM_ENDED_REVIEW_BUDGET_SPENT } from '../queries/ended-arm.js';
|
|
23
24
|
import { createLogger } from '../shell/log.js';
|
|
24
25
|
const log = createLogger({ module: 'focus-stage-lifecycle' });
|
|
25
26
|
// ── Planning-wedge watchdog + zero-actionable log (D2 + D3) ───────
|
|
@@ -288,9 +289,11 @@ function defaultWedgeWatchdogDeps() {
|
|
|
288
289
|
* not a wedge"), which is exactly the blind spot that let a lifecycle-cleared
|
|
289
290
|
* focus still holding work sit outside every detector.
|
|
290
291
|
*
|
|
291
|
-
*
|
|
292
|
-
*
|
|
293
|
-
*
|
|
292
|
+
* Four outcomes: an operator stop is authoritative and stays silent; an arm the
|
|
293
|
+
* daemon ENDED on a spent review budget is authoritative too (the stop is the
|
|
294
|
+
* point -- it is announced, once, and never escalated as a wedge); a clear with
|
|
295
|
+
* all deliveries terminal is a genuine finish; anything else is a strand -- the
|
|
296
|
+
* machine cleared the arm while work remains, and no team can spawn until a
|
|
294
297
|
* human re-arms it.
|
|
295
298
|
*/
|
|
296
299
|
async function evaluateRoleLessFocus(focus, deps) {
|
|
@@ -299,6 +302,27 @@ async function evaluateRoleLessFocus(focus, deps) {
|
|
|
299
302
|
clearFocusWedgeState(focus.focusId);
|
|
300
303
|
return { kind: 'skipped', reason: 'operator_stopped' };
|
|
301
304
|
}
|
|
305
|
+
// A run the daemon ENDED on a spent review budget is authoritative in the same
|
|
306
|
+
// way: the un-arm IS the intended outcome, so it is not a wedge and files no
|
|
307
|
+
// escalation. It is still ANNOUNCED (once per episode), because "no team will
|
|
308
|
+
// spawn here again until a human arms it" is exactly what an operator reading
|
|
309
|
+
// the log needs, and a silent stop is how a run disappears unnoticed.
|
|
310
|
+
if (focus.armEndedReason === ARM_ENDED_REVIEW_BUDGET_SPENT) {
|
|
311
|
+
const sig = `arm_ended:${ARM_ENDED_REVIEW_BUDGET_SPENT}`;
|
|
312
|
+
if (wedgeState.getLogSig(focus.focusId) !== sig) {
|
|
313
|
+
// Clear on the EPISODE EDGE only (it drops the log signature too, so
|
|
314
|
+
// clearing every poll would re-announce every poll), dropping any wedge
|
|
315
|
+
// timer left by the armed episode.
|
|
316
|
+
clearFocusWedgeState(focus.focusId);
|
|
317
|
+
wedgeState.setLogSig(focus.focusId, sig);
|
|
318
|
+
log.warn(`[focus-stage-lifecycle] Focus "${focus.focusName}" is un-armed because its REVIEW BUDGET WAS SPENT ` +
|
|
319
|
+
`(arm_ended_reason='${ARM_ENDED_REVIEW_BUDGET_SPENT}'): the review loop reached TELORA_REVIEW_CYCLE_CAP ` +
|
|
320
|
+
`without converging and the daemon ended the armed run. The criteria still unmet and the findings still ` +
|
|
321
|
+
`open are recorded on the focus (arm_ended_detail). No coding or review pass spawns until a human arms ` +
|
|
322
|
+
`it again; arming grants a fresh budget.`);
|
|
323
|
+
}
|
|
324
|
+
return { kind: 'skipped', reason: 'arm_ended_review_budget_spent' };
|
|
325
|
+
}
|
|
302
326
|
let roleLessDeliveries;
|
|
303
327
|
try {
|
|
304
328
|
roleLessDeliveries = await deps.getFocusDeliveries(focus.focusId);
|