The earliest architectural decision in Convilyn — and still the most consequential — was to build two completely separate processing systems rather than one unified pipeline. We called them Turbo Lane and Goal Lane. They share no code, no infrastructure, and no execution model.

This post explains the reasoning, the tradeoffs, and what the boundary between them looks like in practice.

The Core Insight: Two Different Problems

Turbo Lane and Goal Lane solve fundamentally different problems. Getting them confused leads to systems that are slow where they need to be fast, and rigid where they need to be flexible.

Turbo Lane
  Input:   File in format A
  Output:  Same file in format B
  Time:    2–10 seconds
  AI:      None
  State:   Stateless (one request, one response)
  Cost:    Near zero

Goal Lane
  Input:   File + intent ("tailor my resume for this JD")
  Output:  New artifact addressing the intent
  Time:    30 seconds – 5 minutes
  AI:      Multi-turn LLM agent with tools
  State:   Stateful (persisted graph, resumable)
  Cost:    $0.10–$1.00 per workflow

The operational requirements are different, the user experience is different, and the failure modes are different. A single pipeline would have to carry the worst properties of both.

Turbo Lane: Processor Pipeline

Turbo Lane is a deterministic processor pipeline. A request arrives, a processor is looked up in the registry, and the file is transformed. No LLM involved, no state to persist, no partial results to handle.

HTTP Request
  └─ Validate input format + target format
  └─ Lookup processor in registry: O(1)
  └─ Validate conversion parameters
  └─ Stream file from object storage
  └─ Transform (in-process or subprocess)
  └─ Upload result to object storage
  └─ Return download URL
HTTP Response (2–10s)

The processor registry maps format pairs to implementations. Supporting a new format means adding one class. The routing layer never changes.

Turbo Lane was designed to be predictable above everything else. Users expect a PNG-to-WebP conversion to behave identically every time. Any variability — from AI interpretation or model non-determinism — would be a bug, not a feature.

Goal Lane: Agent Workflow

Goal Lane is an agent-based workflow engine. The user expresses an intent, the system classifies it, selects a workflow, and executes a multi-step agent graph. The agent reads the file, calls tools, makes decisions, and produces a new artifact.

HTTP Request (job submission)
  └─ Classify intent → select workflow spec
  └─ Initialize agent state (files, prompt, tools)
  └─ Persist state to checkpoint store
  └─ Start async execution
HTTP Response immediately (job_id)

  [Background — agent graph running]
  └─ reason: LLM decides next tool to call
  └─ call_tool: Invokes MCP tool, gets result
  └─ reason: Evaluates result, decides next step
  └─ ... (20–120 iterations)
  └─ finish: Stores artifact, emits completion

Client polls SSE stream for progress events

Goal Lane jobs are asynchronous by design. A 5-minute workflow that blocks an HTTP connection would require a 5-minute timeout on every load balancer and proxy in the chain. Instead, the job runs in the background and the client receives real-time events via Server-Sent Events.

Why Keep Them Separate

The temptation in early design is to route everything through a single "smart" pipeline that detects which path to take. We considered this and rejected it for three reasons.

Latency profiles are incompatible. Turbo Lane at 3 seconds and Goal Lane at 3 minutes cannot share infrastructure tuned for one of them. Connection pools, timeout configurations, queue depths — all are sized differently.

Error semantics are different. A Turbo Lane failure is synchronous: the HTTP request returns an error and the user retries. A Goal Lane failure is asynchronous: the job is in-flight, may be partially complete, has a checkpoint that could be restored, and has already been paid for. Recovery paths are fundamentally different.

Cost models are different. Turbo Lane has near-zero marginal cost per conversion. Goal Lane has real LLM inference cost per workflow. Mixing them in a single billing and quota system would make both harder to price correctly.

The Shared Boundary

Despite being separate systems, Turbo Lane and Goal Lane share a common object storage backend and job tracking model. A Goal Lane workflow can invoke Turbo Lane processors as steps — for example, converting an LLM-generated DOCX to PDF as the final artifact.

Goal Lane Workflow
  ├── Phase 1: Extract resume content (MCP tool)
  ├── Phase 2: Tailor resume text (LLM)
  ├── Phase 3: Generate DOCX artifact (MCP tool)
  └── Phase 4: Convert DOCX → PDF (Turbo Lane processor)
                         ↑
              Reuses existing processor registry

The boundary is: Goal Lane can call Turbo Lane as a library. Turbo Lane never calls Goal Lane. Dependency is one-directional.

What This Enabled

The two-lane split made it possible to evolve each system independently. Turbo Lane received support for 280+ formats across six months while Goal Lane was being built. Goal Lane's agent architecture went through three major revisions — conversation history restoration, token budget scaling, universal prompt templating — without touching a line of Turbo Lane code.

The cost of separation is duplication: two job models, two progress tracking systems, two API surfaces. But in systems where the workloads are fundamentally different, the cost of conflation is higher.