fix(tasks): detect stalled sessions and heal orphaned ones in sweep (#3832)

Co-authored-by: Carlos Florencio <carlosmflorencio@gmail.com>
This commit is contained in:
Benjamin
2026-09-21 07:02:29 +08:00
committed by GitHub
parent 80d4e99b5a
commit 00c7469d81
35 changed files with 2258 additions and 30 deletions
+18
View File
@@ -159,6 +159,7 @@ The launcher starts `agentctl`, performs a one-time nonce handshake, and supplie
| YAML key | Environment variable | Default | Current behavior |
| -------------------------- | --------------------------------- | ------- | ------------------------------------------------------------------------------- |
| `tasks.preparationTimeout` | `KANDEV_TASK_PREPARATION_TIMEOUT` | `10m` | Positive Go duration for repository setup and executor-profile prepare scripts. |
| `tasks.stallDetectionThreshold` | `KANDEV_TASK_STALL_DETECTION_THRESHOLD` | `2h` | Positive Go duration for the session reconciliation sweep's stall threshold. |
`tasks.preparationTimeout` controls how long Kandev allows repository setup and
executor-profile prepare scripts to run. The value uses Go duration syntax,
@@ -176,6 +177,22 @@ context, so earlier work such as Sprite uploads does not reduce their full
`10m` preparation budget. The environment variable overrides YAML. This is a
startup setting, not a database or Settings value.
`tasks.stallDetectionThreshold` controls the periodic session reconciliation
sweep. When an unarchived task holds an active session with no live execution
behind it and no session events or messages for longer than this threshold,
Kandev emits a `task.stalled` event and logs a warning. After twice the
threshold of silence, the sweep cancels the orphaned sessions so the task
stops showing a phantom active session. The cancel is all-or-nothing per
task: it runs only when every active session of the task is orphaned and
past the grace window, so a session that still has a live execution blocks
the cancellation of its siblings rather than being swept along with them.
The value is source-specific: an invalid YAML duration fails configuration
parsing, while a zero or negative YAML duration is rejected at startup with
`tasks.stallDetectionThreshold must be positive`. An invalid or non-positive
environment value falls back to `2h`, and non-positive values from a profile
default are ignored, leaving the `2h` default in effect. The environment
variable overrides YAML, and changes require a backend restart.
### Capacity and managed-process startup settings
| YAML key | Environment variable | Type and default | Current behavior |
@@ -439,6 +456,7 @@ agent:
tasks:
preparationTimeout: "10m"
stallDetectionThreshold: "2h"
credentials:
file: ""