import type { MergePlanRecipe } from "./pull-merge-plan.js"; import type { PerFieldStatuses } from "./pull-merge.js"; /** * Defensive: assert that a file path resolves inside a containing * directory. Belt-and-braces guard against path-traversal sinks where * an upstream identity-like string ends up in `path.join` — even if * the upstream validates the string, the guard catches a regression * before the bad write lands. Throws `INPUT_INVALID` on escape. * * Identity-time validation should still happen at the boundary * (`handleOf` validates `Scai Handle` against `HANDLE_PATTERN`) — * this is the second line of defence, not the first. */ export declare const assertWithinDir: (containerDir: string, candidatePath: string) => void; /** * Compare a plan entry's recorded per-field statuses against current * classifications. Returns the list of fields that drifted between * `write-plan` and `apply-plan` time — empty when the plan is still * fresh. * * Exported for unit-test coverage of the staleness path; runRecipePull * calls this inline + throws `INPUT_INVALID` when the result is non- * empty. Caller is responsible for the recipe-kind switch that decides * whether to compare against raw `fieldStatuses` or rolled-up * template statuses (templates use rolled-up; content kinds use raw). */ export declare const detectStalePlanDrift: (planEntry: MergePlanRecipe, currentStatuses: PerFieldStatuses) => string[];