Skip to content

feat(topic): add sqlite topic store parity - #634

Merged
delete-cloud merged 3 commits into
mainfrom
feat/sqlite-topic-store-parity
Jun 26, 2026
Merged

delete-cloud merged 3 commits into
mainfrom
feat/sqlite-topic-store-parity

Conversation

@delete-cloud

@delete-cloud delete-cloud commented Jun 26, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • add SQLiteTopicStore parity for the local durable bundle, including topics, anchors, recall links, costs, constraints, and SQLite/PG shared contract coverage
  • wire Coding Agent product paths to select SQLite TopicStore for local durable bundles and PGTopicStore for full PG durable mode
  • make semantic maintenance, console topics, local runtime preparation, checkpoint restore, and Helm/default docs reflect the SQLite/PG TopicStore split
  • normalize SQLite bundle paths across server builder, SessionManager, and local CLI owner-store creation
  • reconcile topic-derived state during local SQLite checkpoint restore so semantic rebuild cannot index rolled-back topic state

Verification

  • uv run pytest tests/cli/test_local_runtime.py -q
  • uv run pytest tests/coding_agent/test_topic_store_contract.py tests/coding_agent/test_topic_store.py tests/coding_agent/test_sqlite_topic_store.py -q
  • uv run pytest tests/coding_agent/test_sqlite_local_durable_fencing.py -k "topic or upgrade or restore" -q
  • uv run pytest tests/ui/test_session_manager_runtime.py -k "topic_store or semantic_topic_store or checkpoint_restore" -q
  • uv run pytest tests/coding_agent/test_runtime_preparation.py -k "semantic_topic_store or local_daemon" -q
  • uv run pytest tests/ui/test_http_server.py -k "console_topic or normalizes_paths_local_for_sqlite_owner_store" -q
  • uv run pytest tests/coding_agent/test_semantic_maintenance.py -k "factory or topic_store_available or rebuild" -q
  • uv run pytest tests/deploy/test_helm_chart.py -k "topic_store or memory_semantic or storage" -q
  • uv run ruff check <changed python files>
  • uv run ruff format --check <changed python files>
  • git diff --check

Review Gate

  • local subagent review loop ran until the final fresh reviewer returned No P1/P2 findings.
  • addressed reviewer findings for normalized SQLite path split across SessionManager, HTTP builder, and local CLI
  • addressed reviewer finding for checkpoint restore leaving topic-derived state beyond the restored tape boundary

ADR / Task Packet

  • Implements the SQLiteTopicStore parity slice from ADR-0073 and .opencode/prompts/tasks/sqlite-topic-store-parity-task-packet.md.

Summary by CodeRabbit

  • New Features

    • Added durable topic storage support for local SQLite and PostgreSQL setups, with safer topic, anchor, recall-link, and cost tracking.
    • Console and runtime flows now automatically use the selected topic store when available.
  • Bug Fixes

    • Fixed local SQLite path handling so ~-based paths resolve correctly.
    • Improved checkpoint restore behavior to keep topic data consistent after rollback.
  • Documentation

    • Clarified how topic memory and durable storage behave across deployment modes.

Add SQLite TopicStore support for the local durable bundle and wire Coding Agent product paths to select SQLite or PG topic stores consistently.

Cover local durable schema upgrade, path normalization, fenced topic mutations, checkpoint restore reconciliation, semantic rebuild availability, console wiring, Helm defaults, and shared SQLite/PG TopicStore contract behavior.

Verification:

- uv run pytest tests/cli/test_local_runtime.py -q

- uv run pytest tests/coding_agent/test_topic_store_contract.py tests/coding_agent/test_topic_store.py tests/coding_agent/test_sqlite_topic_store.py -q

- uv run pytest tests/coding_agent/test_sqlite_local_durable_fencing.py -k 'topic or upgrade or restore' -q

- uv run pytest tests/ui/test_session_manager_runtime.py -k 'topic_store or semantic_topic_store or checkpoint_restore' -q

- uv run pytest tests/coding_agent/test_runtime_preparation.py -k 'semantic_topic_store or local_daemon' -q

- uv run pytest tests/ui/test_http_server.py -k 'console_topic or normalizes_paths_local_for_sqlite_owner_store' -q

- uv run pytest tests/coding_agent/test_semantic_maintenance.py -k 'factory or topic_store_available or rebuild' -q

- uv run pytest tests/deploy/test_helm_chart.py -k 'topic_store or memory_semantic or storage' -q

- uv run ruff check <changed python files>

- uv run ruff format --check <changed python files>

- git diff --check
@coderabbitai

coderabbitai Bot commented Jun 26, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@delete-cloud, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 27 minutes and 29 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: abc8c786-a3fd-4a3a-b267-ed561134cbde

📥 Commits

Reviewing files that changed from the base of the PR and between 7e5450a and 00ec28c.

📒 Files selected for processing (8)
  • coding-agent/src/coding_agent/server/session_manager.py
  • coding-agent/src/coding_agent/stores/durable_local.py
  • coding-agent/src/coding_agent/topics/store.py
  • coding-agent/tests/coding_agent/test_sqlite_local_durable_fencing.py
  • coding-agent/tests/coding_agent/test_sqlite_topic_store.py
  • coding-agent/tests/coding_agent/test_topic_store.py
  • coding-agent/tests/coding_agent/test_topic_store_contract.py
  • coding-agent/tests/ui/test_session_manager_runtime.py
📝 Walkthrough

Walkthrough

The PR adds a SQLite-backed topic store, fenced local topic durability, and backend-based topic-store selection through session, CLI, and HTTP paths. It also threads optional semantic topic stores into runtime preparation and checkpoint restore flows, with matching docs and tests.

Changes

Topic Store and Semantic Wiring

Layer / File(s) Summary
SQLite topic store contract
coding-agent/docs/AGENTKIT-ARCHITECTURE.md, coding-agent/docs/CODING-AGENT-ARCHITECTURE.md, coding-agent/src/coding_agent/topics/store.py, coding-agent/tests/coding_agent/test_topic_store.py, coding-agent/tests/coding_agent/test_topic_store_contract.py, coding-agent/tests/coding_agent/test_sqlite_topic_store.py
SQLiteTopicStore adds durable topic rows, pagination, anchors, recall links, and cost updates, and the topic-store tests cover cross-backend contract behavior.
Fenced durable topic writes
coding-agent/src/coding_agent/stores/durable_local.py, coding-agent/tests/coding_agent/test_sqlite_local_durable_fencing.py
SQLiteLocalDurableStore adds fenced topic create/close/anchor/recall/cost mutations, authority checks, and checkpoint-restore reconciliation, with tests for ownership conflicts and restore cleanup.
Session manager topic selection
coding-agent/src/coding_agent/server/session_manager.py, coding-agent/src/coding_agent/cli/local_runtime.py, coding-agent/src/coding_agent/server/http_server.py, coding-agent/tests/cli/test_local_runtime.py, coding-agent/tests/ui/test_http_server.py, coding-agent/tests/ui/test_session_manager_runtime.py, coding-agent/tests/deploy/test_helm_chart.py
SessionManager, CLI, and HTTP paths normalize local SQLite bundle paths, select the topic store by backend, and wire the selected store into console/runtime setup; tests cover path resolution and rendered config.
Semantic topic runtime
coding-agent/docs/topic_layer/USAGE.md, coding-agent/src/coding_agent/runs/checkpoint_runtime.py, coding-agent/src/coding_agent/runs/runtime_checkpoint_restore.py, coding-agent/src/coding_agent/runs/runtime_preparation.py, coding-agent/tests/coding_agent/test_checkpoint_runtime_builder.py, coding-agent/tests/coding_agent/test_runtime_preparation.py, coding-agent/tests/coding_agent/test_semantic_maintenance.py
Runtime preparation and checkpoint-restore services accept a semantic topic-store factory, pass it into agent creation, and update semantic-memory maintainer behavior and tests.

Sequence Diagram(s)

sequenceDiagram
  participant SessionManager
  participant LocalDaemonRuntimePreparationService
  participant RuntimeCheckpointRestoreService
  participant CheckpointRuntimeBuilder
  participant create_agent_for_session
  participant SemanticMemoryMaintainer

  SessionManager->>SessionManager: selected_topic_store()
  SessionManager->>LocalDaemonRuntimePreparationService: semantic_topic_store_factory=self.selected_topic_store
  LocalDaemonRuntimePreparationService->>create_agent_for_session: semantic_topic_store=...
  SessionManager->>RuntimeCheckpointRestoreService: semantic_topic_store_factory=self.selected_topic_store
  RuntimeCheckpointRestoreService->>CheckpointRuntimeBuilder: semantic_topic_store_factory=...
  CheckpointRuntimeBuilder->>create_agent_for_session: semantic_topic_store=...
  SessionManager->>SemanticMemoryMaintainer: semantic_memory_maintainer(session_id)
  SemanticMemoryMaintainer->>SessionManager: selected_topic_store()
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~90+ minutes

Possibly related PRs

Poem

I hopped through bundles, soft and clean,
where SQLite paths now shine serene.
I tucked topic carrots in their rows,
and semantic moonlight calmly glows. 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 1.25% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding SQLite TopicStore parity for topic storage.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/sqlite-topic-store-parity

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Restore HTTP session store behavior so PG session storage keeps its dedicated pool semantics while TopicStore selection continues to use SessionManager's durable PG pool.

Verification:

- uv run pytest tests/ui/test_session_manager_public_api.py::test_session_manager_creates_dedicated_pg_pool_for_http_session_store tests/ui/test_session_manager_public_api.py::test_session_manager_http_session_store_does_not_reuse_injected_pg_pool tests/ui/test_session_manager_runtime.py::test_selected_topic_store_returns_pg_topic_store_for_pg_durable_mode -q

- uv run ruff check src/coding_agent/server/session_manager.py tests/ui/test_session_manager_runtime.py

- uv run ruff format --check src/coding_agent/server/session_manager.py tests/ui/test_session_manager_runtime.py

- git diff --check

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@coding-agent/src/coding_agent/stores/durable_local.py`:
- Around line 1264-1268: The restore reconciliation logic currently uses only
entry_count to decide which topics to drop, which can incorrectly remove topics
that existed at checkpoint time but were finalized later. Update
_reconcile_topics_after_checkpoint_restore and its callers to use
snapshot.meta.created_at alongside tape_id and entry_count, so the restore path
can distinguish topics created/closed after the checkpoint from preexisting ones
and reopen or delete them correctly. Make sure the deletion condition and reopen
handling in the affected restore flow are based on checkpoint time, not just
sequence bounds.

In `@coding-agent/src/coding_agent/topics/store.py`:
- Around line 718-723: The SQLite work in the store is still running on the
request event loop, so calls like _connect and the read paths used by
_console_topic_summaries_from_store() and _console_topic_detail_from_store() can
block HTTP traffic during the busy_timeout. Move the sqlite3-backed read
operations in Store behind asyncio.to_thread or the existing executor pattern,
or replace them with an async SQLite client, and apply the same off-thread
approach to the related read methods called in the other affected store ranges.
- Around line 668-677: The topic anchor upsert/schema currently only enforces
topic_id, so a TopicAnchorRecord can be saved with a tape_id that does not
belong to the owning topic. Update the topic_anchors write path in topic store
logic to validate the parent topic’s tape_id before persisting, matching the
guard already used in durable_local.py’s anchor handling. Mirror the same
protection in PGTopicStore and add/adjust contract coverage so mismatched
tape_id anchors are rejected consistently.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0fdbb50f-bb3e-4332-8342-572508600b89

📥 Commits

Reviewing files that changed from the base of the PR and between 55f2f10 and 7e5450a.

📒 Files selected for processing (22)
  • coding-agent/docs/AGENTKIT-ARCHITECTURE.md
  • coding-agent/docs/CODING-AGENT-ARCHITECTURE.md
  • coding-agent/docs/topic_layer/USAGE.md
  • coding-agent/src/coding_agent/cli/local_runtime.py
  • coding-agent/src/coding_agent/runs/checkpoint_runtime.py
  • coding-agent/src/coding_agent/runs/runtime_checkpoint_restore.py
  • coding-agent/src/coding_agent/runs/runtime_preparation.py
  • coding-agent/src/coding_agent/server/http_server.py
  • coding-agent/src/coding_agent/server/session_manager.py
  • coding-agent/src/coding_agent/stores/durable_local.py
  • coding-agent/src/coding_agent/topics/store.py
  • coding-agent/tests/cli/test_local_runtime.py
  • coding-agent/tests/coding_agent/test_checkpoint_runtime_builder.py
  • coding-agent/tests/coding_agent/test_runtime_preparation.py
  • coding-agent/tests/coding_agent/test_semantic_maintenance.py
  • coding-agent/tests/coding_agent/test_sqlite_local_durable_fencing.py
  • coding-agent/tests/coding_agent/test_sqlite_topic_store.py
  • coding-agent/tests/coding_agent/test_topic_store.py
  • coding-agent/tests/coding_agent/test_topic_store_contract.py
  • coding-agent/tests/deploy/test_helm_chart.py
  • coding-agent/tests/ui/test_http_server.py
  • coding-agent/tests/ui/test_session_manager_runtime.py

@delete-cloud
delete-cloud merged commit 33c901e into main Jun 26, 2026
2 checks passed
@delete-cloud
delete-cloud deleted the feat/sqlite-topic-store-parity branch June 26, 2026 09:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant