﻿# A managed conversation edit deletes the unsent query draft

- **Status**: Done
- **Kind**: Bug
- **Authors**: jp
- **Date**: 2026-09-27
- **Label**: client=cli
- **Label**: domain=storage
- **Label**: package=jp_storage
- **Label**: type=bug

`jp conversation edit --events` (or `--metadata`, `--base-config`) on a
projected conversation silently deletes the conversation's `QUERY_MESSAGE.md`,
and reports success.

## Why

After a managed edit, `edit.rs` calls `FsStorageBackend::sync_projection` for
every edited conversation.
`Storage::sync_projection` (`crates/jp_storage/src/lib.rs`) removes the
user-local conversation directory with `remove_conversation_dirs`, then copies
the workspace copy into its place with `copy_dir_all`.

The query draft is written only to the user-local copy: the plugin host's
`draft_path` refuses the workspace tree, because the workspace copy is
committed.
So the draft is never in the copy the sync restores, and replacing the directory
drops it.
Any other file kept only in user-local storage is lost the same way.

## Scope

Contained to the conversation being edited, but hidden: the text the user had
composed and not sent is gone with no diagnostic.
Local-only conversations are unaffected, because the sync returns early when
there is no workspace copy.

## Fix

Make the sync replace the managed files, not the directory: bring the user-local
directory to the workspace copy's name (a `--metadata` edit can change the
title), then copy `metadata.json`, `events.json`, and `base_config.json` across.
That is the shape `persist_conversation_to` already writes each root in.

## Verifying

A regression through `sync_projection`: a projected conversation with a
`QUERY_MESSAGE.md` in its user-local directory, a changed `events.json` in the
workspace copy, then a sync.
Assert the events were synchronized and the draft is still there with its
original content.
A second case with a title change asserts the draft follows the renamed
directory.

## Related

RFD D72 introduces `metadata.local.json` beside the draft, which the same sync
would delete; its Phase 1 depends on this fix.
