/** * Claim store: live instance claims in the git common dir (AC-1…AC-6). * * One YAML file per instance under `/aidlc/claims/` (design * DD2): per-file writes need no cross-instance locking and unlink is an * atomic release. Write discipline is read-check-write-recheck-rename * (NFR-2); the residual TOCTOU window is accepted — claims are advisory * coordination, not mutual exclusion. * * Legacy migration (AC-4, AC-23): a non-null `claim:` in instance.yaml is * moved into the store on first read; on conflict the common-dir claim * wins ("common-dir precedence" — the new store is authoritative once * populated). instance.yaml always ends with `claim: null`. * * Outside a git repo (AC-5) or with an unwritable common dir (AC-27) the * legacy instance.yaml path keeps working via `openClaimStore` returning * a store backed by instance.yaml. */ import type { Claim } from './types.js'; /** Thrown when a write would override another session's live claim (AC-6). */ export declare class ClaimConflictError extends Error { readonly instance: string; readonly holder: string; constructor(instance: string, holder: string); } export interface ClaimStore { /** Where claims live: 'common-dir' or 'legacy' (instance.yaml). */ readonly kind: 'common-dir' | 'legacy'; read(instance: string): Claim | null; write(instance: string, claim: Claim, opts?: { override?: boolean; }): void; release(instance: string): void; /** All live claims, keyed by instance name. */ list(): Map; } export declare function isStale(claim: Claim, timeoutMinutes: number, now?: Date): boolean; /** * Open the claim store for a project. Common-dir backed inside a writable * git repo; legacy instance.yaml backed otherwise (AC-5, AC-27) with a * one-time warning. */ export declare function openClaimStore(projectRoot: string, timeoutMinutes: number): ClaimStore; /** * Every recorded claim, read with no side effect at all * (hooks-carry-lifecycle-state/AC-8, design D2). * * `openClaimStore` would do for the choice of store, but it creates * `/aidlc/` on the way, and a store's `read()` migrates a legacy * `claim:` by rewriting `instance.yaml`. A session-start hook may do neither, so * this picks the store the same way without the `mkdir`, and calls only `list()`, * which on both stores reads files and nothing else. * * Names that are not valid instance names are dropped: whatever this returns can * end up in an agent's context. * * @param common - The git common dir when the caller already resolved it, so a * hook pays for one `git rev-parse`, not two. */ export declare function readClaims(projectRoot: string, common?: string | null): Map; /** Why a claim is orphaned: its worktree is gone, or its instance is complete. */ export type OrphanReason = 'worktree-gone' | 'instance-complete'; export interface OrphanedClaim { instance: string; claim: Claim; reason: OrphanReason; } /** * Whether `/.aidlc/state//instance.yaml` says * `status: complete`. Unreadable or missing state is not complete. Never throws. */ export declare function instanceIsComplete(projectDir: string, instance: string): boolean; /** * Claims nothing holds any more (read-only half of releaseOrphanedClaims): * a recorded worktree_path that no longer exists (git-worktree AC-18b), or an * instance that is complete in the checkout the claim was taken in * (completed-claim-left-behind/AC-8, AC-14). * * The claim's own checkout, not the one prune runs in (design D3): a worktree * that reopened an instance must keep its claim while `main` still says * complete. A claim without worktree_path was taken in the primary checkout. */ export declare function orphanedClaims(store: ClaimStore, projectRoot: string): OrphanedClaim[]; /** * Release orphaned claims. Returns what was released, with why * (update-spring-clean AC-20, completed-claim-left-behind/AC-8). */ export declare function releaseOrphanedClaims(store: ClaimStore, projectRoot: string): OrphanedClaim[]; //# sourceMappingURL=claim-store.d.ts.map