Migration 028 lacked an idempotency check, causing it to fail on databases
where the migration had already been applied. The migration would attempt
to copy data from issues to issues_new, but both tables had the same CHECK
constraint, causing the insert to fail.
Added check for "status = 'tombstone'" in the table schema to detect if
the migration has already been applied and skip if so.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Migration 028 (tombstone_closed_at) recreates the issues table but was
missing the created_by column that exists in schema.go. This caused
`SELECT * FROM issues` to fail with column count mismatch on fresh DBs.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previously, tombstones could not have a closed_at timestamp due to:
1. Go validation: `if status != closed && closed_at != nil` failed
2. SQL CHECK constraint: `(status = 'closed') = (closed_at IS NOT NULL)`
This caused import failures for tombstones that were closed before being
deleted - a valid scenario where we want to preserve the historical
closed_at timestamp for audit purposes.
Changes:
- internal/types/types.go: Updated validation to allow tombstones with
closed_at (line 253)
- internal/storage/sqlite/schema.go: Updated CHECK constraint to allow
closed AND tombstone statuses to have closed_at
- internal/storage/sqlite/migrations/028_tombstone_closed_at.go: Migration
to update existing databases with the new constraint
- .beads/issues.jsonl: Fixed bd-6s61 status from 'closed' to 'tombstone'
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>