@githolon/dsl 0.102.5 → 0.103.1

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 (132) 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 +14 -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 +5539 -1228
  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 +239 -102
  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/acquire_session_test.dart +9 -0
  15. package/dart/test/adv_realm_interference_test.dart +7 -6
  16. package/dart/test/cloud_bound_topology_test.dart +3 -3
  17. package/dart/test/cluster_births_test.dart +4 -3
  18. package/dart/test/cluster_device_keyed_acceptance_test.dart +10 -16
  19. package/dart/test/cluster_local_autosync_test.dart +3 -2
  20. package/dart/test/cluster_scale_test.dart +3 -2
  21. package/dart/test/dlq_session_surface_test.dart +7 -6
  22. package/dart/test/first_app_gauntlet_test.dart +14 -21
  23. package/dart/test/fixtures/wedge/fake-install.mjs +1 -1
  24. package/dart/test/four_layer_nested_topology_test.dart +4 -4
  25. package/dart/test/harness_phase_timeout_test.dart +2 -2
  26. package/dart/test/local_sync_inert_test.dart +1 -1
  27. package/dart/test/parent_signer_recovery_test.dart +2 -2
  28. package/dart/test/sealing_client_test.dart +4 -3
  29. package/dart/test/session_bound_test.dart +8 -7
  30. package/dart/test/test_harness_test.dart +13 -12
  31. package/dart/test/vo_read_typing_test.dart +4 -3
  32. package/dart/test/watch_after_offer_stall_test.dart +4 -3
  33. package/dart/test/webview_bridge_test.dart +102 -5
  34. package/dart_types/CHANGELOG.md +5 -0
  35. package/dart_types/lib/nomos_types.dart +9 -0
  36. package/dart_types/lib/src/nomos_ref.dart +20 -0
  37. package/dart_types/lib/src/optional_ref.dart +85 -0
  38. package/dart_types/lib/src/sha256_digest.dart +41 -0
  39. package/dart_types/lib/src/versioned_nomos_ref.dart +81 -0
  40. package/dart_types/pubspec.yaml +1 -1
  41. package/dart_types/test/optional_ref_test.dart +44 -0
  42. package/dart_types/test/sha256_digest_test.dart +18 -0
  43. package/package.json +9 -5
  44. package/runtime/generated-application-host.js +5365 -1105
  45. package/src/aggregate.ts +18 -0
  46. package/src/application_composition.ts +6 -32
  47. package/src/attested_core.ts +6 -3
  48. package/src/birth_meter.ts +1 -0
  49. package/src/birth_meter_ensure.ts +28 -2
  50. package/src/births.ts +1 -1
  51. package/src/build_package.ts +162 -538
  52. package/src/business_birth.ts +19 -3
  53. package/src/canonical_json.ts +21 -0
  54. package/src/check_package_main.ts +73 -33
  55. package/src/clear_directive.ts +19 -8
  56. package/src/codegen_dart.ts +305 -22
  57. package/src/codegen_dart_application.ts +862 -292
  58. package/src/codegen_dart_client.ts +1084 -407
  59. package/src/codegen_dart_scenario.ts +12 -12
  60. package/src/codegen_proof.ts +169 -39
  61. package/src/codegen_provider_dart.ts +17 -1
  62. package/src/codegen_ts.ts +298 -106
  63. package/src/compat_manifest.ts +2 -2
  64. package/src/compat_package_main.ts +8 -12
  65. package/src/compile_package_main.ts +1860 -592
  66. package/src/compose.ts +1 -1
  67. package/src/directive.ts +208 -15
  68. package/src/engine_entry.ts +165 -111
  69. package/src/evolve_preview.ts +29 -69
  70. package/src/extremum.ts +1 -1
  71. package/src/fields.ts +183 -4
  72. package/src/flow_gate.ts +75 -2
  73. package/src/framework/application_home.ts +2 -0
  74. package/src/framework/auth_provider_law.ts +2 -2
  75. package/src/framework/birth_meter.ts +7 -19
  76. package/src/framework/bootstrap.ts +0 -2
  77. package/src/framework/business_corrections.ts +9 -5
  78. package/src/framework/domain_lifecycle.ts +15 -29
  79. package/src/framework/encryption_scope.ts +2 -1
  80. package/src/framework/framework_aggregates.ts +2 -0
  81. package/src/framework/genesis.ts +16 -14
  82. package/src/framework/home.ts +20 -14
  83. package/src/framework/owned_custody.ts +9 -3
  84. package/src/framework/platform_admin.ts +3 -3
  85. package/src/framework/relations.ts +21 -13
  86. package/src/framework/signing_identity.ts +45 -40
  87. package/src/framework/workspace_invariant.ts +245 -0
  88. package/src/framework/workspaces.ts +23 -29
  89. package/src/index.ts +36 -16
  90. package/src/intent.ts +178 -6
  91. package/src/law_check.ts +32 -11
  92. package/src/law_graph.ts +2902 -0
  93. package/src/law_graph_usda.ts +1799 -0
  94. package/src/law_identity.ts +435 -0
  95. package/src/law_value_type.ts +230 -0
  96. package/src/lsp_server.ts +58 -29
  97. package/src/ops.ts +7 -0
  98. package/src/package_config.ts +141 -0
  99. package/src/package_dependencies.ts +108 -0
  100. package/src/package_dependency_usage.ts +150 -0
  101. package/src/package_source_imports.ts +71 -0
  102. package/src/plan_source_slice.ts +335 -0
  103. package/src/point_guard.ts +192 -0
  104. package/src/precondition.ts +44 -9
  105. package/src/read_projection_namespace.ts +1 -1
  106. package/src/runtime_zod.ts +44 -0
  107. package/src/secondary_ensure.ts +67 -14
  108. package/src/shape_compat.ts +1 -1
  109. package/src/stable_id_identity_bridge.ts +149 -0
  110. package/src/stable_id_lockfile.ts +140 -6
  111. package/src/stable_ids.ts +1 -1
  112. package/src/stable_ids_for_module.ts +348 -0
  113. package/src/stable_ids_types.ts +1 -1
  114. package/src/sum.ts +1 -1
  115. package/src/usd_state.ts +1 -1
  116. package/src/usda_relationship_integrity.ts +66 -0
  117. package/src/usda_text.ts +18 -0
  118. package/src/usdz.ts +78 -0
  119. package/src/value_object.ts +95 -0
  120. package/src/wire.ts +19 -0
  121. package/src/wire_encode.ts +22 -0
  122. package/src/workspace_sharding.ts +52 -36
  123. package/src/workspace_sharing.ts +28 -4
  124. package/src/zod_introspection.ts +1 -1
  125. package/dart/test/cluster_attested_test.dart +0 -201
  126. package/src/compile_engine.ts +0 -595
  127. package/src/manifest.ts +0 -1476
  128. package/src/read_projection_composition.ts +0 -117
  129. package/src/read_projection_manifest.ts +0 -115
  130. package/src/relation_composition.ts +0 -286
  131. package/src/usd.ts +0 -1967
  132. package/src/usd_layers.ts +0 -1776
package/src/aggregate.ts CHANGED
@@ -270,6 +270,9 @@ export interface AggregateHandle<
270
270
  * aggregate is `visibility: requires(cap)` (the scope) and its driver is Lww-class.
271
271
  */
272
272
  readonly encryptedFields?: string[];
273
+ /** ZD6 (encrypted_merge_model.md): the `.blindIndexed()` subset of {@link encryptedFields} —
274
+ * these fields carry edge-indexable equality tokens (`bidx`); the gate enforces presence. */
275
+ readonly blindIndexedFields?: string[];
273
276
  /**
274
277
  * ATTRIBUTED READS (architecture/field_provenance.md) — the STORED field names whose
275
278
  * folded values keep AUTHOR PROVENANCE (`.attributed()` per field, or the aggregate
@@ -408,6 +411,20 @@ export function aggregate<const Id extends string, F extends Record<string, Fiel
408
411
  }
409
412
  }
410
413
  }
414
+ // ZD6 BLIND INDEXES (encrypted_merge_model.md): `.blindIndexed()` is only meaningful on an
415
+ // `.encrypted()` field — a plaintext field is indexed directly; a blind index on it would be
416
+ // a pointless (and confusing) second index. LOUD at compile, per the doctrine.
417
+ const blindIndexedFields = Object.entries(stored)
418
+ .filter(([, f]) => (f as Field).isBlindIndexed === true)
419
+ .map(([name]) => name)
420
+ .sort();
421
+ for (const name of blindIndexedFields) {
422
+ if (!encryptedFields.includes(name)) {
423
+ throw new Error(
424
+ `aggregate '${id}': field '${name}' is .blindIndexed() but not .encrypted() — a blind index serves equality lookups over SEALED values; a plaintext field is indexable directly (declare a query on it instead)`,
425
+ );
426
+ }
427
+ }
411
428
  // SURFACED MERGE CONFLICTS (architecture/surfaced_merge_conflict.md): `.merge(Surfaced(inner))`
412
429
  // is v1-scoped to scalar fields — the pending set holds competing business versions until a
413
430
  // resolver produces one merged result. The factory already refuses a non-scalar INNER; this refuses the
@@ -545,6 +562,7 @@ export function aggregate<const Id extends string, F extends Record<string, Fiel
545
562
  ...(opts?.cap !== undefined ? { cap: opts.cap } : {}),
546
563
  ...(opts?.global === true ? { global: true } : {}),
547
564
  ...(encryptedFields.length > 0 ? { encryptedFields } : {}),
565
+ ...(blindIndexedFields.length > 0 ? { blindIndexedFields } : {}),
548
566
  ...(attributedFields.length > 0 ? { attributedFields } : {}),
549
567
  ...(metaFields.length > 0 ? { metaFields } : {}),
550
568
  };
@@ -1,11 +1,10 @@
1
1
  // NOMOS — OpenUSD is the application/package IR. JavaScript config is authoring input only.
2
2
 
3
3
  import { execFileSync } from "node:child_process";
4
- import { createHash } from "node:crypto";
5
4
  import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
6
5
  import path from "node:path";
7
6
 
8
- import { usdaString, usdaStringArray } from "./usd_layers.js";
7
+ import { usdaString, usdaStringArray } from "./usda_text.js";
9
8
 
10
9
  export type PartKind = "component" | "assembly" | "group";
11
10
 
@@ -51,7 +50,7 @@ export interface ApplicationDeploymentPackage {
51
50
  readonly packageName: string;
52
51
  readonly sourceIdentity: string;
53
52
  readonly assetPath: string;
54
- readonly deployPath: string;
53
+ readonly lawUsdzPath: string;
55
54
  }
56
55
 
57
56
  export interface ApplicationDeploymentPlan {
@@ -361,36 +360,11 @@ export function applicationDeploymentPlan(stagePath: string): ApplicationDeploym
361
360
  }
362
361
  const packageName = identity[1]!;
363
362
  const sourceIdentity = identity[2]!;
364
- const deployPath = path.join(path.dirname(use.assetPath), `${packageName}.deploy.json`);
365
- if (!existsSync(deployPath)) {
366
- throw new Error(`package '${packageName}' has no sibling deploy body: ${deployPath} (compile the package first)`);
363
+ const lawUsdzPath = path.join(path.dirname(use.assetPath), `${packageName}.law.usdz`);
364
+ if (!existsSync(lawUsdzPath)) {
365
+ throw new Error(`package '${packageName}' has no canonical sibling law archive: ${lawUsdzPath} (compile the package first)`);
367
366
  }
368
- let body: {
369
- summary?: { package?: unknown; sourceIdentity?: unknown; domainHash?: unknown };
370
- packageUsda?: unknown;
371
- };
372
- try {
373
- body = JSON.parse(readFileSync(deployPath, "utf8")) as typeof body;
374
- } catch (error) {
375
- throw new Error(`package '${packageName}' deploy body is not valid JSON: ${(error as Error).message}`);
376
- }
377
- if (body.summary?.package !== packageName) {
378
- throw new Error(`package asset '${use.assetPath}' names '${packageName}', but '${deployPath}' does not`);
379
- }
380
- if (body.summary?.sourceIdentity !== sourceIdentity) {
381
- throw new Error(
382
- `package '${packageName}' asset/deploy skew: source identity ${sourceIdentity.slice(0, 12)}… does not match ` +
383
- `${String(body.summary?.sourceIdentity ?? "missing").slice(0, 12)}…; recompile the package and application together`,
384
- );
385
- }
386
- if (typeof body.packageUsda !== "string" || body.packageUsda.length === 0) {
387
- throw new Error(`package '${packageName}' deploy body has no packageUsda`);
388
- }
389
- const lawHash = createHash("sha256").update(Buffer.from(body.packageUsda, "utf8")).digest("hex");
390
- if (body.summary?.domainHash !== lawHash) {
391
- throw new Error(`package '${packageName}' deploy body is internally stale (packageUsda hash does not match its summary)`);
392
- }
393
- return { ...use, packageName, sourceIdentity, deployPath };
367
+ return { ...use, packageName, sourceIdentity, lawUsdzPath };
394
368
  });
395
369
  packages.sort((a, b) => Number(a.placement === "payload") - Number(b.placement === "payload"));
396
370
  return { application, stagePath, packages };
@@ -140,10 +140,13 @@ export interface FromPayloadRef {
140
140
  readonly __nomosFromPayload: true;
141
141
  }
142
142
 
143
- /** Name the PAYLOAD FIELD whose value routes a dynamic attested read (see {@link FromPayloadRef}). */
143
+ /** Name the payload value whose workspace routes a dynamic attested read.
144
+ * A dotted path may select a compiled reference component, e.g.
145
+ * `fromPayload("publication.pinned.workspace")`; the path is law metadata,
146
+ * never a caller-provided selector. */
144
147
  export function fromPayload(field: string): FromPayloadRef {
145
- if (typeof field !== "string" || field.length === 0) {
146
- throw new Error(`fromPayload(): the payload field name must be a non-empty string`);
148
+ if (typeof field !== "string" || !/^[A-Za-z_$][A-Za-z0-9_$]*(\.[A-Za-z_$][A-Za-z0-9_$]*)*$/.test(field)) {
149
+ throw new Error(`fromPayload(): pass a payload field or dotted compiled-reference path`);
147
150
  }
148
151
  return { payloadField: field, __nomosFromPayload: true };
149
152
  }
@@ -332,6 +332,7 @@ export function synthesizeBirthQuotaInvariants(directive: {
332
332
  if (!reads.some((r) => r.queryId === birthRecordsByPrincipal.id)) return { accept: true };
333
333
  return birthQuotaVerdict(reads, birthMeterSubject(ctx?.intent ?? {}));
334
334
  },
335
+ __nomosEvaluator: "birth-quota-v1" as const,
335
336
  __isWorkspaceInvariant: true as const,
336
337
  },
337
338
  ];
@@ -87,6 +87,14 @@ const bornFounderSignerWriteOnce = workspaceInvariant("FounderSignerWriteOnce")
87
87
  : { reject: "founding-signer-already-enrolled" };
88
88
  });
89
89
 
90
+ // This is fixed Nomos bootstrap algebra, not tenant-authored policy. The typed USDA declaration
91
+ // selects the versioned kernel evaluator so every door can apply the same rule directly over the
92
+ // folded tuple instead of booting a tenant report sandbox during every child genesis.
93
+ const nativeBornFounderSignerWriteOnce = {
94
+ ...bornFounderSignerWriteOnce,
95
+ __nomosEvaluator: "founder-signer-write-once-v1" as const,
96
+ };
97
+
90
98
  /**
91
99
  * The sanctioning declaration — an `ensures(NomosBirthRecord)` directive whose plan emits ZERO ops.
92
100
  * Its only load-bearing property is its manifest/USD presence (marker `Ensure`, target
@@ -107,6 +115,12 @@ export const nomosBirthRecordEnsure = directive("nomosBirthRecordEnsure")
107
115
  * overwritten (a law composing the framework governance surface keeps its own bindings).
108
116
  */
109
117
  export function withBirthMeterExports<M extends Record<string, unknown>>(mod: M): M {
118
+ const exportedDirectiveIds = new Set(Object.values(mod).flatMap((value) =>
119
+ value !== null && typeof value === "object" && typeof (value as { id?: unknown }).id === "string"
120
+ ? [(value as { id: string }).id]
121
+ : []));
122
+ const governsBirth =
123
+ exportedDirectiveIds.has("setBirthPolicy") || exportedDirectiveIds.has("grantBirthAllowance");
110
124
  const declaresBirth = Object.values(mod).some(
111
125
  (v) =>
112
126
  v !== null &&
@@ -124,7 +138,7 @@ export function withBirthMeterExports<M extends Record<string, unknown>>(mod: M)
124
138
  (v as { id?: unknown }).id === "seedBirthAttestation" &&
125
139
  typeof (v as Directive<unknown>).plan === "function",
126
140
  );
127
- if (!declaresBirth && !acceptsBirth) return mod;
141
+ if (!declaresBirth && !acceptsBirth && !governsBirth) return mod;
128
142
  const out: Record<string, unknown> = { ...mod };
129
143
  const internal = <T extends object>(v: T): T => ({ ...v, businessBirthInternal: true }) as T;
130
144
  const hasOwn = (key: string): boolean => Object.prototype.hasOwnProperty.call(out, key);
@@ -184,6 +198,11 @@ export function withBirthMeterExports<M extends Record<string, unknown>>(mod: M)
184
198
  }
185
199
  if (!found) out[key] = internal(canonical);
186
200
  };
201
+ if (governsBirth && !declaresBirth && !acceptsBirth) {
202
+ if (exportedDirectiveIds.has("setBirthPolicy")) internalize("__nomos_BirthPolicy", BirthPolicy);
203
+ if (exportedDirectiveIds.has("grantBirthAllowance")) internalize("__nomos_BirthGrant", BirthGrant);
204
+ return out as M;
205
+ }
187
206
  // THE BORN-WORKSPACE CORE: the kernel appends enrollSigner -> attestation -> warrant to every valid birth.
188
207
  // Carry the law needed to judge that internal step in every possible child, plus the write-once guard that
189
208
  // keeps the founding lane a genesis primitive. These declarations are certified but never tenant-facing.
@@ -201,7 +220,14 @@ export function withBirthMeterExports<M extends Record<string, unknown>>(mod: M)
201
220
  reserve("__nomos_authProviderSeedBeforeWarrant", authProviderSeedBeforeWarrant);
202
221
  internalize("__nomos_setAuthProvider", setAuthProvider);
203
222
  internalize("__nomos_authProvider", authProvider);
204
- reserve("__nomos_founderSignerWriteOnce", bornFounderSignerWriteOnce);
223
+ reserve("__nomos_founderSignerWriteOnce", nativeBornFounderSignerWriteOnce);
224
+ // A tenant may deliberately expose the framework governance directives on a platform workspace.
225
+ // Their target schemas are part of that workspace's executable law even when it never births a child;
226
+ // make the directives self-contained instead of requiring a second, undocumented aggregate re-export.
227
+ if (governsBirth) {
228
+ if (exportedDirectiveIds.has("setBirthPolicy")) internalize("__nomos_BirthPolicy", BirthPolicy);
229
+ if (exportedDirectiveIds.has("grantBirthAllowance")) internalize("__nomos_BirthGrant", BirthGrant);
230
+ }
205
231
  if (!declaresBirth) return out as M;
206
232
  // Birth lifecycle is Nomos machinery for every birth-capable law. It remains certified/routable law,
207
233
  // but no generated tenant API gets a second maintenance lane beside business `birth(...)`.
package/src/births.ts CHANGED
@@ -26,7 +26,7 @@ import type { Field, FieldValue } from "./fields.js";
26
26
  */
27
27
 
28
28
  /** ONE birth recipe the plan produced — the child's genesis chain (the `buildGenesisChain` JSON array of
29
- * `{domain, directiveId, payload, actor[, domainPackageB64, domainHash]}` steps). Carried verbatim onto the
29
+ * `{domain, directiveId, payload, actor[, domainHash]}` steps). Carried verbatim onto the
30
30
  * intent's birth effect; the kernel folds it through the child's own gate (each step self-verifies). */
31
31
  export interface BirthRecipe {
32
32
  /** The child workspace name the parent asked to birth (lineage + the child's `:ws` segment). */