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.
- package/dist/cli.mjs +61 -53
- 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
|
-
|
|
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
|
|
1896
|
-
if (
|
|
1897
|
-
payload[
|
|
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,
|
|
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}/${
|
|
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}/${
|
|
1905
|
-
if (
|
|
1906
|
-
const rows = query(eng, ws,
|
|
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 ${
|
|
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 ${
|
|
1911
|
+
lines.push(`\u2713 declared query ${leg.query.id} answers locally \u2014 1 row`);
|
|
1911
1912
|
}
|
|
1912
|
-
if (
|
|
1913
|
-
const c = count(eng, ws,
|
|
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 ${
|
|
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 ${
|
|
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)
|
|
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
|
-
|
|
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
|
|
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,
|
|
4516
|
+
const { oid, doc } = chain[i];
|
|
4502
4517
|
const domain = doc.payload?.domain ?? "?";
|
|
4503
4518
|
const directive = doc.payload?.directiveId ?? "?";
|
|
4504
|
-
const
|
|
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
|
-
|
|
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)}
|
|
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
|
|
4539
|
-
const verb = ev.marker === "Create" ? "+ created" : ev.marker === "Delete" ? "- deleted" :
|
|
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.
|
|
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.
|
|
33
|
-
"@githolon/dsl": "^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": {
|