agentleFS
eldermoraeseldermoraes/quarkus-agentic-scaffolding/CLAUDE.md

quarkus-agentic-scaffolding

CLAUDE.md27 starsChanged 4 months agoApache-2.0View on GitHub

These conventions apply whenever code is written, reviewed, or configured in a Quarkus + LangChain4j project. They are always-on. Procedural scaffolding steps and starter code live in the scaffold-project skill and its templates, not here. These tools are prerequisites for this project, not suggestions. Do not work around their absence: if a required tool is unavailable, stop and report it rather than falling back to model memory or a generic web search. - Quarkus Agents MCP — required for every…

The file

Show its rules and text

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

13 rules. About 0 are common, 0 are distinctive, and 13 are 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.

  • 13

    Very specific

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

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

    superpowers skills — optional: When the third-party superpowers plugin is installed, use its skill for a task it fits.

    line 34
  2. Very specific:

    Import the platform BOMs; do not pin versions they manage: Import quarkus-bom and quarkus-langchain4j-bom at the same platform version and …

    line 78
  3. Very specific:

    CDI-first: Use quarkus-arc and standard CDI (@ApplicationScoped, @Inject, @Produces) for wiring.

    line 82
  4. Very specific:

    REST and API surface: Use quarkus-rest (Quarkus REST) with quarkus-rest-jackson for JSON (Jackson is the Quarkus default serializer), and …

    line 85
  5. Very specific:

    Errors leave the REST edge as RFC 9457 problem details: Add quarkus-http-problem (io.quarkiverse.httpproblem) and every exception escaping …

    line 88
  6. Very specific:

    Observability comes from platform extensions, not code: Add quarkus-micrometer-registry-prometheus (metrics, scraped at /q/metrics) and …

    line 102
  7. Very specific:

    Build for both JVM and native: Keep a native Maven profile so the project can produce a GraalVM native binary alongside the JVM build, and …

    line 115
  8. Very specific:

    Every @RegisterAiService declares modelName, even when the project has a single model: give each role its own named block …

    line 145
  9. Very specific:

    Reusable instructions ship as skills, not as prompt strings: When behavior would otherwise be pasted into an ever-growing @SystemMessage, …

    line 171
  10. Very specific:

    Use @QuarkusTest (artifact io.quarkus:quarkus-junit) for integration-style tests and io.rest-assured:rest-assured to exercise HTTP …

    line 197
  11. Very specific:

    Run native integration tests through maven-failsafe-plugin inside the native profile.

    line 199
  12. Very specific:

    Keep model interactions deterministic in tests (temperature=0, fixed prompts) or mock the model so tests do not depend on live inference.

    line 200
  13. Very specific:

    When maintaining eldermoraes/quarkus-agentic-scaffolding itself, apply the tooling requirements per operation as described in …

    line 216

≈ “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
<!-- BEGIN quarkus-agentic-scaffolding conventions (managed block; do not edit inside. Re-run /setup-agentic-scaffolding to update.) -->

Quarkus + LangChain4j + AI Stack — Project Conventions

Version: 0.23.4

These conventions apply whenever code is written, reviewed, or configured in a Quarkus + LangChain4j project. They are always-on. Procedural scaffolding steps and starter code live in the scaffold-project skill and its templates, not here.


1. Required tooling (mandatory)

These tools are prerequisites for this project, not suggestions. Do not work around their absence: if a required tool is unavailable, stop and report it rather than falling back to model memory or a generic web search.

  • Quarkus Agents MCP — required for every Quarkus task. Project creation, extension selection, configuration, version checks, API usage, and troubleshooting MUST go through the Quarkus Agents MCP; never create a Quarkus project, add an extension, or answer a Quarkus question from model memory by hand. Before any Quarkus task, VERIFY the MCP is reachable — its quarkus_* tools are present and a cheap call (e.g. quarkus_status) succeeds. If the tools are absent or the call fails, STOP immediately: report exactly what is missing, point the user to /setup-agentic-scaffolding (and to restarting the session after registering it, since MCPs load at session start), and end the turn. A missing or unreachable MCP is never permission to proceed manually — do not fall back to the Quarkus CLI, Maven/Gradle archetypes, model memory, or web search, do not offer to "continue without it", and do not treat the stop as optional. The only exception is /setup-agentic-scaffolding, whose job is to install it.
  • context7 — required for external library and framework documentation. Look up a library or framework API (LangChain4j included) with context7 before relying on memory or web search.

Optional tooling — not covered by the stop rule above:

  • superpowers skills — optional. When the third-party superpowers plugin is installed, use its skill for a task it fits. The user installs it by choice, so its absence never blocks work and is not a reason to stop.

2. Java conventions

  • Java 25 is the minimum language level, not a ceiling. Compile with maven.compiler.release set to at least 25 and adopt newer language levels freely. Document any project that must pin an older level and explain why (see §6). One cap applies to native targets: GraalVM ships no releases for JDK 26, 27, or 28, so native-image stays on the JDK 25 baseline (with quarterly updates) until JDK 29 lands (September 2027) — projects that build a native binary keep maven.compiler.release at 25 until then (GraalVM release calendar).
  • Default to Virtual Threads for I/O-bound and blocking concurrent work. Platform threads are acceptable only when the runtime or a critical dependency forbids virtual threads (for example, a JDBC driver that pins the carrier). When a blocking AI or tool call must run inside a reactive endpoint, run it on a virtual thread rather than on the event loop. Concretely: every synchronous REST resource method that calls an AI service, a tool, or other blocking I/O carries @RunOnVirtualThread (io.smallrye.common.annotation) — Quarkus REST otherwise runs it on a pooled platform worker thread — and so does every @Tool method that does I/O; code that fans out by hand uses Thread.startVirtualThread(...) or an Executors.newVirtualThreadPerTaskExecutor().
  • Use Scoped Values in place of ThreadLocal for request- or agent-scoped identity that must survive virtual-thread continuations, avoiding the leakage and inheritance pitfalls of ThreadLocal.
  • Structured concurrency for related subtasks. For fan-out across related concurrent subtasks, prefer declarative parallelism (LangChain4j @ParallelAgent / @ParallelMapperAgent, see §4) or explicit virtual-thread fan-out (Thread.startVirtualThread(...) or an Executors.newVirtualThreadPerTaskExecutor()), instead of ad-hoc executor coordination. StructuredTaskScope is the preferred structured-concurrency primitive where the project can enable it; note it is a Java preview feature (requires --enable-preview) with GraalVM native-image considerations, so adopt it only when the preview flag and the native target allow.
  • Prefer records, sealed types, and pattern matching where they clarify intent. Use records for DTOs and value objects (they also minimize the GraalVM reflection surface), sealed interfaces for closed hierarchies such as event or result types, and pattern-matching switch over those hierarchies so the compiler enforces exhaustiveness.

3. Quarkus conventions

  • Import the platform BOMs; do not pin versions they manage. Import quarkus-bom and quarkus-langchain4j-bom at the same platform version and let the BOMs manage every extension and LangChain4j version. No dependency the BOMs manage carries a <version>, including the non-extension dev.langchain4j:langchain4j-embeddings-* models and document parsers.
  • CDI-first. Use quarkus-arc and standard CDI (@ApplicationScoped, @Inject, @Produces) for wiring. Produce framework objects (retrieval augmentors, memory providers, embedding stores) from @ApplicationScoped producer beans.
  • REST and API surface. Use quarkus-rest (Quarkus REST) with quarkus-rest-jackson for JSON (Jackson is the Quarkus default serializer), and expose quarkus-smallrye-openapi so endpoints are documented and explorable.
  • Errors leave the REST edge as RFC 9457 problem details. Add quarkus-http-problem (io.quarkiverse.httpproblem) and every exception escaping a resource becomes an application/problem+json response instead of a raw 500 with a stack trace — which matters here because an unhandled model timeout, a dead inference endpoint, or a throwing tool would otherwise leak prompts and internal names to the caller; the server still logs the failure in full. It needs no configuration: the quarkus.http-problem.* keys only tune it, and include-details stays false so parser failures do not echo internal class names. This covers the REST edge only — the WebSockets Next streaming path keeps its own @OnError handling (§4) — and it complements rather than replaces the declarative fault tolerance in §4, which handles failure inside the service. The extension is in the platform BOM from Quarkus 3.38.0, so it takes no version pin.
  • Streaming uses WebSockets Next. For token or progress streaming, use quarkus-websockets-next rather than rolling a custom transport (see §4 for the streaming pattern).
  • Observability comes from platform extensions, not code. Add quarkus-micrometer-registry-prometheus (metrics, scraped at /q/metrics) and quarkus-opentelemetry (traces) and AI services are instrumented automatically: per-method timers and counters (langchain4j.aiservices.*), GenAI-semconv token usage (gen_ai.client.token.usage, tagged by operation and token type), one span per AI-service call (langchain4j.aiservices.<Interface>.<method>) and per tool call (langchain4j.tools.<tool>). Register a CDI CostEstimator bean (io.quarkiverse.langchain4j.cost) to emit gen_ai.client.estimated_cost. Prompt and completion text reaches spans only when explicitly enabled (quarkus.langchain4j.tracing.include-prompt / .include-completion) — treat those as dev-only and scope them with %dev., since they record user content.
  • Enable parameter-name retention. Configure the compiler with -parameters (Maven: <parameters>true</parameters>), which REST and AI-service binding rely on.
  • Build for both JVM and native. Keep a native Maven profile so the project can produce a GraalVM native binary alongside the JVM build, and gate native integration tests in that profile. Native builds compile against the GraalVM JDK 25 line until JDK 29 (September 2027) — see §2 — so a project with a native profile does not raise the language level above 25.
  • Disable Dev Services when an external model endpoint is configured. When the project points at a real Ollama endpoint (local or cloud), disable LangChain4j Dev Services (quarkus.langchain4j.devservices.enabled=false) so a container is not started implicitly.

4. LangChain4j conventions

  • Declarative AI services are the default. Define AI services as CDI-managed interfaces annotated with @RegisterAiService (the Quarkus form of LangChain4j's declarative service), using @SystemMessage / @UserMessage for prompts and @MemoryId for per-conversation memory. Prefer this over manual ChatModel wiring unless there is a documented reason.
  • Tools are CDI beans. Expose actions to a model with @Tool methods on @ApplicationScoped beans, wired via @RegisterAiService(tools = …) or @ToolBox — never hand-rolled JSON function dispatch. Tool methods doing I/O follow the §2 virtual-thread rules.
  • Multi-agent workflows are composed declaratively. Build agentic workflows from @RegisterAiService agents annotated with @Agent(name, description, outputKey) and orchestrate them with the LangChain4j Agentic annotations — @SequenceAgent, @ParallelAgent, @ParallelMapperAgent, and @SupervisorAgent (+ @SupervisorRequest) — assembling results with @Output over the AgenticScope. Use the quarkus-langchain4j-agentic extension. Avoid hand-rolled executor or coordination glue between AI services.
  • Structured output via typed return values. Have services return records or enums to get structured results, and set temperature=0 for classification and other deterministic tasks.
  • Name and right-size models. Configure models by name (@RegisterAiService(modelName = "…") on services, @ModelName("…") on injected models) and use a small, fast, low-temperature model for cheap subtasks (classification, query rewriting) and a larger model for the primary task. Every @RegisterAiService declares modelName, even when the project has a single model: give each role its own named block (quarkus.langchain4j.<provider>.<name>.chat-model.*) instead of leaning on the unnamed default, so re-sizing one service is a configuration change.
  • Streaming pattern: reactive only at the edge. Stream over quarkus-websockets-next (@WebSocket, @OnTextMessage returning a Mutiny Multi, @OnError). Keep the agent and engine logic free of reactive types: have the WebSocket delegate to an @ApplicationScoped orchestrator that runs the blocking pipeline on a virtual thread (Multi.createFrom().emitter(...) + Thread.startVirtualThread(...)) and emits progress. Mutiny appears only at the channel edge, never inside the engine.
  • Guardrails wrap AI services declaratively. Validate prompts/responses with @InputGuardrails / @OutputGuardrails beans implementing the upstream dev.langchain4j.guardrail interfaces (the Quarkus-specific guardrail API was retired in favor of upstream); tune retries with quarkus.langchain4j.guardrails.max-retries.
  • Externally originated free text is data, never instructions. Free text the application did not author itself — end-user input, inbound email or ticket bodies, webhook payloads, text relayed from an upstream system — is interpolated into a prompt only inside explicit delimiters (<ticket>…</ticket>), with the system message stating that the delimited span is data to process and never instructions to follow, and every entry method that receives it carries @InputGuardrails. Downstream services reading only model-produced state need no guardrail, but still delimit values derived from that text.
  • Fault tolerance is declarative on AI-service methods. With quarkus-smallrye-fault-tolerance, put MicroProfile @Timeout, @Retry, and @Fallback (org.eclipse.microprofile.faulttolerance) directly on @RegisterAiService methods, with the fallback as a default method on the same interface — never hand-rolled try/retry loops around AI calls. Size @Timeout generously on tool-calling methods: a single invocation may span several model/tool round-trips before it returns.
  • Reusable instructions ship as skills, not as prompt strings. When behavior would otherwise be pasted into an ever-growing @SystemMessage, put it in a SKILL.md (YAML front matter with name and description, instructions in the body), point quarkus.langchain4j.skills.directories at the folder, and annotate the service or method with @Skills (io.quarkiverse.langchain4j.skills, extension quarkus-langchain4j-skills). The extension registers an activate_skill tool and a system message advertising what is available, so the model pulls in a skill's instructions only when they apply — the prompt stays small and each skill stays independently editable. Narrow the surface with @Skills("name") rather than exposing everything. The extension is status:preview: pin the behavior you depend on with a test, and expect its API to move.
  • RAG starts simple with Easy RAG. For retrieval-augmented generation, start with the quarkus-langchain4j-easy-rag extension plus an in-process embedding model: point quarkus.langchain4j.easy-rag.path at a documents folder and let it ingest on startup. Move to a hand-built RetrievalAugmentor (a CDI-produced EmbeddingStore + EmbeddingStoreContentRetriever) only when a project needs control Easy RAG does not provide.
  • Enable request/response logging in dev. Set %dev.quarkus.langchain4j.log-requests=true and %dev.quarkus.langchain4j.log-responses=true so prompts and model output are observable during development without recording user content in production.

5. Testing

  • Every project keeps a @QuarkusTest smoke test. At least one @QuarkusTest under src/test/java injects an AI service and asserts it wired; it boots the application without calling the model, so it needs no live inference.
  • Use @QuarkusTest (artifact io.quarkus:quarkus-junit) for integration-style tests and io.rest-assured:rest-assured to exercise HTTP endpoints.
  • Run native integration tests through maven-failsafe-plugin inside the native profile.
  • Keep model interactions deterministic in tests (temperature=0, fixed prompts) or mock the model so tests do not depend on live inference.
  • Grade model quality with the evaluation framework (quarkus-langchain4j-testing-evaluation-junit5 + semantic-similarity / AI-judge strategies) rather than brittle string asserts; keep the scaffolded @QuarkusTest wiring smoke test green without a live model.

6. Scope and overrides

These conventions apply to projects in this Quarkus + LangChain4j stack. A per-project addition or override is allowed when justified — for example, pinning a fixed older Java version, choosing platform threads for a pinning dependency, or selecting a different model provider — and must be documented inline near the override so the deviation and its reason stay visible.

When maintaining eldermoraes/quarkus-agentic-scaffolding itself, apply the tooling requirements per operation as described in CONTRIBUTING.md (Required tooling). An unavailable MCP blocks only work that needs that tool; independent repository review, documentation, CI inspection, and approved merges may continue. This override applies only to maintenance of the scaffolding repository; applications using its conventions retain the requirements in section 1.

<!-- END quarkus-agentic-scaffolding conventions -->

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.