import { AuthSessionId, ThreadId, type AuthEnvironmentScope } from "@t3tools/contracts";import { assert, describe, it } from "@effect/vitest";import * as DateTime from "effect/DateTime";import * as Effect from "effect/Effect";import * as Layer from "effect/Layer";import * as SqlClient from "effect/unstable/sql/SqlClient"; import * as AuthPairingLinks from "./AuthPairingLinks.ts";import * as AuthSessions from "./AuthSessions.ts";import * as PersistenceErrors from "./Errors.ts";import { SqlitePersistenceMemory } from "./Layers/Sqlite.ts";import * as ProviderSessionRuntime from "./ProviderSessionRuntime.ts"; const issuedAt = DateTime.makeUnsafe("2026-06-20T00:00:00.000Z");const expiresAt = DateTime.makeUnsafe("2027-06-20T00:00:00.000Z");const now = DateTime.makeUnsafe("2026-06-21T00:00:00.000Z");const scopes: ReadonlyArray<AuthEnvironmentScope> = ["access:read"]; const authSessionLayer = AuthSessions.layer.pipe(Layer.provideMerge(SqlitePersistenceMemory));const authPairingLinkLayer = AuthPairingLinks.layer.pipe( Layer.provideMerge(SqlitePersistenceMemory),);const providerSessionRuntimeLayer = ProviderSessionRuntime.layer.pipe( Layer.provideMerge(SqlitePersistenceMemory),); describe("persistence error correlation", () => { it.effect("correlates auth session SQL and row-decode failures without sensitive fields", () => Effect.gen(function* () { const sessions = yield* AuthSessions.AuthSessionRepository; const sql = yield* SqlClient.SqlClient; const sessionId = AuthSessionId.make("session-correlation"); const currentSessionId = AuthSessionId.make("current-session-correlation"); const subject = "session-subject-secret-sentinel"; yield* sessions.create({ sessionId, subject, scopes, method: "browser-session-cookie", client: { label: null, ipAddress: null, userAgent: null, deviceType: "desktop", os: null, browser: null, }, issuedAt, expiresAt, }); yield* sql` UPDATE auth_sessions SET scopes = ${"session-scopes-secret-sentinel"} WHERE session_id = ${sessionId} `; const decodeError = yield* Effect.flip(sessions.listActive({ now })); assert.instanceOf(decodeError, PersistenceErrors.PersistenceDecodeError); assert.deepStrictEqual(decodeError.correlation, { sessionId }); assert.equal( decodeError.message, `Decode error in AuthSessionRepository.listActive:decodeRows: ${decodeError.issue}`, ); assert.notInclude(decodeError.issue, subject); assert.notInclude(decodeError.issue, "session-scopes-secret-sentinel"); assert.notInclude(decodeError.message, subject); yield* sql`DROP TABLE auth_sessions`; const createError = yield* Effect.flip( sessions.create({ sessionId, subject, scopes, method: "browser-session-cookie", client: { label: null, ipAddress: null, userAgent: null, deviceType: "desktop", os: null, browser: null, }, issuedAt, expiresAt, }), ); assert.instanceOf(createError, PersistenceErrors.PersistenceSqlError); assert.deepStrictEqual(createError.correlation, { sessionId }); assert.equal(createError.message, "SQL error in AuthSessionRepository.create:query"); assert.notInclude(createError.message, subject); assert.notInclude(createError.message, DateTime.formatIso(issuedAt)); const revokeOtherError = yield* Effect.flip( sessions.revokeAllExcept({ currentSessionId, revokedAt: now }), ); assert.instanceOf(revokeOtherError, PersistenceErrors.PersistenceSqlError); assert.deepStrictEqual(revokeOtherError.correlation, { currentSessionId }); assert.equal( revokeOtherError.message, "SQL error in AuthSessionRepository.revokeAllExcept:query", ); assert.notInclude(revokeOtherError.message, DateTime.formatIso(now)); }).pipe(Effect.provide(authSessionLayer)), ); it.effect("correlates pairing-link create and revoke failures by id only", () => Effect.gen(function* () { const pairingLinks = yield* AuthPairingLinks.AuthPairingLinkRepository; const sql = yield* SqlClient.SqlClient; const id = "pairing-link-correlation"; const credential = "pairing-credential-secret-sentinel"; const subject = "pairing-subject-secret-sentinel"; const scopesPayload = "pairing-scopes-secret-sentinel"; yield* sql` INSERT INTO auth_pairing_links ( id, credential, method, scopes, subject, label, proof_key_thumbprint, created_at, expires_at, consumed_at, revoked_at ) VALUES ( ${id}, ${credential}, ${"one-time-token"}, ${scopesPayload}, ${subject}, NULL, NULL, ${DateTime.formatIso(issuedAt)}, ${DateTime.formatIso(expiresAt)}, NULL, NULL ) `; const decodeError = yield* Effect.flip(pairingLinks.getByCredential({ credential })); assert.instanceOf(decodeError, PersistenceErrors.PersistenceDecodeError); assert.deepStrictEqual(decodeError.correlation, { pairingLinkId: id }); assert.equal( decodeError.message, `Decode error in AuthPairingLinkRepository.getByCredential:decodeRow: ${decodeError.issue}`, ); assert.notInclude(decodeError.issue, credential); assert.notInclude(decodeError.issue, subject); assert.notInclude(decodeError.issue, scopesPayload); assert.notInclude(decodeError.message, DateTime.formatIso(issuedAt)); yield* sql`DROP TABLE auth_pairing_links`; const createError = yield* Effect.flip( pairingLinks.create({ id, credential, method: "one-time-token", scopes, subject, label: null, proofKeyThumbprint: null, createdAt: issuedAt, expiresAt, }), ); assert.instanceOf(createError, PersistenceErrors.PersistenceSqlError); assert.deepStrictEqual(createError.correlation, { pairingLinkId: id }); assert.notInclude(createError.message, credential); assert.notInclude(createError.message, subject); assert.notInclude(createError.message, DateTime.formatIso(issuedAt)); const revokeError = yield* Effect.flip(pairingLinks.revoke({ id, revokedAt: now })); assert.instanceOf(revokeError, PersistenceErrors.PersistenceSqlError); assert.deepStrictEqual(revokeError.correlation, { pairingLinkId: id }); assert.notInclude(revokeError.message, credential); assert.notInclude(revokeError.message, DateTime.formatIso(now)); }).pipe(Effect.provide(authPairingLinkLayer)), ); it.effect("skips undecodable provider runtime rows and correlates SQL failures by thread", () => Effect.gen(function* () { const runtimes = yield* ProviderSessionRuntime.ProviderSessionRuntimeRepository; const sql = yield* SqlClient.SqlClient; const threadId = ThreadId.make("thread-correlation"); const runtimePayload = "runtime-payload-secret-sentinel"; const lastSeenAt = "2026-06-20T00:00:00.000Z"; yield* sql` INSERT INTO provider_session_runtime ( thread_id, provider_name, provider_instance_id, adapter_key, runtime_mode, status, last_seen_at, resume_cursor_json, runtime_payload_json ) VALUES ( ${threadId}, ${"codex"}, NULL, ${"codex"}, ${"invalid-runtime-mode"}, ${"running"}, ${lastSeenAt}, NULL, ${`{"secret":"${runtimePayload}"}`} ) `; const validThreadId = ThreadId.make("thread-valid"); yield* runtimes.upsert({ threadId: validThreadId, providerName: "codex", providerInstanceId: null, adapterKey: "codex", runtimeMode: "full-access", status: "running", lastSeenAt, resumeCursor: null, runtimePayload: null, }); const listed = yield* runtimes.list(); assert.deepStrictEqual( listed.map((runtime) => runtime.threadId), [validThreadId], ); yield* sql`DROP TABLE provider_session_runtime`; const sqlFailure = yield* Effect.flip( runtimes.upsert({ threadId, providerName: "codex", providerInstanceId: null, adapterKey: "codex", runtimeMode: "full-access", status: "running", lastSeenAt, resumeCursor: null, runtimePayload: { secret: runtimePayload }, }), ); assert.instanceOf(sqlFailure, PersistenceErrors.PersistenceSqlError); assert.deepStrictEqual(sqlFailure.correlation, { threadId }); assert.equal( sqlFailure.message, "SQL error in ProviderSessionRuntimeRepository.upsert:query", ); assert.notInclude(sqlFailure.message, runtimePayload); assert.notInclude(sqlFailure.message, lastSeenAt); }).pipe(Effect.provide(providerSessionRuntimeLayer)), );});
import { AuthSessionId, ThreadId, type AuthEnvironmentScope } from "@t3tools/contracts";
import { assert, describe, it } from "@effect/vitest";
import * as DateTime from "effect/DateTime";
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
import * as SqlClient from "effect/unstable/sql/SqlClient";
import * as AuthPairingLinks from "./AuthPairingLinks.ts";
import * as AuthSessions from "./AuthSessions.ts";
import * as PersistenceErrors from "./Errors.ts";
import { SqlitePersistenceMemory } from "./Layers/Sqlite.ts";
import * as ProviderSessionRuntime from "./ProviderSessionRuntime.ts";
const issuedAt = DateTime.makeUnsafe("2026-06-20T00:00:00.000Z");
const expiresAt = DateTime.makeUnsafe("2027-06-20T00:00:00.000Z");
const now = DateTime.makeUnsafe("2026-06-21T00:00:00.000Z");
const scopes: ReadonlyArray<AuthEnvironmentScope> = ["access:read"];
const authSessionLayer = AuthSessions.layer.pipe(Layer.provideMerge(SqlitePersistenceMemory));
const authPairingLinkLayer = AuthPairingLinks.layer.pipe(
Layer.provideMerge(SqlitePersistenceMemory),
);
const providerSessionRuntimeLayer = ProviderSessionRuntime.layer.pipe(
Layer.provideMerge(SqlitePersistenceMemory),
);
describe("persistence error correlation", () => {
it.effect("correlates auth session SQL and row-decode failures without sensitive fields", () =>
Effect.gen(function* () {
const sessions = yield* AuthSessions.AuthSessionRepository;
const sql = yield* SqlClient.SqlClient;
const sessionId = AuthSessionId.make("session-correlation");
const currentSessionId = AuthSessionId.make("current-session-correlation");
const subject = "session-subject-secret-sentinel";
yield* sessions.create({
sessionId,
subject,
scopes,
method: "browser-session-cookie",
client: {
label: null,
ipAddress: null,
userAgent: null,
deviceType: "desktop",
os: null,
browser: null,
},
issuedAt,
expiresAt,
});
yield* sql`
UPDATE auth_sessions
SET scopes = ${"session-scopes-secret-sentinel"}
WHERE session_id = ${sessionId}
`;
const decodeError = yield* Effect.flip(sessions.listActive({ now }));
assert.instanceOf(decodeError, PersistenceErrors.PersistenceDecodeError);
assert.deepStrictEqual(decodeError.correlation, { sessionId });
assert.equal(
decodeError.message,
`Decode error in AuthSessionRepository.listActive:decodeRows: ${decodeError.issue}`,
);
assert.notInclude(decodeError.issue, subject);
assert.notInclude(decodeError.issue, "session-scopes-secret-sentinel");
assert.notInclude(decodeError.message, subject);
yield* sql`DROP TABLE auth_sessions`;
const createError = yield* Effect.flip(
sessions.create({
sessionId,
subject,
scopes,
method: "browser-session-cookie",
client: {
label: null,
ipAddress: null,
userAgent: null,
deviceType: "desktop",
os: null,
browser: null,
},
issuedAt,
expiresAt,
}),
);
assert.instanceOf(createError, PersistenceErrors.PersistenceSqlError);
assert.deepStrictEqual(createError.correlation, { sessionId });
assert.equal(createError.message, "SQL error in AuthSessionRepository.create:query");
assert.notInclude(createError.message, subject);
assert.notInclude(createError.message, DateTime.formatIso(issuedAt));
const revokeOtherError = yield* Effect.flip(
sessions.revokeAllExcept({ currentSessionId, revokedAt: now }),
);
assert.instanceOf(revokeOtherError, PersistenceErrors.PersistenceSqlError);
assert.deepStrictEqual(revokeOtherError.correlation, { currentSessionId });
assert.equal(
revokeOtherError.message,
"SQL error in AuthSessionRepository.revokeAllExcept:query",
);
assert.notInclude(revokeOtherError.message, DateTime.formatIso(now));
}).pipe(Effect.provide(authSessionLayer)),
);
it.effect("correlates pairing-link create and revoke failures by id only", () =>
Effect.gen(function* () {
const pairingLinks = yield* AuthPairingLinks.AuthPairingLinkRepository;
const sql = yield* SqlClient.SqlClient;
const id = "pairing-link-correlation";
const credential = "pairing-credential-secret-sentinel";
const subject = "pairing-subject-secret-sentinel";
const scopesPayload = "pairing-scopes-secret-sentinel";
yield* sql`
INSERT INTO auth_pairing_links (
id,
credential,
method,
scopes,
subject,
label,
proof_key_thumbprint,
created_at,
expires_at,
consumed_at,
revoked_at
)
VALUES (
${id},
${credential},
${"one-time-token"},
${scopesPayload},
${subject},
NULL,
NULL,
${DateTime.formatIso(issuedAt)},
${DateTime.formatIso(expiresAt)},
NULL,
NULL
)
`;
const decodeError = yield* Effect.flip(pairingLinks.getByCredential({ credential }));
assert.instanceOf(decodeError, PersistenceErrors.PersistenceDecodeError);
assert.deepStrictEqual(decodeError.correlation, { pairingLinkId: id });
assert.equal(
decodeError.message,
`Decode error in AuthPairingLinkRepository.getByCredential:decodeRow: ${decodeError.issue}`,
);
assert.notInclude(decodeError.issue, credential);
assert.notInclude(decodeError.issue, subject);
assert.notInclude(decodeError.issue, scopesPayload);
assert.notInclude(decodeError.message, DateTime.formatIso(issuedAt));
yield* sql`DROP TABLE auth_pairing_links`;
const createError = yield* Effect.flip(
pairingLinks.create({
id,
credential,
method: "one-time-token",
scopes,
subject,
label: null,
proofKeyThumbprint: null,
createdAt: issuedAt,
expiresAt,
}),
);
assert.instanceOf(createError, PersistenceErrors.PersistenceSqlError);
assert.deepStrictEqual(createError.correlation, { pairingLinkId: id });
assert.notInclude(createError.message, credential);
assert.notInclude(createError.message, subject);
assert.notInclude(createError.message, DateTime.formatIso(issuedAt));
const revokeError = yield* Effect.flip(pairingLinks.revoke({ id, revokedAt: now }));
assert.instanceOf(revokeError, PersistenceErrors.PersistenceSqlError);
assert.deepStrictEqual(revokeError.correlation, { pairingLinkId: id });
assert.notInclude(revokeError.message, credential);
assert.notInclude(revokeError.message, DateTime.formatIso(now));
}).pipe(Effect.provide(authPairingLinkLayer)),
);
it.effect("skips undecodable provider runtime rows and correlates SQL failures by thread", () =>
Effect.gen(function* () {
const runtimes = yield* ProviderSessionRuntime.ProviderSessionRuntimeRepository;
const sql = yield* SqlClient.SqlClient;
const threadId = ThreadId.make("thread-correlation");
const runtimePayload = "runtime-payload-secret-sentinel";
const lastSeenAt = "2026-06-20T00:00:00.000Z";
yield* sql`
INSERT INTO provider_session_runtime (
thread_id,
provider_name,
provider_instance_id,
adapter_key,
runtime_mode,
status,
last_seen_at,
resume_cursor_json,
runtime_payload_json
)
VALUES (
${threadId},
${"codex"},
NULL,
${"codex"},
${"invalid-runtime-mode"},
${"running"},
${lastSeenAt},
NULL,
${`{"secret":"${runtimePayload}"}`}
)
`;
const validThreadId = ThreadId.make("thread-valid");
yield* runtimes.upsert({
threadId: validThreadId,
providerName: "codex",
providerInstanceId: null,
adapterKey: "codex",
runtimeMode: "full-access",
status: "running",
lastSeenAt,
resumeCursor: null,
runtimePayload: null,
});
const listed = yield* runtimes.list();
assert.deepStrictEqual(
listed.map((runtime) => runtime.threadId),
[validThreadId],
);
yield* sql`DROP TABLE provider_session_runtime`;
const sqlFailure = yield* Effect.flip(
runtimes.upsert({
threadId,
providerName: "codex",
providerInstanceId: null,
adapterKey: "codex",
runtimeMode: "full-access",
status: "running",
lastSeenAt,
resumeCursor: null,
runtimePayload: { secret: runtimePayload },
}),
);
assert.instanceOf(sqlFailure, PersistenceErrors.PersistenceSqlError);
assert.deepStrictEqual(sqlFailure.correlation, { threadId });
assert.equal(
sqlFailure.message,
"SQL error in ProviderSessionRuntimeRepository.upsert:query",
);
assert.notInclude(sqlFailure.message, runtimePayload);
assert.notInclude(sqlFailure.message, lastSeenAt);
}).pipe(Effect.provide(providerSessionRuntimeLayer)),
);
});