Skip to content
mtecnic edited this page May 27, 2026 · 1 revision

FAQ

Common questions about design rationale, comparisons to other tools, and the philosophy behind specific choices.

What is cadillac trying to be?

An opinionated harness for one specific job: take a task description, produce a validated application.

Not a general-purpose agent framework. Not an in-IDE pair programmer. Not a code-completion tool. The output is a packaged, runnable, behaviorally-tested project — README + deps + tests included.

If you want to use it for something else (chat with LLM, generate code snippets, refactor existing code), there are better tools for that. Use cadillac when "sentence in, working app out" is what you actually want.

How is this different from Devin / OpenHands / Aider / Cursor agent mode / Copilot Workspace?

Honestly: a lot of overlap on the basics. Where cadillac differentiates:

Layer Other tools Cadillac
Validation "code compiles, tests pass" 12-check gate including operational gates (deploy-readiness probes)
Spec inference Implicit (LLM picks its own scope) Explicit SPEC phase — 15-40 stories the build is held to
Completeness None — when LLM says done, it's done CRITIC audits build vs spec, bounces if features missing
Behavioral testing Unit tests only RUNTIME drives real flows against the live artifact
Stuck-loop handling Either infinite retry or give up Surgical mode — focused 500-token edit when same error repeats 3×
Large-spec resilience All-or-nothing build Progressive tiers — must → must+should → could
Self-improvement Manual updates cadillac improve — closed-loop matrix-driven
Local-LLM compat Mostly cloud-only Runs against any OpenAI-compatible endpoint (vLLM, Ollama, etc.)
Audit trail UI-tied Everything's a JSONL on disk; greppable, inspectable

If your priorities are: in-IDE assist, fast feedback, working alongside a human — use Cursor / Copilot / Cody / Aider.

If your priorities are: "I want to type a sentence and walk away, then return to a deployable app with verified behavior" — cadillac.

Why an LLM-agnostic approach instead of integrating tightly with a specific model?

Three reasons:

  1. Local-first compatibility. Some use cases (defense, healthcare, financial) require local LLMs. cadillac runs against vLLM with any open-weight model.
  2. Model churn. Every 3-6 months a new SOTA model arrives. Tools tightly bound to a specific model age fast.
  3. The OpenAI HTTP spec is the LCD. vLLM, Anthropic, Mistral, Together, Groq, Ollama all expose it. By targeting that spec, cadillac works with anything that does.

There's a real cost: no streaming-tool-call optimizations, no model-specific prompt format optimizations. The tradeoff has been net positive — cadillac has worked against Qwen3-Coder, Qwen3.6-27B, OpenAI's gpt-4 family, and Anthropic's Claude family without code changes.

Why so many phases? Isn't this overengineered?

A fair question. The honest answer: the phases were added one at a time, each in response to a recurring failure mode that the previous pipeline couldn't catch.

  • SPEC was added after a build that the user described as "missing half of what I asked for"
  • CRITIC was added after a build that passed every check but lacked logout / delete / search
  • RUNTIME was added after a build whose logout endpoint returned 200 but didn't actually invalidate the token (an exact real example)
  • WIRING was added after a build whose frontend and backend each tested fine but couldn't talk to each other
  • Surgical mode was added after a build that died at retry 5/5 on a single undefined name

Each phase is justified by a specific bug class it prevents. Removing one would re-open that class.

That said: yes, the wiring complexity is real and a smaller pipeline would be simpler. The bet is that completeness + behavioral correctness are worth the complexity for the "deploy-ready" use case.

How long does a typical build take?

Project shape Files Wall time
Simple Python CLI 5-10 ~2-5 min
Flask REST API 10-15 ~10-20 min
Full-stack Flask + React 25-40 ~30-60 min
Modular game (Matrix Doom) 30 modules ~15-20 min
Big spec with tiers (habit tracker, 30 stories) 15-25 ~60-90 min

Wall time is dominated by LLM round-trip latency. A local Qwen3-Coder on a 4090 averages 20-40s per chat completion at typical input sizes; a remote API can be 2-5× faster.

phase_budgets.jsonl makes this self-tuning over time: the next build's budget for each phase is computed from past p90s.

Can I use this commercially?

The repo is Apache 2.0. Patent grant included. Yes — you can use it commercially, modify it, fork it, embed it, build a service on top of it.

If you do something interesting with it, an attribution or a link back is appreciated but not required.

What models work well? What models don't?

Works well (tested):

  • Qwen3-Coder (any size) — the daily-driver
  • Qwen3.6-27B AWQ-INT4
  • GPT-4 / GPT-4-Turbo (cloud)
  • Claude 3.5 / 3.7 / 4 Sonnet (cloud)

Works with caveats:

  • Smaller (<7B) models — succeed on simple builds, struggle with complex modular plans
  • Models without strong function-calling — cadillac uses tool calls heavily; weak tool-call support means missed edits

Won't work:

  • Text-completion-only endpoints (no chat/completions API)
  • Models with <16K context — code map alone exceeds that

Why JSONL everywhere instead of SQLite / Postgres / Redis?

Two reasons:

  1. Greppable + portable: anyone with a text editor or jq can inspect the state. No tooling required. Move a workspace to a different machine? Just tar.
  2. Append-only safety: the worst-case failure of an interrupted append-only write is a malformed last line, which the loader silently skips. The worst-case failure of an interrupted SQLite write is corruption.

The performance ceiling of JSONL is fine for cadillac's volumes (~100K lessons would still be fast). If the volumes ever needed Postgres, the migration path is straightforward — but it's not needed.

Why no web UI?

Two reasons:

  1. Scope: building a web UI is its own project. Every hour spent on UI is an hour not spent on the resilience stack. The terminal UI is sufficient for "watch a build go" and the dashboard is sufficient for "browse past builds."
  2. Operational simplicity: no server to run, no port to expose, no daemon to keep alive, no API to version. Press q and nothing remains.

If you want a web UI for a specific workflow (e.g. internal team visibility), the JSONL state files are the API — build a thin reader and you're done.

What if my build hangs?

Three escape hatches:

  1. Ctrl-C — the SIGINT handler unwinds cleanly, writes phase history, closes the build log. Partial state is preserved for resume.
  2. touch improve/STOP — only for the improve cycle; checked at iteration boundaries.
  3. pkill -f "python3 -m cadillac" — last resort. The phase history may lose the in-flight phase's contribution but everything else is durable.

If a build hangs consistently on the same task, it's a bug — file an issue with the workspace tarball.

Where do the LLM calls go? Can I redirect them?

--api-url URL is the single flag that controls this. Defaults to http://localhost:8000/v1. All chat completions and /v1/models lookups go to that URL.

For models that need an API key, also pass --api-key KEY.

For client-side rate limiting (to be nice to a shared endpoint), --rate 0.5 = max 0.5 calls/sec. --rate 0 disables.

How do I know if it's working?

The phase bar at the top of the live UI is the headline indicator. If you see phases advancing (PLAN → DEPS → SCAFFOLD → BUILD), it's working. If you see the same phase + round counter for >5 minutes, the LLM is stuck mid-response — check the API endpoint.

Auxiliary signals:

  • ~/.../workspace-*/progress.md updates per round
  • ~/.../workspace-*/.cadillac/build.jsonl grows continuously
  • The dashboard's "Live" panel shows which workspaces are active

Why "Cadillac"?

The brand connotation: serious, well-engineered, opinionated, not for everyone but very good at what it does.

The acronym backronym (in the README): Critic-driven · Autonomous · Decomposing · Iterative · Learning · Lifecycle · Adaptive · Compiler

Each letter maps to a named subsystem in the codebase — you can grep for it.

See also

Clone this wiki locally