Adds the session_checkpoints section to the control-plane DB substrate
architecture doc: schema version and row identity, the column groups, the
public API surface, and the hard rules (redaction at write, reconcile
rather than blind restore, unknown live state is not a mismatch, drain
fails closed on an incomplete checkpoint, no transcript storage).
Satisfies acceptance criterion 1 of #660 ("Schema documented and
versioned") for the implementation added in 7e18dcc.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Base-sync of the #660 durable session checkpoint schema branch onto current
master. The only conflicting file was control_plane_db.py, where master added
the #651 usage_events table, migration, and indexes while this branch added the
Resolution keeps both sides in full. Verified against both merge parents: the
resolved file contains every line of master's control_plane_db.py with zero
removals, plus exactly the #660 additions (session_checkpoints table, its two
indexes, _session_checkpoint_row, write_session_checkpoint,
get_session_checkpoint, list_session_checkpoints, reconcile_session_checkpoint,
and checkpoint_completeness).
Conflicts:
control_plane_db.py
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Add a versioned, redacted, reconcile-on-boot session checkpoint store to
control_plane_db so a restart can recover session identity, stage, lease
ownership, and next valid action instead of forcing human reconstruction
(umbrella #655; #628 autonomous-handoff goal).
- Bump SCHEMA_VERSION 4->5. New `session_checkpoints` table + two indexes,
added via `CREATE TABLE IF NOT EXISTS` so table creation is itself the
additive, idempotent v4->v5 migration (dependency_edges precedent).
- Writer `write_session_checkpoint` upserts the current recoverable state
per (remote, org, repo, session_id, work_kind, work_number); stage
transitions audit to `events`. Readers `get_session_checkpoint` /
`list_session_checkpoints`.
- Every free-text and JSON field is passed through `gitea_audit.redact`
before storage — no tokens/credential URLs can land in a checkpoint (AC4).
- `reconcile_session_checkpoint` is pure and never restores: it diagnoses a
stored checkpoint against live head/lease state and flags staleness (AC3).
- Drain gate: `require_complete=True` fails closed (writes nothing) when a
checkpoint is missing a drain-required field, so drain cannot complete on
an unrecoverable record.
- `lease_id`/`assignment_id` are soft references (no enforced FK) so a
checkpoint survives deletion of the lease it names; `work_number=0` is the
NULL-safe session-level sentinel.
Tests: 13 new cases (schema/version, multi-role fixtures, upsert+audit,
JSON round-trip, secret redaction, reconcile stale-head/dead-lease/
reassigned-lease/clean/unknown, drain fail-closed, sentinel key). Existing
schema_version assertion updated 4->5. Full tests/test_control_plane_db.py
suite: 33/33 pass.
Links #652#653#655.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>