How to
How to write an ADR with an AI agent
A decision record is context, options, decision, consequences. Give the agent the options and the question; it writes the record with a block for each part, runs chiltepin check, and hands back a proposal you can review as a diff.
1. Give the agent the request
Install the skill once — npx skills add jdiejim/chiltepin -g — then say what the reader needs, in plain words. Do not name a block type; picking it is the skill's job.
Compare the three caching options we discussed: Redis, Memcached, and an in-process LRU. Recommend one, write it as a decision record in docs/adr/caching.md, and run chiltepin check.
Naming the options keeps the agent honest — it compares what you discussed, not what it would have chosen. “Decision record” is enough for the skill to reach for the ADR shape; chiltepin new adr scaffolds the same shape by hand.
2. What the agent picks, and why
The skill reads the request as the reader's question and answers it with two to five blocks, each a different lens. For this request it picks:
drivers— the forces — the constraints and goals that make this a decision at all, each with a tag and a weightoptions— the comparison — every option with how it works, its pros and cons, and a verdict, side by sidecallout— the decision — one paragraph, tone: note, so the answer is impossible to miss when the record is skimmedrisk— the consequences — what could go wrong after the decision, with likelihood, impact and an owner
Before writing each one it runs chiltepin block <type>, which prints the fields, enums and terse forms from the schema. It writes YAML; it never places a shape.
The block it wrote
The options block an agent wrote for the caching comparison in the gallery, unedited: three options, how each works, pros and cons, a verdict on each.
```options
title: Three ways to cache product-detail reads
items:
- { kicker: Option 1, title: Redis, how: "One managed Redis cluster shared by all replicas. Cache-aside reads; price changes publish an invalidation on a Redis channel.", pros: ["One copy of the hot set, every replica sees the same value", "Pub/sub carries invalidations in under 100 ms", "Sorted sets and hashes fit the related-products list", "Persistence survives a restart without a cold start"], cons: ["Every hit pays a network round trip", "One more managed service to page on", "Single-threaded command path caps a node near 100k ops/s"], verdict: "CHOSEN — meets the 2-second invalidation rule with the least memory", tone: chosen }
- { kicker: Option 2, title: Memcached, how: "One managed Memcached pool shared by all replicas. Cache-aside reads; price changes delete the key on every pool node.", pros: ["Lowest per-hit latency of the network options", "Multi-threaded, scales with cores", "Smallest memory footprint per key"], cons: ["No pub/sub, so invalidation is a client-side fan-out", "Values are opaque bytes, no partial updates", "No persistence, so a pool restart is a cold start"], verdict: "VIABLE — kept as fallback if Redis throughput becomes the limit", tone: viable }
- { kicker: Option 3, title: In-process LRU, how: "Each replica keeps its own bounded LRU map in Node.js heap. Price changes reach replicas through a Kafka topic that each replica consumes.", pros: ["Microsecond hits, no network hop", "No new service to run", "Zero cost for the cache itself"], cons: ["Six copies of the hot set, 12 GB of replica memory", "Each replica warms alone, so hit rate drops after every deploy", "Invalidation depends on Kafka consumer lag, measured at up to 6 seconds", "A 2 GB heap raises GC pause time"], verdict: "REJECTED — fails the 2-second invalidation rule and multiplies memory by replica count", tone: rejected }
```3. Check it
The agent runs npx -y chiltepin check docs/<file>.md --json. Every diagnostic has a stable code, the file and line, and a hint. One it might see on a first draft:
E_PARSE_YAML docs/adr/caching.md:24 options: Block collections are not allowed within flow collections at line 3, column 44
hint: Often an unquoted special character (, : # | & *). Wrap the value in quotes.It fixes what the hint says and re-runs the check. A change is not done until the check passes — and in CI the same command fails the build, so a document cannot drift silently.
4. Render it
npx chiltepin html docs/adr/caching.md -p renders the record. chiltepin build publishes every ADR under one navigation with its status and cross-links resolved. For an architecture review, chiltepin slides makes the record a five-slide deck — forces, options, decision, consequences — with no extra authoring.
See it done
The agent-written document for this request is in the gallery: Cache options for the Catalog API, shown exactly as generated from “Compare the three caching options we discussed: Redis, Memcached, and an in-process LRU.”. Related: software design documents, the ADR template, and the blocks drivers, options, risk.
Frequently asked questions
- What goes in an ADR?
- Context (what forced the decision), the options considered with their trade-offs, the decision, and its consequences — plus a status line that moves from Proposed to Accepted to Superseded. Chiltepin gives each part a block: drivers for the forces, options for the comparison, a callout for the decision itself, and risk or steps for consequences. The ADR template (chiltepin new adr) is a finished record about a real-looking system, not a form.
- Why not just write the ADR in plain Markdown?
- You can; the prose is still Markdown here. The blocks add what prose cannot: a comparison that renders the same way every time, a decision that stands out, and a structure chiltepin check can verify — every option has pros and cons, every referenced diagram exists. Reviewers read a shape they recognise across every record.
- Can the agent decide for me?
- It can recommend, and the request above asks it to. The record still reads as a proposal until you change the status. The value is that the options are laid out side by side with the reasons, so the review is about the trade-offs rather than about formatting.
- How do I link the ADR to the architecture it changes?
- Give the architecture block an id and reference it as doc#id from the ADR; chiltepin check fails on a dangling reference and chiltepin build turns it into a link. A superseded record points at its successor the same way.