# Hybrid Kanban scheduling

The Kanban scheduler combines immediate workflow eligibility with durable timed
retries. Dependencies, planning contracts, artifact ownership, review evidence,
agent activation, provider cooldowns, and Unity compilation/play-mode gates still
apply to every dispatch.

## Operating it

Open **Window > AIRuntime > Kanban** and enable **Run agents**. Closing the panel
does not stop work. Disable **Run agents** to stop admitting new work; an existing
run may finish and persist its result. Explicit continuous-run intent is saved in
the board and restored when Unity next opens that managed board. Legacy boards
default to paused. Single-step commands never persist continuous-run intent.

Unity must remain running for execution. This is an editor service, not an
external daemon. When Unity is closed, due retries remain in the board and become
eligible on reopening; they do not produce a backlog of repeated executions.

Temporary availability, timeout, and empty-response failures can schedule up to
three automatic retries, delayed by 30, 60, and 120 seconds. Authentication,
invalid-request, cancellation, and unavailable-model configuration failures do not
automatically retry. Errors containing authentication failures also stay manual,
even if another provider in the failure chain was temporarily unavailable.
Existing rate-limit cooldowns keep their existing provider-lane backoff policy.

The retry preserves the task's execution memory and planning handoff. Review
retries remain reviews. Exhausting the automatic budget leaves **Retry Available**
for an explicit resume, which starts a new bounded retry series. The status widget
and scheduler diagnostic journal expose the next retry time and its blocker.

An eligible review that has waited five minutes receives its agent's next slot
ahead of implementation work. This does not interrupt a running worker or bypass
workflow/dependency checks.

## Implementation

- `AIRuntimeKanbanWindow` is the view and retains the existing command-line entry
  points for compatibility.
- `AIRuntimeKanbanScheduler` owns the singleton session and editor lifecycle.
  Changes and completions request an immediate wakeup. Active runs are serviced
  at most 250 ms apart when the editor is updating; idle reconciliation is bounded
  to five seconds, shortened for a due retry or cooldown.
- `AIRuntimeKanbanSession` retains the existing board/workflow and shared drawing
  code. Its lifetime is independent of the view. Graph, details, and agent panels
  reference the same session.
- `AIRuntimeKanbanSession.Scheduling` implements retry policy, review aging,
  execution ownership, and persistence checks.

Each real dispatch first saves an attempt ID, owner ID, start time, lease expiry,
and outcome. No provider or tool work starts if this save fails. A process-held
`board.json.scheduler.lock` admits one scheduler owner; the existing short board
write lock, snapshot fingerprint, revision check, and atomic replacement protect
individual saves. Heartbeats renew the two-minute attempt lease every 30 seconds.

Completion and execution-memory callbacks carry the captured attempt ID. A stale
callback cannot complete a newer run or overwrite its checkpoint. External board
conflicts cancel owned transports and stop dispatch until the board is reloaded.
Managed reloads checkpoint and mark their owned attempts interrupted; cancelled
callbacks can drain even when a compilation failure prevents the domain reload.
After a crash, unexpired claims remain waiting, and expired interrupted work
returns through the existing recovery path with its execution memory preserved.
This does not make arbitrary external tool side effects transactionally replayable.

## Persistence and reset checks

The existing version-1 board accepts the additional optional fields:
`SchedulerEnabled`, `NextAttemptAtUtc`, `AutomaticRetryCount`, `RetryReason`,
`RetryReview`, `ReviewQueuedAtUtc`, and `Dispatch`. Missing fields default to an
inactive schedule. All updates use the existing revision-checked save path.

A reset should leave a single `Todo`/`Planning` root with no stale dependencies,
execution memory, retry deadline, or active dispatch claim. Released historical
provider cooldowns do not block it. Check old consumed-input declarations as well:
a reset may preserve an input from an earlier project attempt.

`AIRuntimeKanbanWindow.RepairResetRootInputsForCommandLine` provides explicit,
guarded cleanup of missing `Assets/` inputs on a paused, fresh, single-root board.
It requires `AIRUNTIME_KANBAN_EXPECTED_REVISION`; `AIRUNTIME_KANBAN_BOARD_PATH`
selects the board. `AIRUNTIME_KANBAN_WORKSPACE_ROOT` can identify the real project
when executing the repair from a separate verification project. Existing inputs,
task requests, and artifact files are preserved. This cleanup is never an
automatic load migration.

## Verification

`KanbanHybridSchedulerTests` exercises persisted timing, bounded retry budgets,
manual configuration failures, revision conflicts, exclusive claims, stale
callbacks, restart lease recovery, reload cancellation, heartbeat persistence,
review fairness, and reset cleanup. Its Unity editor-loop integration test starts
one deterministic worker, checks the saved claim before execution, closes the
panel, and verifies that the service saves the completion afterward. It uses no
external provider. Existing Kanban prompt/graph tests exercise the extracted
session without changing their workflow assertions.
