ward.toml
Configuration uses TOML version 1. Each gate is declared in [quality-gates.<id>] and must have a
command:
version = 1preset = "standard" # optional: standard or strict; informational
[quality-gates.tests]enabled = true # default: truecommand = "./mvnw test"
[quality-gates.integration]command = ["./mvnw", "verify"]profiles = ["ci", "strict"]For Gradle projects, use the Gradle Wrapper when present (or gradle when it is not):
[quality-gates.tests]enabled = truecommand = "./gradlew test"command accepts a string or an array of strings. Arrays preserve exact argument boundaries. A
string is parsed into arguments. Neither form is executed through a shell.
Profiles:
- Gates without
profilesbelong todefault. - Init-generated configurations assign fast gates to both
defaultandpre-commit, slower local gates topre-push, and every selected gate toci.pre-pushis cumulative. - Select other profiles with
ward check --profile ci,strict. - Legacy top-level
[profiles]tables are unsupported.
Unknown gate IDs, and checks with no enabled matching gates, are errors.
Mutation score minimum
Section titled “Mutation score minimum”The stryker and PIT mutation gates accept an optional minimum, an integer from 0 to 100. When
it is set and the tool succeeds, Ward reads the tool’s report and fails the gate when the mutation
score is below the minimum. See Stryker mutation score
and PIT mutation score.
[quality-gates.stryker]command = ["npx", "stryker", "run", "--reporters", "clear-text,progress,json"]minimum = 60profiles = ["ci"]minimum on any other gate, or a value that is not an integer from 0 to 100, is a configuration
error that names the key.
Partial checks
Section titled “Partial checks”An optional [quality-gates.<id>.partial] table controls how a gate responds to an edited path
passed to ward check --path:
| Key | Meaning |
|---|---|
inputs | Files the gate analyzes, as patterns relative to the project root. If an edited path matches, args can narrow the command. |
config | Files that configure the gate, as patterns relative to the project root. If an edited path matches, the gate runs its normal command. |
args | The narrowed arguments. {paths} is replaced with the edited paths as separate process arguments, or as one value joined by separator. |
item | How each path is rendered: {path} (the root-relative path) by default, or "**/{name}" for the file name. |
command | Optional. The base command a narrowed check runs, with args appended, instead of the gate’s command. Use it when the full command ends with a target that would still be analyzed, such as prettier --check .. |
[quality-gates.checkstyle.partial]inputs = ["src/**/*.java"]config = ["config/checkstyle.xml", "pom.xml"]args = ["-Dcheckstyle.includes={paths}"]item = "**/{name}"separator = ","
[quality-gates.semgrep.partial]inputs = ["**"]config = [".semgrep.yml", ".semgrepignore"]args = ["{paths}"]
[quality-gates.prettier.partial]inputs = ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.mjs"]config = [".prettierrc*", "package.json"]args = ["{paths}"]command = ["npx", "prettier", "--check"]For example, a Maven Checkstyle edit of src/main/java/acme/Order.java receives
-Dcheckstyle.includes=**/Order.java; a Semgrep edit receives the root-relative path as its own
argument. A Prettier edit of src/app.ts runs npx prettier --check src/app.ts instead of
npx prettier --check .. Other args entries are appended unchanged, and nothing passes through a
shell.
- A
configmatch wins over aninputsmatch, and a gate withoutargsruns in full when an edited path matches itsinputs. - A deleted file counts as an edit of the gate, but is not passed in
{paths}. When every relevant edit is a deletion, the gate runs in full. - Paths outside the project root are ignored. A gate without
partialalways runs in full. argsrequiresinputs,commandrequiresargs, every list must contain non-blank strings, anditemmust contain{path}or{name}. Otherwiseward checkexits with code2.
Verify custom arguments with the real tool: a path format the tool does not understand can analyze
no files and pass. Only checks with --path read these tables.
Security: commands are trusted executable code and run with the current user’s privileges in
the project root. Review ward.toml as carefully as a build script; do not run checks on
untrusted repositories outside a sandbox. See security.
OpenSpec registrations are optional and independent. Use openspec for strict active validation and
openspec-archived for completed-task validation. A configured local executable is resolved from the
target project root and is never silently replaced by a PATH executable. An OpenSpec gate may set
root, a path relative to the project root such as "../..", to run from the directory that holds
openspec/; see OpenSpec tool validations.