githolon 0.100.1 → 0.100.3
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 +102 -15
- package/package.json +3 -3
package/dist/cli.mjs
CHANGED
|
@@ -3120,6 +3120,7 @@ __export(governance_exports, {
|
|
|
3120
3120
|
renderRebirthImpact: () => renderRebirthImpact,
|
|
3121
3121
|
resolveGovernanceHash: () => resolveGovernanceHash,
|
|
3122
3122
|
resolveGovernancePrincipal: () => resolveGovernancePrincipal,
|
|
3123
|
+
signAndPostChildLifecycle: () => signAndPostChildLifecycle,
|
|
3123
3124
|
signAndPostGovernance: () => signAndPostGovernance,
|
|
3124
3125
|
signAndPostOffer: () => signAndPostOffer,
|
|
3125
3126
|
signAndPostWorkspaceBirth: () => signAndPostWorkspaceBirth,
|
|
@@ -3433,6 +3434,22 @@ async function signAndPostWorkspaceRetirement(parent, workspaceId, creator, opts
|
|
|
3433
3434
|
creator
|
|
3434
3435
|
);
|
|
3435
3436
|
}
|
|
3437
|
+
async function signAndPostChildLifecycle(parent, child, creator, action, opts) {
|
|
3438
|
+
return signAndPostPreparedOffer(
|
|
3439
|
+
parent,
|
|
3440
|
+
void 0,
|
|
3441
|
+
(actor) => action === "retire" ? {
|
|
3442
|
+
directiveId: "retireChild",
|
|
3443
|
+
payload: { child, principal: creator, retiredBy: lineageIdentity(actor), retiredAt: Date.now() }
|
|
3444
|
+
} : {
|
|
3445
|
+
directiveId: "reclaimChild",
|
|
3446
|
+
payload: { child, reclaimedBy: lineageIdentity(actor), reclaimedAt: Date.now() }
|
|
3447
|
+
},
|
|
3448
|
+
opts,
|
|
3449
|
+
"self-if-unenrolled",
|
|
3450
|
+
creator
|
|
3451
|
+
);
|
|
3452
|
+
}
|
|
3436
3453
|
async function relaySealedOfferViaStage(cloud, ws, directiveId, intentBytesB64, fetchImpl) {
|
|
3437
3454
|
const raw = Buffer.from(intentBytesB64, "base64");
|
|
3438
3455
|
const sha2562 = createHash("sha256").update(raw).digest("hex");
|
|
@@ -5166,6 +5183,7 @@ var init_lifecycle = __esm({
|
|
|
5166
5183
|
var cloud_exports = {};
|
|
5167
5184
|
__export(cloud_exports, {
|
|
5168
5185
|
activePrincipal: () => activePrincipal,
|
|
5186
|
+
advertisedMainHead: () => advertisedMainHead,
|
|
5169
5187
|
authUse: () => authUse,
|
|
5170
5188
|
clearActAs: () => clearActAs,
|
|
5171
5189
|
cloudBase: () => cloudBase,
|
|
@@ -5187,6 +5205,7 @@ __export(cloud_exports, {
|
|
|
5187
5205
|
setDeviceKey: () => setDeviceKey,
|
|
5188
5206
|
setPrincipal: () => setPrincipal,
|
|
5189
5207
|
setSecret: () => setSecret,
|
|
5208
|
+
waitForDurableMainAdvance: () => waitForDurableMainAdvance,
|
|
5190
5209
|
whoami: () => whoami,
|
|
5191
5210
|
wsCreate: () => wsCreate,
|
|
5192
5211
|
wsReclaim: () => wsReclaim,
|
|
@@ -5469,9 +5488,19 @@ async function wsStatus(name, opts) {
|
|
|
5469
5488
|
out4(text);
|
|
5470
5489
|
return 0;
|
|
5471
5490
|
}
|
|
5491
|
+
async function childBirthRecord(cloud, parent, child) {
|
|
5492
|
+
try {
|
|
5493
|
+
const id = `nomos-birth-record:${child}`;
|
|
5494
|
+
const r = await fetch(`${cloud}/v2/workspaces/${encodeURIComponent(parent)}/aggregates/${encodeURIComponent(id)}`);
|
|
5495
|
+
const body = await r.json().catch(() => void 0);
|
|
5496
|
+
return body?.ok === true ? body.rows?.find((row) => row.data?.child === child) : void 0;
|
|
5497
|
+
} catch {
|
|
5498
|
+
return void 0;
|
|
5499
|
+
}
|
|
5500
|
+
}
|
|
5472
5501
|
async function wsRetire(ws, opts) {
|
|
5473
5502
|
const cloud = cloudBase(opts.cloud);
|
|
5474
|
-
const { signAndPostWorkspaceRetirement: signAndPostWorkspaceRetirement2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
5503
|
+
const { signAndPostChildLifecycle: signAndPostChildLifecycle2, signAndPostWorkspaceRetirement: signAndPostWorkspaceRetirement2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
5475
5504
|
const parent = opts.parent ?? "root";
|
|
5476
5505
|
let record;
|
|
5477
5506
|
try {
|
|
@@ -5483,12 +5512,29 @@ async function wsRetire(ws, opts) {
|
|
|
5483
5512
|
}
|
|
5484
5513
|
const recordId = record?.id;
|
|
5485
5514
|
if (recordId === void 0) {
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
|
|
5489
|
-
|
|
5490
|
-
|
|
5491
|
-
|
|
5515
|
+
const childRecord = await childBirthRecord(cloud, parent, ws);
|
|
5516
|
+
if (childRecord === void 0) {
|
|
5517
|
+
err4(
|
|
5518
|
+
`retire '${ws}': no CloudWorkspace or NomosBirthRecord named '${ws}' in ${parent}'s registry \u2014 nothing lawful to retire.
|
|
5519
|
+
An out-of-band custody repo has no parent lifecycle fact and needs a custodian investigation.`
|
|
5520
|
+
);
|
|
5521
|
+
return 1;
|
|
5522
|
+
}
|
|
5523
|
+
const creator = childRecord.data?.principal ?? "";
|
|
5524
|
+
let childVerdict;
|
|
5525
|
+
try {
|
|
5526
|
+
childVerdict = await signAndPostChildLifecycle2(parent, ws, creator, "retire", opts);
|
|
5527
|
+
} catch (e) {
|
|
5528
|
+
err4(e.message);
|
|
5529
|
+
return 1;
|
|
5530
|
+
}
|
|
5531
|
+
if (!childVerdict.ok) {
|
|
5532
|
+
err4(`retire '${ws}' refused (${childVerdict.status}): ${typeof childVerdict.body === "string" ? childVerdict.body : JSON.stringify(childVerdict.body)}`);
|
|
5533
|
+
return 1;
|
|
5534
|
+
}
|
|
5535
|
+
out4(`\u2713 child ${ws} retired via signed lifecycle offer to ${parent} on ${cloud}`);
|
|
5536
|
+
out4(" custody is retained; reclaim is a separate, law-gated terminal step");
|
|
5537
|
+
return 0;
|
|
5492
5538
|
}
|
|
5493
5539
|
let v;
|
|
5494
5540
|
try {
|
|
@@ -5517,17 +5563,30 @@ async function wsRetire(ws, opts) {
|
|
|
5517
5563
|
}
|
|
5518
5564
|
async function wsReclaim(ws, opts) {
|
|
5519
5565
|
const cloud = cloudBase(opts.cloud);
|
|
5520
|
-
const { signAndPostGovernance: signAndPostGovernance2, resolveGovernancePrincipal: resolveGovernancePrincipal2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
5566
|
+
const { signAndPostChildLifecycle: signAndPostChildLifecycle2, signAndPostGovernance: signAndPostGovernance2, resolveGovernancePrincipal: resolveGovernancePrincipal2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
5521
5567
|
const parent = opts.parent ?? "root";
|
|
5522
5568
|
let v;
|
|
5523
5569
|
try {
|
|
5524
5570
|
const principal = resolveGovernancePrincipal2(opts);
|
|
5525
|
-
|
|
5526
|
-
|
|
5527
|
-
|
|
5528
|
-
|
|
5529
|
-
|
|
5530
|
-
|
|
5571
|
+
const q = await fetch(`${cloud}/v2/workspaces/${parent}/workspaceByName?name=${encodeURIComponent(ws)}`);
|
|
5572
|
+
const qd = await q.json().catch(() => void 0);
|
|
5573
|
+
const rows = qd?.ok === true ? qd.rows ?? [] : [];
|
|
5574
|
+
const workspace = rows.find((r) => r.data?.status === "retired") ?? rows[0];
|
|
5575
|
+
if (workspace?.id !== void 0) {
|
|
5576
|
+
v = await signAndPostGovernance2(
|
|
5577
|
+
parent,
|
|
5578
|
+
"reclaimWorkspace",
|
|
5579
|
+
{ workspaceId: workspace.id, reclaimedBy: principal, reclaimedAt: Date.now() },
|
|
5580
|
+
opts
|
|
5581
|
+
);
|
|
5582
|
+
} else {
|
|
5583
|
+
const child = await childBirthRecord(cloud, parent, ws);
|
|
5584
|
+
if (child === void 0) {
|
|
5585
|
+
err4(`reclaim '${ws}': no CloudWorkspace or NomosBirthRecord named '${ws}' in ${parent}'s registry`);
|
|
5586
|
+
return 1;
|
|
5587
|
+
}
|
|
5588
|
+
v = await signAndPostChildLifecycle2(parent, ws, child.data?.principal ?? "", "reclaim", opts);
|
|
5589
|
+
}
|
|
5531
5590
|
} catch (e) {
|
|
5532
5591
|
err4(e.message);
|
|
5533
5592
|
return 1;
|
|
@@ -5536,10 +5595,28 @@ async function wsReclaim(ws, opts) {
|
|
|
5536
5595
|
err4(`reclaim '${ws}' refused (${v.status}): ${typeof v.body === "string" ? v.body : JSON.stringify(v.body)}`);
|
|
5537
5596
|
return 1;
|
|
5538
5597
|
}
|
|
5539
|
-
out4(`\u2713 workspace ${ws} reclaimed via signed
|
|
5598
|
+
out4(`\u2713 workspace ${ws} reclaimed via signed lifecycle offer to ${parent} on ${cloud}`);
|
|
5540
5599
|
out4(" the custodian drops the ledger bytes on seeing this fact folded; the reclaimed FACT is append-only");
|
|
5541
5600
|
return 0;
|
|
5542
5601
|
}
|
|
5602
|
+
function advertisedMainHead(text) {
|
|
5603
|
+
return /([0-9a-f]{40}) refs\/heads\/main\b/.exec(text)?.[1];
|
|
5604
|
+
}
|
|
5605
|
+
async function durableMainHead(cloud, ws, fetchImpl = fetch) {
|
|
5606
|
+
return fetchImpl(`${cloud}/v2/workspaces/${encodeURIComponent(ws)}/git/info/refs?service=git-upload-pack`).then(async (r) => r.ok ? advertisedMainHead(await r.text()) : void 0).catch(() => void 0);
|
|
5607
|
+
}
|
|
5608
|
+
async function waitForDurableMainAdvance(cloud, ws, previousHead, opts = {}) {
|
|
5609
|
+
const timeoutMs = Math.max(100, Number(opts.timeoutMs) || 3e4);
|
|
5610
|
+
const pollMs = Math.max(1, Number(opts.pollMs) || 250);
|
|
5611
|
+
const fetchImpl = opts.fetchImpl ?? fetch;
|
|
5612
|
+
const deadline = Date.now() + timeoutMs;
|
|
5613
|
+
while (Date.now() < deadline) {
|
|
5614
|
+
const head = await durableMainHead(cloud, ws, fetchImpl);
|
|
5615
|
+
if (head !== void 0 && head !== previousHead) return head;
|
|
5616
|
+
await new Promise((resolve6) => setTimeout(resolve6, pollMs));
|
|
5617
|
+
}
|
|
5618
|
+
return void 0;
|
|
5619
|
+
}
|
|
5543
5620
|
async function deploy2(ws, opts) {
|
|
5544
5621
|
const cloud = cloudBase(opts.cloud);
|
|
5545
5622
|
let file;
|
|
@@ -5553,6 +5630,7 @@ async function deploy2(ws, opts) {
|
|
|
5553
5630
|
const beforeLaw = await fetch(`${cloud}/v2/workspaces/${ws}/domains`).then((br) => br.json()).then((bd) => bd.ok === true ? bd : {}).catch(() => ({}));
|
|
5554
5631
|
const before = beforeLaw.domains ?? [];
|
|
5555
5632
|
const currentLaw2 = beforeLaw.currentLaw ?? {};
|
|
5633
|
+
const beforeDurableHead = await durableMainHead(cloud, ws);
|
|
5556
5634
|
try {
|
|
5557
5635
|
const compat = JSON.parse(readFileSync5(file, "utf8")).nomosCompat;
|
|
5558
5636
|
const requires = compat?.requiresKernel ?? [];
|
|
@@ -5677,6 +5755,15 @@ async function deploy2(ws, opts) {
|
|
|
5677
5755
|
}
|
|
5678
5756
|
};
|
|
5679
5757
|
if (deployedHash !== void 0 && isCurrent) {
|
|
5758
|
+
const wasCurrentBefore = Object.values(currentLaw2).includes(deployedHash);
|
|
5759
|
+
if (!wasCurrentBefore && beforeDurableHead !== void 0) {
|
|
5760
|
+
const durableHead = await waitForDurableMainAdvance(cloud, ws, beforeDurableHead);
|
|
5761
|
+
if (durableHead === void 0) {
|
|
5762
|
+
err4(`deploy '${ws}' was admitted, but canonical Git main did not advance within 30000ms`);
|
|
5763
|
+
err4(` Nomos will not start application code against a law that fresh peers cannot clone yet; retry the deploy.`);
|
|
5764
|
+
return 2;
|
|
5765
|
+
}
|
|
5766
|
+
}
|
|
5680
5767
|
out4(`\u2713 deployed ${fileName} \u2192 ${ws}${phaseSuffix}`);
|
|
5681
5768
|
out4(` law ${describeLawMove(before, deployedHash)}`);
|
|
5682
5769
|
emitPlan();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "githolon",
|
|
3
|
-
"version": "0.100.
|
|
3
|
+
"version": "0.100.3",
|
|
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.100.
|
|
33
|
-
"@githolon/dsl": "^0.100.
|
|
32
|
+
"@githolon/client": "^0.100.3",
|
|
33
|
+
"@githolon/dsl": "^0.100.3",
|
|
34
34
|
"isomorphic-git": "^1.38.4"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|