githolon 0.14.0 → 0.16.0

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 +273 -184
  2. package/package.json +3 -3
package/dist/cli.mjs CHANGED
@@ -449,12 +449,164 @@ 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 out10 = new Uint8Array(n);
457
+ let o = 0;
458
+ for (const c of chunks) {
459
+ out10.set(c, o);
460
+ o += c.length;
461
+ }
462
+ return out10;
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) {
@@ -472,7 +624,7 @@ 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 {
@@ -495,15 +647,10 @@ function call(ex, mode, fields, STDERR) {
495
647
  ex.git_holon_dealloc(reqPtr, req.length);
496
648
  }
497
649
  }
498
- function seedManifests(m, strings) {
499
- m.set("domain_manifests.json", new File(enc2.encode(strings.read)));
500
- m.set("identity-manifests.json", new File(enc2.encode(strings.identity)));
501
- }
502
- async function createEngine({ wasmModule, bootstrapPkg, nomosPkg, manifestStrings, replica, installedBy = "nomos-cloud" }) {
650
+ async function createEngine({ wasmModule, bootstrapPkg, nomosPkg, replica, installedBy = "nomos-cloud" }) {
503
651
  const hashes = { bootstrap: await sha256hex(bootstrapPkg), nomos: await sha256hex(nomosPkg) };
504
652
  const root = /* @__PURE__ */ new Map();
505
- seedManifests(root, manifestStrings);
506
- root.set("domain.package.usda", new File(enc2.encode(bootstrapPkg)));
653
+ root.set("domain.package.usda", new File(enc3.encode(bootstrapPkg)));
507
654
  root.set("ws", new Directory(/* @__PURE__ */ new Map()));
508
655
  const preopen = new PreopenDirectory("/work", root);
509
656
  const STDERR = [];
@@ -523,75 +670,35 @@ async function createEngine({ wasmModule, bootstrapPkg, nomosPkg, manifestString
523
670
  hashes,
524
671
  bootstrapPkg,
525
672
  nomosPkg,
526
- manifestStrings,
527
673
  installedBy,
528
674
  fs: makeGitFs(preopen, "/work", { File, Directory }),
529
675
  mounted: /* @__PURE__ */ new Map(),
530
676
  // ws -> { restored, remoteMain, restoreError }
531
- mainIntents: /* @__PURE__ */ new Map(),
677
+ mainIntents: /* @__PURE__ */ new Map()
532
678
  // ws -> { head, ids:Set, oids:Set } (admission idempotence)
533
- knownDomainsCache: null
534
679
  };
535
680
  return eng;
536
681
  }
537
- function setManifests(eng, strings) {
538
- eng.manifestStrings = strings;
539
- eng.knownDomainsCache = null;
540
- eng.directiveRoutesCache = null;
541
- eng.scopedReadsCache = null;
542
- eng.placementDirectivesCache = null;
543
- eng.tenantTypesCache = null;
544
- eng.globalAggregatesCache = null;
545
- const root = eng.preopen.dir.contents;
546
- seedManifests(root, strings);
547
- const wsRoot = root.get("ws");
548
- for (const ws of eng.mounted.keys()) {
549
- const wsDir = wsRoot.contents.get(ws);
550
- if (wsDir) seedManifests(wsDir.contents, strings);
551
- }
552
- }
553
682
  function stageWorkspaceDir(eng, ws) {
554
683
  const wsContents = /* @__PURE__ */ new Map();
555
- seedManifests(wsContents, eng.manifestStrings);
556
684
  eng.preopen.dir.contents.get("ws").contents.set(ws, new Directory(wsContents));
557
685
  }
558
686
  async function mountWorkspace(eng, ws, ledger) {
559
687
  if (eng.mounted.has(ws)) return eng.mounted.get(ws);
560
688
  stageWorkspaceDir(eng, ws);
561
689
  const gitdir = gitdirOf(ws);
562
- let restored = false, remoteMain = null, restoreError = null, checkpoint = null;
690
+ let restored = false, remoteMain = null, restoreError = null;
563
691
  try {
564
- const info = await git.getRemoteInfo({ http, url: ledger.remote, headers: ledger.headers });
565
- 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" });
566
694
  if (remoteMain) {
567
- await git.init({ fs: eng.fs, gitdir, bare: true, defaultBranch: "main" });
568
- await git.addRemote({ fs: eng.fs, gitdir, remote: "origin", url: ledger.remote, force: true });
569
- const ckpt = await discoverCheckpointFromCustody(ledger).catch(() => null);
570
- let shallowOk = false;
571
- if (ckpt?.cursor && ckpt.frontier) {
572
- const steps = [32, 96, 256, 1024];
573
- for (let i = 0; i < steps.length; i++) {
574
- const depth = steps[i], relative = i > 0;
575
- await git.fetch({ fs: eng.fs, http, gitdir, remote: "origin", ref: "main", singleBranch: true, depth, relative, headers: ledger.headers });
576
- if (await git.readCommit({ fs: eng.fs, gitdir, oid: ckpt.cursor }).then(() => true, () => false)) {
577
- shallowOk = true;
578
- break;
579
- }
580
- }
581
- }
582
- if (!shallowOk) await git.fetch({ fs: eng.fs, http, gitdir, remote: "origin", ref: "main", singleBranch: true, headers: ledger.headers });
583
- await git.writeRef({ fs: eng.fs, gitdir, ref: "refs/heads/main", value: remoteMain, force: true });
584
- await git.writeRef({ fs: eng.fs, gitdir, ref: "HEAD", value: "ref: refs/heads/main", force: true, symbolic: true });
585
- if (shallowOk && ckpt?.blob) {
586
- const r = importCheckpoint(eng, ws, ckpt.blob, ckpt.frontier);
587
- checkpoint = { restored: !!(r && r.restored), frontierSeeded: !!(r && r.frontierSeeded), cursor: r && r.cursor ? r.cursor : ckpt.cursor, ref: ckpt.ref };
588
- }
695
+ kgit.writeRef(eng, gitdir, "HEAD", "ref: refs/heads/main");
589
696
  restored = true;
590
697
  }
591
698
  } catch (e) {
592
699
  restoreError = String(e && e.stack || e).split("\n").slice(0, 5).join(" | ");
593
700
  }
594
- const m = { restored, remoteMain, restoreError, checkpoint };
701
+ const m = { restored, remoteMain, restoreError };
595
702
  eng.mounted.set(ws, m);
596
703
  return m;
597
704
  }
@@ -610,95 +717,69 @@ function mintId(eng, typeTag) {
610
717
  function author(eng, ws, domain, directiveId, payload, controllerHash, opts = {}) {
611
718
  const seq = eng.seq++;
612
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 };
613
- writeWork(eng, `payload-${seq}.json`, enc2.encode(JSON.stringify(payload)));
614
- 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)));
615
722
  const genesis = !controllerHash;
616
723
  const defer = opts.deferProjection !== false;
617
- 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;
618
726
  if (defer && res.ok) (eng.pendingProjection ??= /* @__PURE__ */ new Set()).add(ws);
619
727
  return res;
620
728
  }
621
- function importCheckpoint(eng, ws, blobB64, frontierB64) {
622
- return JSON.parse(call(eng.ex, "checkpoint_import", { repoArg: repoArgOf(ws), workspace: ws, branch: BRANCH, blob: blobB64, ...frontierB64 ? { frontier: frontierB64 } : {} }, eng.STDERR));
623
- }
624
- async function streamAll(stream) {
625
- const chunks = [];
626
- const reader = stream.getReader();
627
- for (; ; ) {
628
- const { done, value } = await reader.read();
629
- if (done) break;
630
- chunks.push(value);
631
- }
632
- let len = 0;
633
- for (const c of chunks) len += c.length;
634
- const out10 = new Uint8Array(len);
635
- let at = 0;
636
- for (const c of chunks) {
637
- out10.set(c, at);
638
- at += c.length;
639
- }
640
- return out10;
641
- }
642
- async function gunzip(bytes) {
643
- const ds = new DecompressionStream("gzip");
644
- return streamAll(new Response(bytes).body.pipeThrough(ds));
645
- }
646
- async function discoverCheckpointFromCustody(ledger) {
647
- const freshHeaders = () => ({ ...ledger.headers || {} });
648
- 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);
649
- if (!refs.length) return null;
650
- const root = /* @__PURE__ */ new Map();
651
- root.set("ckpt", new Directory(/* @__PURE__ */ new Map()));
652
- const preopen = new PreopenDirectory("/work", root);
653
- const fs = makeGitFs(preopen, "/work", { File, Directory });
654
- const gitdir = "/work/ckpt/nomos.git";
655
- await git.init({ fs, gitdir, bare: true, defaultBranch: BRANCH });
656
- await git.addRemote({ fs, gitdir, remote: "origin", url: ledger.remote, force: true });
657
- const readFile = async (oid, filepath) => {
658
- try {
659
- return (await git.readBlob({ fs, gitdir, oid, filepath })).blob;
660
- } catch {
661
- return null;
662
- }
663
- };
664
- for (let i = refs.length - 1; i >= 0 && i >= refs.length - 3; i--) {
665
- 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"]) {
666
732
  try {
667
- await git.fetch({ fs, http, gitdir, remote: "origin", ref, singleBranch: true, depth: 1, headers: freshHeaders() });
668
- const gz = await readFile(oid, "checkpoint");
669
- if (!gz) continue;
670
- let meta = {};
671
- try {
672
- const mb = await readFile(oid, "meta");
673
- if (mb) meta = JSON.parse(dec2.decode(mb));
674
- } catch {
675
- }
676
- const codec = meta.codec ?? "gzip";
677
- const blob = dec2.decode(codec === "gzip" ? await gunzip(gz) : gz);
678
- const fgz = await readFile(oid, "frontier");
679
- const frontier = fgz ? dec2.decode(codec === "gzip" ? await gunzip(fgz) : fgz) : null;
680
- return { ref, oid, cursor: meta.cursor || null, blob, frontier };
681
- } catch {
733
+ await p.mkdir(`${gitdir}${d}`);
734
+ } catch (e) {
735
+ if (e && e.code !== "EEXIST") throw e;
682
736
  }
683
737
  }
684
- 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
+ }
747
+ }
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;
685
756
  }
686
- function applyIntentBytes(eng, ws, bytes) {
687
- const name = `intent-in-${eng.seq++}.json`;
757
+ function offerIntent(eng, ws, bytes, opts) {
758
+ const name = `offer-in-${eng.seq++}.json`;
688
759
  writeWork(eng, name, bytes);
689
- 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);
690
770
  }
691
771
  function verifyChainLocal(eng, ws) {
692
- 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));
693
773
  }
694
- var enc2, dec2, BRANCH, repoArgOf, gitdirOf, unpack, installPayload, qById, query, cryptoUnwrapKey, count, sum;
774
+ var enc3, dec3, BRANCH, repoArgOf, gitdirOf, unpack, repoArgOfGitdir, bytesFromB64, kgit, installPayload, fullRef, applyPackInto, custodyLsRefs, qById, query, cryptoUnwrapKey, count, sum;
695
775
  var init_engine = __esm({
696
776
  "vendor/engine/engine.mjs"() {
697
777
  "use strict";
698
778
  init_git_fs();
699
779
  init_tree();
700
- enc2 = new TextEncoder();
701
- dec2 = new TextDecoder();
780
+ init_custody_transport();
781
+ enc3 = new TextEncoder();
782
+ dec3 = new TextDecoder();
702
783
  BRANCH = "main";
703
784
  repoArgOf = (ws) => `/work/ws/${ws}`;
704
785
  gitdirOf = (ws) => `/work/ws/${ws}/nomos.git`;
@@ -706,12 +787,49 @@ var init_engine = __esm({
706
787
  const v = typeof p === "bigint" ? p : BigInt(p);
707
788
  return { ptr: Number(v >> 32n), len: Number(v & 0xffffffffn) };
708
789
  };
790
+ repoArgOfGitdir = (gitdir) => gitdir.replace(/\/nomos\.git$/, "");
791
+ bytesFromB64 = (b64) => Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
792
+ kgit = {
793
+ // resolveRef → tip oid hex, or null if the ref is absent (replaces git.resolveRef(...).catch(()=>null)).
794
+ resolveRef: (eng, gitdir, ref) => JSON.parse(call(eng.ex, "resolve_ref", { repoArg: repoArgOfGitdir(gitdir), ref }, eng.STDERR)).oid,
795
+ // readBlob → the blob bytes at `path` inside commit `oid`, or null if not found (no throw).
796
+ readBlob: (eng, gitdir, oid, path) => {
797
+ const r = JSON.parse(call(eng.ex, "read_blob", { repoArg: repoArgOfGitdir(gitdir), oid, path }, eng.STDERR));
798
+ return r.ok ? bytesFromB64(r.blobB64) : null;
799
+ },
800
+ // intentsAbove → [{ oid, intentB64 }] oldest→newest over (base, head] (replaces log + readBlob intent.json).
801
+ // `limit` (0 = all) caps to the most-recent N intent commits (replaces git.log depth).
802
+ intentsAbove: (eng, gitdir, head, base = "", limit = 0) => JSON.parse(call(eng.ex, "intents_above", { repoArg: repoArgOfGitdir(gitdir), head, base, limit }, eng.STDERR)).intents,
803
+ // listRefs → [{ ref, oid }] under prefix (replaces git.listRefs for LOCAL refs).
804
+ listRefs: (eng, gitdir, prefix) => JSON.parse(call(eng.ex, "list_refs", { repoArg: repoArgOfGitdir(gitdir), prefix }, eng.STDERR)).refs,
805
+ // writeRef → force-point a ref (plain oid or `ref:`-symbolic) (replaces git.writeRef).
806
+ writeRef: (eng, gitdir, ref, value) => JSON.parse(call(eng.ex, "write_ref", { repoArg: repoArgOfGitdir(gitdir), ref, value }, eng.STDERR)),
807
+ // deleteRef → remove a local ref, idempotent (replaces git.deleteRef).
808
+ deleteRef: (eng, gitdir, ref) => JSON.parse(call(eng.ex, "delete_ref", { repoArg: repoArgOfGitdir(gitdir), ref }, eng.STDERR)),
809
+ // writeMetaCommit → blobs→tree→commit→ref for a CUSTODY-META fact (checkpoint/refused/outbox/shape).
810
+ // `files`: [{ path, bytes:Uint8Array }]; returns the commit oid (replaces writeBlob+writeTree+writeCommit[+writeRef]).
811
+ writeMetaCommit: (eng, gitdir, { parents = [], files, message = "nomos custody meta", timeSecs = 0, ref = "" }) => JSON.parse(call(eng.ex, "write_meta_commit", {
812
+ repoArg: repoArgOfGitdir(gitdir),
813
+ parents,
814
+ files: files.map((f) => ({ path: f.path, blobB64: b64Bytes(f.bytes) })),
815
+ message,
816
+ timeSecs,
817
+ ref
818
+ }, eng.STDERR)).oid
819
+ };
709
820
  installPayload = (hash, usda, installedBy, dispositions) => ({ domainHash: hash, packageUsda: usda, installedBy, dependencies: [], finalizers: [], ...dispositions ? { dispositions } : {} });
710
- 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));
711
- 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));
821
+ fullRef = (r) => r === "HEAD" || r.startsWith("refs/") ? r : `refs/heads/${r}`;
822
+ applyPackInto = (eng, ws, pack) => {
823
+ if (!pack || !pack.length) return;
824
+ const r = JSON.parse(call(eng.ex, "apply_pack", { repoArg: repoArgOf(ws), packB64: b64Bytes(pack) }, eng.STDERR));
825
+ if (!r || r.ok !== true) throw new Error(`apply_pack: ${r && r.error}`);
826
+ };
827
+ custodyLsRefs = (ledger, prefix = null) => lsRefs(ledger.remote, ledger.headers || {}, { service: "git-upload-pack", prefix });
828
+ 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));
829
+ 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));
712
830
  cryptoUnwrapKey = (eng, { secret, hpkeEpk, ct }) => JSON.parse(call(eng.ex, "crypto_unwrap_key", { secret, hpkeEpk, ct }, eng.STDERR)).scopeKey;
713
- count = (eng, ws, countId, groupKey) => JSON.parse(call(eng.ex, "count", { repoArg: repoArgOf(ws), workspace: ws, countId, groupKey, branch: BRANCH }, eng.STDERR));
714
- sum = (eng, ws, sumId, groupKey) => JSON.parse(call(eng.ex, "sum", { repoArg: repoArgOf(ws), workspace: ws, sumId, groupKey, branch: BRANCH }, eng.STDERR));
831
+ 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));
832
+ 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));
715
833
  }
716
834
  });
717
835
 
@@ -740,9 +858,8 @@ async function fetchRuntime(cloud) {
740
858
  const localWasm = process.env["NOMOS_LOCAL_WASM"];
741
859
  if (localWasm) {
742
860
  const bytes = readFileSync2(localWasm);
743
- const manifests2 = await fetchJsonCached(`${cloud}/v1/runtime/manifests`, join4(cache, "manifests.json"));
744
861
  const packages2 = await fetchJsonCached(`${cloud}/v1/runtime/packages`, join4(cache, "packages.json"));
745
- return { wasmBytes: bytes, manifests: manifests2, packages: packages2 };
862
+ return { wasmBytes: bytes, packages: packages2 };
746
863
  }
747
864
  try {
748
865
  const r = await fetch(`${cloud}/v1/runtime/holon.wasm`);
@@ -754,25 +871,8 @@ async function fetchRuntime(cloud) {
754
871
  if (!existsSync3(wasmCache)) throw e;
755
872
  wasmBytes = readFileSync2(wasmCache);
756
873
  }
757
- const manifests = await fetchJsonCached(`${cloud}/v1/runtime/manifests`, join4(cache, "manifests.json"));
758
874
  const packages = await fetchJsonCached(`${cloud}/v1/runtime/packages`, join4(cache, "packages.json"));
759
- return { wasmBytes, manifests, packages };
760
- }
761
- function mergeManifests(baked, overlay) {
762
- const read = JSON.parse(baked.domainManifests);
763
- const identity = JSON.parse(baked.identityManifests);
764
- for (const [k, v] of Object.entries(overlay.identityManifests ?? {})) identity[k] = v;
765
- const r = overlay.readManifest;
766
- if (r !== void 0) {
767
- for (const [t, schema] of Object.entries(r["aggregateFieldKinds"] ?? {})) read["aggregateFieldKinds"][t] = schema;
768
- for (const key of ["queries", "counts", "sums", "mins", "maxes", "spatials", "deriveds", "combineds"]) {
769
- for (const d of r[key] ?? []) {
770
- const list = read[key] = read[key] ?? [];
771
- if (!list.some((x) => JSON.stringify(x) === JSON.stringify(d))) list.push(d);
772
- }
773
- }
774
- }
775
- return { read: JSON.stringify(read), identity: JSON.stringify(identity) };
875
+ return { wasmBytes, packages };
776
876
  }
777
877
  function writeTreeToDisk(dir, diskPath) {
778
878
  mkdirSync3(diskPath, { recursive: true });
@@ -793,13 +893,11 @@ function readTreeFromDisk(diskPath) {
793
893
  }
794
894
  async function holonEngine(cloud, overlay, installedBy) {
795
895
  const runtime = await fetchRuntime(cloud);
796
- const manifestStrings = overlay === void 0 ? { read: runtime.manifests.domainManifests, identity: runtime.manifests.identityManifests } : mergeManifests(runtime.manifests, overlay);
797
896
  const replica = BigInt(`0x${randomBytes(8).toString("hex")}`) & (1n << 63n) - 1n;
798
897
  const eng = await createEngine({
799
898
  wasmModule: await WebAssembly.compile(runtime.wasmBytes),
800
899
  bootstrapPkg: runtime.packages.bootstrap,
801
900
  nomosPkg: runtime.packages.nomos,
802
- manifestStrings,
803
901
  replica,
804
902
  installedBy
805
903
  });
@@ -1365,10 +1463,10 @@ function compileAsync(cwd, args = []) {
1365
1463
  }
1366
1464
  return new Promise((resolveRun) => {
1367
1465
  const chunks = [];
1368
- const dec3 = new TextDecoder();
1466
+ const dec4 = new TextDecoder();
1369
1467
  const child = spawn(process.execPath, [launcher, ...args], { cwd, stdio: ["ignore", "pipe", "pipe"] });
1370
- child.stdout?.on("data", (c) => chunks.push(dec3.decode(c)));
1371
- child.stderr?.on("data", (c) => chunks.push(dec3.decode(c)));
1468
+ child.stdout?.on("data", (c) => chunks.push(dec4.decode(c)));
1469
+ child.stderr?.on("data", (c) => chunks.push(dec4.decode(c)));
1372
1470
  child.on("error", (e) => resolveRun({ ok: false, ms: performance.now() - t0, output: String(e) }));
1373
1471
  child.on(
1374
1472
  "close",
@@ -1534,8 +1632,8 @@ function startServer(s) {
1534
1632
  req.on("data", (c) => chunks.push(c));
1535
1633
  req.on("end", () => {
1536
1634
  try {
1537
- const dec3 = new TextDecoder();
1538
- const body = chunks.map((c) => dec3.decode(c)).join("") || "{}";
1635
+ const dec4 = new TextDecoder();
1636
+ const body = chunks.map((c) => dec4.decode(c)).join("") || "{}";
1539
1637
  const r = author(s.eng, WS, decodeURIComponent(dispatch[1]), decodeURIComponent(dispatch[2]), JSON.parse(body), s.lawHash);
1540
1638
  if (r["ok"] === false) return respond(422, { ok: false, error: r["error"] });
1541
1639
  s.intents++;
@@ -1567,12 +1665,9 @@ function readDeployBody(cwd, packageName) {
1567
1665
  async function installLaw(s, deployBody, installedBy) {
1568
1666
  const newHash = await sha256hex(deployBody.packageUsda);
1569
1667
  if (newHash === s.lawHash) return { ok: true };
1570
- const previous = { ...s.eng.manifestStrings };
1571
1668
  const t0 = performance.now();
1572
- setManifests(s.eng, mergeManifests(s.runtime.manifests, deployBody));
1573
1669
  const res = author(s.eng, WS, "nomos", "installDomain", installPayload(newHash, deployBody.packageUsda, installedBy), s.eng.hashes.nomos);
1574
1670
  if (res.ok === false) {
1575
- setManifests(s.eng, previous);
1576
1671
  return { ok: false, error: `law install refused: ${res.error ?? "unknown"} \u2014 the previous law (${s.lawHash.slice(0, 12)}\u2026) keeps serving; fix and save again` };
1577
1672
  }
1578
1673
  s.lawHash = newHash;
@@ -1756,7 +1851,7 @@ import { randomBytes as randomBytes2 } from "node:crypto";
1756
1851
  import { readFileSync as readFileSync5 } from "node:fs";
1757
1852
  var out5 = (s) => void process.stdout.write(s + "\n");
1758
1853
  var err5 = (s) => void process.stderr.write("error: " + s + "\n");
1759
- function git2(args, opts = {}) {
1854
+ function git(args, opts = {}) {
1760
1855
  const r = spawnSync3("git", args, { stdio: opts.quiet === true ? "ignore" : "inherit" });
1761
1856
  return r.status ?? 1;
1762
1857
  }
@@ -1800,7 +1895,7 @@ async function gitSetup(opts) {
1800
1895
  return 1;
1801
1896
  }
1802
1897
  const helper = `!"${process.execPath}" "${self}" git-credential`;
1803
- if (git2(["config", "--global", `credential.${cloud}.helper`, helper]) !== 0 || git2(["config", "--global", `credential.${cloud}.useHttpPath`, "true"]) !== 0) {
1898
+ if (git(["config", "--global", `credential.${cloud}.helper`, helper]) !== 0 || git(["config", "--global", `credential.${cloud}.useHttpPath`, "true"]) !== 0) {
1804
1899
  err5("git config failed \u2014 is git installed?");
1805
1900
  return 1;
1806
1901
  }
@@ -1810,7 +1905,7 @@ async function gitSetup(opts) {
1810
1905
  }
1811
1906
  async function gitRemote(ws, name, opts) {
1812
1907
  const cloud = cloudBase(opts.cloud);
1813
- if (git2(["rev-parse", "--git-dir"], { quiet: true }) !== 0) {
1908
+ if (git(["rev-parse", "--git-dir"], { quiet: true }) !== 0) {
1814
1909
  err5("not a git repository \u2014 run inside your repo (git init first)");
1815
1910
  return 1;
1816
1911
  }
@@ -1818,8 +1913,8 @@ async function gitRemote(ws, name, opts) {
1818
1913
  if (setupRc !== 0) return setupRc;
1819
1914
  ensureSecret(cloud, ws);
1820
1915
  const url = `${cloud}/v1/workspaces/${ws}/git`;
1821
- if (git2(["remote", "add", name, url], { quiet: true }) !== 0) {
1822
- if (git2(["remote", "set-url", name, url], { quiet: true }) !== 0) {
1916
+ if (git(["remote", "add", name, url], { quiet: true }) !== 0) {
1917
+ if (git(["remote", "set-url", name, url], { quiet: true }) !== 0) {
1823
1918
  err5(`could not add or update remote '${name}'`);
1824
1919
  return 1;
1825
1920
  }
@@ -1835,7 +1930,7 @@ async function gitRemote(ws, name, opts) {
1835
1930
  );
1836
1931
  return 1;
1837
1932
  }
1838
- if (git2(["config", `http.${url}.extraHeader`, `x-nomos-principal: ${principal}`]) !== 0) {
1933
+ if (git(["config", `http.${url}.extraHeader`, `x-nomos-principal: ${principal}`]) !== 0) {
1839
1934
  err5("git config failed setting the principal header");
1840
1935
  return 1;
1841
1936
  }
@@ -1850,7 +1945,7 @@ async function gitRemote(ws, name, opts) {
1850
1945
  var HELP = {
1851
1946
  compile: {
1852
1947
  usage: "githolon compile [config] [--layered]",
1853
- what: "Compile the package by ./nomos.package.mjs (the @githolon/dsl launcher): ONE deterministic\n.package.usda (sha256 = the law's content hash) + read/identity manifests + the deploy body +\nthe typed TS client + the generated proof \u2014 all into build/.",
1948
+ what: "Compile the package by ./nomos.package.mjs (the @githolon/dsl launcher): ONE deterministic\n.package.usda (sha256 = the law's content hash) + the deploy body +\nthe typed TS client + the generated proof \u2014 all into build/.",
1854
1949
  flags: [
1855
1950
  ["[config]", "an alternate config file (default: nomos.package.mjs)"],
1856
1951
  ["--layered", "also emit the per-domain layered USD view"]
@@ -1884,7 +1979,7 @@ var HELP = {
1884
1979
  ["<ws|dir>", "a workspace name on the cloud, or a local holon directory (githolon ledger init)"],
1885
1980
  ["--step N", "non-interactive; print the running tallies every N intents"],
1886
1981
  ["--json", "one JSON line per step + the final verdict (pipe it)"],
1887
- ["--file <deploy.json>", "stage this deploy body's read manifests (default: the one in ./build)"]
1982
+ ["--file <deploy.json>", "reserved for local package hints (default: the one in ./build)"]
1888
1983
  ],
1889
1984
  examples: ["githolon replay my-guestbook", "githolon replay ./my-holon --step 10", "githolon replay my-guestbook --json | jq .directive"]
1890
1985
  },
@@ -2057,9 +2152,9 @@ init_engine();
2057
2152
  init_engine();
2058
2153
  init_cloud();
2059
2154
  init_local_holon();
2060
- import { existsSync as existsSync8, readFileSync as readFileSync7 } from "node:fs";
2155
+ import { existsSync as existsSync8 } from "node:fs";
2061
2156
  import { join as join9 } from "node:path";
2062
- import git3 from "isomorphic-git";
2157
+ import git2 from "isomorphic-git";
2063
2158
  var out7 = (s) => void process.stdout.write(s + "\n");
2064
2159
  var err7 = (s) => void process.stderr.write("error: " + s + "\n");
2065
2160
  var SOURCE = "source";
@@ -2114,12 +2209,12 @@ function typeOf(ev) {
2114
2209
  }
2115
2210
  async function walkChain(eng, ws) {
2116
2211
  const gitdir = gitdirOf(ws);
2117
- const dec3 = new TextDecoder();
2212
+ const dec4 = new TextDecoder();
2118
2213
  const entries = [];
2119
- for (const c of await git3.log({ fs: eng.fs, gitdir, ref: "main" })) {
2214
+ for (const c of await git2.log({ fs: eng.fs, gitdir, ref: "main" })) {
2120
2215
  try {
2121
- const { blob } = await git3.readBlob({ fs: eng.fs, gitdir, oid: c.oid, filepath: "intent.json" });
2122
- entries.push({ oid: c.oid, bytes: blob, doc: JSON.parse(dec3.decode(blob)) });
2216
+ const { blob } = await git2.readBlob({ fs: eng.fs, gitdir, oid: c.oid, filepath: "intent.json" });
2217
+ entries.push({ oid: c.oid, bytes: blob, doc: JSON.parse(dec4.decode(blob)) });
2123
2218
  } catch {
2124
2219
  }
2125
2220
  }
@@ -2147,15 +2242,9 @@ async function replay(target, opts) {
2147
2242
  const cloud = cloudBase(opts.cloud);
2148
2243
  const json = opts.json === true;
2149
2244
  const emit = (o) => out7(JSON.stringify(o));
2150
- let overlay;
2151
- try {
2152
- overlay = JSON.parse(readFileSync7(discoverDeployJson(process.cwd(), opts.file), "utf8"));
2153
- } catch {
2154
- overlay = void 0;
2155
- }
2156
2245
  let eng;
2157
2246
  try {
2158
- ({ eng } = await holonEngine(cloud, overlay, "githolon-replay"));
2247
+ ({ eng } = await holonEngine(cloud, void 0, "githolon-replay"));
2159
2248
  } catch (e) {
2160
2249
  err7(`cannot boot the local holon: ${String(e.message ?? e)}
2161
2250
  the runtime rides ${cloud}/v1/runtime/* (cached in ~/.holon/runtime after one fetch)`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "githolon",
3
- "version": "0.14.0",
3
+ "version": "0.16.0",
4
4
  "type": "module",
5
5
  "description": "githolon — the Nomos developer CLI: Rails-style generators for @githolon/dsl domains + the package compiler. Kernel-independent.",
6
6
  "license": "SEE LICENSE IN LICENSE.md",
@@ -10,7 +10,7 @@
10
10
  "directory": "cli"
11
11
  },
12
12
  "bin": {
13
- "githolon": "./dist/cli.mjs"
13
+ "githolon": "dist/cli.mjs"
14
14
  },
15
15
  "files": [
16
16
  "dist"
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "@bjorn3/browser_wasi_shim": "0.4.2",
30
- "@githolon/dsl": "^0.14.0",
30
+ "@githolon/dsl": "^0.16.0",
31
31
  "isomorphic-git": "^1.38.4"
32
32
  },
33
33
  "devDependencies": {