Harden dev:seed against state it cannot settle

Review of the seeding path found five ways a seeded database could
describe something the copy cannot back up:

- Nothing stopped `dev:seed` from running against a live server. SQLite
  locking lets the seed take the write lock between the server's own
  writes and commit cleanly; what it cannot do is tell that server its
  projections and event log were replaced underneath it. Refuse instead,
  via a pid probe over both state directories.
- A thread copied mid-turn kept `state = 'running'`. The session override
  did not cover it — the turn is read independently, and an unsettled one
  leaves the thread spinning and its timeline unfoldable forever. Settle
  those to "interrupted", matching what the server does when a session
  leaves "running". Streaming messages are finished for the same reason.
- Attachment metadata was copied without the files behind it, so a seeded
  thread rendered an image whose request 404s. Report the referenced ids
  and copy the matching files alongside the rows.
- Orphaned `provider_session_runtime` rows survived the seed naming
  threads it had just deleted, which the session reaper then tried to
  stop against a provider instance the worktree may not define.
- `--threads` had no upper bound, so a large enough value died with "too
  many SQL variables" after the target was already emptied.

Also corrects the projector-cursor comment: `orchestration_events.sequence`
is AUTOINCREMENT, so emptying the log does not reset its high-water mark
and sequence does not restart at 1. Zero remains the right cursor, for the
reason now stated.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
373e7919d1Theo Browne committed on 7/27/2026, 3:38:48 AMparent1800708
9 files changedLine totals unavailable