fix: bind uok status to project db

This commit is contained in:
Mikael Hugo 2026-05-07 06:25:03 +02:00
parent cc08afc3b1
commit 9bd913d4a1
2 changed files with 39 additions and 17 deletions

View file

@ -45,9 +45,7 @@ export async function collectUokStatus(
basePath = process.cwd(),
nowMs = Date.now(),
) {
if (!isDbAvailable()) {
await ensureDbOpen(basePath);
}
await ensureDbOpen(basePath);
const dbAvailable = isDbAvailable();
let runs = [];
if (dbAvailable) {
@ -227,9 +225,7 @@ export async function handleUok(args, ctx) {
}
if (trimmed === "circuit-breakers" || trimmed === "circuit_breakers") {
const basePath = process.cwd();
if (!isDbAvailable()) {
await ensureDbOpen(basePath);
}
await ensureDbOpen(basePath);
if (!isDbAvailable()) {
ctx.ui.notify("Database unavailable", "error");
return;
@ -256,9 +252,7 @@ export async function handleUok(args, ctx) {
}
if (trimmed === "gates") {
const basePath = process.cwd();
if (!isDbAvailable()) {
await ensureDbOpen(basePath);
}
await ensureDbOpen(basePath);
if (!isDbAvailable()) {
ctx.ui.notify("Database unavailable", "error");
return;
@ -280,9 +274,7 @@ export async function handleUok(args, ctx) {
}
if (trimmed === "messages" || trimmed.startsWith("messages ")) {
const basePath = process.cwd();
if (!isDbAvailable()) {
await ensureDbOpen(basePath);
}
await ensureDbOpen(basePath);
if (!isDbAvailable()) {
ctx.ui.notify("Database unavailable", "error");
return;

View file

@ -18,8 +18,10 @@ import {
const NOW = Date.parse("2026-05-06T00:00:00.000Z");
const tmpRoots = [];
const originalCwd = process.cwd();
afterEach(() => {
process.chdir(originalCwd);
closeDatabase();
for (const dir of tmpRoots.splice(0)) {
rmSync(dir, { recursive: true, force: true });
@ -35,7 +37,7 @@ function makeProject() {
test("collectUokStatus_reads_ledger_and_reports_clear_startup_gate", async () => {
const projectRoot = makeProject();
openDatabase(":memory:");
openDatabase(join(projectRoot, ".sf", "sf.db"));
recordUokRunStart({
runId: "uok-status-ok",
sessionId: "session-uok",
@ -67,7 +69,7 @@ test("collectUokStatus_reads_ledger_and_reports_clear_startup_gate", async () =>
test("collectUokStatus_reports_last_error_and_blocked_startup_gate", async () => {
const projectRoot = makeProject();
openDatabase(":memory:");
openDatabase(join(projectRoot, ".sf", "sf.db"));
recordUokRunStart({
runId: "uok-status-error",
path: "uok-kernel",
@ -90,6 +92,29 @@ test("collectUokStatus_reports_last_error_and_blocked_startup_gate", async () =>
assert.deepEqual(status.current.criticalMismatches, 1);
});
test("collectUokStatus_when_process_switches_projects_reads_requested_project_db", async () => {
const first = makeProject();
const second = makeProject();
openDatabase(join(first, ".sf", "sf.db"));
recordUokRunStart({
runId: "first-project-run",
path: "uok-kernel",
startedAt: new Date(NOW - 20_000).toISOString(),
});
recordUokRunExit({
runId: "first-project-run",
path: "uok-kernel",
status: "ok",
endedAt: new Date(NOW - 10_000).toISOString(),
});
const status = await collectUokStatus(second, NOW);
assert.equal(status.dbAvailable, true);
assert.equal(status.lastRun, null);
assert.equal(status.ledgerRunCount, 0);
});
test("formatUokStatus_shows_operator_fields_without_raw_json", () => {
const rendered = formatUokStatus(
{
@ -142,6 +167,8 @@ test("formatUokStatus_shows_operator_fields_without_raw_json", () => {
});
test("handleUok_gates_when_empty_shows_no_recorded_gate_runs", async () => {
const projectRoot = makeProject();
process.chdir(projectRoot);
const notifications = [];
const ctx = {
ui: {
@ -154,7 +181,9 @@ test("handleUok_gates_when_empty_shows_no_recorded_gate_runs", async () => {
});
test("handleUok_gates_lists_observed_gate_runs", async () => {
openDatabase(":memory:");
const projectRoot = makeProject();
process.chdir(projectRoot);
openDatabase(join(projectRoot, ".sf", "sf.db"));
insertGateRun({
traceId: "trace-gates",
turnId: "turn-gates",
@ -190,8 +219,9 @@ test("handleUok_gates_lists_observed_gate_runs", async () => {
});
test("handleUok_messages_shows_bus_metrics", async () => {
makeProject();
openDatabase(":memory:");
const projectRoot = makeProject();
process.chdir(projectRoot);
openDatabase(join(projectRoot, ".sf", "sf.db"));
const notifications = [];
const ctx = {
ui: {