agentleFS
ice-lfernandesice-lfernandes/claude-spring-architect/CLAUDE.md

claude-spring-architect

CLAUDE.md11 starsChanged 5 days agoApache-2.0View on GitHub

Meta-repository: generates Spring Boot projects already prepared for AI-assisted development. It is not a Java application — it has no pom.xml, does not compile, has no Maven tests. What gets edited here are instruction files, data, and a hook. Purpose, features and status: @README.md. java (JDK 21+) · git · curl. Nothing else. Zero Python, zero shell, zero mvn on PATH — the wrapper comes in the Initializr's starter.tgz. The mods under .claude/mods/ run inside Claude Code itself; only the…

1 other project uses a version of this.

Adopted by

Most recently taken up by

The file

We split this CLAUDE.md into the rules it gives an agent

1 rule. About 0 are common, 0 are distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈0

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Every silent trap — the runtime's and this repository's: write territories, frozen spec folders, who owns pom.xml and the outbox, what …

    line 196

≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
CLAUDE.md

Nerviz

Meta-repository: generates Spring Boot projects already prepared for AI-assisted development. It is not a Java application — it has no pom.xml, does not compile, has no Maven tests. What gets edited here are instruction files, data, and a hook.

Purpose, features and status: @README.md.

Dependencies

java (JDK 21+) · git · curl. Nothing else. Zero Python, zero shell, zero mvn on PATH — the wrapper comes in the Initializr's starter.tgz. The mods under .claude/mods/ run inside Claude Code itself; only the mods CI workflow installs anything else (the Claude CLI, from npm, to test them). Node (from npm, pinned by the skill's lockfile) is needed only for /nerviz-diagrams's PNG/video export, in this repository only; everything else, including the CI gate, stays Java.

Commands

ActionCommand
Diagnose the setup on this machine/arch-doctor
Create a project from a blueprint/init-project
Design a new extension of this .claude//claude-code-architect-designer
Run the hook by handjava .claude/hooks/ArchHook.java doctor
The same report as a CI gate — exit 1 when a line doctor.gate.labels lists is red (boundary rules, a source file importing or naming what its module forbids, schema, hook jar, hook registrations, .mcp.json, audit overrides); runner state never gates. The generated project's architectural boundaries job runs itjava .claude/hooks/ArchHook.java doctor gate
Check a spec's implementation checklist against the blocks it carries — what is missing or extra by id; the guard applies the same check when a spec is approvedjava .claude/hooks/ArchHook.java spec check <spec-or-folder>
Check one file against the architectural boundary by hand — exit 2 on a forbidden import or a qualified name written with none, 1 when the path is no .java file, never a read of stdinjava .claude/hooks/ArchHook.java check <path>
Check every compose service is up, no foreign container holds its ports (a warning, never a block, while no container of the project is outside exited or dead), a service stopped on purpose a block the project can turn into a warning with {"exited":"warn"} in .claude/compose-gate.json, every published port is advertised at a host-resolvable address, and every ${VAR:default} pointing at a service holds on the host and in the app container — plus a warning, never a block, when the datasource's database or user disagrees with the database service it reaches, or has no password where the service requires onejava .claude/hooks/ArchHook.java compose
Check which paths a shell command would write, and whether the guard admits them — and whether it is a force push, which it blocksecho '{"tool_input":{"command":"…"}}' | java .claude/hooks/ArchHook.java guard bash
Sweep what the current turn wrote and no tool-time guard admitted against the open phase's territory and the frozen folders — the audit trail exceptedecho '{}' | java .claude/hooks/ArchHook.java guard sweep
Print the open skill phase — its skills, class and write territory — as one JSON line; read-only, what the nerviz-cockpit mod drawsecho '{"session_id":"…"}' | java .claude/hooks/ArchHook.java guard status
The compose check as a gate — silent while healthy, exit 2 otherwiseecho '{}' | java .claude/hooks/ArchHook.java compose gate
Show what an agent receives at SubagentStart — the pattern catalog, or nothingecho '{"agent_type":"java-spring-boot-developer"}' | java .claude/hooks/ArchHook.java context subagent
Render the execution trail of a run by handjava .claude/hooks/ArchHook.java audit flush
Fill a generated project's GENESIS.md — Started, Finished and tokens — from this session's transcripts; /init-project runs it, oncejava .claude/hooks/ArchHook.java audit genesis <project> <session-id>
Write a target project's .claude/ from this one, transformed for a blueprint — exit 2, nothing written, when the destination's build declares a Spring Boot line below doctor.platform.min_line of extensions.json (/platform-upgrade is the way up); doctor reports the same line as Platform, never gatedjava .claude/hooks/ArchHook.java export <dest> --blueprint <id> [--ref <label>] [--commit <sha>] [--dry-run]
Write the OpenRewrite recipe that takes a project below the Spring Boot floor to it — --pass bump the version bump, the coordinate and type renames of doctor.platform.upgrade, the starter a used type now needs (requires_starter), the removal of the version a renamed or added coordinate carried, and — with --initializr, the metadata the Initializr serves for the target — each BOM and versioned library it lists; --pass properties the property renames the resolved jars declare as errors with a replacement; exit 2, nothing written, on a target below the floor, a project already at it, an Initializr file for another Boot version, or a data entry it cannot spell. platform-upgrade runs it; CLAUDE_PROJECT_DIR names the source holding the dataCLAUDE_PROJECT_DIR=<source> java -jar <source>/.claude/hooks/ArchHook.jar upgrade-recipe <project> --pass bump --target <x.y.z> --initializr <file> --out <file>
Record every test case of a build's JUnit XML reports, and compare a later run against it — a test that passed and now fails or is gone, or a failure the baseline never saw, exits 2; a failure that was already there does not; no report at all exits 2 too, since a build that ran no tests is not a pass. platform-upgrade runs it before the bump and after (doctor.platform.upgrade.test_reports holds the globs)CLAUDE_PROJECT_DIR=<source> java -jar <source>/.claude/hooks/ArchHook.jar test-diff snapshot <project> --out <file> · … test-diff compare <project> --baseline <file>
Read what a build left: the totals of the JUnit XML reports and the JaCoCo coverage (Maven and Gradle layouts, doctor.platform.upgrade.test_reports and build_report of extensions.json), the failed tests with their first lines, and — when none failed and --log is given — the log's error lines; --newer <file> ignores a report older than that file. A reader: exit 0 whenever it printed, exit 2 on a usage error or a report it cannot parse. The java-spring-boot-developer agent runs it after every test runjava -jar .claude/hooks/ArchHook.jar build-report <project> [--log <file>] [--newer <file>]
Write a generated project's .claude/forbidden-imports.txt from a blueprint — a multi-module blueprint's forbidden_imports per module, a single-module one's dependency_rules derived per package (boundary_map of extensions.json holds the framework roots); exit 2, nothing written, when the blueprint yields no rule. project-bootstrap § 5 runs itjava .claude/hooks/ArchHook.java boundary-map <dest> --blueprint <id> --package <base.package>
Validate frontmatter of all extension files (a skill named after a native command, a rule without paths, anything a strict YAML parser refuses), .mcp.json, every hook registration in settings.json and in project-bootstrap's template, every !`…` injection's paths, and the export manifest against what is on diskjava .claude/hooks/ArchHook.java schema
List what a generated project configures in its own .claude/ — every file of project_config in extensions.json, each key with its values, default, current value and what doctor says — as one JSON line; or change one: set builds the file as it would be, runs the validator doctor runs, and writes nothing on a problem (exit 2); unset restores a default and deletes a file left empty. The only writer of those files: guard refuses a tool's direct write and names this commandjava .claude/hooks/ArchHook.java config [list] · … config set <id> <key> <value> · … config unset <id> <key>
Reduce a spike worktree's .claude/settings.json to the hooks spike.keep_modes lists (audit) and mark it skip-worktree — exit 2, nothing written, on a path that is no directory, the main checkout, this project's own root, or a worktree with no .claude/settings.json; idempotent. The spike skill runs itjava .claude/hooks/ArchHook.java spike <worktree>
What this .claude/ puts in context — every session (root CLAUDE.md and its imports, rules without paths, skill and agent listing, MCP servers), per skill, agent and rule once loaded, and hook spawns per event — as markdown; over marks a number past footprint.limits, never an exit code. harness-lessons injects itjava .claude/hooks/ArchHook.java footprint
Rebuild .claude/hooks/ArchHook.jar — what every hook launches — from the source, under the JDK hook_build.javac_feature pinsjava .claude/hooks/ArchHook.java build
Check the committed jar is byte for byte what the source compiles to (CI runs it)java .claude/hooks/ArchHook.java build --verify
Check the committed diagrams under docs/diagrams/ equal a fresh render of the data they cite (CI runs it)java .claude/skills/nerviz-diagrams/scripts/Diagrams.java check
List and inspect this repo's MCP serversclaude mcp list · /mcp

Architecture of the AI files

Clean Architecture applied to .claude/ itself. Dependencies point in one direction:

mods/                       interface — draws what hooks/ decide, only where it loads
        ↓ asks (java -jar ArchHook.jar), never restates
hooks/ + settings.json      infra/enforcement — deterministic
        ↓ verifies
skills/                     procedure + exemplars
        ↓ invokes                    ↑ delegates via context: fork
agents/                     isolated execution
        ↓ cites, never copies
rules/ + blueprints/ + .mcp.json   norms and data   ← LEAF

decisions/                  history — nobody reads it at runtime, outside the graph

claude-code-architect-designer writes upward into hooks/ + settings.json after approval — a design-time edge, like project-bootstrap writing src/; the runtime direction is unchanged.

Invariants (non-negotiable)

  1. rules/ is a leaf. A norm never mentions a skill, an agent, or a command. If it needs to, it's a procedure and belongs in a skill.
  2. Each norm has a single owning file. Others cite it by path (@.claude/rules/naming.md). A norm written in two places has diverged — that's a bug.
  3. Code boilerplate lives in templates/ inside the skill that emits it, with the .example suffix. Never inside a norm, never pasted into the body of a SKILL.md.
  4. No new commands/ are created. Slash commands were merged into skills: write skills/<name>/SKILL.md and control invocation with disable-model-invocation.
  5. An agent exists only for one of three reasons: preserving context, restricting tools, or changing model. If none applies, it's a skill.
  6. If a rule must always hold, it's a hook or permissions.deny — not prose in markdown. Owner: claude-code-architect-designer, forms 7 and 8, after approval and always with a record in decisions/. The mirror holds too — a hook against a failure nobody observed is a process per event confirming what was already true.
  7. Architectures are data. Adding a blueprint must never require editing a skill, an agent, or a command.
  8. Java and Spring Boot versions are never written from memory. They are resolved at runtime via Spring Initializr; without network access, ask.
  9. The generated project is self-contained. Whoever clones it does not have Nerviz. Everything cited from inside the project must exist inside the project: norms, development skills, agents, ArchHook.java and schemas/extensions.json. ArchHook.java export writes all of it (step 6.6 of project-bootstrap), and what travels is data, in the export block of @.claude/schemas/extensions.json — creation skills excluded on purpose, and the blueprint catalog too, with one exception the manifest names: the active blueprint travels (export.blueprint_copy), because the stamp records its id, an update has to resolve it, and a blueprint written during adoption exists nowhere else. A new norm, skill or agent is complete once that block lists it: every skill and agent on disk in include or exclude, a derived_paths entry for a rule with a package territory, and ArchHook.java schema failing by name on either gap. An MCP server has the same obligation, per server, not per file: it is declared for this meta-repo (.mcp.json), for the generated project (project-bootstrap/templates/mcp.json.example, copied by export.optional_copy), or both — and the file it's written into is that declaration. A server useful to both is written in both files on purpose; that is not a duplication bug, see invariant 2. A hook, the same: the registration is per file (.claude/settings.json, project-bootstrap/templates/settings.json.example); a mode inside ArchHook.java needs nothing, the export mode copies that file whole. A skill has a second obligation on top of export: a class in skill_classes, which is what gives it a body shape and a write territory. A skill in no class has no territory — schema fails by name on it, in this repo and inside a generated project. An agent has the same second obligation, in agent_classes: its class fixes the sections its body carries, the frontmatter fields it must declare (model and tools always — two of the three reasons it is allowed to exist), whether it may write at all (executor), and the paths it may write. Territory there is keyed on agent_type, so it holds no matter which skill phase the caller left open.
  10. Recognized frontmatter fields, .mcp.json's server fields, and settings.json's hook events and entry fields are data with a single owner. The list lives in .claude/schemas/extensions.json, ArchHook.java schema is what reads it, and any other file that displays it is derived and must match it exactly. A corollary of 2 and 7, written separately because its failure mode is silent: the runtime ignores an unknown field without any error — an unknown event too, and a matcher on an event that never reads one — and claude plugin validate lets it all through, looking at neither .mcp.json nor settings.json. Binds the Java too: a mode reads its lists from extensions.json, never from a constant in the source.
  11. No literal secret in a versioned file. .mcp.json (this repo's or the copy inside a generated project) carries only ${VAR} / ${VAR:-default} expansion, oauth, or headersHelper — never a token, key, or password spelled out. Verified by ArchHook.java schema's secret scan over headers/env. A leaked token in git history is irreversible; that is why this is a hook and not a review checklist.

Routing — when X, read Y

If the task involvesGo to
Creating a project from scratchskill project-bootstrap
Creating a project with the plugin and no clone of this repositoryskill new-project — manual only, the plugin's /nerviz:new-project, run in the directory that will hold the projects. Fetches the latest tag into nerviz-<tag>/ through arch-adopt § 2-3, writes the source.fetch_marker file export stamps from, and hands over to an unchanged /init-project in a session opened there. Never generates in its own session, never travels (@.claude/decisions/0163-create-project-from-the-plugin.md)
Installing this .claude/ into a project that was never generated here, or pulling a newer version into one that wasskill arch-adopt — manual only, runs inside the target project, refuses a dirty worktree, and writes through ArchHook.java export — plus the root CLAUDE.md's bounded-context line, asked when missing. On an update it ends by printing the note and prompt of every migrations entry the project has not seen — a convention change that leaves existing code behind — and never runs them. It travels into the generated project, unlike the other creation skills: that is how a project updates itself once the plugin that delivered it is gone
A project that export or /arch-adopt refused for its Spring Boot line — bringing it to doctor.platform.min_lineskill platform-upgrade — manual only (/platform-upgrade), runs inside the project, refuses a dirty worktree, never commits. Records the project's tests first (ArchHook.jar test-diff), writes the version bump, the BOMs, the renamed starters and types, the starter a used type now needs, and the renamed configuration properties through a recipe ArchHook.jar upgrade-recipe generates from doctor.platform.upgrade, the Initializr's metadata and the jars' own metadata, run by the OpenRewrite core (Apache 2.0) through the project's wrapper; fixes a Gradle wrapper the new plugin refuses; then a guided residue and a context-load run until the build is green and no test is worse than before. Ends by printing /arch-adopt. Travels into the project, and the plugin delivers it with arch-adopt (@.claude/decisions/0175-platform-upgrade-below-the-floor.md, @.claude/decisions/0176-platform-upgrade-baseline-context-and-runtime-starters.md)
Creating a skill, agent, norm, or CLAUDE.md section — and deciding which of the nineskill claude-code-architect-designer
A band above the prompt, a pane, a spinner suffix, a dialog over a tool call, a /command that spends no turn — a mod, TypeScript under .claude/mods/skill claude-code-architect-designer, Form 9 — always on top of a hook or permissions rule, never instead of one, and meta-repo only (0131). Two shipped: nerviz-cockpit — open phase and territory above the prompt, /nerviz-doctor in a pane; and nerviz-config — /nerviz-config, the project's own settings in a pane in the nerviz identity, written only through ArchHook.jar config set|unset after a dialog (@.claude/decisions/0187-project-config-registry-skill-and-mod.md). Load from Claude Code 2.1.287 on; /arch-doctor says when it does not
Creating a hook, a new ArchHook.java mode, or a permissions.allow/deny line — and deciding whether the answer is a guarantee at allskill claude-code-architect-designer, forms 7 and 8. Writes it after approval, always with a record in decisions/, and warns that settings.json is read only at startup
Designing a use case before implementing it; knowing whether a request is one or severalskill use-case-design
Aggregate, value object, invariant, ports of an already-designed use caseskill domain-modeling
Table, JPA mapping, migration, index, slow query, datasource properties — or a MongoDB collection, document mapping, its indexes and validator, @Version, a transaction on a replica set — or auditing: who created or changed a record, when, and its earlier values (stamps, an Envers history)skill persistence-architect — relational or document per the Storage row of 00-use-case.md, which the request states or one factual question records (use-case-design); no pipeline step weighs SQL against NoSQL, that interview belongs to a planned solution-design step (@.claude/decisions/0147-document-storage-and-search-architect.md). The audit level comes from the Audit row the same way, only when the request asks for it — stamps on both families, a history on relational only, the actor never null (@.claude/decisions/0149-auditing-variant-of-persistence-architect.md)
Full-text or faceted search in Elasticsearch or OpenSearch — a search index kept as a projection of a source of truth, mapping, alias and reindex, an indexer fed by change eventsskill search-architect — 23-search.md, step 3e of /new-feature, only when the Search index row of 00-use-case.md names a projection; norms in @.claude/rules/search.md, package .search. A search by meaning stays a vector store port (ai-architect); full-text inside the source's own database stays persistence-architect's
REST adapter, controller, DTO, status, OpenAPI — or an API version: a /v2, deprecating or retiring a versionskill rest-api-architect — the versioning setup (/api/v{version} prefix, supported list, deprecation headers, a per-version metric tag) is written by the project's first REST case and inherited after; a breaking change adds a mapping at the next version as its baseline. Norms in @.claude/rules/api-rest.md § Versioning (@.claude/decisions/0150-api-versioning-in-rest-api-architect.md)
A rate limit or quota per client, a concurrency cap on an endpoint, the 429 and the admission 503 — REST or GraphQLskill rest-api-architect (§ 8 of 30-rest.md) or graphql-api-architect (§ 6 of 31-graphql.md), only when 00-use-case.md's Admission row states a limit — recorded by use-case-design from the request, never asked. Resilience4j for both, the quota per replica or at the edge as a project fact written by the first limited case. Norms in @.claude/rules/inbound-admission.md (@.claude/decisions/0151-inbound-admission-in-rest-and-graphql.md)
A GraphQL API — schema, .graphqls, query or mutation, resolver, @BatchMapping, DataLoader and N+1, connection and cursor, GraphQL errors, depth and complexity limits, introspection — or choosing REST, GraphQL or both for one use caseskill graphql-api-architect — 31-graphql.md, step 3g of /new-feature, right after REST and before security, when 00-use-case.md's Trigger names a GraphQL adapter (REST is skipped when it names GraphQL alone). The protocol is chosen per use case by use-case-design, with the criteria of @.claude/rules/api-graphql.md § Choosing the inbound protocol. Queries and mutations on the servlet stack only (@.claude/decisions/0146-graphql-api-architect-skill.md)
Who may call an endpoint — roles, groups, only the owner — Spring Security on the servlet stack, JWT/opaque token/local users/API key, 401/403, CORS, Actuator and Swagger exposureskill security-architect — 32-security.md, runs after REST and before messaging in /new-feature when the use case's Access row asks for it; norms in @.claude/rules/authorization.md. WebFlux is out of scope
Calling another system over HTTP — a payment gateway, a partner API, another service — RestClient, @HttpExchange, OpenAPI Generator, WebClient for a stream, OpenFeign kept as legacy; engine and pool, timeouts, retry, circuit breaker, outbound authentication (OAuth2 client credentials, token relay, API key, Basic, mTLS, HMAC), what a provider failure becomes (502/503/504)skill http-client-architect — 28-http-client.md, runs after security and before messaging in /new-feature when 10-domain.md declares a port of kind external HTTP; norms in @.claude/rules/http-client.md, failure families in @.claude/rules/error-handling.md § Integration families. A WebFlux application is out of scope
A language model or a vector store behind a port — Spring AI, ChatClient, OpenAI or Anthropic from Java, a prompt, structured output (classify, extract, moderate), embeddings, semantic search, pgvector; what the model's answer may change, which fields go to the provider, timeout and the one retrying layerskill ai-architect — 29-ai.md, runs after outbound HTTP and before messaging in /new-feature when 10-domain.md declares a port of kind LLM or vector store; an adapter in the blueprint's .ai package, norms in @.claude/rules/ai.md. Spring AI 2.x on Boot 4 only; tool calling, chat memory, generation over retrieved passages and multimodal are out of scope (@.claude/decisions/0145-ai-architect-skill.md)
Tests, coverage, installing ArchUnitskill test-architect
A mapper — a DTO, entity, document, payload or provider DTO to and from the model — MapStruct, @Mapper, the annotation processor path@.claude/rules/mapping.md — one mechanism per project, the generated project's root CLAUDE.md **Mappers: paragraph, manual when absent. /new-feature-implement's pre-flight asks once and runs mapstruct-installer, which records manual, or wires MapStruct and converts every existing mapper; never invoked directly. The MapStruct exemplar sits beside the manual one in each mapping skill's templates/ (@.claude/decisions/0160-mapstruct-as-a-per-project-mapper-choice.md)
Designing a full feature (use case → domain → REST → persistence → tests) up to an approved specskill new-feature — manual only: the user types /new-feature <description>, the model can't invoke it. One use case per run; it designs only, and over an approved case it prints the implement command instead
Implementing a spec that is already approved, in a clean sessionskill new-feature-implement — manual only: /new-feature-implement UC-NNN-<slug> after /clear. Pre-flight, then the executor in three chained block groups, then compose-service-installer for every materialize row of the spec's ## Infrastructure, then prints /clear and the /git-publish line — it never invokes git-publish (@.claude/decisions/0182-git-publish-printed-not-chained-by-the-feature-flows.md). Never loads the design procedure, runs on sonnet, writes nothing itself (@.claude/decisions/0135-new-feature-split-spec-and-implement.md). It is the only supported door to the pre-flight and the four mandated findings of an implement run
Creating a git repo, committing, or pushing the project just generated or just implementedskill git-publish — chained automatically only after /init-project; after /new-feature and /new-feature-implement the person types the /git-publish line the final report prints, after /clear; behind two confirmations always
Docker, docker-compose, adding a service (DB, broker) to a project, Testcontainers image consistency at the compose level, choosing an observability backend (Jaeger or Grafana+Tempo+Prometheus) behind the OTLP collectorskill docker-architect. A service a use case needs is decided at design time — persistence-architect and messaging-architect ask, and record exists/external/materialize/pending per @.claude/skills/docker-architect/references/compose-service-decision.md — and a materialize row is added by /new-feature-implement through the compose-service-installer agent, which invokes docker-architect (@.claude/decisions/0137-pending-compose-service-decided-at-design-materialized-at-implement.md)
A versioned file citing a docs/use-cases/UC-NNN-slug/ folder that was deleted or renamedArchHook.java doctor — the UC references line, so /arch-doctor reports it. Reads doctor.uc_references from @.claude/schemas/extensions.json; silent in this meta-repo, which has no docs/use-cases/
A spec citing a backlog row — BL-NN — that docs/use-cases/BACKLOG.md does not have, in either its active or its retired tableArchHook.java doctor — the BL references line, same shape and same data block (doctor.bl_references). BL-NN is the backlog's own identifier, assigned by use-case-design on append and never a UC number: it exists so an impact row can name the case that satisfies a precondition while that case is still backlog
Where TLS terminates — at the edge (ingress, load balancer, Caddy) or in the embedded Tomcat, mutual TLS as a recorded variant — HTTPS, certificates and their renewal, HTTP/2 and h2c, HSTS, X-Forwarded-* and trusted proxiesskill transport-security-setup — chained by project-bootstrap step 7.5 and by arch-adopt when the root CLAUDE.md has no **Transport: paragraph; asks the topology, never writes a key or certificate, proves it with an IT against a real server, hands the local Caddy edge and the Dockerfile port to docker-architect. Norms in @.claude/rules/transport-security.md; where any credential, key or keystore may live is @.claude/rules/secrets.md. Outbound TLS stays with http-client-architect
SonarQube or SonarCloud analysis — scanner plugin, project key, server URL, CI step, a local SonarQube containerskill sonarqube-setup — chained by project-bootstrap step 8.4 and by arch-adopt when the build file has no scanner; asks whether a server exists, delegates the local container to docker-architect, never writes a token
A container that "started" but isn't answering, a port already allocated, OTLP traffic reaching the wrong collector, an OTLP or other default the host run cannot reach, or one app never overrides, a compose image: tag that disagrees with the one src/test pins in DockerImageName.parse, a broker published to the host that no host client can reachArchHook.java compose — hook, not skill. Also folded into doctor, so /arch-doctor reports it. The tag comparison and the advertised-address check need no Docker: they read files
Turning a generated project's SonarQube analysis into a lessons-learned — which .claude/ template, norm or Checkstyle setting produced each group of issues — and filing it here as an issueskill sonar-lessons — manual only (/sonar-lessons), runs inside the generated project, stops when the scanner, server or SONAR_TOKEN is missing. Writes docs/lessons-learned/sonar-NNN.md and ends with the /report-issue command that files it
A diagram of this .claude/ — layers, classes and territories, the /new-feature pipeline and the three orchestrators (/init-project, /new-feature-implement, /platform-upgrade) — as .drawio/.excalidraw/SVG/PNGskill nerviz-diagrams — manual only (/nerviz-diagrams), meta-repo only, derived from extensions.json and the tree; never the specs' Mermaid (@.claude/decisions/0190-nerviz-diagrams-skill-derived-from-data.md, @.claude/decisions/0192-nerviz-diagrams-draws-the-orchestrators.md)
Whether a skill, agent, rule, hook or MCP server costs more context than it needs — token economy, the audit trail's spend, failures and peaks, judged against Claude Code and Anthropic best practicesskill harness-lessons — manual only (/harness-lessons [piece]), here and in a generated project. Reads ArchHook.java footprint and audit summary, revalidates its baseline past 90 days, writes harness-NNN.md — docs/lessons-learned/ there, .claude/lessons-learned/ here — ends with /report-issue there or /claude-code-architect-designer here. /audit-usage prints it, never invokes it (@.claude/decisions/0188-harness-lessons-and-footprint-mode.md)
Filing an issue on this repository from a generated project — from a description or a docs/lessons-learned/ fileskill report-issue — manual only (/report-issue), runs inside the generated project. Picks the form from .github/ISSUE_TEMPLATE/ here, refuses a report with nothing a maintainer can verify, warns when the project is behind the latest release, strips the project from the body, publishes only after confirmation. The single owner of what leaves a project
Triaging an issue of this repository — is the problem real, already fixed, decided on purpose, a duplicateskill triage-issue — manual only (/triage-issue <N>), here only. The read-only issue-verifier agent checks every claim against HEAD; the issue's diagnosis and proposed fix are never inputs. Comment + label only after confirmation, behind permissions.ask too. A confirmed symptom ends with the /claude-code-architect-designer command, typed in the same session
Kafka producer/consumer, publishing or consuming a domain event over a broker, topic/partition/DLQ — the AsyncAPI document of that contract (Springwolf) — or a listener's retry: blocking (DefaultErrorHandler) or non-blocking (@RetryableTopic), which failures retry, the ack modeskill messaging-architect — the container retries and commits, never the listener; one classification by type per project, a lost race (ConcurrentUpdateException) retried; norms in @.claude/rules/messaging.md § Retry and DLQ (@.claude/decisions/0159-typed-concurrent-update-and-kafka-retry-modes.md). The contract is generated from the code and gated by a committed snapshot: § 1 of 25-messaging.md fixes channel, message, headers and the two operations, the executor annotates both sides, test-architect writes the snapshot test, and spec-first (ZenWave) is recorded with its criteria in @.claude/rules/messaging.md § Contract documentation (@.claude/decisions/0162-asyncapi-contract-via-springwolf.md)
Scheduled or background job, cron, choosing between @Scheduled/ShedLock/Quartz/Spring Batch/db-scheduler/JobRunr, a job running twice across replicas, the outbox relay's schedule and its prune jobskill jobs-architect — 35-jobs.md, runs after messaging and before persistence in /new-feature
A cache — @Cacheable/@CacheEvict, Caffeine, Redis as a cache, a key per caller, expiry, eviction on write, a stampede, Redis down — or a read that must be faster than its sourceskill cache-architect — 22-cache.md, runs after persistence and before tests in /new-feature, only when 00-use-case.md's Freshness row states a tolerance (asked by use-case-design in business words); a decorator of the outbound port in the blueprint's .cache package, norms in @.claude/rules/caching.md. Hibernate's second-level cache stays off, HTTP caching is rest-api-architect's (@.claude/decisions/0144-cache-architect-skill.md)
Design pattern, growing if/switch chainInside /new-feature, decided at design time by each design skill for its own layer, in its partial's ## Design patterns, through gof-design-patterns § Design-time use (@.claude/decisions/0089-design-patterns-decided-at-design-time.md). On existing code, skill gof-design-patterns — manual only (/gof-design-patterns). In a generated project, an agent whose agent_classes entry declares pattern_catalog: true receives its catalog at SubagentStart through ArchHook.java context subagent, and applies it without invoking the skill (@.claude/decisions/0077-pattern-catalog-injected-at-subagent-start.md)
Connecting to an external system (Jira, database, GitHub, Figma), a server exposing mcp__* tools, .mcp.jsonskill claude-code-architect-designer
Auditing what a skill or agent run in a generated project spent and chainedArchHook.java audit — hook, wired only into project-bootstrap/templates/settings.json.example; off here on purpose (no .claude/audit-usage/). Which pieces it skips: the class's audited: false, then the project's own .claude/audit-usage/audited.json per piece — never arch-adopt, fixed off in its class override (audit block of @.claude/schemas/extensions.json)
Reading that trail back — spend per skill and agent, which report to openskill audit-usage — renders ArchHook.java audit summary; here it reports the trail is off
A setting a generated project owns in its own .claude/ — which pieces the audit records (audited.json), the plan-window budget (plan-limits.json), whether a stopped compose service blocks (compose-gate.json) — or adding a new oneskill project-config — manual only (/project-config), travels, renders ArchHook.java config list and changes a setting only through `config setunset. A new project setting is one entry in project_configof@.claude/schemas/extensions.json, its validator and its reader — never a fourth file declared in its own block (@.claude/decisions/0187-project-config-registry-skill-and-mod.md`)
A throwaway spike or POC — exploratory code written fast without format, check, tests, compose gate or guard in the wayskill spike — manual only (/spike <slug>, /spike end <slug>), runs in a generated project or here. Creates ../<project>-spike-<slug> on spike/<slug> and reduces that worktree's .claude/settings.json through ArchHook.jar spike to the audit hooks only (spike.keep_modes), marked skip-worktree; the main checkout stays fully enforced and the spike's spend shows in /audit-usage. Never merges, commits or deletes; promoting spike code is a /new-feature run (@.claude/decisions/0198-spike-worktree-with-hooks-off.md)
A plugin whose skills compete with the pipeline for automatic invocation; a personal skill in ~/.claude/skills/ named like one of .claude/skills/enabledPlugins: false in both settings files for every id of settings.blocked_plugins in @.claude/schemas/extensions.json — schema fails on a missing one, and .claude/settings.local.json is where a person re-enables one. A personal skill wins over the project's with no warning; ArchHook.java doctor names it on the Skill shadowing line, never gating (@.claude/decisions/0138-block-colliding-plugins-and-report-shadowed-skills.md)
Which norm covers what@.claude/rules/00-index.md
Which class a skill is, what it may write, and what sections its body must carryskill_classes in @.claude/schemas/extensions.json — ArchHook.java schema validates the body, guard enforces the territory
The same for an agent — plus which frontmatter fields it owes and whether it may write at allagent_classes in @.claude/schemas/extensions.json. Four classes: driver (interviews and delegates, writes a tree that doesn't exist yet), executor (implements an approved spec), installer (one-shot setup, narrow fixed paths — compose-service-installer's are docker-architect's own), verifier (reads untrusted text, writes nothing). executor: true is the single owner of who may write — the old guard.executor_agents list is gone
Which frontmatter fields are valid in each file type@.claude/skills/claude-code-architect-designer/references/frontmatter-fields.md
Why a skill, norm, or agent exists in the form it's in@.claude/decisions/README.md
Contract every blueprint fulfills@.claude/blueprints/_schema.md
Frontmatter fields the runtime recognizes.claude/schemas/extensions.json (owner, read by ArchHook.java schema) · meaning of each: @.claude/skills/claude-code-architect-designer/references/frontmatter-fields.md
How each piece of Claude Code works@claude-help.md
A skill, hook, injection or MCP server that silently does nothing, a write guard refused, a frozen spec folder, who owns pom.xml or the outbox — every silent trap, the runtime's and this repository's@docs/pt-br/11-pitfalls.md
What a generated project gives a GitHub Copilot user — which of .claude/ the Copilot CLI, cloud agent and VS Code read as-is, what needs a file or frontmatter translation (AGENTS.md nested, .instructions.md with applyTo, .agent.md), what only Claude Code has (!` injection, $ARGUMENTS, Skill tool, permissions.deny), and which guarantee of this repo still holds there — the input of roadmap.md phase 8 and of the AGENTS.md design@docs/pt-br/13-github-copilot.md — facts verified against the vendor docs on the date it states, re-verified before a decision uses one

Known pitfalls

Every silent trap — the runtime's and this repository's: write territories, frozen spec folders, who owns pom.xml and the outbox, what guard sweep and compose gate cover — lives in @docs/pt-br/11-pitfalls.md, read when a piece of .claude/ is designed or edited. Most of this repository's sit behind guard, schema or compose gate, whose block message names the rule and the fix. A new pitfall goes there, never here. What stays bites in any session with no hook behind it:

  • The CLAUDE.md at the root of a generated project is not this file. It comes from .claude/skills/project-bootstrap/templates/root.CLAUDE.md.example.
  • The hooks run .claude/hooks/ArchHook.jar, not ArchHook.java. Editing the source changes nothing a hook executes until java .claude/hooks/ArchHook.java build rewrites the jar — under the JDK major hook_build.javac_feature pins, or build refuses, since only the same javac reproduces the committed bytes that CI's build --verify compares. Here a PostToolUse entry rebuilds it on every edit of the source. The jar is committed: .gitignore ignores *.jar and un-ignores this one path — drop that line and CI fails on every OS with the jar "missing". Design: @.claude/decisions/0075-precompiled-hook-jar.md.
  • This repository does not run ./mvnw. ArchHook exits 0 when it finds no wrapper; here that is expected, not a failure.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.