@synopackageland/cli 0.3.10 → 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 (641) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +57 -9
  3. package/dist/bin.js +1 -2
  4. package/dist/build-spk/generator.d.ts +0 -3
  5. package/dist/build-spk/generator.js +138 -287
  6. package/dist/build-spk/native-lifecycle.js +0 -3
  7. package/dist/build-spk/native-payload.js +0 -1
  8. package/dist/build-spk/notices.d.ts +5 -0
  9. package/dist/build-spk/notices.js +60 -0
  10. package/dist/cli.js +178 -151
  11. package/dist/compose/analyze.d.ts +1 -2
  12. package/dist/compose/analyze.js +5 -48
  13. package/dist/contract/unsupported-types.d.ts +10 -0
  14. package/dist/contract/unsupported-types.js +49 -0
  15. package/dist/contract/validate.js +25 -2
  16. package/dist/contract/web-launch.js +0 -2
  17. package/dist/deploy/deploy.d.ts +1 -4
  18. package/dist/deploy/deploy.js +45 -156
  19. package/dist/deploy/homes-values.js +1 -1
  20. package/dist/deploy/plan.d.ts +18 -0
  21. package/dist/deploy/plan.js +54 -0
  22. package/dist/deploy/spk-version.d.ts +2 -14
  23. package/dist/deploy/spk-version.js +25 -111
  24. package/dist/dev.d.ts +1 -3
  25. package/dist/dev.js +14 -28
  26. package/dist/error-registry.js +830 -862
  27. package/dist/host/dsm-client.js +12 -272
  28. package/dist/host/dsm-port-profile.d.ts +0 -1
  29. package/dist/host/dsm-port-profile.js +0 -2
  30. package/dist/host/types.d.ts +1 -83
  31. package/dist/index.d.ts +0 -9
  32. package/dist/index.js +0 -6
  33. package/dist/info.d.ts +0 -1
  34. package/dist/info.js +3 -10
  35. package/dist/init.d.ts +15 -1
  36. package/dist/init.js +128 -12
  37. package/dist/log.js +2 -3
  38. package/dist/native/validate.js +0 -1
  39. package/dist/standalone/binary.d.ts +9 -0
  40. package/dist/standalone/binary.js +67 -0
  41. package/dist/standalone/build.d.ts +25 -0
  42. package/dist/standalone/build.js +110 -0
  43. package/dist/standalone/daemon.d.ts +23 -0
  44. package/dist/standalone/daemon.js +114 -0
  45. package/dist/standalone/dsm-window.d.ts +26 -0
  46. package/dist/standalone/dsm-window.js +291 -0
  47. package/dist/standalone/helper-inventory.d.ts +16 -0
  48. package/dist/standalone/helper-inventory.js +2 -0
  49. package/dist/standalone/helper.d.ts +21 -0
  50. package/dist/standalone/helper.js +105 -0
  51. package/dist/standalone/host-adapter.d.ts +5 -0
  52. package/dist/standalone/host-adapter.js +148 -0
  53. package/dist/standalone/host-platform.d.ts +13 -0
  54. package/dist/standalone/host-platform.js +42 -0
  55. package/dist/standalone/host-types.d.ts +49 -0
  56. package/dist/standalone/host-types.js +1 -0
  57. package/dist/standalone/i18n.d.ts +28 -0
  58. package/dist/standalone/i18n.js +161 -0
  59. package/dist/standalone/inspect-helper.d.ts +6 -0
  60. package/dist/standalone/inspect-helper.js +88 -0
  61. package/dist/standalone/inspect-spk.d.ts +23 -0
  62. package/dist/standalone/inspect-spk.js +209 -0
  63. package/dist/standalone/lifecycle-helper.d.ts +2 -0
  64. package/dist/standalone/lifecycle-helper.js +12 -0
  65. package/dist/standalone/lifecycle.d.ts +3 -0
  66. package/dist/standalone/lifecycle.js +53 -0
  67. package/dist/standalone/manifest.d.ts +73 -0
  68. package/dist/standalone/manifest.js +279 -0
  69. package/dist/standalone/reopen-events.d.ts +2 -0
  70. package/dist/standalone/reopen-events.js +28 -0
  71. package/dist/standalone/root-messages.d.ts +7 -0
  72. package/dist/standalone/root-messages.js +259 -0
  73. package/dist/standalone/root-ops.d.ts +42 -0
  74. package/dist/standalone/root-ops.js +101 -0
  75. package/dist/standalone/root-window.d.ts +36 -0
  76. package/dist/standalone/root-window.js +302 -0
  77. package/dist/standalone/spk.d.ts +23 -0
  78. package/dist/standalone/spk.js +192 -0
  79. package/dist/template-paths.d.ts +2 -0
  80. package/dist/template-paths.js +9 -0
  81. package/dist/templates/_daemon/fixture_linux_test.go +15 -0
  82. package/dist/templates/_daemon/fixture_other_test.go +7 -0
  83. package/dist/templates/_daemon/go.mod +3 -0
  84. package/dist/templates/_daemon/main.go +608 -0
  85. package/dist/templates/_daemon/main_test.go +242 -0
  86. package/dist/templates/_daemon/process_linux.go +55 -0
  87. package/dist/templates/_daemon/process_linux_test.go +161 -0
  88. package/dist/templates/_daemon/process_other.go +14 -0
  89. package/dist/templates/_daemon/testdata/child.go +41 -0
  90. package/dist/templates/_shared/GO-LICENSE +27 -0
  91. package/dist/templates/_shared/GO-PATENTS +22 -0
  92. package/dist/templates/_shared/LICENSES/TEMPLATE.txt +21 -0
  93. package/dist/templates/_shared/notice-overrides/index.json +14 -0
  94. package/dist/templates/_shared/notice-overrides/utils-0.4.2-LICENSE +21 -0
  95. package/dist/templates/_shared/notice-overrides/utils-0.5.0-LICENSE +21 -0
  96. package/dist/templates/_shared/third-party-notices.mjs +51 -0
  97. package/dist/templates/binary/synology-app.yaml +7 -0
  98. package/dist/templates/hello-files/compose.yaml +0 -1
  99. package/dist/templates/hello-web/compose.yaml +13 -10
  100. package/dist/templates/hello-web/html/app.js +1 -23
  101. package/dist/templates/hello-web/html/index.html +1 -3
  102. package/dist/templates/hello-web-page/compose.yaml +13 -10
  103. package/dist/templates/hello-web-page/html/app.js +1 -23
  104. package/dist/templates/hello-web-page/html/index.html +1 -3
  105. package/dist/templates/native-go/README.md +324 -0
  106. package/dist/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +59 -0
  107. package/dist/templates/native-go/backend/cmd/app/main.go +49 -0
  108. package/dist/templates/native-go/backend/cmd/dsm-readonly-probe/main_linux.go +46 -0
  109. package/dist/templates/native-go/backend/cmd/helper/main.go +38 -0
  110. package/dist/templates/native-go/backend/go.mod +7 -0
  111. package/dist/templates/native-go/backend/go.sum +4 -0
  112. package/dist/templates/native-go/backend/internal/api/binary.go +154 -0
  113. package/dist/templates/native-go/backend/internal/api/binary_test.go +165 -0
  114. package/dist/templates/native-go/backend/internal/api/errors.go +33 -0
  115. package/dist/templates/native-go/backend/internal/api/registry.go +104 -0
  116. package/dist/templates/native-go/backend/internal/api/registry_test.go +329 -0
  117. package/dist/templates/native-go/backend/internal/api/server.go +159 -0
  118. package/dist/templates/native-go/backend/internal/app/nas_cgi_artifact_test.go +121 -0
  119. package/dist/templates/native-go/backend/internal/app/nas_refusal_test.go +46 -0
  120. package/dist/templates/native-go/backend/internal/app/root_none.go +9 -0
  121. package/dist/templates/native-go/backend/internal/app/routes.go +138 -0
  122. package/dist/templates/native-go/backend/internal/app/routes_test.go +172 -0
  123. package/dist/templates/native-go/backend/internal/dsm/auth.go +118 -0
  124. package/dist/templates/native-go/backend/internal/dsm/auth_test.go +139 -0
  125. package/dist/templates/native-go/backend/internal/dsmprobe/collector_linux.go +335 -0
  126. package/dist/templates/native-go/backend/internal/dsmprobe/collector_linux_test.go +41 -0
  127. package/dist/templates/native-go/backend/internal/dsmprobe/protocol.go +179 -0
  128. package/dist/templates/native-go/backend/internal/dsmprobe/protocol_test.go +29 -0
  129. package/dist/templates/native-go/backend/internal/helper/cohort.go +393 -0
  130. package/dist/templates/native-go/backend/internal/helper/cohort_publication.go +18 -0
  131. package/dist/templates/native-go/backend/internal/helper/cohort_publication_test.go +105 -0
  132. package/dist/templates/native-go/backend/internal/helper/cohort_test.go +372 -0
  133. package/dist/templates/native-go/backend/internal/helper/control.go +424 -0
  134. package/dist/templates/native-go/backend/internal/helper/control_test.go +250 -0
  135. package/dist/templates/native-go/backend/internal/helper/data_contract.go +242 -0
  136. package/dist/templates/native-go/backend/internal/helper/data_contract_test.go +51 -0
  137. package/dist/templates/native-go/backend/internal/helper/data_decode.go +184 -0
  138. package/dist/templates/native-go/backend/internal/helper/data_decode_pointer_test.go +30 -0
  139. package/dist/templates/native-go/backend/internal/helper/data_protocol.go +416 -0
  140. package/dist/templates/native-go/backend/internal/helper/data_protocol_test.go +449 -0
  141. package/dist/templates/native-go/backend/internal/helper/dsm_acl_linux.go +139 -0
  142. package/dist/templates/native-go/backend/internal/helper/dsm_acl_linux_test.go +121 -0
  143. package/dist/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux.go +95 -0
  144. package/dist/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux_test.go +56 -0
  145. package/dist/templates/native-go/backend/internal/helper/dsm_bridge_linux.go +144 -0
  146. package/dist/templates/native-go/backend/internal/helper/dsm_bridge_linux_test.go +89 -0
  147. package/dist/templates/native-go/backend/internal/helper/dsm_home_linux.go +107 -0
  148. package/dist/templates/native-go/backend/internal/helper/dsm_home_linux_test.go +82 -0
  149. package/dist/templates/native-go/backend/internal/helper/dsm_probe_transport_linux.go +151 -0
  150. package/dist/templates/native-go/backend/internal/helper/dsm_probe_transport_linux_test.go +66 -0
  151. package/dist/templates/native-go/backend/internal/helper/grant_authority.go +516 -0
  152. package/dist/templates/native-go/backend/internal/helper/grant_authority_contract.go +88 -0
  153. package/dist/templates/native-go/backend/internal/helper/grant_authority_test.go +510 -0
  154. package/dist/templates/native-go/backend/internal/helper/grant_cohort.go +389 -0
  155. package/dist/templates/native-go/backend/internal/helper/grant_cohort_test.go +239 -0
  156. package/dist/templates/native-go/backend/internal/helper/grant_delivery.go +49 -0
  157. package/dist/templates/native-go/backend/internal/helper/grant_delivery_methods.go +273 -0
  158. package/dist/templates/native-go/backend/internal/helper/grant_delivery_test.go +322 -0
  159. package/dist/templates/native-go/backend/internal/helper/grant_operation_contract.go +47 -0
  160. package/dist/templates/native-go/backend/internal/helper/grant_readonly_test.go +180 -0
  161. package/dist/templates/native-go/backend/internal/helper/grant_repository_linux.go +415 -0
  162. package/dist/templates/native-go/backend/internal/helper/grant_repository_linux_test.go +468 -0
  163. package/dist/templates/native-go/backend/internal/helper/grant_rpc.go +147 -0
  164. package/dist/templates/native-go/backend/internal/helper/grant_rpc_test.go +51 -0
  165. package/dist/templates/native-go/backend/internal/helper/grant_snapshot.go +75 -0
  166. package/dist/templates/native-go/backend/internal/helper/grant_supervisor_linux.go +134 -0
  167. package/dist/templates/native-go/backend/internal/helper/grant_supervisor_linux_test.go +254 -0
  168. package/dist/templates/native-go/backend/internal/helper/lease.go +112 -0
  169. package/dist/templates/native-go/backend/internal/helper/lease_linux.go +44 -0
  170. package/dist/templates/native-go/backend/internal/helper/lease_other.go +8 -0
  171. package/dist/templates/native-go/backend/internal/helper/lifecycle.go +234 -0
  172. package/dist/templates/native-go/backend/internal/helper/lifecycle_test.go +473 -0
  173. package/dist/templates/native-go/backend/internal/helper/managed_pilot.go +284 -0
  174. package/dist/templates/native-go/backend/internal/helper/managed_pilot_repository_linux.go +74 -0
  175. package/dist/templates/native-go/backend/internal/helper/managed_pilot_repository_linux_test.go +40 -0
  176. package/dist/templates/native-go/backend/internal/helper/managed_pilot_test.go +210 -0
  177. package/dist/templates/native-go/backend/internal/helper/nas_shipped_refusal_linux_test.go +97 -0
  178. package/dist/templates/native-go/backend/internal/helper/native_discovery.go +79 -0
  179. package/dist/templates/native-go/backend/internal/helper/native_identity.go +89 -0
  180. package/dist/templates/native-go/backend/internal/helper/native_provider.go +159 -0
  181. package/dist/templates/native-go/backend/internal/helper/native_provider_test.go +421 -0
  182. package/dist/templates/native-go/backend/internal/helper/observation.go +204 -0
  183. package/dist/templates/native-go/backend/internal/helper/observation_health_test.go +115 -0
  184. package/dist/templates/native-go/backend/internal/helper/observation_reload_budget_test.go +117 -0
  185. package/dist/templates/native-go/backend/internal/helper/observation_test.go +196 -0
  186. package/dist/templates/native-go/backend/internal/helper/observer_diagnostic.go +109 -0
  187. package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_linux.go +76 -0
  188. package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_linux_test.go +124 -0
  189. package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_test.go +98 -0
  190. package/dist/templates/native-go/backend/internal/helper/operation_bootstrap_linux.go +193 -0
  191. package/dist/templates/native-go/backend/internal/helper/operation_credentials_linux.go +56 -0
  192. package/dist/templates/native-go/backend/internal/helper/operation_linux.go +480 -0
  193. package/dist/templates/native-go/backend/internal/helper/operation_linux_test.go +528 -0
  194. package/dist/templates/native-go/backend/internal/helper/peer_linux.go +44 -0
  195. package/dist/templates/native-go/backend/internal/helper/peer_other.go +7 -0
  196. package/dist/templates/native-go/backend/internal/helper/process_linux.go +177 -0
  197. package/dist/templates/native-go/backend/internal/helper/process_other.go +5 -0
  198. package/dist/templates/native-go/backend/internal/helper/publication_test.go +178 -0
  199. package/dist/templates/native-go/backend/internal/helper/read_stream_cohort_linux_test.go +156 -0
  200. package/dist/templates/native-go/backend/internal/helper/read_transfer.go +40 -0
  201. package/dist/templates/native-go/backend/internal/helper/read_transfer_linux.go +109 -0
  202. package/dist/templates/native-go/backend/internal/helper/read_transfer_linux_test.go +118 -0
  203. package/dist/templates/native-go/backend/internal/helper/read_transfer_test.go +177 -0
  204. package/dist/templates/native-go/backend/internal/helper/readonly.go +105 -0
  205. package/dist/templates/native-go/backend/internal/helper/readonly_admission.go +85 -0
  206. package/dist/templates/native-go/backend/internal/helper/readonly_cohort_linux_test.go +253 -0
  207. package/dist/templates/native-go/backend/internal/helper/readonly_linux_test.go +378 -0
  208. package/dist/templates/native-go/backend/internal/helper/readonly_mount_linux.go +65 -0
  209. package/dist/templates/native-go/backend/internal/helper/readonly_mount_proxy_linux.go +113 -0
  210. package/dist/templates/native-go/backend/internal/helper/readonly_operations_linux.go +168 -0
  211. package/dist/templates/native-go/backend/internal/helper/readonly_resolver_linux.go +241 -0
  212. package/dist/templates/native-go/backend/internal/helper/readonly_test.go +40 -0
  213. package/dist/templates/native-go/backend/internal/helper/relaxed_identity.go +252 -0
  214. package/dist/templates/native-go/backend/internal/helper/relaxed_identity_contract.go +105 -0
  215. package/dist/templates/native-go/backend/internal/helper/relaxed_identity_test.go +406 -0
  216. package/dist/templates/native-go/backend/internal/helper/relaxed_invalidation.go +200 -0
  217. package/dist/templates/native-go/backend/internal/helper/repair.go +132 -0
  218. package/dist/templates/native-go/backend/internal/helper/repair_test.go +271 -0
  219. package/dist/templates/native-go/backend/internal/helper/s1r_actor_acl_linux_test.go +303 -0
  220. package/dist/templates/native-go/backend/internal/helper/s1r_actor_fixture_linux_test.go +184 -0
  221. package/dist/templates/native-go/backend/internal/helper/s1r_actor_races_linux_test.go +231 -0
  222. package/dist/templates/native-go/backend/internal/helper/s1r_fixture_contract_linux_test.go +18 -0
  223. package/dist/templates/native-go/backend/internal/helper/server_linux.go +124 -0
  224. package/dist/templates/native-go/backend/internal/helper/status.go +334 -0
  225. package/dist/templates/native-go/backend/internal/helper/status_test.go +288 -0
  226. package/dist/templates/native-go/backend/internal/helper/supervision.go +107 -0
  227. package/dist/templates/native-go/backend/internal/helper/supervision_test.go +124 -0
  228. package/dist/templates/native-go/backend/internal/helper/supervisor_frame.go +76 -0
  229. package/dist/templates/native-go/backend/internal/helper/supervisor_frame_linux_test.go +69 -0
  230. package/dist/templates/native-go/backend/internal/helper/supervisor_frame_test.go +107 -0
  231. package/dist/templates/native-go/backend/internal/helper/supervisor_linux.go +363 -0
  232. package/dist/templates/native-go/backend/internal/helper/supervisor_linux_test.go +913 -0
  233. package/dist/templates/native-go/backend/internal/helper/supervisor_socket_eof_test.go +74 -0
  234. package/dist/templates/native-go/backend/internal/helper/supervisor_socket_test.go +45 -0
  235. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/create.json +23 -0
  236. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/frames.json +67 -0
  237. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/grant-store.json +52 -0
  238. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/intent.json +20 -0
  239. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/list.json +20 -0
  240. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/publish.json +20 -0
  241. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/read.json +22 -0
  242. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/stat.json +22 -0
  243. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/write-stream.json +22 -0
  244. package/dist/templates/native-go/backend/internal/helper/unit_connection.go +75 -0
  245. package/dist/templates/native-go/backend/internal/helper/unit_connection_linux_test.go +135 -0
  246. package/dist/templates/native-go/backend/internal/helper/unit_connection_test.go +133 -0
  247. package/dist/templates/native-go/backend/internal/helper/unit_frame_test.go +32 -0
  248. package/dist/templates/native-go/backend/internal/helper/unit_linux.go +364 -0
  249. package/dist/templates/native-go/backend/internal/helper/unit_linux_test.go +46 -0
  250. package/dist/templates/native-go/backend/internal/helper/unit_mechanisms_linux_test.go +217 -0
  251. package/dist/templates/native-go/backend/internal/helper/unit_padding_linux_test.go +178 -0
  252. package/dist/templates/native-go/backend/internal/helper/unit_query_linux.go +111 -0
  253. package/dist/templates/native-go/backend/internal/helper/unit_reload_linux_test.go +372 -0
  254. package/dist/templates/native-go/backend/internal/helper/unit_reload_sequence_linux_test.go +232 -0
  255. package/dist/templates/native-go/backend/internal/helper/write.go +77 -0
  256. package/dist/templates/native-go/backend/internal/helper/write_admission.go +260 -0
  257. package/dist/templates/native-go/backend/internal/helper/write_admission_test.go +135 -0
  258. package/dist/templates/native-go/backend/internal/helper/write_cohort_linux_test.go +218 -0
  259. package/dist/templates/native-go/backend/internal/helper/write_files_linux.go +202 -0
  260. package/dist/templates/native-go/backend/internal/helper/write_files_linux_test.go +199 -0
  261. package/dist/templates/native-go/backend/internal/helper/write_intent_linux.go +116 -0
  262. package/dist/templates/native-go/backend/internal/helper/write_intent_linux_test.go +74 -0
  263. package/dist/templates/native-go/backend/internal/helper/write_operation_linux.go +245 -0
  264. package/dist/templates/native-go/backend/internal/helper/write_test.go +53 -0
  265. package/dist/templates/native-go/dsm-package.yaml +58 -0
  266. package/dist/templates/native-go/gitignore +1 -0
  267. package/dist/templates/native-go/i18n/glossary.json +662 -0
  268. package/dist/templates/native-go/i18n/messages/de.json +28 -0
  269. package/dist/templates/native-go/i18n/messages/en.json +28 -0
  270. package/dist/templates/native-go/i18n/messages/es.json +28 -0
  271. package/dist/templates/native-go/i18n/messages/fr.json +28 -0
  272. package/dist/templates/native-go/i18n/messages/it.json +28 -0
  273. package/dist/templates/native-go/i18n/messages/ja.json +28 -0
  274. package/dist/templates/native-go/i18n/messages/ko.json +28 -0
  275. package/dist/templates/native-go/i18n/messages/zh-CN.json +28 -0
  276. package/dist/templates/native-go/i18n/messages/zh-TW.json +28 -0
  277. package/dist/templates/native-go/ui/app.css +35 -0
  278. package/dist/templates/native-go/ui/app.js +101 -0
  279. package/dist/templates/native-go-better-auth/backend/internal/app/identity.go +208 -0
  280. package/dist/templates/native-go-better-auth/backend/internal/app/identity_test.go +113 -0
  281. package/dist/templates/native-go-better-auth/node/app.mjs +72 -0
  282. package/dist/templates/native-go-better-auth/node/build.mjs +4 -0
  283. package/dist/templates/native-go-better-auth/node/package-lock.json +862 -0
  284. package/dist/templates/native-go-better-auth/node/package.json +1 -0
  285. package/dist/templates/native-go-better-auth/node/test/auth.test.mjs +31 -0
  286. package/dist/templates/native-go-integration/backend/internal/app/identity_none.go +6 -0
  287. package/dist/templates/native-go-integration/backend/internal/app/personal.go +203 -0
  288. package/dist/templates/native-go-integration/backend/internal/app/personal_test.go +119 -0
  289. package/dist/templates/native-go-root/backend/internal/app/root.go +107 -0
  290. package/dist/templates/native-go-root/backend/internal/app/root_test.go +124 -0
  291. package/dist/templates/native-go-root/root/whoami.sh +6 -0
  292. package/dist/templates/native-go-vue/README.md +224 -0
  293. package/dist/templates/native-go-vue/frontend/DESIGN.md +78 -0
  294. package/dist/templates/native-go-vue/frontend/package-lock.json +2410 -0
  295. package/dist/templates/native-go-vue/frontend/package.json +6 -0
  296. package/dist/templates/native-go-vue/frontend/src/App.vue +159 -0
  297. package/dist/templates/native-go-vue/frontend/src/context.ts +56 -0
  298. package/dist/templates/native-go-vue/frontend/src/main.ts +29 -0
  299. package/dist/templates/native-go-vue/frontend/src/nas/NasGrantSettings.vue +74 -0
  300. package/dist/templates/native-go-vue/frontend/src/nas/NasPathPicker.vue +106 -0
  301. package/dist/templates/native-go-vue/frontend/src/nas/NasUnavailable.vue +20 -0
  302. package/dist/templates/native-go-vue/frontend/src/nas/i18n/de.json +74 -0
  303. package/dist/templates/native-go-vue/frontend/src/nas/i18n/en.json +74 -0
  304. package/dist/templates/native-go-vue/frontend/src/nas/i18n/es.json +74 -0
  305. package/dist/templates/native-go-vue/frontend/src/nas/i18n/fr.json +74 -0
  306. package/dist/templates/native-go-vue/frontend/src/nas/i18n/it.json +74 -0
  307. package/dist/templates/native-go-vue/frontend/src/nas/i18n/ja.json +74 -0
  308. package/dist/templates/native-go-vue/frontend/src/nas/i18n/ko.json +74 -0
  309. package/dist/templates/native-go-vue/frontend/src/nas/i18n/zh-CN.json +74 -0
  310. package/dist/templates/native-go-vue/frontend/src/nas/i18n/zh-TW.json +74 -0
  311. package/dist/templates/native-go-vue/frontend/src/nas/i18n.ts +38 -0
  312. package/dist/templates/native-go-vue/frontend/src/nas/mock-provider.ts +119 -0
  313. package/dist/templates/native-go-vue/frontend/src/nas/provider.ts +59 -0
  314. package/dist/templates/native-go-vue/frontend/src/nas/use-request.ts +27 -0
  315. package/dist/templates/native-go-vue/frontend/src/style.css +31 -0
  316. package/dist/templates/native-go-vue/frontend/test/apps.test.ts +190 -0
  317. package/dist/templates/native-go-vue/frontend/test/nas-provider.test.ts +81 -0
  318. package/dist/templates/native-go-vue/frontend/test/nas-request.test.ts +21 -0
  319. package/dist/templates/native-go-vue/frontend/test/nas-ui.test.ts +261 -0
  320. package/dist/templates/native-go-vue/frontend/tsconfig.json +1 -0
  321. package/dist/templates/native-go-vue/frontend/vite.config.ts +10 -0
  322. package/dist/templates/native-go-vue/gitignore +2 -0
  323. package/dist/types.d.ts +1 -1
  324. package/dist/validate.js +11 -7
  325. package/package.json +5 -8
  326. package/schema/synology-app.schema.json +36 -37
  327. package/skills/SKILL.md +4 -48
  328. package/skills/reference/create.md +11 -83
  329. package/skills/reference/deploy.md +7 -78
  330. package/skills/reference/diagnose.md +4 -101
  331. package/skills/reference/files.md +5 -41
  332. package/skills/reference/identity.md +3 -29
  333. package/skills/reference/wrap.md +0 -2
  334. package/templates/_daemon/fixture_linux_test.go +15 -0
  335. package/templates/_daemon/fixture_other_test.go +7 -0
  336. package/templates/_daemon/go.mod +3 -0
  337. package/templates/_daemon/main.go +608 -0
  338. package/templates/_daemon/main_test.go +242 -0
  339. package/templates/_daemon/process_linux.go +55 -0
  340. package/templates/_daemon/process_linux_test.go +161 -0
  341. package/templates/_daemon/process_other.go +14 -0
  342. package/templates/_daemon/testdata/child.go +41 -0
  343. package/templates/_shared/GO-LICENSE +27 -0
  344. package/templates/_shared/GO-PATENTS +22 -0
  345. package/templates/_shared/LICENSES/TEMPLATE.txt +21 -0
  346. package/templates/_shared/notice-overrides/index.json +14 -0
  347. package/templates/_shared/notice-overrides/utils-0.4.2-LICENSE +21 -0
  348. package/templates/_shared/notice-overrides/utils-0.5.0-LICENSE +21 -0
  349. package/templates/_shared/third-party-notices.mjs +51 -0
  350. package/templates/binary/synology-app.yaml +7 -0
  351. package/templates/hello-files/compose.yaml +0 -1
  352. package/templates/hello-web/compose.yaml +13 -10
  353. package/templates/hello-web/html/app.js +1 -23
  354. package/templates/hello-web/html/index.html +1 -3
  355. package/templates/hello-web-page/compose.yaml +13 -10
  356. package/templates/hello-web-page/html/app.js +1 -23
  357. package/templates/hello-web-page/html/index.html +1 -3
  358. package/templates/native-go/README.md +324 -0
  359. package/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +59 -0
  360. package/templates/native-go/backend/cmd/app/main.go +49 -0
  361. package/templates/native-go/backend/cmd/dsm-readonly-probe/main_linux.go +46 -0
  362. package/templates/native-go/backend/cmd/helper/main.go +38 -0
  363. package/templates/native-go/backend/go.mod +7 -0
  364. package/templates/native-go/backend/go.sum +4 -0
  365. package/templates/native-go/backend/internal/api/binary.go +154 -0
  366. package/templates/native-go/backend/internal/api/binary_test.go +165 -0
  367. package/templates/native-go/backend/internal/api/errors.go +33 -0
  368. package/templates/native-go/backend/internal/api/registry.go +104 -0
  369. package/templates/native-go/backend/internal/api/registry_test.go +329 -0
  370. package/templates/native-go/backend/internal/api/server.go +159 -0
  371. package/templates/native-go/backend/internal/app/nas_cgi_artifact_test.go +121 -0
  372. package/templates/native-go/backend/internal/app/nas_refusal_test.go +46 -0
  373. package/templates/native-go/backend/internal/app/root_none.go +9 -0
  374. package/templates/native-go/backend/internal/app/routes.go +138 -0
  375. package/templates/native-go/backend/internal/app/routes_test.go +172 -0
  376. package/templates/native-go/backend/internal/dsm/auth.go +118 -0
  377. package/templates/native-go/backend/internal/dsm/auth_test.go +139 -0
  378. package/templates/native-go/backend/internal/dsmprobe/collector_linux.go +335 -0
  379. package/templates/native-go/backend/internal/dsmprobe/collector_linux_test.go +41 -0
  380. package/templates/native-go/backend/internal/dsmprobe/protocol.go +179 -0
  381. package/templates/native-go/backend/internal/dsmprobe/protocol_test.go +29 -0
  382. package/templates/native-go/backend/internal/helper/cohort.go +393 -0
  383. package/templates/native-go/backend/internal/helper/cohort_publication.go +18 -0
  384. package/templates/native-go/backend/internal/helper/cohort_publication_test.go +105 -0
  385. package/templates/native-go/backend/internal/helper/cohort_test.go +372 -0
  386. package/templates/native-go/backend/internal/helper/control.go +424 -0
  387. package/templates/native-go/backend/internal/helper/control_test.go +250 -0
  388. package/templates/native-go/backend/internal/helper/data_contract.go +242 -0
  389. package/templates/native-go/backend/internal/helper/data_contract_test.go +51 -0
  390. package/templates/native-go/backend/internal/helper/data_decode.go +184 -0
  391. package/templates/native-go/backend/internal/helper/data_decode_pointer_test.go +30 -0
  392. package/templates/native-go/backend/internal/helper/data_protocol.go +416 -0
  393. package/templates/native-go/backend/internal/helper/data_protocol_test.go +449 -0
  394. package/templates/native-go/backend/internal/helper/dsm_acl_linux.go +139 -0
  395. package/templates/native-go/backend/internal/helper/dsm_acl_linux_test.go +121 -0
  396. package/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux.go +95 -0
  397. package/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux_test.go +56 -0
  398. package/templates/native-go/backend/internal/helper/dsm_bridge_linux.go +144 -0
  399. package/templates/native-go/backend/internal/helper/dsm_bridge_linux_test.go +89 -0
  400. package/templates/native-go/backend/internal/helper/dsm_home_linux.go +107 -0
  401. package/templates/native-go/backend/internal/helper/dsm_home_linux_test.go +82 -0
  402. package/templates/native-go/backend/internal/helper/dsm_probe_transport_linux.go +151 -0
  403. package/templates/native-go/backend/internal/helper/dsm_probe_transport_linux_test.go +66 -0
  404. package/templates/native-go/backend/internal/helper/grant_authority.go +516 -0
  405. package/templates/native-go/backend/internal/helper/grant_authority_contract.go +88 -0
  406. package/templates/native-go/backend/internal/helper/grant_authority_test.go +510 -0
  407. package/templates/native-go/backend/internal/helper/grant_cohort.go +389 -0
  408. package/templates/native-go/backend/internal/helper/grant_cohort_test.go +239 -0
  409. package/templates/native-go/backend/internal/helper/grant_delivery.go +49 -0
  410. package/templates/native-go/backend/internal/helper/grant_delivery_methods.go +273 -0
  411. package/templates/native-go/backend/internal/helper/grant_delivery_test.go +322 -0
  412. package/templates/native-go/backend/internal/helper/grant_operation_contract.go +47 -0
  413. package/templates/native-go/backend/internal/helper/grant_readonly_test.go +180 -0
  414. package/templates/native-go/backend/internal/helper/grant_repository_linux.go +415 -0
  415. package/templates/native-go/backend/internal/helper/grant_repository_linux_test.go +468 -0
  416. package/templates/native-go/backend/internal/helper/grant_rpc.go +147 -0
  417. package/templates/native-go/backend/internal/helper/grant_rpc_test.go +51 -0
  418. package/templates/native-go/backend/internal/helper/grant_snapshot.go +75 -0
  419. package/templates/native-go/backend/internal/helper/grant_supervisor_linux.go +134 -0
  420. package/templates/native-go/backend/internal/helper/grant_supervisor_linux_test.go +254 -0
  421. package/templates/native-go/backend/internal/helper/lease.go +112 -0
  422. package/templates/native-go/backend/internal/helper/lease_linux.go +44 -0
  423. package/templates/native-go/backend/internal/helper/lease_other.go +8 -0
  424. package/templates/native-go/backend/internal/helper/lifecycle.go +234 -0
  425. package/templates/native-go/backend/internal/helper/lifecycle_test.go +473 -0
  426. package/templates/native-go/backend/internal/helper/managed_pilot.go +284 -0
  427. package/templates/native-go/backend/internal/helper/managed_pilot_repository_linux.go +74 -0
  428. package/templates/native-go/backend/internal/helper/managed_pilot_repository_linux_test.go +40 -0
  429. package/templates/native-go/backend/internal/helper/managed_pilot_test.go +210 -0
  430. package/templates/native-go/backend/internal/helper/nas_shipped_refusal_linux_test.go +97 -0
  431. package/templates/native-go/backend/internal/helper/native_discovery.go +79 -0
  432. package/templates/native-go/backend/internal/helper/native_identity.go +89 -0
  433. package/templates/native-go/backend/internal/helper/native_provider.go +159 -0
  434. package/templates/native-go/backend/internal/helper/native_provider_test.go +421 -0
  435. package/templates/native-go/backend/internal/helper/observation.go +204 -0
  436. package/templates/native-go/backend/internal/helper/observation_health_test.go +115 -0
  437. package/templates/native-go/backend/internal/helper/observation_reload_budget_test.go +117 -0
  438. package/templates/native-go/backend/internal/helper/observation_test.go +196 -0
  439. package/templates/native-go/backend/internal/helper/observer_diagnostic.go +109 -0
  440. package/templates/native-go/backend/internal/helper/observer_diagnostic_linux.go +76 -0
  441. package/templates/native-go/backend/internal/helper/observer_diagnostic_linux_test.go +124 -0
  442. package/templates/native-go/backend/internal/helper/observer_diagnostic_test.go +98 -0
  443. package/templates/native-go/backend/internal/helper/operation_bootstrap_linux.go +193 -0
  444. package/templates/native-go/backend/internal/helper/operation_credentials_linux.go +56 -0
  445. package/templates/native-go/backend/internal/helper/operation_linux.go +480 -0
  446. package/templates/native-go/backend/internal/helper/operation_linux_test.go +528 -0
  447. package/templates/native-go/backend/internal/helper/peer_linux.go +44 -0
  448. package/templates/native-go/backend/internal/helper/peer_other.go +7 -0
  449. package/templates/native-go/backend/internal/helper/process_linux.go +177 -0
  450. package/templates/native-go/backend/internal/helper/process_other.go +5 -0
  451. package/templates/native-go/backend/internal/helper/publication_test.go +178 -0
  452. package/templates/native-go/backend/internal/helper/read_stream_cohort_linux_test.go +156 -0
  453. package/templates/native-go/backend/internal/helper/read_transfer.go +40 -0
  454. package/templates/native-go/backend/internal/helper/read_transfer_linux.go +109 -0
  455. package/templates/native-go/backend/internal/helper/read_transfer_linux_test.go +118 -0
  456. package/templates/native-go/backend/internal/helper/read_transfer_test.go +177 -0
  457. package/templates/native-go/backend/internal/helper/readonly.go +105 -0
  458. package/templates/native-go/backend/internal/helper/readonly_admission.go +85 -0
  459. package/templates/native-go/backend/internal/helper/readonly_cohort_linux_test.go +253 -0
  460. package/templates/native-go/backend/internal/helper/readonly_linux_test.go +378 -0
  461. package/templates/native-go/backend/internal/helper/readonly_mount_linux.go +65 -0
  462. package/templates/native-go/backend/internal/helper/readonly_mount_proxy_linux.go +113 -0
  463. package/templates/native-go/backend/internal/helper/readonly_operations_linux.go +168 -0
  464. package/templates/native-go/backend/internal/helper/readonly_resolver_linux.go +241 -0
  465. package/templates/native-go/backend/internal/helper/readonly_test.go +40 -0
  466. package/templates/native-go/backend/internal/helper/relaxed_identity.go +252 -0
  467. package/templates/native-go/backend/internal/helper/relaxed_identity_contract.go +105 -0
  468. package/templates/native-go/backend/internal/helper/relaxed_identity_test.go +406 -0
  469. package/templates/native-go/backend/internal/helper/relaxed_invalidation.go +200 -0
  470. package/templates/native-go/backend/internal/helper/repair.go +132 -0
  471. package/templates/native-go/backend/internal/helper/repair_test.go +271 -0
  472. package/templates/native-go/backend/internal/helper/s1r_actor_acl_linux_test.go +303 -0
  473. package/templates/native-go/backend/internal/helper/s1r_actor_fixture_linux_test.go +184 -0
  474. package/templates/native-go/backend/internal/helper/s1r_actor_races_linux_test.go +231 -0
  475. package/templates/native-go/backend/internal/helper/s1r_fixture_contract_linux_test.go +18 -0
  476. package/templates/native-go/backend/internal/helper/server_linux.go +124 -0
  477. package/templates/native-go/backend/internal/helper/status.go +334 -0
  478. package/templates/native-go/backend/internal/helper/status_test.go +288 -0
  479. package/templates/native-go/backend/internal/helper/supervision.go +107 -0
  480. package/templates/native-go/backend/internal/helper/supervision_test.go +124 -0
  481. package/templates/native-go/backend/internal/helper/supervisor_frame.go +76 -0
  482. package/templates/native-go/backend/internal/helper/supervisor_frame_linux_test.go +69 -0
  483. package/templates/native-go/backend/internal/helper/supervisor_frame_test.go +107 -0
  484. package/templates/native-go/backend/internal/helper/supervisor_linux.go +363 -0
  485. package/templates/native-go/backend/internal/helper/supervisor_linux_test.go +913 -0
  486. package/templates/native-go/backend/internal/helper/supervisor_socket_eof_test.go +74 -0
  487. package/templates/native-go/backend/internal/helper/supervisor_socket_test.go +45 -0
  488. package/templates/native-go/backend/internal/helper/testdata/protocol2/create.json +23 -0
  489. package/templates/native-go/backend/internal/helper/testdata/protocol2/frames.json +67 -0
  490. package/templates/native-go/backend/internal/helper/testdata/protocol2/grant-store.json +52 -0
  491. package/templates/native-go/backend/internal/helper/testdata/protocol2/intent.json +20 -0
  492. package/templates/native-go/backend/internal/helper/testdata/protocol2/list.json +20 -0
  493. package/templates/native-go/backend/internal/helper/testdata/protocol2/publish.json +20 -0
  494. package/templates/native-go/backend/internal/helper/testdata/protocol2/read.json +22 -0
  495. package/templates/native-go/backend/internal/helper/testdata/protocol2/stat.json +22 -0
  496. package/templates/native-go/backend/internal/helper/testdata/protocol2/write-stream.json +22 -0
  497. package/templates/native-go/backend/internal/helper/unit_connection.go +75 -0
  498. package/templates/native-go/backend/internal/helper/unit_connection_linux_test.go +135 -0
  499. package/templates/native-go/backend/internal/helper/unit_connection_test.go +133 -0
  500. package/templates/native-go/backend/internal/helper/unit_frame_test.go +32 -0
  501. package/templates/native-go/backend/internal/helper/unit_linux.go +364 -0
  502. package/templates/native-go/backend/internal/helper/unit_linux_test.go +46 -0
  503. package/templates/native-go/backend/internal/helper/unit_mechanisms_linux_test.go +217 -0
  504. package/templates/native-go/backend/internal/helper/unit_padding_linux_test.go +178 -0
  505. package/templates/native-go/backend/internal/helper/unit_query_linux.go +111 -0
  506. package/templates/native-go/backend/internal/helper/unit_reload_linux_test.go +372 -0
  507. package/templates/native-go/backend/internal/helper/unit_reload_sequence_linux_test.go +232 -0
  508. package/templates/native-go/backend/internal/helper/write.go +77 -0
  509. package/templates/native-go/backend/internal/helper/write_admission.go +260 -0
  510. package/templates/native-go/backend/internal/helper/write_admission_test.go +135 -0
  511. package/templates/native-go/backend/internal/helper/write_cohort_linux_test.go +218 -0
  512. package/templates/native-go/backend/internal/helper/write_files_linux.go +202 -0
  513. package/templates/native-go/backend/internal/helper/write_files_linux_test.go +199 -0
  514. package/templates/native-go/backend/internal/helper/write_intent_linux.go +116 -0
  515. package/templates/native-go/backend/internal/helper/write_intent_linux_test.go +74 -0
  516. package/templates/native-go/backend/internal/helper/write_operation_linux.go +245 -0
  517. package/templates/native-go/backend/internal/helper/write_test.go +53 -0
  518. package/templates/native-go/dsm-package.yaml +58 -0
  519. package/templates/native-go/gitignore +1 -0
  520. package/templates/native-go/i18n/glossary.json +662 -0
  521. package/templates/native-go/i18n/messages/de.json +28 -0
  522. package/templates/native-go/i18n/messages/en.json +28 -0
  523. package/templates/native-go/i18n/messages/es.json +28 -0
  524. package/templates/native-go/i18n/messages/fr.json +28 -0
  525. package/templates/native-go/i18n/messages/it.json +28 -0
  526. package/templates/native-go/i18n/messages/ja.json +28 -0
  527. package/templates/native-go/i18n/messages/ko.json +28 -0
  528. package/templates/native-go/i18n/messages/zh-CN.json +28 -0
  529. package/templates/native-go/i18n/messages/zh-TW.json +28 -0
  530. package/templates/native-go/ui/app.css +35 -0
  531. package/templates/native-go/ui/app.js +101 -0
  532. package/templates/native-go-better-auth/backend/internal/app/identity.go +208 -0
  533. package/templates/native-go-better-auth/backend/internal/app/identity_test.go +113 -0
  534. package/templates/native-go-better-auth/node/app.mjs +72 -0
  535. package/templates/native-go-better-auth/node/build.mjs +4 -0
  536. package/templates/native-go-better-auth/node/package-lock.json +862 -0
  537. package/templates/native-go-better-auth/node/package.json +1 -0
  538. package/templates/native-go-better-auth/node/test/auth.test.mjs +31 -0
  539. package/templates/native-go-integration/backend/internal/app/identity_none.go +6 -0
  540. package/templates/native-go-integration/backend/internal/app/personal.go +203 -0
  541. package/templates/native-go-integration/backend/internal/app/personal_test.go +119 -0
  542. package/templates/native-go-root/backend/internal/app/root.go +107 -0
  543. package/templates/native-go-root/backend/internal/app/root_test.go +124 -0
  544. package/templates/native-go-root/root/whoami.sh +6 -0
  545. package/templates/native-go-vue/README.md +224 -0
  546. package/templates/native-go-vue/frontend/DESIGN.md +78 -0
  547. package/templates/native-go-vue/frontend/package-lock.json +2410 -0
  548. package/templates/native-go-vue/frontend/package.json +6 -0
  549. package/templates/native-go-vue/frontend/src/App.vue +159 -0
  550. package/templates/native-go-vue/frontend/src/context.ts +56 -0
  551. package/templates/native-go-vue/frontend/src/main.ts +29 -0
  552. package/templates/native-go-vue/frontend/src/nas/NasGrantSettings.vue +74 -0
  553. package/templates/native-go-vue/frontend/src/nas/NasPathPicker.vue +106 -0
  554. package/templates/native-go-vue/frontend/src/nas/NasUnavailable.vue +20 -0
  555. package/templates/native-go-vue/frontend/src/nas/i18n/de.json +74 -0
  556. package/templates/native-go-vue/frontend/src/nas/i18n/en.json +74 -0
  557. package/templates/native-go-vue/frontend/src/nas/i18n/es.json +74 -0
  558. package/templates/native-go-vue/frontend/src/nas/i18n/fr.json +74 -0
  559. package/templates/native-go-vue/frontend/src/nas/i18n/it.json +74 -0
  560. package/templates/native-go-vue/frontend/src/nas/i18n/ja.json +74 -0
  561. package/templates/native-go-vue/frontend/src/nas/i18n/ko.json +74 -0
  562. package/templates/native-go-vue/frontend/src/nas/i18n/zh-CN.json +74 -0
  563. package/templates/native-go-vue/frontend/src/nas/i18n/zh-TW.json +74 -0
  564. package/templates/native-go-vue/frontend/src/nas/i18n.ts +38 -0
  565. package/templates/native-go-vue/frontend/src/nas/mock-provider.ts +119 -0
  566. package/templates/native-go-vue/frontend/src/nas/provider.ts +59 -0
  567. package/templates/native-go-vue/frontend/src/nas/use-request.ts +27 -0
  568. package/templates/native-go-vue/frontend/src/style.css +31 -0
  569. package/templates/native-go-vue/frontend/test/apps.test.ts +190 -0
  570. package/templates/native-go-vue/frontend/test/nas-provider.test.ts +81 -0
  571. package/templates/native-go-vue/frontend/test/nas-request.test.ts +21 -0
  572. package/templates/native-go-vue/frontend/test/nas-ui.test.ts +261 -0
  573. package/templates/native-go-vue/frontend/tsconfig.json +1 -0
  574. package/templates/native-go-vue/frontend/vite.config.ts +10 -0
  575. package/templates/native-go-vue/gitignore +2 -0
  576. package/dist/attestation/app-package.d.ts +0 -86
  577. package/dist/attestation/app-package.js +0 -206
  578. package/dist/attestation/install-on-host.d.ts +0 -14
  579. package/dist/attestation/install-on-host.js +0 -52
  580. package/dist/attestation/keyring.d.ts +0 -21
  581. package/dist/attestation/keyring.js +0 -168
  582. package/dist/attestation/platform-service.d.ts +0 -70
  583. package/dist/attestation/platform-service.js +0 -250
  584. package/dist/build-spk/broker-glue.d.ts +0 -16
  585. package/dist/build-spk/broker-glue.js +0 -40
  586. package/dist/deploy/catalog-publish.d.ts +0 -3
  587. package/dist/deploy/catalog-publish.js +0 -7
  588. package/dist/doctor.d.ts +0 -22
  589. package/dist/doctor.js +0 -822
  590. package/dist/error-collector.d.ts +0 -2
  591. package/dist/error-collector.js +0 -46
  592. package/dist/host/broker-paths.d.ts +0 -1
  593. package/dist/host/broker-paths.js +0 -1
  594. package/dist/host/broker-upgrade-preflight.d.ts +0 -61
  595. package/dist/host/broker-upgrade-preflight.js +0 -156
  596. package/dist/host/digests.d.ts +0 -5
  597. package/dist/host/digests.js +0 -63
  598. package/dist/host/fake-nas.d.ts +0 -49
  599. package/dist/host/fake-nas.js +0 -193
  600. package/dist/mock-broker/bootstrap.d.ts +0 -2
  601. package/dist/mock-broker/bootstrap.js +0 -8
  602. package/dist/mock-broker/files.d.ts +0 -60
  603. package/dist/mock-broker/files.js +0 -408
  604. package/dist/mock-broker/oidc.d.ts +0 -31
  605. package/dist/mock-broker/oidc.js +0 -161
  606. package/dist/mock-broker/path.d.ts +0 -9
  607. package/dist/mock-broker/path.js +0 -50
  608. package/dist/mock-broker/server.d.ts +0 -19
  609. package/dist/mock-broker/server.js +0 -350
  610. package/dist/publish/build-ledger.d.ts +0 -22
  611. package/dist/publish/build-ledger.js +0 -26
  612. package/dist/publish/community-path.d.ts +0 -6
  613. package/dist/publish/community-path.js +0 -41
  614. package/dist/publish/curated-release.d.ts +0 -78
  615. package/dist/publish/curated-release.js +0 -883
  616. package/dist/publish/file-build-ledger.d.ts +0 -18
  617. package/dist/publish/file-build-ledger.js +0 -268
  618. package/dist/publish/github-pr.d.ts +0 -25
  619. package/dist/publish/github-pr.js +0 -85
  620. package/dist/publish/github-repo.d.ts +0 -8
  621. package/dist/publish/github-repo.js +0 -21
  622. package/dist/publish/platform-service-release.d.ts +0 -60
  623. package/dist/publish/platform-service-release.js +0 -333
  624. package/dist/publish/preflight.d.ts +0 -24
  625. package/dist/publish/preflight.js +0 -138
  626. package/dist/publish/publish.d.ts +0 -27
  627. package/dist/publish/publish.js +0 -136
  628. package/dist/publish/sync-definition.d.ts +0 -4
  629. package/dist/publish/sync-definition.js +0 -48
  630. package/dist/release-bin.d.ts +0 -2
  631. package/dist/release-bin.js +0 -23
  632. package/dist/templates/hello-web/html/sdk.js +0 -68
  633. package/dist/templates/hello-web-page/html/sdk.js +0 -68
  634. package/dist/templates/native/synology-app.yaml +0 -7
  635. package/dist/test-host.d.ts +0 -15
  636. package/dist/test-host.js +0 -37
  637. package/templates/hello-web/html/sdk.js +0 -68
  638. package/templates/hello-web-page/html/sdk.js +0 -68
  639. package/templates/native/synology-app.yaml +0 -7
  640. /package/dist/templates/{native → binary}/native.yaml +0 -0
  641. /package/templates/{native → binary}/native.yaml +0 -0
@@ -0,0 +1,913 @@
1
+ package helper
2
+
3
+ import (
4
+ "context"
5
+ "encoding/json"
6
+ "errors"
7
+ "net"
8
+ "os"
9
+ "os/exec"
10
+ "path/filepath"
11
+ "strconv"
12
+ "strings"
13
+ "syscall"
14
+ "testing"
15
+ "time"
16
+ )
17
+
18
+ // This opt-in fixture uses a root-only, disposable Linux VM and an independently
19
+ // cross-compiled cmd/helper. Never creates accounts or accesses a NAS.
20
+ func linuxFixture(t *testing.T) LinuxProcesses {
21
+ t.Helper()
22
+ source := os.Getenv("M1C_HELPER_FIXTURE")
23
+ if source == "" {
24
+ t.Skip("requires disposable Linux root VM and M1C_HELPER_FIXTURE")
25
+ }
26
+ if os.Geteuid() != 0 {
27
+ t.Fatal("VM fixture requires root")
28
+ }
29
+ traces, _ := filepath.Glob("/tmp/m1h-trace-*")
30
+ for _, path := range traces {
31
+ if err := os.Remove(path); err != nil {
32
+ t.Fatal(err)
33
+ }
34
+ }
35
+ if t.Name() == "TestLinuxHelperSelfExitIsReapedWithoutSignallingReusedPID" {
36
+ source = "/helper-self-exit"
37
+ }
38
+ if t.Name() == "TestLinuxControllerWaitsForRealCompletionPublisher" {
39
+ source = "/helper-held-completion"
40
+ }
41
+ digest, err := executableDigest(source)
42
+ if err != nil {
43
+ t.Fatal(err)
44
+ }
45
+ i := Inventory{Package: "root", Version: "1.0.0-0001", Protocol: 1, PayloadDigest: digest, RegistryDigest: strings.Repeat("b", 64)}
46
+ c := NewClient(i)
47
+
48
+ for _, dir := range []string{c.StateDir, c.RunDir} {
49
+ if err := os.Mkdir(dir, 0700); err != nil {
50
+ t.Fatal(err)
51
+ }
52
+ t.Cleanup(func() { os.RemoveAll(dir) })
53
+ }
54
+ t.Cleanup(func() {
55
+ r, e := readRecord(c.StateDir, 0)
56
+ b, _ := json.Marshal(r)
57
+ t.Logf("VM final lifecycle=%s readError=%v failed=%t", b, e, t.Failed())
58
+ if t.Failed() {
59
+ traces, _ := filepath.Glob("/tmp/m1h-trace-*")
60
+ for _, path := range traces {
61
+ b, _ := os.ReadFile(path)
62
+ t.Logf("VM trace %s: %s", path, b)
63
+ }
64
+ }
65
+ })
66
+ exe := filepath.Join(c.StateDir, "payload-"+digest)
67
+ b, err := os.ReadFile(source)
68
+ if err != nil {
69
+ t.Fatal(err)
70
+ }
71
+ if err := os.WriteFile(exe, b, 0700); err != nil {
72
+ t.Fatal(err)
73
+ }
74
+ vmUnit(t, "start")
75
+ return LinuxProcesses{Client: c, Binary: exe}
76
+ }
77
+ func startVMHelper(t *testing.T, p LinuxProcesses) Process {
78
+ t.Helper()
79
+ ctl := Controller{Client: p.Client, Processes: p, Observe: observeLinux}
80
+ t.Cleanup(func() {
81
+ r, e := readRecord(p.StateDir, 0)
82
+ b, _ := json.Marshal(r)
83
+ t.Logf("VM pre-cleanup lifecycle=%s readError=%v failed=%t", b, e, t.Failed())
84
+ err := ctl.Control(context.Background(), "disable")
85
+ t.Logf("VM cleanup disable=%v", err)
86
+ if t.Failed() {
87
+ traces, _ := filepath.Glob("/tmp/m1h-trace-*")
88
+ for _, path := range traces {
89
+ b, _ := os.ReadFile(path)
90
+ t.Logf("VM trace %s: %s", path, b)
91
+ }
92
+ }
93
+ })
94
+ if err := ctl.Control(context.Background(), "enable"); err != nil {
95
+ t.Fatal(err)
96
+ }
97
+ record, err := readProcess(p.RunDir, 0)
98
+ if err != nil {
99
+ t.Fatal(err)
100
+ }
101
+ return record
102
+ }
103
+ func supervisedPID(t *testing.T, pid int) int {
104
+ t.Helper()
105
+ paths, _ := filepath.Glob("/proc/" + strconv.Itoa(pid) + "/task/*/children")
106
+ for _, path := range paths {
107
+ b, _ := os.ReadFile(path)
108
+ for _, s := range strings.Fields(string(b)) {
109
+ child, _ := strconv.Atoi(s)
110
+ if child > 1 {
111
+ return child
112
+ }
113
+ }
114
+ }
115
+ t.Fatal("supervisor has no child")
116
+ return 0
117
+ }
118
+
119
+ // Observation only: an absent process or zombie has exited. No signal is sent
120
+ // to this PID, including if it has been reused. These fixtures run in a fresh VM.
121
+ func waitPIDExit(t *testing.T, pid int) {
122
+ t.Helper()
123
+ ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
124
+ defer cancel()
125
+ if waitHealthy(ctx, func(context.Context) bool {
126
+ b, err := os.ReadFile("/proc/" + strconv.Itoa(pid) + "/stat")
127
+ if os.IsNotExist(err) {
128
+ return true
129
+ }
130
+ end := strings.LastIndex(string(b), ") ")
131
+ return err == nil && end >= 0 && strings.HasPrefix(string(b)[end+2:], "Z ")
132
+ }) != nil {
133
+ t.Fatal("owned process survived")
134
+ }
135
+ }
136
+ func TestLinuxActivationAlwaysUsesSupervisorAndNormalStop(t *testing.T) {
137
+ p := linuxFixture(t)
138
+ for n := 0; n < 20; n++ {
139
+ t.Run("cycle-"+strconv.Itoa(n), func(t *testing.T) {
140
+ proc := startVMHelper(t, p)
141
+ if proc.Mode != "supervised" {
142
+ t.Fatalf("activation did not select supervisor: %+v", proc)
143
+ }
144
+ child := supervisedPID(t, proc.PID)
145
+ if p.Status(context.Background()).State != "ready" {
146
+ t.Fatal("missing live handshake")
147
+ }
148
+ if err := (Controller{Client: p.Client, Processes: p, Observe: observeLinux}).Control(context.Background(), "disable"); err != nil {
149
+ t.Fatal(err)
150
+ }
151
+ waitPIDExit(t, child)
152
+ if err := p.CheckStopped(context.Background()); err != nil {
153
+ t.Fatal(err)
154
+ }
155
+ })
156
+ }
157
+ }
158
+
159
+ func TestLinuxHelperSelfExitIsReapedWithoutSignallingReusedPID(t *testing.T) {
160
+ p := linuxFixture(t)
161
+ proc := startVMHelper(t, p)
162
+ if proc.Mode != "supervised" {
163
+ t.Fatal("not supervised")
164
+ }
165
+ child := supervisedPID(t, proc.PID)
166
+ // The VM-only helper fixture exits itself when this root-owned marker exists.
167
+ if err := os.WriteFile(filepath.Join(p.RunDir, "fixture-exit"), nil, 0600); err != nil {
168
+ t.Fatal(err)
169
+ }
170
+ waitPIDExit(t, child)
171
+ ctx, cancel := context.WithTimeout(context.Background(), time.Second)
172
+ defer cancel()
173
+ if waitHealthy(ctx, func(context.Context) bool {
174
+ _, err := os.Stat("/proc/" + strconv.Itoa(child))
175
+ return os.IsNotExist(err)
176
+ }) != nil {
177
+ t.Fatal("supervisor did not reap")
178
+ }
179
+ if err := p.Stop(proc); err != nil {
180
+ t.Fatal(err)
181
+ }
182
+ }
183
+ func TestLinuxSupervisorDeathKillsHelperAndPreservesFailedCleanup(t *testing.T) {
184
+ p := linuxFixture(t)
185
+ record(t, p.Client, Record{Inventory: p.Expected, Enabled: true, Lifecycle: vmLifecycle(t, p)})
186
+ // Keep the supervisor as our own unreaped child; only its parent signals it.
187
+ cmd := exec.Command(p.Binary, "supervise")
188
+ if err := cmd.Start(); err != nil {
189
+ t.Fatal(err)
190
+ }
191
+ owned := &ownedLinuxChild{process: cmd.Process}
192
+ t.Cleanup(func() { stopChild(context.Background(), owned, time.Millisecond) })
193
+ ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
194
+ err := waitHealthy(ctx, func(ctx context.Context) bool { return p.Status(ctx).State == "ready" })
195
+ cancel()
196
+ if err != nil {
197
+ t.Fatal(err)
198
+ }
199
+ proc, err := readProcess(p.RunDir, 0)
200
+ if err != nil || proc.Mode != "supervised" || proc.PID != cmd.Process.Pid {
201
+ t.Fatalf("%+v %v", proc, err)
202
+ }
203
+ child := supervisedPID(t, proc.PID)
204
+ if err := owned.signal(syscall.SIGKILL); err != nil {
205
+ t.Fatal(err)
206
+ }
207
+ waitPIDExit(t, child)
208
+ waitPIDExit(t, proc.PID)
209
+ ctl := Controller{Client: p.Client, Processes: p, Observe: observeLinux}
210
+ if ctl.Control(context.Background(), "teardown") == nil {
211
+ t.Fatal("lost supervisor falsely cleaned")
212
+ }
213
+ s := p.Status(context.Background())
214
+ if s.State != "failed" || s.Cleanup != "required" {
215
+ t.Fatal(s)
216
+ }
217
+ if ctl.Control(context.Background(), "disable") == nil {
218
+ t.Fatal("lost supervisor falsely disabled cleanly")
219
+ }
220
+ r, err := readRecord(p.StateDir, 0)
221
+ if err != nil || r.Enabled || !r.Residual {
222
+ t.Fatalf("%+v %v", r, err)
223
+ }
224
+ if _, err := os.Stat(filepath.Join(p.RunDir, "process.json")); err != nil {
225
+ t.Fatal("failure evidence removed")
226
+ }
227
+ }
228
+ func TestLinuxUnsupervisedRecordAndDirectServeRefuse(t *testing.T) {
229
+ p := linuxFixture(t)
230
+ proc := startVMHelper(t, p)
231
+ for _, mode := range []string{"", "unknown"} {
232
+ foreign := proc
233
+ foreign.Mode = mode
234
+ if p.Stop(foreign) == nil {
235
+ t.Fatal("unsupervised record accepted")
236
+ }
237
+ }
238
+ // Remove stopped sockets before testing the retired action, so a bind
239
+ // conflict cannot masquerade as refusal of unsupervised startup.
240
+ if err := (Controller{Client: p.Client, Processes: p, Observe: observeLinux}).Control(context.Background(), "teardown"); err != nil {
241
+ t.Fatal(err)
242
+ }
243
+ ctx, cancel := context.WithTimeout(context.Background(), time.Second)
244
+ defer cancel()
245
+ cmd := exec.CommandContext(ctx, p.Binary, "serve")
246
+ if cmd.Run() == nil || ctx.Err() != nil {
247
+ t.Fatal("direct unsupervised serve accepted")
248
+ }
249
+ if _, err := os.Stat(filepath.Join(p.RunDir, "helper.sock")); !os.IsNotExist(err) {
250
+ t.Fatal("direct serve opened socket")
251
+ }
252
+ }
253
+
254
+ func TestLinuxOwnedChildSelfExitAndECHILDRefusal(t *testing.T) {
255
+ for _, externallyReaped := range []bool{false, true} {
256
+ cmd := exec.Command("/bin/sh", "-c", "exit 0")
257
+ if err := cmd.Start(); err != nil {
258
+ t.Fatal(err)
259
+ }
260
+ child := &ownedLinuxChild{process: cmd.Process}
261
+ if externallyReaped {
262
+ if err := cmd.Wait(); err != nil {
263
+ t.Fatal(err)
264
+ }
265
+ if err := stopChild(context.Background(), child, time.Millisecond); !errors.Is(err, syscall.ECHILD) {
266
+ t.Fatal("ECHILD did not refuse", err)
267
+ }
268
+ } else {
269
+ ctx, cancel := context.WithTimeout(context.Background(), time.Second)
270
+ err := waitHealthy(ctx, func(context.Context) bool { done, err := child.exited(); return done && err == nil })
271
+ cancel()
272
+ if err != nil {
273
+ t.Fatal(err)
274
+ }
275
+ if err := stopChild(context.Background(), child, time.Millisecond); err != nil {
276
+ t.Fatal(err)
277
+ }
278
+ if child.signal(syscall.SIGTERM) == nil {
279
+ t.Fatal("reaped PID signalled")
280
+ }
281
+ }
282
+ }
283
+ }
284
+ func TestLinuxSupervisorIdentityConflictsAndSocketSubstitutionRefuse(t *testing.T) {
285
+ p := linuxFixture(t)
286
+ proc := startVMHelper(t, p)
287
+ for _, field := range []string{"boot", "start", "inode", "digest", "mode"} {
288
+ foreign := proc
289
+ switch field {
290
+ case "boot":
291
+ foreign.Boot = "reboot"
292
+ case "start":
293
+ foreign.Start = "reuse"
294
+ case "inode":
295
+ foreign.Inode++
296
+ case "digest":
297
+ foreign.Inventory.PayloadDigest = strings.Repeat("c", 64)
298
+ case "mode":
299
+ foreign.Mode = "unknown"
300
+ }
301
+ if p.Stop(foreign) == nil {
302
+ t.Fatal("foreign supervisor accepted", field)
303
+ }
304
+ }
305
+ socket := filepath.Join(p.RunDir, "supervisor.sock")
306
+ old := socket + ".owned"
307
+ if err := os.Rename(socket, old); err != nil {
308
+ t.Fatal(err)
309
+ }
310
+ fake, err := net.ListenUnix("unix", &net.UnixAddr{Name: socket, Net: "unix"})
311
+ if err != nil {
312
+ t.Fatal(err)
313
+ }
314
+ if err := os.Chmod(socket, 0600); err != nil {
315
+ t.Fatal(err)
316
+ }
317
+ if p.Stop(proc) == nil {
318
+ t.Fatal("other root PID substituted supervisor")
319
+ }
320
+ fake.Close()
321
+ if err := os.Rename(old, socket); err != nil {
322
+ t.Fatal(err)
323
+ }
324
+ if p.Status(context.Background()).State != "ready" {
325
+ t.Fatal("refusal stopped real helper")
326
+ }
327
+ if err := p.Stop(proc); err != nil {
328
+ t.Fatal(err)
329
+ }
330
+ }
331
+ func TestLinuxReparentedChildRefusesBeforeSocket(t *testing.T) {
332
+ p := linuxFixture(t)
333
+ record(t, p.Client, Record{Inventory: p.Expected, Enabled: true, Lifecycle: vmLifecycle(t, p)})
334
+ cmd := exec.Command(p.Binary, "serve-child")
335
+ cmd.Env = []string{"PATH=/usr/sbin:/usr/bin:/sbin:/bin", "SYNOPKGLAND_PARENT=1"}
336
+ if cmd.Run() == nil {
337
+ t.Fatal("already reparented child served")
338
+ }
339
+ if _, err := os.Stat(filepath.Join(p.RunDir, "helper.sock")); !os.IsNotExist(err) {
340
+ t.Fatal("unsafe child opened socket")
341
+ }
342
+ }
343
+
344
+ func vmUnit(t *testing.T, action string) {
345
+ t.Helper()
346
+ if out, err := exec.Command("/bin/systemctl", action, "pkgctl-root.service").CombinedOutput(); err != nil {
347
+ t.Fatalf("systemctl %s: %v %s", action, err, out)
348
+ }
349
+ }
350
+
351
+ // Run the generated M1f hook as an unprivileged user against the real M1g
352
+ // helper. The VM models management ordering, not DSM Package Center itself.
353
+ func TestLinuxPrestopRequiresAdminTeardownAndPrestartNeverRecovers(t *testing.T) {
354
+ p := linuxFixture(t)
355
+ for _, dir := range []string{p.StateDir, p.RunDir} {
356
+ if err := os.Chmod(dir, 0755); err != nil {
357
+ t.Fatal(err)
358
+ }
359
+ }
360
+ proc := startVMHelper(t, p)
361
+ child := supervisedPID(t, proc.PID)
362
+ log := "/tmp/m1f-prestop-message"
363
+ if err := os.WriteFile(log, nil, 0600); err != nil {
364
+ t.Fatal(err)
365
+ }
366
+ if err := os.Chown(log, 65534, 65534); err != nil {
367
+ t.Fatal(err)
368
+ }
369
+ t.Cleanup(func() { os.Remove(log) })
370
+ hook := func(action string, allow bool) {
371
+ t.Helper()
372
+ before, err := os.ReadFile(filepath.Join(p.StateDir, "approval.json"))
373
+ if err != nil {
374
+ t.Fatal(err)
375
+ }
376
+ if err := os.Truncate(log, 0); err != nil {
377
+ t.Fatal(err)
378
+ }
379
+ cmd := exec.Command("/var/packages/root/scripts/start-stop-status", action)
380
+ cmd.Env = append(os.Environ(), "SYNOPKG_TEMP_LOGFILE="+log)
381
+ cmd.SysProcAttr = &syscall.SysProcAttr{Credential: &syscall.Credential{Uid: 65534, Gid: 65534}}
382
+ out, err := cmd.CombinedOutput()
383
+ if (err == nil) != allow {
384
+ t.Fatalf("%s allow=%v: %v %s", action, allow, err, out)
385
+ }
386
+ if !allow {
387
+ message, err := os.ReadFile(log)
388
+ if err != nil || string(message) != string(out) || !strings.Contains(string(out), "helper_teardown") {
389
+ t.Fatalf("missing DSM refusal message: %v %s %s", err, out, message)
390
+ }
391
+ }
392
+ after, err := os.ReadFile(filepath.Join(p.StateDir, "approval.json"))
393
+ if err != nil || string(before) != string(after) {
394
+ t.Fatal("nonprivileged hook changed lifecycle latch", err)
395
+ }
396
+ }
397
+ hook("prestop", false)
398
+ if _, err := observeLinux(context.Background(), p.Expected); err != nil {
399
+ t.Fatal("prestop refusal changed active unit", err)
400
+ }
401
+ current, err := readProcess(p.RunDir, 0)
402
+ if err != nil || current != proc || p.Status(context.Background()).State != "ready" {
403
+ t.Fatal("prestop refusal stopped helper", err)
404
+ }
405
+ hook("prestart", true)
406
+ ctl := Controller{Client: p.Client, Processes: p, Observe: observeLinux}
407
+ if err := ctl.Control(context.Background(), "teardown"); err != nil {
408
+ t.Fatal(err)
409
+ }
410
+ waitPIDExit(t, child)
411
+ waitPIDExit(t, proc.PID)
412
+ hook("prestop", true)
413
+ vmUnit(t, "stop")
414
+ hook("stop", true)
415
+ vmUnit(t, "start")
416
+ hook("prestart", true)
417
+ hook("start", true)
418
+ if p.Status(context.Background()).State != "stopped" || !runtimeAbsent(p.Client) {
419
+ t.Fatal("package Start recovered integration")
420
+ }
421
+ stopped, err := readRecord(p.StateDir, 0)
422
+ if err != nil {
423
+ t.Fatal(err)
424
+ }
425
+ incomplete := stopped
426
+ incomplete.Residual = true
427
+ record(t, p.Client, incomplete)
428
+ hook("prestop", false)
429
+ hook("prestart", true)
430
+ record(t, p.Client, stopped)
431
+ if err := ctl.Control(context.Background(), "recover"); err != nil {
432
+ t.Fatal(err)
433
+ }
434
+ recovered, err := readRecord(p.StateDir, 0)
435
+ if err != nil || recovered.Lifecycle.Epoch == stopped.Lifecycle.Epoch || p.Status(context.Background()).State != "ready" {
436
+ t.Fatal("explicit Recover failed", err)
437
+ }
438
+ if err := ctl.Control(context.Background(), "disable"); err != nil {
439
+ t.Fatal(err)
440
+ }
441
+ hook("prestop", true)
442
+ hook("prestart", true)
443
+ if p.Status(context.Background()).State != "not-enabled" || !runtimeAbsent(p.Client) {
444
+ t.Fatal("prestart cleared disabled gate")
445
+ }
446
+ }
447
+
448
+ func vmLifecycle(t *testing.T, p LinuxProcesses) *Lifecycle {
449
+ t.Helper()
450
+ b, err := observeLinux(context.Background(), p.Expected)
451
+ if err != nil {
452
+ t.Fatal(err)
453
+ }
454
+ l, err := newLifecycle(b)
455
+ if err != nil {
456
+ t.Fatal(err)
457
+ }
458
+ if err := createLifetime(p.Client, l); err != nil {
459
+ t.Fatal(err)
460
+ }
461
+ return l
462
+ }
463
+
464
+ func TestLinuxUnitStopFencesBeforeLockAndPublishesCompletion(t *testing.T) {
465
+ p := linuxFixture(t)
466
+ proc := startVMHelper(t, p)
467
+ child := supervisedPID(t, proc.PID)
468
+ lock, err := os.OpenFile(filepath.Join(p.StateDir, "policy.lock"), os.O_RDWR, 0600)
469
+ if err != nil {
470
+ t.Fatal(err)
471
+ }
472
+ defer lock.Close()
473
+ if err := syscall.Flock(int(lock.Fd()), syscall.LOCK_EX); err != nil {
474
+ t.Fatal(err)
475
+ }
476
+ vmUnit(t, "stop")
477
+ ctx, cancel := context.WithTimeout(context.Background(), time.Second)
478
+ err = waitHealthy(ctx, func(context.Context) bool {
479
+ s := p.Status(context.Background())
480
+ return s.State == "failed" && s.Cleanup == "required"
481
+ })
482
+ cancel()
483
+ syscall.Flock(int(lock.Fd()), syscall.LOCK_UN)
484
+ if err != nil {
485
+ t.Fatal("memory fence waited for policy lock", err)
486
+ }
487
+ ctx, cancel = context.WithTimeout(context.Background(), 3*time.Second)
488
+ defer cancel()
489
+ if waitHealthy(ctx, func(context.Context) bool {
490
+ r, e := readRecord(p.StateDir, 0)
491
+ return e == nil && !r.Residual && r.Lifecycle.Phase == "stopped" && r.Lifecycle.Completion != ""
492
+ }) != nil {
493
+ t.Fatal("completion missing")
494
+ }
495
+ r, _ := readRecord(p.StateDir, 0)
496
+ proof, e := completionRecord(p.Client, r)
497
+ if e != nil {
498
+ t.Fatal(e)
499
+ }
500
+ if proof.Process != proc {
501
+ t.Fatal("wrong completion identity", r)
502
+ }
503
+ waitPIDExit(t, child)
504
+ waitPIDExit(t, proc.PID)
505
+ if err := p.CheckStopped(context.Background()); err != nil {
506
+ t.Fatal(err)
507
+ }
508
+ ctl := Controller{Client: p.Client, Processes: p, Observe: observeLinux}
509
+ if ctl.Control(context.Background(), "recover") == nil {
510
+ t.Fatal("inactive unit recovered")
511
+ }
512
+ vmUnit(t, "start")
513
+ if p.Status(context.Background()).State != "stopped" {
514
+ t.Fatal("unit Start resurrected integration")
515
+ }
516
+ if err := ctl.Control(context.Background(), "recover"); err != nil {
517
+ t.Fatal(err)
518
+ }
519
+ next, _ := readRecord(p.StateDir, 0)
520
+ if next.Lifecycle.Epoch == r.Lifecycle.Epoch || p.Status(context.Background()).State != "ready" {
521
+ t.Fatal("explicit recovery failed")
522
+ }
523
+ }
524
+ func TestLinuxRapidUnitStopStartNeverClearsFence(t *testing.T) {
525
+ p := linuxFixture(t)
526
+ proc := startVMHelper(t, p)
527
+ vmUnit(t, "stop")
528
+ vmUnit(t, "start")
529
+ ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
530
+ defer cancel()
531
+ if waitHealthy(ctx, func(context.Context) bool {
532
+ r, e := readRecord(p.StateDir, 0)
533
+ return e == nil && r.Lifecycle.Phase == "stopped" && !r.Residual
534
+ }) != nil {
535
+ t.Fatal("rapid transition missed")
536
+ }
537
+ waitPIDExit(t, proc.PID)
538
+ if p.Status(context.Background()).State != "stopped" {
539
+ t.Fatal("rapid Start resurrected")
540
+ }
541
+ }
542
+ func TestLinuxBusUnavailableRefusesActivation(t *testing.T) {
543
+ p := linuxFixture(t)
544
+ socket := busPath
545
+ if err := os.Rename(socket, socket+".fixture"); err != nil {
546
+ t.Fatal(err)
547
+ }
548
+ defer os.Rename(socket+".fixture", socket)
549
+ ctl := Controller{Client: p.Client, Processes: p, Observe: observeLinux}
550
+ if ctl.Control(context.Background(), "enable") == nil {
551
+ t.Fatal("activation without bus")
552
+ }
553
+ if !runtimeAbsent(p.Client) {
554
+ t.Fatal("unknown authority spawned runtime")
555
+ }
556
+ }
557
+
558
+ func TestLinuxRealOldPayloadReplayRefusesNewApproval(t *testing.T) {
559
+ p := linuxFixture(t)
560
+ _ = startVMHelper(t, p)
561
+ if err := (Controller{Client: p.Client, Processes: p, Observe: observeLinux}).Control(context.Background(), "teardown"); err != nil {
562
+ t.Fatal(err)
563
+ }
564
+ before, err := os.ReadFile(filepath.Join(p.StateDir, "approval.json"))
565
+ if err != nil {
566
+ t.Fatal(err)
567
+ }
568
+ digest, err := executableDigest("/helper-legacy")
569
+ if err != nil {
570
+ t.Fatal(err)
571
+ }
572
+ path := filepath.Join(p.StateDir, "payload-"+digest)
573
+ b, err := os.ReadFile("/helper-legacy")
574
+ if err != nil {
575
+ t.Fatal(err)
576
+ }
577
+ if err := os.WriteFile(path, b, 0700); err != nil {
578
+ t.Fatal(err)
579
+ }
580
+ for _, action := range []string{"enable", "recover", "supervise"} {
581
+ if out, err := exec.Command(path, action).CombinedOutput(); err == nil {
582
+ t.Fatalf("old payload replayed %s %s", action, out)
583
+ }
584
+ }
585
+ after, _ := os.ReadFile(filepath.Join(p.StateDir, "approval.json"))
586
+ if string(before) != string(after) || !runtimeAbsent(p.Client) {
587
+ t.Fatal("old payload changed latch")
588
+ }
589
+ }
590
+ func TestLinuxBusRestartFencesAndCompletesRuntime(t *testing.T) {
591
+ p := linuxFixture(t)
592
+ proc := startVMHelper(t, p)
593
+ if out, err := exec.Command("/bin/systemctl", "restart", "dbus.service").CombinedOutput(); err != nil {
594
+ t.Fatal(err, string(out))
595
+ }
596
+ ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
597
+ defer cancel()
598
+ if waitHealthy(ctx, func(context.Context) bool {
599
+ r, e := readRecord(p.StateDir, 0)
600
+ return e == nil && r.Lifecycle.Phase == "stopped" && !r.Residual && r.Lifecycle.Completion != ""
601
+ }) != nil {
602
+ t.Fatal("bus loss did not complete")
603
+ }
604
+ waitPIDExit(t, proc.PID)
605
+ if p.Status(context.Background()).State != "stopped" {
606
+ t.Fatal("bus reconnection revived helper")
607
+ }
608
+ }
609
+
610
+ func TestLinuxLostSupervisorRepairThenExplicitRecover(t *testing.T) {
611
+ p := linuxFixture(t)
612
+ record(t, p.Client, Record{Inventory: p.Expected, Enabled: true, Lifecycle: vmLifecycle(t, p)})
613
+ cmd := exec.Command(p.Binary, "supervise")
614
+ if err := cmd.Start(); err != nil {
615
+ t.Fatal(err)
616
+ }
617
+ owned := &ownedLinuxChild{process: cmd.Process}
618
+ t.Cleanup(func() { stopChild(context.Background(), owned, time.Millisecond) })
619
+ ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
620
+ err := waitHealthy(ctx, func(ctx context.Context) bool { return p.Status(ctx).State == "ready" })
621
+ cancel()
622
+ if err != nil {
623
+ t.Fatal(err)
624
+ }
625
+ proc, err := readProcess(p.RunDir, 0)
626
+ if err != nil {
627
+ t.Fatal(err)
628
+ }
629
+ child := supervisedPID(t, proc.PID)
630
+ ctl := Controller{Client: p.Client, Processes: p, Observe: observeLinux}
631
+ if ctl.Control(context.Background(), "repair") == nil {
632
+ t.Fatal("repaired live supervisor")
633
+ }
634
+ if p.Status(context.Background()).State != "ready" {
635
+ t.Fatal("busy repair fenced active helper")
636
+ }
637
+ if err := owned.signal(syscall.SIGKILL); err != nil {
638
+ t.Fatal(err)
639
+ }
640
+ waitPIDExit(t, proc.PID)
641
+ waitPIDExit(t, child)
642
+ if ctl.Control(context.Background(), "recover") == nil {
643
+ t.Fatal("loss recovered without repair")
644
+ }
645
+ if err := ctl.Control(context.Background(), "repair"); err != nil {
646
+ t.Fatal(err)
647
+ }
648
+ repaired, err := readRecord(p.StateDir, 0)
649
+ if err != nil || repaired.Residual || repaired.Lifecycle.Completion == "" || p.Status(context.Background()).State != "stopped" {
650
+ t.Fatal("repair not committed", err)
651
+ }
652
+ proof, err := completionRecord(p.Client, repaired)
653
+ if err != nil || proof.Repair == nil || !runtimeAbsent(p.Client) {
654
+ t.Fatal("no repair proof", err)
655
+ }
656
+ if err := ctl.Control(context.Background(), "repair"); err != nil {
657
+ t.Fatal(err)
658
+ }
659
+ if err := ctl.Control(context.Background(), "recover"); err != nil {
660
+ t.Fatal(err)
661
+ }
662
+ next, _ := readRecord(p.StateDir, 0)
663
+ if next.Lifecycle.Epoch == repaired.Lifecycle.Epoch || p.Status(context.Background()).State != "ready" {
664
+ t.Fatal("explicit recovery did not start new epoch")
665
+ }
666
+ t.Cleanup(func() { ctl.Control(context.Background(), "disable") })
667
+ // A package/nonroot process cannot use the executable repair entry.
668
+ for _, dir := range []string{p.StateDir, p.RunDir} {
669
+ if err := os.Chmod(dir, 0755); err != nil {
670
+ t.Fatal(err)
671
+ }
672
+ }
673
+ if err := os.Chmod(p.Binary, 0755); err != nil {
674
+ t.Fatal(err)
675
+ }
676
+ denied := exec.Command(p.Binary, "repair")
677
+ denied.SysProcAttr = &syscall.SysProcAttr{Credential: &syscall.Credential{Uid: 65534, Gid: 65534}}
678
+ output, err := denied.CombinedOutput()
679
+ if err == nil || !strings.Contains(string(output), "helper lifecycle refused") {
680
+ t.Fatal("package user did not reach euid refusal", err, string(output))
681
+ }
682
+
683
+ }
684
+
685
+ func TestLinuxInheritedLifetimePinsLockUntilLastHolderExit(t *testing.T) {
686
+ p := linuxFixture(t)
687
+ l := vmLifecycle(t, p)
688
+ lease, err := acquireLifetime(p.Client, l)
689
+ if err != nil {
690
+ t.Fatal(err)
691
+ }
692
+ cmd := exec.Command("/bin/sleep", "60")
693
+ cmd.ExtraFiles = []*os.File{lease}
694
+ if err := cmd.Start(); err != nil {
695
+ t.Fatal(err)
696
+ }
697
+ child := &ownedLinuxChild{process: cmd.Process}
698
+ t.Cleanup(func() { stopChild(context.Background(), child, time.Millisecond) })
699
+ // Model supervisor loss while the inherited child is still alive. No
700
+ // LOCK_UN: closing that would release the shared flock prematurely.
701
+ lease.Close()
702
+ if got, err := acquireLifetime(p.Client, l); err == nil {
703
+ got.Close()
704
+ t.Fatal("parent close released live child's witness")
705
+ }
706
+ if err := stopChild(context.Background(), child, time.Millisecond); err != nil {
707
+ t.Fatal(err)
708
+ }
709
+ got, err := acquireLifetime(p.Client, l)
710
+ if err != nil {
711
+ t.Fatal(err)
712
+ }
713
+ got.Close()
714
+ }
715
+
716
+ func TestLinuxPreR2PayloadReplayAndLateSupervisorRefuseRepairLatch(t *testing.T) {
717
+ p := linuxFixture(t)
718
+ record(t, p.Client, Record{Inventory: p.Expected, Enabled: true, Residual: true, Lifecycle: vmLifecycle(t, p)})
719
+ ctl := Controller{Client: p.Client, Processes: p, Observe: observeLinux}
720
+ // No process was started: the same lease also proves the startup crash gap.
721
+ if err := ctl.Control(context.Background(), "repair"); err != nil {
722
+ t.Fatal(err)
723
+ }
724
+ before, _ := os.ReadFile(filepath.Join(p.StateDir, "approval.json"))
725
+ if out, err := exec.Command(p.Binary, "supervise").CombinedOutput(); err == nil {
726
+ t.Fatal("late supervisor crossed repair latch", string(out))
727
+ }
728
+ for _, source := range []string{"/helper-pre-r2", "/helper-m1d"} {
729
+ digest, err := executableDigest(source)
730
+ if err != nil {
731
+ t.Fatal(err)
732
+ }
733
+ bytes, err := os.ReadFile(source)
734
+ if err != nil {
735
+ t.Fatal(err)
736
+ }
737
+ path := filepath.Join(p.StateDir, "payload-"+digest)
738
+ if err := os.WriteFile(path, bytes, 0700); err != nil {
739
+ t.Fatal(err)
740
+ }
741
+ for _, action := range []string{"enable", "recover", "supervise", "disable", "teardown"} {
742
+ if out, err := exec.Command(path, action).CombinedOutput(); err == nil {
743
+ t.Fatal("old payload crossed repair schema", source, action, string(out))
744
+ }
745
+ }
746
+ }
747
+ after, _ := os.ReadFile(filepath.Join(p.StateDir, "approval.json"))
748
+ if string(before) != string(after) || !runtimeAbsent(p.Client) {
749
+ t.Fatal("replay altered completion")
750
+ }
751
+ }
752
+
753
+ func TestLinuxActualM1dLostSupervisorResidueCannotGainRepairWitness(t *testing.T) {
754
+ p := linuxFixture(t)
755
+ digest, err := executableDigest("/helper-m1d")
756
+ if err != nil {
757
+ t.Fatal(err)
758
+ }
759
+ old := p
760
+ old.Expected.PayloadDigest = digest
761
+ old.Binary = filepath.Join(p.StateDir, "payload-"+digest)
762
+ bytes, err := os.ReadFile("/helper-m1d")
763
+ if err != nil {
764
+ t.Fatal(err)
765
+ }
766
+ if err := os.WriteFile(old.Binary, bytes, 0700); err != nil {
767
+ t.Fatal(err)
768
+ }
769
+ record(t, p.Client, Record{Inventory: old.Expected, Enabled: true})
770
+ cmd := exec.Command(old.Binary, "supervise")
771
+ if err := cmd.Start(); err != nil {
772
+ t.Fatal(err)
773
+ }
774
+ owned := &ownedLinuxChild{process: cmd.Process}
775
+ t.Cleanup(func() { stopChild(context.Background(), owned, time.Millisecond) })
776
+ ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
777
+ err = waitHealthy(ctx, func(ctx context.Context) bool { return old.Status(ctx).State == "ready" })
778
+ cancel()
779
+ if err != nil {
780
+ t.Fatal(err)
781
+ }
782
+ proc, err := readProcess(p.RunDir, 0)
783
+ if err != nil {
784
+ t.Fatal(err)
785
+ }
786
+ child := supervisedPID(t, proc.PID)
787
+ if err := owned.signal(syscall.SIGKILL); err != nil {
788
+ t.Fatal(err)
789
+ }
790
+ waitPIDExit(t, proc.PID)
791
+ waitPIDExit(t, child)
792
+ // Mimic an upgraded controller; it must not create a new lock as purported
793
+ // historical proof, even though both observed PIDs have exited in this VM.
794
+ ctl := Controller{Client: p.Client, Processes: p, Observe: observeLinux}
795
+ if ctl.Control(context.Background(), "repair") == nil {
796
+ t.Fatal("upgraded helper repaired unwitnessed legacy residue")
797
+ }
798
+ for _, name := range []string{"helper.sock", "supervisor.sock", "process.json"} {
799
+ if _, err := os.Lstat(filepath.Join(p.RunDir, name)); err != nil {
800
+ t.Fatal("legacy evidence removed", name, err)
801
+ }
802
+ }
803
+ leases, _ := filepath.Glob(filepath.Join(p.StateDir, "lifetime-*.lock"))
804
+ if len(leases) != 0 {
805
+ t.Fatal("retroactively manufactured witness", leases)
806
+ }
807
+ }
808
+
809
+ func TestLinuxAdminTeardownSnapshotRace(t *testing.T) {
810
+ p := linuxFixture(t)
811
+ proc := startVMHelper(t, p)
812
+ child := supervisedPID(t, proc.PID)
813
+ ctl := Controller{Client: p.Client, Processes: p, Observe: observeLinux, Boot: linuxBoot}
814
+ // Capture the fenced snapshot inside the policy transaction, before the
815
+ // owner can complete it. Then deliberately let the real owner win the race.
816
+ var before Record
817
+ if err := policyUpdate(p.Client, func(r *Record) error {
818
+ r.Lifecycle.Phase = "fenced"
819
+ r.Lifecycle.Reason = "admin-stop"
820
+ r.Residual = true
821
+ before = *r
822
+ return nil
823
+ }); err != nil {
824
+ t.Fatal(err)
825
+ }
826
+ ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
827
+ defer cancel()
828
+ if waitHealthy(ctx, func(context.Context) bool {
829
+ r, e := readRecord(p.StateDir, 0)
830
+ if e != nil {
831
+ return false
832
+ }
833
+ proof, e := completionRecord(p.Client, r)
834
+ return e == nil && proof.Process == proc && runtimeAbsent(p.Client)
835
+ }) != nil {
836
+ t.Fatal("owner did not commit autonomous admin-stop")
837
+ }
838
+ waitPIDExit(t, child)
839
+ waitPIDExit(t, proc.PID)
840
+ if err := ctl.teardownRecord(before, proc); err != nil {
841
+ t.Fatal("exact committed completion rejected after approval snapshot", err)
842
+ }
843
+ }
844
+
845
+ type pausedCompletionProcesses struct {
846
+ LinuxProcesses
847
+ visible string
848
+ }
849
+
850
+ func (p pausedCompletionProcesses) Stop(proc Process) error {
851
+ ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
852
+ defer cancel()
853
+ if err := waitHealthy(ctx, func(context.Context) bool {
854
+ _, err := os.Stat(p.visible)
855
+ return err == nil
856
+ }); err != nil {
857
+ return err
858
+ }
859
+ // Exercise the real socket/identity path after autonomous runtime unlink.
860
+ return p.LinuxProcesses.Stop(proc)
861
+ }
862
+
863
+ func TestLinuxControllerWaitsForRealCompletionPublisher(t *testing.T) {
864
+ p := linuxFixture(t)
865
+ proc := startVMHelper(t, p)
866
+ child := supervisedPID(t, proc.PID)
867
+ hold := filepath.Join(p.StateDir, "fixture-hold-completion")
868
+ if err := os.WriteFile(hold, []byte("pause publisher after approval rename"), 0600); err != nil {
869
+ t.Fatal(err)
870
+ }
871
+ defer func() {
872
+ os.Remove(hold) // disposable VM fixture only; never a NAS operation
873
+ waitPIDExit(t, child)
874
+ waitPIDExit(t, proc.PID)
875
+ }()
876
+ result := make(chan error, 1)
877
+ go func() {
878
+ processes := pausedCompletionProcesses{LinuxProcesses: p, visible: filepath.Join(p.StateDir, "fixture-completion-visible")}
879
+ result <- (Controller{Client: p.Client, Processes: processes, Observe: observeLinux, Boot: linuxBoot}).Control(context.Background(), "teardown")
880
+ }()
881
+ ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
882
+ defer cancel()
883
+ if waitHealthy(ctx, func(context.Context) bool {
884
+ _, visible := os.Stat(filepath.Join(p.StateDir, "fixture-completion-visible"))
885
+ r, e := readRecord(p.StateDir, 0)
886
+ if visible != nil || e != nil {
887
+ return false
888
+ }
889
+ proof, e := completionRecord(p.Client, r)
890
+ return e == nil && proof.Process == proc && runtimeAbsent(p.Client)
891
+ }) != nil {
892
+ t.Fatal("real supervisor did not publish while holding policy.lock")
893
+ }
894
+ select {
895
+ case err := <-result:
896
+ t.Fatal("controller returned before publisher unlocked", err)
897
+ case <-time.After(100 * time.Millisecond):
898
+ }
899
+ if err := os.Remove(hold); err != nil {
900
+ t.Fatal(err)
901
+ }
902
+ select {
903
+ case err := <-result:
904
+ if err != nil {
905
+ t.Fatal("real committed completion refused after publisher unlock", err)
906
+ }
907
+ case <-ctx.Done():
908
+ t.Fatal("controller did not finish after publisher unlock")
909
+ }
910
+ if err := p.CheckStopped(context.Background()); err != nil {
911
+ t.Fatal(err)
912
+ }
913
+ }