Skip to content

refactor(talk): centralize typed voice session queries - #139103

Merged
steipete merged 1 commit into
mainfrom
codex/sqlite-goal-talk-store
Sep 5, 2026
Merged

steipete merged 1 commit into
mainfrom
codex/sqlite-goal-talk-store

Conversation

@steipete

@steipete steipete commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

Talk voice sessions constructed the same cache queries in both the lifecycle module and the persistence module. Point reads were duplicated, and recovery code owned its own SQL and row assertions.

Why This Change Was Made

Keep all five ordinary queries in the existing Talk store, using the generated agent-database types and shared Kysely compile/bind helpers. The lifecycle code now asks the store for its records. Native get, eager all, and run execution retain the existing database/error owner and supplied transaction handle.

The UPSERT still updates only JSON and update time, preserving blob/expiry columns. Native preparation still precedes payload getters and JSON serialization. Recovery takes its full candidate snapshot before asynchronous work; the legacy lookup still requires a unique open session. Production: +58/-37 (net +21); tests: +58; four row assertions removed. No schema, config, public API, retention, or PostgreSQL change.

Evidence

  • 74 focused tests, a final seven-test store run, full changed-file gate, and Kysely guard passed. Independent review found no P0–P2 findings.
  • Nine actual-owner baseline/candidate scenarios match: a 70,230-byte record, blob/expiry custody, preparation/binding order, rejected write rollback and retry, authorizer denial, agent isolation, malformed records, ambiguous lookup, and stale-snapshot boundaries. Three agent databases reopen with matching rows and valid integrity checks.
  • A real built Gateway stored exactly two transcript messages from three requests, preserved duplicate/close idempotency, and retained exact voice JSON and transcript rows after restart. A post-close append returned the expected structured refusal without a durable change. Owned processes, homes, and ports were cleaned up.

Two early Gateway harness failures involved native row prototypes and JSON-mode error output; both are retained with their cleanup receipts. Only those task-local comparisons were corrected. The single runtime build was reused after comment-only guard annotations were proved to emit identical JavaScript; all 5,597 recorded build hashes remained unchanged. No external voice provider, audio transport, or performance claim.

@steipete steipete self-assigned this Sep 5, 2026
@clawsweeper

clawsweeper Bot commented Sep 5, 2026 •

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

ClawSweeper review complete

ClawSweeper finished reviewing this revision. The review result is being finalized.

View the workflow run.

@openclaw-barnacle openclaw-barnacle Bot added size: S maintainer Maintainer-authored PR labels Sep 5, 2026
@clawsweeper clawsweeper Bot added P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. 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 Sep 5, 2026
@clawsweeper

clawsweeper Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Codex review: blocked before merge. Reviewed September 5, 2026, 9:16 AM ET / 13:16 UTC.

ClawSweeper review

What this changes

Centralizes Talk voice-session database queries in the existing persistence module, uses typed query builders, and adds rollback and retry coverage.

Merge readiness

⛔ Blocked before merge - 2 items remain

Current main still contains the duplicated queries, so this maintainer-owned refactor remains useful. No introduced correctness defect was found.

Priority: P3
Reviewed head: e6b8c770b4e6b9a2ca90c97e7b2c7eaca971aae2

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) A focused refactor with useful storage-contract coverage and no concrete correctness finding.
Proof confidence 🌊 off-meta tidepool Not applicable: The supplied MEMBER association exempts this internal refactor from the external-contributor proof gate; no material authority change triggers an exception. The captured body reports actual-owner persistence and built-Gateway restart checks, which were not independently executed here.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Not applicable Not applicable: The supplied MEMBER association exempts this internal refactor from the external-contributor proof gate; no material authority change triggers an exception. The captured body reports actual-owner persistence and built-Gateway restart checks, which were not independently executed here.
Evidence reviewed 9 items Verified introduction and merge boundary: The introduced delta is merge-base 49ecde8 to the reviewed head. The test merge has the pinned base followed by that exact head as parents, and its delta contains only the four supplied paths. Production changes total +21 net lines; tests add 58 lines; the assertion baseline records four removed assertions.
Current-main necessity: Fetched main retains separate raw-SQL point reads and lifecycle-owned scans. Both production modules match the PR merge-base versions, so this consolidation is not already present there. Inspection of the supplied latest-release tag could not retrieve its source; no release-inclusion claim is made.
Query and transaction invariants: Point reads retain scope/key predicates; recovery retains its inclusive timestamp cutoff and eager all() snapshot. The UPSERT updates only value_json and updated_at, and prepares the native statement before evaluating record bindings. The existing transaction owner still supplies the database handle and handles rollback.
Findings None None.
Security None None.

How this fits together

Talk stores per-agent voice-call records used by client requests, transcript persistence, and abandoned-call recovery. The persistence module translates those operations into SQLite queries while the lifecycle module enforces session ownership and close behavior.

flowchart TD
  A[Talk client requests] --> B[Voice session lifecycle]
  C[Abandoned call recovery] --> B
  B --> D[Ownership and state checks]
  D --> E[Talk persistence module]
  E --> F[Per-agent SQLite database]
  F --> E
  E --> G[Transcript and close outcomes]
Loading

Before merge

  • Resolve merge risk (P1) - Direct Kysely 0.29.5 compiler-contract inspection remains incomplete because dependency source was unavailable locally and upstream DNS failed; this is a reviewer limitation, not missing contributor proof.
  • Complete next step (P2) - Complete direct inspection of Kysely 0.29.5 query compilation and binding semantics in an environment with dependency source available.
Agent review details

Security

None.

PR surface

Source +21, Tests +58, Other 0. Total +79 across 4 files.

View PR surface stats
Area Files Added Removed Net
Source 2 58 37 +21
Tests 1 58 0 +58
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 1 2 2 0
Total 4 118 39 +79

Review metrics

Metric Value Why it matters
Production versus test growth Production +21 net lines; tests +58 net lines The production growth consolidates query ownership and replaces four row assertions; test growth protects rollback and column-preservation contracts.

Merge-risk options

Maintainer options:

  1. Decide the mitigation before merge
    Keep one Talk persistence owner using the shared typed builder while preserving native execution, transaction custody, record format, and eager recovery snapshots.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Technical review

Best possible solution:

Keep one Talk persistence owner using the shared typed builder while preserving native execution, transaction custody, record format, and eager recovery snapshots.

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

Not applicable: this is a behavior-preserving refactor, and source inspection confirms the duplicated queries on current main.

Is this the best way to solve the issue?

Yes at the owner boundary: reusing the existing store and compile/bind helper removes duplicated SQL without switching to an executor that changes native error or iteration behavior.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against d37ed30158b5.

Labels

Label changes:

  • add P3: This is an internal query-ownership cleanup with no intended user-facing behavior change.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🌊 off-meta tidepool and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Not applicable: The supplied MEMBER association exempts this internal refactor from the external-contributor proof gate; no material authority change triggers an exception. The captured body reports actual-owner persistence and built-Gateway restart checks, which were not independently executed here.

Label justifications:

  • P3: This is an internal query-ownership cleanup with no intended user-facing behavior change.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🌊 off-meta tidepool and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Not applicable: The supplied MEMBER association exempts this internal refactor from the external-contributor proof gate; no material authority change triggers an exception. The captured body reports actual-owner persistence and built-Gateway restart checks, which were not independently executed here.

Evidence

What I checked:

  • Verified introduction and merge boundary: The introduced delta is merge-base 49ecde8 to the reviewed head. The test merge has the pinned base followed by that exact head as parents, and its delta contains only the four supplied paths. Production changes total +21 net lines; tests add 58 lines; the assertion baseline records four removed assertions. (e6b8c770b4e6)
  • Current-main necessity: Fetched main retains separate raw-SQL point reads and lifecycle-owned scans. Both production modules match the PR merge-base versions, so this consolidation is not already present there. Inspection of the supplied latest-release tag could not retrieve its source; no release-inclusion claim is made. (src/talk/client-voice-session-store.ts:122, d37ed30158b5)
  • Query and transaction invariants: Point reads retain scope/key predicates; recovery retains its inclusive timestamp cutoff and eager all() snapshot. The UPSERT updates only value_json and updated_at, and prepares the native statement before evaluating record bindings. The existing transaction owner still supplies the database handle and handles rollback. (src/talk/client-voice-session-store.ts:134, e6b8c770b4e6)
  • Callers, siblings, and ownership: Legacy tool-call resolution still requires a unique matching open client record; stale recovery snapshots candidates before awaiting close. Client and relay transcript paths share the same store, and mutation-digest bookkeeping uses its transaction functions. Existing agent/session ownership, origin, and closed-state checks remain unchanged. (src/talk/client-voice-session.ts:397, e6b8c770b4e6)
  • Contract coverage: The added test uses the actual database owner and a SQLite rejection trigger to check rollback, subsequent retry, and blob/expiry preservation. Existing lifecycle tests cover ownership rejection, idempotent close, ambiguous lookup, and stale-versus-recent records. Tests were inspected, not executed; git diff --check passed. (src/talk/client-voice-session-store.test.ts:34, e6b8c770b4e6)
  • Dependency signal and existing abstraction: The patch directly uses the Kysely compile/bind helper; package.json pins Kysely 0.29.5. The helper preserves invocation-local bindings and leaves native execution to callers, an existing pattern also used by proxy-capture persistence. These paths establish a Kysely dependency contract, with no affirmative Codex runtime or protocol dependency. (src/infra/kysely-sync.ts:297, e6b8c770b4e6)

Likely related people:

  • steipete: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)
  • Vincent Koc: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)

Rank-up moves

Optional improvements that raise the rating; they are not merge blockers.

  • Complete reviewer-side inspection of the pinned Kysely compiler and parameter-binding contract.

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
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.

Workflow

  • 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.

@steipete

steipete commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

The two remaining review items and the rank-up move concern access to the same pinned dependency contract. I inspected the installed Kysely 0.29.5 implementation directly: insert-values-parser preserves column/value correspondence; update-set-parser retains the supplied update entries; default-query-compiler visits bound values in SQL order and pushes their original values into the parameter list; the SQLite compiler emits ? placeholders. The shared compile/bind helper therefore receives the original unique markers and resolves their readers in actual compiler order.

The native statement is still prepared before those readers evaluate the record. Talk keeps native get/all/run and the caller-supplied transaction handle; the UPSERT updates only value_json and updated_at. Direct baseline/candidate native proof covered preparation and binding order, blob/expiry preservation, rejected write rollback/retry, agent isolation, ambiguous lookup and stale-snapshot boundaries. The real built Gateway transcript, duplicate/close, restart and post-close refusal checks passed, as did the focused tests and complete changed gate. Four independent review reports are clean, and hosted CI is green on the unchanged head.

This resolves the reviewer-side dependency access gap without a production change or policy exception. No Codex protocol/runtime dependency is involved in this query refactor.

@steipete
steipete merged commit 84b79be into main Sep 5, 2026
180 checks passed
@steipete
steipete deleted the codex/sqlite-goal-talk-store branch September 5, 2026 17:03
@steipete

steipete commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

Merged via squash.

vincentkoc added a commit to aniruddhaadak80/openclaw that referenced this pull request Sep 5, 2026
* commit '3e4becea5e2ce38ede69e8ecf5302805ecbfc09c':
  refactor: simplify outbound message execution context (openclaw#139107)
  fix(models): keep ordinary chat selections session-scoped (openclaw#139232)
  docs: slim root agent instructions and clarify testing scope (openclaw#139236)
  test(agents): give the sibling-drain completion wait a tolerance on slow runners (openclaw#139176)
  refactor(workboard): use canonical queries for card-tree writes (openclaw#139106)
  fix(canvas): recognize versioned macOS nodes (openclaw#138958)
  fix: load GitHub connections without a default agent (openclaw#139222)
  fix(memory): explain unsafe legacy host-event path recovery (openclaw#139195)
  refactor(talk): centralize typed voice session queries (openclaw#139103)
  fix(cli): preserve command dispatch and structured errors (openclaw#139067)
  refactor(agents): consolidate reply failure summaries (openclaw#139175)
  fix(auth): keep an unset default model unchanged during login (openclaw#139218)
  perf(media): reuse validated attachment read handles (openclaw#139168)
  refactor(channels): simplify account configuration updates (openclaw#139096)
  refactor(android): remove unused updater export root (openclaw#139198)
  fix(gateway): stop admitting post-ready producers during close (openclaw#139092)
  fix(gateway): expose agent hook completion outcomes (openclaw#139155)
  fix(config): return the saved configuration after plugin install commits (openclaw#139203)
  fix(android): reduce repeated retries to unreachable gateways (openclaw#138732)
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Sep 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintainer Maintainer-authored PR P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: S 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