@githolon/dsl 0.91.0 → 0.92.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dart/pubspec.yaml +2 -2
- package/dart_types/lib/src/errors.dart +67 -0
- package/dart_types/pubspec.yaml +1 -1
- package/package.json +1 -1
- package/src/codegen_dart_client.ts +17 -10
- package/src/codegen_ts.ts +19 -4
- package/src/compile_package_main.ts +2 -2
- package/src/framework/workspaces.ts +11 -0
package/dart/pubspec.yaml
CHANGED
|
@@ -11,7 +11,7 @@ description: >-
|
|
|
11
11
|
Nomos 2 Dart frontend types — the hand-written kernel wire types plus the
|
|
12
12
|
code-generated per-domain aggregate + directive-payload types. (De)serializes
|
|
13
13
|
the EXACT serde JSON the Rust kernel + projection produce/consume.
|
|
14
|
-
version: 0.
|
|
14
|
+
version: 0.58.0
|
|
15
15
|
|
|
16
16
|
environment:
|
|
17
17
|
sdk: ^3.5.0
|
|
@@ -20,7 +20,7 @@ dependencies:
|
|
|
20
20
|
# The pure-data core (wire types, offer codec, NomosReads, schema validation, error
|
|
21
21
|
# info). nomos_client depends on and re-exports it, so existing imports are unchanged.
|
|
22
22
|
# For local monorepo dev, pubspec_overrides.yaml points this at ../dart_types.
|
|
23
|
-
nomos_types: ^0.
|
|
23
|
+
nomos_types: ^0.5.0
|
|
24
24
|
json_schema: ^5.2.2
|
|
25
25
|
crypto: ^3.0.0
|
|
26
26
|
|
|
@@ -26,6 +26,9 @@ NomosBridgeError nomosErrorFromInfo(NomosErrorInfo info) {
|
|
|
26
26
|
if (info.code.startsWith('nomos.authz.')) return AuthzRefusedError.fromInfo(info);
|
|
27
27
|
if (info.code.startsWith('nomos.auth.')) return AuthError.fromInfo(info);
|
|
28
28
|
if (info.code.startsWith('nomos.load.')) return LoadError.fromInfo(info);
|
|
29
|
+
if (info.code == 'nomos.attested_read.source_not_mounted') {
|
|
30
|
+
return SourceSessionNotMounted.fromInfo(info);
|
|
31
|
+
}
|
|
29
32
|
return NomosBridgeError(info.message, info: info);
|
|
30
33
|
}
|
|
31
34
|
|
|
@@ -62,6 +65,11 @@ class NomosRecommendedAction {
|
|
|
62
65
|
/// [ParentSignerEnrollmentMissing] (a reborn parent that lost the signer tuple).
|
|
63
66
|
static const ensureParentSignerEnrollment = 'ensureParentSignerEnrollment';
|
|
64
67
|
|
|
68
|
+
/// Mount the SOURCE workspace of a colocated attested read as a session on this device's plane
|
|
69
|
+
/// (`bridge.connect(session: <sourceWs>)` / `ref.acquire(bridge)`) — the ONE remedy for
|
|
70
|
+
/// [SourceSessionNotMounted] (a directive's `read(q, {from})` resolves in-engine from the mounted source).
|
|
71
|
+
static const mountSourceSession = 'mountSourceSession';
|
|
72
|
+
|
|
65
73
|
/// No automatic remedy — surface to a human.
|
|
66
74
|
static const none = 'none';
|
|
67
75
|
|
|
@@ -84,6 +92,8 @@ class NomosRecommendedAction {
|
|
|
84
92
|
return 'reopen the holon (reconnect fresh)';
|
|
85
93
|
case ensureParentSignerEnrollment:
|
|
86
94
|
return 'restore the device signer on the parent (ensureParentSignerEnrollment / NomosScope.home repairs it on reopen)';
|
|
95
|
+
case mountSourceSession:
|
|
96
|
+
return 'mount the attested read\'s source workspace as a session on this plane (connect it / ref.acquire) so the read resolves in-engine';
|
|
87
97
|
case none:
|
|
88
98
|
return 'no automatic remedy — inspect the error';
|
|
89
99
|
default:
|
|
@@ -413,6 +423,63 @@ class LoadError extends NomosBridgeError {
|
|
|
413
423
|
'${sourceUrl != null ? ', sourceUrl: $sourceUrl' : ''}, recommendedAction: $recommendedAction): $message';
|
|
414
424
|
}
|
|
415
425
|
|
|
426
|
+
/// SOURCE SESSION NOT MOUNTED (`nomos.attested_read.source_not_mounted`) — a directive whose law declares a
|
|
427
|
+
/// colocated foreign read (`read(query, {from: <sourceWs>})`) was offered while the SOURCE workspace was NOT
|
|
428
|
+
/// mounted as a session on this device's engine plane. A colocated attested read resolves + signs IN-ENGINE
|
|
429
|
+
/// (zero HTTP) from the mounted source; when the source is absent the bridge refuses IMMEDIATELY (this error)
|
|
430
|
+
/// instead of a doomed ~31s remote fetch that answers an unsigned projection. The remedy is
|
|
431
|
+
/// [NomosRecommendedAction.mountSourceSession]: open [sourceWorkspace] as a session on the SAME bridge/realm
|
|
432
|
+
/// (`bridge.connect(session: sourceWorkspace)` / `ref.acquire(bridge)`) BEFORE offering the directive.
|
|
433
|
+
class SourceSessionNotMounted extends NomosBridgeError {
|
|
434
|
+
/// The stable machine code — always `nomos.attested_read.source_not_mounted`.
|
|
435
|
+
final String code;
|
|
436
|
+
|
|
437
|
+
/// The name the directive's `read(..., {from})` (or explicit attested read) referenced — a session alias
|
|
438
|
+
/// or a workspace name.
|
|
439
|
+
final String? from;
|
|
440
|
+
|
|
441
|
+
/// The resolved SOURCE workspace that must be mounted on this plane.
|
|
442
|
+
final String? sourceWorkspace;
|
|
443
|
+
|
|
444
|
+
/// The declared query the foreign read names, when known.
|
|
445
|
+
final String? queryId;
|
|
446
|
+
|
|
447
|
+
/// The named remedy — [NomosRecommendedAction.mountSourceSession].
|
|
448
|
+
final String recommendedAction;
|
|
449
|
+
|
|
450
|
+
SourceSessionNotMounted({
|
|
451
|
+
this.code = 'nomos.attested_read.source_not_mounted',
|
|
452
|
+
required String message,
|
|
453
|
+
this.from,
|
|
454
|
+
this.sourceWorkspace,
|
|
455
|
+
this.queryId,
|
|
456
|
+
this.recommendedAction = NomosRecommendedAction.mountSourceSession,
|
|
457
|
+
NomosErrorInfo? info,
|
|
458
|
+
}) : super(message, info: info);
|
|
459
|
+
|
|
460
|
+
factory SourceSessionNotMounted.fromInfo(NomosErrorInfo info) {
|
|
461
|
+
String? attr(String name) {
|
|
462
|
+
final v = info.attributes['nomos.attested_read.$name'] ?? info.attributes[name];
|
|
463
|
+
return v?.toString();
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
return SourceSessionNotMounted(
|
|
467
|
+
code: info.code,
|
|
468
|
+
message: info.message,
|
|
469
|
+
from: attr('from'),
|
|
470
|
+
sourceWorkspace: attr('source_workspace') ?? attr('sourceWorkspace') ?? info.workspace,
|
|
471
|
+
queryId: (info.attributes['nomos.query_id'] ?? attr('queryId'))?.toString(),
|
|
472
|
+
recommendedAction: attr('recommendedAction') ?? attr('recommended_action') ?? NomosRecommendedAction.mountSourceSession,
|
|
473
|
+
info: info,
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
@override
|
|
478
|
+
String toString() =>
|
|
479
|
+
'SourceSessionNotMounted(source: $sourceWorkspace'
|
|
480
|
+
'${queryId != null ? ', query: $queryId' : ''}, recommendedAction: $recommendedAction): $message';
|
|
481
|
+
}
|
|
482
|
+
|
|
416
483
|
/// The custody phase a [CustodyError] was raised in.
|
|
417
484
|
enum CustodyPhase { fold, author, fetch, unknown }
|
|
418
485
|
|
package/dart_types/pubspec.yaml
CHANGED
|
@@ -11,7 +11,7 @@ description: >-
|
|
|
11
11
|
Pure kernel wire/data types for Nomos Dart frontends — no transport, no bridge,
|
|
12
12
|
no runtime. The hand-written serde-JSON-compatible types plus the offer codec,
|
|
13
13
|
reactive read engine, schema validation, and data-only error/trace types.
|
|
14
|
-
version: 0.
|
|
14
|
+
version: 0.5.0
|
|
15
15
|
|
|
16
16
|
environment:
|
|
17
17
|
sdk: ^3.5.0
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@githolon/dsl",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.92.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Nomos 2 domain-authoring DSL: aggregates + directives in TS, executed and encoded to the Rust kernel's wire shapes.",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
@@ -240,6 +240,13 @@ export function generateDartBridgeClient(mod: DomainModule, opts: DartBridgeClie
|
|
|
240
240
|
const gateDoc = gate !== undefined
|
|
241
241
|
? ` /// GATED: needs an \`actor\` (the \`${gate.relation}\` relation) — throws MissingOfferAuthority otherwise.`
|
|
242
242
|
: "";
|
|
243
|
+
// FALLBACK ATTESTATION INJECTION (co2): a directive whose law declares a foreign read (`.readsFrom(...)`)
|
|
244
|
+
// accepts pre-fetched signed envelopes as an optional `attestations:` param — the manual override when the
|
|
245
|
+
// colocation resolver can't serve the read (the source isn't mounted on the plane). The in-engine
|
|
246
|
+
// colocation path stays the default; only foreign-read directives carry the extra named param.
|
|
247
|
+
const wantAttest = (((d as { declaredForeignReads?: unknown[] }).declaredForeignReads?.length ?? 0) > 0);
|
|
248
|
+
const attNamed = wantAttest ? "List<Map<String, Object?>>? attestations" : "";
|
|
249
|
+
const attArg = wantAttest ? ", attestations: attestations" : "";
|
|
243
250
|
// E2E SEALING (the sealing client): a directive with `.encrypted()` payload fields SEALS them via the
|
|
244
251
|
// bound [keyStore] before dispatch (a missing key throws [EncryptionKeyUnavailable] — never a plaintext
|
|
245
252
|
// write). One async block covers creates + mutate + gated + stamps; `seal: false` is the escape hatch.
|
|
@@ -255,7 +262,7 @@ export function generateDartBridgeClient(mod: DomainModule, opts: DartBridgeClie
|
|
|
255
262
|
` /// Author \`${domain}/${d.id}\` locally under the installed law; returns the typed [NomosOfferOutcome].${createsDoc}`,
|
|
256
263
|
` /// Encrypted field(s) are SEALED via the bound [keyStore] before dispatch (pass \`seal: false\` to skip).${stampsDoc}`,
|
|
257
264
|
...(gateDoc ? [gateDoc] : []),
|
|
258
|
-
` Future<NomosOfferOutcome> ${method}(${payloadClass} payload, {bool seal = true}) async {`,
|
|
265
|
+
` Future<NomosOfferOutcome> ${method}(${payloadClass} payload, {bool seal = true${wantAttest ? ", " + attNamed : ""}}) async {`,
|
|
259
266
|
...(gateGuard ? [gateGuard] : []),
|
|
260
267
|
` final data = payload.toPayloadJson();`,
|
|
261
268
|
...(stamps.length > 0
|
|
@@ -265,7 +272,7 @@ export function generateDartBridgeClient(mod: DomainModule, opts: DartBridgeClie
|
|
|
265
272
|
]
|
|
266
273
|
: []),
|
|
267
274
|
` await _sealPayload(data, ${dartStr(d.id)}, seal);`,
|
|
268
|
-
` return _offer(${dartStr(d.id)}, data);`,
|
|
275
|
+
` return _offer(${dartStr(d.id)}, data${attArg});`,
|
|
269
276
|
` }`,
|
|
270
277
|
``,
|
|
271
278
|
);
|
|
@@ -275,12 +282,12 @@ export function generateDartBridgeClient(mod: DomainModule, opts: DartBridgeClie
|
|
|
275
282
|
methods.push(
|
|
276
283
|
` /// Author \`${domain}/${d.id}\` locally under the installed law; returns the typed [NomosOfferOutcome].${createsDoc}${stampsDoc}`,
|
|
277
284
|
...(gateDoc ? [gateDoc] : []),
|
|
278
|
-
` Future<NomosOfferOutcome> ${method}(${payloadClass} payload) {`,
|
|
285
|
+
` Future<NomosOfferOutcome> ${method}(${payloadClass} payload${wantAttest ? ", {" + attNamed + "}" : ""}) {`,
|
|
279
286
|
...(gateGuard ? [gateGuard] : []),
|
|
280
287
|
` final data = payload.toPayloadJson();`,
|
|
281
288
|
` final now = DateTime.now().toUtc().toIso8601String();`,
|
|
282
289
|
...stamps.map((s) => ` data.putIfAbsent(${dartStr(s)}, () => now);`),
|
|
283
|
-
` return _offer(${dartStr(d.id)}, data);`,
|
|
290
|
+
` return _offer(${dartStr(d.id)}, data${attArg});`,
|
|
284
291
|
` }`,
|
|
285
292
|
``,
|
|
286
293
|
);
|
|
@@ -289,9 +296,9 @@ export function generateDartBridgeClient(mod: DomainModule, opts: DartBridgeClie
|
|
|
289
296
|
methods.push(
|
|
290
297
|
` /// Author \`${domain}/${d.id}\` locally under the installed law; returns the typed [NomosOfferOutcome].${createsDoc}`,
|
|
291
298
|
gateDoc,
|
|
292
|
-
` Future<NomosOfferOutcome> ${method}(${payloadClass} payload) {`,
|
|
299
|
+
` Future<NomosOfferOutcome> ${method}(${payloadClass} payload${wantAttest ? ", {" + attNamed + "}" : ""}) {`,
|
|
293
300
|
gateGuard,
|
|
294
|
-
` return _offer(${dartStr(d.id)}, payload.toPayloadJson());`,
|
|
301
|
+
` return _offer(${dartStr(d.id)}, payload.toPayloadJson()${attArg});`,
|
|
295
302
|
` }`,
|
|
296
303
|
``,
|
|
297
304
|
);
|
|
@@ -299,8 +306,8 @@ export function generateDartBridgeClient(mod: DomainModule, opts: DartBridgeClie
|
|
|
299
306
|
methods.push(
|
|
300
307
|
` /// Author \`${domain}/${d.id}\` locally under the installed law; returns the typed [NomosOfferOutcome].${createsDoc}`,
|
|
301
308
|
...(gateDoc ? [gateDoc] : []),
|
|
302
|
-
` Future<NomosOfferOutcome> ${method}(${payloadClass} payload) =>`,
|
|
303
|
-
` _offer(${dartStr(d.id)}, payload.toPayloadJson());`,
|
|
309
|
+
` Future<NomosOfferOutcome> ${method}(${payloadClass} payload${wantAttest ? ", {" + attNamed + "}" : ""}) =>`,
|
|
310
|
+
` _offer(${dartStr(d.id)}, payload.toPayloadJson()${attArg});`,
|
|
304
311
|
``,
|
|
305
312
|
);
|
|
306
313
|
}
|
|
@@ -879,9 +886,9 @@ export function generateDartBridgeClient(mod: DomainModule, opts: DartBridgeClie
|
|
|
879
886
|
``,
|
|
880
887
|
` /// THE ONE DISPATCH LANE every generated directive method routes through: lazy preflight, then`,
|
|
881
888
|
` /// the session's offer (the generated-internal use of the engine-level lane).`,
|
|
882
|
-
` Future<NomosOfferOutcome> _offer(String directiveId, Object? payload) async {`,
|
|
889
|
+
` Future<NomosOfferOutcome> _offer(String directiveId, Object? payload, {List<Map<String, Object?>>? attestations}) async {`,
|
|
883
890
|
` await _preflightOnce();`,
|
|
884
|
-
` return bridge.offerOutcome(domain: ${dartStr(domain)}, directiveId: directiveId, payload: payload, actor: actor, domainHash: domainHash);`,
|
|
891
|
+
` return bridge.offerOutcome(domain: ${dartStr(domain)}, directiveId: directiveId, payload: payload, actor: actor, domainHash: domainHash, attestations: attestations);`,
|
|
885
892
|
` }`,
|
|
886
893
|
``,
|
|
887
894
|
...(encPresent ? dartEncClassMembers(encMap!) : []),
|
package/src/codegen_ts.ts
CHANGED
|
@@ -1012,7 +1012,7 @@ export function generateTsClient(modules: readonly DomainModule[], opts: TsClien
|
|
|
1012
1012
|
` /** THE ONE ENCODER offer (the single v2-envelope codec lives in @githolon/client \`encodeIntentOfferBytes\`):`,
|
|
1013
1013
|
` * hand the holon a PLANNED directive + the verified \`actor\`; the holon encodes + offers. The generated`,
|
|
1014
1014
|
` * client calls THIS, never building offer bytes itself — so there is exactly ONE copy of the wire format. */`,
|
|
1015
|
-
` offerDirective(domain: string, directiveId: string, payload: unknown, opts?: { domainHash?: string; actor?: string; returnCreated?: boolean }): Promise<string | { head: string; created?: { type: string; id: string }[]; workspace?: string }>;`,
|
|
1015
|
+
` offerDirective(domain: string, directiveId: string, payload: unknown, opts?: { domainHash?: string; actor?: string; returnCreated?: boolean; attestations?: readonly { queryId: string; result: unknown; attestation: unknown }[] }): Promise<string | { head: string; created?: { type: string; id: string }[]; workspace?: string }>;`,
|
|
1016
1016
|
` /** Opaque-bytes offer — retained for carriers that already hold an encoded envelope (back-compat). */`,
|
|
1017
1017
|
` offer(intentBytes: string | Uint8Array): Promise<string>;`,
|
|
1018
1018
|
...(hasBirths
|
|
@@ -1849,7 +1849,22 @@ export function generateTsClient(modules: readonly DomainModule[], opts: TsClien
|
|
|
1849
1849
|
// escape hatch, and `pv` (the sealed copy) replaces `payload` downstream. Non-encrypted directives
|
|
1850
1850
|
// are byte-identical (wantSeal === false ⇒ no prelude, no extra param, plain `payload`).
|
|
1851
1851
|
const wantSeal = encMap?.[domain]?.directives?.[d.id] !== undefined;
|
|
1852
|
-
|
|
1852
|
+
// FALLBACK ATTESTATION INJECTION (co2): a directive whose law declares a foreign read
|
|
1853
|
+
// (`.readsFrom(...)`) accepts pre-fetched signed envelopes as `callOpts.attestations` — the manual
|
|
1854
|
+
// escape hatch when the colocation resolver can't serve the read (the source isn't on the plane). The
|
|
1855
|
+
// in-engine colocation path (the offer resolves the read from the mounted source, zero HTTP) remains
|
|
1856
|
+
// the default; this is the explicit override a caller reaches for. Emitted ONLY for foreign-read
|
|
1857
|
+
// directives (an ordinary directive's signature is byte-identical).
|
|
1858
|
+
const wantAttest = (((d as { declaredForeignReads?: unknown[] }).declaredForeignReads?.length ?? 0) > 0);
|
|
1859
|
+
const attTy = `readonly { queryId: string; result: unknown; attestation: unknown }[]`;
|
|
1860
|
+
const callOptsFields = [
|
|
1861
|
+
...(wantSeal ? ["seal?: boolean"] : []),
|
|
1862
|
+
...(wantAttest ? [`attestations?: ${attTy}`] : []),
|
|
1863
|
+
];
|
|
1864
|
+
const paramSig = callOptsFields.length
|
|
1865
|
+
? `payload: ${payloadName}, callOpts?: { ${callOptsFields.join("; ")} }`
|
|
1866
|
+
: `payload: ${payloadName}`;
|
|
1867
|
+
const offerExtra = wantAttest ? ", attestations: callOpts?.attestations" : "";
|
|
1853
1868
|
const sealPrelude = wantSeal
|
|
1854
1869
|
? ` const _sealed = await _sealFields(holon, keyStore, ${encConst}[${JSON.stringify(domain)}].directives[${JSON.stringify(d.id)}] as Record<string, { scope: string; aggSid: string; fieldSid: string }>, payload as Record<string, unknown>, callOpts?.seal !== false) as ${payloadName};`
|
|
1855
1870
|
: "";
|
|
@@ -1907,7 +1922,7 @@ export function generateTsClient(modules: readonly DomainModule[], opts: TsClien
|
|
|
1907
1922
|
...(gateGuard ? [gateGuard.replace(/\n$/, "")] : []),
|
|
1908
1923
|
...(sealPrelude ? [sealPrelude] : []),
|
|
1909
1924
|
` const ${mint.field} = payload.${mint.field} ?? (await (holon as NomosRoutedHolon).mint(${JSON.stringify(mint.mintType)}${mintOpts}));`,
|
|
1910
|
-
` return _outcome(holon.workspace, holon.offerDirective(${JSON.stringify(domain)}, ${JSON.stringify(d.id)}, ${body}, { domainHash, actor, returnCreated: true }) as Promise<string | { head: string; created?: { type: string; id: string }[] }>, { workspace: holon.workspace, type: ${JSON.stringify(dd.aggregateId ?? mint.mintType)}, id: ${mint.field} });`,
|
|
1925
|
+
` return _outcome(holon.workspace, holon.offerDirective(${JSON.stringify(domain)}, ${JSON.stringify(d.id)}, ${body}, { domainHash, actor, returnCreated: true${offerExtra} }) as Promise<string | { head: string; created?: { type: string; id: string }[] }>, { workspace: holon.workspace, type: ${JSON.stringify(dd.aggregateId ?? mint.mintType)}, id: ${mint.field} });`,
|
|
1911
1926
|
` },`,
|
|
1912
1927
|
);
|
|
1913
1928
|
continue;
|
|
@@ -1924,7 +1939,7 @@ export function generateTsClient(modules: readonly DomainModule[], opts: TsClien
|
|
|
1924
1939
|
` ${d.id}: async (${paramSig}): Promise<NomosOutcome> => {`,
|
|
1925
1940
|
...(gateGuard ? [gateGuard.replace(/\n$/, "")] : []),
|
|
1926
1941
|
...(sealPrelude ? [sealPrelude] : []),
|
|
1927
|
-
` return _outcome(holon.workspace, holon.offerDirective(${JSON.stringify(domain)}, ${JSON.stringify(d.id)}, ${offerPayload}, { domainHash, actor, returnCreated: true }) as Promise<string | { head: string; created?: { type: string; id: string }[] }>);`,
|
|
1942
|
+
` return _outcome(holon.workspace, holon.offerDirective(${JSON.stringify(domain)}, ${JSON.stringify(d.id)}, ${offerPayload}, { domainHash, actor, returnCreated: true${offerExtra} }) as Promise<string | { head: string; created?: { type: string; id: string }[] }>);`,
|
|
1928
1943
|
` },`,
|
|
1929
1944
|
);
|
|
1930
1945
|
}
|
|
@@ -1046,11 +1046,11 @@ const DART_TYPES_IMPORT = `import 'package:nomos_types/nomos_types.dart';`;
|
|
|
1046
1046
|
* just the floor generated code needs — a lagging pin forces tenants into dependency_overrides. */
|
|
1047
1047
|
// 0.3.0: SurfacedValue<T>/SurfacedObservation/PendingConflictRow — generated Surfaced-field typing +
|
|
1048
1048
|
// the pendingConflicts read rows.
|
|
1049
|
-
const NOMOS_TYPES_DEP = "^0.
|
|
1049
|
+
const NOMOS_TYPES_DEP = "^0.5.0";
|
|
1050
1050
|
// 0.48.x: session-bound clients (XClient.bind/NomosClientInterface/DomainClientSessionMismatch/
|
|
1051
1051
|
// DomainNotInstalledForSession, engine.follow, pendingConflicts lanes) — the generated client
|
|
1052
1052
|
// REQUIRES this surface. 0.48.1 fixes NomosSession.watchPendingConflicts delegation.
|
|
1053
|
-
const NOMOS_CLIENT_DEP = "^0.
|
|
1053
|
+
const NOMOS_CLIENT_DEP = "^0.58.0";
|
|
1054
1054
|
// DRIFT TRIPWIRE: pubspec_pins.test.ts asserts these equal the CURRENT versions in dsl/dart/pubspec.yaml
|
|
1055
1055
|
// and dsl/dart_types/pubspec.yaml — a Dart release without this bump fails the suite, so tenants never
|
|
1056
1056
|
// land back in dependency_overrides (the exact co2 report this closes, third occurrence).
|
|
@@ -86,6 +86,17 @@ import { signerObject, SIGNER_RELATION } from "./signing_identity.js";
|
|
|
86
86
|
// them up as part of the `workspaces` domain. (architecture/platform_birth_genesis_bootstrap.md)
|
|
87
87
|
export { GenesisWarrant, seedGenesis } from "./genesis.js";
|
|
88
88
|
export { identityRelations, enrollSigner } from "./signing_identity.js";
|
|
89
|
+
// THE BIRTH-ATTESTATION CARRIER (the K_root attestation spine for platform-hosted homes). A platform must
|
|
90
|
+
// CARRY its own `platform_cert` at `birth-attestation:self` so the kernel's `assemble_home_cert_chain`
|
|
91
|
+
// PREPENDS `[home_cert, delegation]` to it and the child home roots at K_root. Governance carries the cert
|
|
92
|
+
// (this trio) but DELIBERATELY does NOT export the `parentAttestedBirth` era marker — a platform's own 1-link
|
|
93
|
+
// `[platform_cert]` chain would fail `verify_to_root` (>=2 links), so its own verify doors must stay inert
|
|
94
|
+
// while it still carries the cert for its children. Fully additive (new aggregate + directive, no era key ⇒
|
|
95
|
+
// pre-existing chains replay byte-identical). architecture/co2_attestation_spine.md.
|
|
96
|
+
export { BIRTH_ATTESTATION_ID, BirthAttestation, birthAttestation, seedBirthAttestation } from "./home.js";
|
|
97
|
+
// THE ENROLL-ONCE DELEGATION LANE — a platform records each tenant's device-key delegation (signed by its
|
|
98
|
+
// onboarding signer S_P) so the kernel reads it at `signer-delegation:<user>` when assembling a home's chain.
|
|
99
|
+
export { SignerDelegation, enrollDelegation, signerDelegationByUser } from "./signing_identity.js";
|
|
89
100
|
|
|
90
101
|
// ── WORKSPACE SELF-IDENTITY (the law reads its OWN install-context) ──────────────────────────────────
|
|
91
102
|
// The governance bundle runs on root AND every born platform. A workspace knows its ROLE via this
|