// Whether a piece of daemon state travels, declared per manifest entry so the bundler and restorer both derive from it // rather than a hand-kept list. The classes are exhaustive, no unset default, since a credential store left // unclassified would default to carry and leave the sandbox in an exported file. export type Portability = /* Ordinary state. Travels in every bundle. */ | "carry" // Holds a credential (token, webhook secret, ssh key); travels only when the owner opts in at export. | "secret" // Binds this sandbox to its owner, browsers or host; never travels, the target mints its own. | "identity" // Regenerated by the target from state that does travel; left out for size, not safety. | "derived"; // One manifest entry: the path and what happens to it at export. note is user-facing, an instruction to the owner ('log // in again'), not a rationale. export interface StateFile { readonly path: string; readonly portability: Portability; readonly note?: string; } // Longest-prefix match: a nested, more specific entry wins over a general one, like .gitignore's deepest matcher. // Undefined for an unclaimed path; callers pick the default (workspace carry, history derived). export const stateFileFor = (path: string, files: readonly T[]): T | undefined => files .filter((file) => path === file.path || path.startsWith(file.path) || `${path}/` === file.path) .reduce((best, file) => (best === undefined || file.path.length > best.path.length ? file : best), undefined);