githolon 0.107.2 → 0.107.4

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.
Binary file
Binary file
package/dist/full-cli.mjs CHANGED
@@ -1046,6 +1046,58 @@ var init_value_object = __esm({
1046
1046
  }
1047
1047
  });
1048
1048
 
1049
+ // ../dsl/src/evolution.ts
1050
+ function formerAggregate(id, fieldNames = []) {
1051
+ if (!id.trim()) throw new Error("formerAggregate(id) needs the prior aggregate's non-empty name");
1052
+ const fields = {};
1053
+ for (const name of fieldNames) {
1054
+ if (!name.trim()) throw new Error(`formerAggregate(${id}) has an empty prior field name`);
1055
+ if (fields[name] !== void 0) throw new Error(`formerAggregate(${id}) repeats prior field '${name}'`);
1056
+ fields[name] = Object.freeze({
1057
+ [FORMER_FIELD_BRAND]: true,
1058
+ aggregate: id,
1059
+ name
1060
+ });
1061
+ }
1062
+ return Object.freeze({
1063
+ [FORMER_AGGREGATE_BRAND]: true,
1064
+ id,
1065
+ fields: Object.freeze(fields)
1066
+ });
1067
+ }
1068
+ function retirement(entity) {
1069
+ if (entity === null || typeof entity !== "object") {
1070
+ throw new Error("retirement(entity) needs a handle from formerAggregate(...)");
1071
+ }
1072
+ if (entity[FORMER_AGGREGATE_BRAND] === true) {
1073
+ const aggregate2 = entity;
1074
+ return Object.freeze({
1075
+ [RETIREMENT_BRAND]: true,
1076
+ kind: "aggregate",
1077
+ aggregate: aggregate2.id
1078
+ });
1079
+ }
1080
+ if (entity[FORMER_FIELD_BRAND] === true) {
1081
+ const field = entity;
1082
+ return Object.freeze({
1083
+ [RETIREMENT_BRAND]: true,
1084
+ kind: "field",
1085
+ aggregate: field.aggregate,
1086
+ field: field.name
1087
+ });
1088
+ }
1089
+ throw new Error("retirement(entity) needs a handle from formerAggregate(...)");
1090
+ }
1091
+ var FORMER_AGGREGATE_BRAND, FORMER_FIELD_BRAND, RETIREMENT_BRAND;
1092
+ var init_evolution = __esm({
1093
+ "../dsl/src/evolution.ts"() {
1094
+ "use strict";
1095
+ FORMER_AGGREGATE_BRAND = "__nomos_former_aggregate_v1";
1096
+ FORMER_FIELD_BRAND = "__nomos_former_field_v1";
1097
+ RETIREMENT_BRAND = "__nomos_retirement_v1";
1098
+ }
1099
+ });
1100
+
1049
1101
  // ../dsl/src/principal_evidence.ts
1050
1102
  function endorsementOf(value) {
1051
1103
  return typeof value === "object" && value !== null && REGISTRY.has(value) ? REGISTRY.get(value) ?? null : null;
@@ -1063,9 +1115,9 @@ function activityKey(kind, slot) {
1063
1115
  return `activity.${kind}.${slot}`;
1064
1116
  }
1065
1117
  function templateVars(template) {
1066
- const out14 = [];
1067
- for (const m of template.matchAll(/\{([a-zA-Z0-9_]+)\}/g)) out14.push(m[1]);
1068
- return out14;
1118
+ const out15 = [];
1119
+ for (const m of template.matchAll(/\{([a-zA-Z0-9_]+)\}/g)) out15.push(m[1]);
1120
+ return out15;
1069
1121
  }
1070
1122
  function payloadFieldNames(schema) {
1071
1123
  const def = schema?._def ?? schema?.def;
@@ -2253,7 +2305,7 @@ function releaseReceiptAggregateId(candidateHash, atStateRoot) {
2253
2305
  function releaseReceiptInstance(candidateHash, atStateRoot) {
2254
2306
  return instance(ReleaseReceipt, releaseReceiptAggregateId(candidateHash, atStateRoot));
2255
2307
  }
2256
- var MODEL_LIFECYCLE_AUTHORITY, DOMAIN_LIFECYCLE_DIRECTIVES, INSTALL_DOMAIN_DIRECTIVE, modelLifecycleRelations, DOMAIN_INSTALLATION_PHASES, DomainInstallation, RELEASE_RECEIPT_AGGREGATE, RELEASE_RECEIPT_PREFIX, ReleaseReceipt, dispositions, lowerHex64, gitOid, preflightReceipt, installPackagePayload, stagedPackagePayload, installDomain, stageDomain, promoteDomain, rollbackDomain;
2308
+ var MODEL_LIFECYCLE_AUTHORITY, DOMAIN_LIFECYCLE_DIRECTIVES, INSTALL_DOMAIN_DIRECTIVE, modelLifecycleRelations, DOMAIN_INSTALLATION_PHASES, DomainInstallation, RELEASE_RECEIPT_AGGREGATE, RELEASE_RECEIPT_PREFIX, ReleaseReceipt, counterfactualReleaseReceipt, baselineRootRetired, candidateIntentsRetired, candidateRootRetired, completeRetired, divergenceCountRetired, historyHashRetired, projectionEqualRetired, rawPromotableRetired, replayedIntentsRetired, reportHashRetired, reportJsonRetired, dispositions, lowerHex64, gitOid, preflightReceipt, installPackagePayload, stagedPackagePayload, installDomain, stageDomain, promoteDomain, rollbackDomain;
2257
2309
  var init_domain_lifecycle = __esm({
2258
2310
  "../dsl/src/framework/domain_lifecycle.ts"() {
2259
2311
  "use strict";
@@ -2261,6 +2313,7 @@ var init_domain_lifecycle = __esm({
2261
2313
  init_drivers();
2262
2314
  init_fields();
2263
2315
  init_directive();
2316
+ init_evolution();
2264
2317
  init_ops();
2265
2318
  init_relation_schema();
2266
2319
  MODEL_LIFECYCLE_AUTHORITY = relationRef("installDomain");
@@ -2309,6 +2362,30 @@ var init_domain_lifecycle = __esm({
2309
2362
  acceptedBy: attributionField(t.string().merge(Lww)),
2310
2363
  acceptedAt: t.int().merge(Lww)
2311
2364
  }).public();
2365
+ counterfactualReleaseReceipt = formerAggregate(RELEASE_RECEIPT_AGGREGATE, [
2366
+ "baselineRoot",
2367
+ "candidateIntents",
2368
+ "candidateRoot",
2369
+ "complete",
2370
+ "divergenceCount",
2371
+ "historyHash",
2372
+ "projectionEqual",
2373
+ "rawPromotable",
2374
+ "replayedIntents",
2375
+ "reportHash",
2376
+ "reportJson"
2377
+ ]);
2378
+ baselineRootRetired = retirement(counterfactualReleaseReceipt.fields.baselineRoot);
2379
+ candidateIntentsRetired = retirement(counterfactualReleaseReceipt.fields.candidateIntents);
2380
+ candidateRootRetired = retirement(counterfactualReleaseReceipt.fields.candidateRoot);
2381
+ completeRetired = retirement(counterfactualReleaseReceipt.fields.complete);
2382
+ divergenceCountRetired = retirement(counterfactualReleaseReceipt.fields.divergenceCount);
2383
+ historyHashRetired = retirement(counterfactualReleaseReceipt.fields.historyHash);
2384
+ projectionEqualRetired = retirement(counterfactualReleaseReceipt.fields.projectionEqual);
2385
+ rawPromotableRetired = retirement(counterfactualReleaseReceipt.fields.rawPromotable);
2386
+ replayedIntentsRetired = retirement(counterfactualReleaseReceipt.fields.replayedIntents);
2387
+ reportHashRetired = retirement(counterfactualReleaseReceipt.fields.reportHash);
2388
+ reportJsonRetired = retirement(counterfactualReleaseReceipt.fields.reportJson);
2312
2389
  dispositions = z4.object({
2313
2390
  retired: z4.array(z4.string()).optional(),
2314
2391
  retyped: z4.record(z4.string(), z4.string()).optional(),
@@ -2943,15 +3020,15 @@ var init_git_fs = __esm({
2943
3020
  });
2944
3021
 
2945
3022
  // ../cloud/web-client/src/_adapter/tree.ts
2946
- function flatten(dir, prefix, out14) {
3023
+ function flatten(dir, prefix, out15) {
2947
3024
  const children2 = [...(dir.contents ?? /* @__PURE__ */ new Map()).entries()].sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0);
2948
3025
  for (const [name, inode] of children2) {
2949
3026
  const path2 = prefix ? prefix + "/" + name : name;
2950
3027
  if (inode.contents instanceof Map) {
2951
- out14.push({ path: path2, dir: true });
2952
- flatten(inode, path2, out14);
3028
+ out15.push({ path: path2, dir: true });
3029
+ flatten(inode, path2, out15);
2953
3030
  } else {
2954
- out14.push({ path: path2, dir: false, bytes: inode.data ?? new Uint8Array(0) });
3031
+ out15.push({ path: path2, dir: false, bytes: inode.data ?? new Uint8Array(0) });
2955
3032
  }
2956
3033
  }
2957
3034
  }
@@ -2974,13 +3051,13 @@ function serializeTree(workTree) {
2974
3051
  }
2975
3052
  let total = 0;
2976
3053
  for (const c of chunks) total += c.length;
2977
- const out14 = new Uint8Array(total);
3054
+ const out15 = new Uint8Array(total);
2978
3055
  let off = 0;
2979
3056
  for (const c of chunks) {
2980
- out14.set(c, off);
3057
+ out15.set(c, off);
2981
3058
  off += c.length;
2982
3059
  }
2983
- return out14;
3060
+ return out15;
2984
3061
  }
2985
3062
  function deserializeTree(bytes, { File: File4, Directory: Directory4 }) {
2986
3063
  const u8 = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
@@ -3965,13 +4042,13 @@ var init_offer_args = __esm({
3965
4042
  function concatBytes(chunks) {
3966
4043
  let n = 0;
3967
4044
  for (const c of chunks) n += c.length;
3968
- const out14 = new Uint8Array(n);
4045
+ const out15 = new Uint8Array(n);
3969
4046
  let o = 0;
3970
4047
  for (const c of chunks) {
3971
- out14.set(c, o);
4048
+ out15.set(c, o);
3972
4049
  o += c.length;
3973
4050
  }
3974
- return out14;
4051
+ return out15;
3975
4052
  }
3976
4053
  function pkt(payload) {
3977
4054
  const body = typeof payload === "string" ? enc3.encode(payload) : payload;
@@ -4300,7 +4377,7 @@ function compatible(client, workspace) {
4300
4377
  return { ok: missing.length === 0 && incompatible.length === 0, missing, incompatible };
4301
4378
  }
4302
4379
  function memberVerdicts(client, workspace) {
4303
- const out14 = {};
4380
+ const out15 = {};
4304
4381
  const cDirs = client && client.directives || {};
4305
4382
  const wDirs = workspace && workspace.directives || {};
4306
4383
  const cAggs = client && client.aggregates || {};
@@ -4308,7 +4385,7 @@ function memberVerdicts(client, workspace) {
4308
4385
  for (const [did, cShape] of Object.entries(cDirs)) {
4309
4386
  const wShape = wDirs[did];
4310
4387
  if (!wShape) {
4311
- out14[did] = { ok: false, reason: `directive '${did}' is not installed on the workspace` };
4388
+ out15[did] = { ok: false, reason: `directive '${did}' is not installed on the workspace` };
4312
4389
  continue;
4313
4390
  }
4314
4391
  const cf = cShape.fields || {};
@@ -4323,13 +4400,13 @@ function memberVerdicts(client, workspace) {
4323
4400
  const w = wf[f];
4324
4401
  if (w && w.kind !== c.kind) reasons.push(`field '${f}' kind ${c.kind} \u2260 workspace ${w.kind}`);
4325
4402
  }
4326
- out14[did] = reasons.length ? { ok: false, reason: reasons.join("; ") } : { ok: true };
4403
+ out15[did] = reasons.length ? { ok: false, reason: reasons.join("; ") } : { ok: true };
4327
4404
  }
4328
4405
  for (const [sid, cAgg] of Object.entries(cAggs)) {
4329
4406
  const label = cAgg.label || sid;
4330
4407
  const wAgg = wAggs[sid];
4331
4408
  if (!wAgg) {
4332
- out14[label] = { ok: false, reason: `aggregate '${label}' is not served by the workspace` };
4409
+ out15[label] = { ok: false, reason: `aggregate '${label}' is not served by the workspace` };
4333
4410
  continue;
4334
4411
  }
4335
4412
  const cFields = cAgg.fields || {};
@@ -4340,9 +4417,9 @@ function memberVerdicts(client, workspace) {
4340
4417
  if (!w) reasons.push(`field '${label}.${c.label || fsid}' is not served`);
4341
4418
  else if (w.kind !== c.kind) reasons.push(`field '${label}.${c.label || fsid}' read kind ${c.kind} \u2260 workspace ${w.kind}`);
4342
4419
  }
4343
- out14[label] = reasons.length ? { ok: false, reason: reasons.join("; ") } : { ok: true };
4420
+ out15[label] = reasons.length ? { ok: false, reason: reasons.join("; ") } : { ok: true };
4344
4421
  }
4345
- return out14;
4422
+ return out15;
4346
4423
  }
4347
4424
  function interfaceDomains(byDomain) {
4348
4425
  const map = byDomain && typeof byDomain === "object" ? byDomain : {};
@@ -4352,17 +4429,17 @@ function interfaceDomains(byDomain) {
4352
4429
  );
4353
4430
  }
4354
4431
  function mergeDomainInterfaces(byDomain, onlyDomains) {
4355
- const out14 = { directives: {}, aggregates: {} };
4432
+ const out15 = { directives: {}, aggregates: {} };
4356
4433
  const map = byDomain && typeof byDomain === "object" ? byDomain : {};
4357
4434
  const entries = map.directives ? [[String(map.domain ?? "?"), map]] : Object.entries(map);
4358
4435
  for (const [domain, value] of entries) {
4359
4436
  if (onlyDomains !== void 0 && !onlyDomains.has(domain)) continue;
4360
4437
  if (!value || typeof value !== "object") continue;
4361
4438
  const di = value;
4362
- Object.assign(out14.directives, di.directives || {});
4363
- Object.assign(out14.aggregates, di.aggregates || {});
4439
+ Object.assign(out15.directives, di.directives || {});
4440
+ Object.assign(out15.aggregates, di.aggregates || {});
4364
4441
  }
4365
- return out14;
4442
+ return out15;
4366
4443
  }
4367
4444
  var init_shape_compat = __esm({
4368
4445
  "../cloud/web-client/src/shape_compat.ts"() {
@@ -5780,13 +5857,13 @@ async function actorForShareQuote(quote) {
5780
5857
  function osEntropyBuffer(n) {
5781
5858
  const bytes = new Uint8Array(n * 8);
5782
5859
  crypto.getRandomValues(bytes);
5783
- const out14 = new Array(n), T = 2 ** 53;
5860
+ const out15 = new Array(n), T = 2 ** 53;
5784
5861
  for (let i = 0; i < n; i++) {
5785
5862
  let z6 = 0n;
5786
5863
  for (let b = 7; b >= 0; b--) z6 = z6 << 8n | BigInt(bytes[i * 8 + b]);
5787
- out14[i] = Number(z6 >> 11n) / T;
5864
+ out15[i] = Number(z6 >> 11n) / T;
5788
5865
  }
5789
- return out14;
5866
+ return out15;
5790
5867
  }
5791
5868
  async function replicaIdFromValue(str) {
5792
5869
  const b = new Uint8Array(await crypto.subtle.digest("SHA-256", enc4.encode(str)));
@@ -5798,14 +5875,14 @@ async function routeTagHexOfHomeKey(homeKey) {
5798
5875
  return (await sha256hex(`nomos-route:${homeKey}`)).slice(0, 12);
5799
5876
  }
5800
5877
  function installedLawOfRows(rows) {
5801
- const out14 = [];
5878
+ const out15 = [];
5802
5879
  for (const r of rows || []) {
5803
5880
  const d = r && r.data;
5804
5881
  if (!d || d["status.phase"] !== "Active") continue;
5805
5882
  const h = d["spec.domainHash"];
5806
- if (typeof h === "string" && h && !out14.includes(h)) out14.push(h);
5883
+ if (typeof h === "string" && h && !out15.includes(h)) out15.push(h);
5807
5884
  }
5808
- return out14;
5885
+ return out15;
5809
5886
  }
5810
5887
  function lawStatusOf(installed, clientHash) {
5811
5888
  const known = Array.isArray(installed);
@@ -5830,14 +5907,14 @@ function birthOutcomeFailure(birthOutcomes) {
5830
5907
  const first = bad[0];
5831
5908
  const list = bad.map((o) => `${o.workspace || "?"} [${o.status}${o.code ? `: ${o.code}` : ""}]${o.reason ? ` \u2014 ${o.reason}` : ""}`).join("; ");
5832
5909
  const lawUnavailable = bad.some((o) => o.code === "BirthLawPackageUnavailable");
5833
- const err14 = new Error(
5910
+ const err15 = new Error(
5834
5911
  `birth incomplete: ${bad.length} child workspace(s) did NOT come up \u2014 ${list}. The parent offer admitted, but the child was not fully born, so opening it would poll head:null until timeout. ` + (lawUnavailable ? `The child's law package is not resolvable from the parent's custody \u2014 deploy it to the parent (POST /v2/workspaces/<parent>/domains) BEFORE birthing.` : `See the outcome's reason/code for the cause.`) + ` [birth-failed]`
5835
5912
  );
5836
- err14.code = first.code || "BirthFailed";
5837
- err14.status = first.status;
5838
- err14.failedBirths = bad;
5839
- err14.birthOutcomes = birthOutcomes;
5840
- return err14;
5913
+ err15.code = first.code || "BirthFailed";
5914
+ err15.status = first.status;
5915
+ err15.failedBirths = bad;
5916
+ err15.birthOutcomes = birthOutcomes;
5917
+ return err15;
5841
5918
  }
5842
5919
  function isColdFrameworkDescribe(spec) {
5843
5920
  if (!spec || typeof spec !== "object") return false;
@@ -6812,15 +6889,15 @@ ${String(commit).toLowerCase()}`;
6812
6889
  typeof principal === "string" && principal ? principal : typeof tokenSubject === "string" ? tokenSubject : ""
6813
6890
  );
6814
6891
  const readAuthFields = (keys, p) => {
6815
- const out14 = { nowUnix: Math.floor(Date.now() / 1e3) };
6892
+ const out15 = { nowUnix: Math.floor(Date.now() / 1e3) };
6816
6893
  const pr = typeof p === "string" && p ? p : connectionPrincipal;
6817
- if (pr) out14.principal = pr;
6894
+ if (pr) out15.principal = pr;
6818
6895
  if (activeAuthToken) {
6819
- out14.authToken = activeAuthToken;
6896
+ out15.authToken = activeAuthToken;
6820
6897
  }
6821
- if (deviceSecret) out14.authorSecret = deviceSecret;
6822
- if (Array.isArray(keys) && keys.length) out14.keys = keys;
6823
- return out14;
6898
+ if (deviceSecret) out15.authorSecret = deviceSecret;
6899
+ if (Array.isArray(keys) && keys.length) out15.keys = keys;
6900
+ return out15;
6824
6901
  };
6825
6902
  let clientLawHash;
6826
6903
  let warnedDrift = false;
@@ -7250,9 +7327,9 @@ ${String(commit).toLowerCase()}`;
7250
7327
  } catch {
7251
7328
  }
7252
7329
  const missingObject = (text.match(/\b[0-9a-f]{40}\b/) || [null])[0];
7253
- const err14 = new Error(text);
7254
- err14.code = code;
7255
- err14.errorInfo = {
7330
+ const err15 = new Error(text);
7331
+ err15.code = code;
7332
+ err15.errorInfo = {
7256
7333
  code,
7257
7334
  message: text,
7258
7335
  component: "nomos.custody",
@@ -7270,7 +7347,7 @@ ${String(commit).toLowerCase()}`;
7270
7347
  "nomos.custody.recommended_action": source === "localSnapshot" ? "quarantineLocalSnapshotAndReclone" : "refetchFullHistoryAndRetry"
7271
7348
  }
7272
7349
  };
7273
- return err14;
7350
+ return err15;
7274
7351
  };
7275
7352
  if (ckptBlobStr || ckptFrontierStr || ckptStagedFrontierFile || ckptCursor) {
7276
7353
  const _ckptSpan = span("receive", restoreFrom ? "boot: restore folded state (snapshot)" : "boot: restore checkpoint", "boot");
@@ -8897,13 +8974,13 @@ ${String(commit).toLowerCase()}`;
8897
8974
  if (!deviceSecret || !connectionPrincipal) {
8898
8975
  throw new Error("owned device recovery needs a signed-in session with its persisted device credential");
8899
8976
  }
8900
- const out14 = namedQueryTyped(QueryOperation.CRYPTO_OWNED_DEVICE_REQUEST, {
8977
+ const out15 = namedQueryTyped(QueryOperation.CRYPTO_OWNED_DEVICE_REQUEST, {
8901
8978
  authorSecret: deviceSecret,
8902
8979
  workspace,
8903
8980
  principal: connectionPrincipal,
8904
8981
  scope
8905
8982
  });
8906
- return String(out14.request || "");
8983
+ return String(out15.request || "");
8907
8984
  };
8908
8985
  const ownedRecoveryPolicyRaw = (owner) => ownedTupleData(ownedRecoveryPolicyId(owner));
8909
8986
  const ownedRecoveryOrdersRaw = async (recoveryPrincipal) => (await ownedQueryRows("nomosOwnedRecoveryOrdersByRecoveryPrincipal", { recoveryPrincipal })).map((row) => ({ id: String(row.id || ""), ...ownedRowData(row) }));
@@ -10239,11 +10316,11 @@ ${String(commit).toLowerCase()}`;
10239
10316
  await sleep(pollMs);
10240
10317
  }
10241
10318
  if (!sawDelegation) {
10242
- const err14 = new Error(
10319
+ const err15 = new Error(
10243
10320
  `receiving-group setup: parent '${parent}' still holds NO SignerDelegation for '${owner}' after ${pollTimeoutMs}ms. enrollFirstDevice seated the device SIGNER, but the home cert chain's links[1] (the platform-signed delegation) never surfaced \u2014 the birth would come up UNWARRANTED/headless (birth-cert-not-seeded). The enroll must record the keyless delegation (enrollFirstDevice.delegationCert) BEFORE birth. [ParentSignerDelegationMissing]`
10244
10321
  );
10245
- err14.code = "ParentSignerDelegationMissing";
10246
- throw err14;
10322
+ err15.code = "ParentSignerDelegationMissing";
10323
+ throw err15;
10247
10324
  }
10248
10325
  } finally {
10249
10326
  delegationSpan.end();
@@ -10476,10 +10553,10 @@ ${String(commit).toLowerCase()}`;
10476
10553
  const off = installedInterfaceInner();
10477
10554
  if (off === null && _lastInterfaceReadError) {
10478
10555
  const e = _lastInterfaceReadError;
10479
- const err14 = new Error(`projection read failed on workspace '${workspace}': ${e.message}`);
10480
- err14.code = "nomos.projection.read_failed";
10481
- err14.errorInfo = { code: "nomos.projection.read_failed", message: e.message, component: "nomos.projection", workspace, attributes: { "nomos.projection.workspace": workspace } };
10482
- throw err14;
10556
+ const err15 = new Error(`projection read failed on workspace '${workspace}': ${e.message}`);
10557
+ err15.code = "nomos.projection.read_failed";
10558
+ err15.errorInfo = { code: "nomos.projection.read_failed", message: e.message, component: "nomos.projection", workspace, attributes: { "nomos.projection.workspace": workspace } };
10559
+ throw err15;
10483
10560
  }
10484
10561
  return off;
10485
10562
  }),
@@ -11774,12 +11851,12 @@ function routedHolon(coordinator, { cloud, workspace, clientId, authToken, fetch
11774
11851
  }
11775
11852
  async function frontierMap() {
11776
11853
  const rows = await coordinator.query("aggregatesByType", { __type: "NomosSummaryFrontier" });
11777
- const out14 = {};
11854
+ const out15 = {};
11778
11855
  for (const r of rows || []) {
11779
11856
  const d = r.data || {};
11780
- if (typeof d.shard === "string" && typeof d.frontier === "string") out14[d.shard] = d.frontier;
11857
+ if (typeof d.shard === "string" && typeof d.frontier === "string") out15[d.shard] = d.frontier;
11781
11858
  }
11782
- return out14;
11859
+ return out15;
11783
11860
  }
11784
11861
  async function scopedValue(kind, readId, groupKey, opts = {}) {
11785
11862
  if (kind === "min" || kind === "max") {
@@ -12528,15 +12605,15 @@ var init_git_fs2 = __esm({
12528
12605
  });
12529
12606
 
12530
12607
  // vendor/engine/tree.ts
12531
- function flatten2(dir, prefix, out14) {
12608
+ function flatten2(dir, prefix, out15) {
12532
12609
  const children2 = [...(dir.contents ?? /* @__PURE__ */ new Map()).entries()].sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0);
12533
12610
  for (const [name, inode] of children2) {
12534
12611
  const path2 = prefix ? prefix + "/" + name : name;
12535
12612
  if (inode.contents instanceof Map) {
12536
- out14.push({ path: path2, dir: true });
12537
- flatten2(inode, path2, out14);
12613
+ out15.push({ path: path2, dir: true });
12614
+ flatten2(inode, path2, out15);
12538
12615
  } else {
12539
- out14.push({ path: path2, dir: false, bytes: inode.data ?? new Uint8Array(0) });
12616
+ out15.push({ path: path2, dir: false, bytes: inode.data ?? new Uint8Array(0) });
12540
12617
  }
12541
12618
  }
12542
12619
  }
@@ -12559,13 +12636,13 @@ function serializeTree2(workTree) {
12559
12636
  }
12560
12637
  let total = 0;
12561
12638
  for (const c of chunks) total += c.length;
12562
- const out14 = new Uint8Array(total);
12639
+ const out15 = new Uint8Array(total);
12563
12640
  let off = 0;
12564
12641
  for (const c of chunks) {
12565
- out14.set(c, off);
12642
+ out15.set(c, off);
12566
12643
  off += c.length;
12567
12644
  }
12568
- return out14;
12645
+ return out15;
12569
12646
  }
12570
12647
  var enc5, dec5;
12571
12648
  var init_tree2 = __esm({
@@ -12580,13 +12657,13 @@ var init_tree2 = __esm({
12580
12657
  function concatBytes2(chunks) {
12581
12658
  let n = 0;
12582
12659
  for (const c of chunks) n += c.length;
12583
- const out14 = new Uint8Array(n);
12660
+ const out15 = new Uint8Array(n);
12584
12661
  let o = 0;
12585
12662
  for (const c of chunks) {
12586
- out14.set(c, o);
12663
+ out15.set(c, o);
12587
12664
  o += c.length;
12588
12665
  }
12589
- return out14;
12666
+ return out15;
12590
12667
  }
12591
12668
  function pkt2(payload) {
12592
12669
  const body = typeof payload === "string" ? enc6.encode(payload) : payload;
@@ -13113,13 +13190,13 @@ async function sha256hex2(t2) {
13113
13190
  function osEntropyBuffer2(n) {
13114
13191
  const bytes = new Uint8Array(n * 8);
13115
13192
  for (let o = 0; o < bytes.length; o += 65536) crypto.getRandomValues(bytes.subarray(o, Math.min(o + 65536, bytes.length)));
13116
- const out14 = new Array(n), T = 2 ** 53;
13193
+ const out15 = new Array(n), T = 2 ** 53;
13117
13194
  for (let i = 0; i < n; i++) {
13118
13195
  let z6 = 0n;
13119
13196
  for (let b = 7; b >= 0; b--) z6 = z6 << 8n | BigInt(bytes[i * 8 + b]);
13120
- out14[i] = Number(z6 >> 11n) / T;
13197
+ out15[i] = Number(z6 >> 11n) / T;
13121
13198
  }
13122
- return out14;
13199
+ return out15;
13123
13200
  }
13124
13201
  function callProto(ex, operation, STDERR) {
13125
13202
  const requestId = `adapter-${++protoRequestSequence2}`;
@@ -13820,15 +13897,15 @@ function contribution(read, cur) {
13820
13897
  return { group, value: typeof raw === "number" ? raw : 0 };
13821
13898
  }
13822
13899
  function contributionDiff(read, before, after) {
13823
- const out14 = [];
13900
+ const out15 = [];
13824
13901
  if (before && after && before.group === after.group) {
13825
13902
  const d = after.value - before.value;
13826
- if (d !== 0) out14.push({ readId: read.id, group: after.group, delta: d });
13827
- return out14;
13903
+ if (d !== 0) out15.push({ readId: read.id, group: after.group, delta: d });
13904
+ return out15;
13828
13905
  }
13829
- if (before) out14.push({ readId: read.id, group: before.group, delta: -before.value });
13830
- if (after) out14.push({ readId: read.id, group: after.group, delta: after.value });
13831
- return out14.filter((d) => d.delta !== 0);
13906
+ if (before) out15.push({ readId: read.id, group: before.group, delta: -before.value });
13907
+ if (after) out15.push({ readId: read.id, group: after.group, delta: after.value });
13908
+ return out15.filter((d) => d.delta !== 0);
13832
13909
  }
13833
13910
  function countTenantRows(eng, ws) {
13834
13911
  let total = 0;
@@ -13841,16 +13918,16 @@ async function countTenantRowsByHome(eng, ws, homeKeys) {
13841
13918
  const keySet = new Set(homeKeys);
13842
13919
  const tagOf = /* @__PURE__ */ new Map();
13843
13920
  for (const hk of homeKeys) tagOf.set(await routeTagHexOfHomeKey2(hk), hk);
13844
- const out14 = /* @__PURE__ */ new Map();
13845
- for (const hk of homeKeys) out14.set(hk, 0);
13921
+ const out15 = /* @__PURE__ */ new Map();
13922
+ for (const hk of homeKeys) out15.set(hk, 0);
13846
13923
  for (const type of tenantTypes(eng)) {
13847
13924
  for (const r of query2(eng, ws, "aggregatesByType", JSON.stringify({ __type: type }))) {
13848
13925
  const id = String(r.id || "");
13849
13926
  const hk = keySet.has(id) ? id : tagOf.get(routeTagHexOfMintedId(id) ?? "");
13850
- if (hk !== void 0) out14.set(hk, (out14.get(hk) ?? 0) + 1);
13927
+ if (hk !== void 0) out15.set(hk, (out15.get(hk) ?? 0) + 1);
13851
13928
  }
13852
13929
  }
13853
- return out14;
13930
+ return out15;
13854
13931
  }
13855
13932
  async function collectHomedIntents(eng, ws, homeKeys) {
13856
13933
  const routes = directiveRoutes(eng);
@@ -13875,7 +13952,7 @@ async function collectHomedIntents(eng, ws, homeKeys) {
13875
13952
  strikeParity.set(target, (strikeParity.get(target) ?? 0) + 1);
13876
13953
  }
13877
13954
  }
13878
- const out14 = [];
13955
+ const out15 = [];
13879
13956
  for (const { oid, blob, doc } of docs) {
13880
13957
  const id = doc && typeof doc.id === "string" ? doc.id : null;
13881
13958
  if (!id || (strikeParity.get(id) ?? 0) % 2 === 1) continue;
@@ -13891,9 +13968,9 @@ async function collectHomedIntents(eng, ws, homeKeys) {
13891
13968
  const tag = routeTagHexOfMintedId(value);
13892
13969
  homeKey = tag !== void 0 ? tagOf.get(tag) ?? null : null;
13893
13970
  }
13894
- if (homeKey !== null) out14.push({ oid, id, homeKey, blob });
13971
+ if (homeKey !== null) out15.push({ oid, id, homeKey, blob });
13895
13972
  }
13896
- return out14;
13973
+ return out15;
13897
13974
  }
13898
13975
  async function migrateHomes(eng, ws, ledger, sourceWs, homeKeys, { onlyIds = null } = {}) {
13899
13976
  const wanted = onlyIds ? new Set(onlyIds) : null;
@@ -14002,7 +14079,7 @@ async function collectGlobalIntents(eng, ws) {
14002
14079
  strikeParity.set(target, (strikeParity.get(target) ?? 0) + 1);
14003
14080
  }
14004
14081
  }
14005
- const out14 = [];
14082
+ const out15 = [];
14006
14083
  for (const { oid, blob, doc } of docs) {
14007
14084
  const id = doc && typeof doc.id === "string" ? doc.id : null;
14008
14085
  let touches = false;
@@ -14013,9 +14090,9 @@ async function collectGlobalIntents(eng, ws) {
14013
14090
  if (t2 !== void 0 && globals.has(t2)) touches = true;
14014
14091
  }
14015
14092
  if (!touches || !id || (strikeParity.get(id) ?? 0) % 2 === 1) continue;
14016
- out14.push({ oid, id, blob });
14093
+ out15.push({ oid, id, blob });
14017
14094
  }
14018
- return out14;
14095
+ return out15;
14019
14096
  }
14020
14097
  async function replicateIntents(eng, ws, ledger, intents, { push = true } = {}) {
14021
14098
  const main2 = await mainIntentIds(eng, ws);
@@ -14481,8 +14558,8 @@ function stageLawClosure(eng, lawUsdz, label = "candidate-law") {
14481
14558
  }, "lawClosureInfo");
14482
14559
  }
14483
14560
  function currentLaw(eng, ws) {
14484
- const out14 = namedQueryProto(eng, ws, QueryOperation3.CURRENT_LAW);
14485
- return out14.keyMap || {};
14561
+ const out15 = namedQueryProto(eng, ws, QueryOperation3.CURRENT_LAW);
14562
+ return out15.keyMap || {};
14486
14563
  }
14487
14564
  function installedLaw(eng, ws) {
14488
14565
  return namedQueryProto(eng, ws, QueryOperation3.INSTALLED_LAW);
@@ -14511,8 +14588,8 @@ function kernelResource(eng, ws) {
14511
14588
  return response.outcome.value.result.value;
14512
14589
  }
14513
14590
  function declaredCapabilities(eng, ws) {
14514
- const out14 = namedQueryProto(eng, ws, QueryOperation3.DECLARED_CAPABILITIES);
14515
- return out14.capabilities || [];
14591
+ const out15 = namedQueryProto(eng, ws, QueryOperation3.DECLARED_CAPABILITIES);
14592
+ return out15.capabilities || [];
14516
14593
  }
14517
14594
  function outboundOffers(eng, ws, nowMillis = Date.now()) {
14518
14595
  const response = callProto(eng.ex, {
@@ -14553,8 +14630,8 @@ function evolveDryRun(eng, ws, lawUsdz, domainHash, dispositions2 = null) {
14553
14630
  return r.ok ? { admits: true } : { admits: false, detail: r.error };
14554
14631
  }
14555
14632
  function mintId(eng, typeTag) {
14556
- const out14 = namedQueryProto(eng, "root", QueryOperation3.MINT, { typeTag, nowMillis: Date.now() });
14557
- return out14.id;
14633
+ const out15 = namedQueryProto(eng, "root", QueryOperation3.MINT, { typeTag, nowMillis: Date.now() });
14634
+ return out15.id;
14558
14635
  }
14559
14636
  function author(eng, ws, domain, directiveId, payload, controllerHash, opts = {}) {
14560
14637
  const seq = eng.seq++;
@@ -14779,13 +14856,13 @@ async function streamAll(stream) {
14779
14856
  }
14780
14857
  let len = 0;
14781
14858
  for (const c of chunks) len += c.length;
14782
- const out14 = new Uint8Array(len);
14859
+ const out15 = new Uint8Array(len);
14783
14860
  let at = 0;
14784
14861
  for (const c of chunks) {
14785
- out14.set(c, at);
14862
+ out15.set(c, at);
14786
14863
  at += c.length;
14787
14864
  }
14788
- return out14;
14865
+ return out15;
14789
14866
  }
14790
14867
  async function gzip(bytes) {
14791
14868
  const cs = new CompressionStream("gzip");
@@ -16117,7 +16194,7 @@ async function writeRefusedRef(eng, ws, dl) {
16117
16194
  async function listRefusedRefs(eng, ws) {
16118
16195
  const gitdir = gitdirOf(ws);
16119
16196
  const refs = kgit.listRefs(eng, gitdir, "refs/heads/refused/");
16120
- const out14 = [];
16197
+ const out15 = [];
16121
16198
  for (const { ref, oid } of refs) {
16122
16199
  try {
16123
16200
  const vb = kgit.readBlob(eng, gitdir, oid, "verdict.usda") ?? new Uint8Array();
@@ -16129,7 +16206,7 @@ async function listRefusedRefs(eng, ws) {
16129
16206
  law = null;
16130
16207
  }
16131
16208
  const v = kgit.inspectRefusalVerdict(eng, vb);
16132
- out14.push({
16209
+ out15.push({
16133
16210
  ref,
16134
16211
  ...v,
16135
16212
  verdict: { reason: v.reason },
@@ -16139,7 +16216,7 @@ async function listRefusedRefs(eng, ws) {
16139
16216
  } catch {
16140
16217
  }
16141
16218
  }
16142
- return out14;
16219
+ return out15;
16143
16220
  }
16144
16221
  async function refusedSummary(eng, ws) {
16145
16222
  const gitdir = gitdirOf(ws);
@@ -16278,9 +16355,9 @@ async function ledgerStats(eng, ws, ledger = null) {
16278
16355
  const mounted = eng.mounted.get(ws);
16279
16356
  if (mounted && mounted.ledgerStats?.head === head) return mounted.ledgerStats;
16280
16357
  const commits = kgit.intentsAbove(eng, gitdir, head).length;
16281
- const out14 = { head, commits };
16282
- if (mounted) mounted.ledgerStats = out14;
16283
- return out14;
16358
+ const out15 = { head, commits };
16359
+ if (mounted) mounted.ledgerStats = out15;
16360
+ return out15;
16284
16361
  }
16285
16362
  async function countRemoteCommits(eng, ledger) {
16286
16363
  const head = (await custodyLsRefs(ledger, "refs/heads/main"))["refs/heads/main"] || null;
@@ -17277,6 +17354,7 @@ __export(governance_exports, {
17277
17354
  ROOT_CUSTODIAN_SECRET: () => ROOT_CUSTODIAN_SECRET,
17278
17355
  STAGE_THRESHOLD_CHARS: () => STAGE_THRESHOLD_CHARS,
17279
17356
  adoptRootModelLifecycle: () => adoptRootModelLifecycle,
17357
+ adoptWorkspaceModel: () => adoptWorkspaceModel,
17280
17358
  buildCertificate: () => buildCertificate,
17281
17359
  buildRebirthPlan: () => buildRebirthPlan,
17282
17360
  canonicalPrincipal: () => canonicalPrincipal2,
@@ -17472,6 +17550,41 @@ async function adoptRootModelLifecycle(candidateHash, opts, acceptance) {
17472
17550
  const ok = sync.pushFailed !== true && sync.offline !== true && admission?.ok === true && rejected.length === 0;
17473
17551
  return { ok, adoption, sync };
17474
17552
  }
17553
+ async function adoptWorkspaceModel(workspace, domain, candidateHash, opts, acceptance) {
17554
+ const cloud = cloudBase(opts.cloud);
17555
+ const principal = resolveGovernancePrincipal(opts);
17556
+ const device = getDeviceKey(principal);
17557
+ if (device === void 0) {
17558
+ throw new Error(
17559
+ `no signing device is stored for '${principal}' \u2014 use githolon key import/enroll before adopting a model`
17560
+ );
17561
+ }
17562
+ const connect2 = await clientConnect();
17563
+ const holon = await connect2({
17564
+ cloud,
17565
+ workspace,
17566
+ clientId: `githolon-model-adopt-${Date.now().toString(16)}`,
17567
+ principal: canonicalPrincipal2(principal),
17568
+ authorSecret: device.secret
17569
+ });
17570
+ try {
17571
+ if (typeof holon.__nomosAdoptModel !== "function") {
17572
+ throw new Error("the installed @githolon/client has no typed model-adoption surface");
17573
+ }
17574
+ const adoption = await holon.__nomosAdoptModel(domain, candidateHash, acceptance);
17575
+ if (adoption.ok !== true) return { ok: false, adoption };
17576
+ if (typeof holon.sync !== "function") {
17577
+ throw new Error("the installed @githolon/client cannot synchronize the adopted model");
17578
+ }
17579
+ const sync = await holon.sync({ admit: true, discoverRemote: true });
17580
+ const admission = sync.admission;
17581
+ const rejected = (admission?.sessions ?? []).flatMap((session) => session.rejected ?? []);
17582
+ const ok = sync.pushFailed !== true && sync.offline !== true && admission?.ok === true && rejected.length === 0;
17583
+ return { ok, adoption, sync };
17584
+ } finally {
17585
+ holon._dispose?.();
17586
+ }
17587
+ }
17475
17588
  async function signAndPostPreparedOffer(ws, domain, prepare, opts, authorMode = "account", preferActor, lawUsdz, birthCertificate, explicitAuthority) {
17476
17589
  const cloud = cloudBase(opts.cloud);
17477
17590
  const principal = explicitAuthority?.actor ?? resolveGovernancePrincipal(opts);
@@ -20218,7 +20331,7 @@ async function deployPackage(ws, opts, file, placement) {
20218
20331
  (installed) => installed.domainHash === targetHash && installed.phase === "Pending" /* Pending */
20219
20332
  )) {
20220
20333
  out4(`\u2713 ${fileName} is already staged on ${ws} (${targetHash.slice(0, 16)}\u2026 pending)`);
20221
- out4(" the generated application client owns review and adoption; no second offer was submitted");
20334
+ out4(" the model lifecycle owns review and adoption; no second offer was submitted");
20222
20335
  return 0;
20223
20336
  }
20224
20337
  if ((plan?.predecessorCandidates.length ?? 0) > 1) {
@@ -20284,7 +20397,7 @@ async function deployPackage(ws, opts, file, placement) {
20284
20397
  out4(`\u2713 staged ${fileName} \u2192 ${ws} (pending)`);
20285
20398
  if (plan?.supersedes) out4(` current model ${plan.supersedes.slice(0, 16)}\u2026 keeps serving`);
20286
20399
  out4(` candidate ${deployedHash.slice(0, 16)}\u2026 is in custody but cannot serve yet`);
20287
- out4(` next: use the candidate generated client and call model.adopt()`);
20400
+ out4(` next: githolon model adopt ${ws} --domain <candidate-home-domain> --file ${file}`);
20288
20401
  return 0;
20289
20402
  }
20290
20403
  if (deployedHash !== void 0 && isCurrent) {
@@ -21160,22 +21273,22 @@ async function doctor(opts = {}) {
21160
21273
  const cloud = cloudBase(opts.cloud);
21161
21274
  const localLaw = await readLocalLaw(process.cwd(), cloud, opts.file);
21162
21275
  const report = await probeKernelCapabilities(cloud);
21163
- const out14 = [];
21164
- out14.push(`githolon doctor \u2014 release coherence`);
21165
- out14.push(` cloud : ${cloud}`);
21166
- out14.push(` local law : ${localLaw ? `${localLaw.identity.slice(0, 16)}\u2026 (${localLaw.domains.join(", ") || "no domains"})` : "(not admitted \u2014 run `githolon compile` or inspect the error with `githolon deploy`)"}`);
21167
- out14.push(stampLine("prod kernel", report?.prod));
21168
- out14.push(stampLine("test kernel", report?.testmint));
21276
+ const out15 = [];
21277
+ out15.push(`githolon doctor \u2014 release coherence`);
21278
+ out15.push(` cloud : ${cloud}`);
21279
+ out15.push(` local law : ${localLaw ? `${localLaw.identity.slice(0, 16)}\u2026 (${localLaw.domains.join(", ") || "no domains"})` : "(not admitted \u2014 run `githolon compile` or inspect the error with `githolon deploy`)"}`);
21280
+ out15.push(stampLine("prod kernel", report?.prod));
21281
+ out15.push(stampLine("test kernel", report?.testmint));
21169
21282
  if (!localLaw) {
21170
- out14.push(``);
21171
- out14.push(` \u26A0 no local build found \u2014 cannot check the law\u2194kernel fit. Run \`githolon compile\` first.`);
21172
- process.stdout.write(out14.join("\n") + "\n");
21283
+ out15.push(``);
21284
+ out15.push(` \u26A0 no local build found \u2014 cannot check the law\u2194kernel fit. Run \`githolon compile\` first.`);
21285
+ process.stdout.write(out15.join("\n") + "\n");
21173
21286
  return report ? 0 : 1;
21174
21287
  }
21175
- out14.push(``);
21176
- out14.push(` \u2713 ARCHIVE COHERENT \u2014 the selected kernel admitted and composed ${localLaw.identity.slice(0, 16)}\u2026 directly from typed USDA.`);
21177
- out14.push(` Full schema/projection compatibility is enforced again by the ordinary install offer.`);
21178
- process.stdout.write(out14.join("\n") + "\n");
21288
+ out15.push(``);
21289
+ out15.push(` \u2713 ARCHIVE COHERENT \u2014 the selected kernel admitted and composed ${localLaw.identity.slice(0, 16)}\u2026 directly from typed USDA.`);
21290
+ out15.push(` Full schema/projection compatibility is enforced again by the ordinary install offer.`);
21291
+ process.stdout.write(out15.join("\n") + "\n");
21179
21292
  return 0;
21180
21293
  }
21181
21294
  var init_doctor = __esm({
@@ -21604,11 +21717,11 @@ function bareTypeLabel(t2) {
21604
21717
  return i > 0 && i < t2.length - 1 ? t2.slice(i + 1) : t2;
21605
21718
  }
21606
21719
  function geoFieldsOfInstalls(installs) {
21607
- const out14 = /* @__PURE__ */ new Map();
21720
+ const out15 = /* @__PURE__ */ new Map();
21608
21721
  const add2 = (type, field) => {
21609
- const set2 = out14.get(type) ?? /* @__PURE__ */ new Set();
21722
+ const set2 = out15.get(type) ?? /* @__PURE__ */ new Set();
21610
21723
  set2.add(field);
21611
- out14.set(type, set2);
21724
+ out15.set(type, set2);
21612
21725
  };
21613
21726
  for (const inst of installs) {
21614
21727
  for (const layer of inst.layers) {
@@ -21624,7 +21737,7 @@ function geoFieldsOfInstalls(installs) {
21624
21737
  }
21625
21738
  }
21626
21739
  }
21627
- return out14;
21740
+ return out15;
21628
21741
  }
21629
21742
  function pointOfOpValue(setOp) {
21630
21743
  let v = setOp["Json"];
@@ -22376,6 +22489,126 @@ var init_scene = __esm({
22376
22489
  }
22377
22490
  });
22378
22491
 
22492
+ // src/model.ts
22493
+ var model_exports = {};
22494
+ __export(model_exports, {
22495
+ modelAdopt: () => modelAdopt
22496
+ });
22497
+ function domainInventory(value) {
22498
+ if (typeof value !== "object" || value === null) throw new Error("domain inventory is not an object");
22499
+ const row = value;
22500
+ if (row.ok !== true || !Array.isArray(row.domains) || typeof row.currentLaw !== "object" || row.currentLaw === null) {
22501
+ throw new Error("domain inventory has no typed lifecycle projection");
22502
+ }
22503
+ const domains = row.domains.map((candidate) => {
22504
+ if (typeof candidate !== "object" || candidate === null) throw new Error("domain inventory contains a non-record installation");
22505
+ const install = candidate;
22506
+ if (typeof install.domainHash !== "string" || typeof install.phase !== "string" || !Array.isArray(install.domainKeys) || !install.domainKeys.every((key2) => typeof key2 === "string")) {
22507
+ throw new Error("domain inventory contains an invalid installation record");
22508
+ }
22509
+ return { domainHash: install.domainHash, phase: install.phase, domainKeys: install.domainKeys };
22510
+ });
22511
+ const currentLaw2 = Object.fromEntries(Object.entries(row.currentLaw).map(([key2, hash]) => {
22512
+ if (typeof hash !== "string") throw new Error(`domain inventory has a non-string current law for '${key2}'`);
22513
+ return [key2, hash];
22514
+ }));
22515
+ return { ok: true, domains, currentLaw: currentLaw2 };
22516
+ }
22517
+ async function modelAdopt(workspace, opts) {
22518
+ const cloud = cloudBase(opts.cloud);
22519
+ let file;
22520
+ let identity;
22521
+ let domainKeys;
22522
+ try {
22523
+ file = discoverLawUsdz(process.cwd(), opts.file);
22524
+ const { eng } = await holonEngine(cloud, "githolon-model-adopt-inspect");
22525
+ const inspected = inspectLawArchive(eng, file);
22526
+ identity = inspected.identity;
22527
+ domainKeys = inspected.domainKeys;
22528
+ } catch (cause) {
22529
+ err13(`could not derive the candidate from typed USDA: ${cause.message}`);
22530
+ return 1;
22531
+ }
22532
+ if (!domainKeys.includes(opts.domain)) {
22533
+ err13(`candidate ${identity.slice(0, 16)}\u2026 does not contain domain '${opts.domain}' (${domainKeys.join(", ")})`);
22534
+ return 1;
22535
+ }
22536
+ out13(`candidate ${identity} (kernel-derived from ${file})`);
22537
+ out13(`workspace ${workspace} on ${cloud}`);
22538
+ out13(`domain ${opts.domain}`);
22539
+ const startedAt = Date.now();
22540
+ const heartbeat = setInterval(() => {
22541
+ const elapsed = Math.round((Date.now() - startedAt) / 1e3);
22542
+ out13(` ${elapsed}s \u2014 verifying current history and preparing the signed lifecycle decision\u2026`);
22543
+ }, 5e3);
22544
+ heartbeat.unref();
22545
+ try {
22546
+ const result = await adoptWorkspaceModel(
22547
+ workspace,
22548
+ opts.domain,
22549
+ sha256Digest().parse(identity),
22550
+ opts,
22551
+ opts.because === void 0 ? void 0 : { because: opts.because }
22552
+ );
22553
+ if (!result.ok) {
22554
+ const stage = typeof result.adoption.stage === "string" ? result.adoption.stage : "refused";
22555
+ const message = typeof result.adoption.error === "string" ? result.adoption.error : "the candidate remained unchanged";
22556
+ err13(`model adoption ${stage}: ${message}`);
22557
+ const report = result.adoption.report;
22558
+ if (typeof report === "object" && report !== null) {
22559
+ const r = report;
22560
+ out13(` history replayed=${String(r.replayedIntents ?? "?")} candidate=${String(r.candidateIntents ?? "?")}`);
22561
+ out13(` evidence sourceVerified=${String(r.sourceVerified ?? "?")} complete=${String(r.complete ?? "?")}`);
22562
+ }
22563
+ if (stage === "acceptance" && opts.because === void 0) {
22564
+ out13(" next: review the reported divergence, then repeat with --because <accountable business reason>");
22565
+ }
22566
+ return 2;
22567
+ }
22568
+ let inventory;
22569
+ const deadline = Date.now() + 3e4;
22570
+ do {
22571
+ const response = await fetch(`${cloud}/v2/workspaces/${encodeURIComponent(workspace)}/domains`);
22572
+ if (!response.ok) throw new Error(`domain inventory returned ${response.status}`);
22573
+ const observed = domainInventory(await response.json());
22574
+ const candidate2 = observed.domains.find((installed) => installed.domainHash === identity);
22575
+ const keys2 = candidate2?.domainKeys ?? domainKeys;
22576
+ if (candidate2?.phase === "Active" && keys2.every((key2) => observed.currentLaw[key2] === identity)) {
22577
+ inventory = observed;
22578
+ break;
22579
+ }
22580
+ await new Promise((resolve8) => setTimeout(resolve8, 250));
22581
+ } while (Date.now() < deadline);
22582
+ if (inventory === void 0) throw new Error("the active-law projection did not converge within 30 seconds");
22583
+ const candidate = inventory.domains.find((installed) => installed.domainHash === identity);
22584
+ const keys = candidate?.domainKeys ?? domainKeys;
22585
+ const drift = keys.filter((key2) => inventory.currentLaw[key2] !== identity);
22586
+ if (candidate?.phase !== "Active" || drift.length > 0) {
22587
+ err13(`adoption synced but ${identity} is not current for ${drift.join(", ") || "its declared domain keys"}`);
22588
+ return 1;
22589
+ }
22590
+ out13(`\u2713 adopted ${identity} across ${keys.length} domain key${keys.length === 1 ? "" : "s"} in ${Date.now() - startedAt} ms`);
22591
+ return 0;
22592
+ } catch (cause) {
22593
+ err13(cause.message);
22594
+ return 1;
22595
+ } finally {
22596
+ clearInterval(heartbeat);
22597
+ }
22598
+ }
22599
+ var out13, err13;
22600
+ var init_model = __esm({
22601
+ "src/model.ts"() {
22602
+ "use strict";
22603
+ init_src();
22604
+ init_cloud();
22605
+ init_governance();
22606
+ init_local_holon();
22607
+ out13 = (line) => void process.stdout.write(line + "\n");
22608
+ err13 = (line) => void process.stderr.write("error: " + line + "\n");
22609
+ }
22610
+ });
22611
+
22379
22612
  // src/dlq.ts
22380
22613
  var dlq_exports = {};
22381
22614
  __export(dlq_exports, {
@@ -22405,33 +22638,33 @@ async function dlqSweep(ws, opts = {}) {
22405
22638
  const res = await fetch(url);
22406
22639
  body = await res.json();
22407
22640
  if (body.ok !== true || body.root === void 0) {
22408
- err13(`dlq sweep refused: ${String(body.error ?? "no sweep in the response").slice(0, 300)}`);
22641
+ err14(`dlq sweep refused: ${String(body.error ?? "no sweep in the response").slice(0, 300)}`);
22409
22642
  return 1;
22410
22643
  }
22411
22644
  } catch (e) {
22412
- err13(`dlq sweep failed against ${cloud}: ${e.message}`);
22645
+ err14(`dlq sweep failed against ${cloud}: ${e.message}`);
22413
22646
  return 1;
22414
22647
  }
22415
22648
  if (opts.json === true) {
22416
- out13(JSON.stringify(body, null, 2));
22649
+ out14(JSON.stringify(body, null, 2));
22417
22650
  return body.jammed ? 2 : 0;
22418
22651
  }
22419
- out13(`DLQ sweep of '${ws}' \u2014 ${body.nodes} node(s), ${body.jammed} jammed`);
22420
- for (const line of renderSweepNode(body.root)) out13(line);
22652
+ out14(`DLQ sweep of '${ws}' \u2014 ${body.nodes} node(s), ${body.jammed} jammed`);
22653
+ for (const line of renderSweepNode(body.root)) out14(line);
22421
22654
  if (body.jammed) {
22422
- out13("");
22423
- out13("unjam: fix/deploy the law on the jammed workspace, then POST /v2/workspaces/<node>/dead-letters/retry");
22424
- out13(" (or from the app: holon.retryDeadLetter(id); discard is the app's explicit choice)");
22655
+ out14("");
22656
+ out14("unjam: fix/deploy the law on the jammed workspace, then POST /v2/workspaces/<node>/dead-letters/retry");
22657
+ out14(" (or from the app: holon.retryDeadLetter(id); discard is the app's explicit choice)");
22425
22658
  }
22426
22659
  return body.jammed ? 2 : 0;
22427
22660
  }
22428
- var out13, err13;
22661
+ var out14, err14;
22429
22662
  var init_dlq = __esm({
22430
22663
  "src/dlq.ts"() {
22431
22664
  "use strict";
22432
22665
  init_cloud();
22433
- out13 = (s) => void process.stdout.write(s + "\n");
22434
- err13 = (s) => void process.stderr.write("error: " + s + "\n");
22666
+ out14 = (s) => void process.stdout.write(s + "\n");
22667
+ err14 = (s) => void process.stderr.write("error: " + s + "\n");
22435
22668
  }
22436
22669
  });
22437
22670
 
@@ -25221,7 +25454,7 @@ var HELP = {
25221
25454
  },
25222
25455
  deploy: {
25223
25456
  usage: "githolon deploy [<ws>] [--as <uid>] [--parent <ws>] [--file <application.usda|law.usdz>] [--cloud <url>] [--target <name>]\n provider handover: --auth-provider-issuer <url> --auth-provider-jwks-file <path> --auth-provider-jwks-url <url> --auth-provider-audience <aud> --auth-provider-principal-claim <claim> --auth-provider-device-binding-claim <claim>",
25224
- what: "Deploy the compiled application from its OpenUSD composition. Reference-only packages serve on\nthe application workspace; payload packages are staged for child birth and never made current there.\nFor a one-package project, the compiled law archive is the shorthand. There is one model lifecycle:\nthe first serving model becomes active; a successor stays Pending while the current model keeps serving,\nand the generated candidate client owns exact-history adoption. Re-deploying the same content hash is\nidempotent. With no <ws>, the project's workspace binding resolves it.",
25457
+ what: "Deploy the compiled application from its OpenUSD composition. Reference-only packages serve on\nthe application workspace; payload packages are staged for child birth and never made current there.\nFor a one-package project, the compiled law archive is the shorthand. There is one model lifecycle:\nthe first serving model becomes active; a successor stays Pending while the current model keeps serving,\nand exact-history adoption is driven by the generated client or `githolon model adopt`. Re-deploying the\nsame content hash is idempotent. With no <ws>, the project's workspace binding resolves it.",
25225
25458
  flags: [
25226
25459
  ["--as <uid>", "attribute the deployment to this principal (needs its enrolled signing key)"],
25227
25460
  ["--parent <ws>", "birth an unborn application directly below this parent; existing lineage must match"],
@@ -25239,6 +25472,18 @@ var HELP = {
25239
25472
  ],
25240
25473
  examples: ["githolon deploy", "githolon deploy my-guestbook", "githolon deploy co2-platform --as <admin-uid>"]
25241
25474
  },
25475
+ model: {
25476
+ usage: "githolon model adopt [<workspace>] --domain <domain> [--file <law.usdz>] [--because <reason>] [--as <uid>] [--cloud <url>]",
25477
+ what: "Adopt one already-staged application model. The kernel derives the candidate identity directly\nfrom the compiled OpenUSD closure, replays current history under the lifecycle gate, and the selected\nworkspace principal signs the resulting decision. Nothing is promoted when proof or synchronization fails.",
25478
+ flags: [
25479
+ ["--domain <domain>", "a domain key carried by the candidate; required so tooling never guesses the application root"],
25480
+ ["--file <path>", "the exact compiled .law.usdz candidate (default: the single build/*.law.usdz)"],
25481
+ ["--because <reason>", "explicitly accept an intentional historical outcome change; omitted for equivalent evolution"],
25482
+ ["--as <uid>", "sign as this stored workspace principal"],
25483
+ ["--cloud <url>", "target cloud"]
25484
+ ],
25485
+ examples: ["githolon model adopt --domain home", "githolon model adopt co2-platform --domain home --file build/co2.law.usdz"]
25486
+ },
25242
25487
  domains: {
25243
25488
  usage: "githolon domains <status <ws> [--explain-current-interface] | retire <ws> <hashOrKey> [--with <hashOrKey>]>",
25244
25489
  what: "Framework lifecycle inspection and explicit withdrawal.\n\u2022 status: per domain KEY, the active hash, then the superseded/retired lineage behind it.\n Lifecycle vocabulary: active = served now; superseded = replaced by a newer install for the same domain\n key, replayable, not served; retired = explicitly withdrawn, replayable, not served.\n --explain-current-interface spells out why active reads/dispatch use only that active map.\n\u2022 retire: mark an install Retired via a signed installDomain offer. The framework retires only as the\n consequence of installing a SUCCESSOR \u2014 by default the local compiled law (build/*.law.usdz),\n or --with <hashOrKey> names an already-installed successor. A key the successor does not cover is left\n with NO active law \u2014 WARNED loudly, never blocked. A key resolves to its active hash; a 64-hex arg is\n taken as the install hash.",
@@ -25388,9 +25633,9 @@ function capJsonStrings(v, max = 2048) {
25388
25633
  if (typeof v === "string") return v.length > max ? `${v.slice(0, max)}\u2026(${v.length} chars)` : v;
25389
25634
  if (Array.isArray(v)) return v.map((x) => capJsonStrings(x, max));
25390
25635
  if (typeof v === "object" && v !== null) {
25391
- const out14 = {};
25392
- for (const [k, x] of Object.entries(v)) out14[k] = capJsonStrings(x, max);
25393
- return out14;
25636
+ const out15 = {};
25637
+ for (const [k, x] of Object.entries(v)) out15[k] = capJsonStrings(x, max);
25638
+ return out15;
25394
25639
  }
25395
25640
  return v;
25396
25641
  }
@@ -26053,7 +26298,7 @@ Options:
26053
26298
  function cloudArgs(rest) {
26054
26299
  const pos = [];
26055
26300
  const opts = {};
26056
- const VALUE_FLAGS = ["--cloud", "--principal", "--as", "--file", "--target", "--parent", "--via", "--max", "--pool", "--label", "--secret", "--payload", "--payload-file", "--save", "--format", "--with", "--out", "--reason", "--oid", "--seed-secret", "--gcp-secret", "--auth-provider-issuer", "--auth-provider-jwks-file", "--auth-provider-jwks-url", "--auth-provider-audience", "--auth-provider-principal-claim", "--auth-provider-device-binding-claim", "--controller-hash", "--plan", "--depth", "--domain", "--directive"];
26301
+ const VALUE_FLAGS = ["--cloud", "--principal", "--as", "--file", "--target", "--parent", "--via", "--max", "--pool", "--label", "--secret", "--payload", "--payload-file", "--save", "--format", "--with", "--out", "--reason", "--because", "--oid", "--seed-secret", "--gcp-secret", "--auth-provider-issuer", "--auth-provider-jwks-file", "--auth-provider-jwks-url", "--auth-provider-audience", "--auth-provider-principal-claim", "--auth-provider-device-binding-claim", "--controller-hash", "--plan", "--depth", "--domain", "--directive"];
26057
26302
  const BOOL_FLAGS = ["--sha256", "--stamp", "--yes", "--clear", "--explain-current-interface", "--dry-run", "--json", "--full"];
26058
26303
  for (let i = 0; i < rest.length; i++) {
26059
26304
  const a = rest[i];
@@ -26095,6 +26340,7 @@ function cloudArgs(rest) {
26095
26340
  else if (a === "--with") opts.with = v;
26096
26341
  else if (a === "--domain") opts.domain = v;
26097
26342
  else if (a === "--directive") opts.directive = v;
26343
+ else if (a === "--because") opts.because = v;
26098
26344
  else if (a === "--out") opts.out = v;
26099
26345
  else if (a === "--max") {
26100
26346
  const n = Number(v);
@@ -26530,10 +26776,10 @@ async function main(argv) {
26530
26776
  };
26531
26777
  const lawArg = pull("--law");
26532
26778
  const workspace = pull("--workspace") ?? "test-ws";
26533
- const out14 = pull("--out");
26779
+ const out15 = pull("--out");
26534
26780
  const runtime = pull("--runtime");
26535
26781
  const law = (lawArg ?? "").split(",").map((s) => s.trim()).filter(Boolean);
26536
- if (law.length === 0 || out14 === void 0) {
26782
+ if (law.length === 0 || out15 === void 0) {
26537
26783
  process.stderr.write(
26538
26784
  `error: usage: githolon harness-install --law <law.usdz[,law.usdz...]> --workspace <ws> --out <snapshotPath> [--runtime <dir>]
26539
26785
  `
@@ -26541,7 +26787,7 @@ async function main(argv) {
26541
26787
  return 1;
26542
26788
  }
26543
26789
  const { harnessInstall: harnessInstall2 } = await Promise.resolve().then(() => (init_harness(), harness_exports));
26544
- return harnessInstall2({ law, workspace, out: out14, ...runtime !== void 0 ? { runtime } : {} });
26790
+ return harnessInstall2({ law, workspace, out: out15, ...runtime !== void 0 ? { runtime } : {} });
26545
26791
  }
26546
26792
  if (argv[0] === "dev") {
26547
26793
  const rest = argv.slice(1);
@@ -26711,6 +26957,31 @@ ${commandHelp("status")}`);
26711
26957
  }
26712
26958
  return status(pos[0], opts);
26713
26959
  }
26960
+ if (argv[0] === "model") {
26961
+ const { pos, opts, bad } = cloudArgs(argv.slice(1));
26962
+ if (bad !== void 0) {
26963
+ process.stderr.write(`error: ${bad}
26964
+
26965
+ ${commandHelp("model") ?? USAGE}`);
26966
+ return 1;
26967
+ }
26968
+ const [sub2, explicitWorkspace] = pos;
26969
+ if (sub2 !== "adopt" || opts.domain === void 0) {
26970
+ process.stderr.write(`error: expected: githolon model adopt [<workspace>] --domain <domain> [--file <law.usdz>] [--because <reason>]
26971
+
26972
+ ${commandHelp("model") ?? USAGE}`);
26973
+ return 1;
26974
+ }
26975
+ try {
26976
+ const workspace = await resolveWorkspace(explicitWorkspace, process.cwd(), opts.target, "githolon model adopt <workspace>");
26977
+ const { modelAdopt: modelAdopt2 } = await Promise.resolve().then(() => (init_model(), model_exports));
26978
+ return modelAdopt2(workspace, { ...opts, domain: opts.domain, ...opts.because === void 0 ? {} : { because: opts.because } });
26979
+ } catch (cause) {
26980
+ process.stderr.write(`error: ${cause.message}
26981
+ `);
26982
+ return 1;
26983
+ }
26984
+ }
26714
26985
  if (argv[0] === "ws" && argv[1] === "create") {
26715
26986
  process.stderr.write(
26716
26987
  "error: `githolon ws create` is not an application birth API. Declare birth(Aggregate, spec) and call the generated app.birth(businessFacts); Nomos owns custody beneath it.\n"
@@ -27064,8 +27335,8 @@ ${USAGE}`);
27064
27335
  let parsed;
27065
27336
  try {
27066
27337
  parsed = parseArgs(argv);
27067
- } catch (err14) {
27068
- process.stderr.write(`error: ${err14.message}
27338
+ } catch (err15) {
27339
+ process.stderr.write(`error: ${err15.message}
27069
27340
 
27070
27341
  ${USAGE}`);
27071
27342
  return 1;
@@ -27084,8 +27355,8 @@ ${USAGE}`);
27084
27355
  process.stdout.write(`created ${path2}
27085
27356
  `);
27086
27357
  return 0;
27087
- } catch (err14) {
27088
- process.stderr.write(`error: ${err14.message}
27358
+ } catch (err15) {
27359
+ process.stderr.write(`error: ${err15.message}
27089
27360
  `);
27090
27361
  return 1;
27091
27362
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "githolon",
3
- "version": "0.107.2",
3
+ "version": "0.107.4",
4
4
  "type": "module",
5
5
  "description": "githolon — the Nomos developer CLI: Rails-style generators for @githolon/dsl domains + the package compiler. Kernel-independent.",
6
6
  "license": "SEE LICENSE IN LICENSE.md",
@@ -30,7 +30,7 @@
30
30
  "dependencies": {
31
31
  "@bjorn3/browser_wasi_shim": "0.4.2",
32
32
  "@bufbuild/protobuf": "^2.13.0",
33
- "@githolon/dsl": "^0.107.2",
33
+ "@githolon/dsl": "^0.107.4",
34
34
  "fast-xml-parser": "5.10.1",
35
35
  "isomorphic-git": "^1.38.4",
36
36
  "tsx": "^4.19.2"