Skip to content

build(deps): fix SQLite lock-wait cancellation - #169

Merged
steipete merged 2 commits into
mainfrom
fix/sqlite-lock-cancellation
Oct 23, 2026
Merged

steipete merged 2 commits into
mainfrom
fix/sqlite-lock-cancellation

Conversation

@steipete

@steipete steipete commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

A write blocked by another transaction took 5.10 seconds to return with a 100 ms context deadline. Upgrade modernc.org/sqlite to v1.61.0 and its required libc v1.79.0 runtime so busy waits honor cancellation, preserving the Go 1.27.0 minimum and Go 1.27.3 build toolchain.

The regression through store.Open checks the deadline error, bounded return time, no unintended insert, and a successful retry after releasing the lock. Dependency-pair and explicit JSON-subquery documentation are updated.

Downstream migration completed

Gitcrawl #271 is merged. Its synthetic snapshot privacy assertion now wraps the scalar JSON aggregate in json(...), preserving exactly [[null,"",""],"",""] on SQLite 3.53.4 and 3.54.1. Production sanitization is unchanged. The earlier compatibility hold is resolved.

The downstream consumer audit found only that Gitcrawl test query depended on implicit subtype propagation. Notcrawl uses stored scalar fields; Photoscrawl directly decodes its album aggregate on read. Synthetic checks preserve those results on both SQLite versions. The other seven consumers have no SQL JSON constructors requiring migration.

Advance the pinned Gitcrawl source to its merged correction, keeping the existing published Crawlkit baseline, both complete CLI suites, timeouts, and isolation/integrity checks intact.

Validation

  • Old driver reproduces the 5.10-second lock wait; the updated driver passes the bounded cancellation regression.
  • Gitcrawl's original privacy assertion reproduced the candidate-driver failure; corrected snapshot tests pass on both driver versions.
  • Full make check passes on AWS Crabbox: tidy, formatting, vet, deadcode, govulncheck, unit/race tests, and all 48 script tests.
  • The unchanged downstream harness passes the complete baseline and candidate Gitcrawl CLI suites (41.7 seconds each), cancellation isolation, and source/module integrity checks on AWS Crabbox. The outer scratch cleanup encountered read-only Go module cache files after both suites passed; the lease was released. An earlier preflight selected the host Go instead of 1.27.3 and ran no tests; the successful proof explicitly selected 1.27.3.
  • actionlint and all 48 script tests pass after the pin/documentation update.
  • Independent Codex autoreview is scoped-clean through P3. Open Dependabot alerts: zero.

No downstream release is included. After publishing Crawlkit v0.17.3, downstream consumers can bump and release separately.

@steipete
steipete requested a review from a team as a code owner October 23, 2026 07:04
@clawsweeper

clawsweeper Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

🦞👀
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.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-23T21:09:58.906356Z 5ccd29c Draft marked ready
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@steipete
steipete marked this pull request as draft October 23, 2026 07:16
@clawsweeper clawsweeper Bot added clawsweeper:intake:bug Preliminary submission classification; full source review pending. P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed clawsweeper:intake:bug Preliminary submission classification; full source review pending. labels Oct 23, 2026
@clawsweeper

clawsweeper Bot commented Oct 23, 2026

Copy link
Copy Markdown

Codex review: needs changes before merge.

What this changes

Upgrade SQLite and libc to make database lock waits honor context deadlines, with a regression test and documentation updates.

Example: A write has a 100 ms deadline while another transaction holds the database lock.

  • Before: The recorded previous-driver run returned after 5.10 seconds.
  • After: The candidate regression reports timely deadline cancellation, no unintended insert, and a successful retry after unlocking.

Review scores

Measure Result What it means
Overall readiness 🦪 silver shellfish (2/6) The focused regression exercises real store connections, but the candidate has a concrete downstream compatibility failure and is intentionally paused.
Proof confidence 🦐 gold shrimp (3/6) Ordinary contributor proof gating is waived by the supplied maintainer-authored classification; the available cancellation evidence is the real-store regression and reported AWS Crabbox run, whose portal contents were inaccessible here.
Patch quality 🦪 silver shellfish (2/6) 1 actionable review finding remain.

Product

Kind: Bug fix · Worth it: Yes · Fix scope: Complete
User problem: A caller cancelling a database write can remain blocked until SQLite’s busy timeout expires.
Reason: The shared-store repair has clear value and maintainer-authored direction; the recorded hold already settles that this incompatible candidate must not merge yet.

Merge readiness

⛔ Needs changes before merge - 1 item remains

Keep this PR open and paused: cancellation remains unfixed on main, while the proposed dependency upgrade breaks the pinned downstream JSON assertion.

Priority: P2
Reviewed head: 9e5c386ae9e6672f13b385fd96984d41d9665a85

Before merge

  • Preserve the pinned downstream JSON assertion before upgrading SQLite (P2) - With the candidate driver, the scalar-subquery json_group_array result becomes a quoted string inside json_array. Gitcrawl’s pinned TestCloudSQLiteSnapshotLegacyPrivacyColumns/raw_without_comments expects [[null,"",""],"",""] and consequently fails the required downstream comparison. The body records a previous-versus-candidate reproduction, and the inspected downstream source contains that exact assertion. Retain the published runtime pair until an upstream fix or separately validated downstream correction resolves this failure; do not bypass the gate. This evidence establishes an assertion incompatibility, not archive corruption or a privacy leak.

Findings

  • [P2] Preserve the pinned downstream JSON assertion before upgrading SQLite — go.mod:17
Agent review details

How this fits together

Crawlkit’s store package opens SQLite connections for downstream archive applications; caller SQL and contexts enter through database/sql, and query results or cancellation errors return through the driver.

flowchart TD
  A[Downstream archive application] --> B[Crawlkit store]
  B --> C[Go database sql]
  C --> D[Modernc SQLite driver]
  D --> E[SQLite archive file]
  D --> F[Results and context errors]
Loading

Technical review

Best possible solution:

Keep the published runtime pair until a cancellation fix preserves downstream behavior or a separately validated downstream correction resolves the JSON assertion.

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

The temporary-file regression provides a concrete lock-contention reproducer, and the body records failure with the previous driver and success with the candidate; this review did not execute it.

Is this the best way to solve the issue?

Updating the shared driver is appropriately scoped, but this version is unsuitable while its independently identified downstream assertion fails.

Full review comments:

  • [P2] Preserve the pinned downstream JSON assertion before upgrading SQLite — go.mod:17
    With the candidate driver, the scalar-subquery json_group_array result becomes a quoted string inside json_array. Gitcrawl’s pinned TestCloudSQLiteSnapshotLegacyPrivacyColumns/raw_without_comments expects [[null,"",""],"",""] and consequently fails the required downstream comparison. The body records a previous-versus-candidate reproduction, and the inspected downstream source contains that exact assertion. Retain the published runtime pair until an upstream fix or separately validated downstream correction resolves this failure; do not bypass the gate. This evidence establishes an assertion incompatibility, not archive corruption or a privacy leak.
    Confidence: 0.97

Overall correctness: patch is incorrect
Overall confidence: 0.96

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning medium; reviewed against 4777448a4b69.

Provenance checked

  • SQLite/libc runtime selection changes intended behavior with a stated reason (eb92b28: build(deps): bump modernc.org/sqlite from 1.59.0 to 1.60.1 #149 selected SQLite v1.60.1 and its runtime dependencies; this PR explains the replacement as a cancellation repair.)
  • Dependency-pair documentation keeps the original intent (288e02a: chore: prepare crawlkit 0.16.8 #153 documented the shipped SQLite/libc pair; the patch preserves the exact-pair requirement.)
  • Indirect analysis and test dependencies keeps the original intent (af8f93d: Earlier dependency refreshes retained upstream test dependencies; this patch removes explicit requirements while retaining their checksums and reports module-tidiness validation.)

Testing

Proof path: in-process harness.

Security

None.

Evidence

What I checked:

  • Introduced dependency upgrade: The pinned PR diff upgrades SQLite v1.60.1 to v1.61.0 and libc v1.77.1 to v1.79.0; main still uses the published pair. (go.mod:17, 9e5c386ae9e6)
  • Focused cancellation regression: The added test uses temporary SQLite files through store.Open and checks the deadline error, bounded delay, absence of an unintended write, and connection reuse. (store/cancellation_test.go:12, 9e5c386ae9e6)
  • Recorded compatibility hold: The full PR body explicitly holds merging and records the same synthetic query producing a nested array with the previous runtime and a quoted JSON string with the candidate. Body source identity: 54f397aaa1824fe93c68e842df15535191719bf72c3f558d42444e9c59177364. (9e5c386ae9e6)
  • Exact-head downstream failure: The downstream job at https://github.com/openclaw/crawlkit/actions/runs/39915494101/job/120288975500 failed its comparison step for the reviewed head. Its raw log download was blocked by the network allowlist; attribution rests on the recorded comparative reproduction and independently inspected downstream assertion. (.github/workflows/ci.yml:40, 9e5c386ae9e6)
  • Pinned downstream oracle: Crawlkit CI explicitly executes this repository’s pinned CLI suite, establishing the dependency-contract signal. The legacy snapshot test nests json_group_array inside json_array and requires [[null,"",""],"",""]; the production sanitizer clears the underlying private strings. This establishes a changed test-query result, not a demonstrated privacy leak. No root AGENTS.md exists at this pin. (internal/cli/cloud_snapshot_test.go:218, 0a4cefe1858b)
  • Ownership and compatibility policy: The complete root AGENTS.md and boundary documentation require reusable store mechanics, temporary test data, and preservation of downstream contracts. There are no nested governing AGENTS.md files, maintainer notes, or pr-simplify skill in this checkout. (docs/boundary.md:3, 4777448a4b69)

Likely related people:

  • Peter Steinberger: Raw commit 4777448 adds go.mod:5 relative to its recorded parents. This identifies author metadata, not feature responsibility or a PR merger. (role: source-line author; confidence: high; commits: 4777448a4b69; files: go.mod)

Labels

Label changes:

  • add P2: Lock contention can delay cancellation by the five-second busy timeout; no broader outage or urgent released regression is established.
  • add merge-risk: 🚨 compatibility: The dependency upgrade changes nested JSON results and fails the pinned downstream assertion; passing library checks do not resolve that incompatibility.
  • add rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦐 gold shrimp and patch quality is 🦪 silver shellfish.
  • add status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action.

Label justifications:

  • P2: Lock contention can delay cancellation by the five-second busy timeout; no broader outage or urgent released regression is established.
  • merge-risk: 🚨 compatibility: The dependency upgrade changes nested JSON results and fails the pinned downstream assertion; passing library checks do not resolve that incompatibility.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦐 gold shrimp and patch quality is 🦪 silver shellfish.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action.

Rating scale

6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior.

Workflow

ClawSweeper edits this one comment on every review. Comment @clawsweeper re-review for a fresh review only. Repair and merge execution lanes are retired.

Reviewed October 23, 2026, 3:28 AM ET / 07:28 UTC.

steipete added a commit to openclaw/gitcrawl that referenced this pull request Oct 23, 2026
The cloud snapshot privacy check relied on SQLite preserving a JSON subtype through a scalar subquery. SQLite 3.54.1 quotes that nested array, so the check failed despite unchanged sanitization. Explicitly mark the subquery result with `json(...)` and preserve the exact expected array, including nulls and cleared private strings.

This unblocks the SQLite lock-cancellation update in openclaw/crawlkit#169 without weakening its pinned downstream compatibility gate. No production query or sanitizer behavior changes.

Validation: reproduced the existing failure with modernc.org/sqlite v1.61.0 (SQLite 3.54.1); all `TestCloudSQLiteSnapshot*` tests pass with both v1.60.1 (SQLite 3.53.4) and v1.61.0 using isolated module files. Independent Codex autoreview is clean through P3. CI runs the full repository gates.
@steipete
steipete marked this pull request as ready for review October 23, 2026 21:09
@steipete
steipete merged commit 05bbf74 into main Oct 23, 2026
9 of 11 checks passed
@steipete
steipete deleted the fix/sqlite-lock-cancellation branch October 23, 2026 21:19
steipete added a commit that referenced this pull request Oct 23, 2026
Prepare Crawlkit 0.17.3, a patch release for the SQLite write-lock cancellation fix from #169. The release preserves the Go 1.27.0 minimum, uses the matching SQLite v1.61.0/libc v1.79.0 pair, and keeps the migrated Gitcrawl compatibility gate.

Move the existing Unreleased bullet into a dated release section with a one-line highlight. Every existing changelog bullet is preserved, and the empty Unreleased header remains for future work.

Validation: #169's exact-head and post-merge CI are green, including the full downstream comparison. Full make check, govulncheck, and race tests passed during the fix; actionlint passes. This PR changes only the changelog. Independent Codex autoreview is clean through P3; CI repeats the complete gates on this head. Release publication follows the signed-tag GitHub Actions process after the merged-head dry run.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P2 Normal priority bug or improvement with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant