#009 April 9, 2026 · 5 min read

The Append-Only Decision Log: A Time Machine for 'Why Did We Ship This?'

Six months after shipping, I can tell you why I chose Sanity over Webflow for Amal Najib. In one grep. Here's the file that makes it possible.

stella-protocol ai-pm decision-log vivre-cards

The short version

Product decisions have a half-life. At three months, rationale becomes folklore. Stella Protocol's Vivre Cards — an append-only, git-committed markdown log — pin the *why* next to the decision so it survives context compaction. Two rules: never edit past entries, and when a decision reverses, append a new entry that references the old one.

Six months after shipping, I can tell you why I chose Sanity over Webflow for Amal Najib. In one grep.

The problem

Product decisions have a half-life. Three weeks after shipping, I can still reconstruct most of the why. Three months in, the reasoning turns into folklore — “I think we deferred OCR because of bundle size?” Six months in, context compaction has eaten the session history, the Slack thread is gone, the PRD has been edited, and “why did we ship this?” becomes archaeology.

AI-assisted building makes this worse. A typical week produces ten decisions that would have been a single architecture meeting in a team setting. Nobody took minutes. There was no meeting. The decisions happened between a PM and an agent at 11pm, and by Friday the rationale has evaporated.

What you'll learn
01
Why product rationale decays after three months — and what to write down now so future-you can audit the call.
02
The exact 5-field entry format that turns a messy decision into a referenceable log line.
03
Why editing past entries destroys value — and the append-with-reverse pattern that replaces it.

The pattern

Stella Protocol — my AI-PM methodology — uses brain/vivre-cards.md as the decision log. Vivre Cards, from One Piece, are magical pieces of paper that always point to a specific person, no matter where they are. The metaphor: a Vivre Card entry points to the rationale behind a decision, and the paper never lies, no matter how much the product drifts afterward.

Two rules:

  1. Append-only. Never edit a past entry. Never delete one. If a decision gets reversed, append a new entry that references the old one.
  2. Git-committed. The file lives in the project repo. Every entry is a commit. git log brain/vivre-cards.md gives you the exact timeline.

Entry format

## 2026-04-10 — Defer receipt OCR to P1
Phase: DEFINE
Rationale: AI recipe generation is the AHA moment per Observation
Haki Lens 4 (activation behavior); OCR is a convenience layer on
top. Shipping OCR in P0 adds ~2 weeks (either client-side TF.js
with +18MB bundle, or server-side via Google Vision at ~$1.50/1K
which we can't sustain pre-revenue). Activation metric unaffected
— users can type ingredients manually in P0.
Alternatives considered:
  - Google Vision API: cost-prohibitive pre-revenue, deferred
  - Client-side TF.js: bundle bloat, worse mobile perf, rejected
  - Accept typed input only in P0: selected
Impact: P0 scope -15%, expected ship date -10 days

Five fields: date + title, phase, rationale, alternatives considered, impact. The alternatives field is load-bearing — it’s what lets future-me (or a handoff agent) understand not just what was chosen, but what was on the table and why it lost.

Two concrete examples

Stoka — receipt scanning deferred

The entry above is the actual call. Full write-up in the receipt scanning MVP post. The short version: OCR was the feature I was most tempted to ship. The Vivre Card forced me to write down why the temptation was wrong — activation was elsewhere, and the cost/bundle trade-offs didn’t pencil at pre-revenue stage.

Six weeks later I was halfway through a different feature and had the thought “should I slip OCR back in?” Opened vivre-cards.md, grepped OCR, got back the original rationale plus the impact line. Decided no, kept moving. The log prevented a rescope I would otherwise have talked myself into.

House of Riddle — cosmetic store deferred

## 2026-03-22 — Defer cosmetic store to P2
Phase: DEFINE
Rationale: Monetization path undecided — ad revenue vs paid
cosmetics vs both. Shipping a cosmetic store in P0 locks us
into a payments integration (Stripe Connect or RevenueCat)
before we know the audience retention curve. Retention at
D7 > 20% is the gate for any monetization work.
Alternatives considered:
  - Ship free-only cosmetics in P0 (reward system): still useful,
    separate entry — kept in P0
  - Ship full paid store P0: rejected, infra weight too high
  - Defer cosmetics entirely: rejected, reward loop needs them
Impact: P0 scope -1 major feature, P2 blocked on D7 retention data

When D7 came in below 20%, I didn’t have to reopen the decision. The gate was written down. Cosmetic store stayed deferred, and the reason was still legible.

Why append-only matters

Editing past entries is tempting. You learn something new, you want to “correct” the old rationale. Don’t.

Editing loses the evolution of thinking. The wrong decision with its original rationale is more useful than a clean, revised entry that hides the journey. When I reread a bad call from four months ago, I want to see what I believed at the time — that tells me what signals I was missing. A sanitized log teaches me nothing.

When a decision reverses, the pattern is:

## 2026-05-02 — REVERSE: adopt OCR in P1 (was: defer to P1)
Phase: BUILD
References: 2026-04-10 entry
Rationale: User research N=12 showed typed input is a top-3
drop-off point; activation assumption from Apr 10 was wrong.
OCR now on critical path for retention.
Impact: P1 scope +1 major feature, Sanity schema unchanged

Now I have both entries. The old assumption is still there, the reversal is there, and the chain is auditable.

Practical: git is the time machine

Because the file is committed, git log --follow brain/vivre-cards.md gives the full timeline with commit hashes. git blame tells me which commit introduced each entry, which usually corresponds to a specific session. If I need to cross-reference a decision with the code that shipped from it, I go from the Vivre Card timestamp to the commit range, and I have the full story in one place.

No external tool. No Notion page that went stale. No Slack archive that expired. Just markdown in the repo.

Lesson

Deferred work without rationale is mystery debt. Rationale turns mystery debt into honest debt — which is the difference between a roadmap and a broken promise. A roadmap says “we chose not to build this, here’s what we traded for it, here’s what would change our mind.” A broken promise says “we’ll get to it.”

More on how deferred scope stays honest in the deferred scope post.


Key Takeaways

  1. Pin the why at the moment of the decision. Three weeks later you remember. Three months later you don’t. The log only works if you write the entry the same session the call is made.
  2. The “alternatives considered” field is the load-bearing one. What got chosen is visible in the code. What got rejected — and why — is the signal future-you needs to avoid re-opening the same decision.
  3. Reverse by appending, not editing. The old wrong call stays. The new correct call references it. You keep the evolution of thinking intact, and the log teaches you what you were missing.

Satellite: Morgans (this post) · Pipeline: REFLECT — Morgans