AGENTS.md | Instructions both Claude Code and Codex read. Says that done means ./mvnw verify passed, and how to fix each gate |
CLAUDE.md | Imports AGENTS.md for Claude Code versions that don't read it directly |
REVIEW.md | At the repository root, for reviewers: the failures the code doesn't show, which changes are high risk, what not to report, and how to report. The code-reviewer skill and Claude Code's GitHub review read it. Added only when missing; the team fills in the failures, one line each time a review misses a bug |
.claude/settings.json | Lets ./mvnw run without prompts, blocks reading .env files, enables this plugin for every teammate with this marketplace set to update itself, and registers the hooks. For the other skills the team uses, each developer runs install.py from this marketplace once |
.claude/hooks/verify-on-stop.sh | SessionStart and Stop hook. It records the code each session starts from. When a turn ends and the session has changed the code under src or pom.xml, committed or not, it formats the code and runs the gates that need no Docker (compile with NullAway, CodeRulesTests, ConfigurationKeysTests, BuildSetupTests, the module and ArchUnit tests). It blocks the turn only on errors in files the session changed, so Claude fixes its own mistakes and never code it didn't touch; when the build fails only elsewhere, it tells the user the change couldn't be fully verified. A formatting failure blocks too. It skips code that already passed, and gives up after one failed retry on the same code. A session that changes no code costs nothing; a check takes 25 to 75 s |
.claude/hooks/guard.sh | PreToolUse hook. Refuses git push --force, git reset --hard, git clean -f, edits to a Flyway migration that is already on the main branch, edits to the ArchUnit freeze record, and edits to the rule tests (CodeRulesTests, ConfigurationKeysTests, BuildSetupTests, ModuleBoundariesTests, and progen's ArchUnitTests and ModularityTests). A developer changes a rule by hand |
scripts/report.py | Summarises what the hooks did in this clone: turns checked, passed and blocked, blocks by gate, how many the agent fixed, check times, and what the guard refused. Both hooks append one line per run to .git/harness/events.jsonl (no paths, commands or file contents; capped at 2000 lines). Run python3 ${CLAUDE_SKILL_DIR}/scripts/report.py . when the team asks whether the hooks are worth their time |
scripts/baseline.py | For an existing codebase: marks the classes NullAway rejects today @NullUnmarked and records today's CodeRulesTests violations, so verify passes while new code is held to the gates |
ConfigurationKeysTests | Fails on spring., management., server. and logging. keys that no dependency defines, or that are deprecated. Boot ignores those keys silently |
BuildSetupTests | Fails on shortcuts that pass the tests while production runs without the feature: a Boot starter or module in test scope, spring-boot-autoconfigure-classic, Flyway migrations without spring-boot-starter-flyway (Boot 4 doesn't run them with flyway-core alone), unless the app builds Flyway itself, and, when the project has migrations, ddl-auto set to create or update the schema or code that writes flyway_schema_history |
UnusedCodeTests | Fails on a non-private method that only tests call: dead code its tests keep alive, or an internal opened up so a test can look inside. Getters, Spring entry points, overrides and methods named in @PreAuthorize expressions are left out. It runs in verify but not in the Stop hook, because a service is often written and tested before anything calls it |
ModuleBoundariesTests | Spring Modulith verify(): no use of another module's nested packages, no cycles |
CodeRulesTests | ArchUnit rules for mistakes that compile and pass most tests: a class calling its own @Transactional, @Async, @Cacheable or @Retryable method (the proxy is skipped), controllers that start transactions, use repositories, or take or return JPA entities, @Retryable or @ConcurrencyLimit with nothing switching them on, @ManyToMany fields that aren't a Set (with a List, removing one element rewrites every join row), @ManyToOne and @OneToOne without fetch = LAZY, enum columns stored by position, a @Transactional method calling an HTTP client, an HTTP interface or an AWS SDK client, directly or through the project's own classes (it holds a database connection for the whole call), RestClient.create(), WebClient.create(), new RestTemplate(), or the static builder() in a class that sets no request factory (no timeouts), proxy annotations on private, final or static methods, @Async or @Scheduled with nothing switching them on, services that throw ResponseStatusException, use the servlet API or return ResponseEntity, @Deprecated code outside controllers (update the callers and delete it), @Autowired fields, System.out, Jackson 2 (Boot 4 ignores it), Spring's deprecated nullness annotations, JUnit 4 tests (never run), and @Disabled tests. Each failure message says how to fix it. It uses the project's ArchUnit or Taikai, and adds ArchUnit only when neither is declared |
.github/workflows/verify.yml | Runs ./mvnw verify on every pull request, so the gates hold for code nobody ran locally. Added only when no workflow already runs mvnw |
| pom gates | NullAway in JSpecify mode on main code at compile time (tests are excluded, since they routinely dereference response bodies), Spotless check |
| Project skills | add-module (module layout and test, for module-based projects) and db-migration (Flyway naming and safe changes, when the pom uses Flyway). Each tool sees only their names and descriptions until one is used |