/** Test-only: clears the warn-once ledger so a later test can observe a warning. */ export declare function _resetValidateWarnings(): void; /** * Distinguishes failure causes, which a bare `string | undefined` cannot. * * `ENOENT` (the file is gone) has to be told apart from `EACCES`/`ELOOP` (the * file may well be there and we could not look): the first is dropped silently, * the second warns, and the deleted-in-workspace guard (R4 AC 14) keys off it. */ export type RealpathResult = { ok: true; path: string; } | { ok: false; code: string; }; /** * `fs.realpathSync` that never throws. * * Warn policy, unchanged by the move to core: silent on `ENOENT` — a task that * deletes files records them, so warning on every deletion is noise — and * `warnOnce` per `(code, path)` on every other code. */ export declare function safeRealpath(p: string): RealpathResult; /** * The six causes an entry can be dropped for, each counted separately (R4 AC 12). * * `resolve-threw` is **defensive and unreachable** on this path, and is kept only * because R4 AC 12 enumerates it: `path.resolve` throws `ERR_INVALID_ARG_TYPE` * for a non-string argument and nothing else — it accepts NUL bytes, empty * strings and unbounded `..` runs without complaint. Both arguments here are * guaranteed strings: the entry by the `typeof` guard above the call, the roots * by {@link ResolutionRoots}. A NUL byte is therefore rejected one step later, by * `realpathSync`, and counted as `realpath-failed`. Its tests assert it is zero * rather than folding it into a sum, so the day an untyped caller does reach it * the count is not hidden. */ export type DropCause = 'not-array' | 'not-string' | 'resolve-threw' | 'missing' | 'realpath-failed' | 'outside-roots'; export interface ResolvedFile { /** * Absolute, and the `path.resolve` spelling — *not* realpath-normalized. * Containment and dedupe were decided on this path's `realpath`; the spelling * handed back is the one pre-change behaviour handed back (R3 AC 11). */ path: string; /** Which root resolved it (R4 AC 18). */ root: 'workspace' | 'workflow'; /** A *relative* entry that anchored to a distinct existing file under both roots. */ ambiguous: boolean; } export interface FileResolution { files: ResolvedFile[]; workspaceFiles: string[]; workflowFiles: string[]; drops: Record; } export interface ResolutionRoots { workspacePath: string; workflowRoot: string; } /** * Resolves raw implementation-log entries against the workspace and the shared * workflow root. * * Ordering for a relative entry (R4 AC 8, 14, 16): the workspace candidate is * preferred; the workflow-root candidate is accepted only when it lands inside * `/.spec-workflow`. That single rule is what reconciles "anchor * the workflow root second" with "do not substitute": a code file missing from * the workspace but present in the main checkout fails the `.spec-workflow` * containment test and is dropped as `missing`, so the reviewer is never handed * the undeleted copy of a file the task removed. */ export declare function resolveLoggedFiles(input: unknown, roots: ResolutionRoots): FileResolution; //# sourceMappingURL=file-resolution.d.ts.map