/** * MultiPassOrchestrator — Phase 2 of slice-topology-multipass (W2 T9). * * Top-level orchestrator that runs the existing 6-stage algorithm * (`decomposeSlices`) at service-level and/or file-level granularity, then * stitches the passes together with `merge` to produce a v2 * `DecompositionResultV2` with cross-pass edges. * * Granularity semantics: * - 'service': Pass 1 only. Each workUnit becomes a SliceV2 with * granularity='service' and parentSliceId=null. * - 'file': Pass 2 only. `decomposeSlices` is called once on the full * scope (no parent subdivision). Each workUnit becomes a * SliceV2 with granularity='file' and parentSliceId=null. * - 'both': Pass 1 + N Pass 2 (one per parent). Pass 2 runs for every * Pass 1 slice without decider filtering. * - 'auto': Same as 'both' but Pass 2 only runs for parents where * `shouldSubdivide(wu).subdivide !== false` (both `true` and * `'tie-break'` qualify). * * Granularity-mapping approach (see pre-flight note in the task spec): * Approach 1 — pass-through with post-hoc filter. The 6-stage algorithm * (`decomposeSlices`) does NOT accept a `granularity` or `scopeFilter` * option, and the pre-flight note recommends NOT extending `DecomposeOptions` * (surgical change rule). We therefore: * 1. Pass the full `opts` (including the orchestrator-only `granularity` * and `llmRunner` fields) through to `decomposeSlices`; the algorithm * ignores the extra fields. * 2. Filter Pass 2 `result.workUnits` post-hoc so each Pass 2 result * only contains files inside the parent slice's file scope. * * Cross-pass edges are produced by `merge` whenever there are ≥2 passes. * The merger handles both static detection (type-shares, fixture-shares, * import-re-export — runs UNCONDITIONALLY) and the LLM fallback path (only * when `opts.llmRunner` is provided). Without an llmRunner the orchestrator * still gets statically-detected cross-pass edges; only `llmArbitrations` * stays empty. * * @see ./slice-decompose-service.ts — the 6-stage algorithm (reused as-is) * @see ./granularity-decider.ts — subdivide decision * @see ./cross-pass-edge-merger.ts — cross-pass edge detection * @see ./llm-arbitrator.ts — LLM fallback for cross-pass edges * @see ./slice-topology-types.ts — DecompositionResultV2, PassResult, etc. */ import type { LlmRunner } from '../audit/audit-goal-service.js'; import type { DecomposeOptions } from './slice-decompose-types.js'; import type { DecompositionResultV2 } from './slice-topology-types.js'; export type Granularity = 'service' | 'file' | 'both' | 'auto'; export interface MultiPassOptions extends DecomposeOptions { /** Service-level vs file-level vs both. Defaults to `'both'`. */ readonly granularity?: Granularity; /** Optional LLM runner; when present, cross-pass edges are computed via `merge`. */ readonly llmRunner?: LlmRunner; } /** * Run the multi-pass decomposition algorithm and return a v2 result. * * 1. Reset the LLM arbitrator budget for this invocation. * 2. Run Pass 1 (service-level) if granularity includes 'service'. * 3. Run Pass 2 (file-level) — for every qualifying parent in 'both'/'auto', * or once on the full scope in 'file'-only mode. * 4. Compute cross-pass edges via `merge` whenever there are ≥2 passes * (static detection runs unconditionally; LLM fallback only when an * llmRunner is supplied). * 5. Return a `DecompositionResultV2` with `partial: false`. */ export declare function decompose(rid: string, prdMarkdown: string, projectRoot: string, opts?: MultiPassOptions): Promise;