@githolon/dsl 0.102.5 → 0.103.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.
Files changed (131) hide show
  1. package/compile_package.mjs +43 -2
  2. package/compile_proof.d.mts +47 -0
  3. package/compile_proof.mjs +343 -0
  4. package/dart/CHANGELOG.md +7 -0
  5. package/dart/lib/src/dev_cloud.dart +8 -8
  6. package/dart/lib/src/nms_generated_runtime.dart +2 -0
  7. package/dart/lib/src/runner/node-entry.mjs +5504 -1236
  8. package/dart/lib/src/runner/offline-install.mjs +4578 -528
  9. package/dart/lib/src/test_harness.dart +206 -152
  10. package/dart/lib/src/webview_bridge.dart +196 -89
  11. package/dart/pubspec.lock +1 -1
  12. package/dart/pubspec.yaml +2 -2
  13. package/dart/test/acquire_session_credentials_test.dart +4 -3
  14. package/dart/test/adv_realm_interference_test.dart +7 -6
  15. package/dart/test/cloud_bound_topology_test.dart +3 -3
  16. package/dart/test/cluster_births_test.dart +4 -3
  17. package/dart/test/cluster_device_keyed_acceptance_test.dart +10 -16
  18. package/dart/test/cluster_local_autosync_test.dart +3 -2
  19. package/dart/test/cluster_scale_test.dart +3 -2
  20. package/dart/test/dlq_session_surface_test.dart +7 -6
  21. package/dart/test/first_app_gauntlet_test.dart +14 -21
  22. package/dart/test/fixtures/wedge/fake-install.mjs +1 -1
  23. package/dart/test/four_layer_nested_topology_test.dart +4 -4
  24. package/dart/test/harness_phase_timeout_test.dart +2 -2
  25. package/dart/test/local_sync_inert_test.dart +1 -1
  26. package/dart/test/parent_signer_recovery_test.dart +2 -2
  27. package/dart/test/sealing_client_test.dart +4 -3
  28. package/dart/test/session_bound_test.dart +8 -7
  29. package/dart/test/test_harness_test.dart +13 -12
  30. package/dart/test/vo_read_typing_test.dart +4 -3
  31. package/dart/test/watch_after_offer_stall_test.dart +4 -3
  32. package/dart/test/webview_bridge_test.dart +102 -5
  33. package/dart_types/CHANGELOG.md +5 -0
  34. package/dart_types/lib/nomos_types.dart +9 -0
  35. package/dart_types/lib/src/nomos_ref.dart +20 -0
  36. package/dart_types/lib/src/optional_ref.dart +85 -0
  37. package/dart_types/lib/src/sha256_digest.dart +41 -0
  38. package/dart_types/lib/src/versioned_nomos_ref.dart +81 -0
  39. package/dart_types/pubspec.yaml +1 -1
  40. package/dart_types/test/optional_ref_test.dart +44 -0
  41. package/dart_types/test/sha256_digest_test.dart +18 -0
  42. package/package.json +9 -5
  43. package/runtime/generated-application-host.js +5365 -1105
  44. package/src/aggregate.ts +18 -0
  45. package/src/application_composition.ts +6 -32
  46. package/src/attested_core.ts +6 -3
  47. package/src/birth_meter.ts +1 -0
  48. package/src/birth_meter_ensure.ts +28 -2
  49. package/src/births.ts +1 -1
  50. package/src/build_package.ts +162 -538
  51. package/src/business_birth.ts +19 -3
  52. package/src/canonical_json.ts +21 -0
  53. package/src/check_package_main.ts +73 -33
  54. package/src/clear_directive.ts +19 -8
  55. package/src/codegen_dart.ts +305 -22
  56. package/src/codegen_dart_application.ts +844 -292
  57. package/src/codegen_dart_client.ts +1084 -407
  58. package/src/codegen_dart_scenario.ts +12 -12
  59. package/src/codegen_proof.ts +169 -39
  60. package/src/codegen_provider_dart.ts +17 -1
  61. package/src/codegen_ts.ts +298 -106
  62. package/src/compat_manifest.ts +2 -2
  63. package/src/compat_package_main.ts +8 -12
  64. package/src/compile_package_main.ts +1858 -590
  65. package/src/compose.ts +1 -1
  66. package/src/directive.ts +208 -15
  67. package/src/engine_entry.ts +165 -111
  68. package/src/evolve_preview.ts +29 -69
  69. package/src/extremum.ts +1 -1
  70. package/src/fields.ts +183 -4
  71. package/src/flow_gate.ts +75 -2
  72. package/src/framework/application_home.ts +2 -0
  73. package/src/framework/auth_provider_law.ts +2 -2
  74. package/src/framework/birth_meter.ts +7 -19
  75. package/src/framework/bootstrap.ts +0 -2
  76. package/src/framework/business_corrections.ts +9 -5
  77. package/src/framework/domain_lifecycle.ts +15 -29
  78. package/src/framework/encryption_scope.ts +2 -1
  79. package/src/framework/framework_aggregates.ts +2 -0
  80. package/src/framework/genesis.ts +16 -14
  81. package/src/framework/home.ts +20 -14
  82. package/src/framework/owned_custody.ts +9 -3
  83. package/src/framework/platform_admin.ts +3 -3
  84. package/src/framework/relations.ts +21 -13
  85. package/src/framework/signing_identity.ts +45 -40
  86. package/src/framework/workspace_invariant.ts +245 -0
  87. package/src/framework/workspaces.ts +23 -29
  88. package/src/index.ts +36 -16
  89. package/src/intent.ts +178 -6
  90. package/src/law_check.ts +32 -11
  91. package/src/law_graph.ts +2902 -0
  92. package/src/law_graph_usda.ts +1799 -0
  93. package/src/law_identity.ts +435 -0
  94. package/src/law_value_type.ts +230 -0
  95. package/src/lsp_server.ts +58 -29
  96. package/src/ops.ts +7 -0
  97. package/src/package_config.ts +141 -0
  98. package/src/package_dependencies.ts +108 -0
  99. package/src/package_dependency_usage.ts +150 -0
  100. package/src/package_source_imports.ts +71 -0
  101. package/src/plan_source_slice.ts +335 -0
  102. package/src/point_guard.ts +192 -0
  103. package/src/precondition.ts +44 -9
  104. package/src/read_projection_namespace.ts +1 -1
  105. package/src/runtime_zod.ts +44 -0
  106. package/src/secondary_ensure.ts +67 -14
  107. package/src/shape_compat.ts +1 -1
  108. package/src/stable_id_identity_bridge.ts +149 -0
  109. package/src/stable_id_lockfile.ts +140 -6
  110. package/src/stable_ids.ts +1 -1
  111. package/src/stable_ids_for_module.ts +348 -0
  112. package/src/stable_ids_types.ts +1 -1
  113. package/src/sum.ts +1 -1
  114. package/src/usd_state.ts +1 -1
  115. package/src/usda_relationship_integrity.ts +66 -0
  116. package/src/usda_text.ts +18 -0
  117. package/src/usdz.ts +78 -0
  118. package/src/value_object.ts +95 -0
  119. package/src/wire.ts +19 -0
  120. package/src/wire_encode.ts +22 -0
  121. package/src/workspace_sharding.ts +52 -36
  122. package/src/workspace_sharing.ts +28 -4
  123. package/src/zod_introspection.ts +1 -1
  124. package/dart/test/cluster_attested_test.dart +0 -201
  125. package/src/compile_engine.ts +0 -595
  126. package/src/manifest.ts +0 -1476
  127. package/src/read_projection_composition.ts +0 -117
  128. package/src/read_projection_manifest.ts +0 -115
  129. package/src/relation_composition.ts +0 -286
  130. package/src/usd.ts +0 -1967
  131. package/src/usd_layers.ts +0 -1776
@@ -35,6 +35,8 @@
35
35
  * workspace scan / projection read / ambient "current world" read — only the declared refs.
36
36
  */
37
37
 
38
+ import type { PointGuardSpec } from "../point_guard.js";
39
+
38
40
  /** A TYPED verdict — identical shape to the aggregate invariant (the engine parses both). */
39
41
  export type WorkspaceInvariantVerdict = { accept: true } | { reject: string };
40
42
 
@@ -51,6 +53,240 @@ export interface InvariantRef {
51
53
  readonly id: string;
52
54
  }
53
55
 
56
+ /** A native point-read recipe. This is authored in TypeScript, custodied as typed USDA, and
57
+ * interpreted by Rust. It is data, not an executable JavaScript read selector. */
58
+ export type InvariantReadTransform = "none" | "row-key" | "stable-id";
59
+
60
+ export type InvariantReadIdPart =
61
+ | { readonly source: "literal"; readonly value: string }
62
+ | { readonly source: "payload" | "item"; readonly path: readonly string[]; readonly transform: InvariantReadTransform };
63
+
64
+ export type InvariantReadId =
65
+ | { readonly source: "literal"; readonly value: string }
66
+ | {
67
+ readonly source: "payload";
68
+ readonly path: readonly string[];
69
+ readonly prefix: string;
70
+ readonly suffix: string;
71
+ readonly optional: boolean;
72
+ }
73
+ | { readonly source: "template"; readonly parts: readonly InvariantReadIdPart[]; readonly optional: boolean };
74
+
75
+ export interface InvariantReadBinding {
76
+ readonly binding: string;
77
+ readonly aggregate: string;
78
+ readonly state: "pre" | "post";
79
+ readonly eachPayloadPath?: readonly string[];
80
+ readonly id: InvariantReadId;
81
+ }
82
+
83
+ function readPath(path: string | readonly string[]): readonly string[] {
84
+ return typeof path === "string" ? path.split(".").filter(Boolean) : [...path];
85
+ }
86
+
87
+ export function idLiteral(value: string): InvariantReadIdPart {
88
+ return { source: "literal", value };
89
+ }
90
+
91
+ export function idPayload(
92
+ path: string | readonly string[],
93
+ transform: InvariantReadTransform = "none",
94
+ ): InvariantReadIdPart {
95
+ return { source: "payload", path: readPath(path), transform };
96
+ }
97
+
98
+ export function idItem(
99
+ path: string | readonly string[] = [],
100
+ transform: InvariantReadTransform = "none",
101
+ ): InvariantReadIdPart {
102
+ return { source: "item", path: readPath(path), transform };
103
+ }
104
+
105
+ export function idTemplate(
106
+ ...parts: readonly (InvariantReadIdPart | string)[]
107
+ ): readonly InvariantReadIdPart[] {
108
+ return parts.map((part) => typeof part === "string" ? idLiteral(part) : part);
109
+ }
110
+
111
+ const NATIVE_READ_SET = Symbol.for("nomos.workspaceInvariant.nativeReadSet.v1");
112
+
113
+ type NativeReadSet = WorkspaceInvariantReads & {
114
+ readonly [NATIVE_READ_SET]: readonly InvariantReadBinding[];
115
+ };
116
+
117
+ function aggregateName(aggregate: { readonly id: string } | string): string {
118
+ return typeof aggregate === "string" ? aggregate : aggregate.id;
119
+ }
120
+
121
+ /** Begin one typed, bounded aggregate read. Prefer an aggregate handle; strings remain available
122
+ * for framework composition where the declaration is intentionally late-bound. */
123
+ export function readRef(
124
+ binding: string,
125
+ aggregate: { readonly id: string } | string,
126
+ ): {
127
+ at(id: string): InvariantReadBinding;
128
+ fromPayload(path: string | readonly string[], options?: { readonly prefix?: string; readonly suffix?: string }): InvariantReadBinding;
129
+ fromOptionalPayload(path: string | readonly string[], options?: { readonly prefix?: string; readonly suffix?: string }): InvariantReadBinding;
130
+ fromTemplate(parts: readonly InvariantReadIdPart[], options?: { readonly optional?: boolean }): InvariantReadBinding;
131
+ forEach(
132
+ path: string | readonly string[],
133
+ parts: readonly InvariantReadIdPart[],
134
+ options?: { readonly optional?: boolean },
135
+ ): InvariantReadBinding;
136
+ pre(): ReturnType<typeof readRef>;
137
+ post(): ReturnType<typeof readRef>;
138
+ } {
139
+ const build = (state: "pre" | "post") => ({
140
+ at(id: string): InvariantReadBinding {
141
+ return { binding, aggregate: aggregateName(aggregate), state, id: { source: "literal", value: id } };
142
+ },
143
+ fromPayload(
144
+ path: string | readonly string[],
145
+ options: { readonly prefix?: string; readonly suffix?: string } = {},
146
+ ): InvariantReadBinding {
147
+ return {
148
+ binding,
149
+ aggregate: aggregateName(aggregate),
150
+ state,
151
+ id: {
152
+ source: "payload",
153
+ path: readPath(path),
154
+ prefix: options.prefix ?? "",
155
+ suffix: options.suffix ?? "",
156
+ optional: false,
157
+ },
158
+ };
159
+ },
160
+ fromOptionalPayload(
161
+ path: string | readonly string[],
162
+ options: { readonly prefix?: string; readonly suffix?: string } = {},
163
+ ): InvariantReadBinding {
164
+ const binding = build(state).fromPayload(path, options);
165
+ if (binding.id.source !== "payload") return binding;
166
+ return { ...binding, id: { ...binding.id, optional: true } };
167
+ },
168
+ fromTemplate(
169
+ parts: readonly InvariantReadIdPart[],
170
+ options: { readonly optional?: boolean } = {},
171
+ ): InvariantReadBinding {
172
+ return {
173
+ binding,
174
+ aggregate: aggregateName(aggregate),
175
+ state,
176
+ id: { source: "template", parts: [...parts], optional: options.optional ?? false },
177
+ };
178
+ },
179
+ forEach(
180
+ path: string | readonly string[],
181
+ parts: readonly InvariantReadIdPart[],
182
+ options: { readonly optional?: boolean } = {},
183
+ ): InvariantReadBinding {
184
+ return {
185
+ ...build(state).fromTemplate(parts, options),
186
+ eachPayloadPath: readPath(path),
187
+ };
188
+ },
189
+ pre: () => build("pre"),
190
+ post: () => build("post"),
191
+ });
192
+ return build("post");
193
+ }
194
+
195
+ function valueAtPath(value: unknown, path: readonly string[]): unknown {
196
+ let current = value;
197
+ for (const part of path) {
198
+ if (current === null || typeof current !== "object") return undefined;
199
+ current = (current as Record<string, unknown>)[part];
200
+ }
201
+ return current;
202
+ }
203
+
204
+ function transformReadPart(value: string, transform: InvariantReadTransform): string {
205
+ if (transform === "row-key") {
206
+ return value.replace(/%/g, "%25").replace(/_/g, "%5F").replace(/\|/g, "%7C");
207
+ }
208
+ if (transform === "stable-id") return value.replace(/[^A-Za-z0-9.@/-]/g, "-");
209
+ return value;
210
+ }
211
+
212
+ function resolveTemplate(
213
+ parts: readonly InvariantReadIdPart[],
214
+ intent: Record<string, unknown>,
215
+ item: unknown,
216
+ ): string | undefined {
217
+ let result = "";
218
+ for (const part of parts) {
219
+ if (part.source === "literal") {
220
+ result += part.value;
221
+ continue;
222
+ }
223
+ const value = valueAtPath(part.source === "payload" ? intent : item, part.path);
224
+ if (value === undefined || value === null) return undefined;
225
+ if (typeof value !== "string" && typeof value !== "number") return undefined;
226
+ result += transformReadPart(String(value), part.transform);
227
+ }
228
+ return result;
229
+ }
230
+
231
+ /** Resolve a typed read-id expression for authoring-time probes and precondition planning.
232
+ * Runtime admission evaluates the custodied twin directly in Rust. */
233
+ export function resolveInvariantReadId(
234
+ id: InvariantReadId,
235
+ intent: Record<string, unknown>,
236
+ item?: unknown,
237
+ ): string | undefined {
238
+ if (id.source === "literal") return id.value;
239
+ if (id.source === "payload") {
240
+ const value = valueAtPath(intent, id.path);
241
+ if (value === undefined || value === null || value === "") return id.optional ? undefined : "";
242
+ if (typeof value !== "string" && typeof value !== "number") return id.optional ? undefined : "";
243
+ return `${id.prefix}${String(value)}${id.suffix}`;
244
+ }
245
+ return resolveTemplate(id.parts, intent, item);
246
+ }
247
+
248
+ /** Declare a bounded set of generic point reads. The returned callable keeps authoring-time tests
249
+ * ergonomic, while the non-enumerable metadata is what the compiler lowers into USDA. */
250
+ export function readSet(...bindings: readonly InvariantReadBinding[]): WorkspaceInvariantReads {
251
+ const selector = ((ctx: { intent: Record<string, unknown> }) => {
252
+ const refs: InvariantRef[] = [];
253
+ for (const binding of bindings) {
254
+ const repeated = binding.eachPayloadPath === undefined
255
+ ? [undefined]
256
+ : valueAtPath(ctx.intent, binding.eachPayloadPath);
257
+ if (!Array.isArray(repeated)) {
258
+ if (binding.eachPayloadPath !== undefined && binding.id.source === "template" && binding.id.optional) continue;
259
+ if (binding.eachPayloadPath !== undefined) continue;
260
+ }
261
+ const items: readonly unknown[] = Array.isArray(repeated) ? repeated : [undefined];
262
+ for (let index = 0; index < items.length; index += 1) {
263
+ let id = resolveInvariantReadId(binding.id, ctx.intent, items[index]);
264
+ if (id === undefined && binding.id.source !== "literal" && binding.id.optional) continue;
265
+ id ??= "";
266
+ refs.push({
267
+ name: binding.eachPayloadPath === undefined ? binding.binding : `${binding.binding}${index}`,
268
+ aggregate: binding.aggregate,
269
+ id: binding.state === "pre" ? `pre:${id}` : id,
270
+ });
271
+ }
272
+ }
273
+ return refs;
274
+ }) as NativeReadSet;
275
+ Object.defineProperty(selector, NATIVE_READ_SET, {
276
+ value: bindings.map((binding) => ({ ...binding })),
277
+ enumerable: false,
278
+ writable: false,
279
+ });
280
+ return selector;
281
+ }
282
+
283
+ /** Compiler-only access to a native read set. Ordinary callbacks deliberately return undefined. */
284
+ export function nativeReadBindings(
285
+ reads: WorkspaceInvariantReads,
286
+ ): readonly InvariantReadBinding[] | undefined {
287
+ return (reads as Partial<NativeReadSet>)[NATIVE_READ_SET];
288
+ }
289
+
54
290
  /** `inventory.Item` → `item`; `layout.FloorPlan` → `floorPlan` (short segment, first-lower). */
55
291
  function deriveName(aggregateType: string): string {
56
292
  const short = aggregateType.includes(".")
@@ -140,6 +376,8 @@ export interface WorkspaceInvariantDecl {
140
376
  readonly on: string;
141
377
  /** The executable declared read-set — ships in the engine bundle, NOT the manifest. */
142
378
  readonly reads: WorkspaceInvariantReads;
379
+ /** Typed generic read recipes lowered into USDA. Absent only for not-yet-migrated callbacks. */
380
+ readonly __nomosReadBindings?: readonly InvariantReadBinding[];
143
381
  /** The executable predicate — ships in the engine bundle, NOT the manifest. */
144
382
  readonly assert: WorkspaceInvariantAssert;
145
383
  /**
@@ -150,6 +388,11 @@ export interface WorkspaceInvariantDecl {
150
388
  * a secret-correlated refusal.
151
389
  */
152
390
  readonly declassify?: string;
391
+ /** Framework-owned evaluator whose complete semantics are part of the named kernel ABI.
392
+ * Tenant-authored invariants omit this and execute their sealed USDA plan. */
393
+ readonly __nomosEvaluator?: "birth-quota-v1" | "founder-signer-write-once-v1" | "point-guard-v1";
394
+ /** Typed point-state law consumed directly by the kernel when evaluator is `point-guard-v1`. */
395
+ readonly __nomosPointGuard?: PointGuardSpec;
153
396
  /** Framework-only provenance used to keep compiler errors on the tenant-authored surface. */
154
397
  readonly __nomosGenerated?: "directive-precondition";
155
398
  /** Brand so a plain object is never mistaken for a declaration. */
@@ -173,10 +416,12 @@ export function workspaceInvariant(id: string): {
173
416
  } {
174
417
  const finish = (directiveId: string, reads: WorkspaceInvariantReads, declassify: string | undefined) => ({
175
418
  assert(assert: WorkspaceInvariantAssert): WorkspaceInvariantDecl {
419
+ const readBindings = nativeReadBindings(reads);
176
420
  return {
177
421
  id,
178
422
  on: directiveId,
179
423
  reads,
424
+ ...(readBindings === undefined ? {} : { __nomosReadBindings: readBindings }),
180
425
  assert,
181
426
  ...(declassify !== undefined ? { declassify } : {}),
182
427
  __isWorkspaceInvariant: true as const,
@@ -74,7 +74,7 @@ import { t } from "../fields.js";
74
74
  import { set, withMarker } from "../ops.js";
75
75
  import { query } from "../query.js";
76
76
  import { read } from "../read.js";
77
- import { workspaceInvariant, refAs, type WorkspaceInvariantVerdict } from "./workspace_invariant.js";
77
+ import { readRef, readSet, workspaceInvariant, refAs, type WorkspaceInvariantVerdict } from "./workspace_invariant.js";
78
78
  import { writeTuple, removeTuple, RelationTuple, relationTupleInstanceId } from "./relations.js";
79
79
  import { relationType, self, user, key } from "../relation_schema.js";
80
80
  import { GENESIS_WARRANT_ID } from "./genesis.js";
@@ -143,7 +143,7 @@ export const workspaceSelfWriteOnce = workspaceInvariant("WorkspaceSelfWriteOnce
143
143
  // NEVER match the bare runtime id ⇒ the gate stays silently INERT (the #266 side-door bug,
144
144
  // 2026-06-15). Bare matches — exactly the convention the sharding invariants already fire under.
145
145
  .on("ensureWorkspaceSelf")
146
- .reads(() => [refAs("self", "WorkspaceSelf", "pre:" + WORKSPACE_SELF_ID)])
146
+ .reads(readSet(readRef("self", WorkspaceSelf).pre().at(WORKSPACE_SELF_ID)))
147
147
  // WRITE-ONCE on the self-record's PRESENCE via `name` (not the vestigial `role`). At genesis name + role
148
148
  // were always co-written, so an existing born workspace has `name` ⇒ behaviour preserved; a fresh one has
149
149
  // neither ⇒ first set admitted.
@@ -542,15 +542,14 @@ export function buildGenesisChain(p: {
542
542
  rebornFrom?: string;
543
543
  }): string {
544
544
  const founder = "user:" + p.principal;
545
- // THE ORDER-DECLARED LAW INSTALL (G3): the child installs the EXACT law the order names — bytes are NOT in
546
- // the recipe (the kernel resolves them by hash from its own custody when it folds the birth, never the
547
- // host). `domainHash` names the law; `domainPackageB64` stays empty here (the kernel supplies bytes-by-hash
548
- // for the in-chain install). Two layers, matching the genesis bootstrap: bootstrap controller, then law.
545
+ // THE ORDER-DECLARED LAW INSTALL (G3): the child installs the EXACT typed USDA closures the order names.
546
+ // Bytes are NOT in the recipe; the kernel resolves each identity from its own custody when it folds the
547
+ // birth. Two layers, matching the genesis bootstrap: bootstrap controller, then law.
549
548
  const installSteps =
550
549
  p.frameworkHash && p.lawHash
551
550
  ? [
552
- { domain: "bootstrap", directiveId: "installDomain", actor: founder, payload: { domainHash: p.frameworkHash }, domainHash: p.frameworkHash, domainPackageB64: "" },
553
- { domain: "nomos", directiveId: "installDomain", actor: founder, payload: { domainHash: p.lawHash }, domainHash: p.lawHash, domainPackageB64: "" },
551
+ { domain: "bootstrap", directiveId: "installDomain", actor: founder, payload: { domainHash: p.frameworkHash }, domainHash: p.frameworkHash },
552
+ { domain: "nomos", directiveId: "installDomain", actor: founder, payload: { domainHash: p.lawHash }, domainHash: p.lawHash },
554
553
  ]
555
554
  : [];
556
555
  // THE LINEAGE-AUTHORIZATION BINDING (proof-friendly): the child's birthCloud records who authorized it, so
@@ -800,7 +799,8 @@ export const birthCloud = directive("birthCloud")
800
799
  // the born marker; `role` is no longer written (vestigial node-class — see WorkspaceSelf).
801
800
  ensure(WorkspaceSelf, WORKSPACE_SELF_ID).set("name", p.name);
802
801
  return [];
803
- });
802
+ })
803
+ .alsoEnsures(WorkspaceSelf);
804
804
 
805
805
  /**
806
806
  * provisionWorkspace — the worker's RETURN RECEIPT: authored AFTER it physically
@@ -917,9 +917,7 @@ export const retireOwnWorkspace = directive("retireOwnWorkspace")
917
917
  * so the read manifest is unchanged (era-/evolve-safe). */
918
918
  export const retireOwnOnly = workspaceInvariant("RetireOwnOnly")
919
919
  .on("retireOwnWorkspace")
920
- .reads((ctx) => [
921
- refAs("target", "CloudWorkspace", "pre:" + String((ctx?.intent ?? {}).workspaceId ?? "")),
922
- ])
920
+ .reads(readSet(readRef("target", CloudWorkspace).pre().fromPayload("workspaceId")))
923
921
  .assert((refs, ctx) => {
924
922
  const target = (refs as { target?: { principal?: string; createdBy?: string } }).target;
925
923
  // The captured, VERIFIED author rides as a SUBJECT (`user:<uid>`); the record's creator fields
@@ -1031,9 +1029,7 @@ export const rebirthWorkspace = directive("rebirthWorkspace")
1031
1029
  */
1032
1030
  export const rebirthNotRoot = workspaceInvariant("RebirthNotRoot")
1033
1031
  .on("rebirthWorkspace")
1034
- .reads((ctx) => [
1035
- refAs("target", "CloudWorkspace", "pre:" + String((ctx?.intent ?? {}).workspaceId ?? "")),
1036
- ])
1032
+ .reads(readSet(readRef("target", CloudWorkspace).pre().fromPayload("workspaceId")))
1037
1033
  .assert((refs) => {
1038
1034
  const target = (refs as { target?: { name?: string } }).target;
1039
1035
  return target?.name === "root"
@@ -1051,9 +1047,7 @@ export const rebirthNotRoot = workspaceInvariant("RebirthNotRoot")
1051
1047
  */
1052
1048
  export const rebirthRetainsLineage = workspaceInvariant("RebirthRetainsLineage")
1053
1049
  .on("rebirthWorkspace")
1054
- .reads((ctx) => [
1055
- refAs("target", "CloudWorkspace", "pre:" + String((ctx?.intent ?? {}).workspaceId ?? "")),
1056
- ])
1050
+ .reads(readSet(readRef("target", CloudWorkspace).pre().fromPayload("workspaceId")))
1057
1051
  .assert((refs, ctx) => {
1058
1052
  const target = (refs as { target?: { parent?: string } }).target;
1059
1053
  const claimed = (ctx?.intent as { parent?: string } | undefined)?.parent;
@@ -1788,7 +1782,7 @@ export { RelationTuple };
1788
1782
  * owner-rebind the host session-lane used to refuse — is rejected. */
1789
1783
  export const genesisWarrantWriteOnce = workspaceInvariant("GenesisWarrantWriteOnce")
1790
1784
  .on("seedGenesis")
1791
- .reads(() => [refAs("warrant", "GenesisWarrant", "pre:" + GENESIS_WARRANT_ID)])
1785
+ .reads(readSet(readRef("warrant", "GenesisWarrant").pre().at(GENESIS_WARRANT_ID)))
1792
1786
  .assert(({ warrant }, ctx) => {
1793
1787
  const cur = warrant as { principal?: string; workspaceId?: string } | undefined;
1794
1788
  if (!cur?.principal) return { accept: true }; // virgin — genesis may seed the founding warrant
@@ -1823,7 +1817,7 @@ export const founderSignerWriteOnce = workspaceInvariant("FounderSignerWriteOnce
1823
1817
  * WorkspaceSelf.role exists. Genesis births on a role-less chain; materialize births each child once. */
1824
1818
  export const birthCloudOnce = workspaceInvariant("BirthCloudOnce")
1825
1819
  .on("birthCloud")
1826
- .reads(() => [refAs("self", "WorkspaceSelf", "pre:" + WORKSPACE_SELF_ID)])
1820
+ .reads(readSet(readRef("self", WorkspaceSelf).pre().at(WORKSPACE_SELF_ID)))
1827
1821
  // WRITE-ONCE on the self-record's PRESENCE via `name` (not the vestigial `role`) — a workspace is born once.
1828
1822
  .assert(({ self }) =>
1829
1823
  (self as { name?: string })?.name ? { reject: "cloud-already-born" } : { accept: true },
@@ -1837,7 +1831,7 @@ export const birthCloudOnce = workspaceInvariant("BirthCloudOnce")
1837
1831
  * rest. (Worker authors ownerGrantHash=foundingAdminHash for platforms, sha256(freshSecret) for plain.) */
1838
1832
  export const provisionReceiptGuard = workspaceInvariant("ProvisionReceiptGuard")
1839
1833
  .on("provisionWorkspace")
1840
- .reads((ctx) => [refAs("ws", "CloudWorkspace", "pre:" + String((ctx.intent ?? {}).workspaceId ?? ""))])
1834
+ .reads(readSet(readRef("ws", CloudWorkspace).pre().fromPayload("workspaceId")))
1841
1835
  .assert(({ ws }, ctx) => {
1842
1836
  const rec = ws as { status?: string; foundingAdminHash?: string } | undefined;
1843
1837
  if (!rec || rec.status !== "requested") return { reject: "provision-requires-requested-workspace" };
@@ -1856,7 +1850,7 @@ export const provisionReceiptGuard = workspaceInvariant("ProvisionReceiptGuard")
1856
1850
  * refuses reclaiming itself; this guards children.) */
1857
1851
  export const reclaimRequiresRetired = workspaceInvariant("ReclaimRequiresRetired")
1858
1852
  .on("reclaimWorkspace")
1859
- .reads((ctx) => [refAs("ws", "CloudWorkspace", "pre:" + String((ctx.intent ?? {}).workspaceId ?? ""))])
1853
+ .reads(readSet(readRef("ws", CloudWorkspace).pre().fromPayload("workspaceId")))
1860
1854
  .assert(({ ws }) => {
1861
1855
  const rec = ws as { status?: string } | undefined;
1862
1856
  return rec?.status === "retired" ? { accept: true } : { reject: "reclaim-requires-retired" };
@@ -1915,11 +1909,11 @@ function creationPostureVerdict(
1915
1909
  return { reject: "creation.invalid-posture" };
1916
1910
  }
1917
1911
 
1918
- const creationPostureReads = () => [
1919
- refAs("policy", "CloudPolicy", CREATION_POLICY_ID),
1920
- refAs("creators", "RelationTuple", CREATOR_TUPLE_ID),
1921
- refAs("admins", "RelationTuple", ADMIN_TUPLE_ID),
1922
- ];
1912
+ const creationPostureReads = readSet(
1913
+ readRef("policy", CloudPolicy).at(CREATION_POLICY_ID),
1914
+ readRef("creators", RelationTuple).at(CREATOR_TUPLE_ID),
1915
+ readRef("admins", RelationTuple).at(ADMIN_TUPLE_ID),
1916
+ );
1923
1917
 
1924
1918
  /** Compatibility create: open/unset ⇒ proven author; invite ⇒ creator; closed ⇒ admin. */
1925
1919
  export const creationPostureCreate = workspaceInvariant("CreationPostureCreate")
@@ -1961,7 +1955,7 @@ export const workspaceQuotaCreate = workspaceInvariant("WorkspaceQuota")
1961
1955
  .on("createWorkspace")
1962
1956
  // The snapshot ref-set is EMPTY — the count comes from the captured reads (ctx.reads), which the standard
1963
1957
  // ref-resolution cannot produce (it resolves single instances by id, never an enumeration).
1964
- .reads(() => [])
1958
+ .reads(readSet())
1965
1959
  .assert((_snapshots, ctx) =>
1966
1960
  quotaVerdict(ctx?.reads ?? [], String((ctx?.intent ?? {}).principal ?? "")),
1967
1961
  );
@@ -1969,7 +1963,7 @@ export const workspaceQuotaCreate = workspaceInvariant("WorkspaceQuota")
1969
1963
  /** birthChild: the SAME count quota (a leaf or platform birth draws on the principal's allowance). */
1970
1964
  export const workspaceQuotaBirth = workspaceInvariant("WorkspaceQuotaBirth")
1971
1965
  .on("birthChild")
1972
- .reads(() => [])
1966
+ .reads(readSet())
1973
1967
  .assert((_snapshots, ctx) =>
1974
1968
  quotaVerdict(ctx?.reads ?? [], String((ctx?.intent ?? {}).principal ?? "")),
1975
1969
  );
package/src/index.ts CHANGED
@@ -9,6 +9,14 @@
9
9
  // ONE import for a domain file: `z` (payload schemas) rides along with the DSL, so
10
10
  // authors never juggle a separate zod dependency (or risk a second zod instance).
11
11
  export { z } from "zod";
12
+ export {
13
+ definePackage,
14
+ validateNomosPackageConfig,
15
+ type NomosPackageConfig,
16
+ type NomosPackageDefinition,
17
+ type NomosPackageDomainConfig,
18
+ } from "./package_config.js";
19
+ export type { RuntimePackageDependency } from "./package_dependencies.js";
12
20
  export {
13
21
  aggregate,
14
22
  instance,
@@ -41,6 +49,10 @@ export {
41
49
  jsonWithNullSchema,
42
50
  type EvidenceRefValue,
43
51
  evidenceRefSchema,
52
+ type Sha256Digest,
53
+ sha256Digest,
54
+ isSha256DigestSchema,
55
+ NOMOS_SHA256_DIGEST_BRAND,
44
56
  // FIELD FACETS (the endorse model — security_model.md): authority/standing/attribution gate
45
57
  // set() acceptance of PrincipalEvidence; secret/public are the confidentiality lattice.
46
58
  authorityField,
@@ -61,11 +73,15 @@ export {
61
73
  idOf,
62
74
  idOfMetaOf,
63
75
  idOfTargetKindOf,
76
+ versionedRefOf,
77
+ versionedRefOfMetaOf,
64
78
  brandedId,
65
79
  brandedIdMetaOf,
66
80
  voMetaOf,
67
81
  voSample,
68
82
  NOMOS_VO_BRAND,
83
+ NOMOS_VERSIONED_REF_BRAND,
84
+ type VersionedRefOfMeta,
69
85
  geo,
70
86
  type ValueObject,
71
87
  type ValueObjectValue,
@@ -478,6 +494,7 @@ export {
478
494
  recordShare,
479
495
  pruneShare,
480
496
  sharedByWorkspace,
497
+ sharedByObject,
481
498
  ReceivingGroup,
482
499
  ReceivingGroupPolicy,
483
500
  RECEIVING_GROUP_ID,
@@ -594,9 +611,7 @@ export {
594
611
  } from "./framework/capability.js";
595
612
  export {
596
613
  DOMAIN_INSTALLATION_PHASES,
597
- PolicyBundle,
598
614
  DomainInstallation,
599
- policyAggregateId,
600
615
  domainInstallationAggregateId,
601
616
  installDomain,
602
617
  stageDomain,
@@ -623,8 +638,18 @@ export {
623
638
  } from "./framework/repair.js";
624
639
  export {
625
640
  workspaceInvariant,
641
+ readRef,
642
+ readSet,
643
+ idItem,
644
+ idLiteral,
645
+ idPayload,
646
+ idTemplate,
626
647
  ref,
627
648
  refAs,
649
+ type InvariantReadBinding,
650
+ type InvariantReadId,
651
+ type InvariantReadIdPart,
652
+ type InvariantReadTransform,
628
653
  type WorkspaceInvariantDecl,
629
654
  type WorkspaceInvariantVerdict,
630
655
  type WorkspaceInvariantReads,
@@ -729,7 +754,10 @@ export {
729
754
  type InvariantEvidence,
730
755
  type InvariantVerdict,
731
756
  } from "./relation.js";
732
- export { generateDartDomain, type DomainModule } from "./codegen_dart.js";
757
+ // Build-time generators live on explicit package subpaths. Keep the structural type available to
758
+ // authoring tools, but never pull generator implementations into the runtime namespace evaluated by
759
+ // every kernel sandbox.
760
+ export type { DomainModule } from "./codegen_dart.js";
733
761
  // SHAPE COMPATIBILITY (#72) — the structural contract a client negotiates with a workspace
734
762
  // by, instead of the law hash. Pure + deterministic; the editor/CI mirror imports these.
735
763
  export {
@@ -744,28 +772,20 @@ export {
744
772
  // turned on by the `--emit-dot` compiler flag). Pure `DomainModule -> string`, deterministic;
745
773
  // NOT part of the domain identity. Barrel-safe (no node:* imports), so the engine bundle can
746
774
  // import this barrel unaffected.
747
- export { emitDomainDot, type DotOptions } from "./codegen_dot.js";
775
+ export type { DotOptions } from "./codegen_dot.js";
748
776
  // The OPTIONAL OpenUSD `.usda` emitter — a COMPILED DOMAIN as a navigable USD stage (aggregates →
749
777
  // Sphere prims, directives → Cube prims carrying their `plan` lump, the creates/mutates/ref flow →
750
778
  // BasisCurves). The abstract LAW structure as a maths object (holon-maths projection), NOT the org-data
751
779
  // twin. Sibling of `emitDomainDot`: pure `DomainModule -> string`, deterministic, NOT part of the
752
780
  // domain identity; barrel-safe (no node:* imports). Open the output in usdview / any USD tool.
753
- export { emitDomainUsda, type UsdaOptions } from "./codegen_usda.js";
781
+ export type { UsdaOptions } from "./codegen_usda.js";
754
782
  // The PROVIDER SDK codegen (symmetric twin of the peer payload classes). `emitProviderSdk`
755
783
  // is invoked INSIDE `generateDartDomain` for a module's `impureCapabilities`; the type is exported
756
784
  // so the emit script can type its `impureCapabilities` list. A `impureCapability(...)` factory return value
757
785
  // satisfies `ImpureCapabilityDecl` structurally.
758
- export {
759
- emitProviderSdk,
760
- emitProviderTask,
761
- taskBaseName,
762
- type ImpureCapabilityDecl,
763
- } from "./codegen_provider_dart.js";
764
- // NOTE: the canonical-manifest / domain-hash API (`./manifest.js`) is a BUILD-TIME
765
- // concern that imports `node:crypto`. It is DELIBERATELY NOT re-exported from this
766
- // barrel: the deterministic engine bundle (`golden/domain_nomos.js`) imports this
767
- // barrel, and esbuild `--platform=neutral` cannot resolve `node:crypto`. Build-time
768
- // consumers import it via the `@githolon/dsl/manifest` subpath instead.
786
+ export type { ImpureCapabilityDecl } from "./codegen_provider_dart.js";
787
+ // Canonical law is emitted as typed USDA. The retired canonical-JSON manifest helper has
788
+ // been removed from both this barrel and the package exports.
769
789
  export { encodeKernelSchema, executeDirectiveToIntent, encodeRefMode, intentIdFromHlc } from "./wire_encode.js";
770
790
  export type {
771
791
  WireEvent,