githolon 0.99.0 → 0.100.1
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 +321 -191
- package/dist/dev-server.mjs +15 -1
- package/package.json +3 -3
package/dist/cli.mjs
CHANGED
|
@@ -3098,6 +3098,8 @@ __export(governance_exports, {
|
|
|
3098
3098
|
certifyEra: () => certifyEra,
|
|
3099
3099
|
consentRebirth: () => consentRebirth,
|
|
3100
3100
|
discoverSigningDomain: () => discoverSigningDomain,
|
|
3101
|
+
ensureSovereignHome: () => ensureSovereignHome,
|
|
3102
|
+
exchangeOnboardingToken: () => exchangeOnboardingToken,
|
|
3101
3103
|
executeRepairRebirth: () => executeRepairRebirth,
|
|
3102
3104
|
governanceOffer: () => governanceOffer,
|
|
3103
3105
|
governanceRelay: () => governanceRelay,
|
|
@@ -3120,6 +3122,8 @@ __export(governance_exports, {
|
|
|
3120
3122
|
resolveGovernancePrincipal: () => resolveGovernancePrincipal,
|
|
3121
3123
|
signAndPostGovernance: () => signAndPostGovernance,
|
|
3122
3124
|
signAndPostOffer: () => signAndPostOffer,
|
|
3125
|
+
signAndPostWorkspaceBirth: () => signAndPostWorkspaceBirth,
|
|
3126
|
+
signAndPostWorkspaceRetirement: () => signAndPostWorkspaceRetirement,
|
|
3123
3127
|
validatePlanForApply: () => validatePlanForApply,
|
|
3124
3128
|
verifyWorkspaceVerdict: () => verifyWorkspaceVerdict
|
|
3125
3129
|
});
|
|
@@ -3195,28 +3199,239 @@ function canonicalPrincipal(principal) {
|
|
|
3195
3199
|
return s.includes(":") ? s : `user:${s}`;
|
|
3196
3200
|
}
|
|
3197
3201
|
async function signAndPostOffer(ws, domain, directiveId, payload, opts) {
|
|
3202
|
+
return signAndPostPreparedOffer(ws, domain, () => ({ directiveId, payload }), opts);
|
|
3203
|
+
}
|
|
3204
|
+
async function signAndPostPreparedOffer(ws, domain, prepare, opts, authorMode = "account", preferActor) {
|
|
3198
3205
|
const cloud = cloudBase(opts.cloud);
|
|
3199
3206
|
const principal = resolveGovernancePrincipal(opts);
|
|
3200
3207
|
const holon = await connectGovernance(cloud, ws);
|
|
3201
|
-
const resolvedDomain = domain ?? await discoverSigningDomain(holon, ws, directiveId, void 0);
|
|
3202
3208
|
const device = await ensureDeviceKey(holon, principal);
|
|
3209
|
+
const accountActor = canonicalPrincipal(principal);
|
|
3210
|
+
const keyActor = `key:${device.keyHash}`;
|
|
3211
|
+
let actor = accountActor;
|
|
3212
|
+
if (preferActor !== void 0 && preferActor === keyActor) {
|
|
3213
|
+
actor = keyActor;
|
|
3214
|
+
} else if (preferActor !== void 0 && sameIdentity(preferActor, accountActor)) {
|
|
3215
|
+
actor = accountActor;
|
|
3216
|
+
} else if (authorMode === "self-if-unenrolled" && typeof holon.parentSignerEnrollment === "function") {
|
|
3217
|
+
try {
|
|
3218
|
+
const posture = await holon.parentSignerEnrollment({ parent: ws, principal: accountActor, keyHash: device.keyHash });
|
|
3219
|
+
if (!posture.enrolled) actor = keyActor;
|
|
3220
|
+
} catch {
|
|
3221
|
+
}
|
|
3222
|
+
}
|
|
3223
|
+
const prepared = prepare(actor);
|
|
3224
|
+
const resolvedDomain = domain ?? await discoverSigningDomain(holon, ws, prepared.directiveId, void 0);
|
|
3203
3225
|
const sealed = await holon.signGovernanceOffer({
|
|
3204
3226
|
domain: resolvedDomain,
|
|
3205
|
-
directiveId,
|
|
3206
|
-
payload,
|
|
3227
|
+
directiveId: prepared.directiveId,
|
|
3228
|
+
payload: prepared.payload,
|
|
3207
3229
|
authorSecret: device.secret,
|
|
3208
|
-
actor
|
|
3230
|
+
actor
|
|
3209
3231
|
});
|
|
3210
3232
|
if (sealed.intentBytes.length > STAGE_THRESHOLD_CHARS) {
|
|
3211
|
-
const staged = await relaySealedOfferViaStage(cloud, ws, directiveId, sealed.intentBytes, fetch);
|
|
3233
|
+
const staged = await relaySealedOfferViaStage(cloud, ws, prepared.directiveId, sealed.intentBytes, fetch);
|
|
3212
3234
|
if (staged !== null) {
|
|
3213
3235
|
out2(` staged ${staged.size} sealed bytes content-addressed (sha256 ${staged.sha256.slice(0, 16)}\u2026) \u2014 the signed offer names the hash`);
|
|
3214
|
-
return { ...staged.verdict, principal };
|
|
3236
|
+
return { ...staged.verdict, principal, actor, directiveId: prepared.directiveId };
|
|
3215
3237
|
}
|
|
3216
3238
|
err2(`this cloud has no /v2/stage content-addressed lane \u2014 relaying the ${sealed.intentBytes.length}-char sealed offer inline (a 413 here means the worker needs upgrading to accept law this large signed)`);
|
|
3217
3239
|
}
|
|
3218
|
-
const verdict = await holon.postGovernanceOffer({ directiveId, intentBytes: sealed.intentBytes, ws, domain: resolvedDomain });
|
|
3219
|
-
return { ...verdict, principal };
|
|
3240
|
+
const verdict = await holon.postGovernanceOffer({ directiveId: prepared.directiveId, intentBytes: sealed.intentBytes, ws, domain: resolvedDomain });
|
|
3241
|
+
return { ...verdict, principal, actor, directiveId: prepared.directiveId };
|
|
3242
|
+
}
|
|
3243
|
+
async function signAndPostWorkspaceBirth(parent, name, opts) {
|
|
3244
|
+
return signAndPostPreparedOffer(
|
|
3245
|
+
parent,
|
|
3246
|
+
"workspaces",
|
|
3247
|
+
(actor) => {
|
|
3248
|
+
const identity = lineageIdentity(actor);
|
|
3249
|
+
return {
|
|
3250
|
+
directiveId: "createWorkspace",
|
|
3251
|
+
payload: {
|
|
3252
|
+
name,
|
|
3253
|
+
tier: "edge",
|
|
3254
|
+
parent: parent === "root" ? "" : parent,
|
|
3255
|
+
principal: identity,
|
|
3256
|
+
requestedBy: identity,
|
|
3257
|
+
requestedAt: Date.now()
|
|
3258
|
+
}
|
|
3259
|
+
};
|
|
3260
|
+
},
|
|
3261
|
+
opts,
|
|
3262
|
+
"self-if-unenrolled"
|
|
3263
|
+
);
|
|
3264
|
+
}
|
|
3265
|
+
async function exchangeOnboardingToken(session, keyHash, idp = process.env["NOMOS_ONBOARDING_IDP"] ?? DEFAULT_ONBOARDING_IDP, fetchImpl = fetch) {
|
|
3266
|
+
const r = await fetchImpl(`${idp.replace(/\/+$/, "")}/token`, {
|
|
3267
|
+
method: "POST",
|
|
3268
|
+
headers: { authorization: `Bearer ${session}`, "content-type": "application/json" },
|
|
3269
|
+
body: JSON.stringify({ nonce: keyHash })
|
|
3270
|
+
});
|
|
3271
|
+
const body = await r.json().catch(() => null);
|
|
3272
|
+
if (!r.ok || typeof body?.token !== "string" || typeof body.issuer !== "string" || typeof body.subject !== "string") {
|
|
3273
|
+
throw new Error(
|
|
3274
|
+
`Nomos could not establish the first device identity (${r.status}): ${String(body?.error ?? "invalid identity-provider response")}`
|
|
3275
|
+
);
|
|
3276
|
+
}
|
|
3277
|
+
return { token: body.token, issuer: body.issuer, subject: body.subject };
|
|
3278
|
+
}
|
|
3279
|
+
async function ensureSovereignHome(opts = {}) {
|
|
3280
|
+
const cloud = cloudBase(opts.cloud);
|
|
3281
|
+
const uid = opts.principal ?? currentPrincipal();
|
|
3282
|
+
if (!uid) throw new Error("a Nomos session is required \u2014 githolon login --agent");
|
|
3283
|
+
const actor = canonicalPrincipal(uid);
|
|
3284
|
+
if (!actor.startsWith("user:")) throw new Error("blank-session bootstrap requires an identity-provider principal");
|
|
3285
|
+
const bare = actor.slice("user:".length);
|
|
3286
|
+
const auth = await sessionToken();
|
|
3287
|
+
if (!auth) throw new Error("blank-session bootstrap needs the live login session \u2014 githolon login --agent");
|
|
3288
|
+
const client = await import("@githolon/client");
|
|
3289
|
+
const home = await client.homeNameOf(actor);
|
|
3290
|
+
const exists = await fetch(`${cloud}/v2/workspaces/${encodeURIComponent(home)}`).then((r) => r.ok).catch(() => false);
|
|
3291
|
+
const root = await connectGovernance(cloud, "root");
|
|
3292
|
+
const device = await ensureDeviceKey(root, bare);
|
|
3293
|
+
let signerReady = false;
|
|
3294
|
+
if (typeof root.parentSignerEnrollment === "function") {
|
|
3295
|
+
signerReady = await root.parentSignerEnrollment({ parent: "root", principal: actor, keyHash: device.keyHash, authToken: auth }).then((p) => p.enrolled && p.revoked !== true).catch(() => false);
|
|
3296
|
+
}
|
|
3297
|
+
const delegationReady = await fetch(
|
|
3298
|
+
`${cloud}/v2/workspaces/root/workspaces/signerDelegationByUser?user=${encodeURIComponent(actor)}`
|
|
3299
|
+
).then(async (r) => {
|
|
3300
|
+
if (!r.ok) return false;
|
|
3301
|
+
const d = await r.json();
|
|
3302
|
+
return Array.isArray(d.rows) && d.rows.length > 0;
|
|
3303
|
+
}).catch(() => false);
|
|
3304
|
+
if (!signerReady || !delegationReady) {
|
|
3305
|
+
if (typeof root.enrollFirstDevice !== "function") {
|
|
3306
|
+
throw new Error("the installed @githolon/client predates automatic first-device enrollment");
|
|
3307
|
+
}
|
|
3308
|
+
const assertion = await exchangeOnboardingToken(auth, device.keyHash);
|
|
3309
|
+
if (assertion.subject !== bare) {
|
|
3310
|
+
throw new Error(`identity provider returned '${assertion.subject}' for logged-in principal '${bare}'`);
|
|
3311
|
+
}
|
|
3312
|
+
await root.enrollFirstDevice({
|
|
3313
|
+
parent: "root",
|
|
3314
|
+
domain: "workspaces",
|
|
3315
|
+
principal: actor,
|
|
3316
|
+
device,
|
|
3317
|
+
idToken: assertion.token,
|
|
3318
|
+
authToken: assertion.token,
|
|
3319
|
+
verifiedVia: assertion.issuer
|
|
3320
|
+
});
|
|
3321
|
+
}
|
|
3322
|
+
if (!exists) {
|
|
3323
|
+
const domains = await fetch(`${cloud}/v2/workspaces/root/domains`).then(async (r) => {
|
|
3324
|
+
if (!r.ok) throw new Error(`root law discovery failed (${r.status})`);
|
|
3325
|
+
return await r.json();
|
|
3326
|
+
});
|
|
3327
|
+
const frameworkHash = domains.currentLaw?.["nomos"];
|
|
3328
|
+
const lawHash = domains.currentLaw?.["workspaces"];
|
|
3329
|
+
if (!frameworkHash || !lawHash) throw new Error("root does not report the framework and governance laws needed for birth");
|
|
3330
|
+
const birthCert = await root.certSign({
|
|
3331
|
+
child: home,
|
|
3332
|
+
founder: actor,
|
|
3333
|
+
verified: true,
|
|
3334
|
+
parentKey: device.public,
|
|
3335
|
+
parentId: "root",
|
|
3336
|
+
epoch: 0,
|
|
3337
|
+
secret: device.secret
|
|
3338
|
+
});
|
|
3339
|
+
const now = Date.now();
|
|
3340
|
+
const birth = await fetch(`${cloud}/v2/workspaces/root/workspaces/birthChild`, {
|
|
3341
|
+
method: "POST",
|
|
3342
|
+
headers: { "content-type": "application/json" },
|
|
3343
|
+
body: JSON.stringify({
|
|
3344
|
+
name: home,
|
|
3345
|
+
parent: "",
|
|
3346
|
+
principal: bare,
|
|
3347
|
+
tier: "edge",
|
|
3348
|
+
requestedBy: bare,
|
|
3349
|
+
requestedAt: now,
|
|
3350
|
+
foundingAdminHash: device.keyHash,
|
|
3351
|
+
bornAt: new Date(now).toISOString(),
|
|
3352
|
+
frameworkHash,
|
|
3353
|
+
lawHash,
|
|
3354
|
+
platformCert: JSON.stringify(birthCert),
|
|
3355
|
+
actor,
|
|
3356
|
+
authorSecret: device.secret
|
|
3357
|
+
})
|
|
3358
|
+
});
|
|
3359
|
+
const body = await birth.json().catch(() => null);
|
|
3360
|
+
const failed = body?.birthOutcomes?.find((o) => o.status !== "born");
|
|
3361
|
+
if (!birth.ok || body?.ok === false || failed) {
|
|
3362
|
+
throw new Error(
|
|
3363
|
+
`Nomos could not birth the session home (${birth.status}): ${failed?.reason ?? String(body?.error ?? JSON.stringify(body))}`
|
|
3364
|
+
);
|
|
3365
|
+
}
|
|
3366
|
+
const deadline = Date.now() + 3e4;
|
|
3367
|
+
while (Date.now() < deadline) {
|
|
3368
|
+
if (await fetch(`${cloud}/v2/workspaces/${encodeURIComponent(home)}`).then((r) => r.ok).catch(() => false)) break;
|
|
3369
|
+
await new Promise((resolve6) => setTimeout(resolve6, 250));
|
|
3370
|
+
}
|
|
3371
|
+
if (!await fetch(`${cloud}/v2/workspaces/${encodeURIComponent(home)}`).then((r) => r.ok).catch(() => false)) {
|
|
3372
|
+
throw new Error(`Nomos admitted the birth of '${home}' but its custody did not become readable`);
|
|
3373
|
+
}
|
|
3374
|
+
const admin = await signAndPostOffer(
|
|
3375
|
+
home,
|
|
3376
|
+
"workspaces",
|
|
3377
|
+
"grantAdmin",
|
|
3378
|
+
{ principal: bare, label: "founding admin", grantedBy: bare, grantedAt: now },
|
|
3379
|
+
{ ...opts, principal: bare }
|
|
3380
|
+
);
|
|
3381
|
+
if (!admin.ok) throw new Error(`the born home refused its founding admin (${admin.status}): ${JSON.stringify(admin.body)}`);
|
|
3382
|
+
}
|
|
3383
|
+
const homeHolon = await connectGovernance(cloud, home);
|
|
3384
|
+
const homeSigner = typeof homeHolon.parentSignerEnrollment === "function" ? await homeHolon.parentSignerEnrollment({ parent: home, principal: actor, keyHash: device.keyHash, authToken: auth }).catch(() => null) : null;
|
|
3385
|
+
if (!homeSigner?.verifiedVia) {
|
|
3386
|
+
if (typeof homeHolon.enrollFirstDevice !== "function") {
|
|
3387
|
+
throw new Error("the installed @githolon/client predates verified session-home enrollment");
|
|
3388
|
+
}
|
|
3389
|
+
const assertion = await exchangeOnboardingToken(auth, device.keyHash);
|
|
3390
|
+
if (assertion.subject !== bare) {
|
|
3391
|
+
throw new Error(`identity provider returned '${assertion.subject}' for logged-in principal '${bare}'`);
|
|
3392
|
+
}
|
|
3393
|
+
const domain = await discoverSigningDomain(homeHolon, home, "enrollFirstDevice", "workspaces");
|
|
3394
|
+
await homeHolon.enrollFirstDevice({
|
|
3395
|
+
parent: home,
|
|
3396
|
+
domain,
|
|
3397
|
+
principal: actor,
|
|
3398
|
+
device,
|
|
3399
|
+
idToken: assertion.token,
|
|
3400
|
+
authToken: assertion.token,
|
|
3401
|
+
verifiedVia: assertion.issuer,
|
|
3402
|
+
includeDelegation: false
|
|
3403
|
+
});
|
|
3404
|
+
const object = `identity:${actor}`;
|
|
3405
|
+
const deadline = Date.now() + 3e4;
|
|
3406
|
+
let visible = false;
|
|
3407
|
+
while (Date.now() < deadline) {
|
|
3408
|
+
visible = await fetch(
|
|
3409
|
+
`${cloud}/v2/workspaces/${encodeURIComponent(home)}/workspaces/relationTuplesByObject?object=${encodeURIComponent(object)}`
|
|
3410
|
+
).then(async (r) => {
|
|
3411
|
+
if (!r.ok) return false;
|
|
3412
|
+
const body = await r.json();
|
|
3413
|
+
const leaf = body.rows?.[0]?.data?.subjects?.[`key:${device.keyHash}`];
|
|
3414
|
+
return typeof leaf?.verifiedVia === "string" && leaf.verifiedVia.length > 0;
|
|
3415
|
+
}).catch(() => false);
|
|
3416
|
+
if (visible) break;
|
|
3417
|
+
await new Promise((resolve6) => setTimeout(resolve6, 250));
|
|
3418
|
+
}
|
|
3419
|
+
if (!visible) throw new Error(`the session home's verified device enrollment did not become readable`);
|
|
3420
|
+
}
|
|
3421
|
+
return { home, principal: actor, device, created: !exists };
|
|
3422
|
+
}
|
|
3423
|
+
async function signAndPostWorkspaceRetirement(parent, workspaceId, creator, opts) {
|
|
3424
|
+
return signAndPostPreparedOffer(
|
|
3425
|
+
parent,
|
|
3426
|
+
"workspaces",
|
|
3427
|
+
(actor) => ({
|
|
3428
|
+
directiveId: creator !== "" && sameIdentity(creator, actor) ? "retireOwnWorkspace" : "retireWorkspace",
|
|
3429
|
+
payload: { workspaceId, retiredBy: lineageIdentity(actor), retiredAt: Date.now() }
|
|
3430
|
+
}),
|
|
3431
|
+
opts,
|
|
3432
|
+
"self-if-unenrolled",
|
|
3433
|
+
creator
|
|
3434
|
+
);
|
|
3220
3435
|
}
|
|
3221
3436
|
async function relaySealedOfferViaStage(cloud, ws, directiveId, intentBytesB64, fetchImpl) {
|
|
3222
3437
|
const raw = Buffer.from(intentBytesB64, "base64");
|
|
@@ -4517,13 +4732,16 @@ function readSealedIntentBytes(eng, ws, intentOut) {
|
|
|
4517
4732
|
if (f?.data === void 0) return void 0;
|
|
4518
4733
|
return Buffer.from(f.data).toString("base64");
|
|
4519
4734
|
}
|
|
4520
|
-
var out2, err2, STAGE_THRESHOLD_CHARS, HONEST_CEILING, ROOT_CUSTODIAN_SECRET, CLIENT_IMPACT;
|
|
4735
|
+
var out2, err2, lineageIdentity, sameIdentity, DEFAULT_ONBOARDING_IDP, STAGE_THRESHOLD_CHARS, HONEST_CEILING, ROOT_CUSTODIAN_SECRET, CLIENT_IMPACT;
|
|
4521
4736
|
var init_governance = __esm({
|
|
4522
4737
|
"src/governance.ts"() {
|
|
4523
4738
|
"use strict";
|
|
4524
4739
|
init_cloud();
|
|
4525
4740
|
out2 = (s) => void process.stdout.write(s + "\n");
|
|
4526
4741
|
err2 = (s) => void process.stderr.write("error: " + s + "\n");
|
|
4742
|
+
lineageIdentity = (actor) => actor.startsWith("user:") ? actor.slice("user:".length) : actor;
|
|
4743
|
+
sameIdentity = (a, b) => lineageIdentity(a) === lineageIdentity(b);
|
|
4744
|
+
DEFAULT_ONBOARDING_IDP = "https://id.nomos.captainapp.co.uk";
|
|
4527
4745
|
STAGE_THRESHOLD_CHARS = 4 * 1024 * 1024;
|
|
4528
4746
|
HONEST_CEILING = `The operator controls root's law and could deploy law removing the consent check \u2014 but that act is itself a signed, ordered, permanent fact in root's chain, visible to every tenant running \`replay root\`, and grounds for exit-with-everything. Not "we can't" \u2014 "we can't secretly, and you can always leave."`;
|
|
4529
4747
|
ROOT_CUSTODIAN_SECRET = "nomos-root-custodian-key";
|
|
@@ -5181,16 +5399,10 @@ async function logout() {
|
|
|
5181
5399
|
async function wsCreate(name, opts) {
|
|
5182
5400
|
const cloud = cloudBase(opts.cloud);
|
|
5183
5401
|
if (opts.via !== void 0) {
|
|
5184
|
-
const {
|
|
5402
|
+
const { signAndPostWorkspaceBirth: signAndPostWorkspaceBirth2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
5185
5403
|
let v;
|
|
5186
5404
|
try {
|
|
5187
|
-
|
|
5188
|
-
v = await signAndPostGovernance2(
|
|
5189
|
-
opts.via,
|
|
5190
|
-
"createWorkspace",
|
|
5191
|
-
{ name, tier: "edge", parent: opts.via === "root" ? "" : opts.via, principal: principal2, requestedBy: principal2, requestedAt: Date.now() },
|
|
5192
|
-
opts
|
|
5193
|
-
);
|
|
5405
|
+
v = await signAndPostWorkspaceBirth2(opts.via, name, opts);
|
|
5194
5406
|
} catch (e) {
|
|
5195
5407
|
err4(e.message);
|
|
5196
5408
|
return 1;
|
|
@@ -5259,7 +5471,7 @@ async function wsStatus(name, opts) {
|
|
|
5259
5471
|
}
|
|
5260
5472
|
async function wsRetire(ws, opts) {
|
|
5261
5473
|
const cloud = cloudBase(opts.cloud);
|
|
5262
|
-
const {
|
|
5474
|
+
const { signAndPostWorkspaceRetirement: signAndPostWorkspaceRetirement2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
5263
5475
|
const parent = opts.parent ?? "root";
|
|
5264
5476
|
let record;
|
|
5265
5477
|
try {
|
|
@@ -5280,12 +5492,8 @@ async function wsRetire(ws, opts) {
|
|
|
5280
5492
|
}
|
|
5281
5493
|
let v;
|
|
5282
5494
|
try {
|
|
5283
|
-
const principal = resolveGovernancePrincipal2(opts);
|
|
5284
|
-
const payload = { workspaceId: recordId, retiredBy: principal, retiredAt: Date.now() };
|
|
5285
|
-
const bare = (s) => s.startsWith("user:") ? s.slice(5) : s;
|
|
5286
5495
|
const creator = record?.data?.createdBy ?? record?.data?.principal ?? "";
|
|
5287
|
-
|
|
5288
|
-
v = await signAndPostGovernance2(parent, own ? "retireOwnWorkspace" : "retireWorkspace", payload, opts);
|
|
5496
|
+
v = await signAndPostWorkspaceRetirement2(parent, recordId, creator, opts);
|
|
5289
5497
|
} catch (e) {
|
|
5290
5498
|
err4(e.message);
|
|
5291
5499
|
return 1;
|
|
@@ -6083,7 +6291,11 @@ async function runChildBirthLeg(eng, ws, lawHash, cb, frameworkHash) {
|
|
|
6083
6291
|
const checks = downgraded.certChecks !== void 0 ? ` certChecks=${JSON.stringify(downgraded.certChecks)}` : "";
|
|
6084
6292
|
lines.push(`\u26A0 child ${childWs} was born UNWARRANTED \u2014 ${String(downgraded.reason ?? "cert not seeded")}${checks}`);
|
|
6085
6293
|
}
|
|
6086
|
-
|
|
6294
|
+
if (cb.businessAggregateId !== void 0) {
|
|
6295
|
+
lines.push(`\u2713 birth(${cb.businessAggregateId}) \u2014 business facts became a durable holon`);
|
|
6296
|
+
} else {
|
|
6297
|
+
lines.push(`\u2713 child birth ${cb.parentDomain}/${cb.birthDirectiveId} \u2014 ${childWs} born (the offer-effect folded the child genesis through the child's OWN gate)`);
|
|
6298
|
+
}
|
|
6087
6299
|
const installed = (hash) => {
|
|
6088
6300
|
try {
|
|
6089
6301
|
return qById(eng, childWs, `domain-installation:${hash}`).length > 0;
|
|
@@ -6097,7 +6309,11 @@ async function runChildBirthLeg(eng, ws, lawHash, cb, frameworkHash) {
|
|
|
6097
6309
|
if (!installed(lawHash)) {
|
|
6098
6310
|
return done(false, `the born child ${childWs} did not install the child law in-chain (domain-installation:${lawHash.slice(0, 12)}\u2026 absent) \u2014 the genesis nomos/installDomain did not fold (by-hash byte routing failed: does the parent fold this law?)`);
|
|
6099
6311
|
}
|
|
6100
|
-
|
|
6312
|
+
if (cb.businessAggregateId !== void 0) {
|
|
6313
|
+
lines.push(`\u2713 law travelled with ${cb.businessAggregateId} and admitted its first business fact`);
|
|
6314
|
+
} else {
|
|
6315
|
+
lines.push(`\u2713 the born child installed the framework + child law IN-CHAIN (the genesis installDomain\xD72 folded)`);
|
|
6316
|
+
}
|
|
6101
6317
|
let seedRows = [];
|
|
6102
6318
|
if (cb.childSeedInstanceId !== void 0) {
|
|
6103
6319
|
try {
|
|
@@ -6116,7 +6332,9 @@ async function runChildBirthLeg(eng, ws, lawHash, cb, frameworkHash) {
|
|
|
6116
6332
|
if ((cb.childSeedInstanceId !== void 0 || cb.childQuery !== void 0) && seedRows.length < 1) {
|
|
6117
6333
|
return done(false, `the born child ${childWs} did not seed ${cb.childSeedAggregateId ?? "its genesis record"} (${cb.childSeedDirectiveId} produced no readable row) \u2014 the child genesis seed did not run`);
|
|
6118
6334
|
}
|
|
6119
|
-
|
|
6335
|
+
if (cb.businessAggregateId === void 0) {
|
|
6336
|
+
lines.push(`\u2713 the born child's genesis seed ran \u2014 ${cb.childSeedDirectiveId} produced ${seedRows.length} readable ${cb.childSeedAggregateId ?? "row"}(s) in ${childWs}`);
|
|
6337
|
+
}
|
|
6120
6338
|
let verdict;
|
|
6121
6339
|
try {
|
|
6122
6340
|
verdict = verifyChainLocal(eng, childWs);
|
|
@@ -6126,7 +6344,11 @@ async function runChildBirthLeg(eng, ws, lawHash, cb, frameworkHash) {
|
|
|
6126
6344
|
if (verdict.valid !== true) {
|
|
6127
6345
|
return done(false, `the born child ${childWs} FAILED verify_chain at ${verdict.check ?? "?"}${verdict.atIndex !== void 0 ? ` (intent ${verdict.atIndex})` : ""}: ${verdict.error ?? "invalid"} \u2014 the child's own gate refused its genesis`);
|
|
6128
6346
|
}
|
|
6129
|
-
|
|
6347
|
+
if (cb.businessAggregateId !== void 0) {
|
|
6348
|
+
lines.push(`\u2713 full history replayed green locally (${verdict.plansRerun ?? "?"} plans re-run)`);
|
|
6349
|
+
} else {
|
|
6350
|
+
lines.push(`\u2713 verify_chain GREEN on the born child ${childWs} (${verdict.plansRerun ?? "?"} plans re-run \u2014 it self-validates from intent 0 through its OWN gate)`);
|
|
6351
|
+
}
|
|
6130
6352
|
const bornEntry = (res.born ?? []).find((b) => b?.workspace === childWs);
|
|
6131
6353
|
const packed = packBornChildren(eng, bornEntry === void 0 ? [] : [bornEntry]);
|
|
6132
6354
|
const childPack = packed.find((b) => b.workspace === childWs);
|
|
@@ -6148,7 +6370,11 @@ async function runChildBirthLeg(eng, ws, lawHash, cb, frameworkHash) {
|
|
|
6148
6370
|
return done(false, `the recovered child ${childWs} verified but its business root ${cb.childSeedInstanceId} was missing`);
|
|
6149
6371
|
}
|
|
6150
6372
|
}
|
|
6151
|
-
|
|
6373
|
+
if (cb.businessAggregateId !== void 0) {
|
|
6374
|
+
lines.push(`\u2713 persistence + recovery \u2014 evicted, restored from durable custody, and ${cb.businessAggregateId} read back`);
|
|
6375
|
+
} else {
|
|
6376
|
+
lines.push(`\u2713 persistence + recovery \u2014 child custody packed, resident copy discarded, verify_chain GREEN and ${cb.childSeedInstanceId ?? cb.childSeedAggregateId ?? "the business root"} readable after reopen`);
|
|
6377
|
+
}
|
|
6152
6378
|
return done(true);
|
|
6153
6379
|
}
|
|
6154
6380
|
function seatRelationAuthority(eng, ws, lawHash, rb, actor, stamp, lines, authorSecret, subjectActor = actor) {
|
|
@@ -6388,7 +6614,7 @@ async function runOfflineProofStandalone(proofPath, cloud, domain) {
|
|
|
6388
6614
|
}
|
|
6389
6615
|
const deployBody = JSON.parse(readFileSync7(deployFile, "utf8"));
|
|
6390
6616
|
const lawHash = await sha256hex(deployBody.packageUsda);
|
|
6391
|
-
console.log(`githolon proof \u2014
|
|
6617
|
+
console.log(`githolon proof \u2014 generated business proof in the real local engine`);
|
|
6392
6618
|
const runtimeKind = legs.childBirth !== void 0 || (legs.childBirths?.length ?? 0) > 0 ? "test-mint" : "production";
|
|
6393
6619
|
const { eng } = await holonEngine(cloud, deployBody, "githolon-proof", runtimeKind);
|
|
6394
6620
|
const ws = "proof-offline";
|
|
@@ -6403,7 +6629,7 @@ async function runOfflineProofStandalone(proofPath, cloud, domain) {
|
|
|
6403
6629
|
}
|
|
6404
6630
|
console.log(`
|
|
6405
6631
|
OFFLINE PROOF GREEN (${Math.round(v.ms)}ms) \u2014 the same legs rerun on every save in \`githolon dev\`.`);
|
|
6406
|
-
console.log(`
|
|
6632
|
+
console.log(`Run the same generated business proof against Nomos Cloud when ready: githolon proof --live`);
|
|
6407
6633
|
return 0;
|
|
6408
6634
|
}
|
|
6409
6635
|
var keyHashOf, OFFLINE_PROOF_VERIFIER;
|
|
@@ -8822,9 +9048,9 @@ var HELP = {
|
|
|
8822
9048
|
examples: ["githolon compile", "githolon compile nomos.package.mjs --layered"]
|
|
8823
9049
|
},
|
|
8824
9050
|
proof: {
|
|
8825
|
-
usage: "githolon proof [build/<name>.proof.mts] [--domain <key>] [--live]
|
|
8826
|
-
what: "Run the proof GENERATED from your law.
|
|
8827
|
-
examples: ["githolon proof", "githolon proof --domain co2_platform", "githolon proof --live"
|
|
9051
|
+
usage: "githolon proof [build/<name>.proof.mts] [--domain <key>] [--live]",
|
|
9052
|
+
what: "Run the proof GENERATED from your business law. By default it drives the real local engine:\nbirth, full-history verification, durable custody, eviction, restore, and read-back. --live runs the\nsame business proof against Nomos Cloud; identity, provisioning, persistence, and cleanup remain\ninside Nomos. --domain selects one domain in a multi-domain package. ALL GREEN or it names the jam.",
|
|
9053
|
+
examples: ["githolon proof", "githolon proof --domain co2_platform", "githolon proof --live"]
|
|
8828
9054
|
},
|
|
8829
9055
|
dev: {
|
|
8830
9056
|
usage: "githolon dev [--port <n>] [--cloud <url>] [--once]",
|
|
@@ -8911,7 +9137,7 @@ var HELP = {
|
|
|
8911
9137
|
},
|
|
8912
9138
|
login: {
|
|
8913
9139
|
usage: "githolon login --agent | --token <refresh_token>",
|
|
8914
|
-
what: "Establish the
|
|
9140
|
+
what: "Establish the identity Nomos uses beneath birth. --agent creates a verified development identity\n(no browser; linkable later); --token adopts an existing session. Credentials auto-refresh.",
|
|
8915
9141
|
examples: ["githolon login --agent", "githolon login --token <refresh_token>"]
|
|
8916
9142
|
},
|
|
8917
9143
|
whoami: {
|
|
@@ -8932,16 +9158,14 @@ var HELP = {
|
|
|
8932
9158
|
what: "Clear the session. Stored workspace secrets are KEPT."
|
|
8933
9159
|
},
|
|
8934
9160
|
ws: {
|
|
8935
|
-
usage: "githolon ws <
|
|
8936
|
-
what: "
|
|
9161
|
+
usage: "githolon ws <status|retire|reclaim> [<name>] [--parent <ws>] [--cloud <url>] [--target <name>]",
|
|
9162
|
+
what: "Operator inspection and disposal of existing cloud custody. Application creation is not here:\ndeclare birth(Aggregate, spec) and call the generated app.birth(businessFacts). `status` inspects\nlineage and verdicts; `retire` withdraws law while retaining data; `reclaim` discards custody only\nafter retirement.",
|
|
8937
9163
|
flags: [
|
|
8938
|
-
["--principal <p>", "the birth's principal (uid or access token; remembered as the default)"],
|
|
8939
|
-
["--via <parent>", "ws create: sign a createWorkspace offer at <parent> instead of the raw birth"],
|
|
8940
9164
|
["--parent <ws>", "retire/reclaim: the governance workspace to sign against (default root)"],
|
|
8941
9165
|
["--cloud <url>", "target cloud (default: $NOMOS_CLOUD or the public cloud)"],
|
|
8942
9166
|
["--target <name>", "ws status: pick among the project's named workspace targets"]
|
|
8943
9167
|
],
|
|
8944
|
-
examples: ["githolon ws
|
|
9168
|
+
examples: ["githolon ws status", "githolon ws retire my-guestbook"]
|
|
8945
9169
|
},
|
|
8946
9170
|
key: {
|
|
8947
9171
|
usage: "githolon key <enroll|show|import|export> [--principal <uid>] [--secret <key>] [--sha256] [--format hex|base64] [--parent <ws>] [--yes]",
|
|
@@ -8977,9 +9201,8 @@ var HELP = {
|
|
|
8977
9201
|
],
|
|
8978
9202
|
examples: [
|
|
8979
9203
|
`githolon gov root grantCreation --payload '{"principal":"d205ca94-\u2026"}' --as 32c7100e-\u2026 --stamp`,
|
|
8980
|
-
"githolon gov
|
|
8981
|
-
"githolon gov root
|
|
8982
|
-
"githolon gov relay root co2.offer.json"
|
|
9204
|
+
"githolon gov root setGovernancePosture --payload-file posture.json --as 32c7100e-\u2026 --save posture.offer.json",
|
|
9205
|
+
"githolon gov relay root posture.offer.json"
|
|
8983
9206
|
]
|
|
8984
9207
|
},
|
|
8985
9208
|
rebirth: {
|
|
@@ -9050,12 +9273,12 @@ var HELP = {
|
|
|
9050
9273
|
},
|
|
9051
9274
|
git: {
|
|
9052
9275
|
usage: "githolon git <setup | remote [<ws>] [<remoteName>]> [--cloud <url>] [--target <name>]",
|
|
9053
|
-
what: "
|
|
9276
|
+
what: "Operator transport plumbing for existing holons. `setup` installs the credential helper;\n`remote` wires a local repo to existing cloud custody. Application code does not use git to\ncreate business things; it calls the generated birth(businessFacts).",
|
|
9054
9277
|
examples: ["githolon git setup", "githolon git remote my-guestbook", "git push nomos refs/heads/session/dev"]
|
|
9055
9278
|
},
|
|
9056
9279
|
ledger: {
|
|
9057
9280
|
usage: "githolon ledger <init|verify> <dir> [--file <deploy.json>] [--cloud <url>]",
|
|
9058
|
-
what: "
|
|
9281
|
+
what: "Low-level local custody and verification for framework development. `init` writes compiled\nlaw into a git-backed holon; `verify` replays its full history. Application packages use the\ngenerated birth(businessFacts) surface instead.",
|
|
9059
9282
|
examples: ["githolon ledger init ./my-holon", "githolon ledger verify ./my-holon"]
|
|
9060
9283
|
}
|
|
9061
9284
|
};
|
|
@@ -9555,117 +9778,37 @@ async function status(wsArg, opts) {
|
|
|
9555
9778
|
// src/cli.ts
|
|
9556
9779
|
var KINDS = ["domain", "aggregate", "intent"];
|
|
9557
9780
|
var DEFAULT_OUT = "domains";
|
|
9558
|
-
var USAGE = `githolon \u2014
|
|
9781
|
+
var USAGE = `githolon \u2014 model a business; Nomos owns the compute science
|
|
9559
9782
|
|
|
9560
|
-
|
|
9561
|
-
githolon
|
|
9562
|
-
|
|
9563
|
-
|
|
9564
|
-
githolon
|
|
9565
|
-
githolon replay <ws|dir> the ledger as film: step the chain intent-by-
|
|
9566
|
-
intent; finale = the verify_chain verdict
|
|
9567
|
-
githolon scene <ws|dir> [--out <dir>] the ledger as a PORTABLE USD scene: verify_chain-
|
|
9568
|
-
gated chain\u2192USD projection (.usda + .usdz, loads
|
|
9569
|
-
in three.js/usdview/QuickLook; timeCode = index)
|
|
9570
|
-
githolon decrypt <ws> --as <p> --secret <b64> clone + decrypt as a principal: unwrap their scope
|
|
9571
|
-
--query <id> [--param k=v] keys from the chain, read private fields in cleartext
|
|
9783
|
+
Start here:
|
|
9784
|
+
githolon compile compile aggregates, birth, directives, and reads into law + a typed client
|
|
9785
|
+
githolon proof run the generated business proof in the real local engine
|
|
9786
|
+
githolon dev watch, compile, and rerun that proof on every save
|
|
9787
|
+
githolon check explain anything the law can already prove it would refuse
|
|
9572
9788
|
|
|
9573
|
-
|
|
9574
|
-
|
|
9575
|
-
./nomos.package.mjs \u2014 the unified report; exits
|
|
9576
|
-
non-zero on any REFUSE (compile runs it implicitly).
|
|
9577
|
-
--json emits the findings (with file:line) as an array
|
|
9578
|
-
githolon compat <ws-url|deploy.json|dir> [--json] THE CI GATE: compare the current build's interface
|
|
9579
|
-
against a target's installed law, PER MEMBER (#72
|
|
9580
|
-
subtyping); exits non-zero on any incompatible member
|
|
9581
|
-
githolon lsp the author-time gate as a stdio Language Server:
|
|
9582
|
-
red squiggles while you write law (VS Code/Neovim/\u2026)
|
|
9583
|
-
githolon mcp the author-time gate as a stdio MCP server for AI
|
|
9584
|
-
agents (Codex/Claude): tools nomos_check +
|
|
9585
|
-
nomos_evolve_preview. Setup: codex mcp add nomos -- githolon mcp
|
|
9586
|
-
githolon compile [compiler args] compile the package by ./nomos.package.mjs
|
|
9587
|
-
githolon init-editor write .vscode/extensions.json recommending the
|
|
9588
|
-
Nomos Law extension \u2014 the check gate as red
|
|
9589
|
-
squiggles while you type (idempotent)
|
|
9590
|
-
githolon proof [build/<name>.proof.mts] run the proof GENERATED from your law, live
|
|
9591
|
-
(every compile emits it; ALL GREEN or it names the jam)
|
|
9592
|
-
githolon harness-install --deploy <deploy.json[,...]> offline install for the headless TEST HARNESS:
|
|
9593
|
-
--workspace <ws> --out <snapshot> install tenant law IN-CHAIN (no cloud), write the
|
|
9594
|
-
restore snapshot, print { ok, snapshot, lawHashes }
|
|
9595
|
-
githolon generate <domain|aggregate|intent> <name> [options]
|
|
9596
|
-
githolon g <domain|aggregate|intent> <name> [options]
|
|
9789
|
+
The application surface is one idea:
|
|
9790
|
+
const thing = await app.birth(businessFacts)
|
|
9597
9791
|
|
|
9598
|
-
|
|
9599
|
-
|
|
9600
|
-
|
|
9601
|
-
githolon whoami show the principal births will ride + keys on file
|
|
9602
|
-
githolon use [<uid>] [--clear] set/show/clear the ACTIVE signing principal: the one
|
|
9603
|
-
deploy/gov/grant/key author as (--as overrides per-cmd)
|
|
9604
|
-
githolon logout clear the session (workspace secrets kept)
|
|
9605
|
-
githolon key enroll [--principal <uid>] [--parent <ws>] [--domain <d>] [--directive <id>] mint a signing device key + enroll it on-chain (the signing directive is DISCOVERED from the parent's installed law; the flags override)
|
|
9606
|
-
(secret stays local; warrants SIGNED governance)
|
|
9607
|
-
githolon key import --principal <uid> --secret <key> bring an EXISTING admin key into ~/.holon (accepts
|
|
9608
|
-
hex / base64 seed, or --sha256 <passphrase>)
|
|
9609
|
-
githolon key show | export [--principal <uid>] the device key's public identity (export --yes: secret)
|
|
9792
|
+
A born aggregate is a holon: its law, facts, and history travel together. Nomos owns durable identity,
|
|
9793
|
+
authorship, local execution, validation, persistence, synchronisation, provenance, and recovery beneath
|
|
9794
|
+
that call. Those mechanisms are not separate application workflows.
|
|
9610
9795
|
|
|
9611
|
-
|
|
9612
|
-
githolon
|
|
9613
|
-
|
|
9614
|
-
|
|
9615
|
-
githolon
|
|
9616
|
-
githolon
|
|
9617
|
-
[--dry-run [--json]] [--yes] scarred chain; --dry-run = READ-ONLY impact report
|
|
9618
|
-
githolon rebirth plan <ws> [--reason <text>] [--out D] write a stable plan.json + impact.md (rebirths-as-code)
|
|
9619
|
-
githolon rebirth apply --plan <plan.json> drift-pinned apply of a reviewed plan \u2192 certificate.json
|
|
9620
|
-
--gcp-secret nomos-root-custodian-key [--yes] (apply needs the ROOT CUSTODIAN seed; --gcp-secret is blessed)
|
|
9621
|
-
githolon replay <ws> --repair execute the repair matching a red verify (\u2192 certificate)
|
|
9622
|
-
githolon grant <admin|creation> <principal> [--label L] grant authority at the parent (default root)
|
|
9623
|
-
githolon grant quota <principal> --max <N> grant a per-principal workspace allowance
|
|
9624
|
-
githolon revoke <admin|creation> <principal> revoke it (the revoked fact rides the chain)
|
|
9625
|
-
(all gated by the parent's law: only an admin's
|
|
9626
|
-
signature is admitted; --parent <p> targets a platform)
|
|
9796
|
+
Useful authoring commands:
|
|
9797
|
+
githolon generate <domain|aggregate|intent> <name>
|
|
9798
|
+
githolon compat <target>
|
|
9799
|
+
githolon lsp
|
|
9800
|
+
githolon mcp
|
|
9801
|
+
githolon login --agent
|
|
9627
9802
|
|
|
9628
|
-
|
|
9629
|
-
|
|
9630
|
-
githolon ws create <name> [--principal <uid|token>] birth a workspace (no host secret is issued)
|
|
9631
|
-
(no identity on file? it self-onboards an agent login)
|
|
9632
|
-
githolon ws create <name> --via <parent> request it as a SIGNED createWorkspace governance
|
|
9633
|
-
offer at the parent
|
|
9634
|
-
githolon ws status [<name>] workspace status (lineage, phase, verdicts)
|
|
9635
|
-
githolon ws retire <name> [--parent <ws>] retire a workspace via a SIGNED governance offer;
|
|
9636
|
-
quota freed; data retained; reads keep serving
|
|
9637
|
-
githolon ws reclaim <name> [--parent <ws>] lawful custody discard via a SIGNED governance offer
|
|
9638
|
-
(only a retired workspace; never root)
|
|
9639
|
-
githolon deploy [<ws>] [--file <deploy.json>] deploy build/*.deploy.json \u2014 DEFAULT replace-current:
|
|
9640
|
-
[--keep-beside] [--retire-replaced] new law becomes active; prior install is superseded
|
|
9641
|
-
per domain key (prints what moved). --keep-beside
|
|
9642
|
-
installs beside; --retire-replaced marks retired
|
|
9643
|
-
githolon domains status <ws> per domain key: active law plus superseded/retired
|
|
9644
|
-
[--explain-current-interface] lineage (active = served now)
|
|
9645
|
-
githolon domains retire <ws> <hashOrKey> retire an install (marks it retired \u2014 replayable,
|
|
9646
|
-
[--with <hashOrKey>] no longer served) via a signed installDomain offer
|
|
9647
|
-
githolon dlq sweep <ws> [--depth <n>] [--full] sweep a platform subtree's dead-letter queues
|
|
9648
|
-
(registry-enumerated; exit 2 when jams exist)
|
|
9649
|
-
githolon secret set <ws> <push-password> store a git push password (authenticated git sync)
|
|
9650
|
-
githolon secret rotate <ws> RETIRED \u2014 host holds no ownership credential (410)
|
|
9651
|
-
|
|
9652
|
-
Git lane (stock git as the sync transport \u2014 main is not push-writable; a workspace is born by its parent):
|
|
9653
|
-
githolon git setup install the credential helper for the cloud host
|
|
9654
|
-
githolon git remote [<ws>] [<remoteName>] wire this repo to a workspace (default name: nomos)
|
|
9655
|
-
then: git push nomos refs/heads/session/<id>
|
|
9656
|
-
|
|
9657
|
-
The local-first lane (mint + assert a holon on YOUR machine, under YOUR identity):
|
|
9658
|
-
githolon ledger init <dir> genesis + your compiled law, verified by the SAME
|
|
9659
|
-
wasm gate the cloud runs, written as a git repo
|
|
9660
|
-
githolon ledger verify <dir> re-run the chain's self-verification from disk
|
|
9803
|
+
Operational and inspection commands remain available to maintain Nomos itself. Ask any command for its
|
|
9804
|
+
focused screen: githolon <command> --help (for example: status, replay, scene, deploy, domains, or gov).
|
|
9661
9805
|
|
|
9662
9806
|
Options:
|
|
9663
|
-
--cloud <url> target cloud
|
|
9664
|
-
--
|
|
9665
|
-
--
|
|
9666
|
-
--
|
|
9667
|
-
|
|
9668
|
-
-h, --help top level here; \`githolon <command> --help\` for that command's flags + examples
|
|
9807
|
+
--cloud <url> target cloud
|
|
9808
|
+
--out <dir> generate into a different directory (default: ${DEFAULT_OUT})
|
|
9809
|
+
--force overwrite generated source
|
|
9810
|
+
--dry-run print generated source without writing it
|
|
9811
|
+
-h, --help show this page; githolon <command> --help shows one focused command
|
|
9669
9812
|
`;
|
|
9670
9813
|
function cloudArgs(rest) {
|
|
9671
9814
|
const pos = [];
|
|
@@ -9771,8 +9914,7 @@ async function runProof(args) {
|
|
|
9771
9914
|
return 1;
|
|
9772
9915
|
};
|
|
9773
9916
|
const live = args.includes("--live");
|
|
9774
|
-
|
|
9775
|
-
if (keep && !live) return refuse("--keep only applies to --live (the offline proof creates no cloud workspace to keep)");
|
|
9917
|
+
if (args.includes("--keep")) return refuse("--keep no longer applies: proof --live uses your durable signed Nomos home and creates only the requested business aggregate");
|
|
9776
9918
|
let domain;
|
|
9777
9919
|
let domainValueIdx = -1;
|
|
9778
9920
|
const di = args.findIndex((a) => a === "--domain" || a.startsWith("--domain="));
|
|
@@ -9839,58 +9981,40 @@ async function runProof(args) {
|
|
|
9839
9981
|
const tsxPkg = JSON.parse(readFileSync16(join17(tsxDir, "package.json"), "utf8"));
|
|
9840
9982
|
const tsxBinRel = typeof tsxPkg.bin === "string" ? tsxPkg.bin : tsxPkg.bin?.["tsx"];
|
|
9841
9983
|
const tsxCli = join17(tsxDir, tsxBinRel ?? "dist/cli.mjs");
|
|
9842
|
-
console.log("githolon proof --live \u2014
|
|
9843
|
-
const {
|
|
9844
|
-
|
|
9845
|
-
|
|
9846
|
-
|
|
9847
|
-
|
|
9848
|
-
|
|
9849
|
-
} catch {
|
|
9850
|
-
const lr = await login2({ agent: true });
|
|
9851
|
-
principal = lr === 0 ? activePrincipal2() : void 0;
|
|
9984
|
+
console.log("githolon proof --live \u2014 one generated app.birth against Nomos Cloud");
|
|
9985
|
+
const { ensureSovereignHome: ensureSovereignHome2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
9986
|
+
if (currentPrincipal() === void 0) {
|
|
9987
|
+
const lr = await login({ agent: true });
|
|
9988
|
+
if (lr !== 0) {
|
|
9989
|
+
return refuse("proof --live needs a login \u2014 githolon login --agent failed; try it directly");
|
|
9990
|
+
}
|
|
9852
9991
|
}
|
|
9853
|
-
if (
|
|
9992
|
+
if (currentPrincipal() === void 0) {
|
|
9854
9993
|
return refuse("proof --live needs a principal \u2014 githolon login --agent (self-onboarding) failed; try it directly or pass NOMOS_PRINCIPAL");
|
|
9855
9994
|
}
|
|
9856
|
-
|
|
9857
|
-
|
|
9858
|
-
|
|
9859
|
-
|
|
9860
|
-
|
|
9861
|
-
|
|
9862
|
-
|
|
9863
|
-
remedies:
|
|
9864
|
-
\u2022 ask an operator: githolon grant creation ${principal} (then rerun)
|
|
9865
|
-
\u2022 or pre-create a REGISTERED workspace yourself and hand it over: NOMOS_WS=<ws> githolon proof --live
|
|
9866
|
-
\u2022 or develop offline (no cloud workspace at all): githolon proof`
|
|
9867
|
-
);
|
|
9868
|
-
}
|
|
9995
|
+
let home;
|
|
9996
|
+
try {
|
|
9997
|
+
home = await ensureSovereignHome2();
|
|
9998
|
+
} catch (e) {
|
|
9999
|
+
return refuse(
|
|
10000
|
+
`proof --live: Nomos could not establish the signed session home: ${e.message}. No certificate, signer, parent, or provisioning step is part of the application contract.`
|
|
10001
|
+
);
|
|
9869
10002
|
}
|
|
10003
|
+
const barePrincipal = home.principal.startsWith("user:") ? home.principal.slice("user:".length) : home.principal;
|
|
10004
|
+
const deployed = await deploy2(home.home, { principal: barePrincipal });
|
|
10005
|
+
if (deployed !== 0) return refuse("proof --live: Nomos could not install the compiled business law into the signed session home");
|
|
9870
10006
|
const r = spawnSync6(process.execPath, [tsxCli, proofPath], {
|
|
9871
10007
|
stdio: "inherit",
|
|
9872
10008
|
cwd: process.cwd(),
|
|
9873
10009
|
env: {
|
|
9874
10010
|
...process.env,
|
|
9875
|
-
NOMOS_WS:
|
|
9876
|
-
NOMOS_PRINCIPAL: principal,
|
|
9877
|
-
|
|
9878
|
-
|
|
9879
|
-
...keep ? { PROOF_KEEP: "1" } : {}
|
|
10011
|
+
NOMOS_WS: home.home,
|
|
10012
|
+
NOMOS_PRINCIPAL: home.principal,
|
|
10013
|
+
NOMOS_AUTHOR_SECRET: home.device.secret,
|
|
10014
|
+
NOMOS_PROOF_MANAGED: "1"
|
|
9880
10015
|
}
|
|
9881
10016
|
});
|
|
9882
|
-
|
|
9883
|
-
if (keep) {
|
|
9884
|
-
console.log(`workspace ${ws} KEPT (--keep) \u2014 retire it when done: githolon ws retire ${ws}`);
|
|
9885
|
-
return proofStatus;
|
|
9886
|
-
}
|
|
9887
|
-
const rr = await wsRetire2(ws, { principal }).catch(() => 1);
|
|
9888
|
-
if (rr !== 0) {
|
|
9889
|
-
console.error(`\u26A0 THROWAWAY WORKSPACE NOT RETIRED: ${ws}`);
|
|
9890
|
-
console.error(`\u26A0 retire it manually: githolon ws retire ${ws}`);
|
|
9891
|
-
console.error(`\u26A0 (if it has no root registry row it was born unregistered and needs a custodian sweep)`);
|
|
9892
|
-
}
|
|
9893
|
-
return proofStatus;
|
|
10017
|
+
return r.status ?? 1;
|
|
9894
10018
|
}
|
|
9895
10019
|
function parseArgs(argv) {
|
|
9896
10020
|
const [command, ...rest] = argv;
|
|
@@ -10176,6 +10300,12 @@ ${commandHelp("status")}`);
|
|
|
10176
10300
|
}
|
|
10177
10301
|
return status(pos[0], opts);
|
|
10178
10302
|
}
|
|
10303
|
+
if (argv[0] === "ws" && argv[1] === "create") {
|
|
10304
|
+
process.stderr.write(
|
|
10305
|
+
"error: `githolon ws create` is not an application birth API. Declare birth(Aggregate, spec) and call the generated app.birth(businessFacts); Nomos owns custody beneath it.\n"
|
|
10306
|
+
);
|
|
10307
|
+
return 1;
|
|
10308
|
+
}
|
|
10179
10309
|
if (argv[0] === "ws" || argv[0] === "deploy" || argv[0] === "secret") {
|
|
10180
10310
|
return runCloud(argv);
|
|
10181
10311
|
}
|
package/dist/dev-server.mjs
CHANGED
|
@@ -1851,7 +1851,21 @@ function resolveGatewayOperation(spec, opName, method) {
|
|
|
1851
1851
|
const exactPath = `/${String(opName).replace(/^\/+/, "")}`;
|
|
1852
1852
|
const exact = spec.paths[exactPath]?.[normalizedMethod];
|
|
1853
1853
|
if (exact) return { op: exact, path: exactPath, ambiguous: null };
|
|
1854
|
-
|
|
1854
|
+
const slash = String(opName).indexOf("/");
|
|
1855
|
+
if (slash > 0) {
|
|
1856
|
+
const requestedDomain = String(opName).slice(0, slash);
|
|
1857
|
+
const requestedAlias = String(opName).slice(slash + 1);
|
|
1858
|
+
const matches2 = [];
|
|
1859
|
+
for (const [path2, methods] of Object.entries(spec.paths)) {
|
|
1860
|
+
const op = methods?.[normalizedMethod];
|
|
1861
|
+
const x = op?.["x-nomos"];
|
|
1862
|
+
if (!op || !x || x.domain !== requestedDomain) continue;
|
|
1863
|
+
if (aliasIdsFor(x, path2).has(requestedAlias)) matches2.push({ op, path: path2 });
|
|
1864
|
+
}
|
|
1865
|
+
if (matches2.length === 1) return { ...matches2[0], ambiguous: null };
|
|
1866
|
+
if (matches2.length > 1) return { op: null, ambiguous: matches2.map((m) => m.path).sort() };
|
|
1867
|
+
return { op: null, ambiguous: null };
|
|
1868
|
+
}
|
|
1855
1869
|
const matches = [];
|
|
1856
1870
|
for (const [path2, methods] of Object.entries(spec.paths)) {
|
|
1857
1871
|
const op = methods?.[normalizedMethod];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "githolon",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.100.1",
|
|
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.100.1",
|
|
33
|
+
"@githolon/dsl": "^0.100.1",
|
|
34
34
|
"isomorphic-git": "^1.38.4"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|