/** * `aidlc transition ` command — evaluate gates and advance phase. * * Behavior: * - Load instance state, phase states, and resolve template. * - Call `evaluateTransition(state, phaseStates, template, actor, findings, override)`. * - Call `nextStep(state, phaseStates, template)` to determine the target phase. * - If transition is allowed: * - Update current_phase in instance.yaml to the next phase. * - Update source phase status to 'complete'. * - Update target phase status to 'in-progress'. * - Append a TransitionRecord to transitions.log. * - Fire on-phase-exit and on-phase-enter events. * - Print success message. * - If blocked: print all violations, exit code 1. * * Options: * --override Override ownership gate * --json Output result as JSON * * Requirements: 3.6, 6.6, 11.5, 5.5 * * @module */ import { Command } from 'commander'; /** * Determine the actor identity for the ownership gate. * * The claim is the lock, so the claim holder is the canonical identity for a * claimed instance (`retire-owner-quote-titles`). Resolving the actor from * `$USER` alone compared two different identity namespaces: `aidlc claim` * records an agent session as `agent-` (`id_source: agent`), which can * never equal a Unix username, so a phase whose `owner` an agent had written * was blocked for the one session entitled to proceed — the claim holder * itself. Both 2026-09-01 reproductions (`release-gate-runs-too-late`, * `instance-complete-never-fires`) were this. * * `owner` is retired as a *lock* and kept as a *label*: nothing in the CLI * writes it (`start.ts` seeds `owner: null` and the transition path never sets * it), `aidlc status` displays it, and the gate now reaches it only through the * live claim. A different live session is still blocked, because its claim * write would have conflicted first (`ClaimConflictError`) and, failing that, * the recorded owner will not match the claim it does hold. * * Falls back to `$USER` / `$USERNAME` when no live claim exists, which is the * pre-existing behaviour for unclaimed instances. */ export declare function getActorIdentity(projectRoot: string, instance: string): string; /** * Whether the recorded phase owner has *lapsed*: it held a claim on this * instance at some point, and does not hold a live one now. * * `owner` is a label written by whichever session worked the phase, and the * claim is the lock (see `getActorIdentity`). The gate compared the two even * after the owner had let go of the lock, so it blocked two ordinary cases: * * - the same session coming back after `claim_timeout_minutes` of idle — its * claim is stale, so the actor falls back to `$USER`, which is not the owner * (fieldmodel-apps `assertion-store`, requirements → design, 2026-09-27); * - a fresh session taking over after the owner ran `aidlc claim release` — * the recommended handoff at a phase boundary. * * Both needed `--override`, and an override that is routine stops meaning * anything. A stale claim is already treated as abandonable by * `detectConcurrency`; this makes the ownership gate agree with it. * * Deliberately narrow: an owner that appears nowhere in the claim record — no * stored claim and no event in `sessions.ndjson` — is NOT lapsed, so a * hand-written owner still blocks and still needs `--override` (Req 6.6). * Unreadable state reads as "not lapsed", i.e. today's behaviour. */ export declare function ownerHasLapsed(projectRoot: string, instance: string, owner: string): boolean; /** * Register the `aidlc transition` command on the given commander program. */ export declare function registerTransition(program: Command): void; /** What `readContextSafely` reports, and what lands in the JSON payloads. */ export interface ContextSummary { resident_tokens: number; budget_tokens: number; percent: number; over_budget: boolean; } /** * The human context line, and the recommendation when over budget * (first-run-gaps/AC-16). * * The recommendation is prose and never an exit code. A phase boundary is the one * moment a fresh session costs nothing — the instance that produced this fix ran * all five phases in one session at 469k average context against a 150k budget, * and spent 56.7% of its total on cache reads. Nothing told it so at any of the * four boundaries where it could have acted. */ export declare function formatContext(context: ContextSummary | null): string; //# sourceMappingURL=transition.d.ts.map