Skip to content

How it works

Four nested shields around your code: Edit, Commit, Push, and CI. Faster checks sit close to the code, stricter ones further out.

AI coding agents write code faster than anyone can review it. Without guardrails, you repeat the same rules in every prompt, and the agent still forgets some of them. Ward keeps those rules in the repository and checks them at four moments, so the agent gets precise feedback early and nothing it missed reaches production.

Each layer is a profile in ward.toml. Inner layers are fast so they can run constantly; outer layers are stricter and slower.

LayerProfileWhen it runsSet up with
1. EditdefaultAfter every agent edit or writeward init --integration <agent> or ward integrate
2. Commitpre-commitBefore each git commitward init --quality-hooks
3. Pushpre-pushBefore each git pushward init --quality-hooks
4. CIciIn your CI pipelineward init --ci github or the CI/CD guide

After the agent edits or writes a file, its hook runs ward check on the edited files and returns the result to the agent. A failure includes the file, line, and rule, so the agent can fix it in the same turn without you explaining the rule. Only fast checks belong here, such as formatting, Checkstyle, and PMD. See Claude Code, OpenCode, and other agents.

The pre-commit hook runs the same fast checks on the staged files, including a secret scan of those files. It catches what the edit layer can’t see: files changed outside the agent, by a person, or by a tool. See quality hooks.

The pre-push hook adds slower local checks before code leaves your machine: compilation, tests, coverage, SpotBugs, and, with the strict preset, ArchUnit architecture rules and Maven Enforcer.

CI runs every configured gate, including slow ones such as PIT mutation testing and the ones that need network access, a running application, or a baseline, such as Trivy, Semgrep, OWASP Dependency-Check, SonarQube, and OWASP ZAP. This is the last check before production.

ward init puts each gate in the first layer it fits and in every layer after it, so the outer layers always include the inner ones. The bare ward check runs the same checks as pre-commit. To move a gate, edit its profiles list:

[quality-gates.spotbugs]
command = "./mvnw spotbugs:check"
profiles = ["pre-push", "ci"] # not on every edit or commit
  • The project explains the rules, not you. The agent learns about a broken rule from a failing check, at the moment it breaks it, instead of from a long prompt.
  • Mistakes are fixed while they are small. A finding on the edited file is cheaper to fix than a failed review or CI run hours later.
  • Repeated mistakes become rules. With learning, a recurring finding asks the agent to write a preventive rule in AGENTS.md.

The agent skills let your coding agent set up the layers with you: ward-init chooses the preset, gates, agent integration, and Git hooks for the project, ward-tune fits the rules to your real code, and ward-fix fixes the code until the gates pass.

Commit ward.toml, the rule files under config/, the generated agent hooks (such as .claude/ or .opencode/), and, if you generate it, AGENTS.md. Every teammate and every agent then works with the same rules. The commit and push hooks live in .git/hooks/, which Git doesn’t share; a one-step setup for teammates is planned.