@githolon/dsl 0.108.7 → 0.110.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +76 -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 +211 -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 +267 -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 +23905 -15774
- 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 +548 -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_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 +1274 -0
- package/src/codegen_call_usda.ts +49 -6
- package/src/codegen_dart.ts +79 -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 +1994 -1189
- 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
|
@@ -75,16 +75,34 @@ import { set, withMarker } from "../ops.js";
|
|
|
75
75
|
import { query } from "../query.js";
|
|
76
76
|
import { read } from "../read.js";
|
|
77
77
|
import { readRef, readSet, workspaceInvariant, refAs, type WorkspaceInvariantVerdict } from "./workspace_invariant.js";
|
|
78
|
-
import { writeTuple, removeTuple, RelationTuple, relationTupleInstanceId } from "./relations.js";
|
|
78
|
+
import { writeTuple, removeTuple, RelationTuple, relationTupleInstanceId, relationTuplesByObject } from "./relations.js";
|
|
79
|
+
import { readFrameworkDeclaredRows } from "../read.js";
|
|
79
80
|
import { relationType, self, user, key, object } from "../relation_schema.js";
|
|
80
|
-
import { WORKSPACE_ADMIN_RELATION } from "./governance_relations.js";
|
|
81
|
+
import { WORKSPACE_ADMIN_RELATION, WORKSPACE_OPERATOR_RELATION } from "./governance_relations.js";
|
|
81
82
|
import { GENESIS_WARRANT_ID } from "./genesis.js";
|
|
82
|
-
import { idOf } from "../value_object.js";
|
|
83
|
+
import { idOf, valueObject } from "../value_object.js";
|
|
83
84
|
import { enrollSigner, signerObject, SIGNER_RELATION } from "./signing_identity.js";
|
|
85
|
+
import { principalScopeOf } from "../member_authentication.js";
|
|
86
|
+
import {
|
|
87
|
+
GOVERNANCE_SUBJECTS,
|
|
88
|
+
governanceSubject,
|
|
89
|
+
governanceSubjectFields,
|
|
90
|
+
governanceSubjectPayload,
|
|
91
|
+
hasOneGovernanceSubject,
|
|
92
|
+
isGovernanceSubject,
|
|
93
|
+
principalScopeObject,
|
|
94
|
+
providerScopeField,
|
|
95
|
+
readInheritedEnrollers,
|
|
96
|
+
relationTuplesByRelation,
|
|
97
|
+
type InheritedEnroller,
|
|
98
|
+
} from "./principal_enrollment.js";
|
|
99
|
+
import { PRINCIPAL_SCOPE_ENROLLER_RELATION } from "./governance_relations.js";
|
|
84
100
|
import { seedBirthPolicy } from "./birth_meter.js";
|
|
85
101
|
import {
|
|
86
102
|
DomainInstallExecutor,
|
|
87
103
|
domainInstallGenesisOffer,
|
|
104
|
+
type LawClosureReference,
|
|
105
|
+
MODEL_LIFECYCLE_AUTHORITY,
|
|
88
106
|
} from "./domain_lifecycle.js";
|
|
89
107
|
// THE GENESIS BOOTSTRAP (platform-birth genesis bootstrap, Approach A): governance carries the
|
|
90
108
|
// warrant-flip primitives so the birth door can lawfully bootstrap a virgin platform's founding admin —
|
|
@@ -93,6 +111,13 @@ import {
|
|
|
93
111
|
// them up as part of the `workspaces` domain. (architecture/platform_birth_genesis_bootstrap.md)
|
|
94
112
|
export { GenesisWarrant, seedGenesis } from "./genesis.js";
|
|
95
113
|
export { identityRelations, enrollSigner } from "./signing_identity.js";
|
|
114
|
+
// A platform (root, nomos-cafe, a tenant platform) receives workspace effects only where its custodian's
|
|
115
|
+
// admission-checkpoint key is an active signer: its operator seats and retires that key here.
|
|
116
|
+
export {
|
|
117
|
+
enrollAdmissionCheckpointSignerDirect,
|
|
118
|
+
revokeAdmissionCheckpointSigner,
|
|
119
|
+
lastAdmissionCheckpointSignerRemains,
|
|
120
|
+
} from "./signing_identity.js";
|
|
96
121
|
// ERA 0 — the keyless verified first-device door rides the GOVERNANCE law too: a freshly BORN platform
|
|
97
122
|
// has a virgin roster and a cert-ATTESTED AuthProvider (the S_root-signed birth witness), so its founder's
|
|
98
123
|
// FIRST action is `enrollFirstDevice` (token-verified against the attested provider) followed by a SIGNED
|
|
@@ -113,10 +138,42 @@ export {
|
|
|
113
138
|
BirthAttestationLink,
|
|
114
139
|
birthAttestation,
|
|
115
140
|
seedBirthAttestation,
|
|
116
|
-
} from "./
|
|
141
|
+
} from "./receiving_group.js";
|
|
117
142
|
// THE ENROLL-ONCE DELEGATION LANE — a platform records each tenant's device-key delegation (signed by its
|
|
118
143
|
// onboarding signer S_P) so the kernel reads it at `signer-delegation:<user>` when assembling a home's chain.
|
|
119
144
|
export { SignerDelegation, enrollDelegation, signerDelegationByUser } from "./signing_identity.js";
|
|
145
|
+
// D22 — THE KERNEL IS THE AUTHENTICATION: the enroller relation and the enrolled-scope first-key lane
|
|
146
|
+
// ride governance, so every workspace born under it can enrol its scopes' principals.
|
|
147
|
+
export {
|
|
148
|
+
principalScopeRelations,
|
|
149
|
+
enrollDevice,
|
|
150
|
+
revokeDevice,
|
|
151
|
+
relationTuplesByRelation,
|
|
152
|
+
} from "./principal_enrollment.js";
|
|
153
|
+
// D22 — TOKEN-FREE GENESIS: the one founding step of a workspace born without a provider token or a
|
|
154
|
+
// birth certificate, and the invariant fencing it to the virgin, warrant-free prefix.
|
|
155
|
+
export {
|
|
156
|
+
BirthOrigin,
|
|
157
|
+
FoundingPrincipal,
|
|
158
|
+
birthOriginVirginOnly,
|
|
159
|
+
foundingPrincipalVirginOnly,
|
|
160
|
+
seedBirthOrigin,
|
|
161
|
+
seedFoundingPrincipal,
|
|
162
|
+
} from "./founding_genesis.js";
|
|
163
|
+
import { seedFoundingPrincipal } from "./founding_genesis.js";
|
|
164
|
+
// The console's lawful reach (framework/console_governance.ts): the founding seat of inherited operators'
|
|
165
|
+
// and enrollers' keys and law authority, operator handover, and console key rotation.
|
|
166
|
+
export {
|
|
167
|
+
seedInheritedGovernance,
|
|
168
|
+
inheritedGovernanceBeforeWarrant,
|
|
169
|
+
grantConsoleOperator,
|
|
170
|
+
revokeConsoleOperator,
|
|
171
|
+
lastOperatorRemains,
|
|
172
|
+
enrollConsoleSigner,
|
|
173
|
+
revokeConsoleSigner,
|
|
174
|
+
lastConsoleSignerRemains,
|
|
175
|
+
} from "./console_governance.js";
|
|
176
|
+
import { inheritedGovernanceStepFrom, readInheritedSigners, type InheritedSigner } from "./console_governance.js";
|
|
120
177
|
|
|
121
178
|
/** Canonical governance-law namespace. Genesis routes refer to this declaration, never a repeated
|
|
122
179
|
* string literal, so renaming the module cannot silently strand part of the founding ceremony. */
|
|
@@ -201,10 +258,23 @@ export const workspaceRelations = relationType("workspace")
|
|
|
201
258
|
// migration. (A TENANT that wants a workspace-scoped role uses a namespaced `relationType("workspace")`
|
|
202
259
|
// + a `selfWorkspace()` seed; only THIS framework governance type is global.)
|
|
203
260
|
.asGlobal()
|
|
204
|
-
|
|
261
|
+
// admin also admits the framework's console and custodian principals: token-free genesis (D22) seats a
|
|
262
|
+
// `console:`/`custodian:` founding admin by `seedFoundingPrincipal`. Still leaf-only.
|
|
263
|
+
.relation(WORKSPACE_ADMIN_RELATION, { rewrite: self(), allow: [...GOVERNANCE_SUBJECTS] })
|
|
205
264
|
.relation("creator", { rewrite: self(), allow: [user(), key()] })
|
|
206
265
|
.relation("platformCreator", { rewrite: self(), allow: [user(), key()] });
|
|
207
266
|
|
|
267
|
+
/**
|
|
268
|
+
* `workspace:self#operator` (D15/D19), its own fragment of the global `workspace` type so tenant law that
|
|
269
|
+
* gates on it (`.requires("operator")`) composes exactly this relation and not the admin surface — the
|
|
270
|
+
* same shape as `modelLifecycleRelations`. It also admits the console's enrolled principals
|
|
271
|
+
* (`console:<subject>`, D18/D22): the operators who install law sign in through console.nomos.cafe. See
|
|
272
|
+
* GOVERNANCE_SUBJECTS.
|
|
273
|
+
*/
|
|
274
|
+
export const workspaceOperatorRelations = relationType("workspace")
|
|
275
|
+
.asGlobal()
|
|
276
|
+
.relation(WORKSPACE_OPERATOR_RELATION, { rewrite: self(), allow: [...GOVERNANCE_SUBJECTS] });
|
|
277
|
+
|
|
208
278
|
/** Global holarchy edge kept separate so application packages can compose child authority without
|
|
209
279
|
* re-exporting the governance admin/creator surface into a tenant domain. */
|
|
210
280
|
export const workspaceChildRelations = relationType("workspace")
|
|
@@ -271,6 +341,16 @@ const epochMs = z.number().int().nonnegative();
|
|
|
271
341
|
* presented owner bearer against THIS field — the law record, not a worker-side
|
|
272
342
|
* secret store. `""` until provisioned.
|
|
273
343
|
*/
|
|
344
|
+
export const WorkspaceBirthAuthority = valueObject("WorkspaceBirthAuthority", {
|
|
345
|
+
parent: z.string(),
|
|
346
|
+
principal: z.string(),
|
|
347
|
+
authorizedAt: z.number().int().nonnegative(),
|
|
348
|
+
lawHash: z.string(),
|
|
349
|
+
authorizationHash: z.string(),
|
|
350
|
+
parentHead: z.string(),
|
|
351
|
+
rebornFrom: z.string().optional(),
|
|
352
|
+
});
|
|
353
|
+
|
|
274
354
|
export const CloudWorkspace = aggregate("CloudWorkspace", {
|
|
275
355
|
/** Human-meaningful unique workspace name (the `:ws` URL segment). */
|
|
276
356
|
name: t.string().merge(Lww),
|
|
@@ -321,29 +401,17 @@ export const CloudWorkspace = aggregate("CloudWorkspace", {
|
|
|
321
401
|
* request at the cloud level).
|
|
322
402
|
*/
|
|
323
403
|
pool: t.int().merge(Lww).optional(),
|
|
324
|
-
/**
|
|
325
|
-
* THE LAW-AUTHORED GENESIS CHAIN (P1, architecture/provisioning_as_obligations.md "law and law alone").
|
|
326
|
-
* For a genesis birth, `birthChild` authors the child's genesis RECIPE here as data — a JSON array of
|
|
327
|
-
* `{domain, directiveId, payload, actor}` steps (`seedGenesis → grantAdmin → birthCloud`). The birth
|
|
328
|
-
* capability provider REPLAYS this opaque list on the child (it names nothing — the directive ids come
|
|
329
|
-
* from the law, not host source); that is the difference between the host *reconstructing* the genesis
|
|
330
|
-
* (today) and the host *delivering* a law-authored one. Absent for plain births + pre-P1 records (the
|
|
331
|
-
* provider falls back to its inline recipe — flag-gated until live byte-equivalence is proven). Naming
|
|
332
|
-
* the genesis directives HERE is law naming law (legitimate); the prohibition binds only the host.
|
|
333
|
-
*/
|
|
334
|
-
genesisChain: t.json().merge(Lww).optional(),
|
|
335
404
|
/**
|
|
336
405
|
* THE LINEAGE-AUTHORIZATION BINDING (proof-friendly — architecture/sovereign_adapter.md "birth is a kernel
|
|
337
|
-
* offer-effect"). The child's genesis SELF-ATTESTS who authorized it: a
|
|
406
|
+
* offer-effect"). The child's genesis SELF-ATTESTS who authorized it: a structural commitment
|
|
338
407
|
* `{parent, principal, authorizedAt}` — the law-available lineage anchor — that the child's OWN chain
|
|
339
408
|
* carries, so a verifier of the child alone sees its claimed parentage, cross-checkable against the
|
|
340
409
|
* parent's chain (which holds the child's CloudWorkspace + the gated `birthChild` that minted it). It is
|
|
341
410
|
* the clean public-input shape a future recursive-proof circuit (Nova / zkWASM) would expose; the
|
|
342
411
|
* kernel-structural commitments (the parent chain head + the `birthChild` intent hash + the law hash) join
|
|
343
412
|
* it when the KERNEL produces the genesis (B's later slice — until then those ride as `""`). `t.string`
|
|
344
|
-
*
|
|
345
|
-
|
|
346
|
-
bornUnder: t.string().merge(Lww).optional(),
|
|
413
|
+
* encoded as named USDA prims. Absent on root (the base of the world tree, born under nothing). */
|
|
414
|
+
bornUnder: WorkspaceBirthAuthority.field().merge(Lww).optional(),
|
|
347
415
|
/**
|
|
348
416
|
* SUPERSESSION (recovery verb 3 — {@link rebirthWorkspace}, architecture/rebirth_and_custody_lifecycle.md).
|
|
349
417
|
* "Supersession, never forgiveness": a chain scarred by a historical LAW violation cannot be retro-blessed;
|
|
@@ -563,6 +631,19 @@ function planBirthRecord(
|
|
|
563
631
|
// so the chain is a pure function of the payload (deterministic on every replaying peer). Naming the genesis
|
|
564
632
|
// directives here is law naming law; the prohibition binds only the host. The law package bytes are NOT in
|
|
565
633
|
// here — the install-by-hash stays a custody concern of the provider (the bytes-in-pack refinement is later).
|
|
634
|
+
export interface GovernanceGenesisOffer {
|
|
635
|
+
readonly domain: string;
|
|
636
|
+
readonly directiveId: string;
|
|
637
|
+
readonly actor: string;
|
|
638
|
+
readonly payload: Readonly<Record<string, unknown>>;
|
|
639
|
+
readonly domainHash?: LawClosureReference;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
// OPERATOR INHERITANCE (D15) — `readInheritedOperators` lives with the founding step it feeds
|
|
643
|
+
// (`founding_genesis.ts`), so the receiving-group birth can share it without an import cycle.
|
|
644
|
+
export { readInheritedOperators } from "./founding_genesis.js";
|
|
645
|
+
import { readInheritedOperators } from "./founding_genesis.js";
|
|
646
|
+
|
|
566
647
|
export function buildGenesisChain(p: {
|
|
567
648
|
name: string;
|
|
568
649
|
principal: string;
|
|
@@ -586,7 +667,17 @@ export function buildGenesisChain(p: {
|
|
|
586
667
|
* child's birthCloud record (`rebornFrom`) + the bornUnder commitment — the reborn holon testifies to its
|
|
587
668
|
* ancestry while `parent` stays the SUPERSEDED record's parent (a rebirth may never reparent). */
|
|
588
669
|
rebornFrom?: string;
|
|
589
|
-
|
|
670
|
+
/** AUTHPROVIDER INHERITANCE (the same law `birthReceivingGroup` already runs): the parent's CURRENT
|
|
671
|
+
* verifying material, read off the parent's folded state by the calling plan. A child is born WARRANTED,
|
|
672
|
+
* and the warrant permanently closes `seedAuthProvider` — so if the recipe does not seat a verifier here
|
|
673
|
+
* the child can never obtain one (`setAuthProvider` mutates a singleton that would never exist), and no
|
|
674
|
+
* `user:` principal could ever be captured on it: not even its own first-device enrolment. Absent ⇒ the
|
|
675
|
+
* child is born device-key administered, exactly as before. */
|
|
676
|
+
inheritedAuthProvider?: AuthProviderVerifyingConfiguration;
|
|
677
|
+
// Operator (D15) and enroller (D22) inheritance live on the token-free recipe only
|
|
678
|
+
// ({@link buildFoundingGenesisChain}): as admin-gated `grantLawOperator`/`grantEnroller` steps on this
|
|
679
|
+
// warrant-free prefix no admin exists to satisfy `.requires("admin")`, so the kernel refused them.
|
|
680
|
+
}): readonly GovernanceGenesisOffer[] {
|
|
590
681
|
const founder: `user:${string}` = `user:${p.principal}`;
|
|
591
682
|
// THE ORDER-DECLARED LAW INSTALL (G3): the child installs the EXACT typed USDA closures the order names.
|
|
592
683
|
// Bytes are NOT in the recipe; the kernel resolves each identity from its own custody when it folds the
|
|
@@ -611,7 +702,7 @@ export function buildGenesisChain(p: {
|
|
|
611
702
|
// law-available anchor now; the kernel-structural commitments (parent chain head + birthChild intent hash
|
|
612
703
|
// + law hash) join as `""` placeholders until the kernel produces the genesis (B's later slice). The
|
|
613
704
|
// ordering of keys is fixed so the commitment is a stable, content-addressed shape (proof public inputs).
|
|
614
|
-
const bornUnder =
|
|
705
|
+
const bornUnder = {
|
|
615
706
|
parent: p.parent,
|
|
616
707
|
principal: p.principal,
|
|
617
708
|
authorizedAt: p.requestedAt,
|
|
@@ -619,7 +710,7 @@ export function buildGenesisChain(p: {
|
|
|
619
710
|
authorizationHash: "",
|
|
620
711
|
parentHead: "",
|
|
621
712
|
...(p.rebornFrom ? { rebornFrom: p.rebornFrom } : {}),
|
|
622
|
-
}
|
|
713
|
+
};
|
|
623
714
|
if (!Number.isInteger(p.descendantPool) || p.descendantPool < 0) {
|
|
624
715
|
throw new Error(
|
|
625
716
|
"buildGenesisChain requires an explicit non-negative descendantPool; " +
|
|
@@ -645,7 +736,7 @@ export function buildGenesisChain(p: {
|
|
|
645
736
|
setAt: p.bornAt,
|
|
646
737
|
}),
|
|
647
738
|
];
|
|
648
|
-
return
|
|
739
|
+
return [
|
|
649
740
|
...installSteps,
|
|
650
741
|
...poolSteps,
|
|
651
742
|
// ERA 0 — THE GENESIS-ORDER CONTRACT (the birthHome ordering, unified): every recipe seed below runs
|
|
@@ -680,7 +771,113 @@ export function buildGenesisChain(p: {
|
|
|
680
771
|
bornUnder,
|
|
681
772
|
...(p.rebornFrom ? { rebornFrom: p.rebornFrom } : {}),
|
|
682
773
|
}),
|
|
683
|
-
|
|
774
|
+
// THE VERIFIER THE CHILD IS BORN WITH. Still on the warrant-free prefix (the kernel appends the
|
|
775
|
+
// attestation and the warrant AFTER this recipe), so this is the one lawful moment the singleton can
|
|
776
|
+
// come into existence. `setAt: 1` keeps the recipe a pure function of the payload + the parent's
|
|
777
|
+
// committed fold — no clock, byte-identical on every replaying peer.
|
|
778
|
+
...(p.inheritedAuthProvider === undefined ? [] : [
|
|
779
|
+
governanceGenesisStep(seedAuthProvider, {
|
|
780
|
+
...p.inheritedAuthProvider,
|
|
781
|
+
label: "inherited-from-parent",
|
|
782
|
+
setBy: p.principal,
|
|
783
|
+
setAt: 1,
|
|
784
|
+
} as never),
|
|
785
|
+
]),
|
|
786
|
+
];
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
/**
|
|
790
|
+
* THE TOKEN-FREE GENESIS RECIPE (identity target model D22, build order step 2). The recipe a
|
|
791
|
+
* `birthChild` naming a `<scope>:<subject>` founding principal and its founding key hash authors:
|
|
792
|
+
*
|
|
793
|
+
* [installDomain(framework), installDomain(law)] → seedBirthPolicy → seedFoundingPrincipal → birthCloud
|
|
794
|
+
*
|
|
795
|
+
* `seedFoundingPrincipal` seats the founder's signer tuple, the founder as admin, and the operator and
|
|
796
|
+
* enroller tuples the parent held at birth — all in one requires-free, virgin-only step, because no
|
|
797
|
+
* admin exists yet on the warrant-free prefix. No step carries a provider token, verifier, JWKS or
|
|
798
|
+
* certificate, and nothing here asks the kernel to assemble one: the kernel's birth effect appends only
|
|
799
|
+
* the warrant (`seedGenesis`, principal = the founder, self-id = the name), which it binds to the
|
|
800
|
+
* founding record. A parent running law without this builder keeps authoring {@link buildGenesisChain},
|
|
801
|
+
* so live chains keep their path until regenerated (build order step 4 deletes it).
|
|
802
|
+
*/
|
|
803
|
+
export function buildFoundingGenesisChain(p: {
|
|
804
|
+
name: string;
|
|
805
|
+
/** The founding admin principal, `<scope>:<subject>` of a framework governance scope. */
|
|
806
|
+
foundingPrincipal: string;
|
|
807
|
+
/** sha256hex of the founding signer's Ed25519 public key. */
|
|
808
|
+
foundingKeyHash: string;
|
|
809
|
+
/** The parent's proven requester who authorized the birth (`bornUnder.principal`). */
|
|
810
|
+
authorizedBy: string;
|
|
811
|
+
/** The parent CloudWorkspace record id, recorded on the child's lineage (`bornUnder.parent`). */
|
|
812
|
+
parent: string;
|
|
813
|
+
tier: (typeof WORKSPACE_TIERS)[number];
|
|
814
|
+
bornAt: string;
|
|
815
|
+
requestedAt: number;
|
|
816
|
+
descendantPool: number;
|
|
817
|
+
frameworkHash?: Sha256Digest;
|
|
818
|
+
lawHash?: Sha256Digest;
|
|
819
|
+
/** The parent's active `operator` subjects at birth ({@link readInheritedOperators}). */
|
|
820
|
+
inheritedOperators?: readonly string[];
|
|
821
|
+
/** The parent's active enroller tuples at birth (`readInheritedEnrollers`). */
|
|
822
|
+
inheritedEnrollers?: readonly InheritedEnroller[];
|
|
823
|
+
/** The parent's active keys for those operators and enrollers (`readInheritedSigners`). */
|
|
824
|
+
inheritedSigners?: readonly InheritedSigner[];
|
|
825
|
+
}): readonly GovernanceGenesisOffer[] {
|
|
826
|
+
if (!Number.isInteger(p.descendantPool) || p.descendantPool < 0) {
|
|
827
|
+
throw new Error(
|
|
828
|
+
"buildFoundingGenesisChain requires an explicit non-negative descendantPool; " +
|
|
829
|
+
"Nomos has no compiled birth-policy fallback",
|
|
830
|
+
);
|
|
831
|
+
}
|
|
832
|
+
const founder = p.foundingPrincipal;
|
|
833
|
+
const step = <P extends Record<string, unknown>>(declaration: Directive<P>, payload: P) => ({
|
|
834
|
+
domain: WORKSPACES_DOMAIN,
|
|
835
|
+
directiveId: declaration.id,
|
|
836
|
+
actor: founder,
|
|
837
|
+
payload,
|
|
838
|
+
});
|
|
839
|
+
const installSteps =
|
|
840
|
+
p.frameworkHash && p.lawHash
|
|
841
|
+
? [
|
|
842
|
+
domainInstallGenesisOffer(DomainInstallExecutor.StageZero, p.frameworkHash, founder),
|
|
843
|
+
domainInstallGenesisOffer(DomainInstallExecutor.LifecycleController, p.lawHash, founder),
|
|
844
|
+
]
|
|
845
|
+
: [];
|
|
846
|
+
return [
|
|
847
|
+
...installSteps,
|
|
848
|
+
step(seedBirthPolicy, { maxBirthsPerPrincipal: p.descendantPool, setBy: founder, setAt: p.bornAt }),
|
|
849
|
+
step(seedFoundingPrincipal, {
|
|
850
|
+
principal: founder,
|
|
851
|
+
keyHash: p.foundingKeyHash,
|
|
852
|
+
operators: [...(p.inheritedOperators ?? [])],
|
|
853
|
+
enrollers: (p.inheritedEnrollers ?? []).map((enroller) => ({ scope: enroller.scope, subject: enroller.subject })),
|
|
854
|
+
grantedAt: p.requestedAt,
|
|
855
|
+
}),
|
|
856
|
+
// The inherited operators' and enrollers' keys, and installDomain for the operators, so the
|
|
857
|
+
// jurisdiction can act in this child and roll out its law without a re-found.
|
|
858
|
+
...inheritedGovernanceStepFrom(
|
|
859
|
+
WORKSPACES_DOMAIN,
|
|
860
|
+
founder,
|
|
861
|
+
p.inheritedOperators ?? [],
|
|
862
|
+
p.inheritedSigners ?? [],
|
|
863
|
+
p.requestedAt,
|
|
864
|
+
{ principal: founder, keyHash: p.foundingKeyHash },
|
|
865
|
+
),
|
|
866
|
+
step(birthCloud, {
|
|
867
|
+
principal: founder,
|
|
868
|
+
name: p.name,
|
|
869
|
+
tier: p.tier,
|
|
870
|
+
bornAt: p.requestedAt,
|
|
871
|
+
bornUnder: {
|
|
872
|
+
parent: p.parent,
|
|
873
|
+
principal: p.authorizedBy,
|
|
874
|
+
authorizedAt: p.requestedAt,
|
|
875
|
+
lawHash: "",
|
|
876
|
+
authorizationHash: "",
|
|
877
|
+
parentHead: "",
|
|
878
|
+
},
|
|
879
|
+
}),
|
|
880
|
+
];
|
|
684
881
|
}
|
|
685
882
|
|
|
686
883
|
// ── THE QUOTA-GATE QUERIES (declared HERE — used by the WorkspaceQuota captured-read invariant) ────────
|
|
@@ -836,10 +1033,10 @@ export const birthCloud = directive("birthCloud")
|
|
|
836
1033
|
role: z.enum(WORKSPACE_ROLES).optional(),
|
|
837
1034
|
tier: z.enum(WORKSPACE_TIERS).default("edge"),
|
|
838
1035
|
bornAt: epochMs,
|
|
839
|
-
/** THE LINEAGE-AUTHORIZATION BINDING (proof-friendly): the
|
|
1036
|
+
/** THE LINEAGE-AUTHORIZATION BINDING (proof-friendly): the structural commitment to who authorized this
|
|
840
1037
|
* birth, recorded onto the child's self-record so its OWN chain self-attests its parentage. Absent on
|
|
841
1038
|
* root (born under nothing). Authored by {@link buildGenesisChain} for a child birth. */
|
|
842
|
-
bornUnder:
|
|
1039
|
+
bornUnder: WorkspaceBirthAuthority.zod.optional(),
|
|
843
1040
|
/** LINEAGE CONTINUITY: present ONLY on a REBIRTH genesis — the superseded incarnation's genesis oid.
|
|
844
1041
|
* The reborn holon's own chain testifies to its ancestry; `parent` (in bornUnder) stays UNCHANGED. */
|
|
845
1042
|
rebornFrom: z.string().optional(),
|
|
@@ -1312,6 +1509,13 @@ export const birthChild = directive("birthChild")
|
|
|
1312
1509
|
/** GENESIS (optional): present ⇒ this child is born running the governance law (a platform). The
|
|
1313
1510
|
* sha256 of the founding-admin key the requester presented — the provider grants admin to the hash. */
|
|
1314
1511
|
foundingAdminHash: sha256Hex.optional(),
|
|
1512
|
+
/** TOKEN-FREE GENESIS (D22): the child's founding admin, a `<scope>:<subject>` principal of a
|
|
1513
|
+
* framework governance scope (console: or custodian:), and the sha256 of its founding signer's
|
|
1514
|
+
* public key. Both present ⇒ the child's recipe is {@link buildFoundingGenesisChain}: no provider
|
|
1515
|
+
* verifier, no certificate, no token. `principal` stays the proven requester the birth is charged
|
|
1516
|
+
* to. Exclusive with `foundingAdminHash`, which selects the historical recipe. */
|
|
1517
|
+
foundingPrincipal: z.string().min(1).optional(),
|
|
1518
|
+
foundingKeyHash: sha256Hex.optional(),
|
|
1315
1519
|
/** PLATFORM POOL: explicit law-state for how many live children the born platform may parent.
|
|
1316
1520
|
* Required with genesis. There is no framework default. Zero deliberately disables births. */
|
|
1317
1521
|
pool: z.number().int().nonnegative().optional(),
|
|
@@ -1335,32 +1539,85 @@ export const birthChild = directive("birthChild")
|
|
|
1335
1539
|
.refine((d) => !d.foundingAdminHash || (d.principal.length > 0 && !!d.bornAt && d.pool !== undefined), {
|
|
1336
1540
|
message: "a genesis birth (foundingAdminHash present) requires a non-empty principal, bornAt (ISO), and explicit pool",
|
|
1337
1541
|
path: ["pool"],
|
|
1542
|
+
})
|
|
1543
|
+
.refine((d) => !(d.foundingAdminHash && d.foundingKeyHash), {
|
|
1544
|
+
message: "a genesis birth names foundingAdminHash (historical) or foundingKeyHash (token-free), not both",
|
|
1545
|
+
path: ["foundingKeyHash"],
|
|
1546
|
+
})
|
|
1547
|
+
.refine((d) => !d.foundingKeyHash === !d.foundingPrincipal, {
|
|
1548
|
+
message: "a token-free genesis birth names both foundingPrincipal and foundingKeyHash",
|
|
1549
|
+
path: ["foundingPrincipal"],
|
|
1550
|
+
})
|
|
1551
|
+
.refine((d) => !d.foundingPrincipal || (isGovernanceSubject(d.foundingPrincipal) && principalScopeOf(d.foundingPrincipal) !== undefined && !!d.bornAt && d.pool !== undefined), {
|
|
1552
|
+
message: "a token-free genesis birth requires foundingPrincipal as a console: or custodian: <scope>:<subject> principal, bornAt (ISO), and explicit pool",
|
|
1553
|
+
path: ["foundingPrincipal"],
|
|
1338
1554
|
}),
|
|
1339
1555
|
)
|
|
1340
1556
|
.plan((p) => {
|
|
1341
1557
|
// THE WORKSPACE-QUOTA CAPTURED READS (#58 / S2) — same unconditional capture as createWorkspace, so the
|
|
1342
1558
|
// WorkspaceQuota invariant counts this principal's live workspaces against its allowance on every lane.
|
|
1343
1559
|
countQuotaReads(p.principal);
|
|
1560
|
+
// A genesis child inherits its parent's CURRENT verifying material, exactly as a receiving-group birth
|
|
1561
|
+
// does. The read is declared below and captured on the intent, so every replaying peer folds the same
|
|
1562
|
+
// child genesis.
|
|
1563
|
+
const inheritedAuthProvider = p.foundingAdminHash
|
|
1564
|
+
? readAuthProviderVerifyingConfiguration()
|
|
1565
|
+
: undefined;
|
|
1566
|
+
// TOKEN-FREE GENESIS (D22): the founder is a `<scope>:<subject>` principal named with its founding
|
|
1567
|
+
// key hash. The child inherits no provider verifier (there is none to inherit); it inherits the
|
|
1568
|
+
// parent's operator (D15) and enroller (D22) tuples, captured on this intent so every replaying
|
|
1569
|
+
// peer folds the same child genesis, never re-read live from the parent again.
|
|
1570
|
+
if (p.foundingKeyHash && p.foundingPrincipal) {
|
|
1571
|
+
const inheritedOperators = readInheritedOperators();
|
|
1572
|
+
const inheritedEnrollers = readInheritedEnrollers();
|
|
1573
|
+
const inheritedSigners = readInheritedSigners([...inheritedOperators, ...inheritedEnrollers.map((e) => e.subject)]);
|
|
1574
|
+
planBirthRecord(p, { foundingAdminHash: p.foundingKeyHash, pool: p.pool as number });
|
|
1575
|
+
birth({
|
|
1576
|
+
workspace: p.name,
|
|
1577
|
+
genesisChain: buildFoundingGenesisChain({
|
|
1578
|
+
name: p.name,
|
|
1579
|
+
foundingPrincipal: p.foundingPrincipal,
|
|
1580
|
+
foundingKeyHash: p.foundingKeyHash,
|
|
1581
|
+
authorizedBy: p.principal,
|
|
1582
|
+
parent: p.parent,
|
|
1583
|
+
tier: p.tier,
|
|
1584
|
+
bornAt: p.bornAt as string,
|
|
1585
|
+
requestedAt: p.requestedAt,
|
|
1586
|
+
descendantPool: p.pool as number,
|
|
1587
|
+
...(p.frameworkHash ? { frameworkHash: p.frameworkHash } : {}),
|
|
1588
|
+
...(p.lawHash ? { lawHash: p.lawHash } : {}),
|
|
1589
|
+
inheritedOperators,
|
|
1590
|
+
inheritedEnrollers,
|
|
1591
|
+
inheritedSigners,
|
|
1592
|
+
}),
|
|
1593
|
+
});
|
|
1594
|
+
return [];
|
|
1595
|
+
}
|
|
1344
1596
|
const rec = planBirthRecord(p, p.foundingAdminHash ? { foundingAdminHash: p.foundingAdminHash, pool: p.pool as number } : undefined);
|
|
1345
1597
|
// LAW AUTHORS THE GENESIS RECIPE (P1): a genesis birth carries its child's [installDomain×2 →]
|
|
1346
1598
|
// seedGenesis→grantAdmin→birthCloud chain. (refine guarantees principal + bornAt here.)
|
|
1347
1599
|
if (p.foundingAdminHash) {
|
|
1348
1600
|
// ERA 0 — every governance/platform birth is WARRANTED (no compat hatch to thread; buildGenesisChain
|
|
1349
1601
|
// always records the real self-id).
|
|
1350
|
-
const genesisChain = buildGenesisChain({ name: p.name, principal: p.principal, parent: p.parent, tier: p.tier, foundingAdminHash: p.foundingAdminHash, bornAt: p.bornAt as string, requestedAt: p.requestedAt, descendantPool: p.pool as number, ...(p.frameworkHash ? { frameworkHash: p.frameworkHash } : {}), ...(p.lawHash ? { lawHash: p.lawHash } : {}) });
|
|
1351
|
-
// THE GENESIS RECIPE IS ALSO A LINEAGE/AUDIT FACT on the parent's chain (the parent records what it
|
|
1352
|
-
// ORDERED — law naming law, legitimate). The kernel does NOT read this field to detect the birth.
|
|
1353
|
-
rec.set("genesisChain", genesisChain);
|
|
1602
|
+
const genesisChain = buildGenesisChain({ name: p.name, principal: p.principal, parent: p.parent, tier: p.tier, foundingAdminHash: p.foundingAdminHash, bornAt: p.bornAt as string, requestedAt: p.requestedAt, descendantPool: p.pool as number, ...(p.frameworkHash ? { frameworkHash: p.frameworkHash } : {}), ...(p.lawHash ? { lawHash: p.lawHash } : {}), ...(inheritedAuthProvider ? { inheritedAuthProvider } : {}) });
|
|
1354
1603
|
// THE DECLARED BIRTH EFFECT (G3 — the unix model): the recipe rides the committed intent as a declared
|
|
1355
1604
|
// output (`captured_ports.births`). The kernel — reading the `.births` DECLARATION off the law manifest
|
|
1356
1605
|
// (the `nomosBirthGate` era key, NEVER this CloudWorkspace aggregate) — takes the recipe off the intent
|
|
1357
1606
|
// after admit and spawns + self-validates the child through the child's OWN gate. So birth is an
|
|
1358
1607
|
// EXPLICIT, declared consequence of the offer, not a side-effect inferred by scanning domain state.
|
|
1359
|
-
birth({ workspace: p.name, genesisChain
|
|
1608
|
+
birth({ workspace: p.name, genesisChain });
|
|
1360
1609
|
}
|
|
1361
1610
|
return [];
|
|
1362
1611
|
})
|
|
1363
1612
|
.reads(workspacesByPrincipal, quotaByPrincipal, cloudPolicy) // arm the WorkspaceQuota captured-read gate (S2)
|
|
1613
|
+
// The parent's verifier, in the exact provider/keys/certificates order the read helper executes.
|
|
1614
|
+
.reads(authProvider)
|
|
1615
|
+
.reads(authProviderKeysQuery)
|
|
1616
|
+
.reads(authProviderCertificatesQuery)
|
|
1617
|
+
// The parent's current operator subjects (D15) — readInheritedOperators's one declared dependency.
|
|
1618
|
+
.reads(relationTuplesByObject)
|
|
1619
|
+
// The parent's current enroller tuples (D22) — readInheritedEnrollers's one declared dependency.
|
|
1620
|
+
.reads(relationTuplesByRelation)
|
|
1364
1621
|
.births(); // BIRTH IS A DECLARED KERNEL PRIMITIVE (G3): the kernel folds the carried recipe; posture is invariant law
|
|
1365
1622
|
|
|
1366
1623
|
/** workspacesByStatus — the birth provider drains `requested` CloudWorkspaces that CARRY A foundingAdminHash
|
|
@@ -1407,6 +1664,8 @@ export {
|
|
|
1407
1664
|
AUTH_PROVIDER_ID,
|
|
1408
1665
|
AUTH_PROVIDER_KEY_ID_PREFIX,
|
|
1409
1666
|
AUTH_PROVIDER_CERTIFICATE_ID_PREFIX,
|
|
1667
|
+
AUTH_PROVIDER_AUTHORITY,
|
|
1668
|
+
AUTH_PROVIDER_EPOCH_CONSUMER,
|
|
1410
1669
|
AuthProvider,
|
|
1411
1670
|
AuthProviderKey,
|
|
1412
1671
|
AuthProviderCertificate,
|
|
@@ -1419,6 +1678,10 @@ export {
|
|
|
1419
1678
|
seedAuthProvider,
|
|
1420
1679
|
authProviderSeedBeforeWarrant,
|
|
1421
1680
|
setAuthProvider,
|
|
1681
|
+
adoptIdentityProviderWitness,
|
|
1682
|
+
identityProviderSourceTrust,
|
|
1683
|
+
authProviderSourceRelations,
|
|
1684
|
+
authProviderEpochConsumerRelations,
|
|
1422
1685
|
authProvider,
|
|
1423
1686
|
authProviderKeys,
|
|
1424
1687
|
authProviderCertificates,
|
|
@@ -1429,9 +1692,15 @@ import {
|
|
|
1429
1692
|
AuthProviderCertificate,
|
|
1430
1693
|
AuthProviderKey,
|
|
1431
1694
|
authProvider,
|
|
1695
|
+
authProviderCertificates as authProviderCertificatesQuery,
|
|
1696
|
+
authProviderKeys as authProviderKeysQuery,
|
|
1432
1697
|
authProviderKeySet,
|
|
1698
|
+
adoptIdentityProviderWitness,
|
|
1699
|
+
readAuthProviderVerifyingConfiguration,
|
|
1700
|
+
seedAuthProvider,
|
|
1433
1701
|
setAuthProvider,
|
|
1434
1702
|
writeAuthProviderKeySet,
|
|
1703
|
+
type AuthProviderVerifyingConfiguration,
|
|
1435
1704
|
} from "./auth_provider_law.js";
|
|
1436
1705
|
|
|
1437
1706
|
/**
|
|
@@ -1726,17 +1995,102 @@ export const grantAdmin = directive("grantAdmin")
|
|
|
1726
1995
|
// identity, so it survives device-key ROTATION (the signer indirection's whole point) and matches
|
|
1727
1996
|
// the subject a SIGNED author resolves to. `keyHash` (a `key:<hash>` subject) is the legacy
|
|
1728
1997
|
// key-centric grant (the bearer-secret lane). Exactly one — mirrors grantCreation.
|
|
1729
|
-
|
|
1730
|
-
|
|
1998
|
+
// `consolePrincipal` (a `console:<subject>`) — an operator the console enrols (D22): how a real
|
|
1999
|
+
// operator takes over a workspace founded by a stand-in, after birth, with no re-found.
|
|
2000
|
+
...governanceSubjectFields,
|
|
1731
2001
|
label: z.string().min(1),
|
|
1732
2002
|
grantedBy: z.string().min(1),
|
|
1733
2003
|
grantedAt: epochMs,
|
|
1734
2004
|
})
|
|
1735
|
-
.refine(
|
|
2005
|
+
.refine(hasOneGovernanceSubject, { message: "grantAdmin needs exactly one of keyHash (a key: subject), principal (a user: subject) or consolePrincipal (a console: subject)", path: ["keyHash"] }),
|
|
1736
2006
|
)
|
|
1737
|
-
.plan((p) => writeTuple({ object: SELF_ADMIN_OBJECT, relation: "admin", subject: p
|
|
2007
|
+
.plan((p) => writeTuple({ object: SELF_ADMIN_OBJECT, relation: "admin", subject: governanceSubject(p), grantedBy: p.grantedBy, grantedAt: String(p.grantedAt) }))
|
|
1738
2008
|
.requires("admin"); // only an admin grants admin (pre-apply roster ⇒ no self-grant)
|
|
1739
2009
|
|
|
2010
|
+
/**
|
|
2011
|
+
* grantLawOperator — seat `workspace:self#operator@<subject>` (identity target model D15): who may
|
|
2012
|
+
* install, stage or promote law here. Distinct from {@link grantOperator}/{@link revokeOperator}
|
|
2013
|
+
* above, which toggle this workspace's OWN {@link GovernancePosture} (managed vs sovereign) — a
|
|
2014
|
+
* coarse platform-relationship flag, not a principal-level grant. An admin seats this, exactly as an
|
|
2015
|
+
* admin grants admin; a child born under this workspace gets a copy of whoever currently holds it at
|
|
2016
|
+
* the moment of birth (`buildGenesisChain`'s `inheritedOperators`, `readInheritedOperators` below) —
|
|
2017
|
+
* a fact recorded once, never a live read of the parent afterward.
|
|
2018
|
+
*/
|
|
2019
|
+
export const grantLawOperator = directive("grantLawOperator")
|
|
2020
|
+
.ensures(RelationTuple)
|
|
2021
|
+
.payload(
|
|
2022
|
+
z
|
|
2023
|
+
.object({
|
|
2024
|
+
...governanceSubjectFields,
|
|
2025
|
+
label: z.string().min(1),
|
|
2026
|
+
grantedBy: z.string().min(1),
|
|
2027
|
+
grantedAt: epochMs,
|
|
2028
|
+
})
|
|
2029
|
+
.refine(hasOneGovernanceSubject, { message: "grantLawOperator needs exactly one of keyHash (a key: subject), principal (a user: subject) or consolePrincipal (a console: subject)", path: ["keyHash"] }),
|
|
2030
|
+
)
|
|
2031
|
+
// An operator is who installs law (D15), so the seat carries workspace:self#installDomain with it.
|
|
2032
|
+
.plan((p) => [
|
|
2033
|
+
...writeTuple({ object: SELF_ADMIN_OBJECT, relation: "operator", subject: governanceSubject(p), grantedBy: p.grantedBy, grantedAt: String(p.grantedAt) }),
|
|
2034
|
+
...writeTuple({ object: SELF_ADMIN_OBJECT, relation: MODEL_LIFECYCLE_AUTHORITY, subject: governanceSubject(p), grantedBy: p.grantedBy, grantedAt: String(p.grantedAt) }),
|
|
2035
|
+
])
|
|
2036
|
+
.requires("admin");
|
|
2037
|
+
|
|
2038
|
+
/** revokeLawOperator — the operator-relation mirror of revokeAdmin; see its own doc for the leaf mechanics. */
|
|
2039
|
+
export const revokeLawOperator = directive("revokeLawOperator")
|
|
2040
|
+
.ensures(RelationTuple)
|
|
2041
|
+
.payload(
|
|
2042
|
+
z
|
|
2043
|
+
.object({
|
|
2044
|
+
...governanceSubjectFields,
|
|
2045
|
+
revokedBy: z.string().min(1),
|
|
2046
|
+
revokedAt: epochMs,
|
|
2047
|
+
})
|
|
2048
|
+
.refine(hasOneGovernanceSubject, { message: "revokeLawOperator needs exactly one of keyHash, principal or consolePrincipal", path: ["keyHash"] }),
|
|
2049
|
+
)
|
|
2050
|
+
.plan((p) => [
|
|
2051
|
+
...removeTuple({ object: SELF_ADMIN_OBJECT, relation: "operator", subject: governanceSubject(p), grantedBy: p.revokedBy, grantedAt: String(p.revokedAt), revokedBy: p.revokedBy, revokedAt: String(p.revokedAt) }),
|
|
2052
|
+
...removeTuple({ object: SELF_ADMIN_OBJECT, relation: MODEL_LIFECYCLE_AUTHORITY, subject: governanceSubject(p), grantedBy: p.revokedBy, grantedAt: String(p.revokedAt), revokedBy: p.revokedBy, revokedAt: String(p.revokedAt) }),
|
|
2053
|
+
])
|
|
2054
|
+
.requires("admin");
|
|
2055
|
+
|
|
2056
|
+
/**
|
|
2057
|
+
* grantEnroller — seat `principalScope:<scope>#enroller@<subject>` (identity target model D22): who may
|
|
2058
|
+
* write the first signer key of a `<scope>:` principal (`enrollDevice`) and revoke that scope's keys
|
|
2059
|
+
* (`revokeDevice`). Mirrors {@link grantLawOperator} exactly: admin-gated, one subject, and copied into
|
|
2060
|
+
* a child at birth (`buildGenesisChain`'s `inheritedEnrollers`).
|
|
2061
|
+
*/
|
|
2062
|
+
export const grantEnroller = directive("grantEnroller")
|
|
2063
|
+
.ensures(RelationTuple)
|
|
2064
|
+
.payload(
|
|
2065
|
+
z
|
|
2066
|
+
.object({
|
|
2067
|
+
scope: providerScopeField,
|
|
2068
|
+
...governanceSubjectFields,
|
|
2069
|
+
label: z.string().min(1),
|
|
2070
|
+
grantedBy: z.string().min(1),
|
|
2071
|
+
grantedAt: epochMs,
|
|
2072
|
+
})
|
|
2073
|
+
.refine(hasOneGovernanceSubject, { message: "grantEnroller needs exactly one of keyHash, principal or consolePrincipal", path: ["keyHash"] }),
|
|
2074
|
+
)
|
|
2075
|
+
.plan((p) => writeTuple({ object: principalScopeObject(p.scope), relation: PRINCIPAL_SCOPE_ENROLLER_RELATION, subject: governanceSubject(p), grantedBy: p.grantedBy, grantedAt: String(p.grantedAt) }))
|
|
2076
|
+
.requires("admin");
|
|
2077
|
+
|
|
2078
|
+
/** revokeEnroller — the enroller-relation mirror of {@link revokeLawOperator}. */
|
|
2079
|
+
export const revokeEnroller = directive("revokeEnroller")
|
|
2080
|
+
.ensures(RelationTuple)
|
|
2081
|
+
.payload(
|
|
2082
|
+
z
|
|
2083
|
+
.object({
|
|
2084
|
+
scope: providerScopeField,
|
|
2085
|
+
...governanceSubjectFields,
|
|
2086
|
+
revokedBy: z.string().min(1),
|
|
2087
|
+
revokedAt: epochMs,
|
|
2088
|
+
})
|
|
2089
|
+
.refine(hasOneGovernanceSubject, { message: "revokeEnroller needs exactly one of keyHash, principal or consolePrincipal", path: ["keyHash"] }),
|
|
2090
|
+
)
|
|
2091
|
+
.plan((p) => removeTuple({ object: principalScopeObject(p.scope), relation: PRINCIPAL_SCOPE_ENROLLER_RELATION, subject: governanceSubject(p), grantedBy: p.revokedBy, grantedAt: String(p.revokedAt), revokedBy: p.revokedBy, revokedAt: String(p.revokedAt) }))
|
|
2092
|
+
.requires("admin");
|
|
2093
|
+
|
|
1740
2094
|
/**
|
|
1741
2095
|
* revokeAdmin — flip an AdminGrant to `revoked`. The key stops verifying at fold
|
|
1742
2096
|
* time; the grant record (who granted it, when, who killed it) stays on the
|
|
@@ -1750,16 +2104,29 @@ export const revokeAdmin = directive("revokeAdmin")
|
|
|
1750
2104
|
.payload(
|
|
1751
2105
|
z
|
|
1752
2106
|
.object({
|
|
1753
|
-
|
|
1754
|
-
principal: z.string().min(1).optional(),
|
|
2107
|
+
...governanceSubjectFields,
|
|
1755
2108
|
revokedBy: z.string().min(1),
|
|
1756
2109
|
revokedAt: epochMs,
|
|
1757
2110
|
})
|
|
1758
|
-
.refine(
|
|
2111
|
+
.refine(hasOneGovernanceSubject, { message: "revokeAdmin needs exactly one of keyHash, principal or consolePrincipal", path: ["keyHash"] }),
|
|
1759
2112
|
)
|
|
1760
|
-
.plan((p) => removeTuple({ object: SELF_ADMIN_OBJECT, relation: "admin", subject: p
|
|
2113
|
+
.plan((p) => removeTuple({ object: SELF_ADMIN_OBJECT, relation: "admin", subject: governanceSubject(p), grantedBy: p.revokedBy, grantedAt: String(p.revokedAt), revokedBy: p.revokedBy, revokedAt: String(p.revokedAt) }))
|
|
1761
2114
|
.requires("admin");
|
|
1762
2115
|
|
|
2116
|
+
/** A workspace always keeps an admin: revoking the last one (a handover done in the wrong order) is refused. */
|
|
2117
|
+
export const lastAdminRemains = workspaceInvariant("LastAdminRemains")
|
|
2118
|
+
.on("revokeAdmin")
|
|
2119
|
+
.reads(() => [refAs("tuple", "RelationTuple", "pre:" + relationTupleInstanceId(SELF_ADMIN_OBJECT, "admin"))])
|
|
2120
|
+
.assert(({ tuple }, ctx) => {
|
|
2121
|
+
const intent = (ctx?.intent ?? {}) as { keyHash?: string; principal?: string; consolePrincipal?: string };
|
|
2122
|
+
let leaving = "";
|
|
2123
|
+
try { leaving = governanceSubject(intent); } catch { return { reject: "revoke-admin-names-no-subject" }; }
|
|
2124
|
+
const subjects = (tuple as { subjects?: Record<string, { status?: string }> } | undefined)?.subjects ?? {};
|
|
2125
|
+
return Object.entries(subjects).some(([subject, leaf]) => leaf?.status === "active" && subject !== leaving)
|
|
2126
|
+
? { accept: true }
|
|
2127
|
+
: { reject: "last-admin-cannot-be-revoked" };
|
|
2128
|
+
});
|
|
2129
|
+
|
|
1763
2130
|
/**
|
|
1764
2131
|
* grantCreation — mint a workspace-creation credential record (`status:"active"`).
|
|
1765
2132
|
* The lawful replacement for the `NOMOS_CLOUD_INVITE_KEY` env var: who may invite
|