Part of the refactoring roadmap (see parent issue and docs/refactoring/roadmap.md). Phase 4 — the strongest-endorsed structural move.
internal/pipeline/pipeline.go is 5,065 lines / 178 functions with an 8,096-line test file; 38 of the last ~50 commits touch it. Four subsystems sit in verifiable bands: orchestration (~L396–1998), prompt building (~L1999–2700), artifact IO + workbench (~L2700–3450, incl. security-sensitive workspace-escape validation), dossier (~L3452–4550, 22 dedicated types).
Dedup inside the file first (less code to move, fewer symbols to export), then move-only extractions.
Tasks
Risks: test redistribution is the largest cost — don't silently weaken tests while porting; a fingerprint-input change would silently invalidate LLM task caches; land steps fast on this hottest-of-files or rebase pain negates the benefit. External API (DryRun/Live/SelectionOnly/Options) untouched.
Details: docs/refactoring/architecture-report.md proposal 2; docs/refactoring/tactical-simplifications-report.md Tier 1 item 8 + pipeline section.
Part of the refactoring roadmap (see parent issue and
docs/refactoring/roadmap.md). Phase 4 — the strongest-endorsed structural move.internal/pipeline/pipeline.gois 5,065 lines / 178 functions with an 8,096-line test file; 38 of the last ~50 commits touch it. Four subsystems sit in verifiable bands: orchestration (~L396–1998), prompt building (~L1999–2700), artifact IO + workbench (~L2700–3450, incl. security-sensitive workspace-escape validation), dossier (~L3452–4550, 22 dedicated types).Dedup inside the file first (less code to move, fewer symbols to export), then move-only extractions.
Tasks
loadDossierPromptCorefor the duplicated dossier/workbench prompt-input loaders (~110 LOC); unifyrunSelectionPhaserun/no-run branches + fix the eagerly-built-and-discarded prompt input; threeresolve*RuntimeConfig→ oneresolveStageRuntime; dossier inline-thread comparator/conversion dedup; result structs forrunReviewers(7 returns) /runReviewer(5);cap*ForSummary→ genericcapSlice[T]; set-builder consolidation; resolveresolveInvocationRootForSafetyonce (keep the outer pre-check — defense in depth); aliassessionDrafttollmlifecycle.SessionDraft.execute()(~315 lines, pipeline.go:504–817): extract phase helpers; one blocking-failure check replaces four identicalerrors.Is(err, errLLMTaskFailedBlocking)blocks. Caution: the dry-run allocation defer (601–605) must stay inexecute().dossier.go/workbench.go/prompts.go/lifecycle.go+ parallel test files) — zero-risk navigability win.internal/workbench:Prepare(ctx, deps{GitCommand, ResolveRepoRoot}, Request)— coupling is verifiably narrow (both deps are already injected func fields); isolates the escape-path validation; usesfsatomic(Phase 1).internal/llmlifecycle(llmTaskMetadatais already an alias ofllmlifecycle.Metadata); generic artifact-write helpers move intointernal/runartifact.internal/dossierlast, with honest interface design for the summarization deps (summarizeDiscussionArtifactsalso usescheckPromptBudget,llmTaskFingerprint, fingerprint-reset, runtime-config resolution — not a one-method interface). Fold prompt building into dossier or leave in pipeline until a second consumer exists (a standalone prompts package was rejected in review).Risks: test redistribution is the largest cost — don't silently weaken tests while porting; a fingerprint-input change would silently invalidate LLM task caches; land steps fast on this hottest-of-files or rebase pain negates the benefit. External API (
DryRun/Live/SelectionOnly/Options) untouched.Details:
docs/refactoring/architecture-report.mdproposal 2;docs/refactoring/tactical-simplifications-report.mdTier 1 item 8 + pipeline section.