Repository navigation
Sprint 01: SurrealDB spike — parity adapters, migrations, bench (ADR-01) - #1
Merged
Merged
Conversation
…res, bench - append is now ONE BEGIN/COMMIT transaction (counter + create); no crash gaps - 0001_core.surql sanctioned additions: conversation, conv_counter (DEFAULT 0), intent_log fields (SCHEMAFULL was stripping undefined fields — outbox breaker) - type::record -> type::thing (documented API); created_at left to schema VALUE - conftest: surreal params run when SURREAL_URL set, isolated db per test - scripts/bench_snapshot.py: ADR-01 tripwire (1k msgs, 200 snapshots, p50/95/99) - spec sync note: fold .surql additions into SDAI-CHAT-003 Block 5 at 0.1.2 bump
CI surreal params all errored in fixture setup: apply_migrations hit `Parse error: Unexpected token 'an identifier', expected Eof --> [12:56]` — column 56 of line 12 is MTREE. The surrealdb/surrealdb:latest image is v3, which dropped MTREE; HNSW is the supported (and better) vector index. Embeddings are L2-normalized, so default Euclidean distance ranks identically to cosine. Sanctioned minimal fix; fold into SDAI-CHAT-003 Block 5 at the 0.1.2 spec sync.
The 2.x-to-3.x migration guide lists type::record as the new name for
type::thing ('consistent terminology', severity: will break). Restores
the function name Gemini originally used — the architect's swap to
type::thing was correct for v2 but wrong for the v3 image CI runs.
CI: 19 passed, 4 failed — all four failures were append getting None back from the BEGIN/COMMIT block. The SDK returns the last statement's result, and COMMIT yields nothing. Fix per the original architect ruling: LET $msg = (CREATE ...); RETURN $msg; inside the transaction — the transaction's return value is then the created record. Also: bounded retry (25 attempts, linear backoff) when SurrealDB's optimistic transactions report a conflict/retry error — relevant for the 50-concurrent-appends contract test hitting one counter record. Safe because the transaction is all-or-nothing: a conflicted attempt creates nothing, so a retry can never double-append.
…txns) The Python SDK yields None for any BEGIN/COMMIT batch, even with an explicit RETURN — confirmed across two CI runs. Restructure per the original ruling #5: the adapter generates the ULID (dependency-free Crockford base32 generator, no lockfile churn), the transaction is write-only, and the message is read back by known id with a plain single-statement SELECT — the shape that demonstrably works (the whole intent-log suite passes on single statements). turn and created_at remain server-stamped; atomicity is unchanged (counter + create still commit together, retry-on-conflict retained).
…ently CI: 22/23. Last failure showed conflicted transactions abort WITHOUT raising — the SDK returns None for txn batches either way, so the exception-based retry never fired. The read-back by known ULID is now the success check: message present -> committed; absent -> conflict abort -> retry the whole transaction. Safety: an aborted txn creates nothing and rolls back the counter (no turn gaps); a duplicate commit would fail loudly on the existing ULID rather than double-append.
Owner
Author
✅ CI green — 23/23Full contract suite passes identically against SurrealQL / SDK learnings to fold into SDAI-CHAT-003 @ 0.1.2All four CI failures were adapter/migration-side; the contract tests were never modified.
Item 4 was a real production bug, not a test artifact — without the read-back check, concurrent appends would silently drop messages in the live app. Exactly what 003 Block 7 test #6 exists to catch. Bench (local, authoritative)with SurrealDB running. CI bench is informational only (noisy runners). Tripwire: p95 < 100ms or ADR-01 gets revisited. |
Thib2108
marked this pull request as ready for review
July 3, 2026 14:13
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Sprint-01 SurrealDB spike (SDAI-CHAT-003 ADR-01 verdict machinery):
db/surreal.py— env-drivenconnect(), idempotentapply_migrations()(tracked in amigrationtable), all SurrealQL constants live here (Principle 4).repos/surreal_impl.py—SurrealMessageStore+SurrealIntentLogsatisfying the ports Protocols structurally. Append is one BEGIN/COMMIT transaction: ensure conversation →conv_counterUPSERTn += 1 RETURN AFTER→CREATE messagewith the allocated turn. Server stamps id (rand::ulid()), turn,created_at(schemaVALUE). Python byte-check is the authoritative 256 KB cap. No update/delete methods — append-only by construction.0001_core.surql— sanctioned additions (base stays verbatim from spec Block 5):conversationtable,conv_counter(nDEFAULT 0), andintent_logfield definitions (bug: SCHEMAFULL with no fields strips every write — the outbox would have silently stored empty records).tests/conftest.py— surreal params now run whenSURREAL_URLis set; each test gets a fresh isolated database with migrations applied. Skips cleanly otherwise.scripts/bench_snapshot.py— ADR-01 tripwire: 1,000 appends, 200 snapshots, p50/p95/p99/max; exit 1 if p95 ≥ 100 ms.Contract-test bodies: untouched (standing rule)
Verdict process
.surqladditions into SDAI-CHAT-003 Block 5).Known risks for review
_normalise_rowsis deliberately tolerant. If CI shows shape errors, fix parsing — not the tests.string::lenASSERT counts chars, not bytes — adapter byte-check is authoritative (belt-and-braces by design).