# Transcript source of truth — resume everything from the repo root

outcome: `claude --resume` run from `~/Projects/overdeck` lists and resumes EVERY session for that project — worktree sessions and per-account sessions included. One place, native picker, no new command to remember.
status: ACTIVE — worker building in `.worktrees/session-index`; re-scoped 2026-08-15 morning.
source request: owner 2026-08-15 — "need to make sure that all the sessions transcripts are saved in one source of truth then this will not happen"; sharpened same morning: "one source of truth for transcripts so i can resume all transcripts straight from the main repo folder (e.g. ~/Projects/overdeck) instead of worktrees and per-account folders and all that stuff that we have now."

## The incident that forced this

Owner lost his `memory-organizer` session overnight (2026-08-14→15) and spent the whole
morning unable to find it. The session was ALIVE the entire time — pid 3948212, transcript
`f7206ccd…jsonl` sitting in the base project dir, its terminal window open on the desktop
among 15 identically-titled Terminal windows. Three wrong identifications happened before
it was found (UTC-vs-local timestamp comparison, account-scoping theory, birth-time
coincidence). Root scatter mechanism, measured: **232 separate transcript directories for
overdeck alone** — the harness maps cwd → project dir by path-mangling, so every worktree
(`.worktrees/<slug>`, `.claude/worktrees/agent-*`) and every account home gets its own dir,
and `--resume` scans only the dir matching the current cwd. A session is findable only if
you stand in the folder it started in.

## Acceptance

Owner-obtainable evidence: a real session whose transcript lives under
`-home-user-Projects-overdeck--worktrees-*` appears in the `claude --resume` picker run
from `/home/user/Projects/overdeck`, and resuming it works. The owner types nothing new.

## Design constraints (frozen by the re-scope)

- **Native picker is the interface.** An index/query tool is secondary. A tool the owner
  must remember to use fails him by design.
- **Measure the deciding mechanic first**: does the picker enumerate symlinked top-level
  `*.jsonl`? If yes → link farm into the base project dir. If no → hardlinks (same fs).
  Never assume; test on a throwaway session.
- **Never move, rewrite, or delete a transcript.** Links only. A running process holds its
  transcript open; relocation is data loss.
- Link only top-level session `*.jsonl` — never `subagents/` subdirs, never `*.live.jsonl`.
- **Flood control, measured**: agent-worktree dirs (`--claude-worktrees-agent-*`) may hold
  hundreds of worker transcripts; if linking all drowns the picker, exclude agent dirs and
  say so plainly. Owner sessions are never filtered.
- **Convergence, not one-shot**: backfill existing sessions AND keep current via
  SessionStart hook and/or systemd user timer per repo unit conventions (`deckctl units
  apply`, units live in modules/, symlinked in). Idempotent, fail-closed.
- **Generalize by rule**: any project dir mangled as `<base>--worktrees-*` or
  `<base>--claude-worktrees-*` links into `<base>`. Covers Press.zone and zync.is with
  zero per-project config. Per-account homes link into the default home's base dir the
  same way.
- Install before landing: this is local infra the owner runs — live first, git after.

## Current receipt (2026-08-15 midday)

Owner scope grew twice: ALL projects, and account-scatter named the worst pain. Delivered
live so far, ahead of landing (install-before-landing):

- **131 lost account-split sessions FOUND intact** in `.claude-openrouter` (113, Jun 24–Jul 3),
  `.claude2` (11), `.claude-solweb` (7). Root cause of historical loss: every account home
  lacked `cleanupPeriodDays` → 30-day deletion default. All 13 homes (8 account + 5 legacy)
  now set to 36500 by hand; provisioning must make this durable.
- **563 sessions surfaced** by running `session-transcript-converge` live: 441 worktree +
  122 cross-home adoptions; 1,826 already visible; agent-worker dirs excluded; 1 collision
  reported, left alone. Verified by inode: worktree and openrouter sessions now appear in
  their base project dirs.
- Branch `wt/transcript-unify` (4,157-file full tree) = worker's converger + tests, my
  cross-home adoption fix (11/11 tests), timer units, and deploy-local.sh install wiring.
  Built via git plumbing because a machine-wide WRITE-BURST KILLER (active since ~10:30)
  kills any process writing many files fast — full checkouts die <1s, git-remote ops die,
  worktree creation broken. Incident lane hunting it. My earlier commit `8becea6ef` on the
  worker's branch mass-deleted 3,840 files BLIND because the output filter truncated
  `git status` — caught before any land, rebuilt clean; farm2/farm3 worktrees are casualties,
  superseded by `wt/transcript-unify`.

BLOCKED: landing/deploy — git network operations killed by the same incident. Next: land
`wt/transcript-unify` + deploy (installs script to ~/.claude/bin, enables 15-min timer)
once the killer lane clears the path.

## Prior receipt

2026-08-15 morning: worker dispatched, then re-scoped from index-first to
native-resume-first after the owner sharpened the ask. Identity of the lost session
confirmed by the session itself (socket pid 3948212 = `f7206ccd`). Awaiting worker's
symlink-vs-hardlink measurement — that result picks the design.

## Next executable action

Worker: measure picker enumeration of symlinks; build the farm + convergence; prove the
acceptance case; install live; land via ship.sh; report exclusions and unverified steps.
