feat(control-plane): durable MCP session checkpoint schema (Closes #660) #881
Labels
Clear labels
allocator
anti-stomp
architecture
bug
chore
codex
concurrency
contamination
control-plane
dashboard
database
design
documentation
enhancement
gitea
glitchtip
important
incident
incident-bridge
integration
jenkins
labels
leases
mcp
mcp-health
mcp-menu
multi-project
mutating
nice-to-have
observability
portability
preflight
protected-branch
queue
read-only
reconnect
recovery
refactor
release
reliability
resumable-review
reviewer
roadmap
safety
security
self-hosted
sentry
stale-runtime
status:blocked
status:in-progress
status:pr-open
status:ready
terminal-lock
testing
tracker
type:bug
type:feature
type:feature
type:guardrail
visibility
workflow
workflow-hardening
workflow-hardening
Controller-owned work allocator
Prevent concurrent LLM session stomping
Architecture / structural design
OpenAI Codex client / workflow session surface
Concurrent session safety
Workflow or session contamination incident
MCP control-plane coordination and allocation authority
MCP operational dashboard/queue view
Internal coordination storage (SQLite/Postgres)
Design / investigation, no implementation
Docs / runbooks
New feature or improvement
Gitea MCP workflow
GlitchTip integration
Operational or process incident requiring durable audit trail
Sentry-to-Gitea incident bridging
Integration testing
Jenkins integration
Label taxonomy management
Lease adopt/release/expire lifecycle
MCP server / tooling
MCP namespace and runtime health
MCP menu surface
Work spanning multiple monitoring projects or Gitea repos
Mutating action; requires gating
Observability, metrics, traces, error reporting
Cross-platform / portability
Shared preflight gates before mutation
Protected branch / stable-branch policy concern
Work queue visibility and allocation
Read-only, no mutation
MCP client reconnect/reload recovery path
Recovery paths for stale/foreign leases
Code refactor / restructure
Release / versioning
Reliability / failure handling
Persist and resume prepared review verdicts across sessions
Reviewer workflow tooling
Roadmap / umbrella issue
Safety rails and fail-closed mutation guards
Security / trust boundary
Self-hosted infrastructure integration
Sentry error monitoring integration
Stale backend daemon / runtime-vs-master parity failures
Issue is blocked
Issue is being worked on
Issue has an open pull request
Issue is ready for work
Terminal review lock (#332) path
Tests / test coverage
Issue tracker hygiene / meta
Bug or defect
Feature or enhancement
Feature or enhancement
Safety gate or guardrail
Workflow state visibility for LLMs/operators
Cross-tool workflow
LLM workflow coordination hardening
LLM workflow coordination hardening
No labels
Milestone
No items
No Milestone
Projects
Clear projects
No projects
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: Scaled-Tech-Consulting/Gitea-Tools#881
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Implements issue #660: a versioned, redacted, reconcile-on-boot session checkpoint store in
control_plane_dbso restarts can recover session identity, stage, lease ownership, and next valid action instead of forcing human reconstruction (parent #655; vision #652 / roadmap #653; supports #628 autonomous handoff goals).What this adds
session_checkpointstable — current-state row per(remote, org, repo, session_id, work_kind, work_number); session-level sentinel iswork_kind=''/work_number=0. AdditiveCREATE TABLE IF NOT EXISTS(same pattern as dependency edges / usage events).SCHEMA_VERSIONremains 5 (already shipped by #651); rows carrycheckpoint_schema_version.write_session_checkpoint(upsert + stage-change audit toevents),get_session_checkpoint,list_session_checkpoints.gitea_audit.redactbefore storage (AC4).reconcile_session_checkpoint— pure diagnosis only (never blind-restores). Flags stale head / dead or reassigned lease; unknown live inputs do not false-positive (AC3).require_complete=Truerefuses incomplete records (session_id,role,workflow_stage,next_valid_action,recovery_instructions).docs/architecture/control-plane-db-substrate.mddocuments schema, API, and hard rules (AC1).Acceptance criteria
checkpoint_schema_versionSessionCheckpointTest.test_multi_role_fixtures_each_get_a_rowNon-goals honored
Files
control_plane_db.pytests/test_control_plane_db.pydocs/architecture/control-plane-db-substrate.mdValidation
From worktree
/Users/jasonwalker/Development/Gitea-Tools/branches/issue-660-session-checkpoint-schema:Branch tip is merged with current
master(includes #838 inventory); no conflicts on the three files in this PR.Risk
Low. Additive schema + pure APIs; no MCP tool surface or drain/boot integration in this PR. Residual risk is callers forgetting to reconcile before resume — the API returns
reconcile_actionand never restores by itself.Canonical PR state
Closes #660.
36fe4785into feat/issue-660-session-checkpoint-schema 87c30484aarepo: Scaled-Tech-Consulting/Gitea-Tools
pr: #881
issue: #660
reviewer_identity: sysadmin
profile: prgs-reviewer
session_id: 99619-0e7139e466e6
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/baseline-master-9b52899
phase: claimed
candidate_head:
6862049ef6target_branch: master
target_branch_sha:
9b5289940clast_activity: 2026-07-24T20:47:26Z
expires_at: 2026-07-24T20:57:26Z
blocker: none
APPROVE — reviewed at head
6862049ef6c60a55026e6aeb1c10b374554fdae1against basemaster@9b5289940c898d75e90b8d05612d942f36008fb8.NATIVE_REVIEW_PROOF: native reviewer namespace prgs-reviewer (sysadmin), workflow skills/llm-project-workflow/workflows/review-merge-pr.md hash 263d0a6cb8a6, reviewer lease comment 16097, head-scoped final decision at
6862049ef6.Scope
3 files, +692/-1:
control_plane_db.py,tests/test_control_plane_db.py,docs/architecture/control-plane-db-substrate.md. Purely additive — no MCP tool surface, no capability gate, no drain/boot wiring touched. Scope matches #660; no unrelated files.Verified against acceptance criteria
session_checkpointsis created viaCREATE TABLE IF NOT EXISTSinside_SCHEMA_SQL, which_init_schemaruns unconditionally on every open (not gated on a storedschema_version). Confirmed the table therefore lands on databases already stamped version 5 by #651 — no silent "no such table" on existing deployments. Rows carrycheckpoint_schema_version; substrate doc updated with schema, API table, and hard rules.test_multi_role_fixtures_each_get_a_rowwrites author/reviewer/merger/controller rows; UNIQUE key(remote, org, repo, session_id, work_kind, work_number)with the('', 0)session-level sentinel keeps the constraint NULL-safe.reconcile_session_checkpointis a@staticmethodwith no DB handle: it cannot restore, only diagnose.Nonelive inputs are treated as "not checked" and never flag a mismatch on their own; dead lease and reassigned lease are separate paths.gitea_audit.redactend to end: recursive over dicts/lists, key-hint redaction (token/password/secret/authorization/auth),Bearer/Basic/tokenvalue-prefix redaction, and URL/credential redaction with real hosts replaced. None of the checkpoint column names collide with a secret key hint, so no column is blanket-wiped. Redaction is applied to the assembled record before any SQL runs.Drain fail-closed also verified structurally:
require_complete=TrueraisesControlPlaneErrorbefore_tx()is entered, so an incomplete record writes nothing — and the test asserts the table is still empty afterward.Test evidence
Run in the PR worktree at the exact head:
Regression scope — every test module importing
control_plane_db(23 files), run at PR head and atmaster@9b52899:The 7 failures are pre-existing on master (
test_issue_784_dependency_edges.pyassertsSCHEMA_VERSION == 4, stale since #651 bumped it to 5;test_branch_cleanup_guard.pyunrelated). Failure reasons were compared line by line and are identical on both sides. 0 new failures introduced by this PR.Advisories (LOW — none blocking, no remediation required for merge)
checkpoint_schema_versionDDL default is the literal5while inserts write theSCHEMA_VERSIONconstant. WhenSCHEMA_VERSIONnext moves, the column default silently drifts from the written value. Prefer dropping the literal default (the writer always supplies it) on the next touch.work_kindraisesdependency_graph.InvalidEdgeEndpointError, notControlPlaneError. It still fails closed, but the message talks about "dependency edge endpoint" in a checkpoint context, and a caller catching this module'sControlPlaneErrorwill not catch it.evidence/pending_mutationsurfaces a rawTypeError, andcapabilities="read"(a bare string) round-trips as a string rather than a list.work_item_id = NULL, and the only consumer,webui/timeline.py::_CP_EVENTS_QUERY, does an innerJOIN work_items ON e.work_item_id = w.work_item_id, sosession_checkpoint_stage_changeevents never surface there. The durable row itself is unaffected; worth wiring when checkpoints get a UI.recovery_instructions/next_valid_actionto[REDACTED_URL]. Security-correct, but it means recovery text should cite issue/PR numbers rather than links, or the pointer is lost on resume. Worth stating in the substrate doc's hard rules.Canonical PR State
STATE: approved
WHO_IS_NEXT: merger
NEXT_ACTION: Merge PR 881 at head
6862049ef6through the gated merger path; the approval is head-scoped and void if the head advances.NEXT_PROMPT:
WHAT_HAPPENED: Reviewer read the full three-file diff at head
6862049e, traced the redaction path through gitea_audit.redact, confirmed the schema is created by unconditional executescript rather than a version-gated migration, ran the focused suite (33 passed) and the 23-module control_plane_db regression scope at both PR head and master, and compared failure sets.WHY: All five #660 acceptance criteria are satisfied at this head, the change is additive with no gate or tool-surface impact, and the regression scope shows zero new failures against the master baseline.
ISSUE: 660
HEAD_SHA:
6862049ef6REVIEW_STATUS: approved
MERGE_READY: yes
BLOCKERS: none
VALIDATION: tests/test_control_plane_db.py 33 passed at 6862049e; control_plane_db import scope 559 passed / 7 failed at PR head, identical 559 passed / 7 failed at master
9b52899with identical FAILED sets and identical assertion messages (pre-existing SCHEMA_VERSION==4 debt from #651 plus unrelated branch-cleanup failures); merge state mergeable with 0 commits behind and no conflicts.LAST_UPDATED_BY: prgs-reviewer (sysadmin)
adopted_at: 2026-07-24T20:52:33Z
adopted_by_identity: sysadmin
adopted_by_profile: prgs-merger
adopted_from_session_id: 99619-0e7139e466e6
adopted_from_profile: prgs-reviewer
adopted_from_reviewer_identity: sysadmin
adopted_from_comment_id: 16097
adoption_reason: merger-handoff-approved-head
repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #881
issue: #660
reviewer_identity: sysadmin
profile: prgs-merger
session_id: 29320-808c11ff9ef8
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/baseline-master-9b52899
phase: adopted
candidate_head:
6862049ef6target_branch: master
target_branch_sha:
9b5289940clast_activity: 2026-07-24T20:52:33Z
expires_at: 2026-07-24T21:02:33Z
blocker: none
Stale #332 review-decision lock cleanup (#594)
Status: APPLIED
sysadminprgs-merger2026-07-24T20:52:54.683757+00:00approveon PR feat(control-plane): durable MCP session checkpoint schema (Closes #660) (#881)closed(merged=True)870843f999fb4bb8fc8c15ff7ede730448cdb3d42prgs-reviewerManual deletion of session-state files is not the workflow.
This path only clears a lock when the referenced PR is merged/closed.