mirror of
https://github.com/AgentSeal/codeburn.git
synced 2026-08-21 14:34:32 +00:00
observe() classified a stable unparseable session-refresh.lock body as the terminal 'unavailable'. parseAllSessions routes that to a read-only parse, so a zero-byte or truncated lock froze warm-cache ingestion permanently across every later run while each command still exited successfully. A corrupt body is now a recoverable observation carrying a real mtime, and is recovered only through the UNMODIFIED staleness gate — tryTakeover and the age check are byte-identical to main. sameObservation gains an explicit null/non-null boundary and a sha1 of the raw bytes, because two corrupt bodies have no tokens to compare and mtime granularity is coarse on some filesystems. The heartbeat deliberately does NOT rewrite a body it cannot prove is its own. An owner that cannot prove ownership ends its ownership: mtime stops advancing, the publication fence refuses, and a successor recovers the lock one staleMs later. Losing that parse is the price of never having two owners.
25 lines
1.2 KiB
TypeScript
25 lines
1.2 KiB
TypeScript
import { pbkdf2 } from 'crypto'
|
|
import { writeFile } from 'fs/promises'
|
|
import { join } from 'path'
|
|
|
|
import { acquireCacheRefreshLock } from '../../src/cache-refresh-lock.js'
|
|
|
|
// Saturate the (size-1) libuv threadpool so every fs operation inside
|
|
// createExclusive queues behind a pbkdf2 round. No test hook and no patched
|
|
// module: this is what an ordinary process looks like mid cold parse, and it
|
|
// widens the window in which the lock exists at zero bytes -- between
|
|
// open(path,'wx') and the awaited body write -- to something observable.
|
|
const [cacheDir, barrierDir] = process.argv.slice(2)
|
|
if (!cacheDir || !barrierDir) throw new Error('missing owner argument')
|
|
|
|
let stop = false
|
|
const churn = (): void => { if (stop) return; pbkdf2('p', 's', 400_000, 32, 'sha512', () => churn()) }
|
|
churn()
|
|
|
|
const refresh = await acquireCacheRefreshLock({ cacheDir, heartbeatMs: 10_000 })
|
|
stop = true
|
|
await writeFile(join(barrierDir, `owner.${refresh.outcome}`), refresh.outcome === 'acquired' ? refresh.handle.token : '')
|
|
if (refresh.outcome === 'acquired') {
|
|
await writeFile(join(barrierDir, `owner.verify.${await refresh.handle.verifyStillOwner()}`), '')
|
|
await refresh.handle.release()
|
|
}
|