githolon 0.102.1 → 0.102.2
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 +232 -82
- package/dist/dev-server.mjs +87 -42
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -372,7 +372,7 @@ function makeGitFs(preopen, mount, { File: File4, Directory: Directory4 }) {
|
|
|
372
372
|
const rel = p.slice(mount.length + 1).replace(/\/+$/, "");
|
|
373
373
|
return rel === "" ? [] : rel.split("/");
|
|
374
374
|
}
|
|
375
|
-
function
|
|
375
|
+
function resolve8(ps) {
|
|
376
376
|
let cur = root;
|
|
377
377
|
for (const part of ps) {
|
|
378
378
|
if (!isDir(cur)) return null;
|
|
@@ -382,11 +382,11 @@ function makeGitFs(preopen, mount, { File: File4, Directory: Directory4 }) {
|
|
|
382
382
|
}
|
|
383
383
|
return cur;
|
|
384
384
|
}
|
|
385
|
-
const parent = (ps) =>
|
|
385
|
+
const parent = (ps) => resolve8(ps.slice(0, -1));
|
|
386
386
|
const leaf = (ps) => ps[ps.length - 1];
|
|
387
387
|
const promises = {
|
|
388
388
|
async readFile(p, opts) {
|
|
389
|
-
const n =
|
|
389
|
+
const n = resolve8(parts(p));
|
|
390
390
|
if (n === null) throw fsErr("ENOENT", p);
|
|
391
391
|
if (isDir(n)) throw fsErr("EISDIR", p);
|
|
392
392
|
const data = n.data ?? new Uint8Array(0);
|
|
@@ -405,7 +405,7 @@ function makeGitFs(preopen, mount, { File: File4, Directory: Directory4 }) {
|
|
|
405
405
|
if (!isDir(par) || !par.contents.delete(leaf(ps))) throw fsErr("ENOENT", p);
|
|
406
406
|
},
|
|
407
407
|
async readdir(p) {
|
|
408
|
-
const n =
|
|
408
|
+
const n = resolve8(parts(p));
|
|
409
409
|
if (n === null) throw fsErr("ENOENT", p);
|
|
410
410
|
if (!isDir(n)) throw fsErr("ENOTDIR", p);
|
|
411
411
|
return [...n.contents.keys()];
|
|
@@ -425,7 +425,7 @@ function makeGitFs(preopen, mount, { File: File4, Directory: Directory4 }) {
|
|
|
425
425
|
return promises.lstat(p);
|
|
426
426
|
},
|
|
427
427
|
async lstat(p) {
|
|
428
|
-
const n =
|
|
428
|
+
const n = resolve8(parts(p));
|
|
429
429
|
if (n === null) throw fsErr("ENOENT", p);
|
|
430
430
|
const dir = isDir(n);
|
|
431
431
|
return {
|
|
@@ -621,7 +621,7 @@ function wasmModuleFor(base, fetchImpl) {
|
|
|
621
621
|
function parseSnapshot(bytes) {
|
|
622
622
|
try {
|
|
623
623
|
const o = JSON.parse(dec2.decode(bytes));
|
|
624
|
-
if (o && o.v === 2 && typeof o.tree === "string") return { treeBytes:
|
|
624
|
+
if (o && o.v === 2 && typeof o.tree === "string") return { treeBytes: nmsInternalSnapshotFromBase64(o.tree), ckpt: o.ckpt ?? null, frontier: o.frontier ?? null, syncedBase: o.syncedBase ?? null };
|
|
625
625
|
} catch {
|
|
626
626
|
}
|
|
627
627
|
return { treeBytes: bytes, ckpt: null, frontier: null, syncedBase: null };
|
|
@@ -630,7 +630,7 @@ function buildSnapshot(treeBytes, ckpt, syncedBase) {
|
|
|
630
630
|
if ((!ckpt || !ckpt.blob && !ckpt.frontier) && !syncedBase) return treeBytes;
|
|
631
631
|
return enc2.encode(JSON.stringify({
|
|
632
632
|
v: 2,
|
|
633
|
-
tree:
|
|
633
|
+
tree: nmsInternalSnapshotToBase64(treeBytes),
|
|
634
634
|
ckpt: ckpt && ckpt.blob ? ckpt.blob : null,
|
|
635
635
|
frontier: ckpt ? ckpt.frontier ?? null : null,
|
|
636
636
|
cursor: ckpt ? ckpt.cursor ?? null : null,
|
|
@@ -870,7 +870,7 @@ function createWasmEnginePlane({ span } = {}) {
|
|
|
870
870
|
}
|
|
871
871
|
const buf = new Uint8Array(await r.arrayBuffer());
|
|
872
872
|
if (!buf.length) return { applied: false };
|
|
873
|
-
view.applyPack(
|
|
873
|
+
view.applyPack(nmsInternalSnapshotToBase64(buf));
|
|
874
874
|
return { applied: true };
|
|
875
875
|
} finally {
|
|
876
876
|
if (end) end();
|
|
@@ -920,7 +920,7 @@ function createWasmEnginePlane({ span } = {}) {
|
|
|
920
920
|
function createWasmKernelProvider({ span } = {}) {
|
|
921
921
|
return createWasmEnginePlane({ span }).providerFor();
|
|
922
922
|
}
|
|
923
|
-
var enc2, dec2,
|
|
923
|
+
var enc2, dec2, nmsInternalSnapshotToBase64, nmsInternalSnapshotFromBase64, unpack, wasmModuleCache;
|
|
924
924
|
var init_kernel_provider_wasm = __esm({
|
|
925
925
|
"../cloud/web-client/src/kernel_provider_wasm.ts"() {
|
|
926
926
|
"use strict";
|
|
@@ -930,12 +930,20 @@ var init_kernel_provider_wasm = __esm({
|
|
|
930
930
|
init_pack_auth_contract();
|
|
931
931
|
enc2 = new TextEncoder();
|
|
932
932
|
dec2 = new TextDecoder();
|
|
933
|
-
|
|
933
|
+
nmsInternalSnapshotToBase64 = (bytes) => {
|
|
934
|
+
if (typeof Buffer !== "undefined") {
|
|
935
|
+
return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString("base64");
|
|
936
|
+
}
|
|
934
937
|
let s = "";
|
|
935
|
-
for (let i = 0; i < bytes.length; i += 32768)
|
|
938
|
+
for (let i = 0; i < bytes.length; i += 32768) {
|
|
939
|
+
s += String.fromCharCode.apply(null, bytes.subarray(i, i + 32768));
|
|
940
|
+
}
|
|
936
941
|
return btoa(s);
|
|
937
942
|
};
|
|
938
|
-
|
|
943
|
+
nmsInternalSnapshotFromBase64 = (s) => {
|
|
944
|
+
if (typeof Buffer !== "undefined") return Buffer.from(s, "base64");
|
|
945
|
+
return Uint8Array.from(atob(s), (c) => c.charCodeAt(0));
|
|
946
|
+
};
|
|
939
947
|
unpack = (p) => {
|
|
940
948
|
const v = typeof p === "bigint" ? p : BigInt(p);
|
|
941
949
|
return { ptr: Number(v >> 32n), len: Number(v & 0xffffffffn) };
|
|
@@ -7430,7 +7438,7 @@ var init_src = __esm({
|
|
|
7430
7438
|
};
|
|
7431
7439
|
ownedRecoveryScope = (principal2) => `${ownedKeyObject(principal2)}#${OWNED_RECOVERY_RELATION}`;
|
|
7432
7440
|
ownedRecoveryPolicyId = (principal2) => `nomos-owned-recovery-policy:${ownedKeyObject(principal2).slice("nomos-owned-principal:".length)}`;
|
|
7433
|
-
sleep = (ms) => new Promise((
|
|
7441
|
+
sleep = (ms) => new Promise((resolve8) => setTimeout(resolve8, ms));
|
|
7434
7442
|
OFFER_TIMEOUT_MS = 2e4;
|
|
7435
7443
|
DIRECT_OFFER_PENDING_MS = 45e3;
|
|
7436
7444
|
OID40_RE = /^[0-9a-f]{40}$/i;
|
|
@@ -7494,7 +7502,7 @@ function makeGitFs2(preopen, mount, { File: File4, Directory: Directory4 }) {
|
|
|
7494
7502
|
const rel = p.slice(mount.length + 1).replace(/\/+$/, "");
|
|
7495
7503
|
return rel === "" ? [] : rel.split("/");
|
|
7496
7504
|
}
|
|
7497
|
-
function
|
|
7505
|
+
function resolve8(ps) {
|
|
7498
7506
|
let cur = root;
|
|
7499
7507
|
for (const part of ps) {
|
|
7500
7508
|
if (!isDir(cur)) return null;
|
|
@@ -7504,11 +7512,11 @@ function makeGitFs2(preopen, mount, { File: File4, Directory: Directory4 }) {
|
|
|
7504
7512
|
}
|
|
7505
7513
|
return cur;
|
|
7506
7514
|
}
|
|
7507
|
-
const parent = (ps) =>
|
|
7515
|
+
const parent = (ps) => resolve8(ps.slice(0, -1));
|
|
7508
7516
|
const leaf = (ps) => ps[ps.length - 1];
|
|
7509
7517
|
const promises = {
|
|
7510
7518
|
async readFile(p, opts) {
|
|
7511
|
-
const n =
|
|
7519
|
+
const n = resolve8(parts(p));
|
|
7512
7520
|
if (n === null) throw fsErr2("ENOENT", p);
|
|
7513
7521
|
if (isDir(n)) throw fsErr2("EISDIR", p);
|
|
7514
7522
|
const data = n.data ?? new Uint8Array(0);
|
|
@@ -7527,7 +7535,7 @@ function makeGitFs2(preopen, mount, { File: File4, Directory: Directory4 }) {
|
|
|
7527
7535
|
if (!isDir(par) || !par.contents.delete(leaf(ps))) throw fsErr2("ENOENT", p);
|
|
7528
7536
|
},
|
|
7529
7537
|
async readdir(p) {
|
|
7530
|
-
const n =
|
|
7538
|
+
const n = resolve8(parts(p));
|
|
7531
7539
|
if (n === null) throw fsErr2("ENOENT", p);
|
|
7532
7540
|
if (!isDir(n)) throw fsErr2("ENOTDIR", p);
|
|
7533
7541
|
return [...n.contents.keys()];
|
|
@@ -7547,7 +7555,7 @@ function makeGitFs2(preopen, mount, { File: File4, Directory: Directory4 }) {
|
|
|
7547
7555
|
return promises.lstat(p);
|
|
7548
7556
|
},
|
|
7549
7557
|
async lstat(p) {
|
|
7550
|
-
const n =
|
|
7558
|
+
const n = resolve8(parts(p));
|
|
7551
7559
|
if (n === null) throw fsErr2("ENOENT", p);
|
|
7552
7560
|
const dir = isDir(n);
|
|
7553
7561
|
return {
|
|
@@ -7739,11 +7747,16 @@ async function pushPack(remote, headers = {}, { updates = [], pack = null } = {}
|
|
|
7739
7747
|
});
|
|
7740
7748
|
cmds.push(FLUSH);
|
|
7741
7749
|
const body = concatBytes([...cmds, pack && pack.length ? pack : EMPTY_PACK]);
|
|
7742
|
-
|
|
7743
|
-
|
|
7744
|
-
|
|
7745
|
-
|
|
7746
|
-
|
|
7750
|
+
let r;
|
|
7751
|
+
try {
|
|
7752
|
+
r = await fetch(`${remote}/git-receive-pack`, {
|
|
7753
|
+
method: "POST",
|
|
7754
|
+
headers: { "content-type": "application/x-git-receive-pack-request", ...headers },
|
|
7755
|
+
body
|
|
7756
|
+
});
|
|
7757
|
+
} catch (error) {
|
|
7758
|
+
throw new Error(`receive-pack transport failed (${body.byteLength} bytes): ${String(error)}`, { cause: error });
|
|
7759
|
+
}
|
|
7747
7760
|
const txt = dec5.decode(new Uint8Array(await r.arrayBuffer()));
|
|
7748
7761
|
const unpacked = /unpack ok/.test(txt);
|
|
7749
7762
|
const everyRefOk = updates.every((u) => new RegExp(`ok ${u.ref.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`).test(txt));
|
|
@@ -9301,7 +9314,12 @@ async function custodyFetch(eng, ws, ledger, { remoteRef = "refs/heads/main", lo
|
|
|
9301
9314
|
async function custodyPush(eng, ws, ledger, { localRef = null, remoteRef, del = false, pointer = false, newOid = null }) {
|
|
9302
9315
|
const headers = ledger.headers || {};
|
|
9303
9316
|
const remoteRefFull = fullRef(remoteRef);
|
|
9304
|
-
|
|
9317
|
+
let remote;
|
|
9318
|
+
try {
|
|
9319
|
+
remote = await lsRefs(ledger.remote, headers, { service: "git-receive-pack", prefix: remoteRefFull });
|
|
9320
|
+
} catch (error) {
|
|
9321
|
+
throw new Error(`custody receive-pack advertisement failed for ${remoteRefFull}: ${String(error)}`, { cause: error });
|
|
9322
|
+
}
|
|
9305
9323
|
const oldOid = remote[remoteRefFull] || ZERO_OID;
|
|
9306
9324
|
if (del) {
|
|
9307
9325
|
if (oldOid === ZERO_OID) return;
|
|
@@ -9315,14 +9333,21 @@ async function custodyPush(eng, ws, ledger, { localRef = null, remoteRef, del =
|
|
|
9315
9333
|
pack = oldOid !== ZERO_OID ? packDelta(eng, ws, oldOid, tgt) : null;
|
|
9316
9334
|
if (!pack) pack = packDelta(eng, ws, "", tgt);
|
|
9317
9335
|
}
|
|
9318
|
-
|
|
9336
|
+
const packBytes = pack?.byteLength ?? 0;
|
|
9337
|
+
try {
|
|
9338
|
+
return await pushVia(ledger, () => pushPack(ledger.remote, headers, { updates: [{ ref: remoteRefFull, oldOid, newOid: tgt }], pack }));
|
|
9339
|
+
} catch (error) {
|
|
9340
|
+
throw new Error(`custody receive-pack push failed for ${remoteRefFull} (${packBytes} pack bytes): ${String(error)}`, { cause: error });
|
|
9341
|
+
}
|
|
9319
9342
|
}
|
|
9320
9343
|
async function commitAndPush(eng, ws, ledger) {
|
|
9321
9344
|
try {
|
|
9322
9345
|
await custodyPush(eng, ws, ledger, { remoteRef: "refs/heads/main" });
|
|
9323
9346
|
} catch (e) {
|
|
9324
9347
|
unmount(eng, ws);
|
|
9325
|
-
|
|
9348
|
+
const cause = e instanceof Error ? e.cause : void 0;
|
|
9349
|
+
const detail = cause === void 0 ? String(e) : `${e}; cause: ${String(cause)}`;
|
|
9350
|
+
throw new Error(`ledger push failed \u2014 write NOT durable, rolled back to ledger: ${detail}`, { cause: e });
|
|
9326
9351
|
}
|
|
9327
9352
|
}
|
|
9328
9353
|
async function pushShape(eng, ws, ledger) {
|
|
@@ -11216,7 +11241,7 @@ async function waitForWorkspaceMain(cloud, workspace, timeoutMs = 3e4) {
|
|
|
11216
11241
|
while (Date.now() < deadline) {
|
|
11217
11242
|
const head = await workspaceMainHead(cloud, workspace);
|
|
11218
11243
|
if (head !== void 0) return head;
|
|
11219
|
-
await new Promise((
|
|
11244
|
+
await new Promise((resolve8) => setTimeout(resolve8, 250));
|
|
11220
11245
|
}
|
|
11221
11246
|
return void 0;
|
|
11222
11247
|
}
|
|
@@ -11310,7 +11335,7 @@ async function ensureSovereignHome(opts = {}) {
|
|
|
11310
11335
|
const deadline = Date.now() + 3e4;
|
|
11311
11336
|
while (Date.now() < deadline) {
|
|
11312
11337
|
if (await fetch(`${cloud}/v2/workspaces/${encodeURIComponent(home)}`).then((r) => r.ok).catch(() => false)) break;
|
|
11313
|
-
await new Promise((
|
|
11338
|
+
await new Promise((resolve8) => setTimeout(resolve8, 250));
|
|
11314
11339
|
}
|
|
11315
11340
|
if (!await fetch(`${cloud}/v2/workspaces/${encodeURIComponent(home)}`).then((r) => r.ok).catch(() => false)) {
|
|
11316
11341
|
throw new Error(`Nomos admitted the birth of '${home}' but its custody did not become readable`);
|
|
@@ -11358,7 +11383,7 @@ async function ensureSovereignHome(opts = {}) {
|
|
|
11358
11383
|
return typeof leaf?.verifiedVia === "string" && leaf.verifiedVia.length > 0;
|
|
11359
11384
|
}).catch(() => false);
|
|
11360
11385
|
if (visible) break;
|
|
11361
|
-
await new Promise((
|
|
11386
|
+
await new Promise((resolve8) => setTimeout(resolve8, 250));
|
|
11362
11387
|
}
|
|
11363
11388
|
if (!visible) throw new Error(`the session home's verified device enrollment did not become readable`);
|
|
11364
11389
|
}
|
|
@@ -13414,7 +13439,13 @@ function discoverDeployJson(cwd, explicit) {
|
|
|
13414
13439
|
if (!existsSync4(buildDir)) {
|
|
13415
13440
|
throw new Error("no build/ directory \u2014 run `githolon compile` first (or pass --file <path>)");
|
|
13416
13441
|
}
|
|
13417
|
-
const
|
|
13442
|
+
const files = readdirSync3(buildDir);
|
|
13443
|
+
const applications = files.filter((f) => f.endsWith(".application.usda"));
|
|
13444
|
+
if (applications.length === 1) return join5(buildDir, applications[0]);
|
|
13445
|
+
if (applications.length > 1) {
|
|
13446
|
+
throw new Error(`multiple application stages in build/ (${applications.join(", ")}) \u2014 pass --file <path>`);
|
|
13447
|
+
}
|
|
13448
|
+
const bodies = files.filter((f) => f.endsWith(".deploy.json"));
|
|
13418
13449
|
if (bodies.length === 0) {
|
|
13419
13450
|
throw new Error("no build/*.deploy.json \u2014 run `githolon compile` first (or pass --file <path>)");
|
|
13420
13451
|
}
|
|
@@ -13668,12 +13699,11 @@ async function waitForDurableMainAdvance(cloud, ws, previousHead, opts = {}) {
|
|
|
13668
13699
|
while (Date.now() < deadline) {
|
|
13669
13700
|
const head = await durableMainHead(cloud, ws, fetchImpl);
|
|
13670
13701
|
if (head !== void 0 && head !== previousHead) return head;
|
|
13671
|
-
await new Promise((
|
|
13702
|
+
await new Promise((resolve8) => setTimeout(resolve8, pollMs));
|
|
13672
13703
|
}
|
|
13673
13704
|
return void 0;
|
|
13674
13705
|
}
|
|
13675
13706
|
async function deploy2(ws, opts) {
|
|
13676
|
-
const cloud = cloudBase(opts.cloud);
|
|
13677
13707
|
let file;
|
|
13678
13708
|
try {
|
|
13679
13709
|
file = discoverDeployJson(process.cwd(), opts.file);
|
|
@@ -13681,6 +13711,31 @@ async function deploy2(ws, opts) {
|
|
|
13681
13711
|
err4(e.message);
|
|
13682
13712
|
return 1;
|
|
13683
13713
|
}
|
|
13714
|
+
if (file.endsWith(".application.usda")) {
|
|
13715
|
+
let application;
|
|
13716
|
+
try {
|
|
13717
|
+
const { applicationDeploymentPlan } = await import("@githolon/dsl/application-composition");
|
|
13718
|
+
application = applicationDeploymentPlan(file);
|
|
13719
|
+
} catch (error) {
|
|
13720
|
+
err4(`application deployment refused: ${error.message}`);
|
|
13721
|
+
return 1;
|
|
13722
|
+
}
|
|
13723
|
+
out4(`deploying ${application.application} from ${file.split("/").pop()} \u2014 topology comes from OpenUSD`);
|
|
13724
|
+
for (const pkg of application.packages) {
|
|
13725
|
+
out4(` ${pkg.placement === "payload" ? "payload" : "reference"} ${pkg.packageName}`);
|
|
13726
|
+
const code = await deployPackage(ws, opts, pkg.deployPath, pkg.placement);
|
|
13727
|
+
if (code !== 0) {
|
|
13728
|
+
err4(`application '${application.application}' stopped at ${pkg.packageName}; later packages were not attempted`);
|
|
13729
|
+
return code;
|
|
13730
|
+
}
|
|
13731
|
+
}
|
|
13732
|
+
out4(`\u2713 application ${application.application} deployed from its OpenUSD composition`);
|
|
13733
|
+
return 0;
|
|
13734
|
+
}
|
|
13735
|
+
return deployPackage(ws, opts, file, "auto");
|
|
13736
|
+
}
|
|
13737
|
+
async function deployPackage(ws, opts, file, placement) {
|
|
13738
|
+
const cloud = cloudBase(opts.cloud);
|
|
13684
13739
|
const fileName = file.split("/").pop();
|
|
13685
13740
|
try {
|
|
13686
13741
|
const { ensureApplicationWorkspace: ensureApplicationWorkspace2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
@@ -13742,9 +13797,16 @@ async function deploy2(ws, opts) {
|
|
|
13742
13797
|
);
|
|
13743
13798
|
return 1;
|
|
13744
13799
|
}
|
|
13745
|
-
let expectsPending = plan !== void 0 && plan.predecessorCandidates.length === 1 && !plan.idempotent;
|
|
13800
|
+
let expectsPending = placement === "payload" || plan !== void 0 && plan.predecessorCandidates.length === 1 && !plan.idempotent;
|
|
13746
13801
|
const principal2 = opts.principal ?? activePrincipal();
|
|
13747
13802
|
const signed = opts.principal !== void 0 || principal2 !== void 0 && getDeviceKey(principal2) !== void 0;
|
|
13803
|
+
if (placement === "payload" && !signed) {
|
|
13804
|
+
err4(
|
|
13805
|
+
`application payload '${fileName}' must be staged by a signed principal; the unsigned package lane cannot promise that child law stays inactive on the platform workspace`
|
|
13806
|
+
);
|
|
13807
|
+
err4(` run githolon login --agent and enroll/import that principal's device key, then deploy again`);
|
|
13808
|
+
return 1;
|
|
13809
|
+
}
|
|
13748
13810
|
let phaseSuffix = "";
|
|
13749
13811
|
let deployedHash;
|
|
13750
13812
|
if (signed) {
|
|
@@ -17366,7 +17428,11 @@ var init_home = __esm({
|
|
|
17366
17428
|
workspaceName: t.string().merge(Lww),
|
|
17367
17429
|
/** ISO-8601, caller-stamped (determinism — no clock in the plan). */
|
|
17368
17430
|
bornAt: t.string().merge(Lww)
|
|
17369
|
-
|
|
17431
|
+
// The group's genesis seats its controller in OWNED_READ_RELATION below. Declaring that same capability
|
|
17432
|
+
// here makes the law's coarse pack gate recognise the seat, so a newly enrolled device can clone its own
|
|
17433
|
+
// receiving group before any tenant records or tenant-authored grants exist. This remains ordinary,
|
|
17434
|
+
// replayable Zanzibar state: revocation removes the seat; there is no kernel-level founder bypass.
|
|
17435
|
+
}, { cap: 1 }).readableBy(OWNED_READ_RELATION2);
|
|
17370
17436
|
ReceivingGroupPolicy = aggregate("NomosInternalReceivingGroupPolicy7c1f5e", {
|
|
17371
17437
|
additionalDevice: t.string().merge(Lww),
|
|
17372
17438
|
revocation: t.string().merge(Lww),
|
|
@@ -17386,7 +17452,7 @@ var init_home = __esm({
|
|
|
17386
17452
|
allow: [user()]
|
|
17387
17453
|
});
|
|
17388
17454
|
seedReceivingGroup = directive("nomosInternalSeedReceivingGroup7c1f5e").ensures(ReceivingGroup).payload(z9.object({ principal: z9.string().min(1), workspaceName: z9.string().min(1), bornAt: z9.string().min(1) })).plan((p) => writeReceivingGroup(p));
|
|
17389
|
-
receivingGroupNameBindsPrincipal = workspaceInvariant("ReceivingGroupNameBindsPrincipal").on("nomosInternalSeedReceivingGroup7c1f5e").reads(() => [refAs("group", "NomosInternalReceivingGroup7c1f5e", RECEIVING_GROUP_ID)]).assert(({ group: group2 }) => {
|
|
17455
|
+
receivingGroupNameBindsPrincipal = workspaceInvariant("ReceivingGroupNameBindsPrincipal").on("nomosInternalSeedReceivingGroup7c1f5e").reads(() => [refAs("group", "NomosInternalReceivingGroup7c1f5e", RECEIVING_GROUP_ID)]).declassify("the receiving-group address is a public hash of its stable principal; refusing a mismatch reveals no private field").assert(({ group: group2 }) => {
|
|
17390
17456
|
const g = group2 ?? {};
|
|
17391
17457
|
const expected = RECEIVING_GROUP_NAME_PREFIX + nomos.sha256(String(g.principal ?? "")).slice(0, RECEIVING_GROUP_NAME_HASH_LEN);
|
|
17392
17458
|
return g.workspaceName === expected ? { accept: true } : { reject: "a receiving group's workspace name must hash its stable principal" };
|
|
@@ -17395,7 +17461,7 @@ var init_home = __esm({
|
|
|
17395
17461
|
refAs("group", "NomosInternalReceivingGroup7c1f5e", RECEIVING_GROUP_ID),
|
|
17396
17462
|
refAs("policy", "NomosInternalReceivingGroupPolicy7c1f5e", RECEIVING_GROUP_POLICY_ID)
|
|
17397
17463
|
];
|
|
17398
|
-
receivingGroupRejectsKeylessAdditionalDevice = workspaceInvariant("ReceivingGroupRejectsKeylessAdditionalDevice").on("enrollFirstDevice").reads(receivingGroupPolicyRefs).assert(({ group: group2 }) => typeof group2?.principal !== "string" || group2.principal.length === 0 ? { accept: true } : { reject: "receiving-group-additional-device-requires-current-device-or-guardian" });
|
|
17464
|
+
receivingGroupRejectsKeylessAdditionalDevice = workspaceInvariant("ReceivingGroupRejectsKeylessAdditionalDevice").on("enrollFirstDevice").reads(receivingGroupPolicyRefs).declassify("device enrollment deliberately reveals that this receiving group has already completed first-device bootstrap").assert(({ group: group2 }) => typeof group2?.principal !== "string" || group2.principal.length === 0 ? { accept: true } : { reject: "receiving-group-additional-device-requires-current-device-or-guardian" });
|
|
17399
17465
|
receivingGroupAdditionalDeviceFollowsPolicy = workspaceInvariant("ReceivingGroupAdditionalDeviceFollowsPolicy").on("enrollSignerSelf").reads(receivingGroupPolicyRefs).declassify("device lifecycle policy intentionally branches on principal_verified").assert(({ group: group2, policy }, ctx) => {
|
|
17400
17466
|
if (typeof group2?.principal !== "string" || group2.principal.length === 0) return { accept: true };
|
|
17401
17467
|
const p = policy;
|
|
@@ -18918,6 +18984,74 @@ var init_mcp = __esm({
|
|
|
18918
18984
|
}
|
|
18919
18985
|
});
|
|
18920
18986
|
|
|
18987
|
+
// src/test.ts
|
|
18988
|
+
var test_exports = {};
|
|
18989
|
+
__export(test_exports, {
|
|
18990
|
+
resolveTestCloudEntry: () => resolveTestCloudEntry,
|
|
18991
|
+
runDartTests: () => runDartTests
|
|
18992
|
+
});
|
|
18993
|
+
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
18994
|
+
import { existsSync as existsSync12 } from "node:fs";
|
|
18995
|
+
import { dirname as dirname8, resolve as resolve5 } from "node:path";
|
|
18996
|
+
import { fileURLToPath } from "node:url";
|
|
18997
|
+
function resolveTestCloudEntry(options = {}) {
|
|
18998
|
+
const cwd = options.cwd ?? process.cwd();
|
|
18999
|
+
const environment = options.environment ?? process.env;
|
|
19000
|
+
const explicit = environment.NOMOS_TEST_CLOUD_ENTRY;
|
|
19001
|
+
if (explicit !== void 0) {
|
|
19002
|
+
const candidate = resolve5(cwd, explicit);
|
|
19003
|
+
if (!existsSync12(candidate)) {
|
|
19004
|
+
throw new Error(`NOMOS_TEST_CLOUD_ENTRY does not exist: ${candidate}`);
|
|
19005
|
+
}
|
|
19006
|
+
return candidate;
|
|
19007
|
+
}
|
|
19008
|
+
const here = dirname8(fileURLToPath(options.moduleUrl ?? import.meta.url));
|
|
19009
|
+
const candidates = [
|
|
19010
|
+
resolve5(here, "dev-server.mjs"),
|
|
19011
|
+
resolve5(here, "../dist/dev-server.mjs"),
|
|
19012
|
+
resolve5(here, "../../cloud/dev-server/server.ts"),
|
|
19013
|
+
resolve5(cwd, "cloud/dev-server/server.ts")
|
|
19014
|
+
];
|
|
19015
|
+
const server = candidates.find((candidate) => existsSync12(candidate));
|
|
19016
|
+
if (server === void 0) {
|
|
19017
|
+
throw new Error("the bundled local Nomos cloud is missing \u2014 rebuild or reinstall githolon");
|
|
19018
|
+
}
|
|
19019
|
+
return server;
|
|
19020
|
+
}
|
|
19021
|
+
function runDartTests(args) {
|
|
19022
|
+
const diagnostics = args.includes("--diagnostics");
|
|
19023
|
+
const forwarded = args.filter((arg) => arg !== "--diagnostics");
|
|
19024
|
+
let serverEntry;
|
|
19025
|
+
try {
|
|
19026
|
+
serverEntry = resolveTestCloudEntry();
|
|
19027
|
+
} catch (error) {
|
|
19028
|
+
process.stderr.write(`error: ${error instanceof Error ? error.message : error}
|
|
19029
|
+
`);
|
|
19030
|
+
return 1;
|
|
19031
|
+
}
|
|
19032
|
+
process.stdout.write("githolon test \u2014 generated application scenarios with real local custody\n");
|
|
19033
|
+
const result = spawnSync6("flutter", ["test", ...forwarded], {
|
|
19034
|
+
cwd: process.cwd(),
|
|
19035
|
+
stdio: "inherit",
|
|
19036
|
+
env: {
|
|
19037
|
+
...process.env,
|
|
19038
|
+
NOMOS_TEST_CLOUD_ENTRY: serverEntry,
|
|
19039
|
+
...diagnostics ? { NOMOS_TEST_DIAGNOSTICS: "1" } : {}
|
|
19040
|
+
}
|
|
19041
|
+
});
|
|
19042
|
+
if (result.error !== void 0) {
|
|
19043
|
+
process.stderr.write(`error: could not run Flutter tests: ${result.error.message}
|
|
19044
|
+
`);
|
|
19045
|
+
return 1;
|
|
19046
|
+
}
|
|
19047
|
+
return result.status ?? 1;
|
|
19048
|
+
}
|
|
19049
|
+
var init_test = __esm({
|
|
19050
|
+
"src/test.ts"() {
|
|
19051
|
+
"use strict";
|
|
19052
|
+
}
|
|
19053
|
+
});
|
|
19054
|
+
|
|
18921
19055
|
// src/harness.ts
|
|
18922
19056
|
var harness_exports = {};
|
|
18923
19057
|
__export(harness_exports, {
|
|
@@ -18925,7 +19059,7 @@ __export(harness_exports, {
|
|
|
18925
19059
|
harnessInstall: () => harnessInstall,
|
|
18926
19060
|
looksLikeStaleRuntime: () => looksLikeStaleRuntime
|
|
18927
19061
|
});
|
|
18928
|
-
import { existsSync as
|
|
19062
|
+
import { existsSync as existsSync13, readFileSync as readFileSync13, writeFileSync as writeFileSync8 } from "node:fs";
|
|
18929
19063
|
import { join as join14 } from "node:path";
|
|
18930
19064
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
18931
19065
|
function looksLikeStaleRuntime(msg) {
|
|
@@ -18942,7 +19076,7 @@ async function harnessInstall(opts) {
|
|
|
18942
19076
|
`);
|
|
18943
19077
|
const wasmFile = join14(runtimeDir, "holon-testmint.wasm");
|
|
18944
19078
|
const pkgsFile = join14(runtimeDir, "packages.json");
|
|
18945
|
-
if (!
|
|
19079
|
+
if (!existsSync13(wasmFile) || !existsSync13(pkgsFile)) {
|
|
18946
19080
|
die(
|
|
18947
19081
|
`test runtime cache missing at ${runtimeDir} (holon-testmint.wasm + packages.json). Warm it once with a \`githolon\` run (it fetches + caches the runtime), then re-run offline.`
|
|
18948
19082
|
);
|
|
@@ -18979,7 +19113,7 @@ async function harnessInstall(opts) {
|
|
|
18979
19113
|
const lawHashes = [];
|
|
18980
19114
|
const expectedDomainLaw = /* @__PURE__ */ new Map();
|
|
18981
19115
|
for (const p of deployPaths) {
|
|
18982
|
-
if (!
|
|
19116
|
+
if (!existsSync13(p)) die(`deploy JSON not found: ${p} \u2014 run \`npx githolon compile\` first`);
|
|
18983
19117
|
const deploy3 = JSON.parse(readFileSync13(p, "utf8"));
|
|
18984
19118
|
const usda = deploy3.packageUsda;
|
|
18985
19119
|
if (typeof usda !== "string" || !usda.startsWith("#usda")) die(`${p} has no #usda packageUsda`);
|
|
@@ -19043,11 +19177,11 @@ var doctor_exports = {};
|
|
|
19043
19177
|
__export(doctor_exports, {
|
|
19044
19178
|
doctor: () => doctor
|
|
19045
19179
|
});
|
|
19046
|
-
import { existsSync as
|
|
19180
|
+
import { existsSync as existsSync14, readFileSync as readFileSync14 } from "node:fs";
|
|
19047
19181
|
function readLocalCompat(cwd, file) {
|
|
19048
19182
|
try {
|
|
19049
19183
|
const path2 = discoverDeployJson(cwd, file);
|
|
19050
|
-
if (!
|
|
19184
|
+
if (!existsSync14(path2)) return void 0;
|
|
19051
19185
|
const body = JSON.parse(readFileSync14(path2, "utf8"));
|
|
19052
19186
|
return body.nomosCompat;
|
|
19053
19187
|
} catch {
|
|
@@ -22328,8 +22462,8 @@ var scene_exports = {};
|
|
|
22328
22462
|
__export(scene_exports, {
|
|
22329
22463
|
scene: () => scene
|
|
22330
22464
|
});
|
|
22331
|
-
import { existsSync as
|
|
22332
|
-
import { join as join15, resolve as
|
|
22465
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync6, writeFileSync as writeFileSync9 } from "node:fs";
|
|
22466
|
+
import { join as join15, resolve as resolve6 } from "node:path";
|
|
22333
22467
|
import { createHash as createHash6 } from "node:crypto";
|
|
22334
22468
|
import git3 from "isomorphic-git";
|
|
22335
22469
|
async function walkChain2(eng, ws) {
|
|
@@ -22350,8 +22484,8 @@ async function projectOnce(cloud, target, isDir, name) {
|
|
|
22350
22484
|
const { eng } = await holonEngine(cloud, void 0, "githolon-scene");
|
|
22351
22485
|
const SOURCE3 = "source";
|
|
22352
22486
|
if (isDir) {
|
|
22353
|
-
const gitDir =
|
|
22354
|
-
if (!
|
|
22487
|
+
const gitDir = existsSync15(join15(target, ".git")) ? join15(target, ".git") : target;
|
|
22488
|
+
if (!existsSync15(join15(gitDir, "HEAD"))) throw new Error(`${target} is not a git repo (no HEAD)`);
|
|
22355
22489
|
await mountFresh(eng, SOURCE3);
|
|
22356
22490
|
eng.preopen.dir.contents.get("ws").contents.get(SOURCE3).contents.set("nomos.git", readTreeFromDisk(gitDir));
|
|
22357
22491
|
} else {
|
|
@@ -22410,9 +22544,9 @@ async function projectOnce(cloud, target, isDir, name) {
|
|
|
22410
22544
|
}
|
|
22411
22545
|
async function scene(target, opts) {
|
|
22412
22546
|
const cloud = cloudBase(opts.cloud);
|
|
22413
|
-
const isDir =
|
|
22414
|
-
const name = isDir ? (
|
|
22415
|
-
out11(`scene \u2014 ${name} (${isDir ?
|
|
22547
|
+
const isDir = existsSync15(target) || target.includes("/") || target.startsWith(".");
|
|
22548
|
+
const name = isDir ? (resolve6(target).split("/").filter(Boolean).pop() ?? "scene").replace(/\.git$/, "") : target;
|
|
22549
|
+
out11(`scene \u2014 ${name} (${isDir ? resolve6(target) : `${cloud} :: ${target}`})`);
|
|
22416
22550
|
let first2, second;
|
|
22417
22551
|
try {
|
|
22418
22552
|
first2 = await projectOnce(cloud, target, isDir, name);
|
|
@@ -22430,7 +22564,7 @@ async function scene(target, opts) {
|
|
|
22430
22564
|
err11(`the emitted stage violates the portable profile: ${violations.join("; ")}`);
|
|
22431
22565
|
return 1;
|
|
22432
22566
|
}
|
|
22433
|
-
const outDir =
|
|
22567
|
+
const outDir = resolve6(opts.out ?? join15("scene", name));
|
|
22434
22568
|
mkdirSync6(outDir, { recursive: true });
|
|
22435
22569
|
const usdaPath = join15(outDir, `${name}.usda`);
|
|
22436
22570
|
const usdzPath = join15(outDir, `${name}.usdz`);
|
|
@@ -22521,12 +22655,12 @@ var init_dlq = __esm({
|
|
|
22521
22655
|
});
|
|
22522
22656
|
|
|
22523
22657
|
// src/cli.ts
|
|
22524
|
-
import { existsSync as
|
|
22525
|
-
import { spawn as spawn2, spawnSync as
|
|
22658
|
+
import { existsSync as existsSync16, readdirSync as readdirSync6, readFileSync as readFileSync15 } from "node:fs";
|
|
22659
|
+
import { spawn as spawn2, spawnSync as spawnSync7 } from "node:child_process";
|
|
22526
22660
|
import { createHash as createHash7 } from "node:crypto";
|
|
22527
22661
|
import { createRequire as createRequire3 } from "node:module";
|
|
22528
|
-
import { dirname as
|
|
22529
|
-
import { pathToFileURL as pathToFileURL5, fileURLToPath } from "node:url";
|
|
22662
|
+
import { dirname as dirname9, join as join16, resolve as resolve7 } from "node:path";
|
|
22663
|
+
import { pathToFileURL as pathToFileURL5, fileURLToPath as fileURLToPath2 } from "node:url";
|
|
22530
22664
|
|
|
22531
22665
|
// src/generate.ts
|
|
22532
22666
|
import { mkdirSync, existsSync, writeFileSync } from "node:fs";
|
|
@@ -25383,7 +25517,8 @@ var HELP = {
|
|
|
25383
25517
|
["[config]", "package or application authoring input (default: nomos.package.mjs)"],
|
|
25384
25518
|
["--require-usdcat", "refuse unless stock OpenUSD flattens to the same canonical law"],
|
|
25385
25519
|
["--compact", "emit the compact executable package envelope"],
|
|
25386
|
-
["--analyze", "run dart analyze on generated Dart packages"]
|
|
25520
|
+
["--analyze", "run dart analyze on generated Dart packages"],
|
|
25521
|
+
["--no-mount-check", "emit without the CLI runtime mountability gate (framework/CI escape hatch)"]
|
|
25387
25522
|
],
|
|
25388
25523
|
examples: ["githolon compile", "githolon compile nomos.application.mjs --require-usdcat"]
|
|
25389
25524
|
},
|
|
@@ -25392,6 +25527,15 @@ var HELP = {
|
|
|
25392
25527
|
what: "Run the application-wide proof GENERATED from your business law. By default it opens a blank\nlocal application through the same generated API tenant code uses, executes its business journey,\nsynchronizes, reopens, and reads the saved records back. --live runs that same business proof against\nNomos Cloud; identity, provisioning, persistence, and cleanup remain inside Nomos. ALL GREEN or it names the jam.",
|
|
25393
25528
|
examples: ["githolon proof", "githolon proof build/co2.proof.mts", "githolon proof --live"]
|
|
25394
25529
|
},
|
|
25530
|
+
test: {
|
|
25531
|
+
usage: "githolon test [test-file-or-flutter-test-flags] [--diagnostics]",
|
|
25532
|
+
what: "Run generated Dart application scenarios through Flutter with the real local Nomos custody plane.\nThe server rides inside githolon; connected scenarios, partitions, restarts and fresh reinstalls need no\nserver path, environment variables, certificates, workspace setup or separate application state.",
|
|
25533
|
+
flags: [
|
|
25534
|
+
["[test file/flags]", "forwarded to flutter test"],
|
|
25535
|
+
["--diagnostics", "show framework/cloud diagnostics when investigating a failing scenario"]
|
|
25536
|
+
],
|
|
25537
|
+
examples: ["githolon test", "githolon test test/catalogue_birth_test.dart", "githolon test --diagnostics"]
|
|
25538
|
+
},
|
|
25395
25539
|
dev: {
|
|
25396
25540
|
usage: "githolon dev [--port <n>] [--cloud <url>] [--once]",
|
|
25397
25541
|
what: "THE INNER LOOP: watch domains/ + nomos.package.mjs, recompile on save, install the law into\na LOCAL holon (the same engine plane the cloud edge runs \u2014 your data SURVIVES law edits),\nrerun the generated local business checks, and serve the generated application on localhost.\nFully offline after the first runtime fetch (~/.holon/runtime).",
|
|
@@ -25583,11 +25727,11 @@ var HELP = {
|
|
|
25583
25727
|
examples: ["githolon revoke creation 32c7100e-\u2026", "githolon revoke admin 32c7100e-\u2026"]
|
|
25584
25728
|
},
|
|
25585
25729
|
deploy: {
|
|
25586
|
-
usage: "githolon deploy [<ws>] [--as <uid>] [--file <deploy.json>] [--cloud <url>] [--target <name>]",
|
|
25587
|
-
what: "
|
|
25730
|
+
usage: "githolon deploy [<ws>] [--as <uid>] [--file <application.usda|deploy.json>] [--cloud <url>] [--target <name>]",
|
|
25731
|
+
what: "Deploy the compiled application from its OpenUSD composition. Reference-only packages serve on\nthe application workspace; payload packages are staged for child birth and never made current there.\nFor a one-package project, the package deploy body remains the shorthand. There is one model lifecycle:\nthe first serving model becomes active; a successor stays Pending while the current model keeps serving,\nand the generated candidate client owns exact-history adoption. Re-deploying the same content hash is\nidempotent. With no <ws>, the project's workspace binding resolves it.",
|
|
25588
25732
|
flags: [
|
|
25589
25733
|
["--as <uid>", "attribute the deployment to this principal (needs its enrolled signing key)"],
|
|
25590
|
-
["--file <path>", "an
|
|
25734
|
+
["--file <path>", "an application USDA or package deploy body (default: build/*.application.usda, else the one deploy body)"],
|
|
25591
25735
|
["--target <name>", "pick among named targets (workspace: { dev: \u2026, prod: \u2026 })"],
|
|
25592
25736
|
["--cloud <url>", "target cloud"]
|
|
25593
25737
|
],
|
|
@@ -26121,6 +26265,7 @@ var USAGE = `githolon \u2014 model a business; Nomos owns the compute science
|
|
|
26121
26265
|
Start here:
|
|
26122
26266
|
githolon compile compile aggregates, birth, directives, and reads into law + a typed client
|
|
26123
26267
|
githolon proof run the generated business proof in the real local engine
|
|
26268
|
+
githolon test run generated Dart scenarios with real local custody
|
|
26124
26269
|
githolon dev watch, compile, and rerun that proof on every save
|
|
26125
26270
|
githolon check explain anything the law can already prove it would refuse
|
|
26126
26271
|
|
|
@@ -26246,17 +26391,17 @@ function isKind(s) {
|
|
|
26246
26391
|
function resolvedTsxCli() {
|
|
26247
26392
|
const resolvePkgDir = (name, fromDir) => {
|
|
26248
26393
|
try {
|
|
26249
|
-
return
|
|
26394
|
+
return dirname9(createRequire3(pathToFileURL5(join16(fromDir, "noop.js"))).resolve(`${name}/package.json`));
|
|
26250
26395
|
} catch {
|
|
26251
26396
|
return void 0;
|
|
26252
26397
|
}
|
|
26253
26398
|
};
|
|
26254
26399
|
const dslDir = (() => {
|
|
26255
26400
|
try {
|
|
26256
|
-
return
|
|
26401
|
+
return dirname9(createRequire3(pathToFileURL5(join16(process.cwd(), "noop.js"))).resolve("@githolon/dsl/package.json"));
|
|
26257
26402
|
} catch {
|
|
26258
26403
|
try {
|
|
26259
|
-
return
|
|
26404
|
+
return dirname9(createRequire3(import.meta.url).resolve("@githolon/dsl/package.json"));
|
|
26260
26405
|
} catch {
|
|
26261
26406
|
return void 0;
|
|
26262
26407
|
}
|
|
@@ -26270,24 +26415,24 @@ function resolvedTsxCli() {
|
|
|
26270
26415
|
}
|
|
26271
26416
|
async function runGeneratedApplicationProofLocally(proofPath) {
|
|
26272
26417
|
const deployPath = proofPath.replace(/\.proof\.mts$/, ".deploy.json");
|
|
26273
|
-
if (deployPath === proofPath || !
|
|
26418
|
+
if (deployPath === proofPath || !existsSync16(deployPath)) {
|
|
26274
26419
|
throw new Error(`generated application proof needs its sibling deploy artifact: ${deployPath}`);
|
|
26275
26420
|
}
|
|
26276
|
-
const here =
|
|
26421
|
+
const here = dirname9(fileURLToPath2(import.meta.url));
|
|
26277
26422
|
const serverCandidates = [
|
|
26278
|
-
|
|
26279
|
-
|
|
26280
|
-
|
|
26281
|
-
|
|
26423
|
+
resolve7(here, "dev-server.mjs"),
|
|
26424
|
+
resolve7(here, "../dist/dev-server.mjs"),
|
|
26425
|
+
resolve7(here, "../../cloud/dev-server/server.ts"),
|
|
26426
|
+
resolve7(process.cwd(), "cloud/dev-server/server.ts")
|
|
26282
26427
|
];
|
|
26283
|
-
const serverPath = serverCandidates.find((candidate) =>
|
|
26428
|
+
const serverPath = serverCandidates.find((candidate) => existsSync16(candidate));
|
|
26284
26429
|
if (serverPath === void 0) {
|
|
26285
26430
|
throw new Error("the bundled local Nomos cloud is missing \u2014 rebuild or reinstall githolon");
|
|
26286
26431
|
}
|
|
26287
26432
|
const candidateRuntime = process.env.NOMOS_CANDIDATE_RUNTIME ?? process.env.NOMOS_OFFLINE_RUNTIME;
|
|
26288
26433
|
const candidateTestMint = candidateRuntime === void 0 ? void 0 : join16(candidateRuntime, "holon-testmint.wasm");
|
|
26289
26434
|
const priorLocalWasm = process.env.NOMOS_LOCAL_WASM;
|
|
26290
|
-
if (candidateTestMint !== void 0 &&
|
|
26435
|
+
if (candidateTestMint !== void 0 && existsSync16(candidateTestMint)) process.env.NOMOS_LOCAL_WASM = candidateTestMint;
|
|
26291
26436
|
const module = await import(pathToFileURL5(serverPath).href);
|
|
26292
26437
|
if (typeof module.startGeneratedApplicationProofCloud !== "function") {
|
|
26293
26438
|
throw new Error("the bundled local Nomos cloud predates generated application execution \u2014 rebuild githolon");
|
|
@@ -26351,11 +26496,11 @@ async function runProof(args) {
|
|
|
26351
26496
|
const explicit = args.find((a, i) => !a.startsWith("--") && i !== domainValueIdx);
|
|
26352
26497
|
let proofPath;
|
|
26353
26498
|
if (explicit !== void 0) {
|
|
26354
|
-
proofPath =
|
|
26355
|
-
if (!
|
|
26499
|
+
proofPath = resolve7(process.cwd(), explicit);
|
|
26500
|
+
if (!existsSync16(proofPath)) return refuse(`proof not found: ${proofPath} \u2014 run \`githolon compile\` to (re)generate it`);
|
|
26356
26501
|
} else {
|
|
26357
26502
|
const buildDir = join16(process.cwd(), "build");
|
|
26358
|
-
if (!
|
|
26503
|
+
if (!existsSync16(buildDir)) {
|
|
26359
26504
|
return refuse("no build/ directory here \u2014 run `githolon compile` first (every compile generates build/<name>.proof.mts from your law)");
|
|
26360
26505
|
}
|
|
26361
26506
|
const proofs = readdirSync6(buildDir).filter((f) => f.endsWith(".proof.mts"));
|
|
@@ -26407,7 +26552,7 @@ async function runProof(args) {
|
|
|
26407
26552
|
const proofWorkspace = `nomos-proof-${proofIdentity}`;
|
|
26408
26553
|
const deployed = await deploy2(proofWorkspace, { principal: barePrincipal });
|
|
26409
26554
|
if (deployed !== 0) return refuse("proof --live: Nomos could not install the compiled business law into its isolated acceptance application");
|
|
26410
|
-
const r =
|
|
26555
|
+
const r = spawnSync7(process.execPath, [tsxCli, proofPath], {
|
|
26411
26556
|
stdio: "inherit",
|
|
26412
26557
|
cwd: process.cwd(),
|
|
26413
26558
|
env: {
|
|
@@ -26473,9 +26618,10 @@ async function main(argv) {
|
|
|
26473
26618
|
return 0;
|
|
26474
26619
|
}
|
|
26475
26620
|
if (argv[0] === "compile") {
|
|
26476
|
-
const
|
|
26621
|
+
const skipMountCheck = argv.includes("--no-mount-check");
|
|
26622
|
+
const status2 = runCompile(argv.slice(1).filter((arg) => arg !== "--no-mount-check"));
|
|
26477
26623
|
if (status2 !== 0) return status2;
|
|
26478
|
-
if (
|
|
26624
|
+
if (skipMountCheck) return status2;
|
|
26479
26625
|
try {
|
|
26480
26626
|
const { assertCompiledMountable: assertCompiledMountable2 } = await Promise.resolve().then(() => (init_mountability(), mountability_exports));
|
|
26481
26627
|
const { cloudBase: cloudBase2 } = await Promise.resolve().then(() => (init_cloud(), cloud_exports));
|
|
@@ -26516,6 +26662,10 @@ async function main(argv) {
|
|
|
26516
26662
|
if (argv[0] === "proof") {
|
|
26517
26663
|
return runProof(argv.slice(1));
|
|
26518
26664
|
}
|
|
26665
|
+
if (argv[0] === "test") {
|
|
26666
|
+
const { runDartTests: runDartTests2 } = await Promise.resolve().then(() => (init_test(), test_exports));
|
|
26667
|
+
return runDartTests2(argv.slice(1));
|
|
26668
|
+
}
|
|
26519
26669
|
if (argv[0] === "harness-install") {
|
|
26520
26670
|
const rest = argv.slice(1);
|
|
26521
26671
|
const pull = (flag) => {
|
|
@@ -26591,22 +26741,22 @@ usage: githolon cloud dev [--port <n>] [--data <dir>] [--ephemeral]
|
|
|
26591
26741
|
`);
|
|
26592
26742
|
return 1;
|
|
26593
26743
|
}
|
|
26594
|
-
const { spawnSync:
|
|
26595
|
-
const here =
|
|
26744
|
+
const { spawnSync: spawnSync8 } = await import("node:child_process");
|
|
26745
|
+
const here = dirname9(fileURLToPath2(import.meta.url));
|
|
26596
26746
|
const candidates = [
|
|
26597
|
-
|
|
26747
|
+
resolve7(here, "dev-server.mjs"),
|
|
26598
26748
|
// published: dist/dev-server.mjs
|
|
26599
|
-
|
|
26749
|
+
resolve7(here, "../../cloud/dev-server/server.mjs"),
|
|
26600
26750
|
// in-repo (tsx / unbuilt) fallbacks
|
|
26601
|
-
|
|
26602
|
-
|
|
26751
|
+
resolve7(here, "../../../cloud/dev-server/server.mjs"),
|
|
26752
|
+
resolve7(process.cwd(), "cloud/dev-server/server.mjs")
|
|
26603
26753
|
];
|
|
26604
|
-
const serverPath = candidates.find((p) =>
|
|
26754
|
+
const serverPath = candidates.find((p) => existsSync16(p));
|
|
26605
26755
|
if (!serverPath) {
|
|
26606
26756
|
process.stderr.write("error: dev-server not found \u2014 reinstall `githolon` or run `npm run build` in the cli package\n");
|
|
26607
26757
|
return 1;
|
|
26608
26758
|
}
|
|
26609
|
-
const r =
|
|
26759
|
+
const r = spawnSync8(process.execPath, [serverPath, ...argv.slice(2)], { stdio: "inherit" });
|
|
26610
26760
|
return r.status ?? 0;
|
|
26611
26761
|
}
|
|
26612
26762
|
if (argv[0] === "replay") {
|
package/dist/dev-server.mjs
CHANGED
|
@@ -268,11 +268,16 @@ async function pushPack(remote, headers = {}, { updates = [], pack = null } = {}
|
|
|
268
268
|
});
|
|
269
269
|
cmds.push(FLUSH);
|
|
270
270
|
const body = concatBytes([...cmds, pack && pack.length ? pack : EMPTY_PACK]);
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
271
|
+
let r;
|
|
272
|
+
try {
|
|
273
|
+
r = await fetch(`${remote}/git-receive-pack`, {
|
|
274
|
+
method: "POST",
|
|
275
|
+
headers: { "content-type": "application/x-git-receive-pack-request", ...headers },
|
|
276
|
+
body
|
|
277
|
+
});
|
|
278
|
+
} catch (error) {
|
|
279
|
+
throw new Error(`receive-pack transport failed (${body.byteLength} bytes): ${String(error)}`, { cause: error });
|
|
280
|
+
}
|
|
276
281
|
const txt = dec2.decode(new Uint8Array(await r.arrayBuffer()));
|
|
277
282
|
const unpacked = /unpack ok/.test(txt);
|
|
278
283
|
const everyRefOk = updates.every((u) => new RegExp(`ok ${u.ref.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`).test(txt));
|
|
@@ -878,7 +883,12 @@ async function custodyFetch(eng, ws, ledger, { remoteRef = "refs/heads/main", lo
|
|
|
878
883
|
async function custodyPush(eng, ws, ledger, { localRef = null, remoteRef, del = false, pointer = false, newOid = null }) {
|
|
879
884
|
const headers = ledger.headers || {};
|
|
880
885
|
const remoteRefFull = fullRef(remoteRef);
|
|
881
|
-
|
|
886
|
+
let remote;
|
|
887
|
+
try {
|
|
888
|
+
remote = await lsRefs(ledger.remote, headers, { service: "git-receive-pack", prefix: remoteRefFull });
|
|
889
|
+
} catch (error) {
|
|
890
|
+
throw new Error(`custody receive-pack advertisement failed for ${remoteRefFull}: ${String(error)}`, { cause: error });
|
|
891
|
+
}
|
|
882
892
|
const oldOid = remote[remoteRefFull] || ZERO_OID;
|
|
883
893
|
if (del) {
|
|
884
894
|
if (oldOid === ZERO_OID) return;
|
|
@@ -892,14 +902,21 @@ async function custodyPush(eng, ws, ledger, { localRef = null, remoteRef, del =
|
|
|
892
902
|
pack = oldOid !== ZERO_OID ? packDelta(eng, ws, oldOid, tgt) : null;
|
|
893
903
|
if (!pack) pack = packDelta(eng, ws, "", tgt);
|
|
894
904
|
}
|
|
895
|
-
|
|
905
|
+
const packBytes = pack?.byteLength ?? 0;
|
|
906
|
+
try {
|
|
907
|
+
return await pushVia(ledger, () => pushPack(ledger.remote, headers, { updates: [{ ref: remoteRefFull, oldOid, newOid: tgt }], pack }));
|
|
908
|
+
} catch (error) {
|
|
909
|
+
throw new Error(`custody receive-pack push failed for ${remoteRefFull} (${packBytes} pack bytes): ${String(error)}`, { cause: error });
|
|
910
|
+
}
|
|
896
911
|
}
|
|
897
912
|
async function commitAndPush(eng, ws, ledger) {
|
|
898
913
|
try {
|
|
899
914
|
await custodyPush(eng, ws, ledger, { remoteRef: "refs/heads/main" });
|
|
900
915
|
} catch (e) {
|
|
901
916
|
unmount(eng, ws);
|
|
902
|
-
|
|
917
|
+
const cause = e instanceof Error ? e.cause : void 0;
|
|
918
|
+
const detail = cause === void 0 ? String(e) : `${e}; cause: ${String(cause)}`;
|
|
919
|
+
throw new Error(`ledger push failed \u2014 write NOT durable, rolled back to ledger: ${detail}`, { cause: e });
|
|
903
920
|
}
|
|
904
921
|
}
|
|
905
922
|
function describe(eng, ws) {
|
|
@@ -1711,9 +1728,11 @@ function completeDevAuthProviderPayload(deployBody, homeDomain, initial, nowMill
|
|
|
1711
1728
|
return payload;
|
|
1712
1729
|
}
|
|
1713
1730
|
function homeDomainOf(opts) {
|
|
1714
|
-
if (!opts
|
|
1731
|
+
if (!opts) return null;
|
|
1732
|
+
const deploy2 = homeDeployPathOf(opts);
|
|
1733
|
+
if (!deploy2) return null;
|
|
1715
1734
|
try {
|
|
1716
|
-
const body = JSON.parse(readFileSync(
|
|
1735
|
+
const body = JSON.parse(readFileSync(deploy2, "utf8"));
|
|
1717
1736
|
const frameworkPaths = body.openapi?.["x-nomos-framework-routes"]?.paths ?? {};
|
|
1718
1737
|
for (const pathItem of Object.values(frameworkPaths)) {
|
|
1719
1738
|
const route = pathItem.post?.["x-nomos"];
|
|
@@ -1802,7 +1821,8 @@ async function bootstrapPlatform(dev, opts) {
|
|
|
1802
1821
|
{
|
|
1803
1822
|
let apPayload = { issuer: idpIssuer, keys: idpJwks, audience: idpAudience, principalClaim: "sub", deviceBindingClaim: "nonce" };
|
|
1804
1823
|
try {
|
|
1805
|
-
const
|
|
1824
|
+
const homeDeploy = homeDeployPathOf(opts);
|
|
1825
|
+
const deployBody = homeDeploy ? JSON.parse(readFileSync(homeDeploy, "utf8")) : null;
|
|
1806
1826
|
apPayload = completeDevAuthProviderPayload(deployBody, homeDomain, apPayload, Date.now(), OPERATOR);
|
|
1807
1827
|
} catch (e) {
|
|
1808
1828
|
log2(`dev test IdP: BYO-shape fill failed (${errMsg(e).slice(0, 200)}) \u2014 the canonical payload stands`);
|
|
@@ -1869,28 +1889,33 @@ async function bootstrapPlatform(dev, opts) {
|
|
|
1869
1889
|
dev.homeDomain = homeDomain;
|
|
1870
1890
|
}
|
|
1871
1891
|
}
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
const usda = body.packageUsda || body.usda;
|
|
1875
|
-
if (!usda) throw new Error(`--deploy ${opts.deploy} has no packageUsda (nothing to install)`);
|
|
1892
|
+
const deployPaths = deployPathsOf(opts);
|
|
1893
|
+
if (deployPaths.length > 0) {
|
|
1876
1894
|
const founderDevice = dev.operatorDevice;
|
|
1877
1895
|
if (!founderDevice) throw new Error("platform law deploy needs the warranted founder device established by bootstrap");
|
|
1878
|
-
const
|
|
1879
|
-
const
|
|
1880
|
-
const
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1896
|
+
for (const deployPath of deployPaths) {
|
|
1897
|
+
const body = JSON.parse(readFileSync(deployPath, "utf8"));
|
|
1898
|
+
const usda = body.packageUsda || body.usda;
|
|
1899
|
+
if (!usda) throw new Error(`--deploy ${deployPath} has no packageUsda (nothing to install)`);
|
|
1900
|
+
const deployErr = await serialize(async () => {
|
|
1901
|
+
const ledger = ledgerFor(platform);
|
|
1902
|
+
const domainHash = await sha256hex(usda);
|
|
1903
|
+
try {
|
|
1904
|
+
const out = await deploy(eng, platform, ledger, usda, domainHash, body.dispositions || null, {
|
|
1905
|
+
actor: "user:dev-operator",
|
|
1906
|
+
authorSecret: founderDevice.secret
|
|
1907
|
+
});
|
|
1908
|
+
if (out && out.ok === false) return String(out.error || "the law refused the platform package");
|
|
1909
|
+
log2(
|
|
1910
|
+
out.staged === true ? `application payload staged for child birth: ${domainHash.slice(0, 12)} (head ${String(out.head).slice(0, 12)})` : `platform law deployed: ${domainHash.slice(0, 12)} (head ${String(out.head).slice(0, 12)})`
|
|
1911
|
+
);
|
|
1912
|
+
return null;
|
|
1913
|
+
} catch (e) {
|
|
1914
|
+
return errStack(e);
|
|
1915
|
+
}
|
|
1916
|
+
});
|
|
1917
|
+
if (deployErr) throw new Error(`platform law deploy REFUSED (${deployPath}): ${deployErr.slice(0, 400)}`);
|
|
1918
|
+
}
|
|
1894
1919
|
} else {
|
|
1895
1920
|
log2("no --deploy given; platform runs framework law only (deploy your platform package to enable births)");
|
|
1896
1921
|
}
|
|
@@ -1902,7 +1927,7 @@ async function bootstrapPlatform(dev, opts) {
|
|
|
1902
1927
|
log2(attested ? "bootstrap complete \u2014 platform law deployed + ROOT-ATTESTED (BirthAttestation certChain seeded; birthHome assembles a valid travelling cert)." : "bootstrap complete (platform law deployed; attested-birth legs gated as noted above \u2014 need the test-mint wasm).");
|
|
1903
1928
|
return { platform, testMint, attested };
|
|
1904
1929
|
}
|
|
1905
|
-
var log2, FRAMEWORK_HOME_DOMAIN;
|
|
1930
|
+
var log2, FRAMEWORK_HOME_DOMAIN, deployPathsOf, homeDeployPathOf;
|
|
1906
1931
|
var init_bootstrap = __esm({
|
|
1907
1932
|
"../cloud/dev-server/bootstrap.ts"() {
|
|
1908
1933
|
"use strict";
|
|
@@ -1910,6 +1935,8 @@ var init_bootstrap = __esm({
|
|
|
1910
1935
|
init_types();
|
|
1911
1936
|
log2 = (m) => console.log(`[bootstrap] ${m}`);
|
|
1912
1937
|
FRAMEWORK_HOME_DOMAIN = "__nomos_application_home_v1";
|
|
1938
|
+
deployPathsOf = (opts) => opts.deploys && opts.deploys.length > 0 ? [...opts.deploys] : opts.deploy ? [opts.deploy] : [];
|
|
1939
|
+
homeDeployPathOf = (opts) => deployPathsOf(opts).at(-1);
|
|
1913
1940
|
}
|
|
1914
1941
|
});
|
|
1915
1942
|
|
|
@@ -2123,17 +2150,24 @@ function runGitHttpBackend(projectRoot, { method, pathInfo, query: query2, conte
|
|
|
2123
2150
|
CONTENT_TYPE: contentType || "",
|
|
2124
2151
|
CONTENT_LENGTH: String(body ? body.length : 0),
|
|
2125
2152
|
REMOTE_ADDR: "127.0.0.1",
|
|
2126
|
-
REMOTE_USER: "nomos-dev"
|
|
2127
|
-
GIT_HTTP_MAX_REQUEST_BUFFER: String(64 * 1024 * 1024)
|
|
2153
|
+
REMOTE_USER: "nomos-dev"
|
|
2128
2154
|
};
|
|
2129
2155
|
const cgi = spawn(GIT_HTTP_BACKEND, [], { env });
|
|
2130
2156
|
const chunks = [];
|
|
2157
|
+
const stderrChunks = [];
|
|
2131
2158
|
cgi.stdout.on("data", (d) => chunks.push(d));
|
|
2132
|
-
cgi.stderr.on("data", () =>
|
|
2133
|
-
});
|
|
2159
|
+
cgi.stderr.on("data", (d) => stderrChunks.push(d));
|
|
2134
2160
|
cgi.on("error", reject);
|
|
2135
|
-
cgi.on("
|
|
2161
|
+
cgi.stdin.on("error", reject);
|
|
2162
|
+
cgi.on("close", (code, signal) => {
|
|
2136
2163
|
const out = Buffer.concat(chunks);
|
|
2164
|
+
const stderr = Buffer.concat(stderrChunks).toString("utf8").trim();
|
|
2165
|
+
if (code !== 0 && out.length === 0) {
|
|
2166
|
+
reject(new Error(
|
|
2167
|
+
`git-http-backend exited ${signal ? `on ${signal}` : `with ${code}`}${stderr ? `: ${stderr}` : ""}`
|
|
2168
|
+
));
|
|
2169
|
+
return;
|
|
2170
|
+
}
|
|
2137
2171
|
let sep = out.indexOf("\r\n\r\n");
|
|
2138
2172
|
let sepLen = 4;
|
|
2139
2173
|
if (sep < 0) {
|
|
@@ -2157,8 +2191,7 @@ function runGitHttpBackend(projectRoot, { method, pathInfo, query: query2, conte
|
|
|
2157
2191
|
}
|
|
2158
2192
|
resolve({ status, headers, body: payload });
|
|
2159
2193
|
});
|
|
2160
|
-
|
|
2161
|
-
cgi.stdin.end();
|
|
2194
|
+
cgi.stdin.end(body && body.length ? body : void 0);
|
|
2162
2195
|
});
|
|
2163
2196
|
}
|
|
2164
2197
|
function receivePackCommands(raw) {
|
|
@@ -2493,6 +2526,9 @@ async function startDevCloud(opts = {}) {
|
|
|
2493
2526
|
} catch {
|
|
2494
2527
|
return false;
|
|
2495
2528
|
}
|
|
2529
|
+
if (process.env.NOMOS_TEST_DIAGNOSTICS === "1") {
|
|
2530
|
+
console.error(`[dev-cloud] read-posture ${ws} ${kind} ${JSON.stringify(posture)}`);
|
|
2531
|
+
}
|
|
2496
2532
|
if (posture && posture.private && !posture.allowedAny) {
|
|
2497
2533
|
sendJson(res, bulkReadForbidden(ws, kind, posture), 403);
|
|
2498
2534
|
return true;
|
|
@@ -2966,6 +3002,9 @@ async function startDevCloud(opts = {}) {
|
|
|
2966
3002
|
});
|
|
2967
3003
|
async function gitBackend(req, res, repoPathInfo, ws) {
|
|
2968
3004
|
const body = await readBody(req);
|
|
3005
|
+
if (process.env.NOMOS_TEST_DIAGNOSTICS === "1") {
|
|
3006
|
+
console.error(`[dev-cloud] git-http ${req.method || ""} /${repoPathInfo} body=${body.byteLength}`);
|
|
3007
|
+
}
|
|
2969
3008
|
let sessionPush = false;
|
|
2970
3009
|
if (ws && req.method === "POST" && /git-receive-pack/.test(repoPathInfo)) {
|
|
2971
3010
|
try {
|
|
@@ -2986,7 +3025,10 @@ async function startDevCloud(opts = {}) {
|
|
|
2986
3025
|
contentType: req.headers["content-type"],
|
|
2987
3026
|
body
|
|
2988
3027
|
});
|
|
2989
|
-
|
|
3028
|
+
if (process.env.NOMOS_TEST_DIAGNOSTICS === "1") {
|
|
3029
|
+
console.error(`[dev-cloud] git-http ${req.method || ""} /${repoPathInfo} -> ${out.status} body=${out.body.byteLength}`);
|
|
3030
|
+
}
|
|
3031
|
+
res.writeHead(out.status, { ...out.headers, ...CORS, connection: "close" });
|
|
2990
3032
|
res.end(out.body);
|
|
2991
3033
|
if (sessionPush && ws) scheduleAdmit(ws);
|
|
2992
3034
|
}
|
|
@@ -3102,8 +3144,11 @@ function parseArgs(argv) {
|
|
|
3102
3144
|
else if (a === "--data") o.data = argv[++i];
|
|
3103
3145
|
else if (a === "--firebase-project") o.firebaseProject = argv[++i];
|
|
3104
3146
|
else if (a === "--platform") o.platform = argv[++i];
|
|
3105
|
-
else if (a === "--deploy")
|
|
3106
|
-
|
|
3147
|
+
else if (a === "--deploy") {
|
|
3148
|
+
const deploy2 = argv[++i];
|
|
3149
|
+
o.deploy = deploy2;
|
|
3150
|
+
(o.deploys ??= []).push(deploy2);
|
|
3151
|
+
} else if (a === "--auth-provider") o.authProvider = argv[++i];
|
|
3107
3152
|
else if (a === "--bootstrap") o.bootstrap = true;
|
|
3108
3153
|
else if (a === "--attested") o.attested = true;
|
|
3109
3154
|
else if (a === "--kernel-source") o.kernelSource = argv[++i];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "githolon",
|
|
3
|
-
"version": "0.102.
|
|
3
|
+
"version": "0.102.2",
|
|
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,7 +29,7 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@bjorn3/browser_wasi_shim": "0.4.2",
|
|
32
|
-
"@githolon/dsl": "^0.102.
|
|
32
|
+
"@githolon/dsl": "^0.102.2",
|
|
33
33
|
"isomorphic-git": "^1.38.4"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|