agentleFS
ice-lfernandesice-lfernandes/claude-spring-architect/.claude/skills/project-bootstrap/SKILL.md

project-bootstrap

Skill11 starsChanged 7 days agoApache-2.0View on GitHub

Creates the complete initial structure of a Spring Boot project from a declarative architecture blueprint. Use when the user asks to create a project from scratch, start a new project, set up a project, scaffolding, "new Spring project", bootstrap, generate a module structure, create a multi-module Maven or Gradle project, build a hexagonal architecture, clean architecture, onion, layered, vertical slice or modular monolith, or when the /init-project command is run.

  • Reads credentials

40 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use delivery-planning, diagnose and 4 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • lzx-BillSkill

    delivery-planning

    Use when breaking work into tasks, planning milestones, mapping dependencies, sequencing implementation, or maintaining backlog and in-progress views. Trigger when user says "task breakdown", "milestone", "dependencies", "backlog", "sprint", "implementation plan", "delivery plan", or asks to "break this down into tasks". Coordinate with prompt-authoring for task-to-prompt mapping and with acceptance-design for task-to-acceptance mapping.

    Also in 3 projects that use this

  • MicrosoftSkill

    diagnose

    Use to systematically diagnose why scenarios fail — identifies root causes by analyzing agent traces, codebase, and behavioral patterns

    Also in 3 projects that use this

  • MicrosoftSkill

    api-design

    Guide for designing and documenting RESTful APIs. Use when asked to design an API, create endpoints, or document an API.

    Also in 3 projects that use this

  • GoogleSkill

    tdd

    Test-driven development. Use when the user wants to build features or fix bugs test-first, mentions "red-green-refactor", or wants integration tests.

    Also in 3 projects that use this

  • GoogleSkill

    grill-me

    A relentless interview to sharpen a plan or design.

    Also in 3 projects that use this

  • +1 more from google

The file

Show its rules and text

We split this skill into the rules it gives an agent

15 rules. 0 are common, 2 are distinctive, and 13 are very specific to this project.

  • 0

    Common

    Most of the 31 edited versions we read keep these.

  • 2

    Distinctive

    This author's own choices. Worth a look.

  • 13

    Very specific

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

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

    Does not write business code: No example, no seed, no demo aggregate.

    line 20
  2. Distinctive:

    No Python, no template engines, no bash.

    line 37
  3. Very specific:

    Existing directory: If <project> holds pom.xml or build.gradle, stop (§ When NOT to use).

    line 60
  4. Very specific:

    Missing directory: Create it with mkdir -p "<project>".

    line 64
  5. Very specific:

    Files: Every path this skill and its references/ write as relative, or as <project>/…, is written at <project>/…, through an absolute path.

    line 65
  6. Very specific:

    Shell: Run every command in a subshell rooted there: (cd "<project>" && ./mvnw -q test).

    line 67
  7. Very specific:

    Check that the exemplars the procedure cites are there.

    line 83
  8. Very specific:

    If a cited exemplar is missing, or a tool is missing: stop and report, naming what's missing.

    line 108
  9. Very specific:

    Independent calls go in one response: Every turn re-reads the whole context, so a step's exemplars are parallel Reads and its files — every …

    line 135
  10. Distinctive:

    Read the YAML and check, one by one:

    line 157
  11. Very specific:

    Don't invent defaults for dependency_rules — it's the backbone of the enforcement.

    line 169
  12. Very specific:

    Run exactly one of the two, matching the build tool resolved above.

    line 211
  13. Very specific:

    If the network isn't available, stop and ask the user for the versions.

    line 249
  14. Very specific:

    Every rule in .claude/rules/ reaches the project through step 6.6 — ArchHook.java export copies them and rewrites their paths.

    line 428
  15. Very specific:

    No rule file is read: § Applicable rules says where each one already lives in a template, and step 6.6's copy is export's, not a …

    line 475

“Common” is measured: kept by at least 6 in 10 of the 31 edited versions of this file we could read. “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
SKILL.md

Project Bootstrap

Turns a new directory next to this repository into a Spring Boot project with declared architectural boundaries, active hooks, and a green build.

Does not write business code. No example, no seed, no demo aggregate. It emits module structure, packages, POMs, configuration, enforcement, rules, and skills — and stops there. Classes come from the /new-feature pipeline, from a real spec. A User aggregate invented by the bootstrap competes with that spec and diverges from the layer skills' exemplars, which own the shape. Record: @.claude/decisions/0011-bootstrap-without-business-code.md.

The only Java in the freshly generated project is what the Initializr brings — the @SpringBootApplication class and the context test — plus one package-info.java per role in packages.map (step 4.7).

Dependencies

java (JDK 21+) · git · curl. Nothing else. mvn/gradle on the PATH are not required — the Initializr's starter.tgz already brings the matching wrapper (mvnw or gradlew, whichever build.tool resolved to).

No Python, no template engines, no bash. The hooks are a single Java file run in single-file source mode, which makes them identical on Linux, macOS, and Windows — the same dependency the target audience already has mandatorily.

When NOT to use

pom.xml or build.gradle already exists at <project> (§ Where the project is born). This skill does not migrate existing projects nor overwrite structure. In that case: stop, report, suggest /new-feature from a session opened in that directory instead.

Where the project is born

The session runs in a clone of this repository, and the project is generated next to it:

<project> = <this repository>/../<artifactId>

Resolve it to an absolute path once the interview has settled artifactId, before step 3, and use that same absolute path in every later step. Never generate into this repository: ArchHook.java export refuses a destination equal to its source (step 6.6), and the creation skills and blueprint catalog would end up beside the project's code.

  • Existing directory. If <project> holds pom.xml or build.gradle, stop (§ When NOT to use). If it holds anything else, list it and stop: the generation does not merge into a directory it did not create. An empty directory is fine, since the user may have created it to add it to the session.
  • Missing directory. Create it with mkdir -p "<project>".
  • Files. Every path this skill and its references/ write as relative, or as <project>/…, is written at <project>/…, through an absolute path.
  • Shell. Run every command in a subshell rooted there: (cd "<project>" && ./mvnw -q test). The session's shell keeps its cwd between calls, and a bare cd would move every later injection with it.
  • Chained skills. transport-security-setup (step 7.5), sonarqube-setup (step 8.4) and git-publish (at the end, from /init-project) receive project: <project> in their one-line context, and pass it on when they chain docker-architect. Each of them treats that directory as the project root. Step 4.10 applies docker-architect's merge procedure here, so it follows the two rules above.

Preconditions

java --version && git --version && curl --version | head -1
ls ${CLAUDE_SKILL_DIR}/templates/*.example

Check that the exemplars the procedure cites are there. Some are conditional on the active blueprint's build.tool — check only the ones the resolved tool needs, per the table below:

Build toolExemplars (step 4)
mavenpom.parent.xml.example and pom.module.xml.example
gradlesettings.gradle.example, build.gradle.parent.example, and build.gradle.module.example

The rest are shared regardless of build.tool: checkstyle.xml.example and checkstyle-test.xml.example (4.6), lombok.config.example (4.8), Application.java.example and application.yml.example (step 3), features/actuator/application-actuator.yml.example and features/observability/application-observability.yml.example and features/observability/ApplicationTests-tracer.java.example (4.7), docker-compose.yml.example (4.10) plus either Dockerfile.example (maven) or Dockerfile-gradle.example (gradle) — never both, root.CLAUDE.md.example, root.AGENTS.md.example, module.AGENTS.md.example, module.CLAUDE.md.example and copilot-instructions.md.example (step 6), settings.json.example (step 6.6, written by the export mode, not by hand), either ci.yml.example (maven) or ci-gradle.yml.example (gradle) — never both (step 6.5), README.md.example and README.pt-br.md.example (step 8.5), and GENESIS.md.example (step 8.6) — plus whatever the active blueprint's templates: declares. Don't count files against a fixed number: the folder grows, the number falls behind, and the precondition starts failing for nothing. If a cited exemplar is missing, or a tool is missing: stop and report, naming what's missing. Don't improvise a root POM/build.gradle or invent Spring Boot versions from what you think you know — the version you have in memory is stale by construction.

This skill generates exactly one build system per project — Maven or Gradle, never both. build.tool in the blueprint YAML picks it, and it's overridable once at initialization (/init-project's interview); once resolved, every later step branches on that single value and only ever touches that tool's exemplars. Writing a pom.xml and a build.gradle side by side (or vice versa) in the same generated project is a bug in this procedure, not a harmless extra — Maven and Gradle disagree about which one is authoritative, ./mvnw and ./gradlew both exist and diverge on the first dependency bump, and every downstream skill that shells out to a build tool (test-architect, archunit-installer, CI) has to guess which one is real.

Step 4.10 additionally reads docker-architect's own templates/postgres-service.yml.example and templates/otel-collector-service.yml.example (plus its templates/otel-collector-config.yml.example) when persistence-jpa or observability is active — see § 4.10. Missing either when the matching feature is active: same stop-and-report rule.

Naming convention: the .example suffix always comes last (pom.parent.xml.example, DomainException.java.example). An exemplar with the suffix in the middle escapes the glob above and the precondition turns green without the file existing.

Procedure

Independent calls go in one response. Every turn re-reads the whole context, so a step's exemplars are parallel Reads and its files — every package-info.java of step 4.7 — parallel Writes, in one response each. Never a shell loop or heredoc instead: guard bash may not read its paths, and one bad heredoc corrupts every file it writes (@.claude/lessons-learned/lessons-learned-020.md § 7).

1 · Select the blueprint

The blueprint, the build tool and every other answer come from /init-project's interview, run in the main session before the agent that runs this skill starts — that agent runs in the background and cannot ask (@.claude/decisions/0123-lessons-learned-020-init-project-run.md). This skill never asks. A missing answer stops it: report blocked: missing <field>. Never assume the architecture: it's the most expensive decision to reverse in the whole project. Check the given id against .claude/blueprints/*/*.yaml, listed dynamically — each architecture lives at .claude/blueprints/<id>/<id>.yaml.

The blueprint's build.tool (maven or gradle) is a default, not a lock-in — the answer the interview passed wins. Step 2 resolves the final value and every step from step 3 on assumes it's already settled.

2 · Validate the blueprint

Read the YAML and check, one by one:

#RuleIf it fails
1id, name, build, modules, packages, dependency_rules, features, architecture_paths all existStop and name the missing field
2The depends_on graph is acyclicStop and show the cycle
3Exactly one module with contains_main: trueStop and list the candidates
4Every feature referenced by a module exists in featuresStop and name the feature
5Every templates.<role> points to an existing fileStop and name the path
6architecture_paths is not an empty listStop — without this, step 6.6 has nothing to write
7features.messaging-sqs is absent or falseStop — the feature was retired (@.claude/decisions/0178-retire-the-sqs-blueprint-feature.md): no skill or template delivers an SQS adapter. Say to set the key false or remove it

Don't invent defaults for dependency_rules — it's the backbone of the enforcement.

Resolve the effective build tool now, before step 3. build.tool in the blueprint is the default; @.claude/blueprints/_schema.md documents it as "Overridable at initialization" — if the user asked for the other tool in /init-project's interview, that override wins. Whatever the final value — maven or gradle — every step from here on branches on it once and stays with that choice. Never generate both.

3 · Generate the base with Spring Initializr

The Initializr's type= parameter is what actually picks the build system — everything downstream just follows the file shapes it produces:

# build.tool: maven
curl -sS https://start.spring.io/starter.tgz \
  -d type=maven-project \
  -d language=java \
  -d groupId=<groupId> \
  -d artifactId=<artifactId> \
  -d name=<name> \
  -d packageName=<packageBase> \
  -d javaVersion=21 \
  -d dependencies=<list derived from the features> \
  | tar -xzf - -C "<project>"

# build.tool: gradle — same parameters, only `type` changes. Groovy DSL
# (`gradle-project`), not Kotlin DSL (`gradle-project-kotlin`): this skill's own
# exemplars (§ 4) are Groovy, and mixing DSLs between what the Initializr emits and what
# this skill writes on top of it is its own silent divergence.
curl -sS https://start.spring.io/starter.tgz \
  -d type=gradle-project \
  -d language=java \
  -d groupId=<groupId> \
  -d artifactId=<artifactId> \
  -d name=<name> \
  -d packageName=<packageBase> \
  -d javaVersion=21 \
  -d dependencies=<list derived from the features> \
  | tar -xzf - -C "<project>"

Run exactly one of the two, matching the build tool resolved above. Maven's starter.tgz extracts pom.xml, mvnw, mvnw.cmd, and .mvn/wrapper/; Gradle's extracts build.gradle, settings.gradle, gradlew, gradlew.bat, and gradle/wrapper/. There's no third case where both sets exist — if a stray pom.xml or build.gradle is left over from a previous attempt in <project>, that's the "already exists" case from § When NOT to use, not something to merge with the tool just generated.

javaVersion=21 is not a pin from memory — it's this skill's own precondition (JDK 21+, see § Dependencies) made explicit. Without it the Initializr falls back to its own default, which has been observed to be an older LTS than what this skill requires; letting that happen means the generated pom.xml/build.gradle and dependency-catalog.md's reasoning about the target JDK silently disagree.

The Initializr is the version oracle for everything else: it returns the current Spring Boot GA, with nothing pinned in this repository. Confirm what came back:

# maven
grep -m1 '<version>' pom.xml && grep -m1 'java.version' pom.xml

# gradle
grep -m1 "id 'org.springframework.boot'" build.gradle && grep -m1 'sourceCompatibility\|JavaVersion' build.gradle

The build tool's own version is the one the wrapper pins. Read it from the file the starter.tgz extracted — never write it, never edit that file:

# maven
grep distributionUrl .mvn/wrapper/maven-wrapper.properties

# gradle
grep distributionUrl gradle/wrapper/gradle-wrapper.properties

The version in the distribution's file name (apache-maven-<v>-bin.zip, gradle-<v>-bin.zip) is {{wrapperVersion}}, shown in the root CLAUDE.md, the README and the report below.

If the network isn't available, stop and ask the user for the versions. Never write them from memory. If you pin bootVersion explicitly, don't use the .RELEASE suffix — see the note in references/dependency-catalog.md.

Feature → Initializr dependency mapping in references/dependency-catalog.md.

4 · Restructure according to the blueprint

Branch once on the build tool resolved before step 3, and stay on that branch for the rest of this step — write only the files of the tool actually chosen. A gradle project never gets a pom.xml, mvnw, or .mvn/; a maven project never gets a build.gradle, settings.gradle, or gradlew.

Read references/build-<tool>.md § 4 — only the tool just resolved — then references/scaffold.md § 4. The first holds the tool's file layout (POMs or Gradle scripts, wrapper); the second what both tools share, including the andaime rule every later template copy follows. Done when every module of the blueprint exists with its depends_on wired in the build files, and nothing of the other tool is on disk.

The steps from here to 8.6 run in order, every one of them. Each heading below names the reference that holds its body; open it before executing the step — the spine alone is not the procedure.

4.5 · Domain exception family — not here → references/scaffold.md § 4.5

Nothing is generated: the exception family belongs to domain-modeling. Read the section for why, so step 4.7 does not reintroduce it.

4.6 · Generate the Checkstyle config → references/build-<tool>.md § 4.6, then references/scaffold.md § 4.6

config/checkstyle/checkstyle.xml plus the tool's plugin, bound to validate, and config/checkstyle/checkstyle-test.xml, the light rule set for src/test. Done when the build file carries the plugin and both configs exist.

4.7 · Materialize the packages and feature configuration → references/scaffold.md § 4.7

One package-info.java per role in packages.map, plus the application*.yml of each active feature. No other .java.

4.8 · Generate the lombok.config → references/scaffold.md § 4.8

At the project root.

4.9 · Generate the logback-spring.xml → references/scaffold.md § 4.9

Under src/main/resources of the module with contains_main: true.

4.10 · Generate the base Dockerfile and docker-compose.yml → references/scaffold.md § 4.10

Base pair, plus one service per active feature that needs a container, merged through docker-architect's templates.

5 · Generate the boundary map → references/project-files.md § 5

Read references/project-files.md now — it holds steps 5 to 7. .claude/forbidden-imports.txt, written by ArchHook.java boundary-map — never by hand.

6 · Generate the root CLAUDE.md and AGENTS.md, and the module ones → references/project-files.md § 6

6.5 · Generate CI → references/project-files.md § 6.5

Exactly one workflow template — the one of the resolved build tool.

6.6 · Write the project's .claude/ → references/project-files.md § 6.6

ArchHook.java export writes rules, skills, agents, hook, schema and settings, and rewrites the rules' paths. Nothing in the generated project may depend on this repository.

7 · What the enforcement you just installed does → references/project-files.md § 7

Nothing to run — what the final report has to be able to say.

7.5 · Decide transport security → skill transport-security-setup

Invoke transport-security-setup via the Skill tool, with a one-line context: build tool, blueprint id, project: <project>, and "chained from project-bootstrap — skip your Verify". It owns the two questions this step asks — where TLS terminates, and the local profile or local edge — and writes the transport configuration into application.yml, the HSTS filter when no security chain exists, the transport IT, and the **Transport: paragraph of the root CLAUDE.md step 6 wrote; the edge service or the Dockerfile port it hands to docker-architect. Before Verify, so step 8 builds and runs the test it wrote. Same class, territories summed (@.claude/decisions/0092-guard-same-class-chain-sums-territories.md). Don't write any server.ssl, spring.ssl or forward-headers-strategy line here.

8 · Verify → references/build-<tool>.md § 8, then references/verify-and-report.md § 8

Everything in this step branches on the same build tool resolved before step 3 — run only the column that matches.

Read references/verify-and-report.md now — it holds steps 8 to 8.6. Done when the build passes, or when the report says why it failed.

8.4 · Configure SonarQube → skill sonarqube-setup

Invoke sonarqube-setup via the Skill tool, with a one-line context: build tool, coordinates, and project: <project>. It owns the one question this step asks — an existing server (URL, authentication) or a local container — and the scanner in the root build file, the CI step for an external server, and, for a local one, the sonarqube service it hands to docker-architect. After Verify, so the build it touches is already known green; before the README, so step 8.5's {{outputContractBlock}} carries its SonarQube: line. The chained skill joins this phase instead of replacing it — same class, territories summed (@.claude/decisions/0092-guard-same-class-chain-sums-territories.md) — so the steps after it still write. Don't write any sonar.* line here.

8.5 · Generate the project README → references/verify-and-report.md § 8.5

README.md (English) and README.pt-br.md, after Verify.

8.6 · Write the audit genesis record → references/verify-and-report.md § 8.6

.claude/audit-usage/GENESIS.md, once.

Output contract

✅ Project <name> created — blueprint <id>

Modules:
  <path> → depends on <list>
  ...

Versions (resolved by the Initializr): Java <x> · Spring Boot <y> · <build tool> (wrapper <z>)
Active features: <list>
Business code: none — by design. <n> package-info.java written
Boundaries: <n> rules in .claude/forbidden-imports.txt — blocking verified ✓
Checkstyle: config/checkstyle/checkstyle.xml — plugin <v> · tool <v>, validate phase · checkstyle-test.xml over src/test
Spotless: check bound to the build (verify / check) — formatting and unused imports, main and test
Lombok: lombok.config at the root — @Data and @Setter stop compilation
ArchUnit: to be installed — `test-architect` skill (see Next steps)
Coverage: JaCoCo generates a report; the 80%/70% gate comes in with `test-architect`
Self-contained: <n> rules + <n> skills + <n> agents + ArchHook.java + extensions.json written by `ArchHook.java export` — no dead paths ✓
Provenance: .claude/.arch-provenance.json — blueprint <id>, ref <ref>, commit <short sha>. `/arch-doctor` reports anything edited since
Audit trail: .claude/audit-usage/ active — one report per skill or agent invocation from now on, by `/command` or by the model. GENESIS.md records this run itself, in tokens
Docker: Dockerfile + docker-compose.yml — <list: app, plus one entry per service `docker-architect` merged in step 4.10 for an active feature, e.g. "postgres (persistence-jpa)", "otel-collector (observability)"> — extend with `docker-architect` for anything a future use case adds
Local secrets: .env (untracked) holds DB_PASSWORD, read by docker compose and imported by application.yml for the host run; a fresh clone copies .env.example — <only with persistence-jpa; omit the line otherwise>
Observability UI: <omit this line entirely when `observability` is not active> none — the collector exports to `debug`, which writes spans and metrics to its own stdout and is not a dashboard. Run `/docker-architect` to add one: Jaeger (traces, one container) or Grafana + Tempo + Prometheus (traces and metrics, three)
Transport: <the first line of `transport-security-setup`'s report — topology A edge | B direct | C mutual TLS | C′ mesh> — HTTP/2 on, HSTS by <Spring Security | HstsHeaderFilter>, <ForwardedHeadersIT | TransportSecurityIT>
SonarQube: <the first line of `sonarqube-setup`'s report — existing server <url> | SonarCloud <org> | local container on http://localhost:9000> — scanner <v>, CI step <added | none>
MCP: <none — no server designed for this project yet | <n> server(s) copied to .mcp.json, see MCP-SETUP.md>
Build: <PASSED | FAILED: reason>
Docs: README.md (English, default) + README.pt-br.md — origin, blueprint, stack, skills/agents, this report

Next steps:
  1. /use-case-design <first-use-case-name>
  2. Install the architecture tests (ArchUnit) and wire up the coverage gate with the
     `test-architect` skill as soon as business classes exist. Until then boundaries
     are guaranteed by the `check` hook at edit time (inside Claude Code) and by CI's
     `doctor gate`, which sweeps every source file against `.claude/forbidden-imports.txt`
     (whoever wrote it)<, and by the POMs' `depends_on` (in the build) — only if
     `layout: multi-module`>.
  3. SonarQube — <local: `docker compose up -d sonarqube`, log in at http://localhost:9000
     as admin/admin (a password change is forced), create a token under My Account →
     Security, `export SONAR_TOKEN=…`, then `<./mvnw -B verify sonar:sonar | ./gradlew build sonar>`
     | external: create the `SONAR_TOKEN` repository secret; CI analyses from the next push>

The part between <> in line 2 only appears if the blueprint is layout: multi-module. In single-module there's no per-layer POM and the compiler enforces no boundary at all: outside Claude Code, the CI sweep of .claude/forbidden-imports.txt is the only boundary check until ArchUnit is installed — in this layout it carries the dependency_rules directions step 5 derived, plus the framework roots banned from the domain. Say that, and no more: a sentence promising a compiler-level guarantee, or denying the CI one, is false here.

The ArchUnit and coverage lines aren't optional: without them the user ends up thinking code-quality.md, architecture-ddd.md, and testing.md already have full automatic verification. They have part of it — Checkstyle and lombok.config. The other two come in with test-architect, and until they do, verify checks neither dependency direction nor coverage.

Neither is the business-code line: a user used to scaffolds expects to find an example controller. Writing "none — by design" is what keeps them from looking for it and concluding the generation failed.

Applicable rules

Every rule in .claude/rules/ reaches the project through step 6.6 — ArchHook.java export copies them and rewrites their paths. None is read during generation: the part of each rule that a bootstrap step turns into a file is already inside the template that step copies. The table says which, so a rule change knows which template to follow.

RuleEmbodied byStep
@.claude/rules/architecture-ddd.mdthe blueprint's modules and depends_on, .claude/forbidden-imports.txt; its paths come from architecture_paths at export4, 5, 6.6
@.claude/rules/naming.mdthe package names written into package-info.java4.7
@.claude/rules/code-quality.mdtemplates/checkstyle.xml.example — the mechanical half; the ArchUnit half is test-architect's4.6
@.claude/rules/lombok.mdtemplates/lombok.config.example4.8
@.claude/rules/logging.mdtemplates/logback-spring.xml.example4.9
@.claude/rules/testing.mdnothing here — the coverage gate is wired by test-architect—
@.claude/rules/error-handling.md · @.claude/rules/api-rest.mdnothing here — no exception family or handler is generated (4.5)—

A rule that changes what a template must say is followed by an edit to that template, not by a read here. If a step ever needs a rule that doesn't exist in rules/, create the rule file first — don't write it inside this skill.

Why this is a skill and not an agent

Form 1 (auto-invocable skill): it is a long generation procedure with no interview of its own, and /init-project already isolates the verbose part inside the project-initializer agent. Form 3 was rejected for this file because the three reasons for an agent (preserve context, restrict tools, change model) are satisfied by that caller, not by this procedure — two nested agents would only add a second boundary to pass the blueprint across.

Runs on sonnet with effort: high: generation is template- and YAML-driven, and it runs inside project-initializer, also on sonnet. A skill's model inside a subagent is not documented, so the pin there is a declaration that agrees with the agent's (@.claude/decisions/0081-skill-model-required-per-class.md).

Contract

Class: build — the territory is skill_classes.build's override for this skill in @.claude/schemas/extensions.json: the whole tree of the project being generated. It is the only skill with that reach, and it has it because the tree does not exist yet when it runs. ArchHook.java guard enforces it.

Unfiltered Bash: generation runs curl against the Initializr, tar, ./mvnw, java … export, grep and moves over a tree that does not exist yet — a scoped list would run to ~15 prefixes, and one command missing from it aborts the run halfway through. Writes stay under guard/guard bash, and a force push is blocked by guard bash (guard.force_push).

Reads before generating:

  • .claude/blueprints/<id>/<id>.yaml — the blueprint chosen in step 1
  • references/blueprint-selection.md and references/dependency-catalog.md — steps 1 to 3
  • references/build-<tool>.md — step 4, only the resolved tool's
  • references/scaffold.md — step 4
  • references/project-files.md — step 5
  • references/verify-and-report.md — step 8

No rule file is read: § Applicable rules says where each one already lives in a template, and step 6.6's copy is export's, not a transcription.

Writes (paths relative to the generated project, <project> in § Where the project is born, never this repository) — no other skill touches these files:

  • Exactly one of: pom.xml and */pom.xml (build.tool: maven), or settings.gradle, build.gradle, and */build.gradle (build.tool: gradle) — never both in the same project, see step 4
  • CLAUDE.md and */CLAUDE.md, AGENTS.md and */AGENTS.md, .github/copilot-instructions.md
  • .claude/forbidden-imports.txt
  • .claude/rules/*.md — every rule of this repo, paths derived, see step 6.6
  • .claude/skills/** and .claude/agents/** — whatever export's include lists, see step 6.6. The list is data in @.claude/schemas/extensions.json, not prose here
  • Dockerfile and docker-compose.yml — base pair, step 4.10, plus (via docker-architect's own templates and merge procedure, called from the same step) one service per blueprint feature that's already active and needs a container (persistence-jpa, observability today). Every service a use case adds afterward is docker-architect's alone, invoked on its own thread, not this skill's
  • .env, .env.example, and the .env line of .gitignore and .dockerignore — only with persistence-jpa, through the same step 4.10 call (docker-architect step 4.5). .env holds a random DB_PASSWORD, is never committed and never printed
  • .claude/hooks/ArchHook.java — copy, see step 6.6
  • .claude/schemas/extensions.json — copy without its own export block, see step 6.6
  • .claude/settings.json — written whole, see step 6.6
  • The .claude/audit-usage/ directory itself — step 6.6. The reports and history.jsonl inside it are written afterwards by ArchHook.java audit, never by this skill
  • .claude/audit-usage/GENESIS.md — step 8.6, once, the only report in that directory this skill ever writes itself. Everything else in that directory after it is ArchHook.java audit's alone
  • .mcp.json and MCP-SETUP.md — only if templates/mcp.json.example exists, step 6.6 as an optional copy. Absent in most bootstraps, on purpose
  • config/checkstyle/checkstyle.xml and config/checkstyle/checkstyle-test.xml
  • lombok.config
  • src/main/resources/application*.yml
  • src/main/java/**/package-info.java — one per role in packages.map, step 4.7. No other .java: business classes come from the /new-feature pipeline
  • .github/workflows/*
  • README.md and README.pt-br.md — step 8.5, after Verify. English is the default, Portuguese the linked option

.gitignore is deliberately left out — it comes from the Initializr (step 6.5). The one line step 4.10 appends to it (.env) is docker-architect's, applied through its merge procedure.

Chains transport-security-setup in step 7.5 — the transport lines of application.yml, the HSTS filter, the transport IT and the **Transport: paragraph are that skill's (and, for the edge service and the Dockerfile port, docker-architect's), even though they land in files this skill wrote. Chains sonarqube-setup in step 8.4 — the sonar.* lines of the root build file, the workflow's analysis step and the sonarqube compose service are that skill's (and, for the service, docker-architect's), even though they land in files this skill wrote.

Hands off to use-case-design, domain-modeling, persistence-architect, rest-api-architect, and test-architect, which design the first feature. The architecture tests and the coverage gate belong to test-architect's setup mode — this bootstrap deliberately doesn't generate them.

Does not write business code, and this is the § of the contract that says so. No .java beyond the package-info.java files, no .sql, no file in src/test/**. If a future step needs to emit a class, the right question is which layer skill owns that shape — not how to add one more exemplar here.

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.