import { DatabaseSync } from "node:sqlite"; import { readFileSync, mkdtempSync } from "node:fs"; import { join } from "node:path"; import { tmpdir } from "node:os"; const f = join(mkdtempSync(join(tmpdir(), "s1-")), "bus.sqlite"); const db = new DatabaseSync(f, { timeout: 5000 }); db.exec(readFileSync(new URL("./schema.sql", import.meta.url), "utf8")); const now = () => new Date().toISOString(); const tryit = (label, fn) => { try { fn(); console.log("ok ", label); } catch (e) { console.log("refuse", label, "->", e.message); } }; const claim = db.prepare("INSERT INTO role_claims (at,business,role,op,holder_run,harness,address,by,reason,decision) VALUES (?,?,?,?,?,?,?,?,?,?)"); tryit("claim pm by run A", () => claim.run(now(),"mosaic-stack","pm","claim","run-A","t3","thread-1","run-A",null,null)); tryit("claim pm by run B", () => claim.run(now(),"mosaic-stack","pm","claim","run-B","t3","thread-2","run-B",null,null)); tryit("release pm by run B", () => claim.run(now(),"mosaic-stack","pm","release","run-B","t3",null,"run-B",null,null)); tryit("revoke pm without decision", () => claim.run(now(),"mosaic-stack","pm","revoke","run-A","t3",null,"jason","stuck",null)); tryit("release pm by run A", () => claim.run(now(),"mosaic-stack","pm","release","run-A","t3",null,"run-A",null,null)); tryit("claim pm by run B after release", () => claim.run(now(),"mosaic-stack","pm","claim","run-B","t3","thread-2","run-B",null,null)); const dec = db.prepare("INSERT INTO decisions (id,at,business,raised_by_role,raised_by_run,class,action,route_to,question,options,recommendation) VALUES (?,?,?,?,?,?,?,?,?,?,?)"); const opts = JSON.stringify([{key:"A",text:"push"},{key:"B",text:"hold"}]); tryit("raise gated decision", () => dec.run("d-1",now(),"mosaic-stack","coder","run-C","gated","git.push:next","human","Push to next?",opts,"B")); tryit("raise with one option", () => dec.run("d-2",now(),"mosaic-stack","coder","run-C","gated","x","human","?",JSON.stringify([{key:"A"}]),"A")); const ev = db.prepare("INSERT INTO decision_events (decision,at,op,by,choice,note,via) VALUES (?,?,?,?,?,?,?)"); tryit("resolve with choice Z", () => ev.run("d-1",now(),"resolved","jason","Z",null,"cli")); tryit("resolve with choice B", () => ev.run("d-1",now(),"resolved","jason","B",null,"cli")); tryit("resolve again", () => ev.run("d-1",now(),"resolved","jason","A",null,"cli")); tryit("UPDATE decisions", () => db.exec("UPDATE decisions SET recommendation='A' WHERE id='d-1'")); tryit("DELETE decision_events", () => db.exec("DELETE FROM decision_events")); tryit("DELETE role_claims", () => db.exec("DELETE FROM role_claims")); tryit("INSERT OR REPLACE decisions", () => db.exec(`INSERT OR REPLACE INTO decisions (id,at,business,raised_by_role,raised_by_run,class,action,route_to,question,options,recommendation) VALUES ('d-1','x','b','r','r','gated','a','human','q','${opts}','A')`)); tryit("UPSERT decisions", () => db.exec(`INSERT INTO decisions (id,at,business,raised_by_role,raised_by_run,class,action,route_to,question,options,recommendation) VALUES ('d-1','x','b','r','r','gated','a','human','q','${opts}','A') ON CONFLICT(id) DO UPDATE SET recommendation='A'`)); console.log("rows:", db.prepare("SELECT count(*) n FROM decisions").get().n, "rec:", db.prepare("SELECT recommendation r FROM decisions WHERE id='d-1'").get().r); console.log("journal:", db.prepare("PRAGMA journal_mode").get().journal_mode, "| triggers:", db.prepare("SELECT count(*) n FROM sqlite_master WHERE type='trigger'").get().n);