Skip to content

A chat deleted in a Claude home Paddock doesn't own is released but still listed #693

Description

@edspencer

Split out of #689, which is now fixed for the part that mattered (the data loss). This is the remaining half.

Behaviour

In a Claude home Paddock does not own, DELETE /api/projects/:slug/chats/:sessionId releases the session rather than removing the transcript (#692) — correct, since the file is the user's own terminal claude history and there is no Paddock copy to delete.

But the chat stays in the chat list. unadoptSession only drops an adoption record, and a chat Paddock created is rediscovered structurally: the engine scans <claudeHome>/projects/<encoded-cwd>/, finds the JSONL, and lists it again.

Net effect: the transcript is safe and the user's stated intent — "take this out of my list" — is not honoured. The response says { ok: true, removed: false, retained: true }, so a caller can tell, but nothing acts on it.

Asserted as current behaviour in test/integration/delete-chat-unowned-home.test.ts ("does NOT yet remove it from the list (the tombstone is still owed)") so it cannot drift silently.

Fix

A tombstone: a sidecar recording "Paddock must not show this session", checked when listing. The four existing per-chat sidecars (ArchiveStore, StarStore, UnreadStore, ParentDetachStore) are the pattern to follow — same write-through JSON shape, keyed <agent>\0<sessionId>.

The natural choke point is HerdctlService.listSessions / recentSessions rather than the route handlers: every consumer (project chat list, Home aggregation, the sweeper's activity check) goes through those, so filtering there cannot miss a caller.

Why it was deferred

#692 keys this branch off ownsClaudeHome, and #691 removes that flag — Paddock will always own its home, with transcripts: own|host becoming the discriminator. A tombstone written against ownsClaudeHome would have to be rewritten one step later.

Best done alongside #691's transcripts lever, where host is the mode that makes it reachable at all. Low urgency: no data is at risk, and after #691 the state is only reachable by explicitly opting into transcripts: host.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions