ADR-0037.
`runward characterize` detects infrastructure and framework/DB config signals (presence only)
Date: 2026-07-20
Status: proposed
Deciders: Thibault Souris (maintainer)
Method: decision-loop — resume-existing audit finding, reality-checked against detectContainers (characterize.ts:143, a short fixed list) and the M2 need for an architecture note that starts from real signals.
Context
detectContainers (characterize.ts:143) checks a small fixed list (Dockerfile, compose, vercel/netlify/fly, Procfile, Chart.yaml). It misses the signals that most define a modern system's architecture: Infrastructure-as-Code (Terraform, Pulumi, Kubernetes manifests, serverless.yml, AWS SAM) and framework/DB configuration (next.config.*, vite.config.*, nuxt.config.*, tsconfig.json, prisma/schema.prisma, drizzle.config.*, alembic.ini). For brownfield mode M2 — join a project in flight, the architecture note is reconstructed "by observation" — but characterize hands the observer almost nothing on the infra/architecture axis. These are pure-presence facts sitting at rest in the repo.
Decision
characterize adds two presence-only detectors and reports them as facts, feeding --mine candidates.
- Infrastructure & deployment. Detect presence of
*.tf/*.tf.json(bounded walk),Pulumi.yaml, Kubernetes manifests (ak8s//kubernetes/dir orkustomization.yaml),serverless.yml/serverless.yaml,template.yaml/samconfig.toml(SAM). Report under a new "Infrastructure & deployment" section, sorted. - Framework / DB config. Detect presence of
next.config.*,vite.config.*,nuxt.config.*,svelte.config.*,astro.config.*,tailwind.config.*,tsconfig.json,prisma/schema.prisma,drizzle.config.*,alembic.ini,knexfile.*. Report under "Framework / DB config", sorted. - Presence, never intent. The report says "a Terraform configuration is present", never "infrastructure is well-managed" or "the DB schema is X". Pure existence; parsing the content into an architecture claim is the operator's job (ADR-0013).
- Feeds
--mine. A detected IaC/framework signal becomes a candidate DRAFT (ADR-0038) — a hypothesis with provenance,why: UNKNOWN, never an asserted architecture.
Deterministic (sorted), read-only, zero-LLM.
Alternatives discarded
- Parse the IaC/config to extract the real topology (resources, providers, the DB schema). Rejected: heavy, per-tool, and interpretive — it manufactures an architecture claim from a machine read, the overclaim ADR-0014 forbids. Presence is a fact; topology is reconstructed by the operator.
- One ever-growing flat "deploy descriptors" list. Rejected: infra and framework/DB config answer different questions (how it ships vs what it is built on); two labelled sections are more legible and map to the architecture note's structure.
- Deep-walk for every possible config filename. Rejected as unbounded/noisy; a curated, bounded set of high-signal markers (the ones that actually define architecture) via the existing bounded
walk()and root checks.
Consequences
- Positive. The M2 architecture note starts from real infra/framework signals instead of zero.
--minegains meaningful structural candidates beyond stack/CI/deps. Still offline, reproducible, fact-only. - Negative, accepted. A curated marker list will lag new tools; extending it is a one-line addition per marker (and a reopening trigger watches for the gap). Presence without parsing can feel thin — deliberately, to stay on the fact side.
- On other boundaries.
Inventorygrowsinfra+frameworkConfiglists;renderCharacterizationgrows two sections;mineDrafts(ADR-0038) consumes them. The gate is untouched.
Reevaluation trigger (mandatory, dated)
Reopen if (a) a common IaC/framework marker is repeatedly missing from real repos — extend the curated list; (b) operators need parsed topology (resource inventory, schema tables) badly enough to justify per-tool parsing behind the read-only contract — then design it as labelled facts or --mine hypotheses, never an asserted architecture; or (c) the presence lists prove too noisy (false positives on vendored configs).
Trigger set on: 2026-07-20 · Watched via: dogfooding characterize on infra-heavy repos.