A decision's life

From a Slack thread to an answered question six weeks later.

One Tuesday afternoon. One question on a Monday morning, weeks later. The lineage is automatic.

apr 12 · 16:42 · #eng-billing
@rena "let's drop the queue here. it's adding more failure modes than it removes. let's run inline, keep idempotency at the service boundary."
▸ thread · 6 replies · 4 reactors
apr 12 · 17:08 · slack ingest
Statefulai detects an architectural decision in the thread. Captures it as ADR-014, stores rationale and alternatives, and waits for code that confirms it.
▸ episodic · ADR-014 · semantic · -InvoiceQueue +BillingService.flush
apr 14 · 11:20 · PR #471
@marko implements the change. Statefulai links the PR to ADR-014, derives the procedural rule @idempotent-writes, and updates the architectural graph.
▸ derived rule · @idempotent-writes · linked to ADR-014
may 11 · 03:42 · incident
Production double-flush. Root cause: lock not held across retry. Statefulai attaches the incident to ADR-014 — the original constraint is now battle-tested context.
▸ episodic event · incident-2026-05-11 · linked to ADR-014
jun 02 · 09:14 · new hire's first day
@new-hire "Why don't we use a queue for billing? Wiki page mentions one." Agent answer: the queue was removed in ADR-014 (Apr 12); a double-flush incident in May confirmed the lock-based approach. The wiki page is stale — flagging to @rena.
▸ retrieved · ADR-014, incident-2026-05-11, rule @idempotent-writes
Notice the wiki is wrong, and the system knows. Statefulai compares its answer to the wiki page and flags the disagreement — turning stale docs from a silent liability into a queued fix.
Three questions, six weeks later

The "why" questions finally have a place to live.

› Why is auth using cookies, not JWT?
We decided cookies in ADR-007 (Mar 21). The rationale: refresh-token rotation is simpler with cookies, and we were already storing a session ID server-side. Four PR comments since have rejected JWT-in-cookie suggestions. ▸ ADR-007 · rule @no-jwt-cookies · 4 reviewer rejections
› Who knows most about the billing module?
@rena (0.42), @marko (0.28), then claude-code (0.20). Scored by recent edits, review density, and authored ADRs. Two of @rena's PRs in the last quarter rewrote the core flow. ▸ semantic · person edges · last 90 days
› What broke at 3am on May 11?
Invoice double-flush. Lock was not held across retry. Mitigated by pinning the @idempotent-writes rule across BillingService.flush(). ADR-014's original constraint was correct — the implementation drifted from it. ▸ episodic · incident-2026-05-11 · linked to ADR-014
› Why did we reject the JWT pattern @claude suggested?
Two reasons. ADR-007 rules out JWT in cookies; cookie-stored session IDs are the established pattern. Separately, the suggested JWT skipped our DLP redaction step. ▸ ADR-007 · rule @no-jwt-cookies · rule @redact-pii-logs
How decisions get captured

Three paths, one episodic store.

Slack auto-detection

Whitelisted channels are scanned for architectural decisions. The bot proposes capture; you confirm with a 👍. False positives are throwaway-cheap.

ADR file ingest

Drop ADR markdown files into docs/adr/ and Statefulai picks them up as episodic memory, parses front-matter, and links to referenced symbols.

Inline capture

Type /statefulai remember in any channel — or use the agent tool call memory.store({type:"adr"}) — to make a decision official.

ADRs captured
2.1/wk
avg per beta team
stale-doc flags
23/mo
on a 40-eng team
"why" questions resolved
86%
on first agent reply
decision-to-code lineage
94%
PRs auto-linked to ADR
Decisions · durable

Stop losing the answer to "why did we do it this way?"

Get early accessRead the docs