@githolon/dsl 0.108.7 → 0.110.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 (308) 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 +80 -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 +214 -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 +268 -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 +23950 -15776
  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 +550 -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_event_desk_close_test.dart +16 -0
  74. package/dart/test/reception_span_trace_test.dart +23 -0
  75. package/dart/test/replica_readiness_test.dart +156 -0
  76. package/dart/test/runtime_projections_test.dart +92 -0
  77. package/dart/test/runtime_v2_gateway_test.dart +131 -0
  78. package/dart/test/signing_identity_kernel_test.dart +75 -0
  79. package/dart/test/sync_status_preparation_report_test.dart +29 -0
  80. package/dart/test/sync_status_reducer_test.dart +419 -0
  81. package/dart/test/test_harness_test.dart +71 -95
  82. package/dart/test/typed_query_watch_test.dart +170 -0
  83. package/dart/test/typed_watch_registry_test.dart +249 -0
  84. package/dart_lints/README.md +18 -0
  85. package/dart_lints/lib/nomos_lints.dart +70 -0
  86. package/dart_lints/pubspec.lock +580 -0
  87. package/dart_lints/pubspec.yaml +12 -0
  88. package/dart_lints/test/reference_identity_test.dart +75 -0
  89. package/dart_types/CHANGELOG.md +18 -0
  90. package/dart_types/lib/nomos_kernel_protocol.dart +21 -1
  91. package/dart_types/lib/nomos_types.dart +9 -1
  92. package/dart_types/lib/src/admission_decision.dart +37 -0
  93. package/dart_types/lib/src/aggregate_meta.dart +1 -1
  94. package/dart_types/lib/src/approved_model.dart +65 -0
  95. package/dart_types/lib/src/custody.dart +10 -18
  96. package/dart_types/lib/src/error_info.dart +4 -4
  97. package/dart_types/lib/src/errors.dart +29 -29
  98. package/dart_types/lib/src/foreign_ref.dart +62 -33
  99. package/dart_types/lib/src/local_work_rejected.dart +3 -3
  100. package/dart_types/lib/src/nomos_ref.dart +3 -1
  101. package/dart_types/lib/src/principal.dart +2 -2
  102. package/dart_types/lib/src/proto/google/protobuf/any.pb.dart +163 -0
  103. package/dart_types/lib/src/proto/google/protobuf/any.pbenum.dart +11 -0
  104. package/dart_types/lib/src/proto/nomos/discovery/v1/workspace_placement.pb.dart +137 -0
  105. package/dart_types/lib/src/proto/nomos/discovery/v1/workspace_placement.pbenum.dart +11 -0
  106. package/dart_types/lib/src/proto/nomos/kernel/v1/kernel.pb.dart +20721 -10433
  107. package/dart_types/lib/src/proto/nomos/kernel/v1/kernel.pbenum.dart +555 -27
  108. package/dart_types/lib/src/proto/nomos/runtime/v2/application_desk.pb.dart +387 -0
  109. package/dart_types/lib/src/proto/nomos/runtime/v2/application_desk.pbenum.dart +46 -0
  110. package/dart_types/lib/src/proto/nomos/runtime/v2/application_readiness_desk.pb.dart +295 -0
  111. package/dart_types/lib/src/proto/nomos/runtime/v2/application_readiness_desk.pbenum.dart +139 -0
  112. package/dart_types/lib/src/proto/nomos/runtime/v2/authentication_desk.pb.dart +269 -0
  113. package/dart_types/lib/src/proto/nomos/runtime/v2/authentication_desk.pbenum.dart +103 -0
  114. package/dart_types/lib/src/proto/nomos/runtime/v2/compatibility_desk.pb.dart +417 -0
  115. package/dart_types/lib/src/proto/nomos/runtime/v2/compatibility_desk.pbenum.dart +62 -0
  116. package/dart_types/lib/src/proto/nomos/runtime/v2/correspondence_desk.pb.dart +9968 -0
  117. package/dart_types/lib/src/proto/nomos/runtime/v2/correspondence_desk.pbenum.dart +133 -0
  118. package/dart_types/lib/src/proto/nomos/runtime/v2/credentials_desk.pb.dart +204 -0
  119. package/dart_types/lib/src/proto/nomos/runtime/v2/credentials_desk.pbenum.dart +54 -0
  120. package/dart_types/lib/src/proto/nomos/runtime/v2/custody_desk.pb.dart +1550 -0
  121. package/dart_types/lib/src/proto/nomos/runtime/v2/custody_desk.pbenum.dart +11 -0
  122. package/dart_types/lib/src/proto/nomos/runtime/v2/framework.pb.dart +710 -0
  123. package/dart_types/lib/src/proto/nomos/runtime/v2/framework.pbenum.dart +11 -0
  124. package/dart_types/lib/src/proto/nomos/runtime/v2/identity_desk.pb.dart +845 -0
  125. package/dart_types/lib/src/proto/nomos/runtime/v2/identity_desk.pbenum.dart +11 -0
  126. package/dart_types/lib/src/proto/nomos/runtime/v2/interaction_desk.pb.dart +198 -0
  127. package/dart_types/lib/src/proto/nomos/runtime/v2/interaction_desk.pbenum.dart +11 -0
  128. package/dart_types/lib/src/proto/nomos/runtime/v2/law_desk.pb.dart +369 -0
  129. package/dart_types/lib/src/proto/nomos/runtime/v2/law_desk.pbenum.dart +11 -0
  130. package/dart_types/lib/src/proto/nomos/runtime/v2/maintenance_desk.pb.dart +609 -0
  131. package/dart_types/lib/src/proto/nomos/runtime/v2/maintenance_desk.pbenum.dart +65 -0
  132. package/dart_types/lib/src/proto/nomos/runtime/v2/model_adoption_desk.pb.dart +358 -0
  133. package/dart_types/lib/src/proto/nomos/runtime/v2/model_adoption_desk.pbenum.dart +100 -0
  134. package/dart_types/lib/src/proto/nomos/runtime/v2/observability_desk.pb.dart +2231 -0
  135. package/dart_types/lib/src/proto/nomos/runtime/v2/observability_desk.pbenum.dart +271 -0
  136. package/dart_types/lib/src/proto/nomos/runtime/v2/placement_desk.pb.dart +1286 -0
  137. package/dart_types/lib/src/proto/nomos/runtime/v2/placement_desk.pbenum.dart +11 -0
  138. package/dart_types/lib/src/proto/nomos/runtime/v2/receiving_group_desk.pb.dart +636 -0
  139. package/dart_types/lib/src/proto/nomos/runtime/v2/receiving_group_desk.pbenum.dart +116 -0
  140. package/dart_types/lib/src/proto/nomos/runtime/v2/records_desk.pb.dart +1637 -0
  141. package/dart_types/lib/src/proto/nomos/runtime/v2/records_desk.pbenum.dart +175 -0
  142. package/dart_types/lib/src/proto/nomos/runtime/v2/recovery_desk.pb.dart +1269 -0
  143. package/dart_types/lib/src/proto/nomos/runtime/v2/recovery_desk.pbenum.dart +129 -0
  144. package/dart_types/lib/src/proto/nomos/runtime/v2/residency_desk.pb.dart +2782 -0
  145. package/dart_types/lib/src/proto/nomos/runtime/v2/residency_desk.pbenum.dart +97 -0
  146. package/dart_types/lib/src/proto/nomos/runtime/v2/runtime.pb.dart +2232 -8627
  147. package/dart_types/lib/src/proto/nomos/runtime/v2/runtime.pbenum.dart +0 -358
  148. package/dart_types/lib/src/proto/nomos/runtime/v2/sealing_desk.pb.dart +1639 -0
  149. package/dart_types/lib/src/proto/nomos/runtime/v2/sealing_desk.pbenum.dart +46 -0
  150. package/dart_types/lib/src/runtime_outcome.dart +133 -0
  151. package/dart_types/lib/src/subscriptions.dart +116 -23
  152. package/dart_types/pubspec.yaml +1 -1
  153. package/dart_types/test/extremum_subscriptions_test.dart +40 -0
  154. package/dart_types/test/foreign_ref_resolution_test.dart +75 -0
  155. package/dart_types/test/nomos_ref_address_test.dart +25 -0
  156. package/dart_types/test/ordered_subscriptions_test.dart +34 -0
  157. package/operation_contract_check.mjs +24 -0
  158. package/package.json +11 -6
  159. package/src/aggregate.ts +70 -10
  160. package/src/application_topology.ts +18 -11
  161. package/src/attested.ts +3 -0
  162. package/src/attested_core.ts +46 -3
  163. package/src/birth_meter_ensure.ts +19 -7
  164. package/src/births.ts +29 -4
  165. package/src/build_package.ts +140 -13
  166. package/src/business_birth.ts +181 -4
  167. package/src/codegen_call_proto.ts +1276 -0
  168. package/src/codegen_call_usda.ts +49 -6
  169. package/src/codegen_dart.ts +83 -44
  170. package/src/codegen_dart_client.ts +458 -800
  171. package/src/{codegen_dart_application.ts → codegen_dart_facade.ts} +331 -582
  172. package/src/codegen_dart_framework_calls.ts +320 -37
  173. package/src/codegen_dart_indexed_variant.ts +159 -0
  174. package/src/codegen_dart_scenario.ts +42 -13
  175. package/src/codegen_proof.ts +3 -3
  176. package/src/codegen_provider_dart.ts +5 -0
  177. package/src/codegen_query_proto.ts +158 -0
  178. package/src/codegen_refusal.ts +189 -0
  179. package/src/codegen_result_proto.ts +931 -0
  180. package/src/codegen_result_usda.ts +4 -0
  181. package/src/codegen_ts.ts +464 -616
  182. package/src/codegen_workspace_access.ts +105 -0
  183. package/src/compatibility_graph.ts +759 -0
  184. package/src/compatibility_usda.ts +264 -0
  185. package/src/compile_package_main.ts +2017 -1195
  186. package/src/custody_placement.ts +156 -0
  187. package/src/custody_placement_usda.ts +91 -0
  188. package/src/decl_shapes.ts +21 -2
  189. package/src/describe_model.ts +1 -0
  190. package/src/directive.ts +59 -2
  191. package/src/drivers.ts +51 -0
  192. package/src/engine_entry.ts +52 -8
  193. package/src/evolve_preview.ts +11 -4
  194. package/src/exists.ts +2 -0
  195. package/src/fields.ts +75 -11
  196. package/src/flow_gate.ts +2 -1
  197. package/src/framework/application_home.ts +170 -18
  198. package/src/framework/attested_receipts.ts +8 -3
  199. package/src/framework/auth_provider_law.ts +169 -9
  200. package/src/framework/birth_certificate_law.ts +4 -0
  201. package/src/framework/capability.ts +34 -3
  202. package/src/framework/child_authentication.ts +346 -0
  203. package/src/framework/console_governance.ts +295 -0
  204. package/src/framework/delegated_roles.ts +301 -0
  205. package/src/framework/domain_lifecycle.ts +26 -13
  206. package/src/framework/founding_genesis.ts +193 -0
  207. package/src/framework/framework_aggregates.ts +1 -1
  208. package/src/framework/genesis.ts +6 -1
  209. package/src/framework/governance_relations.ts +19 -0
  210. package/src/framework/home.ts +5 -734
  211. package/src/framework/legacy/child_auth_provider_epoch.ts +73 -0
  212. package/src/framework/model_authority_repair.ts +116 -0
  213. package/src/framework/model_authority_seed.ts +185 -0
  214. package/src/framework/model_transition.ts +211 -0
  215. package/src/framework/owned_custody.ts +1 -1
  216. package/src/framework/principal_enrollment.ts +302 -0
  217. package/src/framework/receiving_group.ts +857 -0
  218. package/src/framework/receiving_group_recovery.ts +314 -0
  219. package/src/framework/relations.ts +4 -8
  220. package/src/framework/signing_identity.ts +242 -95
  221. package/src/framework/source_roster.ts +11 -5
  222. package/src/framework/workspace_access.ts +149 -0
  223. package/src/framework/workspace_invariant.ts +73 -52
  224. package/src/framework/workspaces.ts +407 -40
  225. package/src/framework_call_definitions.ts +32 -3
  226. package/src/generated_client_bundle_boundary.ts +97 -0
  227. package/src/generated_client_names.ts +1 -0
  228. package/src/identity_usda.ts +27 -0
  229. package/src/index.ts +183 -12
  230. package/src/indexed_variant.ts +83 -0
  231. package/src/intent.ts +173 -45
  232. package/src/law_check.ts +8 -5
  233. package/src/law_dependency_index.ts +231 -0
  234. package/src/law_graph.ts +508 -71
  235. package/src/law_graph_usda.ts +170 -24
  236. package/src/law_identity.ts +119 -81
  237. package/src/law_source_map.ts +4 -1
  238. package/src/law_units.ts +498 -0
  239. package/src/law_value_type.ts +7 -3
  240. package/src/member_authentication.ts +302 -0
  241. package/src/null_meta.ts +1 -1
  242. package/src/openusd_compiled_layer.ts +132 -0
  243. package/src/operation_contract_check.ts +31 -0
  244. package/src/ordered_read.ts +2 -1
  245. package/src/package_config.ts +33 -12
  246. package/src/package_dependencies.ts +1 -0
  247. package/src/plan_source_slice.ts +30 -1
  248. package/src/protobuf_field_number.ts +36 -0
  249. package/src/provenance_wire.ts +6 -0
  250. package/src/query.ts +2 -1
  251. package/src/read.ts +50 -0
  252. package/src/relation.ts +4 -1
  253. package/src/relation_schema.ts +15 -2
  254. package/src/report.ts +2 -2
  255. package/src/sqlite_computation_bundle.ts +78 -0
  256. package/src/sqlite_computed.ts +102 -0
  257. package/src/sqlite_counts.ts +154 -0
  258. package/src/sqlite_layout.ts +823 -0
  259. package/src/sqlite_reads.ts +275 -0
  260. package/src/sqlite_samples.ts +185 -0
  261. package/src/stable_id_identity_bridge.ts +1 -1
  262. package/src/stable_ids_for_module.ts +16 -4
  263. package/src/test_call_usda.ts +6 -6
  264. package/src/usda_relationship_integrity.ts +20 -3
  265. package/src/usda_text.ts +21 -1
  266. package/src/value_object.ts +81 -11
  267. package/src/wire.ts +22 -0
  268. package/src/wire_encode.ts +227 -20
  269. package/src/workspace_sharding.ts +15 -6
  270. package/src/workspace_sharing.ts +51 -49
  271. package/src/zod_introspection.ts +2 -0
  272. package/compat_package.mjs +0 -46
  273. package/dart/lib/src/home.dart +0 -15
  274. package/dart/lib/src/runner/offline-install.mjs +0 -15367
  275. package/dart/lib/src/source_trust.dart +0 -51
  276. package/dart/lib/src/webview_bridge.dart +0 -6540
  277. package/dart/lib/src/workspace_name.dart +0 -30
  278. package/dart/test/acquire_session_credentials_test.dart +0 -150
  279. package/dart/test/acquire_session_test.dart +0 -534
  280. package/dart/test/adv_realm_interference_test.dart +0 -600
  281. package/dart/test/cloud_bound_topology_test.dart +0 -168
  282. package/dart/test/cluster_births_test.dart +0 -202
  283. package/dart/test/cluster_device_keyed_acceptance_test.dart +0 -105
  284. package/dart/test/cluster_local_autosync_test.dart +0 -123
  285. package/dart/test/cluster_scale_test.dart +0 -122
  286. package/dart/test/compat_test.dart +0 -61
  287. package/dart/test/dlq_session_surface_test.dart +0 -222
  288. package/dart/test/first_app_gauntlet_test.dart +0 -386
  289. package/dart/test/fixtures/wedge/fake-install.mjs +0 -11
  290. package/dart/test/four_layer_nested_topology_test.dart +0 -290
  291. package/dart/test/home_parity_test.dart +0 -13
  292. package/dart/test/local_sync_inert_test.dart +0 -107
  293. package/dart/test/node_runner_transport_test.dart +0 -78
  294. package/dart/test/parent_signer_recovery_test.dart +0 -155
  295. package/dart/test/residency_refusal_test.dart +0 -49
  296. package/dart/test/sealing_client_test.dart +0 -181
  297. package/dart/test/session_bound_test.dart +0 -285
  298. package/dart/test/stale_bundle_test.dart +0 -80
  299. package/dart/test/vo_read_typing_test.dart +0 -131
  300. package/dart/test/watch_after_offer_stall_test.dart +0 -100
  301. package/dart/test/webview_bridge_test.dart +0 -1930
  302. package/dart/test/workspace_name_test.dart +0 -24
  303. package/runtime/generated-application-host.js +0 -22860
  304. package/src/codegen_query_usda.ts +0 -214
  305. package/src/compat_manifest.ts +0 -26
  306. package/src/compat_package_main.ts +0 -224
  307. package/src/shape_compat.ts +0 -352
  308. package/src/usd_state.ts +0 -505
@@ -0,0 +1,149 @@
1
+ /** Source-qualified access correspondence. This is law, not a client delivery loop.
2
+ * The source commits its publication and outbound offer together. The recipient
3
+ * keeps an ordering receipt and ordinary Zanzibar edges; no sender gets Home authority.
4
+ */
5
+ import { z } from "zod";
6
+ import { aggregate, instance } from "../aggregate.js";
7
+ import { directive, nomosImplementationDetail, type Directive } from "../directive.js";
8
+ import type { BusinessIntent } from "../intent.js";
9
+ import type { Ports } from "../ctx.js";
10
+ import { Lww } from "../drivers.js";
11
+ import { t } from "../fields.js";
12
+ import { set, withMarker } from "../ops.js";
13
+ import { query } from "../query.js";
14
+ import { readFrameworkDeclaredRows } from "../read.js";
15
+ import { endorsementOf } from "../principal_evidence.js";
16
+ import { RelationTuple, writeTuple, removeTuple } from "./relations.js";
17
+
18
+ declare const nomos: { sha256(input: string): string };
19
+
20
+ export const workspaceAccessPayload = z.object({
21
+ recipient: z.string().regex(/^user:[A-Za-z0-9][A-Za-z0-9_.-]*$/),
22
+ object: z.string().regex(/^[A-Za-z0-9][A-Za-z0-9_.:/-]*$/),
23
+ relation: z.string().regex(/^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$/),
24
+ active: z.boolean(),
25
+ revision: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),
26
+ });
27
+ export type WorkspaceAccessPublication = z.infer<typeof workspaceAccessPayload>;
28
+ export type WorkspaceAccessChange = Omit<WorkspaceAccessPublication, "revision">;
29
+
30
+ export const WorkspaceAccessPublication = nomosImplementationDetail(aggregate("WorkspaceAccessPublication", {
31
+ coordinate: t.string().merge(Lww),
32
+ revision: t.int().merge(Lww),
33
+ // Ordering metadata has the same visibility as the public RelationTuple facts;
34
+ // it contains neither device credentials nor encrypted business contents.
35
+ }, { global: true }).public());
36
+ export const workspaceAccessPublication = query("workspaceAccessPublication")
37
+ .key("coordinate").returns(WorkspaceAccessPublication);
38
+
39
+ /** Ordering only. Discovery is the RelationTuple below, not another bookmark index. */
40
+ export const WorkspaceAccessReceipt = nomosImplementationDetail(aggregate("WorkspaceAccessReceipt", {
41
+ coordinate: t.string().merge(Lww),
42
+ revision: t.int().merge(Lww),
43
+ subject: t.string().merge(Lww),
44
+ }, { global: true }).public());
45
+ export const workspaceAccessReceipt = query("workspaceAccessReceipt")
46
+ .key("coordinate").returns(WorkspaceAccessReceipt);
47
+
48
+ /** Home's ordinary Zanzibar discovery read. It has its own nominal identity;
49
+ * it must not collide with generic relation queries installed by other domains. */
50
+ export const receivedWorkspaceAccess = nomosImplementationDetail(query("receivedWorkspaceAccess")
51
+ .key("object").returns(RelationTuple));
52
+
53
+ export function accessCoordinate(recipient: string, object: string): string {
54
+ return nomos.sha256(JSON.stringify([recipient, object]));
55
+ }
56
+ export const RECEIVED_ACCESS_RELATION = "receivedAccess";
57
+ export function receivedAccessObject(recipient: string): string {
58
+ return `received-access:${recipient}`;
59
+ }
60
+
61
+ /** A fresh publication gets a fresh userset address. Revoked leaves are never
62
+ * resurrected (the kernel's remove-wins rule), including a later lawful re-share. */
63
+ export function receivedAccessSubject(source: string, p: WorkspaceAccessPublication): string {
64
+ return `shared:${source}/${p.object}/${p.revision}#${p.relation}`;
65
+ }
66
+
67
+ export const recordReceivedWorkspaceAccess = nomosImplementationDetail(directive("recordReceivedWorkspaceAccess")
68
+ .ensures(RelationTuple)
69
+ .payload(workspaceAccessPayload)
70
+ .plan((p, ctx) => {
71
+ const actor = endorsementOf(ctx.principal().asAttribution())?.principal ?? "";
72
+ if (!actor.startsWith("workspace:")) throw new Error("share requires a verified workspace speaker");
73
+ const source = actor.slice("workspace:".length);
74
+ const coordinate = `${source}/${accessCoordinate(p.recipient, p.object)}`;
75
+ const rows = readFrameworkDeclaredRows(workspaceAccessReceipt, WorkspaceAccessReceipt, { coordinate });
76
+ if (rows.length > 1) throw new Error("duplicate workspace access receipt");
77
+ const previous = rows[0];
78
+ // Old instruments are acknowledged without re-applying their consequences.
79
+ if ((previous?.revision ?? 0) >= p.revision) return [];
80
+ const object = receivedAccessObject(p.recipient);
81
+ const subject = receivedAccessSubject(source, p);
82
+ const at = new Date(ctx.clock().physical).toISOString();
83
+ const receipt = instance(WorkspaceAccessReceipt, `access-receipt:${coordinate}`);
84
+ return [
85
+ ...(previous?.subject ? removeTuple({ object, relation: RECEIVED_ACCESS_RELATION,
86
+ subject: previous.subject, grantedBy: actor, grantedAt: at, revokedBy: actor, revokedAt: at }) : []),
87
+ ...(p.active ? writeTuple({ object, relation: RECEIVED_ACCESS_RELATION, subject,
88
+ grantedBy: actor, grantedAt: at }) : []),
89
+ withMarker(set(receipt, "coordinate", coordinate), "ensures"),
90
+ set(receipt, "revision", p.revision),
91
+ set(receipt, "subject", p.active ? subject : ""),
92
+ ];
93
+ })
94
+ .affectsOptional()
95
+ .alsoEnsuresOptional(WorkspaceAccessReceipt)
96
+ .reads(workspaceAccessReceipt)
97
+ .acceptsVerifiedWorkspaceClaim());
98
+
99
+ /** Attach one typed, durable correspondence to a normal public offer. No session,
100
+ * network, key, clock cache or retry state is introduced by this wrapper. */
101
+ export function publishesWorkspaceAccess<P>(
102
+ action: BusinessIntent<P>,
103
+ change: (facts: P, ctx: Ports) => WorkspaceAccessChange | null,
104
+ recipientWorkspace: (recipient: string) => string,
105
+ receiver?: Directive<WorkspaceAccessPublication>,
106
+ ): BusinessIntent<P>;
107
+ export function publishesWorkspaceAccess<P>(
108
+ action: Directive<P>,
109
+ change: (facts: P, ctx: Ports) => WorkspaceAccessChange | null,
110
+ recipientWorkspace: (recipient: string) => string,
111
+ receiver?: Directive<WorkspaceAccessPublication>,
112
+ ): Directive<P>;
113
+ export function publishesWorkspaceAccess<P>(
114
+ action: Directive<P>,
115
+ change: (facts: P, ctx: Ports) => WorkspaceAccessChange | null,
116
+ recipientWorkspace: (recipient: string) => string,
117
+ receiver: Directive<WorkspaceAccessPublication> = recordReceivedWorkspaceAccess,
118
+ ): Directive<P> {
119
+ const publication = (facts: P, ctx: Ports): WorkspaceAccessPublication => {
120
+ const access = change(facts, ctx);
121
+ if (access === null) throw new Error("this offer has no identified access recipient");
122
+ const coordinate = accessCoordinate(access.recipient, access.object);
123
+ const rows = readFrameworkDeclaredRows(workspaceAccessPublication, WorkspaceAccessPublication, { coordinate });
124
+ if (rows.length > 1) throw new Error("duplicate workspace access publication");
125
+ return workspaceAccessPayload.parse({ ...access, revision: (rows[0]?.revision ?? 0) + 1 });
126
+ };
127
+ return {
128
+ ...action,
129
+ secondaryOutputs: [...(action.secondaryOutputs ?? []), {
130
+ aggregateId: WorkspaceAccessPublication.id, aggregate: WorkspaceAccessPublication, marker: "ensures", optional: true,
131
+ }],
132
+ declaredQueryReads: [...(action.declaredQueryReads ?? []), workspaceAccessPublication],
133
+ plan(facts, ctx) {
134
+ const ops = action.plan(facts, ctx);
135
+ if (change(facts, ctx) === null) return ops;
136
+ const p = publication(facts, ctx);
137
+ const coordinate = accessCoordinate(p.recipient, p.object);
138
+ const counter = instance(WorkspaceAccessPublication, `access-publication:${coordinate}`);
139
+ return [...ops, withMarker(set(counter, "coordinate", coordinate), "ensures"), set(counter, "revision", p.revision)];
140
+ },
141
+ workspaceEffects: [...(action.workspaceEffects ?? []), {
142
+ target: receiver,
143
+ // Payload and destination are evaluated from the same captured ports by the plan encoder.
144
+ destination: { kind: "workspace", address: (facts, ctx) => recipientWorkspace(publication(facts, ctx).recipient) },
145
+ when: (facts, ctx) => change(facts, ctx) !== null,
146
+ payload: publication,
147
+ }],
148
+ };
149
+ }
@@ -35,10 +35,40 @@
35
35
  * workspace scan / projection read / ambient "current world" read — only the declared refs.
36
36
  */
37
37
 
38
+ import type { AggregateHandle, ReadModelRow } from "../aggregate.js";
39
+ import type { Directive } from "../directive.js";
40
+ import type { ValueObject, NominalCase } from "../value_object.js";
38
41
  import type { PointGuardSpec } from "../point_guard.js";
39
42
 
40
43
  /** A TYPED verdict — identical shape to the aggregate invariant (the engine parses both). */
41
- export type WorkspaceInvariantVerdict = { accept: true } | { reject: string };
44
+ export type WorkspaceInvariantVerdict<R = string> = { accept: true } | { reject: R };
45
+ export const accept = (): { accept: true } => ({ accept: true });
46
+ export const reject = <R>(value: R): { reject: R } => ({ reject: value });
47
+
48
+ declare const READ_SNAPSHOT: unique symbol;
49
+ type TypedReadBinding<B extends string, R> = InvariantReadBinding & {
50
+ readonly binding: B;
51
+ readonly [READ_SNAPSHOT]?: R;
52
+ };
53
+ type ReadRow<A> = A extends AggregateHandle<string, infer F> ? ReadModelRow<F> : Record<string, unknown>;
54
+ type ReadBuilder<B extends string, R> = {
55
+ at(id: string): TypedReadBinding<B, R>;
56
+ fromPayload(path: string | readonly string[], options?: { readonly prefix?: string; readonly suffix?: string }): TypedReadBinding<B, R>;
57
+ fromOptionalPayload(path: string | readonly string[], options?: { readonly prefix?: string; readonly suffix?: string }): TypedReadBinding<B, R | undefined>;
58
+ fromTemplate(parts: readonly InvariantReadIdPart[], options?: { readonly optional?: boolean }): TypedReadBinding<B, R | undefined>;
59
+ forEach(path: string | readonly string[], parts: readonly InvariantReadIdPart[], options?: { readonly optional?: boolean }): TypedReadBinding<`${B}${number}`, R | undefined>;
60
+ pre(): ReadBuilder<B, R>;
61
+ post(): ReadBuilder<B, R>;
62
+ };
63
+ type ReadSnapshots<B extends readonly InvariantReadBinding[]> = {
64
+ [R in B[number] as R["binding"]]: R extends TypedReadBinding<string, infer V> ? V : Record<string, unknown>;
65
+ };
66
+ declare const READ_SET_SNAPSHOTS: unique symbol;
67
+ type TypedReadSet<S> = WorkspaceInvariantReads & { readonly [READ_SET_SNAPSHOTS]?: S };
68
+ type SnapshotsOf<R> = typeof READ_SET_SNAPSHOTS extends keyof R
69
+ ? R extends TypedReadSet<infer S> ? S : never
70
+ : Record<string, Record<string, unknown>>;
71
+
42
72
 
43
73
  /**
44
74
  * One DECLARED read: the aggregate TYPE (qualified `domain.Aggregate`) + the concrete instance
@@ -120,22 +150,10 @@ function aggregateName(aggregate: { readonly id: string } | string): string {
120
150
 
121
151
  /** Begin one typed, bounded aggregate read. Prefer an aggregate handle; strings remain available
122
152
  * 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
- } {
153
+ export function readRef<const B extends string, A extends { readonly id: string } | string>(
154
+ binding: B,
155
+ aggregate: A,
156
+ ): ReadBuilder<B, ReadRow<A>> {
139
157
  const build = (state: "pre" | "post") => ({
140
158
  at(id: string): InvariantReadBinding {
141
159
  return { binding, aggregate: aggregateName(aggregate), state, id: { source: "literal", value: id } };
@@ -189,7 +207,7 @@ export function readRef(
189
207
  pre: () => build("pre"),
190
208
  post: () => build("post"),
191
209
  });
192
- return build("post");
210
+ return build("post") as ReadBuilder<B, ReadRow<A>>;
193
211
  }
194
212
 
195
213
  function valueAtPath(value: unknown, path: readonly string[]): unknown {
@@ -247,7 +265,7 @@ export function resolveInvariantReadId(
247
265
 
248
266
  /** Declare a bounded set of generic point reads. The returned callable keeps authoring-time tests
249
267
  * ergonomic, while the non-enumerable metadata is what the compiler lowers into USDA. */
250
- export function readSet(...bindings: readonly InvariantReadBinding[]): WorkspaceInvariantReads {
268
+ export function readSet<const B extends readonly InvariantReadBinding[]>(...bindings: B): TypedReadSet<ReadSnapshots<B>> {
251
269
  const selector = ((ctx: { intent: Record<string, unknown> }) => {
252
270
  const refs: InvariantRef[] = [];
253
271
  for (const binding of bindings) {
@@ -379,7 +397,9 @@ export interface WorkspaceInvariantDecl {
379
397
  /** Typed generic read recipes lowered into USDA. Absent only for not-yet-migrated callbacks. */
380
398
  readonly __nomosReadBindings?: readonly InvariantReadBinding[];
381
399
  /** The executable predicate — ships in the engine bundle, NOT the manifest. */
382
- readonly assert: WorkspaceInvariantAssert;
400
+ readonly assert: (...args: Parameters<WorkspaceInvariantAssert>) => WorkspaceInvariantVerdict<unknown>;
401
+ /** Authenticated nominal output contract; absent preserves the legacy string gate. */
402
+ readonly refusal?: ValueObject<unknown>;
383
403
  /**
384
404
  * THE DECLASSIFY WAIVER (nomosFlowGate rule 4 — architecture/security_model.md): present iff
385
405
  * the author acknowledged that this invariant's refusal MAY correlate with a secret it reads
@@ -390,7 +410,7 @@ export interface WorkspaceInvariantDecl {
390
410
  readonly declassify?: string;
391
411
  /** Framework-owned evaluator whose complete semantics are part of the named kernel ABI.
392
412
  * 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";
413
+ readonly __nomosEvaluator?: "birth-quota-v1" | "founder-signer-write-once-v1" | "founder-signer-write-once-v2" | "point-guard-v1";
394
414
  /** Typed point-state law consumed directly by the kernel when evaluator is `point-guard-v1`. */
395
415
  readonly __nomosPointGuard?: PointGuardSpec;
396
416
  /** Framework-only provenance used to keep compiler errors on the tenant-authored surface. */
@@ -404,45 +424,46 @@ export interface WorkspaceInvariantDecl {
404
424
  * The staged builder makes every step REQUIRED at the type level — you cannot register a
405
425
  * half-declared invariant (no `.on`, no `.reads`, or no `.assert`).
406
426
  */
427
+ type InvariantContext<I> = Omit<NonNullable<Parameters<WorkspaceInvariantAssert>[1]>, "intent"> & { intent: I };
428
+ type TypedAssert<I, S, R> = (snapshots: S, ctx: InvariantContext<I>) => WorkspaceInvariantVerdict<R>;
429
+ interface InvariantAssertions<I, S, R = string> {
430
+ assert(predicate: TypedAssert<I, S, R>): WorkspaceInvariantDecl;
431
+ declassify(reason: string): InvariantAssertions<I, S, R>;
432
+ }
433
+ interface InvariantReadsBuilder<I, S> extends InvariantAssertions<I, S> {
434
+ refuses<const N extends string, V>(refusal: ValueObject<V> & { readonly name: N }):
435
+ InvariantAssertions<I, S, NominalCase<N, V>>;
436
+ }
437
+
407
438
  export function workspaceInvariant(id: string): {
408
- on(directiveId: string): {
409
- reads(reads: WorkspaceInvariantReads): {
410
- assert(assert: WorkspaceInvariantAssert): WorkspaceInvariantDecl;
411
- /** Acknowledge an intended secret-correlated refusal (nomosFlowGate rule 4). The reason
412
- * rides the `nomosFlowGate` era key; then chain `.assert(...)` as usual. */
413
- declassify(reason: string): { assert(assert: WorkspaceInvariantAssert): WorkspaceInvariantDecl };
414
- };
415
- };
439
+ on<I>(directive: Directive<I>): { reads<R extends WorkspaceInvariantReads>(reads: R): InvariantReadsBuilder<I, SnapshotsOf<R>> };
440
+ on(directive: string): { reads<R extends WorkspaceInvariantReads>(reads: R): InvariantReadsBuilder<Record<string, unknown>, SnapshotsOf<R>> };
416
441
  } {
417
- const finish = (directiveId: string, reads: WorkspaceInvariantReads, declassify: string | undefined) => ({
418
- assert(assert: WorkspaceInvariantAssert): WorkspaceInvariantDecl {
442
+ const finish = (directiveId: string, reads: WorkspaceInvariantReads, declassify?: string, refusal?: ValueObject<unknown>) => ({
443
+ assert(predicate: WorkspaceInvariantDecl["assert"]): WorkspaceInvariantDecl {
419
444
  const readBindings = nativeReadBindings(reads);
420
445
  return {
421
- id,
422
- on: directiveId,
423
- reads,
446
+ id, on: directiveId, reads,
424
447
  ...(readBindings === undefined ? {} : { __nomosReadBindings: readBindings }),
425
- assert,
426
- ...(declassify !== undefined ? { declassify } : {}),
427
- __isWorkspaceInvariant: true as const,
448
+ assert: predicate,
449
+ ...(refusal === undefined ? {} : { refusal }),
450
+ ...(declassify === undefined ? {} : { declassify }),
451
+ __isWorkspaceInvariant: true,
428
452
  };
429
453
  },
454
+ declassify(reason: string) {
455
+ if (!reason.trim()) throw new Error(`workspaceInvariant('${id}').declassify needs a non-empty reason`);
456
+ return finish(directiveId, reads, reason, refusal);
457
+ },
458
+ refuses(contract: ValueObject<unknown>) {
459
+ return finish(directiveId, reads, declassify, contract);
460
+ },
430
461
  });
462
+ // One erased implementation boundary backs the typed authoring stages. Runtime
463
+ // admission rechecks the law contract; no generic values leak into predicates.
431
464
  return {
432
- on(directiveId: string) {
433
- return {
434
- reads(reads: WorkspaceInvariantReads) {
435
- return {
436
- assert: finish(directiveId, reads, undefined).assert,
437
- declassify(reason: string) {
438
- if (typeof reason !== "string" || reason.trim().length === 0) {
439
- throw new Error(`workspaceInvariant('${id}').declassify(reason) needs a non-empty human reason — it is the audit record for an intended secret-correlated refusal.`);
440
- }
441
- return finish(directiveId, reads, reason);
442
- },
443
- };
444
- },
445
- };
465
+ on(directive: string | Directive<any>) {
466
+ return { reads: (reads: WorkspaceInvariantReads) => finish(typeof directive === "string" ? directive : directive.id, reads) };
446
467
  },
447
- };
468
+ } as ReturnType<typeof workspaceInvariant>;
448
469
  }