# NarrativeTrace > Code is the log. Auto-generate human-readable execution traces from method names, parameter names, and return values. ## Install and first trace (copy this) Java 17+, Gradle 8.0+ (see "Before you start" for a fresh directory with no `./gradlew` yet): ```kotlin // build.gradle.kts plugins { java; application } repositories { mavenCentral() } dependencies { implementation("ai.narrativetrace:narrativetrace-core:0.2.4") implementation("ai.narrativetrace:narrativetrace-proxy:0.2.4") } tasks.withType { options.compilerArgs.add("-parameters") } application { mainClass.set("com.example.orders.Main") } ``` Optional, zero-code step 2 — traces also flow to your logger, `Main.java` below never changes: add `runtimeOnly("ai.narrativetrace:narrativetrace-slf4j:0.2.4")` and `runtimeOnly("ch.qos.logback:logback-classic:1.5.38")`, plus a `logback.xml`. (`OrderService`/`DefaultOrderService` — a one-method interface and its trivial implementation — omitted for length; full listing in [sixty-seconds.md](https://github.com/narrativetrace/narrativetrace-java/blob/v0.2.4/documentation/sixty-seconds.md#2-the-program).) `Main` adopts one fixed `Traceparent` purely so this page's output always names the same trace; your own code never does this — a real run generates a random trace id every time. ```java // src/main/java/com/example/orders/Main.java package com.example.orders; import ai.narrativetrace.api.event.Traceparent; import ai.narrativetrace.core.context.ThreadLocalNarrativeContext; import ai.narrativetrace.core.render.IndentedTextRenderer; import ai.narrativetrace.proxy.NarrativeTraceProxy; public class Main { // snippet:begin fixedTraceparent // A fixed W3C traceparent, adopted so this page's embedded output always names the same trace. // A real run generates a random one every time (never this — it is this DEMO's own constant, // not the library default) via the same mechanism a filter uses for an inbound request header. static final String DEMO_TRACEPARENT = "00-a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4-a1b2c3d4a1b2c3d4-01"; // snippet:end fixedTraceparent public static void main(String[] args) { var context = new ThreadLocalNarrativeContext(); context.adoptTraceparent(Traceparent.parse(DEMO_TRACEPARENT)); OrderService service = NarrativeTraceProxy.trace(new DefaultOrderService(), OrderService.class, context); service.placeOrder("C-1234", "SKU-KB", 2); System.out.println(new IndentedTextRenderer().render(context.captureTrace())); context.reset(); } } ``` ```bash ./gradlew run ``` ```text trace: loose hook parks (a1b2c3d) OrderService.placeOrder(customerId: "C-1234", productId: "SKU-KB", quantity: 2) → "ORD-C-1234-SKU-KB-2" — 13ms ``` ## Before you start - JUnit 5 fails with an unhelpful error without `org.junit.platform:junit-platform-launcher` on `testRuntimeOnly` — the `ai.narrativetrace` Gradle plugin adds it for you; manual setup still needs the line yourself. - Annotations (`@Narrated`, `@NotTraced`, `@OnError`, `@NarrativeSummary`) live in `ai.narrativetrace.api.annotation`. - An empty directory has no `./gradlew` — run `gradle wrapper` once before `./gradlew run`. - Test trace output is on by default; `narrativetrace.output=false` opts out. - `ThreadLocalNarrativeContext` is thread-local, not request- or trace-scoped — crossing a thread needs an explicit `ContextSnapshot`, the Micrometer accessor, or a request-scoped filter; see the [context propagation strategies table](https://github.com/narrativetrace/narrativetrace-java/blob/v0.2.4/documentation/configuration-guide.md#context-propagation-strategies). NarrativeTrace is a Java library that eliminates manual logging. It wraps services with tracing proxies (or uses a Java agent) to capture every method call and renders the result as Markdown, prose, diagrams, or JSON. Includes naming clarity analysis that scores code readability. ## Field notes from AI agents (self-reported, not a benchmark) We asked AI agents to build a Java claims service with NarrativeTrace and write up the experience for another engineer, naming what was awkward. Prompted, one run each, unedited, model named; we wrote the library. All six reports, the exact prompt and the task: https://narrativetrace.ai/#agents-saying - "…the release call is present, generated from a real run, not asserted from inside the process being tested." — Claude Sonnet, 2026-09-11, on the trace file the JUnit extension wrote for a failed payment - "The always-on name-based deny-list is a genuinely nice piece of design: naming a parameter `paymentToken` gets you redaction for free, and I could prove it in a test." — Claude Sonnet, 2026-09-11 - "The trace of a failed payment made missing compensation immediately visible, and approval testing caught an extra call that ordinary value assertions accepted." — GPT-6, 2026-09-08 - "Wrapping a service interface with `NarrativeTraceProxy.trace()` automatically captures all calls, parameters, return values, and durations without any code changes to the service itself." — Claude Haiku, 2026-09-11 What they stumbled on is covered in "Before you start" above. ## Docs - [Agent Skills](https://github.com/narrativetrace/narrativetrace-java/blob/v0.2.4/documentation/agent-skills.md): `add-narrative-tracing` — install and first trace, ending at the doctor — and `narrativetrace-doctor` — a thin, read-only agent skill over the `narrativetrace-cli` `doctor` verb, installable today via `.claude/skills/{add-narrative-tracing,narrativetrace-doctor}/`, `.agents/skills/{add-narrative-tracing,narrativetrace-doctor}/` for Codex, or the always-on `AGENTS.md` pointer - [Complete Reference](https://narrativetrace.ai/java/llms-full.txt): Full API reference, module map, configuration, integration guides, architecture decisions, and troubleshooting - [Javadoc](https://javadoc.io/doc/ai.narrativetrace): API documentation for all published modules - [GitHub](https://github.com/narrativetrace/narrativetrace-java): Source code repository ## For AI Agents: Rich Javadoc in Source JARs All published modules include source JARs with Javadoc written for LLM consumption. To access detailed API context, resolve the sources classifier from Maven Central: Gradle (sources auto-downloaded by IDEs): dependencies { implementation("ai.narrativetrace:narrativetrace-core:0.2.4") } Maven: mvn dependency:sources -DincludeGroupIds=ai.narrativetrace Direct download (any module): https://repo1.maven.org/maven2/ai/narrativetrace/narrativetrace-core/0.2.4/narrativetrace-core-0.2.4-sources.jar Available modules: narrativetrace-api, narrativetrace-core, narrativetrace-proxy, narrativetrace-junit5, narrativetrace-junit4, narrativetrace-clarity, narrativetrace-glossary, narrativetrace-diagrams, narrativetrace-slf4j, narrativetrace-agent, narrativetrace-spring, narrativetrace-spring-web, narrativetrace-servlet, narrativetrace-micronaut, narrativetrace-micronaut-http, narrativetrace-micrometer, narrativetrace-opentelemetry ## Sections in Complete Reference - Overview and philosophy - Quick start (Gradle plugin and manual setup) - Module map with dependency graph (18 modules) - Core API: NarrativeContext, ThreadLocalNarrativeContext, TracingLevel, NarrativeTraceProxy - Data model: TraceTree, TraceNode, MethodSignature, ParameterCapture, TraceOutcome - Annotations: @Narrated, @OnError, @NotTraced, @NarrativeSummary - Configuration: system properties, junit-platform.properties, Gradle plugin DSL, Spring, agent - Integration guides: JDK proxy, JUnit 5, JUnit 4, Spring, servlet filter, SLF4J, Micrometer, Java agent - Clarity scoring: five-dimension analysis, NLP components, standalone scanning - Architecture decisions: eager serialization, ThreadLocal context, sealed types - Troubleshooting: pointer to troubleshooting.md, the dedicated symptom → cause → fix page - FAQ: short skeptical questions (why not OTel/AOP/structured logging, secrets, production safety, async load, free vs Pro, bad names) with pointers to the fuller treatment