@opensoha/contracts 0.1.27 → 0.2.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 (871) hide show
  1. package/COMPATIBILITY.md +141 -16
  2. package/README.md +153 -50
  3. package/agent/agent-protocol.schema.json +2 -2
  4. package/agent/dsh-runtime.README.md +207 -0
  5. package/agent/dsh-runtime.schema.json +1165 -0
  6. package/agent/environment/mcp_stdio.go +30 -0
  7. package/agent/guest/runtime.go +1 -1
  8. package/agent/guest/runtime_test.go +1 -1
  9. package/auth/catalog_generated.go +2 -2
  10. package/auth/docker_permissions_test.go +44 -0
  11. package/auth/permission-catalog.json +65 -1
  12. package/auth/radius_permissions_test.go +44 -0
  13. package/compat/consumer-revisions.json +6 -6
  14. package/compat/json-schema-ecosystem-0.1.0.json +1 -1
  15. package/compat/openapi-loose-boundaries-0.1.0.json +5 -1
  16. package/docker/runtime/compose.go +128 -0
  17. package/docker/runtime/compose_replicas_test.go +20 -0
  18. package/docker/runtime/container_set.go +50 -0
  19. package/docker/runtime/container_set_test.go +31 -0
  20. package/docker/runtime/identity.go +130 -0
  21. package/docker/runtime/identity_test.go +91 -0
  22. package/docker/runtime/read.go +141 -0
  23. package/docker/runtime/read_result.go +93 -0
  24. package/docker/runtime/read_result_test.go +111 -0
  25. package/docker/runtime/read_test.go +63 -0
  26. package/docker/runtime/terminal.go +86 -0
  27. package/docker/runtime/terminal_test.go +50 -0
  28. package/examples/relations_compat_test.go +1 -1
  29. package/fixtures/json-schema/agent-protocol/valid/dsh-agent-status.json +17 -0
  30. package/fixtures/json-schema/docker-container-identity/invalid/name-instead-of-id.json +8 -0
  31. package/fixtures/json-schema/docker-container-identity/invalid/short-id.json +8 -0
  32. package/fixtures/json-schema/docker-container-identity/invalid/unknown-field.json +9 -0
  33. package/fixtures/json-schema/docker-container-identity/invalid/unsafe-service.json +8 -0
  34. package/fixtures/json-schema/docker-container-identity/valid/bound-container.json +8 -0
  35. package/fixtures/json-schema/docker-project-identity/invalid/injected-field.json +7 -0
  36. package/fixtures/json-schema/docker-project-identity/invalid/invalid-uid.json +6 -0
  37. package/fixtures/json-schema/docker-project-identity/invalid/legacy-protocol.json +6 -0
  38. package/fixtures/json-schema/docker-project-identity/invalid/nil-uid.json +6 -0
  39. package/fixtures/json-schema/docker-project-identity/invalid/slug-namespace.json +6 -0
  40. package/fixtures/json-schema/docker-project-identity/valid/bound-project.json +6 -0
  41. package/fixtures/json-schema/docker-runtime-read/invalid/1.json +14 -0
  42. package/fixtures/json-schema/docker-runtime-read/invalid/2.json +14 -0
  43. package/fixtures/json-schema/docker-runtime-read/invalid/3.json +14 -0
  44. package/fixtures/json-schema/docker-runtime-read/invalid/4.json +16 -0
  45. package/fixtures/json-schema/docker-runtime-read/invalid/5.json +14 -0
  46. package/fixtures/json-schema/docker-runtime-read/invalid/6.json +15 -0
  47. package/fixtures/json-schema/docker-runtime-read/invalid/7.json +15 -0
  48. package/fixtures/json-schema/docker-runtime-read/valid/1.json +14 -0
  49. package/fixtures/json-schema/docker-runtime-read/valid/2.json +14 -0
  50. package/fixtures/json-schema/docker-runtime-read/valid/3.json +17 -0
  51. package/fixtures/json-schema/docker-runtime-read/valid/4.json +17 -0
  52. package/fixtures/json-schema/docker-runtime-read-result/invalid/contradictory-completeness.json +21 -0
  53. package/fixtures/json-schema/docker-runtime-read-result/invalid/host-source-leak.json +28 -0
  54. package/fixtures/json-schema/docker-runtime-read-result/invalid/missing-files.json +20 -0
  55. package/fixtures/json-schema/docker-runtime-read-result/invalid/unsupported-browse.json +27 -0
  56. package/fixtures/json-schema/docker-runtime-read-result/valid/logs.json +21 -0
  57. package/fixtures/json-schema/docker-runtime-read-result/valid/volumes.json +27 -0
  58. package/fixtures/json-schema/dsh-runtime/invalid/assembly-report-credential.json +21 -0
  59. package/fixtures/json-schema/dsh-runtime/invalid/attempt-zero.json +18 -0
  60. package/fixtures/json-schema/dsh-runtime/invalid/bad-deadline.json +18 -0
  61. package/fixtures/json-schema/dsh-runtime/invalid/bad-hash.json +18 -0
  62. package/fixtures/json-schema/dsh-runtime/invalid/event-delta-missing.json +10 -0
  63. package/fixtures/json-schema/dsh-runtime/invalid/event-grant.json +12 -0
  64. package/fixtures/json-schema/dsh-runtime/invalid/event-sequence-zero.json +12 -0
  65. package/fixtures/json-schema/dsh-runtime/invalid/fence-zero.json +18 -0
  66. package/fixtures/json-schema/dsh-runtime/invalid/health-unknown-field.json +12 -0
  67. package/fixtures/json-schema/dsh-runtime/invalid/output-budget-zero.json +18 -0
  68. package/fixtures/json-schema/dsh-runtime/invalid/receipt-grant.json +12 -0
  69. package/fixtures/json-schema/dsh-runtime/invalid/start-assembly-url.json +32 -0
  70. package/fixtures/json-schema/dsh-runtime/invalid/start-chat-write-tool.json +38 -0
  71. package/fixtures/json-schema/dsh-runtime/invalid/start-client-base-url.json +19 -0
  72. package/fixtures/json-schema/dsh-runtime/invalid/start-client-callback.json +19 -0
  73. package/fixtures/json-schema/dsh-runtime/invalid/start-missing-readonly.json +37 -0
  74. package/fixtures/json-schema/dsh-runtime/invalid/status-grant.json +19 -0
  75. package/fixtures/json-schema/dsh-runtime/invalid/status-usage-missing.json +13 -0
  76. package/fixtures/json-schema/dsh-runtime/invalid/status-usage-unknown.json +18 -0
  77. package/fixtures/json-schema/dsh-runtime/invalid/tool-call-missing-call-id.json +13 -0
  78. package/fixtures/json-schema/dsh-runtime/invalid/tool-result-missing-hash.json +13 -0
  79. package/fixtures/json-schema/dsh-runtime/invalid/union-extra-field.json +12 -0
  80. package/fixtures/json-schema/dsh-runtime/invalid/unsupported-version.json +18 -0
  81. package/fixtures/json-schema/dsh-runtime/valid/assembly-decision.json +21 -0
  82. package/fixtures/json-schema/dsh-runtime/valid/assembly-report-mcp.json +34 -0
  83. package/fixtures/json-schema/dsh-runtime/valid/assembly-report.json +20 -0
  84. package/fixtures/json-schema/dsh-runtime/valid/cancel.json +8 -0
  85. package/fixtures/json-schema/dsh-runtime/valid/event-delta.json +12 -0
  86. package/fixtures/json-schema/dsh-runtime/valid/event-hook-observed.json +14 -0
  87. package/fixtures/json-schema/dsh-runtime/valid/event-terminal.json +13 -0
  88. package/fixtures/json-schema/dsh-runtime/valid/health.json +11 -0
  89. package/fixtures/json-schema/dsh-runtime/valid/receipt.json +11 -0
  90. package/fixtures/json-schema/dsh-runtime/valid/start-assembly.json +31 -0
  91. package/fixtures/json-schema/dsh-runtime/valid/start-chat.json +18 -0
  92. package/fixtures/json-schema/dsh-runtime/valid/start-heya.json +38 -0
  93. package/fixtures/json-schema/dsh-runtime/valid/status-completed.json +18 -0
  94. package/fixtures/json-schema/dsh-runtime/valid/status-unknown.json +13 -0
  95. package/fixtures/json-schema/dsh-runtime/valid/tool-call.json +1 -0
  96. package/fixtures/json-schema/dsh-runtime/valid/tool-result-denied.json +15 -0
  97. package/fixtures/json-schema/dsh-runtime/valid/tool-result.json +14 -0
  98. package/fixtures/json-schema/memory-policy/invalid/invalid-mode.json +17 -0
  99. package/fixtures/json-schema/memory-policy/valid/scoped.json +17 -0
  100. package/fixtures/json-schema/memory-record/invalid/invalid-source-hash.json +21 -0
  101. package/fixtures/json-schema/memory-record/invalid/invalid-sync-status.json +21 -0
  102. package/fixtures/json-schema/memory-record/invalid/quarantine-reason-too-long.json +23 -0
  103. package/fixtures/json-schema/memory-record/valid/quarantined.json +23 -0
  104. package/fixtures/json-schema/memory-record/valid/synced.json +21 -0
  105. package/fixtures/json-schema/network-ingest-event/invalid/proxy-runtime-epoch-without-sequence.json +23 -0
  106. package/fixtures/json-schema/network-ingest-event/invalid/proxy-runtime-unsafe-sequence.json +24 -0
  107. package/fixtures/json-schema/network-ingest-event/valid/proxy-runtime-epoch.json +24 -0
  108. package/fixtures/json-schema/network-runtime-protocol/invalid/eap-activate-partial-profile.json +16 -0
  109. package/fixtures/json-schema/network-runtime-protocol/invalid/eap-revoke-other-kind.json +16 -0
  110. package/fixtures/json-schema/network-runtime-protocol/invalid/enrollment-duplicate-capability.json +30 -0
  111. package/fixtures/json-schema/network-runtime-protocol/invalid/enrollment-unknown-capability.json +30 -0
  112. package/fixtures/json-schema/network-runtime-protocol/invalid/legacy-with-proof.json +19 -0
  113. package/fixtures/json-schema/network-runtime-protocol/invalid/ttls-certificate.json +42 -0
  114. package/fixtures/json-schema/network-runtime-protocol/invalid/ttls-device-override.json +19 -0
  115. package/fixtures/json-schema/network-runtime-protocol/invalid/ttls-no-proof.json +17 -0
  116. package/fixtures/json-schema/network-runtime-protocol/invalid/ttls-nonstation-identity.json +18 -0
  117. package/fixtures/json-schema/network-runtime-protocol/invalid/ttls-profile-without-pap.json +40 -0
  118. package/fixtures/json-schema/network-runtime-protocol/valid/app-default-enrollment.json +29 -0
  119. package/fixtures/json-schema/network-runtime-protocol/valid/app-mihomo-enrollment.json +32 -0
  120. package/fixtures/json-schema/network-runtime-protocol/valid/eap-activate-profile.json +17 -0
  121. package/fixtures/json-schema/network-runtime-protocol/valid/eap-revoke-result.json +16 -0
  122. package/fixtures/json-schema/network-runtime-protocol/valid/eap-revoke.json +16 -0
  123. package/fixtures/json-schema/network-runtime-protocol/valid/proxy-default-enrollment.json +23 -0
  124. package/fixtures/json-schema/network-runtime-protocol/valid/ttls-authorization.json +18 -0
  125. package/fixtures/json-schema/network-runtime-protocol/valid/ttls-profile-enrollment.json +23 -0
  126. package/fixtures/json-schema/network-runtime-protocol/valid/ttls-profile.json +41 -0
  127. package/fixtures/json-schema/proxy-adapter/invalid/apply-incomplete-result.json +11 -0
  128. package/fixtures/json-schema/proxy-adapter/invalid/close-incomplete-result.json +9 -0
  129. package/fixtures/json-schema/proxy-adapter/invalid/handshake-incomplete-result.json +11 -0
  130. package/fixtures/json-schema/proxy-adapter/invalid/invalid-method.json +11 -0
  131. package/fixtures/json-schema/proxy-adapter/invalid/major.json +11 -0
  132. package/fixtures/json-schema/proxy-adapter/invalid/missing-challenge.json +9 -0
  133. package/fixtures/json-schema/proxy-adapter/invalid/multiple-outcomes.json +12 -0
  134. package/fixtures/json-schema/proxy-adapter/invalid/observe-incomplete-result.json +9 -0
  135. package/fixtures/json-schema/proxy-adapter/invalid/unknown-field.json +12 -0
  136. package/fixtures/json-schema/proxy-adapter/valid/apply-result.json +12 -0
  137. package/fixtures/json-schema/proxy-adapter/valid/close-result.json +11 -0
  138. package/fixtures/json-schema/proxy-adapter/valid/handshake-result.json +19 -0
  139. package/fixtures/json-schema/proxy-adapter/valid/handshake.json +11 -0
  140. package/fixtures/json-schema/proxy-adapter/valid/observe-result.json +20 -0
  141. package/fixtures/json-schema/proxy-runtime/invalid/deployment-stop-accepting.json +19 -0
  142. package/fixtures/json-schema/proxy-runtime/invalid/deployment-stopped-unknown.json +21 -0
  143. package/fixtures/json-schema/proxy-runtime/invalid/duplicate-capability.json +20 -0
  144. package/fixtures/json-schema/proxy-runtime/invalid/guarded-udp-unknown.json +19 -0
  145. package/fixtures/json-schema/proxy-runtime/invalid/ingress-check-cross-payload.json +9 -0
  146. package/fixtures/json-schema/proxy-runtime/invalid/ingress-check-result-cross-payload.json +9 -0
  147. package/fixtures/json-schema/proxy-runtime/invalid/publication-ready-cross-payload.json +9 -0
  148. package/fixtures/json-schema/proxy-runtime/invalid/unknown-field.json +18 -0
  149. package/fixtures/json-schema/proxy-runtime/valid/deployment-process-stopped.json +21 -0
  150. package/fixtures/json-schema/proxy-runtime/valid/deployment-stop-required.json +19 -0
  151. package/fixtures/json-schema/proxy-runtime/valid/guarded-udp.json +20 -0
  152. package/fixtures/json-schema/proxy-runtime/valid/ingress-check-result.json +15 -0
  153. package/fixtures/json-schema/proxy-runtime/valid/ingress-check.json +18 -0
  154. package/fixtures/json-schema/proxy-runtime/valid/management-capabilities.json +26 -0
  155. package/fixtures/json-schema/proxy-runtime/valid/observation.json +17 -0
  156. package/fixtures/json-schema/proxy-runtime/valid/publication-ready.json +16 -0
  157. package/fixtures/json-schema/radius-password-verifier/invalid/bare-pap.json +9 -0
  158. package/fixtures/json-schema/radius-password-verifier/invalid/empty-password.json +9 -0
  159. package/fixtures/json-schema/radius-password-verifier/invalid/enumeration.json +4 -0
  160. package/fixtures/json-schema/radius-password-verifier/invalid/failure-with-subject.json +5 -0
  161. package/fixtures/json-schema/radius-password-verifier/invalid/invalid-station.json +9 -0
  162. package/fixtures/json-schema/radius-password-verifier/invalid/radius-xlat.json +16 -0
  163. package/fixtures/json-schema/radius-password-verifier/invalid/raw-password.json +10 -0
  164. package/fixtures/json-schema/radius-password-verifier/invalid/success-without-receipt.json +5 -0
  165. package/fixtures/json-schema/radius-password-verifier/invalid/too-long.json +9 -0
  166. package/fixtures/json-schema/radius-password-verifier/invalid/url-base64.json +9 -0
  167. package/fixtures/json-schema/radius-password-verifier/invalid/wrong-method.json +9 -0
  168. package/fixtures/json-schema/radius-password-verifier/valid/failure.json +4 -0
  169. package/fixtures/json-schema/radius-password-verifier/valid/radius-success.json +16 -0
  170. package/fixtures/json-schema/radius-password-verifier/valid/request.json +9 -0
  171. package/fixtures/json-schema/radius-password-verifier/valid/success.json +6 -0
  172. package/fixtures/json-schema/radius-runtime/invalid/control-with-secret.json +30 -0
  173. package/fixtures/json-schema/radius-runtime/invalid/known-null.json +21 -0
  174. package/fixtures/json-schema/radius-runtime/invalid/known-without-count.json +20 -0
  175. package/fixtures/json-schema/radius-runtime/invalid/stopped-still-accepting.json +21 -0
  176. package/fixtures/json-schema/radius-runtime/invalid/stopped-with-live-state.json +21 -0
  177. package/fixtures/json-schema/radius-runtime/invalid/unknown-with-zero.json +21 -0
  178. package/fixtures/json-schema/radius-runtime/valid/bootstrap-control.json +29 -0
  179. package/fixtures/json-schema/radius-runtime/valid/known-zero.json +21 -0
  180. package/fixtures/json-schema/radius-runtime/valid/owned-child-stopped.json +21 -0
  181. package/fixtures/json-schema/radius-runtime/valid/unknown-state.json +20 -0
  182. package/fixtures/openapi/AIMemoryPolicy/invalid/invalid-mode.json +16 -0
  183. package/fixtures/openapi/AIMemoryPolicy/valid/legacy-global.json +12 -0
  184. package/fixtures/openapi/AIMemoryPolicy/valid/scoped.json +16 -0
  185. package/fixtures/openapi/AIMemoryPolicyInput/invalid/invalid-mode.json +9 -0
  186. package/fixtures/openapi/AIMemoryPolicyInput/invalid/owner-spoof.json +10 -0
  187. package/fixtures/openapi/AIMemoryPolicyInput/valid/heya-automatic.json +9 -0
  188. package/fixtures/openapi/AIMemoryPolicyInput/valid/scoped.json +9 -0
  189. package/fixtures/openapi/AIMemoryRecord/invalid/invalid-source-hash.json +20 -0
  190. package/fixtures/openapi/AIMemoryRecord/invalid/invalid-sync-status.json +20 -0
  191. package/fixtures/openapi/AIMemoryRecord/invalid/quarantine-reason-too-long.json +22 -0
  192. package/fixtures/openapi/AIMemoryRecord/valid/delete-pending.json +21 -0
  193. package/fixtures/openapi/AIMemoryRecord/valid/quarantined.json +22 -0
  194. package/fixtures/openapi/AIMemoryRecord/valid/synced.json +20 -0
  195. package/fixtures/openapi/AgentConditionalResourceMutationRequest/invalid/preconditions-v1.json +8 -0
  196. package/fixtures/openapi/AgentConditionalResourceMutationRequest/valid/preconditions-v1.json +9 -0
  197. package/fixtures/openapi/AgentConditionalResourceYamlRequest/invalid/preconditions-v1.json +6 -0
  198. package/fixtures/openapi/AgentConditionalResourceYamlRequest/valid/preconditions-v1.json +10 -0
  199. package/fixtures/openapi/AgentPodArgvResult/invalid/native-pod-execution-v1.json +17 -0
  200. package/fixtures/openapi/AgentPodArgvResult/valid/native-pod-execution-v1.json +24 -0
  201. package/fixtures/openapi/AgentPodExecutionCapabilities/invalid/native-pod-execution-v1.json +7 -0
  202. package/fixtures/openapi/AgentPodExecutionCapabilities/valid/native-pod-execution-v1.json +7 -0
  203. package/fixtures/openapi/AgentRunCallbackRequest/valid/dsh-agent-status.json +17 -0
  204. package/fixtures/openapi/AlertOwnershipInput/invalid/workbench.json +3 -0
  205. package/fixtures/openapi/AlertOwnershipInput/valid/workbench.json +4 -0
  206. package/fixtures/openapi/ApplicationEnvironmentListEnvelope/invalid/legacy-list-alias.json +4 -0
  207. package/fixtures/openapi/ApplicationEnvironmentListEnvelope/valid/legacy-list-alias.json +4 -0
  208. package/fixtures/openapi/ApplicationListEnvelope/invalid/legacy-list-alias.json +4 -0
  209. package/fixtures/openapi/ApplicationListEnvelope/valid/legacy-list-alias.json +4 -0
  210. package/fixtures/openapi/ApplicationServiceListEnvelope/invalid/legacy-list-alias.json +4 -0
  211. package/fixtures/openapi/ApplicationServiceListEnvelope/valid/legacy-list-alias.json +4 -0
  212. package/fixtures/openapi/CLIAuthContext/invalid/cli-boundary.json +13 -0
  213. package/fixtures/openapi/CLIAuthContext/valid/cli-boundary.json +12 -0
  214. package/fixtures/openapi/CLIAuthOptions/invalid/cli-boundary.json +14 -0
  215. package/fixtures/openapi/CLIAuthOptions/valid/cli-boundary.json +13 -0
  216. package/fixtures/openapi/CLIAuthOptions/valid/governed-ai.json +14 -0
  217. package/fixtures/openapi/CLIDeviceAuthorization/invalid/cli-boundary.json +10 -0
  218. package/fixtures/openapi/CLIDeviceAuthorization/invalid/numeric-code.json +9 -0
  219. package/fixtures/openapi/CLIDeviceAuthorization/valid/cli-boundary.json +9 -0
  220. package/fixtures/openapi/CLIDeviceAuthorizationCreateRequest/invalid/basic.json +5 -0
  221. package/fixtures/openapi/CLIDeviceAuthorizationCreateRequest/valid/basic.json +5 -0
  222. package/fixtures/openapi/CLIDeviceCancelRequest/invalid/cli-boundary.json +5 -0
  223. package/fixtures/openapi/CLIDeviceCancelRequest/valid/cli-boundary.json +4 -0
  224. package/fixtures/openapi/CLIDeviceDecisionRequest/invalid/basic.json +6 -0
  225. package/fixtures/openapi/CLIDeviceDecisionRequest/valid/basic.json +6 -0
  226. package/fixtures/openapi/CLIDeviceInspectRequest/invalid/basic.json +4 -0
  227. package/fixtures/openapi/CLIDeviceInspectRequest/valid/basic.json +4 -0
  228. package/fixtures/openapi/CLIDeviceTokenRequest/invalid/basic.json +5 -0
  229. package/fixtures/openapi/CLIDeviceTokenRequest/valid/basic.json +5 -0
  230. package/fixtures/openapi/CLILogoutRequest/invalid/cli-boundary.json +4 -0
  231. package/fixtures/openapi/CLILogoutRequest/valid/cli-boundary.json +3 -0
  232. package/fixtures/openapi/CLIRefreshRequest/invalid/basic.json +3 -0
  233. package/fixtures/openapi/CLIRefreshRequest/valid/basic.json +4 -0
  234. package/fixtures/openapi/CLISession/invalid/cli-boundary.json +12 -0
  235. package/fixtures/openapi/CLISession/valid/cli-boundary.json +11 -0
  236. package/fixtures/openapi/DeliveryBlueprintListEnvelope/invalid/legacy-list-alias.json +4 -0
  237. package/fixtures/openapi/DeliveryBlueprintListEnvelope/valid/legacy-list-alias.json +4 -0
  238. package/fixtures/openapi/DeliveryEnvironmentListEnvelope/invalid/legacy-list-alias.json +4 -0
  239. package/fixtures/openapi/DeliveryEnvironmentListEnvelope/valid/legacy-list-alias.json +4 -0
  240. package/fixtures/openapi/DeliveryPlanServiceReferenceImpact/invalid/hidden-count.json +24 -0
  241. package/fixtures/openapi/DeliveryPlanServiceReferenceImpact/invalid/hidden-identities.json +26 -0
  242. package/fixtures/openapi/DeliveryPlanServiceReferenceImpact/invalid/invalid-frozen-revision.json +23 -0
  243. package/fixtures/openapi/DeliveryPlanServiceReferenceImpact/invalid/missing-current-revision.json +22 -0
  244. package/fixtures/openapi/DeliveryPlanServiceReferenceImpact/invalid/private-complete-snapshot.json +37 -0
  245. package/fixtures/openapi/DeliveryPlanServiceReferenceImpact/invalid/too-many-items.json +1223 -0
  246. package/fixtures/openapi/DeliveryPlanServiceReferenceImpact/valid/current-plan.json +23 -0
  247. package/fixtures/openapi/DeliveryPlanServiceReferenceImpact/valid/stale-plan-current-visible-page.json +23 -0
  248. package/fixtures/openapi/DeliveryTemplateUsageApplication/invalid/unknown-field.json +4 -0
  249. package/fixtures/openapi/DeliveryTemplateUsageApplication/valid/minimal.json +3 -0
  250. package/fixtures/openapi/DeliveryTemplateUsageBinding/invalid/unknown-field.json +6 -0
  251. package/fixtures/openapi/DeliveryTemplateUsageBinding/valid/minimal.json +5 -0
  252. package/fixtures/openapi/DeliveryTemplateUsageBuildSource/invalid/unknown-field.json +7 -0
  253. package/fixtures/openapi/DeliveryTemplateUsageBuildSource/valid/minimal.json +6 -0
  254. package/fixtures/openapi/DeliveryTemplateUsageEnvironment/invalid/unknown-field.json +5 -0
  255. package/fixtures/openapi/DeliveryTemplateUsageEnvironment/valid/minimal.json +4 -0
  256. package/fixtures/openapi/DeliveryTemplateUsageRuntimeItem/invalid/unknown-field.json +6 -0
  257. package/fixtures/openapi/DeliveryTemplateUsageRuntimeItem/valid/minimal.json +5 -0
  258. package/fixtures/openapi/DeliveryTemplateUsageRuntimeSummary/invalid/unknown-field.json +20 -0
  259. package/fixtures/openapi/DeliveryTemplateUsageRuntimeSummary/valid/minimal.json +19 -0
  260. package/fixtures/openapi/DeliveryTemplateUsageSummary/invalid/missing-kind.json +16 -0
  261. package/fixtures/openapi/DeliveryTemplateUsageSummary/valid/static.json +17 -0
  262. package/fixtures/openapi/DeliveryTemplateUsageSummaryEnvelope/invalid/legacy-items.json +3 -0
  263. package/fixtures/openapi/DeliveryTemplateUsageSummaryEnvelope/valid/static.json +19 -0
  264. package/fixtures/openapi/DirectorySyncRequestEnvelope/invalid/original-request.json +25 -0
  265. package/fixtures/openapi/DirectorySyncRequestEnvelope/valid/original-request.json +24 -0
  266. package/fixtures/openapi/DirectorySyncRequestInput/invalid/original-request.json +4 -0
  267. package/fixtures/openapi/DirectorySyncRequestInput/valid/original-request.json +3 -0
  268. package/fixtures/openapi/DirectorySyncRequestOrganizations/invalid/original-request.json +7 -0
  269. package/fixtures/openapi/DirectorySyncRequestOrganizations/valid/original-request.json +6 -0
  270. package/fixtures/openapi/DirectorySyncRequestPeople/invalid/original-request.json +7 -0
  271. package/fixtures/openapi/DirectorySyncRequestPeople/valid/original-request.json +6 -0
  272. package/fixtures/openapi/DirectorySyncRequestReceipt/invalid/original-request.json +23 -0
  273. package/fixtures/openapi/DirectorySyncRequestReceipt/valid/original-request.json +22 -0
  274. package/fixtures/openapi/DirectorySyncRequestRun/invalid/cancel-flag.json +1 -0
  275. package/fixtures/openapi/DirectorySyncRequestRun/invalid/original-request.json +19 -0
  276. package/fixtures/openapi/DirectorySyncRequestRun/valid/original-request.json +19 -0
  277. package/fixtures/openapi/DockerConfigurationChange/invalid/field.json +5 -0
  278. package/fixtures/openapi/DockerConfigurationChange/invalid/integer-overflow.json +4 -0
  279. package/fixtures/openapi/DockerConfigurationChange/valid/field.json +4 -0
  280. package/fixtures/openapi/DockerConfigurationDeleteInput/invalid/delete.json +7 -0
  281. package/fixtures/openapi/DockerConfigurationDeleteInput/valid/delete.json +7 -0
  282. package/fixtures/openapi/DockerConfigurationMapValue/invalid/map.json +1 -0
  283. package/fixtures/openapi/DockerConfigurationMapValue/valid/map.json +3 -0
  284. package/fixtures/openapi/DockerConfigurationPatchInput/invalid/missing-target-host.json +13 -0
  285. package/fixtures/openapi/DockerConfigurationPatchInput/invalid/patch.json +8 -0
  286. package/fixtures/openapi/DockerConfigurationPatchInput/invalid/unused-target-host.json +14 -0
  287. package/fixtures/openapi/DockerConfigurationPatchInput/valid/explicit-zero-and-empty.json +21 -0
  288. package/fixtures/openapi/DockerConfigurationPatchInput/valid/host-move.json +14 -0
  289. package/fixtures/openapi/DockerConfigurationPatchInput/valid/patch.json +13 -0
  290. package/fixtures/openapi/DockerConfigurationPreconditions/invalid/identity.json +3 -0
  291. package/fixtures/openapi/DockerConfigurationPreconditions/valid/identity.json +4 -0
  292. package/fixtures/openapi/DockerConfigurationReceipt/invalid/receipt.json +15 -0
  293. package/fixtures/openapi/DockerConfigurationReceipt/valid/receipt.json +14 -0
  294. package/fixtures/openapi/DockerConfigurationReceiptEnvelope/invalid/receipt.json +16 -0
  295. package/fixtures/openapi/DockerConfigurationReceiptEnvelope/valid/receipt.json +16 -0
  296. package/fixtures/openapi/DockerConfigurationScalar/invalid/simple.json +1 -0
  297. package/fixtures/openapi/DockerConfigurationScalar/valid/simple.json +1 -0
  298. package/fixtures/openapi/DockerHostRegistration/invalid/host.json +4 -0
  299. package/fixtures/openapi/DockerHostRegistration/valid/host.json +6 -0
  300. package/fixtures/openapi/DockerHostRegistrationInput/invalid/registration.json +4 -0
  301. package/fixtures/openapi/DockerHostRegistrationInput/valid/registration.json +6 -0
  302. package/fixtures/openapi/DockerNativeTerminalCreated/invalid/native-v1.json +24 -0
  303. package/fixtures/openapi/DockerNativeTerminalCreated/valid/native-v1.json +23 -0
  304. package/fixtures/openapi/DockerNativeTerminalCreatedEnvelope/invalid/native-v1.json +26 -0
  305. package/fixtures/openapi/DockerNativeTerminalCreatedEnvelope/valid/native-v1.json +25 -0
  306. package/fixtures/openapi/DockerNativeTerminalInput/invalid/native-v1.json +9 -0
  307. package/fixtures/openapi/DockerNativeTerminalInput/valid/native-v1.json +8 -0
  308. package/fixtures/openapi/DockerNativeTerminalSession/invalid/native-v1.json +21 -0
  309. package/fixtures/openapi/DockerNativeTerminalSession/valid/native-v1.json +20 -0
  310. package/fixtures/openapi/DockerNativeTerminalSessionEnvelope/invalid/native-v1.json +23 -0
  311. package/fixtures/openapi/DockerNativeTerminalSessionEnvelope/valid/native-v1.json +22 -0
  312. package/fixtures/openapi/DockerProjectDeployInput/invalid/missing-host.json +8 -0
  313. package/fixtures/openapi/DockerProjectDeployInput/valid/bound.json +14 -0
  314. package/fixtures/openapi/DockerProjectDeployInput/valid/legacy.json +1 -0
  315. package/fixtures/openapi/DockerProjectDeployPreconditions/invalid/missing-host.json +6 -0
  316. package/fixtures/openapi/DockerProjectDeployPreconditions/valid/bound.json +11 -0
  317. package/fixtures/openapi/DockerResourceIdentity/invalid/configuration-leak.json +9 -0
  318. package/fixtures/openapi/DockerResourceIdentity/invalid/host-with-host.json +7 -0
  319. package/fixtures/openapi/DockerResourceIdentity/invalid/invalid-uid.json +6 -0
  320. package/fixtures/openapi/DockerResourceIdentity/invalid/missing-revision.json +5 -0
  321. package/fixtures/openapi/DockerResourceIdentity/invalid/missing-uid.json +5 -0
  322. package/fixtures/openapi/DockerResourceIdentity/invalid/project-without-host.json +6 -0
  323. package/fixtures/openapi/DockerResourceIdentity/invalid/wrong-kind.json +6 -0
  324. package/fixtures/openapi/DockerResourceIdentity/valid/host.json +6 -0
  325. package/fixtures/openapi/DockerResourceIdentity/valid/project.json +7 -0
  326. package/fixtures/openapi/DockerResourceIdentityEnvelope/invalid/array-data.json +10 -0
  327. package/fixtures/openapi/DockerResourceIdentityEnvelope/invalid/missing-data.json +1 -0
  328. package/fixtures/openapi/DockerResourceIdentityEnvelope/invalid/unexpected-payload.json +11 -0
  329. package/fixtures/openapi/DockerResourceIdentityEnvelope/valid/host.json +8 -0
  330. package/fixtures/openapi/DockerResourceIdentityEnvelope/valid/project.json +9 -0
  331. package/fixtures/openapi/DockerRuntimeContainerBinding/invalid/identity-bound.json +8 -0
  332. package/fixtures/openapi/DockerRuntimeContainerBinding/valid/identity-bound.json +8 -0
  333. package/fixtures/openapi/DockerRuntimeFileEntry/invalid/identity-bound.json +8 -0
  334. package/fixtures/openapi/DockerRuntimeFileEntry/valid/identity-bound.json +8 -0
  335. package/fixtures/openapi/DockerRuntimeReadEnvelope/invalid/identity-bound.json +23 -0
  336. package/fixtures/openapi/DockerRuntimeReadEnvelope/valid/identity-bound.json +23 -0
  337. package/fixtures/openapi/DockerRuntimeReadResult/invalid/identity-bound.json +21 -0
  338. package/fixtures/openapi/DockerRuntimeReadResult/valid/identity-bound.json +21 -0
  339. package/fixtures/openapi/DockerRuntimeVolume/invalid/identity-bound.json +7 -0
  340. package/fixtures/openapi/DockerRuntimeVolume/valid/identity-bound.json +7 -0
  341. package/fixtures/openapi/EnvironmentServiceReference/invalid/candidate-state.json +60 -0
  342. package/fixtures/openapi/EnvironmentServiceReference/invalid/missing-current-source-revision.json +59 -0
  343. package/fixtures/openapi/EnvironmentServiceReference/invalid/missing-identity-revision.json +59 -0
  344. package/fixtures/openapi/EnvironmentServiceReference/invalid/private-snapshot.json +61 -0
  345. package/fixtures/openapi/EnvironmentServiceReference/valid/active.json +60 -0
  346. package/fixtures/openapi/EnvironmentServiceReferenceCandidate/invalid/active.json +63 -0
  347. package/fixtures/openapi/EnvironmentServiceReferenceCandidate/invalid/raw-secret.json +66 -0
  348. package/fixtures/openapi/EnvironmentServiceReferenceCandidate/valid/generic-operator.json +63 -0
  349. package/fixtures/openapi/EnvironmentServiceReferenceCandidate/valid/helm-root.json +49 -0
  350. package/fixtures/openapi/EnvironmentServiceReferenceCandidateDeleteInput/invalid/missing-binding-cas.json +4 -0
  351. package/fixtures/openapi/EnvironmentServiceReferenceCandidateDeleteInput/invalid/missing-identity.json +4 -0
  352. package/fixtures/openapi/EnvironmentServiceReferenceCandidateDeleteInput/valid/delete-without-source.json +5 -0
  353. package/fixtures/openapi/EnvironmentServiceReferenceCandidateEnvelope/invalid/missing-revision.json +64 -0
  354. package/fixtures/openapi/EnvironmentServiceReferenceCandidateEnvelope/valid/generic-operator.json +65 -0
  355. package/fixtures/openapi/EnvironmentServiceReferenceCandidateEnvelope/valid/helm-root.json +51 -0
  356. package/fixtures/openapi/EnvironmentServiceReferenceCandidateInput/invalid/activation.json +11 -0
  357. package/fixtures/openapi/EnvironmentServiceReferenceCandidateInput/invalid/create-with-old-id.json +11 -0
  358. package/fixtures/openapi/EnvironmentServiceReferenceCandidateInput/invalid/empty-targets.json +8 -0
  359. package/fixtures/openapi/EnvironmentServiceReferenceCandidateInput/invalid/missing-digest.json +9 -0
  360. package/fixtures/openapi/EnvironmentServiceReferenceCandidateInput/invalid/missing-targets.json +7 -0
  361. package/fixtures/openapi/EnvironmentServiceReferenceCandidateInput/invalid/null-targets.json +8 -0
  362. package/fixtures/openapi/EnvironmentServiceReferenceCandidateInput/invalid/update-without-id.json +10 -0
  363. package/fixtures/openapi/EnvironmentServiceReferenceCandidateInput/valid/create.json +10 -0
  364. package/fixtures/openapi/EnvironmentServiceReferenceCandidateInput/valid/update.json +11 -0
  365. package/fixtures/openapi/EnvironmentServiceReferenceCandidatePage/invalid/source-content.json +17 -0
  366. package/fixtures/openapi/EnvironmentServiceReferenceCandidatePage/valid/page.json +13 -0
  367. package/fixtures/openapi/EnvironmentServiceReferenceCandidateSummary/invalid/source-leak.json +9 -0
  368. package/fixtures/openapi/EnvironmentServiceReferenceCandidateSummary/valid/consumer-metadata.json +8 -0
  369. package/fixtures/openapi/EnvironmentServiceReferenceConsumer/invalid/duplicate-target-ids.json +13 -0
  370. package/fixtures/openapi/EnvironmentServiceReferenceConsumer/invalid/source-content.json +38 -0
  371. package/fixtures/openapi/EnvironmentServiceReferenceConsumer/invalid/too-many-target-ids.json +112 -0
  372. package/fixtures/openapi/EnvironmentServiceReferenceConsumer/valid/visible.json +12 -0
  373. package/fixtures/openapi/EnvironmentServiceReferenceConsumerPage/invalid/hidden-count.json +19 -0
  374. package/fixtures/openapi/EnvironmentServiceReferenceConsumerPage/invalid/hidden-identities.json +21 -0
  375. package/fixtures/openapi/EnvironmentServiceReferenceConsumerPage/invalid/missing-restricted-flag.json +17 -0
  376. package/fixtures/openapi/EnvironmentServiceReferenceConsumerPage/invalid/too-many-items.json +1218 -0
  377. package/fixtures/openapi/EnvironmentServiceReferenceConsumerPage/valid/all-consumers-restricted.json +4 -0
  378. package/fixtures/openapi/EnvironmentServiceReferenceConsumerPage/valid/visible-page-with-restricted-consumers.json +18 -0
  379. package/fixtures/openapi/EnvironmentServiceReferenceDeleteInput/invalid/caller-force.json +6 -0
  380. package/fixtures/openapi/EnvironmentServiceReferenceDeleteInput/invalid/missing-consumer-cas.json +4 -0
  381. package/fixtures/openapi/EnvironmentServiceReferenceDeleteInput/invalid/missing-reference-id.json +4 -0
  382. package/fixtures/openapi/EnvironmentServiceReferenceDeleteInput/invalid/zero-reference-revision.json +5 -0
  383. package/fixtures/openapi/EnvironmentServiceReferenceDeleteInput/valid/detach-without-source-access.json +5 -0
  384. package/fixtures/openapi/EnvironmentServiceReferenceEnvelope/invalid/missing-fresh-uid.json +61 -0
  385. package/fixtures/openapi/EnvironmentServiceReferenceEnvelope/valid/active.json +62 -0
  386. package/fixtures/openapi/EnvironmentServiceReferenceInput/invalid/caller-force.json +9 -0
  387. package/fixtures/openapi/EnvironmentServiceReferenceInput/invalid/caller-ownership.json +9 -0
  388. package/fixtures/openapi/EnvironmentServiceReferenceInput/invalid/caller-source.json +9 -0
  389. package/fixtures/openapi/EnvironmentServiceReferenceInput/invalid/caller-targets.json +11 -0
  390. package/fixtures/openapi/EnvironmentServiceReferenceInput/invalid/create-with-reference-id.json +9 -0
  391. package/fixtures/openapi/EnvironmentServiceReferenceInput/invalid/empty-candidate-id.json +8 -0
  392. package/fixtures/openapi/EnvironmentServiceReferenceInput/invalid/invalid-consumer-time.json +8 -0
  393. package/fixtures/openapi/EnvironmentServiceReferenceInput/invalid/invalid-source-digest.json +8 -0
  394. package/fixtures/openapi/EnvironmentServiceReferenceInput/invalid/invalid-source-time.json +8 -0
  395. package/fixtures/openapi/EnvironmentServiceReferenceInput/invalid/missing-candidate-id.json +7 -0
  396. package/fixtures/openapi/EnvironmentServiceReferenceInput/invalid/missing-candidate-revision.json +7 -0
  397. package/fixtures/openapi/EnvironmentServiceReferenceInput/invalid/missing-consumer-cas.json +7 -0
  398. package/fixtures/openapi/EnvironmentServiceReferenceInput/invalid/missing-source-cas.json +7 -0
  399. package/fixtures/openapi/EnvironmentServiceReferenceInput/invalid/missing-source-digest.json +7 -0
  400. package/fixtures/openapi/EnvironmentServiceReferenceInput/invalid/negative-reference-revision.json +8 -0
  401. package/fixtures/openapi/EnvironmentServiceReferenceInput/invalid/oversized-candidate-id.json +8 -0
  402. package/fixtures/openapi/EnvironmentServiceReferenceInput/invalid/update-without-reference-id.json +8 -0
  403. package/fixtures/openapi/EnvironmentServiceReferenceInput/invalid/zero-candidate-revision.json +8 -0
  404. package/fixtures/openapi/EnvironmentServiceReferenceInput/valid/activate.json +8 -0
  405. package/fixtures/openapi/EnvironmentServiceReferenceInput/valid/explicit-rebind.json +9 -0
  406. package/fixtures/openapi/EnvironmentServiceReferencePage/invalid/global-count.json +14 -0
  407. package/fixtures/openapi/EnvironmentServiceReferencePage/invalid/source-content.json +64 -0
  408. package/fixtures/openapi/EnvironmentServiceReferencePage/invalid/too-many-items.json +813 -0
  409. package/fixtures/openapi/EnvironmentServiceReferencePage/valid/empty.json +3 -0
  410. package/fixtures/openapi/EnvironmentServiceReferencePage/valid/page.json +13 -0
  411. package/fixtures/openapi/EnvironmentServiceReferencePreviewEnvelope/invalid/missing-uid.json +54 -0
  412. package/fixtures/openapi/EnvironmentServiceReferencePreviewEnvelope/invalid/raw-values.json +58 -0
  413. package/fixtures/openapi/EnvironmentServiceReferencePreviewEnvelope/valid/generic-operator.json +55 -0
  414. package/fixtures/openapi/EnvironmentServiceReferencePreviewEnvelope/valid/helm-root.json +41 -0
  415. package/fixtures/openapi/EnvironmentServiceReferencePreviewInput/invalid/duplicate-targets.json +10 -0
  416. package/fixtures/openapi/EnvironmentServiceReferencePreviewInput/invalid/empty-targets.json +7 -0
  417. package/fixtures/openapi/EnvironmentServiceReferencePreviewInput/invalid/invalid-revision.json +7 -0
  418. package/fixtures/openapi/EnvironmentServiceReferencePreviewInput/invalid/missing-source-cas.json +5 -0
  419. package/fixtures/openapi/EnvironmentServiceReferencePreviewInput/invalid/null-targets.json +7 -0
  420. package/fixtures/openapi/EnvironmentServiceReferencePreviewInput/invalid/unexpected-write.json +7 -0
  421. package/fixtures/openapi/EnvironmentServiceReferencePreviewInput/valid/all-source-targets.json +6 -0
  422. package/fixtures/openapi/EnvironmentServiceReferencePreviewInput/valid/explicit-group.json +11 -0
  423. package/fixtures/openapi/EnvironmentServiceReferenceResolvedTarget/invalid/missing-origin.json +40 -0
  424. package/fixtures/openapi/EnvironmentServiceReferenceResolvedTarget/invalid/missing-source-uid.json +48 -0
  425. package/fixtures/openapi/EnvironmentServiceReferenceResolvedTarget/invalid/missing-view.json +40 -0
  426. package/fixtures/openapi/EnvironmentServiceReferenceResolvedTarget/invalid/yaml-is-not-authorized.json +50 -0
  427. package/fixtures/openapi/EnvironmentServiceReferenceResolvedTarget/invalid/zero-reference-revision.json +49 -0
  428. package/fixtures/openapi/EnvironmentServiceReferenceResolvedTarget/valid/consumer-view-source-origin.json +49 -0
  429. package/fixtures/openapi/EnvironmentServiceReferenceSummary/invalid/source-leak.json +9 -0
  430. package/fixtures/openapi/EnvironmentServiceReferenceSummary/invalid/zero-reference-revision.json +8 -0
  431. package/fixtures/openapi/EnvironmentServiceReferenceSummary/valid/consumer-metadata.json +8 -0
  432. package/fixtures/openapi/ExecutionArtifactListEnvelope/invalid/legacy-list-alias.json +4 -0
  433. package/fixtures/openapi/ExecutionArtifactListEnvelope/valid/legacy-list-alias.json +4 -0
  434. package/fixtures/openapi/ExecutionLog/invalid/missing-task.json +6 -0
  435. package/fixtures/openapi/ExecutionLog/valid/nested-metadata.json +16 -0
  436. package/fixtures/openapi/ExecutionLog/valid/row.json +7 -0
  437. package/fixtures/openapi/ExecutionLogListEnvelope/invalid/wrong-wrapper.json +3 -0
  438. package/fixtures/openapi/ExecutionLogListEnvelope/valid/empty.json +3 -0
  439. package/fixtures/openapi/ExecutionTaskActionInput/invalid/reason-type.json +3 -0
  440. package/fixtures/openapi/ExecutionTaskActionInput/invalid/unknown.json +3 -0
  441. package/fixtures/openapi/ExecutionTaskActionInput/valid/empty.json +1 -0
  442. package/fixtures/openapi/ExecutionTaskActionInput/valid/reason.json +3 -0
  443. package/fixtures/openapi/ExecutionTaskControlInput/invalid/missing-action.json +3 -0
  444. package/fixtures/openapi/ExecutionTaskControlInput/invalid/reason-too-long.json +4 -0
  445. package/fixtures/openapi/ExecutionTaskControlInput/invalid/unknown-field.json +4 -0
  446. package/fixtures/openapi/ExecutionTaskControlInput/invalid/unsupported-action.json +3 -0
  447. package/fixtures/openapi/ExecutionTaskControlInput/valid/cancel.json +4 -0
  448. package/fixtures/openapi/ExecutionTaskControlInput/valid/retry.json +3 -0
  449. package/fixtures/openapi/ExecutionTaskControlInput/valid/unicode-reason.json +4 -0
  450. package/fixtures/openapi/ExecutionTaskListEnvelope/invalid/legacy-list-alias.json +4 -0
  451. package/fixtures/openapi/ExecutionTaskListEnvelope/valid/legacy-list-alias.json +4 -0
  452. package/fixtures/openapi/GovernedAITokenBinding/invalid/binding.json +5 -0
  453. package/fixtures/openapi/GovernedAITokenBinding/valid/binding.json +5 -0
  454. package/fixtures/openapi/HealingOriginalRequestEnvelope/invalid/original-request.json +19 -0
  455. package/fixtures/openapi/HealingOriginalRequestEnvelope/valid/original-request.json +18 -0
  456. package/fixtures/openapi/HealingOriginalRequestInput/invalid/original-request.json +5 -0
  457. package/fixtures/openapi/HealingOriginalRequestInput/valid/original-request.json +4 -0
  458. package/fixtures/openapi/HealingOriginalRequestReceipt/invalid/original-request.json +17 -0
  459. package/fixtures/openapi/HealingOriginalRequestReceipt/valid/original-request.json +16 -0
  460. package/fixtures/openapi/HealingOriginalRun/invalid/original-request.json +13 -0
  461. package/fixtures/openapi/HealingOriginalRun/valid/original-request.json +12 -0
  462. package/fixtures/openapi/HelmReleaseImportInput/invalid/explicit-service-id.json +4 -0
  463. package/fixtures/openapi/HelmReleaseImportInput/valid/explicit-service-id.json +4 -0
  464. package/fixtures/openapi/IdentityOutpostClaimRequest/invalid/unsupported-control.json +7 -0
  465. package/fixtures/openapi/IdentityOutpostClaimRequest/valid/control-capable.json +7 -0
  466. package/fixtures/openapi/IdentityOutpostHeartbeatRequest/invalid/control-ack.json +11 -0
  467. package/fixtures/openapi/IdentityOutpostHeartbeatRequest/valid/control-ack.json +11 -0
  468. package/fixtures/openapi/IdentityOutpostHeartbeatRequest/valid/legacy.json +6 -0
  469. package/fixtures/openapi/IdentityOutpostRuntime/invalid/runtime.json +10 -0
  470. package/fixtures/openapi/IdentityOutpostRuntime/valid/observed-zero.json +18 -0
  471. package/fixtures/openapi/IdentityOutpostRuntime/valid/runtime.json +11 -0
  472. package/fixtures/openapi/IdentityOutpostRuntimeBindingInput/invalid/runtime.json +6 -0
  473. package/fixtures/openapi/IdentityOutpostRuntimeBindingInput/valid/runtime.json +5 -0
  474. package/fixtures/openapi/IdentityOutpostRuntimeControl/invalid/runtime.json +12 -0
  475. package/fixtures/openapi/IdentityOutpostRuntimeControl/valid/runtime.json +12 -0
  476. package/fixtures/openapi/IdentityOutpostRuntimeControlInput/invalid/arbitrary-target.json +6 -0
  477. package/fixtures/openapi/IdentityOutpostRuntimeControlInput/invalid/empty-request-id.json +5 -0
  478. package/fixtures/openapi/IdentityOutpostRuntimeControlInput/invalid/negative-generation.json +6 -0
  479. package/fixtures/openapi/IdentityOutpostRuntimeControlInput/invalid/reconcile-replicas.json +6 -0
  480. package/fixtures/openapi/IdentityOutpostRuntimeControlInput/invalid/runtime.json +6 -0
  481. package/fixtures/openapi/IdentityOutpostRuntimeControlInput/valid/reconcile.json +5 -0
  482. package/fixtures/openapi/IdentityOutpostRuntimeControlInput/valid/runtime.json +6 -0
  483. package/fixtures/openapi/IdentityOutpostRuntimeExecutorClaimRequest/invalid/runtime.json +6 -0
  484. package/fixtures/openapi/IdentityOutpostRuntimeExecutorClaimRequest/valid/runtime.json +3 -0
  485. package/fixtures/openapi/KubernetesClusterRegistrationRequest/invalid/metric-cluster-value-length.json +3 -0
  486. package/fixtures/openapi/KubernetesClusterRegistrationRequest/invalid/metric-cluster-value-type.json +3 -0
  487. package/fixtures/openapi/KubernetesClusterRegistrationRequest/valid/metric-cluster-alias.json +5 -0
  488. package/fixtures/openapi/KubernetesClusterRegistrationRequest/valid/metric-cluster-dedicated.json +5 -0
  489. package/fixtures/openapi/KubernetesClusterRegistrationRequest/valid/metric-cluster-reset.json +3 -0
  490. package/fixtures/openapi/KubernetesConditionalResourceYamlInput/invalid/preconditions-v1.json +3 -0
  491. package/fixtures/openapi/KubernetesConditionalResourceYamlInput/valid/preconditions-v1.json +7 -0
  492. package/fixtures/openapi/KubernetesConditionalWorkloadActionInput/invalid/preconditions-v1.json +7 -0
  493. package/fixtures/openapi/KubernetesConditionalWorkloadActionInput/valid/preconditions-v1.json +8 -0
  494. package/fixtures/openapi/KubernetesConditionalWorkloadActionReceipt/invalid/preconditions-v1.json +14 -0
  495. package/fixtures/openapi/KubernetesConditionalWorkloadActionReceipt/valid/preconditions-v1.json +14 -0
  496. package/fixtures/openapi/KubernetesConditionalWorkloadActionReceiptEnvelope/invalid/preconditions-v1.json +16 -0
  497. package/fixtures/openapi/KubernetesConditionalWorkloadActionReceiptEnvelope/valid/preconditions-v1.json +16 -0
  498. package/fixtures/openapi/KubernetesHelmReleaseValuesUpdateInput/invalid/revision-overflow.json +4 -0
  499. package/fixtures/openapi/KubernetesHelmReleaseValuesUpdateInput/valid/legacy.json +3 -0
  500. package/fixtures/openapi/KubernetesHelmReleaseValuesUpdateInput/valid/observed-revision.json +4 -0
  501. package/fixtures/openapi/KubernetesJobDetail/invalid/execution-observation.json +23 -0
  502. package/fixtures/openapi/KubernetesJobDetail/valid/execution-observation.json +23 -0
  503. package/fixtures/openapi/KubernetesNode/invalid/labels.json +10 -0
  504. package/fixtures/openapi/KubernetesNode/valid/labels.json +11 -0
  505. package/fixtures/openapi/KubernetesPodArgvInput/invalid/blank-executable.json +6 -0
  506. package/fixtures/openapi/KubernetesPodArgvInput/invalid/invalid-stdin.json +7 -0
  507. package/fixtures/openapi/KubernetesPodArgvInput/invalid/native-pod-execution-v1.json +4 -0
  508. package/fixtures/openapi/KubernetesPodArgvInput/invalid/nul-argv.json +7 -0
  509. package/fixtures/openapi/KubernetesPodArgvInput/valid/native-pod-execution-v1.json +7 -0
  510. package/fixtures/openapi/KubernetesPodArgvToolInput/invalid/empty-argv.json +10 -0
  511. package/fixtures/openapi/KubernetesPodArgvToolInput/invalid/missing-key.json +16 -0
  512. package/fixtures/openapi/KubernetesPodArgvToolInput/invalid/nested-unknown.json +18 -0
  513. package/fixtures/openapi/KubernetesPodArgvToolInput/invalid/timeout.json +17 -0
  514. package/fixtures/openapi/KubernetesPodArgvToolInput/invalid/unknown-shell.json +18 -0
  515. package/fixtures/openapi/KubernetesPodArgvToolInput/invalid/wrong-namespace.json +17 -0
  516. package/fixtures/openapi/KubernetesPodArgvToolInput/valid/reviewed-argv.json +17 -0
  517. package/fixtures/openapi/KubernetesPodExecutionLookupInput/invalid/both.json +7 -0
  518. package/fixtures/openapi/KubernetesPodExecutionLookupInput/invalid/empty-key.json +6 -0
  519. package/fixtures/openapi/KubernetesPodExecutionLookupInput/invalid/neither.json +5 -0
  520. package/fixtures/openapi/KubernetesPodExecutionLookupInput/invalid/noncanonical-id.json +6 -0
  521. package/fixtures/openapi/KubernetesPodExecutionLookupInput/invalid/unknown-command.json +11 -0
  522. package/fixtures/openapi/KubernetesPodExecutionLookupInput/valid/by-id.json +6 -0
  523. package/fixtures/openapi/KubernetesPodExecutionLookupInput/valid/by-key.json +6 -0
  524. package/fixtures/openapi/KubernetesPodExecutionOutput/invalid/native-pod-execution-v1.json +15 -0
  525. package/fixtures/openapi/KubernetesPodExecutionOutput/valid/native-pod-execution-v1.json +15 -0
  526. package/fixtures/openapi/KubernetesPodExecutionReceipt/invalid/native-pod-execution-v1.json +29 -0
  527. package/fixtures/openapi/KubernetesPodExecutionReceipt/valid/native-pod-execution-v1.json +29 -0
  528. package/fixtures/openapi/KubernetesPodExecutionReceiptEnvelope/invalid/native-pod-execution-v1.json +1 -0
  529. package/fixtures/openapi/KubernetesPodExecutionReceiptEnvelope/valid/native-pod-execution-v1.json +31 -0
  530. package/fixtures/openapi/KubernetesPodExecutionTarget/invalid/native-pod-execution-v1.json +7 -0
  531. package/fixtures/openapi/KubernetesPodExecutionTarget/valid/native-pod-execution-v1.json +7 -0
  532. package/fixtures/openapi/KubernetesPodGatewayResult/invalid/encoded-output.json +32 -0
  533. package/fixtures/openapi/KubernetesPodGatewayResult/invalid/missing-text.json +17 -0
  534. package/fixtures/openapi/KubernetesPodGatewayResult/invalid/raw-receipt-availability.json +32 -0
  535. package/fixtures/openapi/KubernetesPodGatewayResult/invalid/raw-receipt-output.json +47 -0
  536. package/fixtures/openapi/KubernetesPodGatewayResult/invalid/withheld-text.json +32 -0
  537. package/fixtures/openapi/KubernetesPodGatewayResult/valid/binary-withheld.json +17 -0
  538. package/fixtures/openapi/KubernetesPodGatewayResult/valid/redacted.json +32 -0
  539. package/fixtures/openapi/KubernetesPodGatewayResult/valid/text.json +32 -0
  540. package/fixtures/openapi/KubernetesPodGatewayResult/valid/unavailable.json +17 -0
  541. package/fixtures/openapi/KubernetesPodListEnvelope/invalid/empty-uid.json +13 -0
  542. package/fixtures/openapi/KubernetesPodListEnvelope/invalid/invalid-container-state.json +20 -0
  543. package/fixtures/openapi/KubernetesPodListEnvelope/invalid/missing-container-ready.json +19 -0
  544. package/fixtures/openapi/KubernetesPodListEnvelope/valid/container-statuses.json +67 -0
  545. package/fixtures/openapi/KubernetesPodListEnvelope/valid/running-pod.json +1 -0
  546. package/fixtures/openapi/KubernetesPodTerminalCreated/invalid/terminal.json +21 -0
  547. package/fixtures/openapi/KubernetesPodTerminalCreated/valid/terminal.json +21 -0
  548. package/fixtures/openapi/KubernetesPodTerminalCreatedEnvelope/invalid/terminal.json +3 -0
  549. package/fixtures/openapi/KubernetesPodTerminalCreatedEnvelope/valid/terminal.json +23 -0
  550. package/fixtures/openapi/KubernetesPodTerminalInput/invalid/terminal.json +4 -0
  551. package/fixtures/openapi/KubernetesPodTerminalInput/valid/terminal.json +3 -0
  552. package/fixtures/openapi/KubernetesPodTerminalResult/invalid/terminal.json +8 -0
  553. package/fixtures/openapi/KubernetesPodTerminalResult/valid/terminal.json +8 -0
  554. package/fixtures/openapi/KubernetesPodTerminalSession/invalid/terminal.json +18 -0
  555. package/fixtures/openapi/KubernetesPodTerminalSession/valid/terminal.json +18 -0
  556. package/fixtures/openapi/KubernetesPodTerminalSessionEnvelope/invalid/terminal.json +3 -0
  557. package/fixtures/openapi/KubernetesPodTerminalSessionEnvelope/valid/terminal.json +20 -0
  558. package/fixtures/openapi/KubernetesPrometheusDetail/invalid/metric-cluster-value-type.json +4 -0
  559. package/fixtures/openapi/KubernetesPrometheusDetail/valid/metric-cluster-alias.json +5 -0
  560. package/fixtures/openapi/KubernetesResourceDeletionReceipt/invalid/preconditions-v1.json +11 -0
  561. package/fixtures/openapi/KubernetesResourceDeletionReceipt/valid/preconditions-v1.json +11 -0
  562. package/fixtures/openapi/KubernetesResourceDeletionReceiptEnvelope/invalid/preconditions-v1.json +5 -0
  563. package/fixtures/openapi/KubernetesResourceDeletionReceiptEnvelope/valid/preconditions-v1.json +13 -0
  564. package/fixtures/openapi/KubernetesResourceGraphEnvelope/invalid/network-edge-source-payload.json +73 -0
  565. package/fixtures/openapi/KubernetesResourceGraphEnvelope/valid/network-edge-facts.json +67 -0
  566. package/fixtures/openapi/KubernetesResourceIdentity/invalid/preconditions-v1.json +11 -0
  567. package/fixtures/openapi/KubernetesResourceIdentity/valid/preconditions-v1.json +8 -0
  568. package/fixtures/openapi/KubernetesResourceIdentityEnvelope/invalid/preconditions-v1.json +3 -0
  569. package/fixtures/openapi/KubernetesResourceIdentityEnvelope/valid/preconditions-v1.json +10 -0
  570. package/fixtures/openapi/KubernetesResourceMutationPreconditions/invalid/preconditions-v1.json +3 -0
  571. package/fixtures/openapi/KubernetesResourceMutationPreconditions/valid/preconditions-v1.json +4 -0
  572. package/fixtures/openapi/KubernetesResourcePresence/invalid/absence-with-uid.json +11 -0
  573. package/fixtures/openapi/KubernetesResourcePresence/invalid/missing-collection-version.json +9 -0
  574. package/fixtures/openapi/KubernetesResourcePresence/invalid/missing-state.json +9 -0
  575. package/fixtures/openapi/KubernetesResourcePresence/invalid/old-protocol.json +10 -0
  576. package/fixtures/openapi/KubernetesResourcePresence/invalid/present-without-uid.json +10 -0
  577. package/fixtures/openapi/KubernetesResourcePresence/invalid/unknown-field.json +11 -0
  578. package/fixtures/openapi/KubernetesResourcePresence/valid/absent.json +10 -0
  579. package/fixtures/openapi/KubernetesResourcePresence/valid/present.json +12 -0
  580. package/fixtures/openapi/KubernetesSecretCertificate/invalid/secret-data.json +1 -0
  581. package/fixtures/openapi/KubernetesSecretCertificate/invalid/status.json +1 -0
  582. package/fixtures/openapi/KubernetesSecretCertificate/valid/available.json +1 -0
  583. package/fixtures/openapi/KubernetesSecretCertificate/valid/missing.json +1 -0
  584. package/fixtures/openapi/KubernetesWorkloadImportInput/invalid/explicit-service-id.json +5 -0
  585. package/fixtures/openapi/KubernetesWorkloadImportInput/valid/explicit-service-id.json +7 -0
  586. package/fixtures/openapi/ManifestBindingListEnvelope/invalid/legacy-object.json +4 -0
  587. package/fixtures/openapi/ManifestBindingListEnvelope/valid/empty-alias.json +4 -0
  588. package/fixtures/openapi/ManifestRevision/invalid/missing-files.json +8 -0
  589. package/fixtures/openapi/ManifestRevision/valid/minimal.json +9 -0
  590. package/fixtures/openapi/ManifestRevisionListEnvelope/invalid/legacy-object.json +4 -0
  591. package/fixtures/openapi/ManifestRevisionListEnvelope/valid/legacy-alias.json +24 -0
  592. package/fixtures/openapi/NativeTerminalClientFrame/invalid/terminal.json +12 -0
  593. package/fixtures/openapi/NativeTerminalClientFrame/valid/terminal.json +4 -0
  594. package/fixtures/openapi/NativeTerminalServerFrame/invalid/terminal.json +4 -0
  595. package/fixtures/openapi/NativeTerminalServerFrame/valid/terminal.json +11 -0
  596. package/fixtures/openapi/NetworkConflictAnalysisRequest/invalid/ipv6-range.json +9 -0
  597. package/fixtures/openapi/NetworkEAPServerTrust/invalid/peap.json +10 -0
  598. package/fixtures/openapi/NetworkEAPServerTrust/invalid/tls-inner.json +11 -0
  599. package/fixtures/openapi/NetworkEAPServerTrust/invalid/ttls-incomplete.json +10 -0
  600. package/fixtures/openapi/NetworkEAPServerTrust/valid/ttls.json +12 -0
  601. package/fixtures/openapi/NetworkMihomoProfileInput/invalid/direct-bundle-raw-source.json +21 -0
  602. package/fixtures/openapi/NetworkMihomoProfileInput/invalid/mapped-raw-source.json +21 -0
  603. package/fixtures/openapi/NetworkMihomoProfileInput/valid/direct-bundle.json +19 -0
  604. package/fixtures/openapi/NetworkMihomoProfileInput/valid/mapped-nodes.json +19 -0
  605. package/fixtures/openapi/NetworkProxyBundleInput/invalid/unknown.json +25 -0
  606. package/fixtures/openapi/NetworkProxyBundleInput/valid/basic.json +24 -0
  607. package/fixtures/openapi/NetworkProxyBundleReadback/invalid/missing-identity.json +9 -0
  608. package/fixtures/openapi/NetworkProxyBundleReadback/invalid/unknown-field.json +11 -0
  609. package/fixtures/openapi/NetworkProxyBundleReadback/valid/basic.json +10 -0
  610. package/fixtures/openapi/NetworkProxyCapability/invalid/unknown-version.json +1 -0
  611. package/fixtures/openapi/NetworkProxyCapability/valid/guarded-udp.json +1 -0
  612. package/fixtures/openapi/NetworkProxyDeployment/invalid/negative-observation.json +7 -0
  613. package/fixtures/openapi/NetworkProxyDeployment/invalid/null-observation.json +7 -0
  614. package/fixtures/openapi/NetworkProxyDeployment/valid/positive.json +7 -0
  615. package/fixtures/openapi/NetworkProxyDeployment/valid/stopped.json +7 -0
  616. package/fixtures/openapi/NetworkProxyDeployment/valid/unobserved.json +6 -0
  617. package/fixtures/openapi/NetworkProxyDeploymentControlInput/invalid/unknown.json +7 -0
  618. package/fixtures/openapi/NetworkProxyDeploymentControlInput/valid/basic.json +6 -0
  619. package/fixtures/openapi/NetworkProxyDeploymentRuntimeAck/invalid/stopped-accepting.json +15 -0
  620. package/fixtures/openapi/NetworkProxyDeploymentRuntimeAck/invalid/stopped-active.json +15 -0
  621. package/fixtures/openapi/NetworkProxyDeploymentRuntimeAck/invalid/stopped-missing-count.json +14 -0
  622. package/fixtures/openapi/NetworkProxyDeploymentRuntimeAck/invalid/stopped-unknown.json +15 -0
  623. package/fixtures/openapi/NetworkProxyDeploymentRuntimeAck/valid/false-with-active-unknown.json +15 -0
  624. package/fixtures/openapi/NetworkProxyDeploymentRuntimeAck/valid/omitted-with-active-unknown.json +14 -0
  625. package/fixtures/openapi/NetworkProxyDeploymentRuntimeAck/valid/process-stopped.json +15 -0
  626. package/fixtures/openapi/NetworkProxyDeploymentRuntimeControl/invalid/stop-while-accepting.json +13 -0
  627. package/fixtures/openapi/NetworkProxyDeploymentRuntimeControl/valid/false-can-serve.json +13 -0
  628. package/fixtures/openapi/NetworkProxyDeploymentRuntimeControl/valid/omitted-can-serve.json +12 -0
  629. package/fixtures/openapi/NetworkProxyDeploymentRuntimeControl/valid/stop-required.json +13 -0
  630. package/fixtures/openapi/NetworkProxyDirectProjection/invalid/gateway-credential.json +22 -0
  631. package/fixtures/openapi/NetworkProxyDirectProjection/invalid/original-source-url.json +20 -0
  632. package/fixtures/openapi/NetworkProxyDirectProjection/invalid/protected-projection.json +41 -0
  633. package/fixtures/openapi/NetworkProxyDirectProjection/invalid/wrong-mode.json +19 -0
  634. package/fixtures/openapi/NetworkProxyDirectProjection/valid/explicit-direct.json +19 -0
  635. package/fixtures/openapi/NetworkProxyEmployeeProjection/invalid/direct-upstream-content.json +42 -0
  636. package/fixtures/openapi/NetworkProxyEmployeeProjection/invalid/unsafe-endpoint.json +41 -0
  637. package/fixtures/openapi/NetworkProxyEmployeeProjection/invalid/upstream.json +42 -0
  638. package/fixtures/openapi/NetworkProxyEmployeeProjection/valid/scoped.json +41 -0
  639. package/fixtures/openapi/NetworkProxyIngressCheckInput/invalid/arbitrary-url.json +12 -0
  640. package/fixtures/openapi/NetworkProxyIngressCheckInput/invalid/missing-identity.json +11 -0
  641. package/fixtures/openapi/NetworkProxyIngressCheckInput/invalid/unknown-field.json +13 -0
  642. package/fixtures/openapi/NetworkProxyIngressCheckInput/valid/basic.json +12 -0
  643. package/fixtures/openapi/NetworkProxyIngressCheckResult/invalid/missing-identity.json +8 -0
  644. package/fixtures/openapi/NetworkProxyIngressCheckResult/invalid/unknown-field.json +10 -0
  645. package/fixtures/openapi/NetworkProxyIngressCheckResult/valid/basic.json +9 -0
  646. package/fixtures/openapi/NetworkProxyInstanceInput/invalid/external.json +5 -0
  647. package/fixtures/openapi/NetworkProxyInstanceInput/valid/external.json +15 -0
  648. package/fixtures/openapi/NetworkProxyRule/invalid/unknown.json +15 -0
  649. package/fixtures/openapi/NetworkProxyRule/valid/basic.json +14 -0
  650. package/fixtures/openapi/NetworkProxyRuntimeCommandInput/invalid/unknown.json +8 -0
  651. package/fixtures/openapi/NetworkProxyRuntimeCommandInput/valid/basic.json +7 -0
  652. package/fixtures/openapi/NetworkProxyServerPublication/invalid/arbitrary-listener.json +21 -0
  653. package/fixtures/openapi/NetworkProxyServerPublication/invalid/missing-identity.json +19 -0
  654. package/fixtures/openapi/NetworkProxyServerPublication/invalid/unknown-field.json +21 -0
  655. package/fixtures/openapi/NetworkProxyServerPublication/valid/basic.json +20 -0
  656. package/fixtures/openapi/NetworkProxySourceInput/invalid/node-quota.json +912 -0
  657. package/fixtures/openapi/NetworkProxySourceInput/invalid/unknown.json +8 -0
  658. package/fixtures/openapi/NetworkProxySourceInput/invalid/unsupported-format.json +7 -0
  659. package/fixtures/openapi/NetworkProxySourceInput/invalid/untyped-direct-format.json +7 -0
  660. package/fixtures/openapi/NetworkProxySourceInput/valid/basic.json +7 -0
  661. package/fixtures/openapi/NetworkProxySourceInput/valid/converted-direct.json +7 -0
  662. package/fixtures/openapi/NetworkProxyTrafficSample/invalid/known-as-null.json +10 -0
  663. package/fixtures/openapi/NetworkProxyTrafficSample/valid/gap-rate.json +10 -0
  664. package/fixtures/openapi/NetworkProxyTrafficSample/valid/known-zero.json +10 -0
  665. package/fixtures/openapi/NetworkProxyTrafficSample/valid/legacy-numeric.json +7 -0
  666. package/fixtures/openapi/NetworkProxyTrafficSample/valid/unknown-rate.json +10 -0
  667. package/fixtures/openapi/NetworkRADIUSConfigurationInput/invalid/arbitrary-image.json +6 -0
  668. package/fixtures/openapi/NetworkRADIUSConfigurationInput/valid/input.json +5 -0
  669. package/fixtures/openapi/NetworkRADIUSControlInput/invalid/arbitrary-image.json +8 -0
  670. package/fixtures/openapi/NetworkRADIUSControlInput/valid/input.json +7 -0
  671. package/fixtures/openapi/NetworkRADIUSOptions/invalid/secret.json +18 -0
  672. package/fixtures/openapi/NetworkRADIUSOptions/valid/approved.json +17 -0
  673. package/fixtures/openapi/NetworkRADIUSPoolInput/invalid/arbitrary-image.json +10 -0
  674. package/fixtures/openapi/NetworkRADIUSPoolInput/valid/create-approved-binding.json +9 -0
  675. package/fixtures/openapi/NetworkRADIUSPoolInput/valid/input.json +9 -0
  676. package/fixtures/openapi/NetworkRADIUSRuntimeACK/invalid/missing-zero.json +20 -0
  677. package/fixtures/openapi/NetworkRADIUSRuntimeACK/invalid/secret.json +22 -0
  678. package/fixtures/openapi/NetworkRADIUSRuntimeACK/valid/current.json +21 -0
  679. package/fixtures/openapi/NetworkRADIUSRuntimeACK/valid/stopped-no-hooks.json +21 -0
  680. package/fixtures/openapi/NetworkRADIUSRuntimeControl/invalid/secret.json +30 -0
  681. package/fixtures/openapi/NetworkRADIUSRuntimeControl/valid/current.json +29 -0
  682. package/fixtures/openapi/OperationCommentInput/invalid/workbench.json +4 -0
  683. package/fixtures/openapi/OperationCommentInput/valid/workbench.json +3 -0
  684. package/fixtures/openapi/PersonalAssistantArtifactListEnvelope/invalid/legacy-object.json +4 -0
  685. package/fixtures/openapi/PersonalAssistantArtifactListEnvelope/valid/legacy-alias.json +4 -0
  686. package/fixtures/openapi/ReleaseTargetInput/invalid/explicit-service-id.json +8 -0
  687. package/fixtures/openapi/ReleaseTargetInput/valid/explicit-service-id.json +8 -0
  688. package/fixtures/openapi/TokenRotationRecord/invalid/cli-boundary.json +10 -0
  689. package/fixtures/openapi/TokenRotationRecord/valid/cli-boundary.json +9 -0
  690. package/fixtures/openapi/WorkbenchAgentRunListEnvelope/valid/dsh-session.json +18 -0
  691. package/fixtures/openapi/WorkbenchSendMessageStreamRequest/invalid/unicode-request-id.json +4 -0
  692. package/fixtures/openapi/WorkbenchSendMessageStreamRequest/valid/unicode-request-id.json +4 -0
  693. package/fixtures/openapi/WorkbenchStreamEvent/valid/dsh-agent-status.json +11 -0
  694. package/fixtures/openapi/WorkbenchStreamEvent/valid/native-system-notice.json +11 -0
  695. package/fixtures/openapi/WorkflowRequestInput/invalid/original-request.json +6 -0
  696. package/fixtures/openapi/WorkflowRequestInput/valid/original-request.json +7 -0
  697. package/fixtures/openapi/WorkflowRequestReceipt/invalid/original-request.json +6 -0
  698. package/fixtures/openapi/WorkflowRequestReceipt/valid/original-request.json +6 -0
  699. package/fixtures/openapi/WorkflowRequestReceiptEnvelope/invalid/receipt.json +8 -0
  700. package/fixtures/openapi/WorkflowRequestReceiptEnvelope/valid/receipt.json +17 -0
  701. package/fixtures/openapi/WorkflowRunEnvelope/invalid/receipt.json +3 -0
  702. package/fixtures/openapi/WorkflowRunEnvelope/valid/receipt.json +11 -0
  703. package/fixtures/openapi/WorkflowTriggerRequest/invalid/workbench.json +4 -0
  704. package/fixtures/openapi/WorkflowTriggerRequest/valid/workbench.json +9 -0
  705. package/gen/go/sohaapi/client.go +108 -1
  706. package/gen/go/sohaapi/client_test.go +85 -0
  707. package/gen/go/sohaapi/docker_configuration_test.go +32 -0
  708. package/gen/go/sohaapi/kubernetes_workload_optional_test.go +40 -0
  709. package/gen/go/sohaapi/memory_types_test.go +59 -0
  710. package/gen/go/sohaapi/pod_status_compat_test.go +36 -0
  711. package/gen/go/sohaapi/proxy_deployment_presence_test.go +47 -0
  712. package/gen/go/sohaapi/proxy_deployment_stop_test.go +40 -0
  713. package/gen/go/sohaapi/proxy_traffic_test.go +41 -0
  714. package/gen/go/sohaapi/radius_presence_test.go +35 -0
  715. package/gen/go/sohaapi/types.go +6580 -365
  716. package/gen/go/sohaapi/types_test.go +63 -0
  717. package/gen/ts/sohaapi/index.ts +36358 -26252
  718. package/go.mod +5 -2
  719. package/go.sum +8 -0
  720. package/helmrelease/delivery.go +1 -1
  721. package/helmrelease/delivery_test.go +1 -1
  722. package/helmrelease/initialization.go +1 -1
  723. package/helmrelease/result.go +1 -1
  724. package/helmrelease/runtime/delivery.go +4 -4
  725. package/helmrelease/runtime/delivery_test.go +2 -2
  726. package/helmrelease/runtime/initialization.go +2 -2
  727. package/helmrelease/runtime/initialization_test.go +2 -2
  728. package/helmrelease/runtime/values_upgrade.go +78 -0
  729. package/helmrelease/runtime/values_upgrade_test.go +123 -0
  730. package/helmrelease/values.go +1 -1
  731. package/helmrelease/values_update.go +31 -0
  732. package/memory/memory-policy.schema.json +5 -1
  733. package/memory/memory-record.schema.json +5 -1
  734. package/network/README.md +79 -0
  735. package/network/network-ingest-event.schema.json +4 -1
  736. package/network/network-runtime-protocol.schema.json +381 -20
  737. package/network/proxy-adapter.schema.json +1018 -0
  738. package/network/proxy-runtime.schema.json +1732 -16
  739. package/network/radius-password-verifier.schema.json +263 -0
  740. package/network/radius-runtime.schema.json +929 -0
  741. package/network/schema.go +12 -0
  742. package/openapi/soha-api.json +70695 -49969
  743. package/openapi/soha-api.yaml +39327 -27176
  744. package/openapi/spec_generated.go +3 -3
  745. package/package.json +19 -6
  746. package/proxyadapter/mihomo_udp.go +15 -0
  747. package/proxyadapter/mihomo_udp_test.go +21 -0
  748. package/proxyadapter/protocol.go +286 -0
  749. package/proxyadapter/protocol_test.go +76 -0
  750. package/proxypolicy/destination_test.go +48 -0
  751. package/proxypolicy/narrow.go +152 -0
  752. package/proxypolicy/narrow_test.go +138 -0
  753. package/proxypolicy/policy.go +329 -0
  754. package/proxypolicy/policy_test.go +36 -0
  755. package/proxytransport/README.md +141 -0
  756. package/proxytransport/handler.go +5 -1
  757. package/proxytransport/native_egress_test.go +236 -0
  758. package/proxytransport/probe.go +5 -1
  759. package/proxytransport/probe_test.go +106 -0
  760. package/proxytransport/refresh_test.go +74 -0
  761. package/proxytransport/scope.go +23 -3
  762. package/proxytransport/socks_upstream.go +440 -0
  763. package/proxytransport/socks_upstream_test.go +368 -0
  764. package/proxytransport/udp_conn.go +234 -0
  765. package/proxytransport/udp_gate.go +521 -0
  766. package/proxytransport/udp_http.go +372 -0
  767. package/proxytransport/udp_socks.go +288 -0
  768. package/proxytransport/udp_test.go +793 -0
  769. package/proxytransport/username.go +51 -0
  770. package/proxytransport/username_test.go +98 -0
  771. package/resource/agent_profiles.go +9 -15
  772. package/resource/agent_profiles_test.go +9 -3
  773. package/resource/conditional_workload_action.go +63 -0
  774. package/resource/custom_graph_page.go +18 -0
  775. package/resource/models.go +102 -57
  776. package/resource/mutation_preconditions.go +67 -0
  777. package/resource/network_topology.go +22 -0
  778. package/resource/network_topology_projection.go +36 -22
  779. package/resource/network_topology_projection_test.go +4 -0
  780. package/resource/network_topology_test.go +20 -0
  781. package/resource/network_topology_validation.go +5 -0
  782. package/resource/observed_workload.go +18 -0
  783. package/resource/pod_execution.go +206 -0
  784. package/resource/pod_execution_gateway.go +119 -0
  785. package/resource/pod_execution_gateway_test.go +149 -0
  786. package/resource/pod_execution_test.go +48 -0
  787. package/resource/pod_status_test.go +22 -0
  788. package/resource/pod_terminal.go +188 -0
  789. package/resource/pod_terminal_test.go +63 -0
  790. package/resource/presence.go +60 -0
  791. package/resource/presence_test.go +28 -0
  792. package/resource/rbac_graph.go +4 -0
  793. package/resource/rollout_optional_test.go +33 -0
  794. package/resource/root_cr.go +1 -1
  795. package/resource/runtime/argocd_observation.go +1 -1
  796. package/resource/runtime/conditional_workload_action.go +141 -0
  797. package/resource/runtime/conditional_workload_action_test.go +259 -0
  798. package/resource/runtime/health.go +1 -1
  799. package/resource/runtime/health_test.go +1 -1
  800. package/resource/runtime/initialization.go +1 -1
  801. package/resource/runtime/initialization_test.go +1 -1
  802. package/resource/runtime/mutation_preconditions.go +106 -0
  803. package/resource/runtime/mutation_preconditions_test.go +172 -0
  804. package/resource/runtime/network_relationship_primitives.go +66 -0
  805. package/resource/runtime/network_relationship_primitives_test.go +147 -0
  806. package/resource/runtime/network_topology.go +18 -6
  807. package/resource/runtime/network_topology_builder.go +405 -0
  808. package/resource/runtime/network_topology_builder_backends.go +195 -0
  809. package/resource/runtime/network_topology_builder_gateway_l4_test.go +86 -0
  810. package/resource/runtime/network_topology_builder_ingress.go +302 -0
  811. package/resource/runtime/network_topology_builder_legacy.go +66 -0
  812. package/resource/runtime/network_topology_builder_providers.go +242 -0
  813. package/resource/runtime/network_topology_builder_test.go +186 -0
  814. package/resource/runtime/network_topology_declarations.go +329 -0
  815. package/resource/runtime/network_topology_test.go +1 -1
  816. package/resource/runtime/node_drain.go +1 -1
  817. package/resource/runtime/node_drain_test.go +1 -1
  818. package/resource/runtime/pod_execution.go +199 -0
  819. package/resource/runtime/pod_execution_test.go +194 -0
  820. package/resource/runtime/pod_execution_transport.go +79 -0
  821. package/resource/runtime/pod_terminal.go +178 -0
  822. package/resource/runtime/pod_terminal_test.go +170 -0
  823. package/resource/runtime/presence.go +58 -0
  824. package/resource/runtime/presence_metadata.go +85 -0
  825. package/resource/runtime/presence_metadata_test.go +56 -0
  826. package/resource/runtime/presence_test.go +85 -0
  827. package/resource/runtime/relations.go +1 -1
  828. package/resource/runtime/relations_test.go +1 -1
  829. package/resource/runtime/resource_edit.go +22 -0
  830. package/resource/runtime/resource_edit_test.go +32 -0
  831. package/resource/runtime/resource_graph_collect.go +325 -0
  832. package/resource/runtime/resource_graph_configuration.go +59 -0
  833. package/resource/runtime/resource_graph_configuration_collect.go +198 -0
  834. package/resource/runtime/resource_graph_configuration_test.go +470 -0
  835. package/resource/runtime/resource_graph_custom_page.go +159 -0
  836. package/resource/runtime/resource_graph_custom_root.go +132 -0
  837. package/resource/runtime/resource_graph_custom_root_test.go +197 -0
  838. package/resource/runtime/resource_graph_enrichment.go +417 -0
  839. package/resource/runtime/resource_graph_enrichment_hpa_test.go +117 -0
  840. package/resource/runtime/resource_graph_enrichment_test.go +201 -0
  841. package/resource/runtime/resource_graph_metadata.go +125 -0
  842. package/resource/runtime/resource_graph_metadata_test.go +204 -0
  843. package/resource/runtime/resource_graph_network.go +224 -0
  844. package/resource/runtime/resource_graph_network_collect.go +174 -0
  845. package/resource/runtime/resource_graph_network_collect_test.go +147 -0
  846. package/resource/runtime/resource_graph_network_test.go +342 -0
  847. package/resource/runtime/resource_graph_rbac.go +278 -0
  848. package/resource/runtime/resource_graph_rbac_test.go +372 -0
  849. package/resource/runtime/resource_graph_rules.go +834 -0
  850. package/resource/runtime/resource_graph_storage.go +144 -0
  851. package/resource/runtime/resource_graph_storage_collect.go +163 -0
  852. package/resource/runtime/resource_graph_storage_test.go +397 -0
  853. package/resource/runtime/resource_graph_test.go +627 -0
  854. package/resource/runtime/resource_monitoring.go +1 -1
  855. package/resource/runtime/rollout_integration_test.go +1 -1
  856. package/resource/runtime/rollout_observation.go +1 -1
  857. package/resource/runtime/rollout_operation.go +1 -1
  858. package/resource/runtime/rollout_task.go +2 -2
  859. package/resource/runtime/rollout_test.go +1 -1
  860. package/resource/runtime/root_cr.go +2 -2
  861. package/resource/runtime/root_cr_test.go +1 -1
  862. package/resource/runtime/secret_certificate.go +44 -0
  863. package/resource/runtime/secret_certificate_test.go +87 -0
  864. package/resource/storage_graph.go +4 -0
  865. package/resource/terminal_options.go +38 -0
  866. package/resource/terminalstream/stream.go +481 -0
  867. package/resource/terminalstream/stream_test.go +277 -0
  868. package/runner/docker-container-identity.schema.json +37 -0
  869. package/runner/docker-project-identity.schema.json +39 -0
  870. package/runner/docker-runtime-read-result.schema.json +317 -0
  871. package/runner/docker-runtime-read.schema.json +85 -0
@@ -0,0 +1,834 @@
1
+ package runtime
2
+
3
+ import (
4
+ "context"
5
+ "errors"
6
+ "fmt"
7
+ cr "github.com/opensoha/soha/contracts/resource"
8
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
10
+ "k8s.io/apimachinery/pkg/labels"
11
+ kruntime "k8s.io/apimachinery/pkg/runtime"
12
+ "sort"
13
+ "strings"
14
+ "time"
15
+ )
16
+
17
+ // ErrInvalidResourceGraphRoot identifies invalid scope or stale root identity.
18
+ var ErrInvalidResourceGraphRoot = errors.New("invalid resource graph root")
19
+
20
+ // ErrUnsupportedResourceGraphRoot identifies roots requiring another collector.
21
+ var ErrUnsupportedResourceGraphRoot = errors.New("unsupported resource graph root")
22
+
23
+ func invalidGraphRoot(message string) error {
24
+ return fmt.Errorf("%w: %s", ErrInvalidResourceGraphRoot, message)
25
+ }
26
+
27
+ var graphBuiltinAPIs = map[string]string{
28
+ "Pod": "v1", "ReplicationController": "v1", "Service": "v1", "Secret": "v1", "ConfigMap": "v1", "PersistentVolumeClaim": "v1", "PersistentVolume": "v1", "ServiceAccount": "v1", "Node": "v1", "Namespace": "v1", "Event": "v1",
29
+ "Deployment": "apps/v1", "StatefulSet": "apps/v1", "DaemonSet": "apps/v1", "ReplicaSet": "apps/v1", "Job": "batch/v1", "CronJob": "batch/v1",
30
+ "Ingress": "networking.k8s.io/v1", "HorizontalPodAutoscaler": "autoscaling/v2", "PodDisruptionBudget": "policy/v1",
31
+ "ResourceQuota": "v1", "LimitRange": "v1", "PriorityClass": "scheduling.k8s.io/v1", "RuntimeClass": "node.k8s.io/v1", "Lease": "coordination.k8s.io/v1",
32
+ "MutatingWebhookConfiguration": "admissionregistration.k8s.io/v1", "ValidatingWebhookConfiguration": "admissionregistration.k8s.io/v1",
33
+ "StorageClass": "storage.k8s.io/v1",
34
+ "Role": graphRBACAPI, "RoleBinding": graphRBACAPI, "ClusterRole": graphRBACAPI, "ClusterRoleBinding": graphRBACAPI,
35
+ }
36
+
37
+ // NormalizeResourceGraphRoot canonicalizes known wire kinds and trims user input.
38
+ // It never supplies a default namespace or relaxes namespaced scope validation.
39
+ func NormalizeResourceGraphRoot(root cr.ResourceRef) (cr.ResourceRef, error) {
40
+ root.ClusterID = strings.TrimSpace(root.ClusterID)
41
+ root.APIVersion = strings.TrimSpace(root.APIVersion)
42
+ root.Kind = strings.TrimSpace(root.Kind)
43
+ root.Name = strings.TrimSpace(root.Name)
44
+ root.Namespace = strings.TrimSpace(root.Namespace)
45
+ for _, definition := range cr.NetworkTopologySources() {
46
+ if networkGraphRootKind(definition.Kind) && strings.EqualFold(root.Kind, definition.Kind) {
47
+ root.Kind = definition.Kind
48
+ break
49
+ }
50
+ }
51
+ for kind := range graphBuiltinAPIs {
52
+ if strings.EqualFold(root.Kind, kind) {
53
+ root.Kind = kind
54
+ break
55
+ }
56
+ }
57
+ return root, validateGraphRoot(root)
58
+ }
59
+ func validateGraphRoot(root cr.ResourceRef) error {
60
+ if root.ClusterID == "" || root.Kind == "" || root.Name == "" {
61
+ return invalidGraphRoot("resource graph root requires cluster, kind and name")
62
+ }
63
+ if definition, ok := networkGraphRootSource(root); ok {
64
+ return validateNetworkGraphRootScope(root, definition)
65
+ }
66
+ builtinAPI, kindKnown := graphBuiltinAPIs[root.Kind]
67
+ known := kindKnown && (root.APIVersion == "" || root.APIVersion == builtinAPI)
68
+ if known && graphStorageRootKind(root.Kind) && root.ScopeMode != "" && root.ScopeMode != topologyScope(root.Kind == "PersistentVolumeClaim") {
69
+ return invalidGraphRoot("storage resource graph root scope mismatch")
70
+ }
71
+ if known && graphRBACRootKind(root.Kind) && root.ScopeMode != "" && root.ScopeMode != topologyScope(!graphRBACClusterKind(root.Kind)) {
72
+ return invalidGraphRoot("RBAC resource graph root scope mismatch")
73
+ }
74
+ coreAPI := root.APIVersion == "" || root.APIVersion == "v1"
75
+ clusterKind := coreAPI && (root.Kind == "Node" || root.Kind == "Namespace") || known && (graphClusterConfigurationKind(root.Kind) || root.Kind == "PersistentVolume" || root.Kind == "StorageClass" || graphRBACClusterKind(root.Kind))
76
+ if root.Namespace == "" && !clusterKind && (known || root.ScopeMode != cr.ResourceScopeModeCluster) {
77
+ return invalidGraphRoot("namespaced resource graph root requires namespace")
78
+ }
79
+ if clusterKind && root.Namespace != "" {
80
+ return invalidGraphRoot("cluster resource graph root cannot have namespace")
81
+ }
82
+ return nil
83
+ }
84
+
85
+ const ResourceGraphWorkingNodeLimit = 10000
86
+ const ResourceGraphWorkingEdgeLimit = 10000
87
+
88
+ var ErrResourceGraphBudget = errors.New("resource graph working set budget exceeded")
89
+
90
+ type graphRules struct {
91
+ ctx context.Context
92
+ err error
93
+ partial bool
94
+ pods []*unstructured.Unstructured
95
+ clusterRoles []*unstructured.Unstructured
96
+
97
+ cluster string
98
+ objects map[string]*unstructured.Unstructured
99
+ nodes map[string]cr.ResourceGraphNode
100
+ edges map[string]cr.ResourceGraphEdge
101
+ }
102
+
103
+ func graphIdentity(api, kind, namespace, name string) string {
104
+ return api + ":" + kind + ":" + namespace + "/" + name
105
+ }
106
+
107
+ var graphIDSegmentEscaper = strings.NewReplacer("%", "%25", ":", "%3A")
108
+
109
+ func graphNodeID(ref cr.ResourceRef) string {
110
+ id := graphIdentity(ref.APIVersion, ref.Kind, ref.Namespace, graphIDSegmentEscaper.Replace(ref.Name))
111
+ if ref.UID != "" {
112
+ id += ":" + graphIDSegmentEscaper.Replace(ref.UID)
113
+ }
114
+ return id
115
+ }
116
+ func (b *graphRules) ref(o *unstructured.Unstructured) cr.ResourceRef {
117
+ scope := cr.ResourceScopeModeNamespace
118
+ if o.GetNamespace() == "" {
119
+ scope = cr.ResourceScopeModeCluster
120
+ }
121
+ return cr.ResourceRef{ClusterID: b.cluster, APIVersion: o.GetAPIVersion(), Kind: o.GetKind(), Namespace: o.GetNamespace(), Name: o.GetName(), UID: string(o.GetUID()), ResourceVersion: o.GetResourceVersion(), ScopeMode: scope}
122
+ }
123
+ func (b *graphRules) active() bool {
124
+ if b.err != nil {
125
+ return false
126
+ }
127
+ if err := b.ctx.Err(); err != nil {
128
+ b.err = err
129
+ return false
130
+ }
131
+ return !b.partial
132
+ }
133
+ func (b *graphRules) node(ref cr.ResourceRef, status string) string {
134
+ return b.addNode(graphNodeID(ref), ref, status)
135
+ }
136
+ func (b *graphRules) addNode(id string, ref cr.ResourceRef, status string) string {
137
+ if !b.active() {
138
+ return ""
139
+ }
140
+ if _, ok := b.nodes[id]; !ok {
141
+ if len(b.nodes) >= ResourceGraphWorkingNodeLimit {
142
+ b.partial = true
143
+ return ""
144
+ }
145
+ b.nodes[id] = cr.ResourceGraphNode{ID: id, Resource: ref, Status: status}
146
+ }
147
+ return id
148
+ }
149
+ func (b *graphRules) target(api, kind, namespace, name, uid string) string {
150
+ if name == "" {
151
+ return ""
152
+ }
153
+ ref := cr.ResourceRef{ClusterID: b.cluster, APIVersion: api, Kind: kind, Namespace: namespace, Name: name, UID: uid, ScopeMode: cr.ResourceScopeModeNamespace}
154
+ if namespace == "" {
155
+ ref.ScopeMode = cr.ResourceScopeModeCluster
156
+ }
157
+ if o := b.objects[graphIdentity(api, kind, namespace, name)]; o != nil && (uid == "" || string(o.GetUID()) == uid) {
158
+ return b.node(b.ref(o), graphStatus(o))
159
+ }
160
+ return b.node(ref, "unresolved")
161
+ }
162
+ func (b *graphRules) edge(source, target, relation string) {
163
+ b.addEdge(cr.ResourceGraphEdge{SourceID: source, TargetID: target, Relation: relation})
164
+ }
165
+ func (b *graphRules) addEdge(edge cr.ResourceGraphEdge) {
166
+ if !b.active() {
167
+ return
168
+ }
169
+ if edge.SourceID == "" || edge.TargetID == "" || edge.SourceID == edge.TargetID {
170
+ return
171
+ }
172
+ edge.ID = edge.Relation + ":" + edge.SourceID + ":" + edge.TargetID
173
+ if _, exists := b.edges[edge.ID]; !exists && len(b.edges) >= ResourceGraphWorkingEdgeLimit {
174
+ b.partial = true
175
+ return
176
+ }
177
+ b.edges[edge.ID] = edge
178
+ }
179
+ func graphIsEvent(o *unstructured.Unstructured) bool {
180
+ return o.GetAPIVersion() == "v1" && o.GetKind() == "Event"
181
+ }
182
+ func graphStatus(o *unstructured.Unstructured) string {
183
+ if !graphBuiltinSpec(o) {
184
+ return ""
185
+ }
186
+ switch o.GetKind() {
187
+ case "Deployment":
188
+ return graphReplicaStatus(o, "availableReplicas")
189
+ case "ReplicaSet":
190
+ return graphReplicaStatus(o, "readyReplicas")
191
+ case "Ingress":
192
+ ingress, _, _ := graphNestedSlice(o.Object, "status", "loadBalancer", "ingress")
193
+ if len(ingress) > 0 {
194
+ return "ready"
195
+ }
196
+ return "pending"
197
+ case "Service":
198
+ value, _, _ := unstructured.NestedString(o.Object, "spec", "type")
199
+ return value
200
+ default:
201
+ phase, _, _ := unstructured.NestedString(o.Object, "status", "phase")
202
+ return phase
203
+ }
204
+ }
205
+ func graphReplicaStatus(o *unstructured.Unstructured, readyField string) string {
206
+ replicas, found, _ := unstructured.NestedInt64(o.Object, "status", "replicas")
207
+ ready, readyFound, _ := unstructured.NestedInt64(o.Object, "status", readyField)
208
+ if found && readyFound && replicas > 0 && ready >= replicas {
209
+ return "healthy"
210
+ }
211
+ return "progressing"
212
+ }
213
+
214
+ // BuildResourceGraphFromObjects applies the same pure rules to typed projections
215
+ // or arbitrary Kubernetes objects. Unknown kinds contribute only metadata
216
+ // ownerReferences; their spec is never inferred. Callers own discovery and scope.
217
+ func BuildResourceGraphFromObjects(root cr.ResourceRef, objects []*unstructured.Unstructured) (cr.ResourceGraph, error) {
218
+ ctx, cancel := context.WithTimeout(context.Background(), ResourceGraphTimeout)
219
+ defer cancel()
220
+ return buildResourceGraphWithContext(ctx, root, objects)
221
+ }
222
+ func buildResourceGraphWithContext(ctx context.Context, root cr.ResourceRef, objects []*unstructured.Unstructured) (cr.ResourceGraph, error) {
223
+ if err := ctx.Err(); err != nil {
224
+ return cr.ResourceGraph{}, err
225
+ }
226
+ if len(objects) > ResourceGraphWorkingNodeLimit {
227
+ return cr.ResourceGraph{}, ErrResourceGraphBudget
228
+ }
229
+ root, err := NormalizeResourceGraphRoot(root)
230
+ if err != nil {
231
+ return cr.ResourceGraph{}, err
232
+ }
233
+ index, err := graphObjectIndex(ctx, root.Namespace, objects)
234
+ if err != nil {
235
+ return cr.ResourceGraph{}, err
236
+ }
237
+ b := &graphRules{ctx: ctx, cluster: root.ClusterID, objects: index, nodes: map[string]cr.ResourceGraphNode{}, edges: map[string]cr.ResourceGraphEdge{}}
238
+ rootObject, err := b.rootObject(root)
239
+ if err != nil {
240
+ return cr.ResourceGraph{}, err
241
+ }
242
+ rootID := b.node(b.ref(rootObject), graphStatus(rootObject))
243
+ keys := b.objectKeys(rootObject)
244
+ storage := graphBuiltinSpec(rootObject) && graphStorageRootKind(root.Kind)
245
+ rbac := graphBuiltinSpec(rootObject) && graphRBACRootKind(root.Kind)
246
+ if err := indexGraphCrossNamespaceAccounts(ctx, rootObject, objects, index); err != nil {
247
+ return cr.ResourceGraph{}, err
248
+ }
249
+ if !storage {
250
+ b.priorityOwners(rootObject)
251
+ for _, key := range keys {
252
+ if !b.active() {
253
+ break
254
+ }
255
+ o := b.objects[key]
256
+ if graphIsEvent(o) {
257
+ continue
258
+ }
259
+ id := b.node(b.ref(o), graphStatus(o))
260
+ b.ownerRelations(o, id)
261
+ }
262
+ }
263
+ for _, key := range keys {
264
+ if !b.active() {
265
+ break
266
+ }
267
+ o := b.objects[key]
268
+ if graphIsEvent(o) {
269
+ continue
270
+ }
271
+ id := b.node(b.ref(o), graphStatus(o))
272
+ if storage {
273
+ b.storageRelations(o, id)
274
+ continue
275
+ }
276
+ if rbac {
277
+ b.rbacRelations(o, id)
278
+ continue
279
+ }
280
+ b.podReferences(o, id)
281
+ b.selectorRelations(o, id)
282
+ b.configurationRelations(o, id)
283
+ }
284
+ if b.err != nil {
285
+ return cr.ResourceGraph{}, b.err
286
+ }
287
+ graph, err := b.bounded(rootID, root.Namespace)
288
+ if err != nil {
289
+ return cr.ResourceGraph{}, err
290
+ }
291
+ if b.partial {
292
+ graph.Warnings = append(graph.Warnings, "resource graph working set truncated at 10000 nodes or 10000 edges")
293
+ }
294
+ if rbac && root.Kind == "ServiceAccount" {
295
+ graph.Warnings = append(graph.Warnings, "RoleBinding source limited to the ServiceAccount namespace")
296
+ }
297
+ for _, key := range keys {
298
+ if err := ctx.Err(); err != nil {
299
+ return cr.ResourceGraph{}, err
300
+ }
301
+ o := b.objects[key]
302
+ if graphIsEvent(o) {
303
+ b.event(&graph, o)
304
+ }
305
+ }
306
+ sort.SliceStable(graph.Evidence, func(i, j int) bool {
307
+ left, _ := time.Parse(time.RFC3339Nano, graph.Evidence[i].ObservedAt)
308
+ right, _ := time.Parse(time.RFC3339Nano, graph.Evidence[j].ObservedAt)
309
+ return left.After(right)
310
+ })
311
+ return graph, ctx.Err()
312
+ }
313
+ func (b *graphRules) objectKeys(root *unstructured.Unstructured) []string {
314
+ rootKey := graphIdentity(root.GetAPIVersion(), root.GetKind(), root.GetNamespace(), root.GetName())
315
+ keys := make([]string, 0, len(b.objects))
316
+ for key := range b.objects {
317
+ if key != rootKey {
318
+ keys = append(keys, key)
319
+ }
320
+ }
321
+ sort.Strings(keys)
322
+ // Pod selector iteration is sorted separately from the root-first rule order.
323
+ for _, key := range keys {
324
+ o := b.objects[key]
325
+ if o.GetKind() == "Pod" && o.GetAPIVersion() == "v1" {
326
+ b.pods = append(b.pods, o)
327
+ }
328
+ if o.GetKind() == "ClusterRole" && o.GetAPIVersion() == graphRBACAPI && o.GetNamespace() == "" {
329
+ b.clusterRoles = append(b.clusterRoles, o)
330
+ }
331
+ }
332
+ if root.GetKind() == "Pod" && root.GetAPIVersion() == "v1" {
333
+ b.pods = append(b.pods, root)
334
+ }
335
+ if root.GetKind() == "ClusterRole" && root.GetAPIVersion() == graphRBACAPI && root.GetNamespace() == "" {
336
+ b.clusterRoles = append(b.clusterRoles, root)
337
+ }
338
+ return append([]string{rootKey}, keys...)
339
+ }
340
+ func (b *graphRules) priorityOwners(root *unstructured.Unstructured) {
341
+ queue := []*unstructured.Unstructured{root}
342
+ seen := map[string]bool{}
343
+ for len(queue) > 0 {
344
+ if !b.active() {
345
+ return
346
+ }
347
+ current := queue[0]
348
+ queue = queue[1:]
349
+ id := graphNodeID(b.ref(current))
350
+ if seen[id] {
351
+ continue
352
+ }
353
+ seen[id] = true
354
+ b.ownerRelations(current, b.node(b.ref(current), graphStatus(current)))
355
+ for _, owner := range current.GetOwnerReferences() {
356
+ if !b.active() {
357
+ return
358
+ }
359
+ if actual := b.observedOwner(current.GetNamespace(), owner); actual != nil {
360
+ queue = append(queue, actual)
361
+ }
362
+ }
363
+ }
364
+ }
365
+ func graphObjectIndex(ctx context.Context, namespace string, objects []*unstructured.Unstructured) (map[string]*unstructured.Unstructured, error) {
366
+ index := map[string]*unstructured.Unstructured{}
367
+ for _, o := range objects {
368
+ if err := ctx.Err(); err != nil {
369
+ return nil, err
370
+ }
371
+ if o == nil || o.GetName() == "" || o.GetKind() == "" || o.GetAPIVersion() == "" {
372
+ continue
373
+ }
374
+ if namespace != "" && o.GetNamespace() != "" && o.GetNamespace() != namespace {
375
+ continue
376
+ }
377
+ key := graphIdentity(o.GetAPIVersion(), o.GetKind(), o.GetNamespace(), o.GetName())
378
+ if _, exists := index[key]; !exists {
379
+ index[key] = o
380
+ }
381
+ }
382
+ return index, nil
383
+ }
384
+ func (b *graphRules) rootObject(root cr.ResourceRef) (*unstructured.Unstructured, error) {
385
+ var result *unstructured.Unstructured
386
+ for _, o := range b.objects {
387
+ if err := b.ctx.Err(); err != nil {
388
+ return nil, err
389
+ }
390
+ if o.GetKind() != root.Kind || o.GetName() != root.Name || o.GetNamespace() != root.Namespace {
391
+ continue
392
+ }
393
+ if root.APIVersion != "" && o.GetAPIVersion() != root.APIVersion {
394
+ continue
395
+ }
396
+ if result != nil {
397
+ return nil, invalidGraphRoot("ambiguous root apiVersion")
398
+ }
399
+ result = o
400
+ }
401
+ if result == nil {
402
+ return nil, invalidGraphRoot("resource graph root not present")
403
+ }
404
+ if root.UID != "" && string(result.GetUID()) != root.UID {
405
+ return nil, invalidGraphRoot("resource graph root UID changed")
406
+ }
407
+ return result, nil
408
+ }
409
+ func (b *graphRules) ownerRelations(o *unstructured.Unstructured, id string) {
410
+ for _, owner := range o.GetOwnerReferences() {
411
+ if !b.active() {
412
+ return
413
+ }
414
+ relation := "owns"
415
+ if owner.Controller != nil && *owner.Controller {
416
+ relation = "controls"
417
+ }
418
+ b.edge(b.ownerTarget(o.GetNamespace(), owner), id, relation)
419
+ }
420
+ }
421
+
422
+ // Kubernetes permits a cluster-scoped owner of a namespaced dependent. Only
423
+ // observed exact identities confirm this; another namespace is never searched.
424
+ func (b *graphRules) observedOwner(namespace string, owner metav1.OwnerReference) *unstructured.Unstructured {
425
+ if owner.UID == "" {
426
+ return nil
427
+ }
428
+ for _, scope := range []string{namespace, ""} {
429
+ candidate := b.objects[graphIdentity(owner.APIVersion, owner.Kind, scope, owner.Name)]
430
+ if candidate != nil && candidate.GetUID() == owner.UID {
431
+ return candidate
432
+ }
433
+ }
434
+ return nil
435
+ }
436
+ func (b *graphRules) ownerTarget(namespace string, owner metav1.OwnerReference) string {
437
+ if actual := b.observedOwner(namespace, owner); actual != nil {
438
+ return b.node(b.ref(actual), graphStatus(actual))
439
+ }
440
+ ref := cr.ResourceRef{ClusterID: b.cluster, APIVersion: owner.APIVersion, Kind: owner.Kind, Namespace: namespace, Name: owner.Name, UID: string(owner.UID), ScopeMode: cr.ResourceScopeModeNamespace}
441
+ // The wire requires a scope enum. Use the dependent lookup context for this
442
+ // unresolved candidate; it does not confirm the target or its actual scope.
443
+ if namespace == "" {
444
+ ref.ScopeMode = cr.ResourceScopeModeCluster
445
+ }
446
+ return b.node(ref, "unresolved")
447
+ }
448
+
449
+ // A custom object may reuse a built-in kind name; spec rules require exact GVK.
450
+ func graphBuiltinSpec(o *unstructured.Unstructured) bool {
451
+ return graphBuiltinAPIs[o.GetKind()] != "" && graphBuiltinAPIs[o.GetKind()] == o.GetAPIVersion()
452
+ }
453
+ func graphNestedMap(object map[string]interface{}, fields ...string) (map[string]interface{}, bool, error) {
454
+ value, found, err := unstructured.NestedFieldNoCopy(object, fields...)
455
+ result, _ := value.(map[string]interface{})
456
+ return result, found, err
457
+ }
458
+ func graphNestedSlice(object map[string]interface{}, fields ...string) ([]interface{}, bool, error) {
459
+ value, found, err := unstructured.NestedFieldNoCopy(object, fields...)
460
+ result, _ := value.([]interface{})
461
+ return result, found, err
462
+ }
463
+ func graphMap(m map[string]interface{}, key string) map[string]interface{} {
464
+ value, _ := m[key].(map[string]interface{})
465
+ return value
466
+ }
467
+ func graphString(m map[string]interface{}, key string) string {
468
+ value, _ := m[key].(string)
469
+ return value
470
+ }
471
+ func graphSlice(m map[string]interface{}, key string) []interface{} {
472
+ value, _ := m[key].([]interface{})
473
+ return value
474
+ }
475
+ func graphPodSpec(o *unstructured.Unstructured) map[string]interface{} {
476
+ if !graphBuiltinSpec(o) {
477
+ return nil
478
+ }
479
+ path := []string{"spec", "template", "spec"}
480
+ switch o.GetKind() {
481
+ case "Pod":
482
+ path = []string{"spec"}
483
+ case "CronJob":
484
+ path = []string{"spec", "jobTemplate", "spec", "template", "spec"}
485
+ case "Deployment", "StatefulSet", "DaemonSet", "Job", "ReplicaSet", "ReplicationController":
486
+ default:
487
+ return nil
488
+ }
489
+ spec, _, _ := graphNestedMap(o.Object, path...)
490
+ return spec
491
+ }
492
+ func (b *graphRules) podReferences(o *unstructured.Unstructured, id string) {
493
+ spec := graphPodSpec(o)
494
+ if spec == nil {
495
+ return
496
+ }
497
+ ref := func(kind, name, relation string) {
498
+ b.edge(id, b.target("v1", kind, o.GetNamespace(), name, ""), relation)
499
+ }
500
+ for _, field := range []string{"containers", "initContainers", "ephemeralContainers"} {
501
+ for _, raw := range graphSlice(spec, field) {
502
+ if !b.active() {
503
+ return
504
+ }
505
+ container, _ := raw.(map[string]interface{})
506
+ graphContainerRefs(container, ref, b.active)
507
+ }
508
+ }
509
+ for _, raw := range graphSlice(spec, "volumes") {
510
+ if !b.active() {
511
+ return
512
+ }
513
+ volume, _ := raw.(map[string]interface{})
514
+ graphVolumeRefs(volume, ref, b.active)
515
+ }
516
+ ref("ServiceAccount", graphString(spec, "serviceAccountName"), ResourceGraphRelationUsesServiceAccount)
517
+ for _, raw := range graphSlice(spec, "imagePullSecrets") {
518
+ if !b.active() {
519
+ return
520
+ }
521
+ entry, _ := raw.(map[string]interface{})
522
+ ref("Secret", graphString(entry, "name"), "uses-secret")
523
+ }
524
+ if node := graphString(spec, "nodeName"); node != "" {
525
+ b.edge(id, b.target("v1", "Node", "", node, ""), "scheduled-on")
526
+ }
527
+ b.edge(id, b.target("scheduling.k8s.io/v1", "PriorityClass", "", graphString(spec, "priorityClassName"), ""), ResourceGraphRelationUsesPriorityClass)
528
+ b.edge(id, b.target("node.k8s.io/v1", "RuntimeClass", "", graphString(spec, "runtimeClassName"), ""), ResourceGraphRelationUsesRuntimeClass)
529
+ }
530
+ func graphContainerRefs(container map[string]interface{}, ref func(string, string, string), active func() bool) {
531
+ for _, raw := range graphSlice(container, "env") {
532
+ if !active() {
533
+ return
534
+ }
535
+ entry, _ := raw.(map[string]interface{})
536
+ value := graphMap(entry, "valueFrom")
537
+ ref("ConfigMap", graphString(graphMap(value, "configMapKeyRef"), "name"), "uses-config")
538
+ ref("Secret", graphString(graphMap(value, "secretKeyRef"), "name"), "uses-secret")
539
+ }
540
+ for _, raw := range graphSlice(container, "envFrom") {
541
+ if !active() {
542
+ return
543
+ }
544
+ entry, _ := raw.(map[string]interface{})
545
+ ref("ConfigMap", graphString(graphMap(entry, "configMapRef"), "name"), "uses-config")
546
+ ref("Secret", graphString(graphMap(entry, "secretRef"), "name"), "uses-secret")
547
+ }
548
+ }
549
+ func graphVolumeRefs(volume map[string]interface{}, ref func(string, string, string), active func() bool) {
550
+ ref("ConfigMap", graphString(graphMap(volume, "configMap"), "name"), "uses-config")
551
+ ref("Secret", graphString(graphMap(volume, "secret"), "secretName"), "uses-secret")
552
+ ref("Secret", graphString(graphMap(graphMap(volume, "csi"), "nodePublishSecretRef"), "name"), "uses-secret")
553
+ ref("PersistentVolumeClaim", graphVolumeClaimName(volume), ResourceGraphRelationMounts)
554
+ for _, raw := range graphSlice(graphMap(volume, "projected"), "sources") {
555
+ if !active() {
556
+ return
557
+ }
558
+ source, _ := raw.(map[string]interface{})
559
+ ref("ConfigMap", graphString(graphMap(source, "configMap"), "name"), "uses-config")
560
+ ref("Secret", graphString(graphMap(source, "secret"), "name"), "uses-secret")
561
+ }
562
+ }
563
+
564
+ func (b *graphRules) selectorRelations(o *unstructured.Unstructured, id string) {
565
+ if !graphBuiltinSpec(o) {
566
+ return
567
+ }
568
+ switch o.GetKind() {
569
+ case "Service", "PodDisruptionBudget":
570
+ b.podSelectorRelations(o, id)
571
+ case "HorizontalPodAutoscaler":
572
+ target, _, _ := graphNestedMap(o.Object, "spec", "scaleTargetRef")
573
+ if graphString(target, "apiVersion") != "" && graphString(target, "kind") != "" {
574
+ b.edge(id, b.target(graphString(target, "apiVersion"), graphString(target, "kind"), o.GetNamespace(), graphString(target, "name"), ""), "scales")
575
+ }
576
+ case "Ingress":
577
+ b.ingressRelations(o, id)
578
+ }
579
+ }
580
+ func graphPodSelector(o *unstructured.Unstructured) labels.Selector {
581
+ selector, found, _ := graphNestedMap(o.Object, "spec", "selector")
582
+ if !found || selector == nil {
583
+ return nil
584
+ }
585
+ if o.GetKind() == "Service" {
586
+ return servicePodSelector(selector)
587
+ }
588
+ var parsed metav1.LabelSelector
589
+ if kruntime.DefaultUnstructuredConverter.FromUnstructured(selector, &parsed) != nil {
590
+ return nil
591
+ }
592
+ query, err := metav1.LabelSelectorAsSelector(&parsed)
593
+ if err != nil {
594
+ return nil
595
+ }
596
+ return query
597
+ }
598
+ func (b *graphRules) podSelectorRelations(o *unstructured.Unstructured, id string) {
599
+ query := graphPodSelector(o)
600
+ if query == nil {
601
+ return
602
+ }
603
+ relation := "selects"
604
+ if o.GetKind() == "PodDisruptionBudget" {
605
+ relation = "protects"
606
+ }
607
+ for _, pod := range b.pods {
608
+ if !b.active() {
609
+ return
610
+ }
611
+ if pod.GetAPIVersion() == "v1" && pod.GetKind() == "Pod" && pod.GetNamespace() == o.GetNamespace() && query.Matches(labels.Set(pod.GetLabels())) {
612
+ b.edge(id, b.node(b.ref(pod), graphStatus(pod)), relation)
613
+ }
614
+ }
615
+ }
616
+ func (b *graphRules) ingressRelations(o *unstructured.Unstructured, id string) {
617
+ forEachIngressBackendDeclaration(o.Object, b.active, func(ref ingressBackendDeclaration) {
618
+ b.edge(id, b.target("v1", "Service", o.GetNamespace(), ref.serviceName, ""), "routes-to")
619
+ })
620
+ }
621
+
622
+ // Traverse each direction independently. In particular, arriving at a shared
623
+ // config/Secret never reverses direction and discovers unrelated consumers.
624
+ type graphTraversalState struct {
625
+ id string
626
+ depth, direction int
627
+ }
628
+ type graphTraversal struct {
629
+ selected, chosen map[string]bool
630
+ depthTruncated, limitTruncated bool
631
+ }
632
+
633
+ func graphNext(current graphTraversalState, edge cr.ResourceGraphEdge) (graphTraversalState, bool) {
634
+ next := graphTraversalState{depth: current.depth + 1, direction: current.direction}
635
+ if current.direction == 1 && edge.SourceID == current.id {
636
+ next.id = edge.TargetID
637
+ }
638
+ if current.direction == -1 && edge.TargetID == current.id {
639
+ next.id = edge.SourceID
640
+ }
641
+ supporting := edge.Relation == "selects" || edge.Relation == "protects" || edge.Relation == "scales"
642
+ if current.direction == 1 && edge.TargetID == current.id && supporting {
643
+ next.id = edge.SourceID
644
+ next.direction = -1
645
+ }
646
+ return next, next.id != ""
647
+ }
648
+ func (t *graphTraversal) include(edge cr.ResourceGraphEdge, next graphTraversalState) bool {
649
+ if (!t.selected[next.id] && len(t.selected) >= ResourceGraphNodeLimit) || (!t.chosen[edge.ID] && len(t.chosen) >= ResourceGraphEdgeLimit) {
650
+ t.limitTruncated = true
651
+ return false
652
+ }
653
+ t.selected[next.id] = true
654
+ t.chosen[edge.ID] = true
655
+ return true
656
+ }
657
+ func graphAdjacency(ctx context.Context, edges []cr.ResourceGraphEdge) (map[string][]cr.ResourceGraphEdge, map[string][]cr.ResourceGraphEdge, error) {
658
+ forward := map[string][]cr.ResourceGraphEdge{}
659
+ reverse := map[string][]cr.ResourceGraphEdge{}
660
+ for _, edge := range edges {
661
+ if err := ctx.Err(); err != nil {
662
+ return nil, nil, err
663
+ }
664
+ forward[edge.SourceID] = append(forward[edge.SourceID], edge)
665
+ reverse[edge.TargetID] = append(reverse[edge.TargetID], edge)
666
+ if edge.Relation == "selects" || edge.Relation == "protects" || edge.Relation == "scales" {
667
+ forward[edge.TargetID] = append(forward[edge.TargetID], edge)
668
+ }
669
+ }
670
+ return forward, reverse, nil
671
+ }
672
+
673
+ // Reserve the root's owner chain before selector fanout consumes output slots.
674
+ func graphSeedOwners(ctx context.Context, rootID string, reverse map[string][]cr.ResourceGraphEdge, result *graphTraversal) error {
675
+ queue := []graphTraversalState{{id: rootID, direction: -1}}
676
+ seen := map[string]bool{}
677
+ for len(queue) > 0 {
678
+ if err := ctx.Err(); err != nil {
679
+ return err
680
+ }
681
+ current := queue[0]
682
+ queue = queue[1:]
683
+ if seen[current.id] || current.depth >= ResourceGraphDepth {
684
+ continue
685
+ }
686
+ seen[current.id] = true
687
+ for _, edge := range reverse[current.id] {
688
+ if err := ctx.Err(); err != nil {
689
+ return err
690
+ }
691
+ if edge.Relation != "owns" && edge.Relation != "controls" {
692
+ continue
693
+ }
694
+ next, ok := graphNext(current, edge)
695
+ if ok && result.include(edge, next) {
696
+ queue = append(queue, next)
697
+ }
698
+ }
699
+ }
700
+ return nil
701
+ }
702
+ func graphTraverse(ctx context.Context, rootID string, edges []cr.ResourceGraphEdge) (*graphTraversal, error) {
703
+ forward, reverse, err := graphAdjacency(ctx, edges)
704
+ if err != nil {
705
+ return nil, err
706
+ }
707
+ result := &graphTraversal{selected: map[string]bool{rootID: true}, chosen: map[string]bool{}}
708
+ if err := graphSeedOwners(ctx, rootID, reverse, result); err != nil {
709
+ return nil, err
710
+ }
711
+ queue := []graphTraversalState{{id: rootID, direction: 1}, {id: rootID, direction: -1}}
712
+ seen := map[graphTraversalState]bool{}
713
+ omitted := map[string]bool{}
714
+ for len(queue) > 0 {
715
+ if err := ctx.Err(); err != nil {
716
+ return nil, err
717
+ }
718
+ current := queue[0]
719
+ queue = queue[1:]
720
+ if seen[current] {
721
+ continue
722
+ }
723
+ seen[current] = true
724
+ adjacent := forward[current.id]
725
+ if current.direction == -1 {
726
+ adjacent = reverse[current.id]
727
+ }
728
+ for _, edge := range adjacent {
729
+ if err := ctx.Err(); err != nil {
730
+ return nil, err
731
+ }
732
+ next, ok := graphNext(current, edge)
733
+ if !ok {
734
+ continue
735
+ }
736
+ if current.depth >= ResourceGraphDepth {
737
+ omitted[edge.ID] = true
738
+ continue
739
+ }
740
+ if result.include(edge, next) {
741
+ queue = append(queue, next)
742
+ }
743
+ }
744
+ }
745
+ for id := range omitted {
746
+ if !result.chosen[id] {
747
+ result.depthTruncated = true
748
+ break
749
+ }
750
+ }
751
+ return result, nil
752
+ }
753
+ func (b *graphRules) bounded(rootID, namespace string) (cr.ResourceGraph, error) {
754
+ graph := cr.ResourceGraph{ClusterID: b.cluster, Namespace: namespace, GeneratedAt: time.Now().UTC().Format(time.RFC3339Nano), RootID: rootID, Nodes: []cr.ResourceGraphNode{}, Edges: []cr.ResourceGraphEdge{}, Evidence: []cr.ResourceEvidence{}, Warnings: []string{}}
755
+ edges := make([]cr.ResourceGraphEdge, 0, len(b.edges))
756
+ for _, edge := range b.edges {
757
+ edges = append(edges, edge)
758
+ }
759
+ sort.Slice(edges, func(i, j int) bool { return edges[i].ID < edges[j].ID })
760
+ selected, err := graphTraverse(b.ctx, rootID, edges)
761
+ if err != nil {
762
+ return cr.ResourceGraph{}, err
763
+ }
764
+ for id := range selected.selected {
765
+ graph.Nodes = append(graph.Nodes, b.nodes[id])
766
+ }
767
+ for _, edge := range edges {
768
+ if selected.chosen[edge.ID] {
769
+ graph.Edges = append(graph.Edges, edge)
770
+ }
771
+ }
772
+ sort.Slice(graph.Nodes, func(i, j int) bool { return graph.Nodes[i].ID < graph.Nodes[j].ID })
773
+ if selected.limitTruncated {
774
+ graph.Warnings = append(graph.Warnings, "resource graph truncated at 500 nodes or 1000 edges")
775
+ }
776
+ if selected.depthTruncated {
777
+ graph.Warnings = append(graph.Warnings, "resource graph truncated by depth at 3 hops")
778
+ }
779
+ return graph, b.ctx.Err()
780
+ }
781
+ func (b *graphRules) event(graph *cr.ResourceGraph, o *unstructured.Unstructured) {
782
+ involved, _, _ := graphNestedMap(o.Object, "involvedObject")
783
+ str := func(key string) string { s, _ := involved[key].(string); return s }
784
+ var id string
785
+ for _, node := range graph.Nodes {
786
+ if err := b.ctx.Err(); err != nil {
787
+ b.err = err
788
+ return
789
+ }
790
+ r := node.Resource
791
+ if r.Kind == str("kind") && r.Name == str("name") && r.Namespace == str("namespace") && (str("apiVersion") == "" || r.APIVersion == str("apiVersion")) && (str("uid") == "" || r.UID == str("uid")) {
792
+ id = node.ID
793
+ break
794
+ }
795
+ }
796
+ if id == "" {
797
+ return
798
+ }
799
+ reason, _, _ := unstructured.NestedString(o.Object, "reason")
800
+ message, _, _ := unstructured.NestedString(o.Object, "message")
801
+ typ, _, _ := unstructured.NestedString(o.Object, "type")
802
+ severity := "info"
803
+ if typ == "Warning" {
804
+ severity = "warning"
805
+ }
806
+ observed := graphEventObservedAt(o)
807
+ if observed.IsZero() {
808
+ return
809
+ }
810
+ graph.Evidence = append(graph.Evidence, cr.ResourceEvidence{ID: "event/" + o.GetNamespace() + "/" + o.GetName(), Type: "kubernetes-event", Severity: severity, Summary: strings.TrimSpace(reason + " " + message), ObservedAt: observed.UTC().Format(time.RFC3339Nano), ResourceID: id, SourceRef: "Event/" + o.GetNamespace() + "/" + o.GetName()})
811
+ }
812
+
813
+ func graphEventObservedAt(o *unstructured.Unstructured) time.Time {
814
+ for _, field := range []string{"lastTimestamp", "eventTime"} {
815
+ value, _, _ := unstructured.NestedString(o.Object, field)
816
+ if observed, err := time.Parse(time.RFC3339Nano, value); err == nil && !observed.IsZero() {
817
+ return observed
818
+ }
819
+ }
820
+ return o.GetCreationTimestamp().Time
821
+ }
822
+
823
+ func validateNetworkGraphRootScope(root cr.ResourceRef, definition cr.NetworkTopologySourceDefinition) error {
824
+ if root.ScopeMode != "" && root.ScopeMode != topologyScope(definition.Namespaced) {
825
+ return invalidGraphRoot("network resource graph root scope mismatch")
826
+ }
827
+ if definition.Namespaced && root.Namespace == "" {
828
+ return invalidGraphRoot("namespaced resource graph root requires namespace")
829
+ }
830
+ if !definition.Namespaced && root.Namespace != "" {
831
+ return invalidGraphRoot("cluster resource graph root cannot have namespace")
832
+ }
833
+ return nil
834
+ }