githolon 0.116.2 → 0.117.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/full-cli.mjs
CHANGED
|
@@ -3707,18 +3707,18 @@ function mint(typeTag) {
|
|
|
3707
3707
|
function recordIdentity(typeTag) {
|
|
3708
3708
|
const queued = authoringContext?.preMintedRecords;
|
|
3709
3709
|
if (queued === void 0 || queued.length === 0) return mint(typeTag);
|
|
3710
|
-
const
|
|
3711
|
-
if (
|
|
3710
|
+
const record2 = queued.shift();
|
|
3711
|
+
if (record2.type !== typeTag) {
|
|
3712
3712
|
throw new Error(
|
|
3713
|
-
`Nomos reserved an owned '${
|
|
3713
|
+
`Nomos reserved an owned '${record2.type}' identity, but the law tried to create '${typeTag}'. The generated client and installed law disagree; recompile them together.`
|
|
3714
3714
|
);
|
|
3715
3715
|
}
|
|
3716
|
-
if (!
|
|
3716
|
+
if (!record2.id.startsWith(`${typeTag}_`)) {
|
|
3717
3717
|
throw new Error(
|
|
3718
|
-
`Nomos reserved owned '${typeTag}' identity '${
|
|
3718
|
+
`Nomos reserved owned '${typeTag}' identity '${record2.id}', but that id belongs to another type. The generated client and installed law disagree; recompile them together.`
|
|
3719
3719
|
);
|
|
3720
3720
|
}
|
|
3721
|
-
return
|
|
3721
|
+
return record2.id;
|
|
3722
3722
|
}
|
|
3723
3723
|
function create(agg) {
|
|
3724
3724
|
const id = recordIdentity(__qualifyAggregateType(agg.id));
|
|
@@ -5656,10 +5656,10 @@ function readInheritedOperators() {
|
|
|
5656
5656
|
function writeFoundingPrincipal(p) {
|
|
5657
5657
|
const grantedBy = "genesis";
|
|
5658
5658
|
const grantedAt = String(p.grantedAt);
|
|
5659
|
-
const
|
|
5659
|
+
const record2 = instance(FoundingPrincipal, FOUNDING_PRINCIPAL_ID);
|
|
5660
5660
|
return [
|
|
5661
|
-
set(
|
|
5662
|
-
set(
|
|
5661
|
+
set(record2, "principal", p.principal),
|
|
5662
|
+
set(record2, "keyHash", p.keyHash),
|
|
5663
5663
|
...writeTuple({
|
|
5664
5664
|
object: signerObject(p.principal),
|
|
5665
5665
|
relation: SIGNER_RELATION,
|
|
@@ -5736,8 +5736,8 @@ var init_founding_genesis = __esm({
|
|
|
5736
5736
|
parentIntent: t.string().merge(Lww)
|
|
5737
5737
|
}).public();
|
|
5738
5738
|
seedBirthOrigin = directive(SEED_BIRTH_ORIGIN_DIRECTIVE).ensures(BirthOrigin).payload(z16.object({ parent: z16.string().min(1), parentIntent: z16.string().min(1) }).strict()).plan((p) => {
|
|
5739
|
-
const
|
|
5740
|
-
return [set(
|
|
5739
|
+
const record2 = instance(BirthOrigin, BIRTH_ORIGIN_ID);
|
|
5740
|
+
return [set(record2, "parent", p.parent), set(record2, "parentIntent", p.parentIntent)];
|
|
5741
5741
|
});
|
|
5742
5742
|
birthOriginVirginOnly = workspaceInvariant("BirthOriginVirginOnly").on(SEED_BIRTH_ORIGIN_DIRECTIVE).reads(readSet(
|
|
5743
5743
|
readRef("warrant", "GenesisWarrant").pre().at(GENESIS_WARRANT_ID),
|
|
@@ -6361,26 +6361,26 @@ var init_birth_meter2 = __esm({
|
|
|
6361
6361
|
];
|
|
6362
6362
|
}).requires("admin");
|
|
6363
6363
|
reclaimChildRequiresRetired = workspaceInvariant("ReclaimChildRequiresRetired").on("reclaimChild").reads(readSet(readRef("record", NomosChildLifecycle).pre().fromPayload("child", { prefix: "nomos-child-lifecycle:" }))).assert(
|
|
6364
|
-
({ record }, ctx) =>
|
|
6364
|
+
({ record: record2 }, ctx) => record2?.status === "retired" && sameLifecyclePrincipal(record2.principal, ctx?.principal) ? { accept: true } : { reject: "reclaim-child-requires-retired" }
|
|
6365
6365
|
);
|
|
6366
6366
|
reclaimChildAsAdminRequiresRetired = workspaceInvariant("ReclaimChildAsAdminRequiresRetired").on("reclaimChildAsAdmin").reads(readSet(readRef("record", NomosChildLifecycle).pre().fromPayload("child", { prefix: "nomos-child-lifecycle:" }))).assert(
|
|
6367
|
-
({ record }) =>
|
|
6367
|
+
({ record: record2 }) => record2?.status === "retired" ? { accept: true } : { reject: "reclaim-child-requires-retired" }
|
|
6368
6368
|
);
|
|
6369
6369
|
retireChildNotReclaimed = workspaceInvariant("RetireChildNotReclaimed").on("retireChild").reads(readSet(readRef("record", NomosChildLifecycle).pre().fromPayload("child", { prefix: "nomos-child-lifecycle:" }))).assert(
|
|
6370
|
-
({ record }) =>
|
|
6370
|
+
({ record: record2 }) => record2?.status === "reclaimed" ? { reject: "reclaimed-child-is-terminal" } : { accept: true }
|
|
6371
6371
|
);
|
|
6372
6372
|
retireChildAsAdminNotReclaimed = workspaceInvariant("RetireChildAsAdminNotReclaimed").on("retireChildAsAdmin").reads(readSet(readRef("record", NomosChildLifecycle).pre().fromPayload("child", { prefix: "nomos-child-lifecycle:" }))).assert(
|
|
6373
|
-
({ record }) =>
|
|
6373
|
+
({ record: record2 }) => record2?.status === "reclaimed" ? { reject: "reclaimed-child-is-terminal" } : { accept: true }
|
|
6374
6374
|
);
|
|
6375
6375
|
retireChildRequiresBirth = workspaceInvariant("RetireChildRequiresBirth").on("retireChild").reads(readSet(readRef("birth", NomosBirthRecord).pre().fromPayload("child", { prefix: "nomos-birth-record:" }))).assert(({ birth: birth2 }, ctx) => {
|
|
6376
|
-
const
|
|
6376
|
+
const record2 = birth2;
|
|
6377
6377
|
const intent2 = ctx?.intent;
|
|
6378
|
-
return
|
|
6378
|
+
return record2?.child === intent2?.child && record2?.principal === intent2?.principal && sameLifecyclePrincipal(record2?.principal, ctx?.principal) ? { accept: true } : { reject: "retire-child-requires-exact-birth-record" };
|
|
6379
6379
|
});
|
|
6380
6380
|
retireChildAsAdminRequiresBirth = workspaceInvariant("RetireChildAsAdminRequiresBirth").on("retireChildAsAdmin").reads(readSet(readRef("birth", NomosBirthRecord).pre().fromPayload("child", { prefix: "nomos-birth-record:" }))).assert(({ birth: birth2 }, ctx) => {
|
|
6381
|
-
const
|
|
6381
|
+
const record2 = birth2;
|
|
6382
6382
|
const intent2 = ctx?.intent;
|
|
6383
|
-
return
|
|
6383
|
+
return record2?.child === intent2?.child && record2?.principal === intent2?.principal ? { accept: true } : { reject: "retire-child-requires-exact-birth-record" };
|
|
6384
6384
|
});
|
|
6385
6385
|
setBirthPolicy = directive("setBirthPolicy").ensures(BirthPolicy).payload(
|
|
6386
6386
|
z20.object({
|
|
@@ -11443,7 +11443,7 @@ var init_pack_import_steps = __esm({
|
|
|
11443
11443
|
this.#millisPerByte = this.#millisPerByte === void 0 ? sample : (this.#millisPerByte + sample) / 2;
|
|
11444
11444
|
}
|
|
11445
11445
|
};
|
|
11446
|
-
yieldToQueuedWork = () => new Promise((
|
|
11446
|
+
yieldToQueuedWork = () => new Promise((resolve12) => setTimeout(resolve12, 0));
|
|
11447
11447
|
}
|
|
11448
11448
|
});
|
|
11449
11449
|
|
|
@@ -12156,6 +12156,18 @@ function gitCustodyDesk(kernel, fetchImpl = fetch, observe, phaseStarted, import
|
|
|
12156
12156
|
}
|
|
12157
12157
|
const publish = async (allowReconcile) => {
|
|
12158
12158
|
const oldHead = remote.get(reference) ?? ZERO_OID;
|
|
12159
|
+
const expectedRemote = sealedMain.get(key2) ?? resolveRef(workspace, receiptRef(ledger)) ?? ZERO_OID;
|
|
12160
|
+
if (allowReconcile && expectedRemote !== ZERO_OID && oldHead !== expectedRemote) {
|
|
12161
|
+
remote = new Map(Object.entries(await lsRefs(
|
|
12162
|
+
ledger.remote,
|
|
12163
|
+
ledger.headers ?? {},
|
|
12164
|
+
{ service: "git-receive-pack", prefix: "refs/", signal: ledger.signal },
|
|
12165
|
+
fetchImpl
|
|
12166
|
+
)));
|
|
12167
|
+
observedRemoteRefs.set(key2, remote);
|
|
12168
|
+
await publish(false);
|
|
12169
|
+
return;
|
|
12170
|
+
}
|
|
12159
12171
|
const bookmarkUpdates = [SYNC_BASE_REF, PLACEMENT_SYNC_BASE_REF].filter((ref2) => named.has(ref2) && remote.get(ref2) !== named.get(ref2)).map((ref2) => ({ ref: ref2, oldOid: remote.get(ref2) ?? ZERO_OID, newOid: named.get(ref2) }));
|
|
12160
12172
|
const outcomeUpdates = cursors.filter(([ref2]) => ref2.startsWith(EFFECT_OUTCOME_PREFIX) && remote.get(ref2) === void 0).map(([ref2, oid]) => ({ ref: ref2, oldOid: ZERO_OID, newOid: oid }));
|
|
12161
12173
|
const deliveryUpdates = cursors.filter(([ref2]) => ref2.startsWith(DELIVERY_PREFIX) && remote.get(ref2) === void 0).map(([ref2, oid]) => ({ ref: ref2, oldOid: ZERO_OID, newOid: oid }));
|
|
@@ -12165,7 +12177,6 @@ function gitCustodyDesk(kernel, fetchImpl = fetch, observe, phaseStarted, import
|
|
|
12165
12177
|
if (ledger.readOnly) {
|
|
12166
12178
|
throw new Error(`read-only custody for '${workspace}' does not hold the requested frontier`);
|
|
12167
12179
|
}
|
|
12168
|
-
const expectedRemote = sealedMain.get(key2) ?? resolveRef(workspace, receiptRef(ledger)) ?? ZERO_OID;
|
|
12169
12180
|
let ancestryPack;
|
|
12170
12181
|
if (oldHead !== expectedRemote && oldHead !== head) {
|
|
12171
12182
|
if (oldHead !== ZERO_OID) {
|
|
@@ -12504,7 +12515,7 @@ function filesystemCustodyFetch(dataDir, origin, options = {}, networkFetch = fe
|
|
|
12504
12515
|
async function runGitHttpBackend(projectRoot, { method, pathInfo, query: query2, contentType, body }, options = {}) {
|
|
12505
12516
|
const stdin = body && body.length ? await requestBodyStdin(body) : void 0;
|
|
12506
12517
|
try {
|
|
12507
|
-
return await new Promise((
|
|
12518
|
+
return await new Promise((resolve12, reject) => {
|
|
12508
12519
|
const env = {
|
|
12509
12520
|
...process.env,
|
|
12510
12521
|
GIT_PROJECT_ROOT: projectRoot,
|
|
@@ -12579,7 +12590,7 @@ async function runGitHttpBackend(projectRoot, { method, pathInfo, query: query2,
|
|
|
12579
12590
|
}
|
|
12580
12591
|
headers[k] = v;
|
|
12581
12592
|
}
|
|
12582
|
-
|
|
12593
|
+
resolve12({ status: status2, headers, body: payload });
|
|
12583
12594
|
});
|
|
12584
12595
|
});
|
|
12585
12596
|
} finally {
|
|
@@ -12871,15 +12882,15 @@ function fileCheckpointStaging(files) {
|
|
|
12871
12882
|
function deskCheckpointStaging(store) {
|
|
12872
12883
|
const chunksOf = (slot) => {
|
|
12873
12884
|
const chunks = [];
|
|
12874
|
-
for (const
|
|
12875
|
-
if (
|
|
12876
|
-
chunks.push(
|
|
12885
|
+
for (const record2 of store.list(NAMESPACE(slot)).filter((candidate) => candidate.key.startsWith("chunk-"))) {
|
|
12886
|
+
if (record2.key !== chunkKey(chunks.length)) break;
|
|
12887
|
+
chunks.push(record2.value);
|
|
12877
12888
|
}
|
|
12878
12889
|
return chunks;
|
|
12879
12890
|
};
|
|
12880
12891
|
return {
|
|
12881
12892
|
held(slot) {
|
|
12882
|
-
const checkpoint = described(store.list(NAMESPACE(slot)).find((
|
|
12893
|
+
const checkpoint = described(store.list(NAMESPACE(slot)).find((record2) => record2.key === META)?.value);
|
|
12883
12894
|
if (!checkpoint) return void 0;
|
|
12884
12895
|
const chunks = chunksOf(slot);
|
|
12885
12896
|
return { checkpoint, bytes: chunks.reduce((total, chunk) => total + chunk.byteLength, 0), chunks: chunks.length };
|
|
@@ -12901,8 +12912,8 @@ function deskCheckpointStaging(store) {
|
|
|
12901
12912
|
return { pack };
|
|
12902
12913
|
},
|
|
12903
12914
|
clear(slot) {
|
|
12904
|
-
for (const
|
|
12905
|
-
store.compareExchange(NAMESPACE(slot),
|
|
12915
|
+
for (const record2 of store.list(NAMESPACE(slot))) {
|
|
12916
|
+
store.compareExchange(NAMESPACE(slot), record2.key, record2.revision, void 0);
|
|
12906
12917
|
}
|
|
12907
12918
|
}
|
|
12908
12919
|
};
|
|
@@ -20229,14 +20240,14 @@ var init_peer_desk_store = __esm({
|
|
|
20229
20240
|
"../peer-office/src/runtime/peer_desk_store.ts"() {
|
|
20230
20241
|
"use strict";
|
|
20231
20242
|
recordId = (namespace2, key2) => `${namespace2.length}:${namespace2}${key2}`;
|
|
20232
|
-
copy2 = (
|
|
20233
|
-
...
|
|
20234
|
-
value:
|
|
20243
|
+
copy2 = (record2) => ({
|
|
20244
|
+
...record2,
|
|
20245
|
+
value: record2.value.slice()
|
|
20235
20246
|
});
|
|
20236
20247
|
MemoryPeerDeskStore = class {
|
|
20237
20248
|
#records = /* @__PURE__ */ new Map();
|
|
20238
20249
|
list(namespace2) {
|
|
20239
|
-
return [...this.#records.values()].filter((
|
|
20250
|
+
return [...this.#records.values()].filter((record2) => record2.namespace === namespace2).sort((left, right) => left.key.localeCompare(right.key)).map(copy2);
|
|
20240
20251
|
}
|
|
20241
20252
|
compareExchange(namespace2, key2, expectedRevision, value) {
|
|
20242
20253
|
const id = recordId(namespace2, key2);
|
|
@@ -20284,22 +20295,22 @@ var init_custody_receipts = __esm({
|
|
|
20284
20295
|
#receipts = /* @__PURE__ */ new Map();
|
|
20285
20296
|
constructor(store = new MemoryPeerDeskStore()) {
|
|
20286
20297
|
this.#store = store;
|
|
20287
|
-
for (const
|
|
20288
|
-
this.#records.set(
|
|
20298
|
+
for (const record2 of store.list(namespace)) {
|
|
20299
|
+
this.#records.set(record2.key, record2);
|
|
20289
20300
|
try {
|
|
20290
|
-
if (
|
|
20291
|
-
const newline =
|
|
20301
|
+
if (record2.key.startsWith("receipt:")) {
|
|
20302
|
+
const newline = record2.value.indexOf(10);
|
|
20292
20303
|
if (newline < 0) continue;
|
|
20293
|
-
const receipt = fromBinary14(CustodyIntentAdmissionSchema,
|
|
20294
|
-
const header2 = JSON.parse(decoder2.decode(
|
|
20295
|
-
if (receipt.outcome.case === "admitted" && typeof header2.generation === "string" && typeof header2.head === "string") this.#receipts.set(
|
|
20304
|
+
const receipt = fromBinary14(CustodyIntentAdmissionSchema, record2.value.subarray(newline + 1));
|
|
20305
|
+
const header2 = JSON.parse(decoder2.decode(record2.value.subarray(0, newline)));
|
|
20306
|
+
if (receipt.outcome.case === "admitted" && typeof header2.generation === "string" && typeof header2.head === "string") this.#receipts.set(record2.key, { ...header2, receipt });
|
|
20296
20307
|
continue;
|
|
20297
20308
|
}
|
|
20298
|
-
if (!
|
|
20299
|
-
const value = JSON.parse(decoder2.decode(
|
|
20309
|
+
if (!record2.key.startsWith("head:")) continue;
|
|
20310
|
+
const value = JSON.parse(decoder2.decode(record2.value));
|
|
20300
20311
|
if (typeof value.head !== "string" || typeof value.generation !== "string" || !Array.isArray(value.bases) || !Array.isArray(value.keys) || value.bases.length > MAX_BASES || value.keys.length > MAX_RECEIPTS) continue;
|
|
20301
20312
|
if (!value.bases.every((base) => typeof base === "string") || !value.keys.every((key2) => typeof key2 === "string")) continue;
|
|
20302
|
-
this.#journals.set(
|
|
20313
|
+
this.#journals.set(record2.key.slice(5), value);
|
|
20303
20314
|
} catch {
|
|
20304
20315
|
}
|
|
20305
20316
|
}
|
|
@@ -20336,8 +20347,8 @@ var init_custody_receipts = __esm({
|
|
|
20336
20347
|
const bytes = new Uint8Array(header2.length + body.length);
|
|
20337
20348
|
bytes.set(header2);
|
|
20338
20349
|
bytes.set(body, header2.length);
|
|
20339
|
-
const
|
|
20340
|
-
if (
|
|
20350
|
+
const record3 = this.#store.compareExchange(namespace, key2, this.#records.get(key2)?.revision, bytes);
|
|
20351
|
+
if (record3) this.#records.set(key2, record3);
|
|
20341
20352
|
this.#receipts.set(key2, {
|
|
20342
20353
|
generation: value.generation,
|
|
20343
20354
|
head: after,
|
|
@@ -20352,13 +20363,13 @@ var init_custody_receipts = __esm({
|
|
|
20352
20363
|
this.#records.delete(key2);
|
|
20353
20364
|
this.#receipts.delete(key2);
|
|
20354
20365
|
}
|
|
20355
|
-
const
|
|
20366
|
+
const record2 = this.#store.compareExchange(
|
|
20356
20367
|
namespace,
|
|
20357
20368
|
journalKey,
|
|
20358
20369
|
this.#records.get(journalKey)?.revision,
|
|
20359
20370
|
encoder2.encode(JSON.stringify(value))
|
|
20360
20371
|
);
|
|
20361
|
-
if (
|
|
20372
|
+
if (record2) this.#records.set(journalKey, record2);
|
|
20362
20373
|
this.#journals.set(workspace, value);
|
|
20363
20374
|
}
|
|
20364
20375
|
};
|
|
@@ -20494,12 +20505,12 @@ var init_birth_refusal = __esm({
|
|
|
20494
20505
|
#load() {
|
|
20495
20506
|
if (this.#records === void 0) {
|
|
20496
20507
|
this.#records = /* @__PURE__ */ new Map();
|
|
20497
|
-
for (const
|
|
20498
|
-
const value = JSON.parse(decoder3.decode(
|
|
20499
|
-
if (value.version !== 1 || value.refusal?.child !==
|
|
20500
|
-
throw new Error(`corrupt birth refusal '${
|
|
20508
|
+
for (const record2 of this.#store.list(BIRTH_REFUSAL_NAMESPACE)) {
|
|
20509
|
+
const value = JSON.parse(decoder3.decode(record2.value));
|
|
20510
|
+
if (value.version !== 1 || value.refusal?.child !== record2.key) {
|
|
20511
|
+
throw new Error(`corrupt birth refusal '${record2.key}' at revision ${record2.revision}`);
|
|
20501
20512
|
}
|
|
20502
|
-
this.#records.set(
|
|
20513
|
+
this.#records.set(record2.key, { refusal: Object.freeze({ ...value.refusal }), revision: record2.revision });
|
|
20503
20514
|
}
|
|
20504
20515
|
}
|
|
20505
20516
|
return this.#records;
|
|
@@ -24331,12 +24342,12 @@ var init_runtime_identity = __esm({
|
|
|
24331
24342
|
});
|
|
24332
24343
|
|
|
24333
24344
|
// ../peer-office/src/runtime/replica_follow_desk.ts
|
|
24334
|
-
function assertSpec(
|
|
24345
|
+
function assertSpec(record2, spec) {
|
|
24335
24346
|
if (!spec.workspace || !spec.credentialCapability || typeof spec.cloudBound !== "boolean" || !Number.isFinite(spec.policy?.debounceMillis) || !Number.isFinite(spec.policy?.fallbackMillis) || spec.policy.debounceMillis < 0 || spec.policy.fallbackMillis <= 0) {
|
|
24336
|
-
throw corrupt(
|
|
24347
|
+
throw corrupt(record2, "invalid specification");
|
|
24337
24348
|
}
|
|
24338
24349
|
}
|
|
24339
|
-
function assertState(
|
|
24350
|
+
function assertState(record2, state) {
|
|
24340
24351
|
switch (state.case) {
|
|
24341
24352
|
case ReplicaFollowPhase.Desired:
|
|
24342
24353
|
return;
|
|
@@ -24378,10 +24389,10 @@ function assertState(record, state) {
|
|
|
24378
24389
|
break;
|
|
24379
24390
|
default: {
|
|
24380
24391
|
const exhaustive = state;
|
|
24381
|
-
throw corrupt(
|
|
24392
|
+
throw corrupt(record2, `unknown state ${String(exhaustive)}`);
|
|
24382
24393
|
}
|
|
24383
24394
|
}
|
|
24384
|
-
throw corrupt(
|
|
24395
|
+
throw corrupt(record2, `invalid '${state.case}' state`);
|
|
24385
24396
|
}
|
|
24386
24397
|
var REPLICA_FOLLOW_NAMESPACE, textEncoder, textDecoder, encode, decode, decodeWarming, decodeRefusal, decodeState, corrupt, samePolicy, sameSpec, ReplicaFollowDesk;
|
|
24387
24398
|
var init_replica_follow_desk = __esm({
|
|
@@ -24392,19 +24403,19 @@ var init_replica_follow_desk = __esm({
|
|
|
24392
24403
|
textEncoder = new TextEncoder();
|
|
24393
24404
|
textDecoder = new TextDecoder();
|
|
24394
24405
|
encode = (follow) => textEncoder.encode(JSON.stringify({ version: 1, spec: follow.spec, state: follow.state }));
|
|
24395
|
-
decode = (
|
|
24396
|
-
const value = JSON.parse(textDecoder.decode(
|
|
24397
|
-
if (!value || typeof value !== "object") throw corrupt(
|
|
24406
|
+
decode = (record2) => {
|
|
24407
|
+
const value = JSON.parse(textDecoder.decode(record2.value));
|
|
24408
|
+
if (!value || typeof value !== "object") throw corrupt(record2, "not an object");
|
|
24398
24409
|
const candidate = value;
|
|
24399
24410
|
if (candidate.version !== 1 || !candidate.spec || !candidate.state) {
|
|
24400
|
-
throw corrupt(
|
|
24411
|
+
throw corrupt(record2, "unsupported or incomplete record");
|
|
24401
24412
|
}
|
|
24402
24413
|
const spec = candidate.spec;
|
|
24403
|
-
const state = decodeState(
|
|
24404
|
-
if (spec.workspace !==
|
|
24405
|
-
assertSpec(
|
|
24406
|
-
assertState(
|
|
24407
|
-
return Object.freeze({ spec: Object.freeze(spec), state: Object.freeze(state), revision:
|
|
24414
|
+
const state = decodeState(record2, candidate.state);
|
|
24415
|
+
if (spec.workspace !== record2.key) throw corrupt(record2, "workspace key mismatch");
|
|
24416
|
+
assertSpec(record2, spec);
|
|
24417
|
+
assertState(record2, state);
|
|
24418
|
+
return Object.freeze({ spec: Object.freeze(spec), state: Object.freeze(state), revision: record2.revision });
|
|
24408
24419
|
};
|
|
24409
24420
|
decodeWarming = (value) => {
|
|
24410
24421
|
const warming = value;
|
|
@@ -24424,8 +24435,8 @@ var init_replica_follow_desk = __esm({
|
|
|
24424
24435
|
...Number.isFinite(refusal2.rerunAtUnixMillis) ? { rerunAtUnixMillis: refusal2.rerunAtUnixMillis } : {}
|
|
24425
24436
|
} } : {};
|
|
24426
24437
|
};
|
|
24427
|
-
decodeState = (
|
|
24428
|
-
if (!value || typeof value !== "object") throw corrupt(
|
|
24438
|
+
decodeState = (record2, value) => {
|
|
24439
|
+
if (!value || typeof value !== "object") throw corrupt(record2, "state is not an object");
|
|
24429
24440
|
const state = value;
|
|
24430
24441
|
switch (state.case) {
|
|
24431
24442
|
case ReplicaFollowPhase.Desired:
|
|
@@ -24497,10 +24508,10 @@ var init_replica_follow_desk = __esm({
|
|
|
24497
24508
|
dueAtUnixMillis: state.dueAtUnixMillis
|
|
24498
24509
|
};
|
|
24499
24510
|
default:
|
|
24500
|
-
throw corrupt(
|
|
24511
|
+
throw corrupt(record2, `unknown state '${String(state.case)}'`);
|
|
24501
24512
|
}
|
|
24502
24513
|
};
|
|
24503
|
-
corrupt = (
|
|
24514
|
+
corrupt = (record2, why) => new Error(`corrupt replica follow '${record2.key}' at revision ${record2.revision}: ${why}`);
|
|
24504
24515
|
samePolicy = (left, right) => left.debounceMillis === right.debounceMillis && left.fallbackMillis === right.fallbackMillis && left.signalMillis === right.signalMillis && left.signalId === right.signalId;
|
|
24505
24516
|
sameSpec = (left, right) => left.workspace === right.workspace && left.replicaId === right.replicaId && left.credentialCapability === right.credentialCapability && left.cloudBound === right.cloudBound && left.cloud === right.cloud && left.custodyBreakPolicy === right.custodyBreakPolicy && samePolicy(left.policy, right.policy);
|
|
24506
24517
|
ReplicaFollowDesk = class {
|
|
@@ -24512,8 +24523,8 @@ var init_replica_follow_desk = __esm({
|
|
|
24512
24523
|
}
|
|
24513
24524
|
load() {
|
|
24514
24525
|
if (!this.#loaded) {
|
|
24515
|
-
for (const
|
|
24516
|
-
const follow = decode(
|
|
24526
|
+
for (const record2 of this.#store.list(REPLICA_FOLLOW_NAMESPACE)) {
|
|
24527
|
+
const follow = decode(record2);
|
|
24517
24528
|
this.#inventory.set(follow.spec.workspace, follow);
|
|
24518
24529
|
}
|
|
24519
24530
|
this.#loaded = true;
|
|
@@ -24666,7 +24677,7 @@ function classifyRebirth(kernel, mount, requestId, disagreement) {
|
|
|
24666
24677
|
});
|
|
24667
24678
|
}
|
|
24668
24679
|
function parkedLocalChanges(kernel, mount, requestId) {
|
|
24669
|
-
return kernel.listRefs(mount, requestId, REFUSED_PREFIX).filter((
|
|
24680
|
+
return kernel.listRefs(mount, requestId, REFUSED_PREFIX).filter((record2) => record2.reference && kernel.readBlob(mount, requestId, record2.oid, "verdict.usda")).map((record2) => ({ reference: record2.reference, oid: record2.oid }));
|
|
24670
24681
|
}
|
|
24671
24682
|
function previewLocalCopyDrop(kernel, mount, requestId, follow, captureClock) {
|
|
24672
24683
|
const localHead = kernel.head(mount, requestId);
|
|
@@ -24745,11 +24756,11 @@ var init_preserved_copies_desk = __esm({
|
|
|
24745
24756
|
this.#store = store;
|
|
24746
24757
|
}
|
|
24747
24758
|
list(workspace) {
|
|
24748
|
-
const
|
|
24749
|
-
if (!
|
|
24750
|
-
const values = JSON.parse(decoder4.decode(
|
|
24759
|
+
const record2 = this.#store.list(PRESERVED_COPIES_NAMESPACE).find((entry) => entry.key === workspace);
|
|
24760
|
+
if (!record2) return [];
|
|
24761
|
+
const values = JSON.parse(decoder4.decode(record2.value));
|
|
24751
24762
|
if (!Array.isArray(values)) {
|
|
24752
|
-
throw new Error(`corrupt preserved-copy record for '${workspace}' at revision ${
|
|
24763
|
+
throw new Error(`corrupt preserved-copy record for '${workspace}' at revision ${record2.revision}`);
|
|
24753
24764
|
}
|
|
24754
24765
|
return values.map((value) => fromJsonString(PreservedLocalCopySchema, JSON.stringify(value)));
|
|
24755
24766
|
}
|
|
@@ -24860,13 +24871,13 @@ var init_seated_peer_desk_store = __esm({
|
|
|
24860
24871
|
list(namespace2) {
|
|
24861
24872
|
if (LOCAL_ONLY_NAMESPACES.has(namespace2)) return this.#inner.list(namespace2);
|
|
24862
24873
|
const kept = [];
|
|
24863
|
-
for (const
|
|
24864
|
-
const sealed = readSeal(
|
|
24874
|
+
for (const record2 of this.#inner.list(namespace2)) {
|
|
24875
|
+
const sealed = readSeal(record2.value);
|
|
24865
24876
|
if (sealed?.seat === this.#seat.digest) {
|
|
24866
|
-
kept.push({ ...
|
|
24877
|
+
kept.push({ ...record2, value: sealed.value.slice() });
|
|
24867
24878
|
continue;
|
|
24868
24879
|
}
|
|
24869
|
-
this.#quarantine(namespace2,
|
|
24880
|
+
this.#quarantine(namespace2, record2, sealed?.seat);
|
|
24870
24881
|
}
|
|
24871
24882
|
return kept;
|
|
24872
24883
|
}
|
|
@@ -24886,16 +24897,16 @@ var init_seated_peer_desk_store = __esm({
|
|
|
24886
24897
|
return { ...stored, value: sealed.value.slice() };
|
|
24887
24898
|
}
|
|
24888
24899
|
/** Preserve the foreign record under the quarantine namespace, then free the slot. */
|
|
24889
|
-
#quarantine(namespace2,
|
|
24890
|
-
const key2 = `${namespace2}\0${
|
|
24900
|
+
#quarantine(namespace2, record2, recordedSeat) {
|
|
24901
|
+
const key2 = `${namespace2}\0${record2.key}\0${record2.revision}`;
|
|
24891
24902
|
try {
|
|
24892
|
-
this.#inner.compareExchange(QUARANTINED_BINDINGS_NAMESPACE, key2, void 0,
|
|
24903
|
+
this.#inner.compareExchange(QUARANTINED_BINDINGS_NAMESPACE, key2, void 0, record2.value);
|
|
24893
24904
|
} catch {
|
|
24894
24905
|
}
|
|
24895
|
-
this.#inner.compareExchange(namespace2,
|
|
24906
|
+
this.#inner.compareExchange(namespace2, record2.key, record2.revision, void 0);
|
|
24896
24907
|
this.#report(create47(QuarantinedBindingSchema, {
|
|
24897
24908
|
namespace: namespace2,
|
|
24898
|
-
key:
|
|
24909
|
+
key: record2.key,
|
|
24899
24910
|
reason: recordedSeat === void 0 ? QuarantineReason.Unseated : QuarantineReason.ForeignSeat,
|
|
24900
24911
|
recordedSeat: recordedSeat ?? "",
|
|
24901
24912
|
officeSeat: this.#seat.digest
|
|
@@ -26551,7 +26562,7 @@ var init_live_correspondence_desk = __esm({
|
|
|
26551
26562
|
// ../peer-office/src/runtime/replica_identity.ts
|
|
26552
26563
|
function replicaIdentity(store, label, sources = {}) {
|
|
26553
26564
|
const read2 = () => {
|
|
26554
|
-
const stored = store.list(REPLICA_IDENTITY_NAMESPACE).find((
|
|
26565
|
+
const stored = store.list(REPLICA_IDENTITY_NAMESPACE).find((record2) => record2.key === REPLICA_IDENTITY_KEY);
|
|
26555
26566
|
if (!stored) return {};
|
|
26556
26567
|
const text3 = new TextDecoder().decode(stored.value);
|
|
26557
26568
|
return isReplicaId(text3) ? { id: text3, revision: stored.revision } : { revision: stored.revision };
|
|
@@ -27029,17 +27040,17 @@ var init_recovery_desk = __esm({
|
|
|
27029
27040
|
}
|
|
27030
27041
|
#entries(mount, requestId) {
|
|
27031
27042
|
const entries = [];
|
|
27032
|
-
for (const
|
|
27043
|
+
for (const record2 of this.#kernel.listRefs(mount, requestId, REFUSED_PREFIX2)) {
|
|
27033
27044
|
const verdictUsda = this.#kernel.readBlob(
|
|
27034
27045
|
mount,
|
|
27035
27046
|
requestId,
|
|
27036
|
-
|
|
27047
|
+
record2.oid,
|
|
27037
27048
|
"verdict.usda"
|
|
27038
27049
|
);
|
|
27039
27050
|
if (!verdictUsda) continue;
|
|
27040
27051
|
entries.push({
|
|
27041
|
-
reference:
|
|
27042
|
-
commitOid:
|
|
27052
|
+
reference: record2.reference,
|
|
27053
|
+
commitOid: record2.oid,
|
|
27043
27054
|
verdict: this.#kernel.inspectRefusalVerdict(mount, requestId, verdictUsda)
|
|
27044
27055
|
});
|
|
27045
27056
|
}
|
|
@@ -29071,9 +29082,9 @@ var init_workspace_sync = __esm({
|
|
|
29071
29082
|
return this.#route?.receptionUrl || `${this.#cloudBase()}/v2/workspaces/${encodeURIComponent(this.#mount.workspace)}`;
|
|
29072
29083
|
}
|
|
29073
29084
|
#authToken() {
|
|
29074
|
-
const
|
|
29075
|
-
if (!
|
|
29076
|
-
return
|
|
29085
|
+
const resolve12 = this.#credentials.authTokenForCapability ?? this.#credentials.authToken;
|
|
29086
|
+
if (!resolve12) throw new Error("workspace sync has no credential capability resolver");
|
|
29087
|
+
return resolve12.call(this.#credentials, this.#binding.credentialCapability);
|
|
29077
29088
|
}
|
|
29078
29089
|
};
|
|
29079
29090
|
}
|
|
@@ -29509,7 +29520,7 @@ var init_history_acquisition_state = __esm({
|
|
|
29509
29520
|
|
|
29510
29521
|
// ../peer-office/src/runtime/history_acquisition_desk.ts
|
|
29511
29522
|
import { create as create62, toBinary as toBinary20 } from "@bufbuild/protobuf";
|
|
29512
|
-
function assertState2(
|
|
29523
|
+
function assertState2(record2, state) {
|
|
29513
29524
|
switch (state.case) {
|
|
29514
29525
|
case HistoryAcquisitionPhase.Desired:
|
|
29515
29526
|
case HistoryAcquisitionPhase.Settled:
|
|
@@ -29522,10 +29533,10 @@ function assertState2(record, state) {
|
|
|
29522
29533
|
break;
|
|
29523
29534
|
default: {
|
|
29524
29535
|
const exhaustive = state;
|
|
29525
|
-
throw corrupt2(
|
|
29536
|
+
throw corrupt2(record2, `unknown state ${String(exhaustive)}`);
|
|
29526
29537
|
}
|
|
29527
29538
|
}
|
|
29528
|
-
throw corrupt2(
|
|
29539
|
+
throw corrupt2(record2, `invalid '${state.case}' state`);
|
|
29529
29540
|
}
|
|
29530
29541
|
var HISTORY_ACQUISITION_NAMESPACE, HISTORY_BACKGROUND_START_MILLIS, OMITTED_HISTORY_HOLD_MILLIS, SLICE_ANSWER_MILLIS, encoder6, decoder6, workId, effectId, encode2, upgraded, decode2, corrupt2, HistoryAcquisitionDesk;
|
|
29531
29542
|
var init_history_acquisition_desk = __esm({
|
|
@@ -29555,25 +29566,25 @@ var init_history_acquisition_desk = __esm({
|
|
|
29555
29566
|
}));
|
|
29556
29567
|
};
|
|
29557
29568
|
upgraded = (state) => state.case === "backoff" ? { case: HistoryAcquisitionPhase.Paced, attempt: state.attempt, delayMillis: state.delayMillis, failed: true } : state;
|
|
29558
|
-
decode2 = (
|
|
29559
|
-
const value = JSON.parse(decoder6.decode(
|
|
29560
|
-
if (!value || typeof value !== "object") throw corrupt2(
|
|
29569
|
+
decode2 = (record2) => {
|
|
29570
|
+
const value = JSON.parse(decoder6.decode(record2.value));
|
|
29571
|
+
if (!value || typeof value !== "object") throw corrupt2(record2, "not an object");
|
|
29561
29572
|
const candidate = value;
|
|
29562
|
-
if (candidate.version !== 1 && candidate.version !== 2 || candidate.workspace !==
|
|
29563
|
-
throw corrupt2(
|
|
29573
|
+
if (candidate.version !== 1 && candidate.version !== 2 || candidate.workspace !== record2.key || !candidate.state) {
|
|
29574
|
+
throw corrupt2(record2, "unsupported or incomplete record");
|
|
29564
29575
|
}
|
|
29565
29576
|
const credentialCapability = candidate.version === 2 ? candidate.credentialCapability : void 0;
|
|
29566
|
-
if (candidate.version === 2 && !credentialCapability) throw corrupt2(
|
|
29577
|
+
if (candidate.version === 2 && !credentialCapability) throw corrupt2(record2, "missing credential capability");
|
|
29567
29578
|
const state = upgraded(candidate.state);
|
|
29568
|
-
assertState2(
|
|
29579
|
+
assertState2(record2, state);
|
|
29569
29580
|
return Object.freeze({
|
|
29570
29581
|
workspace: candidate.workspace,
|
|
29571
29582
|
...credentialCapability ? { credentialCapability } : {},
|
|
29572
29583
|
state: Object.freeze(state),
|
|
29573
|
-
revision:
|
|
29584
|
+
revision: record2.revision
|
|
29574
29585
|
});
|
|
29575
29586
|
};
|
|
29576
|
-
corrupt2 = (
|
|
29587
|
+
corrupt2 = (record2, why) => new Error(`corrupt history acquisition '${record2.key}' at revision ${record2.revision}: ${why}`);
|
|
29577
29588
|
HistoryAcquisitionDesk = class {
|
|
29578
29589
|
#store;
|
|
29579
29590
|
#clock;
|
|
@@ -29780,8 +29791,8 @@ var init_history_acquisition_desk = __esm({
|
|
|
29780
29791
|
}
|
|
29781
29792
|
#load() {
|
|
29782
29793
|
if (this.#loaded) return;
|
|
29783
|
-
for (const
|
|
29784
|
-
const work = decode2(
|
|
29794
|
+
for (const record2 of this.#store.list(HISTORY_ACQUISITION_NAMESPACE)) {
|
|
29795
|
+
const work = decode2(record2);
|
|
29785
29796
|
this.#inventory.set(work.workspace, work);
|
|
29786
29797
|
}
|
|
29787
29798
|
this.#loaded = true;
|
|
@@ -36041,19 +36052,19 @@ function createPeerOfficeFrameRunner(kernel, credentials, profile, observations,
|
|
|
36041
36052
|
};
|
|
36042
36053
|
const runner = {
|
|
36043
36054
|
localReadResumable(workId2) {
|
|
36044
|
-
let
|
|
36055
|
+
let resolve12;
|
|
36045
36056
|
const resumable = new Promise((done) => {
|
|
36046
|
-
|
|
36057
|
+
resolve12 = done;
|
|
36047
36058
|
});
|
|
36048
36059
|
let timer;
|
|
36049
36060
|
const wait = peer2.localReadResumable(workId2, () => {
|
|
36050
36061
|
if (timer !== void 0) clearTimeout(timer);
|
|
36051
|
-
|
|
36062
|
+
resolve12();
|
|
36052
36063
|
});
|
|
36053
36064
|
if (wait === void 0) return void 0;
|
|
36054
36065
|
timer = setTimeout(() => {
|
|
36055
36066
|
wait.cancel();
|
|
36056
|
-
|
|
36067
|
+
resolve12();
|
|
36057
36068
|
}, wait.afterMillis);
|
|
36058
36069
|
return resumable;
|
|
36059
36070
|
},
|
|
@@ -36084,7 +36095,7 @@ function createPeerOfficeFrameRunner(kernel, credentials, profile, observations,
|
|
|
36084
36095
|
const deadline = Date.now() + Math.max(0, withinMillis);
|
|
36085
36096
|
while (outstanding() > 0 && Date.now() < deadline) {
|
|
36086
36097
|
lanes.wake(0);
|
|
36087
|
-
await new Promise((
|
|
36098
|
+
await new Promise((resolve12) => setTimeout(resolve12, 10));
|
|
36088
36099
|
}
|
|
36089
36100
|
return outstanding();
|
|
36090
36101
|
},
|
|
@@ -36147,7 +36158,7 @@ async function drivePeerFrame(runner, initialFrame, fetchImpl = globalThis.fetch
|
|
|
36147
36158
|
if (response.outcome.case === "localReadPending") {
|
|
36148
36159
|
if (yieldLocalReadToCaller) return responseFrame;
|
|
36149
36160
|
const pending2 = response.outcome.value;
|
|
36150
|
-
await (runner.localReadResumable?.(pending2.workId) ?? new Promise((
|
|
36161
|
+
await (runner.localReadResumable?.(pending2.workId) ?? new Promise((resolve12) => setTimeout(resolve12, pending2.resumeAfterMillis)));
|
|
36151
36162
|
responseFrame = await turn(() => runner.handleFrame(toBinary28(RuntimeRequestSchema, create78(RuntimeRequestSchema, {
|
|
36152
36163
|
protocolVersion: response.protocolVersion,
|
|
36153
36164
|
requestId: response.requestId,
|
|
@@ -36345,7 +36356,7 @@ async function executeHistoryAcquisitionEffect(effect, custody) {
|
|
|
36345
36356
|
}
|
|
36346
36357
|
}
|
|
36347
36358
|
async function executeWakeEffect(effect) {
|
|
36348
|
-
await new Promise((
|
|
36359
|
+
await new Promise((resolve12) => setTimeout(resolve12, effect.delayMillis));
|
|
36349
36360
|
return create78(PeerEffectReceiptSchema, { effectId: effect.effectId, outcome: { case: "woken", value: create78(PeerWokenSchema) } });
|
|
36350
36361
|
}
|
|
36351
36362
|
async function executeCredentialRefreshEffect(effect, provider) {
|
|
@@ -36380,9 +36391,9 @@ async function executeDeviceIdentityEffect(effect, store) {
|
|
|
36380
36391
|
const bytes = await store.load(`nomos-device-recovery-v1|${effect.identity}`);
|
|
36381
36392
|
if (bytes !== void 0) recovery = fromBinary25(DeviceRecoveryRecordSchema, bytes);
|
|
36382
36393
|
} else if (effect.operation.case === "saveRecovery") {
|
|
36383
|
-
const
|
|
36384
|
-
if (!
|
|
36385
|
-
await store.save(`nomos-device-recovery-v1|${effect.identity}`, toBinary28(DeviceRecoveryRecordSchema,
|
|
36394
|
+
const record2 = effect.operation.value.record;
|
|
36395
|
+
if (!record2) throw new Error("device recovery save contains no record");
|
|
36396
|
+
await store.save(`nomos-device-recovery-v1|${effect.identity}`, toBinary28(DeviceRecoveryRecordSchema, record2));
|
|
36386
36397
|
} else throw new Error("device identity effect has no operation");
|
|
36387
36398
|
return create78(PeerEffectReceiptSchema, { effectId: effect.effectId, outcome: {
|
|
36388
36399
|
case: "deviceIdentity",
|
|
@@ -37624,7 +37635,7 @@ async function prepareRemoteModelTransition(cloud, input) {
|
|
|
37624
37635
|
}
|
|
37625
37636
|
atHash = status2.outcome.value.head ?? "";
|
|
37626
37637
|
if (atHash || Date.now() >= deadline) break;
|
|
37627
|
-
await new Promise((
|
|
37638
|
+
await new Promise((resolve12) => setTimeout(resolve12, 1e3));
|
|
37628
37639
|
}
|
|
37629
37640
|
if (!atHash) {
|
|
37630
37641
|
throw new Error("workspace has no current Git frontier to prove after pulling it");
|
|
@@ -37670,8 +37681,8 @@ async function prepareRemoteModelTransition(cloud, input) {
|
|
|
37670
37681
|
target3
|
|
37671
37682
|
);
|
|
37672
37683
|
if (response.outcome.case !== "unavailable" || !response.outcome.value.retryable || Date.now() >= proofDeadline) break;
|
|
37673
|
-
await new Promise((
|
|
37674
|
-
|
|
37684
|
+
await new Promise((resolve12) => setTimeout(
|
|
37685
|
+
resolve12,
|
|
37675
37686
|
Math.max(500, response.outcome.case === "unavailable" ? response.outcome.value.retryAfterMillis ?? 1e3 : 1e3)
|
|
37676
37687
|
));
|
|
37677
37688
|
}
|
|
@@ -37823,7 +37834,7 @@ async function invokeUntilAvailable(cloud, command, target3, deadlineMillis = RE
|
|
|
37823
37834
|
return response;
|
|
37824
37835
|
}
|
|
37825
37836
|
const wait = Math.min(5e3, Math.max(250, Number(response.outcome.value.retryAfterMillis ?? 1e3)));
|
|
37826
|
-
await new Promise((
|
|
37837
|
+
await new Promise((resolve12) => setTimeout(resolve12, wait));
|
|
37827
37838
|
}
|
|
37828
37839
|
}
|
|
37829
37840
|
function unavailableDetail(response) {
|
|
@@ -38594,7 +38605,7 @@ async function waitForWorkspaceMain(cloud, workspace, timeoutMs = 3e4) {
|
|
|
38594
38605
|
while (Date.now() < deadline) {
|
|
38595
38606
|
const head = await workspaceMainHead(cloud, workspace);
|
|
38596
38607
|
if (head !== void 0) return head;
|
|
38597
|
-
await new Promise((
|
|
38608
|
+
await new Promise((resolve12) => setTimeout(resolve12, 250));
|
|
38598
38609
|
}
|
|
38599
38610
|
return void 0;
|
|
38600
38611
|
}
|
|
@@ -38815,7 +38826,7 @@ async function ensureSovereignHome(opts = {}) {
|
|
|
38815
38826
|
const deadline = Date.now() + 3e4;
|
|
38816
38827
|
while (Date.now() < deadline) {
|
|
38817
38828
|
if (await fetch(`${cloud}/v2/workspaces/${encodeURIComponent(home)}`).then((r) => r.ok).catch(() => false)) break;
|
|
38818
|
-
await new Promise((
|
|
38829
|
+
await new Promise((resolve12) => setTimeout(resolve12, 250));
|
|
38819
38830
|
}
|
|
38820
38831
|
if (!await fetch(`${cloud}/v2/workspaces/${encodeURIComponent(home)}`).then((r) => r.ok).catch(() => false)) {
|
|
38821
38832
|
throw new Error(`Nomos admitted the birth of '${home}' but its custody did not become readable`);
|
|
@@ -38863,7 +38874,7 @@ async function ensureSovereignHome(opts = {}) {
|
|
|
38863
38874
|
return typeof leaf?.verifiedVia === "string" && leaf.verifiedVia.length > 0;
|
|
38864
38875
|
}).catch(() => false);
|
|
38865
38876
|
if (visible) break;
|
|
38866
|
-
await new Promise((
|
|
38877
|
+
await new Promise((resolve12) => setTimeout(resolve12, 250));
|
|
38867
38878
|
}
|
|
38868
38879
|
if (!visible) throw new Error(`the session home's verified device enrollment did not become readable`);
|
|
38869
38880
|
}
|
|
@@ -40103,7 +40114,7 @@ async function waitForDurableMainAdvance(cloud, ws2, previousHead, opts = {}) {
|
|
|
40103
40114
|
while (Date.now() < deadline) {
|
|
40104
40115
|
const head = await durableMainHead(cloud, ws2, fetchImpl);
|
|
40105
40116
|
if (head !== void 0 && head !== previousHead) return head;
|
|
40106
|
-
await new Promise((
|
|
40117
|
+
await new Promise((resolve12) => setTimeout(resolve12, pollMs));
|
|
40107
40118
|
}
|
|
40108
40119
|
return void 0;
|
|
40109
40120
|
}
|
|
@@ -40497,11 +40508,11 @@ function declaredDirectives(projection, domainPath) {
|
|
|
40497
40508
|
function lawDomainPath(projection, domain) {
|
|
40498
40509
|
return [...projection.prims.values()].find((prim) => /^\/Nomos\/Domains\/d_[0-9a-f]{16}$/.test(prim.path) && (text(prim, "nomos:label") === domain || text(prim, "nomos:publicRoute") === domain))?.path;
|
|
40499
40510
|
}
|
|
40500
|
-
function schemaFields(projection,
|
|
40511
|
+
function schemaFields(projection, record2, remainingDepth) {
|
|
40501
40512
|
if (remainingDepth === 0) {
|
|
40502
|
-
throw new Error(`${
|
|
40513
|
+
throw new Error(`${record2.path} exceeds the operation schema recursion limit`);
|
|
40503
40514
|
}
|
|
40504
|
-
return (projection.childrenOf.get(`${
|
|
40515
|
+
return (projection.childrenOf.get(`${record2.path}/Fields`) ?? []).map((path4) => {
|
|
40505
40516
|
const field = projection.prims.get(path4);
|
|
40506
40517
|
const label = text(field, "nomos:label");
|
|
40507
40518
|
if (label === void 0) throw new Error(`${field.path} has no nomos:label`);
|
|
@@ -41087,7 +41098,7 @@ async function aggregateRow(cloud, workspace, id) {
|
|
|
41087
41098
|
const { status: status2, body } = await getJson(cloud, `/v2/workspaces/${ws(workspace)}/aggregates/${encodeURIComponent(id)}`);
|
|
41088
41099
|
if (body?.ok === true && status2 === 200) return (body.rows ?? [])[0]?.data;
|
|
41089
41100
|
if ((status2 === 202 || status2 === 503) && Date.now() < deadline) {
|
|
41090
|
-
await new Promise((
|
|
41101
|
+
await new Promise((resolve12) => setTimeout(resolve12, 1e3));
|
|
41091
41102
|
continue;
|
|
41092
41103
|
}
|
|
41093
41104
|
refuse(`${workspace} answered no rows for ${id} (HTTP ${status2}${typeof body?.error === "string" ? `: ${body.error}` : ""}); an unanswered read is not read as an absent record`);
|
|
@@ -41174,7 +41185,7 @@ async function foundedLineage(cloud, workspace, origin) {
|
|
|
41174
41185
|
if (parent === "" || parentIntent === "") {
|
|
41175
41186
|
refuse(`${workspace}'s birth origin (${BIRTH_ORIGIN_ID}) names no parent/parentIntent (parent=${parent || "\u2205"}, parentIntent=${parentIntent || "\u2205"})`);
|
|
41176
41187
|
}
|
|
41177
|
-
const [founding, warrant,
|
|
41188
|
+
const [founding, warrant, record2, lifecycle] = await Promise.all([
|
|
41178
41189
|
aggregateRow(cloud, workspace, FOUNDING_PRINCIPAL_ID),
|
|
41179
41190
|
aggregateRow(cloud, workspace, GENESIS_WARRANT_ID),
|
|
41180
41191
|
aggregateRow(cloud, parent, birthRecordId(workspace)),
|
|
@@ -41192,20 +41203,20 @@ async function foundedLineage(cloud, workspace, origin) {
|
|
|
41192
41203
|
if (text2(warrant["principal"]) !== founder || text2(warrant["workspaceId"]) !== workspace) {
|
|
41193
41204
|
refuse(`${workspace}'s genesis warrant names ${text2(warrant["principal"]) || "\u2205"} for ${text2(warrant["workspaceId"]) || "\u2205"}, but its founding record names ${founder} for ${workspace}; the records disagree`);
|
|
41194
41205
|
}
|
|
41195
|
-
if (
|
|
41206
|
+
if (record2 === void 0) {
|
|
41196
41207
|
refuse(`${workspace}'s birth origin names ${parent} (birth intent ${parentIntent}), but ${parent}'s chain records no birth of it (${birthRecordId(workspace)}); origin and parent disagree, and this lane does not guess its lineage`);
|
|
41197
41208
|
}
|
|
41198
|
-
if (text2(
|
|
41199
|
-
refuse(`${parent}'s birth record ${birthRecordId(workspace)} names child ${text2(
|
|
41209
|
+
if (text2(record2["child"]) !== workspace) {
|
|
41210
|
+
refuse(`${parent}'s birth record ${birthRecordId(workspace)} names child ${text2(record2["child"]) || "\u2205"}, not ${workspace}; origin and parent disagree`);
|
|
41200
41211
|
}
|
|
41201
|
-
const recordBornAt = text2(
|
|
41212
|
+
const recordBornAt = text2(record2["bornAt"]);
|
|
41202
41213
|
const warrantBornAt = text2(warrant["bornAt"]);
|
|
41203
41214
|
if (recordBornAt !== "" && warrantBornAt !== "" && recordBornAt !== warrantBornAt) {
|
|
41204
41215
|
refuse(`${parent} records ${workspace} as born at ${recordBornAt}, but its genesis warrant says ${warrantBornAt}; origin and parent disagree`);
|
|
41205
41216
|
}
|
|
41206
41217
|
const status2 = text2(lifecycle?.["status"]) || "active";
|
|
41207
41218
|
if (status2 === "reclaimed") refuse(`${parent} has reclaimed ${workspace} (${childLifecycleId(workspace)}); a reclaimed workspace has no custody to act in`);
|
|
41208
|
-
return { lane: "founded", workspace, parent, founder, parentIntent, foundingKeyHash, lifecycle: status2, birthSubject: text2(
|
|
41219
|
+
return { lane: "founded", workspace, parent, founder, parentIntent, foundingKeyHash, lifecycle: status2, birthSubject: text2(record2["principal"]) };
|
|
41209
41220
|
}
|
|
41210
41221
|
async function attestedLineage(cloud, workspace, birth2) {
|
|
41211
41222
|
if (birth2 === void 0) {
|
|
@@ -41758,7 +41769,7 @@ async function waitFor(condition, deadlineMillis, report) {
|
|
|
41758
41769
|
announced = elapsed;
|
|
41759
41770
|
report(elapsed);
|
|
41760
41771
|
}
|
|
41761
|
-
await new Promise((
|
|
41772
|
+
await new Promise((resolve12) => setTimeout(resolve12, 1e3));
|
|
41762
41773
|
}
|
|
41763
41774
|
return false;
|
|
41764
41775
|
}
|
|
@@ -42145,6 +42156,7 @@ var init_commands = __esm({
|
|
|
42145
42156
|
"doctor",
|
|
42146
42157
|
"cloud",
|
|
42147
42158
|
"console",
|
|
42159
|
+
"reception",
|
|
42148
42160
|
"status",
|
|
42149
42161
|
"model",
|
|
42150
42162
|
"platform",
|
|
@@ -42195,6 +42207,28 @@ var init_help = __esm({
|
|
|
42195
42207
|
"use strict";
|
|
42196
42208
|
init_commands();
|
|
42197
42209
|
HELP = {
|
|
42210
|
+
reception: {
|
|
42211
|
+
usage: "githolon reception <discover|read|offer|status|identity|prepare|enroll|recover|revoke> <workspace>\ngitholon reception batch <targets.json>",
|
|
42212
|
+
what: "Use the target workspace's generated hosted Reception over HTTPS. No local law archive or kernel is required.\nA persistent operation journal resolves lost replies without automatically repeating business commands.",
|
|
42213
|
+
flags: [
|
|
42214
|
+
["--cloud <HTTPS origin>", "provider endpoint (default https://nomos.cafe)"],
|
|
42215
|
+
["--as <principal>", "acting provider-scoped identity; its encrypted cloud device is enrolled and reused automatically"],
|
|
42216
|
+
["NOMOS_RECEPTION_TOKEN", "fresh provider assertion from the environment; never saved in the operation journal"],
|
|
42217
|
+
["--credential <id>", "select an explicitly managed scoped credential instead of automatic identity custody"],
|
|
42218
|
+
["discover --domain <domain>", "resolve an exact realised closure and its API readiness"],
|
|
42219
|
+
["read --closure <identity> --operation <name> [--args <file.json>]", "fresh kernel-authorized typed read"],
|
|
42220
|
+
["offer --domain <domain> --operation <name> --facts <file.json> --operation-id <id> --journal <file>", "persist intent to submit, then return the provider's admission outcome; reruns resolve the same operation"],
|
|
42221
|
+
["status --operation-id <id>", "recover an interrupted operation's retained receipt; pending remains unresolved"],
|
|
42222
|
+
["identity --file <targets.json>", "enroll one retained cloud device across explicit workspace/operation targets in one provider enrollment request; nonce providers return the required keyHash"],
|
|
42223
|
+
["batch <targets.json> --journal <file>", "enroll relevant targets together, fresh-read desired authority, skip existing state and resume retained operations; exit 1 while any target is unresolved"],
|
|
42224
|
+
["prepare --file <scope.json>", "persist a hosted device with operations and expiresAt; acquire a provider assertion with nonce equal to the returned keyHash"],
|
|
42225
|
+
["enroll | recover | revoke --credential <id>", "explicit signer onboarding, interrupted enrollment recovery or revocation with the device-bound provider assertion"]
|
|
42226
|
+
],
|
|
42227
|
+
examples: [
|
|
42228
|
+
"githolon reception discover example-catalogue --domain catalogue --as user:owner",
|
|
42229
|
+
"githolon reception offer example-catalogue --domain catalogue --operation catalogue/grantCatalogueOwner --facts grant.json --operation-id grant-example-owner --journal grants.json --as user:owner"
|
|
42230
|
+
]
|
|
42231
|
+
},
|
|
42198
42232
|
console: {
|
|
42199
42233
|
usage: "githolon console <login|logout|workspaces|universe|adoption|release-registry|releases|release-rollouts|rollouts>",
|
|
42200
42234
|
what: "Use a downloaded console API credential. The browser and CLI use the same console API.\nCredentials are stored locally with owner-only permissions; tokens are never printed.",
|
|
@@ -43001,7 +43035,7 @@ function qualificationProgressLine(run4) {
|
|
|
43001
43035
|
return `[qualify] ${p.judged}/${p.selected} targets judged (${p.percent}%): passed ${p.passed}, failed ${p.failed}, unknown ${p.unknown}${p.skipped ? `, skipped ${p.skipped}` : ""}${p.retrying ? `, retrying ${p.retrying}` : ""}${run4.detail ? ` (${run4.detail})` : ""}`;
|
|
43002
43036
|
}
|
|
43003
43037
|
async function waitForQualification(profile, first, wait, fetcher = fetch) {
|
|
43004
|
-
const sleep2 = wait.sleep ?? ((ms) => new Promise((
|
|
43038
|
+
const sleep2 = wait.sleep ?? ((ms) => new Promise((resolve12) => setTimeout(resolve12, ms)));
|
|
43005
43039
|
const report = wait.report ?? ((line) => console.error(line));
|
|
43006
43040
|
const deadline = Date.now() + wait.timeoutSeconds * 1e3;
|
|
43007
43041
|
let delay = 1e3;
|
|
@@ -43382,7 +43416,7 @@ function rolloutVerdict(progress, options) {
|
|
|
43382
43416
|
verdict: `${progress.state}, incomplete (${tally})${detail}${failures}${options.allowIncomplete ? "\n (allowed by --allow-incomplete)" : ""}`
|
|
43383
43417
|
};
|
|
43384
43418
|
}
|
|
43385
|
-
async function waitForRollout(profile, showPath, options, fetcher = fetch, sleep2 = (ms) => new Promise((
|
|
43419
|
+
async function waitForRollout(profile, showPath, options, fetcher = fetch, sleep2 = (ms) => new Promise((resolve12) => setTimeout(resolve12, ms)), report = (line) => console.error(line)) {
|
|
43386
43420
|
const deadline = Date.now() + options.timeoutSeconds * 1e3;
|
|
43387
43421
|
let delay = 1e3;
|
|
43388
43422
|
let last = "";
|
|
@@ -43404,9 +43438,9 @@ async function waitForRollout(profile, showPath, options, fetcher = fetch, sleep
|
|
|
43404
43438
|
}
|
|
43405
43439
|
}
|
|
43406
43440
|
function writeStdout(text3) {
|
|
43407
|
-
return new Promise((
|
|
43408
|
-
if (process.stdout.write(text3))
|
|
43409
|
-
else process.stdout.once("drain", () =>
|
|
43441
|
+
return new Promise((resolve12) => {
|
|
43442
|
+
if (process.stdout.write(text3)) resolve12();
|
|
43443
|
+
else process.stdout.once("drain", () => resolve12());
|
|
43410
43444
|
});
|
|
43411
43445
|
}
|
|
43412
43446
|
async function consoleCommand(args) {
|
|
@@ -43524,6 +43558,360 @@ var init_console = __esm({
|
|
|
43524
43558
|
}
|
|
43525
43559
|
});
|
|
43526
43560
|
|
|
43561
|
+
// src/hosted_reception.ts
|
|
43562
|
+
var hosted_reception_exports = {};
|
|
43563
|
+
__export(hosted_reception_exports, {
|
|
43564
|
+
HostedReceptionClient: () => HostedReceptionClient,
|
|
43565
|
+
hostedReceptionBatch: () => hostedReceptionBatch,
|
|
43566
|
+
hostedReceptionCommand: () => hostedReceptionCommand
|
|
43567
|
+
});
|
|
43568
|
+
import { createHash as createHash8 } from "node:crypto";
|
|
43569
|
+
import { chmodSync as chmodSync5, closeSync as closeSync2, existsSync as existsSync17, mkdirSync as mkdirSync13, openSync as openSync2, readFileSync as readFileSync16, renameSync as renameSync5, unlinkSync as unlinkSync2, writeFileSync as writeFileSync14 } from "node:fs";
|
|
43570
|
+
import { dirname as dirname6, resolve as resolve5 } from "node:path";
|
|
43571
|
+
function acquireJournalLock(path4) {
|
|
43572
|
+
try {
|
|
43573
|
+
const fd = openSync2(path4, "wx", 384);
|
|
43574
|
+
writeFileSync14(fd, String(process.pid));
|
|
43575
|
+
return fd;
|
|
43576
|
+
} catch (error) {
|
|
43577
|
+
if (error.code !== "EEXIST") throw error;
|
|
43578
|
+
const pid = Number(readFileSync16(path4, "utf8"));
|
|
43579
|
+
if (!Number.isInteger(pid) || pid <= 0) throw new Error("journal lock has no process identity; inspect it before recovery");
|
|
43580
|
+
try {
|
|
43581
|
+
process.kill(pid, 0);
|
|
43582
|
+
} catch (cause) {
|
|
43583
|
+
if (cause.code !== "ESRCH") throw cause;
|
|
43584
|
+
unlinkSync2(path4);
|
|
43585
|
+
const fd = openSync2(path4, "wx", 384);
|
|
43586
|
+
writeFileSync14(fd, String(process.pid));
|
|
43587
|
+
return fd;
|
|
43588
|
+
}
|
|
43589
|
+
throw new Error("another CLI process owns this operation journal");
|
|
43590
|
+
}
|
|
43591
|
+
}
|
|
43592
|
+
async function hostedReceptionBatch(client, targets, journalFile) {
|
|
43593
|
+
if (new Set(targets.map((target3) => target3.operationId)).size !== targets.length) throw new Error("batch operation IDs must be unique");
|
|
43594
|
+
const recovered = /* @__PURE__ */ new Map();
|
|
43595
|
+
for (const target3 of targets) if (client.hasJournaledOperation(target3.operationId, journalFile)) {
|
|
43596
|
+
recovered.set(target3.operationId, await client.offer(target3, journalFile));
|
|
43597
|
+
}
|
|
43598
|
+
const newTargets = targets.filter((target3) => !recovered.has(target3.operationId));
|
|
43599
|
+
const enrollment = client.usesAutomaticIdentity && newTargets.length ? await client.enrollTargets(newTargets.flatMap((target3) => [
|
|
43600
|
+
{ workspace: target3.workspace, operation: target3.operation },
|
|
43601
|
+
{ workspace: target3.workspace, operation: target3.verify.operation }
|
|
43602
|
+
])) : { state: "active" };
|
|
43603
|
+
if (enrollment.state !== "active" && !recovered.size && !Array.isArray(enrollment.identities)) return {
|
|
43604
|
+
...enrollment,
|
|
43605
|
+
state: "pending",
|
|
43606
|
+
...enrollment.code ? {} : { code: "identity_enrollment_unresolved" },
|
|
43607
|
+
enrollment
|
|
43608
|
+
};
|
|
43609
|
+
const active = /* @__PURE__ */ new Set();
|
|
43610
|
+
if (Array.isArray(enrollment.identities)) for (const identity of enrollment.identities) {
|
|
43611
|
+
if (!identity || typeof identity !== "object" || !Array.isArray(identity.targets)) continue;
|
|
43612
|
+
for (const target3 of identity.targets) if (target3?.state === "active") active.add(`${target3.workspace}/${target3.operation}`);
|
|
43613
|
+
}
|
|
43614
|
+
const results = [];
|
|
43615
|
+
for (const target3 of targets) {
|
|
43616
|
+
let submissionReceipt = recovered.get(target3.operationId);
|
|
43617
|
+
const verify = async () => {
|
|
43618
|
+
const discovery = await client.discover(target3.workspace, target3.domain);
|
|
43619
|
+
if (discovery.state !== "ready" || typeof discovery.closure !== "string") return false;
|
|
43620
|
+
const read2 = await client.read(target3.workspace, discovery.closure, target3.verify.operation, target3.verify.args ?? []);
|
|
43621
|
+
if (read2.state !== "read") return false;
|
|
43622
|
+
let observed = read2.result;
|
|
43623
|
+
for (const key2 of target3.verify.path) {
|
|
43624
|
+
if (observed === null || typeof observed !== "object") return false;
|
|
43625
|
+
observed = observed[key2];
|
|
43626
|
+
}
|
|
43627
|
+
if (Object.hasOwn(target3.verify, "contains")) return Array.isArray(observed) && observed.some((value) => canonical(value) === canonical(target3.verify.contains));
|
|
43628
|
+
if (!Object.hasOwn(target3.verify, "equals")) throw new Error("batch verification needs explicit equals or contains");
|
|
43629
|
+
return canonical(observed) === canonical(target3.verify.equals);
|
|
43630
|
+
};
|
|
43631
|
+
try {
|
|
43632
|
+
if (!recovered.has(target3.operationId) && enrollment.state !== "active" && (!active.has(`${target3.workspace}/${target3.operation}`) || !active.has(`${target3.workspace}/${target3.verify.operation}`))) {
|
|
43633
|
+
results.push({
|
|
43634
|
+
workspace: target3.workspace,
|
|
43635
|
+
operationId: target3.operationId,
|
|
43636
|
+
state: "pending",
|
|
43637
|
+
code: "identity_enrollment_unresolved",
|
|
43638
|
+
enrollment
|
|
43639
|
+
});
|
|
43640
|
+
continue;
|
|
43641
|
+
}
|
|
43642
|
+
if (await verify()) {
|
|
43643
|
+
results.push({ workspace: target3.workspace, operationId: target3.operationId, state: "verified", skipped: true });
|
|
43644
|
+
continue;
|
|
43645
|
+
}
|
|
43646
|
+
const receipt = submissionReceipt ??= await client.offer(target3, journalFile);
|
|
43647
|
+
if (receipt.state === "admitted" && await verify()) results.push({ ...receipt, workspace: target3.workspace, state: "verified", admission: receipt });
|
|
43648
|
+
else results.push({ ...receipt, workspace: target3.workspace, ...receipt.state === "admitted" ? { state: "pending", code: "fresh_read_unverified", admission: receipt } : {} });
|
|
43649
|
+
} catch (error) {
|
|
43650
|
+
results.push({
|
|
43651
|
+
workspace: target3.workspace,
|
|
43652
|
+
operationId: target3.operationId,
|
|
43653
|
+
state: "pending",
|
|
43654
|
+
code: "target_unresolved",
|
|
43655
|
+
...submissionReceipt?.state === "admitted" ? { admission: submissionReceipt } : {},
|
|
43656
|
+
detail: error instanceof Error ? error.message : "target request failed"
|
|
43657
|
+
});
|
|
43658
|
+
}
|
|
43659
|
+
}
|
|
43660
|
+
return { state: results.every((result) => result.state === "verified") ? "verified" : "pending", results };
|
|
43661
|
+
}
|
|
43662
|
+
async function hostedReceptionCommand(argv, fetcher = globalThis.fetch) {
|
|
43663
|
+
const [command, workspace] = argv;
|
|
43664
|
+
const opts = {};
|
|
43665
|
+
for (let index = 2; index < argv.length; index += 2) {
|
|
43666
|
+
const flag3 = argv[index];
|
|
43667
|
+
const value = argv[index + 1];
|
|
43668
|
+
if (!flag3.startsWith("--") || value === void 0 || value.startsWith("--")) throw new Error(`expected a value for ${flag3}`);
|
|
43669
|
+
if (!["--cloud", "--as", "--credential", "--domain", "--operation", "--facts", "--args", "--journal", "--operation-id", "--closure", "--file"].includes(flag3)) throw new Error(`unknown flag ${flag3}`);
|
|
43670
|
+
opts[flag3.slice(2)] = value;
|
|
43671
|
+
}
|
|
43672
|
+
const required2 = (key2) => {
|
|
43673
|
+
const value = opts[key2];
|
|
43674
|
+
if (!value) throw new Error(`--${key2} is required; see githolon reception --help`);
|
|
43675
|
+
return value;
|
|
43676
|
+
};
|
|
43677
|
+
if (!workspace) throw new Error("workspace is required");
|
|
43678
|
+
const client = new HostedReceptionClient({
|
|
43679
|
+
endpoint: opts.cloud ?? "https://nomos.cafe",
|
|
43680
|
+
principal: required2("as"),
|
|
43681
|
+
credentialId: opts.credential ?? "",
|
|
43682
|
+
token: process.env.NOMOS_RECEPTION_TOKEN ?? ""
|
|
43683
|
+
}, fetcher);
|
|
43684
|
+
const json = (key2) => opts[key2] ? record(JSON.parse(readFileSync16(required2(key2), "utf8"))) : {};
|
|
43685
|
+
let result;
|
|
43686
|
+
switch (command) {
|
|
43687
|
+
case "discover":
|
|
43688
|
+
result = await client.discover(workspace, required2("domain"));
|
|
43689
|
+
break;
|
|
43690
|
+
case "read": {
|
|
43691
|
+
const args = opts.args ? JSON.parse(readFileSync16(required2("args"), "utf8")) : [];
|
|
43692
|
+
if (!Array.isArray(args)) throw new Error("read args must be a JSON array of generated positional arguments");
|
|
43693
|
+
result = await client.read(workspace, required2("closure"), required2("operation"), args);
|
|
43694
|
+
break;
|
|
43695
|
+
}
|
|
43696
|
+
case "status":
|
|
43697
|
+
result = await client.status(workspace, required2("operation-id"));
|
|
43698
|
+
break;
|
|
43699
|
+
case "offer":
|
|
43700
|
+
result = await client.offer({
|
|
43701
|
+
workspace,
|
|
43702
|
+
domain: required2("domain"),
|
|
43703
|
+
operation: required2("operation"),
|
|
43704
|
+
facts: json("facts"),
|
|
43705
|
+
operationId: required2("operation-id")
|
|
43706
|
+
}, required2("journal"));
|
|
43707
|
+
break;
|
|
43708
|
+
case "identity": {
|
|
43709
|
+
const targets = JSON.parse(readFileSync16(required2("file"), "utf8"));
|
|
43710
|
+
if (!Array.isArray(targets)) throw new Error("identity targets must be a JSON array");
|
|
43711
|
+
result = await client.enrollTargets(targets);
|
|
43712
|
+
break;
|
|
43713
|
+
}
|
|
43714
|
+
case "prepare":
|
|
43715
|
+
result = await client.request(workspace, "/credentials", { ...json("file"), action: "prepare" });
|
|
43716
|
+
break;
|
|
43717
|
+
case "enroll":
|
|
43718
|
+
result = await client.request(workspace, "/credentials", { ...json("file"), action: "enroll", credentialId: required2("credential") });
|
|
43719
|
+
break;
|
|
43720
|
+
case "recover":
|
|
43721
|
+
result = await client.request(workspace, "/credentials", { action: "recover", credentialId: required2("credential") });
|
|
43722
|
+
break;
|
|
43723
|
+
case "revoke":
|
|
43724
|
+
result = await client.request(workspace, "/credentials", { action: "revoke", credentialId: required2("credential") });
|
|
43725
|
+
break;
|
|
43726
|
+
case "batch": {
|
|
43727
|
+
const targets = JSON.parse(readFileSync16(workspace, "utf8"));
|
|
43728
|
+
if (!Array.isArray(targets) || targets.length === 0 || targets.length > 64) throw new Error("batch file must contain 1-64 explicit targets");
|
|
43729
|
+
for (const target3 of targets) {
|
|
43730
|
+
record(target3);
|
|
43731
|
+
record(target3.facts);
|
|
43732
|
+
record(target3.verify);
|
|
43733
|
+
if (!Array.isArray(target3.verify.path) || target3.verify.path.some((key2) => typeof key2 !== "string")) throw new Error("verification path must be an array of field names");
|
|
43734
|
+
}
|
|
43735
|
+
result = await hostedReceptionBatch(client, targets, required2("journal"));
|
|
43736
|
+
break;
|
|
43737
|
+
}
|
|
43738
|
+
default:
|
|
43739
|
+
throw new Error("expected discover, read, offer, status, identity, prepare, enroll, recover, revoke or batch; see githolon reception --help");
|
|
43740
|
+
}
|
|
43741
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}
|
|
43742
|
+
`);
|
|
43743
|
+
return ["ready", "read", "admitted", "active", "prepared", "revoked", "verified"].includes(result.state) ? 0 : 1;
|
|
43744
|
+
}
|
|
43745
|
+
var record, canonical, isOperationReceipt, HostedReceptionClient;
|
|
43746
|
+
var init_hosted_reception = __esm({
|
|
43747
|
+
"src/hosted_reception.ts"() {
|
|
43748
|
+
"use strict";
|
|
43749
|
+
record = (value) => {
|
|
43750
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("expected a JSON object");
|
|
43751
|
+
return value;
|
|
43752
|
+
};
|
|
43753
|
+
canonical = (value) => {
|
|
43754
|
+
if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
|
|
43755
|
+
if (value && typeof value === "object") return `{${Object.keys(value).sort().map((key2) => `${JSON.stringify(key2)}:${canonical(value[key2])}`).join(",")}}`;
|
|
43756
|
+
return JSON.stringify(value);
|
|
43757
|
+
};
|
|
43758
|
+
isOperationReceipt = (receipt, operation, closure, caller) => ["pending", "admitted", "refused", "notAdmitted"].includes(receipt.state) && receipt.operationId === operation.operationId && receipt.workspace === operation.workspace && receipt.principal === caller.principal && typeof receipt.credentialId === "string" && !!receipt.credentialId && (!caller.credentialId || receipt.credentialId === caller.credentialId) && receipt.operation === operation.operation && receipt.closure === closure && receipt.requestDigest === createHash8("sha256").update(canonical({
|
|
43759
|
+
workspace: operation.workspace,
|
|
43760
|
+
principal: caller.principal,
|
|
43761
|
+
credentialId: receipt.credentialId,
|
|
43762
|
+
closure,
|
|
43763
|
+
operation: operation.operation,
|
|
43764
|
+
facts: operation.facts
|
|
43765
|
+
})).digest("hex");
|
|
43766
|
+
HostedReceptionClient = class {
|
|
43767
|
+
#caller;
|
|
43768
|
+
#fetch;
|
|
43769
|
+
#enrolledTargets = /* @__PURE__ */ new Set();
|
|
43770
|
+
constructor(caller, fetcher = globalThis.fetch) {
|
|
43771
|
+
const endpoint = new URL(caller.endpoint);
|
|
43772
|
+
if (endpoint.protocol !== "https:" || !/^https:\/\/[A-Za-z0-9.-]+(?::[0-9]+)?\/?$/.test(caller.endpoint)) {
|
|
43773
|
+
throw new Error("hosted Reception endpoint must be an HTTPS origin");
|
|
43774
|
+
}
|
|
43775
|
+
if (!caller.principal.trim() || !caller.token.trim()) {
|
|
43776
|
+
throw new Error("explicit principal and authentication token are required");
|
|
43777
|
+
}
|
|
43778
|
+
this.#caller = { ...caller, endpoint: endpoint.origin };
|
|
43779
|
+
this.#fetch = fetcher;
|
|
43780
|
+
}
|
|
43781
|
+
async request(workspace, suffix, body) {
|
|
43782
|
+
if (!workspace.trim()) throw new Error("workspace is required");
|
|
43783
|
+
const response = await this.#fetch(`${this.#caller.endpoint}/v2/workspaces/${encodeURIComponent(workspace)}/reception${suffix}`, {
|
|
43784
|
+
method: body === void 0 ? "GET" : "POST",
|
|
43785
|
+
redirect: "error",
|
|
43786
|
+
headers: {
|
|
43787
|
+
authorization: `Bearer ${this.#caller.token}`,
|
|
43788
|
+
"content-type": "application/json",
|
|
43789
|
+
"x-nomos-principal": this.#caller.principal,
|
|
43790
|
+
...this.#caller.credentialId ? { "x-nomos-credential": this.#caller.credentialId } : {}
|
|
43791
|
+
},
|
|
43792
|
+
...body ? { body: JSON.stringify({ ...body, principal: this.#caller.principal, ...this.#caller.credentialId ? { credentialId: this.#caller.credentialId } : {} }) } : {},
|
|
43793
|
+
signal: AbortSignal.timeout(6e4)
|
|
43794
|
+
});
|
|
43795
|
+
const value = record(await response.json());
|
|
43796
|
+
if (typeof value.state !== "string") {
|
|
43797
|
+
if (!response.ok) return { ...value, state: "refused", httpStatus: response.status };
|
|
43798
|
+
throw new Error("hosted Reception returned no typed state");
|
|
43799
|
+
}
|
|
43800
|
+
return { ...value, state: value.state, httpStatus: response.status };
|
|
43801
|
+
}
|
|
43802
|
+
async enrollTargets(targets) {
|
|
43803
|
+
if (!targets.length || targets.length > 128) throw new Error("identity enrollment requires 1-128 explicit targets");
|
|
43804
|
+
const result = await this.request(targets[0].workspace, "/identity", { targets });
|
|
43805
|
+
if (result.state === "active") for (const target3 of targets) this.#enrolledTargets.add(`${target3.workspace}/${target3.operation}`);
|
|
43806
|
+
return result;
|
|
43807
|
+
}
|
|
43808
|
+
get usesAutomaticIdentity() {
|
|
43809
|
+
return !this.#caller.credentialId;
|
|
43810
|
+
}
|
|
43811
|
+
hasJournaledOperation(operationId, journalFile) {
|
|
43812
|
+
return existsSync17(journalFile) && Object.hasOwn(record(JSON.parse(readFileSync16(journalFile, "utf8"))), operationId);
|
|
43813
|
+
}
|
|
43814
|
+
discover(workspace, domain) {
|
|
43815
|
+
return this.request(workspace, `?domain=${encodeURIComponent(domain)}`);
|
|
43816
|
+
}
|
|
43817
|
+
status(workspace, operationId) {
|
|
43818
|
+
return this.request(workspace, `/operations/${encodeURIComponent(operationId)}`);
|
|
43819
|
+
}
|
|
43820
|
+
read(workspace, closure, operation, args = []) {
|
|
43821
|
+
return this.request(workspace, "/read", { closure, operation, args });
|
|
43822
|
+
}
|
|
43823
|
+
/** Persist before sending. A lost response or restarted process queries the same operation;
|
|
43824
|
+
* it cannot turn uncertainty into another authoring attempt. The gateway owns admission status.
|
|
43825
|
+
*/
|
|
43826
|
+
async offer(operation, journalFile) {
|
|
43827
|
+
if (!/^[A-Za-z0-9_-]{1,128}$/.test(operation.operationId)) throw new Error("operation ID must be 1-128 letters, digits, underscores or hyphens");
|
|
43828
|
+
const fingerprint = createHash8("sha256").update(canonical({
|
|
43829
|
+
endpoint: this.#caller.endpoint,
|
|
43830
|
+
principal: this.#caller.principal,
|
|
43831
|
+
credentialId: this.#caller.credentialId,
|
|
43832
|
+
workspace: operation.workspace,
|
|
43833
|
+
domain: operation.domain,
|
|
43834
|
+
operation: operation.operation,
|
|
43835
|
+
facts: operation.facts,
|
|
43836
|
+
operationId: operation.operationId
|
|
43837
|
+
})).digest("hex");
|
|
43838
|
+
mkdirSync13(dirname6(resolve5(journalFile)), { recursive: true, mode: 448 });
|
|
43839
|
+
const lock = `${journalFile}.lock`;
|
|
43840
|
+
const fd = acquireJournalLock(lock);
|
|
43841
|
+
try {
|
|
43842
|
+
const entries = existsSync17(journalFile) ? record(JSON.parse(readFileSync16(journalFile, "utf8"))) : {};
|
|
43843
|
+
const saved = entries[operation.operationId];
|
|
43844
|
+
const persist = (entry2) => {
|
|
43845
|
+
entries[operation.operationId] = entry2;
|
|
43846
|
+
const temporary = `${journalFile}.next`;
|
|
43847
|
+
writeFileSync14(temporary, `${JSON.stringify(entries, null, 2)}
|
|
43848
|
+
`, { mode: 384 });
|
|
43849
|
+
chmodSync5(temporary, 384);
|
|
43850
|
+
renameSync5(temporary, journalFile);
|
|
43851
|
+
};
|
|
43852
|
+
if (saved) {
|
|
43853
|
+
if (saved.fingerprint !== fingerprint) throw new Error("operation ID already binds different facts, principal, credential or endpoint");
|
|
43854
|
+
if (["admitted", "refused", "notAdmitted"].includes(saved.receipt.state)) return saved.receipt;
|
|
43855
|
+
try {
|
|
43856
|
+
const receipt = await this.status(operation.workspace, operation.operationId);
|
|
43857
|
+
const resolved = receipt.httpStatus === 200 && isOperationReceipt(receipt, operation, saved.closure, this.#caller) && (!saved.receipt.requestDigest || receipt.requestDigest === saved.receipt.requestDigest) ? receipt : {
|
|
43858
|
+
state: "pending",
|
|
43859
|
+
code: "operation_status_unknown",
|
|
43860
|
+
operationId: operation.operationId,
|
|
43861
|
+
statusCode: receipt.code,
|
|
43862
|
+
httpStatus: receipt.httpStatus
|
|
43863
|
+
};
|
|
43864
|
+
persist({ ...saved, receipt: resolved });
|
|
43865
|
+
return resolved;
|
|
43866
|
+
} catch {
|
|
43867
|
+
return { state: "pending", code: "operation_status_unavailable", operationId: operation.operationId };
|
|
43868
|
+
}
|
|
43869
|
+
}
|
|
43870
|
+
const discovery = await this.discover(operation.workspace, operation.domain);
|
|
43871
|
+
if (discovery.state !== "ready") return discovery;
|
|
43872
|
+
const closure = discovery.closure;
|
|
43873
|
+
if (typeof closure !== "string" || !/^[0-9a-f]{64}$/.test(closure)) throw new Error("discovery returned no exact closure identity");
|
|
43874
|
+
if (this.usesAutomaticIdentity && !this.#enrolledTargets.has(`${operation.workspace}/${operation.operation}`)) {
|
|
43875
|
+
const enrollment = await this.enrollTargets([{ workspace: operation.workspace, operation: operation.operation }]);
|
|
43876
|
+
if (enrollment.state !== "active") return enrollment;
|
|
43877
|
+
}
|
|
43878
|
+
const entry = {
|
|
43879
|
+
fingerprint,
|
|
43880
|
+
operationId: operation.operationId,
|
|
43881
|
+
workspace: operation.workspace,
|
|
43882
|
+
closure,
|
|
43883
|
+
receipt: { state: "pending", code: "submission_started", operationId: operation.operationId }
|
|
43884
|
+
};
|
|
43885
|
+
persist(entry);
|
|
43886
|
+
try {
|
|
43887
|
+
const receipt = await this.request(operation.workspace, "/offer", {
|
|
43888
|
+
closure,
|
|
43889
|
+
domain: operation.domain,
|
|
43890
|
+
operation: operation.operation,
|
|
43891
|
+
facts: operation.facts,
|
|
43892
|
+
operationId: operation.operationId
|
|
43893
|
+
});
|
|
43894
|
+
const resolved = isOperationReceipt(receipt, operation, closure, this.#caller) ? receipt : {
|
|
43895
|
+
state: "pending",
|
|
43896
|
+
code: "operation_receipt_unavailable",
|
|
43897
|
+
operationId: operation.operationId,
|
|
43898
|
+
statusCode: receipt.code,
|
|
43899
|
+
httpStatus: receipt.httpStatus
|
|
43900
|
+
};
|
|
43901
|
+
persist({ ...entry, receipt: resolved });
|
|
43902
|
+
return resolved;
|
|
43903
|
+
} catch {
|
|
43904
|
+
return entry.receipt;
|
|
43905
|
+
}
|
|
43906
|
+
} finally {
|
|
43907
|
+
closeSync2(fd);
|
|
43908
|
+
unlinkSync2(lock);
|
|
43909
|
+
}
|
|
43910
|
+
}
|
|
43911
|
+
};
|
|
43912
|
+
}
|
|
43913
|
+
});
|
|
43914
|
+
|
|
43527
43915
|
// src/baseline.ts
|
|
43528
43916
|
var baseline_exports = {};
|
|
43529
43917
|
__export(baseline_exports, {
|
|
@@ -43531,9 +43919,9 @@ __export(baseline_exports, {
|
|
|
43531
43919
|
baselineExport: () => baselineExport,
|
|
43532
43920
|
renderBaselineExport: () => renderBaselineExport
|
|
43533
43921
|
});
|
|
43534
|
-
import { mkdirSync as
|
|
43922
|
+
import { mkdirSync as mkdirSync14, mkdtempSync as mkdtempSync4, rmSync as rmSync6, writeFileSync as writeFileSync15 } from "node:fs";
|
|
43535
43923
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
43536
|
-
import { dirname as
|
|
43924
|
+
import { dirname as dirname7, join as join21, resolve as resolve6 } from "node:path";
|
|
43537
43925
|
import { tsImport as tsImport6 } from "tsx/esm/api";
|
|
43538
43926
|
function flag2(args, name) {
|
|
43539
43927
|
const at = args.indexOf(name);
|
|
@@ -43557,8 +43945,8 @@ async function downloadBlob(profile, digest, fetcher) {
|
|
|
43557
43945
|
throw new Error(`Console ${response.status}: ${body.error ?? `artifact ${digest} unavailable`}`);
|
|
43558
43946
|
}
|
|
43559
43947
|
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
43560
|
-
const { createHash:
|
|
43561
|
-
const actual =
|
|
43948
|
+
const { createHash: createHash10 } = await import("node:crypto");
|
|
43949
|
+
const actual = createHash10("sha256").update(bytes).digest("hex");
|
|
43562
43950
|
if (actual !== digest) throw new Error(`the console served ${actual} for ${digest}; refusing bytes that are not their digest`);
|
|
43563
43951
|
return bytes;
|
|
43564
43952
|
}
|
|
@@ -43571,8 +43959,8 @@ async function materialiseRelease(profile, release, fetcher, dsl) {
|
|
|
43571
43959
|
throw new Error(`release ${release.identity} names an unsafe file path '${file.path}'`);
|
|
43572
43960
|
}
|
|
43573
43961
|
const target3 = join21(unitDir, file.path);
|
|
43574
|
-
|
|
43575
|
-
|
|
43962
|
+
mkdirSync14(dirname7(target3), { recursive: true });
|
|
43963
|
+
writeFileSync15(target3, await downloadBlob(profile, file.sha256, fetcher));
|
|
43576
43964
|
}
|
|
43577
43965
|
}
|
|
43578
43966
|
return dir;
|
|
@@ -43597,7 +43985,7 @@ async function releaseOfInstalledUnits(profile, installed, fetcher) {
|
|
|
43597
43985
|
}
|
|
43598
43986
|
async function baselineExport(args, profileFor, fetcher = fetch) {
|
|
43599
43987
|
const dsl = await baselineModule();
|
|
43600
|
-
const out11 =
|
|
43988
|
+
const out11 = resolve6(process.cwd(), flag2(args, "--out") ?? dsl.NOMOS_BASELINE_FILENAME);
|
|
43601
43989
|
const unitsArg = flag2(args, "--units");
|
|
43602
43990
|
const releaseArg = flag2(args, "--release");
|
|
43603
43991
|
const workspaceArg = flag2(args, "--workspace");
|
|
@@ -43609,7 +43997,7 @@ async function baselineExport(args, profileFor, fetcher = fetch) {
|
|
|
43609
43997
|
try {
|
|
43610
43998
|
if (unitsArg !== void 0) {
|
|
43611
43999
|
exported = dsl.exportBaselineFromUnits({
|
|
43612
|
-
unitsDir:
|
|
44000
|
+
unitsDir: resolve6(process.cwd(), unitsArg),
|
|
43613
44001
|
source: "units",
|
|
43614
44002
|
...flag2(args, "--series") === void 0 ? {} : { series: flag2(args, "--series") }
|
|
43615
44003
|
});
|
|
@@ -43653,7 +44041,7 @@ async function baselineExport(args, profileFor, fetcher = fetch) {
|
|
|
43653
44041
|
} finally {
|
|
43654
44042
|
if (scratch !== void 0) rmSync6(scratch, { recursive: true, force: true });
|
|
43655
44043
|
}
|
|
43656
|
-
|
|
44044
|
+
writeFileSync15(out11, exported.text, "utf8");
|
|
43657
44045
|
const identities = Object.keys(exported.baseline.continuity.identity?.entities ?? {}).length;
|
|
43658
44046
|
return {
|
|
43659
44047
|
out: out11,
|
|
@@ -43723,15 +44111,15 @@ __export(mcp_exports, {
|
|
|
43723
44111
|
toolEvolvePreview: () => toolEvolvePreview
|
|
43724
44112
|
});
|
|
43725
44113
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
43726
|
-
import { existsSync as
|
|
43727
|
-
import { dirname as
|
|
44114
|
+
import { existsSync as existsSync18 } from "node:fs";
|
|
44115
|
+
import { dirname as dirname8, isAbsolute as isAbsolute2, resolve as resolve7 } from "node:path";
|
|
43728
44116
|
function resolveConfig(config) {
|
|
43729
44117
|
const arg = config ?? "nomos.project.ts";
|
|
43730
|
-
const configPath = isAbsolute2(arg) ? arg :
|
|
43731
|
-
return { configPath, cfgDir:
|
|
44118
|
+
const configPath = isAbsolute2(arg) ? arg : resolve7(process.cwd(), arg);
|
|
44119
|
+
return { configPath, cfgDir: dirname8(configPath) };
|
|
43732
44120
|
}
|
|
43733
44121
|
function runCheckLauncher(configPath, extraArgs) {
|
|
43734
|
-
const cfgDir =
|
|
44122
|
+
const cfgDir = dirname8(configPath);
|
|
43735
44123
|
const launcher = resolveCheckLauncher(cfgDir) ?? resolveCheckLauncher(process.cwd());
|
|
43736
44124
|
if (launcher === void 0) {
|
|
43737
44125
|
return { findings: [], stdout: "", stderr: "", status: 1, error: NO_DSL_REMEDY };
|
|
@@ -43802,7 +44190,7 @@ function extractDispositions(humanReport) {
|
|
|
43802
44190
|
}
|
|
43803
44191
|
function toolCheck(args) {
|
|
43804
44192
|
const { configPath } = resolveConfig(args.config);
|
|
43805
|
-
if (!
|
|
44193
|
+
if (!existsSync18(configPath)) {
|
|
43806
44194
|
return { text: `nomos_check: config not found: ${configPath}`, isError: true };
|
|
43807
44195
|
}
|
|
43808
44196
|
const extra = args.against !== void 0 ? ["--against", args.against] : [];
|
|
@@ -43819,11 +44207,11 @@ ${JSON.stringify(payload, null, 2)}`, isError: false };
|
|
|
43819
44207
|
}
|
|
43820
44208
|
function toolEvolvePreview(args) {
|
|
43821
44209
|
const { configPath } = resolveConfig(args.config);
|
|
43822
|
-
if (!
|
|
44210
|
+
if (!existsSync18(configPath)) {
|
|
43823
44211
|
return { text: `nomos_evolve_preview: config not found: ${configPath}`, isError: true };
|
|
43824
44212
|
}
|
|
43825
|
-
const againstPath = isAbsolute2(args.against) ? args.against :
|
|
43826
|
-
const priorArg =
|
|
44213
|
+
const againstPath = isAbsolute2(args.against) ? args.against : resolve7(dirname8(configPath), args.against);
|
|
44214
|
+
const priorArg = existsSync18(againstPath) ? againstPath : args.against;
|
|
43827
44215
|
const jsonRun = runCheckJson(configPath, ["--against", priorArg]);
|
|
43828
44216
|
if (jsonRun.error !== void 0) {
|
|
43829
44217
|
return {
|
|
@@ -43985,21 +44373,21 @@ __export(conformance_exports, {
|
|
|
43985
44373
|
runConformance: () => runConformance
|
|
43986
44374
|
});
|
|
43987
44375
|
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
43988
|
-
import { cpSync, existsSync as
|
|
44376
|
+
import { cpSync, existsSync as existsSync19, mkdirSync as mkdirSync15, mkdtempSync as mkdtempSync5, readFileSync as readFileSync17, rmSync as rmSync7, symlinkSync, writeFileSync as writeFileSync16 } from "node:fs";
|
|
43989
44377
|
import { createRequire as createRequire3 } from "node:module";
|
|
43990
44378
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
43991
|
-
import { dirname as
|
|
44379
|
+
import { dirname as dirname9, join as join23, resolve as resolve8 } from "node:path";
|
|
43992
44380
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
43993
44381
|
function installedPackage(name, from) {
|
|
43994
44382
|
const require2 = createRequire3(join23(from, "package.json"));
|
|
43995
44383
|
const entry = require2.resolve(name === "@githolon/testing" ? name : `${name}/package.json`);
|
|
43996
|
-
for (let directory2 =
|
|
44384
|
+
for (let directory2 = dirname9(entry); ; directory2 = dirname9(directory2)) {
|
|
43997
44385
|
const manifest = join23(directory2, "package.json");
|
|
43998
|
-
if (
|
|
43999
|
-
const pkg = JSON.parse(
|
|
44386
|
+
if (existsSync19(manifest)) {
|
|
44387
|
+
const pkg = JSON.parse(readFileSync17(manifest, "utf8"));
|
|
44000
44388
|
if (pkg.name === name) return { name, version: pkg.version, directory: directory2 };
|
|
44001
44389
|
}
|
|
44002
|
-
if (
|
|
44390
|
+
if (dirname9(directory2) === directory2) throw new Error(`Cannot identify installed ${name}`);
|
|
44003
44391
|
}
|
|
44004
44392
|
}
|
|
44005
44393
|
function runConformance(args, cwd = process.cwd()) {
|
|
@@ -44008,7 +44396,7 @@ function runConformance(args, cwd = process.cwd()) {
|
|
|
44008
44396
|
const arg = args[index];
|
|
44009
44397
|
if (arg === "--json") json = true;
|
|
44010
44398
|
else if (arg === "--offline") offline = true;
|
|
44011
|
-
else if (arg === "--runtime" && args[index + 1] && !args[index + 1].startsWith("--")) runtime =
|
|
44399
|
+
else if (arg === "--runtime" && args[index + 1] && !args[index + 1].startsWith("--")) runtime = resolve8(cwd, args[++index]);
|
|
44012
44400
|
else {
|
|
44013
44401
|
process.stderr.write(`error: unknown or incomplete conformance option: ${arg}. See githolon conformance --help.
|
|
44014
44402
|
`);
|
|
@@ -44035,12 +44423,12 @@ function runConformance(args, cwd = process.cwd()) {
|
|
|
44035
44423
|
`);
|
|
44036
44424
|
}
|
|
44037
44425
|
scratch = mkdtempSync5(join23(tmpdir4(), "nomos-conformance-"));
|
|
44038
|
-
const here =
|
|
44039
|
-
const distribution =
|
|
44426
|
+
const here = dirname9(fileURLToPath2(import.meta.url));
|
|
44427
|
+
const distribution = existsSync19(join23(here, "conformance-probe.mjs")) ? here : resolve8(here, "../dist");
|
|
44040
44428
|
cpSync(join23(distribution, "conformance-fixture"), scratch, { recursive: true });
|
|
44041
|
-
|
|
44429
|
+
writeFileSync16(join23(scratch, "package.json"), '{"name":"nomos-conformance-probe","private":true,"type":"module"}\n');
|
|
44042
44430
|
const modules = join23(scratch, "node_modules");
|
|
44043
|
-
|
|
44431
|
+
mkdirSync15(join23(modules, "@githolon"), { recursive: true });
|
|
44044
44432
|
for (const pkg of [dsl, peer2]) {
|
|
44045
44433
|
symlinkSync(pkg.directory, join23(modules, pkg.name), process.platform === "win32" ? "junction" : "dir");
|
|
44046
44434
|
}
|
|
@@ -44082,8 +44470,8 @@ function runConformance(args, cwd = process.cwd()) {
|
|
|
44082
44470
|
timeout: 18e4,
|
|
44083
44471
|
maxBuffer: 8 * 1024 * 1024
|
|
44084
44472
|
});
|
|
44085
|
-
if (
|
|
44086
|
-
const result = JSON.parse(
|
|
44473
|
+
if (existsSync19(resultFile)) {
|
|
44474
|
+
const result = JSON.parse(readFileSync17(resultFile, "utf8"));
|
|
44087
44475
|
report.checks.push(...result.checks);
|
|
44088
44476
|
if (result.runtime) report.runtime = result.runtime;
|
|
44089
44477
|
if (result.failure) report.failure = result.failure;
|
|
@@ -44122,28 +44510,28 @@ __export(test_exports, {
|
|
|
44122
44510
|
runDartTests: () => runDartTests
|
|
44123
44511
|
});
|
|
44124
44512
|
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
44125
|
-
import { existsSync as
|
|
44126
|
-
import { dirname as
|
|
44513
|
+
import { existsSync as existsSync20 } from "node:fs";
|
|
44514
|
+
import { dirname as dirname10, resolve as resolve9 } from "node:path";
|
|
44127
44515
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
44128
44516
|
function resolveTestCloudEntry(options = {}) {
|
|
44129
44517
|
const cwd = options.cwd ?? process.cwd();
|
|
44130
44518
|
const environment = options.environment ?? process.env;
|
|
44131
44519
|
const explicit = environment.NOMOS_TEST_CLOUD_ENTRY;
|
|
44132
44520
|
if (explicit !== void 0) {
|
|
44133
|
-
const candidate =
|
|
44134
|
-
if (!
|
|
44521
|
+
const candidate = resolve9(cwd, explicit);
|
|
44522
|
+
if (!existsSync20(candidate)) {
|
|
44135
44523
|
throw new Error(`NOMOS_TEST_CLOUD_ENTRY does not exist: ${candidate}`);
|
|
44136
44524
|
}
|
|
44137
44525
|
return candidate;
|
|
44138
44526
|
}
|
|
44139
|
-
const here =
|
|
44527
|
+
const here = dirname10(fileURLToPath3(options.moduleUrl ?? import.meta.url));
|
|
44140
44528
|
const candidates = [
|
|
44141
|
-
|
|
44142
|
-
|
|
44143
|
-
|
|
44144
|
-
|
|
44529
|
+
resolve9(here, "dev-server.mjs"),
|
|
44530
|
+
resolve9(here, "../dist/dev-server.mjs"),
|
|
44531
|
+
resolve9(here, "../../platform-shells/node/local-development/server.ts"),
|
|
44532
|
+
resolve9(cwd, "platform-shells/node/local-development/server.ts")
|
|
44145
44533
|
];
|
|
44146
|
-
const server = candidates.find((candidate) =>
|
|
44534
|
+
const server = candidates.find((candidate) => existsSync20(candidate));
|
|
44147
44535
|
if (server === void 0) {
|
|
44148
44536
|
throw new Error("the bundled local Nomos cloud is missing \u2014 rebuild or reinstall githolon");
|
|
44149
44537
|
}
|
|
@@ -44404,8 +44792,8 @@ var init_workspace_epochs = __esm({
|
|
|
44404
44792
|
// ../platform-shells/node/local-development/workspace_epochs.ts
|
|
44405
44793
|
import { execFile } from "node:child_process";
|
|
44406
44794
|
import { createPrivateKey as createPrivateKey3, createPublicKey as createPublicKey3, sign as ed25519Sign2 } from "node:crypto";
|
|
44407
|
-
import { existsSync as
|
|
44408
|
-
import { dirname as
|
|
44795
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync16, readFileSync as readFileSync18, renameSync as renameSync6, rmSync as rmSync8, writeFileSync as writeFileSync17 } from "node:fs";
|
|
44796
|
+
import { dirname as dirname11, join as join24 } from "node:path";
|
|
44409
44797
|
import { promisify } from "node:util";
|
|
44410
44798
|
function localEpochRepoDir(dataDir, repo) {
|
|
44411
44799
|
return join24(dataDir, "custody", `${repo}.git`);
|
|
@@ -44420,10 +44808,10 @@ async function git3(dir, ...args) {
|
|
|
44420
44808
|
function localEpochCustodyHost(dataDir, workspace) {
|
|
44421
44809
|
const pointerPath = localEpochPointerPath(dataDir, workspace);
|
|
44422
44810
|
const dir = (repo) => localEpochRepoDir(dataDir, repo);
|
|
44423
|
-
const storedPointer = () =>
|
|
44811
|
+
const storedPointer = () => existsSync21(pointerPath) ? readFileSync18(pointerPath, "utf8") : void 0;
|
|
44424
44812
|
return {
|
|
44425
44813
|
readHead: async (repo) => {
|
|
44426
|
-
if (!
|
|
44814
|
+
if (!existsSync21(dir(repo))) return void 0;
|
|
44427
44815
|
try {
|
|
44428
44816
|
return parseGitObjectId2((await git3(dir(repo), "rev-parse", "--verify", "-q", "refs/heads/main^{commit}")).trim());
|
|
44429
44817
|
} catch {
|
|
@@ -44431,8 +44819,8 @@ function localEpochCustodyHost(dataDir, workspace) {
|
|
|
44431
44819
|
}
|
|
44432
44820
|
},
|
|
44433
44821
|
createRepo: async (repo) => {
|
|
44434
|
-
if (
|
|
44435
|
-
|
|
44822
|
+
if (existsSync21(dir(repo))) throw new Error(`${repo} already exists`);
|
|
44823
|
+
mkdirSync16(dir(repo), { recursive: true });
|
|
44436
44824
|
await run3("git", ["init", "--bare", "--quiet", dir(repo)]);
|
|
44437
44825
|
await git3(dir(repo), "config", "http.uploadpack", "true");
|
|
44438
44826
|
await git3(dir(repo), "config", "http.receivepack", "true");
|
|
@@ -44458,10 +44846,10 @@ function localEpochCustodyHost(dataDir, workspace) {
|
|
|
44458
44846
|
},
|
|
44459
44847
|
writePointer: async (expected, next) => {
|
|
44460
44848
|
if (storedPointer() !== (expected === void 0 ? void 0 : encodeEpochPointer(expected))) return false;
|
|
44461
|
-
|
|
44849
|
+
mkdirSync16(dirname11(pointerPath), { recursive: true });
|
|
44462
44850
|
const staged = `${pointerPath}.${process.pid}.tmp`;
|
|
44463
|
-
|
|
44464
|
-
|
|
44851
|
+
writeFileSync17(staged, encodeEpochPointer(next), { flag: "wx" });
|
|
44852
|
+
renameSync6(staged, pointerPath);
|
|
44465
44853
|
return true;
|
|
44466
44854
|
}
|
|
44467
44855
|
};
|
|
@@ -44558,7 +44946,7 @@ __export(cloud_epoch_exports, {
|
|
|
44558
44946
|
parseCloudEpochArgs: () => parseCloudEpochArgs,
|
|
44559
44947
|
runCloudEpoch: () => runCloudEpoch
|
|
44560
44948
|
});
|
|
44561
|
-
import { readFileSync as
|
|
44949
|
+
import { readFileSync as readFileSync19 } from "node:fs";
|
|
44562
44950
|
function parseCloudEpochArgs(argv, env = process.env) {
|
|
44563
44951
|
const [sub, workspace, ...rest] = argv;
|
|
44564
44952
|
if (sub !== "plan" && sub !== "cut" && sub !== "verify") return { bad: `unknown epoch subcommand '${sub ?? ""}'` };
|
|
@@ -44648,7 +45036,7 @@ var init_cloud_epoch = __esm({
|
|
|
44648
45036
|
defaultDeps = {
|
|
44649
45037
|
host: localEpochCustodyHost,
|
|
44650
45038
|
kernel: localEpochKernel,
|
|
44651
|
-
readKey: (path4) =>
|
|
45039
|
+
readKey: (path4) => readFileSync19(path4, "utf8"),
|
|
44652
45040
|
write: (text3) => void process.stdout.write(text3)
|
|
44653
45041
|
};
|
|
44654
45042
|
}
|
|
@@ -44891,7 +45279,7 @@ var init_model_children = __esm({
|
|
|
44891
45279
|
init_law_directive_call();
|
|
44892
45280
|
init_law_command_projection();
|
|
44893
45281
|
init_law_encoder();
|
|
44894
|
-
sleep = (ms) => new Promise((
|
|
45282
|
+
sleep = (ms) => new Promise((resolve12) => setTimeout(resolve12, ms));
|
|
44895
45283
|
}
|
|
44896
45284
|
});
|
|
44897
45285
|
|
|
@@ -45016,7 +45404,7 @@ async function modelAdopt(workspace, opts) {
|
|
|
45016
45404
|
inventory = observed;
|
|
45017
45405
|
break;
|
|
45018
45406
|
}
|
|
45019
|
-
await new Promise((
|
|
45407
|
+
await new Promise((resolve12) => setTimeout(resolve12, 250));
|
|
45020
45408
|
} while (Date.now() < deadline);
|
|
45021
45409
|
if (inventory === void 0) throw new Error("the active-law projection did not converge within 30 seconds");
|
|
45022
45410
|
const candidate = inventory.domains.find((installed) => installed.domainHash === identity);
|
|
@@ -45129,9 +45517,9 @@ var init_dlq = __esm({
|
|
|
45129
45517
|
});
|
|
45130
45518
|
|
|
45131
45519
|
// src/custodian.ts
|
|
45132
|
-
import { createHash as
|
|
45133
|
-
import { existsSync as
|
|
45134
|
-
import { dirname as
|
|
45520
|
+
import { createHash as createHash9, createPrivateKey as createPrivateKey4, createPublicKey as createPublicKey4 } from "node:crypto";
|
|
45521
|
+
import { existsSync as existsSync22, readFileSync as readFileSync20 } from "node:fs";
|
|
45522
|
+
import { dirname as dirname12, isAbsolute as isAbsolute3, join as join25, resolve as resolve10 } from "node:path";
|
|
45135
45523
|
import { fileURLToPath as fileURLToPath4, pathToFileURL as pathToFileURL3 } from "node:url";
|
|
45136
45524
|
import { create as create86 } from "@bufbuild/protobuf";
|
|
45137
45525
|
import { AnySchema as AnySchema3 } from "@bufbuild/protobuf/wkt";
|
|
@@ -45141,7 +45529,7 @@ function custodianKeyHash(seed) {
|
|
|
45141
45529
|
const publicKey = Buffer.from(
|
|
45142
45530
|
createPublicKey4(createPrivateKey4({ key: pkcs8, format: "der", type: "pkcs8" })).export({ format: "der", type: "spki" }).subarray(-32)
|
|
45143
45531
|
);
|
|
45144
|
-
return
|
|
45532
|
+
return createHash9("sha256").update(publicKey).digest("hex");
|
|
45145
45533
|
}
|
|
45146
45534
|
function custodianSeedFromText(text3, source) {
|
|
45147
45535
|
const value = text3.trim();
|
|
@@ -45178,8 +45566,8 @@ async function resolveCustodianCredential(reference) {
|
|
|
45178
45566
|
return fromSeed(custodianSeedFromText(device.secret, `~/.holon device key for ${rest}`), reference);
|
|
45179
45567
|
}
|
|
45180
45568
|
if (scheme === "file") {
|
|
45181
|
-
if (rest === "" || !
|
|
45182
|
-
return fromSeed(custodianSeedFromText(
|
|
45569
|
+
if (rest === "" || !existsSync22(rest)) throw new Error(`--custodian-key file:<path> \u2014 no file at '${rest}'`);
|
|
45570
|
+
return fromSeed(custodianSeedFromText(readFileSync20(rest, "utf8"), rest), `file:${rest}`);
|
|
45183
45571
|
}
|
|
45184
45572
|
if (scheme === "env") {
|
|
45185
45573
|
const value = process.env[rest];
|
|
@@ -45205,8 +45593,8 @@ async function resolveCustodianCredential(reference) {
|
|
|
45205
45593
|
}
|
|
45206
45594
|
function readCustodianChain(file) {
|
|
45207
45595
|
if (file === void 0) return [];
|
|
45208
|
-
if (!
|
|
45209
|
-
const parsed = JSON.parse(
|
|
45596
|
+
if (!existsSync22(file)) throw new Error(`--chain <file> \u2014 no file at '${file}'`);
|
|
45597
|
+
const parsed = JSON.parse(readFileSync20(file, "utf8"));
|
|
45210
45598
|
const links = Array.isArray(parsed) ? parsed : typeof parsed === "object" && parsed !== null && Array.isArray(parsed.certChain) ? parsed.certChain : void 0;
|
|
45211
45599
|
if (links === void 0) {
|
|
45212
45600
|
throw new Error(
|
|
@@ -45257,9 +45645,9 @@ function scarFromVerdict(verdict) {
|
|
|
45257
45645
|
function frameworkReceptionPath(here = moduleDirectory()) {
|
|
45258
45646
|
const candidates = [
|
|
45259
45647
|
join25(here, "framework", "nomos.reception.mjs"),
|
|
45260
|
-
|
|
45648
|
+
resolve10(here, "../../cloud/cloudflare-shell/domains/build/nomos/nomos.reception.mjs")
|
|
45261
45649
|
];
|
|
45262
|
-
const found = candidates.find((candidate) =>
|
|
45650
|
+
const found = candidates.find((candidate) => existsSync22(candidate));
|
|
45263
45651
|
if (found === void 0) {
|
|
45264
45652
|
throw new Error(
|
|
45265
45653
|
"the framework controller's compiled Reception is missing \u2014 reinstall `githolon`, or compile it with `node dsl/compile_package.mjs domain_nomos.nomos.project.ts` in cloud/cloudflare-shell/domains"
|
|
@@ -45268,8 +45656,8 @@ function frameworkReceptionPath(here = moduleDirectory()) {
|
|
|
45268
45656
|
return found;
|
|
45269
45657
|
}
|
|
45270
45658
|
async function encodeDirectiveCall(receptionPath, domain, directiveId, workspace, payload) {
|
|
45271
|
-
const absolute = isAbsolute3(receptionPath) ? receptionPath :
|
|
45272
|
-
if (!
|
|
45659
|
+
const absolute = isAbsolute3(receptionPath) ? receptionPath : resolve10(process.cwd(), receptionPath);
|
|
45660
|
+
if (!existsSync22(absolute)) throw new Error(`--reception <path> \u2014 no compiled Reception at '${absolute}'`);
|
|
45273
45661
|
const module = await import(pathToFileURL3(absolute).href);
|
|
45274
45662
|
const frameworkCalls = module["nomosFrameworkCalls"];
|
|
45275
45663
|
if (typeof frameworkCalls === "object" && frameworkCalls !== null) {
|
|
@@ -45334,7 +45722,7 @@ async function encodeDirectiveCall(receptionPath, domain, directiveId, workspace
|
|
|
45334
45722
|
return captured;
|
|
45335
45723
|
}
|
|
45336
45724
|
function readPayload2(opts) {
|
|
45337
|
-
const text3 = opts.payloadFile !== void 0 ?
|
|
45725
|
+
const text3 = opts.payloadFile !== void 0 ? readFileSync20(opts.payloadFile, "utf8") : opts.payload;
|
|
45338
45726
|
if (text3 === void 0) throw new Error("pass the directive's payload with --payload <json> or --payload-file <file>");
|
|
45339
45727
|
const parsed = JSON.parse(text3);
|
|
45340
45728
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
@@ -45403,7 +45791,7 @@ async function custodianCertify(workspace, opts) {
|
|
|
45403
45791
|
custodianPrincipal: actor,
|
|
45404
45792
|
certChain: chain
|
|
45405
45793
|
});
|
|
45406
|
-
const certId =
|
|
45794
|
+
const certId = createHash9("sha256").update(signed.certification).digest("hex");
|
|
45407
45795
|
const call = await encodeDirectiveCall(
|
|
45408
45796
|
opts.receptionPath ?? frameworkReceptionPath(),
|
|
45409
45797
|
CERTIFY_ERA_DOMAIN,
|
|
@@ -45548,7 +45936,7 @@ var init_custodian = __esm({
|
|
|
45548
45936
|
[/forged-principal|ForgedPrincipal|VERIFIED author/i, "ForgedPrincipal"],
|
|
45549
45937
|
[/bad-signature|BadSignature/i, "BadSignature"]
|
|
45550
45938
|
];
|
|
45551
|
-
moduleDirectory = () =>
|
|
45939
|
+
moduleDirectory = () => dirname12(fileURLToPath4(import.meta.url));
|
|
45552
45940
|
CapturedCall = class extends Error {
|
|
45553
45941
|
constructor() {
|
|
45554
45942
|
super("call captured");
|
|
@@ -45674,8 +46062,8 @@ Options
|
|
|
45674
46062
|
});
|
|
45675
46063
|
|
|
45676
46064
|
// src/cli.ts
|
|
45677
|
-
import { existsSync as
|
|
45678
|
-
import { dirname as
|
|
46065
|
+
import { existsSync as existsSync23, readFileSync as readFileSync21 } from "node:fs";
|
|
46066
|
+
import { dirname as dirname13, join as join26, resolve as resolve11 } from "node:path";
|
|
45679
46067
|
import { pathToFileURL as pathToFileURL4, fileURLToPath as fileURLToPath5 } from "node:url";
|
|
45680
46068
|
|
|
45681
46069
|
// src/generate.ts
|
|
@@ -45921,28 +46309,28 @@ async function plan(cloud, parent, child, actor, action) {
|
|
|
45921
46309
|
payload: { child, reclaimedBy: bare(actor), reclaimedAt: at }
|
|
45922
46310
|
};
|
|
45923
46311
|
}
|
|
45924
|
-
const
|
|
45925
|
-
if (
|
|
46312
|
+
const record2 = await registryRow(cloud, parent, child);
|
|
46313
|
+
if (record2 === void 0) {
|
|
45926
46314
|
refuse(
|
|
45927
46315
|
`${action} '${child}': no NomosBirthRecord or CloudWorkspace named '${child}' in ${parent} \u2014 nothing lawful to ${action}.
|
|
45928
46316
|
An out-of-band custody repo has no parent lifecycle fact and needs a custodian investigation.`
|
|
45929
46317
|
);
|
|
45930
46318
|
}
|
|
45931
|
-
const status2 = String(
|
|
45932
|
-
const creatorOf = String(
|
|
46319
|
+
const status2 = String(record2.data["status"] ?? "");
|
|
46320
|
+
const creatorOf = String(record2.data["createdBy"] ?? record2.data["principal"] ?? "");
|
|
45933
46321
|
if (action === "retire") {
|
|
45934
46322
|
const own = sameIdentity2(creatorOf, actor);
|
|
45935
46323
|
return {
|
|
45936
46324
|
lane: "registry",
|
|
45937
46325
|
directive: own ? "retireOwnWorkspace" : "retireWorkspace",
|
|
45938
46326
|
gate: own ? "creator" : "admin",
|
|
45939
|
-
payload: { workspaceId:
|
|
46327
|
+
payload: { workspaceId: record2.id, retiredBy: bare(actor), retiredAt: at },
|
|
45940
46328
|
...status2 === "retired" ? { done: `${child} is already retired in ${parent}` } : {}
|
|
45941
46329
|
};
|
|
45942
46330
|
}
|
|
45943
46331
|
if (status2 === "reclaimed") return { lane: "registry", directive: "reclaimWorkspace", gate: "admin", payload: {}, done: `${child} is already reclaimed in ${parent}` };
|
|
45944
46332
|
if (status2 !== "retired") refuse(`${child} is ${status2 || "live"} in ${parent}; reclaim is two-phase \u2014 retire it first`);
|
|
45945
|
-
return { lane: "registry", directive: "reclaimWorkspace", gate: "admin", payload: { workspaceId:
|
|
46333
|
+
return { lane: "registry", directive: "reclaimWorkspace", gate: "admin", payload: { workspaceId: record2.id, reclaimedBy: bare(actor), reclaimedAt: at } };
|
|
45946
46334
|
}
|
|
45947
46335
|
async function holders(cloud, workspace, relation) {
|
|
45948
46336
|
try {
|
|
@@ -46573,6 +46961,9 @@ async function main(argv) {
|
|
|
46573
46961
|
if (argv[0] === "console") {
|
|
46574
46962
|
return (await Promise.resolve().then(() => (init_console(), console_exports))).consoleCommand(argv.slice(1));
|
|
46575
46963
|
}
|
|
46964
|
+
if (argv[0] === "reception") {
|
|
46965
|
+
return (await Promise.resolve().then(() => (init_hosted_reception(), hosted_reception_exports))).hostedReceptionCommand(argv.slice(1));
|
|
46966
|
+
}
|
|
46576
46967
|
if (argv[0] === "compile") {
|
|
46577
46968
|
return runCompileCommand(argv.slice(1));
|
|
46578
46969
|
}
|
|
@@ -46625,12 +47016,12 @@ ${commandHelp("cloud") ?? USAGE2}`);
|
|
|
46625
47016
|
return 1;
|
|
46626
47017
|
}
|
|
46627
47018
|
const { spawnSync: spawnSync7 } = await import("node:child_process");
|
|
46628
|
-
const here =
|
|
47019
|
+
const here = dirname13(fileURLToPath5(import.meta.url));
|
|
46629
47020
|
const candidates = [
|
|
46630
|
-
|
|
47021
|
+
resolve11(here, "dev-server.mjs")
|
|
46631
47022
|
// published: dist/dev-server.mjs
|
|
46632
47023
|
];
|
|
46633
|
-
const serverPath = candidates.find((p) =>
|
|
47024
|
+
const serverPath = candidates.find((p) => existsSync23(p));
|
|
46634
47025
|
if (!serverPath) {
|
|
46635
47026
|
process.stderr.write("error: dev-server not found \u2014 reinstall `githolon` or run `npm run build` in the cli package\n");
|
|
46636
47027
|
return 1;
|