@githolon/dsl 0.108.6 → 0.110.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 (307) hide show
  1. package/assets/operation-contract.wasm +0 -0
  2. package/check_package.mjs +12 -15
  3. package/compile_package.mjs +17 -18
  4. package/compile_proof.mjs +16 -1
  5. package/dart/CHANGELOG.md +76 -1
  6. package/dart/README.md +25 -2
  7. package/dart/lib/src/admission_decision.dart +41 -0
  8. package/dart/lib/src/application_framework_calls.dart +52 -2
  9. package/dart/lib/src/application_model_adoption.dart +187 -0
  10. package/dart/lib/src/application_status.dart +73 -0
  11. package/dart/lib/src/console_enrolment.dart +271 -0
  12. package/dart/lib/src/console_http_io.dart +26 -0
  13. package/dart/lib/src/console_http_stub.dart +7 -0
  14. package/dart/lib/src/dev_cloud.dart +69 -22
  15. package/dart/lib/src/generated_call.dart +83 -23
  16. package/dart/lib/src/kernel_primitives.dart +119 -0
  17. package/dart/lib/src/nms_conformance_runtime.dart +1 -1
  18. package/dart/lib/src/nms_generated_runtime.dart +32 -10
  19. package/dart/lib/src/nms_test_environment.dart +1 -1
  20. package/dart/lib/src/node_runner_transport.dart +41 -46
  21. package/dart/lib/src/observed_session_directory.dart +70 -0
  22. package/dart/lib/src/operation_receipts.dart +112 -0
  23. package/dart/lib/src/peer_application_streams.dart +103 -0
  24. package/dart/lib/src/reception/dart_reception.dart +4280 -0
  25. package/dart/lib/src/reception/event_desk.dart +211 -0
  26. package/dart/lib/src/reception/extremum_read.dart +46 -0
  27. package/dart/lib/src/reception/local_copies.dart +371 -0
  28. package/dart/lib/src/reception/peer_office_connection.dart +11 -0
  29. package/dart/lib/src/reception/progress_desk.dart +267 -0
  30. package/dart/lib/src/reception/reception_contract.dart +11 -0
  31. package/dart/lib/src/reception/reception_session.dart +284 -0
  32. package/dart/lib/src/reception/sync_diagnostics.dart +26 -0
  33. package/dart/lib/src/reception/workspace_preparation_report.dart +126 -0
  34. package/dart/lib/src/replica_readiness.dart +123 -0
  35. package/dart/lib/src/runner/node-entry.mjs +23905 -15774
  36. package/dart/lib/src/runtime_v2_gateway.dart +56 -3
  37. package/dart/lib/src/runtime_v2_transport.dart +544 -3
  38. package/dart/lib/src/session_bound.dart +200 -311
  39. package/dart/lib/src/signing_identity_kernel.dart +84 -0
  40. package/dart/lib/src/sync_status_projection.dart +548 -0
  41. package/dart/lib/src/sync_status_reducer.dart +170 -0
  42. package/dart/lib/src/test_harness.dart +809 -1153
  43. package/dart/lib/src/testing/test_custody.dart +66 -0
  44. package/dart/lib/src/testing/test_peer.dart +328 -0
  45. package/dart/lib/src/typed_watch_registry.dart +169 -0
  46. package/dart/lib/src/workspace_open_progress.dart +27 -0
  47. package/dart/pubspec.lock +24 -1
  48. package/dart/pubspec.yaml +7 -2
  49. package/dart/pubspec_overrides.yaml +2 -0
  50. package/dart/test/admission_decision_test.dart +48 -0
  51. package/dart/test/background_model_adoption_test.dart +228 -0
  52. package/dart/test/bundle_version_pairing_test.dart +4 -4
  53. package/dart/test/child_authentication_repair_test.dart +359 -0
  54. package/dart/test/cloud_bound_local_shell_test.dart +119 -0
  55. package/dart/test/console_enrolment_refusal_test.dart +52 -0
  56. package/dart/test/console_enrolment_test.dart +227 -0
  57. package/dart/test/errors_test.dart +5 -5
  58. package/dart/test/event_plane_seam_test.dart +50 -164
  59. package/dart/test/extremum_read_test.dart +58 -0
  60. package/dart/test/fixtures/wedge/wedge-entry.mjs +3 -21
  61. package/dart/test/generated_query_test.dart +32 -0
  62. package/dart/test/harness_phase_timeout_test.dart +18 -23
  63. package/dart/test/kernel_author_after_read_test.dart +242 -0
  64. package/dart/test/kernel_fence_test.dart +137 -0
  65. package/dart/test/local_copies_test.dart +222 -0
  66. package/dart/test/model_adoption_test.dart +198 -0
  67. package/dart/test/node_peer_local_custody_test.dart +153 -0
  68. package/dart/test/offer_authentication_proof_test.dart +352 -52
  69. package/dart/test/operation_compatibility_test.dart +151 -0
  70. package/dart/test/platform_credential_effect_test.dart +386 -0
  71. package/dart/test/receiving_group_open_test.dart +213 -0
  72. package/dart/test/reception/workspace_preparation_report_test.dart +103 -0
  73. package/dart/test/reception_span_trace_test.dart +23 -0
  74. package/dart/test/replica_readiness_test.dart +156 -0
  75. package/dart/test/runtime_projections_test.dart +92 -0
  76. package/dart/test/runtime_v2_gateway_test.dart +131 -0
  77. package/dart/test/signing_identity_kernel_test.dart +75 -0
  78. package/dart/test/sync_status_preparation_report_test.dart +29 -0
  79. package/dart/test/sync_status_reducer_test.dart +419 -0
  80. package/dart/test/test_harness_test.dart +71 -95
  81. package/dart/test/typed_query_watch_test.dart +170 -0
  82. package/dart/test/typed_watch_registry_test.dart +249 -0
  83. package/dart_lints/README.md +18 -0
  84. package/dart_lints/lib/nomos_lints.dart +70 -0
  85. package/dart_lints/pubspec.lock +580 -0
  86. package/dart_lints/pubspec.yaml +12 -0
  87. package/dart_lints/test/reference_identity_test.dart +75 -0
  88. package/dart_types/CHANGELOG.md +18 -0
  89. package/dart_types/lib/nomos_kernel_protocol.dart +21 -1
  90. package/dart_types/lib/nomos_types.dart +9 -1
  91. package/dart_types/lib/src/admission_decision.dart +37 -0
  92. package/dart_types/lib/src/aggregate_meta.dart +1 -1
  93. package/dart_types/lib/src/approved_model.dart +65 -0
  94. package/dart_types/lib/src/custody.dart +10 -18
  95. package/dart_types/lib/src/error_info.dart +4 -4
  96. package/dart_types/lib/src/errors.dart +29 -29
  97. package/dart_types/lib/src/foreign_ref.dart +62 -33
  98. package/dart_types/lib/src/local_work_rejected.dart +3 -3
  99. package/dart_types/lib/src/nomos_ref.dart +3 -1
  100. package/dart_types/lib/src/principal.dart +2 -2
  101. package/dart_types/lib/src/proto/google/protobuf/any.pb.dart +163 -0
  102. package/dart_types/lib/src/proto/google/protobuf/any.pbenum.dart +11 -0
  103. package/dart_types/lib/src/proto/nomos/discovery/v1/workspace_placement.pb.dart +137 -0
  104. package/dart_types/lib/src/proto/nomos/discovery/v1/workspace_placement.pbenum.dart +11 -0
  105. package/dart_types/lib/src/proto/nomos/kernel/v1/kernel.pb.dart +20721 -10433
  106. package/dart_types/lib/src/proto/nomos/kernel/v1/kernel.pbenum.dart +555 -27
  107. package/dart_types/lib/src/proto/nomos/runtime/v2/application_desk.pb.dart +387 -0
  108. package/dart_types/lib/src/proto/nomos/runtime/v2/application_desk.pbenum.dart +46 -0
  109. package/dart_types/lib/src/proto/nomos/runtime/v2/application_readiness_desk.pb.dart +295 -0
  110. package/dart_types/lib/src/proto/nomos/runtime/v2/application_readiness_desk.pbenum.dart +139 -0
  111. package/dart_types/lib/src/proto/nomos/runtime/v2/authentication_desk.pb.dart +269 -0
  112. package/dart_types/lib/src/proto/nomos/runtime/v2/authentication_desk.pbenum.dart +103 -0
  113. package/dart_types/lib/src/proto/nomos/runtime/v2/compatibility_desk.pb.dart +417 -0
  114. package/dart_types/lib/src/proto/nomos/runtime/v2/compatibility_desk.pbenum.dart +62 -0
  115. package/dart_types/lib/src/proto/nomos/runtime/v2/correspondence_desk.pb.dart +9968 -0
  116. package/dart_types/lib/src/proto/nomos/runtime/v2/correspondence_desk.pbenum.dart +133 -0
  117. package/dart_types/lib/src/proto/nomos/runtime/v2/credentials_desk.pb.dart +204 -0
  118. package/dart_types/lib/src/proto/nomos/runtime/v2/credentials_desk.pbenum.dart +54 -0
  119. package/dart_types/lib/src/proto/nomos/runtime/v2/custody_desk.pb.dart +1550 -0
  120. package/dart_types/lib/src/proto/nomos/runtime/v2/custody_desk.pbenum.dart +11 -0
  121. package/dart_types/lib/src/proto/nomos/runtime/v2/framework.pb.dart +710 -0
  122. package/dart_types/lib/src/proto/nomos/runtime/v2/framework.pbenum.dart +11 -0
  123. package/dart_types/lib/src/proto/nomos/runtime/v2/identity_desk.pb.dart +845 -0
  124. package/dart_types/lib/src/proto/nomos/runtime/v2/identity_desk.pbenum.dart +11 -0
  125. package/dart_types/lib/src/proto/nomos/runtime/v2/interaction_desk.pb.dart +198 -0
  126. package/dart_types/lib/src/proto/nomos/runtime/v2/interaction_desk.pbenum.dart +11 -0
  127. package/dart_types/lib/src/proto/nomos/runtime/v2/law_desk.pb.dart +369 -0
  128. package/dart_types/lib/src/proto/nomos/runtime/v2/law_desk.pbenum.dart +11 -0
  129. package/dart_types/lib/src/proto/nomos/runtime/v2/maintenance_desk.pb.dart +609 -0
  130. package/dart_types/lib/src/proto/nomos/runtime/v2/maintenance_desk.pbenum.dart +65 -0
  131. package/dart_types/lib/src/proto/nomos/runtime/v2/model_adoption_desk.pb.dart +358 -0
  132. package/dart_types/lib/src/proto/nomos/runtime/v2/model_adoption_desk.pbenum.dart +100 -0
  133. package/dart_types/lib/src/proto/nomos/runtime/v2/observability_desk.pb.dart +2231 -0
  134. package/dart_types/lib/src/proto/nomos/runtime/v2/observability_desk.pbenum.dart +271 -0
  135. package/dart_types/lib/src/proto/nomos/runtime/v2/placement_desk.pb.dart +1286 -0
  136. package/dart_types/lib/src/proto/nomos/runtime/v2/placement_desk.pbenum.dart +11 -0
  137. package/dart_types/lib/src/proto/nomos/runtime/v2/receiving_group_desk.pb.dart +636 -0
  138. package/dart_types/lib/src/proto/nomos/runtime/v2/receiving_group_desk.pbenum.dart +116 -0
  139. package/dart_types/lib/src/proto/nomos/runtime/v2/records_desk.pb.dart +1637 -0
  140. package/dart_types/lib/src/proto/nomos/runtime/v2/records_desk.pbenum.dart +175 -0
  141. package/dart_types/lib/src/proto/nomos/runtime/v2/recovery_desk.pb.dart +1269 -0
  142. package/dart_types/lib/src/proto/nomos/runtime/v2/recovery_desk.pbenum.dart +129 -0
  143. package/dart_types/lib/src/proto/nomos/runtime/v2/residency_desk.pb.dart +2782 -0
  144. package/dart_types/lib/src/proto/nomos/runtime/v2/residency_desk.pbenum.dart +97 -0
  145. package/dart_types/lib/src/proto/nomos/runtime/v2/runtime.pb.dart +2232 -8627
  146. package/dart_types/lib/src/proto/nomos/runtime/v2/runtime.pbenum.dart +0 -358
  147. package/dart_types/lib/src/proto/nomos/runtime/v2/sealing_desk.pb.dart +1639 -0
  148. package/dart_types/lib/src/proto/nomos/runtime/v2/sealing_desk.pbenum.dart +46 -0
  149. package/dart_types/lib/src/runtime_outcome.dart +133 -0
  150. package/dart_types/lib/src/subscriptions.dart +116 -23
  151. package/dart_types/pubspec.yaml +1 -1
  152. package/dart_types/test/extremum_subscriptions_test.dart +40 -0
  153. package/dart_types/test/foreign_ref_resolution_test.dart +75 -0
  154. package/dart_types/test/nomos_ref_address_test.dart +25 -0
  155. package/dart_types/test/ordered_subscriptions_test.dart +34 -0
  156. package/operation_contract_check.mjs +24 -0
  157. package/package.json +11 -6
  158. package/src/aggregate.ts +70 -10
  159. package/src/application_topology.ts +18 -11
  160. package/src/attested.ts +3 -0
  161. package/src/attested_core.ts +46 -3
  162. package/src/birth_meter_ensure.ts +19 -7
  163. package/src/births.ts +29 -4
  164. package/src/build_package.ts +140 -13
  165. package/src/business_birth.ts +181 -4
  166. package/src/codegen_call_proto.ts +1274 -0
  167. package/src/codegen_call_usda.ts +49 -6
  168. package/src/codegen_dart.ts +79 -44
  169. package/src/codegen_dart_client.ts +458 -800
  170. package/src/{codegen_dart_application.ts → codegen_dart_facade.ts} +331 -582
  171. package/src/codegen_dart_framework_calls.ts +320 -37
  172. package/src/codegen_dart_indexed_variant.ts +159 -0
  173. package/src/codegen_dart_scenario.ts +42 -13
  174. package/src/codegen_proof.ts +3 -3
  175. package/src/codegen_provider_dart.ts +5 -0
  176. package/src/codegen_query_proto.ts +158 -0
  177. package/src/codegen_refusal.ts +189 -0
  178. package/src/codegen_result_proto.ts +931 -0
  179. package/src/codegen_result_usda.ts +4 -0
  180. package/src/codegen_ts.ts +464 -616
  181. package/src/codegen_workspace_access.ts +105 -0
  182. package/src/compatibility_graph.ts +759 -0
  183. package/src/compatibility_usda.ts +264 -0
  184. package/src/compile_package_main.ts +2083 -1248
  185. package/src/custody_placement.ts +156 -0
  186. package/src/custody_placement_usda.ts +91 -0
  187. package/src/decl_shapes.ts +21 -2
  188. package/src/describe_model.ts +1 -0
  189. package/src/directive.ts +59 -2
  190. package/src/drivers.ts +51 -0
  191. package/src/engine_entry.ts +52 -8
  192. package/src/evolve_preview.ts +11 -4
  193. package/src/exists.ts +2 -0
  194. package/src/fields.ts +75 -11
  195. package/src/flow_gate.ts +2 -1
  196. package/src/framework/application_home.ts +170 -18
  197. package/src/framework/attested_receipts.ts +8 -3
  198. package/src/framework/auth_provider_law.ts +169 -9
  199. package/src/framework/birth_certificate_law.ts +4 -0
  200. package/src/framework/capability.ts +34 -3
  201. package/src/framework/child_authentication.ts +346 -0
  202. package/src/framework/console_governance.ts +295 -0
  203. package/src/framework/delegated_roles.ts +301 -0
  204. package/src/framework/domain_lifecycle.ts +26 -13
  205. package/src/framework/founding_genesis.ts +193 -0
  206. package/src/framework/framework_aggregates.ts +1 -1
  207. package/src/framework/genesis.ts +6 -1
  208. package/src/framework/governance_relations.ts +19 -0
  209. package/src/framework/home.ts +5 -734
  210. package/src/framework/legacy/child_auth_provider_epoch.ts +73 -0
  211. package/src/framework/model_authority_repair.ts +116 -0
  212. package/src/framework/model_authority_seed.ts +185 -0
  213. package/src/framework/model_transition.ts +211 -0
  214. package/src/framework/owned_custody.ts +1 -1
  215. package/src/framework/principal_enrollment.ts +302 -0
  216. package/src/framework/receiving_group.ts +857 -0
  217. package/src/framework/receiving_group_recovery.ts +314 -0
  218. package/src/framework/relations.ts +4 -8
  219. package/src/framework/signing_identity.ts +242 -95
  220. package/src/framework/source_roster.ts +11 -5
  221. package/src/framework/workspace_access.ts +149 -0
  222. package/src/framework/workspace_invariant.ts +73 -52
  223. package/src/framework/workspaces.ts +407 -40
  224. package/src/framework_call_definitions.ts +32 -3
  225. package/src/generated_client_bundle_boundary.ts +97 -0
  226. package/src/generated_client_names.ts +1 -0
  227. package/src/identity_usda.ts +27 -0
  228. package/src/index.ts +183 -12
  229. package/src/indexed_variant.ts +83 -0
  230. package/src/intent.ts +173 -45
  231. package/src/law_check.ts +8 -5
  232. package/src/law_dependency_index.ts +231 -0
  233. package/src/law_graph.ts +508 -71
  234. package/src/law_graph_usda.ts +170 -24
  235. package/src/law_identity.ts +119 -81
  236. package/src/law_source_map.ts +4 -1
  237. package/src/law_units.ts +498 -0
  238. package/src/law_value_type.ts +7 -3
  239. package/src/member_authentication.ts +302 -0
  240. package/src/null_meta.ts +1 -1
  241. package/src/openusd_compiled_layer.ts +132 -0
  242. package/src/operation_contract_check.ts +31 -0
  243. package/src/ordered_read.ts +2 -1
  244. package/src/package_config.ts +33 -12
  245. package/src/package_dependencies.ts +1 -0
  246. package/src/plan_source_slice.ts +30 -1
  247. package/src/protobuf_field_number.ts +36 -0
  248. package/src/provenance_wire.ts +6 -0
  249. package/src/query.ts +2 -1
  250. package/src/read.ts +50 -0
  251. package/src/relation.ts +4 -1
  252. package/src/relation_schema.ts +15 -2
  253. package/src/report.ts +2 -2
  254. package/src/sqlite_computation_bundle.ts +78 -0
  255. package/src/sqlite_computed.ts +102 -0
  256. package/src/sqlite_counts.ts +154 -0
  257. package/src/sqlite_layout.ts +823 -0
  258. package/src/sqlite_reads.ts +275 -0
  259. package/src/sqlite_samples.ts +185 -0
  260. package/src/stable_id_identity_bridge.ts +1 -1
  261. package/src/stable_ids_for_module.ts +16 -4
  262. package/src/test_call_usda.ts +6 -6
  263. package/src/usda_relationship_integrity.ts +20 -3
  264. package/src/usda_text.ts +21 -1
  265. package/src/value_object.ts +81 -11
  266. package/src/wire.ts +22 -0
  267. package/src/wire_encode.ts +227 -20
  268. package/src/workspace_sharding.ts +15 -6
  269. package/src/workspace_sharing.ts +51 -49
  270. package/src/zod_introspection.ts +2 -0
  271. package/compat_package.mjs +0 -46
  272. package/dart/lib/src/home.dart +0 -15
  273. package/dart/lib/src/runner/offline-install.mjs +0 -15367
  274. package/dart/lib/src/source_trust.dart +0 -51
  275. package/dart/lib/src/webview_bridge.dart +0 -6540
  276. package/dart/lib/src/workspace_name.dart +0 -30
  277. package/dart/test/acquire_session_credentials_test.dart +0 -150
  278. package/dart/test/acquire_session_test.dart +0 -534
  279. package/dart/test/adv_realm_interference_test.dart +0 -600
  280. package/dart/test/cloud_bound_topology_test.dart +0 -168
  281. package/dart/test/cluster_births_test.dart +0 -202
  282. package/dart/test/cluster_device_keyed_acceptance_test.dart +0 -105
  283. package/dart/test/cluster_local_autosync_test.dart +0 -123
  284. package/dart/test/cluster_scale_test.dart +0 -122
  285. package/dart/test/compat_test.dart +0 -61
  286. package/dart/test/dlq_session_surface_test.dart +0 -222
  287. package/dart/test/first_app_gauntlet_test.dart +0 -386
  288. package/dart/test/fixtures/wedge/fake-install.mjs +0 -11
  289. package/dart/test/four_layer_nested_topology_test.dart +0 -290
  290. package/dart/test/home_parity_test.dart +0 -13
  291. package/dart/test/local_sync_inert_test.dart +0 -107
  292. package/dart/test/node_runner_transport_test.dart +0 -78
  293. package/dart/test/parent_signer_recovery_test.dart +0 -155
  294. package/dart/test/residency_refusal_test.dart +0 -49
  295. package/dart/test/sealing_client_test.dart +0 -181
  296. package/dart/test/session_bound_test.dart +0 -285
  297. package/dart/test/stale_bundle_test.dart +0 -80
  298. package/dart/test/vo_read_typing_test.dart +0 -131
  299. package/dart/test/watch_after_offer_stall_test.dart +0 -100
  300. package/dart/test/webview_bridge_test.dart +0 -1930
  301. package/dart/test/workspace_name_test.dart +0 -24
  302. package/runtime/generated-application-host.js +0 -22860
  303. package/src/codegen_query_usda.ts +0 -214
  304. package/src/compat_manifest.ts +0 -26
  305. package/src/compat_package_main.ts +0 -224
  306. package/src/shape_compat.ts +0 -352
  307. package/src/usd_state.ts +0 -505
@@ -0,0 +1,302 @@
1
+ /** Authentication declared by one exact law member (identity target model, D7 and D22).
2
+ *
3
+ * `authenticatesWith(member, provider)` is per directive (and per read): it names the one provider
4
+ * whose principals may author that member. The kernel is the authentication (D22): an intent is
5
+ * admitted as principal P iff it is signed by a key K with `identity:P#signer@key:<sha256(K)>` active in
6
+ * parent state, and P's scope is the scope the member's provider declares. A principal is spelled
7
+ * `<scope>:<subject>` — exactly its Zanzibar subject, so `.requires` checks it verbatim. A provider is
8
+ * one of two kinds, and the kind is law; law declares nothing else about it (no issuer, no key, no
9
+ * token):
10
+ *
11
+ * - **enrolled** — a tenant with a login provider. The first key of a principal is written by a
12
+ * principal holding `principalScope:<scope>#enroller` (`enrollDevice`,
13
+ * `framework/principal_enrollment.ts`), after it verified the provider's token off the ledger.
14
+ * - **sovereign** — no login provider. The principal is `<scope>:<sha256(root public key)>`; the root
15
+ * key certifies its own first signer tuple (`sovereignSelfCertification`). Losing the root is losing
16
+ * the identity.
17
+ *
18
+ * Every further device of either kind is enrolled by proof of possession (`enrollSigner`).
19
+ *
20
+ * A legacy form — `{ scope, identitySha256 }` — pins a workspace-local provider row by digest. It is the
21
+ * provider-token machinery the target model deletes (`auth_provider_law.ts`, build-order step 4); it
22
+ * stays only until that deletion, and new law must not use it.
23
+ */
24
+
25
+ const authenticationProviderBrand: unique symbol = Symbol(
26
+ "nomos.authentication-provider",
27
+ );
28
+
29
+ export type AuthenticationProviderKind = "enrolled" | "sovereign";
30
+
31
+ interface ProviderBase {
32
+ readonly [authenticationProviderBrand]: true;
33
+ /** The provider scope: the principal namespace, and the Zanzibar subject type of its principals. */
34
+ readonly scope: string;
35
+ }
36
+
37
+ export interface EnrolledProviderRef extends ProviderBase {
38
+ readonly kind: "enrolled";
39
+ }
40
+
41
+ export interface SovereignProviderRef extends ProviderBase {
42
+ readonly kind: "sovereign";
43
+ }
44
+
45
+ /** @deprecated The provider-row-by-digest form; deleted with `auth_provider_law.ts` (step 4). */
46
+ export interface LegacySelectedProviderRef extends ProviderBase {
47
+ readonly kind: "legacySelected";
48
+ /** Immutable provider identity, independent of issuer URL and verification-key rotation. */
49
+ readonly identitySha256: string;
50
+ }
51
+
52
+ export type AuthenticationProviderRef =
53
+ | EnrolledProviderRef
54
+ | SovereignProviderRef
55
+ | LegacySelectedProviderRef;
56
+
57
+ export enum MemberAuthenticationKind {
58
+ SelectedProvider = "selectedProvider",
59
+ EnrolledDevice = "enrolledDevice",
60
+ }
61
+
62
+ export type MemberAuthentication =
63
+ | Readonly<{
64
+ kind: MemberAuthenticationKind.SelectedProvider;
65
+ provider: AuthenticationProviderRef;
66
+ }>
67
+ | Readonly<{
68
+ kind: MemberAuthenticationKind.EnrolledDevice;
69
+ }>;
70
+
71
+ export interface AuthenticatedMember {
72
+ readonly authentication?: MemberAuthentication;
73
+ }
74
+
75
+ const scopePattern = /^[A-Za-z][A-Za-z0-9._-]{0,127}$/;
76
+ const digestPattern = /^[0-9a-f]{64}$/;
77
+ /** A principal's subject within its scope: a bounded token that can never re-open the `type:id` split. */
78
+ const principalSubjectPattern = /^[A-Za-z0-9][A-Za-z0-9_.:/-]{0,255}$/;
79
+
80
+ /**
81
+ * Subject types the kernel or framework already owns. A provider's principals are Zanzibar subjects
82
+ * of type `<scope>`, so a scope named after one of these would let a provider's principals pose as
83
+ * framework subjects (`user:…`, `key:…`) in every relation that allows them. `principalScope` is the
84
+ * object type of the enroller relation (D22), reserved for the same reason.
85
+ */
86
+ export const RESERVED_PROVIDER_SCOPES: readonly string[] = Object.freeze([
87
+ "key",
88
+ "identity",
89
+ "workspace",
90
+ "principalScope",
91
+ ]);
92
+
93
+ /**
94
+ * The scope of the principals console.nomos.cafe enrolls: operators who install law, and hosted
95
+ * enrollers acting for tenants who do not run their own backend (D18, D22). Framework vocabulary: the
96
+ * framework's own governance relations (`workspace:self#operator`, `principalScope:<s>#enroller`) allow
97
+ * these principals, so a law that names this scope must declare it `enrolled` — a sovereign `console`
98
+ * scope would let anyone mint a principal the framework treats as a console principal.
99
+ */
100
+ export const CONSOLE_PRINCIPAL_SCOPE = "console";
101
+
102
+ /**
103
+ * The scope of custodian principals: the sovereign identities that found a universe's root (identity
104
+ * target model D22, token-free genesis). A custodian principal is `custodian:<sha256hex(root key)>` and
105
+ * certifies itself — nobody verified a login at root, and root must not depend on the console of its own
106
+ * descendant nomos.cafe, so a sovereign key is the one honest identity a root's founding admin can have.
107
+ * Framework vocabulary like {@link CONSOLE_PRINCIPAL_SCOPE}, and its mirror: a law naming this scope must
108
+ * declare it `sovereign`. Being a custodian principal grants nothing by itself; anyone can self-certify
109
+ * one, and authority is only ever an admin/operator/enroller tuple naming it.
110
+ */
111
+ export const CUSTODIAN_PRINCIPAL_SCOPE = "custodian";
112
+
113
+ /**
114
+ * The scope of an application's signed-in users: `user:<login provider subject>` (for CO2, the Firebase
115
+ * uid). Framework-owned like {@link CONSOLE_PRINCIPAL_SCOPE}: the principal spelling is the framework's
116
+ * existing `user:` Zanzibar subject, so every relation that already allows `user()` holds these
117
+ * principals unchanged. It is enrolled — an enroller holding `principalScope:user#enroller` (the console's
118
+ * hosted enroller) writes each user's first key after verifying the login token off the ledger — and only
119
+ * framework law declares it ({@link userPrincipals}); a tenant naming the scope itself is refused, so no
120
+ * tenant can declare `user` sovereign or re-spell who a user is.
121
+ */
122
+ export const USER_PRINCIPAL_SCOPE = "user";
123
+
124
+ function requireScope(scope: string): string {
125
+ if (typeof scope !== "string" || !scopePattern.test(scope)) {
126
+ throw new Error("authentication provider scope must be a bounded identifier");
127
+ }
128
+ return scope;
129
+ }
130
+
131
+ function requireKindScope(scope: string): string {
132
+ requireScope(scope);
133
+ if (RESERVED_PROVIDER_SCOPES.includes(scope)) {
134
+ throw new Error(
135
+ `authentication provider scope '${scope}' is reserved: its principals would pose as framework '${scope}:' subjects`,
136
+ );
137
+ }
138
+ return scope;
139
+ }
140
+
141
+ /** Declare an enrolled provider: an enroller of this scope writes each principal's first key. */
142
+ export function authenticationProvider(input: {
143
+ readonly kind: "enrolled";
144
+ readonly scope: string;
145
+ }): EnrolledProviderRef;
146
+ /** Declare a sovereign provider: principals are their own root keys. */
147
+ export function authenticationProvider(input: {
148
+ readonly kind: "sovereign";
149
+ readonly scope: string;
150
+ }): SovereignProviderRef;
151
+ /** @deprecated Pins a workspace provider row by digest; deleted in build-order step 4. */
152
+ export function authenticationProvider(input: {
153
+ readonly scope: string;
154
+ readonly identitySha256: string;
155
+ }): LegacySelectedProviderRef;
156
+ export function authenticationProvider(input: {
157
+ readonly kind?: AuthenticationProviderKind;
158
+ readonly scope: string;
159
+ readonly identitySha256?: string;
160
+ }): AuthenticationProviderRef {
161
+ if (input.kind === undefined) {
162
+ requireScope(input.scope);
163
+ if (typeof input.identitySha256 !== "string" || !digestPattern.test(input.identitySha256)) {
164
+ throw new Error(
165
+ "authentication provider identitySha256 must be 64 lowercase hexadecimal characters",
166
+ );
167
+ }
168
+ return Object.freeze({
169
+ [authenticationProviderBrand]: true as const,
170
+ kind: "legacySelected" as const,
171
+ scope: input.scope,
172
+ identitySha256: input.identitySha256,
173
+ });
174
+ }
175
+ if (input.kind !== "enrolled" && input.kind !== "sovereign") {
176
+ throw new Error(
177
+ `unknown authentication provider kind '${String(input.kind)}': a provider is "enrolled" or "sovereign" (D22)`,
178
+ );
179
+ }
180
+ for (const option of Object.keys(input)) {
181
+ if (option !== "kind" && option !== "scope") {
182
+ throw new Error(
183
+ `a ${input.kind} provider declares only its kind and scope; '${option}' is not law (D22: no token, issuer or key reaches a ledger)`,
184
+ );
185
+ }
186
+ }
187
+ const scope = requireKindScope(input.scope);
188
+ if (scope === USER_PRINCIPAL_SCOPE) {
189
+ throw new Error(
190
+ `scope '${USER_PRINCIPAL_SCOPE}' is the framework's enrolled user principals; use userPrincipals, never declare it`,
191
+ );
192
+ }
193
+ if (scope === CONSOLE_PRINCIPAL_SCOPE && input.kind !== "enrolled") {
194
+ throw new Error(
195
+ `scope '${CONSOLE_PRINCIPAL_SCOPE}' is the console's enrolled principals; it cannot be ${input.kind}`,
196
+ );
197
+ }
198
+ if (scope === CUSTODIAN_PRINCIPAL_SCOPE && input.kind !== "sovereign") {
199
+ throw new Error(
200
+ `scope '${CUSTODIAN_PRINCIPAL_SCOPE}' is the framework's sovereign custodian principals; it cannot be ${input.kind}`,
201
+ );
202
+ }
203
+ return Object.freeze({
204
+ [authenticationProviderBrand]: true as const,
205
+ kind: input.kind,
206
+ scope,
207
+ }) as EnrolledProviderRef | SovereignProviderRef;
208
+ }
209
+
210
+ /** The console's principals (`console:<subject>`), enrolled by console.nomos.cafe. */
211
+ export const consolePrincipals: EnrolledProviderRef = authenticationProvider({
212
+ kind: "enrolled",
213
+ scope: CONSOLE_PRINCIPAL_SCOPE,
214
+ });
215
+
216
+ /** The framework's enrolled user principals (`user:<subject>`): see {@link USER_PRINCIPAL_SCOPE}. The one
217
+ * declaration of the scope; built here because the public constructor refuses it to tenant law. */
218
+ export const userPrincipals: EnrolledProviderRef = Object.freeze({
219
+ [authenticationProviderBrand]: true as const,
220
+ kind: "enrolled" as const,
221
+ scope: USER_PRINCIPAL_SCOPE,
222
+ });
223
+
224
+ /** Custodian principals (`custodian:<sha256hex(root key)>`), sovereign: see {@link CUSTODIAN_PRINCIPAL_SCOPE}. */
225
+ export const custodianPrincipals: SovereignProviderRef = authenticationProvider({
226
+ kind: "sovereign",
227
+ scope: CUSTODIAN_PRINCIPAL_SCOPE,
228
+ });
229
+
230
+ /** Is `principal` a well-formed `<scope>:<subject>` principal of a non-reserved scope? Returns its scope. */
231
+ export function principalScopeOf(principal: string): string | undefined {
232
+ if (typeof principal !== "string") return undefined;
233
+ const colon = principal.indexOf(":");
234
+ if (colon <= 0) return undefined;
235
+ const scope = principal.slice(0, colon);
236
+ const subject = principal.slice(colon + 1);
237
+ if (!scopePattern.test(scope) || RESERVED_PROVIDER_SCOPES.includes(scope)) return undefined;
238
+ if (!principalSubjectPattern.test(subject)) return undefined;
239
+ return scope;
240
+ }
241
+
242
+ /** The principal a sovereign scope assigns to a root key: `<scope>:<sha256hex(root public key)>`. */
243
+ export function sovereignPrincipal(provider: SovereignProviderRef, rootKeyHash: string): string {
244
+ if (provider?.[authenticationProviderBrand] !== true || provider.kind !== "sovereign") {
245
+ throw new Error("sovereignPrincipal takes a sovereign provider declared with authenticationProvider");
246
+ }
247
+ if (!digestPattern.test(rootKeyHash)) {
248
+ throw new Error("a sovereign principal's subject is the lowercase sha256 hex of its root public key");
249
+ }
250
+ return `${provider.scope}:${rootKeyHash}`;
251
+ }
252
+
253
+ /** Brand check shared by the framework's provider-taking helpers. */
254
+ export function isAuthenticationProvider(value: unknown): value is AuthenticationProviderRef {
255
+ return (value as { [authenticationProviderBrand]?: unknown } | undefined)?.[authenticationProviderBrand] === true;
256
+ }
257
+
258
+ /**
259
+ * The principals a provider authenticates, as the subject class a relation may store: every
260
+ * `<scope>:<subject>` principal. Sugar for `object(provider.scope)`, so `allow: [principalsOf(members)]`
261
+ * lets the relation hold exactly that provider's principals and no one else's.
262
+ */
263
+ export function principalsOf(provider: EnrolledProviderRef | SovereignProviderRef): {
264
+ readonly kind: "direct";
265
+ readonly type: string;
266
+ } {
267
+ if (provider?.[authenticationProviderBrand] !== true) {
268
+ throw new Error("principalsOf takes a provider declared with authenticationProvider");
269
+ }
270
+ if (provider.kind !== "enrolled" && provider.kind !== "sovereign") {
271
+ throw new Error("principalsOf takes an enrolled or sovereign provider, not a legacy provider row");
272
+ }
273
+ return Object.freeze({ kind: "direct" as const, type: provider.scope });
274
+ }
275
+
276
+ /** Bind a finished read or directive to one exact provider dependency. */
277
+ export function authenticatesWith<
278
+ T extends object & AuthenticatedMember,
279
+ >(member: T, provider: AuthenticationProviderRef): T & {
280
+ readonly authentication: Readonly<{
281
+ kind: MemberAuthenticationKind.SelectedProvider;
282
+ provider: AuthenticationProviderRef;
283
+ }>;
284
+ } {
285
+ if (member.authentication !== undefined) {
286
+ throw new Error("law member already has an authentication selection");
287
+ }
288
+ if (provider?.[authenticationProviderBrand] !== true) {
289
+ throw new Error("authenticatesWith takes a provider declared with authenticationProvider");
290
+ }
291
+ return Object.freeze({
292
+ ...member,
293
+ authentication: Object.freeze({
294
+ kind: MemberAuthenticationKind.SelectedProvider,
295
+ provider,
296
+ }),
297
+ });
298
+ }
299
+
300
+ export function enrolledDeviceAuthentication(): MemberAuthentication {
301
+ return Object.freeze({ kind: MemberAuthenticationKind.EnrolledDevice });
302
+ }
package/src/null_meta.ts CHANGED
@@ -10,7 +10,7 @@
10
10
  * `nullSemantic` (`"forbid"` default · `"explicit-empty"` · `"nullable"`), the required
11
11
  * `nullReason` documentation for the null-admitting semantics, and `isClearable` for the
12
12
  * explicit-clear lane. This module is the ONE reader of those props for the 5 codegen surfaces
13
- * (TS/Dart clients, the Dart bridge client, proof synthesis, openapi) — so a shape change lands
13
+ * (TS/Dart clients, the Dart session client, proof synthesis, openapi) — so a shape change lands
14
14
  * in one place, and the read is a structural cast (the props are additive/optional on `Field`,
15
15
  * so a field carrying none is byte-identical to a pre-feature field).
16
16
  */
@@ -0,0 +1,132 @@
1
+ import { execFile } from "node:child_process";
2
+ import { readFileSync, rmSync, writeFileSync } from "node:fs";
3
+ import path from "node:path";
4
+ import { promisify } from "node:util";
5
+
6
+ const execFileAsync = promisify(execFile);
7
+
8
+ export interface OpenUsdFlattenRequest {
9
+ readonly usdcat: string;
10
+ readonly sourcePath: string;
11
+ readonly populationMask?: readonly string[];
12
+ readonly description: string;
13
+ }
14
+
15
+ export interface OpenUsdEncodeRequest {
16
+ readonly usdcat: string;
17
+ readonly usda: string;
18
+ readonly temporaryDirectory: string;
19
+ readonly temporaryStem: string;
20
+ readonly description: string;
21
+ }
22
+
23
+ function stderrOf(error: unknown): string {
24
+ if (typeof error !== "object" || error === null || !("stderr" in error))
25
+ return "";
26
+ return String((error as { readonly stderr?: unknown }).stderr ?? "").trim();
27
+ }
28
+
29
+ /** Ask stock OpenUSD to compose one source stage into canonical, inspectable USDA. */
30
+ export async function flattenOpenUsdToUsda(
31
+ request: OpenUsdFlattenRequest
32
+ ): Promise<string> {
33
+ const args = ["--flatten", "--skipSourceFileComment"];
34
+ const populationMask =
35
+ request.populationMask === undefined
36
+ ? undefined
37
+ : [...new Set(request.populationMask)]
38
+ .sort((left, right) =>
39
+ left.length === right.length
40
+ ? left.localeCompare(right)
41
+ : left.length - right.length
42
+ )
43
+ .filter(
44
+ (candidate, index, paths) =>
45
+ !paths
46
+ .slice(0, index)
47
+ .some(
48
+ (ancestor) =>
49
+ candidate === ancestor || candidate.startsWith(`${ancestor}/`)
50
+ )
51
+ )
52
+ .sort();
53
+ if (
54
+ populationMask !== undefined &&
55
+ populationMask.length > 0
56
+ ) {
57
+ args.push("--mask", populationMask.join(","));
58
+ }
59
+ args.push(request.sourcePath);
60
+ try {
61
+ const { stdout: usda } = await execFileAsync(request.usdcat, args, {
62
+ encoding: "utf8",
63
+ maxBuffer: 256 * 1024 * 1024,
64
+ });
65
+ if (!usda.startsWith("#usda 1.0")) {
66
+ throw new Error(
67
+ `stock OpenUSD returned a non-USDA ${request.description}`
68
+ );
69
+ }
70
+ // `--skipSourceFileComment` drops usdcat's leading comment, but the flattened layer's `doc`
71
+ // still records the ABSOLUTE root-layer path ("Generated from Composed Stage of root layer
72
+ // /Users/…/build/bootstrap/…"). That is the checkout location, not law: identical sources
73
+ // hashed differently on every machine (four checkouts, four stage-zero law hashes on
74
+ // 2026-09-07) and the kernel release could never reproduce the reviewed candidate. Keep the
75
+ // sentence and the layer's file name; drop the directory.
76
+ return usda.replace(
77
+ /(Generated from Composed Stage of root layer )(?:[^"\n]*\/)?([^"\n/]+)/g,
78
+ "$1$2"
79
+ );
80
+ } catch (error) {
81
+ const stderr = stderrOf(error);
82
+ const maskDetail =
83
+ populationMask === undefined
84
+ ? ""
85
+ : ` (population mask: ${populationMask.length} irredundant paths, ${populationMask.join(",").length} characters)`;
86
+ throw new Error(
87
+ `stock OpenUSD refused the canonical typed USDA closure while compiling ${request.description}${maskDetail}` +
88
+ (stderr.length === 0 ? "" : `: ${stderr}`),
89
+ { cause: error }
90
+ );
91
+ }
92
+ }
93
+
94
+ /** Encode already-composed USDA as OpenUSD's reversible binary crate representation. */
95
+ export async function encodeOpenUsdUsdc(
96
+ request: OpenUsdEncodeRequest
97
+ ): Promise<Uint8Array> {
98
+ const sourcePath = path.join(
99
+ request.temporaryDirectory,
100
+ `.${request.temporaryStem}.tmp.usda`
101
+ );
102
+ const destinationPath = path.join(
103
+ request.temporaryDirectory,
104
+ `.${request.temporaryStem}.tmp.usdc`
105
+ );
106
+ try {
107
+ writeFileSync(sourcePath, request.usda);
108
+ await execFileAsync(request.usdcat, ["-o", destinationPath, sourcePath], {
109
+ maxBuffer: 64 * 1024 * 1024,
110
+ });
111
+ const usdc = readFileSync(destinationPath);
112
+ if (
113
+ usdc.length < 8 ||
114
+ new TextDecoder().decode(usdc.subarray(0, 8)) !== "PXR-USDC"
115
+ ) {
116
+ throw new Error(
117
+ `stock OpenUSD returned a non-USDC ${request.description}`
118
+ );
119
+ }
120
+ return usdc;
121
+ } catch (error) {
122
+ const stderr = stderrOf(error);
123
+ throw new Error(
124
+ `stock OpenUSD could not encode ${request.description} as USDC` +
125
+ (stderr.length === 0 ? "" : `: ${stderr}`),
126
+ { cause: error }
127
+ );
128
+ } finally {
129
+ rmSync(sourcePath, { force: true });
130
+ rmSync(destinationPath, { force: true });
131
+ }
132
+ }
@@ -0,0 +1,31 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ import { createHash } from 'node:crypto';
3
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
4
+ import path from 'node:path';
5
+
6
+ /** Validate the emitted law, not a second in-memory interpretation of the DSL.
7
+ * Cached results accelerate compilation only; they never enter custody or stand
8
+ * in for the kernel's admission decision. A changed checker invalidates hits.
9
+ */
10
+ export function checkOperationContracts(lawPath: string, descriptorPath: string, compilerRoot: string, cacheRoot: string): void {
11
+ const checker = path.join(compilerRoot, 'operation_contract_check.mjs');
12
+ const artifact = path.join(compilerRoot, 'assets', 'operation-contract.wasm');
13
+ if (!existsSync(artifact)) throw new Error('Nomos compiler is missing its bundled operation contract checker; rebuild/reinstall the compiler package');
14
+ const key = createHash('sha256').update('nomos.operation-contract-check.v1\0')
15
+ .update(readFileSync(artifact)).update(readFileSync(checker)).update(readFileSync(lawPath))
16
+ .update(readFileSync(descriptorPath)).digest('hex');
17
+ const cache = path.join(cacheRoot, 'node_modules', '.cache', 'nomos', 'operation-contracts');
18
+ const receipt = path.join(cache, `${key}.ok`);
19
+ if (existsSync(receipt)) return;
20
+ try {
21
+ execFileSync(process.execPath, [checker, path.resolve(lawPath), path.resolve(descriptorPath)], {
22
+ encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], maxBuffer: 8 * 1024 * 1024,
23
+ });
24
+ } catch (error) {
25
+ const detail = error instanceof Error && 'stderr' in error && error.stderr
26
+ ? String(error.stderr) : String(error);
27
+ throw new Error(`Operation contract validation failed:\n${detail}`);
28
+ }
29
+ mkdirSync(cache, { recursive: true });
30
+ writeFileSync(receipt, 'validated by the bundled kernel contract checker\n');
31
+ }
@@ -217,7 +217,8 @@ export function first(id: string): TypelessFirst {
217
217
  * `n` MUST be ≥ 1. `n = 1` is equivalent to `first` but a distinct declaration id.
218
218
  */
219
219
  export function take(id: string, n: number): TypelessTake {
220
- if (n < 1) throw new Error(`take(${id}, ${n}): n must be ≥ 1`);
220
+ if (!Number.isInteger(n) || n < 1 || n > 0xffff_ffff)
221
+ throw new Error(`take(${id}, ${n}): n must be an integer from 1 through 4294967295`);
221
222
  return {
222
223
  id,
223
224
  limit: n,
@@ -8,7 +8,10 @@ import {
8
8
  isApplicationHomeGenesis,
9
9
  type ApplicationHomeGenesis,
10
10
  } from "./application_home_genesis.js";
11
- import type { WorkspaceRole } from "./births.js";
11
+ import {
12
+ RECEIVING_GROUP_RECOVERY_POLICIES,
13
+ type ReceivingGroupRecoveryPolicy,
14
+ } from "./framework/receiving_group.js";
12
15
 
13
16
  /**
14
17
  * One cohesive, vertically sliced business capability inside a domain.
@@ -74,12 +77,17 @@ export interface NomosPackageConfig {
74
77
  * Required for a published application: Nomos never invents a child-workspace allowance. */
75
78
  readonly application?: {
76
79
  readonly maxChildWorkspacesPerUser: number;
77
- /** Target-owned roles granted at genesis to the cryptographically verified platform workspace.
78
- * These are law constants, not caller or host input. */
79
- readonly parentWorkspaceRoles?: readonly WorkspaceRole[];
80
80
  /** Tenant law which must hold from the application's first usable home state. Every entry is
81
81
  * an ordinary offer executed through the child's gate; omission declares no tenant ceremony. */
82
82
  readonly homeGenesis?: ApplicationHomeGenesis;
83
+ /** THE RECEIVING-GROUP DECLARATION. A verified person's receiving group is the framework's identity
84
+ * anchor; the application declares how that anchor behaves as DATA, never by authoring lifecycle law.
85
+ * `recovery` is the posture the anchor is BORN with (`"guardian-quorum"` is the framework default;
86
+ * `"platform-identity-provider"` lets the attested parent platform re-seat a replacement device).
87
+ * Era rule: an application that declares nothing is byte-identical to one compiled before this key. */
88
+ readonly receivingGroup?: {
89
+ readonly recovery?: ReceivingGroupRecoveryPolicy;
90
+ };
83
91
  };
84
92
  /** Separately installed law required at runtime; USDA composition arcs do not belong here. */
85
93
  readonly dependencies?: readonly RuntimePackageDependency[];
@@ -228,15 +236,28 @@ export function validateNomosPackageConfig(value: unknown): {
228
236
  "Nomos will not reinterpret an untyped genesis recipe",
229
237
  );
230
238
  }
231
- if (
232
- config.application.parentWorkspaceRoles !== undefined &&
233
- (!Array.isArray(config.application.parentWorkspaceRoles) ||
234
- config.application.parentWorkspaceRoles.some(
235
- (role) => typeof role !== "string" || !/^[A-Za-z][A-Za-z0-9_-]*$/.test(role),
236
- ))
237
- ) {
239
+ const receivingGroup = config.application.receivingGroup;
240
+ if (receivingGroup !== undefined) {
241
+ if (receivingGroup === null || typeof receivingGroup !== "object" || Array.isArray(receivingGroup)) {
242
+ throw new Error("application.receivingGroup must be an object declaration");
243
+ }
244
+ if (
245
+ receivingGroup.recovery !== undefined &&
246
+ !(RECEIVING_GROUP_RECOVERY_POLICIES as readonly string[]).includes(receivingGroup.recovery as string)
247
+ ) {
248
+ throw new Error(
249
+ `application.receivingGroup.recovery must be one of ${RECEIVING_GROUP_RECOVERY_POLICIES.join(", ")}; ` +
250
+ "Nomos will not reinterpret an unknown recovery posture",
251
+ );
252
+ }
253
+ }
254
+ // RETIRED 2026-09-11 (receiving_group_lifecycle.md, cut 1 item 4): the role a receiving group grants
255
+ // its birthing platform is the framework's own `authProviderAuthority`, seated by construction. A tenant
256
+ // restating (or extending) it is refused loudly rather than silently ignored.
257
+ if ("parentWorkspaceRoles" in config.application) {
238
258
  throw new Error(
239
- "application.parentWorkspaceRoles must contain workspaceRole(...) declarations",
259
+ "application.parentWorkspaceRoles is retired: the framework seats authProviderAuthority for the " +
260
+ "verified platform on every receiving group it births; delete the key",
240
261
  );
241
262
  }
242
263
  }
@@ -81,6 +81,7 @@ export function packageContractUsda(input: {
81
81
  ' def NomosPackage "Package"',
82
82
  " {",
83
83
  ` custom uniform string nomos:name = ${usdaString(input.packageName)}`,
84
+ ' custom uniform token nomos:operationContract = "nomos.protobuf.v1"',
84
85
  ` custom uniform string[] nomos:domains = ${usdaStringArray([...input.exportedDomains].sort())}`,
85
86
  ...(targets.length > 0
86
87
  ? [
@@ -53,7 +53,33 @@ export class PlanSourceSliceProgram {
53
53
  };
54
54
  }
55
55
  }
56
- this.#program = ts.createProgram({ rootNames: rootNames.map(normalized), options });
56
+ // The slicer only ever retains declarations inside the slice roots, so the program needs
57
+ // exactly those files: no lib.d.ts, no @types, and no descent into dependency packages.
58
+ // Resolving `@githolon/dsl`/`zod` from a tenant module otherwise parses the whole dependency
59
+ // type graph (hundreds of files, ~0.4s) for symbols that are discarded on sight.
60
+ options = { ...options, noLib: true, types: [] };
61
+ const host = ts.createCompilerHost(options, true);
62
+ const normalizedRoots = this.#sliceRoots;
63
+ const insideSliceRoots = (file: string): boolean => {
64
+ const absolute = normalized(file);
65
+ return normalizedRoots.some((root) => absolute.startsWith(root)) &&
66
+ !absolute.includes(`${path.sep}node_modules${path.sep}`);
67
+ };
68
+ host.resolveModuleNameLiterals = (literals, containingFile, redirected, compilerOptions) => {
69
+ const containerInside = insideSliceRoots(containingFile);
70
+ return literals.map((literal) => {
71
+ if (!containerInside) return { resolvedModule: undefined };
72
+ const resolution = ts.resolveModuleName(
73
+ literal.text, containingFile, compilerOptions, host, undefined, redirected,
74
+ );
75
+ const resolved = resolution.resolvedModule;
76
+ if (resolved === undefined || !insideSliceRoots(resolved.resolvedFileName)) {
77
+ return { resolvedModule: undefined };
78
+ }
79
+ return resolution;
80
+ });
81
+ };
82
+ this.#program = ts.createProgram({ rootNames: rootNames.map(normalized), options, host });
57
83
  this.#checker = this.#program.getTypeChecker();
58
84
  }
59
85
 
@@ -155,6 +181,9 @@ export class PlanSourceSliceProgram {
155
181
  };
156
182
  const markSymbol = (symbol: ts.Symbol | undefined): void => {
157
183
  if (symbol === undefined || retainedSymbols.has(symbol)) return;
184
+ // An unresolved external import aliases the checker's one shared `unknown` symbol; retaining
185
+ // it would make every other unresolved binding look retained.
186
+ if (symbol.declarations === undefined || symbol.declarations.length === 0) return;
158
187
  retainedSymbols.add(symbol);
159
188
  if ((symbol.flags & ts.SymbolFlags.Alias) !== 0) {
160
189
  try {
@@ -0,0 +1,36 @@
1
+ /**
2
+ * THE ONE DERIVATION of a Protobuf field identity from a stable law identity.
3
+ *
4
+ * The kernel builds every operation descriptor from installed law with this exact function
5
+ * (`kernel/src/operation_contract/descriptor.rs` `protobuf_field_number`), and the compiler emits
6
+ * every generated facade with it too. It is a pure function of the stable identity: nothing is
7
+ * looked up, there is no registry, and declaration order is deliberately not an input — adding a
8
+ * field cannot renumber an existing one.
9
+ *
10
+ * It lives in its own leaf module, importing nothing, because BOTH sides need it: the compiler
11
+ * (`codegen_call_proto.ts` re-exports it) and the Peer Office's law-derived encoder
12
+ * (`peer-office/src/runtime/law_directive_call.ts`), which must derive a call's wire layout from
13
+ * a workspace's own installed law. `@githolon/dsl` already depends on `@githolon/runtime`, so
14
+ * the office cannot be the home without a package cycle; and the office reaches this file the way
15
+ * it already reaches `adapter/proto` — by repository path, inlined by its own bundler. Keeping the
16
+ * module dependency-free is what makes that safe.
17
+ */
18
+
19
+ const fnv64 = (value: string): bigint => {
20
+ let hash = 0xcbf29ce484222325n;
21
+ for (const point of new TextEncoder().encode(value)) {
22
+ hash ^= BigInt(point);
23
+ hash = BigInt.asUintN(64, hash * 0x100000001b3n);
24
+ }
25
+ return hash;
26
+ };
27
+
28
+ export function protobufFieldNumber(stableIdentity: string): number {
29
+ const identity = /^[0-9a-f]{16}$/i.test(stableIdentity)
30
+ ? BigInt(`0x${stableIdentity}`)
31
+ : fnv64(stableIdentity);
32
+ const ordinarySlots = 536_869_911n; // 2^29-1, less the 1,000 reserved numbers.
33
+ let field = Number(identity % ordinarySlots) + 1;
34
+ if (field >= 19_000) field += 1_000;
35
+ return field;
36
+ }
@@ -0,0 +1,6 @@
1
+ // Transport-only identities derived from existing attributed law. No new durable state.
2
+ // Mirrored by kernel/src/call_authoring/provenance.rs and checked by the descriptor gate.
3
+ export const provenanceRowIdentity = (aggregate: string): string => `${aggregate}:result:provenance`;
4
+ export const provenanceFieldIdentity = (field: string): string => `${field}:result:provenance`;
5
+ export const provenanceAuthorIdentity = "nomos:provenance:author";
6
+ export const provenanceContestedIdentity = "nomos:provenance:wasContested";
package/src/query.ts CHANGED
@@ -29,6 +29,7 @@
29
29
  */
30
30
  import type { AggregateHandle } from "./aggregate.js";
31
31
  import type { Field } from "./fields.js";
32
+ import type { AuthenticatedMember } from "./member_authentication.js";
32
33
  import { pathString, type PathRef } from "./path.js";
33
34
 
34
35
  /** A key argument accepted by `.key(...)`: a plain (dotted) string OR a typed {@link PathRef}
@@ -67,7 +68,7 @@ type QueryKeyCompatibility<
67
68
  * sorted), and the aggregate TYPE id it `returns`. Minimal by design: params /
68
69
  * where / scope are later steps.
69
70
  */
70
- export interface QueryDecl {
71
+ export interface QueryDecl extends AuthenticatedMember {
71
72
  readonly id: string;
72
73
  /** Index key fields, in DECLARED order (= index column order). */
73
74
  readonly key: string[];