@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/read.ts
CHANGED
|
@@ -172,6 +172,56 @@ export function readFrameworkDeclaredRows<
|
|
|
172
172
|
return z.array(row).parse(readFrameworkDeclared(query.id, args));
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
+
/**
|
|
176
|
+
* Typed framework foreign read. This is the attested twin of
|
|
177
|
+
* {@link readFrameworkDeclaredRows}: the aggregate declaration remains the
|
|
178
|
+
* only field/type source, while the ordinary foreign-read lane captures the
|
|
179
|
+
* source kernel's proof on the authored intent.
|
|
180
|
+
*
|
|
181
|
+
* Framework laws use this when an admitted local transition copies a typed
|
|
182
|
+
* value from another sovereign workspace. The peer may cache and relay the
|
|
183
|
+
* attestation, but neither it nor a generated application client decodes or
|
|
184
|
+
* vouches for the returned rows.
|
|
185
|
+
*/
|
|
186
|
+
export function readFrameworkAttestedRows<
|
|
187
|
+
const Id extends string,
|
|
188
|
+
F extends Record<string, Field>,
|
|
189
|
+
>(
|
|
190
|
+
query: QueryDecl,
|
|
191
|
+
aggregate: AggregateHandle<Id, F>,
|
|
192
|
+
args: Record<string, string>,
|
|
193
|
+
from: string,
|
|
194
|
+
): Array<ReadModelRow<F>> {
|
|
195
|
+
if (query.returns !== aggregate.id) {
|
|
196
|
+
throw new Error(
|
|
197
|
+
`framework attested read '${query.id}' returns '${query.returns}', not '${aggregate.id}'`,
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
const fields = aggregate.fields as Record<string, Field>;
|
|
201
|
+
const shape = Object.fromEntries(
|
|
202
|
+
Object.entries(fields).map(([name, field]) => [name, field.zod.optional()]),
|
|
203
|
+
) as ProjectionShape<F>;
|
|
204
|
+
const data = z.object(shape).strip() as z.ZodType<ReadModelRow<F>>;
|
|
205
|
+
const envelope = z.object({ data: z.unknown() }).passthrough();
|
|
206
|
+
const row = z.union([envelope, z.unknown()])
|
|
207
|
+
.transform((value) => {
|
|
208
|
+
const wrapped = envelope.safeParse(value);
|
|
209
|
+
const projected = wrapped.success ? wrapped.data.data : value;
|
|
210
|
+
if (projected === null || typeof projected !== "object" || Array.isArray(projected)) {
|
|
211
|
+
return projected;
|
|
212
|
+
}
|
|
213
|
+
const lifted = { ...(projected as Record<string, unknown>) };
|
|
214
|
+
for (const name in fields) {
|
|
215
|
+
if (fields[name]?.kind !== "bool") continue;
|
|
216
|
+
if (lifted[name] === "true") lifted[name] = true;
|
|
217
|
+
else if (lifted[name] === "false") lifted[name] = false;
|
|
218
|
+
}
|
|
219
|
+
return lifted;
|
|
220
|
+
})
|
|
221
|
+
.pipe(data);
|
|
222
|
+
return z.array(row).parse(read(query, args, { from }));
|
|
223
|
+
}
|
|
224
|
+
|
|
175
225
|
function readForeign<T = unknown>(query: QueryDecl | { id: string }, args: Record<string, string>, from: string): T {
|
|
176
226
|
// ── THE FOREIGN (attested cross-workspace) LANE (slice B — attested_reads_design.md §4.1).
|
|
177
227
|
// The port answers the `{rows, attestation}` wrapper: at AUTHOR the kernel verified the
|
package/src/relation.ts
CHANGED
|
@@ -99,7 +99,10 @@ export interface RelationDecl {
|
|
|
99
99
|
|
|
100
100
|
/** Stage 1 of the builder: id + the two endpoints. */
|
|
101
101
|
class RelationSourceStep<Id extends string> {
|
|
102
|
-
|
|
102
|
+
private readonly id: Id;
|
|
103
|
+
constructor(id: Id) {
|
|
104
|
+
this.id = id;
|
|
105
|
+
}
|
|
103
106
|
/** Declare the SOURCE → TARGET endpoints (aggregate TYPE ids). */
|
|
104
107
|
endpoints(source: string, target: string): RelationProposesStep<Id> {
|
|
105
108
|
return new RelationProposesStep(this.id, source, target);
|
package/src/relation_schema.ts
CHANGED
|
@@ -198,9 +198,11 @@ export function mergeRelationTypeDeclarations(
|
|
|
198
198
|
// Framework-owned declarations can cross the published-CLI/package bundle boundary as
|
|
199
199
|
// distinct object identities. The private brand plus byte-identical definition identifies
|
|
200
200
|
// that one canonical concept; tenant-authored collisions remain a loud hard failure.
|
|
201
|
+
// A tenant may also re-export the framework's own fragment (e.g. `workspaceOperatorRelations`,
|
|
202
|
+
// which a business birth composes too): one side branded and byte-identical is that same concept.
|
|
201
203
|
const repeatedFrameworkDeclaration =
|
|
202
|
-
(first as RelationTypeDecl & { businessBirthInternal?: boolean }).businessBirthInternal === true
|
|
203
|
-
|
|
204
|
+
((first as RelationTypeDecl & { businessBirthInternal?: boolean }).businessBirthInternal === true ||
|
|
205
|
+
(declaration as RelationTypeDecl & { businessBirthInternal?: boolean }).businessBirthInternal === true) &&
|
|
204
206
|
JSON.stringify(existing) === JSON.stringify(definition);
|
|
205
207
|
if (repeatedFrameworkDeclaration) continue;
|
|
206
208
|
throw new Error(
|
|
@@ -398,6 +400,17 @@ export function relationType(type: string, caps?: Partial<RelationCaps>): Relati
|
|
|
398
400
|
relation(name: string, opts?: { rewrite?: Rewrite; allow?: AllowedSubject[] }): RelationTypeBuilder {
|
|
399
401
|
requireName(name, "relation");
|
|
400
402
|
if (relations.has(name)) throw new Error(`relationType("${type}"): relation "${name}" declared twice`);
|
|
403
|
+
// Law is compiled without a type check, so an option this builder does not know would otherwise
|
|
404
|
+
// vanish silently — a declared intent the compiled law never carries.
|
|
405
|
+
for (const option of Object.keys(opts ?? {})) {
|
|
406
|
+
if (option === "rewrite" || option === "allow") continue;
|
|
407
|
+
throw new Error(
|
|
408
|
+
option === "seededFromParent"
|
|
409
|
+
? `relationType("${type}"): relation "${name}" cannot be seeded from the parent; only the framework's own ` +
|
|
410
|
+
`operator relation is carried at birth (identity_target_model.md D19)`
|
|
411
|
+
: `relationType("${type}"): relation "${name}" has unknown option "${option}"`,
|
|
412
|
+
);
|
|
413
|
+
}
|
|
401
414
|
const allowed = opts?.allow ?? [];
|
|
402
415
|
validateAllowed(type, name, allowed);
|
|
403
416
|
relations.set(name, { rewrite: opts?.rewrite ?? null, allowed });
|
package/src/report.ts
CHANGED
|
@@ -60,14 +60,14 @@ import {
|
|
|
60
60
|
|
|
61
61
|
/**
|
|
62
62
|
* The declarative query AST a `.select` produces. Mirrors the Rust
|
|
63
|
-
* `
|
|
63
|
+
* `deterministic_rquickjs::query_port::QueryAst` (tagged union). The HOST resolves this; the
|
|
64
64
|
* author only constructs it via the fluent `SelectBuilder`.
|
|
65
65
|
*
|
|
66
66
|
* Two variants now:
|
|
67
67
|
* * `touchedBy` — the original provenance predicate (escape-hatch / disclosure).
|
|
68
68
|
* * `entityGraph` — the PRIMARY path: a typed entity-graph query Nomos compiles
|
|
69
69
|
* into sealed SQL. Carries the certified relation chain + filters + optional
|
|
70
|
-
* touchedBy + agg. Mirrors `
|
|
70
|
+
* touchedBy + agg. Mirrors `deterministic_rquickjs::query_port::QueryAst::EntityGraph`.
|
|
71
71
|
*/
|
|
72
72
|
export type QueryAst =
|
|
73
73
|
| {
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/** Diagnostic only: execute real declarations through the existing sealed engine.
|
|
2
|
+
* This is not an installed law asset or an alternative tenant compiler. */
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
import { createRequire } from "node:module";
|
|
5
|
+
import { dirname, join, resolve } from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
import { readFileSync } from "node:fs";
|
|
8
|
+
import { build } from "esbuild";
|
|
9
|
+
import type { collectEngineRouting } from "./engine_entry.js";
|
|
10
|
+
|
|
11
|
+
export async function sqliteComputationBundle(
|
|
12
|
+
sources: ReadonlyMap<string, string>,
|
|
13
|
+
routing: ReturnType<typeof collectEngineRouting>
|
|
14
|
+
) {
|
|
15
|
+
const src = dirname(fileURLToPath(import.meta.url));
|
|
16
|
+
const zod = dirname(
|
|
17
|
+
createRequire(import.meta.url).resolve("zod/package.json")
|
|
18
|
+
);
|
|
19
|
+
const domains = [
|
|
20
|
+
...new Set([
|
|
21
|
+
...Object.values(routing.derivedOf ?? {}).flat(),
|
|
22
|
+
...Object.values(routing.combinedOf ?? {}).flat(),
|
|
23
|
+
]),
|
|
24
|
+
].sort();
|
|
25
|
+
if (domains.length === 0) return null;
|
|
26
|
+
const result = await build({
|
|
27
|
+
stdin: {
|
|
28
|
+
contents: [
|
|
29
|
+
`import {registerEngine} from ${JSON.stringify(
|
|
30
|
+
join(src, "engine_entry.ts")
|
|
31
|
+
)};`,
|
|
32
|
+
...["core", "registries"].map(
|
|
33
|
+
(n, i) =>
|
|
34
|
+
`import * as seed${i} from ${JSON.stringify(
|
|
35
|
+
join(zod, "v4/core", n + ".js")
|
|
36
|
+
)};`
|
|
37
|
+
),
|
|
38
|
+
"registerEngine({domains:{",
|
|
39
|
+
...domains.map((d) => {
|
|
40
|
+
const s = sources.get(d);
|
|
41
|
+
if (!s) throw Error(`missing computation domain ${d}`);
|
|
42
|
+
return s;
|
|
43
|
+
}),
|
|
44
|
+
`},routing:${JSON.stringify(routing)},seeds:[seed0,seed1]});`,
|
|
45
|
+
].join("\n"),
|
|
46
|
+
loader: "ts",
|
|
47
|
+
resolveDir: resolve(src, ".."),
|
|
48
|
+
},
|
|
49
|
+
bundle: true,
|
|
50
|
+
write: false,
|
|
51
|
+
format: "iife",
|
|
52
|
+
target: "es2020",
|
|
53
|
+
platform: "neutral",
|
|
54
|
+
charset: "utf8",
|
|
55
|
+
minify: true,
|
|
56
|
+
metafile: true,
|
|
57
|
+
define: { __nmsRuntimeLaw: "true" },
|
|
58
|
+
alias: {
|
|
59
|
+
zod: join(src, "runtime_zod.ts"),
|
|
60
|
+
"zod/v4": join(zod, "v4/index.js"),
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
const javascript = result.outputFiles[0]!.text;
|
|
64
|
+
return {
|
|
65
|
+
kind: "diagnostic-sealed-computations",
|
|
66
|
+
javascript,
|
|
67
|
+
sha256: createHash("sha256").update(javascript).digest("hex"),
|
|
68
|
+
domains,
|
|
69
|
+
inputs: Object.keys(result.metafile!.inputs)
|
|
70
|
+
.filter((p) => p !== "<stdin>")
|
|
71
|
+
.map((p) => ({
|
|
72
|
+
path: resolve(p),
|
|
73
|
+
sha256: createHash("sha256")
|
|
74
|
+
.update(readFileSync(resolve(p)))
|
|
75
|
+
.digest("hex"),
|
|
76
|
+
})),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/** Fixed read declarations lower to SQL. Arbitrary function bodies remain in
|
|
2
|
+
* the existing sealed engine. No derived copies or invalidation queue. */
|
|
3
|
+
import type { LawGraph } from "./law_graph.js";
|
|
4
|
+
import type { SqliteLayout } from "./sqlite_layout.js";
|
|
5
|
+
import { scalarSlot } from "./sqlite_reads.js";
|
|
6
|
+
export interface SqliteComputedPlan {
|
|
7
|
+
sid: string;
|
|
8
|
+
name: string;
|
|
9
|
+
kind: "derived" | "combined" | "temporalEnum";
|
|
10
|
+
via: string | null;
|
|
11
|
+
relatedType: string | null;
|
|
12
|
+
temporal: {
|
|
13
|
+
id: string;
|
|
14
|
+
of: string;
|
|
15
|
+
source_field: string;
|
|
16
|
+
missing: string;
|
|
17
|
+
initial: string;
|
|
18
|
+
transitions: { after_millis: number; value: string }[];
|
|
19
|
+
expression: string;
|
|
20
|
+
} | null;
|
|
21
|
+
}
|
|
22
|
+
const quote = (s: string) => `'${s.replaceAll("'", "''")}'`;
|
|
23
|
+
export function planSqliteComputations(
|
|
24
|
+
nodes: ReadonlyMap<string, LawGraph["nodes"][number]>,
|
|
25
|
+
aggregateId: string,
|
|
26
|
+
layout: Pick<SqliteLayout, "table" | "wireType" | "fields">
|
|
27
|
+
) {
|
|
28
|
+
const plans: SqliteComputedPlan[] = [],
|
|
29
|
+
refusals: { sid: string; reason: string }[] = [];
|
|
30
|
+
for (const read of nodes.values()) {
|
|
31
|
+
if (
|
|
32
|
+
read.kind !== "read" ||
|
|
33
|
+
read.of.id !== aggregateId ||
|
|
34
|
+
(read.readKind !== "derived" &&
|
|
35
|
+
read.readKind !== "combined" &&
|
|
36
|
+
read.readKind !== "temporalEnum")
|
|
37
|
+
)
|
|
38
|
+
continue;
|
|
39
|
+
try {
|
|
40
|
+
if (read.predicate) throw Error("computed read predicate not supported");
|
|
41
|
+
if (layout.fields.some((f) => f.name === read.entity.label))
|
|
42
|
+
throw Error("computed output shadows an authored field");
|
|
43
|
+
const p: SqliteComputedPlan = {
|
|
44
|
+
sid: read.entity.sid,
|
|
45
|
+
name: read.entity.label,
|
|
46
|
+
kind: read.readKind,
|
|
47
|
+
via: null,
|
|
48
|
+
relatedType: null,
|
|
49
|
+
temporal: null,
|
|
50
|
+
};
|
|
51
|
+
if (read.readKind === "temporalEnum") {
|
|
52
|
+
const path = read.source.authoredPath.split(".");
|
|
53
|
+
const f = layout.fields.find((f) => f.name === path[0]);
|
|
54
|
+
if (!f || path.length !== 1 || scalarSlot(f, []).kind !== "integer")
|
|
55
|
+
throw Error("temporal source requires a mapped scalar timestamp");
|
|
56
|
+
const source = scalarSlot(f, []).sql;
|
|
57
|
+
const transitions = read.transitions.map((t) => {
|
|
58
|
+
if (!Number.isSafeInteger(t.afterMillis) || t.afterMillis < 0)
|
|
59
|
+
throw Error("invalid temporal threshold");
|
|
60
|
+
return { after_millis: t.afterMillis, value: t.value };
|
|
61
|
+
});
|
|
62
|
+
// ?1 is the captured clock. Guard subtraction against signed-i64
|
|
63
|
+
// underflow; no REAL promotion or ambient SQLite wall clock.
|
|
64
|
+
const cases = [...transitions].reverse().map((t) => {
|
|
65
|
+
const safe = -(1n << 63n) + BigInt(t.after_millis);
|
|
66
|
+
const condition =
|
|
67
|
+
t.after_millis === 0
|
|
68
|
+
? "1"
|
|
69
|
+
: `(?1>=${safe} AND (${source})<=?1-${t.after_millis})`;
|
|
70
|
+
return `WHEN ${condition} THEN ${quote(t.value)}`;
|
|
71
|
+
});
|
|
72
|
+
p.temporal = {
|
|
73
|
+
id: p.name,
|
|
74
|
+
of: layout.wireType,
|
|
75
|
+
source_field: path[0]!,
|
|
76
|
+
missing: read.missing,
|
|
77
|
+
initial: read.initial,
|
|
78
|
+
transitions,
|
|
79
|
+
expression: `CASE WHEN (${source}) IS NULL THEN ${quote(
|
|
80
|
+
read.missing
|
|
81
|
+
)} ${cases.join(" ")} ELSE ${quote(read.initial)} END`,
|
|
82
|
+
};
|
|
83
|
+
} else if (read.readKind === "combined") {
|
|
84
|
+
const path = read.via.authoredPath.split(".");
|
|
85
|
+
const f = layout.fields.find((f) => f.name === path[0]);
|
|
86
|
+
if (!f || path.length !== 1 || scalarSlot(f, []).kind !== "string")
|
|
87
|
+
throw Error(
|
|
88
|
+
"combined join requires a mapped direct string reference"
|
|
89
|
+
);
|
|
90
|
+
const related = nodes.get(read.reads.id);
|
|
91
|
+
if (related?.kind !== "aggregate")
|
|
92
|
+
throw Error("combined related aggregate unavailable");
|
|
93
|
+
p.via = path[0]!;
|
|
94
|
+
p.relatedType = related.wireType;
|
|
95
|
+
}
|
|
96
|
+
plans.push(p);
|
|
97
|
+
} catch (error) {
|
|
98
|
+
refusals.push({ sid: read.entity.sid, reason: (error as Error).message });
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return { plans: plans.sort((a, b) => a.sid.localeCompare(b.sid)), refusals };
|
|
102
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/** Maintained count plans. Predicates stay typed Rust values, never SQL WHERE
|
|
2
|
+
* fragments. A replacement reads only the old/new scalar inputs by primary key.
|
|
3
|
+
*/
|
|
4
|
+
import type { LawGraph, LawStructuralRef } from "./law_graph.js";
|
|
5
|
+
import type { SqliteLayout } from "./sqlite_layout.js";
|
|
6
|
+
import { scalarSlot } from "./sqlite_reads.js";
|
|
7
|
+
|
|
8
|
+
type Nodes = ReadonlyMap<string, LawGraph["nodes"][number]>;
|
|
9
|
+
// Existing projection::CountPred serde representation; not a new predicate VM.
|
|
10
|
+
export type SqliteCountPredicate =
|
|
11
|
+
| { Eq: { field: string; value: string } }
|
|
12
|
+
| { Ne: { field: string; value: string } }
|
|
13
|
+
| { And: SqliteCountPredicate[] }
|
|
14
|
+
| { Or: SqliteCountPredicate[] };
|
|
15
|
+
export interface SqliteCountPlan {
|
|
16
|
+
sid: string;
|
|
17
|
+
name: string;
|
|
18
|
+
groupBy: string[] | null;
|
|
19
|
+
groupColumn: number | null;
|
|
20
|
+
predicate: SqliteCountPredicate | null;
|
|
21
|
+
}
|
|
22
|
+
export interface SqliteCountSnapshot {
|
|
23
|
+
sql: string;
|
|
24
|
+
columns: number;
|
|
25
|
+
fields: { name: string; kind: "string" | "integer"; column: number }[];
|
|
26
|
+
}
|
|
27
|
+
export function planSqliteCounts(
|
|
28
|
+
nodes: Nodes,
|
|
29
|
+
aggregateId: string,
|
|
30
|
+
layout: Pick<SqliteLayout, "table" | "wireType" | "fields">
|
|
31
|
+
) {
|
|
32
|
+
const plans: SqliteCountPlan[] = [];
|
|
33
|
+
const refusals: { sid: string; reason: string }[] = [];
|
|
34
|
+
const inputs = new Map<string, { kind: "string" | "integer"; sql: string }>();
|
|
35
|
+
const groups = new Map<string, string>();
|
|
36
|
+
for (const read of nodes.values()) {
|
|
37
|
+
if (
|
|
38
|
+
read.kind !== "read" ||
|
|
39
|
+
read.readKind !== "count" ||
|
|
40
|
+
read.of.id !== aggregateId
|
|
41
|
+
)
|
|
42
|
+
continue;
|
|
43
|
+
try {
|
|
44
|
+
const local = new Map<
|
|
45
|
+
string,
|
|
46
|
+
{ kind: "string" | "integer"; sql: string }
|
|
47
|
+
>();
|
|
48
|
+
function predicate(
|
|
49
|
+
ref: LawStructuralRef<"predicate">,
|
|
50
|
+
active = new Set<string>()
|
|
51
|
+
): SqliteCountPredicate {
|
|
52
|
+
if (active.has(ref.id)) throw Error("recursive count predicate");
|
|
53
|
+
const node = nodes.get(ref.id);
|
|
54
|
+
if (node?.kind !== "structural" || node.structuralKind !== "predicate")
|
|
55
|
+
throw Error("missing count predicate node");
|
|
56
|
+
const e = node.expression;
|
|
57
|
+
if (e.kind === "and" || e.kind === "or") {
|
|
58
|
+
const clauses = e.terms.map((t) =>
|
|
59
|
+
predicate(t, new Set(active).add(ref.id))
|
|
60
|
+
);
|
|
61
|
+
return e.kind === "and" ? { And: clauses } : { Or: clauses };
|
|
62
|
+
}
|
|
63
|
+
if (e.kind !== "eq" && e.kind !== "ne")
|
|
64
|
+
throw Error("unsupported count predicate");
|
|
65
|
+
const path = e.field.authoredPath.split(".");
|
|
66
|
+
if (path.length !== 1)
|
|
67
|
+
throw Error("count predicates require an own-aggregate scalar field");
|
|
68
|
+
const slot = layout.fields.find((f) => f.name === path[0]);
|
|
69
|
+
if (!slot) throw Error("unmapped count predicate field");
|
|
70
|
+
const scalar = scalarSlot(slot, []);
|
|
71
|
+
// CountPred currently handles Str/Int only. Do not pretend the DSL's
|
|
72
|
+
// boolean support is correct until the shared old/new evaluator agrees.
|
|
73
|
+
if (scalar.kind !== "string" && scalar.kind !== "integer")
|
|
74
|
+
throw Error(
|
|
75
|
+
"shared count predicate evaluator does not support this scalar kind"
|
|
76
|
+
);
|
|
77
|
+
if (
|
|
78
|
+
scalar.kind === "integer" &&
|
|
79
|
+
(!/^-?\d+$/.test(e.value) ||
|
|
80
|
+
BigInt(e.value) < -(1n << 63n) ||
|
|
81
|
+
BigInt(e.value) >= 1n << 63n)
|
|
82
|
+
)
|
|
83
|
+
throw Error("count predicate integer outside i64");
|
|
84
|
+
local.set(path[0]!, { kind: scalar.kind, sql: scalar.sql });
|
|
85
|
+
const clause = { field: path[0]!, value: e.value };
|
|
86
|
+
return e.kind === "eq" ? { Eq: clause } : { Ne: clause };
|
|
87
|
+
}
|
|
88
|
+
const pred = read.predicate ? predicate(read.predicate) : null;
|
|
89
|
+
const path = read.groupBy?.authoredPath.split(".") ?? null;
|
|
90
|
+
let groupSql: string | undefined;
|
|
91
|
+
if (path) {
|
|
92
|
+
const slot = layout.fields.find((f) => f.name === path[0]);
|
|
93
|
+
if (!slot) throw Error("unmapped count group field");
|
|
94
|
+
const scalar = scalarSlot(slot, path.slice(1));
|
|
95
|
+
if (scalar.kind !== "string")
|
|
96
|
+
throw Error("count group keys must be strings");
|
|
97
|
+
groupSql = scalar.sql;
|
|
98
|
+
}
|
|
99
|
+
// A refused read contributes no inputs to supported maintenance plans.
|
|
100
|
+
for (const [name, value] of local) inputs.set(name, value);
|
|
101
|
+
if (groupSql !== undefined) groups.set(read.entity.sid, groupSql);
|
|
102
|
+
plans.push({
|
|
103
|
+
sid: read.entity.sid,
|
|
104
|
+
name: read.entity.label,
|
|
105
|
+
groupBy: path,
|
|
106
|
+
groupColumn: null,
|
|
107
|
+
predicate: pred,
|
|
108
|
+
});
|
|
109
|
+
} catch (error) {
|
|
110
|
+
refusals.push({ sid: read.entity.sid, reason: (error as Error).message });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
plans.sort((a, b) => a.sid.localeCompare(b.sid));
|
|
114
|
+
if (!plans.length) return { plans, refusals, snapshot: null };
|
|
115
|
+
// c0 is not used; one constant permits predicate-free, ungrouped counts too.
|
|
116
|
+
const expressions = ["1"];
|
|
117
|
+
const fields = [...inputs]
|
|
118
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
119
|
+
.map(([name, value]) => {
|
|
120
|
+
const column = expressions.length;
|
|
121
|
+
expressions.push(value.sql);
|
|
122
|
+
return { name, kind: value.kind, column };
|
|
123
|
+
});
|
|
124
|
+
const groupColumns = new Map<string, number>();
|
|
125
|
+
for (const plan of plans) {
|
|
126
|
+
const sql = groups.get(plan.sid);
|
|
127
|
+
if (sql === undefined) continue;
|
|
128
|
+
let column = groupColumns.get(sql);
|
|
129
|
+
if (column === undefined) {
|
|
130
|
+
column = expressions.length;
|
|
131
|
+
expressions.push(sql);
|
|
132
|
+
groupColumns.set(sql, column);
|
|
133
|
+
}
|
|
134
|
+
plan.groupColumn = column;
|
|
135
|
+
}
|
|
136
|
+
if (expressions.length > 2000)
|
|
137
|
+
throw Error("count snapshot exceeds 2000-column SQLite target");
|
|
138
|
+
const type = layout.fields.find((f) => f.name === "__type")!;
|
|
139
|
+
const archive = layout.fields.find((f) => f.name === "__archived")!;
|
|
140
|
+
const literal = `'${layout.wireType.replaceAll("'", "''")}'`;
|
|
141
|
+
return {
|
|
142
|
+
plans,
|
|
143
|
+
refusals,
|
|
144
|
+
snapshot: {
|
|
145
|
+
sql: `SELECT ${expressions.join(",")} FROM ${
|
|
146
|
+
layout.table
|
|
147
|
+
} WHERE id=?1 AND c${type.presence}=2 AND c${
|
|
148
|
+
type.value.column
|
|
149
|
+
}=${literal} AND COALESCE(c${archive.value.column},0)<>1`,
|
|
150
|
+
columns: expressions.length,
|
|
151
|
+
fields,
|
|
152
|
+
} satisfies SqliteCountSnapshot,
|
|
153
|
+
};
|
|
154
|
+
}
|