ccppccpp home

Profiles

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-java

Inside 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-credentials

    JB47 · Spring configuration files reference secrets through placeholders instead of literal passwords, tokens or keys

  • jb47-hardcoded-credentials

    JB47 · Credential-named constants and variables are not initialized with literal values

  • jb47-sensitive-logging

    JB47 · 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-bypass

    JB32 · The user approves broad permit-all rules, disabled CSRF or headers, ignored paths and credentialed wildcard CORS

  • jb32-security-config

    JB32 · 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-body

    JB29 · Request bodies and bound forms are validated (@Valid/@Validated) before they reach the service

  • jb30-entity-request-body

    JB30 · A request body bound directly to a JPA entity is flagged for an explicit input contract (entity from jdtls)

  • jb30-mass-assignment

    JB30 · Request data is not copied wholesale onto entities (copyProperties, readerForUpdating, map-into-entity)

  • jb36-sql-concatenation

    JB36 · The user confirms SQL text built by concatenating or formatting non-constant values

  • jb46-xml-external-entities

    JB46 · XML parsers and transformers disable DTDs and external entities in the class that creates them

  • jb48-unsafe-sinks

    JB48 · 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-tls

    JB32 · 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-suppressions

    JB10 · Suppressions are scoped to the smallest element and name their reason (no class-wide or blanket suppression)

  • jb66-weakened-checks

    JB66 · 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-casts

    JB11 · No new raw generic types or unchecked generic casts in application logic

  • jb13-null-contract

    JB13 · Methods declared to return Optional or a non-null value never return null

  • jb14-null-collections

    JB14 · 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-failures

    JB23 · A catch block never swallows a failure silently nor reports success after it

  • jb24-broad-catch

    JB24 · Catching Exception, Throwable or Error is a boundary handler that logs or rethrows

  • jb25-exception-cause

    JB25 · An exception translated in a catch block keeps the caught one as its cause

  • jb28-log-and-rethrow

    JB28 · 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-interruption

    JB26 · A caught InterruptedException is propagated or the interrupt flag is restored

  • jb49-singleton-request-state

    JB49 · Singleton beans do not keep request-specific mutable state in fields

  • jb50-unsafe-publication

    JB50 · Lazily initialized shared fields are safely published (no double-checked locking without volatile, no shared DateFormat)

  • jb51-discarded-async-typed

    JB51 · A call returning a Future, CompletableFuture, Mono or Flux is not discarded by a statement (type from jdtls)

  • jb51-discarded-futures

    JB51 · Asynchronous work started by a statement has an owner for its failure (no discarded runAsync, submit or then* chain)

  • jb52-unowned-executors

    JB52 · Executors and threads have an owner, a capacity policy and a shutdown lifecycle (not created per call)

  • jb53-blocking-in-reactive

    JB53 · Reactive methods (Mono/Flux) do not block (block(), Thread.sleep, JDBC) without explicit offloading

  • jb54-async-context

    JB54 · 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-resources

    JB27 · Owned streams, files, sockets, connections and statements are closed on every path (try-with-resources)

  • jb35-unbounded-reads

    JB35 · Externally triggered reads are bounded (pagination or limits), not repository findAll()

  • jb41-queries-in-loops

    JB41 · Repository and remote fetches are batched, not issued once per item of a loop

  • jb43-client-timeouts

    JB43 · HTTP clients and requests are built with finite connect and read deadlines

  • jb44-unbounded-retries

    JB44 · Retries are bounded (attempts or deadline); no infinite retry loop or retry() without limit

  • jb45-http-responses

    JB45 · 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-map

    JB01 · Imports respect the project's declared dependency map (off until dependencyRules is set)

  • jb04-field-injection

    JB04 · Required services are injected through the constructor into final fields, not by field or setter injection

  • jb05-context-lookup

    JB05 · Application-context lookups and service locators stay in composition and infrastructure code

  • jb21-wall-clock

    JB21 · 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-components

    JB16 · Records holding collections, arrays or Dates copy them defensively instead of exposing mutable internals

  • jb17-equals-hashcode

    JB17 · A class that overrides equals also overrides hashCode with a compatible definition

  • jb18-reference-equality

    JB18 · Strings and boxed values are compared with equals, not == or !=

  • jb18-typed-reference-equality

    JB18 · Variables typed as strings, boxed numbers, BigDecimal, java.time or UUID values are not compared with == (types from jdtls)

  • jb19-ignored-results-typed

    JB19 · Arithmetic on BigDecimal, BigInteger, String or java.time values is not discarded (receiver type from jdtls)

  • jb19-ignored-results

    JB19 · Results of pure methods (String, java.time, BigDecimal scaling, unterminated streams) are used, not discarded

  • jb20-default-charset

    JB20 · Byte/text conversions name their charset instead of relying on the platform default

  • jb22-numeric-precision

    JB22 · 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-config

    JB33 · Spring Boot configuration does not include stack traces, exception names or messages in error responses

  • jb33-error-details-exposed

    JB33 · 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-transaction

    JB37 · A method with several repository writes is transactional or states its consistency protocol

  • jb38-transaction-self-invocation

    JB38 · A @Transactional method is not called on this from a non-transactional method of the same class (proxy bypass)

  • jb39-rollback-checked-exceptions

    JB39 · A @Transactional method that throws checked exceptions declares its rollback rules

  • jb40-remote-io-in-transaction

    JB40 · 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-migration

    JB42 · 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-output

    JB55 · 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-versions

    JB64 · 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-tests

    JB10 · Disabled tests say why (@Disabled("reason")); tests are not skipped silently

  • jb58-test-assertions

    JB58 · Tests assert an outcome or a specified interaction; assertions are not tautologies

  • jb61-test-determinism

    JB61 · Routine tests do not sleep for fixed durations or call public network hosts

  • jb62-shared-test-state

    JB62 · Test classes do not share mutable static state between tests

Completion evidence 5

A turn ends with its checks run and passing; claims of success need proof after the last edit.

  • jb-turn-baseline

    Records the work tree when a prompt starts, the baseline of the end-of-turn checks (JB56, JB42)

  • jb09-placeholders

    JB09 · Production code ships implemented behavior, not TODO throws, stub returns or empty TODO bodies

  • jb56-new-compile-errors

    JB56 · Claude does not end a turn with compiler errors it introduced in Java sources or their dependents (jdtls)

  • jb66-completion-claims

    JB66 · A final message claiming a passing build or tests needs a successful run after Claude's last edit

  • jb66-evidence-ledger

    JB66 · Records, per session, Claude's edits and the build or test runs (Maven, Gradle) that succeeded after them