githolon 0.15.0 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.mjs +388 -465
  2. package/package.json +2 -2
package/dist/cli.mjs CHANGED
@@ -190,7 +190,7 @@ async function wsCreate(name, opts) {
190
190
  out(` session saved \u2192 ${credsPath()} (auto-refreshed; births ride x-nomos-auth)`);
191
191
  principal = s.accessToken;
192
192
  }
193
- const r = await fetch(`${cloud}/v1/workspaces/${name}`, {
193
+ const r = await fetch(`${cloud}/v2/workspaces/${name}`, {
194
194
  method: "POST",
195
195
  headers: principalHeaders(principal)
196
196
  });
@@ -214,7 +214,7 @@ async function wsCreate(name, opts) {
214
214
  }
215
215
  async function wsStatus(name, opts) {
216
216
  const cloud = cloudBase(opts.cloud);
217
- const r = await fetch(`${cloud}/v1/workspaces/${name}`);
217
+ const r = await fetch(`${cloud}/v2/workspaces/${name}`);
218
218
  const text = await r.text();
219
219
  if (!r.ok) {
220
220
  err(`status '${name}' (${r.status}): ${text}`);
@@ -233,7 +233,7 @@ async function wsRetire(ws, opts) {
233
233
  );
234
234
  return 1;
235
235
  }
236
- const r = await fetch(`${cloud}/v1/workspaces/${ws}/retire`, {
236
+ const r = await fetch(`${cloud}/v2/workspaces/${ws}/retire`, {
237
237
  method: "POST",
238
238
  headers: { authorization: `Bearer ${secret}` }
239
239
  });
@@ -249,7 +249,7 @@ async function wsRetire(ws, opts) {
249
249
  out(`\u2713 workspace ${ws} retired on ${cloud}${d.alreadyRetired === true ? " (it was already retired)" : ""}`);
250
250
  out(" nothing was deleted \u2014 the ledger and its data are retained per the Nomos Pre-Release License");
251
251
  out(" it no longer counts toward your workspace allowance; reads keep serving, deploys/pushes refuse");
252
- out(" to un-retire: contact the operator (an admin restores the record via POST /v1/root/governance)");
252
+ out(" to un-retire: contact the operator (an admin restores the record via root's governance offer, POST /v2/workspaces/root/createWorkspace)");
253
253
  return 0;
254
254
  }
255
255
  async function deploy(ws, opts) {
@@ -270,8 +270,8 @@ async function deploy(ws, opts) {
270
270
  );
271
271
  return 1;
272
272
  }
273
- const before = await fetch(`${cloud}/v1/workspaces/${ws}/domains`).then((br) => br.json()).then((bd) => bd.ok === true ? bd.domains ?? [] : []).catch(() => []);
274
- const r = await fetch(`${cloud}/v1/workspaces/${ws}/domains`, {
273
+ const before = await fetch(`${cloud}/v2/workspaces/${ws}/domains`).then((br) => br.json()).then((bd) => bd.ok === true ? bd.domains ?? [] : []).catch(() => []);
274
+ const r = await fetch(`${cloud}/v2/workspaces/${ws}/domains`, {
275
275
  method: "POST",
276
276
  headers: { "content-type": "application/json", authorization: `Bearer ${secret}` },
277
277
  body: readFileSync(file, "utf8")
@@ -310,7 +310,7 @@ async function secretRotate(ws, opts) {
310
310
  err(`no stored secret for ${ws} on ${cloud} \u2014 githolon secret set ${ws} <secret> first`);
311
311
  return 1;
312
312
  }
313
- const r = await fetch(`${cloud}/v1/workspaces/${ws}/rotate-secret`, {
313
+ const r = await fetch(`${cloud}/v2/workspaces/${ws}/rotate-secret`, {
314
314
  method: "POST",
315
315
  headers: { authorization: `Bearer ${current}` }
316
316
  });
@@ -449,30 +449,182 @@ var init_tree = __esm({
449
449
  }
450
450
  });
451
451
 
452
+ // vendor/engine/custody-transport.mjs
453
+ function concatBytes(chunks) {
454
+ let n = 0;
455
+ for (const c of chunks) n += c.length;
456
+ const out9 = new Uint8Array(n);
457
+ let o = 0;
458
+ for (const c of chunks) {
459
+ out9.set(c, o);
460
+ o += c.length;
461
+ }
462
+ return out9;
463
+ }
464
+ function pkt(payload) {
465
+ const body = typeof payload === "string" ? enc2.encode(payload) : payload;
466
+ const len = (body.length + 4).toString(16).padStart(4, "0");
467
+ return concatBytes([enc2.encode(len), body]);
468
+ }
469
+ function readPktLines(buf, off = 0) {
470
+ const lines = [];
471
+ while (off + 4 <= buf.length) {
472
+ const hex = dec2.decode(buf.subarray(off, off + 4));
473
+ if (!/^[0-9a-f]{4}$/.test(hex)) break;
474
+ const len = parseInt(hex, 16);
475
+ if (len === 0) {
476
+ off += 4;
477
+ break;
478
+ }
479
+ if (len < 4 || off + len > buf.length) break;
480
+ lines.push(buf.subarray(off + 4, off + len));
481
+ off += len;
482
+ }
483
+ return { lines, rest: off };
484
+ }
485
+ async function lsRefs(remote, headers = {}, { service = "git-upload-pack", prefix = null } = {}) {
486
+ const r = await fetch(`${remote}/info/refs?service=${service}`, { headers });
487
+ if (!r.ok) {
488
+ if (r.status === 404) return {};
489
+ throw new Error(`info/refs ${r.status}: ${(await r.text()).slice(0, 180)}`);
490
+ }
491
+ const buf = new Uint8Array(await r.arrayBuffer());
492
+ const banner = readPktLines(buf, 0);
493
+ const { lines } = readPktLines(buf, banner.rest);
494
+ const refs = {};
495
+ for (const line of lines) {
496
+ let s = dec2.decode(line).replace(/\n$/, "");
497
+ if (s.startsWith("#")) continue;
498
+ const nul = s.indexOf("\0");
499
+ if (nul >= 0) s = s.slice(0, nul);
500
+ const sp = s.indexOf(" ");
501
+ if (sp !== 40) continue;
502
+ const oid = s.slice(0, 40), name = s.slice(41);
503
+ if (!/^[0-9a-f]{40}$/.test(oid)) continue;
504
+ if (prefix && !name.startsWith(prefix)) continue;
505
+ refs[name] = oid;
506
+ }
507
+ return refs;
508
+ }
509
+ async function fetchPack(remote, headers = {}, { wants = [], haves = [] } = {}) {
510
+ wants = wants.filter((w) => /^[0-9a-f]{40}$/.test(w) && w !== ZERO_OID);
511
+ if (!wants.length) return null;
512
+ const caps = "thin-pack ofs-delta agent=nomos-cloud";
513
+ const parts = [];
514
+ wants.forEach((w, i) => parts.push(pkt(`want ${w}${i === 0 ? " " + caps : ""}
515
+ `)));
516
+ parts.push(FLUSH);
517
+ for (const h of haves) if (/^[0-9a-f]{40}$/.test(h) && h !== ZERO_OID) parts.push(pkt(`have ${h}
518
+ `));
519
+ parts.push(pkt("done\n"));
520
+ const r = await fetch(`${remote}/git-upload-pack`, {
521
+ method: "POST",
522
+ headers: { "content-type": "application/x-git-upload-pack-request", "accept": "application/x-git-upload-pack-result", ...headers },
523
+ body: concatBytes(parts)
524
+ });
525
+ if (!r.ok) throw new Error(`upload-pack ${r.status}: ${(await r.text()).slice(0, 180)}`);
526
+ const buf = new Uint8Array(await r.arrayBuffer());
527
+ const { lines, rest } = readPktLines(buf, 0);
528
+ const packChunks = [];
529
+ let sideband = false;
530
+ for (const line of lines) {
531
+ if (line.length === 0) continue;
532
+ const head = dec2.decode(line.subarray(0, Math.min(line.length, 3)));
533
+ if (head === "NAK" || head === "ACK" || head === "ERR" || head.startsWith("sha")) continue;
534
+ const band = line[0];
535
+ if (band === 1) {
536
+ packChunks.push(line.subarray(1));
537
+ sideband = true;
538
+ } else if (band === 2) {
539
+ } else if (band === 3) {
540
+ throw new Error("upload-pack fatal: " + dec2.decode(line.subarray(1)).slice(0, 180));
541
+ }
542
+ }
543
+ const pack = sideband ? concatBytes(packChunks) : buf.subarray(rest);
544
+ if (pack.length < 12 || dec2.decode(pack.subarray(0, 4)) !== "PACK") {
545
+ throw new Error(`upload-pack: no pack in response (${pack.length}B, sideband=${sideband})`);
546
+ }
547
+ return pack;
548
+ }
549
+ var enc2, dec2, ZERO_OID, EMPTY_PACK, FLUSH;
550
+ var init_custody_transport = __esm({
551
+ "vendor/engine/custody-transport.mjs"() {
552
+ "use strict";
553
+ enc2 = new TextEncoder();
554
+ dec2 = new TextDecoder();
555
+ ZERO_OID = "0".repeat(40);
556
+ EMPTY_PACK = new Uint8Array([
557
+ 80,
558
+ 65,
559
+ 67,
560
+ 75,
561
+ 0,
562
+ 0,
563
+ 0,
564
+ 2,
565
+ 0,
566
+ 0,
567
+ 0,
568
+ 0,
569
+ // "PACK", ver 2, 0 objects
570
+ 2,
571
+ 157,
572
+ 8,
573
+ 130,
574
+ 59,
575
+ 216,
576
+ 168,
577
+ 234,
578
+ 181,
579
+ 16,
580
+ 173,
581
+ 106,
582
+ // sha1(the 12 header bytes)
583
+ 199,
584
+ 92,
585
+ 130,
586
+ 60,
587
+ 253,
588
+ 62,
589
+ 211,
590
+ 30
591
+ ]);
592
+ FLUSH = enc2.encode("0000");
593
+ }
594
+ });
595
+
452
596
  // vendor/engine/engine.mjs
453
597
  import { WASI, File, Directory, OpenFile, ConsoleStdout, PreopenDirectory } from "@bjorn3/browser_wasi_shim";
454
- import git from "isomorphic-git";
455
- import http from "isomorphic-git/http/web";
598
+ function b64Bytes(bytes) {
599
+ let s = "";
600
+ for (let i = 0; i < bytes.length; i += 32768) {
601
+ s += String.fromCharCode(...bytes.subarray(i, i + 32768));
602
+ }
603
+ return btoa(s);
604
+ }
605
+ function b64Json(o) {
606
+ return b64Bytes(enc3.encode(JSON.stringify(o)));
607
+ }
456
608
  async function sha256hex(t) {
457
- const b = await crypto.subtle.digest("SHA-256", enc2.encode(t));
609
+ const b = await crypto.subtle.digest("SHA-256", enc3.encode(t));
458
610
  return [...new Uint8Array(b)].map((x) => x.toString(16).padStart(2, "0")).join("");
459
611
  }
460
612
  function osEntropyBuffer(n) {
461
613
  const bytes = new Uint8Array(n * 8);
462
614
  for (let o = 0; o < bytes.length; o += 65536) crypto.getRandomValues(bytes.subarray(o, Math.min(o + 65536, bytes.length)));
463
- const out10 = new Array(n), T = 2 ** 53;
615
+ const out9 = new Array(n), T = 2 ** 53;
464
616
  for (let i = 0; i < n; i++) {
465
617
  let z = 0n;
466
618
  for (let b = 7; b >= 0; b--) z = z << 8n | BigInt(bytes[i * 8 + b]);
467
- out10[i] = Number(z >> 11n) / T;
619
+ out9[i] = Number(z >> 11n) / T;
468
620
  }
469
- return out10;
621
+ return out9;
470
622
  }
471
623
  function stringifyBig(o) {
472
624
  return JSON.stringify(o, (_k, v) => typeof v === "bigint" ? `@@B:${v}@@` : v).replace(/"@@B:(\d+)@@"/g, "$1");
473
625
  }
474
626
  function call(ex, mode, fields, STDERR) {
475
- const req = enc2.encode(JSON.stringify({ mode, ...fields }));
627
+ const req = enc3.encode(JSON.stringify({ mode, ...fields }));
476
628
  const reqPtr = ex.git_holon_alloc(req.length);
477
629
  try {
478
630
  new Uint8Array(ex.memory.buffer, reqPtr, req.length).set(req);
@@ -485,7 +637,7 @@ function call(ex, mode, fields, STDERR) {
485
637
  }
486
638
  const { ptr, len } = unpack(packed);
487
639
  try {
488
- const e = JSON.parse(dec2.decode(new Uint8Array(ex.memory.buffer, ptr, len).slice()));
640
+ const e = JSON.parse(dec3.decode(new Uint8Array(ex.memory.buffer, ptr, len).slice()));
489
641
  if (!e.ok) throw new Error((e.error || "holon error") + (STDERR.length ? ` | ${STDERR.slice(-4).join(" / ")}` : ""));
490
642
  return e.result;
491
643
  } finally {
@@ -498,7 +650,7 @@ function call(ex, mode, fields, STDERR) {
498
650
  async function createEngine({ wasmModule, bootstrapPkg, nomosPkg, replica, installedBy = "nomos-cloud" }) {
499
651
  const hashes = { bootstrap: await sha256hex(bootstrapPkg), nomos: await sha256hex(nomosPkg) };
500
652
  const root = /* @__PURE__ */ new Map();
501
- root.set("domain.package.usda", new File(enc2.encode(bootstrapPkg)));
653
+ root.set("domain.package.usda", new File(enc3.encode(bootstrapPkg)));
502
654
  root.set("ws", new Directory(/* @__PURE__ */ new Map()));
503
655
  const preopen = new PreopenDirectory("/work", root);
504
656
  const STDERR = [];
@@ -535,39 +687,18 @@ async function mountWorkspace(eng, ws, ledger) {
535
687
  if (eng.mounted.has(ws)) return eng.mounted.get(ws);
536
688
  stageWorkspaceDir(eng, ws);
537
689
  const gitdir = gitdirOf(ws);
538
- let restored = false, remoteMain = null, restoreError = null, checkpoint = null;
690
+ let restored = false, remoteMain = null, restoreError = null;
539
691
  try {
540
- const info = await git.getRemoteInfo({ http, url: ledger.remote, headers: ledger.headers });
541
- remoteMain = info.refs && info.refs.heads && info.refs.heads.main || null;
692
+ await custodySkeleton(eng, gitdir);
693
+ remoteMain = await custodyFetch(eng, ws, ledger, { remoteRef: "refs/heads/main" });
542
694
  if (remoteMain) {
543
- await git.init({ fs: eng.fs, gitdir, bare: true, defaultBranch: "main" });
544
- await git.addRemote({ fs: eng.fs, gitdir, remote: "origin", url: ledger.remote, force: true });
545
- const ckpt = await discoverCheckpointFromCustody(ledger).catch(() => null);
546
- let shallowOk = false;
547
- if (ckpt?.cursor && ckpt.frontier) {
548
- const steps = [32, 96, 256, 1024];
549
- for (let i = 0; i < steps.length; i++) {
550
- const depth = steps[i], relative = i > 0;
551
- await git.fetch({ fs: eng.fs, http, gitdir, remote: "origin", ref: "main", singleBranch: true, depth, relative, headers: ledger.headers });
552
- if (await git.readCommit({ fs: eng.fs, gitdir, oid: ckpt.cursor }).then(() => true, () => false)) {
553
- shallowOk = true;
554
- break;
555
- }
556
- }
557
- }
558
- if (!shallowOk) await git.fetch({ fs: eng.fs, http, gitdir, remote: "origin", ref: "main", singleBranch: true, headers: ledger.headers });
559
- await git.writeRef({ fs: eng.fs, gitdir, ref: "refs/heads/main", value: remoteMain, force: true });
560
- await git.writeRef({ fs: eng.fs, gitdir, ref: "HEAD", value: "ref: refs/heads/main", force: true, symbolic: true });
561
- if (shallowOk && ckpt?.blob) {
562
- const r = importCheckpoint(eng, ws, ckpt.blob, ckpt.frontier);
563
- checkpoint = { restored: !!(r && r.restored), frontierSeeded: !!(r && r.frontierSeeded), cursor: r && r.cursor ? r.cursor : ckpt.cursor, ref: ckpt.ref };
564
- }
695
+ kgit.writeRef(eng, gitdir, "HEAD", "ref: refs/heads/main");
565
696
  restored = true;
566
697
  }
567
698
  } catch (e) {
568
699
  restoreError = String(e && e.stack || e).split("\n").slice(0, 5).join(" | ");
569
700
  }
570
- const m = { restored, remoteMain, restoreError, checkpoint };
701
+ const m = { restored, remoteMain, restoreError };
571
702
  eng.mounted.set(ws, m);
572
703
  return m;
573
704
  }
@@ -586,108 +717,120 @@ function mintId(eng, typeTag) {
586
717
  function author(eng, ws, domain, directiveId, payload, controllerHash, opts = {}) {
587
718
  const seq = eng.seq++;
588
719
  const envelope = { payload: { domain, directiveId, payload }, captured_ports: { clock: { physical: Date.now(), logical: 0, replica: eng.replica }, rng: osEntropyBuffer(opts.rngDraws ?? 64) }, policy_version: 1, policy_domain: "Nomos", policy_gas: 0, policy_memory: 0 };
589
- writeWork(eng, `payload-${seq}.json`, enc2.encode(JSON.stringify(payload)));
590
- writeWork(eng, `envelope-${seq}.json`, enc2.encode(stringifyBig(envelope)));
720
+ writeWork(eng, `payload-${seq}.json`, enc3.encode(JSON.stringify(payload)));
721
+ writeWork(eng, `envelope-${seq}.json`, enc3.encode(stringifyBig(envelope)));
591
722
  const genesis = !controllerHash;
592
723
  const defer = opts.deferProjection !== false;
593
- const res = JSON.parse(call(eng.ex, "author", { repoArg: repoArgOf(ws), workspace: ws, domain, directiveId, payloadFile: `/work/payload-${seq}.json`, envelopeFile: `/work/envelope-${seq}.json`, seq, actor: opts.actor ?? "", domainFile: genesis ? "/work/domain.package.usda" : "", domainHash: genesis ? "" : controllerHash, branch: BRANCH, ...opts.authorSecret ? { authorSecret: opts.authorSecret } : {}, ...defer ? { deferProjection: true } : {} }, eng.STDERR));
724
+ const v = JSON.parse(call(eng.ex, "offer", { repoArg: repoArgOf(ws), workspace: ws, domain, directiveId, payloadFile: `/work/payload-${seq}.json`, envelopeFile: `/work/envelope-${seq}.json`, seq, actor: opts.actor ?? "", domainFile: genesis ? "/work/domain.package.usda" : "", domainHash: genesis ? "" : controllerHash, branch: BRANCH, ...opts.authorSecret ? { authorSecret: opts.authorSecret } : {}, ...opts.dryRun ? { dryRun: true } : defer ? { deferProjection: true } : {} }, eng.STDERR));
725
+ const res = v.outcome === "admitted" ? { ok: true, head: v.head, intentOut: v.intentOut } : v.outcome === "refused" ? { ok: false, error: v.verdict?.reason ?? v.error } : v;
594
726
  if (defer && res.ok) (eng.pendingProjection ??= /* @__PURE__ */ new Set()).add(ws);
595
727
  return res;
596
728
  }
597
- function importCheckpoint(eng, ws, blobB64, frontierB64) {
598
- return JSON.parse(call(eng.ex, "checkpoint_import", { repoArg: repoArgOf(ws), workspace: ws, branch: BRANCH, blob: blobB64, ...frontierB64 ? { frontier: frontierB64 } : {} }, eng.STDERR));
599
- }
600
- async function streamAll(stream) {
601
- const chunks = [];
602
- const reader = stream.getReader();
603
- for (; ; ) {
604
- const { done, value } = await reader.read();
605
- if (done) break;
606
- chunks.push(value);
607
- }
608
- let len = 0;
609
- for (const c of chunks) len += c.length;
610
- const out10 = new Uint8Array(len);
611
- let at = 0;
612
- for (const c of chunks) {
613
- out10.set(c, at);
614
- at += c.length;
615
- }
616
- return out10;
617
- }
618
- async function gunzip(bytes) {
619
- const ds = new DecompressionStream("gzip");
620
- return streamAll(new Response(bytes).body.pipeThrough(ds));
621
- }
622
- async function discoverCheckpointFromCustody(ledger) {
623
- const freshHeaders = () => ({ ...ledger.headers || {} });
624
- const refs = (await git.listServerRefs({ http, url: ledger.remote, headers: freshHeaders(), prefix: "refs/meta/checkpoint/", protocolVersion: 2 }) || []).filter((r) => r.ref && r.ref.startsWith("refs/meta/checkpoint/") && r.oid);
625
- if (!refs.length) return null;
626
- const root = /* @__PURE__ */ new Map();
627
- root.set("ckpt", new Directory(/* @__PURE__ */ new Map()));
628
- const preopen = new PreopenDirectory("/work", root);
629
- const fs = makeGitFs(preopen, "/work", { File, Directory });
630
- const gitdir = "/work/ckpt/nomos.git";
631
- await git.init({ fs, gitdir, bare: true, defaultBranch: BRANCH });
632
- await git.addRemote({ fs, gitdir, remote: "origin", url: ledger.remote, force: true });
633
- const readFile = async (oid, filepath) => {
634
- try {
635
- return (await git.readBlob({ fs, gitdir, oid, filepath })).blob;
636
- } catch {
637
- return null;
638
- }
639
- };
640
- for (let i = refs.length - 1; i >= 0 && i >= refs.length - 3; i--) {
641
- const { ref, oid } = refs[i];
729
+ async function custodySkeleton(eng, gitdir) {
730
+ const p = eng.fs.promises;
731
+ for (const d of ["", "/objects", "/objects/pack", "/objects/info", "/refs", "/refs/heads"]) {
642
732
  try {
643
- await git.fetch({ fs, http, gitdir, remote: "origin", ref, singleBranch: true, depth: 1, headers: freshHeaders() });
644
- const gz = await readFile(oid, "checkpoint");
645
- if (!gz) continue;
646
- let meta = {};
647
- try {
648
- const mb = await readFile(oid, "meta");
649
- if (mb) meta = JSON.parse(dec2.decode(mb));
650
- } catch {
651
- }
652
- const codec = meta.codec ?? "gzip";
653
- const blob = dec2.decode(codec === "gzip" ? await gunzip(gz) : gz);
654
- const fgz = await readFile(oid, "frontier");
655
- const frontier = fgz ? dec2.decode(codec === "gzip" ? await gunzip(fgz) : fgz) : null;
656
- return { ref, oid, cursor: meta.cursor || null, blob, frontier };
657
- } catch {
733
+ await p.mkdir(`${gitdir}${d}`);
734
+ } catch (e) {
735
+ if (e && e.code !== "EEXIST") throw e;
658
736
  }
659
737
  }
660
- return null;
738
+ try {
739
+ await p.writeFile(`${gitdir}/HEAD`, `ref: refs/heads/${BRANCH}
740
+ `);
741
+ } catch {
742
+ }
743
+ try {
744
+ await p.writeFile(`${gitdir}/config`, "[core]\n repositoryformatversion = 0\n bare = true\n");
745
+ } catch {
746
+ }
661
747
  }
662
- function applyIntentBytes(eng, ws, bytes) {
663
- const name = `intent-in-${eng.seq++}.json`;
748
+ async function custodyFetch(eng, ws, ledger, { remoteRef = "refs/heads/main", localRef = null, have = null } = {}) {
749
+ const remoteRefFull = fullRef(remoteRef);
750
+ const refs = await custodyLsRefs(ledger, remoteRefFull);
751
+ const tip = refs[remoteRefFull] || null;
752
+ if (!tip) return null;
753
+ if (tip !== have) applyPackInto(eng, ws, await fetchPack(ledger.remote, ledger.headers || {}, { wants: [tip], haves: have ? [have] : [] }));
754
+ kgit.writeRef(eng, gitdirOf(ws), fullRef(localRef || remoteRef), tip);
755
+ return tip;
756
+ }
757
+ function offerIntent(eng, ws, bytes, opts) {
758
+ const name = `offer-in-${eng.seq++}.json`;
664
759
  writeWork(eng, name, bytes);
665
- return JSON.parse(call(eng.ex, "apply_intent", { repoArg: repoArgOf(ws), workspace: ws, intentFile: `/work/${name}`, branch: BRANCH }, eng.STDERR));
760
+ const deferProjection = !!(opts && opts.defer);
761
+ const branch = opts && opts.branch || BRANCH;
762
+ return JSON.parse(call(eng.ex, "offer", { repoArg: repoArgOf(ws), workspace: ws, intentFile: `/work/${name}`, branch, deferProjection }, eng.STDERR));
763
+ }
764
+ function offerAdmit(eng, ws, bytes, opts) {
765
+ const v = offerIntent(eng, ws, bytes, opts);
766
+ return v.outcome === "admitted" ? { ok: true, head: v.head } : { ok: false, error: v.verdict?.reason ?? v.error ?? "the offer was refused" };
767
+ }
768
+ function applyIntentBytes(eng, ws, bytes, opts) {
769
+ return offerAdmit(eng, ws, bytes, opts);
666
770
  }
667
771
  function verifyChainLocal(eng, ws) {
668
- return JSON.parse(call(eng.ex, "verify_chain", { repoArg: repoArgOf(ws), workspace: ws, branch: BRANCH }, eng.STDERR));
772
+ return JSON.parse(call(eng.ex, "query", { repoArg: repoArgOf(ws), workspace: ws, queryBytes: b64Json({ op: "verifyChain" }), branch: BRANCH }, eng.STDERR));
669
773
  }
670
- var enc2, dec2, BRANCH, repoArgOf, gitdirOf, unpack, installPayload, qById, query, cryptoUnwrapKey, count, sum;
774
+ var enc3, dec3, BRANCH, RESULT_PACK_INLINE_MAX, repoArgOf, gitdirOf, unpack, repoArgOfGitdir, bytesFromB64, kgit, installPayload, fullRef, applyPackInto, custodyLsRefs, qById, query, cryptoUnwrapKey, count, sum;
671
775
  var init_engine = __esm({
672
776
  "vendor/engine/engine.mjs"() {
673
777
  "use strict";
674
778
  init_git_fs();
675
779
  init_tree();
676
- enc2 = new TextEncoder();
677
- dec2 = new TextDecoder();
780
+ init_custody_transport();
781
+ enc3 = new TextEncoder();
782
+ dec3 = new TextDecoder();
678
783
  BRANCH = "main";
784
+ RESULT_PACK_INLINE_MAX = 256 * 1024;
679
785
  repoArgOf = (ws) => `/work/ws/${ws}`;
680
786
  gitdirOf = (ws) => `/work/ws/${ws}/nomos.git`;
681
787
  unpack = (p) => {
682
788
  const v = typeof p === "bigint" ? p : BigInt(p);
683
789
  return { ptr: Number(v >> 32n), len: Number(v & 0xffffffffn) };
684
790
  };
791
+ repoArgOfGitdir = (gitdir) => gitdir.replace(/\/nomos\.git$/, "");
792
+ bytesFromB64 = (b64) => Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
793
+ kgit = {
794
+ // resolveRef → tip oid hex, or null if the ref is absent (replaces git.resolveRef(...).catch(()=>null)).
795
+ resolveRef: (eng, gitdir, ref) => JSON.parse(call(eng.ex, "resolve_ref", { repoArg: repoArgOfGitdir(gitdir), ref }, eng.STDERR)).oid,
796
+ // readBlob → the blob bytes at `path` inside commit `oid`, or null if not found (no throw).
797
+ readBlob: (eng, gitdir, oid, path) => {
798
+ const r = JSON.parse(call(eng.ex, "read_blob", { repoArg: repoArgOfGitdir(gitdir), oid, path }, eng.STDERR));
799
+ return r.ok ? bytesFromB64(r.blobB64) : null;
800
+ },
801
+ // intentsAbove → [{ oid, intentB64 }] oldest→newest over (base, head] (replaces log + readBlob intent.json).
802
+ // `limit` (0 = all) caps to the most-recent N intent commits (replaces git.log depth).
803
+ intentsAbove: (eng, gitdir, head, base = "", limit = 0) => JSON.parse(call(eng.ex, "intents_above", { repoArg: repoArgOfGitdir(gitdir), head, base, limit }, eng.STDERR)).intents,
804
+ // listRefs → [{ ref, oid }] under prefix (replaces git.listRefs for LOCAL refs).
805
+ listRefs: (eng, gitdir, prefix) => JSON.parse(call(eng.ex, "list_refs", { repoArg: repoArgOfGitdir(gitdir), prefix }, eng.STDERR)).refs,
806
+ // writeRef → force-point a ref (plain oid or `ref:`-symbolic) (replaces git.writeRef).
807
+ writeRef: (eng, gitdir, ref, value) => JSON.parse(call(eng.ex, "write_ref", { repoArg: repoArgOfGitdir(gitdir), ref, value }, eng.STDERR)),
808
+ // deleteRef → remove a local ref, idempotent (replaces git.deleteRef).
809
+ deleteRef: (eng, gitdir, ref) => JSON.parse(call(eng.ex, "delete_ref", { repoArg: repoArgOfGitdir(gitdir), ref }, eng.STDERR)),
810
+ // writeMetaCommit → blobs→tree→commit→ref for a CUSTODY-META fact (checkpoint/refused/outbox/shape).
811
+ // `files`: [{ path, bytes:Uint8Array }]; returns the commit oid (replaces writeBlob+writeTree+writeCommit[+writeRef]).
812
+ writeMetaCommit: (eng, gitdir, { parents = [], files, message = "nomos custody meta", timeSecs = 0, ref = "" }) => JSON.parse(call(eng.ex, "write_meta_commit", {
813
+ repoArg: repoArgOfGitdir(gitdir),
814
+ parents,
815
+ files: files.map((f) => ({ path: f.path, blobB64: b64Bytes(f.bytes) })),
816
+ message,
817
+ timeSecs,
818
+ ref
819
+ }, eng.STDERR)).oid
820
+ };
685
821
  installPayload = (hash, usda, installedBy, dispositions) => ({ domainHash: hash, packageUsda: usda, installedBy, dependencies: [], finalizers: [], ...dispositions ? { dispositions } : {} });
686
- qById = (eng, ws, id, principal = "", keys = []) => JSON.parse(call(eng.ex, "query_by_id", { repoArg: repoArgOf(ws), workspace: ws, aggregateId: id, principal, keys, branch: BRANCH }, eng.STDERR));
687
- query = (eng, ws, queryId, paramsJson, principal = "", keys = []) => JSON.parse(call(eng.ex, "query", { repoArg: repoArgOf(ws), workspace: ws, queryId, paramsJson, principal, keys, branch: BRANCH }, eng.STDERR));
822
+ fullRef = (r) => r === "HEAD" || r.startsWith("refs/") ? r : `refs/heads/${r}`;
823
+ applyPackInto = (eng, ws, pack) => {
824
+ if (!pack || !pack.length) return;
825
+ const r = JSON.parse(call(eng.ex, "apply_pack", { repoArg: repoArgOf(ws), packB64: b64Bytes(pack) }, eng.STDERR));
826
+ if (!r || r.ok !== true) throw new Error(`apply_pack: ${r && r.error}`);
827
+ };
828
+ custodyLsRefs = (ledger, prefix = null) => lsRefs(ledger.remote, ledger.headers || {}, { service: "git-upload-pack", prefix });
829
+ qById = (eng, ws, id, principal = "", keys = []) => JSON.parse(call(eng.ex, "query", { repoArg: repoArgOf(ws), workspace: ws, queryBytes: b64Json({ op: "byId", aggregateId: id }), principal, keys, branch: BRANCH }, eng.STDERR));
830
+ query = (eng, ws, queryId, paramsJson, principal = "", keys = []) => JSON.parse(call(eng.ex, "query", { repoArg: repoArgOf(ws), workspace: ws, queryBytes: b64Json({ kind: "query", queryId, paramsJson }), principal, keys, branch: BRANCH }, eng.STDERR));
688
831
  cryptoUnwrapKey = (eng, { secret, hpkeEpk, ct }) => JSON.parse(call(eng.ex, "crypto_unwrap_key", { secret, hpkeEpk, ct }, eng.STDERR)).scopeKey;
689
- count = (eng, ws, countId, groupKey) => JSON.parse(call(eng.ex, "count", { repoArg: repoArgOf(ws), workspace: ws, countId, groupKey, branch: BRANCH }, eng.STDERR));
690
- sum = (eng, ws, sumId, groupKey) => JSON.parse(call(eng.ex, "sum", { repoArg: repoArgOf(ws), workspace: ws, sumId, groupKey, branch: BRANCH }, eng.STDERR));
832
+ count = (eng, ws, countId, groupKey, principal = "") => JSON.parse(call(eng.ex, "query", { repoArg: repoArgOf(ws), workspace: ws, queryBytes: b64Json({ op: "count", countId, groupKey }), principal, branch: BRANCH }, eng.STDERR));
833
+ sum = (eng, ws, sumId, groupKey, principal = "") => JSON.parse(call(eng.ex, "query", { repoArg: repoArgOf(ws), workspace: ws, queryBytes: b64Json({ op: "sum", sumId, groupKey }), principal, branch: BRANCH }, eng.STDERR));
691
834
  }
692
835
  });
693
836
 
@@ -776,21 +919,21 @@ function sealedIntentOf(eng, ws, res) {
776
919
  }
777
920
  function printVerdict(v) {
778
921
  if (v["valid"] === true) {
779
- out3(`\u2713 chain VALID \u2014 head ${String(v["head"]).slice(0, 12)}\u2026, ${v["intents"]} intent(s), ${v["plansRerun"]} plan(s) re-run`);
780
- out3(` controller ${String(v["controllerHash"]).slice(0, 12)}\u2026 | installed: ${v["installedDomains"]?.map((h) => h.slice(0, 12) + "\u2026").join(", ") ?? "\u2014"}`);
922
+ out2(`\u2713 chain VALID \u2014 head ${String(v["head"]).slice(0, 12)}\u2026, ${v["intents"]} intent(s), ${v["plansRerun"]} plan(s) re-run`);
923
+ out2(` controller ${String(v["controllerHash"]).slice(0, 12)}\u2026 | installed: ${v["installedDomains"]?.map((h) => h.slice(0, 12) + "\u2026").join(", ") ?? "\u2014"}`);
781
924
  return true;
782
925
  }
783
- err3(`chain INVALID at ${v["check"]}${v["atIndex"] !== void 0 ? ` (intent ${v["atIndex"]})` : ""}: ${v["error"]}`);
926
+ err2(`chain INVALID at ${v["check"]}${v["atIndex"] !== void 0 ? ` (intent ${v["atIndex"]})` : ""}: ${v["error"]}`);
784
927
  return false;
785
928
  }
786
- var out3, err3;
929
+ var out2, err2;
787
930
  var init_local_holon = __esm({
788
931
  "src/local_holon.ts"() {
789
932
  "use strict";
790
933
  init_engine();
791
934
  init_cloud();
792
- out3 = (s) => void process.stdout.write(s + "\n");
793
- err3 = (s) => void process.stderr.write("error: " + s + "\n");
935
+ out2 = (s) => void process.stdout.write(s + "\n");
936
+ err2 = (s) => void process.stderr.write("error: " + s + "\n");
794
937
  }
795
938
  });
796
939
 
@@ -939,7 +1082,7 @@ var init_proof_offline = __esm({
939
1082
 
940
1083
  // src/cli.ts
941
1084
  import { existsSync as existsSync9, readdirSync as readdirSync4, readFileSync as readFileSync9 } from "node:fs";
942
- import { spawnSync as spawnSync5 } from "node:child_process";
1085
+ import { spawnSync as spawnSync4 } from "node:child_process";
943
1086
  import { createRequire as createRequire2 } from "node:module";
944
1087
  import { dirname as dirname5, join as join10, resolve as resolve2 } from "node:path";
945
1088
  import { pathToFileURL as pathToFileURL4 } from "node:url";
@@ -1122,171 +1265,11 @@ Re-run with --force to replace it.`
1122
1265
  return { path, contents };
1123
1266
  }
1124
1267
 
1125
- // src/capability.ts
1126
- init_cloud();
1127
- import { spawnSync } from "node:child_process";
1128
- var out2 = (s) => void process.stdout.write(s + "\n");
1129
- var err2 = (s) => void process.stderr.write("error: " + s + "\n");
1130
- var CAP_NAME = /^[a-z0-9][a-z0-9._-]{0,63}$/;
1131
- function readStdin() {
1132
- if (process.stdin.isTTY === true) {
1133
- process.stderr.write(
1134
- "paste the credential value, then Ctrl-D (it never rides argv \u2014 ps/history are hosts too):\n"
1135
- );
1136
- }
1137
- return new Promise((resolveValue) => {
1138
- let buf = "";
1139
- process.stdin.setEncoding("utf8");
1140
- process.stdin.on("data", (chunk) => {
1141
- buf += chunk;
1142
- });
1143
- process.stdin.on("end", () => resolveValue(buf.trim()));
1144
- process.stdin.resume();
1145
- });
1146
- }
1147
- function readGcloud(name) {
1148
- const r = spawnSync("gcloud", ["secrets", "versions", "access", "latest", `--secret=${name}`], {
1149
- encoding: "utf8",
1150
- maxBuffer: 1024 * 1024
1151
- });
1152
- if (r.error !== void 0 || r.status !== 0) {
1153
- throw new Error(
1154
- `gcloud secret read failed (${r.error?.message ?? r.stderr?.trim() ?? `exit ${r.status}`}) \u2014 is gcloud installed + authed, and does secret '${name}' exist?`
1155
- );
1156
- }
1157
- const v = r.stdout.trim();
1158
- if (v === "") throw new Error(`gcloud secret '${name}' is empty`);
1159
- return v;
1160
- }
1161
- function parseExpiresAt(s) {
1162
- const n = /^\d+$/.test(s) ? Number(s) : Date.parse(s);
1163
- if (!Number.isInteger(n) || n <= 0) throw new Error(`--expires-at '${s}' is neither epoch-ms nor an ISO date`);
1164
- return n;
1165
- }
1166
- async function bindLane(lane, ws, capability, opts) {
1167
- const cloud = cloudBase(opts.cloud);
1168
- if (!CAP_NAME.test(capability)) {
1169
- err2(`capability must be a lowercase law name matching [a-z0-9][a-z0-9._-]{0,63} \u2014 e.g. cf-analytics, openai`);
1170
- return 1;
1171
- }
1172
- const secret = getSecret(cloud, ws);
1173
- if (secret === void 0) {
1174
- err2(
1175
- `no stored secret for ${ws} on ${cloud} \u2014 capability ${lane} is owner-gated
1176
- githolon secret set ${ws} <secret> (import the workspaceSecret you hold)`
1177
- );
1178
- return 1;
1179
- }
1180
- let value;
1181
- try {
1182
- value = opts.fromGcloud !== void 0 ? readGcloud(opts.fromGcloud) : await readStdin();
1183
- } catch (e) {
1184
- err2(e.message);
1185
- return 1;
1186
- }
1187
- if (value === "") {
1188
- err2("no credential value arrived \u2014 pipe it on stdin, or pass --from-gcloud <secret-name>");
1189
- return 1;
1190
- }
1191
- let expiresAt;
1192
- try {
1193
- expiresAt = opts.expiresAt !== void 0 ? parseExpiresAt(opts.expiresAt) : void 0;
1194
- } catch (e) {
1195
- err2(e.message);
1196
- return 1;
1197
- }
1198
- const r = await fetch(`${cloud}/v1/workspaces/${ws}/capabilities/${lane}`, {
1199
- method: "POST",
1200
- headers: { "content-type": "application/json", authorization: `Bearer ${secret}` },
1201
- body: JSON.stringify({
1202
- capability,
1203
- secret: value,
1204
- ...opts.scope !== void 0 ? { scope: opts.scope } : {},
1205
- ...expiresAt !== void 0 ? { expiresAt } : {}
1206
- })
1207
- });
1208
- const d = await r.json().catch(() => void 0);
1209
- if (r.status === 401) {
1210
- err2(`${lane} refused (401) \u2014 the stored secret for ${ws} is not the workspace's. githolon secret set ${ws} <secret>`);
1211
- return 1;
1212
- }
1213
- if (!r.ok || d?.ok !== true) {
1214
- err2(`capability ${lane} '${capability}' on ${ws} failed (${r.status}): ${d ? JSON.stringify(d) : "no body"}`);
1215
- return 1;
1216
- }
1217
- out2(`\u2713 ${capability} ${lane === "rotate" ? "rotated" : "bound"} on ${ws} (epoch ${d.epoch})`);
1218
- out2(` the VALUE lives host-side only (the workspace's holon) \u2014 it never enters the ledger`);
1219
- out2(` the law fact: keyHash ${(d.keyHash ?? "").slice(0, 16)}\u2026 status ${d.status}`);
1220
- return 0;
1221
- }
1222
- async function capabilityBind(ws, capability, opts) {
1223
- return bindLane("bind", ws, capability, opts);
1224
- }
1225
- async function capabilityRotate(ws, capability, opts) {
1226
- return bindLane("rotate", ws, capability, opts);
1227
- }
1228
- async function capabilityList(ws, opts) {
1229
- const cloud = cloudBase(opts.cloud);
1230
- const secret = getSecret(cloud, ws);
1231
- if (secret === void 0) {
1232
- err2(`no stored secret for ${ws} on ${cloud} \u2014 the binding facts are owner-gated
1233
- githolon secret set ${ws} <secret>`);
1234
- return 1;
1235
- }
1236
- const r = await fetch(`${cloud}/v1/workspaces/${ws}/capabilities`, {
1237
- headers: { authorization: `Bearer ${secret}` }
1238
- });
1239
- const d = await r.json().catch(() => void 0);
1240
- if (!r.ok || d?.ok !== true) {
1241
- err2(`capability list '${ws}' failed (${r.status}): ${d ? JSON.stringify(d) : "no body"}`);
1242
- return 1;
1243
- }
1244
- const bindings = d.bindings ?? [];
1245
- if (bindings.length === 0) {
1246
- out2(`no capability bindings on ${ws} \u2014 bind one: githolon capability bind ${ws} <capability>`);
1247
- return 0;
1248
- }
1249
- for (const b of bindings) {
1250
- const bits = [
1251
- `epoch ${b.epoch}`,
1252
- `${b.status}`,
1253
- `keyHash ${(b.keyHash ?? "").slice(0, 16)}\u2026`,
1254
- ...b.scope !== void 0 ? [`scope ${b.scope}`] : [],
1255
- ...b.expiresAt !== void 0 ? [`expires ${new Date(b.expiresAt).toISOString()}`] : [],
1256
- ...b.held !== void 0 ? [b.held ? "value held" : "VALUE MISSING (rotate to restore)"] : []
1257
- ];
1258
- out2(`${b.capability} ${bits.join(" \xB7 ")}`);
1259
- }
1260
- out2(`(facts about authority \u2014 the values live host-side and are never listed)`);
1261
- return 0;
1262
- }
1263
- async function capabilityUnbind(ws, capability, opts) {
1264
- const cloud = cloudBase(opts.cloud);
1265
- const secret = getSecret(cloud, ws);
1266
- if (secret === void 0) {
1267
- err2(`no stored secret for ${ws} on ${cloud} \u2014 unbind is owner-gated
1268
- githolon secret set ${ws} <secret>`);
1269
- return 1;
1270
- }
1271
- const r = await fetch(`${cloud}/v1/workspaces/${ws}/capabilities/unbind`, {
1272
- method: "POST",
1273
- headers: { "content-type": "application/json", authorization: `Bearer ${secret}` },
1274
- body: JSON.stringify({ capability })
1275
- });
1276
- const d = await r.json().catch(() => void 0);
1277
- if (!r.ok || d?.ok !== true) {
1278
- err2(`capability unbind '${capability}' on ${ws} failed (${r.status}): ${d ? JSON.stringify(d) : "no body"}`);
1279
- return 1;
1280
- }
1281
- out2(`\u2713 ${capability} unbound on ${ws} \u2014 the law fact is revoked (the record stays) and the host forgot the value`);
1282
- return 0;
1283
- }
1284
-
1285
1268
  // src/cli.ts
1286
1269
  init_cloud();
1287
1270
 
1288
1271
  // src/compile.ts
1289
- import { spawn, spawnSync as spawnSync2 } from "node:child_process";
1272
+ import { spawn, spawnSync } from "node:child_process";
1290
1273
  import { createRequire } from "node:module";
1291
1274
  import { dirname, join as join3 } from "node:path";
1292
1275
  import { pathToFileURL } from "node:url";
@@ -1310,7 +1293,7 @@ function runCompile(args) {
1310
1293
  `);
1311
1294
  return 1;
1312
1295
  }
1313
- const r = spawnSync2(process.execPath, [launcher, ...args], { stdio: "inherit", cwd: process.cwd() });
1296
+ const r = spawnSync(process.execPath, [launcher, ...args], { stdio: "inherit", cwd: process.cwd() });
1314
1297
  return r.status ?? 1;
1315
1298
  }
1316
1299
  function compileAsync(cwd, args = []) {
@@ -1321,10 +1304,10 @@ function compileAsync(cwd, args = []) {
1321
1304
  }
1322
1305
  return new Promise((resolveRun) => {
1323
1306
  const chunks = [];
1324
- const dec3 = new TextDecoder();
1307
+ const dec4 = new TextDecoder();
1325
1308
  const child = spawn(process.execPath, [launcher, ...args], { cwd, stdio: ["ignore", "pipe", "pipe"] });
1326
- child.stdout?.on("data", (c) => chunks.push(dec3.decode(c)));
1327
- child.stderr?.on("data", (c) => chunks.push(dec3.decode(c)));
1309
+ child.stdout?.on("data", (c) => chunks.push(dec4.decode(c)));
1310
+ child.stderr?.on("data", (c) => chunks.push(dec4.decode(c)));
1328
1311
  child.on("error", (e) => resolveRun({ ok: false, ms: performance.now() - t0, output: String(e) }));
1329
1312
  child.on(
1330
1313
  "close",
@@ -1429,8 +1412,8 @@ async function resolveWorkspace(explicit, cwd, target, usageHint) {
1429
1412
 
1430
1413
  // src/dev.ts
1431
1414
  init_proof_offline();
1432
- var out4 = (s) => void process.stdout.write(s + "\n");
1433
- var err4 = (s) => void process.stderr.write("error: " + s + "\n");
1415
+ var out3 = (s) => void process.stdout.write(s + "\n");
1416
+ var err3 = (s) => void process.stderr.write("error: " + s + "\n");
1434
1417
  var WS = "dev";
1435
1418
  var DEFAULT_PORT = 7700;
1436
1419
  var DEBOUNCE_MS = 200;
@@ -1490,8 +1473,8 @@ function startServer(s) {
1490
1473
  req.on("data", (c) => chunks.push(c));
1491
1474
  req.on("end", () => {
1492
1475
  try {
1493
- const dec3 = new TextDecoder();
1494
- const body = chunks.map((c) => dec3.decode(c)).join("") || "{}";
1476
+ const dec4 = new TextDecoder();
1477
+ const body = chunks.map((c) => dec4.decode(c)).join("") || "{}";
1495
1478
  const r = author(s.eng, WS, decodeURIComponent(dispatch[1]), decodeURIComponent(dispatch[2]), JSON.parse(body), s.lawHash);
1496
1479
  if (r["ok"] === false) return respond(422, { ok: false, error: r["error"] });
1497
1480
  s.intents++;
@@ -1553,21 +1536,21 @@ async function dev(opts) {
1553
1536
  const cwd = process.cwd();
1554
1537
  const cloud = cloudBase(opts.cloud);
1555
1538
  const project = await loadProject(cwd).catch((e) => {
1556
- err4(e.message);
1539
+ err3(e.message);
1557
1540
  return void 0;
1558
1541
  });
1559
1542
  if (project === void 0) {
1560
1543
  if (!existsSync6(join7(cwd, CONFIG_FILE))) {
1561
- err4(`no ${CONFIG_FILE} here (${cwd}) \u2014 \`githolon dev\` runs inside a project; scaffold one from examples/guestbook or \`githolon generate domain <name>\``);
1544
+ err3(`no ${CONFIG_FILE} here (${cwd}) \u2014 \`githolon dev\` runs inside a project; scaffold one from examples/guestbook or \`githolon generate domain <name>\``);
1562
1545
  }
1563
1546
  return 1;
1564
1547
  }
1565
1548
  const creds = loadCreds();
1566
1549
  const installedBy = creds.session?.uid ?? creds.principal ?? "githolon-dev";
1567
- out4(`githolon dev \u2014 ${project.name}: compiling\u2026`);
1550
+ out3(`githolon dev \u2014 ${project.name}: compiling\u2026`);
1568
1551
  const firstCompile = await compileAsync(cwd);
1569
1552
  if (!firstCompile.ok) {
1570
- err4(`compile failed \u2014 the dev loop needs one green compile to mint the holon:
1553
+ err3(`compile failed \u2014 the dev loop needs one green compile to mint the holon:
1571
1554
  ${firstCompile.output}`);
1572
1555
  return 1;
1573
1556
  }
@@ -1575,14 +1558,14 @@ ${firstCompile.output}`);
1575
1558
  try {
1576
1559
  deployBody = readDeployBody(cwd, project.name);
1577
1560
  } catch (e) {
1578
- err4(e.message);
1561
+ err3(e.message);
1579
1562
  return 1;
1580
1563
  }
1581
1564
  let engBoot;
1582
1565
  try {
1583
1566
  engBoot = await holonEngine(cloud, deployBody, installedBy);
1584
1567
  } catch (e) {
1585
- err4(`cannot boot the local holon: ${String(e.message ?? e)}
1568
+ err3(`cannot boot the local holon: ${String(e.message ?? e)}
1586
1569
  the runtime rides ${cloud}/v1/runtime/* and is cached in ~/.holon/runtime after one fetch \u2014 connect once, then dev runs offline`);
1587
1570
  return 1;
1588
1571
  }
@@ -1605,19 +1588,19 @@ ${firstCompile.output}`);
1605
1588
  s.intents++;
1606
1589
  const installed = await installLaw(s, deployBody, installedBy);
1607
1590
  if (!installed.ok) {
1608
- err4(installed.error ?? "law install failed");
1591
+ err3(installed.error ?? "law install failed");
1609
1592
  return 1;
1610
1593
  }
1611
1594
  s.proof = await runProofCycle(s, cwd, deployBody, installedBy);
1612
1595
  if (opts.once === true) {
1613
- out4(statusScreen({ ...s, watchRoots: ["(--once: no watch)"] }));
1596
+ out3(statusScreen({ ...s, watchRoots: ["(--once: no watch)"] }));
1614
1597
  return s.proof === void 0 || s.proof.ok ? 0 : 1;
1615
1598
  }
1616
1599
  let server;
1617
1600
  try {
1618
1601
  server = await startServer(s);
1619
1602
  } catch (e) {
1620
- err4(e.message);
1603
+ err3(e.message);
1621
1604
  return 1;
1622
1605
  }
1623
1606
  const moduleDirs = /* @__PURE__ */ new Set();
@@ -1645,7 +1628,7 @@ ${firstCompile.output}`);
1645
1628
  s.compileMs = run.ms;
1646
1629
  if (!run.ok) {
1647
1630
  s.lastError = run.output.trim() || "compile failed";
1648
- out4(`\u2717 cycle ${s.cycle}: compile failed \u2014 the previous law keeps serving
1631
+ out3(`\u2717 cycle ${s.cycle}: compile failed \u2014 the previous law keeps serving
1649
1632
  ${run.output}`);
1650
1633
  } else {
1651
1634
  s.lastError = void 0;
@@ -1654,16 +1637,16 @@ ${run.output}`);
1654
1637
  const inst = await installLaw(s, body, installedBy);
1655
1638
  if (!inst.ok) {
1656
1639
  s.lastError = inst.error ?? "install failed";
1657
- out4(`\u2717 cycle ${s.cycle}: ${s.lastError}`);
1640
+ out3(`\u2717 cycle ${s.cycle}: ${s.lastError}`);
1658
1641
  } else {
1659
1642
  s.proof = await runProofCycle(s, cwd, body, installedBy);
1660
1643
  const total = performance.now() - t0;
1661
- out4(statusScreen(s));
1662
- out4(` cycle edit \u2192 law-live \u2192 proof in ${total.toFixed(0)} ms total`);
1644
+ out3(statusScreen(s));
1645
+ out3(` cycle edit \u2192 law-live \u2192 proof in ${total.toFixed(0)} ms total`);
1663
1646
  }
1664
1647
  } catch (e) {
1665
1648
  s.lastError = String(e.message ?? e);
1666
- out4(`\u2717 cycle ${s.cycle}: ${s.lastError}`);
1649
+ out3(`\u2717 cycle ${s.cycle}: ${s.lastError}`);
1667
1650
  }
1668
1651
  }
1669
1652
  cycling = false;
@@ -1689,8 +1672,8 @@ ${run.output}`);
1689
1672
  })
1690
1673
  );
1691
1674
  s.watchRoots.push(CONFIG_FILE);
1692
- out4(statusScreen(s));
1693
- out4(" (ctrl-c stops; edits in the watched paths recompile + re-prove automatically)");
1675
+ out3(statusScreen(s));
1676
+ out3(" (ctrl-c stops; edits in the watched paths recompile + re-prove automatically)");
1694
1677
  return new Promise((resolveExit) => {
1695
1678
  const stop = () => {
1696
1679
  for (const w of watchers) w.close();
@@ -1704,13 +1687,13 @@ ${run.output}`);
1704
1687
 
1705
1688
  // src/git.ts
1706
1689
  init_cloud();
1707
- import { spawnSync as spawnSync3 } from "node:child_process";
1690
+ import { spawnSync as spawnSync2 } from "node:child_process";
1708
1691
  import { randomBytes as randomBytes2 } from "node:crypto";
1709
1692
  import { readFileSync as readFileSync5 } from "node:fs";
1710
- var out5 = (s) => void process.stdout.write(s + "\n");
1711
- var err5 = (s) => void process.stderr.write("error: " + s + "\n");
1712
- function git2(args, opts = {}) {
1713
- const r = spawnSync3("git", args, { stdio: opts.quiet === true ? "ignore" : "inherit" });
1693
+ var out4 = (s) => void process.stdout.write(s + "\n");
1694
+ var err4 = (s) => void process.stderr.write("error: " + s + "\n");
1695
+ function git(args, opts = {}) {
1696
+ const r = spawnSync2("git", args, { stdio: opts.quiet === true ? "ignore" : "inherit" });
1714
1697
  return r.status ?? 1;
1715
1698
  }
1716
1699
  function ensureSecret(cloud, ws) {
@@ -1730,7 +1713,7 @@ function parseCredentialInput(input) {
1730
1713
  return kv;
1731
1714
  }
1732
1715
  function workspaceFromPath(path) {
1733
- const m = (path ?? "").match(/^v1\/workspaces\/([^/]+)\/git(\/|$)/);
1716
+ const m = (path ?? "").match(/^v[12]\/workspaces\/([^/]+)\/git(\/|$)/);
1734
1717
  return m?.[1];
1735
1718
  }
1736
1719
  async function gitCredential(action) {
@@ -1740,40 +1723,40 @@ async function gitCredential(action) {
1740
1723
  if (kv["protocol"] !== "https" || ws === void 0) return 0;
1741
1724
  const cloud = `https://${kv["host"]}`;
1742
1725
  const token = await sessionToken().catch(() => void 0);
1743
- out5(`username=${token ?? "nomos"}`);
1744
- out5(`password=${ensureSecret(cloud, ws)}`);
1745
- out5("");
1726
+ out4(`username=${token ?? "nomos"}`);
1727
+ out4(`password=${ensureSecret(cloud, ws)}`);
1728
+ out4("");
1746
1729
  return 0;
1747
1730
  }
1748
1731
  async function gitSetup(opts) {
1749
1732
  const cloud = cloudBase(opts.cloud);
1750
1733
  const self = process.argv[1];
1751
1734
  if (self === void 0) {
1752
- err5("cannot locate the githolon CLI entry to install as a credential helper");
1735
+ err4("cannot locate the githolon CLI entry to install as a credential helper");
1753
1736
  return 1;
1754
1737
  }
1755
1738
  const helper = `!"${process.execPath}" "${self}" git-credential`;
1756
- if (git2(["config", "--global", `credential.${cloud}.helper`, helper]) !== 0 || git2(["config", "--global", `credential.${cloud}.useHttpPath`, "true"]) !== 0) {
1757
- err5("git config failed \u2014 is git installed?");
1739
+ if (git(["config", "--global", `credential.${cloud}.helper`, helper]) !== 0 || git(["config", "--global", `credential.${cloud}.useHttpPath`, "true"]) !== 0) {
1740
+ err4("git config failed \u2014 is git installed?");
1758
1741
  return 1;
1759
1742
  }
1760
- out5(`\u2713 git credential helper installed for ${cloud} (global gitconfig)`);
1761
- out5(` pushes/clones of ${cloud}/v1/workspaces/<ws>/git now authenticate from ~/.holon`);
1743
+ out4(`\u2713 git credential helper installed for ${cloud} (global gitconfig)`);
1744
+ out4(` pushes/clones of ${cloud}/v2/workspaces/<ws>/git now authenticate from ~/.holon`);
1762
1745
  return 0;
1763
1746
  }
1764
1747
  async function gitRemote(ws, name, opts) {
1765
1748
  const cloud = cloudBase(opts.cloud);
1766
- if (git2(["rev-parse", "--git-dir"], { quiet: true }) !== 0) {
1767
- err5("not a git repository \u2014 run inside your repo (git init first)");
1749
+ if (git(["rev-parse", "--git-dir"], { quiet: true }) !== 0) {
1750
+ err4("not a git repository \u2014 run inside your repo (git init first)");
1768
1751
  return 1;
1769
1752
  }
1770
1753
  const setupRc = await gitSetup(opts);
1771
1754
  if (setupRc !== 0) return setupRc;
1772
1755
  ensureSecret(cloud, ws);
1773
- const url = `${cloud}/v1/workspaces/${ws}/git`;
1774
- if (git2(["remote", "add", name, url], { quiet: true }) !== 0) {
1775
- if (git2(["remote", "set-url", name, url], { quiet: true }) !== 0) {
1776
- err5(`could not add or update remote '${name}'`);
1756
+ const url = `${cloud}/v2/workspaces/${ws}/git`;
1757
+ if (git(["remote", "add", name, url], { quiet: true }) !== 0) {
1758
+ if (git(["remote", "set-url", name, url], { quiet: true }) !== 0) {
1759
+ err4(`could not add or update remote '${name}'`);
1777
1760
  return 1;
1778
1761
  }
1779
1762
  }
@@ -1781,21 +1764,21 @@ async function gitRemote(ws, name, opts) {
1781
1764
  if (token === void 0) {
1782
1765
  const principal = loadCreds().principal;
1783
1766
  if (principal === void 0) {
1784
- err5(
1767
+ err4(
1785
1768
  `remote '${name}' \u2192 ${url} is wired, but a BIRTH push needs a principal:
1786
1769
  githolon login --agent (then just push)
1787
1770
  \u2014 or re-run after githolon ws create/login so a principal is on file`
1788
1771
  );
1789
1772
  return 1;
1790
1773
  }
1791
- if (git2(["config", `http.${url}.extraHeader`, `x-nomos-principal: ${principal}`]) !== 0) {
1792
- err5("git config failed setting the principal header");
1774
+ if (git(["config", `http.${url}.extraHeader`, `x-nomos-principal: ${principal}`]) !== 0) {
1775
+ err4("git config failed setting the principal header");
1793
1776
  return 1;
1794
1777
  }
1795
1778
  }
1796
- out5(`\u2713 remote '${name}' \u2192 ${url}`);
1797
- out5(` workspace secret on file; ${token !== void 0 ? "births ride your session (verified)" : "births ride x-nomos-principal (bare uid)"}`);
1798
- out5(` birth/deploy by push: git push ${name} main`);
1779
+ out4(`\u2713 remote '${name}' \u2192 ${url}`);
1780
+ out4(` workspace secret on file; ${token !== void 0 ? "births ride your session (verified)" : "births ride x-nomos-principal (bare uid)"}`);
1781
+ out4(` birth/deploy by push: git push ${name} main`);
1799
1782
  return 0;
1800
1783
  }
1801
1784
 
@@ -1899,22 +1882,6 @@ var HELP = {
1899
1882
  what: "The workspace-secret store (~/.holon/credentials.json, 0600). `set` imports one you already\nhold; `rotate` mints a fresh one (and claims a legacy workspace).",
1900
1883
  examples: ["githolon secret set my-ws nws_v1_\u2026", "githolon secret rotate my-ws"]
1901
1884
  },
1902
- capability: {
1903
- usage: "githolon capability <bind|rotate|unbind> <ws> <capability> | list <ws> [--from-gcloud <name>] [--scope <s>] [--expires-at <iso|ms>] [--cloud <url>]",
1904
- what: "Capability credentials (architecture/capability_credentials.md): the ledger holds FACTS ABOUT\nAUTHORITY (the CapabilityBinding record \u2014 keyHash/scope/expiry/epoch), the credential VALUE\nlives at exactly ONE host (the workspace's holon). `bind` ships the value over the owner-gated\nlane ONCE \u2014 from stdin (pipe it) or Google Secret Manager, NEVER argv (ps/history are hosts\ntoo). `rotate` = revoke + re-bind at epoch+1; `unbind` revokes the fact and the host forgets\nthe value; `list` shows facts only.",
1905
- flags: [
1906
- ["--from-gcloud <name>", "read the value from `gcloud secrets versions access latest --secret=<name>`"],
1907
- ["--scope <s>", "a narrowing label recorded on the law fact (e.g. read-only)"],
1908
- ["--expires-at <t>", "expiry recorded on the law fact (ISO date/datetime or epoch-ms; fail-closed at the host)"],
1909
- ["--cloud <url>", "target cloud (default: $NOMOS_CLOUD or the public cloud)"]
1910
- ],
1911
- examples: [
1912
- "cat token.txt | githolon capability bind nomos-usage cf-analytics",
1913
- "githolon capability bind my-ws openai --from-gcloud openai-api-key --scope read-only",
1914
- "githolon capability list nomos-usage",
1915
- "githolon capability rotate nomos-usage cf-analytics --from-gcloud cf-analytics-token"
1916
- ]
1917
- },
1918
1885
  git: {
1919
1886
  usage: "githolon git <setup | remote [<ws>] [<remoteName>]> [--cloud <url>] [--target <name>]",
1920
1887
  what: "Stock git push as deploy/birth. `setup` installs the credential helper for the cloud host;\n`remote` wires this repo to a workspace (then: git push nomos main). With no <ws>, the\nproject's `workspace` binding resolves it.",
@@ -1946,23 +1913,23 @@ function commandHelp(cmd) {
1946
1913
  init_engine();
1947
1914
  init_cloud();
1948
1915
  init_local_holon();
1949
- import { spawnSync as spawnSync4 } from "node:child_process";
1916
+ import { spawnSync as spawnSync3 } from "node:child_process";
1950
1917
  import { existsSync as existsSync7, readdirSync as readdirSync3, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "node:fs";
1951
1918
  import { join as join8 } from "node:path";
1952
- var out6 = (s) => void process.stdout.write(s + "\n");
1953
- var err6 = (s) => void process.stderr.write("error: " + s + "\n");
1919
+ var out5 = (s) => void process.stdout.write(s + "\n");
1920
+ var err5 = (s) => void process.stderr.write("error: " + s + "\n");
1954
1921
  var WS2 = "local";
1955
1922
  async function ledgerInit(dir, opts) {
1956
1923
  const cloud = cloudBase(opts.cloud);
1957
1924
  if (existsSync7(dir) && readdirSync3(dir).length > 0) {
1958
- err6(`refusing to mint into non-empty directory: ${dir}`);
1925
+ err5(`refusing to mint into non-empty directory: ${dir}`);
1959
1926
  return 1;
1960
1927
  }
1961
1928
  let deployFile;
1962
1929
  try {
1963
1930
  deployFile = discoverDeployJson(process.cwd(), opts.file);
1964
1931
  } catch (e) {
1965
- err6(e.message);
1932
+ err5(e.message);
1966
1933
  return 1;
1967
1934
  }
1968
1935
  const deployBody = JSON.parse(readFileSync6(deployFile, "utf8"));
@@ -1970,10 +1937,10 @@ async function ledgerInit(dir, opts) {
1970
1937
  const c = loadCreds();
1971
1938
  const principal = await sessionToken().catch(() => void 0) !== void 0 ? c.session.uid : c.principal;
1972
1939
  if (principal === void 0) {
1973
- err6("a holon is born OF someone \u2014 githolon login --agent first (or githolon ws create --principal <uid> once)");
1940
+ err5("a holon is born OF someone \u2014 githolon login --agent first (or githolon ws create --principal <uid> once)");
1974
1941
  return 1;
1975
1942
  }
1976
- out6(`minting a holon locally (law ${domainHash.slice(0, 12)}\u2026, installedBy ${principal})`);
1943
+ out5(`minting a holon locally (law ${domainHash.slice(0, 12)}\u2026, installedBy ${principal})`);
1977
1944
  const { eng } = await holonEngine(cloud, deployBody, principal);
1978
1945
  await mountFresh(eng, WS2);
1979
1946
  author(eng, WS2, "bootstrap", "installDomain", installPayload(eng.hashes.nomos, eng.nomosPkg, principal), "");
@@ -1985,17 +1952,17 @@ async function ledgerInit(dir, opts) {
1985
1952
  writeTreeToDisk(gitTree, gitDir);
1986
1953
  const cfgPath = join8(gitDir, "config");
1987
1954
  writeFileSync4(cfgPath, readFileSync6(cfgPath, "utf8").replace(/bare = true/, "bare = false"), "utf8");
1988
- spawnSync4("git", ["-C", dir, "reset", "--hard", "main"], { stdio: "ignore" });
1989
- out6(`\u2713 holon written \u2192 ${dir} (a normal git repo; git log IS the audit trail)`);
1990
- out6(`
1955
+ spawnSync3("git", ["-C", dir, "reset", "--hard", "main"], { stdio: "ignore" });
1956
+ out5(`\u2713 holon written \u2192 ${dir} (a normal git repo; git log IS the audit trail)`);
1957
+ out5(`
1991
1958
  Birth it on Nomos Cloud (the cloud re-derives this exact verdict):`);
1992
- out6(` cd ${dir} && npx githolon git remote <ws> && git push nomos main`);
1959
+ out5(` cd ${dir} && npx githolon git remote <ws> && git push nomos main`);
1993
1960
  return 0;
1994
1961
  }
1995
1962
  async function ledgerVerify(dir, opts) {
1996
1963
  const gitDir = existsSync7(join8(dir, ".git")) ? join8(dir, ".git") : dir;
1997
1964
  if (!existsSync7(join8(gitDir, "HEAD"))) {
1998
- err6(`${dir} is not a git repo (no HEAD)`);
1965
+ err5(`${dir} is not a git repo (no HEAD)`);
1999
1966
  return 1;
2000
1967
  }
2001
1968
  const { eng } = await holonEngine(cloudBase(opts.cloud), void 0, "verify");
@@ -2012,9 +1979,9 @@ init_cloud();
2012
1979
  init_local_holon();
2013
1980
  import { existsSync as existsSync8 } from "node:fs";
2014
1981
  import { join as join9 } from "node:path";
2015
- import git3 from "isomorphic-git";
2016
- var out7 = (s) => void process.stdout.write(s + "\n");
2017
- var err7 = (s) => void process.stderr.write("error: " + s + "\n");
1982
+ import git2 from "isomorphic-git";
1983
+ var out6 = (s) => void process.stdout.write(s + "\n");
1984
+ var err6 = (s) => void process.stderr.write("error: " + s + "\n");
2018
1985
  var SOURCE = "source";
2019
1986
  var REPLAY = "replay";
2020
1987
  function summarizePayload(payload, max = 100) {
@@ -2050,9 +2017,9 @@ function capJsonStrings(v, max = 2048) {
2050
2017
  if (typeof v === "string") return v.length > max ? `${v.slice(0, max)}\u2026(${v.length} chars)` : v;
2051
2018
  if (Array.isArray(v)) return v.map((x) => capJsonStrings(x, max));
2052
2019
  if (typeof v === "object" && v !== null) {
2053
- const out10 = {};
2054
- for (const [k, x] of Object.entries(v)) out10[k] = capJsonStrings(x, max);
2055
- return out10;
2020
+ const out9 = {};
2021
+ for (const [k, x] of Object.entries(v)) out9[k] = capJsonStrings(x, max);
2022
+ return out9;
2056
2023
  }
2057
2024
  return v;
2058
2025
  }
@@ -2067,12 +2034,12 @@ function typeOf(ev) {
2067
2034
  }
2068
2035
  async function walkChain(eng, ws) {
2069
2036
  const gitdir = gitdirOf(ws);
2070
- const dec3 = new TextDecoder();
2037
+ const dec4 = new TextDecoder();
2071
2038
  const entries = [];
2072
- for (const c of await git3.log({ fs: eng.fs, gitdir, ref: "main" })) {
2039
+ for (const c of await git2.log({ fs: eng.fs, gitdir, ref: "main" })) {
2073
2040
  try {
2074
- const { blob } = await git3.readBlob({ fs: eng.fs, gitdir, oid: c.oid, filepath: "intent.json" });
2075
- entries.push({ oid: c.oid, bytes: blob, doc: JSON.parse(dec3.decode(blob)) });
2041
+ const { blob } = await git2.readBlob({ fs: eng.fs, gitdir, oid: c.oid, filepath: "intent.json" });
2042
+ entries.push({ oid: c.oid, bytes: blob, doc: JSON.parse(dec4.decode(blob)) });
2076
2043
  } catch {
2077
2044
  }
2078
2045
  }
@@ -2099,12 +2066,12 @@ function readKey() {
2099
2066
  async function replay(target, opts) {
2100
2067
  const cloud = cloudBase(opts.cloud);
2101
2068
  const json = opts.json === true;
2102
- const emit = (o) => out7(JSON.stringify(o));
2069
+ const emit = (o) => out6(JSON.stringify(o));
2103
2070
  let eng;
2104
2071
  try {
2105
2072
  ({ eng } = await holonEngine(cloud, void 0, "githolon-replay"));
2106
2073
  } catch (e) {
2107
- err7(`cannot boot the local holon: ${String(e.message ?? e)}
2074
+ err6(`cannot boot the local holon: ${String(e.message ?? e)}
2108
2075
  the runtime rides ${cloud}/v1/runtime/* (cached in ~/.holon/runtime after one fetch)`);
2109
2076
  return 1;
2110
2077
  }
@@ -2112,15 +2079,15 @@ async function replay(target, opts) {
2112
2079
  if (isDir) {
2113
2080
  const gitDir = existsSync8(join9(target, ".git")) ? join9(target, ".git") : target;
2114
2081
  if (!existsSync8(join9(gitDir, "HEAD"))) {
2115
- err7(`${target} is not a git repo (no HEAD) \u2014 pass a holon directory (githolon ledger init <dir>) or a workspace name`);
2082
+ err6(`${target} is not a git repo (no HEAD) \u2014 pass a holon directory (githolon ledger init <dir>) or a workspace name`);
2116
2083
  return 1;
2117
2084
  }
2118
2085
  await mountFresh(eng, SOURCE);
2119
2086
  eng.preopen.dir.contents.get("ws").contents.get(SOURCE).contents.set("nomos.git", readTreeFromDisk(gitDir));
2120
2087
  } else {
2121
- const m = await mountWorkspace(eng, SOURCE, { remote: `${cloud}/v1/workspaces/${target}/git`, headers: {} });
2088
+ const m = await mountWorkspace(eng, SOURCE, { remote: `${cloud}/v2/workspaces/${target}/git`, headers: {} });
2122
2089
  if (m.restored !== true) {
2123
- err7(
2090
+ err6(
2124
2091
  `workspace '${target}' has no refs/heads/main on ${cloud} \u2014 nothing to replay` + (m.restoreError ? ` (${String(m.restoreError).split(" | ")[0]})` : "") + `
2125
2092
  check the name (githolon ws status ${target}), or pass a local holon directory instead`
2126
2093
  );
@@ -2129,7 +2096,7 @@ async function replay(target, opts) {
2129
2096
  }
2130
2097
  const chain = await walkChain(eng, SOURCE);
2131
2098
  if (chain.length === 0) {
2132
- err7(`the chain on '${target}' carries no intents \u2014 nothing to replay`);
2099
+ err6(`the chain on '${target}' carries no intents \u2014 nothing to replay`);
2133
2100
  return 1;
2134
2101
  }
2135
2102
  await mountFresh(eng, REPLAY);
@@ -2138,8 +2105,8 @@ async function replay(target, opts) {
2138
2105
  const tallies = /* @__PURE__ */ new Map();
2139
2106
  let autoRun = !interactive;
2140
2107
  if (!json) {
2141
- out7(`replaying ${chain.length} intent(s) from ${isDir ? target : `${cloud} :: ${target}`} \u2014 every step re-admitted through the wasm gate`);
2142
- if (interactive) out7(" keys: enter = next intent \xB7 a = run to the end \xB7 q = quit\n");
2108
+ out6(`replaying ${chain.length} intent(s) from ${isDir ? target : `${cloud} :: ${target}`} \u2014 every step re-admitted through the wasm gate`);
2109
+ if (interactive) out6(" keys: enter = next intent \xB7 a = run to the end \xB7 q = quit\n");
2143
2110
  }
2144
2111
  for (let i = 0; i < chain.length; i++) {
2145
2112
  const { oid, bytes, doc } = chain[i];
@@ -2153,8 +2120,8 @@ async function replay(target, opts) {
2153
2120
  if (res.ok === false) {
2154
2121
  const msg = `replay REFUSED at intent ${i} (${domain}/${directive}, ${oid.slice(0, 10)}): ${res.error ?? "unknown"}`;
2155
2122
  if (json) emit({ step: i, oid, domain, directive, refused: true, error: res.error ?? "unknown" });
2156
- else err7(msg);
2157
- err7("the chain's own gate rejects this entry on a fresh fold \u2014 the source it came from would refuse it too (verify below names the check)");
2123
+ else err6(msg);
2124
+ err6("the chain's own gate rejects this entry on a fresh fold \u2014 the source it came from would refuse it too (verify below names the check)");
2158
2125
  printVerdict(verifyChainLocal(eng, SOURCE));
2159
2126
  return 1;
2160
2127
  }
@@ -2175,31 +2142,31 @@ async function replay(target, opts) {
2175
2142
  tallies: Object.fromEntries(tallies)
2176
2143
  });
2177
2144
  } else {
2178
- out7(`[${String(i + 1).padStart(String(chain.length).length)}/${chain.length}] ${domain}/${directive} (${oid.slice(0, 10)}, ${ms.toFixed(0)} ms)`);
2179
- out7(` payload ${summarizePayload(doc.payload?.payload)}`);
2145
+ out6(`[${String(i + 1).padStart(String(chain.length).length)}/${chain.length}] ${domain}/${directive} (${oid.slice(0, 10)}, ${ms.toFixed(0)} ms)`);
2146
+ out6(` payload ${summarizePayload(doc.payload?.payload)}`);
2180
2147
  for (const ev of doc.events ?? []) {
2181
2148
  const id = ev.aggregate ?? "?";
2182
2149
  const was = before.get(id);
2183
2150
  const verb = ev.marker === "Create" ? "+ created" : ev.marker === "Delete" ? "- deleted" : was === void 0 ? "~ touched" : "~ updated";
2184
- out7(` ${verb} ${id}`);
2151
+ out6(` ${verb} ${id}`);
2185
2152
  const ops = summarizeOps(ev);
2186
- if (ops.length > 0) out7(` ${ops}`);
2153
+ if (ops.length > 0) out6(` ${ops}`);
2187
2154
  }
2188
2155
  const tallyLine = [...tallies.entries()].map(([t, n]) => `${t}:${n}`).join(" ");
2189
2156
  const showTally = stepEvery > 0 ? (i + 1) % stepEvery === 0 || i === chain.length - 1 : true;
2190
- if (showTally && tallyLine.length > 0) out7(` rows ${tallyLine}`);
2157
+ if (showTally && tallyLine.length > 0) out6(` rows ${tallyLine}`);
2191
2158
  }
2192
2159
  if (interactive && !autoRun && i < chain.length - 1) {
2193
2160
  const key = await readKey();
2194
2161
  if (key === "quit") {
2195
- out7(`
2162
+ out6(`
2196
2163
  stopped at intent ${i + 1}/${chain.length} \u2014 the verify verdict below covers the WHOLE chain as delivered`);
2197
2164
  break;
2198
2165
  }
2199
2166
  if (key === "all") autoRun = true;
2200
2167
  }
2201
2168
  }
2202
- if (!json) out7("");
2169
+ if (!json) out6("");
2203
2170
  const verdict = verifyChainLocal(eng, SOURCE);
2204
2171
  if (json) {
2205
2172
  emit({ finale: true, verdict });
@@ -2213,40 +2180,40 @@ init_local_holon();
2213
2180
  init_cloud();
2214
2181
  init_engine();
2215
2182
  var SOURCE2 = "source";
2216
- var out8 = (s) => {
2183
+ var out7 = (s) => {
2217
2184
  process.stdout.write(s + "\n");
2218
2185
  };
2219
- var err8 = (s) => {
2186
+ var err7 = (s) => {
2220
2187
  process.stderr.write(`error: ${s}
2221
2188
  `);
2222
2189
  };
2223
2190
  async function decrypt(ws, opts) {
2224
2191
  const cloud = cloudBase(opts.cloud);
2225
2192
  if (!opts.as) {
2226
- err8("--as <principal> is required (who to decrypt as)");
2193
+ err7("--as <principal> is required (who to decrypt as)");
2227
2194
  return 1;
2228
2195
  }
2229
2196
  if (!opts.secret) {
2230
- err8("--secret <base64 X25519 device secret> is required");
2197
+ err7("--secret <base64 X25519 device secret> is required");
2231
2198
  return 1;
2232
2199
  }
2233
2200
  if (!opts.query) {
2234
- err8("--query <queryId> is required (the read to decrypt)");
2201
+ err7("--query <queryId> is required (the read to decrypt)");
2235
2202
  return 1;
2236
2203
  }
2237
2204
  let eng;
2238
2205
  try {
2239
2206
  ({ eng } = await holonEngine(cloud, opts.overlay, "githolon-decrypt"));
2240
2207
  } catch (e) {
2241
- err8(`cannot boot the local holon: ${String(e.message ?? e)}`);
2208
+ err7(`cannot boot the local holon: ${String(e.message ?? e)}`);
2242
2209
  return 1;
2243
2210
  }
2244
2211
  const m = await mountWorkspace(eng, SOURCE2, {
2245
- remote: `${cloud}/v1/workspaces/${ws}/git`,
2212
+ remote: `${cloud}/v2/workspaces/${ws}/git`,
2246
2213
  headers: { "x-nomos-principal": opts.as }
2247
2214
  });
2248
2215
  if (m.restored !== true) {
2249
- err8(`workspace '${ws}' has no main on ${cloud}, or its clone was refused for '${opts.as}'` + (m.restoreError ? ` (${String(m.restoreError).split(" | ")[0]})` : ""));
2216
+ err7(`workspace '${ws}' has no main on ${cloud}, or its clone was refused for '${opts.as}'` + (m.restoreError ? ` (${String(m.restoreError).split(" | ")[0]})` : ""));
2250
2217
  return 1;
2251
2218
  }
2252
2219
  const wraps = query(eng, SOURCE2, "wrappedKeysByRecipient", JSON.stringify({ recipientPrincipal: opts.as }), opts.as);
@@ -2261,14 +2228,14 @@ async function decrypt(ws, opts) {
2261
2228
  }
2262
2229
  }
2263
2230
  }
2264
- if (opts.json !== true) out8(`# resolved ${keys.length} scope key(s) for '${opts.as}': ${keys.map((k) => `${k.scope}@${k.epoch}`).join(", ") || "(none)"}`);
2231
+ if (opts.json !== true) out7(`# resolved ${keys.length} scope key(s) for '${opts.as}': ${keys.map((k) => `${k.scope}@${k.epoch}`).join(", ") || "(none)"}`);
2265
2232
  const rows = query(eng, SOURCE2, opts.query, JSON.stringify(opts.params ?? {}), opts.as, keys);
2266
2233
  if (rows && !Array.isArray(rows) && rows.ok === false) {
2267
- err8(`the read was refused: ${rows.error}` + (String(rows.error).startsWith("read-forbidden") ? `
2234
+ err7(`the read was refused: ${rows.error}` + (String(rows.error).startsWith("read-forbidden") ? `
2268
2235
  '${opts.as}' is not granted this scope's read capability` : ""));
2269
2236
  return 1;
2270
2237
  }
2271
- out8(JSON.stringify(rows, null, opts.json === true ? 0 : 2));
2238
+ out7(JSON.stringify(rows, null, opts.json === true ? 0 : 2));
2272
2239
  return 0;
2273
2240
  }
2274
2241
 
@@ -2276,8 +2243,8 @@ async function decrypt(ws, opts) {
2276
2243
  init_engine();
2277
2244
  init_cloud();
2278
2245
  import { readFileSync as readFileSync8 } from "node:fs";
2279
- var out9 = (s) => void process.stdout.write(s + "\n");
2280
- var err9 = (s) => void process.stderr.write("error: " + s + "\n");
2246
+ var out8 = (s) => void process.stdout.write(s + "\n");
2247
+ var err8 = (s) => void process.stderr.write("error: " + s + "\n");
2281
2248
  function lawDiffVerdict(localHash, installed, ws) {
2282
2249
  const active = installed.filter((d) => d.phase === "Active" && typeof d.domainHash === "string");
2283
2250
  const currents = active.filter((d) => d.current === true);
@@ -2315,7 +2282,7 @@ async function status(wsArg, opts) {
2315
2282
  try {
2316
2283
  ws = await resolveWorkspace(wsArg, process.cwd(), opts.target, "githolon status <ws>");
2317
2284
  } catch (e) {
2318
- err9(e.message);
2285
+ err8(e.message);
2319
2286
  return 1;
2320
2287
  }
2321
2288
  let localHash;
@@ -2325,37 +2292,37 @@ async function status(wsArg, opts) {
2325
2292
  } catch {
2326
2293
  localHash = void 0;
2327
2294
  }
2328
- const r = await fetch(`${cloud}/v1/workspaces/${ws}/domains`).catch(() => void 0);
2295
+ const r = await fetch(`${cloud}/v2/workspaces/${ws}/domains`).catch(() => void 0);
2329
2296
  if (r === void 0) {
2330
- err9(`cannot reach ${cloud} \u2014 githolon status compares against the DEPLOYED law and needs the cloud (local-only: githolon dev)`);
2297
+ err8(`cannot reach ${cloud} \u2014 githolon status compares against the DEPLOYED law and needs the cloud (local-only: githolon dev)`);
2331
2298
  return 1;
2332
2299
  }
2333
2300
  const d = await r.json().catch(() => void 0);
2334
2301
  if (!r.ok || d?.ok !== true) {
2335
- err9(`status '${ws}' failed (${r.status}): ${d ? JSON.stringify(d) : "no body"}
2302
+ err8(`status '${ws}' failed (${r.status}): ${d ? JSON.stringify(d) : "no body"}
2336
2303
  is the workspace born? githolon ws create ${ws}`);
2337
2304
  return 1;
2338
2305
  }
2339
- out9(`workspace ${ws} on ${cloud}`);
2306
+ out8(`workspace ${ws} on ${cloud}`);
2340
2307
  const allDomains = d.domains ?? [];
2341
2308
  const controlPlaneHashes = new Set(CONTROL_PLANE_KEYS.map((k) => d.currentLaw?.[k]).filter(Boolean));
2342
2309
  const domains = allDomains.filter((dm) => !controlPlaneHashes.has(dm.domainHash));
2343
2310
  const controllerCount = allDomains.length - domains.length;
2344
- if (allDomains.length === 0) out9(`installed (none \u2014 not even the controller; the workspace may be unborn)`);
2311
+ if (allDomains.length === 0) out8(`installed (none \u2014 not even the controller; the workspace may be unborn)`);
2345
2312
  for (const dom of domains) {
2346
2313
  const mark = dom.current === true ? " \u2190 current (the holon resolves dispatch here)" : "";
2347
- out9(`installed ${(dom.domainHash ?? "?").slice(0, 16)}\u2026 ${dom.phase ?? "?"} by ${dom.installedBy ?? "?"}${mark}`);
2314
+ out8(`installed ${(dom.domainHash ?? "?").slice(0, 16)}\u2026 ${dom.phase ?? "?"} by ${dom.installedBy ?? "?"}${mark}`);
2348
2315
  }
2349
- if (controllerCount > 0) out9(` (+ ${controllerCount} control-plane install(s) \u2014 the nomos lifecycle controller; not tenant law)`);
2316
+ if (controllerCount > 0) out8(` (+ ${controllerCount} control-plane install(s) \u2014 the nomos lifecycle controller; not tenant law)`);
2350
2317
  const tenantActive = domains.filter((dm) => dm.phase === "Active").length;
2351
- if (tenantActive > 1) out9(` (${tenantActive} active tenant installs \u2014 install-beside keeps every prior deploy Active; the holon serves the current one per domain)`);
2318
+ if (tenantActive > 1) out8(` (${tenantActive} active tenant installs \u2014 install-beside keeps every prior deploy Active; the holon serves the current one per domain)`);
2352
2319
  if (localHash === void 0) {
2353
- out9(`local (no build/*.deploy.json here \u2014 run \`githolon compile\` to build the law this project authors)`);
2320
+ out8(`local (no build/*.deploy.json here \u2014 run \`githolon compile\` to build the law this project authors)`);
2354
2321
  return 0;
2355
2322
  }
2356
- out9(`local ${localHash.slice(0, 16)}\u2026 (build/*.deploy.json)`);
2323
+ out8(`local ${localHash.slice(0, 16)}\u2026 (build/*.deploy.json)`);
2357
2324
  const verdict = lawDiffVerdict(localHash, domains, ws);
2358
- for (const line of verdict.lines) out9(line);
2325
+ for (const line of verdict.lines) out8(line);
2359
2326
  return verdict.inSync ? 0 : 2;
2360
2327
  }
2361
2328
 
@@ -2399,15 +2366,6 @@ a bare <ws> resolves from nomos.package.mjs's optional \`workspace\` binding):
2399
2366
  githolon secret set <ws> <secret> import a secret you already hold
2400
2367
  githolon secret rotate <ws> rotate (and re-save) the workspace secret
2401
2368
 
2402
- Capability credentials (facts on the ledger, values host-side \u2014 the value NEVER rides argv;
2403
- stdin or --from-gcloud only; architecture/capability_credentials.md):
2404
- githolon capability bind <ws> <capability> bind a credential: value from stdin (or
2405
- --from-gcloud <name>) \u2192 the workspace's holon;
2406
- sha256(value) \u2192 the law-state binding fact
2407
- githolon capability list <ws> the binding FACTS (never the values)
2408
- githolon capability rotate <ws> <capability> revoke + re-bind at epoch+1 (new value)
2409
- githolon capability unbind <ws> <capability> revoke the fact; the host forgets the value
2410
-
2411
2369
  Git lane (stock git push as deploy/birth \u2014 see also: push-to-create):
2412
2370
  githolon git setup install the credential helper for the cloud host
2413
2371
  githolon git remote [<ws>] [<remoteName>] wire this repo to a workspace (default name: nomos)
@@ -2486,38 +2444,6 @@ ${USAGE}`);
2486
2444
  if (sub === "rotate" && ws !== void 0) return secretRotate(ws, opts);
2487
2445
  return usageFail("expected: githolon secret <set <ws> <secret> | rotate <ws>>");
2488
2446
  }
2489
- async function runCapability(argv) {
2490
- const usageFail = (m) => {
2491
- process.stderr.write(`error: ${m}
2492
-
2493
- ${commandHelp("capability")}`);
2494
- return 1;
2495
- };
2496
- const pos = [];
2497
- const opts = {};
2498
- const rest = argv.slice(1);
2499
- for (let i = 0; i < rest.length; i++) {
2500
- const a = rest[i];
2501
- if (a === "--cloud" || a === "--from-gcloud" || a === "--scope" || a === "--expires-at") {
2502
- const v = rest[++i];
2503
- if (v === void 0) return usageFail(`${a} requires a value`);
2504
- if (a === "--cloud") opts.cloud = v;
2505
- else if (a === "--from-gcloud") opts.fromGcloud = v;
2506
- else if (a === "--scope") opts.scope = v;
2507
- else opts.expiresAt = v;
2508
- } else if (a.startsWith("--")) {
2509
- return usageFail(`unknown flag '${a}'`);
2510
- } else {
2511
- pos.push(a);
2512
- }
2513
- }
2514
- const [sub, ws, capability] = pos;
2515
- if (sub === "bind" && ws !== void 0 && capability !== void 0) return capabilityBind(ws, capability, opts);
2516
- if (sub === "rotate" && ws !== void 0 && capability !== void 0) return capabilityRotate(ws, capability, opts);
2517
- if (sub === "unbind" && ws !== void 0 && capability !== void 0) return capabilityUnbind(ws, capability, opts);
2518
- if (sub === "list" && ws !== void 0) return capabilityList(ws, opts);
2519
- return usageFail("expected: githolon capability <bind|rotate|unbind> <ws> <capability> | list <ws>");
2520
- }
2521
2447
  function isKind(s) {
2522
2448
  return s !== void 0 && KINDS.includes(s);
2523
2449
  }
@@ -2597,7 +2523,7 @@ async function runProof(args) {
2597
2523
  const tsxBinRel = typeof tsxPkg.bin === "string" ? tsxPkg.bin : tsxPkg.bin?.["tsx"];
2598
2524
  const tsxCli = join10(tsxDir, tsxBinRel ?? "dist/cli.mjs");
2599
2525
  console.log("githolon proof --live \u2014 the full cloud loop (throwaway workspace, retired on exit" + (keep ? "; --keep: kept, secret printed once" : "") + ")");
2600
- const r = spawnSync5(process.execPath, [tsxCli, proofPath], {
2526
+ const r = spawnSync4(process.execPath, [tsxCli, proofPath], {
2601
2527
  stdio: "inherit",
2602
2528
  cwd: process.cwd(),
2603
2529
  env: { ...process.env, ...keep ? { PROOF_KEEP: "1" } : {} }
@@ -2608,7 +2534,7 @@ function parseArgs(argv) {
2608
2534
  const [command, ...rest] = argv;
2609
2535
  if (command !== "generate" && command !== "g") {
2610
2536
  throw new Error(
2611
- `Unknown command '${command ?? "(none)"}'. Expected dev | compile | proof | replay | status | generate | ws | deploy | secret | capability.`
2537
+ `Unknown command '${command ?? "(none)"}'. Expected dev | compile | proof | replay | status | generate | ws | deploy | secret.`
2612
2538
  );
2613
2539
  }
2614
2540
  let outDir = DEFAULT_OUT;
@@ -2774,9 +2700,6 @@ ${commandHelp("status")}`);
2774
2700
  if (argv[0] === "ws" || argv[0] === "deploy" || argv[0] === "secret") {
2775
2701
  return runCloud(argv);
2776
2702
  }
2777
- if (argv[0] === "capability") {
2778
- return runCapability(argv);
2779
- }
2780
2703
  if (argv[0] === "login") {
2781
2704
  const agent = argv.includes("--agent");
2782
2705
  const tokenAt = argv.indexOf("--token");
@@ -2833,8 +2756,8 @@ ${USAGE}`);
2833
2756
  let parsed;
2834
2757
  try {
2835
2758
  parsed = parseArgs(argv);
2836
- } catch (err10) {
2837
- process.stderr.write(`error: ${err10.message}
2759
+ } catch (err9) {
2760
+ process.stderr.write(`error: ${err9.message}
2838
2761
 
2839
2762
  ${USAGE}`);
2840
2763
  return 1;
@@ -2853,8 +2776,8 @@ ${USAGE}`);
2853
2776
  process.stdout.write(`created ${path}
2854
2777
  `);
2855
2778
  return 0;
2856
- } catch (err10) {
2857
- process.stderr.write(`error: ${err10.message}
2779
+ } catch (err9) {
2780
+ process.stderr.write(`error: ${err9.message}
2858
2781
  `);
2859
2782
  return 1;
2860
2783
  }