namespace ClawdDotNet.Core.Tasks;
///
/// Der Ausführungszustand des Taskboards. Die Definition der Aufgaben lebt in
/// Markdown-Dateien; dieses Repository ist die DB-Seite, die das Claiming atomar macht
/// (was ein Dateisystem nicht verlässlich kann) und dem Scanner erlaubt, ohne
/// Dateizugriff zu entscheiden.
///
public interface ITaskRepository
{
///
/// Legt eine Aufgabe an oder aktualisiert ihre Definition (Importer). Idempotent über
/// die — ein zweiter Import erzeugt keine Dublette. Der
/// Ausführungszustand (Marker, Claim) bleibt dabei unangetastet.
///
Task UpsertAsync(TaskItem task, CancellationToken ct);
Task GetAsync(string id, CancellationToken ct);
Task> ListAsync(TaskQuery query, CancellationToken ct);
///
/// #682: Every task in status todo — the scanner's candidates, without a cap.
///
/// clamps to 500 because it serves views and tools. The
/// scanner used it too, so beyond 500 tasks schedules silently fell out of the tick.
/// Only todo can be claimed, so this list is bounded by the work that is
/// actually waiting, not by the size of the board.
///
Task> ListRunnableAsync(CancellationToken ct);
///
/// Every task, without a cap — for the few callers that must see the whole board: the
/// cost forecast, duplicate detection, the import's orphan sweep. Before #716 they used
/// with its limit of 500 and silently saw only part of it.
///
Task> ListAllAsync(bool includeArchived, CancellationToken ct);
///
/// Beansprucht einen fälligen Termin atomar. Genau ein gleichzeitiger Aufruf gewinnt;
/// jeder weitere erhält false. Setzt den Marker ()
/// sofort — ein Termin ist damit auch dann verbraucht, wenn der Lauf später scheitert
/// oder der Prozess abstürzt (at-most-once, kein Retry-Sturm).
///
/// Sortierbarer ISO-UTC-Zeitstempel des Termins.
///
/// Claims, die älter sind, gelten als verwaist (abgestürzter Lauf) und dürfen
/// überschrieben werden.
///
Task TryClaimAsync(
string id, string occurrenceKey, string claimToken,
DateTime now, DateTime leaseCutoff, CancellationToken ct);
///
/// Schließt einen beanspruchten Lauf ab und setzt den Endstatus. Nur wirksam, solange
/// der Aufrufer den Claim noch hält ( passt) — ein Lauf,
/// der seine Lease verloren hat, überschreibt nichts mehr. Gibt zurück, ob der Claim
/// noch gehörte.
///
Task CompleteClaimAsync(
string id, string claimToken, TaskItemStatus finalStatus,
DateTime now, CancellationToken ct);
///
/// Gibt einen Claim zurück, als hätte es ihn nicht gegeben: Status todo und der
/// Marker auf (#643). Für Läufe, die gar nicht
/// stattfanden. Nur wirksam, solange der Aufrufer den Claim hält.
///
Task ReleaseClaimAsync(
string id, string claimToken, string? previousOccurrence, DateTime now, CancellationToken ct);
/// Ändert den Status direkt (Tool-Aktionen, Auto-Dispatch, Eskalation).
Task SetStatusAsync(string id, TaskItemStatus status, DateTime now, CancellationToken ct);
///
/// #716: The budget refused a run of a one-time task. Releases the claim, restores the
/// occurrence (the task is still due) and defers it to .
///
Task CarryOverAsync(
string id, string claimToken, string? previousOccurrence, DateTime deferredUntil,
DateTime now, CancellationToken ct);
///
/// #716: The budget refused a run of a recurring task. Releases the claim back to
/// todo; the occurrence stays consumed. With a
/// single catch-up run is scheduled for then — an already pending one is kept.
///
Task RecordBudgetMissAsync(
string id, string claimToken, DateTime? catchUpUntil, DateTime now, CancellationToken ct);
///
/// #716: A run took place — clears the miss counter, a pending catch-up and the
/// deferral. stays as history.
///
Task ClearBudgetMissAsync(string id, DateTime now, CancellationToken ct);
///
/// Reconciliation beim Start: verwaiste Claims (älter als )
/// lösen und die betroffenen Aufgaben von zurück
/// auf stellen. Gibt die Zahl der zurückgesetzten
/// Aufgaben zurück.
///
Task ReleaseStaleClaimsAsync(DateTime leaseCutoff, DateTime now, CancellationToken ct);
///
/// Aufgaben, die auf warten — Grundlage für den
/// Auto-Dispatch, wenn der letzte Blocker fertig wird.
///
Task> ListBlockedByAsync(string blockerId, CancellationToken ct);
Task CountAsync(CancellationToken ct);
}