@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.
Files changed (438) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +37 -0
  3. package/dist/build-spk/generator.js +3 -0
  4. package/dist/build-spk/notices.d.ts +5 -0
  5. package/dist/build-spk/notices.js +60 -0
  6. package/dist/cli.js +9 -2
  7. package/dist/error-registry.js +20 -0
  8. package/dist/init.d.ts +4 -0
  9. package/dist/init.js +20 -12
  10. package/dist/standalone/build.js +3 -1
  11. package/dist/standalone/daemon.d.ts +23 -0
  12. package/dist/standalone/daemon.js +114 -0
  13. package/dist/standalone/dsm-window.d.ts +1 -1
  14. package/dist/standalone/dsm-window.js +50 -10
  15. package/dist/standalone/helper-inventory.d.ts +16 -0
  16. package/dist/standalone/helper-inventory.js +2 -0
  17. package/dist/standalone/helper.d.ts +2 -12
  18. package/dist/standalone/helper.js +8 -7
  19. package/dist/standalone/host-adapter.d.ts +5 -0
  20. package/dist/standalone/host-adapter.js +148 -0
  21. package/dist/standalone/host-platform.d.ts +13 -0
  22. package/dist/standalone/host-platform.js +42 -0
  23. package/dist/standalone/host-types.d.ts +49 -0
  24. package/dist/standalone/host-types.js +1 -0
  25. package/dist/standalone/inspect-helper.d.ts +6 -0
  26. package/dist/standalone/inspect-helper.js +88 -0
  27. package/dist/standalone/inspect-spk.d.ts +2 -0
  28. package/dist/standalone/inspect-spk.js +49 -0
  29. package/dist/standalone/lifecycle-helper.d.ts +2 -0
  30. package/dist/standalone/lifecycle-helper.js +12 -0
  31. package/dist/standalone/lifecycle.d.ts +3 -0
  32. package/dist/standalone/lifecycle.js +53 -0
  33. package/dist/standalone/manifest.d.ts +2 -0
  34. package/dist/standalone/manifest.js +4 -1
  35. package/dist/standalone/reopen-events.d.ts +2 -0
  36. package/dist/standalone/reopen-events.js +28 -0
  37. package/dist/standalone/root-messages.js +9 -0
  38. package/dist/standalone/root-window.d.ts +4 -3
  39. package/dist/standalone/root-window.js +17 -5
  40. package/dist/standalone/spk.d.ts +4 -3
  41. package/dist/standalone/spk.js +20 -33
  42. package/dist/template-paths.d.ts +2 -0
  43. package/dist/template-paths.js +9 -0
  44. package/dist/templates/_daemon/fixture_linux_test.go +15 -0
  45. package/dist/templates/_daemon/fixture_other_test.go +7 -0
  46. package/dist/templates/_daemon/go.mod +3 -0
  47. package/dist/templates/_daemon/main.go +608 -0
  48. package/dist/templates/_daemon/main_test.go +242 -0
  49. package/dist/templates/_daemon/process_linux.go +55 -0
  50. package/dist/templates/_daemon/process_linux_test.go +161 -0
  51. package/dist/templates/_daemon/process_other.go +14 -0
  52. package/dist/templates/_daemon/testdata/child.go +41 -0
  53. package/dist/templates/_shared/GO-LICENSE +27 -0
  54. package/dist/templates/_shared/GO-PATENTS +22 -0
  55. package/dist/templates/_shared/LICENSES/TEMPLATE.txt +21 -0
  56. package/dist/templates/_shared/notice-overrides/index.json +14 -0
  57. package/dist/templates/_shared/notice-overrides/utils-0.4.2-LICENSE +21 -0
  58. package/dist/templates/_shared/notice-overrides/utils-0.5.0-LICENSE +21 -0
  59. package/dist/templates/_shared/third-party-notices.mjs +51 -0
  60. package/dist/templates/native-go/README.md +57 -1
  61. package/dist/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +59 -0
  62. package/dist/templates/native-go/backend/cmd/dsm-readonly-probe/main_linux.go +46 -0
  63. package/dist/templates/native-go/backend/go.mod +4 -0
  64. package/dist/templates/native-go/backend/go.sum +4 -0
  65. package/dist/templates/native-go/backend/internal/api/binary.go +154 -0
  66. package/dist/templates/native-go/backend/internal/api/binary_test.go +165 -0
  67. package/dist/templates/native-go/backend/internal/api/registry.go +14 -4
  68. package/dist/templates/native-go/backend/internal/api/server.go +4 -0
  69. package/dist/templates/native-go/backend/internal/app/nas_cgi_artifact_test.go +121 -0
  70. package/dist/templates/native-go/backend/internal/app/nas_refusal_test.go +46 -0
  71. package/dist/templates/native-go/backend/internal/app/routes.go +11 -0
  72. package/dist/templates/native-go/backend/internal/app/routes_test.go +10 -5
  73. package/dist/templates/native-go/backend/internal/dsmprobe/collector_linux.go +335 -0
  74. package/dist/templates/native-go/backend/internal/dsmprobe/collector_linux_test.go +41 -0
  75. package/dist/templates/native-go/backend/internal/dsmprobe/protocol.go +179 -0
  76. package/dist/templates/native-go/backend/internal/dsmprobe/protocol_test.go +29 -0
  77. package/dist/templates/native-go/backend/internal/helper/cohort.go +393 -0
  78. package/dist/templates/native-go/backend/internal/helper/cohort_publication.go +18 -0
  79. package/dist/templates/native-go/backend/internal/helper/cohort_publication_test.go +105 -0
  80. package/dist/templates/native-go/backend/internal/helper/cohort_test.go +372 -0
  81. package/dist/templates/native-go/backend/internal/helper/control.go +226 -21
  82. package/dist/templates/native-go/backend/internal/helper/control_test.go +10 -2
  83. package/dist/templates/native-go/backend/internal/helper/data_contract.go +242 -0
  84. package/dist/templates/native-go/backend/internal/helper/data_contract_test.go +51 -0
  85. package/dist/templates/native-go/backend/internal/helper/data_decode.go +184 -0
  86. package/dist/templates/native-go/backend/internal/helper/data_decode_pointer_test.go +30 -0
  87. package/dist/templates/native-go/backend/internal/helper/data_protocol.go +416 -0
  88. package/dist/templates/native-go/backend/internal/helper/data_protocol_test.go +449 -0
  89. package/dist/templates/native-go/backend/internal/helper/dsm_acl_linux.go +139 -0
  90. package/dist/templates/native-go/backend/internal/helper/dsm_acl_linux_test.go +121 -0
  91. package/dist/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux.go +95 -0
  92. package/dist/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux_test.go +56 -0
  93. package/dist/templates/native-go/backend/internal/helper/dsm_bridge_linux.go +144 -0
  94. package/dist/templates/native-go/backend/internal/helper/dsm_bridge_linux_test.go +89 -0
  95. package/dist/templates/native-go/backend/internal/helper/dsm_home_linux.go +107 -0
  96. package/dist/templates/native-go/backend/internal/helper/dsm_home_linux_test.go +82 -0
  97. package/dist/templates/native-go/backend/internal/helper/dsm_probe_transport_linux.go +151 -0
  98. package/dist/templates/native-go/backend/internal/helper/dsm_probe_transport_linux_test.go +66 -0
  99. package/dist/templates/native-go/backend/internal/helper/grant_authority.go +516 -0
  100. package/dist/templates/native-go/backend/internal/helper/grant_authority_contract.go +88 -0
  101. package/dist/templates/native-go/backend/internal/helper/grant_authority_test.go +510 -0
  102. package/dist/templates/native-go/backend/internal/helper/grant_cohort.go +389 -0
  103. package/dist/templates/native-go/backend/internal/helper/grant_cohort_test.go +239 -0
  104. package/dist/templates/native-go/backend/internal/helper/grant_delivery.go +49 -0
  105. package/dist/templates/native-go/backend/internal/helper/grant_delivery_methods.go +273 -0
  106. package/dist/templates/native-go/backend/internal/helper/grant_delivery_test.go +322 -0
  107. package/dist/templates/native-go/backend/internal/helper/grant_operation_contract.go +47 -0
  108. package/dist/templates/native-go/backend/internal/helper/grant_readonly_test.go +180 -0
  109. package/dist/templates/native-go/backend/internal/helper/grant_repository_linux.go +415 -0
  110. package/dist/templates/native-go/backend/internal/helper/grant_repository_linux_test.go +468 -0
  111. package/dist/templates/native-go/backend/internal/helper/grant_rpc.go +147 -0
  112. package/dist/templates/native-go/backend/internal/helper/grant_rpc_test.go +51 -0
  113. package/dist/templates/native-go/backend/internal/helper/grant_snapshot.go +75 -0
  114. package/dist/templates/native-go/backend/internal/helper/grant_supervisor_linux.go +134 -0
  115. package/dist/templates/native-go/backend/internal/helper/grant_supervisor_linux_test.go +254 -0
  116. package/dist/templates/native-go/backend/internal/helper/lease.go +112 -0
  117. package/dist/templates/native-go/backend/internal/helper/lease_linux.go +44 -0
  118. package/dist/templates/native-go/backend/internal/helper/lease_other.go +8 -0
  119. package/dist/templates/native-go/backend/internal/helper/lifecycle.go +234 -0
  120. package/dist/templates/native-go/backend/internal/helper/lifecycle_test.go +473 -0
  121. package/dist/templates/native-go/backend/internal/helper/managed_pilot.go +284 -0
  122. package/dist/templates/native-go/backend/internal/helper/managed_pilot_repository_linux.go +74 -0
  123. package/dist/templates/native-go/backend/internal/helper/managed_pilot_repository_linux_test.go +40 -0
  124. package/dist/templates/native-go/backend/internal/helper/managed_pilot_test.go +210 -0
  125. package/dist/templates/native-go/backend/internal/helper/nas_shipped_refusal_linux_test.go +97 -0
  126. package/dist/templates/native-go/backend/internal/helper/native_discovery.go +79 -0
  127. package/dist/templates/native-go/backend/internal/helper/native_identity.go +89 -0
  128. package/dist/templates/native-go/backend/internal/helper/native_provider.go +159 -0
  129. package/dist/templates/native-go/backend/internal/helper/native_provider_test.go +421 -0
  130. package/dist/templates/native-go/backend/internal/helper/observation.go +204 -0
  131. package/dist/templates/native-go/backend/internal/helper/observation_health_test.go +115 -0
  132. package/dist/templates/native-go/backend/internal/helper/observation_reload_budget_test.go +117 -0
  133. package/dist/templates/native-go/backend/internal/helper/observation_test.go +196 -0
  134. package/dist/templates/native-go/backend/internal/helper/observer_diagnostic.go +109 -0
  135. package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_linux.go +76 -0
  136. package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_linux_test.go +124 -0
  137. package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_test.go +98 -0
  138. package/dist/templates/native-go/backend/internal/helper/operation_bootstrap_linux.go +193 -0
  139. package/dist/templates/native-go/backend/internal/helper/operation_credentials_linux.go +56 -0
  140. package/dist/templates/native-go/backend/internal/helper/operation_linux.go +480 -0
  141. package/dist/templates/native-go/backend/internal/helper/operation_linux_test.go +528 -0
  142. package/dist/templates/native-go/backend/internal/helper/process_linux.go +11 -1
  143. package/dist/templates/native-go/backend/internal/helper/publication_test.go +178 -0
  144. package/dist/templates/native-go/backend/internal/helper/read_stream_cohort_linux_test.go +156 -0
  145. package/dist/templates/native-go/backend/internal/helper/read_transfer.go +40 -0
  146. package/dist/templates/native-go/backend/internal/helper/read_transfer_linux.go +109 -0
  147. package/dist/templates/native-go/backend/internal/helper/read_transfer_linux_test.go +118 -0
  148. package/dist/templates/native-go/backend/internal/helper/read_transfer_test.go +177 -0
  149. package/dist/templates/native-go/backend/internal/helper/readonly.go +105 -0
  150. package/dist/templates/native-go/backend/internal/helper/readonly_admission.go +85 -0
  151. package/dist/templates/native-go/backend/internal/helper/readonly_cohort_linux_test.go +253 -0
  152. package/dist/templates/native-go/backend/internal/helper/readonly_linux_test.go +378 -0
  153. package/dist/templates/native-go/backend/internal/helper/readonly_mount_linux.go +65 -0
  154. package/dist/templates/native-go/backend/internal/helper/readonly_mount_proxy_linux.go +113 -0
  155. package/dist/templates/native-go/backend/internal/helper/readonly_operations_linux.go +168 -0
  156. package/dist/templates/native-go/backend/internal/helper/readonly_resolver_linux.go +241 -0
  157. package/dist/templates/native-go/backend/internal/helper/readonly_test.go +40 -0
  158. package/dist/templates/native-go/backend/internal/helper/relaxed_identity.go +252 -0
  159. package/dist/templates/native-go/backend/internal/helper/relaxed_identity_contract.go +105 -0
  160. package/dist/templates/native-go/backend/internal/helper/relaxed_identity_test.go +406 -0
  161. package/dist/templates/native-go/backend/internal/helper/relaxed_invalidation.go +200 -0
  162. package/dist/templates/native-go/backend/internal/helper/repair.go +132 -0
  163. package/dist/templates/native-go/backend/internal/helper/repair_test.go +271 -0
  164. package/dist/templates/native-go/backend/internal/helper/s1r_actor_acl_linux_test.go +303 -0
  165. package/dist/templates/native-go/backend/internal/helper/s1r_actor_fixture_linux_test.go +184 -0
  166. package/dist/templates/native-go/backend/internal/helper/s1r_actor_races_linux_test.go +231 -0
  167. package/dist/templates/native-go/backend/internal/helper/s1r_fixture_contract_linux_test.go +18 -0
  168. package/dist/templates/native-go/backend/internal/helper/server_linux.go +44 -3
  169. package/dist/templates/native-go/backend/internal/helper/status.go +74 -11
  170. package/dist/templates/native-go/backend/internal/helper/status_test.go +83 -0
  171. package/dist/templates/native-go/backend/internal/helper/supervision.go +28 -5
  172. package/dist/templates/native-go/backend/internal/helper/supervisor_frame.go +76 -0
  173. package/dist/templates/native-go/backend/internal/helper/supervisor_frame_linux_test.go +69 -0
  174. package/dist/templates/native-go/backend/internal/helper/supervisor_frame_test.go +107 -0
  175. package/dist/templates/native-go/backend/internal/helper/supervisor_linux.go +187 -16
  176. package/dist/templates/native-go/backend/internal/helper/supervisor_linux_test.go +618 -7
  177. package/dist/templates/native-go/backend/internal/helper/supervisor_socket_eof_test.go +74 -0
  178. package/dist/templates/native-go/backend/internal/helper/supervisor_socket_test.go +45 -0
  179. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/create.json +23 -0
  180. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/frames.json +67 -0
  181. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/grant-store.json +52 -0
  182. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/intent.json +20 -0
  183. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/list.json +20 -0
  184. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/publish.json +20 -0
  185. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/read.json +22 -0
  186. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/stat.json +22 -0
  187. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/write-stream.json +22 -0
  188. package/dist/templates/native-go/backend/internal/helper/unit_connection.go +75 -0
  189. package/dist/templates/native-go/backend/internal/helper/unit_connection_linux_test.go +135 -0
  190. package/dist/templates/native-go/backend/internal/helper/unit_connection_test.go +133 -0
  191. package/dist/templates/native-go/backend/internal/helper/unit_frame_test.go +32 -0
  192. package/dist/templates/native-go/backend/internal/helper/unit_linux.go +364 -0
  193. package/dist/templates/native-go/backend/internal/helper/unit_linux_test.go +46 -0
  194. package/dist/templates/native-go/backend/internal/helper/unit_mechanisms_linux_test.go +217 -0
  195. package/dist/templates/native-go/backend/internal/helper/unit_padding_linux_test.go +178 -0
  196. package/dist/templates/native-go/backend/internal/helper/unit_query_linux.go +111 -0
  197. package/dist/templates/native-go/backend/internal/helper/unit_reload_linux_test.go +372 -0
  198. package/dist/templates/native-go/backend/internal/helper/unit_reload_sequence_linux_test.go +232 -0
  199. package/dist/templates/native-go/backend/internal/helper/write.go +77 -0
  200. package/dist/templates/native-go/backend/internal/helper/write_admission.go +260 -0
  201. package/dist/templates/native-go/backend/internal/helper/write_admission_test.go +135 -0
  202. package/dist/templates/native-go/backend/internal/helper/write_cohort_linux_test.go +218 -0
  203. package/dist/templates/native-go/backend/internal/helper/write_files_linux.go +202 -0
  204. package/dist/templates/native-go/backend/internal/helper/write_files_linux_test.go +199 -0
  205. package/dist/templates/native-go/backend/internal/helper/write_intent_linux.go +116 -0
  206. package/dist/templates/native-go/backend/internal/helper/write_intent_linux_test.go +74 -0
  207. package/dist/templates/native-go/backend/internal/helper/write_operation_linux.go +245 -0
  208. package/dist/templates/native-go/backend/internal/helper/write_test.go +53 -0
  209. package/dist/templates/native-go/ui/app.js +8 -1
  210. package/dist/templates/native-go-better-auth/node/build.mjs +2 -0
  211. package/dist/templates/native-go-vue/README.md +115 -1
  212. package/dist/templates/native-go-vue/frontend/DESIGN.md +1 -1
  213. package/dist/templates/native-go-vue/frontend/package-lock.json +132 -229
  214. package/dist/templates/native-go-vue/frontend/package.json +1 -1
  215. package/dist/templates/native-go-vue/frontend/src/App.vue +33 -6
  216. package/dist/templates/native-go-vue/frontend/src/context.ts +41 -2
  217. package/dist/templates/native-go-vue/frontend/src/main.ts +4 -1
  218. package/dist/templates/native-go-vue/frontend/src/nas/NasGrantSettings.vue +74 -0
  219. package/dist/templates/native-go-vue/frontend/src/nas/NasPathPicker.vue +106 -0
  220. package/dist/templates/native-go-vue/frontend/src/nas/NasUnavailable.vue +20 -0
  221. package/dist/templates/native-go-vue/frontend/src/nas/i18n/de.json +74 -0
  222. package/dist/templates/native-go-vue/frontend/src/nas/i18n/en.json +74 -0
  223. package/dist/templates/native-go-vue/frontend/src/nas/i18n/es.json +74 -0
  224. package/dist/templates/native-go-vue/frontend/src/nas/i18n/fr.json +74 -0
  225. package/dist/templates/native-go-vue/frontend/src/nas/i18n/it.json +74 -0
  226. package/dist/templates/native-go-vue/frontend/src/nas/i18n/ja.json +74 -0
  227. package/dist/templates/native-go-vue/frontend/src/nas/i18n/ko.json +74 -0
  228. package/dist/templates/native-go-vue/frontend/src/nas/i18n/zh-CN.json +74 -0
  229. package/dist/templates/native-go-vue/frontend/src/nas/i18n/zh-TW.json +74 -0
  230. package/dist/templates/native-go-vue/frontend/src/nas/i18n.ts +38 -0
  231. package/dist/templates/native-go-vue/frontend/src/nas/mock-provider.ts +119 -0
  232. package/dist/templates/native-go-vue/frontend/src/nas/provider.ts +59 -0
  233. package/dist/templates/native-go-vue/frontend/src/nas/use-request.ts +27 -0
  234. package/dist/templates/native-go-vue/frontend/src/style.css +17 -0
  235. package/dist/templates/native-go-vue/frontend/test/apps.test.ts +44 -2
  236. package/dist/templates/native-go-vue/frontend/test/nas-provider.test.ts +81 -0
  237. package/dist/templates/native-go-vue/frontend/test/nas-request.test.ts +21 -0
  238. package/dist/templates/native-go-vue/frontend/test/nas-ui.test.ts +261 -0
  239. package/dist/templates/native-go-vue/frontend/tsconfig.json +1 -1
  240. package/dist/templates/native-go-vue/frontend/vite.config.ts +6 -4
  241. package/package.json +3 -2
  242. package/templates/_daemon/fixture_linux_test.go +15 -0
  243. package/templates/_daemon/fixture_other_test.go +7 -0
  244. package/templates/_daemon/go.mod +3 -0
  245. package/templates/_daemon/main.go +608 -0
  246. package/templates/_daemon/main_test.go +242 -0
  247. package/templates/_daemon/process_linux.go +55 -0
  248. package/templates/_daemon/process_linux_test.go +161 -0
  249. package/templates/_daemon/process_other.go +14 -0
  250. package/templates/_daemon/testdata/child.go +41 -0
  251. package/templates/_shared/GO-LICENSE +27 -0
  252. package/templates/_shared/GO-PATENTS +22 -0
  253. package/templates/_shared/LICENSES/TEMPLATE.txt +21 -0
  254. package/templates/_shared/notice-overrides/index.json +14 -0
  255. package/templates/_shared/notice-overrides/utils-0.4.2-LICENSE +21 -0
  256. package/templates/_shared/notice-overrides/utils-0.5.0-LICENSE +21 -0
  257. package/templates/_shared/third-party-notices.mjs +51 -0
  258. package/templates/native-go/README.md +57 -1
  259. package/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +59 -0
  260. package/templates/native-go/backend/cmd/dsm-readonly-probe/main_linux.go +46 -0
  261. package/templates/native-go/backend/go.mod +4 -0
  262. package/templates/native-go/backend/go.sum +4 -0
  263. package/templates/native-go/backend/internal/api/binary.go +154 -0
  264. package/templates/native-go/backend/internal/api/binary_test.go +165 -0
  265. package/templates/native-go/backend/internal/api/registry.go +14 -4
  266. package/templates/native-go/backend/internal/api/server.go +4 -0
  267. package/templates/native-go/backend/internal/app/nas_cgi_artifact_test.go +121 -0
  268. package/templates/native-go/backend/internal/app/nas_refusal_test.go +46 -0
  269. package/templates/native-go/backend/internal/app/routes.go +11 -0
  270. package/templates/native-go/backend/internal/app/routes_test.go +10 -5
  271. package/templates/native-go/backend/internal/dsmprobe/collector_linux.go +335 -0
  272. package/templates/native-go/backend/internal/dsmprobe/collector_linux_test.go +41 -0
  273. package/templates/native-go/backend/internal/dsmprobe/protocol.go +179 -0
  274. package/templates/native-go/backend/internal/dsmprobe/protocol_test.go +29 -0
  275. package/templates/native-go/backend/internal/helper/cohort.go +393 -0
  276. package/templates/native-go/backend/internal/helper/cohort_publication.go +18 -0
  277. package/templates/native-go/backend/internal/helper/cohort_publication_test.go +105 -0
  278. package/templates/native-go/backend/internal/helper/cohort_test.go +372 -0
  279. package/templates/native-go/backend/internal/helper/control.go +226 -21
  280. package/templates/native-go/backend/internal/helper/control_test.go +10 -2
  281. package/templates/native-go/backend/internal/helper/data_contract.go +242 -0
  282. package/templates/native-go/backend/internal/helper/data_contract_test.go +51 -0
  283. package/templates/native-go/backend/internal/helper/data_decode.go +184 -0
  284. package/templates/native-go/backend/internal/helper/data_decode_pointer_test.go +30 -0
  285. package/templates/native-go/backend/internal/helper/data_protocol.go +416 -0
  286. package/templates/native-go/backend/internal/helper/data_protocol_test.go +449 -0
  287. package/templates/native-go/backend/internal/helper/dsm_acl_linux.go +139 -0
  288. package/templates/native-go/backend/internal/helper/dsm_acl_linux_test.go +121 -0
  289. package/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux.go +95 -0
  290. package/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux_test.go +56 -0
  291. package/templates/native-go/backend/internal/helper/dsm_bridge_linux.go +144 -0
  292. package/templates/native-go/backend/internal/helper/dsm_bridge_linux_test.go +89 -0
  293. package/templates/native-go/backend/internal/helper/dsm_home_linux.go +107 -0
  294. package/templates/native-go/backend/internal/helper/dsm_home_linux_test.go +82 -0
  295. package/templates/native-go/backend/internal/helper/dsm_probe_transport_linux.go +151 -0
  296. package/templates/native-go/backend/internal/helper/dsm_probe_transport_linux_test.go +66 -0
  297. package/templates/native-go/backend/internal/helper/grant_authority.go +516 -0
  298. package/templates/native-go/backend/internal/helper/grant_authority_contract.go +88 -0
  299. package/templates/native-go/backend/internal/helper/grant_authority_test.go +510 -0
  300. package/templates/native-go/backend/internal/helper/grant_cohort.go +389 -0
  301. package/templates/native-go/backend/internal/helper/grant_cohort_test.go +239 -0
  302. package/templates/native-go/backend/internal/helper/grant_delivery.go +49 -0
  303. package/templates/native-go/backend/internal/helper/grant_delivery_methods.go +273 -0
  304. package/templates/native-go/backend/internal/helper/grant_delivery_test.go +322 -0
  305. package/templates/native-go/backend/internal/helper/grant_operation_contract.go +47 -0
  306. package/templates/native-go/backend/internal/helper/grant_readonly_test.go +180 -0
  307. package/templates/native-go/backend/internal/helper/grant_repository_linux.go +415 -0
  308. package/templates/native-go/backend/internal/helper/grant_repository_linux_test.go +468 -0
  309. package/templates/native-go/backend/internal/helper/grant_rpc.go +147 -0
  310. package/templates/native-go/backend/internal/helper/grant_rpc_test.go +51 -0
  311. package/templates/native-go/backend/internal/helper/grant_snapshot.go +75 -0
  312. package/templates/native-go/backend/internal/helper/grant_supervisor_linux.go +134 -0
  313. package/templates/native-go/backend/internal/helper/grant_supervisor_linux_test.go +254 -0
  314. package/templates/native-go/backend/internal/helper/lease.go +112 -0
  315. package/templates/native-go/backend/internal/helper/lease_linux.go +44 -0
  316. package/templates/native-go/backend/internal/helper/lease_other.go +8 -0
  317. package/templates/native-go/backend/internal/helper/lifecycle.go +234 -0
  318. package/templates/native-go/backend/internal/helper/lifecycle_test.go +473 -0
  319. package/templates/native-go/backend/internal/helper/managed_pilot.go +284 -0
  320. package/templates/native-go/backend/internal/helper/managed_pilot_repository_linux.go +74 -0
  321. package/templates/native-go/backend/internal/helper/managed_pilot_repository_linux_test.go +40 -0
  322. package/templates/native-go/backend/internal/helper/managed_pilot_test.go +210 -0
  323. package/templates/native-go/backend/internal/helper/nas_shipped_refusal_linux_test.go +97 -0
  324. package/templates/native-go/backend/internal/helper/native_discovery.go +79 -0
  325. package/templates/native-go/backend/internal/helper/native_identity.go +89 -0
  326. package/templates/native-go/backend/internal/helper/native_provider.go +159 -0
  327. package/templates/native-go/backend/internal/helper/native_provider_test.go +421 -0
  328. package/templates/native-go/backend/internal/helper/observation.go +204 -0
  329. package/templates/native-go/backend/internal/helper/observation_health_test.go +115 -0
  330. package/templates/native-go/backend/internal/helper/observation_reload_budget_test.go +117 -0
  331. package/templates/native-go/backend/internal/helper/observation_test.go +196 -0
  332. package/templates/native-go/backend/internal/helper/observer_diagnostic.go +109 -0
  333. package/templates/native-go/backend/internal/helper/observer_diagnostic_linux.go +76 -0
  334. package/templates/native-go/backend/internal/helper/observer_diagnostic_linux_test.go +124 -0
  335. package/templates/native-go/backend/internal/helper/observer_diagnostic_test.go +98 -0
  336. package/templates/native-go/backend/internal/helper/operation_bootstrap_linux.go +193 -0
  337. package/templates/native-go/backend/internal/helper/operation_credentials_linux.go +56 -0
  338. package/templates/native-go/backend/internal/helper/operation_linux.go +480 -0
  339. package/templates/native-go/backend/internal/helper/operation_linux_test.go +528 -0
  340. package/templates/native-go/backend/internal/helper/process_linux.go +11 -1
  341. package/templates/native-go/backend/internal/helper/publication_test.go +178 -0
  342. package/templates/native-go/backend/internal/helper/read_stream_cohort_linux_test.go +156 -0
  343. package/templates/native-go/backend/internal/helper/read_transfer.go +40 -0
  344. package/templates/native-go/backend/internal/helper/read_transfer_linux.go +109 -0
  345. package/templates/native-go/backend/internal/helper/read_transfer_linux_test.go +118 -0
  346. package/templates/native-go/backend/internal/helper/read_transfer_test.go +177 -0
  347. package/templates/native-go/backend/internal/helper/readonly.go +105 -0
  348. package/templates/native-go/backend/internal/helper/readonly_admission.go +85 -0
  349. package/templates/native-go/backend/internal/helper/readonly_cohort_linux_test.go +253 -0
  350. package/templates/native-go/backend/internal/helper/readonly_linux_test.go +378 -0
  351. package/templates/native-go/backend/internal/helper/readonly_mount_linux.go +65 -0
  352. package/templates/native-go/backend/internal/helper/readonly_mount_proxy_linux.go +113 -0
  353. package/templates/native-go/backend/internal/helper/readonly_operations_linux.go +168 -0
  354. package/templates/native-go/backend/internal/helper/readonly_resolver_linux.go +241 -0
  355. package/templates/native-go/backend/internal/helper/readonly_test.go +40 -0
  356. package/templates/native-go/backend/internal/helper/relaxed_identity.go +252 -0
  357. package/templates/native-go/backend/internal/helper/relaxed_identity_contract.go +105 -0
  358. package/templates/native-go/backend/internal/helper/relaxed_identity_test.go +406 -0
  359. package/templates/native-go/backend/internal/helper/relaxed_invalidation.go +200 -0
  360. package/templates/native-go/backend/internal/helper/repair.go +132 -0
  361. package/templates/native-go/backend/internal/helper/repair_test.go +271 -0
  362. package/templates/native-go/backend/internal/helper/s1r_actor_acl_linux_test.go +303 -0
  363. package/templates/native-go/backend/internal/helper/s1r_actor_fixture_linux_test.go +184 -0
  364. package/templates/native-go/backend/internal/helper/s1r_actor_races_linux_test.go +231 -0
  365. package/templates/native-go/backend/internal/helper/s1r_fixture_contract_linux_test.go +18 -0
  366. package/templates/native-go/backend/internal/helper/server_linux.go +44 -3
  367. package/templates/native-go/backend/internal/helper/status.go +74 -11
  368. package/templates/native-go/backend/internal/helper/status_test.go +83 -0
  369. package/templates/native-go/backend/internal/helper/supervision.go +28 -5
  370. package/templates/native-go/backend/internal/helper/supervisor_frame.go +76 -0
  371. package/templates/native-go/backend/internal/helper/supervisor_frame_linux_test.go +69 -0
  372. package/templates/native-go/backend/internal/helper/supervisor_frame_test.go +107 -0
  373. package/templates/native-go/backend/internal/helper/supervisor_linux.go +187 -16
  374. package/templates/native-go/backend/internal/helper/supervisor_linux_test.go +618 -7
  375. package/templates/native-go/backend/internal/helper/supervisor_socket_eof_test.go +74 -0
  376. package/templates/native-go/backend/internal/helper/supervisor_socket_test.go +45 -0
  377. package/templates/native-go/backend/internal/helper/testdata/protocol2/create.json +23 -0
  378. package/templates/native-go/backend/internal/helper/testdata/protocol2/frames.json +67 -0
  379. package/templates/native-go/backend/internal/helper/testdata/protocol2/grant-store.json +52 -0
  380. package/templates/native-go/backend/internal/helper/testdata/protocol2/intent.json +20 -0
  381. package/templates/native-go/backend/internal/helper/testdata/protocol2/list.json +20 -0
  382. package/templates/native-go/backend/internal/helper/testdata/protocol2/publish.json +20 -0
  383. package/templates/native-go/backend/internal/helper/testdata/protocol2/read.json +22 -0
  384. package/templates/native-go/backend/internal/helper/testdata/protocol2/stat.json +22 -0
  385. package/templates/native-go/backend/internal/helper/testdata/protocol2/write-stream.json +22 -0
  386. package/templates/native-go/backend/internal/helper/unit_connection.go +75 -0
  387. package/templates/native-go/backend/internal/helper/unit_connection_linux_test.go +135 -0
  388. package/templates/native-go/backend/internal/helper/unit_connection_test.go +133 -0
  389. package/templates/native-go/backend/internal/helper/unit_frame_test.go +32 -0
  390. package/templates/native-go/backend/internal/helper/unit_linux.go +364 -0
  391. package/templates/native-go/backend/internal/helper/unit_linux_test.go +46 -0
  392. package/templates/native-go/backend/internal/helper/unit_mechanisms_linux_test.go +217 -0
  393. package/templates/native-go/backend/internal/helper/unit_padding_linux_test.go +178 -0
  394. package/templates/native-go/backend/internal/helper/unit_query_linux.go +111 -0
  395. package/templates/native-go/backend/internal/helper/unit_reload_linux_test.go +372 -0
  396. package/templates/native-go/backend/internal/helper/unit_reload_sequence_linux_test.go +232 -0
  397. package/templates/native-go/backend/internal/helper/write.go +77 -0
  398. package/templates/native-go/backend/internal/helper/write_admission.go +260 -0
  399. package/templates/native-go/backend/internal/helper/write_admission_test.go +135 -0
  400. package/templates/native-go/backend/internal/helper/write_cohort_linux_test.go +218 -0
  401. package/templates/native-go/backend/internal/helper/write_files_linux.go +202 -0
  402. package/templates/native-go/backend/internal/helper/write_files_linux_test.go +199 -0
  403. package/templates/native-go/backend/internal/helper/write_intent_linux.go +116 -0
  404. package/templates/native-go/backend/internal/helper/write_intent_linux_test.go +74 -0
  405. package/templates/native-go/backend/internal/helper/write_operation_linux.go +245 -0
  406. package/templates/native-go/backend/internal/helper/write_test.go +53 -0
  407. package/templates/native-go/ui/app.js +8 -1
  408. package/templates/native-go-better-auth/node/build.mjs +2 -0
  409. package/templates/native-go-vue/README.md +115 -1
  410. package/templates/native-go-vue/frontend/DESIGN.md +1 -1
  411. package/templates/native-go-vue/frontend/package-lock.json +132 -229
  412. package/templates/native-go-vue/frontend/package.json +1 -1
  413. package/templates/native-go-vue/frontend/src/App.vue +33 -6
  414. package/templates/native-go-vue/frontend/src/context.ts +41 -2
  415. package/templates/native-go-vue/frontend/src/main.ts +4 -1
  416. package/templates/native-go-vue/frontend/src/nas/NasGrantSettings.vue +74 -0
  417. package/templates/native-go-vue/frontend/src/nas/NasPathPicker.vue +106 -0
  418. package/templates/native-go-vue/frontend/src/nas/NasUnavailable.vue +20 -0
  419. package/templates/native-go-vue/frontend/src/nas/i18n/de.json +74 -0
  420. package/templates/native-go-vue/frontend/src/nas/i18n/en.json +74 -0
  421. package/templates/native-go-vue/frontend/src/nas/i18n/es.json +74 -0
  422. package/templates/native-go-vue/frontend/src/nas/i18n/fr.json +74 -0
  423. package/templates/native-go-vue/frontend/src/nas/i18n/it.json +74 -0
  424. package/templates/native-go-vue/frontend/src/nas/i18n/ja.json +74 -0
  425. package/templates/native-go-vue/frontend/src/nas/i18n/ko.json +74 -0
  426. package/templates/native-go-vue/frontend/src/nas/i18n/zh-CN.json +74 -0
  427. package/templates/native-go-vue/frontend/src/nas/i18n/zh-TW.json +74 -0
  428. package/templates/native-go-vue/frontend/src/nas/i18n.ts +38 -0
  429. package/templates/native-go-vue/frontend/src/nas/mock-provider.ts +119 -0
  430. package/templates/native-go-vue/frontend/src/nas/provider.ts +59 -0
  431. package/templates/native-go-vue/frontend/src/nas/use-request.ts +27 -0
  432. package/templates/native-go-vue/frontend/src/style.css +17 -0
  433. package/templates/native-go-vue/frontend/test/apps.test.ts +44 -2
  434. package/templates/native-go-vue/frontend/test/nas-provider.test.ts +81 -0
  435. package/templates/native-go-vue/frontend/test/nas-request.test.ts +21 -0
  436. package/templates/native-go-vue/frontend/test/nas-ui.test.ts +261 -0
  437. package/templates/native-go-vue/frontend/tsconfig.json +1 -1
  438. 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 action == "recover" && (err != nil || !r.Enabled) {
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
- if err != nil {
152
- r = Record{Inventory: c.Expected}
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
- if action == "disable" {
155
- r.Enabled = false
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
- // Publish the durable gate first. A crashed/failed disable still refuses
158
- // requests and exposes required cleanup; never report cleanup as successful.
159
- r.Residual = true
160
- if err := writeProtected(c.StateDir, "approval.json", r); err != nil {
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 err := c.teardown(); err != nil {
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 action == "enable" || action == "recover" {
167
- r = Record{Inventory: c.Expected, Enabled: true, Residual: true}
168
- if err := writeProtected(c.StateDir, "approval.json", r); err != nil {
169
- return err
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
- r.Residual = false
176
- return writeProtected(c.StateDir, "approval.json", r)
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 err == nil {
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
+ }