@githolon/dsl 0.103.9 → 0.103.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dart/CHANGELOG.md +11 -0
- package/dart/lib/src/runner/node-entry.mjs +83 -20
- package/dart/lib/src/runner/offline-install.mjs +2 -2
- package/dart/lib/src/webview_bridge.dart +65 -0
- package/dart/pubspec.yaml +1 -1
- package/dart/test/acquire_session_test.dart +73 -0
- package/package.json +1 -1
- package/runtime/generated-application-host.js +73 -18
- package/src/compile_package_main.ts +2 -2
package/dart/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
## 0.64.10
|
|
2
|
+
|
|
3
|
+
- Single-flight each generated child open on the process-wide kernel plane, reuse resident sibling custody
|
|
4
|
+
for foreign reads, and restore every generated child from framework-owned local custody before consulting
|
|
5
|
+
cloud transport. Typed kernel refusals and the offer gate remain the only authority path.
|
|
6
|
+
|
|
7
|
+
## 0.64.9
|
|
8
|
+
|
|
9
|
+
- Cache the installed structural law interface across generated domain binding, eliminating repeated
|
|
10
|
+
full-interface kernel reads while retaining governed invalidation on replay and law changes.
|
|
11
|
+
|
|
1
12
|
## 0.64.8
|
|
2
13
|
|
|
3
14
|
- Deduplicate structurally identical workspace and application status snapshots while still seeding every
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// <define:__NOMOS_KERNEL_RELEASE__>
|
|
4
|
-
var define_NOMOS_KERNEL_RELEASE_default = { production: { hash: "
|
|
4
|
+
var define_NOMOS_KERNEL_RELEASE_default = { production: { hash: "d512065a204a4b5ac59dd8dfc262d98e49d9e47823582a6123351f4668c68c8b", version: "kernel-d512065a", features: ["compoundKeys", "capturedReads", "invariantGate", "surfacedMerge", "fieldProvenance", "nullSemantics", "attestedReads", "conflictSnapshots", "ownedAudience"], protocol: 1 }, testMint: { hash: "1c66f90d98e71f451b5d3505bba09b66694a22674845e2fd499468854c1a0aae", version: "kernel-1c66f90d", features: ["compoundKeys", "capturedReads", "invariantGate", "surfacedMerge", "fieldProvenance", "nullSemantics", "attestedReads", "conflictSnapshots", "ownedAudience"], protocol: 1 } };
|
|
5
5
|
|
|
6
6
|
// runner/node-entry.ts
|
|
7
7
|
import { createInterface } from "node:readline";
|
|
@@ -427,7 +427,15 @@ function createWebviewRunner({ post: post2, openRealm: openRealm2 }) {
|
|
|
427
427
|
async refreshCredentials(a) {
|
|
428
428
|
const rec = pickSession(a);
|
|
429
429
|
const holon = await liveHolon(rec);
|
|
430
|
-
if (typeof holon.
|
|
430
|
+
if (typeof holon.refreshCredentials === "function") {
|
|
431
|
+
const result2 = holon.refreshCredentials({
|
|
432
|
+
...a.authToken !== void 0 ? { authToken: String(a.authToken) } : {},
|
|
433
|
+
...a.authorSecret !== void 0 ? { authorSecret: String(a.authorSecret) } : {}
|
|
434
|
+
});
|
|
435
|
+
if (rec.autoStop?.trigger) rec.autoStop.trigger("credential-refresh");
|
|
436
|
+
return result2;
|
|
437
|
+
}
|
|
438
|
+
if (typeof holon.refreshAuthToken !== "function") throw new Error("connected holon cannot refresh credentials in place");
|
|
431
439
|
const result = holon.refreshAuthToken(String(a.authToken ?? ""));
|
|
432
440
|
if (rec.autoStop?.trigger) rec.autoStop.trigger("credential-refresh");
|
|
433
441
|
return result;
|
|
@@ -6811,7 +6819,7 @@ function providerOperation(mode, rawFields, workBytes) {
|
|
|
6811
6819
|
else throw new Error(`no typed protobuf operation for provider call '${mode}'`);
|
|
6812
6820
|
return { case: "custody", value: create(CustodyRequestSchema, { operation: custody }) };
|
|
6813
6821
|
}
|
|
6814
|
-
function nmsInternalReportProviderTransport(host, encoded, phases, responseBytes) {
|
|
6822
|
+
function nmsInternalReportProviderTransport(host, encoded, phases, responseBytes, context = {}) {
|
|
6815
6823
|
const rounded = Object.fromEntries(Object.entries({ encode: encoded.encodeMs, ...phases }).map(([key, value]) => [key, Math.round(value * 1e3) / 1e3]));
|
|
6816
6824
|
const totalMs = Object.values(rounded).reduce((sum, value) => sum + value, 0);
|
|
6817
6825
|
const debug2 = globalThis.__NOMOS_PROFILE_TRANSPORT__ === true || globalThis.process?.env?.NOMOS_PROFILE_TRANSPORT === "1";
|
|
@@ -6819,10 +6827,13 @@ function nmsInternalReportProviderTransport(host, encoded, phases, responseBytes
|
|
|
6819
6827
|
console.warn(`[nomos-transport-perf] ${JSON.stringify({
|
|
6820
6828
|
host,
|
|
6821
6829
|
mode: encoded.mode,
|
|
6830
|
+
detail: encoded.detail,
|
|
6831
|
+
requestId: encoded.requestId,
|
|
6822
6832
|
totalMs: Math.round(totalMs * 1e3) / 1e3,
|
|
6823
6833
|
phases: rounded,
|
|
6824
6834
|
requestBytes: encoded.bytes.length,
|
|
6825
|
-
responseBytes
|
|
6835
|
+
responseBytes,
|
|
6836
|
+
...context
|
|
6826
6837
|
})}`);
|
|
6827
6838
|
}
|
|
6828
6839
|
function nmsInternalEncodeProviderCall(mode, fields, workBytes, requestPrefix = "browser") {
|
|
@@ -6839,7 +6850,9 @@ function nmsInternalEncodeTypedProviderCall(operation, requestPrefix = "browser"
|
|
|
6839
6850
|
requestId,
|
|
6840
6851
|
operation
|
|
6841
6852
|
}));
|
|
6842
|
-
|
|
6853
|
+
const query = operation.case === "query" ? operation.value.query : void 0;
|
|
6854
|
+
const detail = query?.case === "named" ? `query:named:${String(query.value.operation)}` : query?.case ? `query:${query.case}` : operation.case || "empty";
|
|
6855
|
+
return { requestId, mode: operation.case || "empty", detail, bytes, encodeMs: monotonicMs() - started };
|
|
6843
6856
|
}
|
|
6844
6857
|
function nmsInternalDecodeProviderResponse(bytes, requestId, stderr = []) {
|
|
6845
6858
|
const response = fromBinary(CallResponseSchema, bytes);
|
|
@@ -6900,7 +6913,8 @@ function nmsInternalDecodeProviderResponse(bytes, requestId, stderr = []) {
|
|
|
6900
6913
|
verdictDecodeUs: Number(result.value.spans.verdictDecodeUs),
|
|
6901
6914
|
promoteAndCleanupRefsUs: Number(result.value.spans.promoteAndCleanupRefsUs),
|
|
6902
6915
|
frontierRebuildUs: Number(result.value.spans.frontierRebuildUs),
|
|
6903
|
-
frontierStoreUs: Number(result.value.spans.frontierStoreUs)
|
|
6916
|
+
frontierStoreUs: Number(result.value.spans.frontierStoreUs),
|
|
6917
|
+
verification: result.value.spans.verification ? jsVerifyChainDiagnostics(result.value.spans.verification) : void 0
|
|
6904
6918
|
} : void 0
|
|
6905
6919
|
});
|
|
6906
6920
|
case "repoStats":
|
|
@@ -6969,7 +6983,15 @@ function jsVerifyChainDiagnostics(diagnostics) {
|
|
|
6969
6983
|
typedInstallVerifierUs: Number(step.phases.typedInstallVerifierUs),
|
|
6970
6984
|
admissionUs: Number(step.phases.admissionUs),
|
|
6971
6985
|
foldUs: Number(step.phases.foldUs)
|
|
6972
|
-
} : void 0
|
|
6986
|
+
} : void 0,
|
|
6987
|
+
engineTimings: step.engineTimings.map((timing) => ({
|
|
6988
|
+
phase: timing.phase,
|
|
6989
|
+
totalUs: Number(timing.totalUs)
|
|
6990
|
+
}))
|
|
6991
|
+
})),
|
|
6992
|
+
engineTimings: diagnostics.engineTimings.map((timing) => ({
|
|
6993
|
+
phase: timing.phase,
|
|
6994
|
+
totalUs: Number(timing.totalUs)
|
|
6973
6995
|
}))
|
|
6974
6996
|
};
|
|
6975
6997
|
}
|
|
@@ -7017,7 +7039,7 @@ function nmsInternalParseSnapshot(bytes) {
|
|
|
7017
7039
|
return { treeBytes: bytes, ckpt: null, frontier: null, cursor: null, stateRoot: null, syncedBase: null };
|
|
7018
7040
|
}
|
|
7019
7041
|
function nmsInternalBuildSnapshot(treeBytes, ckpt, syncedBase) {
|
|
7020
|
-
const hasCheckpoint = !!(ckpt && (ckpt.blob || ckpt.frontier || ckpt.cursor
|
|
7042
|
+
const hasCheckpoint = !!(ckpt && (ckpt.blob || ckpt.frontier || ckpt.cursor));
|
|
7021
7043
|
if (!hasCheckpoint && !syncedBase) return treeBytes;
|
|
7022
7044
|
return enc2.encode(JSON.stringify({
|
|
7023
7045
|
v: 2,
|
|
@@ -7163,7 +7185,7 @@ function createWasmEnginePlane({ span } = {}) {
|
|
|
7163
7185
|
const view = {
|
|
7164
7186
|
/** The parsed restore checkpoint (so index.mjs can drive checkpoint_import after boot, exactly as before). */
|
|
7165
7187
|
get restoreCheckpoint() {
|
|
7166
|
-
return _ckptBlobStr || _ckptFrontierStr || _ckptCursor
|
|
7188
|
+
return _ckptBlobStr || _ckptFrontierStr || _ckptCursor ? { blob: _ckptBlobStr, frontier: _ckptFrontierStr, cursor: _ckptCursor, stateRoot: _ckptStateRoot } : null;
|
|
7167
7189
|
},
|
|
7168
7190
|
/** The converged fork point persisted in the restoreFrom snapshot (null for old/tree-only snapshots). */
|
|
7169
7191
|
get restoreSyncedBase() {
|
|
@@ -7337,7 +7359,7 @@ function createWasmEnginePlane({ span } = {}) {
|
|
|
7337
7359
|
const treeBytes = serializeTree(wsDirNode);
|
|
7338
7360
|
return nmsInternalBuildSnapshot(
|
|
7339
7361
|
treeBytes,
|
|
7340
|
-
ckpt && (ckpt.blob || ckpt.frontier || ckpt.cursor
|
|
7362
|
+
ckpt && (ckpt.blob || ckpt.frontier || ckpt.cursor) ? ckpt : null,
|
|
7341
7363
|
opts.syncedBase || null
|
|
7342
7364
|
);
|
|
7343
7365
|
}
|
|
@@ -8605,7 +8627,7 @@ async function connectSingle({ cloud, workspace, clientId, authToken, restoreFro
|
|
|
8605
8627
|
if (salvageOnly) allowUnborn = true;
|
|
8606
8628
|
if (!cloud || !workspace) throw new Error("connect({ cloud, workspace }) required");
|
|
8607
8629
|
const _fetch = typeof fetchImpl === "function" ? fetchImpl : globalThis.fetch;
|
|
8608
|
-
|
|
8630
|
+
let deviceSecret = authorSecret || "";
|
|
8609
8631
|
const base = cloud.replace(/\/+$/, "");
|
|
8610
8632
|
const localOnly = /^local:\/\//i.test(base);
|
|
8611
8633
|
const historicSnapshotConfig = historicSnapshots === false ? null : historicSnapshots && typeof historicSnapshots === "object" ? historicSnapshots : {};
|
|
@@ -8849,9 +8871,11 @@ ${String(commit).toLowerCase()}`;
|
|
|
8849
8871
|
const watchStops = /* @__PURE__ */ new Set();
|
|
8850
8872
|
let installedLawRowsCache;
|
|
8851
8873
|
let installedLawCurrentCache;
|
|
8852
|
-
|
|
8874
|
+
let installedInterfaceCache;
|
|
8875
|
+
const invalidateInstalledLawMetadata = () => {
|
|
8853
8876
|
installedLawRowsCache = void 0;
|
|
8854
8877
|
installedLawCurrentCache = void 0;
|
|
8878
|
+
installedInterfaceCache = void 0;
|
|
8855
8879
|
};
|
|
8856
8880
|
let _disposed = false;
|
|
8857
8881
|
const nudgeWatches = () => {
|
|
@@ -9196,10 +9220,13 @@ ${String(commit).toLowerCase()}`;
|
|
|
9196
9220
|
const compatGuardWrite = (directiveId, force) => assertWriteShippable(compatState, directiveId, { force, workspace });
|
|
9197
9221
|
let _lastInterfaceReadError = null;
|
|
9198
9222
|
const installedInterfaceInner = () => {
|
|
9223
|
+
if (installedInterfaceCache !== void 0) return installedInterfaceCache;
|
|
9199
9224
|
try {
|
|
9200
9225
|
const compact2 = JSON.parse(call("query", { queryBytes: qBytes({ op: "interfaceOffer" }) }));
|
|
9201
9226
|
_lastInterfaceReadError = null;
|
|
9202
|
-
|
|
9227
|
+
const installedInterface = compact2 && typeof compact2 === "object" && !Array.isArray(compact2) && Object.keys(compact2).length ? compact2 : null;
|
|
9228
|
+
installedInterfaceCache = installedInterface;
|
|
9229
|
+
return installedInterface;
|
|
9203
9230
|
} catch (error) {
|
|
9204
9231
|
_lastInterfaceReadError = error instanceof Error ? error : new Error(String(error));
|
|
9205
9232
|
return null;
|
|
@@ -9339,7 +9366,7 @@ ${String(commit).toLowerCase()}`;
|
|
|
9339
9366
|
}
|
|
9340
9367
|
}
|
|
9341
9368
|
}
|
|
9342
|
-
|
|
9369
|
+
invalidateInstalledLawMetadata();
|
|
9343
9370
|
nudgeWatches();
|
|
9344
9371
|
return {
|
|
9345
9372
|
upToDate: false,
|
|
@@ -9481,22 +9508,35 @@ ${String(commit).toLowerCase()}`;
|
|
|
9481
9508
|
};
|
|
9482
9509
|
return err;
|
|
9483
9510
|
};
|
|
9484
|
-
if (ckptBlobStr || ckptFrontierStr || ckptStagedFrontierFile || ckptCursor
|
|
9511
|
+
if (ckptBlobStr || ckptFrontierStr || ckptStagedFrontierFile || ckptCursor) {
|
|
9485
9512
|
const _ckptSpan = span("receive", restoreFrom ? "boot: restore folded state (snapshot)" : "boot: restore checkpoint", "boot");
|
|
9513
|
+
let checkpointResult = null;
|
|
9486
9514
|
try {
|
|
9487
|
-
call("checkpoint_import", {
|
|
9515
|
+
checkpointResult = JSON.parse(call("checkpoint_import", {
|
|
9488
9516
|
...ckptBlobStr ? { blob: ckptBlobStr } : {},
|
|
9489
9517
|
...ckptFrontierStr ? { frontier: ckptFrontierStr } : {},
|
|
9490
9518
|
...ckptStagedFrontierFile ? { stagedFrontierFile: ckptStagedFrontierFile } : {},
|
|
9491
9519
|
...ckptCursor ? { cursor: ckptCursor } : {},
|
|
9492
|
-
...ckptStateRoot ? { stateRoot: ckptStateRoot } : {}
|
|
9493
|
-
|
|
9520
|
+
...ckptStateRoot ? { stateRoot: ckptStateRoot } : {},
|
|
9521
|
+
// Cold-open latency is a public runtime property. Ask the kernel for
|
|
9522
|
+
// its bounded phase table so tenant tooling can distinguish custody,
|
|
9523
|
+
// schema, SQLite hydration and policy-cache work without profiling the
|
|
9524
|
+
// opaque host bridge or weakening the kernel boundary.
|
|
9525
|
+
spans: true
|
|
9526
|
+
}));
|
|
9494
9527
|
} catch (error) {
|
|
9495
9528
|
if (typeof process !== "undefined" && process.env?.NOMOS_DEBUG_RAW) {
|
|
9496
9529
|
console.error("[nomos] checkpoint restore refused", error);
|
|
9497
9530
|
}
|
|
9498
9531
|
}
|
|
9499
|
-
_ckptSpan.end(
|
|
9532
|
+
_ckptSpan.end(checkpointResult ? {
|
|
9533
|
+
restored: checkpointResult.restored,
|
|
9534
|
+
reason: checkpointResult.reason,
|
|
9535
|
+
aggregates: checkpointResult.aggregates,
|
|
9536
|
+
readOnly: checkpointResult.readOnly,
|
|
9537
|
+
lazyReadIndex: checkpointResult.lazyReadIndex,
|
|
9538
|
+
kernelSpans: checkpointResult.kernelSpans
|
|
9539
|
+
} : {});
|
|
9500
9540
|
}
|
|
9501
9541
|
const remoteUnavailableAtConnect = (cause) => {
|
|
9502
9542
|
const msg = String(cause?.message || cause);
|
|
@@ -9972,7 +10012,7 @@ ${String(commit).toLowerCase()}`;
|
|
|
9972
10012
|
affected = Array.isArray(res.affected) ? res.affected : [];
|
|
9973
10013
|
}
|
|
9974
10014
|
if ((domain === "nomos" || domain === "bootstrap") && ["installDomain", "stageDomain", "promoteDomain", "rollbackDomain"].includes(directiveId)) {
|
|
9975
|
-
|
|
10015
|
+
invalidateInstalledLawMetadata();
|
|
9976
10016
|
}
|
|
9977
10017
|
scheduleMaintenanceSoon();
|
|
9978
10018
|
nudgeWatchesSoon();
|
|
@@ -12617,6 +12657,29 @@ ${String(commit).toLowerCase()}`;
|
|
|
12617
12657
|
authHeaders = packAuthHeaders({ authToken: activeAuthToken, principal: connectionPrincipal });
|
|
12618
12658
|
return { refreshed: true };
|
|
12619
12659
|
},
|
|
12660
|
+
/** Refresh the client-held identity proof and/or default signing key without disposing, remounting or
|
|
12661
|
+
* refolding this resident holon. The kernel remains the authority: changing the client key grants
|
|
12662
|
+
* nothing; the next offer still has to prove that key is enrolled under the workspace law. */
|
|
12663
|
+
refreshCredentials: ({ authToken: token, authorSecret: secret } = {}) => {
|
|
12664
|
+
if (token !== void 0) {
|
|
12665
|
+
const next = typeof token === "string" ? token.trim() : "";
|
|
12666
|
+
if (next) {
|
|
12667
|
+
const subjectClaim = jwtClaim(next, "sub");
|
|
12668
|
+
const nextSubject = canonicalPrincipal(
|
|
12669
|
+
typeof subjectClaim === "string" ? subjectClaim : ""
|
|
12670
|
+
);
|
|
12671
|
+
if (!nextSubject || nextSubject !== connectionPrincipal) {
|
|
12672
|
+
throw new Error("credential refresh changed the signed-in identity; reopen the application explicitly");
|
|
12673
|
+
}
|
|
12674
|
+
}
|
|
12675
|
+
activeAuthToken = next;
|
|
12676
|
+
authHeaders = packAuthHeaders({ authToken: activeAuthToken, principal: connectionPrincipal });
|
|
12677
|
+
}
|
|
12678
|
+
if (secret !== void 0) {
|
|
12679
|
+
deviceSecret = typeof secret === "string" ? secret.trim() : "";
|
|
12680
|
+
}
|
|
12681
|
+
return { refreshed: true };
|
|
12682
|
+
},
|
|
12620
12683
|
/**
|
|
12621
12684
|
* THE ONE ENCODER as the public offer entrypoint. A generated client (TS or Dart-via-bridge) calls THIS
|
|
12622
12685
|
* with the planned payload + the verified `actor` — it NEVER re-encodes the v2 envelope itself. The bytes
|
|
@@ -6,7 +6,7 @@ var __export = (target, all) => {
|
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
// <define:__NOMOS_KERNEL_RELEASE__>
|
|
9
|
-
var define_NOMOS_KERNEL_RELEASE_default = { production: { hash: "
|
|
9
|
+
var define_NOMOS_KERNEL_RELEASE_default = { production: { hash: "d512065a204a4b5ac59dd8dfc262d98e49d9e47823582a6123351f4668c68c8b", version: "kernel-d512065a", features: ["compoundKeys", "capturedReads", "invariantGate", "surfacedMerge", "fieldProvenance", "nullSemantics", "attestedReads", "conflictSnapshots", "ownedAudience"], protocol: 1 }, testMint: { hash: "1c66f90d98e71f451b5d3505bba09b66694a22674845e2fd499468854c1a0aae", version: "kernel-1c66f90d", features: ["compoundKeys", "capturedReads", "invariantGate", "surfacedMerge", "fieldProvenance", "nullSemantics", "attestedReads", "conflictSnapshots", "ownedAudience"], protocol: 1 } };
|
|
10
10
|
|
|
11
11
|
// runner/offline-install.ts
|
|
12
12
|
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync } from "node:fs";
|
|
@@ -8817,7 +8817,7 @@ async function countRemoteCommits(eng2, ledger) {
|
|
|
8817
8817
|
}
|
|
8818
8818
|
}
|
|
8819
8819
|
}
|
|
8820
|
-
var projectionStats = (eng2, ws) => namedQueryProto(eng2, ws || "root", QueryOperation.PROJECTION_STATS);
|
|
8820
|
+
var projectionStats = (eng2, ws = "root", options = {}) => namedQueryProto(eng2, ws || "root", QueryOperation.PROJECTION_STATS, options.deep ? { deep: true } : {});
|
|
8821
8821
|
var memoryDropProbe = (eng2, ws) => namedQueryProto(eng2, ws, QueryOperation.MEMORY_DROP_PROBE);
|
|
8822
8822
|
var readiness = (eng2, ws) => namedQueryProto(eng2, ws, QueryOperation.READINESS);
|
|
8823
8823
|
function warmEngine(eng2, opts = {}) {
|
|
@@ -1176,6 +1176,15 @@ class NomosSessionCredentials {
|
|
|
1176
1176
|
});
|
|
1177
1177
|
}
|
|
1178
1178
|
|
|
1179
|
+
/// Framework-owned local custody lookup for generated child workspaces.
|
|
1180
|
+
///
|
|
1181
|
+
/// The callback returns an opaque snapshot string. The bridge never interprets
|
|
1182
|
+
/// it; the kernel authenticates and restores it through the ordinary connect
|
|
1183
|
+
/// path. Keeping this hook on the process-wide bridge lets every generated
|
|
1184
|
+
/// child share the root scope's persistence lifecycle without giving tenant
|
|
1185
|
+
/// code another repository or workspace-opening API.
|
|
1186
|
+
typedef NomosLocalCustodyLoader = Future<String?> Function(String workspace);
|
|
1187
|
+
|
|
1179
1188
|
final class _NomosRetainedCloudAccess {
|
|
1180
1189
|
final String cloud;
|
|
1181
1190
|
final Future<String?> Function() signIn;
|
|
@@ -1258,6 +1267,7 @@ class NomosBridge {
|
|
|
1258
1267
|
// without asking tenant code for cloud URLs, tokens, sessions or signing keys. Kept per source
|
|
1259
1268
|
// session so one local plane may safely host applications from different clouds/identities.
|
|
1260
1269
|
final Map<String, _NomosRetainedCloudAccess> _sessionCloudAccess = {};
|
|
1270
|
+
NomosLocalCustodyLoader? _localCustodyLoader;
|
|
1261
1271
|
// One model-decision policy follows the generated application through its
|
|
1262
1272
|
// child sessions. The callback receives only the typed review object; child
|
|
1263
1273
|
// addresses, archives, credentials and lifecycle directives remain private.
|
|
@@ -2353,6 +2363,27 @@ class NomosBridge {
|
|
|
2353
2363
|
}
|
|
2354
2364
|
return ready(session(workspace));
|
|
2355
2365
|
}
|
|
2366
|
+
String? restoreFrom;
|
|
2367
|
+
final loadLocalCustody = plane._localCustodyLoader;
|
|
2368
|
+
if (loadLocalCustody != null) {
|
|
2369
|
+
try {
|
|
2370
|
+
restoreFrom = await loadLocalCustody(workspace);
|
|
2371
|
+
} catch (_) {
|
|
2372
|
+
// A cache-store failure is absence, never authority. The ordinary
|
|
2373
|
+
// cloud open below remains the correctness path.
|
|
2374
|
+
restoreFrom = null;
|
|
2375
|
+
}
|
|
2376
|
+
}
|
|
2377
|
+
if (ifAbsentCredentials == null && restoreFrom != null) {
|
|
2378
|
+
await connect(
|
|
2379
|
+
workspace: workspace,
|
|
2380
|
+
session: workspace,
|
|
2381
|
+
authorSecret: authorSecret,
|
|
2382
|
+
restoreFrom: restoreFrom,
|
|
2383
|
+
allowUnborn: true,
|
|
2384
|
+
);
|
|
2385
|
+
return ready(session(workspace));
|
|
2386
|
+
}
|
|
2356
2387
|
if (ifAbsentCredentials == null) {
|
|
2357
2388
|
throw StateError(
|
|
2358
2389
|
'acquireSession("$workspace"): the workspace is not on this device\'s plane and no '
|
|
@@ -2366,6 +2397,7 @@ class NomosBridge {
|
|
|
2366
2397
|
clientId: c.clientId,
|
|
2367
2398
|
authToken: c.authToken,
|
|
2368
2399
|
authorSecret: c.authorSecret ?? authorSecret,
|
|
2400
|
+
restoreFrom: restoreFrom,
|
|
2369
2401
|
allowUnborn: c.allowUnborn,
|
|
2370
2402
|
);
|
|
2371
2403
|
return ready(session(workspace));
|
|
@@ -2376,6 +2408,16 @@ class NomosBridge {
|
|
|
2376
2408
|
});
|
|
2377
2409
|
}
|
|
2378
2410
|
|
|
2411
|
+
/// @internal Attach the generated application's opaque local-custody store
|
|
2412
|
+
/// to this process-wide plane. Child opens consult it before cloning from
|
|
2413
|
+
/// cloud; the kernel remains the only component that can authenticate or
|
|
2414
|
+
/// interpret the returned bytes.
|
|
2415
|
+
void nomosInternalRetainLocalCustodyLoader(
|
|
2416
|
+
NomosLocalCustodyLoader loader,
|
|
2417
|
+
) {
|
|
2418
|
+
_eventPlane._localCustodyLoader = loader;
|
|
2419
|
+
}
|
|
2420
|
+
|
|
2379
2421
|
/// Reserve a KERNEL-MINTED typed id (`<TypeTag>_<uuidv7>`) via the holon's front-door mint — for app-side
|
|
2380
2422
|
/// references (routing keys, optimistic UI). `.creates` payloads still carry NO id: the LAW mints those
|
|
2381
2423
|
/// (see [offerCreates], which returns them).
|
|
@@ -2383,6 +2425,29 @@ class NomosBridge {
|
|
|
2383
2425
|
(_asMap(await _call('mintId', {'typeTag': typeTag}))['id'] ?? '')
|
|
2384
2426
|
.toString();
|
|
2385
2427
|
|
|
2428
|
+
/// Refresh client-held credentials on this already-open workspace without
|
|
2429
|
+
/// replacing its resident holon or refolding custody. This grants no
|
|
2430
|
+
/// authority: every offer is still judged by the kernel's author gate.
|
|
2431
|
+
Future<void> refreshCredentials(
|
|
2432
|
+
{String? authToken, String? authorSecret}) async {
|
|
2433
|
+
if (authToken == null && authorSecret == null) return;
|
|
2434
|
+
await _call('refreshCredentials', {
|
|
2435
|
+
if (authToken != null) 'authToken': authToken,
|
|
2436
|
+
if (authorSecret != null) 'authorSecret': authorSecret,
|
|
2437
|
+
});
|
|
2438
|
+
// The resident holon and the plane's future-child template advance
|
|
2439
|
+
// together. Otherwise home signs correctly after first-device enrolment
|
|
2440
|
+
// while a later catalogue/estate opens with the old empty default key.
|
|
2441
|
+
final session = _sessionName;
|
|
2442
|
+
if (session != null && authorSecret != null) {
|
|
2443
|
+
if (authorSecret.isEmpty) {
|
|
2444
|
+
_eventPlane._sessionAuthorSecrets.remove(session);
|
|
2445
|
+
} else {
|
|
2446
|
+
_eventPlane._sessionAuthorSecrets[session] = authorSecret;
|
|
2447
|
+
}
|
|
2448
|
+
}
|
|
2449
|
+
}
|
|
2450
|
+
|
|
2386
2451
|
/// @internal The immutable genesis of a sibling custody chain. This is observational metadata used to
|
|
2387
2452
|
/// compose an ordinary source-enrolment offer; the kernel still reopens and proves every foreign read.
|
|
2388
2453
|
Future<String> nomosWorkspaceGenesis(String workspace,
|
package/dart/pubspec.yaml
CHANGED
|
@@ -7,7 +7,7 @@ repository: https://github.com/Captain-App/nomos2
|
|
|
7
7
|
description: >-
|
|
8
8
|
Nomos 2 Dart client — generated domain values, intent payloads and application
|
|
9
9
|
lifecycle types over the typed Nomos kernel protocol and USDA custody model.
|
|
10
|
-
version: 0.64.
|
|
10
|
+
version: 0.64.10
|
|
11
11
|
|
|
12
12
|
environment:
|
|
13
13
|
sdk: ^3.5.0
|
|
@@ -167,6 +167,54 @@ void main() {
|
|
|
167
167
|
await bridge.dispose();
|
|
168
168
|
});
|
|
169
169
|
|
|
170
|
+
test(
|
|
171
|
+
'an absent generated child restores opaque local custody before cloud convergence',
|
|
172
|
+
() async {
|
|
173
|
+
final runner = FakeRunner();
|
|
174
|
+
final bridge = NomosBridge(runner);
|
|
175
|
+
await bridge.ready;
|
|
176
|
+
var loads = 0;
|
|
177
|
+
bridge.nomosInternalRetainLocalCustodyLoader((workspace) async {
|
|
178
|
+
loads++;
|
|
179
|
+
expect(workspace, 'catalogue');
|
|
180
|
+
return 'opaque-kernel-snapshot';
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
final child = await bridge.acquireSession(
|
|
184
|
+
'catalogue',
|
|
185
|
+
ifAbsentCredentials: () async => const NomosSessionCredentials(
|
|
186
|
+
cloud: 'https://cloud.example',
|
|
187
|
+
authToken: 'token',
|
|
188
|
+
),
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
expect(child.workspace, 'catalogue');
|
|
192
|
+
expect(loads, 1);
|
|
193
|
+
expect(runner.connectCount, 1);
|
|
194
|
+
expect(runner.connectArgs(0)['restoreFrom'], 'opaque-kernel-snapshot');
|
|
195
|
+
expect(runner.connectArgs(0)['cloud'], 'https://cloud.example');
|
|
196
|
+
await bridge.dispose();
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test('opaque local custody can open without inventing cloud authority',
|
|
200
|
+
() async {
|
|
201
|
+
final runner = FakeRunner();
|
|
202
|
+
final bridge = NomosBridge(runner);
|
|
203
|
+
await bridge.ready;
|
|
204
|
+
bridge.nomosInternalRetainLocalCustodyLoader(
|
|
205
|
+
(_) async => 'opaque-kernel-snapshot',
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
final child = await bridge.acquireSession('offline-child');
|
|
209
|
+
|
|
210
|
+
expect(child.workspace, 'offline-child');
|
|
211
|
+
expect(runner.connectCount, 1);
|
|
212
|
+
final args = runner.connectArgs(0);
|
|
213
|
+
expect(args['restoreFrom'], 'opaque-kernel-snapshot');
|
|
214
|
+
expect(args.containsKey('cloud'), isFalse);
|
|
215
|
+
await bridge.dispose();
|
|
216
|
+
});
|
|
217
|
+
|
|
170
218
|
test(
|
|
171
219
|
'a NomosSession delegates acquireSession to the parent plane (one registry)',
|
|
172
220
|
() async {
|
|
@@ -199,6 +247,31 @@ void main() {
|
|
|
199
247
|
await bridge.dispose();
|
|
200
248
|
});
|
|
201
249
|
|
|
250
|
+
test('an in-place signing-key refresh is inherited by later sibling opens',
|
|
251
|
+
() async {
|
|
252
|
+
final runner = FakeRunner(resident: ['catalogue', 'estate']);
|
|
253
|
+
final bridge = NomosBridge(runner);
|
|
254
|
+
await bridge.ready;
|
|
255
|
+
await bridge.connect(workspace: 'home', session: 'home');
|
|
256
|
+
|
|
257
|
+
await bridge
|
|
258
|
+
.session('home')
|
|
259
|
+
.refreshCredentials(authorSecret: 'newly-enrolled-device-key');
|
|
260
|
+
await bridge.session('home').acquireSession('catalogue');
|
|
261
|
+
|
|
262
|
+
expect(runner.connectCount, 2);
|
|
263
|
+
expect(runner.connectArgs(1)['authorSecret'], 'newly-enrolled-device-key',
|
|
264
|
+
reason:
|
|
265
|
+
'refreshing the resident holon must also advance the plane credential inherited by siblings');
|
|
266
|
+
|
|
267
|
+
await bridge.session('home').refreshCredentials(authorSecret: '');
|
|
268
|
+
await bridge.session('home').acquireSession('estate');
|
|
269
|
+
expect(runner.connectArgs(2).containsKey('authorSecret'), isFalse,
|
|
270
|
+
reason:
|
|
271
|
+
'clearing a resident signing key must not leak it into later sibling opens');
|
|
272
|
+
await bridge.dispose();
|
|
273
|
+
});
|
|
274
|
+
|
|
202
275
|
test(
|
|
203
276
|
'generated child inherits typed model decisions and stages opaque USDZ privately',
|
|
204
277
|
() async {
|
package/package.json
CHANGED
|
@@ -5870,7 +5870,7 @@ function providerOperation(mode, rawFields, workBytes) {
|
|
|
5870
5870
|
else throw new Error(`no typed protobuf operation for provider call '${mode}'`);
|
|
5871
5871
|
return { case: "custody", value: create(CustodyRequestSchema, { operation: custody }) };
|
|
5872
5872
|
}
|
|
5873
|
-
function nmsInternalReportProviderTransport(host, encoded, phases, responseBytes) {
|
|
5873
|
+
function nmsInternalReportProviderTransport(host, encoded, phases, responseBytes, context = {}) {
|
|
5874
5874
|
const rounded = Object.fromEntries(Object.entries({ encode: encoded.encodeMs, ...phases }).map(([key, value]) => [key, Math.round(value * 1e3) / 1e3]));
|
|
5875
5875
|
const totalMs = Object.values(rounded).reduce((sum, value) => sum + value, 0);
|
|
5876
5876
|
const debug2 = globalThis.__NOMOS_PROFILE_TRANSPORT__ === true || globalThis.process?.env?.NOMOS_PROFILE_TRANSPORT === "1";
|
|
@@ -5878,10 +5878,13 @@ function nmsInternalReportProviderTransport(host, encoded, phases, responseBytes
|
|
|
5878
5878
|
console.warn(`[nomos-transport-perf] ${JSON.stringify({
|
|
5879
5879
|
host,
|
|
5880
5880
|
mode: encoded.mode,
|
|
5881
|
+
detail: encoded.detail,
|
|
5882
|
+
requestId: encoded.requestId,
|
|
5881
5883
|
totalMs: Math.round(totalMs * 1e3) / 1e3,
|
|
5882
5884
|
phases: rounded,
|
|
5883
5885
|
requestBytes: encoded.bytes.length,
|
|
5884
|
-
responseBytes
|
|
5886
|
+
responseBytes,
|
|
5887
|
+
...context
|
|
5885
5888
|
})}`);
|
|
5886
5889
|
}
|
|
5887
5890
|
function nmsInternalEncodeProviderCall(mode, fields, workBytes, requestPrefix = "browser") {
|
|
@@ -5898,7 +5901,9 @@ function nmsInternalEncodeTypedProviderCall(operation, requestPrefix = "browser"
|
|
|
5898
5901
|
requestId,
|
|
5899
5902
|
operation
|
|
5900
5903
|
}));
|
|
5901
|
-
|
|
5904
|
+
const query = operation.case === "query" ? operation.value.query : void 0;
|
|
5905
|
+
const detail = query?.case === "named" ? `query:named:${String(query.value.operation)}` : query?.case ? `query:${query.case}` : operation.case || "empty";
|
|
5906
|
+
return { requestId, mode: operation.case || "empty", detail, bytes, encodeMs: monotonicMs() - started };
|
|
5902
5907
|
}
|
|
5903
5908
|
function nmsInternalDecodeProviderResponse(bytes, requestId, stderr = []) {
|
|
5904
5909
|
const response = fromBinary(CallResponseSchema, bytes);
|
|
@@ -5959,7 +5964,8 @@ function nmsInternalDecodeProviderResponse(bytes, requestId, stderr = []) {
|
|
|
5959
5964
|
verdictDecodeUs: Number(result.value.spans.verdictDecodeUs),
|
|
5960
5965
|
promoteAndCleanupRefsUs: Number(result.value.spans.promoteAndCleanupRefsUs),
|
|
5961
5966
|
frontierRebuildUs: Number(result.value.spans.frontierRebuildUs),
|
|
5962
|
-
frontierStoreUs: Number(result.value.spans.frontierStoreUs)
|
|
5967
|
+
frontierStoreUs: Number(result.value.spans.frontierStoreUs),
|
|
5968
|
+
verification: result.value.spans.verification ? jsVerifyChainDiagnostics(result.value.spans.verification) : void 0
|
|
5963
5969
|
} : void 0
|
|
5964
5970
|
});
|
|
5965
5971
|
case "repoStats":
|
|
@@ -6028,7 +6034,15 @@ function jsVerifyChainDiagnostics(diagnostics) {
|
|
|
6028
6034
|
typedInstallVerifierUs: Number(step.phases.typedInstallVerifierUs),
|
|
6029
6035
|
admissionUs: Number(step.phases.admissionUs),
|
|
6030
6036
|
foldUs: Number(step.phases.foldUs)
|
|
6031
|
-
} : void 0
|
|
6037
|
+
} : void 0,
|
|
6038
|
+
engineTimings: step.engineTimings.map((timing) => ({
|
|
6039
|
+
phase: timing.phase,
|
|
6040
|
+
totalUs: Number(timing.totalUs)
|
|
6041
|
+
}))
|
|
6042
|
+
})),
|
|
6043
|
+
engineTimings: diagnostics.engineTimings.map((timing) => ({
|
|
6044
|
+
phase: timing.phase,
|
|
6045
|
+
totalUs: Number(timing.totalUs)
|
|
6032
6046
|
}))
|
|
6033
6047
|
};
|
|
6034
6048
|
}
|
|
@@ -6076,7 +6090,7 @@ function nmsInternalParseSnapshot(bytes) {
|
|
|
6076
6090
|
return { treeBytes: bytes, ckpt: null, frontier: null, cursor: null, stateRoot: null, syncedBase: null };
|
|
6077
6091
|
}
|
|
6078
6092
|
function nmsInternalBuildSnapshot(treeBytes, ckpt, syncedBase) {
|
|
6079
|
-
const hasCheckpoint = !!(ckpt && (ckpt.blob || ckpt.frontier || ckpt.cursor
|
|
6093
|
+
const hasCheckpoint = !!(ckpt && (ckpt.blob || ckpt.frontier || ckpt.cursor));
|
|
6080
6094
|
if (!hasCheckpoint && !syncedBase) return treeBytes;
|
|
6081
6095
|
return enc2.encode(JSON.stringify({
|
|
6082
6096
|
v: 2,
|
|
@@ -6222,7 +6236,7 @@ function createWasmEnginePlane({ span } = {}) {
|
|
|
6222
6236
|
const view = {
|
|
6223
6237
|
/** The parsed restore checkpoint (so index.mjs can drive checkpoint_import after boot, exactly as before). */
|
|
6224
6238
|
get restoreCheckpoint() {
|
|
6225
|
-
return _ckptBlobStr || _ckptFrontierStr || _ckptCursor
|
|
6239
|
+
return _ckptBlobStr || _ckptFrontierStr || _ckptCursor ? { blob: _ckptBlobStr, frontier: _ckptFrontierStr, cursor: _ckptCursor, stateRoot: _ckptStateRoot } : null;
|
|
6226
6240
|
},
|
|
6227
6241
|
/** The converged fork point persisted in the restoreFrom snapshot (null for old/tree-only snapshots). */
|
|
6228
6242
|
get restoreSyncedBase() {
|
|
@@ -6396,7 +6410,7 @@ function createWasmEnginePlane({ span } = {}) {
|
|
|
6396
6410
|
const treeBytes = serializeTree(wsDirNode);
|
|
6397
6411
|
return nmsInternalBuildSnapshot(
|
|
6398
6412
|
treeBytes,
|
|
6399
|
-
ckpt && (ckpt.blob || ckpt.frontier || ckpt.cursor
|
|
6413
|
+
ckpt && (ckpt.blob || ckpt.frontier || ckpt.cursor) ? ckpt : null,
|
|
6400
6414
|
opts.syncedBase || null
|
|
6401
6415
|
);
|
|
6402
6416
|
}
|
|
@@ -7664,7 +7678,7 @@ async function connectSingle({ cloud, workspace, clientId, authToken, restoreFro
|
|
|
7664
7678
|
if (salvageOnly) allowUnborn = true;
|
|
7665
7679
|
if (!cloud || !workspace) throw new Error("connect({ cloud, workspace }) required");
|
|
7666
7680
|
const _fetch = typeof fetchImpl === "function" ? fetchImpl : globalThis.fetch;
|
|
7667
|
-
|
|
7681
|
+
let deviceSecret = authorSecret || "";
|
|
7668
7682
|
const base = cloud.replace(/\/+$/, "");
|
|
7669
7683
|
const localOnly = /^local:\/\//i.test(base);
|
|
7670
7684
|
const historicSnapshotConfig = historicSnapshots === false ? null : historicSnapshots && typeof historicSnapshots === "object" ? historicSnapshots : {};
|
|
@@ -7908,9 +7922,11 @@ ${String(commit).toLowerCase()}`;
|
|
|
7908
7922
|
const watchStops = /* @__PURE__ */ new Set();
|
|
7909
7923
|
let installedLawRowsCache;
|
|
7910
7924
|
let installedLawCurrentCache;
|
|
7911
|
-
|
|
7925
|
+
let installedInterfaceCache;
|
|
7926
|
+
const invalidateInstalledLawMetadata = () => {
|
|
7912
7927
|
installedLawRowsCache = void 0;
|
|
7913
7928
|
installedLawCurrentCache = void 0;
|
|
7929
|
+
installedInterfaceCache = void 0;
|
|
7914
7930
|
};
|
|
7915
7931
|
let _disposed = false;
|
|
7916
7932
|
const nudgeWatches = () => {
|
|
@@ -8255,10 +8271,13 @@ ${String(commit).toLowerCase()}`;
|
|
|
8255
8271
|
const compatGuardWrite = (directiveId, force) => assertWriteShippable(compatState, directiveId, { force, workspace });
|
|
8256
8272
|
let _lastInterfaceReadError = null;
|
|
8257
8273
|
const installedInterfaceInner = () => {
|
|
8274
|
+
if (installedInterfaceCache !== void 0) return installedInterfaceCache;
|
|
8258
8275
|
try {
|
|
8259
8276
|
const compact = JSON.parse(call("query", { queryBytes: qBytes({ op: "interfaceOffer" }) }));
|
|
8260
8277
|
_lastInterfaceReadError = null;
|
|
8261
|
-
|
|
8278
|
+
const installedInterface = compact && typeof compact === "object" && !Array.isArray(compact) && Object.keys(compact).length ? compact : null;
|
|
8279
|
+
installedInterfaceCache = installedInterface;
|
|
8280
|
+
return installedInterface;
|
|
8262
8281
|
} catch (error) {
|
|
8263
8282
|
_lastInterfaceReadError = error instanceof Error ? error : new Error(String(error));
|
|
8264
8283
|
return null;
|
|
@@ -8398,7 +8417,7 @@ ${String(commit).toLowerCase()}`;
|
|
|
8398
8417
|
}
|
|
8399
8418
|
}
|
|
8400
8419
|
}
|
|
8401
|
-
|
|
8420
|
+
invalidateInstalledLawMetadata();
|
|
8402
8421
|
nudgeWatches();
|
|
8403
8422
|
return {
|
|
8404
8423
|
upToDate: false,
|
|
@@ -8540,22 +8559,35 @@ ${String(commit).toLowerCase()}`;
|
|
|
8540
8559
|
};
|
|
8541
8560
|
return err;
|
|
8542
8561
|
};
|
|
8543
|
-
if (ckptBlobStr || ckptFrontierStr || ckptStagedFrontierFile || ckptCursor
|
|
8562
|
+
if (ckptBlobStr || ckptFrontierStr || ckptStagedFrontierFile || ckptCursor) {
|
|
8544
8563
|
const _ckptSpan = span("receive", restoreFrom ? "boot: restore folded state (snapshot)" : "boot: restore checkpoint", "boot");
|
|
8564
|
+
let checkpointResult = null;
|
|
8545
8565
|
try {
|
|
8546
|
-
call("checkpoint_import", {
|
|
8566
|
+
checkpointResult = JSON.parse(call("checkpoint_import", {
|
|
8547
8567
|
...ckptBlobStr ? { blob: ckptBlobStr } : {},
|
|
8548
8568
|
...ckptFrontierStr ? { frontier: ckptFrontierStr } : {},
|
|
8549
8569
|
...ckptStagedFrontierFile ? { stagedFrontierFile: ckptStagedFrontierFile } : {},
|
|
8550
8570
|
...ckptCursor ? { cursor: ckptCursor } : {},
|
|
8551
|
-
...ckptStateRoot ? { stateRoot: ckptStateRoot } : {}
|
|
8552
|
-
|
|
8571
|
+
...ckptStateRoot ? { stateRoot: ckptStateRoot } : {},
|
|
8572
|
+
// Cold-open latency is a public runtime property. Ask the kernel for
|
|
8573
|
+
// its bounded phase table so tenant tooling can distinguish custody,
|
|
8574
|
+
// schema, SQLite hydration and policy-cache work without profiling the
|
|
8575
|
+
// opaque host bridge or weakening the kernel boundary.
|
|
8576
|
+
spans: true
|
|
8577
|
+
}));
|
|
8553
8578
|
} catch (error) {
|
|
8554
8579
|
if (typeof process !== "undefined" && process.env?.NOMOS_DEBUG_RAW) {
|
|
8555
8580
|
console.error("[nomos] checkpoint restore refused", error);
|
|
8556
8581
|
}
|
|
8557
8582
|
}
|
|
8558
|
-
_ckptSpan.end(
|
|
8583
|
+
_ckptSpan.end(checkpointResult ? {
|
|
8584
|
+
restored: checkpointResult.restored,
|
|
8585
|
+
reason: checkpointResult.reason,
|
|
8586
|
+
aggregates: checkpointResult.aggregates,
|
|
8587
|
+
readOnly: checkpointResult.readOnly,
|
|
8588
|
+
lazyReadIndex: checkpointResult.lazyReadIndex,
|
|
8589
|
+
kernelSpans: checkpointResult.kernelSpans
|
|
8590
|
+
} : {});
|
|
8559
8591
|
}
|
|
8560
8592
|
const remoteUnavailableAtConnect = (cause) => {
|
|
8561
8593
|
const msg = String(cause?.message || cause);
|
|
@@ -9031,7 +9063,7 @@ ${String(commit).toLowerCase()}`;
|
|
|
9031
9063
|
affected = Array.isArray(res.affected) ? res.affected : [];
|
|
9032
9064
|
}
|
|
9033
9065
|
if ((domain === "nomos" || domain === "bootstrap") && ["installDomain", "stageDomain", "promoteDomain", "rollbackDomain"].includes(directiveId)) {
|
|
9034
|
-
|
|
9066
|
+
invalidateInstalledLawMetadata();
|
|
9035
9067
|
}
|
|
9036
9068
|
scheduleMaintenanceSoon();
|
|
9037
9069
|
nudgeWatchesSoon();
|
|
@@ -11676,6 +11708,29 @@ ${String(commit).toLowerCase()}`;
|
|
|
11676
11708
|
authHeaders = packAuthHeaders({ authToken: activeAuthToken, principal: connectionPrincipal });
|
|
11677
11709
|
return { refreshed: true };
|
|
11678
11710
|
},
|
|
11711
|
+
/** Refresh the client-held identity proof and/or default signing key without disposing, remounting or
|
|
11712
|
+
* refolding this resident holon. The kernel remains the authority: changing the client key grants
|
|
11713
|
+
* nothing; the next offer still has to prove that key is enrolled under the workspace law. */
|
|
11714
|
+
refreshCredentials: ({ authToken: token, authorSecret: secret } = {}) => {
|
|
11715
|
+
if (token !== void 0) {
|
|
11716
|
+
const next = typeof token === "string" ? token.trim() : "";
|
|
11717
|
+
if (next) {
|
|
11718
|
+
const subjectClaim = jwtClaim(next, "sub");
|
|
11719
|
+
const nextSubject = canonicalPrincipal(
|
|
11720
|
+
typeof subjectClaim === "string" ? subjectClaim : ""
|
|
11721
|
+
);
|
|
11722
|
+
if (!nextSubject || nextSubject !== connectionPrincipal) {
|
|
11723
|
+
throw new Error("credential refresh changed the signed-in identity; reopen the application explicitly");
|
|
11724
|
+
}
|
|
11725
|
+
}
|
|
11726
|
+
activeAuthToken = next;
|
|
11727
|
+
authHeaders = packAuthHeaders({ authToken: activeAuthToken, principal: connectionPrincipal });
|
|
11728
|
+
}
|
|
11729
|
+
if (secret !== void 0) {
|
|
11730
|
+
deviceSecret = typeof secret === "string" ? secret.trim() : "";
|
|
11731
|
+
}
|
|
11732
|
+
return { refreshed: true };
|
|
11733
|
+
},
|
|
11679
11734
|
/**
|
|
11680
11735
|
* THE ONE ENCODER as the public offer entrypoint. A generated client (TS or Dart-via-bridge) calls THIS
|
|
11681
11736
|
* with the planned payload + the verified `actor` — it NEVER re-encodes the v2 envelope itself. The bytes
|
|
@@ -1650,8 +1650,8 @@ const NOMOS_TYPES_DEP = "^0.8.4";
|
|
|
1650
1650
|
// 0.48.x: session-bound clients (XClient.bind/NomosClientInterface/DomainClientSessionMismatch/
|
|
1651
1651
|
// DomainNotInstalledForSession, engine.follow, pendingConflicts lanes) — the generated client
|
|
1652
1652
|
// REQUIRES this surface. 0.48.1 fixes NomosSession.watchPendingConflicts delegation.
|
|
1653
|
-
const NOMOS_CLIENT_DEP = "^0.64.
|
|
1654
|
-
const NOMOS_FLUTTER_DEP = "^0.63.
|
|
1653
|
+
const NOMOS_CLIENT_DEP = "^0.64.10";
|
|
1654
|
+
const NOMOS_FLUTTER_DEP = "^0.63.13";
|
|
1655
1655
|
// DRIFT TRIPWIRE: pubspec_pins.test.ts asserts these equal the CURRENT versions in dsl/dart/pubspec.yaml
|
|
1656
1656
|
// and dsl/dart_types/pubspec.yaml — a Dart release without this bump fails the suite, so tenants never
|
|
1657
1657
|
// land back in dependency_overrides (the exact co2 report this closes, third occurrence).
|