/** * Doctor migration registry types (update-spring-clean AC-1..AC-3). * * A migration is a named check/apply pair. `check` is a pure state * inspection — the ONLY source of pending-ness, shared verbatim by * dry-run and real runs so they can never disagree (AC-2, AC-11). * No migration-version stamp exists anywhere (AC-3): repos self-heal * and converge regardless of the version they were initialized at. */ /** * How a migration is allowed to act. * * - `safe` — applies automatically, without prompting. * - `confirm` — applies only with `--yes` or an interactive confirmation. * - `report` — states a condition and applies **nothing**. Its `apply` is never * called, and it is excluded from the pending-confirm set so it never gates * doctor's exit code. * * The `report` tier exists because two compliance obligations have no legitimate * remedy. When someone edits the unreviewed-draft notice out of an installed pack * layer, re-inserting it would write to a file the framework has promised never to * touch; and an out-of-date pack must not be upgraded silently by `doctor`. With * only `safe` and `confirm` available, the options were a migration that writes * where it must not, or a no-op `apply` leaving the check pending forever — which * makes `aidlc doctor` exit 1 on every run and turns an edited-away disclaimer into * a permanently red health check. * * Requirements: compliance-packs/AC-104 */ export type MigrationTier = 'safe' | 'confirm' | 'report'; export interface DoctorContext { projectRoot: string; /** Git common dir, or null outside a git repo (AC-12). */ gitCommonDir: string | null; /** True when running from a linked worktree (AC-21). */ isLinkedWorktree: boolean; /** * The primary checkout's copy of the project, or null outside a git repo. Not * `dirname(gitCommonDir)`: that is the repository's top, and a project can sit * below it (repo-root-is-not-the-project/AC-10). */ primaryProjectRoot: string | null; /** Injected clock so TTL migrations are deterministic in tests. */ now: Date; /** stdout is a TTY — confirm-tier migrations may prompt (AC-23). */ interactive: boolean; /** --yes: apply confirm-tier migrations without prompting (AC-6). */ yes: boolean; } export type CheckResult = { applicable: false; reason: string; } | { applicable: true; pending: false; } | { applicable: true; pending: true; /** One-line "would ..." used by dry-run listings and prompts (AC-11). */ description: string; /** Confirm tier: the exact shell command(s) apply will run (AC-5). */ commands?: string[]; /** Set → apply must not run, even with --yes (AC-8 staged index). */ blocked?: string; }; export interface ApplyResult { changed: boolean; /** One-line report, e.g. "removed 3 expired stash entries" (AC-4). */ summary: string; } export interface Migration { /** Stable id, e.g. 'cost-gitignore' — never renamed (AC-1). */ id: string; tier: MigrationTier; check(ctx: DoctorContext): CheckResult; /** * Remedy the condition `check` found. * * Optional only for the `report` tier, where there is no legitimate remedy and * the runner never calls it. Every `safe` and `confirm` migration must define it; * the registry test asserts that. */ apply?(ctx: DoctorContext): ApplyResult; } export type PendingReason = 'declined' | 'non-interactive' | 'blocked'; export interface MigrationOutcome { id: string; tier: MigrationTier; /** * `reported` is the `report` tier's terminal state: the condition holds, it is * listed, and nothing was or will be applied. Deliberately not `pending`, which * means "somebody still has to act and doctor's exit code says so". */ status: 'applied' | 'clean' | 'not-applicable' | 'would-apply' | 'pending' | 'reported' | 'error'; detail: string; commands?: string[]; pendingReason?: PendingReason; } export interface DoctorRunResult { outcomes: MigrationOutcome[]; /** Confirm-tier items left undone — drives the doctor exit code (AC-10). */ pendingConfirm: MigrationOutcome[]; } //# sourceMappingURL=types.d.ts.map