githolon 0.45.0 → 0.46.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 +61 -53
  2. package/package.json +3 -3
package/dist/cli.mjs CHANGED
@@ -1624,24 +1624,10 @@ function parseAttestedReadNeed(error) {
1624
1624
  }
1625
1625
  return null;
1626
1626
  }
1627
- function offerIntent(eng, ws, bytes, opts) {
1628
- const name = `offer-in-${eng.seq++}.json`;
1629
- writeWork(eng, name, bytes);
1630
- const deferProjection = !!(opts && opts.defer);
1631
- const branch = opts && opts.branch || BRANCH;
1632
- return JSON.parse(call(eng.ex, "offer", { repoArg: repoArgOf(ws), workspace: ws, intentFile: `/work/${name}`, branch, deferProjection }, eng.STDERR));
1633
- }
1634
- function offerAdmit(eng, ws, bytes, opts) {
1635
- const v = offerIntent(eng, ws, bytes, opts);
1636
- return v.outcome === "admitted" ? { ok: true, head: v.head, ...v.born ? { born: v.born } : {} } : { ok: false, error: v.verdict?.reason ?? v.error ?? "the offer was refused" };
1637
- }
1638
- function applyIntentBytes(eng, ws, bytes, opts) {
1639
- return offerAdmit(eng, ws, bytes, opts);
1640
- }
1641
1627
  function verifyChainLocal(eng, ws) {
1642
1628
  return JSON.parse(call(eng.ex, "query", { repoArg: repoArgOf(ws), workspace: ws, queryBytes: b64Json({ op: "verifyChain" }), branch: BRANCH }, eng.STDERR));
1643
1629
  }
1644
- var enc3, dec3, BRANCH, RESULT_PACK_INLINE_MAX, repoArgOf, gitdirOf, unpack, repoArgOfGitdir, bytesFromB64, kgit, installPayload, fullRef, applyPackInto, custodyLsRefs, qById, query, attestedRead, cryptoUnwrapKey, count, sum;
1630
+ var enc3, dec3, BRANCH, RESULT_PACK_INLINE_MAX, repoArgOf, gitdirOf, unpack, repoArgOfGitdir, bytesFromB64, kgit, installPayload, fullRef, applyPackInto, custodyLsRefs, qById, query, attestedRead, cryptoUnwrapKey, count, sum, spatialWithin;
1645
1631
  var init_engine = __esm({
1646
1632
  "vendor/engine/engine.mjs"() {
1647
1633
  "use strict";
@@ -1707,6 +1693,7 @@ var init_engine = __esm({
1707
1693
  cryptoUnwrapKey = (eng, { secret, hpkeEpk, ct }) => JSON.parse(call(eng.ex, "query", { queryBytes: b64Json({ op: "cryptoUnwrapKey", secret, hpkeEpk, ct }) }, eng.STDERR)).scopeKey;
1708
1694
  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));
1709
1695
  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));
1696
+ spatialWithin = (eng, ws, spatialId, bbox, principal = "") => JSON.parse(call(eng.ex, "query", { repoArg: repoArgOf(ws), workspace: ws, queryBytes: b64Json({ op: "spatial", spatialId, minLng: bbox.minLng, minLat: bbox.minLat, maxLng: bbox.maxLng, maxLat: bbox.maxLat }), principal, branch: BRANCH }, eng.STDERR));
1710
1697
  }
1711
1698
  });
1712
1699
 
@@ -1889,32 +1876,55 @@ async function runOfflineLegs(eng, ws, lawHash, legs, frameworkHash, deployUsda)
1889
1876
  });
1890
1877
  const lines = [];
1891
1878
  const kinds = legs.legs ?? (legs.directiveId !== void 0 ? ["standalone-provable"] : []);
1879
+ const createLegs = [];
1892
1880
  if (legs.directiveId !== void 0) {
1893
- const payload = { ...legs.payload };
1881
+ createLegs.push({
1882
+ directiveId: legs.directiveId,
1883
+ ...legs.aggregateId !== void 0 ? { aggregateId: legs.aggregateId } : {},
1884
+ ...legs.payload !== void 0 ? { payload: legs.payload } : {},
1885
+ ...legs.autoStamped !== void 0 ? { autoStamped: legs.autoStamped } : {},
1886
+ ...legs.mintField !== void 0 ? { mintField: legs.mintField } : {},
1887
+ ...legs.query !== void 0 ? { query: legs.query } : {},
1888
+ ...legs.count !== void 0 ? { count: legs.count } : {},
1889
+ ...legs.spatial !== void 0 ? { spatial: legs.spatial } : {}
1890
+ });
1891
+ for (const e of legs.extraCreates ?? []) createLegs.push({ ...e });
1892
+ }
1893
+ for (const leg of createLegs) {
1894
+ const payload = { ...leg.payload };
1894
1895
  const stamp = (/* @__PURE__ */ new Date()).toISOString();
1895
- for (const f of legs.autoStamped ?? []) payload[f] = stamp;
1896
- if (legs.mintField !== void 0 && legs.aggregateId !== void 0) {
1897
- payload[legs.mintField] = mintId(eng, legs.aggregateId);
1896
+ for (const f of leg.autoStamped ?? []) payload[f] = stamp;
1897
+ if (leg.mintField !== void 0 && leg.aggregateId !== void 0) {
1898
+ payload[leg.mintField] = mintId(eng, leg.aggregateId);
1898
1899
  }
1899
- const res = author(eng, ws, legs.domain, legs.directiveId, payload, lawHash);
1900
+ const res = author(eng, ws, legs.domain, leg.directiveId, payload, lawHash);
1900
1901
  if (res.ok === false) {
1901
- return done(false, lines, `dispatch ${legs.domain}/${legs.directiveId} refused: ${res.error ?? "unknown"} \u2014 the law itself rejected its own synthesized sample; check the directive's plan/payload schema`);
1902
+ return done(false, lines, `dispatch ${legs.domain}/${leg.directiveId} refused: ${res.error ?? "unknown"} \u2014 the law itself rejected its own synthesized sample; check the directive's plan/payload schema`);
1902
1903
  }
1903
1904
  const createdId = (sealedIntentOf(eng, ws, res)?.events ?? []).find((e) => e.marker === "Create")?.aggregate;
1904
- lines.push(`\u2713 dispatch ${legs.domain}/${legs.directiveId} \u2014 offline write under the new law${createdId !== void 0 ? ` (${createdId.slice(0, 28)}\u2026)` : ""}`);
1905
- if (legs.query !== void 0) {
1906
- const rows = query(eng, ws, legs.query.id, JSON.stringify(legs.query.params));
1905
+ lines.push(`\u2713 dispatch ${legs.domain}/${leg.directiveId} \u2014 offline write under the new law${createdId !== void 0 ? ` (${createdId.slice(0, 28)}\u2026)` : ""}`);
1906
+ if (leg.query !== void 0) {
1907
+ const rows = query(eng, ws, leg.query.id, JSON.stringify(leg.query.params));
1907
1908
  if (rows.length !== 1 || createdId !== void 0 && rows[0].id !== createdId) {
1908
- return done(false, lines, `declared query ${legs.query.id} expected the 1 created row, got ${JSON.stringify(rows.map((r) => r.id))} \u2014 check the query's key fields against the directive's payload`);
1909
+ return done(false, lines, `declared query ${leg.query.id} expected the 1 created row, got ${JSON.stringify(rows.map((r) => r.id))} \u2014 check the query's key fields against the directive's payload`);
1909
1910
  }
1910
- lines.push(`\u2713 declared query ${legs.query.id} answers locally \u2014 1 row`);
1911
+ lines.push(`\u2713 declared query ${leg.query.id} answers locally \u2014 1 row`);
1911
1912
  }
1912
- if (legs.count !== void 0) {
1913
- const c = count(eng, ws, legs.count.id, legs.count.group).count;
1913
+ if (leg.count !== void 0) {
1914
+ const c = count(eng, ws, leg.count.id, leg.count.group).count;
1914
1915
  if (c !== 1) {
1915
- return done(false, lines, `declared count ${legs.count.id}(${JSON.stringify(legs.count.group)}) expected 1, got ${c} \u2014 check the count's grouping against the created row`);
1916
+ return done(false, lines, `declared count ${leg.count.id}(${JSON.stringify(leg.count.group)}) expected 1, got ${c} \u2014 check the count's grouping against the created row`);
1916
1917
  }
1917
- lines.push(`\u2713 declared count ${legs.count.id}(${JSON.stringify(legs.count.group)}) = 1 locally`);
1918
+ lines.push(`\u2713 declared count ${leg.count.id}(${JSON.stringify(leg.count.group)}) = 1 locally`);
1919
+ }
1920
+ if (leg.spatial !== void 0) {
1921
+ const world = { minLng: -180, minLat: -90, maxLng: 180, maxLat: 90 };
1922
+ const sr = spatialWithin(eng, ws, leg.spatial.id, world);
1923
+ const ids = (sr.rows ?? []).map((r) => r.id);
1924
+ if (sr.ok === false || createdId === void 0 || !ids.includes(createdId)) {
1925
+ return done(false, lines, `spatial ${leg.spatial.id} membership: expected the created row ${createdId ?? "?"} in the world-bbox probe, got ${JSON.stringify(ids)}${sr.error ? ` (${sr.error})` : ""} \u2014 check the indexed geometry path against the directive's payload`);
1926
+ }
1927
+ lines.push(`\u2713 spatial ${leg.spatial.id} \u2014 the created row answers the R*Tree probe (index membership proven)`);
1918
1928
  }
1919
1929
  }
1920
1930
  if (legs.childBirth !== void 0) {
@@ -4112,7 +4122,7 @@ var HELP = {
4112
4122
  },
4113
4123
  replay: {
4114
4124
  usage: "githolon replay <ws|dir> [--step N] [--json] [--cloud <url>]",
4115
- what: "The ledger as film: walk a chain (cloud workspace or local holon directory) and re-apply it\nintent by intent through the SAME wasm gate edge admission runs \u2014 per step: directive, payload,\nthe rows it changed, running per-type tallies. Finale: the chain's verify_chain verdict.\nOn a TTY it steps interactively (enter = next, a = run to end, q = quit).",
4125
+ what: "The ledger as film: walk a chain (cloud workspace or local holon directory), require the\nkernel's from-genesis verify_chain verdict to be green, then render the verified intent stream \u2014\nper step: directive, payload, the rows it changed, running per-type tallies. On a TTY it steps\ninteractively (enter = next, a = run to end, q = quit).",
4116
4126
  flags: [
4117
4127
  ["<ws|dir>", "a workspace name on the cloud, or a local holon directory (githolon ledger init)"],
4118
4128
  ["--step N", "non-interactive; print the running tallies every N intents"],
@@ -4372,7 +4382,6 @@ import git2 from "isomorphic-git";
4372
4382
  var out8 = (s) => void process.stdout.write(s + "\n");
4373
4383
  var err8 = (s) => void process.stderr.write("error: " + s + "\n");
4374
4384
  var SOURCE = "source";
4375
- var REPLAY = "replay";
4376
4385
  function summarizePayload(payload, max = 100) {
4377
4386
  if (payload === void 0) return "\u2014";
4378
4387
  const parts = [];
@@ -4488,32 +4497,26 @@ async function replay(target, opts) {
4488
4497
  err8(`the chain on '${target}' carries no intents \u2014 nothing to replay`);
4489
4498
  return 1;
4490
4499
  }
4491
- await mountFresh(eng, REPLAY);
4500
+ const verdict = verifyChainLocal(eng, SOURCE);
4501
+ if (verdict["valid"] !== true) {
4502
+ if (json) emit({ finale: true, verdict });
4503
+ else printVerdict(verdict);
4504
+ return 1;
4505
+ }
4492
4506
  const interactive = !json && opts.step === void 0 && process.stdout.isTTY === true && process.stdin.isTTY === true;
4493
4507
  const stepEvery = opts.step ?? (json ? 0 : 0);
4494
4508
  const tallies = /* @__PURE__ */ new Map();
4509
+ const seenRows = /* @__PURE__ */ new Set();
4495
4510
  let autoRun = !interactive;
4496
4511
  if (!json) {
4497
- out8(`replaying ${chain.length} intent(s) from ${isDir ? target : `${cloud} :: ${target}`} \u2014 every step re-admitted through the wasm gate`);
4512
+ out8(`replaying ${chain.length} intent(s) from ${isDir ? target : `${cloud} :: ${target}`} \u2014 verify_chain green, rendering the sealed event film`);
4498
4513
  if (interactive) out8(" keys: enter = next intent \xB7 a = run to the end \xB7 q = quit\n");
4499
4514
  }
4500
4515
  for (let i = 0; i < chain.length; i++) {
4501
- const { oid, bytes, doc } = chain[i];
4516
+ const { oid, doc } = chain[i];
4502
4517
  const domain = doc.payload?.domain ?? "?";
4503
4518
  const directive = doc.payload?.directiveId ?? "?";
4504
- const touched = (doc.events ?? []).map((e) => e.aggregate).filter((a) => typeof a === "string");
4505
- const before = new Map(touched.map((id) => [id, qById(eng, REPLAY, id)[0]?.data]));
4506
- const t0 = performance.now();
4507
- const res = applyIntentBytes(eng, REPLAY, bytes);
4508
- const ms = performance.now() - t0;
4509
- if (res.ok === false) {
4510
- const msg = `replay REFUSED at intent ${i} (${domain}/${directive}, ${oid.slice(0, 10)}): ${res.error ?? "unknown"}`;
4511
- if (json) emit({ step: i, oid, domain, directive, refused: true, error: res.error ?? "unknown" });
4512
- else err8(msg);
4513
- err8("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)");
4514
- printVerdict(verifyChainLocal(eng, SOURCE));
4515
- return 1;
4516
- }
4519
+ const seenBeforeStep = new Set(seenRows);
4517
4520
  for (const ev of doc.events ?? []) {
4518
4521
  if (ev.marker === "Create") tallies.set(typeOf(ev), (tallies.get(typeOf(ev)) ?? 0) + 1);
4519
4522
  if (ev.marker === "Delete") tallies.set(typeOf(ev), (tallies.get(typeOf(ev)) ?? 1) - 1);
@@ -4527,16 +4530,16 @@ async function replay(target, opts) {
4527
4530
  directive,
4528
4531
  payload: capJsonStrings(doc.payload?.payload ?? null),
4529
4532
  events: (doc.events ?? []).map((e) => ({ aggregate: e.aggregate, marker: e.marker, ops: summarizeOps(e) })),
4530
- applyMs: +ms.toFixed(1),
4533
+ verified: true,
4531
4534
  tallies: Object.fromEntries(tallies)
4532
4535
  });
4533
4536
  } else {
4534
- out8(`[${String(i + 1).padStart(String(chain.length).length)}/${chain.length}] ${domain}/${directive} (${oid.slice(0, 10)}, ${ms.toFixed(0)} ms)`);
4537
+ out8(`[${String(i + 1).padStart(String(chain.length).length)}/${chain.length}] ${domain}/${directive} (${oid.slice(0, 10)})`);
4535
4538
  out8(` payload ${summarizePayload(doc.payload?.payload)}`);
4536
4539
  for (const ev of doc.events ?? []) {
4537
4540
  const id = ev.aggregate ?? "?";
4538
- const was = before.get(id);
4539
- const verb = ev.marker === "Create" ? "+ created" : ev.marker === "Delete" ? "- deleted" : was === void 0 ? "~ touched" : "~ updated";
4541
+ const hadRow = typeof ev.aggregate === "string" && seenBeforeStep.has(ev.aggregate);
4542
+ const verb = ev.marker === "Create" ? "+ created" : ev.marker === "Delete" ? "- deleted" : hadRow ? "~ updated" : "~ touched";
4540
4543
  out8(` ${verb} ${id}`);
4541
4544
  const ops = summarizeOps(ev);
4542
4545
  if (ops.length > 0) out8(` ${ops}`);
@@ -4545,6 +4548,12 @@ async function replay(target, opts) {
4545
4548
  const showTally = stepEvery > 0 ? (i + 1) % stepEvery === 0 || i === chain.length - 1 : true;
4546
4549
  if (showTally && tallyLine.length > 0) out8(` rows ${tallyLine}`);
4547
4550
  }
4551
+ for (const ev of doc.events ?? []) {
4552
+ if (typeof ev.aggregate === "string") {
4553
+ if (ev.marker === "Delete") seenRows.delete(ev.aggregate);
4554
+ else seenRows.add(ev.aggregate);
4555
+ }
4556
+ }
4548
4557
  if (interactive && !autoRun && i < chain.length - 1) {
4549
4558
  const key = await readKey();
4550
4559
  if (key === "quit") {
@@ -4556,7 +4565,6 @@ stopped at intent ${i + 1}/${chain.length} \u2014 the verify verdict below cover
4556
4565
  }
4557
4566
  }
4558
4567
  if (!json) out8("");
4559
- const verdict = verifyChainLocal(eng, SOURCE);
4560
4568
  if (json) {
4561
4569
  emit({ finale: true, verdict });
4562
4570
  return verdict["valid"] === true ? 0 : 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "githolon",
3
- "version": "0.45.0",
3
+ "version": "0.46.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",
@@ -29,8 +29,8 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "@bjorn3/browser_wasi_shim": "0.4.2",
32
- "@githolon/client": "^0.45.0",
33
- "@githolon/dsl": "^0.45.0",
32
+ "@githolon/client": "^0.46.0",
33
+ "@githolon/dsl": "^0.46.0",
34
34
  "isomorphic-git": "^1.38.4"
35
35
  },
36
36
  "devDependencies": {