Backend Java
Java services, APIs and workers (Spring, JPA, JDBC, reactive) with declared boundaries, explicit failures, owned resources, safe inputs, consistent transactions and evidenced completion. Rule IDs JB01–JB68; NEED TO blocks on demonstrated violations.
Set this profile
ccpp cpo profile set backend-javaInside Claude Code, prefix the command with ! to run it in the session. Downloading a profile needs a Builder or Team plan; listing them does not.
Policies
65 policies, grouped by what they guard.
Secrets & private data 3
Credentials, keys and personal data stay out of files, logs, commands and the conversation.
jb47-config-credentialsJB47 · Spring configuration files reference secrets through placeholders instead of literal passwords, tokens or keys
jb47-hardcoded-credentialsJB47 · Credential-named constants and variables are not initialized with literal values
jb47-sensitive-loggingJB47 · Logs never receive passwords, tokens, keys, authorization headers or card data
Authentication & authorization 2
Who may do what, from roles, privileges and permissions to CSRF, CORS and verified tokens.
jb32-security-bypassJB32 · The user approves broad permit-all rules, disabled CSRF or headers, ignored paths and credentialed wildcard CORS
jb32-security-configJB32 · The user approves configuration that exposes every actuator endpoint or turns security off
Untrusted input 6
Requests, downloads and tool output are validated before they reach SQL, a shell, eval or a deserializer.
jb29-unvalidated-request-bodyJB29 · Request bodies and bound forms are validated (@Valid/@Validated) before they reach the service
jb30-entity-request-bodyJB30 · A request body bound directly to a JPA entity is flagged for an explicit input contract (entity from jdtls)
jb30-mass-assignmentJB30 · Request data is not copied wholesale onto entities (copyProperties, readerForUpdating, map-into-entity)
jb36-sql-concatenationJB36 · The user confirms SQL text built by concatenating or formatting non-constant values
jb46-xml-external-entitiesJB46 · XML parsers and transformers disable DTDs and external entities in the class that creates them
jb48-unsafe-sinksJB48 · Shell commands, expressions, deserialization, paths and URLs are not built from request data or untyped strings
Network & TLS 1
Outbound data, verified certificates, destinations taken from requests and services exposed to others.
jb32-trust-all-tlsJB32 · TLS certificate and hostname verification is never disabled (trust-all managers, allow-all verifiers)
Weakened checks 2
Suppressions, disabled lint or CI steps and relaxed strictness need a reason or the user's approval.
jb10-suppressionsJB10 · Suppressions are scoped to the smallest element and name their reason (no class-wide or blanket suppression)
jb66-weakened-checksJB66 · The user authorizes build or CI changes that skip tests or analysis, ignore failures or drop a check
Type safety 3
No escapes from the type checker (any, unchecked casts, non-null assertions) and explicit contracts.
jb11-raw-types-unchecked-castsJB11 · No new raw generic types or unchecked generic casts in application logic
jb13-null-contractJB13 · Methods declared to return Optional or a non-null value never return null
jb14-null-collectionsJB14 · Methods returning collections, streams or arrays return an empty value for "no results", not null
Error handling 4
Failures are propagated or handled, never swallowed or turned into fake success.
jb23-swallowed-failuresJB23 · A catch block never swallows a failure silently nor reports success after it
jb24-broad-catchJB24 · Catching Exception, Throwable or Error is a boundary handler that logs or rethrows
jb25-exception-causeJB25 · An exception translated in a catch block keeps the caught one as its cause
jb28-log-and-rethrowJB28 · A failure is logged once at its owning boundary, not logged and rethrown at every layer
Async & concurrency 8
Owned tasks, awaited promises, preserved cancellation and no blocking on event loops.
jb26-interruptionJB26 · A caught InterruptedException is propagated or the interrupt flag is restored
jb49-singleton-request-stateJB49 · Singleton beans do not keep request-specific mutable state in fields
jb50-unsafe-publicationJB50 · Lazily initialized shared fields are safely published (no double-checked locking without volatile, no shared DateFormat)
jb51-discarded-async-typedJB51 · A call returning a Future, CompletableFuture, Mono or Flux is not discarded by a statement (type from jdtls)
jb51-discarded-futuresJB51 · Asynchronous work started by a statement has an owner for its failure (no discarded runAsync, submit or then* chain)
jb52-unowned-executorsJB52 · Executors and threads have an owner, a capacity policy and a shutdown lifecycle (not created per call)
jb53-blocking-in-reactiveJB53 · Reactive methods (Mono/Flux) do not block (block(), Thread.sleep, JDBC) without explicit offloading
jb54-async-contextJB54 · Work started on another thread does not assume the caller's transaction or security context
Performance & resource bounds 6
Timeouts, bounded retries and fan-out, reused clients, closed resources, no N+1 queries.
jb27-unclosed-resourcesJB27 · Owned streams, files, sockets, connections and statements are closed on every path (try-with-resources)
jb35-unbounded-readsJB35 · Externally triggered reads are bounded (pagination or limits), not repository findAll()
jb41-queries-in-loopsJB41 · Repository and remote fetches are batched, not issued once per item of a loop
jb43-client-timeoutsJB43 · HTTP clients and requests are built with finite connect and read deadlines
jb44-unbounded-retriesJB44 · Retries are bounded (attempts or deadline); no infinite retry loop or retry() without limit
jb45-http-responsesJB45 · Owned HTTP responses (OkHttp, Apache, JAX-RS, streamed JDK bodies) are closed on every path
Architecture & boundaries 4
Declared layers and dependency directions, no import cycles, small modules, explicit dependencies.
jb01-dependency-mapJB01 · Imports respect the project's declared dependency map (off until dependencyRules is set)
jb04-field-injectionJB04 · Required services are injected through the constructor into final fields, not by field or setter injection
jb05-context-lookupJB05 · Application-context lookups and service locators stay in composition and infrastructure code
jb21-wall-clockJB21 · Business logic reads the current time from an injected Clock, not from the system clock
Language idioms 8
The conventions of the language that keep code predictable for its readers.
jb16-mutable-record-componentsJB16 · Records holding collections, arrays or Dates copy them defensively instead of exposing mutable internals
jb17-equals-hashcodeJB17 · A class that overrides equals also overrides hashCode with a compatible definition
jb18-reference-equalityJB18 · Strings and boxed values are compared with equals, not == or !=
jb18-typed-reference-equalityJB18 · Variables typed as strings, boxed numbers, BigDecimal, java.time or UUID values are not compared with == (types from jdtls)
jb19-ignored-results-typedJB19 · Arithmetic on BigDecimal, BigInteger, String or java.time values is not discarded (receiver type from jdtls)
jb19-ignored-resultsJB19 · Results of pure methods (String, java.time, BigDecimal scaling, unterminated streams) are used, not discarded
jb20-default-charsetJB20 · Byte/text conversions name their charset instead of relying on the platform default
jb22-numeric-precisionJB22 · Money and exact quantities keep their precision (no BigDecimal from double, no unbounded divide, no float money)
HTTP & APIs 2
Request and response contracts, schemas, status codes, error bodies and published API surfaces.
jb33-error-configJB33 · Spring Boot configuration does not include stack traces, exception names or messages in error responses
jb33-error-details-exposedJB33 · Exception messages and stack traces are not written into HTTP responses
Databases & queries 4
Schemas, queries, transactions and the ORM used as intended.
jb37-multi-write-transactionJB37 · A method with several repository writes is transactional or states its consistency protocol
jb38-transaction-self-invocationJB38 · A @Transactional method is not called on this from a non-transactional method of the same class (proxy bypass)
jb39-rollback-checked-exceptionsJB39 · A @Transactional method that throws checked exceptions declares its rollback rules
jb40-remote-io-in-transactionJB40 · Remote calls, messaging and sleeps do not run while a database transaction is held open
Schema migrations 1
Migrations come from the tool, applied history stays immutable and risky changes are rolled out safely.
jb42-entity-without-migrationJB42 · A persisted entity change ends the turn with a Flyway or Liquibase migration (projects with db/migration or db/changelog)
Logging & observability 1
Structured logs, bounded metric labels, no debug prints left in production code.
jb55-console-outputJB55 · Production code reports through the logging system, not System.out/err or printStackTrace
Dependencies & toolchain 1
Packages change through the package manager, lockfiles stay consistent and the project's tools are used.
jb64-dependency-versionsJB64 · Build files pin dependencies (no dynamic, range, LATEST/RELEASE or SNAPSHOT versions)
Tests 4
Tests assert behavior, stay deterministic and are not removed or skipped silently.
jb10-disabled-testsJB10 · Disabled tests say why (@Disabled("reason")); tests are not skipped silently
jb58-test-assertionsJB58 · Tests assert an outcome or a specified interaction; assertions are not tautologies
jb61-test-determinismJB61 · Routine tests do not sleep for fixed durations or call public network hosts
Completion evidence 5
A turn ends with its checks run and passing; claims of success need proof after the last edit.
jb-turn-baselineRecords the work tree when a prompt starts, the baseline of the end-of-turn checks (JB56, JB42)
jb09-placeholdersJB09 · Production code ships implemented behavior, not TODO throws, stub returns or empty TODO bodies
jb56-new-compile-errorsJB56 · Claude does not end a turn with compiler errors it introduced in Java sources or their dependents (jdtls)
jb66-completion-claimsJB66 · A final message claiming a passing build or tests needs a successful run after Claude's last edit
jb66-evidence-ledgerJB66 · Records, per session, Claude's edits and the build or test runs (Maven, Gradle) that succeeded after them