@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.
- package/assets/operation-contract.wasm +0 -0
- package/check_package.mjs +12 -15
- package/compile_package.mjs +17 -18
- package/compile_proof.mjs +16 -1
- package/dart/CHANGELOG.md +80 -1
- package/dart/README.md +25 -2
- package/dart/lib/src/admission_decision.dart +41 -0
- package/dart/lib/src/application_framework_calls.dart +52 -2
- package/dart/lib/src/application_model_adoption.dart +187 -0
- package/dart/lib/src/application_status.dart +73 -0
- package/dart/lib/src/console_enrolment.dart +271 -0
- package/dart/lib/src/console_http_io.dart +26 -0
- package/dart/lib/src/console_http_stub.dart +7 -0
- package/dart/lib/src/dev_cloud.dart +69 -22
- package/dart/lib/src/generated_call.dart +83 -23
- package/dart/lib/src/kernel_primitives.dart +119 -0
- package/dart/lib/src/nms_conformance_runtime.dart +1 -1
- package/dart/lib/src/nms_generated_runtime.dart +32 -10
- package/dart/lib/src/nms_test_environment.dart +1 -1
- package/dart/lib/src/node_runner_transport.dart +41 -46
- package/dart/lib/src/observed_session_directory.dart +70 -0
- package/dart/lib/src/operation_receipts.dart +112 -0
- package/dart/lib/src/peer_application_streams.dart +103 -0
- package/dart/lib/src/reception/dart_reception.dart +4280 -0
- package/dart/lib/src/reception/event_desk.dart +214 -0
- package/dart/lib/src/reception/extremum_read.dart +46 -0
- package/dart/lib/src/reception/local_copies.dart +371 -0
- package/dart/lib/src/reception/peer_office_connection.dart +11 -0
- package/dart/lib/src/reception/progress_desk.dart +268 -0
- package/dart/lib/src/reception/reception_contract.dart +11 -0
- package/dart/lib/src/reception/reception_session.dart +284 -0
- package/dart/lib/src/reception/sync_diagnostics.dart +26 -0
- package/dart/lib/src/reception/workspace_preparation_report.dart +126 -0
- package/dart/lib/src/replica_readiness.dart +123 -0
- package/dart/lib/src/runner/node-entry.mjs +23950 -15776
- package/dart/lib/src/runtime_v2_gateway.dart +56 -3
- package/dart/lib/src/runtime_v2_transport.dart +544 -3
- package/dart/lib/src/session_bound.dart +200 -311
- package/dart/lib/src/signing_identity_kernel.dart +84 -0
- package/dart/lib/src/sync_status_projection.dart +550 -0
- package/dart/lib/src/sync_status_reducer.dart +170 -0
- package/dart/lib/src/test_harness.dart +809 -1153
- package/dart/lib/src/testing/test_custody.dart +66 -0
- package/dart/lib/src/testing/test_peer.dart +328 -0
- package/dart/lib/src/typed_watch_registry.dart +169 -0
- package/dart/lib/src/workspace_open_progress.dart +27 -0
- package/dart/pubspec.lock +24 -1
- package/dart/pubspec.yaml +7 -2
- package/dart/pubspec_overrides.yaml +2 -0
- package/dart/test/admission_decision_test.dart +48 -0
- package/dart/test/background_model_adoption_test.dart +228 -0
- package/dart/test/bundle_version_pairing_test.dart +4 -4
- package/dart/test/child_authentication_repair_test.dart +359 -0
- package/dart/test/cloud_bound_local_shell_test.dart +119 -0
- package/dart/test/console_enrolment_refusal_test.dart +52 -0
- package/dart/test/console_enrolment_test.dart +227 -0
- package/dart/test/errors_test.dart +5 -5
- package/dart/test/event_plane_seam_test.dart +50 -164
- package/dart/test/extremum_read_test.dart +58 -0
- package/dart/test/fixtures/wedge/wedge-entry.mjs +3 -21
- package/dart/test/generated_query_test.dart +32 -0
- package/dart/test/harness_phase_timeout_test.dart +18 -23
- package/dart/test/kernel_author_after_read_test.dart +242 -0
- package/dart/test/kernel_fence_test.dart +137 -0
- package/dart/test/local_copies_test.dart +222 -0
- package/dart/test/model_adoption_test.dart +198 -0
- package/dart/test/node_peer_local_custody_test.dart +153 -0
- package/dart/test/offer_authentication_proof_test.dart +352 -52
- package/dart/test/operation_compatibility_test.dart +151 -0
- package/dart/test/platform_credential_effect_test.dart +386 -0
- package/dart/test/receiving_group_open_test.dart +213 -0
- package/dart/test/reception/workspace_preparation_report_test.dart +103 -0
- package/dart/test/reception_event_desk_close_test.dart +16 -0
- package/dart/test/reception_span_trace_test.dart +23 -0
- package/dart/test/replica_readiness_test.dart +156 -0
- package/dart/test/runtime_projections_test.dart +92 -0
- package/dart/test/runtime_v2_gateway_test.dart +131 -0
- package/dart/test/signing_identity_kernel_test.dart +75 -0
- package/dart/test/sync_status_preparation_report_test.dart +29 -0
- package/dart/test/sync_status_reducer_test.dart +419 -0
- package/dart/test/test_harness_test.dart +71 -95
- package/dart/test/typed_query_watch_test.dart +170 -0
- package/dart/test/typed_watch_registry_test.dart +249 -0
- package/dart_lints/README.md +18 -0
- package/dart_lints/lib/nomos_lints.dart +70 -0
- package/dart_lints/pubspec.lock +580 -0
- package/dart_lints/pubspec.yaml +12 -0
- package/dart_lints/test/reference_identity_test.dart +75 -0
- package/dart_types/CHANGELOG.md +18 -0
- package/dart_types/lib/nomos_kernel_protocol.dart +21 -1
- package/dart_types/lib/nomos_types.dart +9 -1
- package/dart_types/lib/src/admission_decision.dart +37 -0
- package/dart_types/lib/src/aggregate_meta.dart +1 -1
- package/dart_types/lib/src/approved_model.dart +65 -0
- package/dart_types/lib/src/custody.dart +10 -18
- package/dart_types/lib/src/error_info.dart +4 -4
- package/dart_types/lib/src/errors.dart +29 -29
- package/dart_types/lib/src/foreign_ref.dart +62 -33
- package/dart_types/lib/src/local_work_rejected.dart +3 -3
- package/dart_types/lib/src/nomos_ref.dart +3 -1
- package/dart_types/lib/src/principal.dart +2 -2
- package/dart_types/lib/src/proto/google/protobuf/any.pb.dart +163 -0
- package/dart_types/lib/src/proto/google/protobuf/any.pbenum.dart +11 -0
- package/dart_types/lib/src/proto/nomos/discovery/v1/workspace_placement.pb.dart +137 -0
- package/dart_types/lib/src/proto/nomos/discovery/v1/workspace_placement.pbenum.dart +11 -0
- package/dart_types/lib/src/proto/nomos/kernel/v1/kernel.pb.dart +20721 -10433
- package/dart_types/lib/src/proto/nomos/kernel/v1/kernel.pbenum.dart +555 -27
- package/dart_types/lib/src/proto/nomos/runtime/v2/application_desk.pb.dart +387 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/application_desk.pbenum.dart +46 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/application_readiness_desk.pb.dart +295 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/application_readiness_desk.pbenum.dart +139 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/authentication_desk.pb.dart +269 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/authentication_desk.pbenum.dart +103 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/compatibility_desk.pb.dart +417 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/compatibility_desk.pbenum.dart +62 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/correspondence_desk.pb.dart +9968 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/correspondence_desk.pbenum.dart +133 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/credentials_desk.pb.dart +204 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/credentials_desk.pbenum.dart +54 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/custody_desk.pb.dart +1550 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/custody_desk.pbenum.dart +11 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/framework.pb.dart +710 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/framework.pbenum.dart +11 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/identity_desk.pb.dart +845 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/identity_desk.pbenum.dart +11 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/interaction_desk.pb.dart +198 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/interaction_desk.pbenum.dart +11 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/law_desk.pb.dart +369 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/law_desk.pbenum.dart +11 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/maintenance_desk.pb.dart +609 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/maintenance_desk.pbenum.dart +65 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/model_adoption_desk.pb.dart +358 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/model_adoption_desk.pbenum.dart +100 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/observability_desk.pb.dart +2231 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/observability_desk.pbenum.dart +271 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/placement_desk.pb.dart +1286 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/placement_desk.pbenum.dart +11 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/receiving_group_desk.pb.dart +636 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/receiving_group_desk.pbenum.dart +116 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/records_desk.pb.dart +1637 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/records_desk.pbenum.dart +175 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/recovery_desk.pb.dart +1269 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/recovery_desk.pbenum.dart +129 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/residency_desk.pb.dart +2782 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/residency_desk.pbenum.dart +97 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/runtime.pb.dart +2232 -8627
- package/dart_types/lib/src/proto/nomos/runtime/v2/runtime.pbenum.dart +0 -358
- package/dart_types/lib/src/proto/nomos/runtime/v2/sealing_desk.pb.dart +1639 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/sealing_desk.pbenum.dart +46 -0
- package/dart_types/lib/src/runtime_outcome.dart +133 -0
- package/dart_types/lib/src/subscriptions.dart +116 -23
- package/dart_types/pubspec.yaml +1 -1
- package/dart_types/test/extremum_subscriptions_test.dart +40 -0
- package/dart_types/test/foreign_ref_resolution_test.dart +75 -0
- package/dart_types/test/nomos_ref_address_test.dart +25 -0
- package/dart_types/test/ordered_subscriptions_test.dart +34 -0
- package/operation_contract_check.mjs +24 -0
- package/package.json +11 -6
- package/src/aggregate.ts +70 -10
- package/src/application_topology.ts +18 -11
- package/src/attested.ts +3 -0
- package/src/attested_core.ts +46 -3
- package/src/birth_meter_ensure.ts +19 -7
- package/src/births.ts +29 -4
- package/src/build_package.ts +140 -13
- package/src/business_birth.ts +181 -4
- package/src/codegen_call_proto.ts +1276 -0
- package/src/codegen_call_usda.ts +49 -6
- package/src/codegen_dart.ts +83 -44
- package/src/codegen_dart_client.ts +458 -800
- package/src/{codegen_dart_application.ts → codegen_dart_facade.ts} +331 -582
- package/src/codegen_dart_framework_calls.ts +320 -37
- package/src/codegen_dart_indexed_variant.ts +159 -0
- package/src/codegen_dart_scenario.ts +42 -13
- package/src/codegen_proof.ts +3 -3
- package/src/codegen_provider_dart.ts +5 -0
- package/src/codegen_query_proto.ts +158 -0
- package/src/codegen_refusal.ts +189 -0
- package/src/codegen_result_proto.ts +931 -0
- package/src/codegen_result_usda.ts +4 -0
- package/src/codegen_ts.ts +464 -616
- package/src/codegen_workspace_access.ts +105 -0
- package/src/compatibility_graph.ts +759 -0
- package/src/compatibility_usda.ts +264 -0
- package/src/compile_package_main.ts +2017 -1195
- package/src/custody_placement.ts +156 -0
- package/src/custody_placement_usda.ts +91 -0
- package/src/decl_shapes.ts +21 -2
- package/src/describe_model.ts +1 -0
- package/src/directive.ts +59 -2
- package/src/drivers.ts +51 -0
- package/src/engine_entry.ts +52 -8
- package/src/evolve_preview.ts +11 -4
- package/src/exists.ts +2 -0
- package/src/fields.ts +75 -11
- package/src/flow_gate.ts +2 -1
- package/src/framework/application_home.ts +170 -18
- package/src/framework/attested_receipts.ts +8 -3
- package/src/framework/auth_provider_law.ts +169 -9
- package/src/framework/birth_certificate_law.ts +4 -0
- package/src/framework/capability.ts +34 -3
- package/src/framework/child_authentication.ts +346 -0
- package/src/framework/console_governance.ts +295 -0
- package/src/framework/delegated_roles.ts +301 -0
- package/src/framework/domain_lifecycle.ts +26 -13
- package/src/framework/founding_genesis.ts +193 -0
- package/src/framework/framework_aggregates.ts +1 -1
- package/src/framework/genesis.ts +6 -1
- package/src/framework/governance_relations.ts +19 -0
- package/src/framework/home.ts +5 -734
- package/src/framework/legacy/child_auth_provider_epoch.ts +73 -0
- package/src/framework/model_authority_repair.ts +116 -0
- package/src/framework/model_authority_seed.ts +185 -0
- package/src/framework/model_transition.ts +211 -0
- package/src/framework/owned_custody.ts +1 -1
- package/src/framework/principal_enrollment.ts +302 -0
- package/src/framework/receiving_group.ts +857 -0
- package/src/framework/receiving_group_recovery.ts +314 -0
- package/src/framework/relations.ts +4 -8
- package/src/framework/signing_identity.ts +242 -95
- package/src/framework/source_roster.ts +11 -5
- package/src/framework/workspace_access.ts +149 -0
- package/src/framework/workspace_invariant.ts +73 -52
- package/src/framework/workspaces.ts +407 -40
- package/src/framework_call_definitions.ts +32 -3
- package/src/generated_client_bundle_boundary.ts +97 -0
- package/src/generated_client_names.ts +1 -0
- package/src/identity_usda.ts +27 -0
- package/src/index.ts +183 -12
- package/src/indexed_variant.ts +83 -0
- package/src/intent.ts +173 -45
- package/src/law_check.ts +8 -5
- package/src/law_dependency_index.ts +231 -0
- package/src/law_graph.ts +508 -71
- package/src/law_graph_usda.ts +170 -24
- package/src/law_identity.ts +119 -81
- package/src/law_source_map.ts +4 -1
- package/src/law_units.ts +498 -0
- package/src/law_value_type.ts +7 -3
- package/src/member_authentication.ts +302 -0
- package/src/null_meta.ts +1 -1
- package/src/openusd_compiled_layer.ts +132 -0
- package/src/operation_contract_check.ts +31 -0
- package/src/ordered_read.ts +2 -1
- package/src/package_config.ts +33 -12
- package/src/package_dependencies.ts +1 -0
- package/src/plan_source_slice.ts +30 -1
- package/src/protobuf_field_number.ts +36 -0
- package/src/provenance_wire.ts +6 -0
- package/src/query.ts +2 -1
- package/src/read.ts +50 -0
- package/src/relation.ts +4 -1
- package/src/relation_schema.ts +15 -2
- package/src/report.ts +2 -2
- package/src/sqlite_computation_bundle.ts +78 -0
- package/src/sqlite_computed.ts +102 -0
- package/src/sqlite_counts.ts +154 -0
- package/src/sqlite_layout.ts +823 -0
- package/src/sqlite_reads.ts +275 -0
- package/src/sqlite_samples.ts +185 -0
- package/src/stable_id_identity_bridge.ts +1 -1
- package/src/stable_ids_for_module.ts +16 -4
- package/src/test_call_usda.ts +6 -6
- package/src/usda_relationship_integrity.ts +20 -3
- package/src/usda_text.ts +21 -1
- package/src/value_object.ts +81 -11
- package/src/wire.ts +22 -0
- package/src/wire_encode.ts +227 -20
- package/src/workspace_sharding.ts +15 -6
- package/src/workspace_sharing.ts +51 -49
- package/src/zod_introspection.ts +2 -0
- package/compat_package.mjs +0 -46
- package/dart/lib/src/home.dart +0 -15
- package/dart/lib/src/runner/offline-install.mjs +0 -15367
- package/dart/lib/src/source_trust.dart +0 -51
- package/dart/lib/src/webview_bridge.dart +0 -6540
- package/dart/lib/src/workspace_name.dart +0 -30
- package/dart/test/acquire_session_credentials_test.dart +0 -150
- package/dart/test/acquire_session_test.dart +0 -534
- package/dart/test/adv_realm_interference_test.dart +0 -600
- package/dart/test/cloud_bound_topology_test.dart +0 -168
- package/dart/test/cluster_births_test.dart +0 -202
- package/dart/test/cluster_device_keyed_acceptance_test.dart +0 -105
- package/dart/test/cluster_local_autosync_test.dart +0 -123
- package/dart/test/cluster_scale_test.dart +0 -122
- package/dart/test/compat_test.dart +0 -61
- package/dart/test/dlq_session_surface_test.dart +0 -222
- package/dart/test/first_app_gauntlet_test.dart +0 -386
- package/dart/test/fixtures/wedge/fake-install.mjs +0 -11
- package/dart/test/four_layer_nested_topology_test.dart +0 -290
- package/dart/test/home_parity_test.dart +0 -13
- package/dart/test/local_sync_inert_test.dart +0 -107
- package/dart/test/node_runner_transport_test.dart +0 -78
- package/dart/test/parent_signer_recovery_test.dart +0 -155
- package/dart/test/residency_refusal_test.dart +0 -49
- package/dart/test/sealing_client_test.dart +0 -181
- package/dart/test/session_bound_test.dart +0 -285
- package/dart/test/stale_bundle_test.dart +0 -80
- package/dart/test/vo_read_typing_test.dart +0 -131
- package/dart/test/watch_after_offer_stall_test.dart +0 -100
- package/dart/test/webview_bridge_test.dart +0 -1930
- package/dart/test/workspace_name_test.dart +0 -24
- package/runtime/generated-application-host.js +0 -22860
- package/src/codegen_query_usda.ts +0 -214
- package/src/compat_manifest.ts +0 -26
- package/src/compat_package_main.ts +0 -224
- package/src/shape_compat.ts +0 -352
- package/src/usd_state.ts +0 -505
package/src/codegen_ts.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { refusalContracts, tsRefusalDecoder, tsRefusalDecoders } from "./codegen_refusal.js";
|
|
1
2
|
// NOMOS — Nomos Sovereign: participants act · verify · remember LOCALLY; hosted
|
|
2
3
|
// remotes are replaceable custody/transport, not truth. ⇒ ONE Nomos GitHolon
|
|
3
4
|
// wasm32-wasip1 artifact {kernel · projection · embedded
|
|
@@ -9,7 +10,7 @@
|
|
|
9
10
|
* TS CLIENT CODEGEN (#10) — the WEB sibling of `codegen_dart.ts`.
|
|
10
11
|
*
|
|
11
12
|
* Dart apps get generated payload classes / read models / typed query accessors;
|
|
12
|
-
* until this file, a web app on `@githolon/
|
|
13
|
+
* until this file, a web app on `@githolon/runtime` hand-typed directive ids and
|
|
13
14
|
* payload shapes against framework transport primitives. `generateTsClient(modules,
|
|
14
15
|
* opts)` closes that: ONE generated `.ts` file per package, emitted by
|
|
15
16
|
* `nomos-compile` AFTER the package is hashed (the deployed law's content hash is
|
|
@@ -29,12 +30,13 @@
|
|
|
29
30
|
* * a CLIENT FACTORY per domain — typed `offer` wrappers bound to the baked
|
|
30
31
|
* domainHash, typed declared-query accessors, and by-id read/watch helpers —
|
|
31
32
|
* over a STRUCTURAL `NomosHolon` interface, so the file has ZERO imports and
|
|
32
|
-
* binds to `@githolon/
|
|
33
|
+
* binds to `@githolon/runtime`'s `connect()` result (browser or node) as-is.
|
|
33
34
|
*
|
|
34
35
|
* Like every emitter here: NO FALLBACK. An unsupported zod shape throws at compile
|
|
35
36
|
* time, never degrades to `any` silently.
|
|
36
37
|
*/
|
|
37
38
|
import type { z } from "zod";
|
|
39
|
+
import { generateTsWorkspaceAccessRead } from "./codegen_workspace_access.js";
|
|
38
40
|
|
|
39
41
|
import {
|
|
40
42
|
BUSINESS_BIRTH_SEED_PAYLOAD_FIELD,
|
|
@@ -75,10 +77,12 @@ import {
|
|
|
75
77
|
collectActivityDescriptors,
|
|
76
78
|
type PackageActivityEntry,
|
|
77
79
|
} from "./codegen_dart.js";
|
|
78
|
-
import
|
|
80
|
+
import { emitApplicationCompatibilityUsda } from "./compatibility_usda.js";
|
|
81
|
+
import type { OsgiContractRequirement } from "./kernel_capabilities.js";
|
|
79
82
|
import type { QueryDecl } from "./query.js";
|
|
80
83
|
import {
|
|
81
84
|
collectPayloadValueObjectDescriptors,
|
|
85
|
+
collectSchemaValueObjectDescriptors,
|
|
82
86
|
collectValueObjectDescriptors,
|
|
83
87
|
idOfMetaOf,
|
|
84
88
|
idOfTargetKindOf,
|
|
@@ -89,6 +93,8 @@ import {
|
|
|
89
93
|
import { recursiveTypeBaseName, zodUnwrapLazy } from "./zod_lazy.js";
|
|
90
94
|
import { finishCount } from "./count.js";
|
|
91
95
|
import { finishSum } from "./sum.js";
|
|
96
|
+
import { finishExtremum } from "./extremum.js";
|
|
97
|
+
import { finishExists } from "./exists.js";
|
|
92
98
|
import type { AnyDerivedDecl } from "./derived.js";
|
|
93
99
|
import type { CombinedDecl } from "./combined.js";
|
|
94
100
|
import {
|
|
@@ -107,7 +113,7 @@ import {
|
|
|
107
113
|
isNamespacedAggregate,
|
|
108
114
|
qualifyReadProjectionType,
|
|
109
115
|
} from "./read_projection_namespace.js";
|
|
110
|
-
import { publicClientInterface, type DomainInterface } from "./
|
|
116
|
+
import { publicClientInterface, type DomainInterface } from "./compatibility_graph.js";
|
|
111
117
|
import {
|
|
112
118
|
buildNomosDescribeModel,
|
|
113
119
|
type NomosDescribeModel,
|
|
@@ -125,7 +131,7 @@ import {
|
|
|
125
131
|
import { contractTypeName } from "./contract.js";
|
|
126
132
|
import { resolveApplicationTopology } from "./application_topology.js";
|
|
127
133
|
import { recipientMetaOf } from "./recipient.js";
|
|
128
|
-
import type { LawGraph } from "./law_graph.js";
|
|
134
|
+
import type { LawGraph, LawRowReadNode } from "./law_graph.js";
|
|
129
135
|
import {
|
|
130
136
|
zodArrayElement,
|
|
131
137
|
zodDef,
|
|
@@ -134,10 +140,12 @@ import {
|
|
|
134
140
|
zodObjectShape,
|
|
135
141
|
} from "./zod_introspection.js";
|
|
136
142
|
import {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
143
|
+
emitTsCallProtoEncoder,
|
|
144
|
+
publishingIntentOf,
|
|
145
|
+
TS_CALL_PROTO_PRELUDE,
|
|
146
|
+
type TsCallProtoFieldAccess,
|
|
147
|
+
} from "./codegen_call_proto.js";
|
|
148
|
+
import { TS_QUERY_USDA_PRELUDE } from "./codegen_call_usda.js";
|
|
141
149
|
import {
|
|
142
150
|
emitTsResultDecoder,
|
|
143
151
|
emitTsValueObjectDecoders,
|
|
@@ -146,9 +154,13 @@ import {
|
|
|
146
154
|
type TsResultAggregate,
|
|
147
155
|
} from "./codegen_result_usda.js";
|
|
148
156
|
import {
|
|
149
|
-
|
|
157
|
+
emitTsQueryProtoEncoder,
|
|
150
158
|
type QueryScalarKind,
|
|
151
|
-
} from "./
|
|
159
|
+
} from "./codegen_query_proto.js";
|
|
160
|
+
import {
|
|
161
|
+
emitTsQueryResultProtoDecoder,
|
|
162
|
+
TS_RESULT_PROTO_PRELUDE,
|
|
163
|
+
} from "./codegen_result_proto.js";
|
|
152
164
|
|
|
153
165
|
const cap = (s: string) => (s.length ? s[0]!.toUpperCase() + s.slice(1) : s);
|
|
154
166
|
const camel = (s: string) =>
|
|
@@ -220,11 +232,7 @@ export const tsHashConstName = (packageName: string): string =>
|
|
|
220
232
|
|
|
221
233
|
/** `tool-library` → `TOOL_LIBRARY_INTERFACE` — the baked structural-interface const (#72). */
|
|
222
234
|
export const interfaceConstName = (packageName: string): string =>
|
|
223
|
-
`${upperSnake(packageName)}
|
|
224
|
-
|
|
225
|
-
/** `tool-library` → `TOOL_LIBRARY_COMPAT` — the baked client/law compat manifest (§5). */
|
|
226
|
-
export const compatConstName = (packageName: string): string =>
|
|
227
|
-
`${upperSnake(packageName)}_COMPAT`;
|
|
235
|
+
`${upperSnake(packageName)}_COMPATIBILITY_MATRIX_USDA`;
|
|
228
236
|
|
|
229
237
|
/** `tool-library` → `TOOL_LIBRARY_ENCRYPTION` — the baked E2E-sealing map (the sealing client). */
|
|
230
238
|
export const encryptionConstName = (packageName: string): string =>
|
|
@@ -257,7 +265,7 @@ export interface EncDomainMap {
|
|
|
257
265
|
>;
|
|
258
266
|
}
|
|
259
267
|
|
|
260
|
-
/** The sid-keyed read shape of ONE domain's interface (mirrors `
|
|
268
|
+
/** The sid-keyed read shape of ONE domain's interface (mirrors `compatibility_graph.ts` DomainInterface). */
|
|
261
269
|
export interface InterfaceAggShape {
|
|
262
270
|
readonly sid: string;
|
|
263
271
|
readonly label: string;
|
|
@@ -775,8 +783,8 @@ function payloadReferenceTypes(schema: z.ZodTypeAny): Set<string> {
|
|
|
775
783
|
* graph fields that are not authored by this directive are compile-time omitted. */
|
|
776
784
|
function operatorCallFieldAccess(
|
|
777
785
|
schema?: z.ZodTypeAny
|
|
778
|
-
): ReadonlyMap<string,
|
|
779
|
-
const access = new Map<string,
|
|
786
|
+
): ReadonlyMap<string, TsCallProtoFieldAccess> {
|
|
787
|
+
const access = new Map<string, TsCallProtoFieldAccess>();
|
|
780
788
|
const shape =
|
|
781
789
|
schema !== undefined && zodKind(schema) === "object"
|
|
782
790
|
? zodObjectShape(schema)
|
|
@@ -796,6 +804,10 @@ function operatorCallFieldAccess(
|
|
|
796
804
|
const idTarget = idOfMetaOf(fieldSchema);
|
|
797
805
|
if (idTarget !== undefined) {
|
|
798
806
|
const expected = JSON.stringify(idTarget);
|
|
807
|
+
// A contract is implemented by its owning domain, potentially in another
|
|
808
|
+
// workspace. It is not a concrete local-aggregate relationship.
|
|
809
|
+
const referenceWorkspace = idOfTargetKindOf(fieldSchema) === "contract"
|
|
810
|
+
? '\"\"' : "nmsInternalWorkspace";
|
|
799
811
|
const explicitOptionalChoice =
|
|
800
812
|
idOfMetaOf(rawSchema) !== undefined &&
|
|
801
813
|
["optional", "default"].includes(zodKind(rawSchema));
|
|
@@ -803,18 +815,20 @@ function operatorCallFieldAccess(
|
|
|
803
815
|
field,
|
|
804
816
|
explicitOptionalChoice
|
|
805
817
|
? {
|
|
806
|
-
value: `_nmsOptionalReferenceId(${member}, ${expected},
|
|
818
|
+
value: `_nmsOptionalReferenceId(${member}, ${expected}, ${referenceWorkspace}, ${JSON.stringify(
|
|
807
819
|
field
|
|
808
820
|
)})!`,
|
|
809
|
-
present: `_nmsOptionalReferenceId(${member}, ${expected},
|
|
821
|
+
present: `_nmsOptionalReferenceId(${member}, ${expected}, ${referenceWorkspace}, ${JSON.stringify(
|
|
810
822
|
field
|
|
811
823
|
)}) !== undefined`,
|
|
824
|
+
canonical: true,
|
|
812
825
|
}
|
|
813
826
|
: {
|
|
814
|
-
value: `_nmsReferenceId(${value}, ${expected},
|
|
827
|
+
value: `_nmsReferenceId(${value}, ${expected}, ${referenceWorkspace}, ${JSON.stringify(
|
|
815
828
|
field
|
|
816
829
|
)})`,
|
|
817
830
|
...common,
|
|
831
|
+
canonical: true,
|
|
818
832
|
}
|
|
819
833
|
);
|
|
820
834
|
} else if (refOfMetaOf(fieldSchema) !== undefined) {
|
|
@@ -824,11 +838,13 @@ function operatorCallFieldAccess(
|
|
|
824
838
|
refTarget.aggregateType
|
|
825
839
|
)}, "", ${JSON.stringify(field)})`,
|
|
826
840
|
...common,
|
|
841
|
+
canonical: true,
|
|
827
842
|
});
|
|
828
843
|
} else if (versionedRefOfMetaOf(fieldSchema) !== undefined) {
|
|
829
844
|
access.set(field, {
|
|
830
845
|
value: `({ pinned: _nmsReferenceData(${value}.pinned), series: _nmsReferenceData(${value}.series) })`,
|
|
831
846
|
...common,
|
|
847
|
+
canonical: true,
|
|
832
848
|
});
|
|
833
849
|
}
|
|
834
850
|
}
|
|
@@ -983,7 +999,8 @@ const geometryFactoryName: Record<string, string> = {
|
|
|
983
999
|
|
|
984
1000
|
/** One descriptor field → its TS type text. NO FALLBACK (the descriptor set is closed). */
|
|
985
1001
|
function tsTypeOfVoField(f: ValueObjectFieldDescriptor): string {
|
|
986
|
-
|
|
1002
|
+
const value = (() => {
|
|
1003
|
+
switch (f.type) {
|
|
987
1004
|
case "string":
|
|
988
1005
|
return f.idOf !== undefined
|
|
989
1006
|
? `NomosRef<${
|
|
@@ -1007,7 +1024,9 @@ function tsTypeOfVoField(f: ValueObjectFieldDescriptor): string {
|
|
|
1007
1024
|
case "object":
|
|
1008
1025
|
case "geometry":
|
|
1009
1026
|
return f.ref; // the named VO interface (emitted alongside)
|
|
1010
|
-
|
|
1027
|
+
}
|
|
1028
|
+
})();
|
|
1029
|
+
return f.nullable === true ? `${paren(value)} | null` : value;
|
|
1011
1030
|
}
|
|
1012
1031
|
|
|
1013
1032
|
/** Every branded-id name a VO descriptor carries (recursing arrays/maps/union arms) — one
|
|
@@ -1114,18 +1133,17 @@ export interface TsClientOptions {
|
|
|
1114
1133
|
/** Sibling lossless USDZ transport carried by the generated client when its signed-in workspace
|
|
1115
1134
|
* still serves the predecessor model. The archive is never canonical state and is not embedded. */
|
|
1116
1135
|
readonly lawAssetName?: string;
|
|
1117
|
-
/**
|
|
1118
|
-
*
|
|
1119
|
-
* shape-compatibility against the workspace's installed offer — NOT by hash. */
|
|
1136
|
+
/** Compiler graph used to generate the one USDA compatibility matrix. It is
|
|
1137
|
+
* never emitted as a second JavaScript object or interpreted by the client. */
|
|
1120
1138
|
readonly interface?: Record<string, unknown>;
|
|
1121
|
-
/**
|
|
1122
|
-
*
|
|
1123
|
-
readonly
|
|
1139
|
+
/** Standard OSGi Contract Namespace requirements for the kernel ABI. This is
|
|
1140
|
+
* separate from application/law shape compatibility, whose sole artifact is USDA. */
|
|
1141
|
+
readonly kernelContracts?: readonly OsgiContractRequirement[];
|
|
1124
1142
|
/** Explicit application home for direct/synthetic generation. The package compiler derives this from
|
|
1125
1143
|
* business birth topology and passes it here; ambiguous multi-domain packages fail rather than flatten. */
|
|
1126
1144
|
readonly homeDomain?: string;
|
|
1127
|
-
/**
|
|
1128
|
-
*
|
|
1145
|
+
/** Export the holon-level factories beside the application surface: the one TypeScript Reception the
|
|
1146
|
+
* compiler emits carries both (a code-mode or unattended peer binds the factories to any NomosHolon). */
|
|
1129
1147
|
readonly exportHolonFactory?: boolean;
|
|
1130
1148
|
/** Emit only the fixed framework operator call set (identity, lifecycle and birth). This is the
|
|
1131
1149
|
* small server/operator companion: exact generated USDA calls, no application/read runtime. */
|
|
@@ -1140,103 +1158,6 @@ export interface TsClientOptions {
|
|
|
1140
1158
|
|
|
1141
1159
|
type CallUsdaProjection = NonNullable<TsClientOptions["callUsda"]>;
|
|
1142
1160
|
|
|
1143
|
-
const OPERATOR_LIFECYCLE_CALLS = {
|
|
1144
|
-
installDomain,
|
|
1145
|
-
stageDomain,
|
|
1146
|
-
promoteDomain,
|
|
1147
|
-
rollbackDomain,
|
|
1148
|
-
} as const;
|
|
1149
|
-
|
|
1150
|
-
/** Emit the deliberately small operator-side call factory shipped beside one law
|
|
1151
|
-
* package. It contains no application runtime, storage, network or authority code:
|
|
1152
|
-
* only compiler-expanded canonical USDA encoders derived from the package's graph. */
|
|
1153
|
-
export function generateTsLifecycleOperator(
|
|
1154
|
-
callUsda: CallUsdaProjection
|
|
1155
|
-
): string | undefined {
|
|
1156
|
-
const encoders = Object.entries(OPERATOR_LIFECYCLE_CALLS).flatMap(
|
|
1157
|
-
([kind, directive]) =>
|
|
1158
|
-
callUsda.flatMap((law) => {
|
|
1159
|
-
const declares = law.graph.nodes.some(
|
|
1160
|
-
(node) =>
|
|
1161
|
-
node.kind === "intent" &&
|
|
1162
|
-
(node.entity.label === directive.id ||
|
|
1163
|
-
node.publicRoute === directive.id)
|
|
1164
|
-
);
|
|
1165
|
-
if (!declares) return [];
|
|
1166
|
-
const domain = law.graph.domain.entity.label;
|
|
1167
|
-
return [
|
|
1168
|
-
{
|
|
1169
|
-
kind,
|
|
1170
|
-
domain,
|
|
1171
|
-
payloadType: tsTypeOfPayload(
|
|
1172
|
-
directive.payloadSchema as z.ZodTypeAny,
|
|
1173
|
-
[]
|
|
1174
|
-
),
|
|
1175
|
-
encoder: emitTsCallUsdaEncoder(
|
|
1176
|
-
law.graph,
|
|
1177
|
-
law.paths,
|
|
1178
|
-
domain,
|
|
1179
|
-
directive.id,
|
|
1180
|
-
tsTypeOfPayload(directive.payloadSchema as z.ZodTypeAny, [])
|
|
1181
|
-
),
|
|
1182
|
-
},
|
|
1183
|
-
];
|
|
1184
|
-
})
|
|
1185
|
-
);
|
|
1186
|
-
if (encoders.length === 0) return undefined;
|
|
1187
|
-
const methods = Object.keys(OPERATOR_LIFECYCLE_CALLS).filter((kind) =>
|
|
1188
|
-
encoders.some((entry) => entry.kind === kind)
|
|
1189
|
-
);
|
|
1190
|
-
return [
|
|
1191
|
-
`// AUTO-GENERATED by nomos-compile — canonical operator calls for this exact law package.`,
|
|
1192
|
-
`// No application runtime and no authority live here. Do not edit.`,
|
|
1193
|
-
``,
|
|
1194
|
-
...TS_CALL_USDA_PRELUDE,
|
|
1195
|
-
`/** A SHA-256 digest in canonical Nomos wire form. */`,
|
|
1196
|
-
`export type Sha256Digest = string & { readonly __nomosSha256Digest: unique symbol };`,
|
|
1197
|
-
`export const sha256Digest = (value: string): Sha256Digest => {`,
|
|
1198
|
-
` if (!/^[0-9a-f]{64}$/.test(value)) throw new TypeError("expected a 64-character lowercase hexadecimal SHA-256 digest");`,
|
|
1199
|
-
` return value as Sha256Digest;`,
|
|
1200
|
-
`};`,
|
|
1201
|
-
`/** A Git object address in canonical gix custody form. */`,
|
|
1202
|
-
`export type GitObjectId = string & { readonly __nomosGitObjectId: unique symbol };`,
|
|
1203
|
-
`export const gitObjectId = (value: string): GitObjectId => {`,
|
|
1204
|
-
` if (!/^[0-9a-f]{40}$/.test(value)) throw new TypeError("expected a 40-character lowercase hexadecimal Git object id");`,
|
|
1205
|
-
` return value as GitObjectId;`,
|
|
1206
|
-
`};`,
|
|
1207
|
-
`export interface NomosOperatorCall<Domain extends string = string, Directive extends string = string> {`,
|
|
1208
|
-
` readonly domain: Domain;`,
|
|
1209
|
-
` readonly directive: Directive;`,
|
|
1210
|
-
` readonly canonicalUsda: Uint8Array;`,
|
|
1211
|
-
` readonly routingCandidates: readonly string[];`,
|
|
1212
|
-
`}`,
|
|
1213
|
-
``,
|
|
1214
|
-
...encoders.flatMap((entry) => entry.encoder.source),
|
|
1215
|
-
`export const nomosOperatorCalls = {`,
|
|
1216
|
-
...methods.flatMap((kind) => {
|
|
1217
|
-
const alternatives = encoders.filter((entry) => entry.kind === kind);
|
|
1218
|
-
const payloadType = alternatives[0]!.payloadType;
|
|
1219
|
-
return [
|
|
1220
|
-
` ${kind}(input: { readonly domain: string; readonly workspace: string } & ${payloadType}): NomosOperatorCall {`,
|
|
1221
|
-
` const { domain, workspace, ...payload } = input;`,
|
|
1222
|
-
` switch (domain) {`,
|
|
1223
|
-
...alternatives.map(
|
|
1224
|
-
(entry) =>
|
|
1225
|
-
` case ${JSON.stringify(entry.domain)}: return ${
|
|
1226
|
-
entry.encoder.functionName
|
|
1227
|
-
}(payload, workspace);`
|
|
1228
|
-
),
|
|
1229
|
-
` default: throw new Error("This law package has no '${kind}' call in domain '" + domain + "'.");`,
|
|
1230
|
-
` }`,
|
|
1231
|
-
` },`,
|
|
1232
|
-
];
|
|
1233
|
-
}),
|
|
1234
|
-
`} as const;`,
|
|
1235
|
-
``,
|
|
1236
|
-
].join("\n");
|
|
1237
|
-
}
|
|
1238
|
-
|
|
1239
|
-
/** TS string literal (JSON.stringify covers escaping). */
|
|
1240
1161
|
const _actLit = (s: string): string => JSON.stringify(s);
|
|
1241
1162
|
|
|
1242
1163
|
/** Emit the ACTIVITY + SELF-DESCRIPTION block (architecture/activity_descriptors.md): the `ActivityEvent`/`ActivityRef`/
|
|
@@ -1314,164 +1235,7 @@ function emitTsActivityBlock(
|
|
|
1314
1235
|
` },`,
|
|
1315
1236
|
];
|
|
1316
1237
|
};
|
|
1317
|
-
|
|
1318
|
-
`// ── model evolution — generated business surface over exact-history proof ──`,
|
|
1319
|
-
`interface NomosModelDifference {`,
|
|
1320
|
-
` kind: "rules" | "outcome" | "evidence"; area?: string; action?: string; summary: string;`,
|
|
1321
|
-
`}`,
|
|
1322
|
-
`interface NomosModelReview {`,
|
|
1323
|
-
` checkedActions: number; candidateActions: number; sameOutcome: boolean | null;`,
|
|
1324
|
-
` differences: NomosModelDifference[];`,
|
|
1325
|
-
`}`,
|
|
1326
|
-
`type NomosModelAdoption =`,
|
|
1327
|
-
` | { status: "adopted"; summary: string; review: NomosModelReview }`,
|
|
1328
|
-
` | { status: "needs-staging"; summary: string; review: NomosModelReview; stage(): Promise<NomosModelAdoption> }`,
|
|
1329
|
-
` | { status: "needs-decision"; summary: string; review: NomosModelReview; accept(because: string): Promise<NomosModelAdoption> }`,
|
|
1330
|
-
` | { status: "blocked"; summary: string; error: string; review: NomosModelReview };`,
|
|
1331
|
-
`type NomosModelRestoration =`,
|
|
1332
|
-
` | { status: "restored"; summary: string; review: NomosModelReview }`,
|
|
1333
|
-
` | { status: "needs-decision"; summary: string; review: NomosModelReview; accept(because: string): Promise<NomosModelRestoration> }`,
|
|
1334
|
-
` | { status: "blocked"; summary: string; error: string; review: NomosModelReview };`,
|
|
1335
|
-
`interface __NomosModelReportWire {`,
|
|
1336
|
-
` sourceVerified: boolean; complete: boolean; promotable: boolean;`,
|
|
1337
|
-
` replayedIntents: number; candidateIntents: number; evolve: { ok: boolean };`,
|
|
1338
|
-
` projection?: { equal: boolean };`,
|
|
1339
|
-
` divergences: { kind: string; domain?: string; directiveId?: string; admitted?: boolean }[];`,
|
|
1340
|
-
`}`,
|
|
1341
|
-
`interface __NomosModelAdoptionWire {`,
|
|
1342
|
-
` ok: boolean; stage: "promoted" | "already-current" | "identity" | "staging-required" | "preflight" | "acceptance" | "admission";`,
|
|
1343
|
-
` report?: __NomosModelReportWire; error?: string;`,
|
|
1344
|
-
`}`,
|
|
1345
|
-
`interface __NomosModelRestorationWire {`,
|
|
1346
|
-
` ok: boolean; stage: "restored" | "identity" | "preflight" | "acceptance" | "admission";`,
|
|
1347
|
-
` report?: __NomosModelReportWire; error?: string;`,
|
|
1348
|
-
`}`,
|
|
1349
|
-
`function _nomosModelReview(report?: __NomosModelReportWire): NomosModelReview {`,
|
|
1350
|
-
` const differences: NomosModelDifference[] = [];`,
|
|
1351
|
-
` for (const difference of report?.divergences ?? []) {`,
|
|
1352
|
-
` const area = typeof difference.domain === "string" && !difference.domain.includes("nomos_internal")`,
|
|
1353
|
-
` ? difference.domain : undefined;`,
|
|
1354
|
-
` const action = typeof difference.directiveId === "string" && !difference.directiveId.includes("nomos_internal")`,
|
|
1355
|
-
` ? difference.directiveId : undefined;`,
|
|
1356
|
-
` const kind: NomosModelDifference["kind"] = difference.kind === "plan-divergence" ? "outcome"`,
|
|
1357
|
-
` : difference.kind === "unsupported-premise" || difference.kind === "read-conflict" ? "evidence" : "rules";`,
|
|
1358
|
-
` const subject = action ?? (kind === "outcome" ? "A business action" : "A historical action");`,
|
|
1359
|
-
` const summary = kind === "outcome"`,
|
|
1360
|
-
` ? subject + " would produce a different result under this model."`,
|
|
1361
|
-
` : kind === "evidence"`,
|
|
1362
|
-
` ? "Nomos could not reproduce all evidence needed by " + subject + "."`,
|
|
1363
|
-
` : subject + " is not accepted by this model's rules.";`,
|
|
1364
|
-
` differences.push({ kind, ...(area === undefined ? {} : { area }), ...(action === undefined ? {} : { action }), summary });`,
|
|
1365
|
-
` }`,
|
|
1366
|
-
` if (report !== undefined && !report.evolve.ok && !differences.some((d) => d.kind === "rules")) {`,
|
|
1367
|
-
` differences.push({ kind: "rules", summary: "This model does not yet explain how to interpret every existing value." });`,
|
|
1368
|
-
` }`,
|
|
1369
|
-
` if (report !== undefined && (!report.sourceVerified || !report.complete) && !differences.some((d) => d.kind === "evidence")) {`,
|
|
1370
|
-
` differences.push({ kind: "evidence", summary: "Nomos could not re-prove every premise in the current business history." });`,
|
|
1371
|
-
` }`,
|
|
1372
|
-
` return {`,
|
|
1373
|
-
` checkedActions: report?.replayedIntents ?? 0, candidateActions: report?.candidateIntents ?? 0,`,
|
|
1374
|
-
` sameOutcome: report?.projection?.equal ?? null, differences,`,
|
|
1375
|
-
` };`,
|
|
1376
|
-
`}`,
|
|
1377
|
-
`async function _nomosAdoptModel(`,
|
|
1378
|
-
` holon: NomosHolon, domain: string, candidateHash: string, lawAsset?: URL, because?: string,`,
|
|
1379
|
-
`): Promise<NomosModelAdoption> {`,
|
|
1380
|
-
` if (!holon.__nomosAdoptModel) {`,
|
|
1381
|
-
` const error = "This device needs the current Nomos client before it can adopt a model.";`,
|
|
1382
|
-
` return { status: "blocked", summary: error, error, review: _nomosModelReview() };`,
|
|
1383
|
-
` }`,
|
|
1384
|
-
` const raw = await holon.__nomosAdoptModel(domain, candidateHash, because === undefined ? {} : { because });`,
|
|
1385
|
-
` const review = _nomosModelReview(raw.report);`,
|
|
1386
|
-
` if ((raw.stage === "promoted" || raw.stage === "already-current") && raw.ok) {`,
|
|
1387
|
-
` const summary = raw.stage === "promoted"`,
|
|
1388
|
-
` ? "Nomos proved this model against current history and made it active."`,
|
|
1389
|
-
` : "This workspace already runs this model or a server-side successor.";`,
|
|
1390
|
-
` return { status: "adopted", summary, review };`,
|
|
1391
|
-
` }`,
|
|
1392
|
-
` if (raw.stage === "staging-required" && lawAsset !== undefined && holon.__nomosStageGeneratedModel !== undefined) {`,
|
|
1393
|
-
` return {`,
|
|
1394
|
-
` status: "needs-staging",`,
|
|
1395
|
-
` summary: "This workspace is running the previous model. Nomos can stage this generated USDA candidate through its signed author gate.",`,
|
|
1396
|
-
` review,`,
|
|
1397
|
-
` stage: async () => {`,
|
|
1398
|
-
` // Keep Node's file loader behind a runtime-only boundary: browser-generated clients`,
|
|
1399
|
-
` // must typecheck without @types/node, while the local CLI can still stage its USDA asset.`,
|
|
1400
|
-
` const dynamicImport = Function("specifier", "return import(specifier)") as (specifier: string) => Promise<{ readFile(source: URL): Promise<Uint8Array> }>;`,
|
|
1401
|
-
` const { readFile } = await dynamicImport("node:fs/promises");`,
|
|
1402
|
-
` const lawUsdz = new Uint8Array(await readFile(lawAsset));`,
|
|
1403
|
-
` const staged = await holon.__nomosStageGeneratedModel!(domain, candidateHash, lawUsdz);`,
|
|
1404
|
-
` if (staged.ok !== true) {`,
|
|
1405
|
-
` const error = staged.error ?? "The workspace refused the generated USDA candidate.";`,
|
|
1406
|
-
` return { status: "blocked", summary: error, error, review };`,
|
|
1407
|
-
` }`,
|
|
1408
|
-
` return _nomosAdoptModel(holon, domain, candidateHash, lawAsset);`,
|
|
1409
|
-
` },`,
|
|
1410
|
-
` };`,
|
|
1411
|
-
` }`,
|
|
1412
|
-
` if (raw.stage === "acceptance") {`,
|
|
1413
|
-
` return {`,
|
|
1414
|
-
` status: "needs-decision",`,
|
|
1415
|
-
` summary: "This model would change prior business outcomes. Review the differences and record why that is intended.",`,
|
|
1416
|
-
` review,`,
|
|
1417
|
-
` accept: async (reason: string) => {`,
|
|
1418
|
-
` const stated = reason.trim();`,
|
|
1419
|
-
` if (!stated) throw new Error("accept(reason) needs the business reason for changing prior outcomes");`,
|
|
1420
|
-
` return _nomosAdoptModel(holon, domain, candidateHash, lawAsset, stated);`,
|
|
1421
|
-
` },`,
|
|
1422
|
-
` };`,
|
|
1423
|
-
` }`,
|
|
1424
|
-
` const summary = raw.stage === "identity"`,
|
|
1425
|
-
` ? "Sign in before adopting this model so the decision is accountable."`,
|
|
1426
|
-
` : raw.report !== undefined && !raw.report.sourceVerified`,
|
|
1427
|
-
` ? "The current history could not be verified. Nothing changed and the current model remains active."`,
|
|
1428
|
-
` : raw.report !== undefined && !raw.report.complete`,
|
|
1429
|
-
` ? "Nomos could not re-prove every historical dependency. Nothing changed and the current model remains active."`,
|
|
1430
|
-
` : raw.report !== undefined && !raw.report.evolve.ok`,
|
|
1431
|
-
` ? "This model cannot yet interpret every existing value. Nothing changed and the current model remains active."`,
|
|
1432
|
-
` : "The workspace changed or refused this adoption. Nothing changed; ask Nomos to try again.";`,
|
|
1433
|
-
` return { status: "blocked", summary, error: raw.error ?? summary, review };`,
|
|
1434
|
-
`}`,
|
|
1435
|
-
`async function _nomosRestorePreviousModel(`,
|
|
1436
|
-
` holon: NomosHolon, domain: string, currentHash: string, because?: string,`,
|
|
1437
|
-
`): Promise<NomosModelRestoration> {`,
|
|
1438
|
-
` if (!holon.__nomosRestorePreviousModel) {`,
|
|
1439
|
-
` const error = "This device needs the current Nomos client before it can restore a model.";`,
|
|
1440
|
-
` return { status: "blocked", summary: error, error, review: _nomosModelReview() };`,
|
|
1441
|
-
` }`,
|
|
1442
|
-
` const raw = await holon.__nomosRestorePreviousModel(domain, currentHash, because === undefined ? {} : { because });`,
|
|
1443
|
-
` const review = _nomosModelReview(raw.report);`,
|
|
1444
|
-
` if (raw.stage === "restored" && raw.ok) {`,
|
|
1445
|
-
` return { status: "restored", summary: "Nomos re-proved current history and restored the previous model.", review };`,
|
|
1446
|
-
` }`,
|
|
1447
|
-
` if (raw.stage === "acceptance") {`,
|
|
1448
|
-
` return {`,
|
|
1449
|
-
` status: "needs-decision",`,
|
|
1450
|
-
` summary: "Restoring the previous model changes which rules govern future work. Review the effects and record why restoration is intended.",`,
|
|
1451
|
-
` review,`,
|
|
1452
|
-
` accept: async (reason: string) => {`,
|
|
1453
|
-
` const stated = reason.trim();`,
|
|
1454
|
-
` if (!stated) throw new Error("accept(reason) needs the business reason for restoring the previous model");`,
|
|
1455
|
-
` return _nomosRestorePreviousModel(holon, domain, currentHash, stated);`,
|
|
1456
|
-
` },`,
|
|
1457
|
-
` };`,
|
|
1458
|
-
` }`,
|
|
1459
|
-
` const summary = raw.stage === "identity"`,
|
|
1460
|
-
` ? "Sign in before restoring a model so the decision is accountable."`,
|
|
1461
|
-
` : raw.error?.includes("restore-no-previous")`,
|
|
1462
|
-
` ? "This is the first model for this business; there is no previous model to restore."`,
|
|
1463
|
-
` : raw.error?.includes("restore-current-changed")`,
|
|
1464
|
-
` ? "The current model changed before restoration could finish. Nothing changed; ask Nomos to review again."`,
|
|
1465
|
-
` : raw.report !== undefined && !raw.report.sourceVerified`,
|
|
1466
|
-
` ? "The current history could not be verified. Nothing changed and the current model remains active."`,
|
|
1467
|
-
` : raw.report !== undefined && !raw.report.complete`,
|
|
1468
|
-
` ? "Nomos could not re-prove every historical dependency. Nothing changed and the current model remains active."`,
|
|
1469
|
-
` : raw.report !== undefined && !raw.report.evolve.ok`,
|
|
1470
|
-
` ? "The previous model cannot safely interpret every existing value. Nothing changed and the current model remains active."`,
|
|
1471
|
-
` : "The workspace refused restoration. Nothing changed and the current model remains active.";`,
|
|
1472
|
-
` return { status: "blocked", summary, error: raw.error ?? summary, review };`,
|
|
1473
|
-
`}`,
|
|
1474
|
-
``,
|
|
1238
|
+
const emitted = [
|
|
1475
1239
|
`// ── activity feed (architecture/activity_descriptors.md) — typed rows folded from the intent log ──`,
|
|
1476
1240
|
`/** A declared navigation target on an activity row: the same inspectable aggregate reference returned by`,
|
|
1477
1241
|
` * generated reads and writes. A \`from: "@created"\` ref resolves the identity the law minted. */`,
|
|
@@ -1590,6 +1354,13 @@ function emitTsActivityBlock(
|
|
|
1590
1354
|
`}`,
|
|
1591
1355
|
``,
|
|
1592
1356
|
];
|
|
1357
|
+
// Model install/adoption/restoration is Peer Office and kernel lifecycle, not
|
|
1358
|
+
// generated application behavior. Keep only the typed activity surface here.
|
|
1359
|
+
const activityStart = emitted.indexOf(
|
|
1360
|
+
`// ── activity feed (architecture/activity_descriptors.md) — typed rows folded from the intent log ──`
|
|
1361
|
+
);
|
|
1362
|
+
if (activityStart < 0) throw new Error("generated activity block lost its boundary");
|
|
1363
|
+
return emitted.slice(activityStart);
|
|
1593
1364
|
}
|
|
1594
1365
|
|
|
1595
1366
|
/** TRUE when any module declares a PACKED workspace taxonomy (the routed-holon shape).
|
|
@@ -1726,15 +1497,42 @@ export function generateTsClient(
|
|
|
1726
1497
|
// Business-birth framework declarations remain in the certified module, but are not application
|
|
1727
1498
|
// vocabulary. Strip only the presentation marker here; manifests, hashes and the engine see the full law.
|
|
1728
1499
|
modules = modules.map((mod) => {
|
|
1729
|
-
|
|
1500
|
+
// Workspace-sharing is framework procedure, not public application
|
|
1501
|
+
// vocabulary. Its generated binding still needs the exact nominal query
|
|
1502
|
+
// and result type used by the invitation desk, however. Those declarations
|
|
1503
|
+
// can be absent from `mod.queries`/the public aggregate set because the DSL
|
|
1504
|
+
// deliberately keeps framework law out of the tenant surface. Retain them
|
|
1505
|
+
// privately for code generation and hide their methods below.
|
|
1506
|
+
const invitationPendingQueries = (mod.applicationWorkspaceSharing ?? []).map(
|
|
1507
|
+
(policy) => policy.invitationLaw.pendingByRecipient
|
|
1508
|
+
);
|
|
1509
|
+
const invitationPendingQueryIds = new Set(
|
|
1510
|
+
invitationPendingQueries.map((query) => query.id)
|
|
1511
|
+
);
|
|
1512
|
+
const invitationPendingAggregateIds = new Set(
|
|
1513
|
+
invitationPendingQueries.map((query) => query.returns)
|
|
1514
|
+
);
|
|
1515
|
+
const generatedAggregates = mod.aggregates.filter(
|
|
1730
1516
|
(a) =>
|
|
1731
1517
|
(a as { businessBirthInternal?: unknown }).businessBirthInternal !==
|
|
1732
|
-
true &&
|
|
1518
|
+
true &&
|
|
1519
|
+
(!isFrameworkAggregate(a) || invitationPendingAggregateIds.has(a.id))
|
|
1733
1520
|
);
|
|
1734
|
-
const
|
|
1521
|
+
const generatedAggregateIds = new Set(generatedAggregates.map((a) => a.id));
|
|
1522
|
+
const generatedQueries = [
|
|
1523
|
+
...(mod.queries ?? []).filter(
|
|
1524
|
+
(query) =>
|
|
1525
|
+
((query as { businessBirthInternal?: unknown }).businessBirthInternal !== true || invitationPendingQueryIds.has(query.id)) &&
|
|
1526
|
+
generatedAggregateIds.has(query.returns) &&
|
|
1527
|
+
(!isFrameworkQuery(query) || invitationPendingQueryIds.has(query.id))
|
|
1528
|
+
),
|
|
1529
|
+
...invitationPendingQueries.filter(
|
|
1530
|
+
(query) => !(mod.queries ?? []).some((candidate) => candidate.id === query.id)
|
|
1531
|
+
),
|
|
1532
|
+
];
|
|
1735
1533
|
return {
|
|
1736
1534
|
...mod,
|
|
1737
|
-
aggregates:
|
|
1535
|
+
aggregates: generatedAggregates,
|
|
1738
1536
|
// An explicit application language wins. Otherwise the tenant's exported,
|
|
1739
1537
|
// non-framework directives are its business verbs. Framework directives are
|
|
1740
1538
|
// branded by object identity and can never leak merely because they compose
|
|
@@ -1744,20 +1542,15 @@ export function generateTsClient(
|
|
|
1744
1542
|
(d as { businessBirthInternal?: unknown }).businessBirthInternal !==
|
|
1745
1543
|
true && !isFrameworkDirective(d)
|
|
1746
1544
|
),
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
(q) =>
|
|
1752
|
-
(q as { businessBirthInternal?: unknown })
|
|
1753
|
-
.businessBirthInternal !== true && !isFrameworkQuery(q)
|
|
1754
|
-
),
|
|
1755
|
-
}),
|
|
1545
|
+
// Always overwrite the executable module's query list. Omitting the
|
|
1546
|
+
// property when presentation has no queries accidentally preserves the
|
|
1547
|
+
// unfiltered framework queries from `...mod` above.
|
|
1548
|
+
queries: generatedQueries,
|
|
1756
1549
|
...(mod.readModelAggregates === undefined
|
|
1757
1550
|
? {}
|
|
1758
1551
|
: {
|
|
1759
1552
|
readModelAggregates: mod.readModelAggregates.filter((id) =>
|
|
1760
|
-
|
|
1553
|
+
generatedAggregateIds.has(id)
|
|
1761
1554
|
),
|
|
1762
1555
|
}),
|
|
1763
1556
|
};
|
|
@@ -1911,24 +1704,48 @@ export function generateTsClient(
|
|
|
1911
1704
|
);
|
|
1912
1705
|
const out: string[] = [];
|
|
1913
1706
|
const applicationName = tsApplicationName(opts.packageName);
|
|
1914
|
-
const
|
|
1707
|
+
const applicationReception = `receive${applicationName}`;
|
|
1915
1708
|
// A signed-in person gets one application home. Other generated domain factories exist only so a
|
|
1916
1709
|
// business birth or typed navigation can bind them to their own child workspace inside the private plane.
|
|
1917
1710
|
const generatedDomains = [
|
|
1918
1711
|
...new Set(modules.map((mod) => mod.domain ?? mod.name)),
|
|
1919
1712
|
];
|
|
1920
|
-
const invitationPolicies = modules.flatMap((module) =>
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1713
|
+
const invitationPolicies = modules.flatMap((module) => {
|
|
1714
|
+
const domain = module.domain ?? module.name;
|
|
1715
|
+
const clientIndex = topology.rootDomains.indexOf(domain);
|
|
1716
|
+
// The package-level application facade owns only the root clients it opens.
|
|
1717
|
+
// A child workspace keeps its sharing boundary on that domain's generated
|
|
1718
|
+
// typed client; it must not be rebound to an unrelated root or queried
|
|
1719
|
+
// through a generic transport escape hatch.
|
|
1720
|
+
if (clientIndex < 0) return [];
|
|
1721
|
+
return (module.applicationWorkspaceSharing ?? []).map((policy) => {
|
|
1722
|
+
return {
|
|
1723
|
+
domain,
|
|
1724
|
+
domainHash: opts.domainHash,
|
|
1725
|
+
redeem: policy.invitationLaw.redeem.id,
|
|
1726
|
+
pendingMethod: lcFirst(camel(policy.invitationLaw.pendingByRecipient.id)),
|
|
1727
|
+
personField: policy.person,
|
|
1728
|
+
roleField: policy.role,
|
|
1729
|
+
scopeField: policy.scope,
|
|
1730
|
+
clientIndex,
|
|
1731
|
+
};
|
|
1732
|
+
});
|
|
1733
|
+
});
|
|
1931
1734
|
const hasInvitations = invitationPolicies.length > 0;
|
|
1735
|
+
const invitationPoliciesExpression = `[${invitationPolicies
|
|
1736
|
+
.map(
|
|
1737
|
+
(policy) =>
|
|
1738
|
+
`{ domain: ${JSON.stringify(policy.domain)}, domainHash: ${JSON.stringify(
|
|
1739
|
+
policy.domainHash
|
|
1740
|
+
)}, redeem: ${JSON.stringify(policy.redeem)}, pending: async (address: string) => (await _nmsRoot${
|
|
1741
|
+
policy.clientIndex
|
|
1742
|
+
}.${policy.pendingMethod}({ ${JSON.stringify(
|
|
1743
|
+
policy.personField
|
|
1744
|
+
)}: address })).map((row) => ({ orderId: _nmsReferenceData(row.ref).id, object: String(row[${JSON.stringify(
|
|
1745
|
+
policy.scopeField
|
|
1746
|
+
)}]), relation: String(row[${JSON.stringify(policy.roleField)}]) })) }`
|
|
1747
|
+
)
|
|
1748
|
+
.join(", ")}]`;
|
|
1932
1749
|
const clientDomains = topology.rootDomains;
|
|
1933
1750
|
// The PACKAGE-LEVEL recursive-type registry: every directive payload's `z.lazy` knots mint
|
|
1934
1751
|
// named recursive type aliases into it (deduped by lazy identity across directives); the decls
|
|
@@ -1974,6 +1791,7 @@ export function generateTsClient(
|
|
|
1974
1791
|
.filter(
|
|
1975
1792
|
(definition) =>
|
|
1976
1793
|
definition.group === "identity" ||
|
|
1794
|
+
definition.group === "governance" ||
|
|
1977
1795
|
definition.group === "lifecycle" ||
|
|
1978
1796
|
definition.group === "birth"
|
|
1979
1797
|
)
|
|
@@ -2104,7 +1922,7 @@ export function generateTsClient(
|
|
|
2104
1922
|
`TypeScript framework call USDA codegen: '${domain}/${directiveId}' has no authored payload schema`
|
|
2105
1923
|
);
|
|
2106
1924
|
}
|
|
2107
|
-
const encoder =
|
|
1925
|
+
const encoder = emitTsCallProtoEncoder(
|
|
2108
1926
|
law.graph,
|
|
2109
1927
|
law.paths,
|
|
2110
1928
|
domain,
|
|
@@ -2158,7 +1976,7 @@ export function generateTsClient(
|
|
|
2158
1976
|
readonly domain: string;
|
|
2159
1977
|
readonly directiveId: string;
|
|
2160
1978
|
readonly payloadType: string;
|
|
2161
|
-
readonly encoder: ReturnType<typeof
|
|
1979
|
+
readonly encoder: ReturnType<typeof emitTsCallProtoEncoder>;
|
|
2162
1980
|
}
|
|
2163
1981
|
>();
|
|
2164
1982
|
const capabilityReferenceTypes = new Set<string>();
|
|
@@ -2195,7 +2013,7 @@ export function generateTsClient(
|
|
|
2195
2013
|
domain,
|
|
2196
2014
|
directiveId: receipt.id,
|
|
2197
2015
|
payloadType,
|
|
2198
|
-
encoder:
|
|
2016
|
+
encoder: emitTsCallProtoEncoder(
|
|
2199
2017
|
law.graph,
|
|
2200
2018
|
law.paths,
|
|
2201
2019
|
domain,
|
|
@@ -2215,7 +2033,13 @@ export function generateTsClient(
|
|
|
2215
2033
|
`// AUTO-GENERATED by nomos-compile — exact framework operators for package "${opts.packageName}".`,
|
|
2216
2034
|
`// No application runtime and no authority live here. Do not edit.`,
|
|
2217
2035
|
``,
|
|
2218
|
-
...
|
|
2036
|
+
...((operatorEncoders.length + capabilityReceipts.length) > 0 ? [
|
|
2037
|
+
`import { create, toBinary } from "@bufbuild/protobuf";`,
|
|
2038
|
+
`import * as _nmsop from "./operation_payloads_pb.js";`,
|
|
2039
|
+
] : []),
|
|
2040
|
+
``,
|
|
2041
|
+
...TS_CALL_PROTO_PRELUDE,
|
|
2042
|
+
...TS_QUERY_USDA_PRELUDE,
|
|
2219
2043
|
`/** A SHA-256 digest in canonical Nomos wire form. */`,
|
|
2220
2044
|
`export type Sha256Digest = string & { readonly __nomosSha256Digest: unique symbol };`,
|
|
2221
2045
|
`/** A Git object address in canonical gix custody form. */`,
|
|
@@ -2224,7 +2048,8 @@ export function generateTsClient(
|
|
|
2224
2048
|
`export interface NomosFrameworkCall<Domain extends string = string, Directive extends string = string> {`,
|
|
2225
2049
|
` readonly domain: Domain;`,
|
|
2226
2050
|
` readonly directive: Directive;`,
|
|
2227
|
-
` readonly
|
|
2051
|
+
` readonly protobufType: string;`,
|
|
2052
|
+
` readonly protobufPayload: Uint8Array;`,
|
|
2228
2053
|
` readonly routingCandidates: readonly string[];`,
|
|
2229
2054
|
`}`,
|
|
2230
2055
|
`declare const _nomosAggregateType: unique symbol;`,
|
|
@@ -2327,42 +2152,34 @@ export function generateTsClient(
|
|
|
2327
2152
|
}
|
|
2328
2153
|
out.push(
|
|
2329
2154
|
`// AUTO-GENERATED by nomos-compile — typed TS application implementation for package "${opts.packageName}".`,
|
|
2330
|
-
`// Regenerated on every compile; do not edit.
|
|
2155
|
+
`// Regenerated on every compile; do not edit. Peer Office desk types below are deliberately private:`,
|
|
2331
2156
|
`// tenant application code receives the generated business API and cannot import transport machinery.`,
|
|
2332
2157
|
``,
|
|
2333
|
-
`import {
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
``,
|
|
2339
|
-
...(callUsdaByDomain.size > 0 ? TS_CALL_USDA_PRELUDE : []),
|
|
2158
|
+
`import { ${hasSha256Digests ? "sha256Digest, type Sha256Digest, " : ""}${hasGitObjectIds ? "gitObjectId, type GitObjectId, " : ""}type ReceptionSession as _NomosReceptionSession, type GeneratedApplication as _NomosGeneratedApplication } from "@githolon/runtime/application";`,
|
|
2159
|
+
...(modules.some(mod => (mod.workspaceInvariants ?? []).some(rule => rule.refusal)) ? [
|
|
2160
|
+
`import { admissionDecision as _admissionDecision, NominalValue as _NominalValue, parseNominalValue as _parseNominalValue, UnsupportedNominalRefusal as _UnsupportedNominalRefusal, type DomainRefusalEvidence as _DomainRefusalEvidence } from "@githolon/runtime/application";`,
|
|
2161
|
+
`export type { AdmissionDecision, DomainRefusalEvidence } from "@githolon/runtime/application";`,
|
|
2162
|
+
] : []),
|
|
2340
2163
|
...(hasSha256Digests
|
|
2341
2164
|
? [
|
|
2342
|
-
|
|
2343
|
-
`export type
|
|
2344
|
-
`/** Validate and construct a Sha256Digest before an offer is assembled. */`,
|
|
2345
|
-
`export const sha256Digest = (value: string): Sha256Digest => {`,
|
|
2346
|
-
` if (!/^[0-9a-f]{64}$/.test(value)) {`,
|
|
2347
|
-
` throw new TypeError("expected a 64-character lowercase hexadecimal SHA-256 digest");`,
|
|
2348
|
-
` }`,
|
|
2349
|
-
` return value as Sha256Digest;`,
|
|
2350
|
-
`};`,
|
|
2351
|
-
``,
|
|
2165
|
+
`export { sha256Digest };`,
|
|
2166
|
+
`export type { Sha256Digest };`,
|
|
2352
2167
|
]
|
|
2353
2168
|
: []),
|
|
2354
2169
|
...(hasGitObjectIds
|
|
2355
2170
|
? [
|
|
2356
|
-
|
|
2357
|
-
`export type
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
`
|
|
2364
|
-
`
|
|
2171
|
+
`export { gitObjectId };`,
|
|
2172
|
+
`export type { GitObjectId };`,
|
|
2173
|
+
]
|
|
2174
|
+
: []),
|
|
2175
|
+
``,
|
|
2176
|
+
...(callUsdaByDomain.size > 0
|
|
2177
|
+
? [
|
|
2178
|
+
`import { create, fromBinary, toBinary } from "@bufbuild/protobuf";`,
|
|
2179
|
+
`import * as _nmsop from "./operation_payloads_pb.js";`,
|
|
2365
2180
|
``,
|
|
2181
|
+
...TS_CALL_PROTO_PRELUDE,
|
|
2182
|
+
...TS_QUERY_USDA_PRELUDE,
|
|
2366
2183
|
]
|
|
2367
2184
|
: []),
|
|
2368
2185
|
`interface _NomosApplicationStatus {`,
|
|
@@ -2379,12 +2196,7 @@ export function generateTsClient(
|
|
|
2379
2196
|
`interface _NomosApplicationLifecycle {`,
|
|
2380
2197
|
` currentStatus(): Promise<_NomosApplicationStatus>;`,
|
|
2381
2198
|
` watchStatus(listener: (status: _NomosApplicationStatus) => void): () => void;`,
|
|
2382
|
-
`
|
|
2383
|
-
`interface _NomosApplicationModelLifecycle {`,
|
|
2384
|
-
` readonly model: {`,
|
|
2385
|
-
` adopt(): Promise<NomosModelAdoption>;`,
|
|
2386
|
-
` restorePrevious(): Promise<NomosModelRestoration>;`,
|
|
2387
|
-
` };`,
|
|
2199
|
+
` close(): Promise<void>;`,
|
|
2388
2200
|
`}`,
|
|
2389
2201
|
...(hasInvitations
|
|
2390
2202
|
? [
|
|
@@ -2404,25 +2216,11 @@ export function generateTsClient(
|
|
|
2404
2216
|
``,
|
|
2405
2217
|
...(clientInterface !== undefined
|
|
2406
2218
|
? [
|
|
2407
|
-
`/**
|
|
2408
|
-
` *
|
|
2409
|
-
`
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
clientInterface
|
|
2413
|
-
)} as const;`,
|
|
2414
|
-
``,
|
|
2415
|
-
]
|
|
2416
|
-
: []),
|
|
2417
|
-
...(opts.compat !== undefined
|
|
2418
|
-
? [
|
|
2419
|
-
`/** The CLIENT/LAW COMPAT MANIFEST (§5): the law hash + structural interface hash + generator`,
|
|
2420
|
-
` * provenance this client was generated against. A DIAGNOSIS surface — the factory hands it to`,
|
|
2421
|
-
` * the holon's connect-time classifier, which logs a warning on a law-hash mismatch. It NEVER`,
|
|
2422
|
-
` * gates: a hash mismatch with a compatible SHAPE is normal during law evolution (#72). */`,
|
|
2423
|
-
`const ${compatConstName(opts.packageName)} = ${JSON.stringify(
|
|
2424
|
-
opts.compat
|
|
2425
|
-
)} as const;`,
|
|
2219
|
+
`/** Canonical compiler-authored USDA compatibility matrix. The application carries`,
|
|
2220
|
+
` * these bytes opaquely; only the kernel interprets them against installed law. */`,
|
|
2221
|
+
`const ${interfaceConstName(opts.packageName)} = new TextEncoder().encode(${JSON.stringify(
|
|
2222
|
+
emitApplicationCompatibilityUsda(clientInterface)
|
|
2223
|
+
)});`,
|
|
2426
2224
|
``,
|
|
2427
2225
|
]
|
|
2428
2226
|
: []),
|
|
@@ -2518,7 +2316,8 @@ export function generateTsClient(
|
|
|
2518
2316
|
`/** Compare two public record addresses. Neither reference carries or grants authority. */`,
|
|
2519
2317
|
`export function sameRecord<TAggregate>(a: NomosRef<TAggregate>, b: NomosRef<TAggregate>): boolean {`,
|
|
2520
2318
|
` const left = _nmsReferenceData(a); const right = _nmsReferenceData(b);`,
|
|
2521
|
-
`
|
|
2319
|
+
` const sameType = _nmsReferenceTypeMatches(left.type, right.type) || _nmsReferenceTypeMatches(right.type, left.type);`,
|
|
2320
|
+
` return left.workspace === right.workspace && sameType && left.id === right.id;`,
|
|
2522
2321
|
`}`,
|
|
2523
2322
|
`/** The stable \`nomos://<workspace>/<type>/<id>\` string form (each segment URI-encoded — a workspace/`,
|
|
2524
2323
|
` * type/id containing \`/\` or spaces round-trips). Survives URLs, nav params, JSON, logs. */`,
|
|
@@ -2759,9 +2558,9 @@ export function generateTsClient(
|
|
|
2759
2558
|
`/** Read-only primitive used behind the generated, business-shaped historic view. */`,
|
|
2760
2559
|
`interface NomosHistoricHolon {`,
|
|
2761
2560
|
` /** Compiler-generated declared query. Routing identity and USDA arguments remain one nominal value. */`,
|
|
2762
|
-
`
|
|
2561
|
+
` __nomosQuery(query: NmsGeneratedQuery, keys?: ${
|
|
2763
2562
|
encPresent ? "readonly NomosScopeKey[]" : "never"
|
|
2764
|
-
}): Promise<
|
|
2563
|
+
}): Promise<NmsGeneratedResult>;`,
|
|
2765
2564
|
` /** Compiler-generated historic identity lookup returning canonical USDA. */`,
|
|
2766
2565
|
` __nomosQueryByIdUsda(aggregateType: string, aggregateId: string, keys?: ${
|
|
2767
2566
|
encPresent ? "readonly NomosScopeKey[]" : "never"
|
|
@@ -2772,8 +2571,12 @@ export function generateTsClient(
|
|
|
2772
2571
|
}): Promise<Uint8Array>;`,
|
|
2773
2572
|
` count(countId: string, groupKey?: string): Promise<number>;`,
|
|
2774
2573
|
` sum(sumId: string, groupKey?: string): Promise<number>;`,
|
|
2574
|
+
` __nomosExtremum?(id: string, kind: "min" | "max", groupKey?: string): Promise<number | null>;`,
|
|
2775
2575
|
`}`,
|
|
2776
|
-
`/** The holon surface this client binds to (structurally satisfied by @githolon/
|
|
2576
|
+
`/** The holon surface this client binds to (structurally satisfied by @githolon/runtime). */`,
|
|
2577
|
+
`/** The peer's holon as the runtime binds it. Tenant code never constructs one; the generated`,
|
|
2578
|
+
` * factories and receiver take it from the runtime. Its members are deliberately not declared here. */`,
|
|
2579
|
+
`export interface NomosHolonBinding { readonly workspace: string }`,
|
|
2777
2580
|
`interface NomosHolon {`,
|
|
2778
2581
|
` /** Carry one compiler-generated nominal USDA call. Routing identity and bytes cannot be paired independently. */`,
|
|
2779
2582
|
` offerCall(call: NmsGeneratedCall, opts?: { domainHash?: string; actor?: string; returnCreated?: boolean; __nomosConflictSnapshots?: readonly { aggregateType: string; aggregateId: string; field: string; targetSchema: string; token: string }[] }): Promise<string | { head: string; created?: { type: string; id: string }[]; affected?: { type: string; id: string }[]; workspace?: string; born?: unknown; birthOutcomes?: unknown }>;`,
|
|
@@ -2793,7 +2596,7 @@ export function generateTsClient(
|
|
|
2793
2596
|
...(hasBirths
|
|
2794
2597
|
? [
|
|
2795
2598
|
` /** BIRTH A CHILD WORKSPACE (a signed CROSS-WORKSPACE governance offer to \`parent\`) — OPTIONAL:`,
|
|
2796
|
-
` * @githolon/
|
|
2599
|
+
` * @githolon/runtime's connect() attaches it. The generated \`.births()\` methods call this, binding`,
|
|
2797
2600
|
` * the declaring domain/directiveId/law hash so a frontend dev never hand-writes those raw strings. */`,
|
|
2798
2601
|
` createWorkspace?(opts: { domain: string; directiveId: string; domainHash?: string; parent: string; actor: string; authorSecret?: string; payload?: unknown; name?: string; authToken?: string }): Promise<{ ok?: boolean; status?: number; body?: unknown }>;`,
|
|
2799
2602
|
]
|
|
@@ -2803,6 +2606,9 @@ export function generateTsClient(
|
|
|
2803
2606
|
...(callUsdaByDomain.size > 0
|
|
2804
2607
|
? [
|
|
2805
2608
|
` /** Framework-private nominal read lane. Generated code decodes only exact law relationships. */`,
|
|
2609
|
+
` __nomosQuery(query: NmsGeneratedQuery, keys?: ${
|
|
2610
|
+
encPresent ? "readonly NomosScopeKey[]" : "never"
|
|
2611
|
+
}): Promise<NmsGeneratedResult>;`,
|
|
2806
2612
|
` __nomosQueryUsda(query: NmsGeneratedQuery, keys?: ${
|
|
2807
2613
|
encPresent ? "readonly NomosScopeKey[]" : "never"
|
|
2808
2614
|
}): Promise<Uint8Array>;`,
|
|
@@ -2815,6 +2621,13 @@ export function generateTsClient(
|
|
|
2815
2621
|
` __nomosQueryPageUsda(query: NmsGeneratedQuery, page: { pageSize?: number; cursor?: string | null }, keys?: ${
|
|
2816
2622
|
encPresent ? "readonly NomosScopeKey[]" : "never"
|
|
2817
2623
|
}): Promise<Uint8Array>;`,
|
|
2624
|
+
` __nomosQueryPage(query: NmsGeneratedQuery, page: { pageSize?: number; cursor?: string | null }, keys?: ${
|
|
2625
|
+
encPresent ? "readonly NomosScopeKey[]" : "never"
|
|
2626
|
+
}): Promise<NmsGeneratedResult>;`,
|
|
2627
|
+
` __nomosWatch(query: NmsGeneratedQuery, changed: (result: NmsGeneratedResult) => void, failed: (failure: { code: string; message: string; component: string }) => void, opts?: { intervalMs?: number }): () => void;`,
|
|
2628
|
+
` __nomosWatchRows<T>(subscribe: (changed: () => void) => () => void, read: () => Promise<T[]>, cb: (rows: T[]) => void): () => void;`,
|
|
2629
|
+
` __nomosWatchResults<TResult, TRows>(subscribe: (changed: (result: TResult) => void, failed: (failure: { code: string; message: string }) => void) => () => void, decode: (result: TResult) => TRows[] | Promise<TRows[]>, cb: (rows: TRows[]) => void): () => void;`,
|
|
2630
|
+
` __nomosWatchFollow<T>(open: Promise<T>, subscribe: (opened: T) => () => void, unavailable: () => void): () => void;`,
|
|
2818
2631
|
` __nomosWatchUsda(query: NmsGeneratedQuery, cb: (resultUsda: Uint8Array) => void, opts?: { intervalMs?: number }, keys?: ${
|
|
2819
2632
|
encPresent ? "readonly NomosScopeKey[]" : "never"
|
|
2820
2633
|
}): () => void;`,
|
|
@@ -2844,18 +2657,6 @@ export function generateTsClient(
|
|
|
2844
2657
|
` checkReferenceVersions?(refs: readonly { pinned: _NomosRawAddress; series: _NomosRawAddress; currentField: string }[]): Promise<{ unique: { outcome: { status: string; latest?: _NomosRawAddress } }[]; order: number[] }>;`,
|
|
2845
2658
|
]
|
|
2846
2659
|
: []),
|
|
2847
|
-
` /** FRAMEWORK-INTERNAL exact-history adoption seam. Generated clients expose only`,
|
|
2848
|
-
` * \`model.adopt()\` and a chained \`decision.accept(reason)\`. */`,
|
|
2849
|
-
` __nomosAdoptModel?(domain: string, candidateHash: string, opts?: { because?: string }): Promise<__NomosModelAdoptionWire>;`,
|
|
2850
|
-
` /** FRAMEWORK-INTERNAL signed lifecycle offer used by generated model staging. */`,
|
|
2851
|
-
` __nomosStageGeneratedModel?(domain: string, candidateHash: string, lawUsdz: Uint8Array): Promise<{ ok?: boolean; error?: string }>;`,
|
|
2852
|
-
` /** FRAMEWORK-INTERNAL exact-history restoration seam. Generated clients expose only`,
|
|
2853
|
-
` * \`model.restorePrevious()\` and a chained \`decision.accept(reason)\`. */`,
|
|
2854
|
-
` __nomosRestorePreviousModel?(domain: string, currentHash: string, opts?: { because?: string }): Promise<__NomosModelRestorationWire>;`,
|
|
2855
|
-
` /** Persist local custody and reconcile its configured remote. Business birth awaits this when available. */`,
|
|
2856
|
-
` sync?(): Promise<unknown>;`,
|
|
2857
|
-
` /** Complete durable custody and cold-chain verification for a newly born aggregate. */`,
|
|
2858
|
-
` settleBirth?(workspace: string, opts?: { timeoutMs?: number; pollMs?: number }): Promise<unknown>;`,
|
|
2859
2660
|
` /** Verified points in local history. Optional only so a pre-history runtime fails at the named call. */`,
|
|
2860
2661
|
` commits?(opts?: { limit?: number }): Promise<{ oid: string; at: number | null; actorSubject: string | null; domain: string | null; directiveId: string | null }[]>;`,
|
|
2861
2662
|
` /** Read the verified projection at one opaque moment without moving the live world. */`,
|
|
@@ -2923,10 +2724,13 @@ export function generateTsClient(
|
|
|
2923
2724
|
: []),
|
|
2924
2725
|
` /** Declared-count / declared-sum O(1) reads (maintained by the read engine). */`,
|
|
2925
2726
|
` count(countId: string, groupKey?: string): Promise<number>;`,
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2727
|
+
...(modules.some((module) => (module.spatials?.length ?? 0) > 0) ? [
|
|
2728
|
+
` /** Framework-private R*Tree read. Only the generated law decoder interprets tenant rows. */`,
|
|
2729
|
+
` __nomosSpatialWithinUsda(spatialId: string, bbox: { minX: number; minY: number; maxX: number; maxY: number } | { minLng: number; minLat: number; maxLng: number; maxLat: number }): Promise<Uint8Array>;`,
|
|
2730
|
+
] : []),
|
|
2929
2731
|
` sum(sumId: string, groupKey?: string): Promise<number>;`,
|
|
2732
|
+
` /** Declared maintained extrema. Optional only to diagnose missing runtime support, never to return a fabricated value. */`,
|
|
2733
|
+
` __nomosExtremum?(id: string, kind: "min" | "max", groupKey?: string): Promise<number | null>;`,
|
|
2930
2734
|
` /** Bounded authenticated query page. Optional only so generated clients diagnose an old runtime cleanly. */`,
|
|
2931
2735
|
` queryPage?(queryId: string, params?: Record<string, unknown>, page?: { pageSize?: number; cursor?: string | null }, keys?: readonly unknown[], principal?: string): Promise<{ rows: unknown[]; cursor: string | null; done: boolean }>;`,
|
|
2932
2736
|
` /** The DEAD-LETTER QUEUE — refused-but-legitimate intents the app must handle`,
|
|
@@ -2944,11 +2748,11 @@ export function generateTsClient(
|
|
|
2944
2748
|
` activityLog?(opts?: { base?: string; limit?: number }): Promise<ActivityRawRow[]>;`,
|
|
2945
2749
|
]
|
|
2946
2750
|
: []),
|
|
2947
|
-
` /** THE COMPAT SUPERPOWER (#72b) — OPTIONAL: a holon from @githolon/
|
|
2751
|
+
` /** THE COMPAT SUPERPOWER (#72b) — OPTIONAL: a holon from @githolon/runtime's connect() attaches it.`,
|
|
2948
2752
|
` * The factory hands over this client's baked compat manifest + structural interface (the requirement),`,
|
|
2949
2753
|
` * and the holon computes the LIVE per-member verdict on \`holon.compat\`. A KNOWN-incompatible directive`,
|
|
2950
2754
|
` * then refuses CLIENT-SIDE at write time (LawMismatchError), never as a server 422. */`,
|
|
2951
|
-
` checkCompat?(
|
|
2755
|
+
` checkCompat?(matrixUsda: Uint8Array): NomosCompatVerdict | null;`,
|
|
2952
2756
|
` /** Framework-private readiness hint; generated domain bindings keep first-use plan work off the offer path. */`,
|
|
2953
2757
|
` prepareDomain?(domain: string, packageHash: string): void;`,
|
|
2954
2758
|
` /** Resolve the law's standard OSGi Contract Namespace requirements before bind. */`,
|
|
@@ -3086,7 +2890,7 @@ export function generateTsClient(
|
|
|
3086
2890
|
` const keys = keyStore == null || ordinary.length === 0 ? [] : await keyStore.readKeys(ordinary);`,
|
|
3087
2891
|
` for (const s of scopes) {`,
|
|
3088
2892
|
` if (s.owned !== true) continue;`,
|
|
3089
|
-
` if (!holon.__nomosOwnedScopeKeys) throw new Error("owned record reads need the current @githolon/
|
|
2893
|
+
` if (!holon.__nomosOwnedScopeKeys) throw new Error("owned record reads need the current @githolon/runtime");`,
|
|
3090
2894
|
` for (const record of records) {`,
|
|
3091
2895
|
` for (const held of await holon.__nomosOwnedScopeKeys({ scope: s.scope, record })) {`,
|
|
3092
2896
|
` if (!keys.some((key) => key.scope === held.scope && key.epoch === held.epoch)) keys.push(held);`,
|
|
@@ -3134,32 +2938,6 @@ export function generateTsClient(
|
|
|
3134
2938
|
` return read(keys);`,
|
|
3135
2939
|
`};`,
|
|
3136
2940
|
``,
|
|
3137
|
-
`/** Reactive owned reads use the exact same two-pass, record-key-aware read as one-shot reads.`,
|
|
3138
|
-
` * The raw watch is only a local change signal; ciphertext rows never reach application callbacks. */`,
|
|
3139
|
-
`const _watchWithOwnedKeys = <T>(`,
|
|
3140
|
-
` subscribe: (changed: () => void) => () => void,`,
|
|
3141
|
-
` read: () => Promise<T[]>,`,
|
|
3142
|
-
` cb: (rows: T[]) => void,`,
|
|
3143
|
-
`): (() => void) => {`,
|
|
3144
|
-
` let active = true;`,
|
|
3145
|
-
` let pending = Promise.resolve();`,
|
|
3146
|
-
` const changed = () => {`,
|
|
3147
|
-
` pending = pending.catch(() => undefined).then(async () => {`,
|
|
3148
|
-
` try {`,
|
|
3149
|
-
` const rows = await read();`,
|
|
3150
|
-
` if (active) cb(rows);`,
|
|
3151
|
-
` } catch (error) {`,
|
|
3152
|
-
` if (!active) return;`,
|
|
3153
|
-
` const message = String((error as { message?: unknown })?.message ?? error).toLowerCase();`,
|
|
3154
|
-
` if (/forbid|denied|not been shared|not currently sharing|no longer shared/.test(message)) { cb([]); return; }`,
|
|
3155
|
-
` throw error;`,
|
|
3156
|
-
` }`,
|
|
3157
|
-
` });`,
|
|
3158
|
-
` };`,
|
|
3159
|
-
` const stop = subscribe(changed);`,
|
|
3160
|
-
` return () => { active = false; stop(); };`,
|
|
3161
|
-
`};`,
|
|
3162
|
-
``,
|
|
3163
2941
|
...(manualEncryptionPresent
|
|
3164
2942
|
? [
|
|
3165
2943
|
`// ── E2E OWNER CEREMONY (the sealing client, slice 2) — grantAndWrap / revokeAndRotate / rotate ──`,
|
|
@@ -3254,7 +3032,7 @@ export function generateTsClient(
|
|
|
3254
3032
|
` return typeof e === "number" ? e : -1;`,
|
|
3255
3033
|
` };`,
|
|
3256
3034
|
` const freshScopeKey = async (): Promise<string> => {`,
|
|
3257
|
-
` if (!holon.cryptoKeygen) throw new Error("this holon predates E2E keygen — upgrade @githolon/
|
|
3035
|
+
` if (!holon.cryptoKeygen) throw new Error("this holon predates E2E keygen — upgrade @githolon/runtime");`,
|
|
3258
3036
|
` const kp = await holon.cryptoKeygen();`,
|
|
3259
3037
|
` return _bytesToB64(_b64ToBytes(kp.secret).subarray(0, 32)); // the 32-byte epoch secret; NEVER lands on chain`,
|
|
3260
3038
|
` };`,
|
|
@@ -3289,7 +3067,7 @@ export function generateTsClient(
|
|
|
3289
3067
|
` if (missing.length || extra.length) throw new EncryptionRosterMismatch(scope, missing, extra);`,
|
|
3290
3068
|
` }`,
|
|
3291
3069
|
` const key = opts.scopeKey ?? await freshScopeKey();`,
|
|
3292
|
-
` if (!holon.cryptoWrapKey) throw new Error("this holon predates E2E wrap — upgrade @githolon/
|
|
3070
|
+
` if (!holon.cryptoWrapKey) throw new Error("this holon predates E2E wrap — upgrade @githolon/runtime");`,
|
|
3293
3071
|
` const wraps: { recipientPrincipal: string; recipientPubKey: string; hpkeEpk: string; ct: string }[] = [];`,
|
|
3294
3072
|
` for (const principal of members) {`,
|
|
3295
3073
|
` const pub = await memberPubKey(principal, { publicKey: opts.add?.publicKey, principal: opts.add?.principal, memberKeys: opts.memberKeys });`,
|
|
@@ -3326,6 +3104,11 @@ export function generateTsClient(
|
|
|
3326
3104
|
);
|
|
3327
3105
|
}
|
|
3328
3106
|
|
|
3107
|
+
out.push(
|
|
3108
|
+
`/** Reactive typed reads use the raw watch only as a local invalidation signal, then`,
|
|
3109
|
+
` * re-read through the generated operation-specific result contract. */`,
|
|
3110
|
+
);
|
|
3111
|
+
|
|
3329
3112
|
const aggByType = new Map<string, AggregateHandle>();
|
|
3330
3113
|
const runtimeTypeByAggregate = new Map<string, string>();
|
|
3331
3114
|
const resultUsdaByAggregate = new Map<string, TsResultAggregate>();
|
|
@@ -3445,7 +3228,7 @@ export function generateTsClient(
|
|
|
3445
3228
|
readonly result: TsResultAggregate;
|
|
3446
3229
|
readonly query?: {
|
|
3447
3230
|
readonly id: string;
|
|
3448
|
-
readonly encoder: ReturnType<typeof
|
|
3231
|
+
readonly encoder: ReturnType<typeof emitTsQueryProtoEncoder>;
|
|
3449
3232
|
};
|
|
3450
3233
|
}
|
|
3451
3234
|
const frameworkReadEmissions: FrameworkReadEmission[] =
|
|
@@ -3556,7 +3339,7 @@ export function generateTsClient(
|
|
|
3556
3339
|
if (queryLaw !== undefined) {
|
|
3557
3340
|
query = {
|
|
3558
3341
|
id: definition.query.id,
|
|
3559
|
-
encoder:
|
|
3342
|
+
encoder: emitTsQueryProtoEncoder(
|
|
3560
3343
|
queryLaw.graph,
|
|
3561
3344
|
queryLaw.paths,
|
|
3562
3345
|
queryLaw.graph.domain.entity.label,
|
|
@@ -3649,7 +3432,8 @@ export function generateTsClient(
|
|
|
3649
3432
|
if (resultUsdaByAggregate.size > 0 || frameworkReadEmissions.length > 0) {
|
|
3650
3433
|
out.push(
|
|
3651
3434
|
`// Canonical USDA result syntax plus graph-generated nominal decoders.`,
|
|
3652
|
-
...TS_RESULT_USDA_PRELUDE
|
|
3435
|
+
...TS_RESULT_USDA_PRELUDE,
|
|
3436
|
+
...TS_RESULT_PROTO_PRELUDE,
|
|
3653
3437
|
);
|
|
3654
3438
|
if (hasSurfaced) {
|
|
3655
3439
|
out.push(
|
|
@@ -3885,11 +3669,16 @@ export function generateTsClient(
|
|
|
3885
3669
|
.directives ?? []
|
|
3886
3670
|
);
|
|
3887
3671
|
const aggregateVos = collectValueObjectDescriptors(mod.aggregates);
|
|
3672
|
+
const readVos = collectSchemaValueObjectDescriptors([
|
|
3673
|
+
...(mod.deriveds ?? []).map((read) => read.returns),
|
|
3674
|
+
...(mod.combineds ?? []).map((read) => read.returns),
|
|
3675
|
+
]);
|
|
3888
3676
|
for (const d of [
|
|
3889
3677
|
...((mod as { valueObjects?: readonly ValueObjectDescriptor[] })
|
|
3890
3678
|
.valueObjects ?? []),
|
|
3891
3679
|
...aggregateVos,
|
|
3892
3680
|
...payloadVos,
|
|
3681
|
+
...readVos,
|
|
3893
3682
|
]) {
|
|
3894
3683
|
const existing = voByName.get(d.name);
|
|
3895
3684
|
if (
|
|
@@ -4604,6 +4393,7 @@ export function generateTsClient(
|
|
|
4604
4393
|
targetDomain: string;
|
|
4605
4394
|
applicationType: string;
|
|
4606
4395
|
}> = [];
|
|
4396
|
+
const emittedResultRowDecoders = new Set<string>();
|
|
4607
4397
|
for (const mod of modules) {
|
|
4608
4398
|
const domain = mod.domain ?? mod.name;
|
|
4609
4399
|
const domainCallUsda = callUsdaByDomain.get(domain);
|
|
@@ -4615,7 +4405,11 @@ export function generateTsClient(
|
|
|
4615
4405
|
(d as { businessBirthInternal?: unknown }).businessBirthInternal !==
|
|
4616
4406
|
true &&
|
|
4617
4407
|
((d as { birthsChild?: unknown }).birthsChild !== true ||
|
|
4618
|
-
(d as { businessBirth?: unknown }).businessBirth !== undefined)
|
|
4408
|
+
(d as { businessBirth?: unknown }).businessBirth !== undefined) &&
|
|
4409
|
+
// A directive the law offers only THROUGH a business intent (a capability obligation that
|
|
4410
|
+
// intent `.directs`) is not a second client call: its route and contract are the publisher's.
|
|
4411
|
+
(domainCallUsda === undefined ||
|
|
4412
|
+
publishingIntentOf(domainCallUsda.graph, domain, d.id) === undefined)
|
|
4619
4413
|
);
|
|
4620
4414
|
if (dirs.length > 0 && domainCallUsda === undefined) {
|
|
4621
4415
|
throw new Error(
|
|
@@ -4629,6 +4423,7 @@ export function generateTsClient(
|
|
|
4629
4423
|
(d as { businessBirth?: unknown }).businessBirth === undefined
|
|
4630
4424
|
);
|
|
4631
4425
|
out.push(`// ── domain "${domain}" ──`, ``);
|
|
4426
|
+
if (domainCallUsda) out.push(...tsRefusalDecoders(mod, domainCallUsda.graph, domainCallUsda.paths));
|
|
4632
4427
|
|
|
4633
4428
|
const mintPlan = mintPlans.get(mod);
|
|
4634
4429
|
// PLACEMENT directives (packed taxonomy births): their `shard` is AUTO-PICKED
|
|
@@ -4649,6 +4444,12 @@ export function generateTsClient(
|
|
|
4649
4444
|
}
|
|
4650
4445
|
}
|
|
4651
4446
|
const methods: string[] = [];
|
|
4447
|
+
if (domainCallUsda?.graph.nodes.some(node => node.kind === "read" && node.entity.label === "receivedWorkspaceAccess")) {
|
|
4448
|
+
const read = generateTsWorkspaceAccessRead(domainCallUsda.graph, domainCallUsda.paths);
|
|
4449
|
+
out.push(...read.source);
|
|
4450
|
+
methods.push(` /** Source-qualified access discovered entirely from this Home's local Zanzibar graph. */`,
|
|
4451
|
+
` receivedAccess: () => ${read.functionName}(holon),`);
|
|
4452
|
+
}
|
|
4652
4453
|
const callEncoderByDirective = new Map<string, string>();
|
|
4653
4454
|
const internalCallTypeByDirective = new Map<string, string>();
|
|
4654
4455
|
const sourceTrustViaIds = new Set(
|
|
@@ -4671,7 +4472,7 @@ export function generateTsClient(
|
|
|
4671
4472
|
via.payloadSchema as z.ZodTypeAny,
|
|
4672
4473
|
[]
|
|
4673
4474
|
);
|
|
4674
|
-
const encoder =
|
|
4475
|
+
const encoder = emitTsCallProtoEncoder(
|
|
4675
4476
|
domainCallUsda.graph,
|
|
4676
4477
|
domainCallUsda.paths,
|
|
4677
4478
|
domain,
|
|
@@ -4822,7 +4623,7 @@ export function generateTsClient(
|
|
|
4822
4623
|
for (const actions of Object.values(ownedActions)) {
|
|
4823
4624
|
for (const action of ["share", "unshare", "transfer"] as const) {
|
|
4824
4625
|
const directiveId = actions[action];
|
|
4825
|
-
const encoder =
|
|
4626
|
+
const encoder = emitTsCallProtoEncoder(
|
|
4826
4627
|
domainCallUsda!.graph,
|
|
4827
4628
|
domainCallUsda!.paths,
|
|
4828
4629
|
domain,
|
|
@@ -4836,7 +4637,7 @@ export function generateTsClient(
|
|
|
4836
4637
|
out.push(...encoder.source);
|
|
4837
4638
|
}
|
|
4838
4639
|
}
|
|
4839
|
-
const approvalEncoder =
|
|
4640
|
+
const approvalEncoder = emitTsCallProtoEncoder(
|
|
4840
4641
|
domainCallUsda!.graph,
|
|
4841
4642
|
domainCallUsda!.paths,
|
|
4842
4643
|
domain,
|
|
@@ -4862,7 +4663,7 @@ export function generateTsClient(
|
|
|
4862
4663
|
` corrections: {`,
|
|
4863
4664
|
` undo: async (reason: string): Promise<NomosCorrectionOutcome> => {`,
|
|
4864
4665
|
` if (!reason.trim()) throw new Error("corrections.undo() needs a reason");`,
|
|
4865
|
-
` if (!holon.correctMostRecent) throw new Error("corrections need the current @githolon/
|
|
4666
|
+
` if (!holon.correctMostRecent) throw new Error("corrections need the current @githolon/runtime");`,
|
|
4866
4667
|
` return holon.correctMostRecent({ kind: "undo", domain: ${JSON.stringify(
|
|
4867
4668
|
domain
|
|
4868
4669
|
)}, actions: ${JSON.stringify(
|
|
@@ -4871,7 +4672,7 @@ export function generateTsClient(
|
|
|
4871
4672
|
` },`,
|
|
4872
4673
|
` redo: async (reason: string): Promise<NomosCorrectionOutcome> => {`,
|
|
4873
4674
|
` if (!reason.trim()) throw new Error("corrections.redo() needs a reason");`,
|
|
4874
|
-
` if (!holon.correctMostRecent) throw new Error("corrections need the current @githolon/
|
|
4675
|
+
` if (!holon.correctMostRecent) throw new Error("corrections need the current @githolon/runtime");`,
|
|
4875
4676
|
` return holon.correctMostRecent({ kind: "redo", domain: ${JSON.stringify(
|
|
4876
4677
|
domain
|
|
4877
4678
|
)}, actions: ${JSON.stringify(
|
|
@@ -5094,7 +4895,7 @@ export function generateTsClient(
|
|
|
5094
4895
|
ownedRuntimeType === undefined
|
|
5095
4896
|
? ""
|
|
5096
4897
|
: ownedRecordTarget.kind === "premint"
|
|
5097
|
-
? ` if (!holon.mint) throw new Error("this holon predates record-bound .owned() identity — upgrade @githolon/
|
|
4898
|
+
? ` if (!holon.mint) throw new Error("this holon predates record-bound .owned() identity — upgrade @githolon/runtime");\n` +
|
|
5098
4899
|
` const _ownedRecord = { type: ${JSON.stringify(
|
|
5099
4900
|
ownedRuntimeType
|
|
5100
4901
|
)}, id: await holon.mint(${JSON.stringify(
|
|
@@ -5126,7 +4927,7 @@ export function generateTsClient(
|
|
|
5126
4927
|
const ownedBirthPrelude =
|
|
5127
4928
|
ownedBirthDescriptor === undefined
|
|
5128
4929
|
? ""
|
|
5129
|
-
: ` if (!holon.__nomosOwnedBirthScopeKey) throw new Error("this holon predates automatic .owned() birth custody — upgrade @githolon/
|
|
4930
|
+
: ` if (!holon.__nomosOwnedBirthScopeKey) throw new Error("this holon predates automatic .owned() birth custody — upgrade @githolon/runtime");\n` +
|
|
5130
4931
|
` const _ownedBirthKey = await holon.__nomosOwnedBirthScopeKey({ scope: ${JSON.stringify(
|
|
5131
4932
|
ownedBirthDescriptor.scope
|
|
5132
4933
|
)}, namespace: ${JSON.stringify(
|
|
@@ -5216,12 +5017,18 @@ export function generateTsClient(
|
|
|
5216
5017
|
`TypeScript source-trust codegen: '${domain}/${d.id}' satisfaction query '${satisfactionQuery.id}' has mismatched keys`
|
|
5217
5018
|
);
|
|
5218
5019
|
}
|
|
5219
|
-
// A
|
|
5220
|
-
//
|
|
5221
|
-
//
|
|
5222
|
-
|
|
5223
|
-
|
|
5020
|
+
// A satisfaction query observes enrollment; declaring it does
|
|
5021
|
+
// not create a trust row. Only an absent row invokes the declared
|
|
5022
|
+
// gated enrollment. Existing identities remain the kernel's call.
|
|
5023
|
+
const satisfactionPrelude = satisfactionQuery === undefined ? [] : [
|
|
5024
|
+
` const _sourceTrustAlreadySatisfied = (await _application.${satisfactionQuery.id}({ ${satisfactionQuery.key
|
|
5025
|
+
.map(key => `${JSON.stringify(key)}: ${payloadPath(inputPayload, satisfactionArgs[key]!)}`)
|
|
5026
|
+
.join(", ")} })).length > 0;`,
|
|
5027
|
+
" if (!_sourceTrustAlreadySatisfied) {",
|
|
5028
|
+
];
|
|
5029
|
+
const indent = satisfactionQuery === undefined ? " " : " ";
|
|
5224
5030
|
return [
|
|
5031
|
+
...satisfactionPrelude,
|
|
5225
5032
|
`${indent}const _sourceWorkspace = String(${payloadPath(
|
|
5226
5033
|
inputPayload,
|
|
5227
5034
|
sourceTrust.fromPayload
|
|
@@ -5238,6 +5045,7 @@ export function generateTsClient(
|
|
|
5238
5045
|
`${indent} ${JSON.stringify(sourceTrust.keyHashesField)}: [],`,
|
|
5239
5046
|
`${indent}} satisfies ${payloadType};`,
|
|
5240
5047
|
`${indent}await _commit(holon.offerCall(${encoder}(_sourceTrustCall, holon.workspace), { domainHash, actor, returnCreated: true }) as Promise<_NomosRawWriteResult>);`,
|
|
5048
|
+
...(satisfactionQuery === undefined ? [] : [" }"]),
|
|
5241
5049
|
];
|
|
5242
5050
|
})();
|
|
5243
5051
|
const sealPrelude =
|
|
@@ -5248,7 +5056,7 @@ export function generateTsClient(
|
|
|
5248
5056
|
? businessBirth !== undefined
|
|
5249
5057
|
? [` const _ownedKey = _ownedBirthKey;`]
|
|
5250
5058
|
: [
|
|
5251
|
-
` if (!holon.__nomosOwnedScopeKey) throw new Error("this holon predates automatic .owned() key custody — upgrade @githolon/
|
|
5059
|
+
` if (!holon.__nomosOwnedScopeKey) throw new Error("this holon predates automatic .owned() key custody — upgrade @githolon/runtime");`,
|
|
5252
5060
|
` const _ownedKey = await holon.__nomosOwnedScopeKey({ scope: ${JSON.stringify(
|
|
5253
5061
|
Object.values(encFields)[0]!.scope
|
|
5254
5062
|
)}, record: _ownedRecord });`,
|
|
@@ -5277,7 +5085,7 @@ export function generateTsClient(
|
|
|
5277
5085
|
` if (!${key}) throw new EncryptionKeyUnavailable(${JSON.stringify(
|
|
5278
5086
|
descriptor.scope
|
|
5279
5087
|
)}, ${JSON.stringify(field)});`,
|
|
5280
|
-
` if (!holon.cryptoSealField) throw new Error("this holon predates E2E sealing — upgrade @githolon/
|
|
5088
|
+
` if (!holon.cryptoSealField) throw new Error("this holon predates E2E sealing — upgrade @githolon/runtime");`,
|
|
5281
5089
|
` const ${sealed} = ${value} == null ? ${value} : await holon.cryptoSealField({`,
|
|
5282
5090
|
` scopeKey: ${key}.key, scope: ${
|
|
5283
5091
|
descriptor.owned === true
|
|
@@ -5357,7 +5165,7 @@ export function generateTsClient(
|
|
|
5357
5165
|
.map((o) => `\`${o.aggregateId}\` (${o.marker})`)
|
|
5358
5166
|
.join(" + ")}.`
|
|
5359
5167
|
: "";
|
|
5360
|
-
const callAccess = new Map<string,
|
|
5168
|
+
const callAccess = new Map<string, TsCallProtoFieldAccess>();
|
|
5361
5169
|
const callExtraFields = new Map<
|
|
5362
5170
|
string,
|
|
5363
5171
|
{ readonly type: string; readonly optional?: true }
|
|
@@ -5392,6 +5200,8 @@ export function generateTsClient(
|
|
|
5392
5200
|
const idTarget = idOfMetaOf(fieldSchema);
|
|
5393
5201
|
if (idTarget !== undefined) {
|
|
5394
5202
|
const expected = JSON.stringify(idTarget);
|
|
5203
|
+
const referenceWorkspace = idOfTargetKindOf(fieldSchema) === "contract"
|
|
5204
|
+
? '\"\"' : "nmsInternalWorkspace";
|
|
5395
5205
|
const explicitOptionalChoice =
|
|
5396
5206
|
idOfMetaOf(rawSchema) !== undefined &&
|
|
5397
5207
|
["optional", "default"].includes(zodKind(rawSchema));
|
|
@@ -5399,18 +5209,20 @@ export function generateTsClient(
|
|
|
5399
5209
|
field,
|
|
5400
5210
|
explicitOptionalChoice
|
|
5401
5211
|
? {
|
|
5402
|
-
value: `_nmsOptionalReferenceId(${member}, ${expected},
|
|
5212
|
+
value: `_nmsOptionalReferenceId(${member}, ${expected}, ${referenceWorkspace}, ${JSON.stringify(
|
|
5403
5213
|
field
|
|
5404
5214
|
)})!`,
|
|
5405
|
-
present: `_nmsOptionalReferenceId(${member}, ${expected},
|
|
5215
|
+
present: `_nmsOptionalReferenceId(${member}, ${expected}, ${referenceWorkspace}, ${JSON.stringify(
|
|
5406
5216
|
field
|
|
5407
5217
|
)}) !== undefined`,
|
|
5218
|
+
canonical: true,
|
|
5408
5219
|
}
|
|
5409
5220
|
: {
|
|
5410
|
-
value: `_nmsReferenceId(${value}, ${expected},
|
|
5221
|
+
value: `_nmsReferenceId(${value}, ${expected}, ${referenceWorkspace}, ${JSON.stringify(
|
|
5411
5222
|
field
|
|
5412
5223
|
)})`,
|
|
5413
5224
|
...common,
|
|
5225
|
+
canonical: true,
|
|
5414
5226
|
}
|
|
5415
5227
|
);
|
|
5416
5228
|
} else if (refOfMetaOf(fieldSchema) !== undefined) {
|
|
@@ -5420,16 +5232,19 @@ export function generateTsClient(
|
|
|
5420
5232
|
refTarget.aggregateType
|
|
5421
5233
|
)}, "", ${JSON.stringify(field)})`,
|
|
5422
5234
|
...common,
|
|
5235
|
+
canonical: true,
|
|
5423
5236
|
});
|
|
5424
5237
|
} else if (versionedRefOfMetaOf(fieldSchema) !== undefined) {
|
|
5425
5238
|
callAccess.set(field, {
|
|
5426
5239
|
value: `({ pinned: _nmsReferenceData(${value}.pinned), series: _nmsReferenceData(${value}.series) })`,
|
|
5427
5240
|
...common,
|
|
5241
|
+
canonical: true,
|
|
5428
5242
|
});
|
|
5429
5243
|
} else if (recipientMetaOf(fieldSchema) !== undefined) {
|
|
5430
5244
|
callAccess.set(field, {
|
|
5431
5245
|
value: `_nmsRecipientAddress(${value}, ${JSON.stringify(field)})`,
|
|
5432
5246
|
...common,
|
|
5247
|
+
canonical: true,
|
|
5433
5248
|
});
|
|
5434
5249
|
} else {
|
|
5435
5250
|
callAccess.set(field, { value, ...common });
|
|
@@ -5487,7 +5302,7 @@ export function generateTsClient(
|
|
|
5487
5302
|
}: ${descriptor.type}`
|
|
5488
5303
|
)
|
|
5489
5304
|
.join("; ")} }`;
|
|
5490
|
-
const callEncoder =
|
|
5305
|
+
const callEncoder = emitTsCallProtoEncoder(
|
|
5491
5306
|
domainCallUsda!.graph,
|
|
5492
5307
|
domainCallUsda!.paths,
|
|
5493
5308
|
domain,
|
|
@@ -5767,13 +5582,14 @@ export function generateTsClient(
|
|
|
5767
5582
|
` ${lcFirst(
|
|
5768
5583
|
camel(sp.id)
|
|
5769
5584
|
)}: (bbox: { minX: number; minY: number; maxX: number; maxY: number } | { minLng: number; minLat: number; maxLng: number; maxLat: number }) => ${wrapP(
|
|
5770
|
-
|
|
5771
|
-
sp.id
|
|
5772
|
-
)}, bbox) as Promise<Row<${sp.of}>[]>`
|
|
5585
|
+
nominalRows(sp.of, `holon.__nomosSpatialWithinUsda(${JSON.stringify(sp.id)}, bbox)`)
|
|
5773
5586
|
)},`
|
|
5774
5587
|
);
|
|
5775
5588
|
}
|
|
5776
|
-
for (const
|
|
5589
|
+
for (const read of [...(mod.queries ?? []), ...(mod.orderedReads ?? [])]) {
|
|
5590
|
+
const ordered = "orderKey" in read ? read : undefined;
|
|
5591
|
+
// Shared row codecs; selection and cardinality remain properties of the law node.
|
|
5592
|
+
const q = "orderKey" in read ? { id: read.id, returns: read.of, key: [] as string[] } : read;
|
|
5777
5593
|
const agg = aggByType.get(q.returns);
|
|
5778
5594
|
const params = q.key
|
|
5779
5595
|
.map((k) => {
|
|
@@ -5797,7 +5613,7 @@ export function generateTsClient(
|
|
|
5797
5613
|
`TypeScript query USDA codegen: composed law is missing domain '${domain}'`
|
|
5798
5614
|
);
|
|
5799
5615
|
}
|
|
5800
|
-
const queryEncoder =
|
|
5616
|
+
const queryEncoder = emitTsQueryProtoEncoder(
|
|
5801
5617
|
renderedQueryLaw.graph,
|
|
5802
5618
|
renderedQueryLaw.paths,
|
|
5803
5619
|
domain,
|
|
@@ -5836,30 +5652,72 @@ export function generateTsClient(
|
|
|
5836
5652
|
})
|
|
5837
5653
|
);
|
|
5838
5654
|
out.push(...queryEncoder.source);
|
|
5655
|
+
const queryNode = renderedQueryLaw.graph.nodes.find(
|
|
5656
|
+
(node): node is LawRowReadNode =>
|
|
5657
|
+
node.kind === "read" &&
|
|
5658
|
+
(node.readKind === "query" || node.readKind === "ordered") &&
|
|
5659
|
+
node.entity.label === q.id,
|
|
5660
|
+
);
|
|
5661
|
+
const resultAggregate = resultUsdaByAggregate.get(q.returns);
|
|
5662
|
+
if (queryNode === undefined || resultAggregate === undefined) {
|
|
5663
|
+
throw new Error(
|
|
5664
|
+
`TypeScript query result codegen: '${domain}.${q.id}' has no generated realm result contract`,
|
|
5665
|
+
);
|
|
5666
|
+
}
|
|
5667
|
+
const resultRowKey = `${domain}\0${q.returns}`;
|
|
5668
|
+
const emitResultRowDecoder = !emittedResultRowDecoders.has(resultRowKey);
|
|
5669
|
+
const queryResultDecoder = emitTsQueryResultProtoDecoder(
|
|
5670
|
+
renderedQueryLaw.graph,
|
|
5671
|
+
renderedQueryLaw.paths,
|
|
5672
|
+
queryNode,
|
|
5673
|
+
resultAggregate,
|
|
5674
|
+
emitResultRowDecoder,
|
|
5675
|
+
);
|
|
5676
|
+
emittedResultRowDecoders.add(resultRowKey);
|
|
5677
|
+
out.push(...queryResultDecoder.source);
|
|
5839
5678
|
const nominalQuery = queryEncoder.call;
|
|
5840
5679
|
const qScopes = readScopesFor(q.returns);
|
|
5841
5680
|
const qOwned = qScopes.some((scope) => scope.owned === true);
|
|
5842
5681
|
const qScopeJson = JSON.stringify(qScopes);
|
|
5843
5682
|
const liveQueryRows = (keys?: string): string =>
|
|
5844
|
-
|
|
5845
|
-
|
|
5846
|
-
|
|
5847
|
-
|
|
5848
|
-
|
|
5849
|
-
|
|
5683
|
+
`(async () => ${queryResultDecoder.rowsFunction}(await holon.__nomosQuery(${nominalQuery}${
|
|
5684
|
+
keys === undefined ? "" : `, ${keys}`
|
|
5685
|
+
}), holon))()`;
|
|
5686
|
+
const historicQueryRows = (keys?: string): string =>
|
|
5687
|
+
`(async () => ${queryResultDecoder.rowsFunction}(await historic.__nomosQuery(${nominalQuery}${
|
|
5688
|
+
keys === undefined ? "" : `, ${keys}`
|
|
5689
|
+
}), holon))()`;
|
|
5690
|
+
const rowCallback = ordered?.limit === 1
|
|
5691
|
+
? `(records: NomosRecord<${q.returns}>[]) => cb(records[0] ?? null)` : "cb";
|
|
5850
5692
|
const nominalWatch = qScopes.length
|
|
5851
5693
|
? qOwned
|
|
5852
|
-
? `
|
|
5853
|
-
`_readWithOwnedKeys(holon, keyStore, ${qScopeJson}, (keys) => ${liveQueryRows(
|
|
5854
|
-
|
|
5855
|
-
|
|
5856
|
-
)}, cb)`
|
|
5857
|
-
: `_watchWithOwnedKeys((changed) => holon.__nomosWatchUsda(${nominalQuery}, () => changed(), opts), async () => ${wrapP(
|
|
5694
|
+
? `holon.__nomosWatchRows((changed) => holon.__nomosWatchUsda(${nominalQuery}, () => changed(), opts), () => ${wrapP(
|
|
5695
|
+
`_readWithOwnedKeys(holon, keyStore, ${qScopeJson}, (keys) => ${liveQueryRows("keys")})`
|
|
5696
|
+
)}, ${rowCallback})`
|
|
5697
|
+
: `holon.__nomosWatchRows((changed) => holon.__nomosWatchUsda(${nominalQuery}, () => changed(), opts), async () => ${wrapP(
|
|
5858
5698
|
liveQueryRows(`await _readKeys(holon, keyStore, ${qScopeJson})`)
|
|
5859
|
-
)},
|
|
5860
|
-
: `holon.
|
|
5861
|
-
|
|
5862
|
-
)}
|
|
5699
|
+
)}, ${rowCallback})`
|
|
5700
|
+
: `holon.__nomosWatchResults<NmsGeneratedResult, NomosRecord<${q.returns}>>((changed, failed) => holon.__nomosWatch(${nominalQuery}, changed, failed, opts), (result) => ${wrapRows(
|
|
5701
|
+
`${queryResultDecoder.rowsFunction}(result, holon)`
|
|
5702
|
+
)}, ${rowCallback})`;
|
|
5703
|
+
if (ordered !== undefined) {
|
|
5704
|
+
const resultType = ordered.limit === 1 ? `NomosRecord<${q.returns}> | null` : `NomosRecord<${q.returns}>[]`;
|
|
5705
|
+
const select = ordered.limit === 1 ? "rows[0] ?? null" : "rows";
|
|
5706
|
+
const withKeys = (rows: (keys?: string) => string): string => wrapP(qScopes.length
|
|
5707
|
+
? qOwned
|
|
5708
|
+
? `_readWithOwnedKeys(holon, keyStore, ${qScopeJson}, (keys) => ${rows("keys")})`
|
|
5709
|
+
: rows(`await _readKeys(holon, keyStore, ${qScopeJson})`)
|
|
5710
|
+
: rows());
|
|
5711
|
+
methods.push(
|
|
5712
|
+
` /** Declared ordered read, at most ${ordered.limit} visible records; no caller override. */`,
|
|
5713
|
+
` ${lcFirst(camel(q.id))}: async (): Promise<${resultType}> => { const rows = await (${withKeys(liveQueryRows)}); return ${select}; },`,
|
|
5714
|
+
` watch${cap(camel(q.id))}: (cb: (records: ${resultType}) => void, opts?: { intervalMs?: number }) => ${nominalWatch},`,
|
|
5715
|
+
);
|
|
5716
|
+
pastMethods.push(
|
|
5717
|
+
` ${lcFirst(camel(q.id))}: async (): Promise<${resultType}> => { const rows = await (${withKeys(historicQueryRows)}); return ${select}; },`,
|
|
5718
|
+
);
|
|
5719
|
+
continue; // ID-key pagination is not a value-order cursor.
|
|
5720
|
+
}
|
|
5863
5721
|
methods.push(
|
|
5864
5722
|
` /** @deprecated Whole-result reads scale with result size. Use ${lcFirst(
|
|
5865
5723
|
camel(q.id)
|
|
@@ -5899,42 +5757,24 @@ export function generateTsClient(
|
|
|
5899
5757
|
? ` ${lcFirst(
|
|
5900
5758
|
camel(q.id)
|
|
5901
5759
|
)}: async (params: { ${params} }) => ${wrapP(
|
|
5902
|
-
`_readWithOwnedKeys(holon, keyStore, ${qScopeJson}, (keys) => ${
|
|
5903
|
-
q.returns,
|
|
5904
|
-
`historic.__nomosQueryUsda(${nominalQuery}, keys)`
|
|
5905
|
-
)})`
|
|
5760
|
+
`_readWithOwnedKeys(holon, keyStore, ${qScopeJson}, (keys) => ${historicQueryRows("keys")})`
|
|
5906
5761
|
)},`
|
|
5907
5762
|
: ` ${lcFirst(
|
|
5908
5763
|
camel(q.id)
|
|
5909
5764
|
)}: async (params: { ${params} }) => ${wrapP(
|
|
5910
|
-
|
|
5911
|
-
q.returns,
|
|
5912
|
-
`historic.__nomosQueryUsda(${nominalQuery}, await _readKeys(holon, keyStore, ${qScopeJson}))`
|
|
5913
|
-
)
|
|
5765
|
+
historicQueryRows(`await _readKeys(holon, keyStore, ${qScopeJson})`)
|
|
5914
5766
|
)},`
|
|
5915
5767
|
: ` ${lcFirst(
|
|
5916
5768
|
camel(q.id)
|
|
5917
5769
|
)}: (params: { ${params} }) => ${wrapP(
|
|
5918
|
-
|
|
5919
|
-
q.returns,
|
|
5920
|
-
`historic.__nomosQueryUsda(${nominalQuery})`
|
|
5921
|
-
)
|
|
5770
|
+
historicQueryRows()
|
|
5922
5771
|
)},`
|
|
5923
5772
|
);
|
|
5924
5773
|
const queryPageCall = qScopes.length
|
|
5925
5774
|
? qOwned
|
|
5926
|
-
? `_readPageWithOwnedKeys(holon, keyStore, ${qScopeJson}, (keys) => ${
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
)})`
|
|
5930
|
-
: nominalPage(
|
|
5931
|
-
q.returns,
|
|
5932
|
-
`holon.__nomosQueryPageUsda(${nominalQuery}, page, await _readKeys(holon, keyStore, ${qScopeJson}))`
|
|
5933
|
-
)
|
|
5934
|
-
: nominalPage(
|
|
5935
|
-
q.returns,
|
|
5936
|
-
`holon.__nomosQueryPageUsda(${nominalQuery}, page)`
|
|
5937
|
-
);
|
|
5775
|
+
? `_readPageWithOwnedKeys(holon, keyStore, ${qScopeJson}, async (keys) => ${queryResultDecoder.pageFunction}(await holon.__nomosQueryPage(${nominalQuery}, page, keys), holon))`
|
|
5776
|
+
: `(async () => ${queryResultDecoder.pageFunction}(await holon.__nomosQueryPage(${nominalQuery}, page, await _readKeys(holon, keyStore, ${qScopeJson})), holon))()`
|
|
5777
|
+
: `(async () => ${queryResultDecoder.pageFunction}(await holon.__nomosQueryPage(${nominalQuery}, page), holon))()`;
|
|
5938
5778
|
methods.push(
|
|
5939
5779
|
` /** Bounded \`${q.id}\` read. This is the default estate-scale surface: stable opaque cursor, no whole-result hydration. */`,
|
|
5940
5780
|
` ${lcFirst(
|
|
@@ -5995,6 +5835,30 @@ export function generateTsClient(
|
|
|
5995
5835
|
)}: () => historic.count(${JSON.stringify(c.id)}),`
|
|
5996
5836
|
);
|
|
5997
5837
|
}
|
|
5838
|
+
for (const membership of (mod.exists_ ?? []).map(finishExists)) {
|
|
5839
|
+
const key = membership.by;
|
|
5840
|
+
const parameter = key == null ? "" : tsGroupParam(key);
|
|
5841
|
+
const field = key == null ? undefined : aggByType.get(membership.of)?.fields[key.split(".")[0]!];
|
|
5842
|
+
const groupType = field?.kind === "ref" ? tsBaseTypeOfField(field) : "string";
|
|
5843
|
+
const wire = field?.kind === "ref"
|
|
5844
|
+
? `_nmsReferenceId(${parameter}, ${JSON.stringify(field.refAggregateId ?? "")}, holon.workspace, ${JSON.stringify(key)})`
|
|
5845
|
+
: parameter;
|
|
5846
|
+
const args = `${JSON.stringify(membership.id)}${key == null ? "" : `, ${wire}`}`;
|
|
5847
|
+
const signature = `${lcFirst(camel(membership.id))}: async (${key == null ? "" : `${parameter}: ${groupType}`}): Promise<boolean>`;
|
|
5848
|
+
methods.push(
|
|
5849
|
+
` /** Declared membership, backed by the maintained count, never a row scan. */`,
|
|
5850
|
+
` ${signature} => {`,
|
|
5851
|
+
` if (typeof holon.count !== "function") throw new Error("Nomos runtime does not support declared membership reads");`,
|
|
5852
|
+
` return (await holon.count(${args})) > 0;`,
|
|
5853
|
+
` },`,
|
|
5854
|
+
);
|
|
5855
|
+
pastMethods.push(
|
|
5856
|
+
` ${signature} => {`,
|
|
5857
|
+
` if (typeof historic.count !== "function") throw new Error("Nomos runtime does not support historic declared membership reads");`,
|
|
5858
|
+
` return (await historic.count(${args})) > 0;`,
|
|
5859
|
+
` },`,
|
|
5860
|
+
);
|
|
5861
|
+
}
|
|
5998
5862
|
for (const s of (mod.sums ?? []).map((raw) => finishSum(raw))) {
|
|
5999
5863
|
const grouped = s.by != null;
|
|
6000
5864
|
const p = grouped ? tsGroupParam(s.by!) : "";
|
|
@@ -6042,6 +5906,35 @@ export function generateTsClient(
|
|
|
6042
5906
|
);
|
|
6043
5907
|
}
|
|
6044
5908
|
|
|
5909
|
+
for (const extremum of [...(mod.mins ?? []), ...(mod.maxes ?? [])].map(finishExtremum)) {
|
|
5910
|
+
const grouped = extremum.by != null;
|
|
5911
|
+
const parameter = grouped ? tsGroupParam(extremum.by!) : "";
|
|
5912
|
+
const groupField = grouped
|
|
5913
|
+
? aggByType.get(extremum.of)?.fields[extremum.by!.split(".")[0]!] as Field | undefined
|
|
5914
|
+
: undefined;
|
|
5915
|
+
const groupType = groupField?.kind === "ref" ? tsBaseTypeOfField(groupField) : "string";
|
|
5916
|
+
const groupWire = groupField?.kind === "ref"
|
|
5917
|
+
? `_nmsReferenceId(${parameter}, ${JSON.stringify(groupField.refAggregateId ?? "")}, holon.workspace, ${JSON.stringify(extremum.by)})`
|
|
5918
|
+
: parameter;
|
|
5919
|
+
const parameters = grouped ? `${parameter}: ${groupType}` : "";
|
|
5920
|
+
const arguments_ = `${JSON.stringify(extremum.id)}, ${JSON.stringify(extremum.kind)}${grouped ? `, ${groupWire}` : ""}`;
|
|
5921
|
+
const method = lcFirst(camel(extremum.id));
|
|
5922
|
+
methods.push(
|
|
5923
|
+
` /** Declared ${extremum.kind} \`${extremum.id}\`. Null means no contributing member; zero is a value. */`,
|
|
5924
|
+
` ${method}: async (${parameters}): Promise<number | null> => {`,
|
|
5925
|
+
` if (!holon.__nomosExtremum) throw new Error("Nomos runtime does not support declared extrema reads");`,
|
|
5926
|
+
` return holon.__nomosExtremum(${arguments_});`,
|
|
5927
|
+
` },`,
|
|
5928
|
+
);
|
|
5929
|
+
pastMethods.push(
|
|
5930
|
+
` /** Declared ${extremum.kind} \`${extremum.id}\` at this moment. */`,
|
|
5931
|
+
` ${method}: async (${parameters}): Promise<number | null> => {`,
|
|
5932
|
+
` if (!historic.__nomosExtremum) throw new Error("Nomos runtime does not support historic declared extrema reads");`,
|
|
5933
|
+
` return historic.__nomosExtremum(${arguments_});`,
|
|
5934
|
+
` },`,
|
|
5935
|
+
);
|
|
5936
|
+
}
|
|
5937
|
+
|
|
6045
5938
|
// ── BUSINESS MERGE CONFLICT DX: Nomos keeps its heterogeneous workspace index private. The
|
|
6046
5939
|
// generated surface exposes a summary, then aggregate-specific pending conflict references.
|
|
6047
5940
|
// Each reference owns the one lawful `merge(...)` action for its field — Git semantics: inspect
|
|
@@ -6108,7 +6001,7 @@ export function generateTsClient(
|
|
|
6108
6001
|
` * conflict is the typed capability that can merge itself. Nomos's raw index stays private. */`,
|
|
6109
6002
|
` conflicts: {`,
|
|
6110
6003
|
` summary: async (): Promise<${conflictSummaryType}> => {`,
|
|
6111
|
-
` if (!holon.__nomosPendingConflictSummaryUsda) throw new Error("conflicts need the current @githolon/
|
|
6004
|
+
` if (!holon.__nomosPendingConflictSummaryUsda) throw new Error("conflicts need the current @githolon/runtime");`,
|
|
6112
6005
|
` const summary = _nmsConflictUsdaSummary(await holon.__nomosPendingConflictSummaryUsda());`,
|
|
6113
6006
|
` const count = (aggregatePath: string): number => summary.byAggregate.find((entry) => entry.aggregatePath === aggregatePath)?.count ?? 0;`,
|
|
6114
6007
|
` return {`,
|
|
@@ -6165,7 +6058,7 @@ export function generateTsClient(
|
|
|
6165
6058
|
` /** Pending merges for ${aggregateId}. Querying creates typed merge references;`,
|
|
6166
6059
|
` * no aggregate id, field name, or directive id is supplied by the app. */`,
|
|
6167
6060
|
` pending: async (): Promise<Array<${pendingType}>> => {`,
|
|
6168
|
-
` if (!holon.__nomosPendingConflictsUsda) throw new Error("conflicts need the current @githolon/
|
|
6061
|
+
` if (!holon.__nomosPendingConflictsUsda) throw new Error("conflicts need the current @githolon/runtime");`,
|
|
6169
6062
|
` const rows = _nmsConflictUsdaRows(await holon.__nomosPendingConflictsUsda(${JSON.stringify(
|
|
6170
6063
|
runtimeAggregateType
|
|
6171
6064
|
)}));`,
|
|
@@ -6348,6 +6241,13 @@ export function generateTsClient(
|
|
|
6348
6241
|
methods.push(
|
|
6349
6242
|
` /** ${agg.id} identity and reads. Business actions remain application-level because one action may change many aggregate kinds. */`,
|
|
6350
6243
|
` ${collection}: {`,
|
|
6244
|
+
...(agg.implementsContracts ?? []).flatMap((contractId) => [
|
|
6245
|
+
` /** Expose the contract this aggregate declares, preserving its workspace and record id. This grants no access. */`,
|
|
6246
|
+
` as${contractTypeName(contractId)}: (record: NomosRecord<${agg.id}>): NomosRef<${contractTypeName(contractId)}> => {`,
|
|
6247
|
+
` const reference = record.ref; _nmsReferenceId(reference, ${JSON.stringify(agg.id)}, "", "record");`,
|
|
6248
|
+
` return _nmsRef<${contractTypeName(contractId)}>(reference.workspace, ${JSON.stringify(contractId)}, reference.id);`,
|
|
6249
|
+
` },`,
|
|
6250
|
+
]),
|
|
6351
6251
|
` /** Recover a typed reference from its stable public address. This identifies a record; it never grants authority. */`,
|
|
6352
6252
|
` fromAddress: (address: string): NomosRef<${
|
|
6353
6253
|
agg.id
|
|
@@ -6362,7 +6262,7 @@ export function generateTsClient(
|
|
|
6362
6262
|
agg.id
|
|
6363
6263
|
)}, "", "record");`,
|
|
6364
6264
|
` if (ref.workspace !== holon.workspace) {`,
|
|
6365
|
-
` if (!holon.__nomosOpenChild) throw new Error("opening this record needs the current @githolon/
|
|
6265
|
+
` if (!holon.__nomosOpenChild) throw new Error("opening this record needs the current @githolon/runtime");`,
|
|
6366
6266
|
` return (await ${tsClientFactoryName(
|
|
6367
6267
|
domain
|
|
6368
6268
|
)}(await holon.__nomosOpenChild(ref.workspace)).${collection}.find(record));`,
|
|
@@ -6381,17 +6281,15 @@ export function generateTsClient(
|
|
|
6381
6281
|
agg.id
|
|
6382
6282
|
)}, "", "record");`,
|
|
6383
6283
|
` if (ref.workspace !== holon.workspace) {`,
|
|
6384
|
-
`
|
|
6385
|
-
`
|
|
6386
|
-
` void holon.__nomosOpenChild(ref.workspace).then((child) => { if (active) stop = ${tsClientFactoryName(
|
|
6284
|
+
` if (!holon.__nomosOpenChild) throw new Error("opening this record needs the current @githolon/runtime");`,
|
|
6285
|
+
` return holon.__nomosWatchFollow(holon.__nomosOpenChild(ref.workspace), (child) => ${tsClientFactoryName(
|
|
6387
6286
|
domain
|
|
6388
|
-
)}(child).${collection}.watchOne(record, cb, opts)
|
|
6389
|
-
` return () => { active = false; stop(); };`,
|
|
6287
|
+
)}(child).${collection}.watchOne(record, cb, opts), () => cb(undefined));`,
|
|
6390
6288
|
` }`,
|
|
6391
6289
|
` const id = ref.id;`,
|
|
6392
6290
|
...(aScopes.length
|
|
6393
6291
|
? [
|
|
6394
|
-
` return
|
|
6292
|
+
` return holon.__nomosWatchRows((changed) => holon.__nomosWatchByIdUsda(${JSON.stringify(
|
|
6395
6293
|
runtimeType
|
|
6396
6294
|
)}, id, () => changed(), opts), async () => ${wrapP(
|
|
6397
6295
|
findRows
|
|
@@ -6461,7 +6359,7 @@ export function generateTsClient(
|
|
|
6461
6359
|
` /** Historic scrubbing in the same generated business language as live reads. */`,
|
|
6462
6360
|
` past: {`,
|
|
6463
6361
|
` moments: async (opts: { limit?: number } = {}): Promise<NomosMoment[]> => {`,
|
|
6464
|
-
` if (!holon.commits) throw new Error("past.moments() needs the current @githolon/
|
|
6362
|
+
` if (!holon.commits) throw new Error("past.moments() needs the current @githolon/runtime");`,
|
|
6465
6363
|
` const actions = new Set<string>(${JSON.stringify([
|
|
6466
6364
|
...dirs.map((directive) => directive.id),
|
|
6467
6365
|
...(correctionActions.length > 0
|
|
@@ -6483,7 +6381,7 @@ export function generateTsClient(
|
|
|
6483
6381
|
` }));`,
|
|
6484
6382
|
` },`,
|
|
6485
6383
|
` at: (moment: NomosMoment) => {`,
|
|
6486
|
-
` if (!holon.at) throw new Error("past.at() needs the current @githolon/
|
|
6384
|
+
` if (!holon.at) throw new Error("past.at() needs the current @githolon/runtime");`,
|
|
6487
6385
|
` const historic = holon.at(moment.id);`,
|
|
6488
6386
|
` return {`,
|
|
6489
6387
|
...pastMethods,
|
|
@@ -6526,7 +6424,7 @@ export function generateTsClient(
|
|
|
6526
6424
|
` ? "This part of the organisation was reclaimed. Its birth remains part of this workspace's history."`,
|
|
6527
6425
|
` : "This part of the organisation has a newer lifecycle this client does not understand. Its link remains visible.",`,
|
|
6528
6426
|
` open: async (): Promise<NomosDescription> => {`,
|
|
6529
|
-
` if (!holon.__nomosOpenChild) throw new Error("opening an organisation link needs the current @githolon/
|
|
6427
|
+
` if (!holon.__nomosOpenChild) throw new Error("opening an organisation link needs the current @githolon/runtime");`,
|
|
6530
6428
|
` return ${tsClientFactoryName(
|
|
6531
6429
|
domain
|
|
6532
6430
|
)}(await holon.__nomosOpenChild(child.workspace)).describe();`,
|
|
@@ -6662,19 +6560,21 @@ export function generateTsClient(
|
|
|
6662
6560
|
out.push(
|
|
6663
6561
|
`/** Framework binding for the generated application. Law identity, author identity and key custody`,
|
|
6664
6562
|
` * are captured from the connected stateful client; callers cannot override them. */`,
|
|
6665
|
-
`/** THE HOLON-LEVEL FACTORY — the
|
|
6666
|
-
` *
|
|
6563
|
+
`/** THE HOLON-LEVEL FACTORY — the code-mode binding of this application's Reception. Binds`,
|
|
6564
|
+
` * to the peer's holon however it was opened: a full \`connect()\` holon, or the thin remote holon`,
|
|
6667
6565
|
` * (\`connectRemote\`) for isolates that live beside the edge. The application surface`,
|
|
6668
|
-
` * (\`
|
|
6566
|
+
` * (\`receive<Name>Application\`) remains the batteries-included entry for devices. The binding is`,
|
|
6567
|
+
` * opaque to tenant code: the peer runtime hands it in; its members are not a tenant surface. */`,
|
|
6669
6568
|
`${
|
|
6670
6569
|
opts.exportHolonFactory === true ? "export " : ""
|
|
6671
|
-
}function ${tsClientFactoryName(domain)}(
|
|
6570
|
+
}function ${tsClientFactoryName(domain)}(binding: NomosHolonBinding) {`,
|
|
6571
|
+
` const holon = binding as unknown as NomosHolon;`,
|
|
6672
6572
|
` const domainHash = ${hashConst};`,
|
|
6673
6573
|
` const actor = holon.principal;`,
|
|
6674
6574
|
...(activityPresent
|
|
6675
6575
|
? [
|
|
6676
|
-
` const _nomosActivityLog = (opts?: { base?: string; limit?: number }) => { if (!holon.activityLog) throw new Error("activity reads need a custody-capable @githolon/
|
|
6677
|
-
` const _nomosWatchActivity = (cb: (rows: ActivityRawRow[]) => void, opts?: { base?: string; intervalMs?: number }) => { if (!holon.watchActivity) throw new Error("activity watches need a custody-capable @githolon/
|
|
6576
|
+
` const _nomosActivityLog = (opts?: { base?: string; limit?: number }) => { if (!holon.activityLog) throw new Error("activity reads need a custody-capable @githolon/runtime binding"); return holon.activityLog(opts); };`,
|
|
6577
|
+
` const _nomosWatchActivity = (cb: (rows: ActivityRawRow[]) => void, opts?: { base?: string; intervalMs?: number }) => { if (!holon.watchActivity) throw new Error("activity watches need a custody-capable @githolon/runtime binding"); return holon.watchActivity(cb, opts); };`,
|
|
6678
6578
|
]
|
|
6679
6579
|
: []),
|
|
6680
6580
|
` holon.prepareDomain?.(${JSON.stringify(domain)}, domainHash);`,
|
|
@@ -6682,7 +6582,7 @@ export function generateTsClient(
|
|
|
6682
6582
|
? [
|
|
6683
6583
|
` const keyStore: NomosKeyStore | undefined = ${
|
|
6684
6584
|
domScopes.length > 0
|
|
6685
|
-
? `{ scopeKey: async (scope) => { if (!holon.__nomosScopeKey) throw new Error("encrypted business data needs the current @githolon/
|
|
6585
|
+
? `{ scopeKey: async (scope) => { if (!holon.__nomosScopeKey) throw new Error("encrypted business data needs the current @githolon/runtime"); return holon.__nomosScopeKey({ scope }); }, readKeys: async (scopes) => { if (!holon.__nomosScopeKeys) throw new Error("encrypted business data needs the current @githolon/runtime"); return holon.__nomosScopeKeys({ scopes }); } }`
|
|
6686
6586
|
: "undefined"
|
|
6687
6587
|
};`,
|
|
6688
6588
|
]
|
|
@@ -6699,7 +6599,7 @@ export function generateTsClient(
|
|
|
6699
6599
|
)}, domain: ${JSON.stringify(
|
|
6700
6600
|
domain
|
|
6701
6601
|
)}, domainHash }).catch((error) => { _ownedReadyError = error; })`,
|
|
6702
|
-
` : Promise.resolve().then(() => { _ownedReadyError = new Error("owned records need the current @githolon/
|
|
6602
|
+
` : Promise.resolve().then(() => { _ownedReadyError = new Error("owned records need the current @githolon/runtime"); });`,
|
|
6703
6603
|
` const _ownedRecordAction = async (action: "share" | "unshare" | "transfer", record: NomosRef<_NomosAnyAggregate>, peer: string): Promise<void> => {`,
|
|
6704
6604
|
` await _ownedReady;`,
|
|
6705
6605
|
` if (_ownedReadyError !== undefined) throw _ownedReadyError;`,
|
|
@@ -6708,7 +6608,7 @@ export function generateTsClient(
|
|
|
6708
6608
|
` const directiveId = _ownedActions[recordData.type]?.[action];`,
|
|
6709
6609
|
` if (directiveId === undefined) throw new Error(\`${"${action}()"} needs a generated owned record reference\`);`,
|
|
6710
6610
|
` if (!peer.trim()) throw new Error(\`${"${action}()"} needs the person to act with\`);`,
|
|
6711
|
-
` if (!holon.__nomosPrepareOwnedRecordAction) throw new Error("record sharing needs the current @githolon/
|
|
6611
|
+
` if (!holon.__nomosPrepareOwnedRecordAction) throw new Error("record sharing needs the current @githolon/runtime");`,
|
|
6712
6612
|
` switch (directiveId) {`,
|
|
6713
6613
|
...[...ownedActionCallEncoders]
|
|
6714
6614
|
.sort(([left], [right]) => left.localeCompare(right))
|
|
@@ -6725,53 +6625,25 @@ export function generateTsClient(
|
|
|
6725
6625
|
` };`,
|
|
6726
6626
|
]
|
|
6727
6627
|
: []),
|
|
6728
|
-
...(opts.
|
|
6628
|
+
...(opts.kernelContracts !== undefined
|
|
6729
6629
|
? [
|
|
6730
6630
|
clientInterface !== undefined
|
|
6731
|
-
? ` holon.checkCompat?.(${
|
|
6732
|
-
|
|
6733
|
-
|
|
6734
|
-
|
|
6735
|
-
|
|
6736
|
-
opts.packageName
|
|
6737
|
-
)}.kernelContracts ?? [], { lawHash: ${compatConstName(
|
|
6738
|
-
opts.packageName
|
|
6739
|
-
)}.lawHash });`,
|
|
6631
|
+
? ` holon.checkCompat?.(${interfaceConstName(opts.packageName)});`
|
|
6632
|
+
: ` void 0;`,
|
|
6633
|
+
` holon.assertKernelCoherence?.(${JSON.stringify(
|
|
6634
|
+
opts.kernelContracts
|
|
6635
|
+
)}, { lawHash: ${hashConst} });`,
|
|
6740
6636
|
]
|
|
6741
6637
|
: []),
|
|
6742
|
-
`
|
|
6638
|
+
` const _application = {`,
|
|
6743
6639
|
` domain: ${JSON.stringify(domain)} as const,`,
|
|
6744
|
-
` domainHash,`,
|
|
6745
|
-
` /** Adopt THIS generated model. Nomos proves it against current history; a deliberate`,
|
|
6746
|
-
` * difference returns a decision whose accept(reason) re-proves and records the reason. */`,
|
|
6747
|
-
` model: {`,
|
|
6748
|
-
` adopt: (): Promise<NomosModelAdoption> => _nomosAdoptModel(holon, ${JSON.stringify(
|
|
6749
|
-
domain
|
|
6750
|
-
)}, domainHash${
|
|
6751
|
-
opts.lawAssetName === undefined
|
|
6752
|
-
? ""
|
|
6753
|
-
: `, new URL(${JSON.stringify(
|
|
6754
|
-
`./${opts.lawAssetName}`
|
|
6755
|
-
)}, import.meta.url)`
|
|
6756
|
-
}),`,
|
|
6757
|
-
` restorePrevious: (): Promise<NomosModelRestoration> => _nomosRestorePreviousModel(holon, ${JSON.stringify(
|
|
6758
|
-
domain
|
|
6759
|
-
)}, domainHash),`,
|
|
6760
|
-
` },`,
|
|
6761
|
-
...(clientInterface !== undefined
|
|
6762
|
-
? [
|
|
6763
|
-
` interface: ${interfaceConstName(
|
|
6764
|
-
opts.packageName
|
|
6765
|
-
)}[${JSON.stringify(domain)}],`,
|
|
6766
|
-
]
|
|
6767
|
-
: []),
|
|
6768
6640
|
...(ownedScope !== undefined && ownedWritesAvailable
|
|
6769
6641
|
? [
|
|
6770
6642
|
` /** Opt into all-device-loss recovery with one explicitly designated person. Nomos owns the handoff. */`,
|
|
6771
6643
|
` recovery: {`,
|
|
6772
6644
|
` protectWith: async (person: string): Promise<{ status: "protected"; recoveryPrincipal: string; unchanged?: boolean }> => {`,
|
|
6773
6645
|
` if (!person.trim()) throw new Error("recovery.protectWith() needs the person who will recover you");`,
|
|
6774
|
-
` if (!holon.__nomosProtectOwnedIdentity) throw new Error("recovery.protectWith() needs the current @githolon/
|
|
6646
|
+
` if (!holon.__nomosProtectOwnedIdentity) throw new Error("recovery.protectWith() needs the current @githolon/runtime");`,
|
|
6775
6647
|
` return holon.__nomosProtectOwnedIdentity({ scope: ${JSON.stringify(
|
|
6776
6648
|
ownedScope
|
|
6777
6649
|
)}, domain: ${JSON.stringify(
|
|
@@ -6782,7 +6654,7 @@ export function generateTsClient(
|
|
|
6782
6654
|
` /** Add another of this person's devices through one opaque request and approval. */`,
|
|
6783
6655
|
` devices: {`,
|
|
6784
6656
|
` request: async (): Promise<NomosDeviceRequest> => {`,
|
|
6785
|
-
` if (!holon.__nomosOwnedDeviceRequest) throw new Error("devices.request() needs the current @githolon/
|
|
6657
|
+
` if (!holon.__nomosOwnedDeviceRequest) throw new Error("devices.request() needs the current @githolon/runtime");`,
|
|
6786
6658
|
` return await holon.__nomosOwnedDeviceRequest({ scope: ${JSON.stringify(
|
|
6787
6659
|
ownedScope
|
|
6788
6660
|
)} });`,
|
|
@@ -6790,7 +6662,7 @@ export function generateTsClient(
|
|
|
6790
6662
|
` approve: async (request: NomosDeviceRequest): Promise<void> => {`,
|
|
6791
6663
|
` const principal = actor ?? holon.principal;`,
|
|
6792
6664
|
` if (!principal || !principal.trim()) throw new Error("devices.approve() needs a signed-in Nomos session");`,
|
|
6793
|
-
` if (!holon.__nomosPrepareOwnedDeviceApproval) throw new Error("devices.approve() needs the current @githolon/
|
|
6665
|
+
` if (!holon.__nomosPrepareOwnedDeviceApproval) throw new Error("devices.approve() needs the current @githolon/runtime");`,
|
|
6794
6666
|
` const payload = await holon.__nomosPrepareOwnedDeviceApproval({ request, scope: ${JSON.stringify(
|
|
6795
6667
|
ownedScope
|
|
6796
6668
|
)} });`,
|
|
@@ -6812,6 +6684,14 @@ export function generateTsClient(
|
|
|
6812
6684
|
: []),
|
|
6813
6685
|
...methods,
|
|
6814
6686
|
` };`,
|
|
6687
|
+
...(dirs.some(command => refusalContracts(mod, command.id).length > 0) ? [
|
|
6688
|
+
` return { ..._application,`,
|
|
6689
|
+
...dirs.filter(command => refusalContracts(mod, command.id).length > 0).map(command => {
|
|
6690
|
+
const method = (command as { businessBirth?: unknown }).businessBirth !== undefined && !isBusinessIntent(command) ? "birth" : command.id;
|
|
6691
|
+
return ` decide${cap(camel(command.id))}: (...args: Parameters<typeof _application.${method}>) => _admissionDecision(() => _application.${method}(...args), ${tsRefusalDecoder(mod, command.id)}),`;
|
|
6692
|
+
}),
|
|
6693
|
+
` };`,
|
|
6694
|
+
] : [` return _application;`]),
|
|
6815
6695
|
`}`,
|
|
6816
6696
|
``
|
|
6817
6697
|
);
|
|
@@ -6881,6 +6761,7 @@ export function generateTsClient(
|
|
|
6881
6761
|
"encryption",
|
|
6882
6762
|
"recovery",
|
|
6883
6763
|
"devices",
|
|
6764
|
+
...invitationPolicies.map((policy) => policy.pendingMethod),
|
|
6884
6765
|
...internalApplicationDirectiveMembers,
|
|
6885
6766
|
...applicationBirths.map((birth) => birth.method),
|
|
6886
6767
|
] as const;
|
|
@@ -6923,25 +6804,9 @@ export function generateTsClient(
|
|
|
6923
6804
|
),
|
|
6924
6805
|
`type _${applicationName}Business = ${applicationType};`,
|
|
6925
6806
|
`export type ${applicationName}Status = _NomosApplicationStatus;`,
|
|
6926
|
-
`export
|
|
6927
|
-
` readonly operation: "open" | "offer" | "birth" | "read" | "sync" | "maintenance";`,
|
|
6928
|
-
` readonly name: string; readonly durationMs: number; readonly domain?: string; readonly directive?: string;`,
|
|
6929
|
-
`}`,
|
|
6930
|
-
`export type ${applicationName} = _${applicationName}Business & _NomosApplicationParticipant & _NomosApplicationLifecycle & _NomosApplicationModelLifecycle${
|
|
6807
|
+
`export type ${applicationName} = _${applicationName}Business & _NomosApplicationParticipant & _NomosApplicationLifecycle${
|
|
6931
6808
|
hasInvitations ? " & _NomosApplicationInvitations" : ""
|
|
6932
6809
|
};`,
|
|
6933
|
-
`export interface ${applicationName}OpenOptions {`,
|
|
6934
|
-
` /** Nomos Cloud serving this deployed application. Configure it once at the app boundary. */`,
|
|
6935
|
-
` readonly cloud: string;`,
|
|
6936
|
-
` /** The deployed business application anchor, configured once at the app boundary. */`,
|
|
6937
|
-
` readonly application: string;`,
|
|
6938
|
-
` /** Return the signed-in authority credential; when supplied, bind its opaque device challenge. */`,
|
|
6939
|
-
` readonly signIn: (request?: { readonly deviceChallenge?: string }) => Promise<string>;`,
|
|
6940
|
-
` /** Typed timings for developer tooling; Nomos routing, credentials and Git custody remain private. */`,
|
|
6941
|
-
` readonly onPerformance?: (sample: ${applicationName}PerformanceSample) => void;`,
|
|
6942
|
-
` /** Supply the accountable business decision when this client intentionally changes the deployed model. */`,
|
|
6943
|
-
` readonly approveModel?: (decision: { readonly summary: string; readonly review: NomosModelReview }) => Promise<{ readonly because: string }>;`,
|
|
6944
|
-
`}`,
|
|
6945
6810
|
`function _nomosPublicDomain<T extends Record<string, unknown>>(domain: T): _NomosPublicDomain<T> {`,
|
|
6946
6811
|
` const application: Record<string, unknown> = {};`,
|
|
6947
6812
|
` const privateMembers = new Set<string>(${JSON.stringify(
|
|
@@ -6950,10 +6815,11 @@ export function generateTsClient(
|
|
|
6950
6815
|
` for (const [name, value] of Object.entries(domain)) if (!privateMembers.has(name)) application[name] = value;`,
|
|
6951
6816
|
` return application as _NomosPublicDomain<T>;`,
|
|
6952
6817
|
`}`,
|
|
6953
|
-
`function
|
|
6818
|
+
`function _nomosReceive${applicationName}(`,
|
|
6954
6819
|
` holon: NomosHolon,`,
|
|
6955
6820
|
` user: { readonly identityId: string; readonly identityAddress: string },`,
|
|
6956
|
-
`
|
|
6821
|
+
` reception: _NomosReceptionSession<NomosHolon>,`,
|
|
6822
|
+
`): _${applicationName}Business & _NomosApplicationParticipant${
|
|
6957
6823
|
hasInvitations ? " & _NomosApplicationInvitations" : ""
|
|
6958
6824
|
} {`,
|
|
6959
6825
|
...clientDomains.map(
|
|
@@ -6965,9 +6831,6 @@ export function generateTsClient(
|
|
|
6965
6831
|
.join(", ")}] as const;`,
|
|
6966
6832
|
` const application: Record<string, unknown> = {};`,
|
|
6967
6833
|
` application.currentUser = { identity: { id: user.identityId, address: user.identityAddress } } as User;`,
|
|
6968
|
-
` application.model = _nmsRoot${clientDomains.indexOf(
|
|
6969
|
-
homeDomain
|
|
6970
|
-
)}.model;`,
|
|
6971
6834
|
...(hasInvitations
|
|
6972
6835
|
? [
|
|
6973
6836
|
` for (const reserved of ["recipient", "createInvitation", "redeemInvitation"] as const) {`,
|
|
@@ -6978,12 +6841,10 @@ export function generateTsClient(
|
|
|
6978
6841
|
` if (!value) throw new TypeError("recipient(uid) needs the identity provider user id");`,
|
|
6979
6842
|
` return _nmsRecipient<User>("user:" + value);`,
|
|
6980
6843
|
` };`,
|
|
6981
|
-
|
|
6982
|
-
|
|
6983
|
-
|
|
6984
|
-
|
|
6985
|
-
invitationPolicies
|
|
6986
|
-
)}, _nmsFrameworkCalls);`,
|
|
6844
|
+
` application.createInvitation = async (): Promise<Invitation<User>> =>`,
|
|
6845
|
+
` _nmsInvitation<User>(await reception.createInvitation());`,
|
|
6846
|
+
` application.redeemInvitation = (link: string): Promise<void> =>`,
|
|
6847
|
+
` reception.redeemInvitation(link, ${invitationPoliciesExpression}, _nmsFrameworkCalls);`,
|
|
6987
6848
|
]
|
|
6988
6849
|
: []),
|
|
6989
6850
|
` const privateMembers = new Set<string>(${JSON.stringify(
|
|
@@ -7025,18 +6886,11 @@ export function generateTsClient(
|
|
|
7025
6886
|
birth.method
|
|
7026
6887
|
)}](input);`,
|
|
7027
6888
|
` const address = _nmsReferenceData(root);`,
|
|
7028
|
-
` const
|
|
7029
|
-
`
|
|
7030
|
-
` address.workspace,`,
|
|
7031
|
-
` (child) => _nomosPublicDomain(${tsClientFactoryName(
|
|
6889
|
+
` const followed = await reception.follow(address.workspace);`,
|
|
6890
|
+
` const child = _nomosPublicDomain(${tsClientFactoryName(
|
|
7032
6891
|
birth.targetDomain
|
|
7033
|
-
)}(
|
|
7034
|
-
`
|
|
7035
|
-
` const creationReceipt = (async (): Promise<void> => {`,
|
|
7036
|
-
` await holon.sync?.();`,
|
|
7037
|
-
` if (!holon.settleBirth) throw new Error("birth() requires the current @githolon/client to prove remote custody convergence");`,
|
|
7038
|
-
` await holon.settleBirth(address.workspace);`,
|
|
7039
|
-
` })();`,
|
|
6892
|
+
)}(followed.reception.desk));`,
|
|
6893
|
+
` const creationReceipt = followed.settled;`,
|
|
7040
6894
|
` void creationReceipt.catch(() => {});`,
|
|
7041
6895
|
` Object.defineProperty(child, "creationReceipt", { value: creationReceipt, enumerable: true, configurable: false, writable: false });`,
|
|
7042
6896
|
` return child as ${birth.applicationType};`,
|
|
@@ -7093,7 +6947,7 @@ export function generateTsClient(
|
|
|
7093
6947
|
` }`,
|
|
7094
6948
|
` throw unsupported ?? new Error(name + " needs a generated owned record reference");`,
|
|
7095
6949
|
` };`,
|
|
7096
|
-
` return application as unknown as _${applicationName}Business & _NomosApplicationParticipant
|
|
6950
|
+
` return application as unknown as _${applicationName}Business & _NomosApplicationParticipant${
|
|
7097
6951
|
hasInvitations ? " & _NomosApplicationInvitations" : ""
|
|
7098
6952
|
};`,
|
|
7099
6953
|
`}`,
|
|
@@ -7204,41 +7058,35 @@ export function generateTsClient(
|
|
|
7204
7058
|
` },`,
|
|
7205
7059
|
]),
|
|
7206
7060
|
`};`,
|
|
7207
|
-
|
|
7208
|
-
|
|
7209
|
-
|
|
7210
|
-
|
|
7211
|
-
|
|
7212
|
-
|
|
7213
|
-
|
|
7214
|
-
|
|
7215
|
-
|
|
7216
|
-
`
|
|
7217
|
-
|
|
7218
|
-
`export
|
|
7219
|
-
`
|
|
7220
|
-
`
|
|
7061
|
+
`/** Reception presents the generated business vocabulary for one Peer Office application desk.`,
|
|
7062
|
+
` * The compiler contributes no custody, sync, credential, placement or law lifecycle. */`,
|
|
7063
|
+
`export function ${applicationReception}(reception: _NomosReceptionSession<NomosHolonBinding>): ${applicationName} {`,
|
|
7064
|
+
` const session = reception as unknown as _NomosReceptionSession<NomosHolon>;`,
|
|
7065
|
+
` const application = _nomosReceive${applicationName}(session.desk, session.user, session) as ${applicationName};`,
|
|
7066
|
+
` Object.defineProperty(application, "currentStatus", { value: () => reception.status.current(), enumerable: false });`,
|
|
7067
|
+
` Object.defineProperty(application, "watchStatus", { value: (listener: (status: _NomosApplicationStatus) => void) => reception.status.watch(listener), enumerable: false });`,
|
|
7068
|
+
` Object.defineProperty(application, "close", { value: () => reception.close(), enumerable: false });`,
|
|
7069
|
+
` return application;`,
|
|
7070
|
+
`}`,
|
|
7071
|
+
`/** Immutable compiler output. Peer Office compares this requirement with each workspace's current law. */`,
|
|
7072
|
+
`export const ${applicationName}Definition = {`,
|
|
7073
|
+
` name: ${JSON.stringify(opts.packageName)},`,
|
|
7074
|
+
` compatibility: {`,
|
|
7075
|
+
` lawIdentity: sha256Digest(${hashConst}),`,
|
|
7076
|
+
` matrixUsda: ${clientInterface === undefined ? "new Uint8Array()" : interfaceConstName(opts.packageName)},`,
|
|
7077
|
+
` readyCommands: [${rootBirths
|
|
7221
7078
|
.map(
|
|
7222
7079
|
(birth) =>
|
|
7223
7080
|
`{ domain: ${JSON.stringify(
|
|
7224
7081
|
birth.sourceDomain
|
|
7225
|
-
)}, packageHash: ${hashConst}, directiveId: ${JSON.stringify(
|
|
7082
|
+
)}, packageHash: sha256Digest(${hashConst}), directiveId: ${JSON.stringify(
|
|
7226
7083
|
birth.directiveId
|
|
7227
7084
|
)} }`
|
|
7228
7085
|
)
|
|
7229
|
-
.join(", ")}]
|
|
7230
|
-
`
|
|
7231
|
-
`
|
|
7232
|
-
`}
|
|
7233
|
-
...(clientInterface === undefined
|
|
7234
|
-
? []
|
|
7235
|
-
: [
|
|
7236
|
-
`// Compiler tooling compares the requirement carried by the client that will actually ship.`,
|
|
7237
|
-
`// A global symbol keeps this off tenant autocomplete while avoiding a duplicate sidecar.`,
|
|
7238
|
-
`Object.defineProperty(${applicationOpener}, Symbol.for("nomos.generated-interface"), { value: ${interfaceConstName(
|
|
7239
|
-
opts.packageName
|
|
7240
|
-
)}, enumerable: false });`,
|
|
7241
|
-
]),
|
|
7086
|
+
.join(", ")}],`,
|
|
7087
|
+
` },`,
|
|
7088
|
+
` receive: ${applicationReception},`,
|
|
7089
|
+
`} satisfies _NomosGeneratedApplication<NomosHolon, ${applicationName}>;`,
|
|
7242
7090
|
``
|
|
7243
7091
|
);
|
|
7244
7092
|
}
|