Files
stack/agents/darkwing/work/slice1-proto/proto.mjs
T
jason.woltjeandClaude Opus 5.5 bb7e37dda2 docs(plans): slice 1 data model note and prototype; lead decision 46
Darkwing's design note and SQLite prototype as records. Sage accepts
seven of eight open questions; the PM launching sessions goes to Jason.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 14:19:14 -05:00

31 lines
3.4 KiB
JavaScript

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);