Retract a premise, and the build tells you what rested on it
Write down why you decided something. Cite that decision by code wherever it
does work. Later, change your mind — mark it Rejected, or Superseded, or
Deferred.
Every place that leaned on it now fails the build.
$ luria lint
luria: 2 warning(s) — retired documents cited unacknowledged
ADR-012 is Superseded, cited 6× in 4 file(s) — Cache invalidation is time-based
ADR-019 is Rejected, cited 2× in 2 file(s) — Workers own their own retry policy
luria: 1 violation(s)
docs/scaling.md:88: ADR-012 is not a link — run `luria link --fix`
Not "this file is out of date." These four files argue from something you no longer believe, and here they are.
This is a truth maintenance system
Not a metaphor. A truth maintenance system — Doyle, 1979 — holds a set of beliefs together with the justifications linking them. Each node is IN or OUT. Retract a belief, and the system propagates to every node whose justification depended on it.
Luria is that, with three differences that make it usable by people:
- The nodes are documents you wrote. The justification graph is a side effect of citing premises by code instead of by paraphrase.
- Propagation stops at a finding. A classical TMS marks a node OUT automatically. Whether a withdrawn premise actually kills the argument resting on it is a judgment, so luria fails the build and waits for you.
- Acknowledgement is first-class.
<!-- inactive-ok: ADR-012 — the decision this one replaces -->says I know, and I mean it. Most findings resolve that way, and a suppression that stops applying reports itself.
If you know the literature: a JTMS with linter-style suppressions, enforced in CI. Retraction is AGM contraction. The industrial cousin is requirements traceability with impact analysis. We say so plainly rather than inventing a word — the reasoning is in ADR-058.
Why bother
A repository's real memory is not in its documentation. It is in the arguments people had, the alternatives they rejected, and the constraints they found the hard way — and that lives in review threads and in the heads of whoever was there. When they leave, you re-litigate it. When an agent joins, it has no access at all.
Writing decisions down is the well-known half. The half nobody does is keeping them honest. Documentation rots not by becoming wrong but by staying confidently right about a world that moved, and the only thing that reliably stops it is a check. Every convention here governed by prose alone has drifted; every one guarded by an executable check has held. That finding is DP-5, and it is why this exists.
Sixty seconds
$ pip install luria
$ luria init # scaffold record/ and docs/ into the current repo
$ luria new adr # a decision, numbered and templated
$ luria link --fix # a bare `ADR-004` in prose becomes a link
$ luria index # regenerate every view from the frontmatter
$ luria lint # exit 1, one line per violation
Then the quickstart, which gets you to a real finding in about fifteen minutes.
What it looks like in a repo
luria.toml what schemes exist, what gets scanned, what fails
record/ the WRITE surface — hand-edited, one file per record
decisions.d/
ADR-001.md frontmatter (status, title, tags) + prose
_template.md what `luria new adr` copies
tags.yaml what each tag means
statuses.yaml what each status means IN THIS SCHEME
docs/ the READ surface — indexes, tag pages, reports
decisions/README.md generated; never hand-edited
reports/ what is pending, what is cited but retired
You write in record/. Everything under docs/ is derived, and a stale view
fails the lint rather than sitting there quietly wrong.
More than decisions
ADR is one scheme, not the product. A scheme is a family of numbered
records with its own directory, template, tag vocabulary and status meanings,
and luria.toml is where you declare as many as you need.
One project reading a corpus of philosophical arguments runs six: claims, arguments, concepts, positions, decisions, principles. Its arguments cite claims as premises, so retiring a claim surfaces every argument built on it — the same engine, pointed at a body of ideas instead of a codebase.
Schemes covers designing your own.
Documentation
| Quickstart | fifteen minutes, ending in a real finding |
| Concepts | the model: records, status, citations, propagation |
| Schemes | record families beyond decisions |
| CLI reference | every command and flag |
| Configuration | every luria.toml key, generated from the schema |
| Directives | the acknowledgement vocabulary |
| Adopting | bringing luria to a repo that already has history |
| In practice | three real records compared, and what drove each choice |
| Python API | using it as a library |
| Project memory | the doctrine: four layers, and what goes where |
| Contributing | how this repo works on itself |
This repo eats its own cooking
The badges above are generated from this project's own record. needs decision
counts documents sitting at Proposed or Deferred; cited, not in force
counts references to retired documents nobody has acknowledged. They are
sometimes non-zero on purpose — a project whose own reports always read clean is
one whose reports are not wired to anything.
The decision record is every choice this package made and the alternatives that lost. The devlog is what went wrong on the way.
License
MIT.
Release files for luria 0.4.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| luria-0.4.1.tar.gz | 231.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| luria-0.4.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 396.3 kB
Release files / luria-0.4.1.tar.gz
| Download URL | luria-0.4.1.tar.gz |
|---|---|
| Size | 231.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c4cbba1a686152353957b6d458b4253c0e808c34c622527accfceaff333f6b09
|
|
BLAKE2b-256 checksum How to use checksums |
c932d17c999b08e11cae350624f283e3d6edcda0870a12eae8dcb0b7e0ba53d6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.
Transparency logRelease files / luria-0.4.1-py3-none-any.whl
| Download URL | luria-0.4.1-py3-none-any.whl |
|---|---|
| Size | 164.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2e4011dcced504f84b9dd6993114a4455f0b3e4d9247c6963bfeb60f9d8d02b4
|
|
BLAKE2b-256 checksum How to use checksums |
e785913d3f15cf47861035ba6d2a894572677bbacce514e2b307bf67d0d2e8ad
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.
Transparency log