Analyze

Facts and evidence

How Brunel turns a repository into facts, each with a confidence and the file and lines that prove it, and how to correct a fact that is wrong.

Why facts

A design is only as good as what it is based on. Brunel does not ask a model to guess what your code does: 16 deterministic detectors read the files and emit facts, and every fact carries its evidence. The design then cites the facts that justify each component, so you can trace any decision back to a line of your repository.

Anatomy of a fact

A fact
{
  "id": "f_db_postgres",
  "category": "datastore",
  "key": "postgres",
  "value": "16",
  "confidence": 0.95,
  "evidence": [
    { "path": "docker-compose.yml", "lines": [12, 14], "snippet": "image: postgres:16-alpine" },
    { "path": "package.json", "lines": [21, 21], "snippet": "\"pg\": \"^8.11.3\"" }
  ],
  "source": "detector"
}
CategoryWhat it covers
languageLanguages by share of code
frameworkWeb frameworks and app frameworks
runtimeNode.js, Python, Go, JVM, PHP, Ruby, Rust, Bun… and their versions
datastoreRelational and document databases, search engines, object storage
middlewareCaches, queues, streams, reverse proxies
workloadWeb processes, workers, cron jobs, websockets, release commands
integrationPayments, email, SMS, AI services, authentication, Slack…
envEnvironment variable names (never values) and what they imply
containerDockerfiles: base image, ports, multi-stage builds, user
ciExisting CI and whether tests run
existing-infraWhere the app runs today: Terraform, Kubernetes, Helm, Vercel, Heroku, Fly, Render, Railway…
scale-hintSignals of size: monorepo, number of models, migrations…

Confidence

Each rule has a confidence between 0 and 1. A dependency named exactly like a framework's server package is strong evidence; a generic name is weaker. When several detectors find the same thing, their evidence is merged into one fact and the confidence is the highest one.

Secrets never become facts

Environment files give names only: DATABASE_URL tells Brunel you use a relational database, S3_BUCKET object storage, SMTP_HOST email. Values are never read into facts. Secret-looking values are redacted from every stored excerpt and from anything the AI sees.

Correct a fact

Every fact can be corrected in the analysis view. A fact you set has source: "user" and wins over detection: re-analyses keep it, and the design uses it. Removing a wrong fact removes the components it justified at the next design.

From facts to services

The facts feed the identification of services: what gets deployed, with its type (web-ssr, spa, api, worker, cron, websocket, static), runtime, port and whether it keeps state. Things Brunel could not determine are listed as unknowns, never invented.

See What Brunel detects for the complete list of recognized packages.

Facts and evidence · Brunel Docs