Have the Agent Discover the Project's Own Commands
Your AI agent is running the wrong test command. It types npm test in a repo that gates merges on npm run test:ci, or bare pytest in a project whose real suite runs through tox. A guessed command can pass while the actual suite fails — or quietly skip the checks that gate the repo. Canonical always beats guessed.
Why guessed commands lie
A generic command is not "roughly right." It can be wrong in ways that look green:
- It runs a subset —
pytestwithout the coverage gate, lint, or type check that CI enforces. - It runs with the wrong environment — the system Python instead of the project venv, or without the env vars CI sets.
- It runs nothing that matters —
npm testprintsError: no test specifiedand exits nonzero in a repo whose real checks live in a Makefile.
The result is an agent that reports "tests pass" on work the repo would reject. The fix isn't a smarter guess — it's telling the agent to stop guessing.
The discovery pass
Before the agent runs anything generic, have it read the project surface and record the exact commands it finds. One instruction covers it:
Before running any build, test, or lint command, inspect the repo's own definitions — package manifests, task runners, and CI — and use the exact commands defined there. Never substitute a generic equivalent.
Where the truth usually lives:
| Surface | What to read | What it yields |
|---|---|---|
package.json | the scripts field | npm run build, npm run test:ci, npm run lint |
pyproject.toml | [project], [tool.*] tables | test runner config, lint/type-check settings, entry points |
Makefile / justfile | targets | make test, make check — often the wrapper CI itself calls |
.github/workflows/*.yml | run: steps in each job | the literal commands that gate merges |
CONTRIBUTING.md / AGENTS.md | setup and check sections | human-documented commands and their order |
CI workflows are the highest-authority source: whatever runs in the merge-gating job is the definition of "green" for that repo.
Record it, don't rediscover it
Discovery is cheap once and wasteful every time. After the first pass, have the agent write the findings down — in your agent instructions file (AGENTS.md, CLAUDE.md, or your tool's equivalent):
## Commands (discovered from CI + Makefile)
- Build: npm run build
- Type check: npm run typecheck
- Lint: npm run lint
- Tests (what CI runs): npm run test:ci
Now every future session starts with the canonical commands already in context, and a green result really means ready.
Power-user moves
- Diff local against CI. Ask the agent to list every
run:step in the merge-gating workflow and flag any check it wasn't running locally. Missing steps are exactly where "passes for the agent, fails in CI" comes from. - Prefer the repo's wrapper over its parts. If
make checkexists and CI calls it, runmake check— not your own reconstruction of its pieces. Wrappers encode ordering and env setup you can't see from the outside. - Re-discover on drift. Commands change. If a recorded command fails with "unknown script" or "no such target," the correct move is a fresh discovery pass — not a fallback to a generic guess.
- Capture the environment, not just the verb. Note the package manager (
npmvspnpmvsyarn— check the lockfile), the Python entry point (tox,nox,hatch, plainpytest), and required env vars from CI.
Resources
- npm scripts — the
scriptsfield ofpackage.json - Writing your
pyproject.toml— Python Packaging User Guide - GNU Make manual — introduction to Makefiles and rules
- Workflow syntax for GitHub Actions — jobs and
runsteps - AGENTS.md — an open format for giving coding agents project instructions
Building an AI feature? Yeda AI designs, audits, and ships production LLM systems.