devils.md

The devil is in the details.

A Detail Devil document is a single Markdown file that tracks a project's last-mile details — decisions and plain matters of fact alike, asked as questions — as a dependency graph. It exists to catch the thing ordinary documents hide: an answer that rests on something nobody has settled yet.

The whole format is one rule

A question is resolved when it has an answer and every question it depends on is resolved.

Everything else follows. Because the rule tests two facts, every question in a document is in exactly one of four states — and one of them has no name in ordinary project tracking:

all dependencies resolvedsome dependency unresolved
answeredResolvedProvisional
unansweredReadyBlocked

Provisional is the devil. It is an answer standing on ground that is still open — the decision someone made by quietly assuming something nobody had settled. Teams produce these constantly, and nothing in a normal document or issue tracker makes them visible.

Ready is the other half of the payoff: the questions that can usefully be answered right now, because nothing is in their way. It is a work queue you never have to maintain, and it makes a decent meeting agenda.

What a document looks like

DEVILS.md

# Can we launch v1.0 publicly?

## Which email provider?

Answer: Resend on port 2587 —
DigitalOcean blocks 587.

Assumes [[who pays for infra?]]
lands under $20/mo.

## Who pays for infra?

Need to ask before committing
to a paid tier.

## Do we show contact emails?

### Answer

Yes, on ride cards, to anyone
signed in.

What a reader computes

Who pays for infra?Ready
Which email provider?Provisional
Do we show contact emails?Resolved
Can we launch v1.0?Blocked

Nobody wrote any of that down. The states are computed from the file every time it is read, which is why the file cannot misreport its own progress — it records only what a human asserted.

Four constructs, no new syntax

Cycles are allowed, because the venue really does depend on the headcount and the headcount on the venue. They are reported as a set to decide jointly rather than rejected — a format that refuses an honest cycle only teaches its authors to write dishonest documents.

Details, not roadmaps

The format is deliberately low-level — the name is the scope. A question may be a decision (which email provider?) or an empirical fact (how many people are coming?); what the format tracks is not deliberation but open-ness. Roadmaps, milestones, and prioritization belong in other tools, and a broad question appears in a document only as the root that details hang from. This is for devil-in-the-details problems: the last mile, not the plan.

Start one

Add a DEVILS.md to the root of your project, and open it with this preamble so that anyone — or any agent — who meets the file cold knows how to read it:

> **What this file is.** The unsettled details of this project — decisions and
> plain matters of fact alike — tracked as questions, and what depends on what.
> A heading ending in `?` is a question; the block marked `Answer:` beneath
> it is its answer.
>
> **The part that isn't obvious.** A question also depends on every question
> nested beneath it, and on any question it names in `[[double brackets]]`. It
> counts as resolved only when it has an answer *and* everything it depends on is
> resolved too. So an answered question sitting on unanswered ones is an
> assumption, not a decision — making those visible is the point of the file.
>
> Format spec: https://devils.md

Then write questions. That is the entire onboarding.

Tooling

This repository carries a reference implementation in dependency-free Ruby — one file, no gems, and a reporter that reads any document:

$ bin/devils DEVILS.md

devils.md — 16 questions: 9 resolved, 2 provisional, 3 ready, 2 blocked

Provisional — answered on open ground (2)
  Is the format specified?
    rests on Do references in a plain section's block declare a question?
    rests on May a reference span a line break?

Ready — answerable now (3)
  Do references in a plain section's block declare a question? (unblocks 4)
  May a reference span a line break? (unblocks 4)
  How do people discover the format? (unblocks 1)

It also computes a trace for any unresolved question — the answer to "why isn't this resolved?" — and leverage, the number of questions waiting on it, which ranks the Ready queue for you.

A second implementation, in dependency-free JavaScript, was written clean-room from the specification as a test of its precision; the two are cross-checked against the same documents. What that exercise surfaced is tracked in the project's own DEVILS.md.

Design principles

  1. Assertions in, state computed. A document may not record whether a question is resolved, so it cannot misreport itself.
  2. Git is the provenance layer. No author, created, or modified fields. The substrate already has them.
  3. Fail toward unresolved. Where a construct is ambiguous, the reading that leaves a question open is the correct one. A tracker that wrongly reports "resolved" is worse than useless.