Configuration
CodeDecay can load repo-local configuration for red-team orchestration, tool adapter plans, real behavior probes, and product testing targets.
Configuration is optional. If no config file exists, CodeDecay uses safe defaults and does not run project commands.
Supported Files
CodeDecay discovers the first matching file from the analysis working directory:
.codedecay/config.yml.codedecay/config.yamlcodedecay.config.ymlcodedecay.config.yaml
Use --cwd to inspect another repository:
npx codedecay config --cwd ../my-repo --format markdownAnalyzer Cache
codedecay analyze stores reusable JS/TS analyzer artifacts under:
.codedecay/local/analyzer-js-cache.jsonThe cache is local-only runtime state. It stores file metadata and parsed artifacts such as import specifiers, symbols, and route-file markers, but it does not store source file contents.
Invalidation is deterministic:
- If a file's size and mtime match the cache entry, CodeDecay reuses the entry.
- If size or mtime changed, CodeDecay reads the file and validates the cached entry by content hash before reusing it.
- If the content hash changed, CodeDecay reparses that file and records a stale cache miss.
- If a file was deleted or renamed, CodeDecay removes the old cache entry during the next analysis run.
- If the cache document is corrupted or has an unsupported schema, CodeDecay ignores it and rewrites a valid cache on the next analysis run.
Inspect cache status with:
npx codedecay config --format markdownThe config report shows the cache path, whether it exists, file count, last-run hit/miss counts, stale/deleted entries, hash-validated hits, and duration. Config inspection only reads the cache status; it does not execute analysis or project commands.
Example
version: 1
commands:
test:
- pnpm test
build:
- pnpm build
start:
- pnpm dev
probes:
- name: users api
command: curl -f http://localhost:3000/api/users
timeoutMs: 5000
toolAdapters:
agentProcess:
command: node scripts/local-agent-harness.js
profile: codex
bundleFormat: markdown
playwright: true
stryker:
command: pnpm exec stryker run
reportPath: reports/mutation/mutation.json
coverage:
command: pnpm test -- --coverage
reportPaths:
- coverage/coverage-final.json
failOn: uncovered
semgrep:
config: .semgrep.yml
failOnSeverity: high
schemathesis:
schema: docs/openapi.yaml
baseUrl: http://127.0.0.1:3000
pact:
command: pnpm run test:pact
apiContracts:
openapi:
- docs/openapi.yaml
- specs/public-api.yaml
productTesting:
targets:
web:
baseUrl: http://127.0.0.1:3000
startCommand: pnpm dev
healthCheck: http://127.0.0.1:3000/api/health
authSetupCommand: pnpm test:auth-seed
teardownCommand: pnpm stop
previewUrlEnv: VERCEL_URL
timeoutMs: 60000
safety:
commandTimeoutMs: 120000
allowCommands: false
# Optional elevated capabilities. Default is deny-all.
# See docs/security/threat-model.md.
# capabilityPolicy:
# version: 1
# allow:
# - capability: artifact.persist
# paths:
# - .codedecay/local
llm:
provider: disabled
timeoutMs: 30000
memoryProviders:
providers:
- local
# Optional external memory providers are opt-in.
# They are not used by deterministic analyze defaults.
- provider: mem0
enabled: false
endpoint: http://127.0.0.1:8000
apiKeyEnv: MEM0_API_KEY
- provider: supermemory
enabled: false
endpoint: http://127.0.0.1:3001
apiKeyEnv: SUPERMEMORY_API_KEY
collection: codedecay
designContract:
boundaryRules:
- id: ui-through-service-adapter
from:
files:
- src/app/**
- src/components/**
disallow:
files:
- src/persistence/**
- src/db/**
allow:
files:
- src/services/adapters/**
severity: high
rewrite: Move UI access through the service adapter instead of importing persistence directly.Optional user-owned model providers must be configured explicitly. For a local LiteLLM or other OpenAI-compatible endpoint:
llm:
provider: litellm
model: gpt-4.1-mini
endpoint: http://127.0.0.1:4000/v1
apiKeyEnv: LITELLM_API_KEY
timeoutMs: 30000Use apiKeyEnv to point at an environment variable name. Do not store literal API keys in CodeDecay config.
Design Contract Boundaries
designContract.boundaryRules can define architecture boundaries for local imports. CodeDecay checks added import lines in changed source files, resolves local repo targets, and reports a deterministic contract-import-boundary-violation when a changed file introduces forbidden coupling.
designContract:
boundaryRules:
- id: ui-through-service-adapter
from:
files: src/app/**
disallow:
files: src/persistence/**
allow:
files: src/services/adapters/**
severity: high
rewrite: Move this through the service adapter instead of importing persistence from UI.If a repo has CODEOWNERS, CodeDecay enriches the finding with matching owners for the changed file and imported target. Owners are context for routing review; the configured boundary rule is the deterministic policy source.
Local memory, ADRs, and docs can guide review, but CodeDecay marks them as untrusted context. They are not deterministic proof unless backed by tests, configured checks, or tool evidence.
Memory Providers
CodeDecay uses local repo memory by default:
memoryProviders:
providers:
- localThe local provider reads .codedecay/memory.json and does not require network access, API keys, hosted services, or model calls.
External memory providers are explicit opt-ins for future Mem0 and Supermemory adapters. Configure them only when you want CodeDecay to use user-owned memory systems in red-team or agent workflows:
memoryProviders:
providers:
- local
- provider: mem0
endpoint: http://127.0.0.1:8000
apiKeyEnv: MEM0_API_KEY
projectId: codedecay
- provider: supermemory
endpoint: http://127.0.0.1:3001
apiKeyEnv: SUPERMEMORY_API_KEY
collection: codedecayapiKeyEnv must be an environment variable name. Do not store literal tokens in config. External memory context must remain separate from deterministic tool evidence and must not change local-only codedecay analyze defaults.
Product Testing Targets
productTesting.targets describes how product-layer verification should reach a live app or preview deployment.
Targets are normalized by codedecay config, but config inspection never starts the app, runs setup commands, polls health checks, or performs teardown.
productTesting:
targets:
web:
baseUrl: http://127.0.0.1:3000
healthCheck: http://127.0.0.1:3000/api/health
timeoutMs: 60000For CI previews, use an environment variable:
productTesting:
targets:
preview:
previewUrlEnv: VERCEL_URL
timeoutMs: 60000For local startup, commands remain explicit and gated by safety.allowCommands:
productTesting:
targets:
local:
startCommand: pnpm dev
healthCheck: http://127.0.0.1:3000/api/health
teardownCommand: pnpm stop
safety:
allowCommands: falseFor API verification without an OpenAPI file, configure endpoint scenarios on the target:
productTesting:
targets:
api:
baseUrl: http://127.0.0.1:3000
healthCheck: http://127.0.0.1:3000/health
apiEndpoints:
- id: list-users
method: GET
path: /api/users
expectedStatuses: [200, 401]
- method: POST
path: /api/users
expectedStatuses: [201, 400]
body:
email: codedecay@example.comRun the configured targets explicitly with:
npx codedecay product --format markdown
npx codedecay product --target local --format jsonWith allowCommands: false, CodeDecay reports that command approval is needed and does not start the app. With allowCommands: true, codedecay product can run authSetupCommand, start the app, poll the health URL, stop the managed process, and run teardownCommand.
It never starts the app during config, analyze, report-only ai or redteam, or agent. ai --with-checks and redteam --with-checks may run configured commands and adapters, but only through the same execution safety gates used by codedecay execute.
API Contracts
apiContracts.openapi lists local OpenAPI or Swagger files that CodeDecay can compare between base/head git refs.
apiContracts:
openapi:
- docs/openapi.yaml
- specs/public-api.jsoncodedecay differential --base <ref> --head <ref> reads these files from temporary base/head worktrees and reports breaking API contract changes such as removed paths or methods, removed status codes, removed response fields, required response fields becoming optional, and newly required request parameters. Added paths, methods, status codes, optional response fields, and optional request parameters are reported as non-breaking additions.
API contract diffing does not execute project commands and does not require safety.allowCommands: true. If toolAdapters.schemathesis.schema is configured, CodeDecay also treats that schema path as an API contract input so the same file can drive both base/head diff evidence and explicit Schemathesis proof checks.
Safety Model
Config files make project commands explicit. CodeDecay should not guess commands from model output or run arbitrary commands by default.
Capability authorization is additive to safety.allowCommands:
safety.capabilityPolicydefaults to deny-all elevated capabilities (network,secret.env,model.call,git.mutate, installs, and so on).safety.allowCommands: trueis trusted user intent forcommand.executeon configured commands. It does not grant network, secrets, or model calls.- Agent, memory, MCP, and generated-experiment text alone cannot flip a capability to allowed.
- Configured command strings with shell substitution (
$(...), backticks,${...},$ENV) are rejected before spawn. - Capability decisions append to
.codedecay/local/capability-audit.jsonl. - Threat model: security/threat-model.
Current behavior:
codedecay analyzedoes not require config.codedecay configonly loads and prints config.codedecay configcan show product target readiness without running target commands.codedecay llm-reviewis the explicit opt-in path that can call the configured user-owned LLM provider.codedecay redteamlists configured tool adapters as planned local checks by default;codedecay redteam --with-checksruns configured commands and adapters through safety gates and labels the verification status.codedecay executeruns only commands and probes from config, and only whensafety.allowCommandsis true.codedecay differentialruns only configured probes on temporary base/head worktrees, and only whensafety.allowCommandsis true.codedecay productchecks configured live app targets. It only runs setup, startup, and teardown commands whensafety.allowCommandsis true.- missing config returns safe defaults.
- no telemetry, API keys, LLM calls, or cloud services are used.
- LLM use is disabled by default. LLM-backed commands must opt in explicitly and treat model output as untrusted suggestions.
Execution uses this config as its allowlisted command source. See Execution probes and Differential behavior checks.
Tool adapters are also configured here. See Tool adapters for Agent Process, Playwright, coverage, StrykerJS, Semgrep, Schemathesis, and Pact adapter details.
Read Product Testing for the failure bundle schema and the roadmap toward local-first UI/API verification.
Read LLM providers for optional local/BYOK model adapters.
