Skip to main content
Rule ID: AE-TEST-001 · Severity: High · Category: Testing · Auto-fixable: No

Why this rule

An agent that writes code in a language with no automated tests has no way to verify its own work. Tests are the agent’s exit condition — without them it can only produce a diff, not a proof. The AGENTS.md standard treats the test command as one of the highest-value pieces of context an agent can have. AE-TEST-001 checks that there is actually something to run — before AE-AUTO-001 checks that the command is discoverable.

What triggers it

Charter detects active languages from manifest files committed to the repo: A language is only active when its manifest is present and the repo contains at least one non-test source file for that language outside tooling directories (scripts/, vendor/, node_modules/, dist/, build/). For each active language, Charter checks whether at least one test file exists using standard naming conventions: Files in directories named test/, tests/, spec/, or __tests__/ also count, regardless of language.
Charter detects active languages by manifest, not by line count. A go.mod with one .go source file (non-test) counts as an active language and requires at least one test file.

Examples

A Go module with source files under internal/ but no *_test.go file anywhere:
A TypeScript project with source files but no test files:

How to fix

Add a minimal test file for each active language that Charter flags. The test does not need comprehensive coverage — Charter checks for presence, not coverage percentage or pyramid shape.
1

Identify the active languages

Run charter doctor or charter explain AE-TEST-001 to see which languages are flagged and which manifest triggered each one.
2

Add a minimal test file

Create at least one test file using the language’s standard naming convention. A single passing test satisfies the rule.
3

Verify the finding clears

Run charter doctor again to confirm the finding no longer appears.

Score impact

High (−10 per finding). No hard cap — caps are reserved for raw-secret and Blocker findings. If multiple active languages all lack tests, each fires a separate finding instance. See Scoring and caps.

Edge cases

AE-TEST-001 does not fire when no recognized code language is active. A repo containing only Markdown, YAML config, or tooling scripts is not penalized.
A //go:embed’d web asset (e.g. a report.js embedded into a Go binary) is a bundled resource, not a language surface. It does not activate JavaScript/TypeScript even when a build-tooling package.json is present.
A lone *.rb Homebrew formula with no Gemfile, or a stray *.py helper with no pyproject.toml, is not an active language and does not require tests.
Rust inline unit tests count via the #[cfg(test)] / #[test] content signal — no separate tests/ directory is required.

AE-AUTO-001

Requires a discoverable command to run the tests that this rule checks for.

AE-CI-002

Requires CI to run those tests on every pull request.

CLI