Gratuito e de código disponível · BSL 1.1 · TypeScript · Java · .NET · Python
Logging gerado a partir do seu código.
Cada chamada, seus parâmetros e seu resultado viram linhas de log legíveis, pelo logger que você já usa. Segredos redigidos. Seu agente de IA lê o mesmo trace para verificar e depurar.
O código é o log.
TypeScript no npm · Java no Maven Central · .NET no NuGet · Python no PyPI
Ao vivo · rodando nesta aba
Você é o O. Cada método que o computador chama para escolher a jogada aparece à direita no momento em que acontece — um trace real da biblioteca real, sem gravação, sem servidor. Experimente o menu trace level, clique em uma casa já ocupada e depois em Copiar trace. Como funciona →
A abertura dele é a busca mais ampla do jogo — nove candidatas, meio milhão de posições. A sua resposta costuma ser a mais estreita: uma tática dispara e a busca nem chega a rodar.
Comece aqui com o seu agente
Cole isto no seu agente de código. Ele configura o NarrativeTrace no seu projeto e mostra o primeiro trace.
Cole isto no Claude Code, Cursor ou Codex dentro do seu projeto.
Set up NarrativeTrace in this project and show me its first trace.
1. Read https://narrativetrace.ai/typescript/llms.txt first. It carries the install block and the known traps. Do not guess versions or artifact names.
2. If this directory has no project yet, create the smallest console app that llms.txt's "Install and first trace" block describes. Otherwise work inside the existing project and trace one real service boundary.
3. Add `@narrativetrace/cli` as a dev dependency the way llms.txt shows, then run `npx @narrativetrace/cli init --dry-run` and show me the diff. It installs the NarrativeTrace agent skills into this project and adds a marked section to AGENTS.md. Run it for real only after I have seen the diff.
4. If the `add-narrative-tracing` skill is now available, follow it. Otherwise follow the "Install and first trace (copy this)" block in llms.txt.
5. Add one test that traces a call with a deny-listed parameter and asserts the trace shows `[REDACTED]` for it.
6. Run the program, then run the doctor (`npx @narrativetrace/cli doctor`). Paste the trace and the doctor report, explain the trace in two sentences, and list exactly what changed in the project.
Rules: never disable redaction; do not commit `.received.nt` files; pass parameter names to `traceObject` explicitly so arguments never render as `arg0`; run everything in the foreground and read the output before you report; if you cannot fetch URLs, say so and I will paste llms.txt.
Set up NarrativeTrace in this project and show me its first trace.
1. Read https://narrativetrace.ai/java/llms.txt first. It carries the install block and the known traps. Do not guess versions or artifact names.
2. If this directory has no project yet, create the smallest console app that llms.txt's "Install and first trace" block describes. Otherwise work inside the existing project and trace one real service boundary.
3. Add the plugin the way llms.txt shows, then run `./gradlew narrativetraceInit --diff` and show me the diff. It installs the NarrativeTrace agent skills into this project and adds a marked section to AGENTS.md. Run it for real only after I have seen the diff.
4. If the `add-narrative-tracing` skill is now available, follow it. Otherwise follow the "Install and first trace (copy this)" block in llms.txt.
5. Add one test that traces a call with a deny-listed parameter and asserts the trace shows `[REDACTED]` for it.
6. Run the program, then run the doctor (`./gradlew narrativetraceDoctor`). Paste the trace and the doctor report, explain the trace in two sentences, and list exactly what changed in the project.
Rules: never disable redaction; do not commit `.received.nt` files; keep the `-parameters` compiler flag; run everything in the foreground and read the output before you report; if you cannot fetch URLs, say so and I will paste llms.txt.
Set up NarrativeTrace in this project and show me its first trace.
1. Read https://narrativetrace.ai/dotnet/llms.txt first. It carries the install block and the known traps. Do not guess versions or artifact names.
2. If this directory has no project yet, create the smallest console app that llms.txt's "Install and first trace" block describes. Otherwise work inside the existing project and trace one real service boundary.
3. Install the CLI the way llms.txt shows, then run `dotnet tool run dotnet-narrativetrace init --dry-run` and show me the diff. It installs the NarrativeTrace agent skills into this project and adds a marked section to AGENTS.md. Run it for real only after I have seen the diff.
4. If the `add-narrative-tracing` skill is now available, follow it. Otherwise follow the "Install and first trace (copy this)" block in llms.txt.
5. Add one test that traces a call with a deny-listed parameter and asserts the trace shows `[REDACTED]` for it.
6. Run the program, then run the doctor (`dotnet tool run dotnet-narrativetrace doctor`). Paste the trace and the doctor report, explain the trace in two sentences, and list exactly what changed in the project.
Rules: never disable redaction; do not commit `.received.nt` files; run everything in the foreground and read the output before you report; if you cannot fetch URLs, say so and I will paste llms.txt.
Set up NarrativeTrace in this project and show me its first trace.
1. Read https://narrativetrace.ai/python/llms.txt first. It carries the install block and the known traps. Do not guess versions or artifact names.
2. If this directory has no project yet, create the smallest console app that llms.txt's "Install and first trace" block describes. Otherwise work inside the existing project and trace one real service boundary.
3. Add the `narrativetrace` package the way llms.txt shows, then run `uv run narrativetrace init --dry-run` and show me the diff. It installs the NarrativeTrace agent skills into this project and adds a marked section to AGENTS.md. Run it for real only after I have seen the diff.
4. If the `add-narrative-tracing` skill is now available, follow it. Otherwise follow the "Install and first trace (copy this)" block in llms.txt.
5. Add one test that traces a call with a deny-listed parameter and asserts the trace shows `[REDACTED]` for it.
6. Run the program, then run the doctor (`uv run narrativetrace doctor`). Paste the trace and the doctor report, explain the trace in two sentences, and list exactly what changed in the project.
Rules: never disable redaction; do not commit `.received.nt` files; apply `@not_traced` to the real parameter, because importing it protects nothing; run everything in the foreground and read the output before you report; if you cannot fetch URLs, say so and I will paste llms.txt.
Demo com IA: crie uma aplicação de dois serviços do zero
O prompt está em inglês. Seu agente explicará os resultados em português.
Read https://narrativetrace.ai/typescript/llms.txt
Create a TypeScript console app in a new folder. Keep all application code in main.ts: two service classes, OrderService calling InventoryService, and the entry point. Use NarrativeTrace to capture both services without handwritten log statements.
Set module and moduleResolution to NodeNext. Install @types/node and set types to ["node"]. Typecheck before running.
Create demo.sh (macOS/Linux) and demo.ps1 (Windows) launchers that work from any directory, install project dependencies if needed, and print Markdown traces to the terminal.
Run the launcher supported on this machine for one successful order and one out-of-stock failure. Show the actual generated traces, briefly explain what happened, and give me both launch commands.
Explain the setup, results, and launch commands in Brazilian Portuguese.
Read https://narrativetrace.ai/java/llms.txt
Create a deliberately small Java console app in a new folder, with no package directory. Keep the example in one Main.java file: a public Main entry point and tiny package-private service types (or nested types) with strings and primitives only. Do not add DTO, result, or item classes. Use NarrativeTrace to capture OrderService calling InventoryService, without handwritten log statements.
Use the repository's documented build setup. If there is no Gradle wrapper, initialize one before running. Keep the example compact and explain any unavoidable Java boilerplate; the first run may download the build tool and dependencies.
Create demo.sh (macOS/Linux) and demo.ps1 (Windows) launchers that work from any directory, install project dependencies if needed, and print Markdown traces to the terminal.
Run the launcher supported on this machine for one successful order and one out-of-stock failure. Show the actual Markdown traces, briefly explain what happened, and give me both launch commands. Test the other launcher if the platform supports it; otherwise review it and say that it was not executed.
Explain the setup, results, and launch commands in Brazilian Portuguese.
Read https://narrativetrace.ai/dotnet/llms.txt
Create a C#/.NET app in a new folder using dotnet new console; keep its generated project settings. In Program.cs, put top-level calls before OrderService, InventoryService, and their interfaces. OrderService calls InventoryService; use strings and primitives for inputs and results. Capture both services with NarrativeTrace, without handwritten log statements.
Create demo.sh (macOS/Linux) and demo.ps1 (Windows) launchers that work from any directory, restore dependencies if needed, and print Markdown traces to the terminal. Show restore output and stop on setup or execution errors.
Run the launcher supported on this machine for one successful order and one out-of-stock failure. Show the actual generated traces, briefly explain what happened, and give me both launch commands. State which launchers were executed and which were only reviewed.
Explain the setup, results, and launch commands in Brazilian Portuguese.
Read https://narrativetrace.ai/python/llms.txt
Create a Python console app in a new folder. Keep all application code in main.py: two service classes, OrderService calling InventoryService, and the entry point. Use NarrativeTrace to capture both services without handwritten log statements.
Create demo.sh (macOS/Linux) and demo.ps1 (Windows) launchers that work from any directory, install project dependencies if needed, and print Markdown traces to the terminal.
Run the launcher supported on this machine for one successful order and one out-of-stock failure. Show the actual generated traces, briefly explain what happened, and give me both launch commands.
Explain the setup, results, and launch commands in Brazilian Portuguese.
Três estudos recentes
Agentes de IA registram menos que os humanos e, na maioria das vezes, não cumprem quando solicitados.
Os agentes não registram.
Em 58,4% dos 81 repositórios, os agentes tocaram no logging em uma parcela menor dos seus pull requests do que os humanos; quando um revisor pediu explicitamente para adicionar logging, eles não o fizeram em 67% das vezes. — Do AI Coding Agents Log Like Humans?, 2026
Traces brutos não explicam.
Em um pequeno estudo com usuários, os engenheiros encontraram a causa raiz a partir de traces brutos em 42% das vezes, contra 89% com uma explicação estruturada, e levaram quase o triplo do tempo. — XAI for Coding Agent Failures, 2026
Explicações fiéis vêm da estrutura, não do modelo.
Um pipeline ancorado no trace produziu zero explicações com falha em 548 traces; a narração livre de um LLM falhou em 18% das vezes. Cada afirmação precisa apontar para algo que de fato aconteceu. — Explaining AI Agents Through Execution Traces, Universidade Sapienza de Roma, 2026
O NarrativeTrace aplica o terceiro achado ao código que o agente entrega: o trace sai da estrutura, é lido como prosa e nunca contém valores de execução. O resto dos números, e a resposta do NarrativeTrace, estão logo abaixo.
O código é o log
Apague ou enriqueça as instruções de logging. Mantenha a história — e a stack.
O painel abaixo é logging disciplinado, não um espantalho: uma linha na entrada, uma no
sucesso, uma no catch — sem despejo de objetos, como uma equipe cuidadosa já
escreveria. O NarrativeTrace não é um argumento contra logging descuidado. Ele também
substitui o cuidadoso, porque um conjunto fixo de linhas só pode relatar as chamadas que
alguém pensou, de antemão, em anotar. Os eventos vão para onde os seus logs já vão
— pelo SLF4J, pelo ILogger, pelo pino ou pelo winston, para o que quer
que os agregue — e as instruções de log que você ainda não apagou continuam
funcionando.
Pontes de logging →
Um estudo de 2026 analisou 4,550 pull requests abertos por agentes de código com IA contra 3,276 abertos por humanos, em 81 repositórios open source, e descobriu que os agentes mexem em logging em apenas 20.7% dos seus PRs, deixam de adicionar logging quando um revisor pede isso explicitamente 67% das vezes e — quando uma instrução de log em um PR de agente é, de fato, corrigida — os humanos escrevem 72.5% dessas correções eles mesmos, em silêncio, em um commit posterior em vez de durante a revisão de código (arXiv 2604.09409). O estudo mede que os agentes não escrevem logging por conta própria nem cumprem de forma confiável quando pedido, e que os humanos consertam essa lacuna em silêncio, fora da revisão. A resposta do NarrativeTrace é que o código é o log, então não há nada para o agente escrever ou cumprir, e que os traces de aprovação transformam a observabilidade em um portão determinístico — a classe de proteção que as próprias recomendações do estudo pedem.
Antes — três linhas de log cuidadosas
placeOrder(req: OrderRequest): Order {
logger.info({ orderId: req.id }, 'placing order');
try {
const customer = this.customers.find(req.id);
const price = this.catalog.price(req.sku);
this.inventory.reserve(req.sku, req.qty);
const payment = this.payments.charge(price);
const order = this.orders.save(customer, payment);
logger.info({ orderId: order.id }, 'order succeeded');
return order;
} catch (err) {
logger.error({ orderId: req.id, err }, 'placing order failed');
throw err;
}
}
Depois — o código é o log
placeOrder(req: OrderRequest): Order {
const customer = this.customers.find(req.id);
const price = this.catalog.price(req.sku);
this.inventory.reserve(req.sku, req.qty);
const payment = this.payments.charge(price);
return this.orders.save(customer, payment);
}
// Zero linhas de log.
// O NarrativeTrace captura a narrativa
// automaticamente.
Antes — três linhas de log cuidadosas
public Order placeOrder(OrderRequest req) {
logger.info("Placing order {}", req.id());
try {
var customer = customers.find(req.id());
var price = catalog.price(req.sku());
inventory.reserve(req.sku(), req.qty());
var payment = payments.charge(price);
var order = orders.save(customer, payment);
logger.info("Order succeeded {}", order.id());
return order;
} catch (Exception e) {
logger.error("Placing order failed {}", req.id(), e);
throw e;
}
}
Depois — o código é o log
public Order placeOrder(OrderRequest req) {
var customer = customers.find(req.id());
var price = catalog.price(req.sku());
inventory.reserve(req.sku(), req.qty());
var payment = payments.charge(price);
return orders.save(customer, payment);
}
// Zero linhas de log.
// O NarrativeTrace captura a narrativa
// automaticamente.
Antes — três linhas de log cuidadosas
public Order PlaceOrder(OrderRequest req)
{
_logger.LogInformation("Placing order {OrderId}", req.Id);
try
{
var customer = _customers.Find(req.Id);
var price = _catalog.Price(req.Sku);
_inventory.Reserve(req.Sku, req.Qty);
var payment = _payments.Charge(price);
var order = _orders.Save(customer, payment);
_logger.LogInformation("Order succeeded {OrderId}", order.Id);
return order;
}
catch (Exception ex)
{
_logger.LogError(ex, "Placing order failed {OrderId}", req.Id);
throw;
}
}
Depois — o código é o log
public Order PlaceOrder(OrderRequest req)
{
var customer = _customers.Find(req.Id);
var price = _catalog.Price(req.Sku);
_inventory.Reserve(req.Sku, req.Qty);
var payment = _payments.Charge(price);
return _orders.Save(customer, payment);
}
// Zero linhas de log.
// O NarrativeTrace captura a narrativa
// automaticamente.
Antes — três linhas de log cuidadosas
def place_order(self, req: OrderRequest) -> Order:
logger.info("Placing order %s", req.id)
try:
customer = self._customers.find(req.id)
price = self._catalog.price(req.sku)
self._inventory.reserve(req.sku, req.qty)
payment = self._payments.charge(price)
order = self._orders.save(customer, payment)
logger.info("Order succeeded %s", order.id)
return order
except Exception:
logger.exception("Placing order failed %s", req.id)
raise
Depois — o código é o log
def place_order(self, req: OrderRequest) -> Order:
customer = self._customers.find(req.id)
price = self._catalog.price(req.sku)
self._inventory.reserve(req.sku, req.qty)
payment = self._payments.charge(price)
return self._orders.save(customer, payment)
# Zero linhas de log.
# O NarrativeTrace captura a narrativa
# automaticamente.
3h da manhã, o pagamento é recusado
INFO Placing order {customerId: "C-1234", productId: "SKU-KB", quantity: 2}
ERROR Order failed {customerId: "C-1234", productId: "SKU-KB", err: PaymentDeclinedError}
OrderService.placeOrder(customerId: "C-1234", productId: "SKU-KB", quantity: 2)
CustomerService.findCustomer(customerId: "C-1234") → Customer{tier: "gold"} — 4ms
ProductCatalogService.lookupPrice(productId: "SKU-KB") → 24.99 — 2ms
InventoryService.reserve(productId: "SKU-KB", quantity: 2) → Reservation{productId: "SKU-KB", quantity: 2} — 6ms
PaymentService.charge(customerId: "C-1234", amount: 49.98, cardToken: [REDACTED]) !! PaymentDeclinedError: card declined — 640ms
!! PaymentDeclinedError: card declined — 652ms total
Os dois registros vêm da mesma chamada que falhou. O bloco catch envolve o método
inteiro, então o log de erro só consegue dizer o id do cliente, o id do produto e um
tipo de exceção — não qual das quatro chamadas de fato falhou. O trace diz:
PaymentService.charge, aos 640ms. Ele também tem o que o log nunca
capturou — o preço, o token do cartão redigido, e
InventoryService.reserve duas linhas antes, sem nenhum release
correspondente em nenhum dos dois registros. Nada à direita foi escrito à mão, então não
pode ficar desatualizado na próxima vez que alguém adicionar uma etapa.
Uma execução, dois leitores
The order service places an order for customer id "C-42", quantity 5:
Customers verify good standing for "C-42", returning true.
The pricing service calculates for quantity 5, returning 49.95.
The payment service charges card [REDACTED], returning PaymentConfirmation(txId="T-9").
The order repository saves the order, returning Order{id=ORD-1001, total=49.95}.
- OrderService.placeOrder(customerId, qty) → value
- Customers.verifyGoodStanding(customerId) → value
- PricingService.calculate(qty) → value
- PaymentService.charge(card) → value
- OrderRepository.save(order) → value
// sem dados, sem PII, nada por onde injetar
A prosa lê exatamente tão bem quanto os seus nomes, e é por isso que a pontuação de clareza avalia cada nome a partir da narrativa de execução — o código aprende a contar a própria história. Diagnóstico de clareza →
O que um agente ganha
Quatro coisas que um agente realmente usa
llms.txt para ler
Um índice estruturado feito para agentes, não para buscadores — o deste site, e cada runtime traz o seu no próprio repositório.
O llms.txt do JavaTraces .nt para comparar
A árvore de chamadas sem nenhum valor em tempo de execução — pequena, estrutural, e segura para um agente ler e comparar.
Formato do trace estruturalTraces de aprovação como portão
Uma mudança de comportamento vira uma falha de build com um diff legível, não uma surpresa silenciosa, até que uma pessoa a aprove.
Como funciona o modo de aprovaçãoUm skill que instala tudo pra você
add-narrative-tracing instala a biblioteca e leva você ao primeiro
trace; narrativetrace-doctor diagnostica um projeto que já a tem
— os dois rodam como skills no Claude Code e no Codex.
Autorrelato, não benchmark
O que os agentes de IA estão dizendo
The trace of a failed payment made missing compensation immediately visible, and approval testing caught an extra call that ordinary value assertions accepted.
…the release call is present, generated from a real run, not asserted from inside the process being tested.
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.
Wrapping a service interface with NarrativeTraceProxy.trace() automatically captures all calls, parameters, return values, and durations without any code changes to the service itself. This is elegant.
…the clarity report told meClaimProcessor.processscored 0.10 for a “generic verb” the very first time I ran the suite, and it was right — I renamed it toadjudicate… and the suite average from ~0.78 to ~0.81.
Yes, for agent-driven development of Java applications with meaningful service boundaries. Getting useful traces required little configuration, and the combination of values, exception paths, and structural approvals gave me evidence I could act on.
The rendered Markdown trace was legitimately useful while building this, not just as a deliverable … which is how I caught that my first draft of scenario 6’s numbers didn’t actually trigger InsufficientCoverageError … well before any test told me.
That’s not a library gap so much as a library doing exactly its job: it rendered what was actually being passed around, and what was actually being passed around was more than any of those services needed.
Pedimos a agentes de IA que construíssem um serviço Java com o NarrativeTrace e escrevessem sobre a experiência para outro engenheiro — com honestidade, nomeando o que foi estranho. Estas são as palavras deles, sem edição, com o modelo identificado. Não é um benchmark: uma execução de cada, e a biblioteca fomos nós que escrevemos. A tarefa e o prompt estão sob o botão, para que o próximo relato possa ser do seu agente.
Experimente você mesmo
Este é o exercício de onde vieram esses relatos. Uma diferença: as nossas execuções deram ao agente uma cópia da documentação; a sua vai apontá-lo para o repositório público. Dois arquivos, três passos.
- Salve a especificação como
TASK.mdem um diretório vazio. - Inicie seu agente nesse diretório e dê a ele o prompt.
- Leia o
FINDINGS.md— e se você publicar nas Discussions do runtime que usou (Java · TypeScript · .NET · Python), nós também vamos ler.
O prompt
You are building a Java application from a written specification.
The specification is in `TASK.md` in the current directory. Read it, then build the
application it describes. Build it properly: it should compile, its tests should
pass, and the demo should run.
A library called **NarrativeTrace** is available to you for this project. Its
documentation is in its public repository:
- https://github.com/narrativetrace/narrativetrace-java — start with the README
- https://github.com/narrativetrace/narrativetrace-java/blob/main/documentation/llms.txt
— a short orientation written for AI agents
- https://narrativetrace.ai/java/llms-full.txt — the full documentation written for AI agents
Read that documentation first, then use the library in the application you build.
Its artifacts are published on Maven Central under the group `ai.narrativetrace`;
the Gradle plugin id is `ai.narrativetrace`. Take the version from the install
block in llms.txt; the documentation explains which artifacts you need and how to
wire them up.
Rules for this exercise:
- Work **only** inside the current directory. Do not read, search, or modify
anything outside it, and do not clone the library's source code — the
documentation is what you have.
- You may use the network to read that documentation and to resolve build
dependencies.
- You choose the design, the libraries, the project layout, and the testing
approach. There is no house style to match and no reviewer to please.
- Work in the foreground. Do not background the build or the tests and then end
your turn — run them, wait for them, and read the output.
- When the build and tests are green and the demo runs, write `FINDINGS.md` as
the specification describes. In addition to what the specification asks for,
cover what using NarrativeTrace was actually like: what the documentation got
right or left you guessing about, what integration cost you, and whether the
output it produced was of any use to you while you worked.
Finish by reporting, in your final message: whether the build and tests are
green, what you built, and where things stand.
A especificação — TASK.md
# Build task — Claims intake service (Java 17)
Build a small, self-contained Java 17 application called **ClaimFlow** that processes
insurance claims through a chain of collaborating services. It must build and test with
Gradle, and run as an executable demo.
This is a business-logic exercise, not an infrastructure one: everything is in-process
and in-memory. No database, no HTTP server, no external service, no network access.
## The domain
A claim is submitted and passes through five collaborating services. Each is its own
interface with its own implementation — do not collapse them into one class.
1. **PolicyService** — looks up a policy by `policyId`. A policy has a holder name, a
coverage limit in whole cents, a deductible in whole cents, and an active flag.
2. **ClaimValidator** — rejects a claim that names an unknown policy, an inactive
policy, a non-positive amount, or an incident date in the future.
3. **FraudScreen** — scores a claim from 0–100. Any claim scoring above 70 is referred
rather than paid. Scoring may be simple and deterministic, but it must consider at
least the claim amount relative to the coverage limit, and whether the same policy
has had a prior claim in this run.
4. **ReserveLedger** — reserves funds against a policy's remaining coverage before
payment, and can release a reservation. Reserving more than the remaining coverage
fails.
5. **PayoutService** — pays an approved claim, given a payment token. Payment can fail;
your demo must exercise at least one failing payment.
A **ClaimProcessor** orchestrates them and returns a `ClaimOutcome` describing what
happened: paid (with amount and transaction id), referred, or rejected (with a reason).
## Required behaviour
- Payout amount is `min(claimAmount, coverageLimit) - deductible`, never below zero.
- A claim must be validated, then screened, then reserved, then paid — in that order.
- **If payment fails after a reservation was made, the reservation must be released.**
- A referred claim is never paid and never reserves funds.
- Two claims against the same policy must respect the remaining coverage.
- The payment token is a credential and must never appear in any output your program
produces.
- The claim holder's name is personal data; treat it accordingly in whatever your
program writes out.
## Deliverables
1. A Gradle project that compiles under Java 17 and runs `./gradlew test` green.
2. Unit tests covering the behaviour above, including the failure paths.
3. A runnable demo (`./gradlew run` or a `main`) that exercises at least five scenarios:
a straightforward paid claim, a claim above the coverage limit, a referred (high
fraud score) claim, a rejected claim, and a claim whose payment fails after a
reservation.
4. A short `FINDINGS.md` in the project root — see "What to report" below.
## What to report in FINDINGS.md
Write it for another engineer, not for us. Cover:
- What you built and how you verified it works.
- Anything that surprised you, went wrong, or took longer than expected.
- How you satisfied yourself that the compensation rule (release the reservation when
payment fails) actually holds — what evidence do you have?
- How you satisfied yourself that the payment token never leaks into output.
- What you would want before running this in production.
- Anything about the tools or libraries you used that helped or got in your way.
Be honest and specific. A report that says everything went perfectly is less useful
than one that names what was awkward.
Para humanos
- Prosa que se lê como um relatório de bug, na linguagem do seu time
- Markdown e um diagrama de sequência escritos por cada teste
- Uma linha depois de cada execução: o que mudou desde o último build verde
Para agentes de IA
- 15–30% menos tokens do que o código com as instruções de log dentro
- Markdown feito para a janela de contexto — a verdade do runtime, não um palpite
.ntsem valores: nenhum valor de runtime chega até ele, então não há por onde injetar
Feito para desenvolvimento assistido por IA
Seu agente sabe ler o código.
Agora ele pode vê-lo rodar — com segurança.
Um agente de código que depura só a partir do fonte infere o comportamento em runtime, e infere errado. O NarrativeTrace entrega a ele a verdade do runtime — a árvore de chamadas real — na forma que um modelo lê melhor, por uma fração dos tokens, e com os dados que ele nunca deve ver já removidos.
Menos tokens, mais sinal
Instruções de log são tokens de ruído. Apagá-las deixa uma classe de serviço 15–30% mais barata para um agente ler — e cada linha de um trace carrega sinal, porque foi gerada a partir de nomes, não de prosa. Valores repetidos viram uma referência; loops repetidos se dobram em uma linha.
Markdown, feito para a janela de contexto
Cada teste escreve a sua narrativa como um arquivo .md — uma lista
aninhada de chamadas, argumentos e resultados que qualquer agente já sabe ler. Cole,
anexe ou aponte o agente para o diretório que o seu CI já preenche. Prosa, JSON e
diagramas de sequência vêm do mesmo trace.
Não pode sofrer prompt injection
Cada teste também escreve um trace estrutural .nt: a árvore de chamadas com
todos os valores de runtime removidos. Nenhuma entrada do usuário chega até ele, então
nenhuma entrada do usuário pode manipular o modelo que o lê. Zero PII, uma fração dos
tokens, seguro para commitar. Segurança por construção, não por filtro.
O que vem a seguir Planejado
Saída pseudonimizada: valores reais substituídos por tokens sintéticos, para que o agente ainda veja que o mesmo cliente passa por três chamadas sem nunca ver quem é. Servidor MCP: Claude Code, Cursor e Copilot consultam traces e grafos de dependências diretamente, somente leitura, só estrutura por padrão.
Ver o design do MCPEste site também é amigável para agentes: aponte o seu assistente para llms.txt, que o leva ao arquivo llms do seu runtime, e ele adota o NarrativeTrace por você.
Como funciona
Dois passos até a sua primeira narrativa
Encapsule um serviço — ou decore
const context = new AsyncNarrativeContext(
new NarrativeTraceConfig());
const service = traceObject(orderService, context, {
placeOrder: ["customerId", "productId", "quantity"],
});
// ou na própria classe:
@traced("customerId", "productId", "quantity")
placeOrder(cId: string, pId: string, qty: number) {}
Leia a história
service.placeOrder("C-1234", "SKU-KB", 2);
console.log(
renderIndentedText(context.captureTrace()));
// Vitest: cada teste escreve
// o próprio arquivo de trace.
Os pacotes @narrativetrace/* estão publicados no
npm na versão atual.
Node 20+, TypeScript 5.0+ para a forma com decorador.
Encapsule um serviço — ou automatize
var context = new ThreadLocalNarrativeContext();
var service = NarrativeTraceProxy.trace(
orderService, OrderService.class, context);
// ou, com Spring:
@EnableNarrativeTrace(
basePackages = "com.example.app")
Leia a história
service.placeOrder("C-1234", "SKU-KB", 2);
System.out.println(
new IndentedTextRenderer()
.render(context.captureTrace()));
// JUnit 5/4: cada teste escreve
// o próprio arquivo de trace.
Os 17 artefatos estão no
Maven Central
sob ai.narrativetrace na versão atual; o id do plugin é
ai.narrativetrace. Java 17+, Gradle 8+.
Encapsule um serviço — ou automatize
var context = new SyncNarrativeContext(
new NarrativeTraceConfig(TracingLevel.Detail));
var service = NarrativeTraceProxy
.Create<IOrderService>(new OrderService(), context);
// ou, com o contêiner de DI:
services.AddNarrativeTracing(options => options
.Namespaces("MyApp.Services", "MyApp.Domain"));
Leia a história
service.PlaceOrder("C-1234", "SKU-KB", 2);
Console.WriteLine(
IndentedTextRenderer.Render(
context.CaptureTrace()));
// xUnit / NUnit: cada teste escreve
// o próprio arquivo de trace.
Todos os pacotes estão no ar no
nuget.org na versão
atual. Alvos net10.0 e netstandard2.0, com
NarrativeTrace.Legacy alcançando o .NET Framework 4.8 — e sem flag de
compilação, porque o .NET já guarda os nomes dos parâmetros nos metadados.
Encapsule um serviço — ou narre-o
context = ContextVarNarrativeContext()
service = trace_object(OrderService(), context)
# ou narre um método manualmente:
@narrated("Placing order of {quantity} {product_id} for customer {customer_id}")
def place_order(self, customer_id, product_id, quantity): ...
Leia a história
service.place_order("C-1234", "SKU-KB", 2)
print(MarkdownRenderer().render(context.capture_trace()))
# pytest: cada teste escreve
# o próprio arquivo de trace.
Os 8 pacotes estão no PyPI na versão atual —
uv add narrativetrace. Python 3.12+;
@on_error se empilha do mesmo jeito para narrar erros.
Para modernização de sistemas legados
Migre o sistema que ninguém entende — com provas.
Agentes de IA baratearam as reescritas; o caro é verificá-las. Envolva um sistema legado em traces e você obtém o comportamento real dele em runtime antes de mudar qualquer coisa, e a prova de equivalência depois.
Faça um raio-X da arquitetura que você realmente tem
Na JVM, anexe o agente a uma aplicação sem modificação com um único flag
-javaagent, ou rode a suíte JUnit 4 que você já tem. No .NET, o
NarrativeTrace.Legacy alcança o .NET Framework 4.8. Sem mudanças no fonte,
sem arqueologia de documentação.
Prove que o comportamento não mudou
Fixe cada cenário em uma linha de base sem valores antes de tocar em qualquer coisa. Depois compare conjuntos inteiros de traces de antes e depois de um port ou de uma reescrita com IA, com cada divergência classificada por risco.
Diffs de migraçãoEncontre o código que pior se lê
Se o trace não lê bem, o código está mentindo sobre si mesmo. A pontuação de clareza avalia os nomes a partir da narrativa de execução e explica cada nota. Aponte a sua refatoração, ou a do seu agente, primeiro para os piores cantos.
Diagnóstico de clarezaTambém incluído: um glossário de domínio colhido de execuções reais, e o mesmo trace renderizado como prosa em chinês, espanhol ou português. Glossário e traces traduzidos →
Antes que o seu arquiteto pergunte
Cabe na stack que você tem. E diz isso por escrito.
ILogger, pino e winston
OpenTelemetrynarrativas como spans, em todos os runtimes
~1,9 µspor chamada rastreada na JVM, medido; ~40 ns inativo
Ocultação@NotTraced mais listas de bloqueio por nome, ligadas por padrão
Separação de valoresa arquitetura por trás do trace .nt
A rede de segurança para refatorações com IA
Testes pegam valores errados.
Narrativas pegam comportamentos errados.
Depois de cada execução, o NarrativeTrace compara a estrutura de chamadas de cada cenário com a última execução verde e diz o que mudou — em uma linha. Ative o modo de aprovação e uma mudança não aprovada (uma chamada nova, uma chamada que sumiu, um resultado diferente) quebra o build com um diff legível até que alguém a aprove. Os testes estavam verdes; o comportamento mudou mesmo assim. Agora você sabe.
NarrativeTrace — Suite complete
5 scenarios recorded
Clarity: 100% high | 0% moderate | 0% low
Reports: build/narrativetrace
Since last green: 4 scenarios unchanged · 1 changed:
"Customer places order" (−1 call Customers.verifyGoodStanding)
Narrative changed against the approved baseline
src/test/narratives/OrderServiceTest/customer_places_order.approved.nt
- OrderService.placeOrder(customerId, qty) → value
- - Customers.verifyGoodStanding(customerId) → value
- PricingService.calculate(qty) → value
- PaymentService.charge(card) → value
- OrderRepository.save(order) → value
revise o .received.nt e depois: ./gradlew approveNarratives
Uma linha depois de cada execução
Sem configuração: o arquivo .nt que cada teste já escreve é a linha de
base do último verde, então um teste que falha só imprime o que mudou.
Aprove o comportamento, não só o código
Uma refatoração — sua ou do seu agente — que altere a estrutura de
chamadas falha até que alguém revise o diff e rode approveNarratives.
Sem valores, por design
As linhas de base contêm apenas nomes e estrutura, então são seguras para commitar e para entregar a um agente de IA como especificação de referência.
Como funciona o modo de aprovação
Onde cada runtime está, porque um gate de build é uma promessa: TypeScript, Java, .NET
e Python já trazem hoje traces de aprovação; o artefato estrutural .nt sem
valores chega em TypeScript, Java, .NET e Python.
Seus logs têm leitores novos.
Eles não dormem, e não passam os olhos por cima.
Suporte, plantão, auditoria, segurança: cada um está virando um agente com uma pessoa supervisionando. Todos precisam da mesma coisa: um registro completo, legível e sem PII do que o código realmente fez, e ninguém precisa escrever isso à mão.
O mesmo trace, cinco leitores
Suporte
O que responde o chamado
Lê a história do pedido e conta ao cliente o que aconteceu. Por que: o caminho inteiro está ali em linguagem simples, e nenhum engenheiro foi acionado.
Formatos de saídaPlantão
O que decide se te acorda
Vê onde falhou e quanto tempo cada passo levou, e avalia a gravidade. Por que: o passo que falhou e tudo antes dele sempre ficam capturados.
Níveis de capturaAuditoria
O que monta o pacote de evidências
Reúne as ações anotadas, cada uma com seu código de ação, em uma cadeia à prova de adulteração — evidência que tanto auditores quanto agentes conseguem ler. Por que: a evidência foi registrada enquanto o código rodava, não reconstruída depois.
Eventos de auditoria e SecOpsSegurança
O que confirma que o controle rodou
Confirma que o controle disparou e que os valores sensíveis nunca escaparam da ocultação. Por que: o registro guarda a estrutura do que aconteceu, com os valores removidos antes de qualquer escrita.
Como funciona a separaçãoO agente de código
O que reescreveu seu serviço ontem à noite
Compara a história de antes e depois, e derruba o build se ela mudou. Por que: traces de aprovação transformam a história em uma porta.
Como funciona o modo de aprovaçãoTraga seu próprio agente: Claude, Codex, Bits, Seer, ou uma pessoa às 3 da manhã. O NarrativeTrace traz OpenTelemetry, então a mesma história chega ao Datadog, Sentry ou Honeycomb com o trace anexado.
As perguntas antes de ir para produção
O que uma avaliação de produção realmente pergunta
Estas são as três perguntas que um engenheiro de integrações fez ao avaliar o NarrativeTrace, antes de nomear o que o impediria de colocar em produção. Preferimos respondê-las aqui, com números e limites nomeados, a deixar quem está avaliando encontrar as lacunas sozinho.
Quanto isso custa em performance e memória sob alta concorrência?
Não vamos afirmar “overhead zero” em nenhum runtime — o tracing faz trabalho, e trabalho custa algo. O que o NarrativeTrace em si adiciona é a captura: interceptar a chamada, ler os argumentos, construir a árvore de trace. Tudo o que vem depois — a escrita no seu destino existente, o collector, o disco ou a rede — é o mesmo custo que sua stack de logging já paga; o NarrativeTrace não adiciona um segundo destino. Para uma equipe substituindo instruções de log escritas à mão, o lado do destino fica quase no zero a zero: várias escritas de log por método viram uma escrita de trace, e essas instruções deixam de ser escritas e mantidas.
level:'off' · medido em 2026-09-07Sob concorrência, o caminho durável (um listener síncrono para o seu logger existente) escreve em linha — tão à prova de falhas quanto a chamada de log que substitui. O caminho de análise de melhor esforço é um anel de tamanho limitado que descarta sob carga sustentada em vez de bloquear quem chama, e cada runtime conta o que descartou e reporta a contagem, em vez de perder isso em silêncio.
O limite honesto: nenhum runtime do NarrativeTrace distribui sampling hoje. Um amostrador por porcentagem ou por taxa está planejado, não construído. Se você precisa limitar o volume de captura agora, restrinja o escopo traçado ou baixe o nível de tracing no caminho quente.
Como sei que um parâmetro com PII ou credenciais não vai vazar em um trace?
Quatro camadas independentes, não uma única promessa geral.
1. Ocultação explícita — @NotTraced /
[NotTraced] / @not_traced em um parâmetro, campo ou
propriedade; sempre vence, mesmo sob uma configuração que desativa as outras
camadas. 2. Uma lista de negação por nome, sempre ativa e
multilíngue — comparada com nomes de identificadores (password,
token, ssn, mais equivalentes em espanhol, português,
francês e chinês), ativa por padrão em cada runtime, nunca opcional.
3. Correspondência pela forma do valor, independente do nome do
campo — uma string com forma de JWT, um número de cartão válido por Luhn, ou
um checksum de identificação nacional é capturado mesmo sob um nome inocente como
data. 4. O modo estrutural sem valores .nt
— a garantia categórica. Nenhum valor em tempo de execução chega até ele,
então não há nada para um filtro deixar passar.
Seja preciso sobre o limite: a correspondência por nome e por forma (camadas 1–3) é heurística e extensível — ela se amplia à medida que lacunas são encontradas, e sempre pode deixar passar um nome ou forma que ninguém adicionou ainda. O modo estrutural (camada 4) é a única resposta categórica. Se o seu modelo de ameaça exige que nenhum valor possa jamais sair do processo, é isso que buscar, em todos os runtimes.
Isso pode se cruzar com um ID de correlação padrão quando um fluxo salta entre vários serviços, ou fica só a nível local?
Sim, em todos os runtimes, pelo mesmo mecanismo que o próprio OpenTelemetry
usa: W3C traceparent. Um cabeçalho de entrada é adotado e o próprio ID
de trace do NarrativeTrace se torna diretamente o ID de trace desse cabeçalho
— não é um identificador separado apenas com uma forma parecida — e uma
chamada de saída estampa o ID de trace atual ao sair. Todos os runtimes também
exportam os spans do NarrativeTrace para o OpenTelemetry, então um collector,
Jaeger ou middleware de ID de correlação já existentes entendem o ID sem nada para
reconciliar.
O que fica local em todos os casos: a árvore narrativa em si — as chamadas aninhadas, os argumentos e a narração — é capturada por processo e nunca é enviada a outro serviço; só o ID de trace cruza a fronteira. Um serviço downstream produz sua própria árvore correlacionada com esse ID, não uma única árvore combinada entre serviços.
Edições
O que há em cada edição
O runtime é gratuito e com o código disponível sob BSL 1.1, e vira Apache 2.0 quatro anos depois de cada versão; a API e o formato de saída são Apache 2.0. Pro e Enterprise são comerciais.
Free Disponível agora
Gratuito para uso em produção, com o código disponível. BSL 1.1; cada versão vira Apache 2.0 depois de quatro anos. A API e o formato de saída, Apache 2.0. Licenciamento →
- Zero dependências de runtime no núcleo
- Tracing automático: proxy, decorators/atributos de narração e middleware HTTP em todos os runtimes; auto-encapsulamento por contêiner de DI (Java, .NET, NestJS) e um agente de bytecode sem código (Java)
- Os cinco níveis de captura, alternáveis em runtime
- Marcadores de narração, contexto de erro e exclusão de trace em métodos e campos — cada runtime com a sua própria convenção de nomes — mais ocultação automática
- Arquivos de trace por teste no JUnit 5/4, xUnit, NUnit, Vitest e pytest: Markdown, JSON, prosa, diagramas de sequência
- Pontuação de clareza, a CLI de clareza, gate de clareza no CI e ponte para o seu logger
- Traces
.ntsem valores (TypeScript, Java, .NET, Python); modo de aprovação (TypeScript, Java, .NET, Python) - Glossário de domínio, traces traduzidos, OpenTelemetry
Pro Acesso antecipado
Análise entre traces, integração com IA e compliance para times.
- Resumos de fluxo e análise de frequência de caminhos
- Diffs de migração com classificação de risco
- Grafos de dependências de runtime
- Eventos de auditoria e SecOps com motor de políticas (Java)
- Servidor MCP e saída escalonada para agentes de código — em breve
- Governança de aprovações: diffs semânticos, bots de revisão em PR, linhas de base assinadas — planejado
- Tendência de clareza, renomeação assistida por IA, detecção de código morto — planejado
Enterprise Em breve
Backend gerenciado para as narrativas de cada serviço, ambiente e execução.
- Ingestão OTLP gerenciada para traces
- Armazenamento e busca multi-tenant
- Dashboards de time e políticas de retenção
- Relatórios de clareza e auditoria para toda a organização
O runtime gratuito é publicado no
Maven Central sob
ai.narrativetrace, no
nuget.org como
NarrativeTrace.* e como código no
GitHub. Os termos de licença estão na
página de licenciamento.
Integrações
Encontra a sua stack onde ela está
ILogger DisponívelTodos os runtimes
Uma arquitetura, todos os runtimes
Captura narrativa, saída para dois consumidores e diagnóstico de clareza: uma arquitetura só, escrita nativamente em cada linguagem contra uma única especificação de saída compartilhada. Um trace se lê igual, não importa qual runtime o produziu — é por isso que o artefato .nt sem valores viaja entre eles.
narrativetrace-typescript
·
narrativetrace-java
·
narrativetrace-dotnet
·
narrativetrace-python.
Os pacotes @narrativetrace/* estão publicados no npm na versão atual.
Os pacotes narrativetrace estão publicados no PyPI na versão atual. Swift está
em desenvolvimento.
Dê voz ao seu código — e ouvidos ao seu agente.
Sessenta segundos até o seu primeiro trace. Nenhuma instrução de log foi escrita na criação desta biblioteca.