@synopackageland/cli 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +37 -0
- package/dist/build-spk/generator.js +3 -0
- package/dist/build-spk/notices.d.ts +5 -0
- package/dist/build-spk/notices.js +60 -0
- package/dist/cli.js +9 -2
- package/dist/error-registry.js +20 -0
- package/dist/init.d.ts +4 -0
- package/dist/init.js +20 -12
- package/dist/standalone/build.js +3 -1
- package/dist/standalone/daemon.d.ts +23 -0
- package/dist/standalone/daemon.js +114 -0
- package/dist/standalone/dsm-window.d.ts +1 -1
- package/dist/standalone/dsm-window.js +50 -10
- package/dist/standalone/helper-inventory.d.ts +16 -0
- package/dist/standalone/helper-inventory.js +2 -0
- package/dist/standalone/helper.d.ts +2 -12
- package/dist/standalone/helper.js +8 -7
- package/dist/standalone/host-adapter.d.ts +5 -0
- package/dist/standalone/host-adapter.js +148 -0
- package/dist/standalone/host-platform.d.ts +13 -0
- package/dist/standalone/host-platform.js +42 -0
- package/dist/standalone/host-types.d.ts +49 -0
- package/dist/standalone/host-types.js +1 -0
- package/dist/standalone/inspect-helper.d.ts +6 -0
- package/dist/standalone/inspect-helper.js +88 -0
- package/dist/standalone/inspect-spk.d.ts +2 -0
- package/dist/standalone/inspect-spk.js +49 -0
- package/dist/standalone/lifecycle-helper.d.ts +2 -0
- package/dist/standalone/lifecycle-helper.js +12 -0
- package/dist/standalone/lifecycle.d.ts +3 -0
- package/dist/standalone/lifecycle.js +53 -0
- package/dist/standalone/manifest.d.ts +2 -0
- package/dist/standalone/manifest.js +4 -1
- package/dist/standalone/reopen-events.d.ts +2 -0
- package/dist/standalone/reopen-events.js +28 -0
- package/dist/standalone/root-messages.js +9 -0
- package/dist/standalone/root-window.d.ts +4 -3
- package/dist/standalone/root-window.js +17 -5
- package/dist/standalone/spk.d.ts +4 -3
- package/dist/standalone/spk.js +20 -33
- package/dist/template-paths.d.ts +2 -0
- package/dist/template-paths.js +9 -0
- package/dist/templates/_daemon/fixture_linux_test.go +15 -0
- package/dist/templates/_daemon/fixture_other_test.go +7 -0
- package/dist/templates/_daemon/go.mod +3 -0
- package/dist/templates/_daemon/main.go +608 -0
- package/dist/templates/_daemon/main_test.go +242 -0
- package/dist/templates/_daemon/process_linux.go +55 -0
- package/dist/templates/_daemon/process_linux_test.go +161 -0
- package/dist/templates/_daemon/process_other.go +14 -0
- package/dist/templates/_daemon/testdata/child.go +41 -0
- package/dist/templates/_shared/GO-LICENSE +27 -0
- package/dist/templates/_shared/GO-PATENTS +22 -0
- package/dist/templates/_shared/LICENSES/TEMPLATE.txt +21 -0
- package/dist/templates/_shared/notice-overrides/index.json +14 -0
- package/dist/templates/_shared/notice-overrides/utils-0.4.2-LICENSE +21 -0
- package/dist/templates/_shared/notice-overrides/utils-0.5.0-LICENSE +21 -0
- package/dist/templates/_shared/third-party-notices.mjs +51 -0
- package/dist/templates/native-go/README.md +57 -1
- package/dist/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +59 -0
- package/dist/templates/native-go/backend/cmd/dsm-readonly-probe/main_linux.go +46 -0
- package/dist/templates/native-go/backend/go.mod +4 -0
- package/dist/templates/native-go/backend/go.sum +4 -0
- package/dist/templates/native-go/backend/internal/api/binary.go +154 -0
- package/dist/templates/native-go/backend/internal/api/binary_test.go +165 -0
- package/dist/templates/native-go/backend/internal/api/registry.go +14 -4
- package/dist/templates/native-go/backend/internal/api/server.go +4 -0
- package/dist/templates/native-go/backend/internal/app/nas_cgi_artifact_test.go +121 -0
- package/dist/templates/native-go/backend/internal/app/nas_refusal_test.go +46 -0
- package/dist/templates/native-go/backend/internal/app/routes.go +11 -0
- package/dist/templates/native-go/backend/internal/app/routes_test.go +10 -5
- package/dist/templates/native-go/backend/internal/dsmprobe/collector_linux.go +335 -0
- package/dist/templates/native-go/backend/internal/dsmprobe/collector_linux_test.go +41 -0
- package/dist/templates/native-go/backend/internal/dsmprobe/protocol.go +179 -0
- package/dist/templates/native-go/backend/internal/dsmprobe/protocol_test.go +29 -0
- package/dist/templates/native-go/backend/internal/helper/cohort.go +393 -0
- package/dist/templates/native-go/backend/internal/helper/cohort_publication.go +18 -0
- package/dist/templates/native-go/backend/internal/helper/cohort_publication_test.go +105 -0
- package/dist/templates/native-go/backend/internal/helper/cohort_test.go +372 -0
- package/dist/templates/native-go/backend/internal/helper/control.go +226 -21
- package/dist/templates/native-go/backend/internal/helper/control_test.go +10 -2
- package/dist/templates/native-go/backend/internal/helper/data_contract.go +242 -0
- package/dist/templates/native-go/backend/internal/helper/data_contract_test.go +51 -0
- package/dist/templates/native-go/backend/internal/helper/data_decode.go +184 -0
- package/dist/templates/native-go/backend/internal/helper/data_decode_pointer_test.go +30 -0
- package/dist/templates/native-go/backend/internal/helper/data_protocol.go +416 -0
- package/dist/templates/native-go/backend/internal/helper/data_protocol_test.go +449 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_acl_linux.go +139 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_acl_linux_test.go +121 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux.go +95 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux_test.go +56 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_bridge_linux.go +144 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_bridge_linux_test.go +89 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_home_linux.go +107 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_home_linux_test.go +82 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_probe_transport_linux.go +151 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_probe_transport_linux_test.go +66 -0
- package/dist/templates/native-go/backend/internal/helper/grant_authority.go +516 -0
- package/dist/templates/native-go/backend/internal/helper/grant_authority_contract.go +88 -0
- package/dist/templates/native-go/backend/internal/helper/grant_authority_test.go +510 -0
- package/dist/templates/native-go/backend/internal/helper/grant_cohort.go +389 -0
- package/dist/templates/native-go/backend/internal/helper/grant_cohort_test.go +239 -0
- package/dist/templates/native-go/backend/internal/helper/grant_delivery.go +49 -0
- package/dist/templates/native-go/backend/internal/helper/grant_delivery_methods.go +273 -0
- package/dist/templates/native-go/backend/internal/helper/grant_delivery_test.go +322 -0
- package/dist/templates/native-go/backend/internal/helper/grant_operation_contract.go +47 -0
- package/dist/templates/native-go/backend/internal/helper/grant_readonly_test.go +180 -0
- package/dist/templates/native-go/backend/internal/helper/grant_repository_linux.go +415 -0
- package/dist/templates/native-go/backend/internal/helper/grant_repository_linux_test.go +468 -0
- package/dist/templates/native-go/backend/internal/helper/grant_rpc.go +147 -0
- package/dist/templates/native-go/backend/internal/helper/grant_rpc_test.go +51 -0
- package/dist/templates/native-go/backend/internal/helper/grant_snapshot.go +75 -0
- package/dist/templates/native-go/backend/internal/helper/grant_supervisor_linux.go +134 -0
- package/dist/templates/native-go/backend/internal/helper/grant_supervisor_linux_test.go +254 -0
- package/dist/templates/native-go/backend/internal/helper/lease.go +112 -0
- package/dist/templates/native-go/backend/internal/helper/lease_linux.go +44 -0
- package/dist/templates/native-go/backend/internal/helper/lease_other.go +8 -0
- package/dist/templates/native-go/backend/internal/helper/lifecycle.go +234 -0
- package/dist/templates/native-go/backend/internal/helper/lifecycle_test.go +473 -0
- package/dist/templates/native-go/backend/internal/helper/managed_pilot.go +284 -0
- package/dist/templates/native-go/backend/internal/helper/managed_pilot_repository_linux.go +74 -0
- package/dist/templates/native-go/backend/internal/helper/managed_pilot_repository_linux_test.go +40 -0
- package/dist/templates/native-go/backend/internal/helper/managed_pilot_test.go +210 -0
- package/dist/templates/native-go/backend/internal/helper/nas_shipped_refusal_linux_test.go +97 -0
- package/dist/templates/native-go/backend/internal/helper/native_discovery.go +79 -0
- package/dist/templates/native-go/backend/internal/helper/native_identity.go +89 -0
- package/dist/templates/native-go/backend/internal/helper/native_provider.go +159 -0
- package/dist/templates/native-go/backend/internal/helper/native_provider_test.go +421 -0
- package/dist/templates/native-go/backend/internal/helper/observation.go +204 -0
- package/dist/templates/native-go/backend/internal/helper/observation_health_test.go +115 -0
- package/dist/templates/native-go/backend/internal/helper/observation_reload_budget_test.go +117 -0
- package/dist/templates/native-go/backend/internal/helper/observation_test.go +196 -0
- package/dist/templates/native-go/backend/internal/helper/observer_diagnostic.go +109 -0
- package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_linux.go +76 -0
- package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_linux_test.go +124 -0
- package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_test.go +98 -0
- package/dist/templates/native-go/backend/internal/helper/operation_bootstrap_linux.go +193 -0
- package/dist/templates/native-go/backend/internal/helper/operation_credentials_linux.go +56 -0
- package/dist/templates/native-go/backend/internal/helper/operation_linux.go +480 -0
- package/dist/templates/native-go/backend/internal/helper/operation_linux_test.go +528 -0
- package/dist/templates/native-go/backend/internal/helper/process_linux.go +11 -1
- package/dist/templates/native-go/backend/internal/helper/publication_test.go +178 -0
- package/dist/templates/native-go/backend/internal/helper/read_stream_cohort_linux_test.go +156 -0
- package/dist/templates/native-go/backend/internal/helper/read_transfer.go +40 -0
- package/dist/templates/native-go/backend/internal/helper/read_transfer_linux.go +109 -0
- package/dist/templates/native-go/backend/internal/helper/read_transfer_linux_test.go +118 -0
- package/dist/templates/native-go/backend/internal/helper/read_transfer_test.go +177 -0
- package/dist/templates/native-go/backend/internal/helper/readonly.go +105 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_admission.go +85 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_cohort_linux_test.go +253 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_linux_test.go +378 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_mount_linux.go +65 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_mount_proxy_linux.go +113 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_operations_linux.go +168 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_resolver_linux.go +241 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_test.go +40 -0
- package/dist/templates/native-go/backend/internal/helper/relaxed_identity.go +252 -0
- package/dist/templates/native-go/backend/internal/helper/relaxed_identity_contract.go +105 -0
- package/dist/templates/native-go/backend/internal/helper/relaxed_identity_test.go +406 -0
- package/dist/templates/native-go/backend/internal/helper/relaxed_invalidation.go +200 -0
- package/dist/templates/native-go/backend/internal/helper/repair.go +132 -0
- package/dist/templates/native-go/backend/internal/helper/repair_test.go +271 -0
- package/dist/templates/native-go/backend/internal/helper/s1r_actor_acl_linux_test.go +303 -0
- package/dist/templates/native-go/backend/internal/helper/s1r_actor_fixture_linux_test.go +184 -0
- package/dist/templates/native-go/backend/internal/helper/s1r_actor_races_linux_test.go +231 -0
- package/dist/templates/native-go/backend/internal/helper/s1r_fixture_contract_linux_test.go +18 -0
- package/dist/templates/native-go/backend/internal/helper/server_linux.go +44 -3
- package/dist/templates/native-go/backend/internal/helper/status.go +74 -11
- package/dist/templates/native-go/backend/internal/helper/status_test.go +83 -0
- package/dist/templates/native-go/backend/internal/helper/supervision.go +28 -5
- package/dist/templates/native-go/backend/internal/helper/supervisor_frame.go +76 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_frame_linux_test.go +69 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_frame_test.go +107 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_linux.go +187 -16
- package/dist/templates/native-go/backend/internal/helper/supervisor_linux_test.go +618 -7
- package/dist/templates/native-go/backend/internal/helper/supervisor_socket_eof_test.go +74 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_socket_test.go +45 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/create.json +23 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/frames.json +67 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/grant-store.json +52 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/intent.json +20 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/list.json +20 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/publish.json +20 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/read.json +22 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/stat.json +22 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/write-stream.json +22 -0
- package/dist/templates/native-go/backend/internal/helper/unit_connection.go +75 -0
- package/dist/templates/native-go/backend/internal/helper/unit_connection_linux_test.go +135 -0
- package/dist/templates/native-go/backend/internal/helper/unit_connection_test.go +133 -0
- package/dist/templates/native-go/backend/internal/helper/unit_frame_test.go +32 -0
- package/dist/templates/native-go/backend/internal/helper/unit_linux.go +364 -0
- package/dist/templates/native-go/backend/internal/helper/unit_linux_test.go +46 -0
- package/dist/templates/native-go/backend/internal/helper/unit_mechanisms_linux_test.go +217 -0
- package/dist/templates/native-go/backend/internal/helper/unit_padding_linux_test.go +178 -0
- package/dist/templates/native-go/backend/internal/helper/unit_query_linux.go +111 -0
- package/dist/templates/native-go/backend/internal/helper/unit_reload_linux_test.go +372 -0
- package/dist/templates/native-go/backend/internal/helper/unit_reload_sequence_linux_test.go +232 -0
- package/dist/templates/native-go/backend/internal/helper/write.go +77 -0
- package/dist/templates/native-go/backend/internal/helper/write_admission.go +260 -0
- package/dist/templates/native-go/backend/internal/helper/write_admission_test.go +135 -0
- package/dist/templates/native-go/backend/internal/helper/write_cohort_linux_test.go +218 -0
- package/dist/templates/native-go/backend/internal/helper/write_files_linux.go +202 -0
- package/dist/templates/native-go/backend/internal/helper/write_files_linux_test.go +199 -0
- package/dist/templates/native-go/backend/internal/helper/write_intent_linux.go +116 -0
- package/dist/templates/native-go/backend/internal/helper/write_intent_linux_test.go +74 -0
- package/dist/templates/native-go/backend/internal/helper/write_operation_linux.go +245 -0
- package/dist/templates/native-go/backend/internal/helper/write_test.go +53 -0
- package/dist/templates/native-go/ui/app.js +8 -1
- package/dist/templates/native-go-better-auth/node/build.mjs +2 -0
- package/dist/templates/native-go-vue/README.md +115 -1
- package/dist/templates/native-go-vue/frontend/DESIGN.md +1 -1
- package/dist/templates/native-go-vue/frontend/package-lock.json +132 -229
- package/dist/templates/native-go-vue/frontend/package.json +1 -1
- package/dist/templates/native-go-vue/frontend/src/App.vue +33 -6
- package/dist/templates/native-go-vue/frontend/src/context.ts +41 -2
- package/dist/templates/native-go-vue/frontend/src/main.ts +4 -1
- package/dist/templates/native-go-vue/frontend/src/nas/NasGrantSettings.vue +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/NasPathPicker.vue +106 -0
- package/dist/templates/native-go-vue/frontend/src/nas/NasUnavailable.vue +20 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/de.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/en.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/es.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/fr.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/it.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/ja.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/ko.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/zh-CN.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/zh-TW.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n.ts +38 -0
- package/dist/templates/native-go-vue/frontend/src/nas/mock-provider.ts +119 -0
- package/dist/templates/native-go-vue/frontend/src/nas/provider.ts +59 -0
- package/dist/templates/native-go-vue/frontend/src/nas/use-request.ts +27 -0
- package/dist/templates/native-go-vue/frontend/src/style.css +17 -0
- package/dist/templates/native-go-vue/frontend/test/apps.test.ts +44 -2
- package/dist/templates/native-go-vue/frontend/test/nas-provider.test.ts +81 -0
- package/dist/templates/native-go-vue/frontend/test/nas-request.test.ts +21 -0
- package/dist/templates/native-go-vue/frontend/test/nas-ui.test.ts +261 -0
- package/dist/templates/native-go-vue/frontend/tsconfig.json +1 -1
- package/dist/templates/native-go-vue/frontend/vite.config.ts +6 -4
- package/package.json +3 -2
- package/templates/_daemon/fixture_linux_test.go +15 -0
- package/templates/_daemon/fixture_other_test.go +7 -0
- package/templates/_daemon/go.mod +3 -0
- package/templates/_daemon/main.go +608 -0
- package/templates/_daemon/main_test.go +242 -0
- package/templates/_daemon/process_linux.go +55 -0
- package/templates/_daemon/process_linux_test.go +161 -0
- package/templates/_daemon/process_other.go +14 -0
- package/templates/_daemon/testdata/child.go +41 -0
- package/templates/_shared/GO-LICENSE +27 -0
- package/templates/_shared/GO-PATENTS +22 -0
- package/templates/_shared/LICENSES/TEMPLATE.txt +21 -0
- package/templates/_shared/notice-overrides/index.json +14 -0
- package/templates/_shared/notice-overrides/utils-0.4.2-LICENSE +21 -0
- package/templates/_shared/notice-overrides/utils-0.5.0-LICENSE +21 -0
- package/templates/_shared/third-party-notices.mjs +51 -0
- package/templates/native-go/README.md +57 -1
- package/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +59 -0
- package/templates/native-go/backend/cmd/dsm-readonly-probe/main_linux.go +46 -0
- package/templates/native-go/backend/go.mod +4 -0
- package/templates/native-go/backend/go.sum +4 -0
- package/templates/native-go/backend/internal/api/binary.go +154 -0
- package/templates/native-go/backend/internal/api/binary_test.go +165 -0
- package/templates/native-go/backend/internal/api/registry.go +14 -4
- package/templates/native-go/backend/internal/api/server.go +4 -0
- package/templates/native-go/backend/internal/app/nas_cgi_artifact_test.go +121 -0
- package/templates/native-go/backend/internal/app/nas_refusal_test.go +46 -0
- package/templates/native-go/backend/internal/app/routes.go +11 -0
- package/templates/native-go/backend/internal/app/routes_test.go +10 -5
- package/templates/native-go/backend/internal/dsmprobe/collector_linux.go +335 -0
- package/templates/native-go/backend/internal/dsmprobe/collector_linux_test.go +41 -0
- package/templates/native-go/backend/internal/dsmprobe/protocol.go +179 -0
- package/templates/native-go/backend/internal/dsmprobe/protocol_test.go +29 -0
- package/templates/native-go/backend/internal/helper/cohort.go +393 -0
- package/templates/native-go/backend/internal/helper/cohort_publication.go +18 -0
- package/templates/native-go/backend/internal/helper/cohort_publication_test.go +105 -0
- package/templates/native-go/backend/internal/helper/cohort_test.go +372 -0
- package/templates/native-go/backend/internal/helper/control.go +226 -21
- package/templates/native-go/backend/internal/helper/control_test.go +10 -2
- package/templates/native-go/backend/internal/helper/data_contract.go +242 -0
- package/templates/native-go/backend/internal/helper/data_contract_test.go +51 -0
- package/templates/native-go/backend/internal/helper/data_decode.go +184 -0
- package/templates/native-go/backend/internal/helper/data_decode_pointer_test.go +30 -0
- package/templates/native-go/backend/internal/helper/data_protocol.go +416 -0
- package/templates/native-go/backend/internal/helper/data_protocol_test.go +449 -0
- package/templates/native-go/backend/internal/helper/dsm_acl_linux.go +139 -0
- package/templates/native-go/backend/internal/helper/dsm_acl_linux_test.go +121 -0
- package/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux.go +95 -0
- package/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux_test.go +56 -0
- package/templates/native-go/backend/internal/helper/dsm_bridge_linux.go +144 -0
- package/templates/native-go/backend/internal/helper/dsm_bridge_linux_test.go +89 -0
- package/templates/native-go/backend/internal/helper/dsm_home_linux.go +107 -0
- package/templates/native-go/backend/internal/helper/dsm_home_linux_test.go +82 -0
- package/templates/native-go/backend/internal/helper/dsm_probe_transport_linux.go +151 -0
- package/templates/native-go/backend/internal/helper/dsm_probe_transport_linux_test.go +66 -0
- package/templates/native-go/backend/internal/helper/grant_authority.go +516 -0
- package/templates/native-go/backend/internal/helper/grant_authority_contract.go +88 -0
- package/templates/native-go/backend/internal/helper/grant_authority_test.go +510 -0
- package/templates/native-go/backend/internal/helper/grant_cohort.go +389 -0
- package/templates/native-go/backend/internal/helper/grant_cohort_test.go +239 -0
- package/templates/native-go/backend/internal/helper/grant_delivery.go +49 -0
- package/templates/native-go/backend/internal/helper/grant_delivery_methods.go +273 -0
- package/templates/native-go/backend/internal/helper/grant_delivery_test.go +322 -0
- package/templates/native-go/backend/internal/helper/grant_operation_contract.go +47 -0
- package/templates/native-go/backend/internal/helper/grant_readonly_test.go +180 -0
- package/templates/native-go/backend/internal/helper/grant_repository_linux.go +415 -0
- package/templates/native-go/backend/internal/helper/grant_repository_linux_test.go +468 -0
- package/templates/native-go/backend/internal/helper/grant_rpc.go +147 -0
- package/templates/native-go/backend/internal/helper/grant_rpc_test.go +51 -0
- package/templates/native-go/backend/internal/helper/grant_snapshot.go +75 -0
- package/templates/native-go/backend/internal/helper/grant_supervisor_linux.go +134 -0
- package/templates/native-go/backend/internal/helper/grant_supervisor_linux_test.go +254 -0
- package/templates/native-go/backend/internal/helper/lease.go +112 -0
- package/templates/native-go/backend/internal/helper/lease_linux.go +44 -0
- package/templates/native-go/backend/internal/helper/lease_other.go +8 -0
- package/templates/native-go/backend/internal/helper/lifecycle.go +234 -0
- package/templates/native-go/backend/internal/helper/lifecycle_test.go +473 -0
- package/templates/native-go/backend/internal/helper/managed_pilot.go +284 -0
- package/templates/native-go/backend/internal/helper/managed_pilot_repository_linux.go +74 -0
- package/templates/native-go/backend/internal/helper/managed_pilot_repository_linux_test.go +40 -0
- package/templates/native-go/backend/internal/helper/managed_pilot_test.go +210 -0
- package/templates/native-go/backend/internal/helper/nas_shipped_refusal_linux_test.go +97 -0
- package/templates/native-go/backend/internal/helper/native_discovery.go +79 -0
- package/templates/native-go/backend/internal/helper/native_identity.go +89 -0
- package/templates/native-go/backend/internal/helper/native_provider.go +159 -0
- package/templates/native-go/backend/internal/helper/native_provider_test.go +421 -0
- package/templates/native-go/backend/internal/helper/observation.go +204 -0
- package/templates/native-go/backend/internal/helper/observation_health_test.go +115 -0
- package/templates/native-go/backend/internal/helper/observation_reload_budget_test.go +117 -0
- package/templates/native-go/backend/internal/helper/observation_test.go +196 -0
- package/templates/native-go/backend/internal/helper/observer_diagnostic.go +109 -0
- package/templates/native-go/backend/internal/helper/observer_diagnostic_linux.go +76 -0
- package/templates/native-go/backend/internal/helper/observer_diagnostic_linux_test.go +124 -0
- package/templates/native-go/backend/internal/helper/observer_diagnostic_test.go +98 -0
- package/templates/native-go/backend/internal/helper/operation_bootstrap_linux.go +193 -0
- package/templates/native-go/backend/internal/helper/operation_credentials_linux.go +56 -0
- package/templates/native-go/backend/internal/helper/operation_linux.go +480 -0
- package/templates/native-go/backend/internal/helper/operation_linux_test.go +528 -0
- package/templates/native-go/backend/internal/helper/process_linux.go +11 -1
- package/templates/native-go/backend/internal/helper/publication_test.go +178 -0
- package/templates/native-go/backend/internal/helper/read_stream_cohort_linux_test.go +156 -0
- package/templates/native-go/backend/internal/helper/read_transfer.go +40 -0
- package/templates/native-go/backend/internal/helper/read_transfer_linux.go +109 -0
- package/templates/native-go/backend/internal/helper/read_transfer_linux_test.go +118 -0
- package/templates/native-go/backend/internal/helper/read_transfer_test.go +177 -0
- package/templates/native-go/backend/internal/helper/readonly.go +105 -0
- package/templates/native-go/backend/internal/helper/readonly_admission.go +85 -0
- package/templates/native-go/backend/internal/helper/readonly_cohort_linux_test.go +253 -0
- package/templates/native-go/backend/internal/helper/readonly_linux_test.go +378 -0
- package/templates/native-go/backend/internal/helper/readonly_mount_linux.go +65 -0
- package/templates/native-go/backend/internal/helper/readonly_mount_proxy_linux.go +113 -0
- package/templates/native-go/backend/internal/helper/readonly_operations_linux.go +168 -0
- package/templates/native-go/backend/internal/helper/readonly_resolver_linux.go +241 -0
- package/templates/native-go/backend/internal/helper/readonly_test.go +40 -0
- package/templates/native-go/backend/internal/helper/relaxed_identity.go +252 -0
- package/templates/native-go/backend/internal/helper/relaxed_identity_contract.go +105 -0
- package/templates/native-go/backend/internal/helper/relaxed_identity_test.go +406 -0
- package/templates/native-go/backend/internal/helper/relaxed_invalidation.go +200 -0
- package/templates/native-go/backend/internal/helper/repair.go +132 -0
- package/templates/native-go/backend/internal/helper/repair_test.go +271 -0
- package/templates/native-go/backend/internal/helper/s1r_actor_acl_linux_test.go +303 -0
- package/templates/native-go/backend/internal/helper/s1r_actor_fixture_linux_test.go +184 -0
- package/templates/native-go/backend/internal/helper/s1r_actor_races_linux_test.go +231 -0
- package/templates/native-go/backend/internal/helper/s1r_fixture_contract_linux_test.go +18 -0
- package/templates/native-go/backend/internal/helper/server_linux.go +44 -3
- package/templates/native-go/backend/internal/helper/status.go +74 -11
- package/templates/native-go/backend/internal/helper/status_test.go +83 -0
- package/templates/native-go/backend/internal/helper/supervision.go +28 -5
- package/templates/native-go/backend/internal/helper/supervisor_frame.go +76 -0
- package/templates/native-go/backend/internal/helper/supervisor_frame_linux_test.go +69 -0
- package/templates/native-go/backend/internal/helper/supervisor_frame_test.go +107 -0
- package/templates/native-go/backend/internal/helper/supervisor_linux.go +187 -16
- package/templates/native-go/backend/internal/helper/supervisor_linux_test.go +618 -7
- package/templates/native-go/backend/internal/helper/supervisor_socket_eof_test.go +74 -0
- package/templates/native-go/backend/internal/helper/supervisor_socket_test.go +45 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/create.json +23 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/frames.json +67 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/grant-store.json +52 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/intent.json +20 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/list.json +20 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/publish.json +20 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/read.json +22 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/stat.json +22 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/write-stream.json +22 -0
- package/templates/native-go/backend/internal/helper/unit_connection.go +75 -0
- package/templates/native-go/backend/internal/helper/unit_connection_linux_test.go +135 -0
- package/templates/native-go/backend/internal/helper/unit_connection_test.go +133 -0
- package/templates/native-go/backend/internal/helper/unit_frame_test.go +32 -0
- package/templates/native-go/backend/internal/helper/unit_linux.go +364 -0
- package/templates/native-go/backend/internal/helper/unit_linux_test.go +46 -0
- package/templates/native-go/backend/internal/helper/unit_mechanisms_linux_test.go +217 -0
- package/templates/native-go/backend/internal/helper/unit_padding_linux_test.go +178 -0
- package/templates/native-go/backend/internal/helper/unit_query_linux.go +111 -0
- package/templates/native-go/backend/internal/helper/unit_reload_linux_test.go +372 -0
- package/templates/native-go/backend/internal/helper/unit_reload_sequence_linux_test.go +232 -0
- package/templates/native-go/backend/internal/helper/write.go +77 -0
- package/templates/native-go/backend/internal/helper/write_admission.go +260 -0
- package/templates/native-go/backend/internal/helper/write_admission_test.go +135 -0
- package/templates/native-go/backend/internal/helper/write_cohort_linux_test.go +218 -0
- package/templates/native-go/backend/internal/helper/write_files_linux.go +202 -0
- package/templates/native-go/backend/internal/helper/write_files_linux_test.go +199 -0
- package/templates/native-go/backend/internal/helper/write_intent_linux.go +116 -0
- package/templates/native-go/backend/internal/helper/write_intent_linux_test.go +74 -0
- package/templates/native-go/backend/internal/helper/write_operation_linux.go +245 -0
- package/templates/native-go/backend/internal/helper/write_test.go +53 -0
- package/templates/native-go/ui/app.js +8 -1
- package/templates/native-go-better-auth/node/build.mjs +2 -0
- package/templates/native-go-vue/README.md +115 -1
- package/templates/native-go-vue/frontend/DESIGN.md +1 -1
- package/templates/native-go-vue/frontend/package-lock.json +132 -229
- package/templates/native-go-vue/frontend/package.json +1 -1
- package/templates/native-go-vue/frontend/src/App.vue +33 -6
- package/templates/native-go-vue/frontend/src/context.ts +41 -2
- package/templates/native-go-vue/frontend/src/main.ts +4 -1
- package/templates/native-go-vue/frontend/src/nas/NasGrantSettings.vue +74 -0
- package/templates/native-go-vue/frontend/src/nas/NasPathPicker.vue +106 -0
- package/templates/native-go-vue/frontend/src/nas/NasUnavailable.vue +20 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/de.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/en.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/es.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/fr.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/it.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/ja.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/ko.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/zh-CN.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/zh-TW.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n.ts +38 -0
- package/templates/native-go-vue/frontend/src/nas/mock-provider.ts +119 -0
- package/templates/native-go-vue/frontend/src/nas/provider.ts +59 -0
- package/templates/native-go-vue/frontend/src/nas/use-request.ts +27 -0
- package/templates/native-go-vue/frontend/src/style.css +17 -0
- package/templates/native-go-vue/frontend/test/apps.test.ts +44 -2
- package/templates/native-go-vue/frontend/test/nas-provider.test.ts +81 -0
- package/templates/native-go-vue/frontend/test/nas-request.test.ts +21 -0
- package/templates/native-go-vue/frontend/test/nas-ui.test.ts +261 -0
- package/templates/native-go-vue/frontend/tsconfig.json +1 -1
- package/templates/native-go-vue/frontend/vite.config.ts +6 -4
|
@@ -9,6 +9,7 @@ import (
|
|
|
9
9
|
"net"
|
|
10
10
|
"os"
|
|
11
11
|
"path/filepath"
|
|
12
|
+
"strings"
|
|
12
13
|
"syscall"
|
|
13
14
|
"time"
|
|
14
15
|
)
|
|
@@ -32,6 +33,8 @@ type Processes interface {
|
|
|
32
33
|
type Controller struct {
|
|
33
34
|
Client
|
|
34
35
|
Processes Processes
|
|
36
|
+
Observe Observation
|
|
37
|
+
Boot func() (string, error)
|
|
35
38
|
}
|
|
36
39
|
|
|
37
40
|
func waitHealthy(ctx context.Context, probe func(context.Context) bool) error {
|
|
@@ -61,7 +64,7 @@ func writeProtected(dir, name string, value any) error {
|
|
|
61
64
|
}
|
|
62
65
|
defer os.Remove(f.Name())
|
|
63
66
|
mode := fs.FileMode(0644)
|
|
64
|
-
if name == "process.json" {
|
|
67
|
+
if name == "observer-diagnostic.json" || name == "process.json" || strings.HasPrefix(name, "completion-") {
|
|
65
68
|
mode = 0600
|
|
66
69
|
}
|
|
67
70
|
if err := f.Chmod(mode); err != nil {
|
|
@@ -120,7 +123,7 @@ func (c Controller) Control(ctx context.Context, action string) error {
|
|
|
120
123
|
if ctx.Err() != nil {
|
|
121
124
|
return ctx.Err()
|
|
122
125
|
}
|
|
123
|
-
if action != "enable" && action != "recover" && action != "teardown" && action != "disable" {
|
|
126
|
+
if action != "enable" && action != "recover" && action != "teardown" && action != "disable" && action != "repair" {
|
|
124
127
|
return errors.New("unsupported lifecycle action")
|
|
125
128
|
}
|
|
126
129
|
if !c.Expected.Valid() || c.Processes == nil {
|
|
@@ -145,50 +148,252 @@ func (c Controller) Control(ctx context.Context, action string) error {
|
|
|
145
148
|
if err != nil && !errors.Is(err, fs.ErrNotExist) {
|
|
146
149
|
return err
|
|
147
150
|
}
|
|
148
|
-
if
|
|
151
|
+
if errors.Is(err, fs.ErrNotExist) {
|
|
152
|
+
r = Record{Inventory: c.Expected}
|
|
153
|
+
}
|
|
154
|
+
if action == "repair" {
|
|
155
|
+
if err != nil {
|
|
156
|
+
return err
|
|
157
|
+
}
|
|
158
|
+
return c.repair(r)
|
|
159
|
+
}
|
|
160
|
+
starting := action == "enable" || action == "recover"
|
|
161
|
+
if action == "recover" && (err != nil || !r.Enabled || r.Inventory != c.Expected || r.Lifecycle == nil) {
|
|
149
162
|
return errors.New("explicit enable approval required")
|
|
150
163
|
}
|
|
151
|
-
|
|
152
|
-
|
|
164
|
+
// A stopped approval referencing a completion must have the private,
|
|
165
|
+
// digest-bound proof; missing/corrupt artifacts are not completion.
|
|
166
|
+
if starting && r.Lifecycle != nil && r.Lifecycle.Completion != "" {
|
|
167
|
+
if _, e := completionRecord(c.Client, r); e != nil {
|
|
168
|
+
return e
|
|
169
|
+
}
|
|
153
170
|
}
|
|
154
|
-
|
|
155
|
-
|
|
171
|
+
var next *Lifecycle
|
|
172
|
+
if starting {
|
|
173
|
+
if c.Observe == nil {
|
|
174
|
+
return errTrust
|
|
175
|
+
}
|
|
176
|
+
binding, e := c.Observe(ctx, c.Expected)
|
|
177
|
+
if e != nil {
|
|
178
|
+
return e
|
|
179
|
+
}
|
|
180
|
+
if action == "recover" && (r.Lifecycle.Binding.Boot != binding.Boot || r.Lifecycle.Binding.Install != binding.Install) {
|
|
181
|
+
return errors.New("installation continuity changed; enable approval required")
|
|
182
|
+
}
|
|
183
|
+
next, err = newLifecycle(binding)
|
|
184
|
+
if err != nil {
|
|
185
|
+
return err
|
|
186
|
+
}
|
|
187
|
+
if err := createLifetime(c.Client, next); err != nil {
|
|
188
|
+
return err
|
|
189
|
+
}
|
|
156
190
|
}
|
|
157
|
-
//
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
191
|
+
// Preserve the owned identity before fencing lets the supervisor unlink it.
|
|
192
|
+
owned, ownedErr := readProcess(c.RunDir, c.Owner)
|
|
193
|
+
// Never hold policy.lock across Stop/ACK. Autonomous fencing shares only
|
|
194
|
+
// this short lock, so a controller holding control.lock cannot deadlock it.
|
|
195
|
+
if err := policyUpdate(c.Client, func(r *Record) error {
|
|
196
|
+
if action == "disable" {
|
|
197
|
+
r.Enabled = false
|
|
198
|
+
}
|
|
199
|
+
r.Residual = true
|
|
200
|
+
if r.Lifecycle != nil && r.Lifecycle.Phase != "stopped" {
|
|
201
|
+
r.Lifecycle.Phase = "fenced"
|
|
202
|
+
r.Lifecycle.Completion = ""
|
|
203
|
+
if r.Lifecycle.Reason == "" {
|
|
204
|
+
r.Lifecycle.Reason = "admin-stop"
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return nil
|
|
208
|
+
}); err != nil {
|
|
161
209
|
return err
|
|
162
210
|
}
|
|
163
|
-
if
|
|
211
|
+
if ownedErr != nil && !errors.Is(ownedErr, fs.ErrNotExist) {
|
|
212
|
+
return ownedErr
|
|
213
|
+
}
|
|
214
|
+
if err := c.teardownFor(r, owned); err != nil {
|
|
164
215
|
return err
|
|
165
216
|
}
|
|
166
|
-
if
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}
|
|
217
|
+
if err := c.commitTeardown(r, owned, next); err != nil {
|
|
218
|
+
return err
|
|
219
|
+
}
|
|
220
|
+
if starting {
|
|
171
221
|
if err := c.Processes.Start(c.Expected); err != nil {
|
|
172
222
|
return err
|
|
173
223
|
}
|
|
224
|
+
return finalizeStart(c.Client, next.Epoch)
|
|
174
225
|
}
|
|
175
|
-
|
|
176
|
-
|
|
226
|
+
return nil
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Keep the post-teardown policy commit separate from socket reconciliation.
|
|
230
|
+
func (c Controller) commitTeardown(before Record, owned Process, next *Lifecycle) error {
|
|
231
|
+
observed, err := readRecord(c.StateDir, c.Owner)
|
|
232
|
+
if err != nil {
|
|
233
|
+
return err
|
|
234
|
+
}
|
|
235
|
+
if !sameTeardownEpoch(observed, before) {
|
|
236
|
+
return errTrust
|
|
237
|
+
}
|
|
238
|
+
published := ""
|
|
239
|
+
if observed.Lifecycle != nil {
|
|
240
|
+
published = observed.Lifecycle.Completion
|
|
241
|
+
}
|
|
242
|
+
// Rename makes completion visible before the owner's directory fsync and
|
|
243
|
+
// lock release. Wait only for that publisher; every other error is final.
|
|
244
|
+
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
245
|
+
defer cancel()
|
|
246
|
+
last := errBusy
|
|
247
|
+
// A budget expiry keeps the last lock refusal; it never certifies success.
|
|
248
|
+
_ = waitHealthy(ctx, func(context.Context) bool {
|
|
249
|
+
last = policyUpdate(c.Client, func(r *Record) error {
|
|
250
|
+
if !sameTeardownEpoch(*r, before) || !runtimeAbsent(c.Client) {
|
|
251
|
+
return errTrust
|
|
252
|
+
}
|
|
253
|
+
if published != "" && (r.Lifecycle == nil || r.Lifecycle.Completion != published) {
|
|
254
|
+
return errTrust
|
|
255
|
+
}
|
|
256
|
+
if r.Lifecycle != nil && r.Lifecycle.Completion != "" {
|
|
257
|
+
proof, err := completionRecord(c.Client, *r)
|
|
258
|
+
if err != nil {
|
|
259
|
+
return err
|
|
260
|
+
}
|
|
261
|
+
if owned.PID > 1 {
|
|
262
|
+
if proof.Repair != nil || proof.Process != owned {
|
|
263
|
+
return errTrust
|
|
264
|
+
}
|
|
265
|
+
} else if before.Lifecycle == nil || before.Lifecycle.Phase != "stopped" {
|
|
266
|
+
return errTrust
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if next != nil {
|
|
270
|
+
*r = Record{Inventory: c.Expected, Enabled: true, Residual: true, Lifecycle: next}
|
|
271
|
+
} else {
|
|
272
|
+
r.Residual = false
|
|
273
|
+
if r.Lifecycle != nil {
|
|
274
|
+
r.Lifecycle.Phase = "stopped"
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return nil
|
|
278
|
+
})
|
|
279
|
+
return !errors.Is(last, errBusy)
|
|
280
|
+
})
|
|
281
|
+
return last
|
|
177
282
|
}
|
|
178
283
|
|
|
179
284
|
func (c Controller) teardown() error {
|
|
285
|
+
r, err := readRecord(c.StateDir, c.Owner)
|
|
286
|
+
if err != nil && !errors.Is(err, fs.ErrNotExist) {
|
|
287
|
+
return err
|
|
288
|
+
}
|
|
289
|
+
p, err := readProcess(c.RunDir, c.Owner)
|
|
290
|
+
if err != nil && !errors.Is(err, fs.ErrNotExist) {
|
|
291
|
+
return err
|
|
292
|
+
}
|
|
293
|
+
return c.teardownFor(r, p)
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
func (c Controller) teardownFor(before Record, owned Process) error {
|
|
297
|
+
r, err := readRecord(c.StateDir, c.Owner)
|
|
298
|
+
if err != nil && !errors.Is(err, fs.ErrNotExist) {
|
|
299
|
+
return err
|
|
300
|
+
}
|
|
301
|
+
if !sameTeardownEpoch(r, before) {
|
|
302
|
+
return errTrust
|
|
303
|
+
}
|
|
304
|
+
if r.Lifecycle != nil && r.Lifecycle.Completion != "" {
|
|
305
|
+
if owned.PID == 0 && before.Lifecycle != nil && before.Lifecycle.Phase != "stopped" {
|
|
306
|
+
return errTrust // no pre-fence process identity to reconcile this exit
|
|
307
|
+
}
|
|
308
|
+
if _, err := completionRecord(c.Client, r); err != nil {
|
|
309
|
+
return err
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return c.teardownRecord(r, owned)
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Phase, completion and enabled/residual flags may change while the owning
|
|
316
|
+
// supervisor exits; inventory, epoch, binding and optional lease must not.
|
|
317
|
+
func sameTeardownEpoch(current, before Record) bool {
|
|
318
|
+
if current.Inventory != before.Inventory {
|
|
319
|
+
return false
|
|
320
|
+
}
|
|
321
|
+
a, b := current.Lifecycle, before.Lifecycle
|
|
322
|
+
if a == nil || b == nil {
|
|
323
|
+
return a == nil && b == nil
|
|
324
|
+
}
|
|
325
|
+
if a.Epoch != b.Epoch || a.Binding != b.Binding {
|
|
326
|
+
return false
|
|
327
|
+
}
|
|
328
|
+
if a.Lease == nil || b.Lease == nil {
|
|
329
|
+
return a.Lease == nil && b.Lease == nil
|
|
330
|
+
}
|
|
331
|
+
return *a.Lease == *b.Lease
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Reconcile runtime against the approval and pre-fence owned process witness.
|
|
335
|
+
func (c Controller) teardownRecord(r Record, owned Process) error {
|
|
180
336
|
p, err := readProcess(c.RunDir, c.Owner)
|
|
181
337
|
if err != nil && !errors.Is(err, fs.ErrNotExist) {
|
|
182
338
|
return err
|
|
183
339
|
}
|
|
184
340
|
if err == nil {
|
|
185
|
-
if p.Inventory.Package != c.Expected.Package {
|
|
341
|
+
if p != owned || p.Inventory.Package != c.Expected.Package {
|
|
186
342
|
return errTrust
|
|
187
343
|
}
|
|
188
344
|
if err := c.Processes.Stop(p); err != nil {
|
|
345
|
+
if c.waitTeardownCompletion(r, owned) == nil {
|
|
346
|
+
return nil
|
|
347
|
+
}
|
|
189
348
|
return err
|
|
190
349
|
}
|
|
350
|
+
} else if owned.PID > 1 {
|
|
351
|
+
// The owner can unlink after our approval snapshot but before this read.
|
|
352
|
+
// Absence alone is never success, including the artifact-before-commit gap.
|
|
353
|
+
if c.waitTeardownCompletion(r, owned) == nil {
|
|
354
|
+
return nil
|
|
355
|
+
}
|
|
356
|
+
return errTrust
|
|
357
|
+
}
|
|
358
|
+
if errors.Is(err, fs.ErrNotExist) && r.Lifecycle != nil && r.Lifecycle.Phase == "fenced" {
|
|
359
|
+
// Runtime unlink followed by a crash is not committed completion. Only
|
|
360
|
+
// a verified new boot + absent /run artifacts permits explicit repair.
|
|
361
|
+
if c.Boot == nil || !runtimeAbsent(c.Client) {
|
|
362
|
+
return errTrust
|
|
363
|
+
}
|
|
364
|
+
boot, e := c.Boot()
|
|
365
|
+
if e != nil || boot == "" || boot == r.Lifecycle.Binding.Boot {
|
|
366
|
+
return errTrust
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
if err := cleanRuntime(c.Client, err == nil); err != nil {
|
|
370
|
+
if c.waitTeardownCompletion(r, owned) == nil {
|
|
371
|
+
return nil
|
|
372
|
+
}
|
|
373
|
+
return err
|
|
191
374
|
}
|
|
375
|
+
return nil
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
func (c Controller) waitTeardownCompletion(before Record, owned Process) error {
|
|
379
|
+
if before.Lifecycle == nil || owned.PID <= 1 || owned.Inventory != before.Inventory || owned.Boot != before.Lifecycle.Binding.Boot {
|
|
380
|
+
return errTrust
|
|
381
|
+
}
|
|
382
|
+
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
383
|
+
defer cancel()
|
|
384
|
+
return waitHealthy(ctx, func(context.Context) bool {
|
|
385
|
+
r, err := readRecord(c.StateDir, c.Owner)
|
|
386
|
+
if err != nil || !sameTeardownEpoch(r, before) {
|
|
387
|
+
return false
|
|
388
|
+
}
|
|
389
|
+
proof, err := completionRecord(c.Client, r)
|
|
390
|
+
return err == nil && proof.Process == owned && runtimeAbsent(c.Client)
|
|
391
|
+
})
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// cleanRuntime is shared by verified controller and owned supervisor cleanup.
|
|
395
|
+
// The caller must first prove child teardown; it never signals a recorded PID.
|
|
396
|
+
func cleanRuntime(c Client, hasProcess bool) error {
|
|
192
397
|
for _, name := range []string{"helper.sock", "supervisor.sock"} {
|
|
193
398
|
path := filepath.Join(c.RunDir, name)
|
|
194
399
|
st, e := os.Lstat(path)
|
|
@@ -212,7 +417,7 @@ func (c Controller) teardown() error {
|
|
|
212
417
|
return e
|
|
213
418
|
}
|
|
214
419
|
}
|
|
215
|
-
if
|
|
420
|
+
if hasProcess {
|
|
216
421
|
return os.Remove(filepath.Join(c.RunDir, "process.json"))
|
|
217
422
|
}
|
|
218
423
|
return nil
|
|
@@ -23,9 +23,13 @@ type fakeProcesses struct {
|
|
|
23
23
|
current Process
|
|
24
24
|
stopped, started int
|
|
25
25
|
stopErr error
|
|
26
|
+
stopHook func(Process) error
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
func (f *fakeProcesses) Stop(want Process) error {
|
|
30
|
+
if f.stopHook != nil {
|
|
31
|
+
return f.stopHook(want)
|
|
32
|
+
}
|
|
29
33
|
if f.stopErr != nil {
|
|
30
34
|
return f.stopErr
|
|
31
35
|
}
|
|
@@ -41,8 +45,8 @@ func controlFixture(t *testing.T) (Controller, *fakeProcesses) {
|
|
|
41
45
|
c := fixture(t)
|
|
42
46
|
p := Process{Inventory: c.Expected, Mode: "supervised", PID: 1234, Boot: "fixture-boot", Start: "100", Device: 1, Inode: 2}
|
|
43
47
|
f := &fakeProcesses{current: p}
|
|
44
|
-
ctl := Controller{Client: c, Processes: f}
|
|
45
|
-
record(t, c, Record{Inventory: c.Expected, Enabled: true})
|
|
48
|
+
ctl := Controller{Client: c, Processes: f, Observe: func(context.Context, Inventory) (Binding, error) { return testBinding(), nil }}
|
|
49
|
+
record(t, c, Record{Inventory: c.Expected, Enabled: true, Lifecycle: testLifecycle("running")})
|
|
46
50
|
if err := writeProcess(c.RunDir, p); err != nil {
|
|
47
51
|
t.Fatal(err)
|
|
48
52
|
}
|
|
@@ -135,6 +139,10 @@ func TestSocketResidueCannotUnlinkForeignFilesOrLiveListeners(t *testing.T) {
|
|
|
135
139
|
for _, kind := range []string{"file", "symlink", "live", "stale"} {
|
|
136
140
|
t.Run(kind, func(t *testing.T) {
|
|
137
141
|
c, f := controlFixture(t)
|
|
142
|
+
// This test covers migration cleanup of pre-M1g owned stale sockets.
|
|
143
|
+
// A schema-2 incomplete transaction is tested separately and cannot use
|
|
144
|
+
// absent runtime alone as completion proof.
|
|
145
|
+
record(t, c.Client, Record{Inventory: c.Expected, Enabled: true})
|
|
138
146
|
os.Remove(filepath.Join(c.RunDir, "process.json"))
|
|
139
147
|
p := filepath.Join(c.RunDir, "helper.sock")
|
|
140
148
|
switch kind {
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
package helper
|
|
2
|
+
|
|
3
|
+
import "time"
|
|
4
|
+
|
|
5
|
+
// These are S0 contracts only. No data operation is served by the M1 socket.
|
|
6
|
+
const (
|
|
7
|
+
DataProtocol = 2
|
|
8
|
+
GrantSchema = 1
|
|
9
|
+
MaxHealthBytes = 4096
|
|
10
|
+
MaxControlBytes = 16 * 1024
|
|
11
|
+
MaxGrants = 256 // includes revoked tombstones
|
|
12
|
+
MaxGrantStoreBytes = 1 << 20
|
|
13
|
+
MaxPageEntries = 200
|
|
14
|
+
MaxMetadataBytes = 256 * 1024
|
|
15
|
+
MaxLiveIntents = 8 // per native subject
|
|
16
|
+
MaxPathBytes = 4096
|
|
17
|
+
MaxPathSegments = 32
|
|
18
|
+
MaxSegmentBytes = 255
|
|
19
|
+
MaxBoundedBytes = 1 << 20
|
|
20
|
+
MaxTransferBytes = 64 << 20
|
|
21
|
+
MaxChunkBytes = 64 << 10
|
|
22
|
+
MaxOutstandingLeases = 1 // per transfer
|
|
23
|
+
MaxPackageOperations = 4
|
|
24
|
+
MaxSubjectOperations = 2
|
|
25
|
+
MaxReplayEntries = 256 // per epoch/session window; full means busy, never eviction
|
|
26
|
+
ControlTimeout = time.Second
|
|
27
|
+
MetadataTimeout = 5 * time.Second
|
|
28
|
+
BoundedTimeout = 10 * time.Second
|
|
29
|
+
CandidateTTL = 60 * time.Second
|
|
30
|
+
IntentTTL = 30 * time.Second
|
|
31
|
+
StreamIdleTimeout = 10 * time.Second
|
|
32
|
+
StreamTotalTimeout = 120 * time.Second
|
|
33
|
+
NativeProofFreshness = 2 * time.Second
|
|
34
|
+
RevokeDrainTimeout = 2 * time.Second
|
|
35
|
+
TerminateGrace = time.Second
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
type Action string
|
|
39
|
+
|
|
40
|
+
const (
|
|
41
|
+
ActionList Action = "nas.files.list"
|
|
42
|
+
ActionStat Action = "nas.files.stat"
|
|
43
|
+
ActionRead Action = "nas.files.read"
|
|
44
|
+
ActionReadStream Action = "nas.files.read-stream"
|
|
45
|
+
ActionCreate Action = "nas.files.create"
|
|
46
|
+
ActionWriteStream Action = "nas.files.write-stream"
|
|
47
|
+
ActionPublish Action = "nas.files.publish"
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
func (a Action) ReadOnly() bool {
|
|
51
|
+
return a == ActionList || a == ActionStat || a == ActionRead || a == ActionReadStream
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Code deliberately has no underlying native error, path, credential or stderr.
|
|
55
|
+
type Code string
|
|
56
|
+
|
|
57
|
+
const (
|
|
58
|
+
ErrInvalid Code = "invalid-request"
|
|
59
|
+
ErrIncompatible Code = "incompatible"
|
|
60
|
+
ErrUnsupported Code = "unsupported"
|
|
61
|
+
ErrReplay Code = "replay"
|
|
62
|
+
ErrStale Code = "stale"
|
|
63
|
+
ErrExpired Code = "expired"
|
|
64
|
+
ErrDenied Code = "denied"
|
|
65
|
+
ErrUnavailable Code = "unavailable"
|
|
66
|
+
ErrSuspended Code = "suspended"
|
|
67
|
+
ErrRevoked Code = "revoked"
|
|
68
|
+
ErrFenced Code = "fenced"
|
|
69
|
+
ErrBusy Code = "busy"
|
|
70
|
+
ErrLimit Code = "limit-exceeded"
|
|
71
|
+
ErrCanceled Code = "canceled"
|
|
72
|
+
ErrTimeout Code = "timeout"
|
|
73
|
+
ErrPartial Code = "partial"
|
|
74
|
+
ErrCommitUncertain Code = "commit-uncertain"
|
|
75
|
+
ErrCleanupRequired Code = "cleanup-required"
|
|
76
|
+
ErrInternal Code = "internal"
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
func (c Code) Error() string { return string(c) }
|
|
80
|
+
func (c Code) Valid() bool {
|
|
81
|
+
switch c {
|
|
82
|
+
case ErrInvalid, ErrIncompatible, ErrUnsupported, ErrReplay, ErrStale, ErrExpired,
|
|
83
|
+
ErrDenied, ErrUnavailable, ErrSuspended, ErrRevoked, ErrFenced, ErrBusy, ErrLimit,
|
|
84
|
+
ErrCanceled, ErrTimeout, ErrPartial, ErrCommitUncertain, ErrCleanupRequired, ErrInternal:
|
|
85
|
+
return true
|
|
86
|
+
}
|
|
87
|
+
return false
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
type SafeError struct {
|
|
91
|
+
Code Code `json:"code"`
|
|
92
|
+
OperationID string `json:"operationId,omitempty"`
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
type ScopeKind string
|
|
96
|
+
|
|
97
|
+
const (
|
|
98
|
+
ScopeShared ScopeKind = "app-shared"
|
|
99
|
+
ScopePersonal ScopeKind = "user-personal"
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
// Principal and Scope are root-derived authority records, never caller claims.
|
|
103
|
+
// Strict proof references require S1 validation; the opt-in managed pilot uses
|
|
104
|
+
// a separately labeled SDK enrollment and the SAME S3 admission guard. It never
|
|
105
|
+
// claims native incarnation. Name/UID/dev/inode are not continuity.
|
|
106
|
+
type Principal struct {
|
|
107
|
+
Kind string `json:"kind"` // local only
|
|
108
|
+
SubjectRef string `json:"subjectRef"`
|
|
109
|
+
InstanceRef string `json:"instanceRef"`
|
|
110
|
+
// Explicit S1R discriminator. Omitted legacy fields remain strict/managed;
|
|
111
|
+
// no decoder may reinterpret their references as UID/username evidence.
|
|
112
|
+
IdentityBasis string `json:"identityBasis,omitempty"`
|
|
113
|
+
UID uint32 `json:"uid,omitempty"`
|
|
114
|
+
Username string `json:"username,omitempty"`
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
type Scope struct {
|
|
118
|
+
Kind ScopeKind `json:"kind"`
|
|
119
|
+
TargetKind string `json:"targetKind"` // directory only
|
|
120
|
+
AnchorRef string `json:"anchorRef"` // trusted share or own-home anchor
|
|
121
|
+
Segments []string `json:"segments"`
|
|
122
|
+
ObjectRef string `json:"objectRef"`
|
|
123
|
+
MountRef string `json:"mountRef"` // validated local mount identity, not just st_dev
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
type ContinuityBinding struct {
|
|
127
|
+
Epoch string `json:"epoch"`
|
|
128
|
+
SubjectProof string `json:"subjectProof"`
|
|
129
|
+
ScopeProof string `json:"scopeProof"`
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
type GrantState string
|
|
133
|
+
|
|
134
|
+
const (
|
|
135
|
+
GrantActive GrantState = "active"
|
|
136
|
+
GrantSuspended GrantState = "suspended"
|
|
137
|
+
GrantRevoked GrantState = "revoked"
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
type Grant struct {
|
|
141
|
+
Schema int `json:"grantSchema"`
|
|
142
|
+
ID string `json:"grantId"`
|
|
143
|
+
Revision uint64 `json:"grantRevision"`
|
|
144
|
+
Inventory Inventory `json:"inventory"`
|
|
145
|
+
ApprovalBinding string `json:"approvalBinding"`
|
|
146
|
+
CapabilityDigest string `json:"capabilityDigest"`
|
|
147
|
+
Owner Principal `json:"owner"`
|
|
148
|
+
Issuer Principal `json:"issuer"`
|
|
149
|
+
Scope Scope `json:"scope"`
|
|
150
|
+
Actions []Action `json:"actions"`
|
|
151
|
+
State GrantState `json:"state"`
|
|
152
|
+
CreatedAt int64 `json:"createdAt"` // Unix milliseconds
|
|
153
|
+
RevokedAt int64 `json:"revokedAt,omitempty"`
|
|
154
|
+
Reason Code `json:"reason,omitempty"`
|
|
155
|
+
LastValidated ContinuityBinding `json:"lastValidatedBinding"`
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// EffectiveState never restores a revoked or suspended grant. Restart callers
|
|
159
|
+
// must pass continuous=false even if a restored epoch happens to match.
|
|
160
|
+
func (g Grant) EffectiveState(current ContinuityBinding, continuous bool) GrantState {
|
|
161
|
+
if g.State == GrantRevoked {
|
|
162
|
+
return GrantRevoked
|
|
163
|
+
}
|
|
164
|
+
if g.State != GrantActive || !continuous || !validContinuity(current) || g.LastValidated != current {
|
|
165
|
+
return GrantSuspended
|
|
166
|
+
}
|
|
167
|
+
return GrantActive
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
type GrantStore struct {
|
|
171
|
+
Schema int `json:"grantSchema"`
|
|
172
|
+
Revision uint64 `json:"storeRevision"`
|
|
173
|
+
Grants []Grant `json:"grants"`
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Intent is ephemeral and server-derived. Confirmation consumes it only after
|
|
177
|
+
// fresh native identity/role/ACL and exact summary/epoch/candidate revalidation.
|
|
178
|
+
type Intent struct {
|
|
179
|
+
ID string `json:"intentId"`
|
|
180
|
+
Inventory Inventory `json:"inventory"`
|
|
181
|
+
Epoch string `json:"epoch"`
|
|
182
|
+
SubjectRef string `json:"subjectRef"`
|
|
183
|
+
SessionRef string `json:"sessionRef"`
|
|
184
|
+
CandidateID string `json:"candidateId"`
|
|
185
|
+
ScopeKind ScopeKind `json:"scopeKind"`
|
|
186
|
+
Actions []Action `json:"actions"`
|
|
187
|
+
SummaryDigest string `json:"summaryDigest"`
|
|
188
|
+
ExpiresAt int64 `json:"expiresAt"` // Unix milliseconds; at most IntentTTL
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
type ListArgs struct {
|
|
192
|
+
Segments []string `json:"segments"`
|
|
193
|
+
Limit uint32 `json:"limit"`
|
|
194
|
+
Cursor string `json:"cursor,omitempty"`
|
|
195
|
+
}
|
|
196
|
+
type StatArgs struct {
|
|
197
|
+
Segments []string `json:"segments"`
|
|
198
|
+
}
|
|
199
|
+
type ReadArgs struct {
|
|
200
|
+
Segments []string `json:"segments"`
|
|
201
|
+
MaxBytes uint64 `json:"maxBytes"` // no caller offsets/ranges/resume
|
|
202
|
+
}
|
|
203
|
+
type CreateArgs struct {
|
|
204
|
+
Segments []string `json:"segments"`
|
|
205
|
+
Bytes uint64 `json:"bytes"` // bulk data never carried in JSON
|
|
206
|
+
Exclusive bool `json:"exclusive"`
|
|
207
|
+
}
|
|
208
|
+
type WriteStreamArgs struct {
|
|
209
|
+
Segments []string `json:"segments"`
|
|
210
|
+
MaxBytes uint64 `json:"maxBytes"`
|
|
211
|
+
}
|
|
212
|
+
type PublishArgs struct {
|
|
213
|
+
StageID string `json:"stageId"`
|
|
214
|
+
NoOverwrite bool `json:"noOverwrite"`
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
type Entry struct {
|
|
218
|
+
EntryID string `json:"entryId"`
|
|
219
|
+
Name string `json:"name"` // visible only after actor ACL
|
|
220
|
+
Kind string `json:"kind"` // directory or regular
|
|
221
|
+
Bytes uint64 `json:"bytes"`
|
|
222
|
+
}
|
|
223
|
+
type ListResult struct {
|
|
224
|
+
Entries []Entry `json:"entries"`
|
|
225
|
+
Cursor string `json:"cursor,omitempty"` // opaque, bound to actor/grant/revision/epoch
|
|
226
|
+
}
|
|
227
|
+
type ReadResult struct {
|
|
228
|
+
Bytes uint64 `json:"bytes"`
|
|
229
|
+
} // separate bounded binary relay
|
|
230
|
+
type MutationReceipt struct {
|
|
231
|
+
EffectsUnknown bool `json:"effectsUnknown,omitempty"`
|
|
232
|
+
Created bool `json:"created"`
|
|
233
|
+
Published bool `json:"published"`
|
|
234
|
+
BytesWritten uint64 `json:"bytesWritten"`
|
|
235
|
+
Committed bool `json:"committed"`
|
|
236
|
+
}
|
|
237
|
+
type RevokeResult struct {
|
|
238
|
+
GrantID string `json:"grantId"`
|
|
239
|
+
Revision uint64 `json:"grantRevision"`
|
|
240
|
+
Revoked bool `json:"revoked"` // R: durable tombstone, deny new admissions
|
|
241
|
+
Drained bool `json:"drained"` // Q: child/relay/lease/FD completion proof
|
|
242
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
package helper
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"encoding/json"
|
|
5
|
+
"strings"
|
|
6
|
+
"testing"
|
|
7
|
+
"time"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
func TestDataContractTypes(t *testing.T) {
|
|
11
|
+
if DataProtocol != 2 || GrantSchema != 1 || MaxControlBytes != 16*1024 || MaxHealthBytes != 4096 || MaxBoundedBytes != 1<<20 {
|
|
12
|
+
t.Fatal("protocol/schema/transport ceilings changed")
|
|
13
|
+
}
|
|
14
|
+
if CandidateTTL != 60*time.Second || IntentTTL != 30*time.Second || MaxGrants != 256 || MaxPageEntries != 200 {
|
|
15
|
+
t.Fatal("consent and metadata ceilings changed")
|
|
16
|
+
}
|
|
17
|
+
if !ActionList.ReadOnly() || !ActionStat.ReadOnly() || !ActionRead.ReadOnly() || ActionCreate.ReadOnly() || ActionPublish.ReadOnly() || Action("shell").ReadOnly() {
|
|
18
|
+
t.Fatal("action classification must be closed")
|
|
19
|
+
}
|
|
20
|
+
b, err := json.Marshal(SafeError{Code: ErrDenied, OperationID: strings.Repeat("a", 64)})
|
|
21
|
+
if err != nil || strings.Contains(string(b), "path") || strings.Contains(string(b), "message") {
|
|
22
|
+
t.Fatalf("unsafe error shape: %s %v", b, err)
|
|
23
|
+
}
|
|
24
|
+
if ErrDenied.Error() != "denied" || Code("raw stderr").Valid() || Code("").Valid() {
|
|
25
|
+
t.Fatal("error set must be closed")
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
func TestGrantContinuityContract(t *testing.T) {
|
|
30
|
+
b := ContinuityBinding{Epoch: strings.Repeat("a", 64), SubjectProof: strings.Repeat("b", 64), ScopeProof: strings.Repeat("c", 64)}
|
|
31
|
+
g := Grant{State: GrantActive, LastValidated: b}
|
|
32
|
+
if g.EffectiveState(b, true) != GrantActive || g.EffectiveState(b, false) != GrantSuspended {
|
|
33
|
+
t.Fatal("unknown continuity must suspend")
|
|
34
|
+
}
|
|
35
|
+
changed := b
|
|
36
|
+
changed.Epoch = strings.Repeat("d", 64)
|
|
37
|
+
if g.EffectiveState(changed, true) != GrantSuspended {
|
|
38
|
+
t.Fatal("new epoch must suspend")
|
|
39
|
+
}
|
|
40
|
+
g.State = GrantRevoked
|
|
41
|
+
if g.EffectiveState(changed, false) != GrantRevoked {
|
|
42
|
+
t.Fatal("tombstone must remain revoked")
|
|
43
|
+
}
|
|
44
|
+
g.State = GrantSuspended
|
|
45
|
+
if g.EffectiveState(b, true) != GrantSuspended {
|
|
46
|
+
t.Fatal("continuity alone must not un-suspend")
|
|
47
|
+
}
|
|
48
|
+
if (Grant{State: GrantActive}).EffectiveState(ContinuityBinding{}, true) != GrantSuspended {
|
|
49
|
+
t.Fatal("empty proof cannot establish continuity")
|
|
50
|
+
}
|
|
51
|
+
}
|