@githolon/dsl 0.108.6 → 0.110.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +2083 -1248
- 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/framework/home.ts
CHANGED
|
@@ -4,738 +4,9 @@
|
|
|
4
4
|
// If a file isn't this / hosting this / authoring for this / proving this — it's gone.
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* framework/home.ts
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* It holds only PUBLIC material + signed facts (private keys never leave the client, so the cloud hosting
|
|
12
|
-
* it stays operator-blind):
|
|
13
|
-
* - KEY DIRECTORY — the identity's public device keys: the `signer` relation
|
|
14
|
-
* (`identity:<principal>#signer@key:<hash>`, `framework/signing_identity.ts`). Re-exported here so a
|
|
15
|
-
* home holon's law carries it: "wrap the scope key to U's device" becomes "read U's home key roster."
|
|
16
|
-
* - SHARED-WITH-ME index (§5) — one record per verified cross-custody attestation delivered here, so
|
|
17
|
-
* "show me everything shared with me" is a LOCAL query, no fan-out.
|
|
18
|
-
* - INBOX — grants/invites/notifications/dead-letters addressed to the identity.
|
|
19
|
-
*
|
|
20
|
-
* THE FORWARD-CHECK DOCTRINE (§5): the index is a DISCOVERY HINT, not the authority. When the identity
|
|
21
|
-
* actually opens the asserting workspace, THAT workspace's gate does the live `Check` — so a stale share
|
|
22
|
-
* (the asserter revoked it) is fail-safe: the identity sees a workspace it can no longer open, the forward
|
|
23
|
-
* check denies, the hint is pruned. (The cross-custody ATTESTATION that proves a delivered share is signed
|
|
24
|
-
* + verifiable is §3; the host DELIVERY lane that fills the index is §5. This file is the law that holds
|
|
25
|
-
* the result, and the owner-authored lane to maintain it.)
|
|
7
|
+
* @deprecated `framework/home.ts` is the OLD NAME of `framework/receiving_group.ts` (the receiving
|
|
8
|
+
* group is the framework concept; "home" is a tenant's word for the business law it composes into
|
|
9
|
+
* that anchor — `architecture/receiving_group_lifecycle.md`). This shim re-exports the same
|
|
10
|
+
* declarations, byte-identical, for ONE release; import `./receiving_group.js` instead.
|
|
26
11
|
*/
|
|
27
|
-
|
|
28
|
-
import type { ApplicationHomeGenesis } from "../application_home_genesis.js";
|
|
29
|
-
import { aggregate, instance, OWNED_READ_RELATION } from "../aggregate.js";
|
|
30
|
-
import { sha256Digest, t } from "../fields.js";
|
|
31
|
-
import { Lww } from "../drivers.js";
|
|
32
|
-
import { directive } from "../directive.js";
|
|
33
|
-
import { ensure } from "../authoring.js";
|
|
34
|
-
import { set, withMarker, type PlannedOp } from "../ops.js";
|
|
35
|
-
import { query } from "../query.js";
|
|
36
|
-
import { birth, type WorkspaceRole } from "../births.js";
|
|
37
|
-
import {
|
|
38
|
-
authProvider as authProviderQuery,
|
|
39
|
-
authProviderCertificates as authProviderCertificatesQuery,
|
|
40
|
-
authProviderKeys as authProviderKeysQuery,
|
|
41
|
-
readAuthProviderVerifyingConfiguration,
|
|
42
|
-
seedAuthProvider,
|
|
43
|
-
} from "./auth_provider_law.js";
|
|
44
|
-
import { readRef, readSet, workspaceInvariant, refAs } from "./workspace_invariant.js";
|
|
45
|
-
import {
|
|
46
|
-
identityRelations,
|
|
47
|
-
} from "./signing_identity.js";
|
|
48
|
-
import {
|
|
49
|
-
RelationTuple,
|
|
50
|
-
writeTuple,
|
|
51
|
-
} from "./relations.js";
|
|
52
|
-
import { relationType, self, user, selfObject } from "../relation_schema.js";
|
|
53
|
-
import { requireParentAttestedBirth, type ParentAttestedBirthMarker } from "../births.js";
|
|
54
|
-
import { GenesisWarrant, seedGenesis } from "./genesis.js";
|
|
55
|
-
import { idOf } from "../value_object.js";
|
|
56
|
-
import {
|
|
57
|
-
DomainInstallExecutor,
|
|
58
|
-
domainInstallGenesisOffer,
|
|
59
|
-
} from "./domain_lifecycle.js";
|
|
60
|
-
import { birthCertificatePayload } from "./birth_certificate_law.js";
|
|
61
|
-
|
|
62
|
-
// `nomos.sha256` — the TRUSTLESS, pure hash computed IN the githolon (Rust sha2 bound in the sealed engine;
|
|
63
|
-
// see deterministic-rquickjs). Available as a global to plans + invariant predicates (like `nomos.mint`); it
|
|
64
|
-
// lets the home law re-derive `home-<hash(owner)>` itself, so the SQUAT invariant runs in-law on every peer.
|
|
65
|
-
declare const nomos: { sha256(input: string): string };
|
|
66
|
-
|
|
67
|
-
/** The KEY DIRECTORY is the `signer` relation — re-exported so a home holon's law composes it (the
|
|
68
|
-
* identity's public device keys, enrolled via `enrollSigner`, checked by the gate). */
|
|
69
|
-
export { identityRelations };
|
|
70
|
-
|
|
71
|
-
/** THE GENESIS WARRANT primitives — re-exported so a HOME law carries them in the `home` domain key. The
|
|
72
|
-
* birthHome genesis chain runs `home/seedGenesis` to record the home's unique self-id (== homeName), so
|
|
73
|
-
* `workspace_self_id` resolves on the home and BOTH the signed-author regime + the parent-attested-birth
|
|
74
|
-
* cert door FIRE on every home (BREAK 1). Without this the home is unwarranted and both doors are inert. */
|
|
75
|
-
export { GenesisWarrant, seedGenesis };
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* THE RECEIVING GROUP — one sovereign framework identity whose enrolled devices clone this same holon.
|
|
79
|
-
* It is not a tenant Person, an IdP account or a host-owned account. The native global
|
|
80
|
-
* `identity:<principal>#signer@key:<hash>` relation is its device roster; this singleton binds the group's
|
|
81
|
-
* stable principal to the workspace that carries that roster and its access manifest.
|
|
82
|
-
*
|
|
83
|
-
* The wire identifiers are deliberately obscure framework names. Tenant business packages may model their
|
|
84
|
-
* own `ReceivingGroup`, `home` or `group` concepts without silently colliding with this implementation.
|
|
85
|
-
*/
|
|
86
|
-
export const RECEIVING_GROUP_ID = "nomos-internal-receiving-group-7c1f5e:self";
|
|
87
|
-
/** A receiving group's self-committed workspace-name prefix. */
|
|
88
|
-
export const RECEIVING_GROUP_NAME_PREFIX = "nomos-rg-";
|
|
89
|
-
export const RECEIVING_GROUP_NAME_HASH_LEN = 40;
|
|
90
|
-
export const RECEIVING_GROUP_POLICY_ID = "nomos-internal-receiving-group-policy-7c1f5e:self";
|
|
91
|
-
export const ReceivingGroup = aggregate("NomosInternalReceivingGroup7c1f5e", {
|
|
92
|
-
/** The stable Zanzibar principal represented by this group. Credentials may locate it but do not own it. */
|
|
93
|
-
principal: t.string().merge(Lww),
|
|
94
|
-
/** The group's self-committed workspace name, deterministically bound to its stable principal. */
|
|
95
|
-
workspaceName: t.string().merge(Lww),
|
|
96
|
-
/** ISO-8601, caller-stamped (determinism — no clock in the plan). */
|
|
97
|
-
bornAt: t.string().merge(Lww),
|
|
98
|
-
// The group's genesis seats its controller in OWNED_READ_RELATION below. Declaring that same capability
|
|
99
|
-
// here makes the law's coarse pack gate recognise the seat, so a newly enrolled device can clone its own
|
|
100
|
-
// receiving group before any tenant records or tenant-authored grants exist. This remains ordinary,
|
|
101
|
-
// replayable Zanzibar state: revocation removes the seat; there is no kernel-level founder bypass.
|
|
102
|
-
}, { cap: 1 }).readableBy(OWNED_READ_RELATION);
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* The framework-owned device lifecycle policy for one receiving group. This is deliberately data, not a
|
|
106
|
-
* client-side branch: every peer replays the same rule. The first supported posture is intentionally small
|
|
107
|
-
* and secure: a live, verified device may add or revoke another device; keyless IdP enrolment is only the
|
|
108
|
-
* pre-group bootstrap lane.
|
|
109
|
-
*
|
|
110
|
-
* ALL-DEVICE-LOSS RECOVERY — CO2 already recovers through its platform AuthProvider, but the implementation
|
|
111
|
-
* reaches that result by repeating birth after this home's direct enrollment policy refuses. The corrected
|
|
112
|
-
* design (`architecture/guardian_device_recovery.md`, reconciled 2026-08-10) makes recovery authority an
|
|
113
|
-
* explicit tenant-selected policy: platform identity provider or guardian quorum. The missing work is to
|
|
114
|
-
* evaluate that choice at the existing child's frontier and delete the client-side birth-repeat bypass.
|
|
115
|
-
*/
|
|
116
|
-
export const ReceivingGroupPolicy = aggregate("NomosInternalReceivingGroupPolicy7c1f5e", {
|
|
117
|
-
additionalDevice: t.string().merge(Lww),
|
|
118
|
-
revocation: t.string().merge(Lww),
|
|
119
|
-
recovery: t.string().merge(Lww),
|
|
120
|
-
guardianQuorum: t.int().merge(Lww),
|
|
121
|
-
setAt: t.string().merge(Lww),
|
|
122
|
-
}, { cap: 1 }).public();
|
|
123
|
-
|
|
124
|
-
export const DEFAULT_RECEIVING_GROUP_POLICY = {
|
|
125
|
-
additionalDevice: "current-device",
|
|
126
|
-
revocation: "current-device",
|
|
127
|
-
recovery: "guardian-quorum",
|
|
128
|
-
guardianQuorum: 1,
|
|
129
|
-
} as const;
|
|
130
|
-
|
|
131
|
-
/** The recovery authorities a receiving group may explicitly select. The default remains guardian
|
|
132
|
-
* quorum; an application must deliberately choose its attested parent identity provider. */
|
|
133
|
-
export const RECEIVING_GROUP_RECOVERY_POLICIES = [
|
|
134
|
-
"guardian-quorum",
|
|
135
|
-
"platform-identity-provider",
|
|
136
|
-
] as const;
|
|
137
|
-
export const receivingGroupRecoveryPolicy = z.enum(RECEIVING_GROUP_RECOVERY_POLICIES);
|
|
138
|
-
export type ReceivingGroupRecoveryPolicy = z.infer<typeof receivingGroupRecoveryPolicy>;
|
|
139
|
-
export const PLATFORM_IDENTITY_PROVIDER_RECOVERY: ReceivingGroupRecoveryPolicy =
|
|
140
|
-
"platform-identity-provider";
|
|
141
|
-
|
|
142
|
-
function writeReceivingGroupPolicy(p: {
|
|
143
|
-
setAt: string;
|
|
144
|
-
recovery?: ReceivingGroupRecoveryPolicy | undefined;
|
|
145
|
-
}): PlannedOp[] {
|
|
146
|
-
const policy = instance(ReceivingGroupPolicy, RECEIVING_GROUP_POLICY_ID);
|
|
147
|
-
return [
|
|
148
|
-
set(policy, "additionalDevice", DEFAULT_RECEIVING_GROUP_POLICY.additionalDevice),
|
|
149
|
-
set(policy, "revocation", DEFAULT_RECEIVING_GROUP_POLICY.revocation),
|
|
150
|
-
set(policy, "recovery", p.recovery ?? DEFAULT_RECEIVING_GROUP_POLICY.recovery),
|
|
151
|
-
set(policy, "guardianQuorum", DEFAULT_RECEIVING_GROUP_POLICY.guardianQuorum),
|
|
152
|
-
set(policy, "setAt", p.setAt),
|
|
153
|
-
];
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/** Genesis-only default policy. Policy changes become a separate, guardian-aware ceremony. */
|
|
157
|
-
export const seedReceivingGroupPolicy = directive("nomosInternalSeedReceivingGroupPolicy7c1f5e")
|
|
158
|
-
.ensures(ReceivingGroupPolicy)
|
|
159
|
-
.payload(z.object({
|
|
160
|
-
setAt: z.string().min(1),
|
|
161
|
-
recovery: receivingGroupRecoveryPolicy.optional(),
|
|
162
|
-
}))
|
|
163
|
-
.plan((p) => writeReceivingGroupPolicy(p));
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* The group's controller relation binds its stable principal inside the same genesis. Business representation
|
|
167
|
-
* remains separate Zanzibar edges; this relation only establishes who controls this receiving-group holon.
|
|
168
|
-
*/
|
|
169
|
-
export const receivingGroupRelations = relationType("nomos.internal.receiving-group.7c1f5e").relation("controller", {
|
|
170
|
-
rewrite: self(),
|
|
171
|
-
allow: [user()],
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
/** Stamp the receiving group and atomically seat its controller relation. */
|
|
175
|
-
export function writeReceivingGroup(p: { principal: string; workspaceName: string; bornAt: string }): PlannedOp[] {
|
|
176
|
-
const h = instance(ReceivingGroup, RECEIVING_GROUP_ID);
|
|
177
|
-
return [
|
|
178
|
-
set(h, "principal", p.principal),
|
|
179
|
-
set(h, "workspaceName", p.workspaceName),
|
|
180
|
-
set(h, "bornAt", p.bornAt),
|
|
181
|
-
...writeTuple({
|
|
182
|
-
object: selfObject(receivingGroupRelations),
|
|
183
|
-
relation: "controller",
|
|
184
|
-
subject: p.principal,
|
|
185
|
-
grantedBy: p.principal,
|
|
186
|
-
grantedAt: p.bornAt,
|
|
187
|
-
}),
|
|
188
|
-
// A device clones the encrypted workspace before record-level ownership can be evaluated locally.
|
|
189
|
-
// Seat the group's controller for that ciphertext transport in the same genesis; individual owned
|
|
190
|
-
// records still require their own per-record reader edge before they decrypt or appear in reads.
|
|
191
|
-
...writeTuple({
|
|
192
|
-
object: "workspace:self",
|
|
193
|
-
relation: OWNED_READ_RELATION,
|
|
194
|
-
subject: p.principal,
|
|
195
|
-
grantedBy: p.principal,
|
|
196
|
-
grantedAt: p.bornAt,
|
|
197
|
-
}),
|
|
198
|
-
];
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Genesis-only receiving-group stamp. The name is caller-supplied but the invariant below re-derives it.
|
|
203
|
-
*/
|
|
204
|
-
export const seedReceivingGroup = directive("nomosInternalSeedReceivingGroup7c1f5e")
|
|
205
|
-
.ensures(ReceivingGroup)
|
|
206
|
-
.payload(z.object({ principal: z.string().min(1), workspaceName: z.string().min(1), bornAt: z.string().min(1) }))
|
|
207
|
-
.plan((p) => writeReceivingGroup(p))
|
|
208
|
-
.alsoEnsures(RelationTuple);
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* THE SQUAT INVARIANT (home_holons §5) — a home holon's self-committed `homeName` MUST be the hash of its
|
|
212
|
-
* owner: `homeName == home-<sha256(principal)>`. Declared by the home law, it EXECUTES at the one gate — and
|
|
213
|
-
* crucially at `verify_chain` (the bailiff's upload-birth): a squatter's chain (claiming `home-<hash(bob)>`
|
|
214
|
-
* but owned by `mallory`) FAILS the home law's OWN gate during adoption — refused IN THE GITHOLON, BY THE LAW,
|
|
215
|
-
* never by a host check. The host only routes the chain to the name it commits to (custody). `nomos.sha256`
|
|
216
|
-
* re-derives the hash in-law on every peer, so the verdict is identical everywhere.
|
|
217
|
-
*/
|
|
218
|
-
export const receivingGroupNameBindsPrincipal = workspaceInvariant("ReceivingGroupNameBindsPrincipal")
|
|
219
|
-
.on("nomosInternalSeedReceivingGroup7c1f5e")
|
|
220
|
-
.reads(readSet(readRef("group", ReceivingGroup).at(RECEIVING_GROUP_ID)))
|
|
221
|
-
.declassify("the receiving-group address is a public hash of its stable principal; refusing a mismatch reveals no private field")
|
|
222
|
-
.assert(({ group }) => {
|
|
223
|
-
const g = (group ?? {}) as { principal?: string; workspaceName?: string };
|
|
224
|
-
const expected = RECEIVING_GROUP_NAME_PREFIX
|
|
225
|
-
+ nomos.sha256(String(g.principal ?? "")).slice(0, RECEIVING_GROUP_NAME_HASH_LEN);
|
|
226
|
-
return g.workspaceName === expected
|
|
227
|
-
? { accept: true }
|
|
228
|
-
: { reject: "a receiving group's workspace name must hash its stable principal" };
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
const receivingGroupPolicyRefs = readSet(
|
|
232
|
-
readRef("group", ReceivingGroup).at(RECEIVING_GROUP_ID),
|
|
233
|
-
readRef("policy", ReceivingGroupPolicy).at(RECEIVING_GROUP_POLICY_ID),
|
|
234
|
-
);
|
|
235
|
-
|
|
236
|
-
/** An IdP token may bootstrap the parent before the group exists; it may never bypass an existing group's
|
|
237
|
-
* device policy. An existing group chooses whether recovery is delegated to its platform AuthProvider or to
|
|
238
|
-
* guardians; the current default below says guardian, while CO2's current product behaviour is platform IdP.
|
|
239
|
-
*
|
|
240
|
-
* KNOWN GAP (`architecture/guardian_device_recovery.md`): this invariant is declared `.on("enrollFirstDevice")`
|
|
241
|
-
* and only fires when that directive targets THIS home directly. It is NOT re-applied when the birth
|
|
242
|
-
* offer-effect (`run_birth_effect`, repeating `nomosInternalBirthReceivingGroup` against an ALREADY-founded
|
|
243
|
-
* home) folds a signer seat via the SAME underlying mechanism. That is how CO2 recovery works today, but its
|
|
244
|
-
* home frontier still says `guardian-quorum`. The fix is not to ban platform recovery: add the explicit
|
|
245
|
-
* platform-identity-provider policy, make CO2 choose it, and have the child gate verify the chosen evidence. */
|
|
246
|
-
export const receivingGroupRejectsKeylessAdditionalDevice = workspaceInvariant("ReceivingGroupRejectsKeylessAdditionalDevice")
|
|
247
|
-
.on("enrollFirstDevice")
|
|
248
|
-
.reads(receivingGroupPolicyRefs)
|
|
249
|
-
.declassify("device enrollment deliberately reveals that this receiving group has already completed first-device bootstrap")
|
|
250
|
-
.assert(({ group }) => typeof group?.principal !== "string" || group.principal.length === 0
|
|
251
|
-
? { accept: true }
|
|
252
|
-
: { reject: "receiving-group-additional-device-requires-current-device-or-guardian" });
|
|
253
|
-
|
|
254
|
-
/** The shipped additional-device policy: an already enrolled, verified device signs the self-bound enrol. */
|
|
255
|
-
export const receivingGroupAdditionalDeviceFollowsPolicy = workspaceInvariant("ReceivingGroupAdditionalDeviceFollowsPolicy")
|
|
256
|
-
.on("enrollSignerSelf")
|
|
257
|
-
.reads(receivingGroupPolicyRefs)
|
|
258
|
-
.declassify("device lifecycle policy intentionally branches on principal_verified")
|
|
259
|
-
.assert(({ group, policy }, ctx) => {
|
|
260
|
-
if (typeof group?.principal !== "string" || group.principal.length === 0) return { accept: true };
|
|
261
|
-
const p = policy as { additionalDevice?: string } | undefined;
|
|
262
|
-
return p?.additionalDevice === "current-device" && ctx?.principalVerified === true
|
|
263
|
-
? { accept: true }
|
|
264
|
-
: { reject: "receiving-group-additional-device-policy-refused" };
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
/** The shipped revocation policy: a live verified group device authors the remove-wins signer change. */
|
|
268
|
-
export const receivingGroupRevocationFollowsPolicy = workspaceInvariant("ReceivingGroupRevocationFollowsPolicy")
|
|
269
|
-
.on("revokeSigner")
|
|
270
|
-
.reads(receivingGroupPolicyRefs)
|
|
271
|
-
.declassify("device lifecycle policy intentionally branches on principal_verified")
|
|
272
|
-
.assert(({ group, policy }, ctx) => {
|
|
273
|
-
if (typeof group?.principal !== "string" || group.principal.length === 0) return { accept: true };
|
|
274
|
-
const p = policy as { revocation?: string } | undefined;
|
|
275
|
-
return p?.revocation === "current-device" && ctx?.principalVerified === true
|
|
276
|
-
? { accept: true }
|
|
277
|
-
: { reject: "receiving-group-revocation-policy-refused" };
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
/** Re-derive a receiving group's workspace name in-law. */
|
|
281
|
-
export function receivingGroupNameOf(principal: string): string {
|
|
282
|
-
return RECEIVING_GROUP_NAME_PREFIX
|
|
283
|
-
+ nomos.sha256(String(principal)).slice(0, RECEIVING_GROUP_NAME_HASH_LEN);
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
/**
|
|
287
|
-
* `birthHome` — THE FRAMEWORK BIRTH PRIMITIVE for a home holon. This is the MECHANICS (OURS) so a tenant
|
|
288
|
-
* never hand-builds a home genesis: the parent (the cloud/platform whose governance includes this directive)
|
|
289
|
-
* ORDERS the birth of an identity's home holon, and the kernel's offer-effect spawns it + self-validates it
|
|
290
|
-
* through the child's OWN gate from intent 0 (the `.births()` declared consequence; `architecture/
|
|
291
|
-
* home_holons_and_cross_custody.md` + `sovereign_adapter.md` "birth is a kernel offer-effect").
|
|
292
|
-
*
|
|
293
|
-
* SELF-BOUND — squatting is structurally impossible (no separate grant needed; the policy gate is the
|
|
294
|
-
* tenant's `setAuthProvider` auth scoping, which decides whether the offering principal is verified at all):
|
|
295
|
-
* 1. The home OWNER rides the payload (`owner`, a `user:<uid>` subject). `ctx.principal()` is opaque
|
|
296
|
-
* PrincipalEvidence — it CANNOT be read as a raw string in-plan to compute the slot name — so the owner
|
|
297
|
-
* is payload-carried, but the binding below makes it sound.
|
|
298
|
-
* 2. The workspace name + the seeded `homeName` are BOTH derived from THE SAME payload `owner` via
|
|
299
|
-
* {@link homeNameOf} — they cannot diverge in this plan.
|
|
300
|
-
* 3. The child's genesis includes `seedHomeOwner(owner, homeNameOf(owner), bornAt)`, and the home law's
|
|
301
|
-
* {@link homeNameBindsOwner} invariant RE-DERIVES `home-<sha256(owner)>` at the child's gate (author AND
|
|
302
|
-
* verify_chain). So a chain that claims `home-<hash(alice)>` but seeds owner `bob` FAILS the child's own
|
|
303
|
-
* law — refused in the githolon, by the law, never by a host. A verified principal is required upstream
|
|
304
|
-
* (no anonymous home birth); the offer principal IS the auth boundary (the tenant's setAuthProvider).
|
|
305
|
-
*
|
|
306
|
-
* The genesis chain it authors (reusing the order-declares-the-law install shape — bytes resolved by hash
|
|
307
|
-
* from the parent's typed USDA closure custody):
|
|
308
|
-
* [ bootstrap/installDomain(frameworkHash), nomos/home installDomain(lawHash), seedHomeOwner(owner, …) ]
|
|
309
|
-
* `frameworkHash` (the bootstrap controller hash) + `lawHash` (the HOME law package domainHash) are
|
|
310
|
-
* tenant-PINNED at their governance compile (mirroring `birthChild`) — the end-user app supplies neither;
|
|
311
|
-
* the tenant's HomeBirth.viaCoordinator buildBody / their governance fills them. `seedHomeOwner` is INCLUDED
|
|
312
|
-
* so HomeOwner is seeded and `homeNameBindsOwner` passes (a birth without it would be an invalid, un-owned
|
|
313
|
-
* home).
|
|
314
|
-
*/
|
|
315
|
-
// Standalone framework law explicitly declares `home`; compiler-composed business applications explicitly
|
|
316
|
-
// declare the obscure APPLICATION_HOME_DOMAIN. The kernel refuses law with no attestation-seed registrar.
|
|
317
|
-
export const RECEIVING_GROUP_LAW_DOMAIN = "home";
|
|
318
|
-
/**
|
|
319
|
-
* Build the private home-birth primitive for the domain key that carries the home law.
|
|
320
|
-
*
|
|
321
|
-
* Most framework-authored laws still use the historic public `home` key through
|
|
322
|
-
* {@link birthHome}. Business packages use an obscure compiler-owned key instead, so a
|
|
323
|
-
* tenant remains free to model a business concept called "home". The key is closed over
|
|
324
|
-
* here and written into every child-genesis step; it is never a tenant payload field.
|
|
325
|
-
*/
|
|
326
|
-
export function birthReceivingGroupForDomain(
|
|
327
|
-
groupLawDomain: string,
|
|
328
|
-
maxChildWorkspacesPerUser: number,
|
|
329
|
-
birthPolicyDomains: readonly string[],
|
|
330
|
-
homeGenesis?: ApplicationHomeGenesis,
|
|
331
|
-
parentWorkspaceRoles: readonly WorkspaceRole[] = [],
|
|
332
|
-
) {
|
|
333
|
-
if (groupLawDomain.length === 0) {
|
|
334
|
-
throw new Error("birthReceivingGroupForDomain requires a non-empty receiving-group law domain");
|
|
335
|
-
}
|
|
336
|
-
if (!Number.isInteger(maxChildWorkspacesPerUser) || maxChildWorkspacesPerUser < 0) {
|
|
337
|
-
throw new Error(
|
|
338
|
-
"birthReceivingGroupForDomain requires an explicit non-negative maxChildWorkspacesPerUser; " +
|
|
339
|
-
"Nomos has no compiled birth-policy fallback",
|
|
340
|
-
);
|
|
341
|
-
}
|
|
342
|
-
const policyDomains = [...new Set(birthPolicyDomains)];
|
|
343
|
-
if (
|
|
344
|
-
policyDomains.length === 0 ||
|
|
345
|
-
policyDomains.some((domain) => domain.trim().length === 0) ||
|
|
346
|
-
!policyDomains.includes(groupLawDomain)
|
|
347
|
-
) {
|
|
348
|
-
throw new Error(
|
|
349
|
-
"birthReceivingGroupForDomain requires every co-resident birth-capable law domain, " +
|
|
350
|
-
"including its own domain; Nomos will not birth partially configured law",
|
|
351
|
-
);
|
|
352
|
-
}
|
|
353
|
-
const birthDirective = directive("nomosInternalBirthReceivingGroup7c1f5e")
|
|
354
|
-
.creates(ReceivingGroup)
|
|
355
|
-
.payload(
|
|
356
|
-
z.object({
|
|
357
|
-
/** The identity this home belongs to (a `user:<uid>` subject). The workspace name + seeded homeName are
|
|
358
|
-
* both `home-<sha256(owner)>` — self-bound, so you can only birth YOUR OWN home slot. */
|
|
359
|
-
owner: z.string().min(1),
|
|
360
|
-
/** The bootstrap framework controller content hash — tenant-pinned at governance compile (the child
|
|
361
|
-
* installs it IN-CHAIN as intent 0; the kernel resolves the bytes by hash from the parent's custody). */
|
|
362
|
-
frameworkHash: sha256Digest(),
|
|
363
|
-
/** The HOME law package domainHash — tenant-pinned at governance compile (the child's second install). */
|
|
364
|
-
lawHash: sha256Digest(),
|
|
365
|
-
/** ISO-8601 birth time, caller-stamped (the timestamp doctrine — the plan reads no clock). */
|
|
366
|
-
bornAt: z.string().min(1),
|
|
367
|
-
/** AUTHPROVIDER INHERITANCE — DEFAULT ON, opt out with `false`. Verification is PER-WORKSPACE (the
|
|
368
|
-
* kernel never walks up to the parent), so a PRIVATE child born without its own AuthProvider cannot
|
|
369
|
-
* verify any token — its own owner is locked out of verified reads (the co2 phase-6 wall). By
|
|
370
|
-
* default the birth READS the parent's `authProvider` row (the #58 captured-read lane — live at
|
|
371
|
-
* author, CAS-re-derived at the gate) and, when one is declared, COPIES it AS DATA into the child's
|
|
372
|
-
* genesis (a `setAuthProvider` step) — the child still OWNS its verifier as its own law-state; the
|
|
373
|
-
* parent's later rotations do NOT propagate (re-set on the child to rotate). Requirements the
|
|
374
|
-
* refusals name: the parent law must compose the `authProvider` query and the child law the
|
|
375
|
-
* `setAuthProvider` directive (both ride the framework export set). Pass `false` for a child that
|
|
376
|
-
* must NOT trust the parent's IdP (it then seeds its own or stays bare-principal). */
|
|
377
|
-
inheritAuthProvider: z.boolean().optional(),
|
|
378
|
-
}),
|
|
379
|
-
)
|
|
380
|
-
.plan((p) => {
|
|
381
|
-
const founder = p.owner; // the actor for the child's own genesis steps (its self-bound owner subject)
|
|
382
|
-
const groupName = receivingGroupNameOf(p.owner);
|
|
383
|
-
// THE PARENT'S DECLARED VERIFIER. This captured read supplies the inherited provider seed.
|
|
384
|
-
// Birth-certificate verification and founding-signer enrollment belong to the kernel-owned
|
|
385
|
-
// attestation step, so neither fact is duplicated in this tenant plan or payload.
|
|
386
|
-
const inheritedProvider = p.inheritAuthProvider === false
|
|
387
|
-
? undefined
|
|
388
|
-
: readAuthProviderVerifyingConfiguration();
|
|
389
|
-
const genesisChain: Array<{ domain: string; directiveId: string; actor: string; payload: Record<string, unknown>; domainHash?: string }> = [
|
|
390
|
-
// THE ORDER-DECLARED LAW INSTALL: two typed closure identities. The kernel resolves each
|
|
391
|
-
// closure from the parent's custody when it folds the birth; law bytes never ride the intent.
|
|
392
|
-
domainInstallGenesisOffer(
|
|
393
|
-
DomainInstallExecutor.StageZero,
|
|
394
|
-
p.frameworkHash,
|
|
395
|
-
founder,
|
|
396
|
-
),
|
|
397
|
-
domainInstallGenesisOffer(
|
|
398
|
-
DomainInstallExecutor.LifecycleController,
|
|
399
|
-
p.lawHash,
|
|
400
|
-
founder,
|
|
401
|
-
),
|
|
402
|
-
{
|
|
403
|
-
domain: groupLawDomain,
|
|
404
|
-
directiveId: "nomosInternalSeedReceivingGroupPolicy7c1f5e",
|
|
405
|
-
actor: founder,
|
|
406
|
-
payload: { setAt: p.bornAt },
|
|
407
|
-
},
|
|
408
|
-
// SEED THE OWNER — the home is born OWNED; the homeNameBindsOwner invariant in the child's law proves
|
|
409
|
-
// homeName == home-<sha256(owner)> at the child's own gate, so the slot can ONLY be its rightful owner's.
|
|
410
|
-
{
|
|
411
|
-
domain: groupLawDomain,
|
|
412
|
-
directiveId: "nomosInternalSeedReceivingGroup7c1f5e",
|
|
413
|
-
actor: founder,
|
|
414
|
-
payload: { principal: p.owner, workspaceName: groupName, bornAt: p.bornAt },
|
|
415
|
-
},
|
|
416
|
-
// The receiving group is born with its child-workspace allowance as explicit law-state. The
|
|
417
|
-
// value is closed over by the package's application policy, so neither the host nor the end
|
|
418
|
-
// user can substitute it in the offer payload.
|
|
419
|
-
...policyDomains.map((domain) => ({
|
|
420
|
-
domain,
|
|
421
|
-
directiveId: "seedBirthPolicy",
|
|
422
|
-
actor: founder,
|
|
423
|
-
payload: {
|
|
424
|
-
maxBirthsPerPrincipal: maxChildWorkspacesPerUser,
|
|
425
|
-
setBy: p.owner,
|
|
426
|
-
setAt: p.bornAt,
|
|
427
|
-
},
|
|
428
|
-
})),
|
|
429
|
-
// Tenant founding law is an ordered list of ordinary offers. Values derive solely from the
|
|
430
|
-
// canonical home facts; every payload is parsed by the target directive before it reaches
|
|
431
|
-
// the child's author gate. There is no host append point and no framework-selected fallback.
|
|
432
|
-
...(homeGenesis?.steps ?? []).map((step) => ({
|
|
433
|
-
domain: step.domain,
|
|
434
|
-
directiveId: step.directive.id,
|
|
435
|
-
actor: founder,
|
|
436
|
-
payload: step.directive.payloadSchema.parse(step.payload({
|
|
437
|
-
owner: p.owner,
|
|
438
|
-
workspaceName: groupName,
|
|
439
|
-
bornAt: p.bornAt,
|
|
440
|
-
})),
|
|
441
|
-
})),
|
|
442
|
-
];
|
|
443
|
-
// AUTHPROVIDER INHERITANCE (default ON — see the payload doc): copy the parent's declared provider
|
|
444
|
-
// (the up-front captured read above) AS DATA into the child genesis. The child owns the copy as its
|
|
445
|
-
// own law-state; nothing is inherited-by-reference. Opt out: `inheritAuthProvider: false`.
|
|
446
|
-
if (p.inheritAuthProvider !== false) {
|
|
447
|
-
if (inheritedProvider !== undefined) {
|
|
448
|
-
genesisChain.push({
|
|
449
|
-
domain: groupLawDomain,
|
|
450
|
-
directiveId: "seedAuthProvider",
|
|
451
|
-
actor: founder,
|
|
452
|
-
payload: {
|
|
453
|
-
...inheritedProvider,
|
|
454
|
-
label: "inherited-from-parent",
|
|
455
|
-
setBy: p.owner,
|
|
456
|
-
setAt: 1, // genesis position — deterministic, like enrollSigner's grantedAt
|
|
457
|
-
},
|
|
458
|
-
});
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
// THE DECLARED BIRTH EFFECT (the unix model): the recipe rides the committed intent as a declared output
|
|
462
|
-
// (captured_ports.births). The kernel — reading the `.births()` declaration off the law manifest — takes
|
|
463
|
-
// the recipe and spawns + self-validates the child through the child's OWN gate (each step self-verifies).
|
|
464
|
-
birth({
|
|
465
|
-
workspace: groupName,
|
|
466
|
-
genesisChain,
|
|
467
|
-
...(parentWorkspaceRoles.length > 0 ? { parentWorkspaceRoles } : {}),
|
|
468
|
-
});
|
|
469
|
-
// Parent/child lineage is an ordinary global Zanzibar relation in parent custody. The exact child
|
|
470
|
-
// address comes from the same plan which births it, so neither the host nor the caller can redirect
|
|
471
|
-
// this seat. Application law can then authorize upward workspace effects with the ordinary relation.
|
|
472
|
-
return writeTuple({
|
|
473
|
-
object: "workspace:self",
|
|
474
|
-
relation: "child",
|
|
475
|
-
subject: `workspace:${groupName}`,
|
|
476
|
-
grantedBy: p.owner,
|
|
477
|
-
grantedAt: p.bornAt,
|
|
478
|
-
});
|
|
479
|
-
})
|
|
480
|
-
.reads(authProviderQuery) // the parent-side AuthProvider capture the inheritance copies (the #58 lane)
|
|
481
|
-
.reads(authProviderKeysQuery)
|
|
482
|
-
.reads(authProviderCertificatesQuery)
|
|
483
|
-
.alsoEnsures(RelationTuple)
|
|
484
|
-
.births(); // BIRTH IS A DECLARED KERNEL PRIMITIVE — emits the `nomosBirthGate` era key; the kernel folds the recipe
|
|
485
|
-
return {
|
|
486
|
-
...birthDirective,
|
|
487
|
-
...(homeGenesis === undefined || homeGenesis.steps.length === 0
|
|
488
|
-
? {}
|
|
489
|
-
: {
|
|
490
|
-
birthGenesisRequirements: homeGenesis.steps.map((step) => ({
|
|
491
|
-
domain: step.domain,
|
|
492
|
-
directiveId: step.directive.id,
|
|
493
|
-
})),
|
|
494
|
-
}),
|
|
495
|
-
};
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
/** Build the standalone framework receiving-group law with an explicit allowance. */
|
|
499
|
-
export const birthReceivingGroup = (maxChildWorkspacesPerUser: number) =>
|
|
500
|
-
birthReceivingGroupForDomain(
|
|
501
|
-
RECEIVING_GROUP_LAW_DOMAIN,
|
|
502
|
-
maxChildWorkspacesPerUser,
|
|
503
|
-
[RECEIVING_GROUP_LAW_DOMAIN],
|
|
504
|
-
);
|
|
505
|
-
|
|
506
|
-
/**
|
|
507
|
-
* THE SHARED-WITH-ME INDEX (§5) — one record per cross-custody attestation delivered to this home holon:
|
|
508
|
-
* a signed edge `<asserterWorkspace> : <object> # <relation> @ this-identity`, indexed LOCALLY so the
|
|
509
|
-
* access list is a local query (no fan-out across every resource holon). A DISCOVERY HINT — the live authz
|
|
510
|
-
* stays the forward `Check` on the asserting holon when the identity opens it.
|
|
511
|
-
*/
|
|
512
|
-
export const SharedWithMe = aggregate("SharedWithMe", {
|
|
513
|
-
/** The holon that signed + delivered this edge — WHERE the live forward `Check` runs when opened. */
|
|
514
|
-
asserterWorkspace: t.string().merge(Lww),
|
|
515
|
-
/** The shared OBJECT — the whole workspace (`workspace:self`) or a specific record (`Entry:<id>`). */
|
|
516
|
-
object: t.string().merge(Lww),
|
|
517
|
-
/** The relation granted (`reader` / `editor` / a read cap). */
|
|
518
|
-
relation: t.string().merge(Lww),
|
|
519
|
-
/** The asserter's OWNER principal — whose key signed the attestation (verified at §3 admission). */
|
|
520
|
-
asserterPrincipal: t.string().merge(Lww),
|
|
521
|
-
/** ISO-8601, caller-stamped (determinism — no clock in the plan). */
|
|
522
|
-
attestedAt: t.string().merge(Lww),
|
|
523
|
-
/** PRUNED (forward-check fail-safe): set when the live `Check` on the asserter denies — the hint is
|
|
524
|
-
* dropped from the list but the audit row stays. `""` = live. */
|
|
525
|
-
prunedAt: t.string().merge(Lww),
|
|
526
|
-
}).public();
|
|
527
|
-
|
|
528
|
-
/** One idempotent access-manifest row per source edge in this home. Delivery is at-least-once: a retry,
|
|
529
|
-
* reconnect or source outbox replay must update the same bookmark rather than manufacture another thing the
|
|
530
|
-
* recipient appears to have access to. The home itself scopes the recipient, so the edge coordinate is the
|
|
531
|
-
* source workspace + protected object + granted relation. */
|
|
532
|
-
export function sharedWithMeId(asserterWorkspace: string, object: string, relation: string): string {
|
|
533
|
-
const coordinate = JSON.stringify([asserterWorkspace, object, relation]);
|
|
534
|
-
return `SharedWithMe_${nomos.sha256(coordinate)}`;
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
/**
|
|
538
|
-
* `recordShare` — index a cross-custody share into the home holon's access list. AUTHORED on the home
|
|
539
|
-
* holon (the identity's own subject-side root). The payload carries the §3 CROSS-CUSTODY ATTESTATION — a
|
|
540
|
-
* SIGNED QUOTE: the asserter's device `publicKey` + a `signature` over the edge
|
|
541
|
-
* `<asserterWorkspace>:<object>#<relation>@<this-home-owner>`. The home holon's OWN gate verifies it
|
|
542
|
-
* (`executor::record_share_attestation_violation`, bound to the warrant owner), so the BAILIFF can deliver
|
|
543
|
-
* it HOST-FREE (the host carries bytes, vouches nothing — the gate vouches). The owner lane authors the
|
|
544
|
-
* SAME shape (the owner holds the quote the asserter gave it). The signature is a verification input, not
|
|
545
|
-
* stored — only the edge facts fold into the index. The live authority stays the forward `Check` on the
|
|
546
|
-
* asserter when the identity opens it (§5 fail-safe); a stale/forged quote can't enter the list at all.
|
|
547
|
-
*/
|
|
548
|
-
export const recordShare = directive("recordShare")
|
|
549
|
-
.ensures(SharedWithMe)
|
|
550
|
-
.payload(
|
|
551
|
-
z.object({
|
|
552
|
-
asserterWorkspace: z.string().min(1),
|
|
553
|
-
object: z.string().min(1),
|
|
554
|
-
relation: z.string().min(1),
|
|
555
|
-
asserterPrincipal: z.string().min(1),
|
|
556
|
-
attestedAt: z.string().min(1),
|
|
557
|
-
/** The asserter's device PUBLIC KEY (base64) — what the §3 gate verifies the quote against. */
|
|
558
|
-
publicKey: z.string().min(1),
|
|
559
|
-
/** The asserter's SIGNATURE (base64) over the edge bytes, subject = this home's owner. */
|
|
560
|
-
signature: z.string().min(1),
|
|
561
|
-
}),
|
|
562
|
-
)
|
|
563
|
-
.plan((p) => {
|
|
564
|
-
// ENSURE, never CREATE: signed delivery is retryable and therefore at-least-once. Re-delivery (including
|
|
565
|
-
// a later re-grant after prune) refreshes this exact access edge and makes it live again.
|
|
566
|
-
ensure(SharedWithMe, sharedWithMeId(p.asserterWorkspace, p.object, p.relation))
|
|
567
|
-
.set("asserterWorkspace", p.asserterWorkspace)
|
|
568
|
-
.set("object", p.object)
|
|
569
|
-
.set("relation", p.relation)
|
|
570
|
-
.set("asserterPrincipal", p.asserterPrincipal)
|
|
571
|
-
.set("attestedAt", p.attestedAt)
|
|
572
|
-
.set("prunedAt", "");
|
|
573
|
-
return [];
|
|
574
|
-
})
|
|
575
|
-
// CROSS-CUSTODY ATTESTATION-AUTHORIZED (§3/§5): the payload's signed quote IS the authorization (lowered
|
|
576
|
-
// into the `nomosAttestationGate` era key) — the one gate verifies it against the home's owner (the
|
|
577
|
-
// LAW-DECLARED owner-source below, NOT a kernel-hardcoded id) + pins the principal to the attestation key,
|
|
578
|
-
// so the bailiff delivers it host-free to an OFFLINE subject (no device key, no author block).
|
|
579
|
-
.attestationAuthorized({ ownerObject: RECEIVING_GROUP_ID, ownerField: "principal" });
|
|
580
|
-
|
|
581
|
-
/**
|
|
582
|
-
* `pruneShare` — fail-safe drop of a hint whose forward `Check` denied (the asserter revoked it). The row
|
|
583
|
-
* stays for audit; `prunedAt` removes it from the live list. (The forward check itself is the resource
|
|
584
|
-
* holon's job — this records the verdict locally.)
|
|
585
|
-
*/
|
|
586
|
-
export const pruneShare = directive("pruneShare")
|
|
587
|
-
.mutates(SharedWithMe)
|
|
588
|
-
.payload(z.object({ shareId: idOf(SharedWithMe), prunedAt: z.string().min(1) }))
|
|
589
|
-
.plan((p) => [set(instance(SharedWithMe, p.shareId), "prunedAt", p.prunedAt)]);
|
|
590
|
-
|
|
591
|
-
/** "Show me everything <asserter> shared with me" — an indexed probe over the local access list. */
|
|
592
|
-
export const sharedByWorkspace = query("sharedByWorkspace").key("asserterWorkspace").returns(SharedWithMe);
|
|
593
|
-
|
|
594
|
-
/** "Show me every share for this protected object" — the indexed access-list probe used by generated
|
|
595
|
-
* application discovery. A home commonly has a very large installed law, so discovery must never fall back
|
|
596
|
-
* to the generic `aggregatesByType(SharedWithMe)` scan merely to find whole-workspace shares. */
|
|
597
|
-
export const sharedByObject = query("sharedByObject").key("object").returns(SharedWithMe);
|
|
598
|
-
|
|
599
|
-
// ─────────────────── THE PEER-SOVEREIGN ROOT-OF-TRUST (the BirthAttestation cert chain) ───────────────────
|
|
600
|
-
|
|
601
|
-
/**
|
|
602
|
-
* THE BIRTH ATTESTATION (the cert, on-chain for AUDIT). When a parent P births this home via the offer-
|
|
603
|
-
* effect, the kernel seeds a SIGNED [executor::birth_cert::BirthCert] {child, founder, verified, parentKey,
|
|
604
|
-
* parentId, epoch} into the home's genesis (it travels with the home's `GenesisWarrant.bornUnder` so a peer
|
|
605
|
-
* verifies it OFFLINE), AND folds this singleton record so the home's projection surfaces "who attested my
|
|
606
|
-
* birth, and was my founder verified". `verified` + `founder` are the parent's GATE verdict (captured-port,
|
|
607
|
-
* CAS-as-law), never the offer payload. A peer's TRUST decision uses the travelling signed chain (the kernel
|
|
608
|
-
* verify doors); this aggregate is the human-readable mirror.
|
|
609
|
-
*/
|
|
610
|
-
export const BIRTH_ATTESTATION_ID = "birth-attestation:self";
|
|
611
|
-
export const BIRTH_ATTESTATION_LINK_PREFIX = "birth-attestation-link:";
|
|
612
|
-
export const BirthAttestation = aggregate("BirthAttestation", {
|
|
613
|
-
/** This home's self-id (`home-<sha256(founder)>`) — the cert's `child`. */
|
|
614
|
-
child: t.string().merge(Lww),
|
|
615
|
-
/** The founding principal the parent attested (== {@link HomeOwner} `principal`). */
|
|
616
|
-
founder: t.string().merge(Lww),
|
|
617
|
-
/** THE PARENT'S GATE VERDICT: was `founder` VERIFIED at the parent's offer gate (an IdP vouched)? */
|
|
618
|
-
verified: t.string().merge(Lww), // "true"/"false" (string for the Lww scalar projection)
|
|
619
|
-
/** The parent's workspace self-id (lineage). */
|
|
620
|
-
parentId: t.string().merge(Lww),
|
|
621
|
-
/** The parent's enrolled signer PUBLIC KEY (base64) — `K_P`, the cert's signer. */
|
|
622
|
-
parentKey: t.string().merge(Lww),
|
|
623
|
-
/** The parent's SignerEpoch at the attestation (informational; the cert is judged at birth-time validity). */
|
|
624
|
-
epoch: t.int().merge(Lww),
|
|
625
|
-
/** Legacy replay slot for histories authored before `BirthAttestationLink`. New histories write the
|
|
626
|
-
* travelling chain only as ordered, typed link records below. */
|
|
627
|
-
certChain: t.string().merge(Lww).optional(),
|
|
628
|
-
}).public();
|
|
629
|
-
|
|
630
|
-
/** One exact link in the travelling certificate chain. The zero-padded index is custody order; every
|
|
631
|
-
* certificate member is a separate typed USDA property. `certChain` above remains only as a replay fallback
|
|
632
|
-
* for histories authored before this aggregate existed. */
|
|
633
|
-
export const BirthAttestationLink = aggregate("BirthAttestationLink", {
|
|
634
|
-
index: t.int().merge(Lww),
|
|
635
|
-
child: t.string().merge(Lww),
|
|
636
|
-
founder: t.string().merge(Lww),
|
|
637
|
-
verified: t.bool().merge(Lww),
|
|
638
|
-
parentKey: t.string().merge(Lww),
|
|
639
|
-
parentId: t.string().merge(Lww),
|
|
640
|
-
epoch: t.int().merge(Lww),
|
|
641
|
-
signature: t.string().merge(Lww),
|
|
642
|
-
verifiedVia: t.string().merge(Lww).optional(),
|
|
643
|
-
idpToken: t.string().merge(Lww).optional(),
|
|
644
|
-
capturedClock: t.int().merge(Lww).optional(),
|
|
645
|
-
authProviderIssuer: t.string().merge(Lww).optional(),
|
|
646
|
-
authProviderJwks: t.string().merge(Lww).optional(),
|
|
647
|
-
authProviderAudience: t.string().merge(Lww).optional(),
|
|
648
|
-
}).public();
|
|
649
|
-
|
|
650
|
-
/** Audit read: this home's birth attestation (who attested it + the verified verdict). */
|
|
651
|
-
export const birthAttestation = query("birthAttestation").key("child").returns(BirthAttestation);
|
|
652
|
-
|
|
653
|
-
/**
|
|
654
|
-
* `seedBirthAttestation` — THE GENESIS-DOOR step the parent's offer-effect INJECTS into the home's genesis
|
|
655
|
-
* chain (the kernel appends it in `run_birth_effect` carrying the assembled + signed cert chain). It folds
|
|
656
|
-
* the [`BirthAttestation`] singleton so the home's own state carries its travelling cert. A CONTROL-PLANE
|
|
657
|
-
* write seeded once at birth (the open session lane structurally refuses it by directive id). The values
|
|
658
|
-
* are the parent's GATE VERDICT (`founder`/`verified` lowered from the captured port — CAS-as-law, never
|
|
659
|
-
* the offer payload) + the typed signed links; the home's verify doors re-derive trust from the chain.
|
|
660
|
-
*/
|
|
661
|
-
export const seedBirthAttestation = directive("seedBirthAttestation")
|
|
662
|
-
.ensures(BirthAttestation)
|
|
663
|
-
.payload(
|
|
664
|
-
z.object({
|
|
665
|
-
child: z.string().min(1),
|
|
666
|
-
founder: z.string().min(1),
|
|
667
|
-
verified: z.string().min(1), // "true"/"false"
|
|
668
|
-
/** The parent's workspace self-id (lineage). EMPTY for a root-DIRECT birth (root carries no self-id
|
|
669
|
-
* binding in the unwarranted lane) — the cert's terminal link is then signed by K_root directly. */
|
|
670
|
-
parentId: z.string(),
|
|
671
|
-
parentKey: z.string().min(1), // base64 K_P
|
|
672
|
-
epoch: z.number().int().nonnegative(),
|
|
673
|
-
links: z.array(birthCertificatePayload).min(1),
|
|
674
|
-
/** Law-declared target roles for the verified immediate parent workspace. The kernel injects this
|
|
675
|
-
* value from the admitted birth recipe and supplies `parentId`; no host chooses either fact. */
|
|
676
|
-
parentWorkspaceRoles: z.array(z.string().regex(/^[A-Za-z][A-Za-z0-9_-]*$/)).optional(),
|
|
677
|
-
}).superRefine((payload, ctx) => {
|
|
678
|
-
if ((payload.parentWorkspaceRoles?.length ?? 0) > 0 && payload.parentId.length === 0) {
|
|
679
|
-
ctx.addIssue({ code: "custom", message: "parent workspace roles require a verified non-root parentId" });
|
|
680
|
-
}
|
|
681
|
-
}),
|
|
682
|
-
)
|
|
683
|
-
.plan((p) => {
|
|
684
|
-
const h = instance(BirthAttestation, BIRTH_ATTESTATION_ID);
|
|
685
|
-
const header = [
|
|
686
|
-
set(h, "child", p.child),
|
|
687
|
-
set(h, "founder", p.founder),
|
|
688
|
-
set(h, "verified", p.verified),
|
|
689
|
-
set(h, "parentId", p.parentId),
|
|
690
|
-
set(h, "parentKey", p.parentKey),
|
|
691
|
-
set(h, "epoch", p.epoch),
|
|
692
|
-
];
|
|
693
|
-
const links = p.links.flatMap((certificate, index) => {
|
|
694
|
-
const link = instance(BirthAttestationLink, `${BIRTH_ATTESTATION_LINK_PREFIX}${String(index).padStart(8, "0")}`);
|
|
695
|
-
return [
|
|
696
|
-
withMarker(set(link, "index", index), "ensures"),
|
|
697
|
-
withMarker(set(link, "child", certificate.child), "ensures"),
|
|
698
|
-
withMarker(set(link, "founder", certificate.founder), "ensures"),
|
|
699
|
-
withMarker(set(link, "verified", certificate.verified), "ensures"),
|
|
700
|
-
withMarker(set(link, "parentKey", certificate.parentKey), "ensures"),
|
|
701
|
-
withMarker(set(link, "parentId", certificate.parentId), "ensures"),
|
|
702
|
-
withMarker(set(link, "epoch", certificate.epoch), "ensures"),
|
|
703
|
-
withMarker(set(link, "signature", certificate.signature), "ensures"),
|
|
704
|
-
...(certificate.verifiedVia ? [withMarker(set(link, "verifiedVia", certificate.verifiedVia), "ensures")] : []),
|
|
705
|
-
...(certificate.idpToken ? [withMarker(set(link, "idpToken", certificate.idpToken), "ensures")] : []),
|
|
706
|
-
...(certificate.capturedClock === undefined ? [] : [withMarker(set(link, "capturedClock", certificate.capturedClock), "ensures")]),
|
|
707
|
-
...(certificate.authProviderIssuer ? [withMarker(set(link, "authProviderIssuer", certificate.authProviderIssuer), "ensures")] : []),
|
|
708
|
-
...(certificate.authProviderJwks ? [withMarker(set(link, "authProviderJwks", certificate.authProviderJwks), "ensures")] : []),
|
|
709
|
-
...(certificate.authProviderAudience ? [withMarker(set(link, "authProviderAudience", certificate.authProviderAudience), "ensures")] : []),
|
|
710
|
-
];
|
|
711
|
-
});
|
|
712
|
-
const parentAuthority = (p.parentWorkspaceRoles ?? []).flatMap((relation) => writeTuple({
|
|
713
|
-
object: "workspace:self",
|
|
714
|
-
relation,
|
|
715
|
-
subject: `workspace:${p.parentId}`,
|
|
716
|
-
grantedBy: `workspace:${p.parentId}`,
|
|
717
|
-
grantedAt: String(p.epoch),
|
|
718
|
-
}));
|
|
719
|
-
return [...header, ...links, ...parentAuthority];
|
|
720
|
-
})
|
|
721
|
-
.alsoEnsures(BirthAttestationLink)
|
|
722
|
-
.alsoEnsures(RelationTuple);
|
|
723
|
-
|
|
724
|
-
/**
|
|
725
|
-
* THE ERA DECLARATION (the `nomosParentAttestedBirth` USD key). Exporting this sentinel from the home law
|
|
726
|
-
* tells the kernel's verify doors to VERIFY THE TRAVELLING CERT CHAIN to the pinned `K_root` on every lane
|
|
727
|
-
* (author / receive / verify_chain) — so a warranted home that self-asserts a verified founder WITHOUT a
|
|
728
|
-
* parent-signed chain rooting at root is refused (`ParentDidNotAttest` / `CertChainBroken` /
|
|
729
|
-
* `NotRootedAtRoot`). Era-ruled: a home law that does NOT export this carries no key and replays byte-
|
|
730
|
-
* identical (the squat-only `homeNameBindsOwner` check still runs; the cert check is simply inert).
|
|
731
|
-
*/
|
|
732
|
-
export const parentAttestedBirth: ParentAttestedBirthMarker = {
|
|
733
|
-
...requireParentAttestedBirth,
|
|
734
|
-
// DECLARE the owner + cert locators so the KERNEL reads them (it names neither): the home owner lives at
|
|
735
|
-
// the `HomeOwner` singleton's `principal`. `certObject`/`certField` retain the legacy chain locator for
|
|
736
|
-
// old histories; current histories are discovered through the typed `BirthAttestationLink` aggregate.
|
|
737
|
-
ownerObject: RECEIVING_GROUP_ID,
|
|
738
|
-
ownerField: "principal",
|
|
739
|
-
certObject: BIRTH_ATTESTATION_ID,
|
|
740
|
-
certField: "certChain",
|
|
741
|
-
};
|
|
12
|
+
export * from "./receiving_group.js";
|