@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
@@ -0,0 +1,179 @@
1
+ // Package dsmprobe defines a bounded, non-secret observation protocol. It is
2
+ // private to the helper/probe; neither browser nor package RPC exposes it.
3
+ package dsmprobe
4
+
5
+ import (
6
+ "bytes"
7
+ "encoding/hex"
8
+ "encoding/json"
9
+ "errors"
10
+ "io"
11
+ )
12
+
13
+ const MaxRequestBytes = 4096
14
+ const MaxResponseBytes = 32768
15
+ const Protocol = 1
16
+
17
+ var ErrInvalid = errors.New("invalid probe request")
18
+
19
+ type Request struct {
20
+ Version int `json:"version"`
21
+ Nonce string `json:"nonce"`
22
+ Kind string `json:"kind"`
23
+ Username string `json:"username"`
24
+ UID uint32 `json:"uid"`
25
+ GID uint32 `json:"gid"`
26
+ Groups []uint32 `json:"groups"`
27
+ ExpectedRuntime string `json:"expectedRuntime"`
28
+ }
29
+ type LibraryEvidence struct {
30
+ Name string `json:"name"`
31
+ SHA256 string `json:"sha256"`
32
+ Exports []string `json:"exports"`
33
+ }
34
+ type Runtime struct {
35
+ VersionDigest string `json:"versionDigest"`
36
+ Architecture string `json:"architecture"`
37
+ DSMBuild string `json:"dsmBuild"`
38
+ Kernel string `json:"kernel"`
39
+ BootRef string `json:"bootRef"`
40
+ Fingerprint string `json:"fingerprint"`
41
+ Libraries []LibraryEvidence `json:"libraries"`
42
+ ACLModule bool `json:"aclModule"`
43
+ }
44
+ type Identity struct {
45
+ UID uint32 `json:"uid"`
46
+ GID uint32 `json:"gid"`
47
+ Groups []uint32 `json:"groups"`
48
+ NoNewPrivs bool `json:"noNewPrivs"`
49
+ NonDumpable bool `json:"nonDumpable"`
50
+ }
51
+ type Account struct {
52
+ Username string `json:"username"`
53
+ UID uint32 `json:"uid"`
54
+ GID uint32 `json:"gid"`
55
+ Groups []uint32 `json:"groups"`
56
+ Home string `json:"home"`
57
+ NativeKnown bool `json:"nativeKnown"`
58
+ Local bool `json:"local"`
59
+ Enabled bool `json:"enabled"`
60
+ GroupsKnown bool `json:"groupsKnown"`
61
+ }
62
+ type Home struct {
63
+ HomesPath string `json:"homesPath"`
64
+ StatusKnown bool `json:"statusKnown"`
65
+ Enabled bool `json:"enabled"`
66
+ Existing bool `json:"existing"`
67
+ Device uint64 `json:"device"`
68
+ Inode uint64 `json:"inode"`
69
+ Owner uint32 `json:"owner"`
70
+ }
71
+ type Share struct {
72
+ Name string `json:"name"`
73
+ Path string `json:"path"`
74
+ NativeKnown bool `json:"nativeKnown"`
75
+ Available bool `json:"available"`
76
+ VolumeKnown bool `json:"volumeKnown"`
77
+ PermissionKnown bool `json:"permissionKnown"`
78
+ ReadAllowed bool `json:"readAllowed"`
79
+ }
80
+ type ACLSample struct {
81
+ Attempted bool `json:"attempted"`
82
+ FilesystemSupport int64 `json:"filesystemSupport"`
83
+ ObjectSupport int64 `json:"objectSupport"`
84
+ SupportErrno []uint32 `json:"supportErrno"`
85
+ CheckResult int64 `json:"checkResult"`
86
+ CheckErrno uint32 `json:"checkErrno"`
87
+ Mask uint32 `json:"mask"`
88
+ Certified bool `json:"certified"`
89
+ }
90
+ type Response struct {
91
+ Version int `json:"version"`
92
+ Nonce string `json:"nonce"`
93
+ Status string `json:"status"`
94
+ Runtime Runtime `json:"runtime"`
95
+ Identity Identity `json:"identity"`
96
+ Account Account `json:"account"`
97
+ Home Home `json:"home"`
98
+ Share Share `json:"share"`
99
+ ACL ACLSample `json:"acl"`
100
+ }
101
+
102
+ func DigestValid(s string) bool {
103
+ b, e := hex.DecodeString(s)
104
+ return e == nil && len(b) == 32 && len(s) == 64
105
+ }
106
+ func (r Request) Validate() error {
107
+ if r.Version != Protocol || !DigestValid(r.Nonce) || r.Groups == nil || len(r.Groups) > 512 {
108
+ return ErrInvalid
109
+ }
110
+ for i, g := range r.Groups {
111
+ if i > 0 && r.Groups[i-1] >= g {
112
+ return ErrInvalid
113
+ }
114
+ }
115
+ if r.Kind == "runtime" {
116
+ if r.Username != "" || r.ExpectedRuntime != "" {
117
+ return ErrInvalid
118
+ }
119
+ return nil
120
+ }
121
+ if (r.Username != "normal3" && r.Username != "admin") || r.UID == 0 {
122
+ return ErrInvalid
123
+ }
124
+ switch r.Kind {
125
+ case "metadata":
126
+ if r.ExpectedRuntime != "" {
127
+ return ErrInvalid
128
+ }
129
+ case "acl":
130
+ if !DigestValid(r.ExpectedRuntime) {
131
+ return ErrInvalid
132
+ }
133
+ default:
134
+ return ErrInvalid
135
+ }
136
+ return nil
137
+ }
138
+ func DecodeRequest(b []byte) (Request, error) {
139
+ var out Request
140
+ if len(b) > MaxRequestBytes {
141
+ return out, ErrInvalid
142
+ }
143
+ d := json.NewDecoder(bytes.NewReader(b))
144
+ token, e := d.Token()
145
+ if e != nil || token != json.Delim('{') {
146
+ return out, ErrInvalid
147
+ }
148
+ allowed := map[string]bool{"version": true, "nonce": true, "kind": true, "username": true, "uid": true, "gid": true, "groups": true, "expectedRuntime": true}
149
+ raw := map[string]json.RawMessage{}
150
+ for d.More() {
151
+ t, e := d.Token()
152
+ if e != nil {
153
+ return out, ErrInvalid
154
+ }
155
+ k, ok := t.(string)
156
+ if !ok || !allowed[k] {
157
+ return out, ErrInvalid
158
+ }
159
+ if _, ok := raw[k]; ok {
160
+ return out, ErrInvalid
161
+ }
162
+ var v json.RawMessage
163
+ if d.Decode(&v) != nil {
164
+ return out, ErrInvalid
165
+ }
166
+ raw[k] = v
167
+ }
168
+ if t, e := d.Token(); e != nil || t != json.Delim('}') {
169
+ return out, ErrInvalid
170
+ }
171
+ if _, e = d.Token(); e != io.EOF {
172
+ return out, ErrInvalid
173
+ }
174
+ data, _ := json.Marshal(raw)
175
+ if json.Unmarshal(data, &out) != nil {
176
+ return Request{}, ErrInvalid
177
+ }
178
+ return out, out.Validate()
179
+ }
@@ -0,0 +1,29 @@
1
+ package dsmprobe
2
+
3
+ import (
4
+ "strings"
5
+ "testing"
6
+ )
7
+
8
+ func TestRequestRejectsUnknownDuplicateAndOversized(t *testing.T) {
9
+ for _, s := range []string{`{"version":1,"nonce":"` + strings.Repeat("a", 64) + `","username":"normal3","uid":1217,"gid":100,"groups":[100],"kind":"metadata","kind":"acl"}`, `{"version":1,"nonce":"` + strings.Repeat("a", 64) + `","username":"normal3","uid":1217,"gid":100,"groups":[100],"kind":"metadata","allow":true}`, strings.Repeat(" ", MaxRequestBytes+1)} {
10
+ if _, e := DecodeRequest([]byte(s)); e == nil {
11
+ t.Fatal("invalid request accepted")
12
+ }
13
+ }
14
+ }
15
+ func TestRequestRestrictsFixtureAndNeverCarriesSession(t *testing.T) {
16
+ r := Request{Version: 1, Nonce: strings.Repeat("a", 64), Kind: "metadata", Username: "normal3", UID: 1217, GID: 100, Groups: []uint32{100}}
17
+ if r.Validate() != nil {
18
+ t.Fatal("valid fixture refused")
19
+ }
20
+ r.Username = "normal1"
21
+ if r.Validate() == nil {
22
+ t.Fatal("reserved account accepted")
23
+ }
24
+ r.Username = "normal3"
25
+ r.Kind = "acl"
26
+ if r.Validate() == nil {
27
+ t.Fatal("ACL without runtime fingerprint accepted")
28
+ }
29
+ }
@@ -0,0 +1,393 @@
1
+ package helper
2
+
3
+ import (
4
+ "context"
5
+ "syscall"
6
+ "time"
7
+ )
8
+
9
+ // Staged root-side API. Only the supervisor owner loop calls these methods;
10
+ // native adapters, grant/ACL authority and a public data transport are NOT installed.
11
+ // Operation children are fixed synthetic operations, never caller executables.
12
+ type operationBinding struct {
13
+ Inventory Inventory `json:"inventory"`
14
+ Epoch string `json:"epoch"`
15
+ OperationID string `json:"operationId"`
16
+ Nonce string `json:"nonce"`
17
+ GrantID string `json:"grantId"`
18
+ GrantRevision uint64 `json:"grantRevision"`
19
+ }
20
+ type operationPeer struct {
21
+ PID int
22
+ UID uint32
23
+ }
24
+ type operationProcess interface {
25
+ supervisedChild
26
+ chunk(uint32) error
27
+ idle() (bool, error)
28
+ stopRelay()
29
+ relayStopped() bool
30
+ }
31
+ type cohortOperation struct {
32
+ binding operationBinding
33
+ actor NativeActor
34
+ process operationProcess
35
+ bytes uint64
36
+ canceled bool
37
+ admittedAt time.Time
38
+ lastActivity time.Time
39
+ maxBytes uint64
40
+ segments []string
41
+ commitReserved bool
42
+ writeWork *writeWork
43
+ work *readOnlyWork
44
+ root readOnlyRootWitness
45
+ }
46
+ type CohortCompletion struct {
47
+ Started uint64 `json:"started"`
48
+ Reaped uint64 `json:"reaped"`
49
+ WriteIntents uint64 `json:"writeIntents,omitempty"`
50
+ WriteEffectsUnknown bool `json:"writeEffectsUnknown,omitempty"`
51
+ RelaysStopped bool `json:"relaysStopped"`
52
+ }
53
+
54
+ func (q CohortCompletion) valid() bool {
55
+ return q.Started > 0 && q.Started <= MaxReplayEntries && q.Started == q.Reaped && q.RelaysStopped && q.WriteIntents <= q.Started && (!q.WriteEffectsUnknown || q.WriteIntents > 0)
56
+ }
57
+
58
+ type operationCohort struct {
59
+ inventory Inventory
60
+ epoch string
61
+ helperPID int
62
+ helperLive func() bool
63
+ gate *admission
64
+ now func() time.Time
65
+ startChild func(NativeActor, operationBinding) (operationProcess, error)
66
+ operations map[string]*cohortOperation
67
+ seen map[string]bool
68
+ started, reaped uint64
69
+ receipts map[string]cohortReceipt
70
+ fenced bool
71
+ }
72
+
73
+ func newOperationCohort(i Inventory, epoch string, pid int, g *admission, live func() bool) *operationCohort {
74
+ return &operationCohort{inventory: i, epoch: epoch, helperPID: pid, gate: g, helperLive: live, now: time.Now, operations: map[string]*cohortOperation{}, seen: map[string]bool{}, receipts: map[string]cohortReceipt{}}
75
+ }
76
+ func (c *operationCohort) peerAllowed(p operationPeer) bool {
77
+ return c.helperPID > 1 && p.PID == c.helperPID && p.UID == 0 && c.helperLive != nil && c.helperLive()
78
+ }
79
+ func (c *operationCohort) bound(b operationBinding) bool {
80
+ return c.inventory.Protocol == DataProtocol && c.inventory.Valid() && b.Inventory == c.inventory && b.Epoch == c.epoch && digestPattern.MatchString(c.epoch) && digestPattern.MatchString(b.OperationID) && digestPattern.MatchString(b.Nonce) && digestPattern.MatchString(b.GrantID) && b.GrantRevision > 0
81
+ }
82
+
83
+ // Called with the observer's mutex held, including child/lease admission.
84
+ func (c *operationCohort) allowed() bool {
85
+ if c.now().Before(c.gate.seen) {
86
+ c.gate.fenceLocked("observation-expired")
87
+ }
88
+ return !c.fenced && c.gate.allowLocked(c.now())
89
+ }
90
+ func (c *operationCohort) start(ctx context.Context, peer operationPeer, p *NativeProvider, carriers SessionCarriers, old NativeActor, b operationBinding) Code {
91
+ if c.fenced {
92
+ return ErrFenced
93
+ }
94
+ if !c.peerAllowed(peer) {
95
+ return ErrDenied
96
+ }
97
+ if !c.bound(b) {
98
+ return ErrInvalid
99
+ }
100
+ if !old.valid || old.UID() == 0 || old.GID() == 0 || old.account.Groups == nil {
101
+ return ErrDenied
102
+ }
103
+ actor, code := p.Revalidate(ctx, carriers, old)
104
+ if code != "" {
105
+ return code
106
+ }
107
+ c.gate.mu.Lock()
108
+ op, code := c.reserveLocked(actor, b)
109
+ c.gate.mu.Unlock()
110
+ if code != "" {
111
+ return code
112
+ }
113
+ return c.launchReserved(op)
114
+ }
115
+
116
+ // Only registers a slot and replay history. No child/bootstrap/I/O under locks.
117
+ func (c *operationCohort) reserveLocked(actor NativeActor, b operationBinding) (*cohortOperation, Code) {
118
+ if !c.allowed() {
119
+ return nil, ErrFenced
120
+ }
121
+ if !c.bound(b) || !actor.valid || actor.UID() == 0 || actor.GID() == 0 || actor.account.Groups == nil {
122
+ return nil, ErrDenied
123
+ }
124
+ if !nativeFresh(actor.account.CheckedAt, c.now()) {
125
+ return nil, ErrStale
126
+ }
127
+ if c.seen["op:"+b.OperationID] || c.seen["nonce:"+b.Nonce] {
128
+ return nil, ErrReplay
129
+ }
130
+ count := 0
131
+ for _, op := range c.operations {
132
+ if op.actor.Principal().SubjectRef == actor.Principal().SubjectRef {
133
+ count++
134
+ }
135
+ }
136
+ if len(c.operations) >= MaxPackageOperations || count >= MaxSubjectOperations || len(c.seen) >= 2*MaxReplayEntries {
137
+ return nil, ErrBusy
138
+ }
139
+ if c.startChild == nil {
140
+ return nil, ErrUnavailable
141
+ }
142
+ op := &cohortOperation{binding: b, actor: actor, admittedAt: c.now(), maxBytes: MaxBoundedBytes}
143
+ c.operations[b.OperationID] = op
144
+ c.seen["op:"+b.OperationID] = true
145
+ c.seen["nonce:"+b.Nonce] = true
146
+ return op, ""
147
+ }
148
+ func (c *operationCohort) launchReserved(op *cohortOperation) Code {
149
+ c.gate.mu.Lock()
150
+ exists := c.operations[op.binding.OperationID] == op && !op.canceled && c.allowed()
151
+ if !exists {
152
+ delete(c.operations, op.binding.OperationID)
153
+ }
154
+ c.gate.mu.Unlock()
155
+ if !exists {
156
+ return ErrFenced
157
+ }
158
+ child, err := c.startChild(op.actor, op.binding)
159
+ c.gate.mu.Lock()
160
+ defer c.gate.mu.Unlock()
161
+ if child == nil {
162
+ delete(c.operations, op.binding.OperationID)
163
+ return ErrUnavailable
164
+ }
165
+ c.started++
166
+ op.process = child
167
+ if !c.allowed() {
168
+ op.canceled = true
169
+ child.stopRelay()
170
+ return ErrFenced
171
+ }
172
+ if err != nil {
173
+ op.canceled = true
174
+ child.stopRelay()
175
+ return ErrCleanupRequired
176
+ }
177
+ return ""
178
+ }
179
+ func (c *operationCohort) chunk(ctx context.Context, peer operationPeer, p *NativeProvider, carriers SessionCarriers, b operationBinding, n uint32) Code {
180
+ if c.fenced || !c.gate.allow(c.now()) {
181
+ return ErrFenced
182
+ }
183
+ if !c.peerAllowed(peer) {
184
+ return ErrDenied
185
+ }
186
+ op := c.operations[b.OperationID]
187
+ if op == nil || op.binding != b {
188
+ return ErrDenied
189
+ }
190
+ if op.canceled {
191
+ return ErrCanceled
192
+ }
193
+ if op.expired(c.now()) {
194
+ op.canceled = true
195
+ op.process.stopRelay()
196
+ return ErrTimeout
197
+ }
198
+ actor, code := p.Revalidate(ctx, carriers, op.actor)
199
+ if code != "" {
200
+ op.canceled = true
201
+ op.process.stopRelay()
202
+ return code
203
+ }
204
+ c.gate.mu.Lock()
205
+ code = c.reserveChunkLocked(op, actor, n)
206
+ c.gate.mu.Unlock()
207
+ if code != "" {
208
+ return code
209
+ }
210
+ return c.deliverChunk(op, n)
211
+ }
212
+ func (c *operationCohort) reserveChunkLocked(op *cohortOperation, actor NativeActor, n uint32) Code {
213
+ if !c.allowed() {
214
+ return ErrFenced
215
+ }
216
+ if op.process == nil || op.canceled {
217
+ return ErrCanceled
218
+ }
219
+ if op.expired(c.now()) {
220
+ op.canceled = true
221
+ op.process.stopRelay()
222
+ return ErrTimeout
223
+ }
224
+ if !nativeFresh(actor.account.CheckedAt, c.now()) {
225
+ op.canceled = true
226
+ op.process.stopRelay()
227
+ return ErrStale
228
+ }
229
+ ceiling := op.maxBytes
230
+ if ceiling == 0 {
231
+ ceiling = MaxBoundedBytes
232
+ }
233
+ if n == 0 || n > MaxChunkBytes || uint64(n) > ceiling || op.bytes > ceiling-uint64(n) {
234
+ return ErrLimit
235
+ }
236
+ idle, err := op.process.idle()
237
+ if err != nil {
238
+ op.canceled = true
239
+ op.process.stopRelay()
240
+ return ErrCleanupRequired
241
+ }
242
+ if !idle {
243
+ return ErrBusy
244
+ }
245
+ op.bytes += uint64(n)
246
+ op.actor = actor
247
+ op.lastActivity = c.now()
248
+ return ""
249
+ }
250
+ func (c *operationCohort) deliverChunk(op *cohortOperation, n uint32) Code {
251
+ if op.canceled {
252
+ return ErrCanceled
253
+ }
254
+ var err error
255
+ if p, ok := op.process.(interface {
256
+ chunkWithActor(uint32, NativeActor) error
257
+ }); ok {
258
+ err = p.chunkWithActor(n, op.actor)
259
+ } else {
260
+ err = op.process.chunk(n)
261
+ }
262
+ if err != nil {
263
+ op.canceled = true
264
+ op.process.stopRelay()
265
+ return ErrCleanupRequired
266
+ }
267
+ return ""
268
+ }
269
+ func (c *operationCohort) poll() error {
270
+ for id, op := range c.operations {
271
+ if op.process == nil {
272
+ if op.canceled {
273
+ delete(c.operations, id)
274
+ }
275
+ continue
276
+ }
277
+ if op.expired(c.now()) {
278
+ op.canceled = true
279
+ op.process.stopRelay()
280
+ }
281
+ if _, relayErr := op.process.idle(); relayErr != nil {
282
+ op.canceled = true
283
+ op.process.stopRelay()
284
+ }
285
+ done, err := op.process.exited()
286
+ if err != nil {
287
+ return err
288
+ }
289
+ if op.canceled && !done {
290
+ if err := op.process.signal(syscall.SIGKILL); err != nil {
291
+ return err
292
+ }
293
+ }
294
+ if done {
295
+ op.process.stopRelay()
296
+ if op.process.relayStopped() {
297
+ c.retire(id, op)
298
+ }
299
+ }
300
+ }
301
+ return nil
302
+ }
303
+ func (c *operationCohort) deny() {
304
+ c.fenced = true
305
+ for _, op := range c.operations {
306
+ op.canceled = true
307
+ if op.process != nil {
308
+ op.process.stopRelay()
309
+ }
310
+ }
311
+ }
312
+ func (c *operationCohort) drain(ctx context.Context, grace time.Duration) error {
313
+ c.deny()
314
+ return c.drainSelected(ctx, grace, func(*cohortOperation) bool { return true })
315
+ }
316
+
317
+ // S3 calls this after durable R; other grants keep running. This is only Q proof.
318
+ func (c *operationCohort) cancelGrant(ctx context.Context, id string, revision uint64) error {
319
+ return c.drainSelected(ctx, TerminateGrace, func(op *cohortOperation) bool {
320
+ return op.binding.GrantID == id && op.binding.GrantRevision <= revision
321
+ })
322
+ }
323
+ func (c *operationCohort) drainSelected(ctx context.Context, grace time.Duration, selected func(*cohortOperation) bool) error {
324
+ if err := ctx.Err(); err != nil {
325
+ return err
326
+ }
327
+ killed := map[string]bool{}
328
+ term := map[string]bool{}
329
+ escalate := time.Now().Add(grace)
330
+ for {
331
+ pending := false
332
+ for id, op := range c.operations {
333
+ if !selected(op) {
334
+ continue
335
+ }
336
+ op.canceled = true
337
+ if op.process == nil {
338
+ delete(c.operations, id)
339
+ continue
340
+ }
341
+ op.process.stopRelay()
342
+ done, err := op.process.exited()
343
+ if err != nil {
344
+ return err
345
+ }
346
+ if done {
347
+ if op.process.relayStopped() {
348
+ c.retire(id, op)
349
+ continue
350
+ }
351
+ } else if !term[id] {
352
+ if err := op.process.signal(syscall.SIGTERM); err != nil {
353
+ return err
354
+ }
355
+ term[id] = true
356
+ } else if !killed[id] && !time.Now().Before(escalate) {
357
+ if err := op.process.signal(syscall.SIGKILL); err != nil {
358
+ return err
359
+ }
360
+ killed[id] = true
361
+ }
362
+ pending = true
363
+ }
364
+ if !pending {
365
+ return nil
366
+ }
367
+ timer := time.NewTimer(time.Millisecond)
368
+ select {
369
+ case <-ctx.Done():
370
+ timer.Stop()
371
+ return ctx.Err()
372
+ case <-timer.C:
373
+ }
374
+ }
375
+ }
376
+ func (c *operationCohort) proof() (*CohortCompletion, error) {
377
+ if !c.fenced || len(c.operations) != 0 || c.started != c.reaped {
378
+ return nil, errTrust
379
+ }
380
+ if c.started == 0 {
381
+ return nil, nil
382
+ }
383
+ proof := &CohortCompletion{Started: c.started, Reaped: c.reaped, RelaysStopped: true}
384
+ for _, r := range c.receipts {
385
+ if r.write != nil {
386
+ proof.WriteIntents++
387
+ if r.write.unknown || r.write.code == ErrCommitUncertain {
388
+ proof.WriteEffectsUnknown = true
389
+ }
390
+ }
391
+ }
392
+ return proof, nil
393
+ }
@@ -0,0 +1,18 @@
1
+ package helper
2
+
3
+ import (
4
+ "context"
5
+ "errors"
6
+ )
7
+
8
+ // Match the controller's completion-publication handoff: only a busy lock may
9
+ // be retried, with the caller's finite budget. The transaction re-reads and
10
+ // validates authority after acquiring policy.lock. Expiry preserves refusal.
11
+ func retryCohortPolicy(ctx context.Context, commit func() error) error {
12
+ last := errBusy
13
+ _ = waitHealthy(ctx, func(context.Context) bool {
14
+ last = commit()
15
+ return !errors.Is(last, errBusy)
16
+ })
17
+ return last
18
+ }