/** * Substrate-path resolver (mmnto-ai/totem#1820, ADR-100 Phase C). * * Single source of truth for "where are the substrate `.handoff/` and * `.journal/` directories on disk." After ADR-100, both directories live * in a sibling `mmnto-ai/totem-substrate` repo; the original in-repo paths * are sediment-frozen per ADR-100 Q7C and serve as fallback during the * sediment window. * * Resolution walks four precedence layers: * * 1. **env** — `TOTEM_SUBSTRATE_PATH`. * 2. **config** — `TotemConfig.substratePath`. * 3. **sibling-walk** — walk up to 3 levels from `configRoot` looking for * `/totem-substrate/`. * 4. **repo-local sediment** — `/.handoff/` and * `/.journal/`. * * Layers 1-3 require full substrate shape (a git metadata subdir plus * `.handoff/` and `.journal/` subdirs) to gate against stale empty * clones. Layer 4 (sediment) accepts partial state — `.handoff/` alone * OR `.journal/` alone is valid and returns the populated dir with the * missing one as null. * * Returns a `SubstratePaths` record whose `source` field discriminates * the resolution outcome. ADR-090 graceful degradation: if all four * layers fail, returns `{ handoffRoot: null, journalRoot: null, * source: 'none' }`. Consumers handle null per their existing contract. * * Pure utility. No caching, no side effects, no logging — same stance as * `resolveStrategyRoot` (PR mmnto-ai/totem#1743). Each call walks the chain * from scratch so a process that mutates `process.env` mid-run sees the * new value next call. */ /** * Resolved substrate path triple. Non-null path values are absolute. * * - `source: 'substrate'` ⟹ both paths populated; layers 1-3 resolved. * - `source: 'repo-local'` ⟹ at least one path populated; layer 4 fallback. * - `source: 'none'` ⟹ both paths null; all layers failed. */ export interface SubstratePaths { handoffRoot: string | null; journalRoot: string | null; source: 'substrate' | 'repo-local' | 'none'; } /** * Minimal config shape consumed by the resolver. Avoids importing the full * `TotemConfig` type to keep this module dependency-light and to let * callers pass partial config objects (e.g., during init or in tests). */ export interface SubstrateResolverConfig { substratePath?: string; } export interface SubstrateResolverOptions { /** Test seam — production callers omit and the resolver reads `process.env`. */ env?: Record; /** Loaded `totem.config.ts` shape (only `substratePath` is read). */ config?: SubstrateResolverConfig; /** Test seam — production callers omit and the resolver invokes `resolveGitRoot(configRoot)` itself. Mirrors `StrategyResolverOptions.gitRoot`. */ gitRoot?: string | null; } /** * Walk the four-layer precedence chain. Returns a `SubstratePaths` record * whose `source` discriminates the resolution outcome. * * Layer order: env → config → sibling-walk (up to 3 levels from * `configRoot`) → repo-local sediment (`/.handoff/` and * `/.journal/`). * * @param configRoot Anchor for relative env / config values and start * of the sibling-walk. Typically the directory containing * `totem.config.ts` (the project root). */ export declare function resolveSubstratePaths(configRoot: string, options?: SubstrateResolverOptions): SubstratePaths; //# sourceMappingURL=substrate-resolver.d.ts.map