C:\> Documentation

Environments: QA, staging, prod

Documentation

Running more than one environment? Codepanion can keep them apart. Label each database connection, each code snapshot, and each log source with an environment — qa, staging, prod — and the agent investigates against exactly one of them. A QA engineer can point an investigation at the QA build's source, the QA database, and the QA logs in the same conversation, without prod data bleeding in.

An environment is a first-class investigation context. Pick one from the environment picker at the top of an investigation to pin it — every tool then defaults to that environment's code, data, and logs. Leave it on all environments and the agent uses the default for each, or scopes per request as you ask.

Labelled database connections

In Settings → Database Connections, add one connection per environment: pick a label, paste the connection string, test, save. Each connection is stored as its own encrypted Key Vault secret, gets the same automatic read-only enforcement, and keeps its own last-test status. Tenants with a single database don't need to do anything — the existing connection simply lives under the default label.

Catalog databases

Multi-tenant yourself? If you keep a catalog/registry database that maps each of your tenants to its own database, you don't have to paste a fixed connection string — set an environment's kind to Catalog, give us the catalog's connection string, and write a small resolver script that looks the real connection string up:

const rows = connection.query({
  table: 'tenants',
  columns: ['server', 'database', 'username', 'password'],
  where: [{ column: 'tenant_key', op: '=', value: resolveKey }],
  limit: 1
});
if (rows.length === 0) throw new Error('unknown tenant');
const r = rows[0];
return 'Server=' + r.server + ';Database=' + r.database +
       ';User Id=' + r.username + ';Password=' + r.password + ';';

The script sees exactly two globals: resolveKey — the lookup key you configure per environment (or the environment label if you leave it blank) — and connection, whose single query(...) method runs a read-only, parameterised query against your catalog (the same structured query format the agent uses — never raw SQL). It must return the connection string. The Test button runs a real resolution end to end, including a live probe of the resolved connection.

Sandboxed by design

Resolver scripts run in an isolated, locked-down interpreter on a separate service that holds no credentials of its own — no network, no filesystem, no .NET access, and strict time (~2s), memory and statement budgets. The resolved connection string passes the same safety validation as one you paste in, and read-only access is enforced on both the catalog and the resolved database.

Labelled code snapshots

Tag an ingest with the environment it was built from using the X-Environment header (and optionally give the snapshot a human-readable name with X-Snapshot-Name):

curl -X POST "https://api.codepanion.app/api/ingest/$TENANT_ID" \
  -H "Authorization: Bearer $CODEPANION_TOKEN" \
  -H "Content-Type: application/gzip" \
  -H "X-Commit-Sha: $COMMIT_SHA" \
  -H "X-Environment: qa" \
  -H "X-Snapshot-Name: QA build 2026-06-10" \
  --data-binary @repo.tar.gz

Labels are lowercase letters, digits and hyphens. Each environment keeps its own snapshot lineage — a qa upload chains to the previous qa snapshot. Uploads without a label keep working exactly as before.

Environments are not the same thing as codebases: a codebase says which repository the code came from, an environment says which deployment it was built for. The two are independent — labels apply within each codebase, so your billing-service codebase can carry its own qa and prod snapshots alongside another repo's.

Labelled log sources

Logs are labelled per environment too. In Settings → Log sources, connect a Seq log source under each environment label — qa, staging, prod — and the agent's search_logs and get_log_context tools read the environment they're pinned to. So an investigation pointed at qa reads the QA build's source, queries the QA database, and searches the QA logs — the same environment end to end. Log sources are configured in the app, not pushed over the ingest endpoint; see the logs guide.

Asking about one environment

Pin an environment from the picker — or just name it in your message, "why is checkout failing in QA?" — and the agent searches the QA snapshot, queries the QA database, and reads the QA logs together. When you don't pin or name one, it uses the default environment, and the audit log records which environment every query and log search ran against.

Good to know

This is how QA teams use Codepanion as more than a support tool: point a qa environment at your QA build, QA database, and QA logs, and investigate test failures with the agent before they ever reach production.

Need help getting set up?

Every pilot customer gets hands-on onboarding from the founding team. We'll walk through setup together and make sure everything is working.