dira decision memory for AI coding agents
$dira whydec-0011
int-0001The why of a decision survives the session that made itactive 2026-07-29
dec-0006Tiers are fractal — one entry model, one join rule, one drift flag, at every levelaccepted 2026-07-29
dec-0011Cross-boundary parent refs publish opaquely, and resolution reports three statesaccepted 2026-07-30
✗ Publish opaque refs but keep drift two-state (no withheld state)Same publishing behaviour, but it collapses "parent exists and is not readable here" into "no parent", which destroys the orphan-work signal on exactly the surface where a stranger evaluates the product.
✗ Strip upward edges on publishLooks safest and is worst.
✗ Redacted public stub entries for each private parentDisqualified on kind, not on cost.
int-0001The why of a decision survives the session that made it
dec-0006Tiers are fractal — one entry model, one join rule, one drift flag, at every level
dec-0011Cross-boundary parent refs publish opaquely, and resolution reports three states
✗Publish opaque refs but keep drift two-state (no withheld state)
✗Strip upward edges on publish
✗Redacted public stub entries for each private parent
dec-0011 ◆ accepted 2026-07-30

Arising from dec-0006 — Tiers are fractal — one entry model, one join rule, one drift flag, at every level

Cross-boundary parent refs publish opaquely, and resolution reports three states

A public ledger publishes a cross-boundary parent ref **verbatim and opaquely** — `derives_from: sire:int-0002` ships as written. Nothing is stripped, nothing is duplicated, nothing is redacted.

**Why this and not the alternatives: it is the only candidate that does not require superseding an accepted constraint.** `cst-0003` rule 3 already settles the adjacent case — where a check must cite a private constraint in a public context, "it cites the **ref only** (`me:cst-0002`), never the text." A namespaced `derives_from` edge in a public entry *is* that construction. Candidate 1 is that rule applied consistently; both other candidates would have required overruling it. That asymmetry is decisive and `qst-0001` never named it.

Resolution reports three states, not two

The only real objection to opaque refs was that drift could no longer distinguish "no parent" from "private parent I cannot see." It can — the distinction is present in the data:

| State | Condition | Is it drift? | |---|---|---| | **oriented** | edge present, target resolved and readable | no | | **withheld** | edge present, parent namespace declared but not readable here | **no** | | **orphan** | no `derives_from` edge at all | **yes** |

Only `orphan` is drift. This preserves the signal that `dec-0006` depends on, and it supplies the state `docs/design/DESIGN.md` recorded as undesigned with the note that "unresolved" must not look like an error. Withheld is a legitimate, designed state — not a failure, not an error, not a warning.

What it costs, stated plainly rather than left to be discovered

**What leaks:** the existence of a private parent ledger, its namespace, and an integer id. **What does not leak:** the parent's title, its body, its alternatives, its edge notes — anything a human wrote.

The namespace is typically a venture name that is public anyway. Where it is not, `[parents]` may declare the namespace with `visibility = "private"` and omit the human-facing label, so the ref remains resolvable-as-withheld without shipping the name. This is a real disclosure and adopting a private parent should be a considered act, not a default.

Implementation notes

No schema change is required. `schema/entry.schema.json` `$defs/ref` already permits namespaced refs (its own examples are `sire:int-0002` and `me:cst-0002`), and a `private` boolean already exists on entries.

What is new is one config field — `visibility` on a `[parents]` entry — and the three-state resolution in the query layer. A namespaced ref whose namespace is **not** declared in `[parents]` is an error rather than a withheld state: an undeclared foreign ref is a typo or an invention, and treating it as withheld would let real mistakes hide behind the privacy boundary.

Alternatives on record — 3

✗Publish opaque refs but keep drift two-state (no withheld state)refused Same publishing behaviour, but it collapses "parent exists and is not readable here" into "no parent", which destroys the orphan-work signal on exactly the surface where a stranger evaluates the product.

That distinction is already in the data; discarding it is an implementation choice, not a consequence of opaque refs.

✗Strip upward edges on publishrefused Looks safest and is worst.

It makes the public artifact deny an edge that exists, so every adopting repo's ledger reads as unexplained work — inverting dec-0006's claim that the drift flag is the mechanism answering "what are we actually doing?". It also presumes a publish step, and dec-0002 is built on there not being one: the files in git ARE the ledger, which is what makes `git log -p` a review surface and lets the record outlive the tool. A transform between working tree and committed tree adds a "did the strip run?" failure class to the one area where a miss is unrecoverable.

revisit ifa ledger must be published somewhere the namespace itself is sensitive

✗Redacted public stub entries for each private parentrefused Disqualified on kind, not on cost.

It is a private-to-public *write* path whose safety depends on a human judgement made under time pressure on every write, and cst-0003 exists precisely because this boundary must be enforced by the architecture rather than by care. It converts an architectural guarantee into a recurring judgement call, and the two copies then drift.

Every decision in this repo is recorded like this one.

Keep your own →