Files
orca/tests/e2e/helpers/orchestration-mail-store.ts
T
Jinwoo Hong 2b42de1f52 fix(orchestration): wake coordinators with mail pointers (#12988)
Wake idle Run coordinators with durable orchestration mail pointers while keeping message payloads in the store until check consumes them. Preserve waiter, Cursor, restart, real Codex title, and PTY replacement behavior.\n\nPart of #12953.
2026-08-06 22:50:09 -07:00

81 lines
2.5 KiB
TypeScript

/**
* Direct reads of the orchestration mailbox for E2E assertions.
*
* Why read SQLite instead of `orchestration.check`: check is itself a consumer —
* it marks rows read and backfills `delivered_at` — so using it to observe would
* destroy the very distinction these specs exist to test. A pointer changes
* neither marker; only an out-of-band read can prove that before check consumes.
*/
import path from 'node:path'
import Database from '../../../src/main/sqlite/sync-database'
export type MailRow = {
id: string
type: string
to_handle: string
subject: string
read: number
delivered_at: string | null
}
export type MailDisposition = 'pending' | 'pushed' | 'pulled'
function withMailDb<T>(userDataDir: string, read: (db: Database) => T): T {
const db = new Database(path.join(userDataDir, 'orchestration.db'))
try {
return read(db)
} finally {
db.close()
}
}
export function readMailRow(userDataDir: string, id: string): MailRow | undefined {
return withMailDb(userDataDir, (db) =>
db
.prepare('SELECT id, type, to_handle, subject, read, delivered_at FROM messages WHERE id = ?')
.get(id)
) as MailRow | undefined
}
export function readMailbox(userDataDir: string, toHandle: string): MailRow[] {
return withMailDb(userDataDir, (db) =>
db
.prepare(
'SELECT id, type, to_handle, subject, read, delivered_at FROM messages WHERE to_handle = ? ORDER BY sequence'
)
.all(toHandle)
) as MailRow[]
}
/**
* Mark `handle` as a legacy running coordinator to prove it no longer suppresses Enter.
*
* Why seed instead of calling `orchestration.run`: that RPC starts a coordinator
* loop whose scheduling would race the assertion.
*/
export function startCoordinatorRun(userDataDir: string, handle: string): void {
withMailDb(userDataDir, (db) => {
db.prepare(
`INSERT INTO coordinator_runs (id, spec, status, coordinator_handle)
VALUES (?, 'e2e coordinator Enter carve-out', 'running', ?)`
).run(`e2e-coordinator-${handle}`, handle)
})
}
/**
* How a row was consumed under either the current or historical push behavior.
*
* `read` is checked first because a pull backfills `delivered_at` via COALESCE,
* so a pulled row also carries a delivery stamp — the stamp alone cannot prove
* a push happened.
*/
export function mailDisposition(row: MailRow | undefined): MailDisposition | 'missing' {
if (!row) {
return 'missing'
}
if (row.read === 1) {
return 'pulled'
}
return row.delivered_at === null ? 'pending' : 'pushed'
}