Skip to content

fix(cloud-agent-next): prefix-scan preparation events by range, not LIKE - #4761

Merged
St0rmz1 merged 2 commits into
mainfrom
fix/cloud-agent-next-sqlite-glob-pattern
Jul 24, 2026
Merged

fix(cloud-agent-next): prefix-scan preparation events by range, not LIKE#4761
St0rmz1 merged 2 commits into
mainfrom
fix/cloud-agent-next-sqlite-glob-pattern

Conversation

@St0rmz1

@St0rmz1 St0rmz1 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Summary

The cloud-agent-next session storage had a single SQL LIKE, in
findByEntityPrefix (queries/events.ts), used to load preparation-history
events by entity_id prefix. That prefix embeds a preparation attemptId. When
a session's stored attemptId is very large, the pattern passed to LIKE
exceeds SQLite's max LIKE pattern length (50 KB) and throws "LIKE or GLOB
pattern too complex", which resets the Durable Object. reconcileStalePreparationAttempts
runs that query on every client reconnect, so once a session holds an oversized
attemptId it fails on every reconnect and cannot deliver its message.

This replaces the LIKE with a range scan that has no pattern-length limit, and
bounds the id length at ingest so an oversized value cannot be stored in the
first place. The affected query path was added with the preparation-history
feature in #4583.

Changes

  • queries/events.ts: findByEntityPrefix now matches prefixes with a
    half-open range scan (entity_id >= prefix AND entity_id < prefixUpperBound(prefix))
    instead of like(entity_id, ${prefix}%). Adds an exported prefixUpperBound
    helper (increments the final code unit of the prefix) and removes the now
    unused like import.
  • preparation-history.ts: materializePreparationEvent rejects a preparing
    event whose attemptId or triggerMessageId exceeds 256 characters before it
    is stored, and logs a warning with the sessionId and the offending lengths.
  • Tests: events.test.ts covers the prefixUpperBound bound arithmetic,
    including that a 100 KB prefix no longer throws. preparation-history.test.ts
    covers the oversized-id rejection (event dropped, nothing stored).

Verification

No manual end-to-end run. The failure lives in the Durable Object SQLite path,
and there is no local Durable Object harness in the service to exercise the real
query, so verification is by automated coverage plus static checks.

  • pnpm --filter cloud-agent-next test for the two changed test files (22 pass)
  • typecheck, lint (oxlint, 0 errors), format (oxfmt) all pass
  • Not manually run against a live session

Visual Changes

N/A

Reviewer Notes

  • For the entity_id values in use (ASCII paths ending in /), the range scan
    is equivalent to LIKE prefix%. It also stops treating %/_ in a prefix as
    wildcards, and removes the 50 KB pattern limit that caused the crash.
  • prefixUpperBound returns null for an empty prefix or one that is entirely
    U+FFFF; callers then fall back to a lower-bound-only scan (matches all rows at
    or after the prefix, same as the previous LIKE '%' for an empty prefix).
  • The 256-character id bound is defense in depth. A normal attemptId is a UUID
    (36 chars). The warn log surfaces the case if it ever happens, so the upstream
    emitter can be traced rather than the value being dropped silently.
  • No schema or migration change. The behavior change is limited to how the
    prefix query is expressed.

@kilo-code-bot

kilo-code-bot Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

Reviewed the incremental commit adding ASCII validation for preparation attemptId/triggerMessageId (on top of the existing length bound) to keep entity_id keys ASCII for the prefixUpperBound range-scan invariant; the isAscii check correctly flags surrogate-pair code units (e.g. emoji) as non-ASCII, and the new test verifies rejection.

Files Reviewed (3 files)
  • services/cloud-agent-next/src/session/preparation-history.ts
  • services/cloud-agent-next/src/session/preparation-history.test.ts
  • services/cloud-agent-next/src/session/queries/events.ts (doc-comment update only, no logic change)
Previous Review Summary (commit 7b91d5e)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 7b91d5e)

Status: No Issues Found | Recommendation: Merge

Executive Summary

Reviewed the switch from LIKE-based prefix scanning to a half-open range scan (prefixUpperBound) plus an oversized-id guard for preparation events, with high confidence in correctness after verifying the boundary arithmetic and test coverage.

Files Reviewed (4 files)
  • services/cloud-agent-next/src/session/queries/events.ts
  • services/cloud-agent-next/src/session/queries/events.test.ts
  • services/cloud-agent-next/src/session/preparation-history.ts
  • services/cloud-agent-next/src/session/preparation-history.test.ts

Reviewed by claude-sonnet-5 · Input: 24 · Output: 4.4K · Cached: 467.7K

Review guidance: REVIEW.md from base branch main

@St0rmz1
St0rmz1 merged commit bb0f8ff into main Jul 24, 2026
15 checks passed
@St0rmz1
St0rmz1 deleted the fix/cloud-agent-next-sqlite-glob-pattern branch July 24, 2026 20:56
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.

2 participants