@synopackageland/cli 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (438) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +37 -0
  3. package/dist/build-spk/generator.js +3 -0
  4. package/dist/build-spk/notices.d.ts +5 -0
  5. package/dist/build-spk/notices.js +60 -0
  6. package/dist/cli.js +9 -2
  7. package/dist/error-registry.js +20 -0
  8. package/dist/init.d.ts +4 -0
  9. package/dist/init.js +20 -12
  10. package/dist/standalone/build.js +3 -1
  11. package/dist/standalone/daemon.d.ts +23 -0
  12. package/dist/standalone/daemon.js +114 -0
  13. package/dist/standalone/dsm-window.d.ts +1 -1
  14. package/dist/standalone/dsm-window.js +50 -10
  15. package/dist/standalone/helper-inventory.d.ts +16 -0
  16. package/dist/standalone/helper-inventory.js +2 -0
  17. package/dist/standalone/helper.d.ts +2 -12
  18. package/dist/standalone/helper.js +8 -7
  19. package/dist/standalone/host-adapter.d.ts +5 -0
  20. package/dist/standalone/host-adapter.js +148 -0
  21. package/dist/standalone/host-platform.d.ts +13 -0
  22. package/dist/standalone/host-platform.js +42 -0
  23. package/dist/standalone/host-types.d.ts +49 -0
  24. package/dist/standalone/host-types.js +1 -0
  25. package/dist/standalone/inspect-helper.d.ts +6 -0
  26. package/dist/standalone/inspect-helper.js +88 -0
  27. package/dist/standalone/inspect-spk.d.ts +2 -0
  28. package/dist/standalone/inspect-spk.js +49 -0
  29. package/dist/standalone/lifecycle-helper.d.ts +2 -0
  30. package/dist/standalone/lifecycle-helper.js +12 -0
  31. package/dist/standalone/lifecycle.d.ts +3 -0
  32. package/dist/standalone/lifecycle.js +53 -0
  33. package/dist/standalone/manifest.d.ts +2 -0
  34. package/dist/standalone/manifest.js +4 -1
  35. package/dist/standalone/reopen-events.d.ts +2 -0
  36. package/dist/standalone/reopen-events.js +28 -0
  37. package/dist/standalone/root-messages.js +9 -0
  38. package/dist/standalone/root-window.d.ts +4 -3
  39. package/dist/standalone/root-window.js +17 -5
  40. package/dist/standalone/spk.d.ts +4 -3
  41. package/dist/standalone/spk.js +20 -33
  42. package/dist/template-paths.d.ts +2 -0
  43. package/dist/template-paths.js +9 -0
  44. package/dist/templates/_daemon/fixture_linux_test.go +15 -0
  45. package/dist/templates/_daemon/fixture_other_test.go +7 -0
  46. package/dist/templates/_daemon/go.mod +3 -0
  47. package/dist/templates/_daemon/main.go +608 -0
  48. package/dist/templates/_daemon/main_test.go +242 -0
  49. package/dist/templates/_daemon/process_linux.go +55 -0
  50. package/dist/templates/_daemon/process_linux_test.go +161 -0
  51. package/dist/templates/_daemon/process_other.go +14 -0
  52. package/dist/templates/_daemon/testdata/child.go +41 -0
  53. package/dist/templates/_shared/GO-LICENSE +27 -0
  54. package/dist/templates/_shared/GO-PATENTS +22 -0
  55. package/dist/templates/_shared/LICENSES/TEMPLATE.txt +21 -0
  56. package/dist/templates/_shared/notice-overrides/index.json +14 -0
  57. package/dist/templates/_shared/notice-overrides/utils-0.4.2-LICENSE +21 -0
  58. package/dist/templates/_shared/notice-overrides/utils-0.5.0-LICENSE +21 -0
  59. package/dist/templates/_shared/third-party-notices.mjs +51 -0
  60. package/dist/templates/native-go/README.md +57 -1
  61. package/dist/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +59 -0
  62. package/dist/templates/native-go/backend/cmd/dsm-readonly-probe/main_linux.go +46 -0
  63. package/dist/templates/native-go/backend/go.mod +4 -0
  64. package/dist/templates/native-go/backend/go.sum +4 -0
  65. package/dist/templates/native-go/backend/internal/api/binary.go +154 -0
  66. package/dist/templates/native-go/backend/internal/api/binary_test.go +165 -0
  67. package/dist/templates/native-go/backend/internal/api/registry.go +14 -4
  68. package/dist/templates/native-go/backend/internal/api/server.go +4 -0
  69. package/dist/templates/native-go/backend/internal/app/nas_cgi_artifact_test.go +121 -0
  70. package/dist/templates/native-go/backend/internal/app/nas_refusal_test.go +46 -0
  71. package/dist/templates/native-go/backend/internal/app/routes.go +11 -0
  72. package/dist/templates/native-go/backend/internal/app/routes_test.go +10 -5
  73. package/dist/templates/native-go/backend/internal/dsmprobe/collector_linux.go +335 -0
  74. package/dist/templates/native-go/backend/internal/dsmprobe/collector_linux_test.go +41 -0
  75. package/dist/templates/native-go/backend/internal/dsmprobe/protocol.go +179 -0
  76. package/dist/templates/native-go/backend/internal/dsmprobe/protocol_test.go +29 -0
  77. package/dist/templates/native-go/backend/internal/helper/cohort.go +393 -0
  78. package/dist/templates/native-go/backend/internal/helper/cohort_publication.go +18 -0
  79. package/dist/templates/native-go/backend/internal/helper/cohort_publication_test.go +105 -0
  80. package/dist/templates/native-go/backend/internal/helper/cohort_test.go +372 -0
  81. package/dist/templates/native-go/backend/internal/helper/control.go +226 -21
  82. package/dist/templates/native-go/backend/internal/helper/control_test.go +10 -2
  83. package/dist/templates/native-go/backend/internal/helper/data_contract.go +242 -0
  84. package/dist/templates/native-go/backend/internal/helper/data_contract_test.go +51 -0
  85. package/dist/templates/native-go/backend/internal/helper/data_decode.go +184 -0
  86. package/dist/templates/native-go/backend/internal/helper/data_decode_pointer_test.go +30 -0
  87. package/dist/templates/native-go/backend/internal/helper/data_protocol.go +416 -0
  88. package/dist/templates/native-go/backend/internal/helper/data_protocol_test.go +449 -0
  89. package/dist/templates/native-go/backend/internal/helper/dsm_acl_linux.go +139 -0
  90. package/dist/templates/native-go/backend/internal/helper/dsm_acl_linux_test.go +121 -0
  91. package/dist/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux.go +95 -0
  92. package/dist/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux_test.go +56 -0
  93. package/dist/templates/native-go/backend/internal/helper/dsm_bridge_linux.go +144 -0
  94. package/dist/templates/native-go/backend/internal/helper/dsm_bridge_linux_test.go +89 -0
  95. package/dist/templates/native-go/backend/internal/helper/dsm_home_linux.go +107 -0
  96. package/dist/templates/native-go/backend/internal/helper/dsm_home_linux_test.go +82 -0
  97. package/dist/templates/native-go/backend/internal/helper/dsm_probe_transport_linux.go +151 -0
  98. package/dist/templates/native-go/backend/internal/helper/dsm_probe_transport_linux_test.go +66 -0
  99. package/dist/templates/native-go/backend/internal/helper/grant_authority.go +516 -0
  100. package/dist/templates/native-go/backend/internal/helper/grant_authority_contract.go +88 -0
  101. package/dist/templates/native-go/backend/internal/helper/grant_authority_test.go +510 -0
  102. package/dist/templates/native-go/backend/internal/helper/grant_cohort.go +389 -0
  103. package/dist/templates/native-go/backend/internal/helper/grant_cohort_test.go +239 -0
  104. package/dist/templates/native-go/backend/internal/helper/grant_delivery.go +49 -0
  105. package/dist/templates/native-go/backend/internal/helper/grant_delivery_methods.go +273 -0
  106. package/dist/templates/native-go/backend/internal/helper/grant_delivery_test.go +322 -0
  107. package/dist/templates/native-go/backend/internal/helper/grant_operation_contract.go +47 -0
  108. package/dist/templates/native-go/backend/internal/helper/grant_readonly_test.go +180 -0
  109. package/dist/templates/native-go/backend/internal/helper/grant_repository_linux.go +415 -0
  110. package/dist/templates/native-go/backend/internal/helper/grant_repository_linux_test.go +468 -0
  111. package/dist/templates/native-go/backend/internal/helper/grant_rpc.go +147 -0
  112. package/dist/templates/native-go/backend/internal/helper/grant_rpc_test.go +51 -0
  113. package/dist/templates/native-go/backend/internal/helper/grant_snapshot.go +75 -0
  114. package/dist/templates/native-go/backend/internal/helper/grant_supervisor_linux.go +134 -0
  115. package/dist/templates/native-go/backend/internal/helper/grant_supervisor_linux_test.go +254 -0
  116. package/dist/templates/native-go/backend/internal/helper/lease.go +112 -0
  117. package/dist/templates/native-go/backend/internal/helper/lease_linux.go +44 -0
  118. package/dist/templates/native-go/backend/internal/helper/lease_other.go +8 -0
  119. package/dist/templates/native-go/backend/internal/helper/lifecycle.go +234 -0
  120. package/dist/templates/native-go/backend/internal/helper/lifecycle_test.go +473 -0
  121. package/dist/templates/native-go/backend/internal/helper/managed_pilot.go +284 -0
  122. package/dist/templates/native-go/backend/internal/helper/managed_pilot_repository_linux.go +74 -0
  123. package/dist/templates/native-go/backend/internal/helper/managed_pilot_repository_linux_test.go +40 -0
  124. package/dist/templates/native-go/backend/internal/helper/managed_pilot_test.go +210 -0
  125. package/dist/templates/native-go/backend/internal/helper/nas_shipped_refusal_linux_test.go +97 -0
  126. package/dist/templates/native-go/backend/internal/helper/native_discovery.go +79 -0
  127. package/dist/templates/native-go/backend/internal/helper/native_identity.go +89 -0
  128. package/dist/templates/native-go/backend/internal/helper/native_provider.go +159 -0
  129. package/dist/templates/native-go/backend/internal/helper/native_provider_test.go +421 -0
  130. package/dist/templates/native-go/backend/internal/helper/observation.go +204 -0
  131. package/dist/templates/native-go/backend/internal/helper/observation_health_test.go +115 -0
  132. package/dist/templates/native-go/backend/internal/helper/observation_reload_budget_test.go +117 -0
  133. package/dist/templates/native-go/backend/internal/helper/observation_test.go +196 -0
  134. package/dist/templates/native-go/backend/internal/helper/observer_diagnostic.go +109 -0
  135. package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_linux.go +76 -0
  136. package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_linux_test.go +124 -0
  137. package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_test.go +98 -0
  138. package/dist/templates/native-go/backend/internal/helper/operation_bootstrap_linux.go +193 -0
  139. package/dist/templates/native-go/backend/internal/helper/operation_credentials_linux.go +56 -0
  140. package/dist/templates/native-go/backend/internal/helper/operation_linux.go +480 -0
  141. package/dist/templates/native-go/backend/internal/helper/operation_linux_test.go +528 -0
  142. package/dist/templates/native-go/backend/internal/helper/process_linux.go +11 -1
  143. package/dist/templates/native-go/backend/internal/helper/publication_test.go +178 -0
  144. package/dist/templates/native-go/backend/internal/helper/read_stream_cohort_linux_test.go +156 -0
  145. package/dist/templates/native-go/backend/internal/helper/read_transfer.go +40 -0
  146. package/dist/templates/native-go/backend/internal/helper/read_transfer_linux.go +109 -0
  147. package/dist/templates/native-go/backend/internal/helper/read_transfer_linux_test.go +118 -0
  148. package/dist/templates/native-go/backend/internal/helper/read_transfer_test.go +177 -0
  149. package/dist/templates/native-go/backend/internal/helper/readonly.go +105 -0
  150. package/dist/templates/native-go/backend/internal/helper/readonly_admission.go +85 -0
  151. package/dist/templates/native-go/backend/internal/helper/readonly_cohort_linux_test.go +253 -0
  152. package/dist/templates/native-go/backend/internal/helper/readonly_linux_test.go +378 -0
  153. package/dist/templates/native-go/backend/internal/helper/readonly_mount_linux.go +65 -0
  154. package/dist/templates/native-go/backend/internal/helper/readonly_mount_proxy_linux.go +113 -0
  155. package/dist/templates/native-go/backend/internal/helper/readonly_operations_linux.go +168 -0
  156. package/dist/templates/native-go/backend/internal/helper/readonly_resolver_linux.go +241 -0
  157. package/dist/templates/native-go/backend/internal/helper/readonly_test.go +40 -0
  158. package/dist/templates/native-go/backend/internal/helper/relaxed_identity.go +252 -0
  159. package/dist/templates/native-go/backend/internal/helper/relaxed_identity_contract.go +105 -0
  160. package/dist/templates/native-go/backend/internal/helper/relaxed_identity_test.go +406 -0
  161. package/dist/templates/native-go/backend/internal/helper/relaxed_invalidation.go +200 -0
  162. package/dist/templates/native-go/backend/internal/helper/repair.go +132 -0
  163. package/dist/templates/native-go/backend/internal/helper/repair_test.go +271 -0
  164. package/dist/templates/native-go/backend/internal/helper/s1r_actor_acl_linux_test.go +303 -0
  165. package/dist/templates/native-go/backend/internal/helper/s1r_actor_fixture_linux_test.go +184 -0
  166. package/dist/templates/native-go/backend/internal/helper/s1r_actor_races_linux_test.go +231 -0
  167. package/dist/templates/native-go/backend/internal/helper/s1r_fixture_contract_linux_test.go +18 -0
  168. package/dist/templates/native-go/backend/internal/helper/server_linux.go +44 -3
  169. package/dist/templates/native-go/backend/internal/helper/status.go +74 -11
  170. package/dist/templates/native-go/backend/internal/helper/status_test.go +83 -0
  171. package/dist/templates/native-go/backend/internal/helper/supervision.go +28 -5
  172. package/dist/templates/native-go/backend/internal/helper/supervisor_frame.go +76 -0
  173. package/dist/templates/native-go/backend/internal/helper/supervisor_frame_linux_test.go +69 -0
  174. package/dist/templates/native-go/backend/internal/helper/supervisor_frame_test.go +107 -0
  175. package/dist/templates/native-go/backend/internal/helper/supervisor_linux.go +187 -16
  176. package/dist/templates/native-go/backend/internal/helper/supervisor_linux_test.go +618 -7
  177. package/dist/templates/native-go/backend/internal/helper/supervisor_socket_eof_test.go +74 -0
  178. package/dist/templates/native-go/backend/internal/helper/supervisor_socket_test.go +45 -0
  179. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/create.json +23 -0
  180. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/frames.json +67 -0
  181. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/grant-store.json +52 -0
  182. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/intent.json +20 -0
  183. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/list.json +20 -0
  184. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/publish.json +20 -0
  185. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/read.json +22 -0
  186. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/stat.json +22 -0
  187. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/write-stream.json +22 -0
  188. package/dist/templates/native-go/backend/internal/helper/unit_connection.go +75 -0
  189. package/dist/templates/native-go/backend/internal/helper/unit_connection_linux_test.go +135 -0
  190. package/dist/templates/native-go/backend/internal/helper/unit_connection_test.go +133 -0
  191. package/dist/templates/native-go/backend/internal/helper/unit_frame_test.go +32 -0
  192. package/dist/templates/native-go/backend/internal/helper/unit_linux.go +364 -0
  193. package/dist/templates/native-go/backend/internal/helper/unit_linux_test.go +46 -0
  194. package/dist/templates/native-go/backend/internal/helper/unit_mechanisms_linux_test.go +217 -0
  195. package/dist/templates/native-go/backend/internal/helper/unit_padding_linux_test.go +178 -0
  196. package/dist/templates/native-go/backend/internal/helper/unit_query_linux.go +111 -0
  197. package/dist/templates/native-go/backend/internal/helper/unit_reload_linux_test.go +372 -0
  198. package/dist/templates/native-go/backend/internal/helper/unit_reload_sequence_linux_test.go +232 -0
  199. package/dist/templates/native-go/backend/internal/helper/write.go +77 -0
  200. package/dist/templates/native-go/backend/internal/helper/write_admission.go +260 -0
  201. package/dist/templates/native-go/backend/internal/helper/write_admission_test.go +135 -0
  202. package/dist/templates/native-go/backend/internal/helper/write_cohort_linux_test.go +218 -0
  203. package/dist/templates/native-go/backend/internal/helper/write_files_linux.go +202 -0
  204. package/dist/templates/native-go/backend/internal/helper/write_files_linux_test.go +199 -0
  205. package/dist/templates/native-go/backend/internal/helper/write_intent_linux.go +116 -0
  206. package/dist/templates/native-go/backend/internal/helper/write_intent_linux_test.go +74 -0
  207. package/dist/templates/native-go/backend/internal/helper/write_operation_linux.go +245 -0
  208. package/dist/templates/native-go/backend/internal/helper/write_test.go +53 -0
  209. package/dist/templates/native-go/ui/app.js +8 -1
  210. package/dist/templates/native-go-better-auth/node/build.mjs +2 -0
  211. package/dist/templates/native-go-vue/README.md +115 -1
  212. package/dist/templates/native-go-vue/frontend/DESIGN.md +1 -1
  213. package/dist/templates/native-go-vue/frontend/package-lock.json +132 -229
  214. package/dist/templates/native-go-vue/frontend/package.json +1 -1
  215. package/dist/templates/native-go-vue/frontend/src/App.vue +33 -6
  216. package/dist/templates/native-go-vue/frontend/src/context.ts +41 -2
  217. package/dist/templates/native-go-vue/frontend/src/main.ts +4 -1
  218. package/dist/templates/native-go-vue/frontend/src/nas/NasGrantSettings.vue +74 -0
  219. package/dist/templates/native-go-vue/frontend/src/nas/NasPathPicker.vue +106 -0
  220. package/dist/templates/native-go-vue/frontend/src/nas/NasUnavailable.vue +20 -0
  221. package/dist/templates/native-go-vue/frontend/src/nas/i18n/de.json +74 -0
  222. package/dist/templates/native-go-vue/frontend/src/nas/i18n/en.json +74 -0
  223. package/dist/templates/native-go-vue/frontend/src/nas/i18n/es.json +74 -0
  224. package/dist/templates/native-go-vue/frontend/src/nas/i18n/fr.json +74 -0
  225. package/dist/templates/native-go-vue/frontend/src/nas/i18n/it.json +74 -0
  226. package/dist/templates/native-go-vue/frontend/src/nas/i18n/ja.json +74 -0
  227. package/dist/templates/native-go-vue/frontend/src/nas/i18n/ko.json +74 -0
  228. package/dist/templates/native-go-vue/frontend/src/nas/i18n/zh-CN.json +74 -0
  229. package/dist/templates/native-go-vue/frontend/src/nas/i18n/zh-TW.json +74 -0
  230. package/dist/templates/native-go-vue/frontend/src/nas/i18n.ts +38 -0
  231. package/dist/templates/native-go-vue/frontend/src/nas/mock-provider.ts +119 -0
  232. package/dist/templates/native-go-vue/frontend/src/nas/provider.ts +59 -0
  233. package/dist/templates/native-go-vue/frontend/src/nas/use-request.ts +27 -0
  234. package/dist/templates/native-go-vue/frontend/src/style.css +17 -0
  235. package/dist/templates/native-go-vue/frontend/test/apps.test.ts +44 -2
  236. package/dist/templates/native-go-vue/frontend/test/nas-provider.test.ts +81 -0
  237. package/dist/templates/native-go-vue/frontend/test/nas-request.test.ts +21 -0
  238. package/dist/templates/native-go-vue/frontend/test/nas-ui.test.ts +261 -0
  239. package/dist/templates/native-go-vue/frontend/tsconfig.json +1 -1
  240. package/dist/templates/native-go-vue/frontend/vite.config.ts +6 -4
  241. package/package.json +3 -2
  242. package/templates/_daemon/fixture_linux_test.go +15 -0
  243. package/templates/_daemon/fixture_other_test.go +7 -0
  244. package/templates/_daemon/go.mod +3 -0
  245. package/templates/_daemon/main.go +608 -0
  246. package/templates/_daemon/main_test.go +242 -0
  247. package/templates/_daemon/process_linux.go +55 -0
  248. package/templates/_daemon/process_linux_test.go +161 -0
  249. package/templates/_daemon/process_other.go +14 -0
  250. package/templates/_daemon/testdata/child.go +41 -0
  251. package/templates/_shared/GO-LICENSE +27 -0
  252. package/templates/_shared/GO-PATENTS +22 -0
  253. package/templates/_shared/LICENSES/TEMPLATE.txt +21 -0
  254. package/templates/_shared/notice-overrides/index.json +14 -0
  255. package/templates/_shared/notice-overrides/utils-0.4.2-LICENSE +21 -0
  256. package/templates/_shared/notice-overrides/utils-0.5.0-LICENSE +21 -0
  257. package/templates/_shared/third-party-notices.mjs +51 -0
  258. package/templates/native-go/README.md +57 -1
  259. package/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +59 -0
  260. package/templates/native-go/backend/cmd/dsm-readonly-probe/main_linux.go +46 -0
  261. package/templates/native-go/backend/go.mod +4 -0
  262. package/templates/native-go/backend/go.sum +4 -0
  263. package/templates/native-go/backend/internal/api/binary.go +154 -0
  264. package/templates/native-go/backend/internal/api/binary_test.go +165 -0
  265. package/templates/native-go/backend/internal/api/registry.go +14 -4
  266. package/templates/native-go/backend/internal/api/server.go +4 -0
  267. package/templates/native-go/backend/internal/app/nas_cgi_artifact_test.go +121 -0
  268. package/templates/native-go/backend/internal/app/nas_refusal_test.go +46 -0
  269. package/templates/native-go/backend/internal/app/routes.go +11 -0
  270. package/templates/native-go/backend/internal/app/routes_test.go +10 -5
  271. package/templates/native-go/backend/internal/dsmprobe/collector_linux.go +335 -0
  272. package/templates/native-go/backend/internal/dsmprobe/collector_linux_test.go +41 -0
  273. package/templates/native-go/backend/internal/dsmprobe/protocol.go +179 -0
  274. package/templates/native-go/backend/internal/dsmprobe/protocol_test.go +29 -0
  275. package/templates/native-go/backend/internal/helper/cohort.go +393 -0
  276. package/templates/native-go/backend/internal/helper/cohort_publication.go +18 -0
  277. package/templates/native-go/backend/internal/helper/cohort_publication_test.go +105 -0
  278. package/templates/native-go/backend/internal/helper/cohort_test.go +372 -0
  279. package/templates/native-go/backend/internal/helper/control.go +226 -21
  280. package/templates/native-go/backend/internal/helper/control_test.go +10 -2
  281. package/templates/native-go/backend/internal/helper/data_contract.go +242 -0
  282. package/templates/native-go/backend/internal/helper/data_contract_test.go +51 -0
  283. package/templates/native-go/backend/internal/helper/data_decode.go +184 -0
  284. package/templates/native-go/backend/internal/helper/data_decode_pointer_test.go +30 -0
  285. package/templates/native-go/backend/internal/helper/data_protocol.go +416 -0
  286. package/templates/native-go/backend/internal/helper/data_protocol_test.go +449 -0
  287. package/templates/native-go/backend/internal/helper/dsm_acl_linux.go +139 -0
  288. package/templates/native-go/backend/internal/helper/dsm_acl_linux_test.go +121 -0
  289. package/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux.go +95 -0
  290. package/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux_test.go +56 -0
  291. package/templates/native-go/backend/internal/helper/dsm_bridge_linux.go +144 -0
  292. package/templates/native-go/backend/internal/helper/dsm_bridge_linux_test.go +89 -0
  293. package/templates/native-go/backend/internal/helper/dsm_home_linux.go +107 -0
  294. package/templates/native-go/backend/internal/helper/dsm_home_linux_test.go +82 -0
  295. package/templates/native-go/backend/internal/helper/dsm_probe_transport_linux.go +151 -0
  296. package/templates/native-go/backend/internal/helper/dsm_probe_transport_linux_test.go +66 -0
  297. package/templates/native-go/backend/internal/helper/grant_authority.go +516 -0
  298. package/templates/native-go/backend/internal/helper/grant_authority_contract.go +88 -0
  299. package/templates/native-go/backend/internal/helper/grant_authority_test.go +510 -0
  300. package/templates/native-go/backend/internal/helper/grant_cohort.go +389 -0
  301. package/templates/native-go/backend/internal/helper/grant_cohort_test.go +239 -0
  302. package/templates/native-go/backend/internal/helper/grant_delivery.go +49 -0
  303. package/templates/native-go/backend/internal/helper/grant_delivery_methods.go +273 -0
  304. package/templates/native-go/backend/internal/helper/grant_delivery_test.go +322 -0
  305. package/templates/native-go/backend/internal/helper/grant_operation_contract.go +47 -0
  306. package/templates/native-go/backend/internal/helper/grant_readonly_test.go +180 -0
  307. package/templates/native-go/backend/internal/helper/grant_repository_linux.go +415 -0
  308. package/templates/native-go/backend/internal/helper/grant_repository_linux_test.go +468 -0
  309. package/templates/native-go/backend/internal/helper/grant_rpc.go +147 -0
  310. package/templates/native-go/backend/internal/helper/grant_rpc_test.go +51 -0
  311. package/templates/native-go/backend/internal/helper/grant_snapshot.go +75 -0
  312. package/templates/native-go/backend/internal/helper/grant_supervisor_linux.go +134 -0
  313. package/templates/native-go/backend/internal/helper/grant_supervisor_linux_test.go +254 -0
  314. package/templates/native-go/backend/internal/helper/lease.go +112 -0
  315. package/templates/native-go/backend/internal/helper/lease_linux.go +44 -0
  316. package/templates/native-go/backend/internal/helper/lease_other.go +8 -0
  317. package/templates/native-go/backend/internal/helper/lifecycle.go +234 -0
  318. package/templates/native-go/backend/internal/helper/lifecycle_test.go +473 -0
  319. package/templates/native-go/backend/internal/helper/managed_pilot.go +284 -0
  320. package/templates/native-go/backend/internal/helper/managed_pilot_repository_linux.go +74 -0
  321. package/templates/native-go/backend/internal/helper/managed_pilot_repository_linux_test.go +40 -0
  322. package/templates/native-go/backend/internal/helper/managed_pilot_test.go +210 -0
  323. package/templates/native-go/backend/internal/helper/nas_shipped_refusal_linux_test.go +97 -0
  324. package/templates/native-go/backend/internal/helper/native_discovery.go +79 -0
  325. package/templates/native-go/backend/internal/helper/native_identity.go +89 -0
  326. package/templates/native-go/backend/internal/helper/native_provider.go +159 -0
  327. package/templates/native-go/backend/internal/helper/native_provider_test.go +421 -0
  328. package/templates/native-go/backend/internal/helper/observation.go +204 -0
  329. package/templates/native-go/backend/internal/helper/observation_health_test.go +115 -0
  330. package/templates/native-go/backend/internal/helper/observation_reload_budget_test.go +117 -0
  331. package/templates/native-go/backend/internal/helper/observation_test.go +196 -0
  332. package/templates/native-go/backend/internal/helper/observer_diagnostic.go +109 -0
  333. package/templates/native-go/backend/internal/helper/observer_diagnostic_linux.go +76 -0
  334. package/templates/native-go/backend/internal/helper/observer_diagnostic_linux_test.go +124 -0
  335. package/templates/native-go/backend/internal/helper/observer_diagnostic_test.go +98 -0
  336. package/templates/native-go/backend/internal/helper/operation_bootstrap_linux.go +193 -0
  337. package/templates/native-go/backend/internal/helper/operation_credentials_linux.go +56 -0
  338. package/templates/native-go/backend/internal/helper/operation_linux.go +480 -0
  339. package/templates/native-go/backend/internal/helper/operation_linux_test.go +528 -0
  340. package/templates/native-go/backend/internal/helper/process_linux.go +11 -1
  341. package/templates/native-go/backend/internal/helper/publication_test.go +178 -0
  342. package/templates/native-go/backend/internal/helper/read_stream_cohort_linux_test.go +156 -0
  343. package/templates/native-go/backend/internal/helper/read_transfer.go +40 -0
  344. package/templates/native-go/backend/internal/helper/read_transfer_linux.go +109 -0
  345. package/templates/native-go/backend/internal/helper/read_transfer_linux_test.go +118 -0
  346. package/templates/native-go/backend/internal/helper/read_transfer_test.go +177 -0
  347. package/templates/native-go/backend/internal/helper/readonly.go +105 -0
  348. package/templates/native-go/backend/internal/helper/readonly_admission.go +85 -0
  349. package/templates/native-go/backend/internal/helper/readonly_cohort_linux_test.go +253 -0
  350. package/templates/native-go/backend/internal/helper/readonly_linux_test.go +378 -0
  351. package/templates/native-go/backend/internal/helper/readonly_mount_linux.go +65 -0
  352. package/templates/native-go/backend/internal/helper/readonly_mount_proxy_linux.go +113 -0
  353. package/templates/native-go/backend/internal/helper/readonly_operations_linux.go +168 -0
  354. package/templates/native-go/backend/internal/helper/readonly_resolver_linux.go +241 -0
  355. package/templates/native-go/backend/internal/helper/readonly_test.go +40 -0
  356. package/templates/native-go/backend/internal/helper/relaxed_identity.go +252 -0
  357. package/templates/native-go/backend/internal/helper/relaxed_identity_contract.go +105 -0
  358. package/templates/native-go/backend/internal/helper/relaxed_identity_test.go +406 -0
  359. package/templates/native-go/backend/internal/helper/relaxed_invalidation.go +200 -0
  360. package/templates/native-go/backend/internal/helper/repair.go +132 -0
  361. package/templates/native-go/backend/internal/helper/repair_test.go +271 -0
  362. package/templates/native-go/backend/internal/helper/s1r_actor_acl_linux_test.go +303 -0
  363. package/templates/native-go/backend/internal/helper/s1r_actor_fixture_linux_test.go +184 -0
  364. package/templates/native-go/backend/internal/helper/s1r_actor_races_linux_test.go +231 -0
  365. package/templates/native-go/backend/internal/helper/s1r_fixture_contract_linux_test.go +18 -0
  366. package/templates/native-go/backend/internal/helper/server_linux.go +44 -3
  367. package/templates/native-go/backend/internal/helper/status.go +74 -11
  368. package/templates/native-go/backend/internal/helper/status_test.go +83 -0
  369. package/templates/native-go/backend/internal/helper/supervision.go +28 -5
  370. package/templates/native-go/backend/internal/helper/supervisor_frame.go +76 -0
  371. package/templates/native-go/backend/internal/helper/supervisor_frame_linux_test.go +69 -0
  372. package/templates/native-go/backend/internal/helper/supervisor_frame_test.go +107 -0
  373. package/templates/native-go/backend/internal/helper/supervisor_linux.go +187 -16
  374. package/templates/native-go/backend/internal/helper/supervisor_linux_test.go +618 -7
  375. package/templates/native-go/backend/internal/helper/supervisor_socket_eof_test.go +74 -0
  376. package/templates/native-go/backend/internal/helper/supervisor_socket_test.go +45 -0
  377. package/templates/native-go/backend/internal/helper/testdata/protocol2/create.json +23 -0
  378. package/templates/native-go/backend/internal/helper/testdata/protocol2/frames.json +67 -0
  379. package/templates/native-go/backend/internal/helper/testdata/protocol2/grant-store.json +52 -0
  380. package/templates/native-go/backend/internal/helper/testdata/protocol2/intent.json +20 -0
  381. package/templates/native-go/backend/internal/helper/testdata/protocol2/list.json +20 -0
  382. package/templates/native-go/backend/internal/helper/testdata/protocol2/publish.json +20 -0
  383. package/templates/native-go/backend/internal/helper/testdata/protocol2/read.json +22 -0
  384. package/templates/native-go/backend/internal/helper/testdata/protocol2/stat.json +22 -0
  385. package/templates/native-go/backend/internal/helper/testdata/protocol2/write-stream.json +22 -0
  386. package/templates/native-go/backend/internal/helper/unit_connection.go +75 -0
  387. package/templates/native-go/backend/internal/helper/unit_connection_linux_test.go +135 -0
  388. package/templates/native-go/backend/internal/helper/unit_connection_test.go +133 -0
  389. package/templates/native-go/backend/internal/helper/unit_frame_test.go +32 -0
  390. package/templates/native-go/backend/internal/helper/unit_linux.go +364 -0
  391. package/templates/native-go/backend/internal/helper/unit_linux_test.go +46 -0
  392. package/templates/native-go/backend/internal/helper/unit_mechanisms_linux_test.go +217 -0
  393. package/templates/native-go/backend/internal/helper/unit_padding_linux_test.go +178 -0
  394. package/templates/native-go/backend/internal/helper/unit_query_linux.go +111 -0
  395. package/templates/native-go/backend/internal/helper/unit_reload_linux_test.go +372 -0
  396. package/templates/native-go/backend/internal/helper/unit_reload_sequence_linux_test.go +232 -0
  397. package/templates/native-go/backend/internal/helper/write.go +77 -0
  398. package/templates/native-go/backend/internal/helper/write_admission.go +260 -0
  399. package/templates/native-go/backend/internal/helper/write_admission_test.go +135 -0
  400. package/templates/native-go/backend/internal/helper/write_cohort_linux_test.go +218 -0
  401. package/templates/native-go/backend/internal/helper/write_files_linux.go +202 -0
  402. package/templates/native-go/backend/internal/helper/write_files_linux_test.go +199 -0
  403. package/templates/native-go/backend/internal/helper/write_intent_linux.go +116 -0
  404. package/templates/native-go/backend/internal/helper/write_intent_linux_test.go +74 -0
  405. package/templates/native-go/backend/internal/helper/write_operation_linux.go +245 -0
  406. package/templates/native-go/backend/internal/helper/write_test.go +53 -0
  407. package/templates/native-go/ui/app.js +8 -1
  408. package/templates/native-go-better-auth/node/build.mjs +2 -0
  409. package/templates/native-go-vue/README.md +115 -1
  410. package/templates/native-go-vue/frontend/DESIGN.md +1 -1
  411. package/templates/native-go-vue/frontend/package-lock.json +132 -229
  412. package/templates/native-go-vue/frontend/package.json +1 -1
  413. package/templates/native-go-vue/frontend/src/App.vue +33 -6
  414. package/templates/native-go-vue/frontend/src/context.ts +41 -2
  415. package/templates/native-go-vue/frontend/src/main.ts +4 -1
  416. package/templates/native-go-vue/frontend/src/nas/NasGrantSettings.vue +74 -0
  417. package/templates/native-go-vue/frontend/src/nas/NasPathPicker.vue +106 -0
  418. package/templates/native-go-vue/frontend/src/nas/NasUnavailable.vue +20 -0
  419. package/templates/native-go-vue/frontend/src/nas/i18n/de.json +74 -0
  420. package/templates/native-go-vue/frontend/src/nas/i18n/en.json +74 -0
  421. package/templates/native-go-vue/frontend/src/nas/i18n/es.json +74 -0
  422. package/templates/native-go-vue/frontend/src/nas/i18n/fr.json +74 -0
  423. package/templates/native-go-vue/frontend/src/nas/i18n/it.json +74 -0
  424. package/templates/native-go-vue/frontend/src/nas/i18n/ja.json +74 -0
  425. package/templates/native-go-vue/frontend/src/nas/i18n/ko.json +74 -0
  426. package/templates/native-go-vue/frontend/src/nas/i18n/zh-CN.json +74 -0
  427. package/templates/native-go-vue/frontend/src/nas/i18n/zh-TW.json +74 -0
  428. package/templates/native-go-vue/frontend/src/nas/i18n.ts +38 -0
  429. package/templates/native-go-vue/frontend/src/nas/mock-provider.ts +119 -0
  430. package/templates/native-go-vue/frontend/src/nas/provider.ts +59 -0
  431. package/templates/native-go-vue/frontend/src/nas/use-request.ts +27 -0
  432. package/templates/native-go-vue/frontend/src/style.css +17 -0
  433. package/templates/native-go-vue/frontend/test/apps.test.ts +44 -2
  434. package/templates/native-go-vue/frontend/test/nas-provider.test.ts +81 -0
  435. package/templates/native-go-vue/frontend/test/nas-request.test.ts +21 -0
  436. package/templates/native-go-vue/frontend/test/nas-ui.test.ts +261 -0
  437. package/templates/native-go-vue/frontend/tsconfig.json +1 -1
  438. package/templates/native-go-vue/frontend/vite.config.ts +6 -4
@@ -0,0 +1,184 @@
1
+ package helper
2
+
3
+ import (
4
+ "bytes"
5
+ "encoding/json"
6
+ "io"
7
+ "reflect"
8
+ "strings"
9
+ "unicode/utf8"
10
+ )
11
+
12
+ // The ordinary Go decoder accepts case aliases, duplicate keys, nulls and
13
+ // malformed Unicode replacement. A bounded token pass rejects these first.
14
+ func decodeDataObject(reader io.Reader, dst any, limit int) Code {
15
+ b, err := io.ReadAll(io.LimitReader(reader, int64(limit)+1))
16
+ if err != nil {
17
+ return ErrInvalid
18
+ }
19
+ if len(b) > limit {
20
+ return ErrLimit
21
+ }
22
+ if !validJSONUnicode(b) {
23
+ return ErrInvalid
24
+ }
25
+ d := json.NewDecoder(bytes.NewReader(b))
26
+ d.UseNumber()
27
+ if !scanDataShape(d, reflect.TypeOf(dst).Elem(), 0) {
28
+ return ErrInvalid
29
+ }
30
+ if _, err := d.Token(); err != io.EOF {
31
+ return ErrInvalid
32
+ }
33
+ d = json.NewDecoder(bytes.NewReader(b))
34
+ d.DisallowUnknownFields()
35
+ if d.Decode(dst) != nil || d.Decode(new(any)) != io.EOF {
36
+ return ErrInvalid
37
+ }
38
+ return ""
39
+ }
40
+
41
+ func scanDataShape(d *json.Decoder, t reflect.Type, depth int) bool {
42
+ if depth > 64 {
43
+ return false
44
+ }
45
+ for t != nil && t.Kind() == reflect.Pointer {
46
+ t = t.Elem()
47
+ }
48
+ if t == reflect.TypeOf(json.RawMessage{}) {
49
+ t = nil
50
+ }
51
+ token, err := d.Token()
52
+ if err != nil || token == nil {
53
+ return false
54
+ }
55
+ delim, container := token.(json.Delim)
56
+ if !container {
57
+ return t == nil || (t.Kind() != reflect.Struct && t.Kind() != reflect.Slice)
58
+ }
59
+ switch delim {
60
+ case '{':
61
+ if t != nil && t.Kind() != reflect.Struct {
62
+ return false
63
+ }
64
+ fields := map[string]reflect.Type{}
65
+ if t != nil {
66
+ for i := 0; i < t.NumField(); i++ {
67
+ f := t.Field(i)
68
+ name := strings.Split(f.Tag.Get("json"), ",")[0]
69
+ fields[name] = f.Type
70
+ }
71
+ }
72
+ seen := map[string]bool{}
73
+ for d.More() {
74
+ k, err := d.Token()
75
+ if err != nil {
76
+ return false
77
+ }
78
+ key, ok := k.(string)
79
+ if !ok || seen[key] {
80
+ return false
81
+ }
82
+ seen[key] = true
83
+ field, known := fields[key]
84
+ if t != nil && !known {
85
+ return false
86
+ }
87
+ if !scanDataShape(d, field, depth+1) {
88
+ return false
89
+ }
90
+ }
91
+ end, err := d.Token()
92
+ if err != nil || end != json.Delim('}') {
93
+ return false
94
+ }
95
+ if t != nil {
96
+ for i := 0; i < t.NumField(); i++ {
97
+ tag := strings.Split(t.Field(i).Tag.Get("json"), ",")
98
+ if len(tag) == 1 && !seen[tag[0]] {
99
+ return false
100
+ }
101
+ }
102
+ }
103
+ return true
104
+ case '[':
105
+ if t != nil && t.Kind() != reflect.Slice {
106
+ return false
107
+ }
108
+ var elem reflect.Type
109
+ if t != nil {
110
+ elem = t.Elem()
111
+ }
112
+ for d.More() {
113
+ if !scanDataShape(d, elem, depth+1) {
114
+ return false
115
+ }
116
+ }
117
+ end, err := d.Token()
118
+ return err == nil && end == json.Delim(']')
119
+ }
120
+ return false
121
+ }
122
+
123
+ func validJSONUnicode(b []byte) bool {
124
+ if !utf8.Valid(b) {
125
+ return false
126
+ }
127
+ inString := false
128
+ for i := 0; i < len(b); i++ {
129
+ if b[i] == '"' {
130
+ inString = !inString
131
+ continue
132
+ }
133
+ if !inString || b[i] != '\\' {
134
+ continue
135
+ }
136
+ i++
137
+ if i >= len(b) {
138
+ return false
139
+ }
140
+ if b[i] != 'u' {
141
+ continue
142
+ }
143
+ if i+4 >= len(b) {
144
+ return false
145
+ }
146
+ r, ok := unicodeEscape(b[i+1 : i+5])
147
+ if !ok {
148
+ return false
149
+ }
150
+ i += 4
151
+ if r >= 0xdc00 && r <= 0xdfff {
152
+ return false
153
+ }
154
+ if r >= 0xd800 && r <= 0xdbff {
155
+ if i+6 >= len(b) || b[i+1] != '\\' || b[i+2] != 'u' {
156
+ return false
157
+ }
158
+ low, ok := unicodeEscape(b[i+3 : i+7])
159
+ if !ok || low < 0xdc00 || low > 0xdfff {
160
+ return false
161
+ }
162
+ i += 6
163
+ }
164
+ }
165
+ return !inString
166
+ }
167
+
168
+ func unicodeEscape(b []byte) (uint16, bool) {
169
+ var r uint16
170
+ for _, c := range b {
171
+ r <<= 4
172
+ switch {
173
+ case c >= '0' && c <= '9':
174
+ r += uint16(c - '0')
175
+ case c >= 'a' && c <= 'f':
176
+ r += uint16(c - 'a' + 10)
177
+ case c >= 'A' && c <= 'F':
178
+ r += uint16(c - 'A' + 10)
179
+ default:
180
+ return 0, false
181
+ }
182
+ }
183
+ return r, true
184
+ }
@@ -0,0 +1,30 @@
1
+ package helper
2
+
3
+ import (
4
+ "strings"
5
+ "testing"
6
+ )
7
+
8
+ func TestDataDecodeOptionalStructPointersRemainStrict(t *testing.T) {
9
+ type child struct {
10
+ Value uint64 `json:"value"`
11
+ }
12
+ type envelope struct {
13
+ Child *child `json:"child,omitempty"`
14
+ }
15
+ for _, tc := range []struct {
16
+ frame string
17
+ want Code
18
+ }{
19
+ {`{}`, ""}, {`{"child":{"value":1}}`, ""},
20
+ {`{"child":null}`, ErrInvalid}, {`{"child":{}}`, ErrInvalid},
21
+ {`{"child":{"value":1,"unknown":2}}`, ErrInvalid},
22
+ {`{"child":{"value":1,"value":2}}`, ErrInvalid},
23
+ {`{"Child":{"value":1}}`, ErrInvalid},
24
+ } {
25
+ var value envelope
26
+ if c := decodeDataObject(strings.NewReader(tc.frame), &value, MaxControlBytes); c != tc.want {
27
+ t.Fatalf("%s: %q want %q", tc.frame, c, tc.want)
28
+ }
29
+ }
30
+ }
@@ -0,0 +1,416 @@
1
+ package helper
2
+
3
+ import (
4
+ "bytes"
5
+ "crypto/sha256"
6
+ "encoding/hex"
7
+ "encoding/json"
8
+ "io"
9
+ "strings"
10
+ "sync"
11
+ "time"
12
+ "unicode/utf8"
13
+ )
14
+
15
+ type DataRequest struct {
16
+ Inventory Inventory `json:"inventory"`
17
+ Op Action `json:"op"`
18
+ Nonce string `json:"nonce"`
19
+ OperationID string `json:"operationId"`
20
+ Epoch string `json:"epoch"`
21
+ GrantID string `json:"grantId"`
22
+ GrantRevision uint64 `json:"grantRevision"`
23
+ Ticket string `json:"ticket"`
24
+ Args json.RawMessage `json:"args"`
25
+ }
26
+
27
+ // Digest binds the entire control, including args, to a trusted single-use
28
+ // ticket. It is not a signature or identity proof. RawMessage object order is
29
+ // preserved; the issuer must digest the same decoded control as the consumer.
30
+ func (r DataRequest) Digest() string {
31
+ b, err := json.Marshal(r)
32
+ if err != nil {
33
+ return ""
34
+ }
35
+ d := sha256.Sum256(b)
36
+ return hex.EncodeToString(d[:])
37
+ }
38
+
39
+ // NegotiateProtocol pins the selection to the approved inventory. Supporting
40
+ // both versions permits legacy health only for an approved protocol 1 payload;
41
+ // it never converts a file request or approved v2 payload into protocol 1.
42
+ func NegotiateProtocol(offered []int, approved Inventory, files bool) (int, Code) {
43
+ if len(offered) == 0 || len(offered) > 2 {
44
+ return 0, ErrInvalid
45
+ }
46
+ seen := map[int]bool{}
47
+ for _, p := range offered {
48
+ if p != 1 && p != DataProtocol {
49
+ return 0, ErrIncompatible
50
+ }
51
+ if seen[p] {
52
+ return 0, ErrInvalid
53
+ }
54
+ seen[p] = true
55
+ }
56
+ if !approved.Valid() || (approved.Protocol != 1 && approved.Protocol != DataProtocol) || !seen[approved.Protocol] || (files && approved.Protocol != DataProtocol) {
57
+ return 0, ErrIncompatible
58
+ }
59
+ return approved.Protocol, ""
60
+ }
61
+
62
+ // DecodeDataRequest is bounded syntax validation, not admission. No session,
63
+ // ACL, grant store, operation child or filesystem is accessed here.
64
+ func DecodeDataRequest(reader io.Reader) (DataRequest, Code) {
65
+ var r DataRequest
66
+ if c := decodeDataObject(reader, &r, MaxControlBytes); c != "" {
67
+ return DataRequest{}, c
68
+ }
69
+ if c := validateDataRequest(r); c != "" {
70
+ return DataRequest{}, c
71
+ }
72
+ return r, ""
73
+ }
74
+
75
+ func validateDataRequest(r DataRequest) Code { return validateOperationRequest(r, writeGates{}) }
76
+ func validateOperationRequest(r DataRequest, writes writeGates) Code {
77
+ if !r.Inventory.Valid() || r.Inventory.Protocol != DataProtocol {
78
+ return ErrIncompatible
79
+ }
80
+ if !allReferences(r.Nonce, r.OperationID, r.Epoch, r.GrantID, r.Ticket) || r.GrantRevision == 0 {
81
+ return ErrInvalid
82
+ }
83
+ var segments []string
84
+ var allowRoot bool
85
+ switch r.Op {
86
+ case ActionList:
87
+ var a ListArgs
88
+ if c := decodeDataObject(bytes.NewReader(r.Args), &a, MaxControlBytes); c != "" {
89
+ return c
90
+ }
91
+ if a.Limit == 0 {
92
+ return ErrInvalid
93
+ }
94
+ if a.Limit > MaxPageEntries {
95
+ return ErrLimit
96
+ }
97
+ if a.Cursor != "" && !digestPattern.MatchString(a.Cursor) {
98
+ return ErrInvalid
99
+ }
100
+ segments, allowRoot = a.Segments, true
101
+ case ActionStat:
102
+ var a StatArgs
103
+ if c := decodeDataObject(bytes.NewReader(r.Args), &a, MaxControlBytes); c != "" {
104
+ return c
105
+ }
106
+ segments, allowRoot = a.Segments, true
107
+ case ActionRead, ActionReadStream:
108
+ var a ReadArgs
109
+ if c := decodeDataObject(bytes.NewReader(r.Args), &a, MaxControlBytes); c != "" {
110
+ return c
111
+ }
112
+ if a.MaxBytes == 0 {
113
+ return ErrInvalid
114
+ }
115
+ ceiling := uint64(MaxBoundedBytes)
116
+ if r.Op == ActionReadStream {
117
+ ceiling = MaxTransferBytes
118
+ }
119
+ if a.MaxBytes > ceiling {
120
+ return ErrLimit
121
+ }
122
+ segments = a.Segments
123
+ case ActionCreate:
124
+ var a CreateArgs
125
+ if c := decodeDataObject(bytes.NewReader(r.Args), &a, MaxControlBytes); c != "" {
126
+ return c
127
+ }
128
+ if !a.Exclusive {
129
+ return ErrInvalid
130
+ }
131
+ if a.Bytes > MaxBoundedBytes {
132
+ return ErrLimit
133
+ }
134
+ if c := ValidateRelativeSegments(a.Segments, false); c != "" {
135
+ return c
136
+ }
137
+ if !writes.allows(r.Op) {
138
+ return ErrUnsupported
139
+ }
140
+ if a.Bytes == 0 {
141
+ return ErrLimit
142
+ }
143
+ return ""
144
+ case ActionWriteStream:
145
+ var a WriteStreamArgs
146
+ if c := decodeDataObject(bytes.NewReader(r.Args), &a, MaxControlBytes); c != "" {
147
+ return c
148
+ }
149
+ if a.MaxBytes == 0 {
150
+ return ErrInvalid
151
+ }
152
+ if a.MaxBytes > MaxTransferBytes {
153
+ return ErrLimit
154
+ }
155
+ if c := ValidateRelativeSegments(a.Segments, false); c != "" {
156
+ return c
157
+ }
158
+ if !writes.allows(r.Op) {
159
+ return ErrUnsupported
160
+ }
161
+ return ""
162
+ case ActionPublish:
163
+ var a PublishArgs
164
+ if c := decodeDataObject(bytes.NewReader(r.Args), &a, MaxControlBytes); c != "" {
165
+ return c
166
+ }
167
+ if !a.NoOverwrite || !digestPattern.MatchString(a.StageID) {
168
+ return ErrInvalid
169
+ }
170
+ if !writes.allows(r.Op) {
171
+ return ErrUnsupported
172
+ }
173
+ return ""
174
+ default:
175
+ return ErrUnsupported
176
+ }
177
+ return ValidateRelativeSegments(segments, allowRoot)
178
+ }
179
+
180
+ // JSON carries literal UTF-8 segments, never a URL-encoded path. No Clean,
181
+ // unescape, Unicode normalization or path-prefix authorization is performed.
182
+ func ValidateRelativeSegments(segments []string, allowRoot bool) Code {
183
+ if len(segments) > MaxPathSegments {
184
+ return ErrLimit
185
+ }
186
+ if segments == nil || (!allowRoot && len(segments) == 0) {
187
+ return ErrInvalid
188
+ }
189
+ total := 0
190
+ for i, s := range segments {
191
+ if len(s) > MaxSegmentBytes {
192
+ return ErrLimit
193
+ }
194
+ if s == "" || s == "." || s == ".." || !utf8.ValidString(s) || strings.ContainsAny(s, "/\\\x00") {
195
+ return ErrInvalid
196
+ }
197
+ total += len(s)
198
+ if i > 0 {
199
+ total++
200
+ }
201
+ if total > MaxPathBytes {
202
+ return ErrLimit
203
+ }
204
+ }
205
+ return ""
206
+ }
207
+
208
+ // TicketBinding may only be constructed by the future trusted S1 validator.
209
+ // In particular, package UID, opaque IDs and caller-supplied principal fields
210
+ // do not establish identity. This binding stays in deadline-bounded memory.
211
+ type TicketBinding struct {
212
+ Inventory Inventory
213
+ Epoch, SubjectRef, SessionRef string
214
+ Action Action
215
+ GrantID string
216
+ GrantRevision uint64
217
+ OperationID, Nonce, Ticket, RequestDigest string
218
+ ExpiresAt time.Time
219
+ }
220
+
221
+ // ReplayWindow is a contract fixture primitive for one validated native
222
+ // session in one epoch. The admission owner must retain exactly one window
223
+ // for that binding; it must never replace a full window to bypass replay.
224
+ // S2/S3 must integrate consumption at their common admission ordering point.
225
+ type ReplayWindow struct {
226
+ mu sync.Mutex
227
+ inventory Inventory
228
+ epoch, subject, session string
229
+ nonces, operations, tickets map[string]bool
230
+ }
231
+
232
+ func NewReplayWindow(i Inventory, epoch, subject, session string) (*ReplayWindow, Code) {
233
+ if !i.Valid() || i.Protocol != DataProtocol {
234
+ return nil, ErrIncompatible
235
+ }
236
+ if !allReferences(epoch, subject, session) {
237
+ return nil, ErrInvalid
238
+ }
239
+ return &ReplayWindow{inventory: i, epoch: epoch, subject: subject, session: session, nonces: map[string]bool{}, operations: map[string]bool{}, tickets: map[string]bool{}}, ""
240
+ }
241
+
242
+ func (w *ReplayWindow) Consume(r DataRequest, b TicketBinding, now time.Time) Code {
243
+ if w == nil || w.nonces == nil {
244
+ return ErrIncompatible
245
+ }
246
+ if c := validateDataRequest(r); c != "" {
247
+ return c
248
+ }
249
+ if r.Inventory != w.inventory || b.Inventory != w.inventory {
250
+ return ErrIncompatible
251
+ }
252
+ if r.Epoch != w.epoch || b.Epoch != w.epoch {
253
+ return ErrStale
254
+ }
255
+ if b.SubjectRef != w.subject || b.SessionRef != w.session || b.Action != r.Op || b.GrantID != r.GrantID || b.GrantRevision != r.GrantRevision || b.OperationID != r.OperationID || b.Nonce != r.Nonce || b.Ticket != r.Ticket || b.RequestDigest != r.Digest() {
256
+ return ErrDenied
257
+ }
258
+ if !now.Before(b.ExpiresAt) {
259
+ return ErrExpired
260
+ }
261
+ if b.ExpiresAt.Sub(now) > IntentTTL {
262
+ return ErrInvalid
263
+ }
264
+ w.mu.Lock()
265
+ defer w.mu.Unlock()
266
+ if w.nonces[r.Nonce] || w.operations[r.OperationID] || w.tickets[r.Ticket] {
267
+ return ErrReplay
268
+ }
269
+ if len(w.nonces) >= MaxReplayEntries {
270
+ return ErrBusy
271
+ }
272
+ w.nonces[r.Nonce] = true
273
+ w.operations[r.OperationID] = true
274
+ w.tickets[r.Ticket] = true
275
+ return ""
276
+ }
277
+
278
+ func DecodeGrantStore(reader io.Reader) (GrantStore, Code) {
279
+ var s GrantStore
280
+ if c := decodeDataObject(reader, &s, MaxGrantStoreBytes); c != "" {
281
+ return GrantStore{}, c
282
+ }
283
+ if s.Schema != GrantSchema || s.Revision == 0 || s.Grants == nil {
284
+ return GrantStore{}, ErrInvalid
285
+ }
286
+ if len(s.Grants) > MaxGrants {
287
+ return GrantStore{}, ErrLimit
288
+ }
289
+ seen := map[string]bool{}
290
+ for _, g := range s.Grants {
291
+ if c := validateGrant(g); c != "" {
292
+ return GrantStore{}, c
293
+ }
294
+ if seen[g.ID] {
295
+ return GrantStore{}, ErrInvalid
296
+ }
297
+ seen[g.ID] = true
298
+ }
299
+ return s, ""
300
+ }
301
+
302
+ func validateGrant(g Grant) Code {
303
+ if g.Schema != GrantSchema || g.Revision == 0 || !allReferences(g.ID, g.ApprovalBinding, g.CapabilityDigest) || g.CreatedAt <= 0 {
304
+ return ErrInvalid
305
+ }
306
+ if !g.Inventory.Valid() || g.Inventory.Protocol != DataProtocol {
307
+ return ErrIncompatible
308
+ }
309
+ if !validPrincipal(g.Owner) || !validPrincipal(g.Issuer) || !validContinuity(g.LastValidated) {
310
+ return ErrInvalid
311
+ }
312
+ if g.Owner.IdentityBasis == "uid-username" || g.Issuer.IdentityBasis == "uid-username" {
313
+ if g.Inventory.DataAccess != "relaxed" || g.Owner.IdentityBasis != "uid-username" || g.Issuer.IdentityBasis != "uid-username" {
314
+ return ErrInvalid
315
+ }
316
+ }
317
+ if g.Scope.Kind != ScopeShared && g.Scope.Kind != ScopePersonal {
318
+ return ErrInvalid
319
+ }
320
+ if g.Scope.TargetKind != "directory" || !allReferences(g.Scope.AnchorRef, g.Scope.ObjectRef, g.Scope.MountRef) {
321
+ return ErrInvalid
322
+ }
323
+ if g.Scope.Kind == ScopePersonal && g.Owner != g.Issuer {
324
+ return ErrDenied
325
+ }
326
+ if c := ValidateRelativeSegments(g.Scope.Segments, g.Scope.Kind == ScopeShared); c != "" {
327
+ return c
328
+ }
329
+ if c := validateGrantActions(g.Actions); c != "" {
330
+ return c
331
+ }
332
+ switch g.State {
333
+ case GrantActive:
334
+ if g.RevokedAt != 0 || g.Reason != "" {
335
+ return ErrInvalid
336
+ }
337
+ case GrantSuspended:
338
+ if g.RevokedAt != 0 || !g.Reason.Valid() {
339
+ return ErrInvalid
340
+ }
341
+ case GrantRevoked:
342
+ if g.RevokedAt < g.CreatedAt || !g.Reason.Valid() {
343
+ return ErrInvalid
344
+ }
345
+ default:
346
+ return ErrInvalid
347
+ }
348
+ return ""
349
+ }
350
+
351
+ func DecodeIntent(reader io.Reader) (Intent, Code) {
352
+ var i Intent
353
+ if c := decodeDataObject(reader, &i, MaxControlBytes); c != "" {
354
+ return Intent{}, c
355
+ }
356
+ if !i.Inventory.Valid() || i.Inventory.Protocol != DataProtocol {
357
+ return Intent{}, ErrIncompatible
358
+ }
359
+ if !allReferences(i.ID, i.Epoch, i.SubjectRef, i.SessionRef, i.CandidateID, i.SummaryDigest) || i.ExpiresAt <= 0 || (i.ScopeKind != ScopeShared && i.ScopeKind != ScopePersonal) {
360
+ return Intent{}, ErrInvalid
361
+ }
362
+ if c := validateGrantActions(i.Actions); c != "" {
363
+ return Intent{}, c
364
+ }
365
+ return i, ""
366
+ }
367
+
368
+ func validateGrantActions(actions []Action) Code {
369
+ if len(actions) == 0 || len(actions) > 7 {
370
+ return ErrInvalid
371
+ }
372
+ seen := map[Action]bool{}
373
+ for _, a := range actions {
374
+ if !a.ReadOnly() && a != ActionCreate && a != ActionWriteStream && a != ActionPublish {
375
+ return ErrUnsupported
376
+ }
377
+ if seen[a] {
378
+ return ErrInvalid
379
+ }
380
+ seen[a] = true
381
+ }
382
+ return ""
383
+ }
384
+ func allReferences(refs ...string) bool {
385
+ for _, r := range refs {
386
+ if !digestPattern.MatchString(r) {
387
+ return false
388
+ }
389
+ }
390
+ return true
391
+ }
392
+ func validPrincipal(p Principal) bool {
393
+ if p.Kind != "local" || !allReferences(p.SubjectRef, p.InstanceRef) {
394
+ return false
395
+ }
396
+ if p.IdentityBasis == "" {
397
+ return p.UID == 0 && p.Username == ""
398
+ }
399
+ return p.IdentityBasis == "uid-username" && validRelaxedIdentity(RelaxedIdentity{p.UID, p.Username})
400
+ }
401
+ func validContinuity(b ContinuityBinding) bool {
402
+ return allReferences(b.Epoch, b.SubjectProof, b.ScopeProof)
403
+ }
404
+
405
+ // MarshalJSON prevents an accidentally propagated native error string from
406
+ // becoming a wire code or operation ID. Paths/messages have no field here.
407
+ func (e SafeError) MarshalJSON() ([]byte, error) {
408
+ if !e.Code.Valid() {
409
+ e.Code = ErrInternal
410
+ }
411
+ if e.OperationID != "" && !digestPattern.MatchString(e.OperationID) {
412
+ e.OperationID = ""
413
+ }
414
+ type safe SafeError
415
+ return json.Marshal(safe(e))
416
+ }