refactor(core): cursor decode into core, queries and caches host-side (phase 8, stateful tier) - #840
Merged
Merged
Conversation
… (phase 8, stateful tier) Cursor is the bucket-D stateful multi-store provider: it keeps its bespoke adapter (no createBridgedProvider) and the host retains every store read. Tagged-record composition over five query families. The host issues all five queries in the load-bearing order [1] composerData meta, [2] bubble COUNT, [3] bubbles (paged or since), [4] agentKv, [5] user messages, preserving the per-query degradation semantics: [1]/[4]/[5] degrade to empty, [2] to total=0, and a [3] failure early-returns zero calls while still writing the (empty) cache and skipping [4]/[5]. decodeCursor() receives the four row sets plus the host-supplied agentKv timestamp and performs the whole stitched pass — the pre-pass scan, the agentKv fold, the user-message queue, and all three emit arms (per-bubble, per-conversation input, stream-only). The 19-key emitted call shape is a cache-compatibility contract. CURSOR_CACHE_VERSION stays 6 and PROVIDER_PARSE_VERSIONS['cursor'] is unchanged, so existing cursor-results.json files on disk are replayed through the new path; adding, dropping, or undefined-ing any key would poison them. The goldens gate the key set with Object.keys() on every arm, which is what catches a key present with an undefined value — toEqual cannot see one, and JSON.stringify drops exactly those on the way into the cache. Pricing, bash base-name extraction, display names, project attribution, SQL, paging, env reads and clock reads all stay host-side; toProviderCall is the single mapper that re-adds costBasis 'estimated', costIsEstimated true and the resolved pricing model. No costUSD is ever emitted. Composer-id / dedup-key envelope finding: composer ids and request ids flow into sessionId and into the envelope's dedupKeys by design, exactly like every other provider's machine identifiers, so the content-smuggling block deliberately does not plant a secret there. Hashing dedup keys uniformly is a schema-wide follow-up, not a cursor-local change. Validator fixes on top of the migration: - relocated the content-smuggling block from cursor-decode.test.ts into content-smuggling.test.ts, matching all 25 other providers, and added a probe proving each planted secret actually reaches the field it guards - G11 now gates the undefined-key cache contract it claimed to (toEqual passed under an injected extra undefined key; toStrictEqual plus key-set assertions catch it) - restored the CODEBURN_CURSOR_MAX_BUBBLES override in the golden's afterEach so G12 cannot leak the scan budget into cursor-large-db-cap.test.ts - restored the comment rationales that must travel with their code verbatim (pos-cursor queue performance note, parseComposerIdFromKey CR/LF signature, agentKv stream and pending-flush notes, dedup-key history, costIsEstimated) The 12 goldens were cross-checked against the pre-migration provider by restoring it in place: they pass identically on both sides. H2 (queue pop before skip) and H4 (arm B dedup-key burn before the timestamp check) were mutation tested and are killed by G8 and C6 respectively.
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.
Phase 8 stateful tier (tracking #809), second of three: cursor. The pure decode over all three emit arms (per-bubble, per-conversation-input, agentKv-only) moves into
@codeburn/coreas tagged records; the five sqlite query families keep their lazy order and exact non-uniform failure semantics host-side (bubble-query failure still early-returns AND writes the empty cache), along with blobToText, workspace routing, paging/cap,resolveModel/CURSOR_COST_MODEL, and the results cache.The 19-key emitted shape is a cache-compatibility contract —
CURSOR_CACHE_VERSIONstays 6, so live caches on users' disks must read back shape-identical. The goldens gate it with explicit sorted-key assertions; validation proved by mutation that those key-set gates (nottoEqual, which is blind to present-with-undefined keys) are what hold the contract, and strengthened the cache round-trip golden totoStrictEqualafter showing its claimed guarantee was false as written.Flow: Opus spec (18-hazard checklist) → Kimi in checkpointed steps (12 goldens verified 12/12 pre-migration; core module; CLI conversion) after an earlier monolithic draft attempt wedged and was discarded → Opus validation with oracle restoration (54/54 identical under the pre-migration original) and mutation batteries (queue-pop-before-skip and key-burn-before-timestamp-check both killed).
Also surfaced and documented: composer ids flow verbatim into envelope
deduplicationKeys by design (they are client-generated UUIDs; identifier-class fields are exempt from secret-planting per the established convention, reasoning in the smuggling block) — uniform envelope-side dedup-key hashing is logged as a schema-wide follow-up, not a cursor-local change. Validator additionally fixed an env-var leak between test files, restored condensed must-move-verbatim comments, and relocated the smuggling block tocontent-smuggling.test.tsmatching all 25 other providers.Gates: core 465/465; CLI suite and root
npm test2440 passed, 5 skipped; the five pre-existing cursor test files byte-identical;tsc --noEmitclean; no cache/parse-version changes.Known wart (pre-existing, flagged):
cursor-cache.tsignoresCODEBURN_CACHE_DIR(useshomedir()directly).