Breadcrumbs
Breadcrumbs adds traceability to spec-driven development, whatever
approach you use. Specs carry links and claims, and the claims are
checked against the code with a plain line match, so a stale spec
shows up after the fact, by hand or with bcr.
The problem
Code says what a repository does, not why. The why lives in tickets, chats, design documents and people's heads, and it drifts away from the code without anyone noticing. A document that once described the code keeps reading as true after the code has changed.
Later, nobody can tell whether the code still does what was asked of it, or which decision a piece of code was meant to carry out.
How it works
Code stays the source of truth for what the repository does. The documents that hold its intent, such as decisions, specs and tasks, each carry a breadcrumb: a few lines of YAML front matter that say what the document is, which documents it links to, and what it claims about the repository's files.
---
breadcrumb:
id: verify
type: spec
links:
- constrained_by ADR-0016
claims:
- 'docs/bcr.md has-line ### verify'
---
idnames the breadcrumb, andtypesays what kind of document carries it.- Each entry of
linksis a verb and the id of another breadcrumb. - Each entry of
claimsis a file, a kind of claim and its argument.
The toolkit, bcr, reads the breadcrumbs, checks that their ids are
unique and their links point to a breadcrumb, and checks each claim
against the files. Each breadcrumb then gets one of three verdicts:
- Confirmed: all of its claims hold.
- Refuted: one of its claims fails. The document and the file disagree. Either the code drifted from the intent, or the claim went stale because the intent changed or its target moved; a person decides which.
- Undecided: it has no claims, or it has a problem. Nothing about it was checked.
The only kind of claim is has-line: the file has a line equal to
the text, once the spaces and tabs at the line's start and end are
removed. It is a text match. Confirmed means the line is there, not
that the document is right.
The report
bcr report turns the verdicts into one page: every breadcrumb with
its verdict, every problem, every claim, and a diagram for each spec.
A diagram shows a spec, the breadcrumbs it links to and those that
link to it, each with its verdict. A Refuted one is outlined in red,
so drift is seen at a glance. GitHub draws the diagrams in a Markdown
file.

The filter spec in Breadcrumbs' own report, the morning it was
specified: its claim on the documentation was Refuted until the
documentation landed, 17 minutes later.
How to make one, and what each part of it means:
bcr report.
Honest scope
Breadcrumbs makes drift visible after the fact; it does not prevent it. It lets drift happen, and shows where a document and a file disagree.
A breadcrumb describes the code and never replaces it. What it holds is what code cannot: why.
A repository records as much or as little as its owners choose, and a
claim can be checked by hand, against the files, without bcr.
Try it
bcr is a single Go binary. Install it with Go 1.22 or later:
go install github.com/rodolfo-mendes/breadcrumb-sdd/cmd/bcr@latest
Put a breadcrumb at the top of one file, here notes.md:
---
breadcrumb:
id: notes
type: note
links: []
claims:
- 'notes.md has-line # Notes'
---
# Notes
Then run four of the commands of bcr as a pipe, on that file:
bcr extract notes.md | bcr verify | bcr audit | bcr report
bcr extractreads each breadcrumb and prints it as records.bcr verifychecks the whole set: unique ids, and links that point to a breadcrumb.bcr auditchecks each claim against the files, and gives each claim and each breadcrumb a verdict.bcr reportwrites one Markdown page: every breadcrumb by verdict, and every problem.
The page lists notes as Confirmed. Change the heading of notes.md
and run the pipe again: it is Refuted.
To set a whole repository up, run bcr init in its
root. Every command, record, output and exit code is in the
documentation.
Who it's for
People who build software with AI agents writing most of the code, first a solo builder or a small team, most often in a repository that already exists and adopts spec-driven development a piece at a time. Many keep agents to small, local changes, and hold back from writing specs they expect to drift soon after. Months later they need to know whether the code still does what was asked, and which decision a piece of code was meant to carry out. They will not keep up a heavy process to find out.
Breadcrumbs is not a spec-driven development method. Teams already have several, and some build their own; Breadcrumbs adds what they lack, the links and claims that make drift between a repository's intent and its code visible, to whichever method a repository uses.
Adopting Breadcrumbs should cost as little as possible: one binary and a few lines of front matter, with no service to run.
Status
The released version is v0.9.0; each release is on the releases page.
Before 1.0, a command, a flag or an output may still change between releases; a breadcrumb's keys and a kind of claim keep their meaning.
Deferred: has-line is the only kind of claim there is.
The repository of Breadcrumbs is developed with Breadcrumbs itself: its decisions, specs and tasks each carry a breadcrumb, and every push audits them.