@synopackageland/cli 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (631) hide show
  1. package/README.md +7 -3
  2. package/dist/build-spk/delete-app-data.d.ts +27 -7
  3. package/dist/build-spk/delete-app-data.js +35 -34
  4. package/dist/build-spk/dsm-arch.d.ts +6 -1
  5. package/dist/build-spk/dsm-arch.js +25 -1
  6. package/dist/build-spk/dsm-version.d.ts +14 -0
  7. package/dist/build-spk/dsm-version.js +47 -0
  8. package/dist/build-spk/gateway.d.ts +31 -0
  9. package/dist/build-spk/gateway.js +55 -0
  10. package/dist/build-spk/generator.d.ts +5 -0
  11. package/dist/build-spk/generator.js +103 -107
  12. package/dist/build-spk/install-wizard.d.ts +20 -0
  13. package/dist/build-spk/install-wizard.js +76 -0
  14. package/dist/build-spk/native-lifecycle.d.ts +5 -0
  15. package/dist/build-spk/native-lifecycle.js +12 -2
  16. package/dist/build-spk/resource-worker.d.ts +9 -4
  17. package/dist/build-spk/resource-worker.js +15 -6
  18. package/dist/build-spk/share-combobox.d.ts +3 -0
  19. package/dist/build-spk/share-combobox.js +27 -0
  20. package/dist/build-spk/uninstall-wizard.d.ts +14 -0
  21. package/dist/build-spk/uninstall-wizard.js +33 -0
  22. package/dist/build-spk/wizard-i18n.d.ts +18 -0
  23. package/dist/build-spk/wizard-i18n.js +38 -0
  24. package/dist/build-spk/wizard-messages.d.ts +388 -0
  25. package/dist/build-spk/wizard-messages.js +387 -0
  26. package/dist/cli.js +130 -30
  27. package/dist/compose/analyze.d.ts +20 -0
  28. package/dist/compose/analyze.js +75 -11
  29. package/dist/contract/validate.js +33 -1
  30. package/dist/contract/web-launch.d.ts +22 -0
  31. package/dist/contract/web-launch.js +37 -0
  32. package/dist/deploy/deploy.d.ts +3 -0
  33. package/dist/deploy/deploy.js +11 -2
  34. package/dist/error-registry.js +60 -1
  35. package/dist/host/open-url.d.ts +2 -0
  36. package/dist/host/open-url.js +4 -1
  37. package/dist/images/pin.d.ts +52 -0
  38. package/dist/images/pin.js +249 -0
  39. package/dist/init.d.ts +27 -3
  40. package/dist/init.js +104 -15
  41. package/dist/inspect.d.ts +3 -0
  42. package/dist/inspect.js +15 -3
  43. package/dist/standalone/background.d.ts +21 -0
  44. package/dist/standalone/background.js +52 -0
  45. package/dist/standalone/binary.d.ts +1 -0
  46. package/dist/standalone/binary.js +1 -1
  47. package/dist/standalone/build.d.ts +2 -0
  48. package/dist/standalone/build.js +38 -6
  49. package/dist/standalone/dsm-window.js +2 -2
  50. package/dist/standalone/helper-inventory.d.ts +15 -0
  51. package/dist/standalone/helper-inventory.js +9 -0
  52. package/dist/standalone/helper.d.ts +1 -0
  53. package/dist/standalone/helper.js +28 -10
  54. package/dist/standalone/host-adapter.d.ts +1 -1
  55. package/dist/standalone/host-adapter.js +33 -15
  56. package/dist/standalone/host-file-navigation.d.ts +7 -0
  57. package/dist/standalone/host-file-navigation.js +172 -0
  58. package/dist/standalone/inspect-helper.js +9 -4
  59. package/dist/standalone/inspect-spk.d.ts +1 -1
  60. package/dist/standalone/inspect-spk.js +200 -7
  61. package/dist/standalone/job-diagnostics.d.ts +1 -0
  62. package/dist/standalone/job-diagnostics.js +49 -0
  63. package/dist/standalone/lifecycle.js +12 -2
  64. package/dist/standalone/manifest.d.ts +15 -2
  65. package/dist/standalone/manifest.js +37 -6
  66. package/dist/standalone/native-layout.d.ts +74 -0
  67. package/dist/standalone/native-layout.js +318 -0
  68. package/dist/standalone/resource.d.ts +11 -0
  69. package/dist/standalone/resource.js +13 -0
  70. package/dist/standalone/root-window.d.ts +3 -1
  71. package/dist/standalone/root-window.js +156 -38
  72. package/dist/standalone/shared-folder.d.ts +39 -0
  73. package/dist/standalone/shared-folder.js +141 -0
  74. package/dist/standalone/spk.d.ts +2 -0
  75. package/dist/standalone/spk.js +33 -3
  76. package/dist/standalone/worker-contract-json.d.ts +8 -0
  77. package/dist/standalone/worker-contract-json.js +141 -0
  78. package/dist/standalone/worker-contract.d.ts +189 -0
  79. package/dist/standalone/worker-contract.js +175 -0
  80. package/dist/standalone/worker-registry.d.ts +40 -0
  81. package/dist/standalone/worker-registry.js +167 -0
  82. package/dist/templates/_daemon/go.mod +2 -0
  83. package/dist/templates/_gateway/auth.go +101 -0
  84. package/dist/templates/_gateway/auth_test.go +216 -0
  85. package/dist/templates/_gateway/cgi.go +133 -0
  86. package/dist/templates/_gateway/cgi_test.go +156 -0
  87. package/dist/templates/_gateway/csrf.go +73 -0
  88. package/dist/templates/_gateway/csrf_test.go +155 -0
  89. package/dist/templates/_gateway/directory.go +108 -0
  90. package/dist/templates/_gateway/directory_test.go +202 -0
  91. package/dist/templates/_gateway/gateway.go +412 -0
  92. package/dist/templates/_gateway/gateway_test.go +676 -0
  93. package/dist/templates/_gateway/go.mod +3 -0
  94. package/dist/templates/_gateway/groups.go +66 -0
  95. package/dist/templates/_gateway/main.go +45 -0
  96. package/dist/templates/binary/synology-app.yaml +1 -1
  97. package/dist/templates/compose-import/compose.yaml +1 -1
  98. package/dist/templates/compose-import/synology-app.yaml +1 -1
  99. package/dist/templates/hello-files/compose.yaml +1 -1
  100. package/dist/templates/hello-files/synology-app.yaml +1 -1
  101. package/dist/templates/hello-web/compose.yaml +5 -2
  102. package/dist/templates/hello-web/synology-app.yaml +4 -1
  103. package/dist/templates/hello-web-page/compose.yaml +5 -2
  104. package/dist/templates/hello-web-page/synology-app.yaml +4 -1
  105. package/dist/templates/native-go/README.md +93 -4
  106. package/dist/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +3 -1
  107. package/dist/templates/native-go/backend/cmd/app/main.go +17 -0
  108. package/dist/templates/native-go/backend/cmd/app/sdk_main.go +60 -0
  109. package/dist/templates/native-go/backend/cmd/background-worker/main.go +38 -0
  110. package/dist/templates/native-go/backend/cmd/helper/main.go +10 -1
  111. package/dist/templates/native-go/backend/cmd/helper/sdk_registry.go +19 -0
  112. package/dist/templates/native-go/backend/go.mod +5 -3
  113. package/dist/templates/native-go/backend/go.sum +4 -4
  114. package/dist/templates/native-go/backend/internal/api/registry.go +17 -6
  115. package/dist/templates/native-go/backend/internal/api/server.go +7 -1
  116. package/dist/templates/native-go/backend/internal/app/background.go +270 -0
  117. package/dist/templates/native-go/backend/internal/app/background_none.go +8 -0
  118. package/dist/templates/native-go/backend/internal/app/background_owner.go +59 -0
  119. package/dist/templates/native-go/backend/internal/app/background_owner_test.go +145 -0
  120. package/dist/templates/native-go/backend/internal/app/background_schedule.go +74 -0
  121. package/dist/templates/native-go/backend/internal/app/background_schedule_test.go +62 -0
  122. package/dist/templates/native-go/backend/internal/app/background_test.go +346 -0
  123. package/dist/templates/native-go/backend/internal/app/integration_state.go +16 -0
  124. package/dist/templates/native-go/backend/internal/app/migrations.go +41 -0
  125. package/dist/templates/native-go/backend/internal/app/migrations_test.go +41 -0
  126. package/dist/templates/native-go/backend/internal/app/nas_cgi_artifact_test.go +8 -0
  127. package/dist/templates/native-go/backend/internal/app/routes.go +17 -3
  128. package/dist/templates/native-go/backend/internal/app/routes_test.go +20 -3
  129. package/dist/templates/native-go/backend/internal/app/sdk_jobs.go +70 -0
  130. package/dist/templates/native-go/backend/internal/app/sdk_jobs_test.go +116 -0
  131. package/dist/templates/native-go/backend/internal/app/sdk_routes.go +174 -0
  132. package/dist/templates/native-go/backend/internal/app/session_files.go +15 -0
  133. package/dist/templates/native-go/backend/internal/app/session_files_test.go +26 -0
  134. package/dist/templates/native-go/backend/internal/app/shared_folder.go +144 -0
  135. package/dist/templates/native-go/backend/internal/app/shared_folder_test.go +158 -0
  136. package/dist/templates/native-go/backend/internal/background/access.go +57 -0
  137. package/dist/templates/native-go/backend/internal/background/owner_test.go +126 -0
  138. package/dist/templates/native-go/backend/internal/background/runner.go +185 -0
  139. package/dist/templates/native-go/backend/internal/background/runner_test.go +209 -0
  140. package/dist/templates/native-go/backend/internal/background/schedule.go +300 -0
  141. package/dist/templates/native-go/backend/internal/background/schedule_test.go +335 -0
  142. package/dist/templates/native-go/backend/internal/background/store.go +807 -0
  143. package/dist/templates/native-go/backend/internal/background/store_test.go +407 -0
  144. package/dist/templates/native-go/backend/internal/datamigrate/migrate.go +191 -0
  145. package/dist/templates/native-go/backend/internal/datamigrate/migrate_test.go +177 -0
  146. package/dist/templates/native-go/backend/internal/filestation/browse_test.go +67 -0
  147. package/dist/templates/native-go/backend/internal/filestation/client.go +251 -0
  148. package/dist/templates/native-go/backend/internal/filestation/client_test.go +155 -0
  149. package/dist/templates/native-go/backend/internal/filestation/doc.go +4 -0
  150. package/dist/templates/native-go/backend/internal/filestation/read_file_test.go +90 -0
  151. package/dist/templates/native-go/backend/internal/filestation/repository.go +207 -0
  152. package/dist/templates/native-go/backend/internal/filestation/repository_test.go +104 -0
  153. package/dist/templates/native-go/backend/internal/filestation/sdk_session.go +241 -0
  154. package/dist/templates/native-go/backend/internal/filestation/sdk_session_test.go +183 -0
  155. package/dist/templates/native-go/backend/internal/filestation/service.go +254 -0
  156. package/dist/templates/native-go/backend/internal/filestation/service_test.go +94 -0
  157. package/dist/templates/native-go/backend/internal/filestation/session_semantics_test.go +383 -0
  158. package/dist/templates/native-go/backend/internal/filestation/write.go +72 -0
  159. package/dist/templates/native-go/backend/internal/filestation/write_test.go +123 -0
  160. package/dist/templates/native-go/backend/internal/helper/background_proof.go +163 -0
  161. package/dist/templates/native-go/backend/internal/helper/background_proof_contract.go +46 -0
  162. package/dist/templates/native-go/backend/internal/helper/background_proof_test.go +161 -0
  163. package/dist/templates/native-go/backend/internal/helper/data_contract.go +3 -0
  164. package/dist/templates/native-go/backend/internal/helper/data_protocol.go +3 -0
  165. package/dist/templates/native-go/backend/internal/helper/data_protocol_test.go +1 -1
  166. package/dist/templates/native-go/backend/internal/helper/grant_authority.go +3 -0
  167. package/dist/templates/native-go/backend/internal/helper/grant_authority_test.go +1 -1
  168. package/dist/templates/native-go/backend/internal/helper/grant_repository_linux.go +2 -1
  169. package/dist/templates/native-go/backend/internal/helper/grant_repository_linux_test.go +4 -3
  170. package/dist/templates/native-go/backend/internal/helper/grant_snapshot.go +3 -0
  171. package/dist/templates/native-go/backend/internal/helper/jobcontract/bindings.go +48 -0
  172. package/dist/templates/native-go/backend/internal/helper/jobcontract/contract_test.go +436 -0
  173. package/dist/templates/native-go/backend/internal/helper/jobcontract/decode.go +185 -0
  174. package/dist/templates/native-go/backend/internal/helper/jobcontract/digest.go +55 -0
  175. package/dist/templates/native-go/backend/internal/helper/jobcontract/registry.go +85 -0
  176. package/dist/templates/native-go/backend/internal/helper/jobcontract/registry_test.go +73 -0
  177. package/dist/templates/native-go/backend/internal/helper/jobcontract/result.go +53 -0
  178. package/dist/templates/native-go/backend/internal/helper/jobcontract/stub.go +8 -0
  179. package/dist/templates/native-go/backend/internal/helper/jobcontract/testdata/input-digests.json +127 -0
  180. package/dist/templates/native-go/backend/internal/helper/jobcontract/types.go +234 -0
  181. package/dist/templates/native-go/backend/internal/helper/jobcontract/types_test.go +29 -0
  182. package/dist/templates/native-go/backend/internal/helper/jobcontract/validate.go +462 -0
  183. package/dist/templates/native-go/backend/internal/helper/legacy_authority_schema_linux_test.go +34 -0
  184. package/dist/templates/native-go/backend/internal/helper/legacy_authority_schema_test.go +6 -0
  185. package/dist/templates/native-go/backend/internal/helper/management.go +79 -0
  186. package/dist/templates/native-go/backend/internal/helper/observation.go +42 -2
  187. package/dist/templates/native-go/backend/internal/helper/observation_health_test.go +13 -1
  188. package/dist/templates/native-go/backend/internal/helper/observer_diagnostic.go +56 -10
  189. package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_linux_test.go +6 -0
  190. package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_writer.go +40 -0
  191. package/dist/templates/native-go/backend/internal/helper/process_linux.go +3 -0
  192. package/dist/templates/native-go/backend/internal/helper/query_deadline_linux_test.go +115 -0
  193. package/dist/templates/native-go/backend/internal/helper/query_pending_diagnostic_test.go +254 -0
  194. package/dist/templates/native-go/backend/internal/helper/relaxed_invalidation.go +3 -0
  195. package/dist/templates/native-go/backend/internal/helper/s1r_actor_races_linux_test.go +23 -4
  196. package/dist/templates/native-go/backend/internal/helper/sdk_assembly_linux.go +51 -0
  197. package/dist/templates/native-go/backend/internal/helper/sdk_attach.go +83 -0
  198. package/dist/templates/native-go/backend/internal/helper/sdk_attach_contract.go +32 -0
  199. package/dist/templates/native-go/backend/internal/helper/sdk_attach_test.go +184 -0
  200. package/dist/templates/native-go/backend/internal/helper/sdk_authority_schema_test.go +6 -0
  201. package/dist/templates/native-go/backend/internal/helper/sdk_background_authority.go +832 -0
  202. package/dist/templates/native-go/backend/internal/helper/sdk_background_authority_test.go +714 -0
  203. package/dist/templates/native-go/backend/internal/helper/sdk_background_invalidation.go +218 -0
  204. package/dist/templates/native-go/backend/internal/helper/sdk_background_lease.go +218 -0
  205. package/dist/templates/native-go/backend/internal/helper/sdk_background_snapshot.go +110 -0
  206. package/dist/templates/native-go/backend/internal/helper/sdk_background_store_linux_test.go +261 -0
  207. package/dist/templates/native-go/backend/internal/helper/sdk_background_store_test.go +58 -0
  208. package/dist/templates/native-go/backend/internal/helper/sdk_bindings.go +60 -0
  209. package/dist/templates/native-go/backend/internal/helper/sdk_data_contract.go +251 -0
  210. package/dist/templates/native-go/backend/internal/helper/sdk_data_protocol.go +424 -0
  211. package/dist/templates/native-go/backend/internal/helper/sdk_dispatch_absence_test.go +51 -0
  212. package/dist/templates/native-go/backend/internal/helper/sdk_display.go +488 -0
  213. package/dist/templates/native-go/backend/internal/helper/sdk_display_contract.go +121 -0
  214. package/dist/templates/native-go/backend/internal/helper/sdk_display_test.go +459 -0
  215. package/dist/templates/native-go/backend/internal/helper/sdk_grant_authority.go +559 -0
  216. package/dist/templates/native-go/backend/internal/helper/sdk_grant_repository_linux.go +417 -0
  217. package/dist/templates/native-go/backend/internal/helper/sdk_grant_snapshot.go +94 -0
  218. package/dist/templates/native-go/backend/internal/helper/sdk_history.go +80 -0
  219. package/dist/templates/native-go/backend/internal/helper/sdk_history_test.go +76 -0
  220. package/dist/templates/native-go/backend/internal/helper/sdk_job.go +697 -0
  221. package/dist/templates/native-go/backend/internal/helper/sdk_job_child_linux.go +309 -0
  222. package/dist/templates/native-go/backend/internal/helper/sdk_job_contract.go +122 -0
  223. package/dist/templates/native-go/backend/internal/helper/sdk_job_linux_test.go +159 -0
  224. package/dist/templates/native-go/backend/internal/helper/sdk_job_process_linux.go +327 -0
  225. package/dist/templates/native-go/backend/internal/helper/sdk_job_test.go +501 -0
  226. package/dist/templates/native-go/backend/internal/helper/sdk_job_vm_linux_test.go +343 -0
  227. package/dist/templates/native-go/backend/internal/helper/sdk_journal.go +77 -0
  228. package/dist/templates/native-go/backend/internal/helper/sdk_journal_linux.go +244 -0
  229. package/dist/templates/native-go/backend/internal/helper/sdk_journal_linux_test.go +295 -0
  230. package/dist/templates/native-go/backend/internal/helper/sdk_journal_test.go +71 -0
  231. package/dist/templates/native-go/backend/internal/helper/sdk_picker_test.go +50 -0
  232. package/dist/templates/native-go/backend/internal/helper/sdk_process_linux.go +184 -0
  233. package/dist/templates/native-go/backend/internal/helper/sdk_public_vm_linux_test.go +129 -0
  234. package/dist/templates/native-go/backend/internal/helper/sdk_relaxed_invalidation.go +242 -0
  235. package/dist/templates/native-go/backend/internal/helper/sdk_rpc.go +299 -0
  236. package/dist/templates/native-go/backend/internal/helper/sdk_rpc_contract.go +70 -0
  237. package/dist/templates/native-go/backend/internal/helper/sdk_rpc_test.go +135 -0
  238. package/dist/templates/native-go/backend/internal/helper/sdk_server_linux.go +152 -0
  239. package/dist/templates/native-go/backend/internal/helper/sdk_session.go +677 -0
  240. package/dist/templates/native-go/backend/internal/helper/sdk_session_contract.go +72 -0
  241. package/dist/templates/native-go/backend/internal/helper/sdk_session_fence_test.go +215 -0
  242. package/dist/templates/native-go/backend/internal/helper/sdk_session_test.go +475 -0
  243. package/dist/templates/native-go/backend/internal/helper/sdk_supervisor_frame.go +78 -0
  244. package/dist/templates/native-go/backend/internal/helper/sdk_supervisor_linux.go +414 -0
  245. package/dist/templates/native-go/backend/internal/helper/sdk_transport.go +79 -0
  246. package/dist/templates/native-go/backend/internal/helper/sdk_transport_linux.go +82 -0
  247. package/dist/templates/native-go/backend/internal/helper/sdk_transport_test.go +64 -0
  248. package/dist/templates/native-go/backend/internal/helper/server_linux.go +3 -0
  249. package/dist/templates/native-go/backend/internal/helper/stale_management_linux_test.go +126 -0
  250. package/dist/templates/native-go/backend/internal/helper/stale_management_test.go +122 -0
  251. package/dist/templates/native-go/backend/internal/helper/startup_diagnostic.go +68 -0
  252. package/dist/templates/native-go/backend/internal/helper/startup_diagnostic_linux_test.go +126 -0
  253. package/dist/templates/native-go/backend/internal/helper/startup_diagnostic_test.go +117 -0
  254. package/dist/templates/native-go/backend/internal/helper/status.go +22 -13
  255. package/dist/templates/native-go/backend/internal/helper/status_test.go +45 -0
  256. package/dist/templates/native-go/backend/internal/helper/supervision.go +1 -1
  257. package/dist/templates/native-go/backend/internal/helper/supervisor_frame.go +3 -0
  258. package/dist/templates/native-go/backend/internal/helper/supervisor_linux.go +6 -2
  259. package/dist/templates/native-go/backend/internal/helper/unit_connection_test.go +22 -4
  260. package/dist/templates/native-go/backend/internal/helper/unit_linux.go +7 -3
  261. package/dist/templates/native-go/backend/internal/helper/unit_query_linux.go +5 -1
  262. package/dist/templates/native-go/backend/internal/helper/write_files_linux.go +7 -4
  263. package/dist/templates/native-go/backend/internal/helper/write_files_linux_test.go +26 -0
  264. package/dist/templates/native-go/dsm-package.yaml +1 -1
  265. package/dist/templates/native-go-background/BACKGROUND.md +111 -0
  266. package/dist/templates/native-go-background/backend/internal/app/background_on.go +7 -0
  267. package/dist/templates/native-go-background/backend/internal/app/background_routes_test.go +32 -0
  268. package/dist/templates/native-go-background/frontend/src/background/BackgroundPanel.vue +178 -0
  269. package/dist/templates/native-go-background/frontend/src/background/i18n/de.json +83 -0
  270. package/dist/templates/native-go-background/frontend/src/background/i18n/en.json +83 -0
  271. package/dist/templates/native-go-background/frontend/src/background/i18n/es.json +83 -0
  272. package/dist/templates/native-go-background/frontend/src/background/i18n/fr.json +83 -0
  273. package/dist/templates/native-go-background/frontend/src/background/i18n/it.json +83 -0
  274. package/dist/templates/native-go-background/frontend/src/background/i18n/ja.json +83 -0
  275. package/dist/templates/native-go-background/frontend/src/background/i18n/ko.json +83 -0
  276. package/dist/templates/native-go-background/frontend/src/background/i18n/zh-CN.json +83 -0
  277. package/dist/templates/native-go-background/frontend/src/background/i18n/zh-TW.json +83 -0
  278. package/dist/templates/native-go-background/frontend/src/background/i18n.ts +19 -0
  279. package/dist/templates/native-go-background/frontend/src/background/picker-provider.ts +13 -0
  280. package/dist/templates/native-go-background/frontend/test/background.test.ts +179 -0
  281. package/dist/templates/native-go-integration/backend/internal/app/personal.go +2 -2
  282. package/dist/templates/native-go-integration/backend/internal/app/personal_test.go +37 -0
  283. package/dist/templates/native-go-vue/README.md +38 -7
  284. package/dist/templates/native-go-vue/frontend/DESIGN.md +15 -3
  285. package/dist/templates/native-go-vue/frontend/README-JOBS.md +75 -0
  286. package/dist/templates/native-go-vue/frontend/README-M2.md +64 -0
  287. package/dist/templates/native-go-vue/frontend/package-lock.json +5 -4
  288. package/dist/templates/native-go-vue/frontend/package.json +1 -1
  289. package/dist/templates/native-go-vue/frontend/src/App.vue +39 -11
  290. package/dist/templates/native-go-vue/frontend/src/M2App.vue +57 -0
  291. package/dist/templates/native-go-vue/frontend/src/SDKApp.vue +203 -0
  292. package/dist/templates/native-go-vue/frontend/src/jobs/InteractiveJobForm.vue +70 -0
  293. package/dist/templates/native-go-vue/frontend/src/jobs/JobsAdminPanel.vue +33 -0
  294. package/dist/templates/native-go-vue/frontend/src/jobs/JobsPanel.vue +135 -0
  295. package/dist/templates/native-go-vue/frontend/src/jobs/connected-provider.ts +179 -0
  296. package/dist/templates/native-go-vue/frontend/src/jobs/i18n/de.json +62 -0
  297. package/dist/templates/native-go-vue/frontend/src/jobs/i18n/en.json +62 -0
  298. package/dist/templates/native-go-vue/frontend/src/jobs/i18n/es.json +62 -0
  299. package/dist/templates/native-go-vue/frontend/src/jobs/i18n/fr.json +62 -0
  300. package/dist/templates/native-go-vue/frontend/src/jobs/i18n/it.json +62 -0
  301. package/dist/templates/native-go-vue/frontend/src/jobs/i18n/ja.json +62 -0
  302. package/dist/templates/native-go-vue/frontend/src/jobs/i18n/ko.json +62 -0
  303. package/dist/templates/native-go-vue/frontend/src/jobs/i18n/zh-CN.json +62 -0
  304. package/dist/templates/native-go-vue/frontend/src/jobs/i18n/zh-TW.json +62 -0
  305. package/dist/templates/native-go-vue/frontend/src/jobs/i18n.ts +15 -0
  306. package/dist/templates/native-go-vue/frontend/src/jobs/mock-provider.ts +67 -0
  307. package/dist/templates/native-go-vue/frontend/src/jobs/provider.ts +60 -0
  308. package/dist/templates/native-go-vue/frontend/src/jobs/validate.ts +44 -0
  309. package/dist/templates/native-go-vue/frontend/src/m2-main.ts +21 -0
  310. package/dist/templates/native-go-vue/frontend/src/m2-style.css +7 -0
  311. package/dist/templates/native-go-vue/frontend/src/nas/M2Files.vue +94 -0
  312. package/dist/templates/native-go-vue/frontend/src/nas/M2PathPicker.vue +70 -0
  313. package/dist/templates/native-go-vue/frontend/src/nas/M2Settings.vue +69 -0
  314. package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/de.json +56 -0
  315. package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/en.json +56 -0
  316. package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/es.json +56 -0
  317. package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/fr.json +56 -0
  318. package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/it.json +56 -0
  319. package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/ja.json +56 -0
  320. package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/ko.json +56 -0
  321. package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/zh-CN.json +56 -0
  322. package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/zh-TW.json +56 -0
  323. package/dist/templates/native-go-vue/frontend/src/nas/m2-contract.ts +33 -0
  324. package/dist/templates/native-go-vue/frontend/src/nas/m2-i18n.ts +24 -0
  325. package/dist/templates/native-go-vue/frontend/src/nas/m2-provider.ts +104 -0
  326. package/dist/templates/native-go-vue/frontend/src/nas/use-m2-request.ts +18 -0
  327. package/dist/templates/native-go-vue/frontend/src/sdk-main.ts +39 -0
  328. package/dist/templates/native-go-vue/frontend/src/shell/AppShell.vue +48 -0
  329. package/dist/templates/native-go-vue/frontend/src/shell/i18n/de.json +10 -0
  330. package/dist/templates/native-go-vue/frontend/src/shell/i18n/en.json +10 -0
  331. package/dist/templates/native-go-vue/frontend/src/shell/i18n/es.json +10 -0
  332. package/dist/templates/native-go-vue/frontend/src/shell/i18n/fr.json +10 -0
  333. package/dist/templates/native-go-vue/frontend/src/shell/i18n/it.json +10 -0
  334. package/dist/templates/native-go-vue/frontend/src/shell/i18n/ja.json +10 -0
  335. package/dist/templates/native-go-vue/frontend/src/shell/i18n/ko.json +10 -0
  336. package/dist/templates/native-go-vue/frontend/src/shell/i18n/zh-CN.json +10 -0
  337. package/dist/templates/native-go-vue/frontend/src/shell/i18n/zh-TW.json +10 -0
  338. package/dist/templates/native-go-vue/frontend/src/shell/i18n.ts +17 -0
  339. package/dist/templates/native-go-vue/frontend/src/shell/pages.ts +34 -0
  340. package/dist/templates/native-go-vue/frontend/src/style.css +2 -6
  341. package/dist/templates/native-go-vue/frontend/test/apps.test.ts +21 -0
  342. package/dist/templates/native-go-vue/frontend/test/jobs-connected.test.ts +163 -0
  343. package/dist/templates/native-go-vue/frontend/test/jobs-preview.html +22 -0
  344. package/dist/templates/native-go-vue/frontend/test/jobs.test.ts +176 -0
  345. package/dist/templates/native-go-vue/frontend/test/m2-preview.html +27 -0
  346. package/dist/templates/native-go-vue/frontend/test/m2-provider.test.ts +87 -0
  347. package/dist/templates/native-go-vue/frontend/test/m2-ui.test.ts +209 -0
  348. package/dist/templates/native-go-vue/frontend/test/native-controls.test.ts +27 -0
  349. package/dist/templates/native-go-vue/frontend/test/picker-wire.test.ts +110 -0
  350. package/dist/templates/native-go-vue/frontend/test/shell-preview.html +19 -0
  351. package/dist/templates/native-go-vue/frontend/test/shell-sdk.test.ts +73 -0
  352. package/dist/templates/native-go-vue/frontend/test/shell-ui.test.ts +114 -0
  353. package/dist/templates/native-go-vue/frontend/test/shell.test.ts +45 -0
  354. package/dist/templates/native-go-vue/frontend/vite.config.ts +2 -2
  355. package/dist/validate.js +6 -3
  356. package/package.json +1 -1
  357. package/schema/synology-app.schema.json +19 -0
  358. package/skills/reference/create.md +4 -0
  359. package/templates/_daemon/go.mod +2 -0
  360. package/templates/_gateway/auth.go +101 -0
  361. package/templates/_gateway/auth_test.go +216 -0
  362. package/templates/_gateway/cgi.go +133 -0
  363. package/templates/_gateway/cgi_test.go +156 -0
  364. package/templates/_gateway/csrf.go +73 -0
  365. package/templates/_gateway/csrf_test.go +155 -0
  366. package/templates/_gateway/directory.go +108 -0
  367. package/templates/_gateway/directory_test.go +202 -0
  368. package/templates/_gateway/gateway.go +412 -0
  369. package/templates/_gateway/gateway_test.go +676 -0
  370. package/templates/_gateway/go.mod +3 -0
  371. package/templates/_gateway/groups.go +66 -0
  372. package/templates/_gateway/main.go +45 -0
  373. package/templates/binary/synology-app.yaml +1 -1
  374. package/templates/compose-import/compose.yaml +1 -1
  375. package/templates/compose-import/synology-app.yaml +1 -1
  376. package/templates/hello-files/compose.yaml +1 -1
  377. package/templates/hello-files/synology-app.yaml +1 -1
  378. package/templates/hello-web/compose.yaml +5 -2
  379. package/templates/hello-web/synology-app.yaml +4 -1
  380. package/templates/hello-web-page/compose.yaml +5 -2
  381. package/templates/hello-web-page/synology-app.yaml +4 -1
  382. package/templates/native-go/README.md +93 -4
  383. package/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +3 -1
  384. package/templates/native-go/backend/cmd/app/main.go +17 -0
  385. package/templates/native-go/backend/cmd/app/sdk_main.go +60 -0
  386. package/templates/native-go/backend/cmd/background-worker/main.go +38 -0
  387. package/templates/native-go/backend/cmd/helper/main.go +10 -1
  388. package/templates/native-go/backend/cmd/helper/sdk_registry.go +19 -0
  389. package/templates/native-go/backend/go.mod +5 -3
  390. package/templates/native-go/backend/go.sum +4 -4
  391. package/templates/native-go/backend/internal/api/registry.go +17 -6
  392. package/templates/native-go/backend/internal/api/server.go +7 -1
  393. package/templates/native-go/backend/internal/app/background.go +270 -0
  394. package/templates/native-go/backend/internal/app/background_none.go +8 -0
  395. package/templates/native-go/backend/internal/app/background_owner.go +59 -0
  396. package/templates/native-go/backend/internal/app/background_owner_test.go +145 -0
  397. package/templates/native-go/backend/internal/app/background_schedule.go +74 -0
  398. package/templates/native-go/backend/internal/app/background_schedule_test.go +62 -0
  399. package/templates/native-go/backend/internal/app/background_test.go +346 -0
  400. package/templates/native-go/backend/internal/app/integration_state.go +16 -0
  401. package/templates/native-go/backend/internal/app/migrations.go +41 -0
  402. package/templates/native-go/backend/internal/app/migrations_test.go +41 -0
  403. package/templates/native-go/backend/internal/app/nas_cgi_artifact_test.go +8 -0
  404. package/templates/native-go/backend/internal/app/routes.go +17 -3
  405. package/templates/native-go/backend/internal/app/routes_test.go +20 -3
  406. package/templates/native-go/backend/internal/app/sdk_jobs.go +70 -0
  407. package/templates/native-go/backend/internal/app/sdk_jobs_test.go +116 -0
  408. package/templates/native-go/backend/internal/app/sdk_routes.go +174 -0
  409. package/templates/native-go/backend/internal/app/session_files.go +15 -0
  410. package/templates/native-go/backend/internal/app/session_files_test.go +26 -0
  411. package/templates/native-go/backend/internal/app/shared_folder.go +144 -0
  412. package/templates/native-go/backend/internal/app/shared_folder_test.go +158 -0
  413. package/templates/native-go/backend/internal/background/access.go +57 -0
  414. package/templates/native-go/backend/internal/background/owner_test.go +126 -0
  415. package/templates/native-go/backend/internal/background/runner.go +185 -0
  416. package/templates/native-go/backend/internal/background/runner_test.go +209 -0
  417. package/templates/native-go/backend/internal/background/schedule.go +300 -0
  418. package/templates/native-go/backend/internal/background/schedule_test.go +335 -0
  419. package/templates/native-go/backend/internal/background/store.go +807 -0
  420. package/templates/native-go/backend/internal/background/store_test.go +407 -0
  421. package/templates/native-go/backend/internal/datamigrate/migrate.go +191 -0
  422. package/templates/native-go/backend/internal/datamigrate/migrate_test.go +177 -0
  423. package/templates/native-go/backend/internal/filestation/browse_test.go +67 -0
  424. package/templates/native-go/backend/internal/filestation/client.go +251 -0
  425. package/templates/native-go/backend/internal/filestation/client_test.go +155 -0
  426. package/templates/native-go/backend/internal/filestation/doc.go +4 -0
  427. package/templates/native-go/backend/internal/filestation/read_file_test.go +90 -0
  428. package/templates/native-go/backend/internal/filestation/repository.go +207 -0
  429. package/templates/native-go/backend/internal/filestation/repository_test.go +104 -0
  430. package/templates/native-go/backend/internal/filestation/sdk_session.go +241 -0
  431. package/templates/native-go/backend/internal/filestation/sdk_session_test.go +183 -0
  432. package/templates/native-go/backend/internal/filestation/service.go +254 -0
  433. package/templates/native-go/backend/internal/filestation/service_test.go +94 -0
  434. package/templates/native-go/backend/internal/filestation/session_semantics_test.go +383 -0
  435. package/templates/native-go/backend/internal/filestation/write.go +72 -0
  436. package/templates/native-go/backend/internal/filestation/write_test.go +123 -0
  437. package/templates/native-go/backend/internal/helper/background_proof.go +163 -0
  438. package/templates/native-go/backend/internal/helper/background_proof_contract.go +46 -0
  439. package/templates/native-go/backend/internal/helper/background_proof_test.go +161 -0
  440. package/templates/native-go/backend/internal/helper/data_contract.go +3 -0
  441. package/templates/native-go/backend/internal/helper/data_protocol.go +3 -0
  442. package/templates/native-go/backend/internal/helper/data_protocol_test.go +1 -1
  443. package/templates/native-go/backend/internal/helper/grant_authority.go +3 -0
  444. package/templates/native-go/backend/internal/helper/grant_authority_test.go +1 -1
  445. package/templates/native-go/backend/internal/helper/grant_repository_linux.go +2 -1
  446. package/templates/native-go/backend/internal/helper/grant_repository_linux_test.go +4 -3
  447. package/templates/native-go/backend/internal/helper/grant_snapshot.go +3 -0
  448. package/templates/native-go/backend/internal/helper/jobcontract/bindings.go +48 -0
  449. package/templates/native-go/backend/internal/helper/jobcontract/contract_test.go +436 -0
  450. package/templates/native-go/backend/internal/helper/jobcontract/decode.go +185 -0
  451. package/templates/native-go/backend/internal/helper/jobcontract/digest.go +55 -0
  452. package/templates/native-go/backend/internal/helper/jobcontract/registry.go +85 -0
  453. package/templates/native-go/backend/internal/helper/jobcontract/registry_test.go +73 -0
  454. package/templates/native-go/backend/internal/helper/jobcontract/result.go +53 -0
  455. package/templates/native-go/backend/internal/helper/jobcontract/stub.go +8 -0
  456. package/templates/native-go/backend/internal/helper/jobcontract/testdata/input-digests.json +127 -0
  457. package/templates/native-go/backend/internal/helper/jobcontract/types.go +234 -0
  458. package/templates/native-go/backend/internal/helper/jobcontract/types_test.go +29 -0
  459. package/templates/native-go/backend/internal/helper/jobcontract/validate.go +462 -0
  460. package/templates/native-go/backend/internal/helper/legacy_authority_schema_linux_test.go +34 -0
  461. package/templates/native-go/backend/internal/helper/legacy_authority_schema_test.go +6 -0
  462. package/templates/native-go/backend/internal/helper/management.go +79 -0
  463. package/templates/native-go/backend/internal/helper/observation.go +42 -2
  464. package/templates/native-go/backend/internal/helper/observation_health_test.go +13 -1
  465. package/templates/native-go/backend/internal/helper/observer_diagnostic.go +56 -10
  466. package/templates/native-go/backend/internal/helper/observer_diagnostic_linux_test.go +6 -0
  467. package/templates/native-go/backend/internal/helper/observer_diagnostic_writer.go +40 -0
  468. package/templates/native-go/backend/internal/helper/process_linux.go +3 -0
  469. package/templates/native-go/backend/internal/helper/query_deadline_linux_test.go +115 -0
  470. package/templates/native-go/backend/internal/helper/query_pending_diagnostic_test.go +254 -0
  471. package/templates/native-go/backend/internal/helper/relaxed_invalidation.go +3 -0
  472. package/templates/native-go/backend/internal/helper/s1r_actor_races_linux_test.go +23 -4
  473. package/templates/native-go/backend/internal/helper/sdk_assembly_linux.go +51 -0
  474. package/templates/native-go/backend/internal/helper/sdk_attach.go +83 -0
  475. package/templates/native-go/backend/internal/helper/sdk_attach_contract.go +32 -0
  476. package/templates/native-go/backend/internal/helper/sdk_attach_test.go +184 -0
  477. package/templates/native-go/backend/internal/helper/sdk_authority_schema_test.go +6 -0
  478. package/templates/native-go/backend/internal/helper/sdk_background_authority.go +832 -0
  479. package/templates/native-go/backend/internal/helper/sdk_background_authority_test.go +714 -0
  480. package/templates/native-go/backend/internal/helper/sdk_background_invalidation.go +218 -0
  481. package/templates/native-go/backend/internal/helper/sdk_background_lease.go +218 -0
  482. package/templates/native-go/backend/internal/helper/sdk_background_snapshot.go +110 -0
  483. package/templates/native-go/backend/internal/helper/sdk_background_store_linux_test.go +261 -0
  484. package/templates/native-go/backend/internal/helper/sdk_background_store_test.go +58 -0
  485. package/templates/native-go/backend/internal/helper/sdk_bindings.go +60 -0
  486. package/templates/native-go/backend/internal/helper/sdk_data_contract.go +251 -0
  487. package/templates/native-go/backend/internal/helper/sdk_data_protocol.go +424 -0
  488. package/templates/native-go/backend/internal/helper/sdk_dispatch_absence_test.go +51 -0
  489. package/templates/native-go/backend/internal/helper/sdk_display.go +488 -0
  490. package/templates/native-go/backend/internal/helper/sdk_display_contract.go +121 -0
  491. package/templates/native-go/backend/internal/helper/sdk_display_test.go +459 -0
  492. package/templates/native-go/backend/internal/helper/sdk_grant_authority.go +559 -0
  493. package/templates/native-go/backend/internal/helper/sdk_grant_repository_linux.go +417 -0
  494. package/templates/native-go/backend/internal/helper/sdk_grant_snapshot.go +94 -0
  495. package/templates/native-go/backend/internal/helper/sdk_history.go +80 -0
  496. package/templates/native-go/backend/internal/helper/sdk_history_test.go +76 -0
  497. package/templates/native-go/backend/internal/helper/sdk_job.go +697 -0
  498. package/templates/native-go/backend/internal/helper/sdk_job_child_linux.go +309 -0
  499. package/templates/native-go/backend/internal/helper/sdk_job_contract.go +122 -0
  500. package/templates/native-go/backend/internal/helper/sdk_job_linux_test.go +159 -0
  501. package/templates/native-go/backend/internal/helper/sdk_job_process_linux.go +327 -0
  502. package/templates/native-go/backend/internal/helper/sdk_job_test.go +501 -0
  503. package/templates/native-go/backend/internal/helper/sdk_job_vm_linux_test.go +343 -0
  504. package/templates/native-go/backend/internal/helper/sdk_journal.go +77 -0
  505. package/templates/native-go/backend/internal/helper/sdk_journal_linux.go +244 -0
  506. package/templates/native-go/backend/internal/helper/sdk_journal_linux_test.go +295 -0
  507. package/templates/native-go/backend/internal/helper/sdk_journal_test.go +71 -0
  508. package/templates/native-go/backend/internal/helper/sdk_picker_test.go +50 -0
  509. package/templates/native-go/backend/internal/helper/sdk_process_linux.go +184 -0
  510. package/templates/native-go/backend/internal/helper/sdk_public_vm_linux_test.go +129 -0
  511. package/templates/native-go/backend/internal/helper/sdk_relaxed_invalidation.go +242 -0
  512. package/templates/native-go/backend/internal/helper/sdk_rpc.go +299 -0
  513. package/templates/native-go/backend/internal/helper/sdk_rpc_contract.go +70 -0
  514. package/templates/native-go/backend/internal/helper/sdk_rpc_test.go +135 -0
  515. package/templates/native-go/backend/internal/helper/sdk_server_linux.go +152 -0
  516. package/templates/native-go/backend/internal/helper/sdk_session.go +677 -0
  517. package/templates/native-go/backend/internal/helper/sdk_session_contract.go +72 -0
  518. package/templates/native-go/backend/internal/helper/sdk_session_fence_test.go +215 -0
  519. package/templates/native-go/backend/internal/helper/sdk_session_test.go +475 -0
  520. package/templates/native-go/backend/internal/helper/sdk_supervisor_frame.go +78 -0
  521. package/templates/native-go/backend/internal/helper/sdk_supervisor_linux.go +414 -0
  522. package/templates/native-go/backend/internal/helper/sdk_transport.go +79 -0
  523. package/templates/native-go/backend/internal/helper/sdk_transport_linux.go +82 -0
  524. package/templates/native-go/backend/internal/helper/sdk_transport_test.go +64 -0
  525. package/templates/native-go/backend/internal/helper/server_linux.go +3 -0
  526. package/templates/native-go/backend/internal/helper/stale_management_linux_test.go +126 -0
  527. package/templates/native-go/backend/internal/helper/stale_management_test.go +122 -0
  528. package/templates/native-go/backend/internal/helper/startup_diagnostic.go +68 -0
  529. package/templates/native-go/backend/internal/helper/startup_diagnostic_linux_test.go +126 -0
  530. package/templates/native-go/backend/internal/helper/startup_diagnostic_test.go +117 -0
  531. package/templates/native-go/backend/internal/helper/status.go +22 -13
  532. package/templates/native-go/backend/internal/helper/status_test.go +45 -0
  533. package/templates/native-go/backend/internal/helper/supervision.go +1 -1
  534. package/templates/native-go/backend/internal/helper/supervisor_frame.go +3 -0
  535. package/templates/native-go/backend/internal/helper/supervisor_linux.go +6 -2
  536. package/templates/native-go/backend/internal/helper/unit_connection_test.go +22 -4
  537. package/templates/native-go/backend/internal/helper/unit_linux.go +7 -3
  538. package/templates/native-go/backend/internal/helper/unit_query_linux.go +5 -1
  539. package/templates/native-go/backend/internal/helper/write_files_linux.go +7 -4
  540. package/templates/native-go/backend/internal/helper/write_files_linux_test.go +26 -0
  541. package/templates/native-go/dsm-package.yaml +1 -1
  542. package/templates/native-go-background/BACKGROUND.md +111 -0
  543. package/templates/native-go-background/backend/internal/app/background_on.go +7 -0
  544. package/templates/native-go-background/backend/internal/app/background_routes_test.go +32 -0
  545. package/templates/native-go-background/frontend/src/background/BackgroundPanel.vue +178 -0
  546. package/templates/native-go-background/frontend/src/background/i18n/de.json +83 -0
  547. package/templates/native-go-background/frontend/src/background/i18n/en.json +83 -0
  548. package/templates/native-go-background/frontend/src/background/i18n/es.json +83 -0
  549. package/templates/native-go-background/frontend/src/background/i18n/fr.json +83 -0
  550. package/templates/native-go-background/frontend/src/background/i18n/it.json +83 -0
  551. package/templates/native-go-background/frontend/src/background/i18n/ja.json +83 -0
  552. package/templates/native-go-background/frontend/src/background/i18n/ko.json +83 -0
  553. package/templates/native-go-background/frontend/src/background/i18n/zh-CN.json +83 -0
  554. package/templates/native-go-background/frontend/src/background/i18n/zh-TW.json +83 -0
  555. package/templates/native-go-background/frontend/src/background/i18n.ts +19 -0
  556. package/templates/native-go-background/frontend/src/background/picker-provider.ts +13 -0
  557. package/templates/native-go-background/frontend/test/background.test.ts +179 -0
  558. package/templates/native-go-integration/backend/internal/app/personal.go +2 -2
  559. package/templates/native-go-integration/backend/internal/app/personal_test.go +37 -0
  560. package/templates/native-go-vue/README.md +38 -7
  561. package/templates/native-go-vue/frontend/DESIGN.md +15 -3
  562. package/templates/native-go-vue/frontend/README-JOBS.md +75 -0
  563. package/templates/native-go-vue/frontend/README-M2.md +64 -0
  564. package/templates/native-go-vue/frontend/package-lock.json +5 -4
  565. package/templates/native-go-vue/frontend/package.json +1 -1
  566. package/templates/native-go-vue/frontend/src/App.vue +39 -11
  567. package/templates/native-go-vue/frontend/src/M2App.vue +57 -0
  568. package/templates/native-go-vue/frontend/src/SDKApp.vue +203 -0
  569. package/templates/native-go-vue/frontend/src/jobs/InteractiveJobForm.vue +70 -0
  570. package/templates/native-go-vue/frontend/src/jobs/JobsAdminPanel.vue +33 -0
  571. package/templates/native-go-vue/frontend/src/jobs/JobsPanel.vue +135 -0
  572. package/templates/native-go-vue/frontend/src/jobs/connected-provider.ts +179 -0
  573. package/templates/native-go-vue/frontend/src/jobs/i18n/de.json +62 -0
  574. package/templates/native-go-vue/frontend/src/jobs/i18n/en.json +62 -0
  575. package/templates/native-go-vue/frontend/src/jobs/i18n/es.json +62 -0
  576. package/templates/native-go-vue/frontend/src/jobs/i18n/fr.json +62 -0
  577. package/templates/native-go-vue/frontend/src/jobs/i18n/it.json +62 -0
  578. package/templates/native-go-vue/frontend/src/jobs/i18n/ja.json +62 -0
  579. package/templates/native-go-vue/frontend/src/jobs/i18n/ko.json +62 -0
  580. package/templates/native-go-vue/frontend/src/jobs/i18n/zh-CN.json +62 -0
  581. package/templates/native-go-vue/frontend/src/jobs/i18n/zh-TW.json +62 -0
  582. package/templates/native-go-vue/frontend/src/jobs/i18n.ts +15 -0
  583. package/templates/native-go-vue/frontend/src/jobs/mock-provider.ts +67 -0
  584. package/templates/native-go-vue/frontend/src/jobs/provider.ts +60 -0
  585. package/templates/native-go-vue/frontend/src/jobs/validate.ts +44 -0
  586. package/templates/native-go-vue/frontend/src/m2-main.ts +21 -0
  587. package/templates/native-go-vue/frontend/src/m2-style.css +7 -0
  588. package/templates/native-go-vue/frontend/src/nas/M2Files.vue +94 -0
  589. package/templates/native-go-vue/frontend/src/nas/M2PathPicker.vue +70 -0
  590. package/templates/native-go-vue/frontend/src/nas/M2Settings.vue +69 -0
  591. package/templates/native-go-vue/frontend/src/nas/i18n/m2/de.json +56 -0
  592. package/templates/native-go-vue/frontend/src/nas/i18n/m2/en.json +56 -0
  593. package/templates/native-go-vue/frontend/src/nas/i18n/m2/es.json +56 -0
  594. package/templates/native-go-vue/frontend/src/nas/i18n/m2/fr.json +56 -0
  595. package/templates/native-go-vue/frontend/src/nas/i18n/m2/it.json +56 -0
  596. package/templates/native-go-vue/frontend/src/nas/i18n/m2/ja.json +56 -0
  597. package/templates/native-go-vue/frontend/src/nas/i18n/m2/ko.json +56 -0
  598. package/templates/native-go-vue/frontend/src/nas/i18n/m2/zh-CN.json +56 -0
  599. package/templates/native-go-vue/frontend/src/nas/i18n/m2/zh-TW.json +56 -0
  600. package/templates/native-go-vue/frontend/src/nas/m2-contract.ts +33 -0
  601. package/templates/native-go-vue/frontend/src/nas/m2-i18n.ts +24 -0
  602. package/templates/native-go-vue/frontend/src/nas/m2-provider.ts +104 -0
  603. package/templates/native-go-vue/frontend/src/nas/use-m2-request.ts +18 -0
  604. package/templates/native-go-vue/frontend/src/sdk-main.ts +39 -0
  605. package/templates/native-go-vue/frontend/src/shell/AppShell.vue +48 -0
  606. package/templates/native-go-vue/frontend/src/shell/i18n/de.json +10 -0
  607. package/templates/native-go-vue/frontend/src/shell/i18n/en.json +10 -0
  608. package/templates/native-go-vue/frontend/src/shell/i18n/es.json +10 -0
  609. package/templates/native-go-vue/frontend/src/shell/i18n/fr.json +10 -0
  610. package/templates/native-go-vue/frontend/src/shell/i18n/it.json +10 -0
  611. package/templates/native-go-vue/frontend/src/shell/i18n/ja.json +10 -0
  612. package/templates/native-go-vue/frontend/src/shell/i18n/ko.json +10 -0
  613. package/templates/native-go-vue/frontend/src/shell/i18n/zh-CN.json +10 -0
  614. package/templates/native-go-vue/frontend/src/shell/i18n/zh-TW.json +10 -0
  615. package/templates/native-go-vue/frontend/src/shell/i18n.ts +17 -0
  616. package/templates/native-go-vue/frontend/src/shell/pages.ts +34 -0
  617. package/templates/native-go-vue/frontend/src/style.css +2 -6
  618. package/templates/native-go-vue/frontend/test/apps.test.ts +21 -0
  619. package/templates/native-go-vue/frontend/test/jobs-connected.test.ts +163 -0
  620. package/templates/native-go-vue/frontend/test/jobs-preview.html +22 -0
  621. package/templates/native-go-vue/frontend/test/jobs.test.ts +176 -0
  622. package/templates/native-go-vue/frontend/test/m2-preview.html +27 -0
  623. package/templates/native-go-vue/frontend/test/m2-provider.test.ts +87 -0
  624. package/templates/native-go-vue/frontend/test/m2-ui.test.ts +209 -0
  625. package/templates/native-go-vue/frontend/test/native-controls.test.ts +27 -0
  626. package/templates/native-go-vue/frontend/test/picker-wire.test.ts +110 -0
  627. package/templates/native-go-vue/frontend/test/shell-preview.html +19 -0
  628. package/templates/native-go-vue/frontend/test/shell-sdk.test.ts +73 -0
  629. package/templates/native-go-vue/frontend/test/shell-ui.test.ts +114 -0
  630. package/templates/native-go-vue/frontend/test/shell.test.ts +45 -0
  631. package/templates/native-go-vue/frontend/vite.config.ts +2 -2
@@ -12,6 +12,8 @@ const observerDiagnosticLimit = 32768
12
12
  // Only fixed branch names and transport metadata belong here. Never store a
13
13
  // signal body, query value, installation identity, or an error's text.
14
14
  type observerEvent struct {
15
+ Stage string `json:"stage,omitempty"`
16
+ Code Code `json:"code,omitempty"`
15
17
  At time.Time `json:"at"`
16
18
  Kind string `json:"kind"`
17
19
  Detail string `json:"detail,omitempty"`
@@ -23,12 +25,27 @@ type observerEvent struct {
23
25
  SignalSequence uint64 `json:"signalSequence,omitempty"`
24
26
  QuerySerial uint64 `json:"querySerial,omitempty"`
25
27
  }
28
+
29
+ // One pinned period survives ring wrap. Timestamps contain no query values;
30
+ // elapsed time is measured before UTC serialization, using Go's monotonic clock.
31
+ type observerQueryPending struct {
32
+ StartedAt time.Time `json:"startedAt"`
33
+ PendingAt time.Time `json:"pendingAt"`
34
+ EndedAt time.Time `json:"endedAt"`
35
+ Outcome string `json:"outcome"`
36
+ ElapsedNS int64 `json:"elapsedNs"`
37
+ Phase string `json:"phase"`
38
+ ErrorClass string `json:"errorClass"`
39
+ QuerySerial uint64 `json:"querySerial"`
40
+ }
41
+
26
42
  type observerDiagnostic struct {
27
- Schema int `json:"schema"`
28
- Epoch string `json:"epoch"`
29
- Reason string `json:"reason"`
30
- Fence observerEvent `json:"fence"`
31
- Events []observerEvent `json:"events"`
43
+ QueryPending *observerQueryPending `json:"queryPending,omitempty"`
44
+ Schema int `json:"schema"`
45
+ Epoch string `json:"epoch"`
46
+ Reason string `json:"reason"`
47
+ Fence observerEvent `json:"fence"`
48
+ Events []observerEvent `json:"events"`
32
49
  }
33
50
 
34
51
  func (g *admission) recordObserver(e observerEvent) {
@@ -40,6 +57,7 @@ func (g *admission) recordObserverLocked(e observerEvent) {
40
57
  if e.At.IsZero() {
41
58
  e.At = time.Now().UTC()
42
59
  }
60
+ e.At = e.At.UTC()
43
61
  g.events[g.eventNext] = e
44
62
  g.eventNext = (g.eventNext + 1) % observerEventLimit
45
63
  if g.eventCount < observerEventLimit {
@@ -54,7 +72,7 @@ func (g *admission) fenceObserver(reason string, e observerEvent) {
54
72
  func (g *admission) fenceObserverLocked(reason string, e observerEvent) {
55
73
  e.Kind = "fence"
56
74
  if e.At.IsZero() {
57
- e.At = time.Now().UTC()
75
+ e.At = time.Now()
58
76
  }
59
77
  if e.Detail == "" {
60
78
  e.Detail = reason
@@ -62,6 +80,8 @@ func (g *admission) fenceObserverLocked(reason string, e observerEvent) {
62
80
  if g.blocked == "" {
63
81
  g.blocked = reason
64
82
  g.firstFence = e
83
+ g.finishQueryPendingLocked("fence", e.At)
84
+ g.notifyObserverDiagnosticLocked()
65
85
  }
66
86
  g.recordObserverLocked(e)
67
87
  }
@@ -69,6 +89,14 @@ func (g *admission) observerDiagnostic(epoch string) observerDiagnostic {
69
89
  g.mu.Lock()
70
90
  defer g.mu.Unlock()
71
91
  d := observerDiagnostic{Schema: 1, Epoch: epoch, Reason: g.blocked, Fence: g.firstFence, Events: make([]observerEvent, g.eventCount)}
92
+ if g.queryPending != nil {
93
+ period := *g.queryPending
94
+ period.StartedAt = period.StartedAt.UTC()
95
+ period.PendingAt = period.PendingAt.UTC()
96
+ period.EndedAt = period.EndedAt.UTC()
97
+ d.QueryPending = &period
98
+ }
99
+ d.Fence.At = d.Fence.At.UTC()
72
100
  start := (g.eventNext - g.eventCount + observerEventLimit) % observerEventLimit
73
101
  for n := range d.Events {
74
102
  d.Events[n] = g.events[(start+n)%observerEventLimit]
@@ -76,12 +104,30 @@ func (g *admission) observerDiagnostic(epoch string) observerDiagnostic {
76
104
  return d
77
105
  }
78
106
 
79
- // Diagnostics are independent of approval/completion authority. Write once on
80
- // owner return, after teardown attempts. A parked owner retains its lifecycle
81
- // sub-reason; a failed diagnostic write cannot change its fence or proof.
107
+ // Coalesce notifications while storage is slow. The latest pinned period keeps
108
+ // both endpoints even when a start and end arrive before the writer can run.
109
+ func (g *admission) notifyObserverDiagnosticLocked() {
110
+ select {
111
+ case g.diagnosticWake <- struct{}{}:
112
+ default:
113
+ }
114
+ }
115
+ func (g *admission) finishQueryPendingLocked(outcome string, now time.Time) {
116
+ if g.queryPending == nil || g.queryPending.Outcome != "pending" {
117
+ return
118
+ }
119
+ g.queryPending.EndedAt = now
120
+ g.queryPending.Outcome = outcome
121
+ g.queryPending.ElapsedNS = int64(now.Sub(g.queryPending.StartedAt))
122
+ g.recordObserverLocked(observerEvent{At: now, Kind: "query-pending-ended", Detail: outcome, QuerySerial: g.unitSerial})
123
+ g.notifyObserverDiagnosticLocked()
124
+ }
125
+
126
+ // A write error cannot change a fence, admission, completion proof, or return
127
+ // result. This fixed-size snapshot never stores signal bodies or query values.
82
128
  func persistObserverDiagnostic(c Client, epoch string, g *admission) {
83
129
  d := g.observerDiagnostic(epoch)
84
- if d.Reason == "" || !digestPattern.MatchString(epoch) {
130
+ if (d.Reason == "" && d.QueryPending == nil) || !digestPattern.MatchString(epoch) {
85
131
  return
86
132
  }
87
133
  b, err := json.Marshal(d)
@@ -67,6 +67,12 @@ func TestLinuxObserverQueryErrorClassification(t *testing.T) {
67
67
  return Binding{}, nil, &unitSnapshotError{reason: "observation-unavailable", cause: c.err, phase: "get-unit"}
68
68
  })
69
69
  d := o.gate.observerDiagnostic("")
70
+ if c.want == "deadline" {
71
+ if err != nil || o.gate.readiness(time.Now()) != "query-revalidating" {
72
+ t.Fatalf("deadline not pending: %+v %v", d, err)
73
+ }
74
+ continue
75
+ }
70
76
  if err == nil || d.Fence.Phase != "get-unit" || d.Fence.ErrorClass != c.want || d.Fence.Detail != "query-failed" {
71
77
  t.Fatalf("classification %s: %+v %v", c.want, d, err)
72
78
  }
@@ -0,0 +1,40 @@
1
+ package helper
2
+
3
+ import "sync"
4
+
5
+ // Diagnostics are independent of approval/completion authority. A single
6
+ // worker does live writes; the signal/admission ordering point never does I/O.
7
+ // Shutdown retains the existing best-effort final snapshot after teardown.
8
+ func startObserverDiagnostics(c Client, epoch string, g *admission) func() {
9
+ return startObserverDiagnosticWriter(g, func() { persistObserverDiagnostic(c, epoch, g) })
10
+ }
11
+
12
+ func startObserverDiagnosticWriter(g *admission, persist func()) func() {
13
+ wake, stop, done := make(chan struct{}, 1), make(chan struct{}), make(chan struct{})
14
+ g.mu.Lock()
15
+ g.diagnosticWake = wake
16
+ g.mu.Unlock()
17
+ go func() {
18
+ defer close(done)
19
+ persist()
20
+ for {
21
+ select {
22
+ case <-wake:
23
+ persist()
24
+ case <-stop:
25
+ persist()
26
+ return
27
+ }
28
+ }
29
+ }()
30
+ var once sync.Once
31
+ return func() {
32
+ once.Do(func() {
33
+ g.mu.Lock()
34
+ g.diagnosticWake = nil
35
+ g.mu.Unlock()
36
+ close(stop)
37
+ <-done
38
+ })
39
+ }
40
+ }
@@ -1,3 +1,6 @@
1
+ //go:build !synopkgland_sdk_workers
2
+
3
+ //line dsmapp/internal/helper/process_linux.go:1
1
4
  package helper
2
5
 
3
6
  import (
@@ -0,0 +1,115 @@
1
+ package helper
2
+
3
+ import (
4
+ "context"
5
+ "github.com/godbus/dbus/v5"
6
+ "testing"
7
+ "time"
8
+ )
9
+
10
+ // Shared systemd congestion caused by Alpha's upgrade must not kill Beta.
11
+ // A real 500ms context expiry exercises the same GetUnit/GetAll error path.
12
+ func TestLinuxQueryDeadlineCrossPackageRecovery(t *testing.T) {
13
+ for _, name := range []string{"Alpha", "Beta"} {
14
+ t.Run(name, func(t *testing.T) {
15
+ for _, phase := range []string{"get-unit", "get-all"} {
16
+ t.Run(phase, func(t *testing.T) {
17
+ o := diagnosticObserver(t)
18
+ o.unit = "pkgctl-" + name + ".service"
19
+ ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
20
+ defer cancel()
21
+ err := o.reconcileSnapshot(ctx, func(ctx context.Context) (Binding, map[string]dbus.Variant, error) {
22
+ <-ctx.Done()
23
+ return Binding{}, nil, &unitSnapshotError{reason: "observation-unavailable", cause: ctx.Err(), phase: phase}
24
+ })
25
+ if err != nil || o.gate.readiness(time.Now()) != "query-revalidating" || o.gate.allow(time.Now()) {
26
+ t.Fatalf("temporary deadline fenced instead of pending: %v %+v", err, o.gate.observerDiagnostic(""))
27
+ }
28
+ time.Sleep(250 * time.Millisecond)
29
+ if err := o.reconcileSnapshot(context.Background(), func(context.Context) (Binding, map[string]dbus.Variant, error) {
30
+ return testBinding(), activeUnitValues(o), nil
31
+ }); err != nil || !o.gate.allow(time.Now()) {
32
+ t.Fatalf("unchanged snapshot did not recover: %v", err)
33
+ }
34
+ })
35
+ }
36
+ })
37
+ }
38
+ }
39
+
40
+ func TestLinuxQueryDeadlineBoundAndStickyFence(t *testing.T) {
41
+ o := diagnosticObserver(t)
42
+ start := time.Now()
43
+ timeout := func(context.Context) (Binding, map[string]dbus.Variant, error) {
44
+ return Binding{}, nil, &unitSnapshotError{reason: "observation-unavailable", cause: context.DeadlineExceeded, phase: "get-unit"}
45
+ }
46
+ if err := o.reconcileSnapshot(context.Background(), timeout); err != nil {
47
+ t.Fatal("first deadline fenced", err)
48
+ }
49
+ for n := 0; n < 3; n++ {
50
+ if err := o.reconcileSnapshot(context.Background(), timeout); err != nil {
51
+ t.Fatal("retry fenced", err)
52
+ }
53
+ }
54
+ if o.gate.readiness(start.Add(2900*time.Millisecond)) != "query-revalidating" {
55
+ t.Fatal("missing bounded pending")
56
+ }
57
+ if !o.gate.fenced(start.Add(3100*time.Millisecond)) || o.gate.observerDiagnostic("").Fence.Detail != "query-deadline" {
58
+ t.Fatal("query budget extended", o.gate.observerDiagnostic(""))
59
+ }
60
+ _ = o.observeValues(testBinding(), activeUnitValues(o), o.gate.unitSerial, time.Now())
61
+ if o.gate.allow(time.Now()) {
62
+ t.Fatal("fence resurrected")
63
+ }
64
+ }
65
+
66
+ func TestLinuxQueryDeadlineCannotExtendReloadOrHideIdentity(t *testing.T) {
67
+ for _, kind := range []string{"reload-first", "query-first", "identity", "cancel", "initial"} {
68
+ t.Run(kind, func(t *testing.T) {
69
+ o := diagnosticObserver(t)
70
+ now := time.Now()
71
+ if kind == "initial" {
72
+ o.gate = newAdmission(testBinding())
73
+ }
74
+ if kind == "reload-first" {
75
+ o.gate.requestUnitCheck(true, now.Add(-9500*time.Millisecond))
76
+ o.gate.requestUnitCheck(false, now)
77
+ }
78
+ err := o.reconcileSnapshot(context.Background(), func(context.Context) (Binding, map[string]dbus.Variant, error) {
79
+ return Binding{}, nil, &unitSnapshotError{reason: "observation-unavailable", cause: context.DeadlineExceeded, phase: "get-all"}
80
+ })
81
+ if kind == "initial" {
82
+ if err == nil {
83
+ t.Fatal("initial failure acquired authority")
84
+ }
85
+ return
86
+ }
87
+ if err != nil {
88
+ t.Fatal("deadline fenced early", err)
89
+ }
90
+ switch kind {
91
+ case "query-first":
92
+ o.gate.requestUnitCheck(true, now.Add(time.Second))
93
+ if !o.gate.fenced(now.Add(3100 * time.Millisecond)) {
94
+ t.Fatal("reload extended query budget")
95
+ }
96
+ case "reload-first":
97
+ if !o.gate.fenced(now.Add(3100 * time.Millisecond)) {
98
+ t.Fatal("query extended verification")
99
+ }
100
+ case "identity":
101
+ v := activeUnitValues(o)
102
+ v["ActiveEnterTimestampMonotonic"] = dbus.MakeVariant(uint64(999))
103
+ if o.observeValues(testBinding(), v, o.gate.unitSerial, time.Now()) == nil {
104
+ t.Fatal("changed identity accepted")
105
+ }
106
+ case "cancel":
107
+ if o.reconcileSnapshot(context.Background(), func(context.Context) (Binding, map[string]dbus.Variant, error) {
108
+ return Binding{}, nil, context.Canceled
109
+ }) == nil {
110
+ t.Fatal("cancel retried")
111
+ }
112
+ }
113
+ })
114
+ }
115
+ }
@@ -0,0 +1,254 @@
1
+ package helper
2
+
3
+ import (
4
+ "encoding/json"
5
+ "os"
6
+ "path/filepath"
7
+ "strings"
8
+ "sync/atomic"
9
+ "testing"
10
+ "time"
11
+ )
12
+
13
+ func TestQueryPendingDiagnosticSnapshotIsBoundedAndDetached(t *testing.T) {
14
+ g := newAdmission(testBinding())
15
+ now := time.Now().In(time.FixedZone("fixture", 8*60*60))
16
+ g.queryPending = &observerQueryPending{StartedAt: now, PendingAt: now.Add(500 * time.Millisecond), Outcome: "pending", Phase: "get-unit", ErrorClass: "deadline"}
17
+ for n := 0; n < observerEventLimit+20; n++ {
18
+ g.recordObserver(observerEvent{Kind: "query-phase"})
19
+ }
20
+ d := g.observerDiagnostic(strings.Repeat("e", 64))
21
+ if d.QueryPending == nil || !d.QueryPending.StartedAt.Equal(now) {
22
+ t.Fatalf("missing pinned period: %+v", d)
23
+ }
24
+ if d.QueryPending.StartedAt.Location() != time.UTC || d.QueryPending.PendingAt.Location() != time.UTC {
25
+ t.Fatal("diagnostic timestamps are not UTC")
26
+ }
27
+ d.QueryPending.Outcome = "mutated"
28
+ if g.observerDiagnostic(d.Epoch).QueryPending.Outcome != "pending" {
29
+ t.Fatal("snapshot aliases period")
30
+ }
31
+ payload, err := json.Marshal(d)
32
+ if err != nil || len(payload) > observerDiagnosticLimit {
33
+ t.Fatalf("size %d: %v", len(payload), err)
34
+ }
35
+ var decoded observerDiagnostic
36
+ if err := json.Unmarshal(payload, &decoded); err != nil || decoded.QueryPending == nil || !decoded.QueryPending.StartedAt.Equal(now) {
37
+ t.Fatalf("period roundtrip: %+v %v", decoded, err)
38
+ }
39
+ }
40
+
41
+ func TestQueryPendingDiagnosticPeriodLifecycle(t *testing.T) {
42
+ for _, outcome := range []string{"ready", "fence", "signal-fence", "reload-fence"} {
43
+ t.Run(outcome, func(t *testing.T) {
44
+ start := time.Now()
45
+ g := newAdmission(testBinding())
46
+ g.observeUnit(testBinding(), 7, "", false, true, 0, start)
47
+ e := observerEvent{Phase: "get-owner", ErrorClass: "deadline", QuerySerial: 0}
48
+ if !g.deferUnitDeadline(0, start, start.Add(500*time.Millisecond), e) {
49
+ t.Fatal("first timeout fenced")
50
+ }
51
+ first := g.observerDiagnostic("").QueryPending
52
+ if first == nil || !first.StartedAt.Equal(start) || !first.PendingAt.Equal(start.Add(500*time.Millisecond)) || first.Outcome != "pending" || first.Phase != "get-owner" || first.ElapsedNS != 0 {
53
+ t.Fatalf("wrong first query: %+v", first)
54
+ }
55
+ e.Phase = "get-all"
56
+ if !g.deferUnitDeadline(0, start.Add(750*time.Millisecond), start.Add(time.Second), e) {
57
+ t.Fatal("retry fenced")
58
+ }
59
+ for n := 0; n < observerEventLimit+20; n++ {
60
+ g.recordObserver(observerEvent{Kind: "query-phase"})
61
+ }
62
+ end := start.Add(1500 * time.Millisecond)
63
+ want := outcome
64
+ switch outcome {
65
+ case "ready":
66
+ g.observeUnit(testBinding(), 7, "", false, true, 0, end)
67
+ case "fence":
68
+ end = start.Add(unitQueryRecoveryBudget)
69
+ g.fenced(end)
70
+ case "signal-fence":
71
+ want = "fence"
72
+ g.fenceObserver("bus-owner-changed", observerEvent{At: end, Detail: "owner-signal"})
73
+ case "reload-fence":
74
+ want = "fence"
75
+ g.requestUnitCheck(true, start.Add(time.Second))
76
+ end = start.Add(unitQueryRecoveryBudget)
77
+ g.fenced(end)
78
+ }
79
+ d := g.observerDiagnostic("")
80
+ p := d.QueryPending
81
+ if p == nil || !p.StartedAt.Equal(start) || !p.PendingAt.Equal(start.Add(500*time.Millisecond)) || !p.EndedAt.Equal(end) || p.Outcome != want || p.ElapsedNS != int64(end.Sub(start)) || p.Phase != "get-owner" {
82
+ t.Fatalf("wrong ended period: %+v", p)
83
+ }
84
+ if want == "ready" {
85
+ if !g.allow(end) {
86
+ t.Fatal("recovered admission denied")
87
+ }
88
+ later := end.Add(100 * time.Millisecond)
89
+ g.deferUnitDeadline(0, later, later.Add(500*time.Millisecond), e)
90
+ if p = g.observerDiagnostic("").QueryPending; !p.StartedAt.Equal(later) || p.Outcome != "pending" || !p.EndedAt.IsZero() || p.ElapsedNS != 0 {
91
+ t.Fatalf("latest cycle not replaced: %+v", p)
92
+ }
93
+ } else {
94
+ g.observeUnit(testBinding(), 7, "", false, true, g.unitSerial, end)
95
+ if g.allow(end) || g.observerDiagnostic("").QueryPending.ElapsedNS != p.ElapsedNS {
96
+ t.Fatal("terminal period or fence changed")
97
+ }
98
+ }
99
+ })
100
+ }
101
+ }
102
+
103
+ func TestQueryPendingDiagnosticDiscardedProbeDoesNotStartOrEndPeriod(t *testing.T) {
104
+ start := time.Now()
105
+ g := newAdmission(testBinding())
106
+ if g.deferUnitDeadline(0, start, start, observerEvent{}) || g.observerDiagnostic("").QueryPending != nil {
107
+ t.Fatal("startup acquired pending")
108
+ }
109
+ g.observeUnit(testBinding(), 7, "", false, true, 0, start)
110
+ g.requestUnitCheck(true, start)
111
+ if g.deferUnitDeadline(0, start, start, observerEvent{}) || g.observerDiagnostic("").QueryPending != nil {
112
+ t.Fatal("obsolete probe started pending")
113
+ }
114
+ g.requestUnitCheck(false, start)
115
+ g.deferUnitDeadline(g.unitSerial, start, start.Add(500*time.Millisecond), observerEvent{Phase: "get-unit", ErrorClass: "deadline"})
116
+ g.observeUnit(testBinding(), 7, "", false, true, 0, start.Add(time.Second))
117
+ if p := g.observerDiagnostic("").QueryPending; p == nil || p.Outcome != "pending" {
118
+ t.Fatalf("obsolete success ended pending: %+v", p)
119
+ }
120
+ }
121
+
122
+ func TestQueryPendingDiagnosticPersistsWhileOwnerLives(t *testing.T) {
123
+ for _, fail := range []bool{false, true} {
124
+ t.Run(map[bool]string{false: "private-file", true: "write-failure"}[fail], func(t *testing.T) {
125
+ c := fixture(t)
126
+ path := filepath.Join(c.StateDir, "observer-diagnostic.json")
127
+ if fail {
128
+ if err := os.Mkdir(path, 0700); err != nil {
129
+ t.Fatal(err)
130
+ }
131
+ }
132
+ start := time.Now()
133
+ g := newAdmission(testBinding())
134
+ g.observeUnit(testBinding(), 7, "", false, true, 0, start)
135
+ stop := startObserverDiagnostics(c, strings.Repeat("e", 64), g)
136
+ defer stop()
137
+ g.deferUnitDeadline(0, start, start.Add(500*time.Millisecond), observerEvent{Phase: "get-all", ErrorClass: "deadline"})
138
+ read := func(want string) observerDiagnostic {
139
+ t.Helper()
140
+ deadline := time.Now().Add(2 * time.Second)
141
+ for time.Now().Before(deadline) {
142
+ b, err := os.ReadFile(path)
143
+ var d observerDiagnostic
144
+ if err == nil && json.Unmarshal(b, &d) == nil && d.QueryPending != nil && d.QueryPending.Outcome == want {
145
+ return d
146
+ }
147
+ time.Sleep(time.Millisecond)
148
+ }
149
+ t.Fatalf("live %s diagnostic not persisted", want)
150
+ return observerDiagnostic{}
151
+ }
152
+ if !fail {
153
+ read("pending")
154
+ }
155
+ end := start.Add(750 * time.Millisecond)
156
+ g.observeUnit(testBinding(), 7, "", false, true, 0, end)
157
+ if !g.allow(end) {
158
+ t.Fatal("write failure changed recovery")
159
+ }
160
+ if !fail {
161
+ d := read("ready")
162
+ if d.Reason != "" || d.Epoch != strings.Repeat("e", 64) || d.QueryPending.ElapsedNS != int64(750*time.Millisecond) {
163
+ t.Fatalf("bad live recovery: %+v", d)
164
+ }
165
+ st, err := os.Stat(path)
166
+ if err != nil || st.Mode().Perm() != 0600 || st.Size() > observerDiagnosticLimit {
167
+ t.Fatalf("bad private bounded file: %v %v", st, err)
168
+ }
169
+ g.deferUnitDeadline(0, end, end.Add(500*time.Millisecond), observerEvent{Phase: "get-unit", ErrorClass: "deadline"})
170
+ g.fenced(end.Add(unitQueryRecoveryBudget))
171
+ d = read("fence")
172
+ if d.QueryPending.ElapsedNS != int64(unitQueryRecoveryBudget) || d.Fence.Detail != "query-deadline" {
173
+ t.Fatalf("bad live fence: %+v", d)
174
+ }
175
+ }
176
+ })
177
+ }
178
+ }
179
+
180
+ func TestQueryPendingDiagnosticSlowWriterCannotDelayAdmission(t *testing.T) {
181
+ g := newAdmission(testBinding())
182
+ start := time.Now()
183
+ g.observeUnit(testBinding(), 7, "", false, true, 0, start)
184
+ entered := make(chan struct{})
185
+ release := make(chan struct{})
186
+ var writes atomic.Int32
187
+ stop := startObserverDiagnosticWriter(g, func() {
188
+ if writes.Add(1) == 1 {
189
+ close(entered)
190
+ <-release
191
+ }
192
+ })
193
+ // Always release before shutdown, including a failing assertion.
194
+ defer stop()
195
+ defer close(release)
196
+ select {
197
+ case <-entered:
198
+ case <-time.After(time.Second):
199
+ t.Fatal("writer not started")
200
+ }
201
+ done := make(chan struct{})
202
+ go func() {
203
+ // Repeated periods while storage is stalled must coalesce in bounded memory.
204
+ for n := 0; n < observerEventLimit*2; n++ {
205
+ at := start.Add(time.Duration(n) * time.Millisecond)
206
+ g.deferUnitDeadline(0, at, at.Add(time.Microsecond), observerEvent{Phase: "get-unit", ErrorClass: "deadline"})
207
+ g.observeUnit(testBinding(), 7, "", false, true, 0, at.Add(2*time.Microsecond))
208
+ }
209
+ g.deferUnitDeadline(0, start, start.Add(500*time.Millisecond), observerEvent{Phase: "get-unit", ErrorClass: "deadline"})
210
+ g.fenced(start.Add(unitQueryRecoveryBudget))
211
+ close(done)
212
+ }()
213
+ select {
214
+ case <-done:
215
+ case <-time.After(time.Second):
216
+ t.Fatal("storage blocked admission")
217
+ }
218
+ d := g.observerDiagnostic("")
219
+ if d.QueryPending == nil || d.QueryPending.Outcome != "fence" || d.QueryPending.ElapsedNS != int64(unitQueryRecoveryBudget) || len(d.Events) != observerEventLimit {
220
+ t.Fatalf("latest period lost: %+v", d)
221
+ }
222
+ }
223
+
224
+ func TestQueryPendingDiagnosticShutdownFlushesLatest(t *testing.T) {
225
+ g := newAdmission(testBinding())
226
+ start := time.Now()
227
+ g.observeUnit(testBinding(), 7, "", false, true, 0, start)
228
+ entered, release := make(chan struct{}), make(chan struct{})
229
+ var latest atomic.Pointer[observerDiagnostic]
230
+ var writes atomic.Int32
231
+ stop := startObserverDiagnosticWriter(g, func() {
232
+ if writes.Add(1) == 1 {
233
+ close(entered)
234
+ <-release
235
+ }
236
+ d := g.observerDiagnostic(strings.Repeat("e", 64))
237
+ latest.Store(&d)
238
+ })
239
+ defer stop()
240
+ select {
241
+ case <-entered:
242
+ case <-time.After(time.Second):
243
+ close(release)
244
+ t.Fatal("writer not started")
245
+ }
246
+ g.deferUnitDeadline(0, start, start.Add(500*time.Millisecond), observerEvent{Phase: "get-unit", ErrorClass: "deadline"})
247
+ g.observeUnit(testBinding(), 7, "", false, true, 0, start.Add(750*time.Millisecond))
248
+ close(release)
249
+ stop()
250
+ d := latest.Load()
251
+ if d == nil || d.QueryPending == nil || d.QueryPending.Outcome != "ready" || d.QueryPending.ElapsedNS != int64(750*time.Millisecond) {
252
+ t.Fatalf("shutdown lost latest: %+v", d)
253
+ }
254
+ }
@@ -1,3 +1,6 @@
1
+ //go:build !synopkgland_sdk_workers
2
+
3
+ //line dsmapp/internal/helper/relaxed_invalidation.go:1
1
4
  package helper
2
5
 
3
6
  import (
@@ -2,9 +2,12 @@ package helper
2
2
 
3
3
  import (
4
4
  "context"
5
+ "errors"
5
6
  "os"
6
7
  "strings"
7
8
  "testing"
9
+
10
+ "golang.org/x/sys/unix"
8
11
  )
9
12
 
10
13
  func s1rActorRaces(t *testing.T, spec s1rActorSpec, kind string) {
@@ -190,15 +193,31 @@ func s1rActorRaces(t *testing.T, spec s1rActorSpec, kind string) {
190
193
  s1rMust(t, os.Chmod(root, 0500))
191
194
  defer os.Chmod(root, 0700)
192
195
  r, c := x.Commit(ctx)
193
- // Current S7 maps linkat EACCES to unsupported; require the exact behavior,
194
- // report it, and preserve the fail-closed publish gate.
195
- if c != ErrUnsupported || r.Published || r.Committed || r.BytesWritten != 3 {
196
+ if c != ErrDenied || !r.Created || r.Published || r.Committed || r.BytesWritten != 3 {
196
197
  t.Fatal("publish after parent chmod", r, c)
197
198
  }
198
199
  if _, e := os.Stat(root + "/result"); !os.IsNotExist(e) {
199
200
  t.Fatal("publish wrote forbidden directory", e)
200
201
  }
201
- t.Log("parent write permission removed: kernel denies linkat; receipt retains staged bytes, published=false")
202
+ var st unix.Stat_t
203
+ s1rMust(t, unix.Fstat(int(x.file.Fd()), &st))
204
+ if st.Nlink != 0 || st.Size != 3 {
205
+ t.Fatal("anonymous stage changed after denial", st.Nlink, st.Size)
206
+ }
207
+ if retry, code := x.Commit(ctx); code != ErrReplay || retry != r {
208
+ t.Fatal("denied publish replay changed receipt", retry, code)
209
+ }
210
+ x.Close()
211
+ x.Close()
212
+ if _, e := x.file.Stat(); !errors.Is(e, os.ErrClosed) {
213
+ t.Fatal("stage descriptor still open", e)
214
+ }
215
+ entries, e := os.ReadDir(root)
216
+ s1rMust(t, e)
217
+ if len(entries) != 1 || entries[0].Name() != "file" {
218
+ t.Fatal("denied publish left a named stage", entries)
219
+ }
220
+ t.Log("parent write permission removed: publish denied; staged bytes and receipt retained; close leaves no named stage")
202
221
  case "open-fd-write-permission-loss":
203
222
  work := writeWork{RootPath: root, Action: ActionCreate, Segments: []string{"result"}, MaxBytes: 6}
204
223
  x, c := openActorWriteTransfer(ctx, pin, work, fixtureReadOnlyACL{})
@@ -0,0 +1,51 @@
1
+ //go:build linux && synopkgland_sdk_workers
2
+
3
+ package helper
4
+
5
+ import (
6
+ "context"
7
+ "dsmapp/internal/dsm"
8
+ "dsmapp/internal/filestation"
9
+ )
10
+
11
+ type unavailableSDKValidator struct{}
12
+
13
+ func (unavailableSDKValidator) ValidateJob(context.Context, NativeActor, sdkJobRequest, Grant, sdkJobCheckpoint) (sdkJobProof, Code) {
14
+ return sdkJobProof{}, ErrUnavailable
15
+ }
16
+
17
+ // The sole owner calls this once, after the authority's startup reconciliation.
18
+ // Native/POSIX services stay unavailable. Production uses only session-authenticated
19
+ // File Station requests; explicit native VM fixtures retain their own test seam.
20
+ func openSDKJobs(c Client, binary string, s *supervisorGrants, repo *FileGrantRepository) (*sdkJobOwner, Code, string) {
21
+ if len(sdkCompiledRegistry) == 0 {
22
+ return nil, ErrUnavailable, "jobs-registry"
23
+ }
24
+ journal, code, stage := newSDKFileJobJournalDiagnostic(repo)
25
+ if code != "" {
26
+ return nil, code, stage
27
+ }
28
+ var validator sdkJobValidator = unavailableSDKValidator{}
29
+ if v, ok := s.services.consent.(sdkJobValidator); ok {
30
+ validator = v
31
+ }
32
+ o, code := newSDKJobOwner(s, sdkCompiledRegistry, sdkJobServices{Validator: validator, Journal: journal, Start: func(a NativeActor, b operationBinding, p sdkJobPlan) (sdkJobProcess, error) {
33
+ return startLinuxSDKJob(c, binary, a, b, p)
34
+ }})
35
+ if code != "" {
36
+ return nil, code, "jobs-owner"
37
+ }
38
+ // Reuse the same retained journal/index for revocation. No observer, validator,
39
+ // ready/consume loop or background child bootstrap is installed.
40
+ if _, code = newSDKBackgroundOwner(o, nil, nil, journal, newSDKEpochClock()); code != "" {
41
+ return nil, code, "background-index"
42
+ }
43
+ if _, nativeFixture := s.services.consent.(sdkJobValidator); !nativeFixture {
44
+ o.session, code = newSDKSessionJobs(o, filestation.Local("/var/packages/"+c.Expected.Package+"/var"), dsm.NewAuthenticator())
45
+ if code != "" {
46
+ return nil, code, "session-history"
47
+ }
48
+ }
49
+ newSDKJobViews(o)
50
+ return o, "", ""
51
+ }