Skip to content

Refactor Phase 4: decompose pipeline.go (in-file dedup, then workbench + dossier extraction) #451

Description

@rianjs

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

  • In-file tactical dedup: shared loadDossierPromptCore for the duplicated dossier/workbench prompt-input loaders (~110 LOC); unify runSelectionPhase run/no-run branches + fix the eagerly-built-and-discarded prompt input; three resolve*RuntimeConfig → one resolveStageRuntime; dossier inline-thread comparator/conversion dedup; result structs for runReviewers (7 returns) / runReviewer (5); cap*ForSummary → generic capSlice[T]; set-builder consolidation; resolve resolveInvocationRootForSafety once (keep the outer pre-check — defense in depth); alias sessionDraft to llmlifecycle.SessionDraft.
  • Decompose execute() (~315 lines, pipeline.go:504–817): extract phase helpers; one blocking-failure check replaces four identical errors.Is(err, errLLMTaskFailedBlocking) blocks. Caution: the dry-run allocation defer (601–605) must stay in execute().
  • In-package file split (dossier.go/workbench.go/prompts.go/lifecycle.go + parallel test files) — zero-risk navigability win.
  • Extract internal/workbench: Prepare(ctx, deps{GitCommand, ResolveRepoRoot}, Request) — coupling is verifiably narrow (both deps are already injected func fields); isolates the escape-path validation; uses fsatomic (Phase 1).
  • Finish the llmlifecycle absorption: task-metadata fingerprint/read/write helpers move into internal/llmlifecycle (llmTaskMetadata is already an alias of llmlifecycle.Metadata); generic artifact-write helpers move into internal/runartifact.
  • Extract internal/dossier last, with honest interface design for the summarization deps (summarizeDiscussionArtifacts also uses checkPromptBudget, 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.md proposal 2; docs/refactoring/tactical-simplifications-report.md Tier 1 item 8 + pipeline section.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:pipelineEnd-to-end review pipeline

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions