githolon 0.91.0 → 0.93.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 +226 -103
- package/dist/dev-server.mjs +145 -19
- package/package.json +3 -3
package/dist/cli.mjs
CHANGED
|
@@ -4480,6 +4480,108 @@ var init_governance = __esm({
|
|
|
4480
4480
|
}
|
|
4481
4481
|
});
|
|
4482
4482
|
|
|
4483
|
+
// src/capabilities.ts
|
|
4484
|
+
var capabilities_exports = {};
|
|
4485
|
+
__export(capabilities_exports, {
|
|
4486
|
+
INLINE_OFFER_CAP_CHARS: () => INLINE_OFFER_CAP_CHARS,
|
|
4487
|
+
negotiateDeployRoute: () => negotiateDeployRoute,
|
|
4488
|
+
openapiRoutesDirective: () => openapiRoutesDirective,
|
|
4489
|
+
probeCloudCapabilities: () => probeCloudCapabilities,
|
|
4490
|
+
probeKernelCapabilities: () => probeKernelCapabilities,
|
|
4491
|
+
probeOfferLane: () => probeOfferLane,
|
|
4492
|
+
probeStageLane: () => probeStageLane
|
|
4493
|
+
});
|
|
4494
|
+
async function probeStageLane(cloud, fetchImpl = fetch) {
|
|
4495
|
+
try {
|
|
4496
|
+
const r = await fetchImpl(`${cloud}/v2/stage/${ZERO_SHA}`, { method: "GET" });
|
|
4497
|
+
const body = await r.json().catch(() => void 0);
|
|
4498
|
+
return typeof body?.staged === "boolean";
|
|
4499
|
+
} catch {
|
|
4500
|
+
return void 0;
|
|
4501
|
+
}
|
|
4502
|
+
}
|
|
4503
|
+
async function probeKernelCapabilities(cloud, fetchImpl = fetch) {
|
|
4504
|
+
try {
|
|
4505
|
+
const r = await fetchImpl(`${cloud.replace(/\/+$/, "")}/v1/runtime/capabilities`, { method: "GET" });
|
|
4506
|
+
if (!r.ok) return void 0;
|
|
4507
|
+
const body = await r.json().catch(() => void 0);
|
|
4508
|
+
return body && typeof body === "object" ? body : void 0;
|
|
4509
|
+
} catch {
|
|
4510
|
+
return void 0;
|
|
4511
|
+
}
|
|
4512
|
+
}
|
|
4513
|
+
function openapiRoutesDirective(spec, domain, directiveId) {
|
|
4514
|
+
const paths = spec?.paths ?? {};
|
|
4515
|
+
const wantPath = `/${domain}/${directiveId}`;
|
|
4516
|
+
const wantBare = `/${directiveId}`;
|
|
4517
|
+
const wantOp = `${domain}__${directiveId}`;
|
|
4518
|
+
for (const [p, ops] of Object.entries(paths)) {
|
|
4519
|
+
if (p === wantPath || p === wantBare) return true;
|
|
4520
|
+
for (const method of Object.values(ops ?? {})) {
|
|
4521
|
+
if (method?.operationId === wantOp) return true;
|
|
4522
|
+
}
|
|
4523
|
+
}
|
|
4524
|
+
return false;
|
|
4525
|
+
}
|
|
4526
|
+
async function probeOfferLane(cloud, ws, route, fetchImpl = fetch) {
|
|
4527
|
+
try {
|
|
4528
|
+
const r = await fetchImpl(`${cloud}/v2/workspaces/${ws}/openapi.json`, { method: "GET" });
|
|
4529
|
+
if (!r.ok) return { served: false, routesTarget: void 0 };
|
|
4530
|
+
const spec = await r.json().catch(() => void 0);
|
|
4531
|
+
if (spec === void 0 || typeof spec !== "object") return { served: false, routesTarget: void 0 };
|
|
4532
|
+
const served = true;
|
|
4533
|
+
const routesTarget = route === void 0 ? void 0 : openapiRoutesDirective(spec, route.domain, route.directiveId);
|
|
4534
|
+
return { served, routesTarget };
|
|
4535
|
+
} catch {
|
|
4536
|
+
return { served: void 0, routesTarget: void 0 };
|
|
4537
|
+
}
|
|
4538
|
+
}
|
|
4539
|
+
async function probeCloudCapabilities(cloud, ws, route, fetchImpl = fetch) {
|
|
4540
|
+
const [stage, offer] = await Promise.all([
|
|
4541
|
+
probeStageLane(cloud, fetchImpl),
|
|
4542
|
+
probeOfferLane(cloud, ws, route, fetchImpl)
|
|
4543
|
+
]);
|
|
4544
|
+
return {
|
|
4545
|
+
cloud,
|
|
4546
|
+
stage,
|
|
4547
|
+
offerLane: offer.served,
|
|
4548
|
+
routesTarget: offer.routesTarget,
|
|
4549
|
+
openDeploy: void 0
|
|
4550
|
+
// the open /domains lane is universal in every worker/dev-server; not separately probed
|
|
4551
|
+
};
|
|
4552
|
+
}
|
|
4553
|
+
function negotiateDeployRoute(caps, opts) {
|
|
4554
|
+
if (opts.signed) {
|
|
4555
|
+
if (caps.offerLane === false) {
|
|
4556
|
+
return {
|
|
4557
|
+
fail: `${caps.cloud} does not serve the SIGNED OFFER lane \u2014 POST /v2/workspaces/${opts.ws}/${opts.route.domain}/${opts.route.directiveId} is not routed (the workspace serves no self-describing OpenAPI, so this cloud has no gateway to route a signed offer). This is often a lightweight cloud (e.g. \`githolon cloud dev\`) without the offer gateway.
|
|
4558
|
+
\u2192 deploy the OPEN (unsigned) lane instead (drop --as/--principal) if this workspace is unwarranted, or target a cloud that serves the offer gateway.`
|
|
4559
|
+
};
|
|
4560
|
+
}
|
|
4561
|
+
if (caps.offerLane === true && caps.routesTarget === false) {
|
|
4562
|
+
return {
|
|
4563
|
+
fail: `${caps.cloud} serves the offer gateway for ${opts.ws}, but its OpenAPI does not name the route ${opts.route.domain}/${opts.route.directiveId} \u2014 the ${opts.route.domain} controller is not installed here, so a signed ${opts.route.directiveId} would 404.
|
|
4564
|
+
\u2192 confirm the workspace is born and the controller is deployed, or deploy the OPEN lane (drop --as).`
|
|
4565
|
+
};
|
|
4566
|
+
}
|
|
4567
|
+
if (opts.sealedSizeChars > INLINE_OFFER_CAP_CHARS && caps.stage === false) {
|
|
4568
|
+
return {
|
|
4569
|
+
fail: `this signed package is ~${Math.round(opts.sealedSizeChars / (1024 * 1024))} MiB sealed \u2014 over the ${INLINE_OFFER_CAP_CHARS / (1024 * 1024)} MiB inline offer cap \u2014 and ${caps.cloud} has no /v2/stage content-addressed lane to carry it.
|
|
4570
|
+
\u2192 target a cloud that serves /v2/stage, or shrink the package (githolon compile --compact).`
|
|
4571
|
+
};
|
|
4572
|
+
}
|
|
4573
|
+
}
|
|
4574
|
+
return void 0;
|
|
4575
|
+
}
|
|
4576
|
+
var INLINE_OFFER_CAP_CHARS, ZERO_SHA;
|
|
4577
|
+
var init_capabilities = __esm({
|
|
4578
|
+
"src/capabilities.ts"() {
|
|
4579
|
+
"use strict";
|
|
4580
|
+
INLINE_OFFER_CAP_CHARS = 8 * 1024 * 1024;
|
|
4581
|
+
ZERO_SHA = "0".repeat(64);
|
|
4582
|
+
}
|
|
4583
|
+
});
|
|
4584
|
+
|
|
4483
4585
|
// src/lifecycle.ts
|
|
4484
4586
|
var lifecycle_exports = {};
|
|
4485
4587
|
__export(lifecycle_exports, {
|
|
@@ -4791,97 +4893,6 @@ var init_lifecycle = __esm({
|
|
|
4791
4893
|
}
|
|
4792
4894
|
});
|
|
4793
4895
|
|
|
4794
|
-
// src/capabilities.ts
|
|
4795
|
-
var capabilities_exports = {};
|
|
4796
|
-
__export(capabilities_exports, {
|
|
4797
|
-
INLINE_OFFER_CAP_CHARS: () => INLINE_OFFER_CAP_CHARS,
|
|
4798
|
-
negotiateDeployRoute: () => negotiateDeployRoute,
|
|
4799
|
-
openapiRoutesDirective: () => openapiRoutesDirective,
|
|
4800
|
-
probeCloudCapabilities: () => probeCloudCapabilities,
|
|
4801
|
-
probeOfferLane: () => probeOfferLane,
|
|
4802
|
-
probeStageLane: () => probeStageLane
|
|
4803
|
-
});
|
|
4804
|
-
async function probeStageLane(cloud, fetchImpl = fetch) {
|
|
4805
|
-
try {
|
|
4806
|
-
const r = await fetchImpl(`${cloud}/v2/stage/${ZERO_SHA}`, { method: "GET" });
|
|
4807
|
-
const body = await r.json().catch(() => void 0);
|
|
4808
|
-
return typeof body?.staged === "boolean";
|
|
4809
|
-
} catch {
|
|
4810
|
-
return void 0;
|
|
4811
|
-
}
|
|
4812
|
-
}
|
|
4813
|
-
function openapiRoutesDirective(spec, domain, directiveId) {
|
|
4814
|
-
const paths = spec?.paths ?? {};
|
|
4815
|
-
const wantPath = `/${domain}/${directiveId}`;
|
|
4816
|
-
const wantBare = `/${directiveId}`;
|
|
4817
|
-
const wantOp = `${domain}__${directiveId}`;
|
|
4818
|
-
for (const [p, ops] of Object.entries(paths)) {
|
|
4819
|
-
if (p === wantPath || p === wantBare) return true;
|
|
4820
|
-
for (const method of Object.values(ops ?? {})) {
|
|
4821
|
-
if (method?.operationId === wantOp) return true;
|
|
4822
|
-
}
|
|
4823
|
-
}
|
|
4824
|
-
return false;
|
|
4825
|
-
}
|
|
4826
|
-
async function probeOfferLane(cloud, ws, route, fetchImpl = fetch) {
|
|
4827
|
-
try {
|
|
4828
|
-
const r = await fetchImpl(`${cloud}/v2/workspaces/${ws}/openapi.json`, { method: "GET" });
|
|
4829
|
-
if (!r.ok) return { served: false, routesTarget: void 0 };
|
|
4830
|
-
const spec = await r.json().catch(() => void 0);
|
|
4831
|
-
if (spec === void 0 || typeof spec !== "object") return { served: false, routesTarget: void 0 };
|
|
4832
|
-
const served = true;
|
|
4833
|
-
const routesTarget = route === void 0 ? void 0 : openapiRoutesDirective(spec, route.domain, route.directiveId);
|
|
4834
|
-
return { served, routesTarget };
|
|
4835
|
-
} catch {
|
|
4836
|
-
return { served: void 0, routesTarget: void 0 };
|
|
4837
|
-
}
|
|
4838
|
-
}
|
|
4839
|
-
async function probeCloudCapabilities(cloud, ws, route, fetchImpl = fetch) {
|
|
4840
|
-
const [stage, offer] = await Promise.all([
|
|
4841
|
-
probeStageLane(cloud, fetchImpl),
|
|
4842
|
-
probeOfferLane(cloud, ws, route, fetchImpl)
|
|
4843
|
-
]);
|
|
4844
|
-
return {
|
|
4845
|
-
cloud,
|
|
4846
|
-
stage,
|
|
4847
|
-
offerLane: offer.served,
|
|
4848
|
-
routesTarget: offer.routesTarget,
|
|
4849
|
-
openDeploy: void 0
|
|
4850
|
-
// the open /domains lane is universal in every worker/dev-server; not separately probed
|
|
4851
|
-
};
|
|
4852
|
-
}
|
|
4853
|
-
function negotiateDeployRoute(caps, opts) {
|
|
4854
|
-
if (opts.signed) {
|
|
4855
|
-
if (caps.offerLane === false) {
|
|
4856
|
-
return {
|
|
4857
|
-
fail: `${caps.cloud} does not serve the SIGNED OFFER lane \u2014 POST /v2/workspaces/${opts.ws}/${opts.route.domain}/${opts.route.directiveId} is not routed (the workspace serves no self-describing OpenAPI, so this cloud has no gateway to route a signed offer). This is often a lightweight cloud (e.g. \`githolon cloud dev\`) without the offer gateway.
|
|
4858
|
-
\u2192 deploy the OPEN (unsigned) lane instead (drop --as/--principal) if this workspace is unwarranted, or target a cloud that serves the offer gateway.`
|
|
4859
|
-
};
|
|
4860
|
-
}
|
|
4861
|
-
if (caps.offerLane === true && caps.routesTarget === false) {
|
|
4862
|
-
return {
|
|
4863
|
-
fail: `${caps.cloud} serves the offer gateway for ${opts.ws}, but its OpenAPI does not name the route ${opts.route.domain}/${opts.route.directiveId} \u2014 the ${opts.route.domain} controller is not installed here, so a signed ${opts.route.directiveId} would 404.
|
|
4864
|
-
\u2192 confirm the workspace is born and the controller is deployed, or deploy the OPEN lane (drop --as).`
|
|
4865
|
-
};
|
|
4866
|
-
}
|
|
4867
|
-
if (opts.sealedSizeChars > INLINE_OFFER_CAP_CHARS && caps.stage === false) {
|
|
4868
|
-
return {
|
|
4869
|
-
fail: `this signed package is ~${Math.round(opts.sealedSizeChars / (1024 * 1024))} MiB sealed \u2014 over the ${INLINE_OFFER_CAP_CHARS / (1024 * 1024)} MiB inline offer cap \u2014 and ${caps.cloud} has no /v2/stage content-addressed lane to carry it.
|
|
4870
|
-
\u2192 target a cloud that serves /v2/stage, or shrink the package (githolon compile --compact).`
|
|
4871
|
-
};
|
|
4872
|
-
}
|
|
4873
|
-
}
|
|
4874
|
-
return void 0;
|
|
4875
|
-
}
|
|
4876
|
-
var INLINE_OFFER_CAP_CHARS, ZERO_SHA;
|
|
4877
|
-
var init_capabilities = __esm({
|
|
4878
|
-
"src/capabilities.ts"() {
|
|
4879
|
-
"use strict";
|
|
4880
|
-
INLINE_OFFER_CAP_CHARS = 8 * 1024 * 1024;
|
|
4881
|
-
ZERO_SHA = "0".repeat(64);
|
|
4882
|
-
}
|
|
4883
|
-
});
|
|
4884
|
-
|
|
4885
4896
|
// src/cloud.ts
|
|
4886
4897
|
var cloud_exports = {};
|
|
4887
4898
|
__export(cloud_exports, {
|
|
@@ -5273,6 +5284,29 @@ async function deploy2(ws, opts) {
|
|
|
5273
5284
|
const beforeLaw = await fetch(`${cloud}/v2/workspaces/${ws}/domains`).then((br) => br.json()).then((bd) => bd.ok === true ? bd : {}).catch(() => ({}));
|
|
5274
5285
|
const before = beforeLaw.domains ?? [];
|
|
5275
5286
|
const currentLaw2 = beforeLaw.currentLaw ?? {};
|
|
5287
|
+
try {
|
|
5288
|
+
const compat = JSON.parse(readFileSync5(file, "utf8")).nomosCompat;
|
|
5289
|
+
const requires = compat?.requiresKernel ?? [];
|
|
5290
|
+
if (requires.length > 0) {
|
|
5291
|
+
const { probeKernelCapabilities: probeKernelCapabilities2 } = await Promise.resolve().then(() => (init_capabilities(), capabilities_exports));
|
|
5292
|
+
const report = await probeKernelCapabilities2(cloud);
|
|
5293
|
+
const kernel = report?.prod;
|
|
5294
|
+
if (kernel?.features) {
|
|
5295
|
+
const missing = requires.filter((f) => !kernel.features.includes(f));
|
|
5296
|
+
if (missing.length > 0) {
|
|
5297
|
+
const lawH = String(compat?.lawHash ?? "").slice(0, 8);
|
|
5298
|
+
const kernH = String(kernel.hash ?? "").slice(0, 8);
|
|
5299
|
+
err4(
|
|
5300
|
+
`deploy '${ws}' REFUSED \u2014 release coherence: kernel ${kernH} lacks capability '${missing.join("', '")}' that law ${lawH} requires (the cloud runs a STALE kernel: ${kernel.note ?? kernel.version}).` + (missing.includes("compoundKeys") ? `
|
|
5301
|
+
A compound-key query (\`.key(a, b, \u2026)\`) would be refused deep in a law fold ("query declares N index keys; the read router supports exactly one").` : "") + `
|
|
5302
|
+
Point at a cloud whose kernel is coherent with this release, or upgrade the cloud's kernel.`
|
|
5303
|
+
);
|
|
5304
|
+
return 1;
|
|
5305
|
+
}
|
|
5306
|
+
}
|
|
5307
|
+
}
|
|
5308
|
+
} catch {
|
|
5309
|
+
}
|
|
5276
5310
|
const { readDeployBody: readDeployBody3, domainKeysOf: domainKeysOf2, packageHashOf: packageHashOf2, resolveDeployPlan: resolveDeployPlan2, describeDeployPlan: describeDeployPlan2 } = await Promise.resolve().then(() => (init_lifecycle(), lifecycle_exports));
|
|
5277
5311
|
let plan;
|
|
5278
5312
|
let targetHash;
|
|
@@ -5645,9 +5679,9 @@ function parseOfflineLegs(proofSource) {
|
|
|
5645
5679
|
}
|
|
5646
5680
|
const domain = dom[1];
|
|
5647
5681
|
const autoStamped = [];
|
|
5648
|
-
const
|
|
5649
|
-
if (
|
|
5650
|
-
for (const m of
|
|
5682
|
+
const stampLine2 = proofSource.split("\n").find((l) => l.includes("omitted \u2014 the client auto-stamps ISO now()"));
|
|
5683
|
+
if (stampLine2 !== void 0) {
|
|
5684
|
+
for (const m of stampLine2.matchAll(/`(\w+)`/g)) autoStamped.push(m[1]);
|
|
5651
5685
|
}
|
|
5652
5686
|
let queryLeg;
|
|
5653
5687
|
const q = proofSource.match(/local declared query (\w+):/);
|
|
@@ -6553,6 +6587,84 @@ var init_harness = __esm({
|
|
|
6553
6587
|
}
|
|
6554
6588
|
});
|
|
6555
6589
|
|
|
6590
|
+
// src/doctor.ts
|
|
6591
|
+
var doctor_exports = {};
|
|
6592
|
+
__export(doctor_exports, {
|
|
6593
|
+
doctor: () => doctor
|
|
6594
|
+
});
|
|
6595
|
+
import { existsSync as existsSync14, readFileSync as readFileSync15 } from "node:fs";
|
|
6596
|
+
function readLocalCompat(cwd, file) {
|
|
6597
|
+
try {
|
|
6598
|
+
const path = discoverDeployJson(cwd, file);
|
|
6599
|
+
if (!existsSync14(path)) return void 0;
|
|
6600
|
+
const body = JSON.parse(readFileSync15(path, "utf8"));
|
|
6601
|
+
return body.nomosCompat;
|
|
6602
|
+
} catch {
|
|
6603
|
+
return void 0;
|
|
6604
|
+
}
|
|
6605
|
+
}
|
|
6606
|
+
function stampLine(label, stamp) {
|
|
6607
|
+
if (!stamp) return ` ${label.padEnd(12)}: (not advertised)`;
|
|
6608
|
+
const h = String(stamp.hash || "").slice(0, 12);
|
|
6609
|
+
const caps = stamp.features?.length ? `[${stamp.features.join(", ")}]` : "[]";
|
|
6610
|
+
const known = stamp.known ? "" : " \u26A0 UNKNOWN to registry";
|
|
6611
|
+
return ` ${label.padEnd(12)}: ${h}\u2026 ${stamp.version ?? ""}${known}
|
|
6612
|
+
caps ${caps}`;
|
|
6613
|
+
}
|
|
6614
|
+
async function doctor(opts = {}) {
|
|
6615
|
+
const cloud = cloudBase(opts.cloud);
|
|
6616
|
+
const compat = readLocalCompat(process.cwd(), opts.file);
|
|
6617
|
+
const report = await probeKernelCapabilities(cloud);
|
|
6618
|
+
const out13 = [];
|
|
6619
|
+
out13.push(`githolon doctor \u2014 release coherence`);
|
|
6620
|
+
out13.push(` cloud : ${cloud}`);
|
|
6621
|
+
out13.push(` compiler : @githolon/dsl ${compat?.generator?.dsl ?? "(no local build \u2014 run `githolon compile`)"}`);
|
|
6622
|
+
out13.push(` runner : cloud expects bundle version ${report?.expectedBundleVersion ?? "(not advertised)"}`);
|
|
6623
|
+
out13.push(stampLine("prod kernel", report?.prod));
|
|
6624
|
+
out13.push(stampLine("test kernel", report?.testmint));
|
|
6625
|
+
const requires = compat?.requiresKernel ?? [];
|
|
6626
|
+
if (!compat) {
|
|
6627
|
+
out13.push(``);
|
|
6628
|
+
out13.push(` \u26A0 no local build found \u2014 cannot check the law\u2194kernel fit. Run \`githolon compile\` first.`);
|
|
6629
|
+
process.stdout.write(out13.join("\n") + "\n");
|
|
6630
|
+
return report ? 0 : 1;
|
|
6631
|
+
}
|
|
6632
|
+
if (!report?.prod) {
|
|
6633
|
+
out13.push(``);
|
|
6634
|
+
out13.push(` \u26A0 cloud advertises no kernel capabilities (older worker?) \u2014 coherence UNVERIFIABLE.`);
|
|
6635
|
+
out13.push(` law ${String(compat.lawHash).slice(0, 8)} requires: [${requires.join(", ") || "none"}]`);
|
|
6636
|
+
process.stdout.write(out13.join("\n") + "\n");
|
|
6637
|
+
return 0;
|
|
6638
|
+
}
|
|
6639
|
+
const feats = report.prod.features ?? [];
|
|
6640
|
+
const missing = requires.filter((f) => !feats.includes(f));
|
|
6641
|
+
out13.push(``);
|
|
6642
|
+
const lawH = String(compat.lawHash || "").slice(0, 8);
|
|
6643
|
+
const kernH = String(report.prod.hash || "").slice(0, 8);
|
|
6644
|
+
if (requires.length === 0) {
|
|
6645
|
+
out13.push(` \u2713 COHERENT \u2014 law ${lawH} requires no special kernel capabilities.`);
|
|
6646
|
+
} else if (missing.length === 0) {
|
|
6647
|
+
out13.push(` \u2713 COHERENT \u2014 kernel ${kernH} supports all capabilities law ${lawH} requires: [${requires.join(", ")}].`);
|
|
6648
|
+
} else {
|
|
6649
|
+
out13.push(` \u2717 SKEW \u2014 kernel ${kernH} lacks capability '${missing.join("', '")}' that law ${lawH} requires.`);
|
|
6650
|
+
out13.push(` The cloud is running a STALE kernel (${report.prod.note ?? report.prod.version ?? "unknown build"}).`);
|
|
6651
|
+
if (missing.includes("compoundKeys")) {
|
|
6652
|
+
out13.push(` A compound-key query (\`.key(a, b, \u2026)\`) will be refused deep in a law fold with`);
|
|
6653
|
+
out13.push(` "query declares N index keys; the read router supports exactly one".`);
|
|
6654
|
+
}
|
|
6655
|
+
out13.push(` Point at a cloud whose kernel is coherent with this release, or upgrade the cloud's kernel.`);
|
|
6656
|
+
}
|
|
6657
|
+
process.stdout.write(out13.join("\n") + "\n");
|
|
6658
|
+
return missing.length > 0 ? 1 : 0;
|
|
6659
|
+
}
|
|
6660
|
+
var init_doctor = __esm({
|
|
6661
|
+
"src/doctor.ts"() {
|
|
6662
|
+
"use strict";
|
|
6663
|
+
init_cloud();
|
|
6664
|
+
init_capabilities();
|
|
6665
|
+
}
|
|
6666
|
+
});
|
|
6667
|
+
|
|
6556
6668
|
// src/scene_projector.ts
|
|
6557
6669
|
import { createHash as createHash4 } from "node:crypto";
|
|
6558
6670
|
function fnv1a32(s) {
|
|
@@ -7609,7 +7721,7 @@ var scene_exports = {};
|
|
|
7609
7721
|
__export(scene_exports, {
|
|
7610
7722
|
scene: () => scene
|
|
7611
7723
|
});
|
|
7612
|
-
import { existsSync as
|
|
7724
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync6, writeFileSync as writeFileSync9 } from "node:fs";
|
|
7613
7725
|
import { join as join16, resolve as resolve4 } from "node:path";
|
|
7614
7726
|
import { createHash as createHash5 } from "node:crypto";
|
|
7615
7727
|
import git3 from "isomorphic-git";
|
|
@@ -7631,8 +7743,8 @@ async function projectOnce(cloud, target, isDir, name) {
|
|
|
7631
7743
|
const { eng } = await holonEngine(cloud, void 0, "githolon-scene");
|
|
7632
7744
|
const SOURCE3 = "source";
|
|
7633
7745
|
if (isDir) {
|
|
7634
|
-
const gitDir =
|
|
7635
|
-
if (!
|
|
7746
|
+
const gitDir = existsSync15(join16(target, ".git")) ? join16(target, ".git") : target;
|
|
7747
|
+
if (!existsSync15(join16(gitDir, "HEAD"))) throw new Error(`${target} is not a git repo (no HEAD)`);
|
|
7636
7748
|
await mountFresh(eng, SOURCE3);
|
|
7637
7749
|
eng.preopen.dir.contents.get("ws").contents.get(SOURCE3).contents.set("nomos.git", readTreeFromDisk(gitDir));
|
|
7638
7750
|
} else {
|
|
@@ -7691,7 +7803,7 @@ async function projectOnce(cloud, target, isDir, name) {
|
|
|
7691
7803
|
}
|
|
7692
7804
|
async function scene(target, opts) {
|
|
7693
7805
|
const cloud = cloudBase(opts.cloud);
|
|
7694
|
-
const isDir =
|
|
7806
|
+
const isDir = existsSync15(target) || target.includes("/") || target.startsWith(".");
|
|
7695
7807
|
const name = isDir ? (resolve4(target).split("/").filter(Boolean).pop() ?? "scene").replace(/\.git$/, "") : target;
|
|
7696
7808
|
out11(`scene \u2014 ${name} (${isDir ? resolve4(target) : `${cloud} :: ${target}`})`);
|
|
7697
7809
|
let first, second;
|
|
@@ -7802,7 +7914,7 @@ var init_dlq = __esm({
|
|
|
7802
7914
|
});
|
|
7803
7915
|
|
|
7804
7916
|
// src/cli.ts
|
|
7805
|
-
import { existsSync as
|
|
7917
|
+
import { existsSync as existsSync16, readdirSync as readdirSync6, readFileSync as readFileSync16 } from "node:fs";
|
|
7806
7918
|
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
7807
7919
|
import { createRequire as createRequire3 } from "node:module";
|
|
7808
7920
|
import { dirname as dirname9, join as join17, resolve as resolve5 } from "node:path";
|
|
@@ -9436,10 +9548,10 @@ async function runProof(args) {
|
|
|
9436
9548
|
let proofPath;
|
|
9437
9549
|
if (explicit !== void 0) {
|
|
9438
9550
|
proofPath = resolve5(process.cwd(), explicit);
|
|
9439
|
-
if (!
|
|
9551
|
+
if (!existsSync16(proofPath)) return refuse(`proof not found: ${proofPath} \u2014 run \`githolon compile\` to (re)generate it`);
|
|
9440
9552
|
} else {
|
|
9441
9553
|
const buildDir = join17(process.cwd(), "build");
|
|
9442
|
-
if (!
|
|
9554
|
+
if (!existsSync16(buildDir)) {
|
|
9443
9555
|
return refuse("no build/ directory here \u2014 run `githolon compile` first (every compile generates build/<name>.proof.mts from your law)");
|
|
9444
9556
|
}
|
|
9445
9557
|
const proofs = readdirSync6(buildDir).filter((f) => f.endsWith(".proof.mts"));
|
|
@@ -9482,7 +9594,7 @@ async function runProof(args) {
|
|
|
9482
9594
|
if (tsxDir === void 0) {
|
|
9483
9595
|
return refuse("tsx not found \u2014 add @githolon/dsl to your project's dependencies (tsx rides along) and npm install");
|
|
9484
9596
|
}
|
|
9485
|
-
const tsxPkg = JSON.parse(
|
|
9597
|
+
const tsxPkg = JSON.parse(readFileSync16(join17(tsxDir, "package.json"), "utf8"));
|
|
9486
9598
|
const tsxBinRel = typeof tsxPkg.bin === "string" ? tsxPkg.bin : tsxPkg.bin?.["tsx"];
|
|
9487
9599
|
const tsxCli = join17(tsxDir, tsxBinRel ?? "dist/cli.mjs");
|
|
9488
9600
|
console.log("githolon proof --live \u2014 the full cloud loop (throwaway workspace, retired on exit" + (keep ? "; --keep: kept" : "") + ")");
|
|
@@ -9687,6 +9799,17 @@ ${commandHelp("dev")}`);
|
|
|
9687
9799
|
...once ? { once: true } : {}
|
|
9688
9800
|
});
|
|
9689
9801
|
}
|
|
9802
|
+
if (argv[0] === "doctor") {
|
|
9803
|
+
const rest = argv.slice(1);
|
|
9804
|
+
let cloudFlag;
|
|
9805
|
+
let fileFlag;
|
|
9806
|
+
for (let i = 0; i < rest.length; i++) {
|
|
9807
|
+
if (rest[i] === "--cloud") cloudFlag = rest[++i];
|
|
9808
|
+
else if (rest[i] === "--file") fileFlag = rest[++i];
|
|
9809
|
+
}
|
|
9810
|
+
const { doctor: doctor2 } = await Promise.resolve().then(() => (init_doctor(), doctor_exports));
|
|
9811
|
+
return doctor2({ ...cloudFlag !== void 0 ? { cloud: cloudFlag } : {}, ...fileFlag !== void 0 ? { file: fileFlag } : {} });
|
|
9812
|
+
}
|
|
9690
9813
|
if (argv[0] === "cloud") {
|
|
9691
9814
|
const sub2 = argv[1];
|
|
9692
9815
|
if (sub2 !== "dev") {
|
|
@@ -9707,7 +9830,7 @@ usage: githolon cloud dev [--port <n>] [--data <dir>] [--ephemeral]
|
|
|
9707
9830
|
resolve5(here, "../../../cloud/dev-server/server.mjs"),
|
|
9708
9831
|
resolve5(process.cwd(), "cloud/dev-server/server.mjs")
|
|
9709
9832
|
];
|
|
9710
|
-
const serverPath = candidates.find((p) =>
|
|
9833
|
+
const serverPath = candidates.find((p) => existsSync16(p));
|
|
9711
9834
|
if (!serverPath) {
|
|
9712
9835
|
process.stderr.write("error: dev-server not found \u2014 reinstall `githolon` or run `npm run build` in the cli package\n");
|
|
9713
9836
|
return 1;
|
package/dist/dev-server.mjs
CHANGED
|
@@ -1411,7 +1411,7 @@ async function ledgerStats(eng, ws, ledger = null) {
|
|
|
1411
1411
|
if (mounted) mounted.ledgerStats = out;
|
|
1412
1412
|
return out;
|
|
1413
1413
|
}
|
|
1414
|
-
var enc3, dec3, BRANCH, RESULT_PACK_INLINE_MAX, repoArgOf, gitdirOf, unpack, log, repoArgOfGitdir, bytesFromB64, kgit, installPayload, routeTagHexOfHomeKey, SUMMARY_SEP, summaryKey, splitSummaryKey, NOMOS_SHARD_ROWS_READ, groupOf, tallyOf, isExtremumRead, extremumMonotone, pushVia, fullRef, applyPackInto, custodyLsRefs, qById, query, authorKeygen, attestedRead, count, sum, pendingConflicts, spatialBboxParams, spatialWithin, extremum, nomosActive, refusedRefName;
|
|
1414
|
+
var enc3, dec3, BRANCH, RESULT_PACK_INLINE_MAX, repoArgOf, gitdirOf, unpack, log, repoArgOfGitdir, bytesFromB64, kgit, installPayload, routeTagHexOfHomeKey, SUMMARY_SEP, summaryKey, splitSummaryKey, NOMOS_SHARD_ROWS_READ, groupOf, tallyOf, isExtremumRead, extremumMonotone, pushVia, fullRef, applyPackInto, custodyLsRefs, qById, query, authorKeygen, attestedRead, certSign, count, sum, pendingConflicts, spatialBboxParams, spatialWithin, extremum, nomosActive, refusedRefName;
|
|
1415
1415
|
var init_engine = __esm({
|
|
1416
1416
|
"../adapter/engine.mjs"() {
|
|
1417
1417
|
init_git_fs();
|
|
@@ -1494,6 +1494,7 @@ var init_engine = __esm({
|
|
|
1494
1494
|
branch: BRANCH,
|
|
1495
1495
|
queryBytes: b64Json({ op: "attestedRead", queryId, paramsJson: paramsJson || "{}", attestorSecret, nowMs: nowMs ?? Date.now(), sourceWorkspace: ws, ...includeRosterProof ? { includeRosterProof: true } : {} })
|
|
1496
1496
|
}, eng.STDERR));
|
|
1497
|
+
certSign = (eng, { child, founder, verified, parentKey, parentId, epoch, secret }) => JSON.parse(call(eng.ex, "query", { queryBytes: b64Json({ op: "certSign", child, founder, verified, parentKey, parentId, epoch, secret }) }, eng.STDERR)).cert;
|
|
1497
1498
|
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));
|
|
1498
1499
|
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));
|
|
1499
1500
|
pendingConflicts = (eng, ws, principal = "") => JSON.parse(call(eng.ex, "query", { repoArg: repoArgOf(ws), workspace: ws, queryBytes: b64Json({ op: "pendingConflicts" }), principal, branch: BRANCH }, eng.STDERR));
|
|
@@ -1512,6 +1513,7 @@ var init_engine = __esm({
|
|
|
1512
1513
|
var bootstrap_exports = {};
|
|
1513
1514
|
__export(bootstrap_exports, {
|
|
1514
1515
|
bootstrapPlatform: () => bootstrapPlatform,
|
|
1516
|
+
homeDomainOf: () => homeDomainOf,
|
|
1515
1517
|
isTestMint: () => isTestMint
|
|
1516
1518
|
});
|
|
1517
1519
|
import { readFileSync } from "node:fs";
|
|
@@ -1523,6 +1525,17 @@ function isTestMint(eng) {
|
|
|
1523
1525
|
return !/poisoned|unknown|adapter-visible API/.test(String(e && e.message || e));
|
|
1524
1526
|
}
|
|
1525
1527
|
}
|
|
1528
|
+
function homeDomainOf(opts) {
|
|
1529
|
+
if (!opts || !opts.deploy) return null;
|
|
1530
|
+
try {
|
|
1531
|
+
const body = JSON.parse(readFileSync(opts.deploy, "utf8"));
|
|
1532
|
+
const domains = body.summary && body.summary.domains || [];
|
|
1533
|
+
const hit = domains.find((d) => Array.isArray(d.directives) && d.directives.includes("seedBirthAttestation"));
|
|
1534
|
+
return hit ? hit.domain : null;
|
|
1535
|
+
} catch {
|
|
1536
|
+
return null;
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1526
1539
|
async function bootstrapPlatform(dev, opts) {
|
|
1527
1540
|
const { eng, custody, ledgerFor, serialize, origin } = dev;
|
|
1528
1541
|
const platform = opts.platform || "co2-platform-local";
|
|
@@ -1535,20 +1548,23 @@ async function bootstrapPlatform(dev, opts) {
|
|
|
1535
1548
|
if (opts.deploy) {
|
|
1536
1549
|
const body = JSON.parse(readFileSync(opts.deploy, "utf8"));
|
|
1537
1550
|
const usda = body.packageUsda || body.usda;
|
|
1538
|
-
if (!usda) {
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
log2(`WARN platform law deploy refused: ${String(e && e.message || e).slice(0, 200)}`);
|
|
1551
|
+
if (!usda) throw new Error(`--deploy ${opts.deploy} has no packageUsda (nothing to install)`);
|
|
1552
|
+
let deployErr = null;
|
|
1553
|
+
await serialize(async () => {
|
|
1554
|
+
const ledger = ledgerFor(platform);
|
|
1555
|
+
const domainHash = await sha256hex(usda);
|
|
1556
|
+
try {
|
|
1557
|
+
const out = await deploy(eng, platform, ledger, usda, domainHash, body.dispositions || null, { actor: "user:dev-admin" });
|
|
1558
|
+
if (out && out.ok === false) {
|
|
1559
|
+
deployErr = String(out.error || "the law refused the platform package");
|
|
1560
|
+
return;
|
|
1549
1561
|
}
|
|
1550
|
-
|
|
1551
|
-
|
|
1562
|
+
log2(`platform law deployed: ${domainHash.slice(0, 12)} (head ${String(out.head).slice(0, 12)})`);
|
|
1563
|
+
} catch (e) {
|
|
1564
|
+
deployErr = String(e && e.message || e);
|
|
1565
|
+
}
|
|
1566
|
+
});
|
|
1567
|
+
if (deployErr) throw new Error(`platform law deploy REFUSED: ${deployErr.slice(0, 400)}`);
|
|
1552
1568
|
} else {
|
|
1553
1569
|
log2("no --deploy given; platform runs framework law only (deploy your platform package to enable births)");
|
|
1554
1570
|
}
|
|
@@ -1559,18 +1575,71 @@ async function bootstrapPlatform(dev, opts) {
|
|
|
1559
1575
|
log2(" \u2192 re-run: NOMOS_LOCAL_WASM=<that.wasm> githolon cloud dev --platform " + platform + " --bootstrap");
|
|
1560
1576
|
log2(" Without it the platform cannot roots-at-K_root-attest home births (LEG rejected by design).");
|
|
1561
1577
|
} else {
|
|
1578
|
+
const OPERATOR = opts.operator || "user:dev-operator";
|
|
1562
1579
|
const kRoot = authorKeygen(eng);
|
|
1563
1580
|
setTestKRoot(eng, kRoot.public);
|
|
1564
1581
|
log2(`K_root ceremony: pinned LOCAL test K_root ${kRoot.public.slice(0, 16)}\u2026`);
|
|
1565
|
-
|
|
1566
|
-
|
|
1582
|
+
const sP = authorKeygen(eng);
|
|
1583
|
+
const platformCert = certSign(eng, {
|
|
1584
|
+
child: platform,
|
|
1585
|
+
founder: OPERATOR,
|
|
1586
|
+
verified: true,
|
|
1587
|
+
parentKey: sP.public,
|
|
1588
|
+
// P_P — the onboarding signer the platform vouches for
|
|
1589
|
+
parentId: "root",
|
|
1590
|
+
epoch: 0,
|
|
1591
|
+
secret: kRoot.secret
|
|
1592
|
+
// signed by S_root
|
|
1593
|
+
});
|
|
1594
|
+
const certChain = JSON.stringify({ links: [platformCert] });
|
|
1595
|
+
const homeDomain = homeDomainOf(opts) || "home";
|
|
1596
|
+
const lawKeys = await serialize(async () => {
|
|
1597
|
+
await mountWorkspace(eng, platform, ledgerFor(platform));
|
|
1598
|
+
return currentLaw(eng, platform);
|
|
1599
|
+
});
|
|
1600
|
+
const lawHash = (lawKeys || {})[homeDomain] || "";
|
|
1601
|
+
if (!lawHash) {
|
|
1602
|
+
log2(`ATTESTED BIRTHS: the deployed platform law declares no '${homeDomain}' framework domain`);
|
|
1603
|
+
log2(" (seedBirthAttestation/birthHome absent) \u2014 attested home births are not available on this platform.");
|
|
1604
|
+
dev.testKRoot = kRoot;
|
|
1605
|
+
dev.onboardingSigner = sP;
|
|
1606
|
+
} else {
|
|
1607
|
+
const seed = await serialize(async () => authorOn(
|
|
1608
|
+
eng,
|
|
1609
|
+
platform,
|
|
1610
|
+
ledgerFor(platform),
|
|
1611
|
+
homeDomain,
|
|
1612
|
+
"seedBirthAttestation",
|
|
1613
|
+
{
|
|
1614
|
+
child: platform,
|
|
1615
|
+
founder: OPERATOR,
|
|
1616
|
+
verified: "true",
|
|
1617
|
+
parentId: "root",
|
|
1618
|
+
parentKey: sP.public,
|
|
1619
|
+
epoch: 0,
|
|
1620
|
+
certChain
|
|
1621
|
+
},
|
|
1622
|
+
lawHash,
|
|
1623
|
+
{ actor: OPERATOR, principalVerified: true }
|
|
1624
|
+
));
|
|
1625
|
+
if (!seed.ok) throw new Error(`platform BirthAttestation seed REFUSED: ${String(seed.error).slice(0, 400)}`);
|
|
1626
|
+
log2(`root-attested platform: seeded BirthAttestation certChain (platform_cert signed by K_root, P_P=${sP.public.slice(0, 12)}\u2026)`);
|
|
1627
|
+
log2(" a birthHome under this platform now assembles [home_cert, u_delegation(S_P), platform_cert(K_root)] \u2014 no unwarranted-cert.");
|
|
1628
|
+
log2(" ENROLL each user at your app's enroll gate: home/enrollSigner(device key) + home/enrollDelegation(S_P-signed cert).");
|
|
1629
|
+
dev.testKRoot = kRoot;
|
|
1630
|
+
dev.onboardingSigner = sP;
|
|
1631
|
+
dev.platformCert = platformCert;
|
|
1632
|
+
dev.platformBirthAttestation = { child: platform, parentKey: sP.public, certChain };
|
|
1633
|
+
dev.homeDomain = homeDomain;
|
|
1634
|
+
}
|
|
1567
1635
|
}
|
|
1568
1636
|
if (opts.authProvider || opts.firebaseProject) {
|
|
1569
1637
|
log2(`AuthProvider: ${opts.authProvider || `firebase:${opts.firebaseProject}`} \u2014 register it via the platform's setAuthProvider governance offer;`);
|
|
1570
1638
|
log2(" the kernel verifies x-nomos-auth JWTs against the law-declared key (host stays blind).");
|
|
1571
1639
|
}
|
|
1572
|
-
|
|
1573
|
-
|
|
1640
|
+
const attested = testMint && !!dev.platformBirthAttestation;
|
|
1641
|
+
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).");
|
|
1642
|
+
return { platform, testMint, attested };
|
|
1574
1643
|
}
|
|
1575
1644
|
var log2;
|
|
1576
1645
|
var init_bootstrap = __esm({
|
|
@@ -1839,6 +1908,31 @@ function firstExisting(...paths) {
|
|
|
1839
1908
|
}
|
|
1840
1909
|
var TEST_MINT_MARKER = Buffer.from("set_test_k_root");
|
|
1841
1910
|
var isTestMintBytes = (bytes) => bytes.includes(TEST_MINT_MARKER);
|
|
1911
|
+
var KERNEL_CAPABILITY_REGISTRY = [
|
|
1912
|
+
{
|
|
1913
|
+
prefix: "846c6bf8",
|
|
1914
|
+
version: "kernel-846c6bf8",
|
|
1915
|
+
note: "production (accepts compound-key law)",
|
|
1916
|
+
features: ["compoundKeys", "capturedReads", "invariantGate", "surfacedMerge", "fieldProvenance", "nullSemantics", "attestedReads"]
|
|
1917
|
+
},
|
|
1918
|
+
{
|
|
1919
|
+
prefix: "f6e44b3a",
|
|
1920
|
+
version: "kernel-f6e44b3a",
|
|
1921
|
+
note: "test-mint (DEV) \u2014 current, feature-equivalent to production",
|
|
1922
|
+
features: ["compoundKeys", "capturedReads", "invariantGate", "surfacedMerge", "fieldProvenance", "nullSemantics", "attestedReads"]
|
|
1923
|
+
},
|
|
1924
|
+
{
|
|
1925
|
+
prefix: "f81cb952",
|
|
1926
|
+
version: "kernel-f81cb952",
|
|
1927
|
+
note: "test-mint (DEV ONLY \u2014 STALE: predates compound-key read router; superseded by f6e44b3a)",
|
|
1928
|
+
features: ["capturedReads", "invariantGate", "surfacedMerge", "fieldProvenance", "nullSemantics", "attestedReads"]
|
|
1929
|
+
}
|
|
1930
|
+
];
|
|
1931
|
+
function capabilitiesForKernelHash(hash) {
|
|
1932
|
+
const h = String(hash || "").toLowerCase();
|
|
1933
|
+
const hit = KERNEL_CAPABILITY_REGISTRY.find((e) => h.startsWith(e.prefix) || e.prefix.startsWith(h.slice(0, 8)));
|
|
1934
|
+
return hit ? { hash: h, version: hit.version, note: hit.note, features: hit.features, known: true } : { hash: h, version: null, note: "UNKNOWN kernel \u2014 not in the capability registry", features: [], known: false };
|
|
1935
|
+
}
|
|
1842
1936
|
var DEFAULT_KERNEL_SOURCE = "https://nomos.captainapp.co.uk";
|
|
1843
1937
|
async function resolveTestMintWasm(kernelSource) {
|
|
1844
1938
|
const runtimeCache = path.join(configDir(), "runtime");
|
|
@@ -2049,6 +2143,18 @@ async function startDevCloud(opts = {}) {
|
|
|
2049
2143
|
res.writeHead(200, { ...CORS, "content-type": "application/wasm", "cache-control": "no-store", "x-nomos-kernel": kernelKind, "x-nomos-kernel-sha": kernelSha });
|
|
2050
2144
|
return res.end(Buffer.from(wasmBytes));
|
|
2051
2145
|
}
|
|
2146
|
+
if (url.pathname === "/v1/runtime/capabilities") {
|
|
2147
|
+
const stamp = capabilitiesForKernelHash(kernelSha);
|
|
2148
|
+
return sendJson(res, {
|
|
2149
|
+
ok: true,
|
|
2150
|
+
prod: stamp,
|
|
2151
|
+
// the dev cloud serves ONE kernel; it is what holon.wasm returns
|
|
2152
|
+
testmint: kernelKind === "test-mint" ? stamp : null,
|
|
2153
|
+
kernelKind,
|
|
2154
|
+
expectedBundleVersion: 1,
|
|
2155
|
+
vocabulary: KERNEL_CAPABILITY_REGISTRY.flatMap((e) => e.features).filter((f, i, a) => a.indexOf(f) === i).sort()
|
|
2156
|
+
});
|
|
2157
|
+
}
|
|
2052
2158
|
if (url.pathname === "/v1/runtime/packages") {
|
|
2053
2159
|
return sendJson(res, { bootstrap: bootstrapPkg, nomos: nomosPkg });
|
|
2054
2160
|
}
|
|
@@ -2469,10 +2575,30 @@ if (import.meta.url === `file://${process.argv[1]}`) {
|
|
|
2469
2575
|
console.log(`[dev-cloud] Nomos dev cloud listening on ${dev.origin}`);
|
|
2470
2576
|
console.log(`[dev-cloud] data dir : ${dev.dataDir}`);
|
|
2471
2577
|
console.log(`[dev-cloud] kernel : ${dev.kernelSha.slice(0, 16)}\u2026`);
|
|
2578
|
+
{
|
|
2579
|
+
const stamp = capabilitiesForKernelHash(dev.kernelSha);
|
|
2580
|
+
if (stamp.known) {
|
|
2581
|
+
console.log(`[dev-cloud] caps : ${stamp.version} \u2014 [${stamp.features.join(", ")}]`);
|
|
2582
|
+
if (/STALE/.test(stamp.note || "")) {
|
|
2583
|
+
console.log(`[dev-cloud] \u26A0 STALE KERNEL: ${stamp.note}. Law using compound-key queries will be REFUSED here.`);
|
|
2584
|
+
console.log(`[dev-cloud] Update the dev kernel (holon-testmint.wasm) to a build coherent with your compiler/release.`);
|
|
2585
|
+
}
|
|
2586
|
+
} else {
|
|
2587
|
+
console.log(`[dev-cloud] \u26A0 caps : kernel ${dev.kernelSha.slice(0, 8)} is UNKNOWN to the capability registry \u2014 coherence cannot be verified.`);
|
|
2588
|
+
}
|
|
2589
|
+
console.log(`[dev-cloud] coherence: GET ${dev.origin}/v1/runtime/capabilities`);
|
|
2590
|
+
}
|
|
2472
2591
|
console.log(`[dev-cloud] point your Flutter app's cloud: base URL at ${dev.origin}`);
|
|
2473
2592
|
if (opts.bootstrap || opts.platform) {
|
|
2474
2593
|
const { bootstrapPlatform: bootstrapPlatform2 } = await Promise.resolve().then(() => (init_bootstrap(), bootstrap_exports));
|
|
2475
|
-
|
|
2594
|
+
try {
|
|
2595
|
+
await bootstrapPlatform2(dev, opts);
|
|
2596
|
+
} catch (e) {
|
|
2597
|
+
console.error("[dev-cloud] bootstrap FAILED:", String(e && e.message || e));
|
|
2598
|
+
await dev.close().catch(() => {
|
|
2599
|
+
});
|
|
2600
|
+
process.exit(1);
|
|
2601
|
+
}
|
|
2476
2602
|
}
|
|
2477
2603
|
process.on("SIGINT", async () => {
|
|
2478
2604
|
await dev.close();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "githolon",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.93.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.93.0",
|
|
33
|
+
"@githolon/dsl": "^0.93.0",
|
|
34
34
|
"isomorphic-git": "^1.38.4"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|