@githolon/dsl 0.14.0 → 0.15.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/src/usd.ts CHANGED
@@ -33,6 +33,7 @@ import {
33
33
  type CanonicalManifest,
34
34
  type CanonicalProjectionReturn,
35
35
  } from "./manifest.js";
36
+ import type { AggregateHandle } from "./aggregate.js";
36
37
  import {
37
38
  mergeRequiresScope,
38
39
  CompositionViolation,
@@ -126,10 +127,46 @@ export interface UsdCombined {
126
127
  readonly returns: CanonicalProjectionReturn;
127
128
  }
128
129
 
130
+ /** One field's read-projection descriptor: the field kind plus a map's value kind. */
131
+ export interface UsdFieldKindDescriptor {
132
+ readonly kind: string;
133
+ readonly mapValueKind?: string;
134
+ }
135
+
136
+ export interface UsdReadProjection {
137
+ readonly aggregateFieldKinds: Record<string, Record<string, UsdFieldKindDescriptor>>;
138
+ readonly queries: { id: string; key: { field: string; kind: string }[]; returns: string }[];
139
+ readonly counts: { id: string; of: string; by: string | null; where?: unknown }[];
140
+ readonly spatials: { id: string; of: string; on: string }[];
141
+ readonly deriveds: { id: string; of: string; returns: CanonicalProjectionReturn }[];
142
+ readonly combineds: { id: string; of: string; refField: string; reads: string; returns: CanonicalProjectionReturn }[];
143
+ readonly sums?: { id: string; of: string; field: string; by: string | null; where?: unknown }[];
144
+ readonly mins?: { id: string; of: string; field: string; by: string | null; where?: unknown }[];
145
+ readonly maxes?: { id: string; of: string; field: string; by: string | null; where?: unknown }[];
146
+ readonly orderedReads?: {
147
+ id: string;
148
+ of: string;
149
+ orderKey: string;
150
+ orderDesc?: true;
151
+ where?: unknown;
152
+ limit: number;
153
+ }[];
154
+ }
155
+
129
156
  /** One USD layer: a stage path + its prims (canonically sorted by prim path). */
130
157
  export interface UsdLayer {
131
158
  readonly path: string;
132
159
  readonly prims: UsdPrim[];
160
+ /**
161
+ * The canonical admission/merge manifest for this layer, committed inside the package.
162
+ * Hosts must not stage or mutate this view; holons derive it from active installed law.
163
+ */
164
+ readonly nomosIdentityManifest?: CanonicalManifest;
165
+ /**
166
+ * The projection schema/read-routing fragment for this layer, committed inside the package.
167
+ * It carries the projection-only field-kind data that cannot be recovered from merge drivers.
168
+ */
169
+ readonly nomosReadProjection?: UsdReadProjection;
133
170
  /**
134
171
  * The layer's NAMED, INDEXED read declarations (read-side closure step 1), SORTED
135
172
  * by id. OMITTED (`undefined`) when the module declares no query, so a query-free
@@ -363,6 +400,123 @@ function encodeModuleToPrims(layerPath: string, mod: DomainModule): UsdPrim[] {
363
400
  return sortPrims(prims);
364
401
  }
365
402
 
403
+ function aggregateFieldKindsForModule(
404
+ mod: DomainModule,
405
+ ): Record<string, Record<string, UsdFieldKindDescriptor>> {
406
+ const out: Record<string, Record<string, UsdFieldKindDescriptor>> = {};
407
+ for (const agg of [...(mod.aggregates as AggregateHandle[])].sort((a, b) =>
408
+ a.id < b.id ? -1 : a.id > b.id ? 1 : 0,
409
+ )) {
410
+ const fields: Record<string, UsdFieldKindDescriptor> = {};
411
+ for (const name of Object.keys(agg.fields).sort()) {
412
+ const field = agg.fields[name]!;
413
+ fields[name] = {
414
+ kind: field.kind,
415
+ ...(field.mapValueKind !== undefined ? { mapValueKind: field.mapValueKind } : {}),
416
+ };
417
+ }
418
+ out[agg.id] = fields;
419
+ }
420
+ return out;
421
+ }
422
+
423
+ function readKeyFieldKind(
424
+ byType: Record<string, Record<string, UsdFieldKindDescriptor>>,
425
+ queryId: string,
426
+ returns: string,
427
+ keyField: string,
428
+ ): string {
429
+ const schema = byType[returns];
430
+ if (schema === undefined) {
431
+ throw new Error(
432
+ `usd: query '${queryId}' returns '${returns}', which has no field schema in nomosReadProjection`,
433
+ );
434
+ }
435
+ const lookup = keyField.includes(".") ? keyField.split(".")[0]! : keyField;
436
+ const descriptor = schema[lookup];
437
+ if (descriptor === undefined) {
438
+ throw new Error(
439
+ `usd: query '${queryId}' is keyed on '${keyField}' (field '${lookup}'), which '${returns}' does not declare`,
440
+ );
441
+ }
442
+ return descriptor.kind;
443
+ }
444
+
445
+ function readProjectionForModule(mod: DomainModule, manifest: CanonicalManifest): UsdReadProjection {
446
+ const aggregateFieldKinds = aggregateFieldKindsForModule(mod);
447
+ return {
448
+ aggregateFieldKinds,
449
+ queries: (manifest.queries ?? []).map((q) => ({
450
+ id: q.id,
451
+ key: q.key.map((field) => ({
452
+ field,
453
+ kind: readKeyFieldKind(aggregateFieldKinds, q.id, q.returns, field),
454
+ })),
455
+ returns: q.returns,
456
+ })),
457
+ counts: (manifest.counts ?? []).map((c) => ({
458
+ id: c.id,
459
+ of: c.of,
460
+ by: c.by ?? null,
461
+ ...(c.where !== undefined ? { where: c.where } : {}),
462
+ })),
463
+ spatials: (manifest.spatials ?? []).map((s) => ({ id: s.id, of: s.of, on: s.on })),
464
+ deriveds: (manifest.deriveds ?? []).map((d) => ({ id: d.id, of: d.of, returns: d.returns })),
465
+ combineds: (manifest.combineds ?? []).map((c) => ({
466
+ id: c.id,
467
+ of: c.of,
468
+ refField: c.refField,
469
+ reads: c.reads,
470
+ returns: c.returns,
471
+ })),
472
+ ...((manifest.sums ?? []).length > 0
473
+ ? {
474
+ sums: manifest.sums!.map((s) => ({
475
+ id: s.id,
476
+ of: s.of,
477
+ field: s.sumField,
478
+ by: s.by ?? null,
479
+ ...(s.where !== undefined ? { where: s.where } : {}),
480
+ })),
481
+ }
482
+ : {}),
483
+ ...((manifest.mins ?? []).length > 0
484
+ ? {
485
+ mins: manifest.mins!.map((e) => ({
486
+ id: e.id,
487
+ of: e.of,
488
+ field: e.valueField,
489
+ by: e.by ?? null,
490
+ ...(e.where !== undefined ? { where: e.where } : {}),
491
+ })),
492
+ }
493
+ : {}),
494
+ ...((manifest.maxes ?? []).length > 0
495
+ ? {
496
+ maxes: manifest.maxes!.map((e) => ({
497
+ id: e.id,
498
+ of: e.of,
499
+ field: e.valueField,
500
+ by: e.by ?? null,
501
+ ...(e.where !== undefined ? { where: e.where } : {}),
502
+ })),
503
+ }
504
+ : {}),
505
+ ...((manifest.orderedReads ?? []).length > 0
506
+ ? {
507
+ orderedReads: manifest.orderedReads!.map((r) => ({
508
+ id: r.id,
509
+ of: r.of,
510
+ orderKey: r.orderKey,
511
+ ...(r.orderDesc ? { orderDesc: true as const } : {}),
512
+ ...(r.where !== undefined ? { where: r.where } : {}),
513
+ limit: r.limit,
514
+ })),
515
+ }
516
+ : {}),
517
+ };
518
+ }
519
+
366
520
  /**
367
521
  * Lower a layer's `relationType` decls into the canonical `nomosRelations` wire object (P1) —
368
522
  * keys SORTED for byte-determinism, omit-when-empty (the era rule). Multiple decls for one type
@@ -549,6 +703,8 @@ export function emitUsd(
549
703
  return {
550
704
  path: l.path,
551
705
  prims: encodeModuleToPrims(l.path, l.module),
706
+ nomosIdentityManifest: manifest,
707
+ nomosReadProjection: readProjectionForModule(l.module, manifest),
552
708
  ...(manifest.queries !== undefined ? { queries: manifest.queries } : {}),
553
709
  ...(manifest.deriveds !== undefined ? { deriveds: manifest.deriveds } : {}),
554
710
  ...(manifest.combineds !== undefined ? { combineds: manifest.combineds } : {}),
package/src/usd_layers.ts CHANGED
@@ -143,6 +143,40 @@ function sortedSchema(schema: WireSchema): WireSchema {
143
143
  return out;
144
144
  }
145
145
 
146
+ function domainLayerAttrLines(domain: string, layer: UsdLayer, indent: string): string[] {
147
+ return [
148
+ `${indent}custom string nomos:kind = "domain"`,
149
+ `${indent}custom string nomos:domain = ${usdaString(domain)}`,
150
+ ...(layer.nomosIdentityManifest !== undefined
151
+ ? [`${indent}custom string nomos:identityManifestHex = ${usdaString(hexUtf8(JSON.stringify(layer.nomosIdentityManifest)))}`]
152
+ : []),
153
+ ...(layer.nomosReadProjection !== undefined
154
+ ? [`${indent}custom string nomos:readProjectionHex = ${usdaString(hexUtf8(JSON.stringify(layer.nomosReadProjection)))}`]
155
+ : []),
156
+ ...(layer.nomosStableIds !== undefined
157
+ ? [`${indent}custom string nomos:stableIdsHex = ${usdaString(hexUtf8(JSON.stringify(layer.nomosStableIds)))}`]
158
+ : []),
159
+ ...(layer.nomosReadGate !== undefined
160
+ ? [`${indent}custom string nomos:readGateHex = ${usdaString(hexUtf8(JSON.stringify(layer.nomosReadGate)))}`]
161
+ : []),
162
+ ...(layer.nomosReadVisibility !== undefined
163
+ ? [`${indent}custom string nomos:readVisibilityHex = ${usdaString(hexUtf8(JSON.stringify(layer.nomosReadVisibility)))}`]
164
+ : []),
165
+ ...(layer.nomosEncryption !== undefined
166
+ ? [`${indent}custom string nomos:encryptionHex = ${usdaString(hexUtf8(JSON.stringify(layer.nomosEncryption)))}`]
167
+ : []),
168
+ ...(layer.nomosRelations !== undefined
169
+ ? [`${indent}custom string nomos:relationsHex = ${usdaString(hexUtf8(JSON.stringify(layer.nomosRelations)))}`]
170
+ : []),
171
+ ...(layer.nomosRelationGate !== undefined
172
+ ? [`${indent}custom string nomos:relationGateHex = ${usdaString(hexUtf8(JSON.stringify(layer.nomosRelationGate)))}`]
173
+ : []),
174
+ ...(layer.nomosAttestationGate !== undefined
175
+ ? [`${indent}custom string nomos:attestationGateHex = ${usdaString(hexUtf8(JSON.stringify(layer.nomosAttestationGate)))}`]
176
+ : []),
177
+ ];
178
+ }
179
+
146
180
  // ── per-module layer emission ────────────────────────────────────────────────────────
147
181
 
148
182
  /** One authored module of a domain's ordered module list (weak → strong). */
@@ -349,31 +383,9 @@ export function usdaLayerText(
349
383
  `{`,
350
384
  ` def Scope ${usdaString(primName(domain))}`,
351
385
  ` {`,
352
- ` custom string nomos:kind = "domain"`,
353
- ` custom string nomos:domain = ${usdaString(domain)}`,
354
- // STABLE IDS + the captured-read gate (#58): layer-level law keys, hex-carried
386
+ // Stable ids + holon-owned manifests: layer-level law keys, hex-carried
355
387
  // so the .usda round-trips byte-faithfully to the IR layer.
356
- ...(layer.nomosStableIds !== undefined
357
- ? [` custom string nomos:stableIdsHex = ${usdaString(hexUtf8(JSON.stringify(layer.nomosStableIds)))}`]
358
- : []),
359
- ...(layer.nomosReadGate !== undefined
360
- ? [` custom string nomos:readGateHex = ${usdaString(hexUtf8(JSON.stringify(layer.nomosReadGate)))}`]
361
- : []),
362
- ...(layer.nomosReadVisibility !== undefined
363
- ? [` custom string nomos:readVisibilityHex = ${usdaString(hexUtf8(JSON.stringify(layer.nomosReadVisibility)))}`]
364
- : []),
365
- ...(layer.nomosEncryption !== undefined
366
- ? [` custom string nomos:encryptionHex = ${usdaString(hexUtf8(JSON.stringify(layer.nomosEncryption)))}`]
367
- : []),
368
- ...(layer.nomosRelations !== undefined
369
- ? [` custom string nomos:relationsHex = ${usdaString(hexUtf8(JSON.stringify(layer.nomosRelations)))}`]
370
- : []),
371
- ...(layer.nomosRelationGate !== undefined
372
- ? [` custom string nomos:relationGateHex = ${usdaString(hexUtf8(JSON.stringify(layer.nomosRelationGate)))}`]
373
- : []),
374
- ...(layer.nomosAttestationGate !== undefined
375
- ? [` custom string nomos:attestationGateHex = ${usdaString(hexUtf8(JSON.stringify(layer.nomosAttestationGate)))}`]
376
- : []),
388
+ ...domainLayerAttrLines(domain, layer, " "),
377
389
  ``,
378
390
  ...body,
379
391
  ` }`,
@@ -388,8 +400,30 @@ export function usdaLayerText(
388
400
  * list is STRONGEST-FIRST, so the list is emitted REVERSED. Same monoid, opposite
389
401
  * notation — the reversal IS the correspondence, recorded in the doc string.
390
402
  */
391
- export function layeredRootUsda(sublayerRelPathsWeakToStrong: readonly string[]): string {
403
+ export function layeredRootUsda(
404
+ sublayerRelPathsWeakToStrong: readonly string[],
405
+ composed?: UsdDocument,
406
+ ): string {
392
407
  const strongestFirst = [...sublayerRelPathsWeakToStrong].reverse();
408
+ const composedDomainOpinions =
409
+ composed === undefined || composed.layers.length === 0
410
+ ? []
411
+ : [
412
+ ``,
413
+ `over "Nomos"`,
414
+ `{`,
415
+ ...composed.layers.flatMap((layer) => {
416
+ const domain = layer.path.slice(layer.path.lastIndexOf("/") + 1);
417
+ return [
418
+ ` over ${usdaString(primName(domain))}`,
419
+ ` {`,
420
+ ...domainLayerAttrLines(domain, layer, " "),
421
+ ` }`,
422
+ ];
423
+ }),
424
+ `}`,
425
+ ``,
426
+ ];
393
427
  return [
394
428
  `#usda 1.0`,
395
429
  `(`,
@@ -406,6 +440,7 @@ export function layeredRootUsda(sublayerRelPathsWeakToStrong: readonly string[])
406
440
  ),
407
441
  ` ]`,
408
442
  `)`,
443
+ ...composedDomainOpinions,
409
444
  ``,
410
445
  ].join("\n");
411
446
  }
@@ -461,6 +496,97 @@ function foldById<T extends { readonly id: string }>(
461
496
  return [...byId.keys()].sort().map((id) => byId.get(id)!);
462
497
  }
463
498
 
499
+ function foldByKey<T>(
500
+ lists: readonly (readonly T[] | undefined)[],
501
+ keyOf: (item: T) => string,
502
+ ): T[] | undefined {
503
+ const byKey = new Map<string, T>();
504
+ for (const list of lists) for (const item of list ?? []) byKey.set(keyOf(item), item);
505
+ if (byKey.size === 0) return undefined;
506
+ return [...byKey.keys()].sort().map((key) => byKey.get(key)!);
507
+ }
508
+
509
+ function foldRecord<T>(
510
+ records: readonly (Readonly<Record<string, T>> | undefined)[],
511
+ ): Record<string, T> | undefined {
512
+ const byKey = new Map<string, T>();
513
+ for (const record of records) {
514
+ if (record === undefined) continue;
515
+ for (const [key, value] of Object.entries(record)) byKey.set(key, value);
516
+ }
517
+ if (byKey.size === 0) return undefined;
518
+ const out: Record<string, T> = {};
519
+ for (const key of [...byKey.keys()].sort()) out[key] = byKey.get(key)!;
520
+ return out;
521
+ }
522
+
523
+ function foldIdentityManifest(
524
+ stack: readonly UsdLayer[],
525
+ stableIds: UsdLayer["nomosStableIds"],
526
+ ): UsdLayer["nomosIdentityManifest"] {
527
+ const manifests = stack
528
+ .map((l) => l.nomosIdentityManifest)
529
+ .filter((m): m is NonNullable<UsdLayer["nomosIdentityManifest"]> => m !== undefined);
530
+ if (manifests.length === 0) return undefined;
531
+ const domain = manifests[manifests.length - 1]!.domain;
532
+ const workspaceInvariants = foldById(manifests.map((m) => m.workspaceInvariants));
533
+ const queries = foldById(manifests.map((m) => m.queries));
534
+ const counts = foldById(manifests.map((m) => m.counts));
535
+ const spatials = foldById(manifests.map((m) => m.spatials));
536
+ const sums = foldById(manifests.map((m) => m.sums));
537
+ const deriveds = foldById(manifests.map((m) => m.deriveds));
538
+ const combineds = foldById(manifests.map((m) => m.combineds));
539
+ const mins = foldById(manifests.map((m) => m.mins));
540
+ const maxes = foldById(manifests.map((m) => m.maxes));
541
+ const orderedReads = foldById(manifests.map((m) => m.orderedReads));
542
+ const workspaceTypes = foldById(manifests.map((m) => m.workspaceTypes));
543
+ const homes = foldRecord(manifests.map((m) => m.homes));
544
+ const routes = foldByKey(manifests.map((m) => m.routes), (r) => r.directive);
545
+ return {
546
+ domain,
547
+ aggregates: foldById(manifests.map((m) => m.aggregates)) ?? [],
548
+ directives: foldById(manifests.map((m) => m.directives)) ?? [],
549
+ ...(stableIds !== undefined ? { stableIds } : {}),
550
+ ...(workspaceInvariants !== undefined ? { workspaceInvariants } : {}),
551
+ ...(queries !== undefined ? { queries } : {}),
552
+ ...(counts !== undefined ? { counts } : {}),
553
+ ...(spatials !== undefined ? { spatials } : {}),
554
+ ...(sums !== undefined ? { sums } : {}),
555
+ ...(deriveds !== undefined ? { deriveds } : {}),
556
+ ...(combineds !== undefined ? { combineds } : {}),
557
+ ...(mins !== undefined ? { mins } : {}),
558
+ ...(maxes !== undefined ? { maxes } : {}),
559
+ ...(orderedReads !== undefined ? { orderedReads } : {}),
560
+ ...(workspaceTypes !== undefined ? { workspaceTypes } : {}),
561
+ ...(homes !== undefined ? { homes } : {}),
562
+ ...(routes !== undefined ? { routes } : {}),
563
+ };
564
+ }
565
+
566
+ function foldReadProjection(stack: readonly UsdLayer[]): UsdLayer["nomosReadProjection"] {
567
+ const projections = stack
568
+ .map((l) => l.nomosReadProjection)
569
+ .filter((p): p is NonNullable<UsdLayer["nomosReadProjection"]> => p !== undefined);
570
+ if (projections.length === 0) return undefined;
571
+ const aggregateFieldKinds = foldRecord(projections.map((p) => p.aggregateFieldKinds)) ?? {};
572
+ const sums = foldById(projections.map((p) => p.sums));
573
+ const mins = foldById(projections.map((p) => p.mins));
574
+ const maxes = foldById(projections.map((p) => p.maxes));
575
+ const orderedReads = foldById(projections.map((p) => p.orderedReads));
576
+ return {
577
+ aggregateFieldKinds,
578
+ queries: foldById(projections.map((p) => p.queries)) ?? [],
579
+ counts: foldById(projections.map((p) => p.counts)) ?? [],
580
+ spatials: foldById(projections.map((p) => p.spatials)) ?? [],
581
+ deriveds: foldById(projections.map((p) => p.deriveds)) ?? [],
582
+ combineds: foldById(projections.map((p) => p.combineds)) ?? [],
583
+ ...(sums !== undefined ? { sums } : {}),
584
+ ...(mins !== undefined ? { mins } : {}),
585
+ ...(maxes !== undefined ? { maxes } : {}),
586
+ ...(orderedReads !== undefined ? { orderedReads } : {}),
587
+ };
588
+ }
589
+
464
590
  /**
465
591
  * THE ORDERED OPINION-MAP FOLD: flatten module layers (weak → strong within each
466
592
  * stage path) into the effective single-layer-per-domain document. Strongest
@@ -509,6 +635,8 @@ export function flattenLayeredUsd(layers: readonly UsdLayer[]): UsdDocument {
509
635
  stableIds = { v: 1, domain: domainSid, aggregates };
510
636
  }
511
637
  }
638
+ const identityManifest = foldIdentityManifest(stack, stableIds);
639
+ const readProjection = foldReadProjection(stack);
512
640
  // The captured-read gate (#58): queries + per-directive read sets merged
513
641
  // later-wins, SORTED keys (matching the composed emission).
514
642
  let readGate: UsdLayer["nomosReadGate"];
@@ -606,6 +734,8 @@ export function flattenLayeredUsd(layers: readonly UsdLayer[]): UsdDocument {
606
734
  return {
607
735
  path,
608
736
  prims: [...prims.keys()].sort().map((p) => prims.get(p)!),
737
+ ...(identityManifest !== undefined ? { nomosIdentityManifest: identityManifest } : {}),
738
+ ...(readProjection !== undefined ? { nomosReadProjection: readProjection } : {}),
609
739
  ...(queries !== undefined ? { queries } : {}),
610
740
  ...(deriveds !== undefined ? { deriveds } : {}),
611
741
  ...(combineds !== undefined ? { combineds } : {}),
@@ -733,6 +863,8 @@ function attrStringArray(prim: ParsedPrim, name: string): string[] {
733
863
  export function parseUsdaDocument(text: string): UsdDocument {
734
864
  const prims = parseUsdaPrims(text);
735
865
  const domainByScope = new Map<string, string>();
866
+ const identityManifestByDomain = new Map<string, UsdLayer["nomosIdentityManifest"]>();
867
+ const readProjectionByDomain = new Map<string, UsdLayer["nomosReadProjection"]>();
736
868
  const stableIdsByDomain = new Map<string, UsdLayer["nomosStableIds"]>();
737
869
  const readGateByDomain = new Map<string, UsdLayer["nomosReadGate"]>();
738
870
  const readVisibilityByDomain = new Map<string, UsdLayer["nomosReadVisibility"]>();
@@ -744,7 +876,15 @@ export function parseUsdaDocument(text: string): UsdDocument {
744
876
  if (p.attrs.get("nomos:kind") === "domain") {
745
877
  const domain = attrString(p, "nomos:domain");
746
878
  domainByScope.set(p.path, domain);
747
- // STABLE IDS + the captured-read gate (#58): the hex-carried layer-level keys.
879
+ // Holon-owned manifests + gates: the hex-carried layer-level law keys.
880
+ const idHex = p.attrs.get("nomos:identityManifestHex");
881
+ if (typeof idHex === "string") {
882
+ identityManifestByDomain.set(domain, JSON.parse(unhexUtf8(idHex)) as UsdLayer["nomosIdentityManifest"]);
883
+ }
884
+ const rpHex = p.attrs.get("nomos:readProjectionHex");
885
+ if (typeof rpHex === "string") {
886
+ readProjectionByDomain.set(domain, JSON.parse(unhexUtf8(rpHex)) as UsdLayer["nomosReadProjection"]);
887
+ }
748
888
  const sidHex = p.attrs.get("nomos:stableIdsHex");
749
889
  if (typeof sidHex === "string") {
750
890
  stableIdsByDomain.set(domain, JSON.parse(unhexUtf8(sidHex)) as UsdLayer["nomosStableIds"]);
@@ -865,6 +1005,8 @@ export function parseUsdaDocument(text: string): UsdDocument {
865
1005
  const layers: UsdLayer[] = [...buckets.keys()]
866
1006
  .map((domain) => {
867
1007
  const b = buckets.get(domain)!;
1008
+ const identity = identityManifestByDomain.get(domain);
1009
+ const readProjection = readProjectionByDomain.get(domain);
868
1010
  const sids = stableIdsByDomain.get(domain);
869
1011
  const rg = readGateByDomain.get(domain);
870
1012
  const rv = readVisibilityByDomain.get(domain);
@@ -875,6 +1017,8 @@ export function parseUsdaDocument(text: string): UsdDocument {
875
1017
  return {
876
1018
  path: `/Nomos/${domain}`,
877
1019
  prims: [...b.prims].sort(byPath),
1020
+ ...(identity !== undefined ? { nomosIdentityManifest: identity } : {}),
1021
+ ...(readProjection !== undefined ? { nomosReadProjection: readProjection } : {}),
878
1022
  ...(b.queries.length > 0 ? { queries: [...b.queries].sort(byId) } : {}),
879
1023
  ...(b.deriveds.length > 0 ? { deriveds: [...b.deriveds].sort(byId) } : {}),
880
1024
  ...(b.combineds.length > 0 ? { combineds: [...b.combineds].sort(byId) } : {}),
@@ -10,7 +10,7 @@
10
10
  * invariants, slice 3 delta lane + least-loaded placement).
11
11
  *
12
12
  * `nomos-compile` APPENDS this module to a TAXONOMY-BEARING domain's module list —
13
- * both in the canonical manifests (the placement law is hash-bearing law) and in the
13
+ * both in the compiled package metadata (the placement law is hash-bearing law) and in the
14
14
  * generated engine entry (the plans ship in the lump). A taxonomy-FREE package never
15
15
  * imports it (subpath `@githolon/dsl/workspace-sharding`, never the runtime barrel —
16
16
  * the slice-1 hash-stability law: its bytes must not enter other tenants' lumps).
@@ -110,7 +110,7 @@ export interface ShardingRouteSpec {
110
110
  export interface ShardingLawSpec {
111
111
  readonly axes: readonly ShardingAxisSpec[];
112
112
  /**
113
- * THE DERIVED ROUTES (slice 2's canonical-manifest `routes`, fed back into the law):
113
+ * THE DERIVED ROUTES (slice 2's package route facts, fed back into the law):
114
114
  * per routed directive, the homing invariant `nomosWrongHome:<directive>` is derived
115
115
  * so THE CHAIN GATE ITSELF refuses a wrong-home write (#41 — slice 3a; the edge
116
116
  * bailiff stays as defense-in-depth). OMITTED routes ⇒ no invariants (slice-2 shape).
@@ -317,7 +317,6 @@ export const NomosSummarySubtotal = aggregate("NomosSummarySubtotal", {
317
317
  export const NomosSummaryFrontier = aggregate("NomosSummaryFrontier", {
318
318
  shard: t.string().merge(Lww),
319
319
  frontier: t.string().merge(Lww), // the shard main oid the subtotals are true at
320
- readManifestHash: t.string().merge(Lww),
321
320
  updatedAt: t.string().merge(Lww),
322
321
  });
323
322
 
@@ -530,7 +529,6 @@ export const nomosAmendSummaryFrontier = directive("nomosAmendSummaryFrontier")
530
529
  z.object({
531
530
  shard: z.string().regex(/^s\d+$/),
532
531
  frontier: z.string(),
533
- readManifestHash: z.string(),
534
532
  updatedAt: z.string(),
535
533
  }),
536
534
  )
@@ -539,7 +537,6 @@ export const nomosAmendSummaryFrontier = directive("nomosAmendSummaryFrontier")
539
537
  return [
540
538
  withMarker(set(wm, "shard", p.shard), "ensures"),
541
539
  set(wm, "frontier", p.frontier),
542
- set(wm, "readManifestHash", p.readManifestHash),
543
540
  set(wm, "updatedAt", p.updatedAt),
544
541
  ];
545
542
  });
@@ -656,7 +653,6 @@ export const nomosPropagateSummary = directive("nomosPropagateSummary")
656
653
  shard: z.string().regex(/^s\d+$/),
657
654
  fromOid: z.string(), // "" = the shard's first delta (a virgin coordinator record)
658
655
  toOid: z.string().min(1),
659
- readManifestHash: z.string(),
660
656
  propagatedAt: z.string(),
661
657
  subtotals: z.array(summarySubtotalSchema).min(1).max(1024),
662
658
  events: z.array(summaryEventSchema).max(4096),
@@ -762,7 +758,6 @@ export const nomosPropagateSummary = directive("nomosPropagateSummary")
762
758
  ops.push(
763
759
  withMarker(set(wm, "shard", p.shard), "ensures"),
764
760
  set(wm, "frontier", p.toOid),
765
- set(wm, "readManifestHash", p.readManifestHash),
766
761
  set(wm, "updatedAt", p.propagatedAt),
767
762
  );
768
763
  return ops;