Skip to content

Split query-engine.ts into retrieval stages #2

@devin-ai-integration

Description

@devin-ai-integration

Objective

Split query-engine.ts (currently 1,614 lines) into distinct retrieval stages. QueryEngine becomes the orchestrator wiring stages together and exposing query(), trace(), and inspect().

Proposed stages:

Stage Responsibility
QueryNormalizer Question normalization, ID/lexeme/route/family/status detection
CandidateSeeder Scoring patterns, routes, lexemes, index descriptions, heuristic seeds, session context
CandidateRanker Ranking, route-wins logic, initial node selection
FrontierExpander Bounded graph expansion with hop budget and role-coverage
AnswerProjector Route answers, pattern answers, Part C drafts, confidence, gaps
SynthesisAdapter Optional LLM synthesis handoff with deterministic fallback

"Done" looks like: Each stage is a separate module, QueryEngine is an orchestrator only, and existing tests pass.

Kind

refactor

Affected area

src/runtime/ (compiler & query engine)

Acceptance criteria

  • query-engine.ts split into ≥ 5 focused modules under src/runtime/
  • Each stage has typed input/output interfaces
  • QueryEngine acts as orchestrator only
  • Trace determinism: same snapshot + same query → same selected support set
  • Projection stability: answer surface may rephrase, support set must not silently drift
  • Stage isolation: seeder changes do not affect projection; projection changes do not affect seeding
  • All existing tests pass without modification

Agent-delegable?

partially — needs human review

Additional context

  • Current file: src/runtime/query-engine.ts (1,614 lines)
  • Seven responsibilities: question interpretation, candidate seeding, ranking, frontier expansion, trace emission, answer projection, synthesis brokering
  • trace is a first-class public operation — retrieval internals are partly user-facing

FPF grounding:

  • A.15 (Role–Method–Work Alignment, Stable): Each proposed stage maps to a distinct Role with its own Method and Work evidence. The monolith is "process soup" (A.15:8) — seven responsibilities under one class.
  • A.7 (Strict Distinction / Clarity Lattice, Stable): A bad answer could come from normalization, seeding, ranking, expansion, or projection — "category collapse" (A.7:3) makes fault attribution impossible.
  • A.3 (Transformer Quartet, Stable): Each stage is a transformer with typed input→output, making the transformation chain explicit and auditable.
  • E.19 (Pattern Quality Gates, Stable): Stage contracts enable stage-local review and quality gates.

Note: Previous version cited E.20 (Mechanism Introduction Protocol). E.20 has Draft status in the spec. Replaced with E.19 (Stable) and added A.7, A.3.

Measurable impact

Metric Before After (target) How to measure
LOC in query-engine.ts 1614 ≤400 (orchestrator only) wc -l src/runtime/query-engine.ts
Runtime module count under src/runtime/ 15 ≥20 (≥5 new stage modules) ls src/runtime/*.ts | wc -l
Typed stage interfaces 3 ≥8 (≥5 new stage input/output types) grep -Ec 'export (interface|type).*(Input|Output)' src/runtime/*.ts | awk -F: '{s+=$2} END {print s}'
Existing test pass rate all pass all pass (no regressions) bun run test

Metadata

Metadata

Assignees

Labels

taskA concrete work item — research, refactor, chore, or agent-delegable task

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions