Adr Writer logo

Adr Writer

Community
llopresto87
adr-writer

Author an Architecture Decision Record that captures a non-obvious technical choice — its context, the decision, the consequences, the rejected alternatives, and the reversibility cost. Use whenever a non-trivial dependency is picked, a framework is chosen, a one-way door is opened, two specialists disagree and the orchestrator must pick, or anyone in a future session would ask "why did we do this?" An ADR exists so the answer is on disk, not in someone's head. Its lifecycle status lives in frontmatter in the schema's one vocabulary (proposed, accepted, open, deferred, hotfix, rejected, superseded, closed); superseding is a new ADR plus a status flip on the old — never an edit of its body.

Overview

Publisherllopresto87
RepositoryCypress
Skill nameadr-writer
Stars
113
Forks
6
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by llopresto87 on GitHub. Read the source before you install it.

Installation

Install the Adr Writer AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/llopresto87/Cypress/tree/main/skills/adr-writer
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/llopresto87/Cypress.git /tmp/Cypress
mkdir -p .claude/skills
cp -r /tmp/Cypress/skills/adr-writer .claude/skills/adr-writer
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Adr Writer in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Adr Writer on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Adr Writer is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

adr-writer

ADRs (Architecture Decision Records) live in docs/graph/decisions/ and record every non-obvious technical choice. Each is a short, recorded answer to "why did we pick this?"; a design doc is a different artifact.

This skill encodes the discipline of writing them well.

When to apply this skill

  • A new dependency is being committed to (the wiki page handles the what; the ADR handles the why).
  • A framework, language, or platform is being chosen.
  • A one-way door is being opened (data model, public API contract, vendor lock-in).
  • A boundary between two services or modules is being drawn.
  • Two specialists disagreed and the orchestrator picked an option.
  • A bug post-mortem revealed an implicit decision that should have been explicit.
  • A T2 contained-lane change made a real choice among options and owes its why-record (tiers.contained-lane). Write the short form: Context, Decision, Consequences, Reversibility, the sections that carry the why. Skip Alternatives when none were weighed, and say so in one line. A contained change whose why needs every section was misclassified: hand it back for T3.
  • Anyone asks "why did we do it this way?" and the answer isn't in an existing ADR.

ADR numbering and status

ADRs are numbered monotonically: adr-NNNN-short-slug.md. Find the next free number in docs/graph/decisions/ and in the index, because a number can be taken without a file. Each number names one decision for good, because citations outlive files.

A number allocated to a decision that is owed but not yet written (a spec reserves it, or the owner has not ruled yet) gets an index row marked reserved or owed, naming who owes the body. The index row is the whole reservation, because a stub ADR file is fiction that satisfies a linter. The reservation holds even when the decision is abandoned. Where a program keeps more than one ADR series (one per repository, say), a citation names the series as well as the number, so two ADRs with the same number cannot be confused.

Status lives in frontmatter, in the schema's lifecycle vocabulary (docs/graph/_schema.md §"Lifecycle status" is the home; read it for the meanings): status: proposed | accepted | open | deferred | hotfix | rejected | superseded | closed, always with status_date, plus the companion the value requires: owner while open | hotfix | deferred, reopen_when when deferred, status_evidence when closed, superseded_by when superseded. The body's ## Status section is a pointer to the frontmatter; a body value that disagrees is a lint failure (python3 docs/graph/status-register.py --root docs/graph), the drift the register exists to catch. An ADR is born proposed and becomes accepted when the owner ratifies it (the grill.md §6 row); the base values apply as the schema defines them: a "do nothing now" decision parked behind a named trigger is deferred with reopen_when, a choice taken under pressure that owes a proper decision is hotfix with an owner.

To replace a decision, write a new ADR with a new number and status: accepted, and set the old ADR's frontmatter to status: superseded + superseded_by: ADR-NNNN + a fresh status_date. A ratified ADR's body is never rewritten (the append-only exception in holistic-editing). Besides the supersede flip it takes one other change: when the decision stands but a fact in its context or reasons proves false, or execution reached the decision by a route the body does not describe, a dated ## Correction is appended after the body, stating the corrected fact with its evidence and a pointer, and the text above it stays as written. When the decision itself moves, supersede it. To see what is still owed: python3 docs/graph/status-register.py --by-kind adr --open --hotfix (add --deferred for parked decisions). The register is the query surface; the index at docs/graph/decisions/README.md is the human table.

The template (4 sections that matter most)

Use docs/graph/templates/adr.template.md. Its frontmatter is the status home (above); the four body sections that earn their keep:

Context

What is the situation that forces a decision? Include the constraint that makes "do nothing" not viable. Cross-link to grill.md and the relevant spec.

Bad: "We need a database."

Good: "Spec SPEC-0003 requires submissions to persist across restarts. Grill.md §4 caps p95 latency at 200ms and cost at $X/month. The current implementation uses an in-memory map, which loses state on restart. We need to choose a persistent store."

When the owner states how an external arrangement works (a partner handles a class of requests, a contract covers a duty), record it as a declaration attributed to them, in their words where they matter, and name what it leaves open. Conclusions drawn from it, legal ones above all, are agent.legal's to reach against its corpus; until then the ADR records the question as owed.

Decision

What we have decided, in one sentence. Optionally a short paragraph naming the central tradeoff. A sentence that holds several decisions is several ADRs: split it.

Bad: "We'll use PostgreSQL."

Good: "We will persist submissions in PostgreSQL 16, using the managed instance on platform X, accepting an additional ~$45/mo in exchange for ACID guarantees and ecosystem maturity over the in-memory alternative."

Consequences

What changes downstream. Be concrete:

  • New constraints (e.g. "migrations now belong in migrations/ and run on deploy").
  • Migration or rewrite cost if reversed.
  • Effect on the verification plan (new gates, integration tests against a test database).
  • Effect on the wiki (new library to wikify: the database driver and the migration tool).

Alternatives considered

For each rejected alternative: one paragraph naming the alternative and the concrete reason it lost, because "not as good" tells the next agent nothing.

Bad: "SQLite — not as good for our use case."

Good: "SQLite — rejected because grill.md §4 requires concurrent writes from multiple workers; SQLite serializes them and would violate the 200ms p95 budget at the projected request rate."

Reversibility tag

Every ADR tags reversibility as one of:

  • reversible: can be changed in a single session without data migration.
  • expensive: can be changed but requires a multi-day project.
  • one-way: changing it later requires a rewrite or a migration on live data.

The tag tells the next agent how much weight the decision carries. one-way ADRs get extra scrutiny. They are the ones where the "alternatives considered" section earns its keep: the next agent needs to understand why the alternative was rejected, not just that it was.

What counts as a decision

An ADR records a choice that was made. An implementation detail reconstructed from source is an observation: record it where observations live (a node, a runbook) with its rationale marked "not recorded". A survey that turns up no genuine decisions leaves the index empty and says so, because the next agent trusts every ADR it finds, and a fabricated one is worse than a missing one.

Four decisions people forget to record, because they feel like inaction:

  • "Do nothing now" is a decision. Ratifying a destination while taking no code yet, deferring the first increment behind a named, checkable trigger, is an ADR. Separate the destination (which end-state is correct) from the timing (what licenses starting), and state what makes waiting safe ("the drift is now tested, not invisible"). Its frontmatter is status: deferred with reopen_when: naming that trigger, so the register lists it among what is parked.
  • The asymmetric cost of being wrong is often the whole rationale. Record what being wrong costs in each direction ("wrong on X risks an irreversible incident; wrong on Y costs a bounded, recoverable delay") and let the asymmetry decide, rather than arguing which option is abstractly "best".
  • Declining a fix is a decision. When the owner accepts a residual risk instead of remediating it, the ADR says plainly that nothing is remediated by it; what it changes is the finding's standing, not the measurement. It separates exactly what is declined from what is not. An implemented-but-unverified control is a different finding from an unremediated one; name which each item is, because a record that blurs the two misleads both ways. It names the residual in plain terms and its register row, lists any compensating control with what that control does not cover, and quotes the owner's constraints and the attesting person. It states the revisit trigger, or states that there is none; a qualifier like "for now" in the acceptance is kept, because it makes the standing expire. What a declined fix is in the register, and when a standing acceptance becomes a deviation node, is method.incident-posture §6, its one home; link it.
  • A declared no-go area is a decision. When the owner puts a repository, system, or environment off limits, the ADR states the boundary exactly: which commands are barred (read-only ones included, if the owner said so), and which nearby configuration that lives elsewhere stays in scope. A contradiction seen inside the boundary before it closed is recorded not recorded; the owner's boundary outranks settling it with a probe. The consequences say that the graph's facts about the area are frozen at their last pin and must be presented as historical. Its standing form is a deviation node (docs/graph/nodes/_deviation.template.md).

Workflow

  1. Find the next free number. Read the most recent few ADRs to match the project's tone.
  2. Copy docs/graph/templates/adr.template.md to docs/graph/decisions/adr-NNNN-<slug>.md, and fill the frontmatter: status: proposed (or accepted when the owner has already ratified), status_date, and the companion the value requires. Leave the body ## Status as the pointer it is.
  3. Fill Context first. If you can't write the context, you don't yet know what decision you're making.
  4. Fill Decision in one sentence. If you can't, the decision isn't yet made; back up to research or brainstorm.
  5. Fill Consequences concretely, with file paths and budget impacts where applicable.
  6. Fill Alternatives considered: at least one alternative, usually two or three, each with a concrete rejection reason.
  7. Fill Reversibility and, if expensive or one-way, name the cost in concrete terms.
  8. Cross-link: spec, grill.md, wiki pages, external sources.
  9. If this ADR replaces one: set the old ADR's frontmatter to status: superseded + superseded_by: ADR-NNNN + status_date, and nothing else in it.
  10. Add a row to docs/graph/decisions/README.md (the index).
  11. Add a row to grill.md §6 with the ADR's identifier; when the owner ratifies, flip the frontmatter to accepted with a fresh status_date. If what shipped departs from a proposed ADR, the as-written text is not what gets flipped to accepted: record the difference between as-written and as-shipped next to it (its index row) and owe the amendment to the ADR's author. The close-out leaves the body as written.
  12. Before the status flips to accepted: the body is prose a person reads in a year. Apply docs/graph/skills/humanizer.md in file mode and run python3 docs/graph/prose-lint.py --file <adr> --against HEAD; a strong tell or a dropped number, heading, or code span blocks the flip.

Reference files

  • docs/graph/templates/adr.template.md: the template.
  • docs/graph/_schema.md §"Lifecycle status": the vocabulary and its companions; docs/graph/status-register.py: its lint and query.
  • docs/graph/agents/01-architect.md: the agent that primarily writes ADRs.
  • docs/graph/templates/docs/ + decisions/README.md: the index template installed at docs/graph/decisions/README.md.

Frequently asked questions

What does the Adr Writer AI skill do?

Author an Architecture Decision Record that captures a non-obvious technical choice — its context, the decision, the consequences, the rejected alternatives, and the reversibility cost. Use whenever a non-trivial dependency is picked, a framework is chosen, a one-way door is opened, two specialists disagree and the orchestrator must pick, or anyone in a future session would ask "why did we do this?" An ADR exists so the answer is on disk, not in someone's head. Its lifecycle status lives in frontmatter in the schema's one vocabulary (proposed, accepted, open, deferred, hotfix, rejected, sup...

Why use Adr Writer on TypingMind?

Because you install it once and use it with any model. Adr Writer is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Adr Writer in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/llopresto87/Cypress/tree/main/skills/adr-writer. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Adr Writer?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Adr Writer?

As many as you like. As long as a model supports skills, you can use Adr Writer with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Adr Writer AI skill free?

Yes. It is published on GitHub by llopresto87 under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇