githolon 0.100.6 → 0.101.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -328,6 +328,13 @@ var init_custody_transport = __esm({
328
328
  }
329
329
  });
330
330
 
331
+ // ../adapter/managed-promotion.ts
332
+ var init_managed_promotion = __esm({
333
+ "../adapter/managed-promotion.ts"() {
334
+ "use strict";
335
+ }
336
+ });
337
+
331
338
  // ../adapter/engine.ts
332
339
  import { WASI, File, Directory, OpenFile, ConsoleStdout, PreopenDirectory } from "@bjorn3/browser_wasi_shim";
333
340
  function b64Bytes(bytes) {
@@ -780,6 +787,9 @@ function evolveDryRun(eng, ws, usda, domainHash, dispositions = null) {
780
787
  function author(eng, ws, domain, directiveId, payload, controllerHash, opts = {}) {
781
788
  const seq = eng.seq++;
782
789
  const capPorts = { clock: { physical: Date.now(), logical: 0, replica: eng.replica }, rng: osEntropyBuffer(opts.rngDraws ?? 64) };
790
+ if (opts.__nomosConflictSnapshots !== void 0 && opts.__nomosConflictSnapshots.length > 0) {
791
+ capPorts.conflict_snapshots = opts.__nomosConflictSnapshots;
792
+ }
783
793
  if (opts.validFromEpoch !== void 0) capPorts.valid_from_epoch = opts.validFromEpoch;
784
794
  if (opts.principalVerified !== void 0) {
785
795
  capPorts.principal = opts.actor ?? "";
@@ -1376,26 +1386,89 @@ async function boot(eng, ws, ledger) {
1376
1386
  );
1377
1387
  }
1378
1388
  async function deploy(eng, ws, ledger, usda, domainHash, dispositions, opts = {}) {
1379
- const result = author(eng, ws, "nomos", "installDomain", installPayload(domainHash, usda, eng.installedBy, dispositions), eng.hashes.nomos, { actor: opts.actor ?? "", ...opts.authToken ? { authToken: opts.authToken } : {} });
1380
- if (result.ok === false) {
1389
+ const existing = qById(eng, ws, `domain-installation:${domainHash}`);
1390
+ if (existing.length > 0) {
1391
+ const phase = String(existing[0]?.data?.["status.phase"] ?? "");
1392
+ return {
1393
+ head: kgit.resolveRef(eng, gitdirOf(ws), BRANCH),
1394
+ installation: existing,
1395
+ staged: phase === "Pending",
1396
+ alreadyInstalled: true
1397
+ };
1398
+ }
1399
+ const before = currentLaw(eng, ws);
1400
+ const tenantHashes = [...new Set(Object.values(before).filter(
1401
+ (hash) => typeof hash === "string" && hash !== eng.hashes.bootstrap && hash !== eng.hashes.nomos
1402
+ ))];
1403
+ const upgrade = tenantHashes.length > 0;
1404
+ let supersedes = opts.supersedes?.trim() || void 0;
1405
+ if (supersedes !== void 0 && !tenantHashes.includes(supersedes)) {
1381
1406
  throw new Error(
1382
- `deploy-refused: installing ${domainHash.slice(0, 12)}\u2026 was REFUSED by the one gate (custody unchanged): ${result.error ?? "unknown refusal"}`
1407
+ `deploy-predecessor-changed: the client named ${supersedes.slice(0, 12)}\u2026 as the current model, but this workspace no longer serves it. Refresh and deploy again; nothing was committed.`
1383
1408
  );
1384
1409
  }
1385
- const installation = qById(eng, ws, `domain-installation:${domainHash}`);
1386
- const keys = installation[0]?.data?.domainKeys ?? installation[0]?.domainKeys ?? [];
1387
- if (keys.length > 0) {
1388
- const law = installedLaw(eng, ws);
1389
- const currentLaw2 = law?.currentLaw ?? {};
1390
- const stale = keys.filter((k) => currentLaw2[k] !== void 0 && currentLaw2[k] !== domainHash);
1391
- if (stale.length > 0) {
1410
+ if (upgrade && supersedes === void 0) {
1411
+ if (tenantHashes.length === 1) supersedes = tenantHashes[0];
1412
+ else {
1392
1413
  throw new Error(
1393
- `deploy-did-not-advance: the install of ${domainHash.slice(0, 12)}\u2026 ADMITTED but the workspace's current law still serves ${stale.map((k) => `'${k}' from ${String(currentLaw2[k]).slice(0, 12)}\u2026`).join(", ")} \u2014 refusing (custody unchanged) instead of a silent no-op. This usually means the existing installation's era/lineage prevents supersession: run \`githolon deploy --dry-run=evolve\` for the gate's verdict, supply #58 dispositions for a true removal/retype, or re-forge the workspace onto the current lineage.`
1414
+ `deploy-predecessor-ambiguous: this workspace currently serves ${tenantHashes.length} business-model packages. Nomos will not guess which one this candidate follows; use the generated deploy client, which binds the candidate to the current model before staging. Nothing was committed.`
1394
1415
  );
1395
1416
  }
1396
1417
  }
1397
- await commitAndPush(eng, ws, ledger);
1398
- return { head: result.head, installation };
1418
+ if (upgrade && dispositions && Object.keys(dispositions).length > 0) {
1419
+ throw new Error(
1420
+ "deploy-manual-evolution-refused: successor deployment no longer accepts caller-chosen schema dispositions. Schema evolution belongs to the candidate model's adoption proof; nothing was committed."
1421
+ );
1422
+ }
1423
+ const directiveId = upgrade ? "stageDomain" : "installDomain";
1424
+ const payload = upgrade ? stagePayload(domainHash, usda, eng.installedBy, supersedes) : installPayload(domainHash, usda, eng.installedBy, dispositions);
1425
+ const result = author(eng, ws, "nomos", directiveId, payload, eng.hashes.nomos, {
1426
+ actor: opts.actor ?? "",
1427
+ ...opts.authToken ? { authToken: opts.authToken } : {}
1428
+ });
1429
+ if (result.ok === false) {
1430
+ unmount(eng, ws);
1431
+ throw new Error(
1432
+ `deploy-refused: ${upgrade ? "staging" : "installing"} ${domainHash.slice(0, 12)}\u2026 was REFUSED by the one gate (custody unchanged): ${result.error ?? "unknown refusal"}`
1433
+ );
1434
+ }
1435
+ try {
1436
+ const installation = qById(eng, ws, `domain-installation:${domainHash}`);
1437
+ if (upgrade) {
1438
+ const phase = String(installation[0]?.data?.["status.phase"] ?? "");
1439
+ if (phase !== "Pending") {
1440
+ throw new Error(
1441
+ `deploy-did-not-stage: candidate ${domainHash.slice(0, 12)}\u2026 admitted but its lifecycle phase is '${phase || "missing"}', not Pending. Custody was not pushed.`
1442
+ );
1443
+ }
1444
+ const after = currentLaw(eng, ws);
1445
+ const moved = Object.entries(before).filter(([key, hash]) => after[key] !== hash);
1446
+ if (moved.length > 0 || Object.values(after).includes(domainHash)) {
1447
+ throw new Error(
1448
+ `deploy-activated-candidate: staging ${domainHash.slice(0, 12)}\u2026 changed served law (${moved.map(([key]) => key).join(", ") || "candidate became current"}). Nomos refuses to persist an upgrade that bypassed model.adopt().`
1449
+ );
1450
+ }
1451
+ await commitAndPush(eng, ws, ledger);
1452
+ return { head: result.head, installation, staged: true, supersedes };
1453
+ }
1454
+ const law = installedLaw(eng, ws);
1455
+ const installed = (law?.domains ?? []).find((row) => row?.domainHash === domainHash);
1456
+ const keys = installed?.domainKeys ?? installation[0]?.data?.domainKeys ?? installation[0]?.domainKeys ?? [];
1457
+ if (keys.length > 0) {
1458
+ const currentLaw2 = law?.currentLaw ?? {};
1459
+ const stale = keys.filter((k) => currentLaw2[k] !== domainHash);
1460
+ if (stale.length > 0) {
1461
+ throw new Error(
1462
+ `deploy-did-not-advance: the install of ${domainHash.slice(0, 12)}\u2026 ADMITTED but the workspace's current law still serves ${stale.map((k) => `'${k}' from ${String(currentLaw2[k]).slice(0, 12)}\u2026`).join(", ")} \u2014 refusing (custody unchanged) instead of a silent no-op. This usually means the existing installation's era/lineage prevents supersession: run \`githolon deploy --dry-run=evolve\` for the gate's verdict, supply #58 dispositions for a true removal/retype, or re-forge the workspace onto the current lineage.`
1463
+ );
1464
+ }
1465
+ }
1466
+ await commitAndPush(eng, ws, ledger);
1467
+ return { head: result.head, installation, staged: false };
1468
+ } catch (error) {
1469
+ unmount(eng, ws);
1470
+ throw error;
1471
+ }
1399
1472
  }
1400
1473
  function snapshot(eng, ws) {
1401
1474
  const wsDir = dirOf(eng.preopen.dir.contents.get("ws")).contents.get(ws);
@@ -1428,13 +1501,14 @@ async function ledgerStats(eng, ws, ledger = null) {
1428
1501
  if (mounted) mounted.ledgerStats = out;
1429
1502
  return out;
1430
1503
  }
1431
- var enc3, dec3, BRANCH, RESULT_PACK_INLINE_MAX, dirOf, repoArgOf, gitdirOf, unpack, log, repoArgOfGitdir, bytesFromB64, kgit, installPayload, routeTagHexOfHomeKey, SUMMARY_SEP, summaryKey, splitSummaryKey, NOMOS_SHARD_ROWS_READ, groupOf, tallyOf, isExtremumRead, extremumMonotone, pushVia, fullRef, applyPackInto, custodyLsRefs, qById, query, authorKeygen, attestedRead, certSign, readPosture, count, sum, pendingConflicts, spatialBboxParams, spatialWithin, extremum, nomosActive, refusedRefName, GENESIS_WARRANT_ID, isWarranted;
1504
+ var enc3, dec3, BRANCH, RESULT_PACK_INLINE_MAX, dirOf, repoArgOf, gitdirOf, unpack, log, repoArgOfGitdir, bytesFromB64, kgit, installPayload, stagePayload, routeTagHexOfHomeKey, SUMMARY_SEP, summaryKey, splitSummaryKey, NOMOS_SHARD_ROWS_READ, groupOf, tallyOf, isExtremumRead, extremumMonotone, pushVia, fullRef, applyPackInto, custodyLsRefs, qById, query, authorKeygen, attestedRead, certSign, readPosture, count, sum, pendingConflicts, pendingConflictSummary, spatialBboxParams, spatialWithin, extremum, nomosActive, refusedRefName, GENESIS_WARRANT_ID, isWarranted;
1432
1505
  var init_engine = __esm({
1433
1506
  "../adapter/engine.ts"() {
1434
1507
  "use strict";
1435
1508
  init_git_fs();
1436
1509
  init_tree();
1437
1510
  init_custody_transport();
1511
+ init_managed_promotion();
1438
1512
  enc3 = new TextEncoder();
1439
1513
  dec3 = new TextDecoder();
1440
1514
  BRANCH = "main";
@@ -1480,6 +1554,14 @@ var init_engine = __esm({
1480
1554
  }, eng.STDERR)).oid
1481
1555
  };
1482
1556
  installPayload = (hash, usda, installedBy, dispositions) => ({ domainHash: hash, packageUsda: usda, installedBy, dependencies: [], finalizers: [], ...dispositions ? { dispositions } : {} });
1557
+ stagePayload = (hash, usda, installedBy, supersedes) => ({
1558
+ domainHash: hash,
1559
+ packageUsda: usda,
1560
+ installedBy,
1561
+ dependencies: [],
1562
+ ...supersedes ? { supersedes } : {},
1563
+ finalizers: []
1564
+ });
1483
1565
  routeTagHexOfHomeKey = async (homeKey) => (await sha256hex(`nomos-route:${homeKey}`)).slice(0, 12);
1484
1566
  SUMMARY_SEP = "";
1485
1567
  summaryKey = (readId, group) => `${readId}${SUMMARY_SEP}${group}`;
@@ -1547,7 +1629,8 @@ var init_engine = __esm({
1547
1629
  readPosture = (eng, ws, principal = "", authToken = "", nowUnix = 0) => JSON.parse(call(eng.ex, "query", { repoArg: repoArgOf(ws), workspace: ws, queryBytes: b64Json({ op: "readPosture", authToken, nowUnix }), principal, branch: BRANCH }, eng.STDERR));
1548
1630
  count = (eng, ws, countId, groupKey, principal = "") => JSON.parse(call(eng.ex, "query", { repoArg: repoArgOf(ws), workspace: ws, queryBytes: b64Json({ op: "count", countId, groupKey }), principal, branch: BRANCH }, eng.STDERR));
1549
1631
  sum = (eng, ws, sumId, groupKey, principal = "") => JSON.parse(call(eng.ex, "query", { repoArg: repoArgOf(ws), workspace: ws, queryBytes: b64Json({ op: "sum", sumId, groupKey }), principal, branch: BRANCH }, eng.STDERR));
1550
- pendingConflicts = (eng, ws, principal = "") => JSON.parse(call(eng.ex, "query", { repoArg: repoArgOf(ws), workspace: ws, queryBytes: b64Json({ op: "pendingConflicts" }), principal, branch: BRANCH }, eng.STDERR));
1632
+ pendingConflicts = (eng, ws, principal = "", aggregateType = "") => JSON.parse(call(eng.ex, "query", { repoArg: repoArgOf(ws), workspace: ws, queryBytes: b64Json({ op: "pendingConflicts", aggregateType }), principal, branch: BRANCH }, eng.STDERR));
1633
+ pendingConflictSummary = (eng, ws, principal = "") => JSON.parse(call(eng.ex, "query", { repoArg: repoArgOf(ws), workspace: ws, queryBytes: b64Json({ op: "pendingConflictSummary" }), principal, branch: BRANCH }, eng.STDERR));
1551
1634
  spatialBboxParams = (bbox) => {
1552
1635
  const minX = bbox.minX ?? bbox.minLng, minY = bbox.minY ?? bbox.minLat, maxX = bbox.maxX ?? bbox.maxLng, maxY = bbox.maxY ?? bbox.maxLat;
1553
1636
  return { minX, minY, maxX, maxY, minLng: minX, minLat: minY, maxLng: maxX, maxLat: maxY };
@@ -1579,6 +1662,7 @@ var init_types = __esm({
1579
1662
  var bootstrap_exports = {};
1580
1663
  __export(bootstrap_exports, {
1581
1664
  bootstrapPlatform: () => bootstrapPlatform,
1665
+ completeDevAuthProviderPayload: () => completeDevAuthProviderPayload,
1582
1666
  homeDomainOf: () => homeDomainOf,
1583
1667
  isTestMint: () => isTestMint
1584
1668
  });
@@ -1592,10 +1676,42 @@ function isTestMint(eng) {
1592
1676
  return !/poisoned|unknown|adapter-visible API/.test(errMsg(e));
1593
1677
  }
1594
1678
  }
1679
+ function completeDevAuthProviderPayload(deployBody, homeDomain, initial, nowMillis = Date.now(), operator = "user:dev-operator") {
1680
+ const payload = { ...initial };
1681
+ const iface = deployBody?.interface ?? {};
1682
+ const legacy = iface.domains?.[homeDomain]?.directives?.setAuthProvider?.fields ?? iface[homeDomain]?.directives?.setAuthProvider?.fields ?? {};
1683
+ const openapi = deployBody?.openapi;
1684
+ const frameworkPaths = openapi?.["x-nomos-framework-routes"]?.paths ?? {};
1685
+ const setAuthOperation = Object.values(frameworkPaths).map((pathItem) => pathItem.post).filter((operation) => operation?.["x-nomos"]?.directiveId === "setAuthProvider").sort((a, b) => Number(b?.["x-nomos"]?.domain === homeDomain) - Number(a?.["x-nomos"]?.domain === homeDomain))[0] ?? frameworkPaths["/setAuthProvider"]?.post;
1686
+ const schema = setAuthOperation?.requestBody?.content?.["application/json"]?.schema;
1687
+ const required = new Set(schema?.required ?? []);
1688
+ const fields = { ...legacy };
1689
+ for (const [name, spec] of Object.entries(schema?.properties ?? {})) {
1690
+ fields[name] = {
1691
+ kind: spec.type === "integer" ? "int" : spec.type,
1692
+ optional: !required.has(name)
1693
+ };
1694
+ }
1695
+ for (const [name, spec] of Object.entries(fields)) {
1696
+ if (spec.optional === true || payload[name] !== void 0) continue;
1697
+ if (spec.kind === "int" && /At$/.test(name)) payload[name] = nowMillis;
1698
+ else if (spec.kind === "string" && /At$/.test(name)) payload[name] = new Date(nowMillis).toISOString();
1699
+ else if (spec.kind === "string" && /By$/.test(name)) payload[name] = operator;
1700
+ else if (spec.kind === "string" && /url$/i.test(name)) payload[name] = `${payload.issuer}/jwks.json`;
1701
+ else if (spec.kind === "string") payload[name] = "dev";
1702
+ else log2(`dev test IdP: required setAuthProvider field '${name}' (kind ${spec.kind}) is not synthesizable \u2014 the author below may refuse typed`);
1703
+ }
1704
+ return payload;
1705
+ }
1595
1706
  function homeDomainOf(opts) {
1596
1707
  if (!opts || !opts.deploy) return null;
1597
1708
  try {
1598
1709
  const body = JSON.parse(readFileSync(opts.deploy, "utf8"));
1710
+ const frameworkPaths = body.openapi?.["x-nomos-framework-routes"]?.paths ?? {};
1711
+ for (const pathItem of Object.values(frameworkPaths)) {
1712
+ const route = pathItem.post?.["x-nomos"];
1713
+ if (route?.directiveId === "birthHome" && typeof route.domain === "string") return route.domain;
1714
+ }
1599
1715
  const domains = body.summary && body.summary.domains || [];
1600
1716
  const hit = domains.find((d) => Array.isArray(d.directives) && d.directives.includes("seedBirthAttestation"));
1601
1717
  return hit ? hit.domain : null;
@@ -1655,6 +1771,19 @@ async function bootstrapPlatform(dev, opts) {
1655
1771
  setTestKRoot(eng, kRoot.public);
1656
1772
  log2(`K_root ceremony: pinned LOCAL test K_root ${kRoot.public.slice(0, 16)}\u2026`);
1657
1773
  const sP = authorKeygen(eng);
1774
+ const { generateKeyPairSync, sign: nodeSign } = await import("node:crypto");
1775
+ const { privateKey: idpPrivateKey, publicKey: idpPublicKey } = generateKeyPairSync("ec", { namedCurve: "P-256" });
1776
+ const idpJwk = idpPublicKey.export({ format: "jwk" });
1777
+ const idpIssuer = `https://dev-idp.local/${platform}`;
1778
+ const idpAudience = `${platform}-app`;
1779
+ const idpJwks = JSON.stringify({ keys: [{ kty: "EC", crv: "P-256", kid: "dev-idp", alg: "ES256", use: "sig", x: idpJwk.x, y: idpJwk.y }] });
1780
+ const b64url = (b) => Buffer.from(b).toString("base64url");
1781
+ const mintDevToken = (claims) => {
1782
+ const header = b64url(JSON.stringify({ alg: "ES256", typ: "JWT", kid: "dev-idp" }));
1783
+ const payload = b64url(JSON.stringify({ iss: idpIssuer, aud: idpAudience, nbf: 0, exp: 4102444800, ...claims }));
1784
+ const si = `${header}.${payload}`;
1785
+ return `${si}.${b64url(nodeSign("sha256", Buffer.from(si), { key: idpPrivateKey, dsaEncoding: "ieee-p1363" }))}`;
1786
+ };
1658
1787
  const platformCert = certSign(eng, {
1659
1788
  child: platform,
1660
1789
  founder: OPERATOR,
@@ -1663,6 +1792,9 @@ async function bootstrapPlatform(dev, opts) {
1663
1792
  // P_P — the onboarding signer the platform vouches for
1664
1793
  parentId: "root",
1665
1794
  epoch: 0,
1795
+ authProviderIssuer: idpIssuer,
1796
+ authProviderJwks: idpJwks,
1797
+ authProviderAudience: idpAudience,
1666
1798
  secret: kRoot.secret
1667
1799
  // signed by S_root
1668
1800
  });
@@ -1681,38 +1813,14 @@ async function bootstrapPlatform(dev, opts) {
1681
1813
  let devIdP;
1682
1814
  let pendingIdP;
1683
1815
  {
1684
- const { generateKeyPairSync, sign: nodeSign } = await import("node:crypto");
1685
- const { privateKey, publicKey } = generateKeyPairSync("ec", { namedCurve: "P-256" });
1686
- const jwk = publicKey.export({ format: "jwk" });
1687
- const ISS = `https://dev-idp.local/${platform}`;
1688
- const AUD = `${platform}-app`;
1689
- const JWKS = JSON.stringify({ keys: [{ kty: "EC", crv: "P-256", kid: "dev-idp", alg: "ES256", use: "sig", x: jwk.x, y: jwk.y }] });
1690
- const b64url = (b) => Buffer.from(b).toString("base64url");
1691
- const mint = (claims) => {
1692
- const header = b64url(JSON.stringify({ alg: "ES256", typ: "JWT", kid: "dev-idp" }));
1693
- const payload = b64url(JSON.stringify({ iss: ISS, aud: AUD, nbf: 0, exp: 4102444800, ...claims }));
1694
- const si = `${header}.${payload}`;
1695
- return `${si}.${b64url(nodeSign("sha256", Buffer.from(si), { key: privateKey, dsaEncoding: "ieee-p1363" }))}`;
1696
- };
1697
- const apPayload = { issuer: ISS, keys: JWKS, audience: AUD, principalClaim: "sub", deviceBindingClaim: "nonce" };
1816
+ let apPayload = { issuer: idpIssuer, keys: idpJwks, audience: idpAudience, principalClaim: "sub", deviceBindingClaim: "nonce" };
1698
1817
  try {
1699
1818
  const deployBody = opts.deploy ? JSON.parse(readFileSync(opts.deploy, "utf8")) : null;
1700
- const iface = deployBody?.interface ?? {};
1701
- const domIface = iface.domains?.[homeDomain] ?? iface[homeDomain];
1702
- const fields = domIface?.directives?.["setAuthProvider"]?.fields ?? {};
1703
- for (const [name, spec] of Object.entries(fields)) {
1704
- if (spec?.optional === true || apPayload[name] !== void 0) continue;
1705
- if (spec?.kind === "int" && /At$/.test(name)) apPayload[name] = Date.now();
1706
- else if (spec?.kind === "string" && /At$/.test(name)) apPayload[name] = (/* @__PURE__ */ new Date()).toISOString();
1707
- else if (spec?.kind === "string" && /By$/.test(name)) apPayload[name] = OPERATOR;
1708
- else if (spec?.kind === "string" && /url$/i.test(name)) apPayload[name] = `${ISS}/jwks.json`;
1709
- else if (spec?.kind === "string") apPayload[name] = "dev";
1710
- else log2(`dev test IdP: required setAuthProvider field '${name}' (kind ${spec?.kind}) is not synthesizable \u2014 the author below may refuse typed`);
1711
- }
1819
+ apPayload = completeDevAuthProviderPayload(deployBody, homeDomain, apPayload, Date.now(), OPERATOR);
1712
1820
  } catch (e) {
1713
1821
  log2(`dev test IdP: BYO-shape fill failed (${errMsg(e).slice(0, 200)}) \u2014 the canonical payload stands`);
1714
1822
  }
1715
- pendingIdP = { ISS, AUD, JWKS, mint, apPayload };
1823
+ pendingIdP = { ISS: idpIssuer, AUD: idpAudience, JWKS: idpJwks, mint: mintDevToken, apPayload };
1716
1824
  }
1717
1825
  const sOp = authorKeygen(eng);
1718
1826
  const opKeyHash = createHash("sha256").update(Buffer.from(sOp.public, "base64")).digest("hex");
@@ -1890,6 +1998,12 @@ function resolveGatewayOperation(spec, opName, method) {
1890
1998
  return { op: null, ambiguous: null };
1891
1999
  }
1892
2000
 
2001
+ // ../cloud/cloudflare-shell/src/kernel-registry.generated.ts
2002
+ var DEPLOYED_KERNELS = [
2003
+ { prefix: "cf01b3ae", hash: "cf01b3ae327618b26da3af8eb6abe5e16a7f050e8a9d9b6ca92e2a1d78dd280b", version: "kernel-cf01b3ae", note: "production (this candidate)", features: ["compoundKeys", "capturedReads", "invariantGate", "surfacedMerge", "fieldProvenance", "nullSemantics", "attestedReads", "conflictSnapshots", "ownedAudience"] },
2004
+ { prefix: "4f8ffb62", hash: "4f8ffb623c3717d973b1ced653e23f7a8f63fe73b83aa5a0f83f4dd8c46bd81f", version: "kernel-4f8ffb62", note: "test-mint (this candidate) \u2014 feature-equivalent to production", features: ["compoundKeys", "capturedReads", "invariantGate", "surfacedMerge", "fieldProvenance", "nullSemantics", "attestedReads", "conflictSnapshots", "ownedAudience"] }
2005
+ ];
2006
+
1893
2007
  // ../cloud/cloudflare-shell/src/staged-intents.ts
1894
2008
  var STAGE_THRESHOLD_CHARS = 4 * 1024 * 1024;
1895
2009
  var MAX_INLINE_INTENT_CHARS = 8 * 1024 * 1024;
@@ -2108,7 +2222,13 @@ function firstExisting(...paths) {
2108
2222
  }
2109
2223
  var TEST_MINT_MARKER = Buffer.from("set_test_k_root");
2110
2224
  var isTestMintBytes = (bytes) => bytes.includes(TEST_MINT_MARKER);
2111
- var KERNEL_CAPABILITY_REGISTRY = [
2225
+ var HISTORICAL_KERNEL_CAPABILITY_REGISTRY = [
2226
+ {
2227
+ prefix: "f50d0cc5",
2228
+ version: "kernel-f50d0cc5",
2229
+ note: "current local production build",
2230
+ features: ["compoundKeys", "capturedReads", "invariantGate", "surfacedMerge", "fieldProvenance", "nullSemantics", "attestedReads"]
2231
+ },
2112
2232
  {
2113
2233
  prefix: "846c6bf8",
2114
2234
  version: "kernel-846c6bf8",
@@ -2128,6 +2248,10 @@ var KERNEL_CAPABILITY_REGISTRY = [
2128
2248
  features: ["capturedReads", "invariantGate", "surfacedMerge", "fieldProvenance", "nullSemantics", "attestedReads"]
2129
2249
  }
2130
2250
  ];
2251
+ var KERNEL_CAPABILITY_REGISTRY = [
2252
+ ...DEPLOYED_KERNELS,
2253
+ ...HISTORICAL_KERNEL_CAPABILITY_REGISTRY
2254
+ ];
2131
2255
  function capabilitiesForKernelHash(hash) {
2132
2256
  const h = String(hash || "").toLowerCase();
2133
2257
  const hit = KERNEL_CAPABILITY_REGISTRY.find((e) => h.startsWith(e.prefix) || e.prefix.startsWith(h.slice(0, 8)));
@@ -2367,7 +2491,10 @@ async function startDevCloud(opts = {}) {
2367
2491
  dataDir,
2368
2492
  wasmPath,
2369
2493
  workspaces: custody.list(),
2370
- ...devSelf?.platformReady !== void 0 ? { platformReady: devSelf.platformReady } : {}
2494
+ ...devSelf?.platformReady !== void 0 ? { platformReady: devSelf.platformReady } : {},
2495
+ // DEV/HARNESS ONLY: every peer in this ephemeral trust universe must pin the same K_root before
2496
+ // replaying or birthing descendants. Production bakes the one real anchor into the kernel.
2497
+ ...devSelf?.testKRoot?.public ? { testKRootPublic: devSelf.testKRoot.public } : {}
2371
2498
  });
2372
2499
  }
2373
2500
  if (url.pathname === "/dev/mint-token" && req.method === "POST") {
@@ -2500,10 +2627,19 @@ async function startDevCloud(opts = {}) {
2500
2627
  const authToken = authTokenOf(req);
2501
2628
  try {
2502
2629
  const out = await deploy(eng, ws, ledger, usda, domainHash, dispositions, { actor, ...authToken ? { authToken } : {} });
2503
- sendJson(res, { ok: true, ws, domainHash, head: out.head, installation: out.installation }, 201);
2630
+ sendJson(res, {
2631
+ ok: true,
2632
+ ws,
2633
+ domainHash,
2634
+ head: out.head,
2635
+ installation: out.installation,
2636
+ staged: out.staged === true,
2637
+ ...out.supersedes ? { supersedes: out.supersedes } : {},
2638
+ ...out.alreadyInstalled ? { alreadyInstalled: true } : {}
2639
+ }, 201);
2504
2640
  } catch (e) {
2505
2641
  const msg = errMsg(e);
2506
- const status = /deploy-did-not-advance/.test(msg) ? 409 : 422;
2642
+ const status = /deploy-did-not-advance|deploy-did-not-stage|deploy-predecessor|deploy-activated-candidate/.test(msg) ? 409 : 422;
2507
2643
  sendJson(res, { ok: false, refused: true, error: msg.slice(0, 600) }, status);
2508
2644
  }
2509
2645
  });
@@ -2721,7 +2857,8 @@ async function startDevCloud(opts = {}) {
2721
2857
  if (x.kind === "sum") return sendJson(res, { ok: true, ws, ...sum(eng, ws, x.sumId, group, principal) });
2722
2858
  if (x.kind === "extremum") return sendJson(res, { ok: true, ws, ...extremum(eng, ws, x.extremumId, x.extremumKind || url.searchParams.get("kind") || "", group, principal) });
2723
2859
  if (x.kind === "spatial") return sendJson(res, { ok: true, ws, ...spatialWithin(eng, ws, x.spatialId, url.searchParams.get("bbox") || {}, principal) });
2724
- if (x.kind === "pendingConflicts") return sendJson(res, { ok: true, ws, rows: pendingConflicts(eng, ws, principal) });
2860
+ if (x.kind === "pendingConflicts") return sendJson(res, { ok: true, ws, rows: pendingConflicts(eng, ws, principal, url.searchParams.get("aggregateType") || "") });
2861
+ if (x.kind === "pendingConflictSummary") return sendJson(res, { ok: true, ws, ...pendingConflictSummary(eng, ws, principal) });
2725
2862
  } catch (e) {
2726
2863
  return sendJson(res, { ok: false, error: errMsg(e).slice(0, 600) }, 403);
2727
2864
  }