Skip to content

fix: persist ACP metadata in SQLite#88724

Merged
steipete merged 2 commits into
mainfrom
fix/acp-sqlite-metadata-ledger
May 31, 2026
Merged

fix: persist ACP metadata in SQLite#88724
steipete merged 2 commits into
mainfrom
fix/acp-sqlite-metadata-ledger

Conversation

@steipete

Copy link
Copy Markdown
Contributor

Summary

  • Move ACP session metadata and the ACP replay/event ledger into OpenClaw SQLite state.
  • Migrate legacy sessions.json ACP metadata and file-backed ACP event ledgers into SQLite, then keep session-store rows discoverable without embedded acp blocks.
  • Update reset/delete/list/status/tail/dispatch/session-spawn/Telegram/gateway paths to read ACP metadata from SQLite with canonical session-key and session-id checks.

Verification

  • node scripts/run-vitest.mjs src/acp/runtime/session-meta.test.ts src/acp/control-plane/manager.test.ts src/gateway/session-utils.subagent.test.ts src/gateway/server.sessions.reset-cleanup.test.ts src/gateway/server.sessions.delete-lifecycle.test.ts src/commands/sessions.acp-model-display.test.ts src/commands/status.test.ts src/commands/sessions-tail.test.ts extensions/telegram/src/thread-bindings.test.ts src/acp/event-ledger.test.ts src/commands/doctor-state-migrations.test.ts src/config/sessions/sessions.test.ts src/auto-reply/reply/commands-acp.test.ts src/auto-reply/reply/dispatch-from-config.test.ts src/auto-reply/reply/dispatch-from-config.acp-abort.test.ts src/gateway/server.sessions-send.test.ts src/agents/tools/sessions-send-tool.a2a.test.ts src/agents/acp-spawn.test.ts src/auto-reply/reply/routing-policy.test.ts src/auto-reply/reply/dispatch-acp-delivery.test.ts passed, 9 shards / 636 tests.
  • node scripts/run-tsgo.mjs -p tsconfig.core.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/core.tsbuildinfo passed.
  • node scripts/run-oxlint.mjs ... on touched ACP/session/gateway/dispatch surfaces passed.
  • pnpm db:kysely:check passed.
  • git diff --check passed.
  • Autoreview clean: no accepted/actionable findings reported.
  • Remote changed proof: pnpm check:changed delegated to Blacksmith Testbox tbx_01kszgt2yn9ydp0z67tzv7eew8, exit 0. GitHub Actions run: https://github.com/openclaw/openclaw/actions/runs/26719270163

Real behavior proof

Behavior addressed: ACP metadata and ACP replay/event ledgers now survive restart/update paths through SQLite state instead of session-store JSON or file sidecars.

Real environment tested: Blacksmith Testbox via Crabbox, plus focused local Vitest and type/lint/schema checks in this checkout.

Exact steps or command run after this patch: pnpm check:changed through the repository wrapper, which delegated to Blacksmith Testbox and ran the selected core, coreTests, extensions, extensionTests, and docs lanes.

Evidence after fix: Testbox lease tbx_01kszgt2yn9ydp0z67tzv7eew8 completed with exit 0; local focused Vitest suite passed 9 shards / 636 tests.

Observed result after fix: ACP metadata reads join SQLite rows to the current session entry and session id, reset/delete cleanup finds canonical metadata for raw legacy keys, ACP session listings work for explicit stores, and legacy JSON/file ACP state migrates into SQLite.

What was not tested: A manual Discord ACP end-to-end run was not performed in this PR; coverage is from unit/integration tests plus the remote changed lane.

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: telegram Channel integration: telegram gateway Gateway runtime commands Command implementations agents Agent runtime and tooling channel: feishu Channel integration: feishu size: XL maintainer Maintainer-authored PR labels May 31, 2026
@clawsweeper

clawsweeper Bot commented May 31, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed May 31, 2026, 1:38 PM ET / 17:38 UTC.

Summary
The branch moves ACP session metadata and ACP replay/event-ledger persistence from session JSON/file sidecars into shared OpenClaw SQLite state, with migration coverage and updated gateway, command, dispatch, Telegram, and Feishu readers.

PR surface: Source +939, Tests +538, Docs +3, Generated +39. Total +1519 across 36 files.

Reproducibility: yes. at source level: current main stores ACP metadata on SessionEntry.acp and uses a file-backed ACP event ledger, while this PR moves those runtime state paths to SQLite. I did not run a live restart/update reproduction in this read-only review.

Review metrics: 1 noteworthy metric.

  • State Migration Surface: 1 SQLite table added; 2 ACP legacy state surfaces migrated. The PR changes persistent ACP storage, so maintainers need to review both schema addition and upgrade behavior before merge.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🐚 platinum hermit ✨ media proof bonus
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P2] Have an owner verify the legacy-upgrade path for existing ACP metadata and replay ledgers before merge.

Risk before merge

  • [P1] This migration changes the canonical storage for ACP runtime metadata and replay state; if any upgrade path or custom session-store target is missed, existing ACP sessions can become undiscoverable or lose resume metadata.
  • [P1] ACP metadata now gates parent/child delivery suppression, session reset/delete cleanup, model display, and channel stale-binding checks, so an incorrect canonical-key or session-id join can duplicate, suppress, or misroute follow-up delivery.
  • [P2] The PR removes the session-store ACP preservation fallback and file-ledger runtime path, which is intentional under the database-first policy but should be accepted explicitly because rollback/compat behavior changes for existing installs.

Maintainer options:

  1. Require Upgrade Proof Before Merge (recommended)
    Run or inspect an upgrade/restart proof with legacy sessions.json ACP metadata and a file-backed ACP event ledger, then verify SQLite rows drive reset, list, tail, and delivery decisions afterward.
  2. Accept The Storage Migration Risk
    Maintainers can land on the PR's focused tests and Testbox changed-lane proof if they are comfortable owning any missed legacy ACP state cases after release.
  3. Pause For A Smaller Migration Split
    If the combined session-metadata and replay-ledger migration is too broad to review safely, split the PR into separate metadata and ledger migrations with focused upgrade proof for each.

Next step before merge

  • [P2] The PR has no narrow mechanical blocker for an automated repair lane, but the protected maintainer label and compatibility-sensitive state migration need human owner review.

Security
Cleared: No concrete security or supply-chain regression was found in the diff; it does not change workflows, dependencies, lockfiles, secrets handling, or package resolution.

Review details

Best possible solution:

Land this only after owner review confirms the SQLite schema, legacy doctor migration, and restart/update behavior preserve existing ACP sessions across canonical keys, session IDs, and channel delivery paths.

Do we have a high-confidence way to reproduce the issue?

Yes at source level: current main stores ACP metadata on SessionEntry.acp and uses a file-backed ACP event ledger, while this PR moves those runtime state paths to SQLite. I did not run a live restart/update reproduction in this read-only review.

Is this the best way to solve the issue?

Yes, likely: the shared SQLite store plus doctor migration is the maintainable direction under the repository's database-first policy. The remaining question is upgrade proof, not a better implementation layer.

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against a3fa5b6577a2.

Label changes

Label changes:

  • add P2: This is a normal-priority ACP persistence bugfix/refactor with meaningful but bounded gateway, command, and channel blast radius.
  • add merge-risk: 🚨 compatibility: Existing installs with ACP metadata in sessions.json or file-backed replay ledgers rely on the migration path to keep working after upgrade.
  • add merge-risk: 🚨 message-delivery: The migrated metadata controls ACP child delivery suppression and channel stale-session decisions, making delivery behavior sensitive to the new joins.
  • add merge-risk: 🚨 session-state: ACP runtime identity, state, and replay metadata move to SQLite and are matched by session key and session id, so a mismatch can stale or lose session state.
  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes structured after-fix proof from Blacksmith Testbox changed-lane execution plus focused Vitest, tsgo, oxlint, db schema check, and observed SQLite migration outcomes; no manual Discord ACP E2E was claimed.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (linked_artifact): The PR body includes structured after-fix proof from Blacksmith Testbox changed-lane execution plus focused Vitest, tsgo, oxlint, db schema check, and observed SQLite migration outcomes; no manual Discord ACP E2E was claimed.

Label justifications:

  • P2: This is a normal-priority ACP persistence bugfix/refactor with meaningful but bounded gateway, command, and channel blast radius.
  • merge-risk: 🚨 compatibility: Existing installs with ACP metadata in sessions.json or file-backed replay ledgers rely on the migration path to keep working after upgrade.
  • merge-risk: 🚨 session-state: ACP runtime identity, state, and replay metadata move to SQLite and are matched by session key and session id, so a mismatch can stale or lose session state.
  • merge-risk: 🚨 message-delivery: The migrated metadata controls ACP child delivery suppression and channel stale-session decisions, making delivery behavior sensitive to the new joins.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (linked_artifact): The PR body includes structured after-fix proof from Blacksmith Testbox changed-lane execution plus focused Vitest, tsgo, oxlint, db schema check, and observed SQLite migration outcomes; no manual Discord ACP E2E was claimed.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes structured after-fix proof from Blacksmith Testbox changed-lane execution plus focused Vitest, tsgo, oxlint, db schema check, and observed SQLite migration outcomes; no manual Discord ACP E2E was claimed.
Evidence reviewed

PR surface:

Source +939, Tests +538, Docs +3, Generated +39. Total +1519 across 36 files.

View PR surface stats
Area Files Added Removed Net
Source 23 1202 263 +939
Tests 10 978 440 +538
Docs 1 4 1 +3
Config 0 0 0 0
Generated 2 39 0 +39
Other 0 0 0 0
Total 36 2223 704 +1519

What I checked:

  • Repository policy read: Read the full root AGENTS.md plus scoped docs, extensions, agents, agent-tools, gateway, and gateway/server-methods guides; the storage-first and upgrade-sensitive state guidance directly affects this review. (AGENTS.md:1, 7061c1e5fd67)
  • Protected review state: The provided GitHub context shows the PR has the protected maintainer label, so this workflow should keep it open for explicit maintainer handling rather than close it as cleanup.
  • SQLite metadata implementation: The PR adds SQLite-backed ACP metadata reads and writes through readAcpSessionMeta, readAcpSessionEntry, listAcpSessionEntries, and upsertAcpSessionMeta, while removing embedded entry.acp persistence from session-store writes. (src/acp/runtime/session-meta.ts:160, 077d27f2124e)
  • Replay ledger implementation: The PR migrates legacy file-backed ACP replay ledgers and creates a SQLite-backed event ledger for runtime writes. (src/acp/event-ledger.ts:505, 077d27f2124e)
  • Doctor migration path: Legacy sessions.json ACP metadata is copied into SQLite and removed from the session entry during state migration. (src/infra/state-migrations.ts:2539, 077d27f2124e)
  • State schema surface: The PR adds the acp_sessions table and indexes to the shared OpenClaw state schema; replay tables already existed in the sampled base. (src/state/openclaw-state-schema.sql:529, 077d27f2124e)

Likely related people:

  • steipete: Prior history and shortlog show the largest sampled contribution volume across ACP, gateway, session-store, and state paths, including ACP/session helper refactors before this PR. (role: recent area contributor; confidence: high; commits: f476f8211c27, 5f3356a746ba, 28d478dc5232; files: src/acp/runtime/session-meta.ts, src/gateway/session-reset-service.ts, src/config/sessions/store.ts)
  • Bob: Prior ACP hardening work touched the startup and configured routing area that this SQLite metadata migration now depends on. (role: adjacent ACP runtime contributor; confidence: medium; commits: ea15819ecf2b, f6124f3e17a9; files: src/acp/runtime/session-meta.ts, src/acp/event-ledger.ts, src/gateway/session-reset-service.ts)
  • Vincent Koc: Recent history shows gateway and session-store discovery/type-surface work near the canonical-key and multi-store behavior this PR relies on. (role: adjacent gateway/session contributor; confidence: medium; commits: 46f0bfc55b58, f630e8d44037, 74e7b8d47b18; files: src/gateway/session-utils.ts, src/config/sessions/store.ts, src/acp/runtime/session-meta.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 077d27f212

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/acp-spawn.ts
const sessionStore = loadSessionStore(storePath);
for (const [sessionKey, entry] of Object.entries(sessionStore)) {
if (!sessionEntryMatchesAcpResumeSessionId(entry, resumeSessionId)) {
const acp = readAcpSessionMeta({ sessionKey });

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Pass the active config when reading ACP resume metadata

When spawnAcpDirect is invoked with a config whose session.store differs from the process-global runtime config, this lookup reads ACP metadata without params.cfg even though the target session store was loaded from params.cfg just above. readAcpSessionMeta then resolves a different store path before accepting rows with a session_id, so a valid resumeSessionId recorded in the configured target store is treated as missing and the spawn is rejected as resume_forbidden. Pass the same cfg/env context used to load sessionStore into the metadata read.

Useful? React with 👍 / 👎.

@steipete steipete merged commit db40fde into main May 31, 2026
150 checks passed
@steipete steipete deleted the fix/acp-sqlite-metadata-ledger branch May 31, 2026 17:38
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels May 31, 2026
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jun 1, 2026
* fix: persist acp metadata in sqlite

* test: align session store acp expectations
SYU8384 pushed a commit to SYU8384/openclaw that referenced this pull request Jun 3, 2026
* fix: persist acp metadata in sqlite

* test: align session store acp expectations
sablehead pushed a commit to sablehead/openclaw that referenced this pull request Jun 10, 2026
* fix: persist acp metadata in sqlite

* test: align session store acp expectations
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling channel: feishu Channel integration: feishu channel: telegram Channel integration: telegram commands Command implementations docs Improvements or additions to documentation gateway Gateway runtime maintainer Maintainer-authored PR proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: XL status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant