Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
edfd951
feat(cursor): add owner-scoped OAuth pool kernel
yansigit Sep 6, 2026
fe0593a
fix(cursor): harden pool isolation and rollback
yansigit Sep 6, 2026
c42ce67
chore(cursor): remove unused pool import
yansigit Sep 6, 2026
1d0e67b
test(cursor): cover pool security invariants
yansigit Sep 6, 2026
04b7424
fix(cursor): align pool tests with flat account seam
yansigit Sep 6, 2026
8290e84
style(cursor): format pool kernel and tests
yansigit Sep 6, 2026
e9e0462
fix(cursor): make rollback and rotation CAS precise
yansigit Sep 6, 2026
debedc6
fix(cursor): scope TTL affinity cleanup by owner
yansigit Sep 6, 2026
415bb1e
test(cursor): keep TTL fixtures usable
yansigit Sep 6, 2026
20a36cb
fix(cursor): restore identity fallback and clear opaque refs
yansigit Sep 6, 2026
d3a6345
style(cursor): keep crypto import at module boundary
yansigit Sep 6, 2026
126ee93
fix(cursor): preserve pool compatibility contracts
yansigit Sep 6, 2026
d5e2ed2
fix(cursor): scope pool rollback generations
yansigit Sep 6, 2026
3db5d22
test(cursor): verify pooled-token transport wiring in adapter
yansigit Sep 6, 2026
2b58f12
fix(cursor): address review findings for pool references, versions, a…
yansigit Sep 6, 2026
23f900a
fix(cursor): clear versions on pool reset and eliminate redundant sto…
yansigit Sep 6, 2026
6e1d189
fix(cursor): prune removed refs below activation threshold
yansigit Sep 6, 2026
45fafac
fix(cursor): invalidate snapshots for removed accounts
yansigit Sep 6, 2026
29115af
fix(cursor): invalidate swept account snapshots
yansigit Sep 6, 2026
5192183
fix(cursor): prune orphaned pool versions
yansigit Sep 6, 2026
4700059
perf(cursor): bound pool cleanup scans
yansigit Sep 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions src/adapters/cursor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ export interface CursorAdapterDeps {
kv?: CursorKvStore;
/** Test seam: observe/replace context-usage rekeying on conversation-id rotation. */
rekeyContextUsage?: (fromConversationId: string, toConversationId: string) => void;
/** Optional internal pool seam. Owner is supplied by trusted route parsing, never request headers. */
selectPoolToken?: (owner: string, thread: string) => string | undefined;
}

function safeCursorTransportError(err: unknown, sizeContext?: CursorSizeContext): string {
Expand Down Expand Up @@ -169,9 +171,8 @@ export function createCursorAdapter(provider: OcxProviderConfig, deps: CursorAda
const makeTransport = deps.createTransport ?? createLiveCursorTransport;
const kv = deps.kv ?? createCursorKvStore({}, incoming.translatorBudget);
const rekeyContextUsage = deps.rekeyContextUsage ?? rekeyCursorContextUsage;
// Namespace thread→conversation derivation by the authenticated Cursor credential so
// shared-proxy tenants with different Cursor accounts cannot collide on a parent thread id.
// Prefer an already-set auth scope (e.g. Codex pool account) when present.
// Pool ownership is a trusted parsed-route field. When older callers do not provide
// that scope, retain the credential-isolation fallback; the digest is never emitted.
if (!_parsed._cursorIdentityScope) {
try {
const token = resolveCursorToken(provider, incoming.headers);
Expand All @@ -181,9 +182,11 @@ export function createCursorAdapter(provider: OcxProviderConfig, deps: CursorAda
.digest("hex")
.slice(0, 16);
} catch {
/* Missing credential is handled by the live transport path below. */
// Missing credentials fail closed in the live transport path.
}
}
const pooledToken = deps.selectPoolToken?.(_parsed._cursorIdentityScope ?? "", _parsed._clientThreadId ?? "");
const activeProvider = pooledToken ? { ...provider, apiKey: pooledToken } : provider;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
const inheritedCheckpointRef = _parsed._providerContinuation?.cursor?.checkpointRef;
const previousConversationId = _parsed._cursorConversationId;
let request = {
Expand Down Expand Up @@ -323,7 +326,7 @@ export function createCursorAdapter(provider: OcxProviderConfig, deps: CursorAda
await runCursorTurnWithRetry(
makeTransport,
{
provider,
provider: activeProvider,
headers: incoming.headers,
translatorBudget: incoming.translatorBudget,
requestDeclaresFullAccess: cursorRequestDeclaresFullAccess(activeRequest),
Expand Down
Loading
Loading