githolon 0.69.1 → 0.69.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.mjs +387 -258
  2. package/package.json +3 -3
package/dist/cli.mjs CHANGED
@@ -2828,9 +2828,151 @@ var init_local_holon = __esm({
2828
2828
  }
2829
2829
  });
2830
2830
 
2831
+ // src/repairs.ts
2832
+ var repairs_exports = {};
2833
+ __export(repairs_exports, {
2834
+ discoverRepairs: () => discoverRepairs,
2835
+ knownRepairBlock: () => knownRepairBlock,
2836
+ matchRepair: () => matchRepair,
2837
+ parseRefusal: () => parseRefusal
2838
+ });
2839
+ import { spawnSync } from "node:child_process";
2840
+ import { createRequire } from "node:module";
2841
+ import { existsSync as existsSync3, mkdtempSync, readdirSync as readdirSync2, readFileSync as readFileSync2, rmSync, writeFileSync as writeFileSync3 } from "node:fs";
2842
+ import { tmpdir } from "node:os";
2843
+ import { dirname as dirname2, isAbsolute, join as join3, resolve } from "node:path";
2844
+ import { pathToFileURL } from "node:url";
2845
+ function parseRefusal(verdict) {
2846
+ const check2 = String(verdict["check"] ?? "");
2847
+ const error = String(verdict["error"] ?? "");
2848
+ const raw = `${check2}: ${error}`;
2849
+ const kind = /evolve.?gate/i.test(raw) || /evolve/i.test(check2) ? "evolve-gate" : "other";
2850
+ const sids = /* @__PURE__ */ new Set();
2851
+ const structured = verdict["stableId"] ?? verdict["stableIds"];
2852
+ if (typeof structured === "string" && SID_SHAPE.test(structured)) sids.add(structured.toLowerCase());
2853
+ if (Array.isArray(structured)) {
2854
+ for (const s of structured) if (typeof s === "string" && SID_SHAPE.test(s)) sids.add(s.toLowerCase());
2855
+ }
2856
+ for (const m of raw.matchAll(SID_RE)) sids.add(m[1].toLowerCase());
2857
+ return { kind, stableIds: [...sids], raw };
2858
+ }
2859
+ function matchRepair(refusal, repairs) {
2860
+ if (refusal.kind === "other") return void 0;
2861
+ return repairs.find(
2862
+ (r) => r.matcher.refusal === refusal.kind && refusal.stableIds.includes(r.matcher.stableId.toLowerCase())
2863
+ );
2864
+ }
2865
+ function knownRepairBlock(repair) {
2866
+ return [
2867
+ "",
2868
+ `\u2726 KNOWN REPAIR: '${repair.id}' (${repair.file}) declares a remedy for exactly this refusal.`,
2869
+ ` reason: ${repair.reason}`,
2870
+ " Re-run with --repair to execute it."
2871
+ ].join("\n");
2872
+ }
2873
+ function resolveTsxCli(cwd) {
2874
+ const pkgDir = (name, fromDir) => {
2875
+ try {
2876
+ return dirname2(createRequire(pathToFileURL(join3(fromDir, "noop.js")).href).resolve(`${name}/package.json`));
2877
+ } catch {
2878
+ return void 0;
2879
+ }
2880
+ };
2881
+ const dslDir = pkgDir("@githolon/dsl", cwd) ?? (() => {
2882
+ try {
2883
+ return dirname2(createRequire(import.meta.url).resolve("@githolon/dsl/package.json"));
2884
+ } catch {
2885
+ return void 0;
2886
+ }
2887
+ })();
2888
+ const tsxDir = pkgDir("tsx", cwd) ?? (dslDir !== void 0 ? pkgDir("tsx", dslDir) : void 0);
2889
+ if (tsxDir === void 0) return void 0;
2890
+ try {
2891
+ const pkg = JSON.parse(
2892
+ readFileSync2(join3(tsxDir, "package.json"), "utf8")
2893
+ );
2894
+ const rel = typeof pkg.bin === "string" ? pkg.bin : pkg.bin?.["tsx"];
2895
+ return join3(tsxDir, rel ?? "dist/cli.mjs");
2896
+ } catch {
2897
+ return void 0;
2898
+ }
2899
+ }
2900
+ function resolveDslEntry(cwd) {
2901
+ const tryFrom = (fromUrl) => {
2902
+ try {
2903
+ return createRequire(fromUrl).resolve("@githolon/dsl");
2904
+ } catch {
2905
+ return void 0;
2906
+ }
2907
+ };
2908
+ return tryFrom(pathToFileURL(join3(cwd, "noop.js")).href) ?? tryFrom(import.meta.url);
2909
+ }
2910
+ function discoverRepairs(cwd) {
2911
+ const dir = join3(cwd, "repairs");
2912
+ if (!existsSync3(dir)) return { repairs: [] };
2913
+ let files;
2914
+ try {
2915
+ files = readdirSync2(dir).filter((f) => /\.(ts|mts|cts)$/.test(f) && !/\.d\.ts$/.test(f)).sort().map((f) => resolve(dir, f));
2916
+ } catch (e) {
2917
+ return { error: `could not read the repairs/ folder: ${e.message}` };
2918
+ }
2919
+ if (files.length === 0) return { repairs: [] };
2920
+ const tsxCli = resolveTsxCli(cwd);
2921
+ const dslEntry = resolveDslEntry(cwd);
2922
+ if (tsxCli === void 0 || dslEntry === void 0) {
2923
+ return { error: "repairs/ is present but the toolchain to load it is missing \u2014 add @githolon/dsl (tsx + the DSL ride it) to the project and npm install" };
2924
+ }
2925
+ const scratch = mkdtempSync(join3(tmpdir(), "githolon-repairs-"));
2926
+ const loader = join3(scratch, "discover.mts");
2927
+ const loaderSrc = `
2928
+ import { repairsOf } from ${JSON.stringify(dslEntry)};
2929
+ const files = ${JSON.stringify(files)};
2930
+ const out = [];
2931
+ const seen = new Map();
2932
+ for (const file of files) {
2933
+ const mod = await import(${JSON.stringify("file://")} + file);
2934
+ for (const r of repairsOf(mod)) {
2935
+ if (seen.has(r.id)) {
2936
+ throw new Error("duplicate repair id '" + r.id + "' \u2014 declared in " + seen.get(r.id) + " and " + file);
2937
+ }
2938
+ seen.set(r.id, file);
2939
+ out.push({ id: r.id, matcher: r.matcher, reason: r.reason, verb: r.verb, file });
2940
+ }
2941
+ }
2942
+ process.stdout.write("\\u0001REPAIRS\\u0001" + JSON.stringify(out) + "\\u0001END\\u0001\\n");
2943
+ `;
2944
+ try {
2945
+ writeFileSync3(loader, loaderSrc, "utf8");
2946
+ const r = spawnSync(process.execPath, [tsxCli, loader], { cwd, encoding: "utf8" });
2947
+ if (r.status !== 0) {
2948
+ const msg = (r.stderr || r.stdout || "").trim().split("\n").filter(Boolean).slice(-4).join("\n");
2949
+ return { error: `loading repairs/ failed:
2950
+ ${msg || `tsx exited ${r.status ?? "?"}`}` };
2951
+ }
2952
+ const m = /REPAIRS([\s\S]*?)END/.exec(r.stdout);
2953
+ if (m === null) return { error: "the repairs loader produced no manifest (unexpected \u2014 the DSL/tsx may be too old)" };
2954
+ const parsed = JSON.parse(m[1]);
2955
+ const repairs = parsed.map((p) => ({ ...p, file: isAbsolute(p.file) ? p.file : resolve(cwd, p.file) }));
2956
+ return { repairs };
2957
+ } catch (e) {
2958
+ return { error: `loading repairs/ failed: ${e.message}` };
2959
+ } finally {
2960
+ rmSync(scratch, { recursive: true, force: true });
2961
+ }
2962
+ }
2963
+ var SID_RE, SID_SHAPE;
2964
+ var init_repairs = __esm({
2965
+ "src/repairs.ts"() {
2966
+ "use strict";
2967
+ SID_RE = /stable id ([0-9a-f]{16})/gi;
2968
+ SID_SHAPE = /^[0-9a-f]{16}$/i;
2969
+ }
2970
+ });
2971
+
2831
2972
  // src/governance.ts
2832
2973
  var governance_exports = {};
2833
2974
  __export(governance_exports, {
2975
+ ROOT_CUSTODIAN_SECRET: () => ROOT_CUSTODIAN_SECRET,
2834
2976
  buildCertificate: () => buildCertificate,
2835
2977
  buildRebirthPlan: () => buildRebirthPlan,
2836
2978
  certifyEra: () => certifyEra,
@@ -2846,6 +2988,7 @@ __export(governance_exports, {
2846
2988
  rebirthPlanCommand: () => rebirthPlanCommand,
2847
2989
  rebirthWorkspace: () => rebirthWorkspace,
2848
2990
  renderRebirthImpact: () => renderRebirthImpact,
2991
+ resolveGovernanceHash: () => resolveGovernanceHash,
2849
2992
  resolveGovernancePrincipal: () => resolveGovernancePrincipal,
2850
2993
  signAndPostGovernance: () => signAndPostGovernance,
2851
2994
  signAndPostOffer: () => signAndPostOffer,
@@ -2853,8 +2996,8 @@ __export(governance_exports, {
2853
2996
  verifyWorkspaceVerdict: () => verifyWorkspaceVerdict
2854
2997
  });
2855
2998
  import { createHash, createPrivateKey, createPublicKey } from "node:crypto";
2856
- import { mkdirSync as mkdirSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync3 } from "node:fs";
2857
- import { dirname as dirname2, join as join3 } from "node:path";
2999
+ import { mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync4 } from "node:fs";
3000
+ import { dirname as dirname3, join as join4 } from "node:path";
2858
3001
  async function clientConnect() {
2859
3002
  const mod = await import("@githolon/client");
2860
3003
  return mod.connect;
@@ -3072,7 +3215,7 @@ async function keyExport(opts) {
3072
3215
  return 0;
3073
3216
  }
3074
3217
  function buildOfferPayload(opts) {
3075
- const raw = opts.payloadFile !== void 0 ? readFileSync2(opts.payloadFile, "utf8") : opts.payload;
3218
+ const raw = opts.payloadFile !== void 0 ? readFileSync3(opts.payloadFile, "utf8") : opts.payload;
3076
3219
  let payload = {};
3077
3220
  if (raw !== void 0 && raw.trim() !== "") payload = JSON.parse(raw);
3078
3221
  if (typeof payload !== "object" || payload === null || Array.isArray(payload)) {
@@ -3106,7 +3249,7 @@ async function governanceOffer(ws, directiveId, opts) {
3106
3249
  const holon = await connectGovernance(cloudBase(opts.cloud), ws);
3107
3250
  const device = await ensureDeviceKey(holon, principal);
3108
3251
  const sealed = await holon.signGovernanceOffer({ directiveId, payload, authorSecret: device.secret, actor: `user:${principal}` });
3109
- writeFileSync3(opts.save, JSON.stringify({ ws, directiveId, principal, intentBytes: sealed.intentBytes }, null, 2) + "\n");
3252
+ writeFileSync4(opts.save, JSON.stringify({ ws, directiveId, principal, intentBytes: sealed.intentBytes }, null, 2) + "\n");
3110
3253
  } catch (e) {
3111
3254
  err2(e.message);
3112
3255
  return 1;
@@ -3133,7 +3276,7 @@ async function governanceOffer(ws, directiveId, opts) {
3133
3276
  async function governanceRelay(ws, file, opts) {
3134
3277
  let saved;
3135
3278
  try {
3136
- saved = JSON.parse(readFileSync2(file, "utf8"));
3279
+ saved = JSON.parse(readFileSync3(file, "utf8"));
3137
3280
  } catch (e) {
3138
3281
  err2(`cannot read offer file ${file}: ${e.message}`);
3139
3282
  return 1;
@@ -3294,6 +3437,15 @@ certify-era ${ws}:`);
3294
3437
  out2(` verify: githolon ledger verify ${ws} (expect GREEN with certifiedRanges naming the oids)`);
3295
3438
  return 0;
3296
3439
  }
3440
+ async function resolveGovernanceHash(cloud, domainKey, ws = "root", fetchImpl = fetch) {
3441
+ try {
3442
+ const d = await (await fetchImpl(`${cloud}/v2/workspaces/${ws}/domains`)).json();
3443
+ const h = d && d.currentLaw && d.currentLaw[domainKey];
3444
+ return typeof h === "string" && h.length > 0 ? h : void 0;
3445
+ } catch {
3446
+ return void 0;
3447
+ }
3448
+ }
3297
3449
  async function parkedAreAllLawInstalls(engMod, eng, ws, oids) {
3298
3450
  try {
3299
3451
  const git4 = (await import("isomorphic-git")).default;
@@ -3351,18 +3503,27 @@ async function buildRebirthPlan(cloud, ws, reason) {
3351
3503
  } catch {
3352
3504
  }
3353
3505
  const lawHashes = {};
3506
+ let currentLaw2 = {};
3354
3507
  try {
3355
3508
  const d = await (await fetch(`${cloud}/v2/workspaces/${ws}/domains`)).json();
3509
+ currentLaw2 = d.currentLaw ?? {};
3510
+ const currentHashes = new Set(Object.values(currentLaw2));
3356
3511
  for (const dom of d.domains ?? []) {
3357
- if (typeof dom.domainHash === "string" && dom.phase === "Active") lawHashes[dom.domainHash] = dom.phase;
3512
+ if (typeof dom.domainHash !== "string") continue;
3513
+ lawHashes[dom.domainHash] = {
3514
+ phase: dom.phase ?? "unknown",
3515
+ current: dom.current === true || currentHashes.has(dom.domainHash)
3516
+ };
3358
3517
  }
3359
3518
  } catch {
3360
3519
  }
3361
3520
  let verdict = { replay: "unknown", firstRefusal: null };
3521
+ let rawVerdict = null;
3362
3522
  try {
3363
3523
  const m = await mountWorkspace2(eng, ws, { remote: `${cloud}/v2/workspaces/${ws}/git`, headers: {} });
3364
3524
  if (m.restored === true) {
3365
3525
  const v = verifyChainLocal2(eng, ws);
3526
+ rawVerdict = v;
3366
3527
  if (v["valid"] === true) verdict = { replay: "green", firstRefusal: null };
3367
3528
  else verdict = { replay: "red", firstRefusal: `${String(v["check"] ?? "?")}${v["atIndex"] !== void 0 ? ` @intent ${v["atIndex"]}` : ""}: ${String(v["error"] ?? "").slice(0, 200)}` };
3368
3529
  }
@@ -3384,13 +3545,42 @@ async function buildRebirthPlan(cloud, ws, reason) {
3384
3545
  } catch {
3385
3546
  }
3386
3547
  const mode = compaction.scarShape === "mid-chain" && !((compaction.parked ?? 99) <= 2 && parkedAllLawInstalls) ? "state-seed" : "replay-compact";
3548
+ let repairs = [];
3549
+ if (rawVerdict !== null && rawVerdict["valid"] !== true) {
3550
+ try {
3551
+ const { discoverRepairs: discoverRepairs2, parseRefusal: parseRefusal2, matchRepair: matchRepair2 } = await Promise.resolve().then(() => (init_repairs(), repairs_exports));
3552
+ const discovered = discoverRepairs2(process.cwd());
3553
+ if (!("error" in discovered) && discovered.repairs.length > 0) {
3554
+ const refusal = parseRefusal2(rawVerdict);
3555
+ for (const r of discovered.repairs) {
3556
+ if (r.matcher.refusal === refusal.kind && refusal.stableIds.includes(r.matcher.stableId.toLowerCase())) {
3557
+ const v = r.verb;
3558
+ repairs.push({
3559
+ id: r.id,
3560
+ file: r.file,
3561
+ reason: r.reason,
3562
+ matcher: { refusal: r.matcher.refusal, stableId: r.matcher.stableId },
3563
+ verb: {
3564
+ kind: String(v.kind ?? ""),
3565
+ ...typeof v.aggregateId === "string" ? { aggregateId: v.aggregateId } : {},
3566
+ ...typeof v.field === "string" ? { field: v.field } : {},
3567
+ ...typeof v.through === "string" ? { through: v.through } : {}
3568
+ },
3569
+ execution: "recorded"
3570
+ });
3571
+ }
3572
+ }
3573
+ }
3574
+ } catch {
3575
+ }
3576
+ }
3387
3577
  const frozenAt = priorSupersessions === 0 ? ws : `${ws}--i${priorSupersessions}`;
3388
3578
  const newCustodyAddress = `${ws}--i${priorSupersessions + 1}`;
3389
3579
  const plan = {
3390
3580
  v: 1,
3391
3581
  workspace: ws,
3392
3582
  reason: reason ?? null,
3393
- pinned: { incarnation, lawHashes, parent },
3583
+ pinned: { incarnation, lawHashes, currentLaw: currentLaw2, parent },
3394
3584
  will: {
3395
3585
  newCustodyAddress,
3396
3586
  frozenAt,
@@ -3400,7 +3590,7 @@ async function buildRebirthPlan(cloud, ws, reason) {
3400
3590
  verdict,
3401
3591
  mode,
3402
3592
  compaction,
3403
- repairs: [],
3593
+ repairs,
3404
3594
  clientImpact: CLIENT_IMPACT,
3405
3595
  generatedAt: (/* @__PURE__ */ new Date()).toISOString()
3406
3596
  };
@@ -3416,8 +3606,15 @@ function renderRebirthImpact(plan, ledgerCommits) {
3416
3606
  L.push(` incarnation : ${plan.pinned.incarnation ? plan.pinned.incarnation.slice(0, 16) + "\u2026" : "(none recorded \u2014 first incarnation)"}`);
3417
3607
  L.push(` verify_chain : ${plan.verdict.replay.toUpperCase()}${plan.verdict.firstRefusal ? ` \u2014 first refusal: ${plan.verdict.firstRefusal}` : ""}`);
3418
3608
  L.push(` ledger size : ${ledgerCommits !== null ? `${ledgerCommits} commit(s)` : "(unknown)"}`);
3419
- const laws = Object.keys(plan.pinned.lawHashes);
3420
- L.push(` installed law : ${laws.length ? laws.map((h) => h.slice(0, 12) + "\u2026").join(", ") : "(none read)"}`);
3609
+ const laws = Object.entries(plan.pinned.lawHashes);
3610
+ const currentLaw2 = plan.pinned.currentLaw ?? {};
3611
+ const keysForHash = (hash) => Object.entries(currentLaw2).filter(([, h]) => h === hash).map(([k]) => k);
3612
+ const currentHashes = laws.filter(([, m]) => m.current).map(([h]) => h);
3613
+ const currentDesc = currentHashes.length ? currentHashes.map((h) => {
3614
+ const ks = keysForHash(h);
3615
+ return `${h.slice(0, 8)}\u2026${ks.length ? ` (${ks.join(", ")})` : ""}`;
3616
+ }).join(" \xB7 ") : "(none current)";
3617
+ L.push(` installed law : ${laws.length} historical \xB7 current: ${currentDesc}`);
3421
3618
  L.push(` parent : ${plan.pinned.parent || "(root)"}`);
3422
3619
  L.push("");
3423
3620
  L.push("WHAT A REBIRTH WOULD DO");
@@ -3450,9 +3647,33 @@ function renderRebirthImpact(plan, ledgerCommits) {
3450
3647
  L.push(" \u2192 preserved by lineage continuity; their birth-cert chains stay valid (same founding key + self-id).");
3451
3648
  }
3452
3649
  L.push("");
3650
+ L.push(`REPAIRS (${plan.repairs.length})`);
3651
+ if (plan.repairs.length === 0) L.push(" (none matched \u2014 a plain compaction; no corrective verb declared for this refusal)");
3652
+ else {
3653
+ for (const r of plan.repairs) {
3654
+ const v = r.verb;
3655
+ const verbDesc = `${v.kind}${v.aggregateId ? ` ${v.aggregateId}${v.field ? `.${v.field}` : ""}` : ""}${v.through ? ` through ${v.through}` : ""}`;
3656
+ L.push(` \u2726 ${r.id} [${r.execution}]`);
3657
+ L.push(` matches : ${r.matcher.refusal} \xB7 stable id ${r.matcher.stableId}`);
3658
+ L.push(` verb : ${verbDesc} (${r.file})`);
3659
+ L.push(` reason : ${r.reason}`);
3660
+ }
3661
+ L.push(" \u2192 v1 records the repair as provenance/justification (the certificate + supersession reason name it);");
3662
+ L.push(" state-transform verbs execute at the re-fold seam in a future release.");
3663
+ }
3664
+ L.push("");
3453
3665
  L.push("CLIENT IMPACT");
3454
3666
  L.push(` ${plan.clientImpact}.`);
3455
3667
  L.push(" Recommend tenants DRAIN/SYNC their clients before the rebirth window.");
3668
+ L.push("");
3669
+ L.push("NEXT STEPS \u2014 the blessed golden path");
3670
+ L.push(" 1. plan (this)");
3671
+ L.push(` 2. apply githolon rebirth apply --plan <path> --gcp-secret ${ROOT_CUSTODIAN_SECRET} [--yes]`);
3672
+ L.push(" (apply requires the ROOT CUSTODIAN seed \u2014 --gcp-secret is the blessed path;");
3673
+ L.push(" --seed-secret <b64> is break-glass, env NOMOS_ROOT_SEED is the CI lane)");
3674
+ L.push(` 3. replay githolon replay ${plan.workspace} (expect GREEN from intent 0)`);
3675
+ L.push(` 4. status githolon status ${plan.workspace} (incarnation + supersession history)`);
3676
+ L.push(" 5. compat githolon compat (clients raise CustodyBreak \u2014 choose adopt/reject)");
3456
3677
  return L.join("\n");
3457
3678
  }
3458
3679
  async function rebirthPlanCommand(ws, opts) {
@@ -3463,19 +3684,22 @@ async function rebirthPlanCommand(ws, opts) {
3463
3684
  return 1;
3464
3685
  }
3465
3686
  const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
3466
- const dir = opts.out ?? join3("rebirths", `${date}-${ws}`);
3687
+ const dir = opts.out ?? join4("rebirths", `${date}-${ws}`);
3467
3688
  try {
3468
3689
  mkdirSync3(dir, { recursive: true });
3469
- writeFileSync3(join3(dir, "plan.json"), JSON.stringify(built.plan, null, 2) + "\n");
3470
- writeFileSync3(join3(dir, "impact.md"), "```\n" + renderRebirthImpact(built.plan, built.ledgerCommits) + "\n```\n");
3690
+ writeFileSync4(join4(dir, "plan.json"), JSON.stringify(built.plan, null, 2) + "\n");
3691
+ writeFileSync4(join4(dir, "impact.md"), "```\n" + renderRebirthImpact(built.plan, built.ledgerCommits) + "\n```\n");
3471
3692
  } catch (e) {
3472
3693
  err2(`could not write the plan into ${dir}: ${e.message}`);
3473
3694
  return 1;
3474
3695
  }
3475
3696
  out2(renderRebirthImpact(built.plan, built.ledgerCommits));
3476
3697
  out2("");
3477
- out2(`\u2713 plan written: ${join3(dir, "plan.json")} + ${join3(dir, "impact.md")}`);
3478
- out2(" fill in `reason` before a future `githolon rebirth apply --plan` (apply is not yet available).");
3698
+ out2(`\u2713 plan written: ${join4(dir, "plan.json")} + ${join4(dir, "impact.md")}`);
3699
+ if (built.plan.reason === null) out2(" fill in the plan's `reason` (the mandatory audit justification) before apply.");
3700
+ out2(" apply requires the ROOT CUSTODIAN seed. The blessed command:");
3701
+ out2(` githolon rebirth apply --plan ${join4(dir, "plan.json")} --gcp-secret ${ROOT_CUSTODIAN_SECRET} [--yes]`);
3702
+ out2(" (--seed-secret <b64> is break-glass \u2014 avoid in shell history; env NOMOS_ROOT_SEED is the CI lane.)");
3479
3703
  return 0;
3480
3704
  }
3481
3705
  async function rebirthWorkspace(ws, opts) {
@@ -3503,9 +3727,12 @@ async function rebirthWorkspace(ws, opts) {
3503
3727
  err2("the law refuses to rebirth root \u2014 the seat of the authorizing law cannot supersede itself");
3504
3728
  return 1;
3505
3729
  }
3506
- if (opts.plan !== void 0 && Array.isArray(opts.plan.repairs) && opts.plan.repairs.length > 0) {
3507
- err2("repair verbs are not yet available \u2014 the plan may not carry repairs (the `repairs` array must be empty)");
3508
- return 1;
3730
+ if (opts.plan !== void 0 && Array.isArray(opts.plan.repairs)) {
3731
+ const unknown = opts.plan.repairs.find((r2) => r2.execution !== "recorded");
3732
+ if (unknown !== void 0) {
3733
+ err2(`the plan carries a repair with an unsupported execution '${String(unknown.execution)}' \u2014 v1 executes only execution:"recorded" (state-transform verbs land in a future release)`);
3734
+ return 1;
3735
+ }
3509
3736
  }
3510
3737
  let seed = opts.seedSecret ?? process.env["NOMOS_ROOT_SEED"];
3511
3738
  if (seed === void 0 && opts.gcpSecret !== void 0) {
@@ -3518,7 +3745,7 @@ async function rebirthWorkspace(ws, opts) {
3518
3745
  }
3519
3746
  }
3520
3747
  if (seed === void 0 || seed.trim() === "") {
3521
- err2("gov rebirth needs the custodian seed \u2014 --seed-secret <b64>, env NOMOS_ROOT_SEED, or --gcp-secret <name>");
3748
+ err2(`gov rebirth needs the ROOT CUSTODIAN seed \u2014 the blessed path is --gcp-secret ${ROOT_CUSTODIAN_SECRET}; --seed-secret <b64> is break-glass (avoid in shell history), env NOMOS_ROOT_SEED is the CI lane`);
3522
3749
  return 1;
3523
3750
  }
3524
3751
  const cloud = cloudBase(opts.cloud);
@@ -3578,9 +3805,9 @@ gov rebirth ${ws}:`);
3578
3805
  }
3579
3806
  }
3580
3807
  const rebornAt = Date.now();
3581
- const controllerHash = opts.controllerHash ?? eng.hashes?.nomos;
3808
+ const controllerHash = opts.controllerHash ?? await resolveGovernanceHash(cloud, "workspaces");
3582
3809
  if (typeof controllerHash !== "string") {
3583
- err2("could not resolve root's governance controller hash (pass --controller-hash)");
3810
+ err2("could not resolve root's governance (workspaces) law hash from root currentLaw (pass --controller-hash)");
3584
3811
  return 1;
3585
3812
  }
3586
3813
  const res = author2(eng, "root", "workspaces", "rebirthWorkspace", { workspaceId, reason, rebornAt }, controllerHash, { authorSecret: seed, actor: "user:root-custodian" });
@@ -3628,8 +3855,11 @@ function validatePlanForApply(plan, liveIncarnation) {
3628
3855
  if (plan.reason === null || typeof plan.reason === "string" && plan.reason.trim() === "") {
3629
3856
  return { error: "the plan's `reason` is still null \u2014 fill it in (the mandatory audit justification) before apply" };
3630
3857
  }
3631
- if (Array.isArray(plan.repairs) && plan.repairs.length > 0) {
3632
- return { error: "repair verbs are not yet executable \u2014 the plan may not carry `repairs` (the array must be empty); state-transform verbs land in a future release" };
3858
+ if (Array.isArray(plan.repairs)) {
3859
+ const bad = plan.repairs.find((r) => r.execution !== "recorded");
3860
+ if (bad !== void 0) {
3861
+ return { error: `the plan carries a repair with an unsupported execution '${String(bad.execution)}' \u2014 this CLI executes only execution:"recorded" (state-transform verbs land in a future release)` };
3862
+ }
3633
3863
  }
3634
3864
  if (plan.pinned.incarnation !== null) {
3635
3865
  if (liveIncarnation === void 0) {
@@ -3643,6 +3873,7 @@ function validatePlanForApply(plan, liveIncarnation) {
3643
3873
  }
3644
3874
  function buildCertificate(args) {
3645
3875
  const { plan } = args;
3876
+ const childNames = plan.children.map((c) => c.name);
3646
3877
  return {
3647
3878
  v: 1,
3648
3879
  plan,
@@ -3651,12 +3882,17 @@ function buildCertificate(args) {
3651
3882
  custodian: args.custodian,
3652
3883
  oldIncarnation: args.oldIncarnation,
3653
3884
  newIncarnation: args.newIncarnation,
3885
+ oldHead: args.oldHead ?? args.oldIncarnation,
3886
+ newHead: args.newHead ?? args.newIncarnation,
3887
+ oldCustodyAddress: plan.will.frozenAt,
3654
3888
  newCustodyAddress: plan.will.newCustodyAddress,
3655
3889
  carried: plan.compaction.carried,
3656
3890
  parked: plan.compaction.parked,
3657
3891
  verdictBefore: args.verdictBefore,
3658
3892
  ...args.firstRefusal ? { firstRefusal: args.firstRefusal } : {},
3659
- verdictAfter: args.verdictAfter
3893
+ verdictAfter: args.verdictAfter,
3894
+ activeLawAfter: args.activeLawAfter ?? {},
3895
+ childrenCarried: { count: childNames.length, names: childNames }
3660
3896
  },
3661
3897
  supersessionFacts: {
3662
3898
  supersededBy: plan.will.newCustodyAddress,
@@ -3665,6 +3901,7 @@ function buildCertificate(args) {
3665
3901
  custodian: args.custodian,
3666
3902
  at: args.at
3667
3903
  },
3904
+ repairs: Array.isArray(plan.repairs) ? plan.repairs : [],
3668
3905
  ...args.repair !== void 0 ? { repair: args.repair } : {}
3669
3906
  };
3670
3907
  }
@@ -3684,6 +3921,14 @@ async function verifyWorkspaceVerdict(cloud, ws) {
3684
3921
  return { replay: "unknown", firstRefusal: null };
3685
3922
  }
3686
3923
  }
3924
+ async function currentLawOf(cloud, ws) {
3925
+ try {
3926
+ const d = await (await fetch(`${cloud}/v2/workspaces/${ws}/domains`)).json();
3927
+ return d.currentLaw ?? {};
3928
+ } catch {
3929
+ return {};
3930
+ }
3931
+ }
3687
3932
  async function liveIncarnationOf(cloud, ws) {
3688
3933
  try {
3689
3934
  const s = await (await fetch(`${cloud}/v2/workspaces/${ws}`)).json();
@@ -3695,7 +3940,7 @@ async function liveIncarnationOf(cloud, ws) {
3695
3940
  async function rebirthApply(planPath, opts) {
3696
3941
  let plan;
3697
3942
  try {
3698
- plan = JSON.parse(readFileSync2(planPath, "utf8"));
3943
+ plan = JSON.parse(readFileSync3(planPath, "utf8"));
3699
3944
  } catch (e) {
3700
3945
  err2(`cannot read the plan ${planPath}: ${e.message}`);
3701
3946
  return 1;
@@ -3730,9 +3975,11 @@ async function rebirthApply(planPath, opts) {
3730
3975
  }
3731
3976
  const verdictBefore = plan.verdict.replay === "green" ? "green" : "red";
3732
3977
  const custodian = opts.principal ?? activePrincipal() ?? "root-custodian";
3978
+ const repairIds = (plan.repairs ?? []).map((r) => r.id);
3979
+ const effectiveReason = repairIds.length ? `${plan.reason ?? ""} ${repairIds.map((id) => `[repair:${id}]`).join(" ")}`.trim() : plan.reason ?? void 0;
3733
3980
  const code = await rebirthWorkspace(ws, {
3734
3981
  ...opts,
3735
- reason: plan.reason ?? void 0,
3982
+ reason: effectiveReason,
3736
3983
  plan,
3737
3984
  quiet: true,
3738
3985
  yes: true
@@ -3743,19 +3990,21 @@ async function rebirthApply(planPath, opts) {
3743
3990
  }
3744
3991
  const newIncarnation = await liveIncarnationOf(cloud, ws) ?? null;
3745
3992
  const verdictAfter = await verifyWorkspaceVerdict(cloud, ws);
3993
+ const activeLawAfter = await currentLawOf(cloud, ws);
3746
3994
  const cert = buildCertificate({
3747
3995
  plan,
3748
3996
  custodian,
3749
3997
  at: (/* @__PURE__ */ new Date()).toISOString(),
3750
3998
  oldIncarnation: plan.pinned.incarnation,
3751
3999
  newIncarnation,
4000
+ activeLawAfter,
3752
4001
  verdictBefore,
3753
4002
  ...plan.verdict.firstRefusal ? { firstRefusal: plan.verdict.firstRefusal } : {},
3754
4003
  verdictAfter
3755
4004
  });
3756
- const certPath = join3(dirname2(planPath), "certificate.json");
4005
+ const certPath = join4(dirname3(planPath), "certificate.json");
3757
4006
  try {
3758
- writeFileSync3(certPath, JSON.stringify(cert, null, 2) + "\n");
4007
+ writeFileSync4(certPath, JSON.stringify(cert, null, 2) + "\n");
3759
4008
  } catch (e) {
3760
4009
  err2(`the rebirth succeeded but the certificate could not be written to ${certPath}: ${e.message}`);
3761
4010
  return 1;
@@ -3806,12 +4055,14 @@ async function executeRepairRebirth(cloud, ws, repair, verdict, opts) {
3806
4055
  }
3807
4056
  const newIncarnation = await liveIncarnationOf(cloudBaseUrl, ws) ?? null;
3808
4057
  const verdictAfter = await verifyWorkspaceVerdict(cloudBaseUrl, ws);
4058
+ const activeLawAfter = await currentLawOf(cloudBaseUrl, ws);
3809
4059
  const cert = buildCertificate({
3810
4060
  plan,
3811
4061
  custodian,
3812
4062
  at: (/* @__PURE__ */ new Date()).toISOString(),
3813
4063
  oldIncarnation: plan.pinned.incarnation,
3814
4064
  newIncarnation,
4065
+ activeLawAfter,
3815
4066
  verdictBefore,
3816
4067
  firstRefusal,
3817
4068
  verdictAfter,
@@ -3822,9 +4073,9 @@ async function executeRepairRebirth(cloud, ws, repair, verdict, opts) {
3822
4073
  note: "repair verb recorded; state transform verbs land in a future release (v1 rebirth only)"
3823
4074
  }
3824
4075
  });
3825
- const certPath = join3(dirname2(repair.file), "certificate.json");
4076
+ const certPath = join4(dirname3(repair.file), "certificate.json");
3826
4077
  try {
3827
- writeFileSync3(certPath, JSON.stringify(cert, null, 2) + "\n");
4078
+ writeFileSync4(certPath, JSON.stringify(cert, null, 2) + "\n");
3828
4079
  } catch (e) {
3829
4080
  err2(`the repair rebirth succeeded but the certificate could not be written to ${certPath}: ${e.message}`);
3830
4081
  return 1;
@@ -3844,13 +4095,14 @@ function readSealedIntentBytes(eng, ws, intentOut) {
3844
4095
  if (f?.data === void 0) return void 0;
3845
4096
  return Buffer.from(f.data).toString("base64");
3846
4097
  }
3847
- var out2, err2, CLIENT_IMPACT;
4098
+ var out2, err2, ROOT_CUSTODIAN_SECRET, CLIENT_IMPACT;
3848
4099
  var init_governance = __esm({
3849
4100
  "src/governance.ts"() {
3850
4101
  "use strict";
3851
4102
  init_cloud();
3852
4103
  out2 = (s) => void process.stdout.write(s + "\n");
3853
4104
  err2 = (s) => void process.stderr.write("error: " + s + "\n");
4105
+ ROOT_CUSTODIAN_SECRET = "nomos-root-custodian-key";
3854
4106
  CLIENT_IMPACT = "every connected client raises CustodyBreak(superseded); unsynced client work is invisible to the cloud \u2014 drain/sync clients first";
3855
4107
  }
3856
4108
  });
@@ -3874,7 +4126,7 @@ __export(lifecycle_exports, {
3874
4126
  signingAvailable: () => signingAvailable
3875
4127
  });
3876
4128
  import { createHash as createHash2 } from "node:crypto";
3877
- import { readFileSync as readFileSync3 } from "node:fs";
4129
+ import { readFileSync as readFileSync4 } from "node:fs";
3878
4130
  async function fetchInstalledLaw(cloud, ws) {
3879
4131
  try {
3880
4132
  const r = await fetch(`${cloud}/v2/workspaces/${ws}/domains`);
@@ -3897,7 +4149,7 @@ async function fetchInstalledPackage(cloud, ws, hash) {
3897
4149
  function readDeployBody(file) {
3898
4150
  let body;
3899
4151
  try {
3900
- body = JSON.parse(readFileSync3(file, "utf8"));
4152
+ body = JSON.parse(readFileSync4(file, "utf8"));
3901
4153
  } catch (e) {
3902
4154
  throw new Error(`deploy body ${file} is not valid JSON \u2014 recompile (githolon compile): ${e.message}`);
3903
4155
  }
@@ -4197,9 +4449,9 @@ __export(cloud_exports, {
4197
4449
  wsRetire: () => wsRetire,
4198
4450
  wsStatus: () => wsStatus
4199
4451
  });
4200
- import { chmodSync, existsSync as existsSync3, mkdirSync as mkdirSync4, readdirSync as readdirSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "node:fs";
4452
+ import { chmodSync, existsSync as existsSync4, mkdirSync as mkdirSync4, readdirSync as readdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "node:fs";
4201
4453
  import { createHash as createHash3 } from "node:crypto";
4202
- import { join as join4 } from "node:path";
4454
+ import { join as join5 } from "node:path";
4203
4455
  import { homedir } from "node:os";
4204
4456
  function cloudBase(flag) {
4205
4457
  return (flag ?? process.env["NOMOS_CLOUD"] ?? DEFAULT_CLOUD).replace(/\/+$/, "");
@@ -4211,18 +4463,18 @@ function authAnonKey() {
4211
4463
  return process.env["HOLON_AUTH_ANON_KEY"] ?? DEFAULT_AUTH_ANON_KEY;
4212
4464
  }
4213
4465
  function configDir() {
4214
- return process.env["HOLON_CONFIG_DIR"] ?? join4(homedir(), ".holon");
4466
+ return process.env["HOLON_CONFIG_DIR"] ?? join5(homedir(), ".holon");
4215
4467
  }
4216
4468
  function credsPath() {
4217
- return join4(configDir(), "credentials.json");
4469
+ return join5(configDir(), "credentials.json");
4218
4470
  }
4219
4471
  function loadCreds() {
4220
- if (!existsSync3(credsPath())) return { version: 1, secrets: {} };
4221
- return JSON.parse(readFileSync4(credsPath(), "utf8"));
4472
+ if (!existsSync4(credsPath())) return { version: 1, secrets: {} };
4473
+ return JSON.parse(readFileSync5(credsPath(), "utf8"));
4222
4474
  }
4223
4475
  function saveCreds(c) {
4224
4476
  mkdirSync4(configDir(), { recursive: true });
4225
- writeFileSync4(credsPath(), JSON.stringify(c, null, 2) + "\n", "utf8");
4477
+ writeFileSync5(credsPath(), JSON.stringify(c, null, 2) + "\n", "utf8");
4226
4478
  chmodSync(credsPath(), 384);
4227
4479
  }
4228
4480
  function getSecret(cloud, ws) {
@@ -4337,21 +4589,21 @@ async function sessionToken() {
4337
4589
  }
4338
4590
  function discoverDeployJson(cwd, explicit) {
4339
4591
  if (explicit !== void 0) {
4340
- if (!existsSync3(explicit)) throw new Error(`deploy body not found: ${explicit}`);
4592
+ if (!existsSync4(explicit)) throw new Error(`deploy body not found: ${explicit}`);
4341
4593
  return explicit;
4342
4594
  }
4343
- const buildDir = join4(cwd, "build");
4344
- if (!existsSync3(buildDir)) {
4595
+ const buildDir = join5(cwd, "build");
4596
+ if (!existsSync4(buildDir)) {
4345
4597
  throw new Error("no build/ directory \u2014 run `githolon compile` first (or pass --file <path>)");
4346
4598
  }
4347
- const bodies = readdirSync2(buildDir).filter((f) => f.endsWith(".deploy.json"));
4599
+ const bodies = readdirSync3(buildDir).filter((f) => f.endsWith(".deploy.json"));
4348
4600
  if (bodies.length === 0) {
4349
4601
  throw new Error("no build/*.deploy.json \u2014 run `githolon compile` first (or pass --file <path>)");
4350
4602
  }
4351
4603
  if (bodies.length > 1) {
4352
4604
  throw new Error(`multiple deploy bodies in build/ (${bodies.join(", ")}) \u2014 pass --file <path>`);
4353
4605
  }
4354
- return join4(buildDir, bodies[0]);
4606
+ return join5(buildDir, bodies[0]);
4355
4607
  }
4356
4608
  async function login(opts) {
4357
4609
  if (opts.agent !== true && opts.token === void 0) {
@@ -4578,7 +4830,7 @@ async function deploy2(ws, opts) {
4578
4830
  if (signed) {
4579
4831
  let body;
4580
4832
  try {
4581
- body = JSON.parse(readFileSync4(file, "utf8"));
4833
+ body = JSON.parse(readFileSync5(file, "utf8"));
4582
4834
  } catch (e) {
4583
4835
  err4(`deploy body ${file} is not valid JSON \u2014 recompile: ${e.message}`);
4584
4836
  return 1;
@@ -4617,7 +4869,7 @@ async function deploy2(ws, opts) {
4617
4869
  const r = await fetch(`${cloud}/v2/workspaces/${ws}/domains`, {
4618
4870
  method: "POST",
4619
4871
  headers: { "content-type": "application/json" },
4620
- body: readFileSync4(file, "utf8")
4872
+ body: readFileSync5(file, "utf8")
4621
4873
  });
4622
4874
  const d = await r.json().catch(() => void 0);
4623
4875
  if (!r.ok || d?.ok !== true) {
@@ -4711,27 +4963,27 @@ __export(editor_exports, {
4711
4963
  initEditor: () => initEditor,
4712
4964
  writeEditorRecommendation: () => writeEditorRecommendation
4713
4965
  });
4714
- import { existsSync as existsSync4, mkdirSync as mkdirSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "node:fs";
4715
- import { dirname as dirname3, join as join5 } from "node:path";
4966
+ import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync6 } from "node:fs";
4967
+ import { dirname as dirname4, join as join6 } from "node:path";
4716
4968
  function hasEditorRecommendation(cwd) {
4717
- const p = join5(cwd, ".vscode", "extensions.json");
4718
- if (!existsSync4(p)) return false;
4969
+ const p = join6(cwd, ".vscode", "extensions.json");
4970
+ if (!existsSync5(p)) return false;
4719
4971
  try {
4720
- const json = JSON.parse(readFileSync5(p, "utf8"));
4972
+ const json = JSON.parse(readFileSync6(p, "utf8"));
4721
4973
  return Array.isArray(json.recommendations) && json.recommendations.includes(NOMOS_LAW_EXTENSION_ID);
4722
4974
  } catch {
4723
4975
  return true;
4724
4976
  }
4725
4977
  }
4726
4978
  function writeEditorRecommendation(cwd) {
4727
- const dir = join5(cwd, ".vscode");
4728
- const path = join5(dir, "extensions.json");
4979
+ const dir = join6(cwd, ".vscode");
4980
+ const path = join6(dir, "extensions.json");
4729
4981
  let json = {};
4730
4982
  let existed = false;
4731
- if (existsSync4(path)) {
4983
+ if (existsSync5(path)) {
4732
4984
  existed = true;
4733
4985
  try {
4734
- const parsed = JSON.parse(readFileSync5(path, "utf8"));
4986
+ const parsed = JSON.parse(readFileSync6(path, "utf8"));
4735
4987
  if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
4736
4988
  json = parsed;
4737
4989
  } else {
@@ -4749,8 +5001,8 @@ function writeEditorRecommendation(cwd) {
4749
5001
  }
4750
5002
  recs.push(NOMOS_LAW_EXTENSION_ID);
4751
5003
  json.recommendations = recs;
4752
- mkdirSync5(dirname3(path), { recursive: true });
4753
- writeFileSync5(path, JSON.stringify(json, null, 2) + "\n", "utf8");
5004
+ mkdirSync5(dirname4(path), { recursive: true });
5005
+ writeFileSync6(path, JSON.stringify(json, null, 2) + "\n", "utf8");
4754
5006
  return { path, action: existed ? "updated" : "created" };
4755
5007
  }
4756
5008
  function initEditor(cwd = process.cwd()) {
@@ -4784,21 +5036,21 @@ var init_editor = __esm({
4784
5036
  });
4785
5037
 
4786
5038
  // src/compile.ts
4787
- import { spawn, spawnSync } from "node:child_process";
4788
- import { createRequire } from "node:module";
4789
- import { dirname as dirname4, join as join6 } from "node:path";
4790
- import { pathToFileURL } from "node:url";
5039
+ import { spawn, spawnSync as spawnSync2 } from "node:child_process";
5040
+ import { createRequire as createRequire2 } from "node:module";
5041
+ import { dirname as dirname5, join as join7 } from "node:path";
5042
+ import { pathToFileURL as pathToFileURL2 } from "node:url";
4791
5043
  function resolveCompileLauncher(cwd) {
4792
5044
  const resolveDslPkg = (fromDir) => {
4793
5045
  try {
4794
- const req = fromDir === void 0 ? createRequire(import.meta.url) : createRequire(pathToFileURL(join6(fromDir, "noop.js")));
5046
+ const req = fromDir === void 0 ? createRequire2(import.meta.url) : createRequire2(pathToFileURL2(join7(fromDir, "noop.js")));
4795
5047
  return req.resolve("@githolon/dsl/package.json");
4796
5048
  } catch {
4797
5049
  return void 0;
4798
5050
  }
4799
5051
  };
4800
5052
  const dslPkg = resolveDslPkg(cwd) ?? resolveDslPkg(void 0);
4801
- return dslPkg === void 0 ? void 0 : join6(dirname4(dslPkg), "compile_package.mjs");
5053
+ return dslPkg === void 0 ? void 0 : join7(dirname5(dslPkg), "compile_package.mjs");
4802
5054
  }
4803
5055
  function runCompile(args) {
4804
5056
  const launcher = resolveCompileLauncher(process.cwd());
@@ -4807,7 +5059,7 @@ function runCompile(args) {
4807
5059
  `);
4808
5060
  return 1;
4809
5061
  }
4810
- const r = spawnSync(process.execPath, [launcher, ...args], { stdio: "inherit", cwd: process.cwd() });
5062
+ const r = spawnSync2(process.execPath, [launcher, ...args], { stdio: "inherit", cwd: process.cwd() });
4811
5063
  const status2 = r.status ?? 1;
4812
5064
  if (status2 === 0 && process.stdout.isTTY) {
4813
5065
  try {
@@ -4821,7 +5073,7 @@ ${INIT_EDITOR_HINT}
4821
5073
  }
4822
5074
  function resolveCheckLauncher(cwd) {
4823
5075
  const launcher = resolveCompileLauncher(cwd);
4824
- return launcher === void 0 ? void 0 : join6(dirname4(launcher), "check_package.mjs");
5076
+ return launcher === void 0 ? void 0 : join7(dirname5(launcher), "check_package.mjs");
4825
5077
  }
4826
5078
  function runCheck(args) {
4827
5079
  const launcher = resolveCheckLauncher(process.cwd());
@@ -4830,12 +5082,12 @@ function runCheck(args) {
4830
5082
  `);
4831
5083
  return 1;
4832
5084
  }
4833
- const r = spawnSync(process.execPath, [launcher, ...args], { stdio: "inherit", cwd: process.cwd() });
5085
+ const r = spawnSync2(process.execPath, [launcher, ...args], { stdio: "inherit", cwd: process.cwd() });
4834
5086
  return r.status ?? 1;
4835
5087
  }
4836
5088
  function resolveCompatLauncher(cwd) {
4837
5089
  const launcher = resolveCompileLauncher(cwd);
4838
- return launcher === void 0 ? void 0 : join6(dirname4(launcher), "compat_package.mjs");
5090
+ return launcher === void 0 ? void 0 : join7(dirname5(launcher), "compat_package.mjs");
4839
5091
  }
4840
5092
  function runCompat(args) {
4841
5093
  const launcher = resolveCompatLauncher(process.cwd());
@@ -4844,12 +5096,12 @@ function runCompat(args) {
4844
5096
  `);
4845
5097
  return 1;
4846
5098
  }
4847
- const r = spawnSync(process.execPath, [launcher, ...args], { stdio: "inherit", cwd: process.cwd() });
5099
+ const r = spawnSync2(process.execPath, [launcher, ...args], { stdio: "inherit", cwd: process.cwd() });
4848
5100
  return r.status ?? 1;
4849
5101
  }
4850
5102
  function resolveLspLauncher(cwd) {
4851
5103
  const launcher = resolveCompileLauncher(cwd);
4852
- return launcher === void 0 ? void 0 : join6(dirname4(launcher), "lsp_server.mjs");
5104
+ return launcher === void 0 ? void 0 : join7(dirname5(launcher), "lsp_server.mjs");
4853
5105
  }
4854
5106
  function runLsp(args) {
4855
5107
  const launcher = resolveLspLauncher(process.cwd());
@@ -4858,7 +5110,7 @@ function runLsp(args) {
4858
5110
  `);
4859
5111
  return 1;
4860
5112
  }
4861
- const r = spawnSync(process.execPath, [launcher, ...args], { stdio: "inherit", cwd: process.cwd() });
5113
+ const r = spawnSync2(process.execPath, [launcher, ...args], { stdio: "inherit", cwd: process.cwd() });
4862
5114
  return r.status ?? 1;
4863
5115
  }
4864
5116
  function compileAsync(cwd, args = []) {
@@ -4898,8 +5150,8 @@ __export(proof_offline_exports, {
4898
5150
  runOfflineProofStandalone: () => runOfflineProofStandalone,
4899
5151
  runRelationBootstrapLeg: () => runRelationBootstrapLeg
4900
5152
  });
4901
- import { existsSync as existsSync6, readFileSync as readFileSync6 } from "node:fs";
4902
- import { basename, dirname as dirname5, join as join8 } from "node:path";
5153
+ import { existsSync as existsSync7, readFileSync as readFileSync7 } from "node:fs";
5154
+ import { basename, dirname as dirname6, join as join9 } from "node:path";
4903
5155
  function parseOfflineLegs(proofSource) {
4904
5156
  if (!proofSource.includes("AUTO-GENERATED by nomos-compile")) {
4905
5157
  throw new Error("not a generated proof (missing the AUTO-GENERATED header) \u2014 run `githolon compile` to (re)generate build/<name>.proof.mts");
@@ -5324,16 +5576,16 @@ function actorFromPayload(payload, field) {
5324
5576
  return typeof value === "string" && value.trim().length > 0 ? value : void 0;
5325
5577
  }
5326
5578
  async function runOfflineProofStandalone(proofPath, cloud, domain) {
5327
- const src = readFileSync6(proofPath, "utf8");
5579
+ const src = readFileSync7(proofPath, "utf8");
5328
5580
  const packageName = basename(proofPath).replace(/\.proof\.mts$/, "");
5329
- const deployFile = join8(dirname5(proofPath), `${packageName}.deploy.json`);
5330
- if (!existsSync6(deployFile)) {
5581
+ const deployFile = join9(dirname6(proofPath), `${packageName}.deploy.json`);
5582
+ if (!existsSync7(deployFile)) {
5331
5583
  throw new Error(`missing ${deployFile} \u2014 run \`githolon compile\` (the proof and the deploy body are built together)`);
5332
5584
  }
5333
5585
  let legs;
5334
- const legsFile = join8(dirname5(proofPath), `${packageName}.proof-legs.json`);
5335
- if (existsSync6(legsFile)) {
5336
- const index = JSON.parse(readFileSync6(legsFile, "utf8"));
5586
+ const legsFile = join9(dirname6(proofPath), `${packageName}.proof-legs.json`);
5587
+ if (existsSync7(legsFile)) {
5588
+ const index = JSON.parse(readFileSync7(legsFile, "utf8"));
5337
5589
  const keys = Object.keys(index.domains);
5338
5590
  const chosen = domain ?? index.default;
5339
5591
  if (index.domains[chosen] === void 0) {
@@ -5351,7 +5603,7 @@ async function runOfflineProofStandalone(proofPath, cloud, domain) {
5351
5603
  if (domain !== void 0) throw new Error(`--domain needs a per-domain legs index (build/${packageName}.proof-legs.json) \u2014 recompile with \`githolon compile\` to emit it`);
5352
5604
  legs = parseOfflineLegs(src);
5353
5605
  }
5354
- const deployBody = JSON.parse(readFileSync6(deployFile, "utf8"));
5606
+ const deployBody = JSON.parse(readFileSync7(deployFile, "utf8"));
5355
5607
  const lawHash = await sha256hex(deployBody.packageUsda);
5356
5608
  console.log(`githolon proof \u2014 OFFLINE legs on a local holon (the cloud loop: githolon proof --live)`);
5357
5609
  const { eng } = await holonEngine(cloud, deployBody, "githolon-proof");
@@ -5378,147 +5630,6 @@ var init_proof_offline = __esm({
5378
5630
  }
5379
5631
  });
5380
5632
 
5381
- // src/repairs.ts
5382
- var repairs_exports = {};
5383
- __export(repairs_exports, {
5384
- discoverRepairs: () => discoverRepairs,
5385
- knownRepairBlock: () => knownRepairBlock,
5386
- matchRepair: () => matchRepair,
5387
- parseRefusal: () => parseRefusal
5388
- });
5389
- import { spawnSync as spawnSync4 } from "node:child_process";
5390
- import { createRequire as createRequire2 } from "node:module";
5391
- import { existsSync as existsSync9, mkdtempSync, readdirSync as readdirSync4, readFileSync as readFileSync10, rmSync, writeFileSync as writeFileSync7 } from "node:fs";
5392
- import { tmpdir } from "node:os";
5393
- import { dirname as dirname7, isAbsolute, join as join11, resolve as resolve2 } from "node:path";
5394
- import { pathToFileURL as pathToFileURL4 } from "node:url";
5395
- function parseRefusal(verdict) {
5396
- const check2 = String(verdict["check"] ?? "");
5397
- const error = String(verdict["error"] ?? "");
5398
- const raw = `${check2}: ${error}`;
5399
- const kind = /evolve.?gate/i.test(raw) || /evolve/i.test(check2) ? "evolve-gate" : "other";
5400
- const sids = /* @__PURE__ */ new Set();
5401
- const structured = verdict["stableId"] ?? verdict["stableIds"];
5402
- if (typeof structured === "string" && SID_SHAPE.test(structured)) sids.add(structured.toLowerCase());
5403
- if (Array.isArray(structured)) {
5404
- for (const s of structured) if (typeof s === "string" && SID_SHAPE.test(s)) sids.add(s.toLowerCase());
5405
- }
5406
- for (const m of raw.matchAll(SID_RE)) sids.add(m[1].toLowerCase());
5407
- return { kind, stableIds: [...sids], raw };
5408
- }
5409
- function matchRepair(refusal, repairs) {
5410
- if (refusal.kind === "other") return void 0;
5411
- return repairs.find(
5412
- (r) => r.matcher.refusal === refusal.kind && refusal.stableIds.includes(r.matcher.stableId.toLowerCase())
5413
- );
5414
- }
5415
- function knownRepairBlock(repair) {
5416
- return [
5417
- "",
5418
- `\u2726 KNOWN REPAIR: '${repair.id}' (${repair.file}) declares a remedy for exactly this refusal.`,
5419
- ` reason: ${repair.reason}`,
5420
- " Re-run with --repair to execute it."
5421
- ].join("\n");
5422
- }
5423
- function resolveTsxCli(cwd) {
5424
- const pkgDir = (name, fromDir) => {
5425
- try {
5426
- return dirname7(createRequire2(pathToFileURL4(join11(fromDir, "noop.js")).href).resolve(`${name}/package.json`));
5427
- } catch {
5428
- return void 0;
5429
- }
5430
- };
5431
- const dslDir = pkgDir("@githolon/dsl", cwd) ?? (() => {
5432
- try {
5433
- return dirname7(createRequire2(import.meta.url).resolve("@githolon/dsl/package.json"));
5434
- } catch {
5435
- return void 0;
5436
- }
5437
- })();
5438
- const tsxDir = pkgDir("tsx", cwd) ?? (dslDir !== void 0 ? pkgDir("tsx", dslDir) : void 0);
5439
- if (tsxDir === void 0) return void 0;
5440
- try {
5441
- const pkg = JSON.parse(
5442
- readFileSync10(join11(tsxDir, "package.json"), "utf8")
5443
- );
5444
- const rel = typeof pkg.bin === "string" ? pkg.bin : pkg.bin?.["tsx"];
5445
- return join11(tsxDir, rel ?? "dist/cli.mjs");
5446
- } catch {
5447
- return void 0;
5448
- }
5449
- }
5450
- function resolveDslEntry(cwd) {
5451
- const tryFrom = (fromUrl) => {
5452
- try {
5453
- return createRequire2(fromUrl).resolve("@githolon/dsl");
5454
- } catch {
5455
- return void 0;
5456
- }
5457
- };
5458
- return tryFrom(pathToFileURL4(join11(cwd, "noop.js")).href) ?? tryFrom(import.meta.url);
5459
- }
5460
- function discoverRepairs(cwd) {
5461
- const dir = join11(cwd, "repairs");
5462
- if (!existsSync9(dir)) return { repairs: [] };
5463
- let files;
5464
- try {
5465
- files = readdirSync4(dir).filter((f) => /\.(ts|mts|cts)$/.test(f) && !/\.d\.ts$/.test(f)).sort().map((f) => resolve2(dir, f));
5466
- } catch (e) {
5467
- return { error: `could not read the repairs/ folder: ${e.message}` };
5468
- }
5469
- if (files.length === 0) return { repairs: [] };
5470
- const tsxCli = resolveTsxCli(cwd);
5471
- const dslEntry = resolveDslEntry(cwd);
5472
- if (tsxCli === void 0 || dslEntry === void 0) {
5473
- return { error: "repairs/ is present but the toolchain to load it is missing \u2014 add @githolon/dsl (tsx + the DSL ride it) to the project and npm install" };
5474
- }
5475
- const scratch = mkdtempSync(join11(tmpdir(), "githolon-repairs-"));
5476
- const loader = join11(scratch, "discover.mts");
5477
- const loaderSrc = `
5478
- import { repairsOf } from ${JSON.stringify(dslEntry)};
5479
- const files = ${JSON.stringify(files)};
5480
- const out = [];
5481
- const seen = new Map();
5482
- for (const file of files) {
5483
- const mod = await import(${JSON.stringify("file://")} + file);
5484
- for (const r of repairsOf(mod)) {
5485
- if (seen.has(r.id)) {
5486
- throw new Error("duplicate repair id '" + r.id + "' \u2014 declared in " + seen.get(r.id) + " and " + file);
5487
- }
5488
- seen.set(r.id, file);
5489
- out.push({ id: r.id, matcher: r.matcher, reason: r.reason, verb: r.verb, file });
5490
- }
5491
- }
5492
- process.stdout.write("\\u0001REPAIRS\\u0001" + JSON.stringify(out) + "\\u0001END\\u0001\\n");
5493
- `;
5494
- try {
5495
- writeFileSync7(loader, loaderSrc, "utf8");
5496
- const r = spawnSync4(process.execPath, [tsxCli, loader], { cwd, encoding: "utf8" });
5497
- if (r.status !== 0) {
5498
- const msg = (r.stderr || r.stdout || "").trim().split("\n").filter(Boolean).slice(-4).join("\n");
5499
- return { error: `loading repairs/ failed:
5500
- ${msg || `tsx exited ${r.status ?? "?"}`}` };
5501
- }
5502
- const m = /REPAIRS([\s\S]*?)END/.exec(r.stdout);
5503
- if (m === null) return { error: "the repairs loader produced no manifest (unexpected \u2014 the DSL/tsx may be too old)" };
5504
- const parsed = JSON.parse(m[1]);
5505
- const repairs = parsed.map((p) => ({ ...p, file: isAbsolute(p.file) ? p.file : resolve2(cwd, p.file) }));
5506
- return { repairs };
5507
- } catch (e) {
5508
- return { error: `loading repairs/ failed: ${e.message}` };
5509
- } finally {
5510
- rmSync(scratch, { recursive: true, force: true });
5511
- }
5512
- }
5513
- var SID_RE, SID_SHAPE;
5514
- var init_repairs = __esm({
5515
- "src/repairs.ts"() {
5516
- "use strict";
5517
- SID_RE = /stable id ([0-9a-f]{16})/gi;
5518
- SID_SHAPE = /^[0-9a-f]{16}$/i;
5519
- }
5520
- });
5521
-
5522
5633
  // src/mcp.ts
5523
5634
  var mcp_exports = {};
5524
5635
  __export(mcp_exports, {
@@ -7258,20 +7369,20 @@ init_engine();
7258
7369
  init_cloud();
7259
7370
  init_compile();
7260
7371
  init_local_holon();
7261
- import { existsSync as existsSync7, readFileSync as readFileSync7, watch } from "node:fs";
7372
+ import { existsSync as existsSync8, readFileSync as readFileSync8, watch } from "node:fs";
7262
7373
  import { createServer } from "node:http";
7263
- import { dirname as dirname6, join as join9, resolve } from "node:path";
7264
- import { pathToFileURL as pathToFileURL3 } from "node:url";
7374
+ import { dirname as dirname7, join as join10, resolve as resolve2 } from "node:path";
7375
+ import { pathToFileURL as pathToFileURL4 } from "node:url";
7265
7376
 
7266
7377
  // src/project.ts
7267
- import { existsSync as existsSync5, statSync as statSync2 } from "node:fs";
7268
- import { join as join7 } from "node:path";
7269
- import { pathToFileURL as pathToFileURL2 } from "node:url";
7378
+ import { existsSync as existsSync6, statSync as statSync2 } from "node:fs";
7379
+ import { join as join8 } from "node:path";
7380
+ import { pathToFileURL as pathToFileURL3 } from "node:url";
7270
7381
  var CONFIG_FILE = "nomos.package.mjs";
7271
7382
  async function loadProject(cwd, opts = {}) {
7272
- const configPath = join7(cwd, CONFIG_FILE);
7273
- if (!existsSync5(configPath)) return void 0;
7274
- const href = pathToFileURL2(configPath).href + (opts.bust === true ? `?v=${statSync2(configPath).mtimeMs}-${Date.now()}` : "");
7383
+ const configPath = join8(cwd, CONFIG_FILE);
7384
+ if (!existsSync6(configPath)) return void 0;
7385
+ const href = pathToFileURL3(configPath).href + (opts.bust === true ? `?v=${statSync2(configPath).mtimeMs}-${Date.now()}` : "");
7275
7386
  const mod = await import(href);
7276
7387
  const cfg = mod.default;
7277
7388
  if (cfg === void 0 || typeof cfg.name !== "string" || cfg.name.length === 0) {
@@ -7435,11 +7546,11 @@ function startServer(s) {
7435
7546
  });
7436
7547
  }
7437
7548
  function readDeployBody2(cwd, packageName) {
7438
- const file = join9(cwd, "build", `${packageName}.deploy.json`);
7439
- if (!existsSync7(file)) {
7549
+ const file = join10(cwd, "build", `${packageName}.deploy.json`);
7550
+ if (!existsSync8(file)) {
7440
7551
  throw new Error(`compile produced no ${file} \u2014 check the compile output above`);
7441
7552
  }
7442
- return JSON.parse(readFileSync7(file, "utf8"));
7553
+ return JSON.parse(readFileSync8(file, "utf8"));
7443
7554
  }
7444
7555
  async function installLaw(s, deployBody, installedBy) {
7445
7556
  const newHash = await sha256hex(deployBody.packageUsda);
@@ -7455,11 +7566,11 @@ async function installLaw(s, deployBody, installedBy) {
7455
7566
  return { ok: true };
7456
7567
  }
7457
7568
  async function runProofCycle(s, cwd, deployBody, installedBy) {
7458
- const proofPath = join9(cwd, "build", `${s.packageName}.proof.mts`);
7459
- if (!existsSync7(proofPath)) return void 0;
7569
+ const proofPath = join10(cwd, "build", `${s.packageName}.proof.mts`);
7570
+ if (!existsSync8(proofPath)) return void 0;
7460
7571
  const scratch = `proof-${s.cycle}`;
7461
7572
  try {
7462
- const legs = parseOfflineLegs(readFileSync7(proofPath, "utf8"));
7573
+ const legs = parseOfflineLegs(readFileSync8(proofPath, "utf8"));
7463
7574
  await mountFresh(s.eng, scratch);
7464
7575
  author(s.eng, scratch, "bootstrap", "installDomain", installPayload(s.eng.hashes.nomos, s.eng.nomosPkg, installedBy), "");
7465
7576
  author(s.eng, scratch, "nomos", "installDomain", installPayload(s.lawHash, deployBody.packageUsda, installedBy), s.eng.hashes.nomos);
@@ -7478,7 +7589,7 @@ async function dev(opts) {
7478
7589
  return void 0;
7479
7590
  });
7480
7591
  if (project === void 0) {
7481
- if (!existsSync7(join9(cwd, CONFIG_FILE))) {
7592
+ if (!existsSync8(join10(cwd, CONFIG_FILE))) {
7482
7593
  err5(`no ${CONFIG_FILE} here (${cwd}) \u2014 \`githolon dev\` runs inside a project; scaffold one from examples/guestbook or \`githolon generate domain <name>\``);
7483
7594
  }
7484
7595
  return 1;
@@ -7543,14 +7654,14 @@ ${firstCompile.output}`);
7543
7654
  }
7544
7655
  const moduleDirs = /* @__PURE__ */ new Set();
7545
7656
  try {
7546
- const cfgModule = await import(pathToFileURL3(project.configPath).href);
7657
+ const cfgModule = await import(pathToFileURL4(project.configPath).href);
7547
7658
  for (const d of cfgModule.default?.domains ?? []) {
7548
- for (const m of d.modules ?? []) moduleDirs.add(dirname6(resolve(cwd, m)));
7659
+ for (const m of d.modules ?? []) moduleDirs.add(dirname7(resolve2(cwd, m)));
7549
7660
  }
7550
7661
  } catch {
7551
- moduleDirs.add(join9(cwd, "domains"));
7662
+ moduleDirs.add(join10(cwd, "domains"));
7552
7663
  }
7553
- if (moduleDirs.size === 0) moduleDirs.add(join9(cwd, "domains"));
7664
+ if (moduleDirs.size === 0) moduleDirs.add(join10(cwd, "domains"));
7554
7665
  let timer;
7555
7666
  let cycling = false;
7556
7667
  let queued = false;
@@ -7600,7 +7711,7 @@ ${run.output}`);
7600
7711
  };
7601
7712
  const watchers = [];
7602
7713
  for (const d of moduleDirs) {
7603
- if (!existsSync7(d)) continue;
7714
+ if (!existsSync8(d)) continue;
7604
7715
  watchers.push(watch(d, { recursive: true }, (_evt, f) => onChange(f)));
7605
7716
  s.watchRoots.push(d.startsWith(cwd) ? d.slice(cwd.length + 1) + "/" : d);
7606
7717
  }
@@ -7625,13 +7736,13 @@ ${run.output}`);
7625
7736
 
7626
7737
  // src/git.ts
7627
7738
  init_cloud();
7628
- import { spawnSync as spawnSync2 } from "node:child_process";
7739
+ import { spawnSync as spawnSync3 } from "node:child_process";
7629
7740
  import { randomBytes as randomBytes2 } from "node:crypto";
7630
- import { readFileSync as readFileSync8 } from "node:fs";
7741
+ import { readFileSync as readFileSync9 } from "node:fs";
7631
7742
  var out6 = (s) => void process.stdout.write(s + "\n");
7632
7743
  var err6 = (s) => void process.stderr.write("error: " + s + "\n");
7633
7744
  function git(args, opts = {}) {
7634
- const r = spawnSync2("git", args, { stdio: opts.quiet === true ? "ignore" : "inherit" });
7745
+ const r = spawnSync3("git", args, { stdio: opts.quiet === true ? "ignore" : "inherit" });
7635
7746
  return r.status ?? 1;
7636
7747
  }
7637
7748
  function ensureSecret(cloud, ws) {
@@ -7656,7 +7767,7 @@ function workspaceFromPath(path) {
7656
7767
  }
7657
7768
  async function gitCredential(action) {
7658
7769
  if (action !== "get") return 0;
7659
- const kv = parseCredentialInput(readFileSync8(0, "utf8"));
7770
+ const kv = parseCredentialInput(readFileSync9(0, "utf8"));
7660
7771
  const ws = workspaceFromPath(kv["path"]);
7661
7772
  if (kv["protocol"] !== "https" || ws === void 0) return 0;
7662
7773
  const cloud = `https://${kv["host"]}`;
@@ -7878,6 +7989,23 @@ var HELP = {
7878
7989
  "githolon gov relay root co2.offer.json"
7879
7990
  ]
7880
7991
  },
7992
+ rebirth: {
7993
+ usage: "githolon rebirth plan <ws> [--reason <text>] [--out <dir>]\n githolon rebirth apply --plan <plan.json> --gcp-secret nomos-root-custodian-key [--yes]",
7994
+ what: "LAWFUL SUPERSESSION as code (the migrations-folder workflow; architecture/rebirth_and_custody_lifecycle.md).\n`plan` writes a read-only, drift-pinned plan.json + impact.md into rebirths/<date>-<ws>/ \u2014 the reviewable\nintent (pinned incarnation, law lifecycle, children, verdict, and any MATCHED repairs from repairs/*.ts).\n`apply` drives the reviewed plan through the signed rebirth path \u2192 certificate.json beside it.\nAPPLY REQUIRES THE ROOT CUSTODIAN SEED \u2014 the blessed path is --gcp-secret nomos-root-custodian-key;\n--seed-secret <b64> is break-glass (avoid in shell history), env NOMOS_ROOT_SEED is the CI lane.\n\nTHE BLESSED GOLDEN PATH:\n 1. githolon rebirth plan <ws>\n 2. githolon rebirth apply --plan <path> --gcp-secret nomos-root-custodian-key [--yes]\n 3. githolon replay <ws> (expect GREEN from intent 0)\n 4. githolon status <ws> (incarnation + supersession history)\n 5. githolon compat (clients raise CustodyBreak \u2014 choose adopt/reject)",
7995
+ flags: [
7996
+ ["--reason <text>", "the mandatory audit justification (fill it into the plan before apply)"],
7997
+ ["--out <dir>", "plan: an alternate output dir (default: rebirths/<date>-<ws>)"],
7998
+ ["--plan <plan.json>", "apply: the reviewed plan file to execute (drift-pinned)"],
7999
+ ["--gcp-secret <name>", "apply: read the root custodian seed from this GCP secret (blessed: nomos-root-custodian-key)"],
8000
+ ["--seed-secret <b64>", "apply: break-glass \u2014 the seed inline (avoid in shell history)"],
8001
+ ["--yes", "apply: skip the interactive confirm"],
8002
+ ["--cloud <url>", "target cloud"]
8003
+ ],
8004
+ examples: [
8005
+ "githolon rebirth plan co2-platform --reason 'evolve-gate scar at intent 74'",
8006
+ "githolon rebirth apply --plan rebirths/2026-07-09-co2-platform/plan.json --gcp-secret nomos-root-custodian-key --yes"
8007
+ ]
8008
+ },
7881
8009
  grant: {
7882
8010
  usage: "githolon grant <admin|creation|quota> <principal> [--max <N>] [--label <L>] [--parent <ws>] [--cloud <url>]",
7883
8011
  what: "Grant authority as a SIGNED governance offer to the parent (default root) \u2014 never a host\nendpoint. The grant is attributed to YOUR signing principal; only an admin's signature is\nadmitted by the far-side gate. `admin`/`creation` grant the principal-centric relation; `quota`\ngrants a per-principal workspace allowance (--max). Enroll a device key first (githolon key enroll).",
@@ -7958,15 +8086,15 @@ function commandHelp(cmd) {
7958
8086
  init_engine();
7959
8087
  init_cloud();
7960
8088
  init_local_holon();
7961
- import { spawnSync as spawnSync3 } from "node:child_process";
7962
- import { existsSync as existsSync8, readdirSync as readdirSync3, readFileSync as readFileSync9, writeFileSync as writeFileSync6 } from "node:fs";
7963
- import { join as join10 } from "node:path";
8089
+ import { spawnSync as spawnSync4 } from "node:child_process";
8090
+ import { existsSync as existsSync9, readdirSync as readdirSync4, readFileSync as readFileSync10, writeFileSync as writeFileSync7 } from "node:fs";
8091
+ import { join as join11 } from "node:path";
7964
8092
  var out7 = (s) => void process.stdout.write(s + "\n");
7965
8093
  var err7 = (s) => void process.stderr.write("error: " + s + "\n");
7966
8094
  var WS2 = "local";
7967
8095
  async function ledgerInit(dir, opts) {
7968
8096
  const cloud = cloudBase(opts.cloud);
7969
- if (existsSync8(dir) && readdirSync3(dir).length > 0) {
8097
+ if (existsSync9(dir) && readdirSync4(dir).length > 0) {
7970
8098
  err7(`refusing to mint into non-empty directory: ${dir}`);
7971
8099
  return 1;
7972
8100
  }
@@ -7977,7 +8105,7 @@ async function ledgerInit(dir, opts) {
7977
8105
  err7(e.message);
7978
8106
  return 1;
7979
8107
  }
7980
- const deployBody = JSON.parse(readFileSync9(deployFile, "utf8"));
8108
+ const deployBody = JSON.parse(readFileSync10(deployFile, "utf8"));
7981
8109
  const domainHash = await sha256hex(deployBody.packageUsda);
7982
8110
  const c = loadCreds();
7983
8111
  const principal = await sessionToken().catch(() => void 0) !== void 0 ? c.session.uid : c.principal;
@@ -7993,11 +8121,11 @@ async function ledgerInit(dir, opts) {
7993
8121
  const verdict = verifyChainLocal(eng, WS2);
7994
8122
  if (!printVerdict(verdict)) return 1;
7995
8123
  const gitTree = eng.preopen.dir.contents.get("ws").contents.get(WS2).contents.get("nomos.git");
7996
- const gitDir = join10(dir, ".git");
8124
+ const gitDir = join11(dir, ".git");
7997
8125
  writeTreeToDisk(gitTree, gitDir);
7998
- const cfgPath = join10(gitDir, "config");
7999
- writeFileSync6(cfgPath, readFileSync9(cfgPath, "utf8").replace(/bare = true/, "bare = false"), "utf8");
8000
- spawnSync3("git", ["-C", dir, "reset", "--hard", "main"], { stdio: "ignore" });
8126
+ const cfgPath = join11(gitDir, "config");
8127
+ writeFileSync7(cfgPath, readFileSync10(cfgPath, "utf8").replace(/bare = true/, "bare = false"), "utf8");
8128
+ spawnSync4("git", ["-C", dir, "reset", "--hard", "main"], { stdio: "ignore" });
8001
8129
  out7(`\u2713 holon written \u2192 ${dir} (a normal git repo; git log IS the audit trail)`);
8002
8130
  out7(`
8003
8131
  Birth it on Nomos Cloud (the cloud re-derives this exact verdict):`);
@@ -8005,8 +8133,8 @@ Birth it on Nomos Cloud (the cloud re-derives this exact verdict):`);
8005
8133
  return 0;
8006
8134
  }
8007
8135
  async function ledgerVerify(dir, opts) {
8008
- const gitDir = existsSync8(join10(dir, ".git")) ? join10(dir, ".git") : dir;
8009
- if (!existsSync8(join10(gitDir, "HEAD"))) {
8136
+ const gitDir = existsSync9(join11(dir, ".git")) ? join11(dir, ".git") : dir;
8137
+ if (!existsSync9(join11(gitDir, "HEAD"))) {
8010
8138
  err7(`${dir} is not a git repo (no HEAD)`);
8011
8139
  return 1;
8012
8140
  }
@@ -8480,7 +8608,8 @@ Governance (SIGNED client-side, relayed as {intentBytes} \u2014 never a host-aut
8480
8608
  githolon gov rebirth <ws> --reason <text> LAWFUL SUPERSESSION (recovery verb 3): supersede a
8481
8609
  [--dry-run [--json]] [--yes] scarred chain; --dry-run = READ-ONLY impact report
8482
8610
  githolon rebirth plan <ws> [--reason <text>] [--out D] write a stable plan.json + impact.md (rebirths-as-code)
8483
- githolon rebirth apply --plan <plan.json> [--yes] drift-pinned apply of a reviewed plan \u2192 certificate.json
8611
+ githolon rebirth apply --plan <plan.json> drift-pinned apply of a reviewed plan \u2192 certificate.json
8612
+ --gcp-secret nomos-root-custodian-key [--yes] (apply needs the ROOT CUSTODIAN seed; --gcp-secret is blessed)
8484
8613
  githolon replay <ws> --repair execute the repair matching a red verify (\u2192 certificate)
8485
8614
  githolon grant <admin|creation> <principal> [--label L] grant authority at the parent (default root)
8486
8615
  githolon grant quota <principal> --max <N> grant a per-principal workspace allowance
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "githolon",
3
- "version": "0.69.1",
3
+ "version": "0.69.3",
4
4
  "type": "module",
5
5
  "description": "githolon — the Nomos developer CLI: Rails-style generators for @githolon/dsl domains + the package compiler. Kernel-independent.",
6
6
  "license": "SEE LICENSE IN LICENSE.md",
@@ -29,8 +29,8 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "@bjorn3/browser_wasi_shim": "0.4.2",
32
- "@githolon/client": "^0.69.1",
33
- "@githolon/dsl": "^0.69.1",
32
+ "@githolon/client": "^0.69.3",
33
+ "@githolon/dsl": "^0.69.3",
34
34
  "isomorphic-git": "^1.38.4"
35
35
  },
36
36
  "devDependencies": {