githolon 0.74.0 → 0.75.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 +226 -64
- package/package.json +3 -3
package/dist/cli.mjs
CHANGED
|
@@ -113,14 +113,14 @@ var init_git_fs = __esm({
|
|
|
113
113
|
});
|
|
114
114
|
|
|
115
115
|
// vendor/engine/tree.mjs
|
|
116
|
-
function flatten(dir, prefix,
|
|
116
|
+
function flatten(dir, prefix, out13) {
|
|
117
117
|
for (const [name, inode] of dir.contents) {
|
|
118
118
|
const path = prefix ? prefix + "/" + name : name;
|
|
119
119
|
if (inode.contents instanceof Map) {
|
|
120
|
-
|
|
121
|
-
flatten(inode, path,
|
|
120
|
+
out13.push({ path, dir: true });
|
|
121
|
+
flatten(inode, path, out13);
|
|
122
122
|
} else {
|
|
123
|
-
|
|
123
|
+
out13.push({ path, dir: false, bytes: inode.data ?? new Uint8Array(0) });
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
126
|
}
|
|
@@ -143,13 +143,13 @@ function serializeTree(workTree) {
|
|
|
143
143
|
}
|
|
144
144
|
let total = 0;
|
|
145
145
|
for (const c of chunks) total += c.length;
|
|
146
|
-
const
|
|
146
|
+
const out13 = new Uint8Array(total);
|
|
147
147
|
let off = 0;
|
|
148
148
|
for (const c of chunks) {
|
|
149
|
-
|
|
149
|
+
out13.set(c, off);
|
|
150
150
|
off += c.length;
|
|
151
151
|
}
|
|
152
|
-
return
|
|
152
|
+
return out13;
|
|
153
153
|
}
|
|
154
154
|
var enc, dec;
|
|
155
155
|
var init_tree = __esm({
|
|
@@ -164,13 +164,13 @@ var init_tree = __esm({
|
|
|
164
164
|
function concatBytes(chunks) {
|
|
165
165
|
let n = 0;
|
|
166
166
|
for (const c of chunks) n += c.length;
|
|
167
|
-
const
|
|
167
|
+
const out13 = new Uint8Array(n);
|
|
168
168
|
let o = 0;
|
|
169
169
|
for (const c of chunks) {
|
|
170
|
-
|
|
170
|
+
out13.set(c, o);
|
|
171
171
|
o += c.length;
|
|
172
172
|
}
|
|
173
|
-
return
|
|
173
|
+
return out13;
|
|
174
174
|
}
|
|
175
175
|
function pkt(payload) {
|
|
176
176
|
const body = typeof payload === "string" ? enc2.encode(payload) : payload;
|
|
@@ -418,6 +418,7 @@ __export(engine_exports, {
|
|
|
418
418
|
readShape: () => readShape,
|
|
419
419
|
rebirthCompact: () => rebirthCompact,
|
|
420
420
|
refreshProjection: () => refreshProjection,
|
|
421
|
+
refusedSummary: () => refusedSummary,
|
|
421
422
|
replicateIntents: () => replicateIntents,
|
|
422
423
|
repoArgOf: () => repoArgOf,
|
|
423
424
|
restoreCheckpointFromCustody: () => restoreCheckpointFromCustody,
|
|
@@ -461,13 +462,13 @@ async function sha256hex(t) {
|
|
|
461
462
|
function osEntropyBuffer(n) {
|
|
462
463
|
const bytes = new Uint8Array(n * 8);
|
|
463
464
|
for (let o = 0; o < bytes.length; o += 65536) crypto.getRandomValues(bytes.subarray(o, Math.min(o + 65536, bytes.length)));
|
|
464
|
-
const
|
|
465
|
+
const out13 = new Array(n), T = 2 ** 53;
|
|
465
466
|
for (let i = 0; i < n; i++) {
|
|
466
467
|
let z = 0n;
|
|
467
468
|
for (let b = 7; b >= 0; b--) z = z << 8n | BigInt(bytes[i * 8 + b]);
|
|
468
|
-
|
|
469
|
+
out13[i] = Number(z >> 11n) / T;
|
|
469
470
|
}
|
|
470
|
-
return
|
|
471
|
+
return out13;
|
|
471
472
|
}
|
|
472
473
|
function stringifyBig(o) {
|
|
473
474
|
return JSON.stringify(o, (_k, v) => typeof v === "bigint" ? `@@B:${v}@@` : v).replace(/"@@B:(\d+)@@"/g, "$1");
|
|
@@ -914,15 +915,15 @@ function contribution(read, cur) {
|
|
|
914
915
|
return { group, value: typeof raw === "number" ? raw : 0 };
|
|
915
916
|
}
|
|
916
917
|
function contributionDiff(read, before, after) {
|
|
917
|
-
const
|
|
918
|
+
const out13 = [];
|
|
918
919
|
if (before && after && before.group === after.group) {
|
|
919
920
|
const d = after.value - before.value;
|
|
920
|
-
if (d !== 0)
|
|
921
|
-
return
|
|
921
|
+
if (d !== 0) out13.push({ readId: read.id, group: after.group, delta: d });
|
|
922
|
+
return out13;
|
|
922
923
|
}
|
|
923
|
-
if (before)
|
|
924
|
-
if (after)
|
|
925
|
-
return
|
|
924
|
+
if (before) out13.push({ readId: read.id, group: before.group, delta: -before.value });
|
|
925
|
+
if (after) out13.push({ readId: read.id, group: after.group, delta: after.value });
|
|
926
|
+
return out13.filter((d) => d.delta !== 0);
|
|
926
927
|
}
|
|
927
928
|
function countTenantRows(eng, ws) {
|
|
928
929
|
let total = 0;
|
|
@@ -935,16 +936,16 @@ async function countTenantRowsByHome(eng, ws, homeKeys) {
|
|
|
935
936
|
const keySet = new Set(homeKeys);
|
|
936
937
|
const tagOf = /* @__PURE__ */ new Map();
|
|
937
938
|
for (const hk of homeKeys) tagOf.set(await routeTagHexOfHomeKey(hk), hk);
|
|
938
|
-
const
|
|
939
|
-
for (const hk of homeKeys)
|
|
939
|
+
const out13 = /* @__PURE__ */ new Map();
|
|
940
|
+
for (const hk of homeKeys) out13.set(hk, 0);
|
|
940
941
|
for (const type of tenantTypes(eng)) {
|
|
941
942
|
for (const r of query(eng, ws, "aggregatesByType", JSON.stringify({ __type: type }))) {
|
|
942
943
|
const id = String(r.id || "");
|
|
943
944
|
const hk = keySet.has(id) ? id : tagOf.get(routeTagHexOfMintedId(id) ?? "");
|
|
944
|
-
if (hk !== void 0)
|
|
945
|
+
if (hk !== void 0) out13.set(hk, (out13.get(hk) ?? 0) + 1);
|
|
945
946
|
}
|
|
946
947
|
}
|
|
947
|
-
return
|
|
948
|
+
return out13;
|
|
948
949
|
}
|
|
949
950
|
async function collectHomedIntents(eng, ws, homeKeys) {
|
|
950
951
|
const routes = directiveRoutes(eng);
|
|
@@ -969,7 +970,7 @@ async function collectHomedIntents(eng, ws, homeKeys) {
|
|
|
969
970
|
strikeParity.set(target, (strikeParity.get(target) ?? 0) + 1);
|
|
970
971
|
}
|
|
971
972
|
}
|
|
972
|
-
const
|
|
973
|
+
const out13 = [];
|
|
973
974
|
for (const { oid, blob, doc } of docs) {
|
|
974
975
|
const id = doc && typeof doc.id === "string" ? doc.id : null;
|
|
975
976
|
if (!id || (strikeParity.get(id) ?? 0) % 2 === 1) continue;
|
|
@@ -985,9 +986,9 @@ async function collectHomedIntents(eng, ws, homeKeys) {
|
|
|
985
986
|
const tag = routeTagHexOfMintedId(value);
|
|
986
987
|
homeKey = tag !== void 0 ? tagOf.get(tag) ?? null : null;
|
|
987
988
|
}
|
|
988
|
-
if (homeKey !== null)
|
|
989
|
+
if (homeKey !== null) out13.push({ oid, id, homeKey, blob });
|
|
989
990
|
}
|
|
990
|
-
return
|
|
991
|
+
return out13;
|
|
991
992
|
}
|
|
992
993
|
async function migrateHomes(eng, ws, ledger, sourceWs, homeKeys, { onlyIds = null } = {}) {
|
|
993
994
|
const wanted = onlyIds ? new Set(onlyIds) : null;
|
|
@@ -1096,7 +1097,7 @@ async function collectGlobalIntents(eng, ws) {
|
|
|
1096
1097
|
strikeParity.set(target, (strikeParity.get(target) ?? 0) + 1);
|
|
1097
1098
|
}
|
|
1098
1099
|
}
|
|
1099
|
-
const
|
|
1100
|
+
const out13 = [];
|
|
1100
1101
|
for (const { oid, blob, doc } of docs) {
|
|
1101
1102
|
const id = doc && typeof doc.id === "string" ? doc.id : null;
|
|
1102
1103
|
let touches = false;
|
|
@@ -1107,9 +1108,9 @@ async function collectGlobalIntents(eng, ws) {
|
|
|
1107
1108
|
if (t !== void 0 && globals.has(t)) touches = true;
|
|
1108
1109
|
}
|
|
1109
1110
|
if (!touches || !id || (strikeParity.get(id) ?? 0) % 2 === 1) continue;
|
|
1110
|
-
|
|
1111
|
+
out13.push({ oid, id, blob });
|
|
1111
1112
|
}
|
|
1112
|
-
return
|
|
1113
|
+
return out13;
|
|
1113
1114
|
}
|
|
1114
1115
|
async function replicateIntents(eng, ws, ledger, intents, { push = true } = {}) {
|
|
1115
1116
|
const main2 = await mainIntentIds(eng, ws);
|
|
@@ -1382,8 +1383,8 @@ function writeWork(eng, name, bytes) {
|
|
|
1382
1383
|
eng.preopen.dir.contents.set(name, new File(bytes));
|
|
1383
1384
|
}
|
|
1384
1385
|
function currentLaw(eng, ws) {
|
|
1385
|
-
const
|
|
1386
|
-
return
|
|
1386
|
+
const out13 = JSON.parse(call(eng.ex, "query", { repoArg: repoArgOf(ws), workspace: ws, queryBytes: b64Json({ op: "currentLaw" }), branch: BRANCH }, eng.STDERR));
|
|
1387
|
+
return out13.keyMap || {};
|
|
1387
1388
|
}
|
|
1388
1389
|
function installedLaw(eng, ws) {
|
|
1389
1390
|
return JSON.parse(call(eng.ex, "query", { repoArg: repoArgOf(ws), workspace: ws, queryBytes: b64Json({ op: "installedLaw" }), branch: BRANCH }, eng.STDERR));
|
|
@@ -1392,8 +1393,8 @@ function domainPackage(eng, ws, hash) {
|
|
|
1392
1393
|
return JSON.parse(call(eng.ex, "query", { repoArg: repoArgOf(ws), workspace: ws, queryBytes: b64Json({ op: "domainPackage", hash }), branch: BRANCH }, eng.STDERR));
|
|
1393
1394
|
}
|
|
1394
1395
|
function declaredCapabilities(eng, ws) {
|
|
1395
|
-
const
|
|
1396
|
-
return
|
|
1396
|
+
const out13 = JSON.parse(call(eng.ex, "query", { repoArg: repoArgOf(ws), workspace: ws, queryBytes: b64Json({ op: "declaredCapabilities" }), branch: BRANCH }, eng.STDERR));
|
|
1397
|
+
return out13.capabilities || [];
|
|
1397
1398
|
}
|
|
1398
1399
|
function reactorScan(eng, ws) {
|
|
1399
1400
|
return JSON.parse(call(eng.ex, "outbox", { repoArg: repoArgOf(ws), branch: BRANCH }, eng.STDERR));
|
|
@@ -1494,13 +1495,13 @@ async function streamAll(stream) {
|
|
|
1494
1495
|
}
|
|
1495
1496
|
let len = 0;
|
|
1496
1497
|
for (const c of chunks) len += c.length;
|
|
1497
|
-
const
|
|
1498
|
+
const out13 = new Uint8Array(len);
|
|
1498
1499
|
let at = 0;
|
|
1499
1500
|
for (const c of chunks) {
|
|
1500
|
-
|
|
1501
|
+
out13.set(c, at);
|
|
1501
1502
|
at += c.length;
|
|
1502
1503
|
}
|
|
1503
|
-
return
|
|
1504
|
+
return out13;
|
|
1504
1505
|
}
|
|
1505
1506
|
async function gzip(bytes) {
|
|
1506
1507
|
const cs = new CompressionStream("gzip");
|
|
@@ -2078,13 +2079,16 @@ async function admitAll(eng, ws, ledger, { receiptFence = null, shardRouting = n
|
|
|
2078
2079
|
_projDone();
|
|
2079
2080
|
}
|
|
2080
2081
|
}
|
|
2082
|
+
let unparkedSessions = /* @__PURE__ */ new Set();
|
|
2081
2083
|
if (deadLetters.length) {
|
|
2082
2084
|
try {
|
|
2083
|
-
await materializeRefused(eng, ws, ledger, deadLetters);
|
|
2085
|
+
unparkedSessions = (await materializeRefused(eng, ws, ledger, deadLetters)).unparkedSessions;
|
|
2084
2086
|
} catch (e) {
|
|
2087
|
+
unparkedSessions = new Set(deadLetters.map((dl) => dl.session).filter(Boolean));
|
|
2085
2088
|
log("refused-materialize-failed", { ws, error: String(e).slice(0, 200) });
|
|
2086
2089
|
}
|
|
2087
2090
|
}
|
|
2091
|
+
const prunable = unparkedSessions.size ? consumed.filter((c) => !unparkedSessions.has(c.cid)) : consumed;
|
|
2088
2092
|
const hasCoordination = !!(summaryCtx || placements.length || splits.length || globalsOut.length);
|
|
2089
2093
|
const deferDurability = defer && !hasCoordination;
|
|
2090
2094
|
let _sealed = true;
|
|
@@ -2102,7 +2106,7 @@ async function admitAll(eng, ws, ledger, { receiptFence = null, shardRouting = n
|
|
|
2102
2106
|
}
|
|
2103
2107
|
}
|
|
2104
2108
|
if (_sealed && !deferDurability) {
|
|
2105
|
-
for (const { ref } of
|
|
2109
|
+
for (const { ref } of prunable) {
|
|
2106
2110
|
try {
|
|
2107
2111
|
await custodyPush(eng, ws, ledger, { remoteRef: ref, del: true });
|
|
2108
2112
|
} catch {
|
|
@@ -2125,7 +2129,7 @@ async function admitAll(eng, ws, ledger, { receiptFence = null, shardRouting = n
|
|
|
2125
2129
|
...globalsOut.length ? { globals: globalsOut } : {},
|
|
2126
2130
|
// The adapter's backup lane consumes these: `deferred` ⇒ resident main carries totalAdmitted
|
|
2127
2131
|
// un-backed-up commits and `consumed` are the session branches to delete AFTER the push lands.
|
|
2128
|
-
...deferDurability && totalAdmitted ? { deferred: true, consumed, admitted: totalAdmitted } : {}
|
|
2132
|
+
...deferDurability && totalAdmitted ? { deferred: true, consumed: prunable, admitted: totalAdmitted } : {}
|
|
2129
2133
|
};
|
|
2130
2134
|
}
|
|
2131
2135
|
async function backupHead(eng, ws, ledger, head) {
|
|
@@ -2308,11 +2312,23 @@ async function archiveRefusedMain(eng, ws, ledger, label) {
|
|
|
2308
2312
|
async function writeRefusedRef(eng, ws, dl) {
|
|
2309
2313
|
const gitdir = gitdirOf(ws);
|
|
2310
2314
|
const blob = dl.blob instanceof Uint8Array ? dl.blob : enc3.encode(String(dl.blob || ""));
|
|
2315
|
+
const refForStamp = refusedRefName(dl.intentId || dl.oid);
|
|
2316
|
+
let parkedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2317
|
+
try {
|
|
2318
|
+
const prevOid = kgit.resolveRef(eng, gitdir, refForStamp);
|
|
2319
|
+
if (prevOid) {
|
|
2320
|
+
const prev = JSON.parse(dec3.decode(kgit.readBlob(eng, gitdir, prevOid, "verdict.json")));
|
|
2321
|
+
if (prev && typeof prev.parkedAt === "string") parkedAt = prev.parkedAt;
|
|
2322
|
+
}
|
|
2323
|
+
} catch {
|
|
2324
|
+
}
|
|
2311
2325
|
const verdict = enc3.encode(JSON.stringify({
|
|
2312
2326
|
offerId: dl.intentId || null,
|
|
2313
2327
|
oid: dl.oid || null,
|
|
2314
2328
|
domain: dl.domain || null,
|
|
2315
2329
|
directiveId: dl.directiveId || null,
|
|
2330
|
+
session: dl.session || null,
|
|
2331
|
+
parkedAt,
|
|
2316
2332
|
verdict: { reason: String(dl.error || "refused") }
|
|
2317
2333
|
}));
|
|
2318
2334
|
const ref = refusedRefName(dl.intentId || dl.oid);
|
|
@@ -2328,31 +2344,46 @@ async function writeRefusedRef(eng, ws, dl) {
|
|
|
2328
2344
|
async function listRefusedRefs(eng, ws) {
|
|
2329
2345
|
const gitdir = gitdirOf(ws);
|
|
2330
2346
|
const refs = kgit.listRefs(eng, gitdir, "refs/heads/refused/");
|
|
2331
|
-
const
|
|
2347
|
+
const out13 = [];
|
|
2332
2348
|
for (const { ref, oid } of refs) {
|
|
2333
2349
|
try {
|
|
2334
2350
|
const vb = kgit.readBlob(eng, gitdir, oid, "verdict.json");
|
|
2335
2351
|
const ib = kgit.readBlob(eng, gitdir, oid, "intent.json");
|
|
2336
2352
|
const v = JSON.parse(dec3.decode(vb));
|
|
2337
|
-
|
|
2353
|
+
out13.push({ ref, ...v, intentB64: b64Bytes(ib) });
|
|
2338
2354
|
} catch {
|
|
2339
2355
|
}
|
|
2340
2356
|
}
|
|
2341
|
-
return
|
|
2357
|
+
return out13;
|
|
2342
2358
|
}
|
|
2343
|
-
async function
|
|
2359
|
+
async function refusedSummary(eng, ws) {
|
|
2344
2360
|
const gitdir = gitdirOf(ws);
|
|
2361
|
+
const refs = kgit.listRefs(eng, gitdir, "refs/heads/refused/");
|
|
2362
|
+
let count2 = 0, latestParkedAt = null;
|
|
2363
|
+
for (const { oid } of refs) {
|
|
2364
|
+
try {
|
|
2365
|
+
const v = JSON.parse(dec3.decode(kgit.readBlob(eng, gitdir, oid, "verdict.json")));
|
|
2366
|
+
count2++;
|
|
2367
|
+
if (v && typeof v.parkedAt === "string" && (!latestParkedAt || v.parkedAt > latestParkedAt)) latestParkedAt = v.parkedAt;
|
|
2368
|
+
} catch {
|
|
2369
|
+
}
|
|
2370
|
+
}
|
|
2371
|
+
return { count: count2, latestParkedAt };
|
|
2372
|
+
}
|
|
2373
|
+
async function materializeRefused(eng, ws, ledger, deadLetters) {
|
|
2345
2374
|
const refs = [];
|
|
2375
|
+
const unparkedSessions = /* @__PURE__ */ new Set();
|
|
2346
2376
|
for (const dl of deadLetters || []) {
|
|
2347
2377
|
try {
|
|
2348
2378
|
const ref = await writeRefusedRef(eng, ws, dl);
|
|
2349
2379
|
await custodyPush(eng, ws, ledger, { remoteRef: ref });
|
|
2350
2380
|
refs.push(ref);
|
|
2351
2381
|
} catch (e) {
|
|
2382
|
+
if (dl && dl.session) unparkedSessions.add(dl.session);
|
|
2352
2383
|
log("refused-ref-materialize-failed", { ws, intentId: dl?.intentId, error: String(e).slice(0, 200) });
|
|
2353
2384
|
}
|
|
2354
2385
|
}
|
|
2355
|
-
return refs;
|
|
2386
|
+
return { refs, unparkedSessions };
|
|
2356
2387
|
}
|
|
2357
2388
|
async function deleteRefusedRef(eng, ws, ledger, offerId) {
|
|
2358
2389
|
const gitdir = gitdirOf(ws);
|
|
@@ -2501,9 +2532,9 @@ async function ledgerStats(eng, ws, ledger = null) {
|
|
|
2501
2532
|
const mounted = eng.mounted.get(ws);
|
|
2502
2533
|
if (mounted?.ledgerStats?.head === head) return mounted.ledgerStats;
|
|
2503
2534
|
const commits = kgit.intentsAbove(eng, gitdir, head).length;
|
|
2504
|
-
const
|
|
2505
|
-
if (mounted) mounted.ledgerStats =
|
|
2506
|
-
return
|
|
2535
|
+
const out13 = { head, commits };
|
|
2536
|
+
if (mounted) mounted.ledgerStats = out13;
|
|
2537
|
+
return out13;
|
|
2507
2538
|
}
|
|
2508
2539
|
async function countRemoteCommits(eng, ledger) {
|
|
2509
2540
|
const head = (await custodyLsRefs(ledger, "refs/heads/main"))["refs/heads/main"] || null;
|
|
@@ -2976,6 +3007,7 @@ var governance_exports = {};
|
|
|
2976
3007
|
__export(governance_exports, {
|
|
2977
3008
|
HONEST_CEILING: () => HONEST_CEILING,
|
|
2978
3009
|
ROOT_CUSTODIAN_SECRET: () => ROOT_CUSTODIAN_SECRET,
|
|
3010
|
+
STAGE_THRESHOLD_CHARS: () => STAGE_THRESHOLD_CHARS,
|
|
2979
3011
|
buildCertificate: () => buildCertificate,
|
|
2980
3012
|
buildRebirthPlan: () => buildRebirthPlan,
|
|
2981
3013
|
certifyEra: () => certifyEra,
|
|
@@ -2996,6 +3028,7 @@ __export(governance_exports, {
|
|
|
2996
3028
|
rebirthApply: () => rebirthApply,
|
|
2997
3029
|
rebirthPlanCommand: () => rebirthPlanCommand,
|
|
2998
3030
|
rebirthWorkspace: () => rebirthWorkspace,
|
|
3031
|
+
relaySealedOfferViaStage: () => relaySealedOfferViaStage,
|
|
2999
3032
|
renderRebirthImpact: () => renderRebirthImpact,
|
|
3000
3033
|
resolveGovernanceHash: () => resolveGovernanceHash,
|
|
3001
3034
|
resolveGovernancePrincipal: () => resolveGovernancePrincipal,
|
|
@@ -3055,9 +3088,41 @@ async function signAndPostOffer(ws, domain, directiveId, payload, opts) {
|
|
|
3055
3088
|
authorSecret: device.secret,
|
|
3056
3089
|
actor: `user:${principal}`
|
|
3057
3090
|
});
|
|
3091
|
+
if (sealed.intentBytes.length > STAGE_THRESHOLD_CHARS) {
|
|
3092
|
+
const staged = await relaySealedOfferViaStage(cloud, ws, directiveId, sealed.intentBytes, fetch);
|
|
3093
|
+
if (staged !== null) {
|
|
3094
|
+
out2(` staged ${staged.size} sealed bytes content-addressed (sha256 ${staged.sha256.slice(0, 16)}\u2026) \u2014 the signed offer names the hash`);
|
|
3095
|
+
return { ...staged.verdict, principal };
|
|
3096
|
+
}
|
|
3097
|
+
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)`);
|
|
3098
|
+
}
|
|
3058
3099
|
const verdict = await holon.postGovernanceOffer({ directiveId, intentBytes: sealed.intentBytes, ws });
|
|
3059
3100
|
return { ...verdict, principal };
|
|
3060
3101
|
}
|
|
3102
|
+
async function relaySealedOfferViaStage(cloud, ws, directiveId, intentBytesB64, fetchImpl) {
|
|
3103
|
+
const raw = Buffer.from(intentBytesB64, "base64");
|
|
3104
|
+
const sha2562 = createHash("sha256").update(raw).digest("hex");
|
|
3105
|
+
let put;
|
|
3106
|
+
try {
|
|
3107
|
+
put = await fetchImpl(`${cloud}/v2/stage/${sha2562}`, { method: "PUT", body: raw });
|
|
3108
|
+
} catch {
|
|
3109
|
+
return null;
|
|
3110
|
+
}
|
|
3111
|
+
if (!put.ok) return null;
|
|
3112
|
+
const r = await fetchImpl(`${cloud}/v2/workspaces/${ws}/${directiveId}`, {
|
|
3113
|
+
method: "POST",
|
|
3114
|
+
headers: { "content-type": "application/json" },
|
|
3115
|
+
body: JSON.stringify({ intentRef: { sha256: sha2562, size: raw.length } })
|
|
3116
|
+
});
|
|
3117
|
+
const text = await r.text();
|
|
3118
|
+
let body;
|
|
3119
|
+
try {
|
|
3120
|
+
body = JSON.parse(text);
|
|
3121
|
+
} catch {
|
|
3122
|
+
body = text;
|
|
3123
|
+
}
|
|
3124
|
+
return { sha256: sha2562, size: raw.length, verdict: { ok: r.ok, status: r.status, body } };
|
|
3125
|
+
}
|
|
3061
3126
|
async function signAndPostGovernance(parent, directiveId, payload, opts) {
|
|
3062
3127
|
return signAndPostOffer(parent, "workspaces", directiveId, payload, opts);
|
|
3063
3128
|
}
|
|
@@ -4273,13 +4338,14 @@ function readSealedIntentBytes(eng, ws, intentOut) {
|
|
|
4273
4338
|
if (f?.data === void 0) return void 0;
|
|
4274
4339
|
return Buffer.from(f.data).toString("base64");
|
|
4275
4340
|
}
|
|
4276
|
-
var out2, err2, HONEST_CEILING, ROOT_CUSTODIAN_SECRET, CLIENT_IMPACT;
|
|
4341
|
+
var out2, err2, STAGE_THRESHOLD_CHARS, HONEST_CEILING, ROOT_CUSTODIAN_SECRET, CLIENT_IMPACT;
|
|
4277
4342
|
var init_governance = __esm({
|
|
4278
4343
|
"src/governance.ts"() {
|
|
4279
4344
|
"use strict";
|
|
4280
4345
|
init_cloud();
|
|
4281
4346
|
out2 = (s) => void process.stdout.write(s + "\n");
|
|
4282
4347
|
err2 = (s) => void process.stderr.write("error: " + s + "\n");
|
|
4348
|
+
STAGE_THRESHOLD_CHARS = 4 * 1024 * 1024;
|
|
4283
4349
|
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."`;
|
|
4284
4350
|
ROOT_CUSTODIAN_SECRET = "nomos-root-custodian-key";
|
|
4285
4351
|
CLIENT_IMPACT = "every connected client raises CustodyBreak(superseded); unsynced client work is invisible to the cloud \u2014 drain/sync clients first";
|
|
@@ -6582,11 +6648,11 @@ function bareTypeLabel(t) {
|
|
|
6582
6648
|
return i > 0 && i < t.length - 1 ? t.slice(i + 1) : t;
|
|
6583
6649
|
}
|
|
6584
6650
|
function geoFieldsOfInstalls(installs) {
|
|
6585
|
-
const
|
|
6651
|
+
const out13 = /* @__PURE__ */ new Map();
|
|
6586
6652
|
const add2 = (type, field) => {
|
|
6587
|
-
const set =
|
|
6653
|
+
const set = out13.get(type) ?? /* @__PURE__ */ new Set();
|
|
6588
6654
|
set.add(field);
|
|
6589
|
-
|
|
6655
|
+
out13.set(type, set);
|
|
6590
6656
|
};
|
|
6591
6657
|
for (const inst of installs) {
|
|
6592
6658
|
for (const layer of inst.layers) {
|
|
@@ -6602,7 +6668,7 @@ function geoFieldsOfInstalls(installs) {
|
|
|
6602
6668
|
}
|
|
6603
6669
|
}
|
|
6604
6670
|
}
|
|
6605
|
-
return
|
|
6671
|
+
return out13;
|
|
6606
6672
|
}
|
|
6607
6673
|
function pointOfOpValue(setOp) {
|
|
6608
6674
|
let v = setOp["Json"];
|
|
@@ -7360,6 +7426,65 @@ var init_scene = __esm({
|
|
|
7360
7426
|
}
|
|
7361
7427
|
});
|
|
7362
7428
|
|
|
7429
|
+
// src/dlq.ts
|
|
7430
|
+
var dlq_exports = {};
|
|
7431
|
+
__export(dlq_exports, {
|
|
7432
|
+
dlqSweep: () => dlqSweep,
|
|
7433
|
+
renderSweepNode: () => renderSweepNode
|
|
7434
|
+
});
|
|
7435
|
+
function renderSweepNode(n, indent = "") {
|
|
7436
|
+
const jammed = n.dlqCount > 0;
|
|
7437
|
+
const badge = n.error !== void 0 ? "?" : jammed ? "\u2717" : "\u2713";
|
|
7438
|
+
const detail = n.error !== void 0 ? `unreachable: ${n.error}` : jammed ? `${n.dlqCount} dead-letter${n.dlqCount === 1 ? "" : "s"} (latest ${n.latestParkedAt ?? "unknown"})` : "clean";
|
|
7439
|
+
const lines = [`${indent}${badge} ${n.workspace} \u2014 ${detail}`];
|
|
7440
|
+
for (const dl of n.deadLetters ?? []) {
|
|
7441
|
+
lines.push(`${indent} \xB7 ${dl.domain ?? "?"}/${dl.directiveId ?? "?"} [${dl.intentId ?? "?"}] ${String(dl.error ?? "").slice(0, 100)}`);
|
|
7442
|
+
}
|
|
7443
|
+
for (const c of n.children ?? []) lines.push(...renderSweepNode(c, indent + " "));
|
|
7444
|
+
if (n.truncatedChildren) lines.push(`${indent} \u2026 ${n.truncatedChildren} more child(ren) truncated \u2014 raise ?limit or sweep a subtree`);
|
|
7445
|
+
return lines;
|
|
7446
|
+
}
|
|
7447
|
+
async function dlqSweep(ws, opts = {}) {
|
|
7448
|
+
const cloud = cloudBase(opts.cloud);
|
|
7449
|
+
const q = new URLSearchParams();
|
|
7450
|
+
if (opts.depth !== void 0) q.set("depth", String(opts.depth));
|
|
7451
|
+
if (opts.full === true) q.set("full", "1");
|
|
7452
|
+
const url = `${cloud}/v2/workspaces/${encodeURIComponent(ws)}/dlq-sweep${q.size ? `?${q}` : ""}`;
|
|
7453
|
+
let body;
|
|
7454
|
+
try {
|
|
7455
|
+
const res = await fetch(url);
|
|
7456
|
+
body = await res.json();
|
|
7457
|
+
if (body.ok !== true || body.root === void 0) {
|
|
7458
|
+
err12(`dlq sweep refused: ${String(body.error ?? "no sweep in the response").slice(0, 300)}`);
|
|
7459
|
+
return 1;
|
|
7460
|
+
}
|
|
7461
|
+
} catch (e) {
|
|
7462
|
+
err12(`dlq sweep failed against ${cloud}: ${e.message}`);
|
|
7463
|
+
return 1;
|
|
7464
|
+
}
|
|
7465
|
+
if (opts.json === true) {
|
|
7466
|
+
out12(JSON.stringify(body, null, 2));
|
|
7467
|
+
return body.jammed ? 2 : 0;
|
|
7468
|
+
}
|
|
7469
|
+
out12(`DLQ sweep of '${ws}' \u2014 ${body.nodes} node(s), ${body.jammed} jammed`);
|
|
7470
|
+
for (const line of renderSweepNode(body.root)) out12(line);
|
|
7471
|
+
if (body.jammed) {
|
|
7472
|
+
out12("");
|
|
7473
|
+
out12("unjam: fix/deploy the law on the jammed workspace, then POST /v2/workspaces/<node>/dead-letters/retry");
|
|
7474
|
+
out12(" (or from the app: holon.retryDeadLetter(id); discard is the app's explicit choice)");
|
|
7475
|
+
}
|
|
7476
|
+
return body.jammed ? 2 : 0;
|
|
7477
|
+
}
|
|
7478
|
+
var out12, err12;
|
|
7479
|
+
var init_dlq = __esm({
|
|
7480
|
+
"src/dlq.ts"() {
|
|
7481
|
+
"use strict";
|
|
7482
|
+
init_cloud();
|
|
7483
|
+
out12 = (s) => void process.stdout.write(s + "\n");
|
|
7484
|
+
err12 = (s) => void process.stderr.write("error: " + s + "\n");
|
|
7485
|
+
}
|
|
7486
|
+
});
|
|
7487
|
+
|
|
7363
7488
|
// src/cli.ts
|
|
7364
7489
|
import { existsSync as existsSync14, readdirSync as readdirSync5, readFileSync as readFileSync14 } from "node:fs";
|
|
7365
7490
|
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
@@ -8078,6 +8203,18 @@ var HELP = {
|
|
|
8078
8203
|
],
|
|
8079
8204
|
examples: ["githolon status", "githolon status my-guestbook", "githolon status --target prod"]
|
|
8080
8205
|
},
|
|
8206
|
+
dlq: {
|
|
8207
|
+
usage: "githolon dlq sweep <workspace> [--depth <n>] [--full] [--json] [--cloud <url>]",
|
|
8208
|
+
what: "THE FLEET/SUBTREE DLQ SWEEP (architecture/operator_dlq_sweep.md): one look across a platform's\ndead-letter queues. The cloud enumerates the subtree via the REGISTRY (the maintained\nworkspacesByParent projection index \u2014 never a chain walk), reads each node's O(1) DLQ summary\n({count, latestParkedAt}) and prints the tree; jammed nodes carry their parked entries under\n--full. Read-only; the unjam stays POST /v2/workspaces/<node>/dead-letters/retry after the law\nfix. Exit codes: 0 all clean \xB7 2 jams found \xB7 1 error.",
|
|
8209
|
+
flags: [
|
|
8210
|
+
["<workspace>", "the subtree root \u2014 a platform, or any workspace (a non-governance node is a leaf)"],
|
|
8211
|
+
["--depth <n>", "recursion depth (default 2, max 4; 1 = the node alone)"],
|
|
8212
|
+
["--full", "include the parked entries for jammed nodes (clean nodes never pay a fetch)"],
|
|
8213
|
+
["--json", "the raw sweep tree, machine-consumable"],
|
|
8214
|
+
["--cloud <url>", "target cloud (default: $NOMOS_CLOUD or the public cloud)"]
|
|
8215
|
+
],
|
|
8216
|
+
examples: ["githolon dlq sweep co2-platform", "githolon dlq sweep co2-platform --depth 3 --full", "githolon dlq sweep my-ws --json"]
|
|
8217
|
+
},
|
|
8081
8218
|
compat: {
|
|
8082
8219
|
usage: "githolon compat <ws-url | deploy.json | interface.json | dir> [--config <cfg>] [--workspace <ws>] [--json]",
|
|
8083
8220
|
what: "THE CI GATE (the compat superpower): compare the CURRENT build's structural interface\n(build/<name>.interface.json \u2014 run `githolon compile` first) against a TARGET's installed law,\nPER MEMBER via #72 subtyping. Exits NON-ZERO on any incompatible member, so a client/law\nmismatch is caught before it ships. Target: a deploy.json (its staged .interface is the offer),\nan .interface.json / build dir, or a LIVE workspace URL (connect()s + reads the on-ledger offer).",
|
|
@@ -8374,9 +8511,9 @@ function capJsonStrings(v, max = 2048) {
|
|
|
8374
8511
|
if (typeof v === "string") return v.length > max ? `${v.slice(0, max)}\u2026(${v.length} chars)` : v;
|
|
8375
8512
|
if (Array.isArray(v)) return v.map((x) => capJsonStrings(x, max));
|
|
8376
8513
|
if (typeof v === "object" && v !== null) {
|
|
8377
|
-
const
|
|
8378
|
-
for (const [k, x] of Object.entries(v))
|
|
8379
|
-
return
|
|
8514
|
+
const out13 = {};
|
|
8515
|
+
for (const [k, x] of Object.entries(v)) out13[k] = capJsonStrings(x, max);
|
|
8516
|
+
return out13;
|
|
8380
8517
|
}
|
|
8381
8518
|
return v;
|
|
8382
8519
|
}
|
|
@@ -8834,6 +8971,8 @@ deploy is OPEN + kernel-gated \u2014 births return no host secret, ownership is
|
|
|
8834
8971
|
[--explain-current-interface] lineage (active = served now)
|
|
8835
8972
|
githolon domains retire <ws> <hashOrKey> retire an install (marks it retired \u2014 replayable,
|
|
8836
8973
|
[--with <hashOrKey>] no longer served) via a signed installDomain offer
|
|
8974
|
+
githolon dlq sweep <ws> [--depth <n>] [--full] sweep a platform subtree's dead-letter queues
|
|
8975
|
+
(registry-enumerated; exit 2 when jams exist)
|
|
8837
8976
|
githolon secret set <ws> <push-password> store a git push password (push-to-create birth lane)
|
|
8838
8977
|
githolon secret rotate <ws> RETIRED \u2014 host holds no ownership credential (410)
|
|
8839
8978
|
|
|
@@ -8858,8 +8997,8 @@ Options:
|
|
|
8858
8997
|
function cloudArgs(rest) {
|
|
8859
8998
|
const pos = [];
|
|
8860
8999
|
const opts = {};
|
|
8861
|
-
const VALUE_FLAGS = ["--cloud", "--principal", "--as", "--file", "--target", "--parent", "--via", "--max", "--label", "--secret", "--payload", "--payload-file", "--save", "--format", "--with", "--out", "--reason", "--oid", "--seed-secret", "--gcp-secret", "--controller-hash", "--plan"];
|
|
8862
|
-
const BOOL_FLAGS = ["--sha256", "--stamp", "--yes", "--clear", "--keep-beside", "--retire-replaced", "--explain-current-interface", "--dry-run", "--json"];
|
|
9000
|
+
const VALUE_FLAGS = ["--cloud", "--principal", "--as", "--file", "--target", "--parent", "--via", "--max", "--label", "--secret", "--payload", "--payload-file", "--save", "--format", "--with", "--out", "--reason", "--oid", "--seed-secret", "--gcp-secret", "--controller-hash", "--plan", "--depth"];
|
|
9001
|
+
const BOOL_FLAGS = ["--sha256", "--stamp", "--yes", "--clear", "--keep-beside", "--retire-replaced", "--explain-current-interface", "--dry-run", "--json", "--full"];
|
|
8863
9002
|
for (let i = 0; i < rest.length; i++) {
|
|
8864
9003
|
const a = rest[i];
|
|
8865
9004
|
if (BOOL_FLAGS.includes(a)) {
|
|
@@ -8871,6 +9010,7 @@ function cloudArgs(rest) {
|
|
|
8871
9010
|
else if (a === "--explain-current-interface") opts.explain = true;
|
|
8872
9011
|
else if (a === "--dry-run") opts.dryRun = true;
|
|
8873
9012
|
else if (a === "--json") opts.json = true;
|
|
9013
|
+
else if (a === "--full") opts.full = true;
|
|
8874
9014
|
else opts.yes = true;
|
|
8875
9015
|
} else if (VALUE_FLAGS.includes(a)) {
|
|
8876
9016
|
const v = rest[++i];
|
|
@@ -8892,6 +9032,10 @@ function cloudArgs(rest) {
|
|
|
8892
9032
|
const n = Number(v);
|
|
8893
9033
|
if (!Number.isInteger(n) || n <= 0) return { pos, opts, bad: `--max requires a positive integer` };
|
|
8894
9034
|
opts.max = n;
|
|
9035
|
+
} else if (a === "--depth") {
|
|
9036
|
+
const n = Number(v);
|
|
9037
|
+
if (!Number.isInteger(n) || n <= 0) return { pos, opts, bad: `--depth requires a positive integer` };
|
|
9038
|
+
opts.depth = n;
|
|
8895
9039
|
} else opts.file = v;
|
|
8896
9040
|
} else if (a.startsWith("--")) {
|
|
8897
9041
|
return { pos, opts, bad: `unknown flag '${a}'` };
|
|
@@ -9155,10 +9299,10 @@ async function main(argv) {
|
|
|
9155
9299
|
};
|
|
9156
9300
|
const deployArg = pull("--deploy");
|
|
9157
9301
|
const workspace = pull("--workspace") ?? "test-ws";
|
|
9158
|
-
const
|
|
9302
|
+
const out13 = pull("--out");
|
|
9159
9303
|
const runtime = pull("--runtime");
|
|
9160
9304
|
const deploy3 = (deployArg ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
9161
|
-
if (deploy3.length === 0 ||
|
|
9305
|
+
if (deploy3.length === 0 || out13 === void 0) {
|
|
9162
9306
|
process.stderr.write(
|
|
9163
9307
|
`error: usage: githolon harness-install --deploy <deploy.json[,deploy.json...]> --workspace <ws> --out <snapshotPath> [--runtime <dir>]
|
|
9164
9308
|
`
|
|
@@ -9166,7 +9310,7 @@ async function main(argv) {
|
|
|
9166
9310
|
return 1;
|
|
9167
9311
|
}
|
|
9168
9312
|
const { harnessInstall: harnessInstall2 } = await Promise.resolve().then(() => (init_harness(), harness_exports));
|
|
9169
|
-
return harnessInstall2({ deploy: deploy3, workspace, out:
|
|
9313
|
+
return harnessInstall2({ deploy: deploy3, workspace, out: out13, ...runtime !== void 0 ? { runtime } : {} });
|
|
9170
9314
|
}
|
|
9171
9315
|
if (argv[0] === "dev") {
|
|
9172
9316
|
const rest = argv.slice(1);
|
|
@@ -9300,6 +9444,24 @@ ${commandHelp("status")}`);
|
|
|
9300
9444
|
if (argv[0] === "ws" || argv[0] === "deploy" || argv[0] === "secret") {
|
|
9301
9445
|
return runCloud(argv);
|
|
9302
9446
|
}
|
|
9447
|
+
if (argv[0] === "dlq") {
|
|
9448
|
+
const { dlqSweep: dlqSweep2 } = await Promise.resolve().then(() => (init_dlq(), dlq_exports));
|
|
9449
|
+
const { pos, opts, bad } = cloudArgs(argv.slice(1));
|
|
9450
|
+
if (bad !== void 0) {
|
|
9451
|
+
process.stderr.write(`error: ${bad}
|
|
9452
|
+
|
|
9453
|
+
${commandHelp("dlq") ?? USAGE}`);
|
|
9454
|
+
return 1;
|
|
9455
|
+
}
|
|
9456
|
+
const [sub2, ws] = pos;
|
|
9457
|
+
if (sub2 !== "sweep" || ws === void 0) {
|
|
9458
|
+
process.stderr.write(`error: expected: githolon dlq sweep <workspace> [--depth <n>] [--full] [--json]
|
|
9459
|
+
|
|
9460
|
+
${commandHelp("dlq") ?? USAGE}`);
|
|
9461
|
+
return 1;
|
|
9462
|
+
}
|
|
9463
|
+
return dlqSweep2(ws, opts);
|
|
9464
|
+
}
|
|
9303
9465
|
if (argv[0] === "domains") {
|
|
9304
9466
|
const { domainsRetire: domainsRetire2, domainsStatus: domainsStatus2 } = await Promise.resolve().then(() => (init_lifecycle(), lifecycle_exports));
|
|
9305
9467
|
const { pos, opts, bad } = cloudArgs(argv.slice(1));
|
|
@@ -9626,8 +9788,8 @@ ${USAGE}`);
|
|
|
9626
9788
|
let parsed;
|
|
9627
9789
|
try {
|
|
9628
9790
|
parsed = parseArgs(argv);
|
|
9629
|
-
} catch (
|
|
9630
|
-
process.stderr.write(`error: ${
|
|
9791
|
+
} catch (err13) {
|
|
9792
|
+
process.stderr.write(`error: ${err13.message}
|
|
9631
9793
|
|
|
9632
9794
|
${USAGE}`);
|
|
9633
9795
|
return 1;
|
|
@@ -9646,8 +9808,8 @@ ${USAGE}`);
|
|
|
9646
9808
|
process.stdout.write(`created ${path}
|
|
9647
9809
|
`);
|
|
9648
9810
|
return 0;
|
|
9649
|
-
} catch (
|
|
9650
|
-
process.stderr.write(`error: ${
|
|
9811
|
+
} catch (err13) {
|
|
9812
|
+
process.stderr.write(`error: ${err13.message}
|
|
9651
9813
|
`);
|
|
9652
9814
|
return 1;
|
|
9653
9815
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "githolon",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.75.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.75.1",
|
|
33
|
+
"@githolon/dsl": "^0.75.1",
|
|
34
34
|
"isomorphic-git": "^1.38.4"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|