@a5c-ai/kradle 5.0.1-staging.3abdf9534c25

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 (295) hide show
  1. package/Dockerfile +31 -0
  2. package/README.md +187 -0
  3. package/bin/kradle-demo.mjs +23 -0
  4. package/bin/kradle-server.mjs +14 -0
  5. package/dist/kradle-controller-ui.json +3482 -0
  6. package/dist/kradle-lifecycle.json +201 -0
  7. package/dist/kradle-runtime-snapshot.json +3125 -0
  8. package/dist/kradle-summary.json +724 -0
  9. package/docs/README.md +61 -0
  10. package/docs/agents/README.md +83 -0
  11. package/docs/agents/acceptance-test-matrix.md +193 -0
  12. package/docs/agents/agent-mux-adapter-contract.md +167 -0
  13. package/docs/agents/agent-mux-source-map.md +310 -0
  14. package/docs/agents/agent-run-memory-import-spec.md +256 -0
  15. package/docs/agents/agent-stack-management-spec.md +421 -0
  16. package/docs/agents/api-contract-spec.md +309 -0
  17. package/docs/agents/artifacts-writeback-spec.md +145 -0
  18. package/docs/agents/chart-packaging-spec.md +128 -0
  19. package/docs/agents/ci-orchestration-spec.md +140 -0
  20. package/docs/agents/context-assembly-spec.md +219 -0
  21. package/docs/agents/controller-reconciliation-spec.md +255 -0
  22. package/docs/agents/crd-schema-spec.md +315 -0
  23. package/docs/agents/decision-log-open-questions.md +169 -0
  24. package/docs/agents/developer-implementation-checklist.md +329 -0
  25. package/docs/agents/dispatching-design.md +262 -0
  26. package/docs/agents/gaps-agent-mux-to-kradle-crds.md +298 -0
  27. package/docs/agents/glossary.md +66 -0
  28. package/docs/agents/implementation-blueprint.md +324 -0
  29. package/docs/agents/implementation-rollout-slices.md +251 -0
  30. package/docs/agents/memory-context-integration-spec.md +194 -0
  31. package/docs/agents/memory-ontology-schema-spec.md +253 -0
  32. package/docs/agents/memory-operations-runbook.md +121 -0
  33. package/docs/agents/mvp-vertical-slice-spec.md +146 -0
  34. package/docs/agents/observability-audit-spec.md +265 -0
  35. package/docs/agents/operator-runbook.md +174 -0
  36. package/docs/agents/org-memory-api-payload-examples.md +333 -0
  37. package/docs/agents/org-memory-controller-sequence-spec.md +181 -0
  38. package/docs/agents/org-memory-e2e-fixture-plan.md +161 -0
  39. package/docs/agents/org-memory-ui-implementation-map.md +114 -0
  40. package/docs/agents/org-memory-vertical-slice-spec.md +168 -0
  41. package/docs/agents/org-resource-model-delta-spec.md +111 -0
  42. package/docs/agents/org-route-resource-model-spec.md +183 -0
  43. package/docs/agents/org-scoping-namespace-spec.md +114 -0
  44. package/docs/agents/rbac-secrets-management-spec.md +406 -0
  45. package/docs/agents/repository-page-integration-spec.md +255 -0
  46. package/docs/agents/resource-contract-examples.md +808 -0
  47. package/docs/agents/resource-relationship-map.md +190 -0
  48. package/docs/agents/security-threat-model.md +188 -0
  49. package/docs/agents/shared-memory-company-brain-spec.md +358 -0
  50. package/docs/agents/storage-migration-spec.md +168 -0
  51. package/docs/agents/subagent-orchestration-spec.md +152 -0
  52. package/docs/agents/system-overview.md +88 -0
  53. package/docs/agents/tools-mcp-skills-spec.md +189 -0
  54. package/docs/agents/traceability-matrix.md +79 -0
  55. package/docs/agents/ui-flow-spec.md +211 -0
  56. package/docs/agents/ui-ux-system-spec.md +426 -0
  57. package/docs/agents/workspace-lifecycle-spec.md +166 -0
  58. package/docs/architecture-spec.md +78 -0
  59. package/docs/architecture-v2.md +2759 -0
  60. package/docs/components/control-plane.md +78 -0
  61. package/docs/components/data-plane.md +69 -0
  62. package/docs/components/hooks-events.md +67 -0
  63. package/docs/components/identity-rbac-policy.md +73 -0
  64. package/docs/components/kubevela-oam.md +70 -0
  65. package/docs/components/operations-publishing.md +81 -0
  66. package/docs/components/runners-ci.md +66 -0
  67. package/docs/components/web-ui.md +94 -0
  68. package/docs/crd-behaviors-and-relationships.md +3926 -0
  69. package/docs/external/README.md +47 -0
  70. package/docs/external/bidirectional-sync-design.md +134 -0
  71. package/docs/external/cicd-interface.md +64 -0
  72. package/docs/external/external-backend-controllers.md +170 -0
  73. package/docs/external/external-backend-crds.md +234 -0
  74. package/docs/external/external-backend-ui-spec.md +151 -0
  75. package/docs/external/external-backend-ux-flows.md +115 -0
  76. package/docs/external/external-object-mapping.md +125 -0
  77. package/docs/external/git-forge-interface.md +68 -0
  78. package/docs/external/github-integration-design.md +151 -0
  79. package/docs/external/issue-tracking-interface.md +66 -0
  80. package/docs/external/provider-capability-manifests.md +204 -0
  81. package/docs/external/provider-catalog.md +139 -0
  82. package/docs/external/provider-rollout-testing.md +78 -0
  83. package/docs/external/research-results.md +48 -0
  84. package/docs/external/security-auth-permissions.md +81 -0
  85. package/docs/external/sync-state-machines.md +108 -0
  86. package/docs/external/unified-external-backend-model.md +107 -0
  87. package/docs/external/user-facing-changes.md +67 -0
  88. package/docs/gaps.md +161 -0
  89. package/docs/install.md +94 -0
  90. package/docs/integration-and-design-decisions.md +1530 -0
  91. package/docs/kradle-design.md +334 -0
  92. package/docs/local-minikube.md +55 -0
  93. package/docs/ontology/README.md +32 -0
  94. package/docs/ontology/bounded-contexts.md +29 -0
  95. package/docs/ontology/events-and-hooks.md +32 -0
  96. package/docs/ontology/oam-kubevela.md +32 -0
  97. package/docs/ontology/operations-and-release.md +25 -0
  98. package/docs/ontology/personas-and-actors.md +32 -0
  99. package/docs/ontology/policies-and-invariants.md +33 -0
  100. package/docs/ontology/problem-space.md +30 -0
  101. package/docs/ontology/resource-contracts.md +40 -0
  102. package/docs/ontology/resource-taxonomy.md +42 -0
  103. package/docs/ontology/runners-and-ci.md +29 -0
  104. package/docs/ontology/solution-space.md +24 -0
  105. package/docs/ontology/storage-and-data-boundaries.md +29 -0
  106. package/docs/ontology/validation-matrix.md +24 -0
  107. package/docs/ontology/web-ui-excellent-flows.md +32 -0
  108. package/docs/ontology/workflows.md +39 -0
  109. package/docs/ontology/world.md +35 -0
  110. package/docs/openapi.yaml +1291 -0
  111. package/docs/product-requirements.md +62 -0
  112. package/docs/requirements-v2.md +235 -0
  113. package/docs/roadmap-mvp.md +87 -0
  114. package/docs/sdk-api-reference.md +1108 -0
  115. package/docs/system-requirements.md +90 -0
  116. package/docs/system-spec-v2.md +1230 -0
  117. package/docs/tests/README.md +53 -0
  118. package/docs/tests/agent-qa-plan.md +63 -0
  119. package/docs/tests/browser-ui-tests.md +62 -0
  120. package/docs/tests/ci-quality-gates.md +48 -0
  121. package/docs/tests/coverage-model.md +64 -0
  122. package/docs/tests/e2e-scenario-tests.md +53 -0
  123. package/docs/tests/fixtures-test-data.md +63 -0
  124. package/docs/tests/observability-reliability-tests.md +54 -0
  125. package/docs/tests/product-test-matrix.md +145 -0
  126. package/docs/tests/qa-adoption-roadmap.md +130 -0
  127. package/docs/tests/qa-automation-plan.md +101 -0
  128. package/docs/tests/security-compliance-tests.md +57 -0
  129. package/docs/tests/test-framework-tools.md +88 -0
  130. package/docs/tests/test-suite-layout.md +121 -0
  131. package/docs/tests/unit-integration-tests.md +48 -0
  132. package/docs/todo-kyverno +714 -0
  133. package/docs/todos.md +4 -0
  134. package/docs/user-stories.md +78 -0
  135. package/docs/web-console-spec.md +533 -0
  136. package/examples/minikube-demo.yaml +190 -0
  137. package/examples/oam-application.yaml +23 -0
  138. package/examples/policy-kyverno-pr-title.yaml +18 -0
  139. package/package.json +66 -0
  140. package/scripts/build.mjs +29 -0
  141. package/scripts/setup-minikube.mjs +65 -0
  142. package/scripts/smoke.mjs +37 -0
  143. package/scripts/validate-doc-coverage.mjs +152 -0
  144. package/scripts/validate-package.mjs +95 -0
  145. package/scripts/validate-ui.mjs +305 -0
  146. package/src/agent-adapter-controller.js +169 -0
  147. package/src/agent-approval-controller.js +170 -0
  148. package/src/agent-context-bundles.js +242 -0
  149. package/src/agent-dispatch-controller.js +549 -0
  150. package/src/agent-gateway-config-controller.js +147 -0
  151. package/src/agent-identity-migration.js +115 -0
  152. package/src/agent-memory-controller.js +357 -0
  153. package/src/agent-memory-import.js +327 -0
  154. package/src/agent-memory-query.js +292 -0
  155. package/src/agent-memory-repository-source-controller.js +255 -0
  156. package/src/agent-mux-client.js +589 -0
  157. package/src/agent-permission-review.js +250 -0
  158. package/src/agent-persona-controller.js +135 -0
  159. package/src/agent-project-controller.js +117 -0
  160. package/src/agent-prompt-composition.js +55 -0
  161. package/src/agent-provider-config-controller.js +151 -0
  162. package/src/agent-secret-config-grant-controller.js +282 -0
  163. package/src/agent-session-transcript-controller.js +189 -0
  164. package/src/agent-stack-controller.js +421 -0
  165. package/src/agent-subagent-controller.js +160 -0
  166. package/src/agent-transport-binding-controller.js +121 -0
  167. package/src/agent-trigger-controller.js +387 -0
  168. package/src/agent-workspace-controller.js +702 -0
  169. package/src/agent-writeback-controller.js +302 -0
  170. package/src/api-controller.js +621 -0
  171. package/src/argocd-gitops.js +43 -0
  172. package/src/artifact-registry-controller.js +542 -0
  173. package/src/assistant-runtime.js +284 -0
  174. package/src/async-controller.js +207 -0
  175. package/src/audit-controller.js +191 -0
  176. package/src/auth.js +310 -0
  177. package/src/component-catalog.js +41 -0
  178. package/src/control-plane.js +136 -0
  179. package/src/controller-client.js +112 -0
  180. package/src/controller-ui.js +620 -0
  181. package/src/data-plane.js +179 -0
  182. package/src/event-bus.js +397 -0
  183. package/src/external/conflict-controller.js +225 -0
  184. package/src/external/github/auth.js +96 -0
  185. package/src/external/github/cicd.js +180 -0
  186. package/src/external/github/git-forge.js +240 -0
  187. package/src/external/github/index.js +144 -0
  188. package/src/external/github/issue-tracking.js +163 -0
  189. package/src/external/provider-adapter.js +161 -0
  190. package/src/external/provider-resource-factory.js +221 -0
  191. package/src/external/sync-controller.js +235 -0
  192. package/src/external/webhook-controller.js +144 -0
  193. package/src/external/write-controller.js +283 -0
  194. package/src/gitea-backend.js +131 -0
  195. package/src/gitea-service.js +173 -0
  196. package/src/handoff.js +98 -0
  197. package/src/health-probes.js +134 -0
  198. package/src/hooks-events.js +63 -0
  199. package/src/hooks-lifecycle.js +117 -0
  200. package/src/http-server.js +409 -0
  201. package/src/identity-policy.js +86 -0
  202. package/src/index.js +71 -0
  203. package/src/jitsi-agent-bridge.js +141 -0
  204. package/src/jitsi-meeting-controller.js +291 -0
  205. package/src/jitsi-sync-controller.js +198 -0
  206. package/src/kradle-inference-service-controller.js +246 -0
  207. package/src/kubernetes-controller-async.js +531 -0
  208. package/src/kubernetes-controller.js +904 -0
  209. package/src/kubernetes-resource-gateway.js +48 -0
  210. package/src/model-route-controller.js +364 -0
  211. package/src/notification-controller.js +178 -0
  212. package/src/operations.js +112 -0
  213. package/src/org-scoping.js +5 -0
  214. package/src/resource-model.js +282 -0
  215. package/src/runner-controller.js +272 -0
  216. package/src/runners-ci.js +48 -0
  217. package/src/runtime.js +196 -0
  218. package/src/snapshot-cache.js +157 -0
  219. package/src/virtual-model-controller.js +538 -0
  220. package/src/virtual-model-hook-bridge.js +200 -0
  221. package/src/web-ui.js +40 -0
  222. package/tests/agent-adapter-controller.test.js +361 -0
  223. package/tests/agent-approval-controller.test.js +173 -0
  224. package/tests/agent-context-bundles.test.js +278 -0
  225. package/tests/agent-dispatch-controller.test.js +679 -0
  226. package/tests/agent-gateway-config-controller.test.js +386 -0
  227. package/tests/agent-identity-migration.test.js +87 -0
  228. package/tests/agent-memory-controller.test.js +461 -0
  229. package/tests/agent-memory-import-snapshot.test.js +477 -0
  230. package/tests/agent-memory-query.test.js +404 -0
  231. package/tests/agent-memory-repository-source.test.js +514 -0
  232. package/tests/agent-mux-client.test.js +389 -0
  233. package/tests/agent-mux-integration.test.js +971 -0
  234. package/tests/agent-permission-review-v2.test.js +317 -0
  235. package/tests/agent-permission-review.test.js +209 -0
  236. package/tests/agent-persona-controller.test.js +127 -0
  237. package/tests/agent-project-controller.test.js +302 -0
  238. package/tests/agent-prompt-composition.test.js +76 -0
  239. package/tests/agent-provider-config-controller.test.js +376 -0
  240. package/tests/agent-resources.test.js +303 -0
  241. package/tests/agent-secret-config-grant.test.js +231 -0
  242. package/tests/agent-session-transcript-controller.test.js +499 -0
  243. package/tests/agent-stack-controller.test.js +283 -0
  244. package/tests/agent-subagent-controller.test.js +201 -0
  245. package/tests/agent-transport-binding-controller.test.js +294 -0
  246. package/tests/agent-trigger-controller.test.js +271 -0
  247. package/tests/agent-trigger-routes.test.js +190 -0
  248. package/tests/agent-trigger-sources.test.js +245 -0
  249. package/tests/agent-workspace-controller.test.js +181 -0
  250. package/tests/agent-writeback.test.js +292 -0
  251. package/tests/approval-persistence.test.js +171 -0
  252. package/tests/artifact-registry.test.js +511 -0
  253. package/tests/assistant-runtime.test.js +506 -0
  254. package/tests/async-controller.test.js +252 -0
  255. package/tests/audit-controller.test.js +227 -0
  256. package/tests/codespace-controller.test.js +318 -0
  257. package/tests/controller-client.test.js +133 -0
  258. package/tests/deployment.test.js +527 -0
  259. package/tests/e2e/lifecycle.test.js +120 -0
  260. package/tests/event-bus-integration.test.js +355 -0
  261. package/tests/external-github-forge.test.js +560 -0
  262. package/tests/external-github-issues-cicd.test.js +520 -0
  263. package/tests/external-integration.test.js +470 -0
  264. package/tests/external-persistence.test.js +415 -0
  265. package/tests/external-provider-adapter.test.js +365 -0
  266. package/tests/external-resource-model.test.js +223 -0
  267. package/tests/external-webhook-sync.test.js +287 -0
  268. package/tests/external-write-conflict.test.js +353 -0
  269. package/tests/gitea-service.test.js +253 -0
  270. package/tests/health-check-real.test.js +165 -0
  271. package/tests/health-probes.test.js +90 -0
  272. package/tests/hooks-lifecycle.test.js +364 -0
  273. package/tests/integration/full-flow.test.js +266 -0
  274. package/tests/jitsi-agent-bridge.test.js +119 -0
  275. package/tests/jitsi-helm-integration.test.js +77 -0
  276. package/tests/jitsi-meeting-controller.test.js +170 -0
  277. package/tests/jitsi-resource-model.test.js +73 -0
  278. package/tests/jitsi-sync-controller.test.js +112 -0
  279. package/tests/kradle-inference-service.test.js +689 -0
  280. package/tests/kradle.test.js +779 -0
  281. package/tests/memory-search-wiring.test.js +270 -0
  282. package/tests/model-route-controller.test.js +733 -0
  283. package/tests/notification-controller.test.js +196 -0
  284. package/tests/notification-integration.test.js +179 -0
  285. package/tests/org-scoping.test.js +687 -0
  286. package/tests/runner-controller.test.js +327 -0
  287. package/tests/runner-integration.test.js +231 -0
  288. package/tests/session-cookie-hmac.test.js +151 -0
  289. package/tests/snapshot-performance.test.js +315 -0
  290. package/tests/sse-events.test.js +107 -0
  291. package/tests/virtual-model-controller.test.js +877 -0
  292. package/tests/virtual-model-hook-bridge.test.js +384 -0
  293. package/tests/webhook-trigger.test.js +198 -0
  294. package/tests/workspace-volumes.test.js +312 -0
  295. package/tests/writeback-persistence.test.js +207 -0
@@ -0,0 +1,1230 @@
1
+ # Kradle System Specification v2
2
+
3
+ > Exhaustive system specification derived from implementation source code.
4
+ > Source: `packages/kradle/core/src/resource-model.js`, `http-server.js`, controller files.
5
+
6
+ ---
7
+
8
+ ## 1. Resource Taxonomy
9
+
10
+ All 83 resource kinds from `RESOURCE_DEFINITIONS` in `packages/kradle/core/src/resource-model.js`.
11
+ Every resource follows the Kubernetes object model:
12
+
13
+ ```javascript
14
+ {
15
+ apiVersion: 'kradle.a5c.ai/v1alpha1',
16
+ kind: '<ResourceKind>',
17
+ metadata: {
18
+ name: '<unique-name>', // Required: validated by validateResource()
19
+ namespace: '<kradle-org-slug>', // Defaults to 'default' if not provided
20
+ labels: { 'kradle.a5c.ai/org': '<org>' },
21
+ annotations: {}
22
+ },
23
+ spec: { /* kind-specific; requiredSpec fields validated */ },
24
+ status: { /* storage, phase, conditions */ }
25
+ }
26
+ ```
27
+
28
+ ### 1.1 CONFIG Kinds (etcd storage — 44 kinds)
29
+
30
+ #### Identity Context (11 kinds)
31
+
32
+ | # | Kind | Plural | Required Spec Fields | Purpose |
33
+ |---|------|--------|---------------------|---------|
34
+ | 1 | Organization | organizations | `displayName`, `namespaceName` | Kradle organization identity in the platform namespace with a bound tenant namespace |
35
+ | 2 | OrgNamespaceBinding | orgnamespacebindings | `organizationRef`, `namespace` | Binding from one organization to exactly one tenant namespace for resources and side effects |
36
+ | 3 | User | users | `organizationRef`, `displayName`, `email` | Human account profile, sign-in state, admin flag, and linked identities |
37
+ | 4 | Team | teams | `organizationRef`, `displayName` | Team membership, maintainers, and repository permission grants |
38
+ | 5 | Invite | invites | `organizationRef`, `email`, `role` | Pending user invitation with requested teams and expiry |
39
+ | 6 | IdentityMapping | identitymappings | `organizationRef`, `user`, `provider`, `subject` | Mapping between Kradle users, sign-in subjects, workspace identities, and repository accounts |
40
+ | 7 | AuthProvider | authproviders | `organizationRef`, `type` | Installation sign-in provider visibility and delegated identity settings |
41
+ | 8 | AgentServiceAccount | agentserviceaccounts | `organizationRef`, `namespace`, `serviceAccountName` | Kubernetes ServiceAccount wrapper for agent/runner identity binding |
42
+ | 9 | AgentRoleBinding | agentrolebindings | `organizationRef`, `subject`, `roleRef`, `scope` | Managed projection to native Kubernetes RBAC for agent identity |
43
+ | 10 | AgentSecretGrant | agentsecretgrants | `organizationRef`, `subject`, `secretRef`, `purpose` | Explicit permission for subject to access Secret keys with purpose scope |
44
+ | 11 | AgentConfigGrant | agentconfiggrants | `organizationRef`, `subject`, `configMapRef`, `purpose` | Explicit permission for subject to access ConfigMap keys with purpose scope |
45
+
46
+ #### Data-Plane Context (4 kinds)
47
+
48
+ | # | Kind | Plural | Required Spec Fields | Purpose |
49
+ |---|------|--------|---------------------|---------|
50
+ | 12 | Repository | repositories | `organizationRef`, `visibility` | Repository identity, visibility, repository hosting integration, object storage, and search settings |
51
+ | 13 | SSHKey | sshkeys | `organizationRef`, `scope`, `key` | User, deploy, and automation SSH keys reconciled into repository key APIs |
52
+ | 14 | RepositoryPermission | repositorypermissions | `organizationRef`, `repository`, `subject`, `permission` | Repository collaborators and teams synced with repository permissions |
53
+ | 15 | RefPolicy | refpolicies | `organizationRef` | Reference deny rules, force-push policy, signing policy, and future custom hook gates |
54
+
55
+ #### Control-Plane Context (1 kind)
56
+
57
+ | # | Kind | Plural | Required Spec Fields | Purpose |
58
+ |---|------|--------|---------------------|---------|
59
+ | 16 | BranchProtection | branchprotections | `organizationRef`, `refs` | Protected ref rules such as pull-request requirements |
60
+
61
+ #### Policy Context (4 kinds)
62
+
63
+ | # | Kind | Plural | Required Spec Fields | Purpose |
64
+ |---|------|--------|---------------------|---------|
65
+ | 17 | PolicyProfile | policyprofiles | `organizationRef`, `displayName`, `mode` | Organization policy posture, default templates, rollout mode, and exception approval rules |
66
+ | 18 | PolicyTemplate | policytemplates | `displayName`, `targetKinds`, `kyverno` | Curated Kyverno policy template metadata, parameters, rollout defaults, and remediation guidance |
67
+ | 19 | PolicyBinding | policybindings | `organizationRef`, `templateRef`, `mode` | Binding from a policy template to org/repo/env with audit/enforce rollout state |
68
+ | 20 | PolicyExceptionRequest | policyexceptionrequests | `organizationRef`, `policyRef`, `justification`, `expiresAt` | Auditable request and approval workflow for temporary Kyverno PolicyException resources |
69
+
70
+ #### Hooks-Events Context (1 kind)
71
+
72
+ | # | Kind | Plural | Required Spec Fields | Purpose |
73
+ |---|------|--------|---------------------|---------|
74
+ | 21 | WebhookSubscription | webhooksubscriptions | `organizationRef`, `url`, `events` | Endpoint, event filters, signing reference, delivery mode, and retry policy |
75
+
76
+ #### Runners-CI Context (1 kind)
77
+
78
+ | # | Kind | Plural | Required Spec Fields | Purpose |
79
+ |---|------|--------|---------------------|---------|
80
+ | 22 | RunnerPool | runnerpools | `organizationRef`, `warmReplicas`, `maxReplicas` | Runner capacity, warm/max replicas, cache policy, and trust boundary |
81
+
82
+ #### Web-UI Context (2 kinds)
83
+
84
+ | # | Kind | Plural | Required Spec Fields | Purpose |
85
+ |---|------|--------|---------------------|---------|
86
+ | 23 | View | views | `organizationRef`, `selector` | Saved triage and dashboard view backed by resource selectors |
87
+ | 24 | Selector | selectors | `organizationRef` | Reusable label/query selector for workflows and views |
88
+
89
+ #### Agents Context (18 kinds)
90
+
91
+ | # | Kind | Plural | Required Spec Fields | Purpose |
92
+ |---|------|--------|---------------------|---------|
93
+ | 25 | AgentStack | agentstacks | `organizationRef`, `baseAgent`, `adapter`, `runtimeIdentity` | Reusable agent definition with model, prompt, tools, MCP servers, skills, subagents, approval mode, and runner policy |
94
+ | 26 | AgentSubagent | agentsubagents | `organizationRef`, `rolePrompt`, `taskKinds` | Named child-agent definition with role, task kinds, tool subset, and workspace scope |
95
+ | 27 | AgentToolProfile | agenttoolprofiles | `organizationRef`, `filesystemPolicy`, `approvalPolicyByTool` | Native tool policy for filesystem, network, shell, and approval gates |
96
+ | 28 | AgentMcpServer | agentmcpservers | `organizationRef`, `transport`, `scope` | Managed MCP endpoint with transport, discovery, health, and secret/config refs |
97
+ | 29 | AgentSkill | agentskills | `organizationRef`, `format`, `sourceRef` | Reusable runbook/procedure bundle with prompt fragments, tool deps, and output contracts |
98
+ | 30 | AgentTriggerRule | agenttriggerrules | `organizationRef`, `sources`, `agentStack`, `taskKind` | Event-to-stack routing for CI failures, webhooks, comments, labels, schedules, and manual dispatch |
99
+ | 31 | AgentContextLabel | agentcontextlabels | `organizationRef`, `promptFragment`, `allowedSources` | Reviewed prompt fragment with provenance and allowlisted sources |
100
+ | 32 | KradleWorkspacePolicy | kradleworkspacepolicies | `organizationRef`, `mode`, `retentionPolicy` | Git worktree provisioning, cleanup, retention, and trust tier policies |
101
+ | 33 | AgentAdapter | agentadapters | `organizationRef`, `adapterType`, `transport` | Agent adapter definition with transport type, capabilities matrix, auth requirements, and installation method |
102
+ | 34 | AgentTransportBinding | agenttransportbindings | `organizationRef`, `adapterRef`, `endpoint`, `protocol` | Connection configuration for an adapter instance with endpoint, protocol, auth, health check, and reconnect policy |
103
+ | 35 | AgentProviderConfig | agentproviderconfigs | `organizationRef`, `provider`, `authType` | Model provider configuration with API base, auth type, default model, model translations, and rate limits |
104
+ | 36 | KradleProject | kradleprojects | `organizationRef`, `displayName` | Org project grouping issues, linked repositories, kanban board config, default workflow, and backend sync refs |
105
+ | 37 | AgentGatewayConfig | agentgatewayconfigs | `organizationRef`, `gatewayUrl` | Runtime Agent Mux gateway connection settings with URL, auth, reconnect policy, and feature flags |
106
+ | 38 | AgentMemoryRepository | agentmemoryrepositories | `organizationRef`, `repositoryRef`, `defaultBranch`, `layoutProfile` | Org-level Git repository pointer for shared agent memory with layout profile and index policy |
107
+ | 39 | AgentMemorySource | agentmemorysources | `organizationRef`, `repositoryRef`, `appliesTo`, `include` | Read policy for memory paths and kinds per repository, team, stack, or trigger |
108
+ | 40 | AgentMemoryOntology | agentmemoryontologies | `organizationRef`, `memoryRepository`, `ontologyPath` | Ontology policy pointer with required fields, edge kinds, and controlled vocabulary |
109
+ | 41 | AgentMemoryAssociation | agentmemoryassociations | `organizationRef`, `memoryRef`, `targetRef`, `relationship` | Bridge record linking memory content to Kradle resources by relationship type |
110
+
111
+ #### Workspaces Context (1 kind)
112
+
113
+ | # | Kind | Plural | Required Spec Fields | Purpose |
114
+ |---|------|--------|---------------------|---------|
115
+ | 42 | KradleWorkspace | kradleworkspaces | `organizationRef`, `repository`, `volumeSpec` | Volume-backed git workspace with PVC lifecycle, repo binding, and runner mount spec |
116
+
117
+ #### External-Backends Context (4 kinds)
118
+
119
+ | # | Kind | Plural | Required Spec Fields | Purpose |
120
+ |---|------|--------|---------------------|---------|
121
+ | 43 | ExternalBackendProvider | externalbackendproviders | `organizationRef`, `providerType`, `endpoint` | External backend provider registration with type, endpoint, auth configuration, and capability discovery settings |
122
+ | 44 | ExternalBackendBinding | externalbackendbindings | `organizationRef`, `providerRef`, `credentialRef` | Binding of an external backend provider to an organization with credential reference and sync scope |
123
+ | 45 | ExternalBackendSyncPolicy | externalbackendsyncpolicies | `organizationRef`, `providerRef`, `syncInterval` | Sync interval, conflict resolution mode, field mapping overrides, and retry policy for an external backend provider |
124
+ | 46 | ExternalProviderCapabilityManifest | externalprovidercapabilitymanifests | `organizationRef`, `providerRef`, `capabilities` | Discovered capability surface of an external backend provider including supported resource kinds and API features |
125
+
126
+ ### 1.2 AGGREGATED Kinds (postgres storage — 32 kinds)
127
+
128
+ #### Control-Plane Context (3 kinds)
129
+
130
+ | # | Kind | Plural | Required Spec Fields | Purpose |
131
+ |---|------|--------|---------------------|---------|
132
+ | 47 | PullRequest | pullrequests | `organizationRef`, `repository`, `title` | Review unit with source/target refs, title, checks, and merge lifecycle |
133
+ | 48 | Issue | issues | `organizationRef`, `title` | Project-scoped work item with labels, comments, backend sync metadata, and zero-or-more repository associations |
134
+ | 49 | Review | reviews | `organizationRef`, `pullRequest` | Approval, comment, or change-request record for a pull request |
135
+
136
+ #### Runners-CI Context (2 kinds)
137
+
138
+ | # | Kind | Plural | Required Spec Fields | Purpose |
139
+ |---|------|--------|---------------------|---------|
140
+ | 50 | Pipeline | pipelines | `organizationRef`, `repository`, `ref` | CI pipeline run state, trust tier, steps, and resume point |
141
+ | 51 | Job | jobs | `organizationRef`, `pipeline`, `step` | Executable CI step with service-account scope and isolation metadata |
142
+
143
+ #### Hooks-Events Context (1 kind)
144
+
145
+ | # | Kind | Plural | Required Spec Fields | Purpose |
146
+ |---|------|--------|---------------------|---------|
147
+ | 52 | WebhookDelivery | webhookdeliveries | `organizationRef`, `subscription`, `eventType`, `signature` | Durable outbound webhook delivery attempt with signature, phase, response, and replay metadata |
148
+
149
+ #### Agents Context (17 kinds)
150
+
151
+ | # | Kind | Plural | Required Spec Fields | Purpose |
152
+ |---|------|--------|---------------------|---------|
153
+ | 53 | AgentDispatchRun | agentdispatchruns | `organizationRef`, `repository`, `sourceRefs`, `agentStack`, `taskKind` | Logical CI-like run visible beside Pipeline/Job records with queue, status, workspace, and cost |
154
+ | 54 | AgentDispatchAttempt | agentdispatchattempts | `organizationRef`, `agentDispatchRun`, `attemptReason`, `agentStackSnapshot` | Concrete execution attempt with reason, stack snapshot, and runtime state |
155
+ | 55 | AgentSession | agentsessions | `organizationRef`, `agentMuxSessionId`, `dispatchRun` | Kradle projection of Agent Mux chat/session with lifecycle state |
156
+ | 56 | AgentContextBundle | agentcontextbundles | `organizationRef`, `dispatchRun`, `digest`, `sources` | Immutable prompt/context snapshot with digest, provenance, and redaction manifest |
157
+ | 57 | KradleArtifact | kradleartifacts | `organizationRef`, `dispatchRun`, `kind`, `digest` | Durable agent output with kind, digest, and retention policy |
158
+ | 58 | AgentApproval | agentapprovals | `organizationRef`, `dispatchRun`, `action`, `requestedBy` | Human gate for tools, secrets, write-back, and release actions |
159
+ | 59 | AgentTriggerExecution | agenttriggerexecutions | `organizationRef`, `triggerRule`, `sourceEvent`, `decision` | Durable trigger evaluation record with dedupe, coalescing, and rejection reason |
160
+ | 60 | AgentCapabilityRequirement | agentcapabilityrequirements | `organizationRef`, `ownerRef`, `requiredRoles` | Computed dependency record from tools, MCP, skills, models, and subagents |
161
+ | 61 | WorkItemSessionLink | workitemsessionlinks | `organizationRef`, `workItemRef`, `agentSession` | Association between issues/PRs and agent sessions |
162
+ | 62 | WorkItemWorkspaceLink | workitemworkspacelinks | `organizationRef`, `workItemRef`, `workspace` | Association between issues/PRs and agent workspaces |
163
+ | 63 | AgentSessionTranscript | agentsessiontranscripts | `organizationRef`, `sessionRef`, `messages` | Durable chat transcript with message nodes, pagination support, and cost per turn |
164
+ | 64 | AgentSessionAttachment | agentsessionattachments | `organizationRef`, `sessionRef`, `sourceType`, `digest` | File attached to a session message with source type, MIME type, digest, and redaction status |
165
+ | 65 | KradleWorkspaceRuntime | kradleworkspaceruntimes | `organizationRef`, `workspaceRef`, `status` | Workspace runtime surface state with cwd, environment variables, process status, and preview URL |
166
+ | 66 | AgentMemorySnapshot | agentmemorysnapshots | `organizationRef`, `memoryRepository`, `requestedRef`, `resolvedCommit` | Immutable dispatch-time memory pin with resolved commit, query manifest digest, and selected records digest |
167
+ | 67 | AgentMemoryQuery | agentmemoryqueries | `organizationRef`, `snapshotRef`, `requester`, `query` | Graph and grep retrieval record with query parameters, result digests, and ranking metadata |
168
+ | 68 | AgentMemoryUpdate | agentmemoryupdates | `organizationRef`, `memoryRepository`, `sourceRun`, `changes` | Reviewable proposed memory mutation with branch, changes, and validation status |
169
+ | 69 | AgentRunMemoryImport | agentrunmemoryimports | `organizationRef`, `memoryRepository`, `source`, `include` | Import curated babysitter run metadata into org company brain with redaction and review |
170
+
171
+ #### External-Backends Context (6 kinds)
172
+
173
+ | # | Kind | Plural | Required Spec Fields | Purpose |
174
+ |---|------|--------|---------------------|---------|
175
+ | 70 | ExternalWebhookDelivery | externalwebhookdeliveries | `organizationRef`, `providerRef`, `eventType`, `payload` | Inbound webhook delivery from an external backend provider with event type, payload, and processing state |
176
+ | 71 | ExternalSyncEvent | externalsyncevents | `organizationRef`, `providerRef`, `eventKind`, `resourceRef` | Discrete sync event record from an external backend for a specific resource kind with dedupe and ordering metadata |
177
+ | 72 | ExternalSyncState | externalsyncstates | `organizationRef`, `providerRef`, `resourceRef`, `phase` | Current sync phase, last successful sync timestamp, and error details for an external resource binding |
178
+ | 73 | ExternalWriteIntent | externalwriteintents | `organizationRef`, `providerRef`, `resourceRef`, `operation` | Queued write-back intent to an external backend with operation, payload snapshot, and approval state |
179
+ | 74 | ExternalSyncConflict | externalsyncconflicts | `organizationRef`, `providerRef`, `resourceRef`, `conflictKind` | Detected conflict between local and external state with conflict kind, diff, and resolution outcome |
180
+ | 75 | ExternalObjectLink | externalobjectlinks | `organizationRef`, `providerRef`, `externalId`, `localRef` | Stable mapping between a Kradle local resource and its external backend counterpart by external ID |
181
+
182
+ ---
183
+
184
+ ## 2. API Surface
185
+
186
+ Source: `packages/kradle/core/src/http-server.js`
187
+
188
+ ### 2.1 All HTTP Routes (40 routes)
189
+
190
+ | # | Method | Path | Auth | Request Body | Success | Error | Purpose |
191
+ |---|--------|------|------|-------------|---------|-------|---------|
192
+ | 1 | GET | `/healthz` | No | — | 200 `{ ok: true }` | — | Health check |
193
+ | 2 | GET | `/api/controller` | No | Query: `?org=` | 200 UI model | 400 | Full controller UI model |
194
+ | 3 | GET | `/api/orgs` | No | — | 200 `{ organizations }` | 400 | List organizations |
195
+ | 4 | POST | `/api/orgs` | Yes | `{ slug, displayName }` | 201 `{ organization, namespace, binding }` | 400 | Create organization |
196
+ | 5 | GET | `/api/orgs/:org/resources` | No | Query: `?kind=` | 200 `{ items }` | 400 | List resources by kind |
197
+ | 6 | POST | `/api/orgs/:org/resources` | Yes | Resource object | 201 `{ operation, resource }` | 400 | Apply resource |
198
+ | 7 | GET | `/api/orgs/:org/resources/:kind/:name` | No | — | 200 resource | 400 | Get single resource |
199
+ | 8 | DELETE | `/api/orgs/:org/resources/:kind/:name` | Yes | — | 200 result | 400 | Delete resource |
200
+ | 9 | GET | `/api/orgs/:org/repositories` | No | — | 200 `{ items }` | 400 | List repositories |
201
+ | 10 | POST | `/api/orgs/:org/repositories` | Yes | `{ name, visibility }` | 201 `{ repository }` | 400 | Create repository |
202
+ | 11 | GET | `/api/orgs/:org/repositories/:name` | No | — | 200 resource | 400 | Get repository |
203
+ | 12 | DELETE | `/api/orgs/:org/repositories/:name` | Yes | — | 200 result | 400 | Delete repository |
204
+ | 13 | GET | `/api/orgs/:org/snapshot` | No | — | 200 snapshot | 400 | Org runtime snapshot |
205
+ | 14 | POST | `/api/orgs/:org/snapshot` | Yes | Snapshot object | 200 result | 400 | Import snapshot |
206
+ | 15 | GET | `/api/orgs/:org/runtime-resources/:kind` | No | — | 200 items | 400 | List runtime resources |
207
+ | 16 | POST | `/api/orgs/:org/repositories/:repo/objects` | Yes | Object data | 201 result | 400 | Record git object |
208
+ | 17 | POST | `/api/orgs/:org/repositories/:repo/search-index` | Yes | Index request | 202 result | 400 | Enqueue search index |
209
+ | 18 | POST | `/api/orgs/:org/pullrequests` | Yes | PR data | 201 PR | 400 | Create pull request |
210
+ | 19 | POST | `/api/orgs/:org/pullrequests/:pr/reviews` | Yes | Review data | 201 review | 400 | Add review |
211
+ | 20 | POST | `/api/orgs/:org/pullrequests/:pr/checks/complete` | Yes | Pipeline data | 200 result | 400 | Complete pipeline check |
212
+ | 21 | POST | `/api/orgs/:org/pullrequests/:pr/merge` | Yes | Merge options | 200 result | 400 | Merge pull request |
213
+ | 22 | POST | `/api/orgs/:org/agents/approvals/:name/decide` | Yes | `{ decision, decidedBy, reason }` | 200 result | 400 | Approve/deny agent action |
214
+ | 23 | POST | `/api/orgs/:org/agents/webhooks/ingest` | Yes | Webhook payload | 200 result | 400 | Ingest webhook event |
215
+ | 24 | POST | `/api/orgs/:org/agents/events/pipeline-failure` | Yes | `{ name, repository, ref }` | 200 result | 400 | Pipeline failure event |
216
+ | 25 | POST | `/api/orgs/:org/agents/events/comment` | Yes | `{ kind, name, body }` | 200 result | 400 | Comment event |
217
+ | 26 | POST | `/api/orgs/:org/agents/events/label` | Yes | `{ kind, name, label }` | 200 result | 400 | Label event |
218
+ | 27 | POST | `/api/orgs/:org/agents/triggers/process` | Yes | Event + options | 200 result | 400 | Process trigger |
219
+ | 28 | POST | `/api/orgs/:org/agents/memory/query` | Yes | `{ query, mode, kinds }` | 200 results | 400 | Query agent memory |
220
+ | 29 | GET | `/api/orgs/:org/secrets` | No | — | 200 `{ secrets }` | 400 | List secrets |
221
+ | 30 | POST | `/api/orgs/:org/secrets` | Yes | `{ name, data }` | 201 result | 400 | Create secret |
222
+ | 31 | DELETE | `/api/orgs/:org/secrets/:name` | Yes | — | 200 result | 400 | Delete secret |
223
+ | 32 | GET | `/api/orgs/:org/secret-grants` | No | — | 200 grants | 400 | List secret grants |
224
+ | 33 | POST | `/api/orgs/:org/secret-grants` | Yes | Grant data | 201 grant | 400 | Create secret grant |
225
+ | 34 | POST | `/api/orgs/:org/external/sync` | Yes | `{ bindingName, kind, localName, spec, externalEnvelope }` | 200 result | 400 | Trigger external sync |
226
+ | 35 | POST | `/api/orgs/:org/external/conflicts/:name/resolve` | Yes | `{ strategy, resolvedValue }` | 200 result | 400 | Resolve sync conflict |
227
+ | 36 | POST | `/api/orgs/:org/external/write-intents/:name/approve` | Yes | `{ approvedBy }` | 200 result | 400 | Approve write intent |
228
+ | 37 | POST | `/api/orgs/:org/external/write-intents/:name/cancel` | Yes | `{ cancelledBy }` | 200 result | 400 | Cancel write intent |
229
+ | 38 | GET | `/api/orgs/:org/agents/events/stream` | No | — | 200 SSE | — | SSE event stream |
230
+
231
+ ### 2.2 Route Pattern Matching
232
+
233
+ All routes use regex matching on `url.pathname`:
234
+ ```javascript
235
+ url.pathname.match(/^\/api\/orgs\/([^/]+)\/resources$/)
236
+ ```
237
+
238
+ Priority: routes are checked in order of declaration in `createKradleHttpHandler()`.
239
+
240
+ ### 2.3 SSE Protocol
241
+
242
+ ```
243
+ GET /api/orgs/:org/agents/events/stream HTTP/1.1
244
+
245
+ HTTP/1.1 200 OK
246
+ Content-Type: text/event-stream
247
+ Cache-Control: no-cache
248
+ Connection: keep-alive
249
+ X-Accel-Buffering: no
250
+
251
+ data: {"type":"connected"}
252
+
253
+ data: {"type":"heartbeat"}
254
+
255
+ data: {"type":"resource-change","kind":"Repository","name":"my-repo","operation":"apply","timestamp":"2025-01-01T00:00:00.000Z"}
256
+ ```
257
+
258
+ ---
259
+
260
+ ## 3. Controller Boundaries
261
+
262
+ ### 3.1 Complete Controller Inventory
263
+
264
+ | # | Controller | Source File | Lines | Methods |
265
+ |---|-----------|-------------|-------|---------|
266
+ | 1 | KubernetesResourceClient | `kubernetes-controller.js` | 883 | snapshot, listResource, getResource, applyResource, deleteResource, createRepository, createOrganization, watchResource |
267
+ | 2 | KradleKubernetesReconciler | `kubernetes-controller.js` | (shared) | describeReconciliationScope, reconcileRepository, reconcileIdentityAccess, reconcileIdentityAccessResources |
268
+ | 3 | KubernetesResourceGateway | `kubernetes-resource-gateway.js` | 48 | snapshot, list, get, apply, delete, createRepository, createOrganization, watch |
269
+ | 4 | KradleApiController | `api-controller.js` | 541 | snapshot, listResource, getResource, applyResource, deleteResource, createRepository, createOrganization, dispatchAgent, processWebhookEvent, queryAgentMemory, syncExternalBinding, resolveExternalConflict, + 10 more |
270
+ | 5 | AgentStackController | `agent-stack-controller.js` | 347 | reconcileStack, listStackCapabilities, checkMcpHealth |
271
+ | 6 | AgentDispatchController | `agent-dispatch-controller.js` | 209 | createManualDispatch |
272
+ | 7 | AgentWorkspaceController | `agent-workspace-controller.js` | 702 | createWorkspace, deleteWorkspace, getWorkspaceStatus, initializeWorkspace, checkoutBranch, syncWorkspace, getMountSpec, findReusableWorkspace, claimWorkspace, releaseWorkspace, provisionWorkspace, archiveWorkspace, recoverWorkspace, bindSession, linkWorkItem, linkWorkItemToSession, listWorkspacesForRepo, listWorkspacesForRun, launchCodespace, stopCodespace, getCodespaceStatus, addAssociation, removeAssociation, listAssociations, getWorkspaceRuns |
273
+ | 8 | AgentTriggerController | `agent-trigger-controller.js` | 381 | matchRule, evaluateEvent, createTriggerExecution, evaluateWebhookEvent, processEvent |
274
+ | 9 | AgentApprovalController | `agent-approval-controller.js` | 170 | createApprovalRequest, recordDecision, isActionApproved, listPendingApprovals, listApprovalsForRun, persistApproval, enforceApproval |
275
+ | 10 | AgentMemoryQuery | `agent-memory-query.js` | 293 | queryGraph, queryGrep, queryMemory |
276
+ | 11 | WebhookController | `external/webhook-controller.js` | 144 | verifyHmacSignature, createDeliveryRecord, recordDelivery, isDuplicate, onEvent, processDelivery |
277
+ | 12 | SyncController | `external/sync-controller.js` | 235 | normalizeEvent, upsertResource, updateWatermark, getWatermark, applyOwnershipMode, createTombstone, getTombstone |
278
+ | 13 | ConflictController | `external/conflict-controller.js` | 225 | detectConflict, resolveConflict, listOpenConflicts, supersede |
279
+ | 14 | WriteController | `external/write-controller.js` | 283 | createWriteIntent, approveWriteIntent, rejectWriteIntent, markSending, confirmSuccess, confirmFailure, listIntents |
280
+ | 15 | AuditController | `audit-controller.js` | ~180 | log, query, getStream, getMetrics |
281
+ | 16 | RunnerController | `runner-controller.js` | ~300 | validateRunnerPool, getPoolStatus, getCapacity, createRunner, assignJob, releaseRunner, generatePodSpec |
282
+ | 17 | NotificationController | `notification-controller.js` | 178 | createNotification, listNotifications, markAsRead, markAllAsRead, getUnreadCount, getPreferences, updatePreferences |
283
+ | 18 | PermissionReviewer | `agent-permission-review.js` | 250 | reviewPermissions, createPermissionSnapshot |
284
+
285
+ ### 3.2 Boundary Pattern
286
+
287
+ Every controller exports:
288
+ ```javascript
289
+ export const <NAME>_BOUNDARY = {
290
+ role: 'controller-name',
291
+ scope: 'What it does in one sentence',
292
+ owns: ['capability-1', 'capability-2'],
293
+ delegatesTo: ['other-controller-1'],
294
+ mustNotOwn: ['thing-it-must-not-do']
295
+ };
296
+ ```
297
+
298
+ ---
299
+
300
+ ## 4. Resource Validation Rules
301
+
302
+ Source: `packages/kradle/core/src/resource-model.js` — `validateResource()`
303
+
304
+ ### 4.1 Universal Validation
305
+
306
+ 1. `resource` must be a non-null object
307
+ 2. `resource.kind` must match a key in `RESOURCE_DEFINITIONS`
308
+ 3. `resource.metadata.name` is required (non-empty string)
309
+ 4. `resource.spec` and `resource.status` default to `{}` if missing
310
+ 5. `resource.metadata.namespace` defaults to `'default'`
311
+ 6. `resource.metadata.labels` and `annotations` default to `{}`
312
+ 7. Every field listed in `requiredSpec` must be non-null, non-undefined, non-empty-string
313
+
314
+ ### 4.2 Name Normalization
315
+
316
+ `normalizeName(value)`:
317
+ ```javascript
318
+ String(value).toLowerCase()
319
+ .replace(/[^a-z0-9-]+/g, '-')
320
+ .replace(/^-+|-+$/g, '')
321
+ .slice(0, 63) || 'user'
322
+ ```
323
+
324
+ ### 4.3 Org Slug Normalization
325
+
326
+ `normalizeOrgSlug(value)`:
327
+ ```javascript
328
+ String(value).trim().toLowerCase()
329
+ .replace(/[^a-z0-9-]+/g, '-')
330
+ .replace(/^-+|-+$/g, '')
331
+ .slice(0, 63)
332
+ ```
333
+
334
+ ---
335
+
336
+ ## 5. MCP Server Protocol
337
+
338
+ Source: `packages/kradle/cli/src/mcp-server.js`
339
+
340
+ ### 5.1 Tools (14)
341
+
342
+ | # | Tool | Inputs | Output |
343
+ |---|------|--------|--------|
344
+ | 1 | `kradle_list_resources` | `{ kind: string }` | Resource list |
345
+ | 2 | `kradle_get_resource` | `{ kind: string, name: string }` | Single resource |
346
+ | 3 | `kradle_apply_resource` | `{ resource: object }` | Apply result |
347
+ | 4 | `kradle_delete_resource` | `{ kind: string, name: string }` | Delete result |
348
+ | 5 | `kradle_snapshot` | `{}` | Full org snapshot |
349
+ | 6 | `kradle_search` | `{ query: string }` | Search results |
350
+ | 7 | `kradle_list_stacks` | `{}` | Agent stacks |
351
+ | 8 | `kradle_create_stack` | `{ name: string, org: string }` | Created stack |
352
+ | 9 | `kradle_dispatch_agent` | `{ stackRef: string }` | Dispatch result |
353
+ | 10 | `kradle_list_secrets` | `{ org?: string }` | Secret grants |
354
+ | 11 | `kradle_create_secret` | `{ name, org, agentRef, secretRef }` | Created grant |
355
+ | 12 | `kradle_sync_external` | `{ bindingName, kind, localName }` | Sync result |
356
+ | 13 | `kradle_resolve_conflict` | `{ conflictName, strategy }` | Resolution |
357
+ | 14 | `kradle_audit_query` | `{ org?, action?, since?, until?, limit?, offset? }` | Audit events |
358
+
359
+ ### 5.2 Prompts (3)
360
+
361
+ | Prompt | Description |
362
+ |--------|-------------|
363
+ | `kradle_workspace_setup` | Guide for setting up a new kradle workspace |
364
+ | `kradle_stack_config` | Help configuring an agent stack |
365
+ | `kradle_troubleshoot` | Diagnose common kradle issues |
366
+
367
+ ### 5.3 Resources (2)
368
+
369
+ | URI | MIME Type |
370
+ |-----|-----------|
371
+ | `kradle://snapshot` | application/json |
372
+ | `kradle://stacks` | application/json |
373
+
374
+ ---
375
+
376
+ ## 6. CLI Commands
377
+
378
+ Source: `packages/kradle/cli/src/index.js`
379
+
380
+ | Command | Description | Key Options |
381
+ |---------|-------------|-------------|
382
+ | `kradle serve` | Start HTTP API server | `--port 3080` |
383
+ | `kradle mcp` | Start MCP server over stdio | — |
384
+ | `kradle status` | Show workspace status | `--org`, `--json` |
385
+ | `kradle stacks` | List agent stacks | `--org`, `--json` |
386
+ | `kradle dispatch` | Dispatch an agent run | `--stack`, `--repo`, `--ref` |
387
+ | `kradle apply` | Apply resource from file | `--file`, `--org` |
388
+ | `kradle get` | Get resource by kind/name | `kind`, `name`, `--org` |
389
+ | `kradle list` | List resources by kind | `kind`, `--org`, `--json` |
390
+ | `kradle delete` | Delete resource | `kind`, `name`, `--org` |
391
+ | `kradle version` | Show CLI version | — |
392
+
393
+ ---
394
+
395
+ ## 7. Event System
396
+
397
+ ### 7.1 Event Bus API
398
+
399
+ ```javascript
400
+ const bus = createEventBus();
401
+ bus.subscribe(fn); // Add listener
402
+ bus.unsubscribe(fn); // Remove listener
403
+ bus.emit(event); // Broadcast
404
+ bus.emitResourceChange(kind, name, op); // Convenience
405
+ ```
406
+
407
+ ### 7.2 Event Types
408
+
409
+ | Type | Origin | Payload |
410
+ |------|--------|---------|
411
+ | `connected` | SSE endpoint | `{}` |
412
+ | `heartbeat` | SSE interval (30s) | `{}` |
413
+ | `resource-change` | applyResource/deleteResource | `{ kind, name, operation, timestamp }` |
414
+
415
+ ### 7.3 Notification Types
416
+
417
+ | Type | Trigger | Severity |
418
+ |------|---------|----------|
419
+ | `run-complete` | AgentDispatchRun phase change | info/error |
420
+ | `approval-needed` | AgentApproval created (pending) | warning |
421
+ | `conflict-detected` | ExternalSyncConflict created | warning |
422
+ | `workspace-ready` | KradleWorkspace claimed | info |
423
+ | `system` | Default/fallback | info |
424
+
425
+ ---
426
+
427
+ ## 8. Trigger Rule System
428
+
429
+ ### 8.1 Source Types
430
+
431
+ | Source Type | Detection Logic | Validation Function |
432
+ |-------------|----------------|-------------------|
433
+ | `cron` | `spec.cronExpression !== undefined` | `validateCronExpression(expr)` |
434
+ | `webhook` | `spec.webhookTrigger !== undefined` | `validateWebhookTrigger(config)` |
435
+ | `comment` | `spec.commentTrigger !== undefined` | `validateCommentTrigger(config)` |
436
+ | `label` | `spec.labelTrigger !== undefined` | `validateLabelTrigger(config)` |
437
+ | `event` | `spec.sources !== undefined` | Array.isArray + non-empty |
438
+
439
+ ### 8.2 Rule Matching Algorithm
440
+
441
+ For event-based rules (`matchRule()`):
442
+ 1. Event type must be in `rule.spec.sources[]`
443
+ 2. If `rule.spec.repository` set: must match `event.repository`
444
+ 3. If `rule.spec.allowedActors[]` non-empty: `event.actor` must be included
445
+
446
+ For webhook-based rules (`evaluateWebhookEvent()`):
447
+ 1. `rule.spec.enabled !== false`
448
+ 2. `rule.spec.webhookTrigger` must exist
449
+ 3. `webhookTrigger.events` includes event type (or `['*']` or absent)
450
+ 4. `webhookTrigger.repository` matches (if set)
451
+ 5. `webhookTrigger.action` matches (if set)
452
+
453
+ ### 8.3 Deduplication
454
+
455
+ Before dispatching, checks `AgentTriggerExecution` resources:
456
+ ```javascript
457
+ executions.some(ex =>
458
+ ex.spec?.triggerRule === rule.metadata?.name &&
459
+ ex.spec?.sourceEvent === eventUid &&
460
+ ex.status?.phase !== 'Failed'
461
+ )
462
+ ```
463
+
464
+ Event UID format: `${event.type}:${event.source.kind}:${event.source.name}`
465
+
466
+ ---
467
+
468
+ ## 9. Approval System
469
+
470
+ ### 9.1 Valid Actions
471
+
472
+ ```javascript
473
+ const VALID_ACTIONS = new Set(['tool-use', 'secret-access', 'write-back', 'release', 'escalation']);
474
+ ```
475
+
476
+ ### 9.2 Approval Phases
477
+
478
+ ```
479
+ (none) → Pending → Approved
480
+ → Denied
481
+ ```
482
+
483
+ ### 9.3 Duplicate Detection
484
+
485
+ Before creating a new approval, checks for existing:
486
+ ```javascript
487
+ resources.AgentApproval.find(a =>
488
+ a.spec?.dispatchRun === dispatchRun &&
489
+ a.spec?.action === action &&
490
+ (!a.status?.phase || a.status.phase === 'Pending')
491
+ )
492
+ ```
493
+
494
+ ---
495
+
496
+ ## 10. Stack Readiness Conditions
497
+
498
+ Source: `agent-stack-controller.js` — `reconcileStack()`
499
+
500
+ | Condition Type | True When | False When |
501
+ |---------------|-----------|------------|
502
+ | `CapabilitiesResolved` | All referenced resources exist | Any missing ref |
503
+ | `ToolsAdmitted` | AgentToolProfile found (or no ref) | Referenced profile missing |
504
+ | `McpHealthy` | All AgentMcpServer resources exist | Any missing MCP server |
505
+ | `SkillsValidated` | All skills exist with valid format+sourceRef | Missing or invalid skills |
506
+ | `SubagentsValid` | All subagents exist with non-empty taskKinds | Missing or invalid subagents |
507
+ | `ContextLabelsValid` | All context labels exist | Any missing label |
508
+ | `RuntimeIdentityReady` | AgentServiceAccount found | SA not found |
509
+ | `RolesAdmitted` | No role binding errors in permission review | Missing AgentRoleBinding |
510
+ | `SecretsAdmitted` | No secret grant errors | Missing AgentSecretGrant |
511
+ | `ConfigAdmitted` | No config grant errors | Missing AgentConfigGrant |
512
+ | `Ready` | ALL above conditions are True | ANY condition is False |
513
+
514
+ ---
515
+
516
+ ## 11. External Conflict Resolution
517
+
518
+ ### 11.1 Valid Strategies
519
+
520
+ ```javascript
521
+ const VALID_STRATEGIES = ['prefer-external', 'prefer-kradle', 'manual', 'ignore'];
522
+ ```
523
+
524
+ ### 11.2 Conflict Lifecycle
525
+
526
+ ```
527
+ (detected) → Open → Resolved (with strategy + resolvedValue)
528
+ → Superseded (newer conflict replaces)
529
+ ```
530
+
531
+ ### 11.3 Write Intent Phases
532
+
533
+ ```javascript
534
+ const VALID_PHASES = ['PendingApproval', 'ReadyToSend', 'Sending', 'Retrying', 'Succeeded', 'Failed', 'Rejected'];
535
+ ```
536
+
537
+ Lifecycle:
538
+ ```
539
+ PendingApproval → ReadyToSend (approved) → Sending → Succeeded
540
+ → Retrying → Sending (retry)
541
+ → Failed
542
+ → Rejected (cancelled)
543
+ ```
544
+
545
+ ---
546
+
547
+ ## 12. Runner System
548
+
549
+ ### 12.1 Pool Validation Rules
550
+
551
+ - `spec.organizationRef`: required, non-empty string
552
+ - `spec.warmReplicas`: non-negative integer
553
+ - `spec.maxReplicas`: positive integer (>= 1)
554
+ - `warmReplicas <= maxReplicas`
555
+
556
+ ### 12.2 Runner Statuses
557
+
558
+ ```javascript
559
+ const RUNNER_STATUSES = new Set(['Idle', 'Running', 'Terminating']);
560
+ ```
561
+
562
+ ### 12.3 Pool Phases
563
+
564
+ | Phase | Condition |
565
+ |-------|-----------|
566
+ | `Empty` | No runners registered |
567
+ | `Active` | At least one runner is Running |
568
+ | `Idle` | All runners are Idle |
569
+
570
+ ### 12.4 Scaling States
571
+
572
+ | State | Condition |
573
+ |-------|-----------|
574
+ | `ScalingUp` | total < warmReplicas |
575
+ | `ScalingDown` | total > maxReplicas |
576
+ | `Stable` | warmReplicas <= total <= maxReplicas |
577
+
578
+ ---
579
+
580
+ ## 13. Audit System
581
+
582
+ ### 13.1 Event Structure
583
+
584
+ ```javascript
585
+ {
586
+ id: number, // Auto-incrementing sequence
587
+ org: string, // Required
588
+ actor: string, // Default: 'system'
589
+ action: string, // Required (e.g., 'apply', 'delete', 'dispatch')
590
+ resource: object, // Optional resource reference
591
+ timestamp: string // ISO 8601
592
+ }
593
+ ```
594
+
595
+ ### 13.2 Query Parameters
596
+
597
+ | Parameter | Type | Description |
598
+ |-----------|------|-------------|
599
+ | `org` | string | Filter by organization |
600
+ | `action` | string | Filter by action type |
601
+ | `since` | string (ISO) | Events after this time |
602
+ | `until` | string (ISO) | Events before this time |
603
+ | `limit` | number | Max results to return |
604
+ | `offset` | number | Skip first N results |
605
+
606
+ ---
607
+
608
+ ## 14. Resource Model Utility Functions
609
+
610
+ Source: `packages/kradle/core/src/resource-model.js`
611
+
612
+ | Function | Signature | Purpose |
613
+ |----------|-----------|---------|
614
+ | `listResourceDefinitions()` | `() → Array<{kind, storage, context, plural, purpose, requiredSpec}>` | List all 76 definitions |
615
+ | `resourceDefinitionForKind(kind)` | `(string) → definition` | Lookup by kind name |
616
+ | `resourceSchemaForKind(kind)` | `(string) → schema object` | Get schema with required fields |
617
+ | `storageClassForKind(kind)` | `(string) → 'etcd' | 'postgres'` | Get storage backend |
618
+ | `resourceKey(resource)` | `(object) → 'Kind/namespace/name'` | Unique resource key |
619
+ | `clone(value)` | `(any) → deep copy` | `JSON.parse(JSON.stringify(value))` |
620
+ | `createResource(kind, metadata, spec, status)` | `(string, object, object, object) → resource` | Create well-formed resource |
621
+ | `validateResource(resource)` | `(object) → resource (mutated)` | Validate and normalize |
622
+ | `toKubernetesList(kind, items)` | `(string, Array) → { apiVersion, kind, items }` | Wrap as K8s list |
623
+ | `matchLabels(resource, selector)` | `(object, object) → boolean` | Label selector match |
624
+ | `createSelector(spec)` | `(object) → Selector resource` | Create Selector |
625
+ | `createView(spec)` | `(object) → View resource` | Create View |
626
+ | `resourceToYaml(resource)` | `(object) → string` | Serialize to YAML |
627
+
628
+ ---
629
+
630
+ ## 5. Complete KRADLE_RESOURCES Array
631
+
632
+ > Source: `packages/kradle/core/src/kubernetes-controller.js` — lines 31–111
633
+
634
+ Every entry in `KRADLE_RESOURCES` with all fields:
635
+
636
+ ```javascript
637
+ // ─── Platform-Scoped (listed from kradle-system only) ───
638
+ { kind: 'Organization', plural: 'organizations', namespaced: true, namespace: KRADLE_PLATFORM_NAMESPACE, storage: 'etcd', platformScoped: true }
639
+ { kind: 'OrgNamespaceBinding', plural: 'orgnamespacebindings', namespaced: true, namespace: KRADLE_PLATFORM_NAMESPACE, storage: 'etcd', platformScoped: true }
640
+
641
+ // ─── Identity & Access (etcd, org-scoped) ───
642
+ { kind: 'User', plural: 'users', namespaced: true, storage: 'etcd' }
643
+ { kind: 'Team', plural: 'teams', namespaced: true, storage: 'etcd' }
644
+ { kind: 'Invite', plural: 'invites', namespaced: true, storage: 'etcd' }
645
+ { kind: 'IdentityMapping', plural: 'identitymappings', namespaced: true, storage: 'etcd' }
646
+ { kind: 'AuthProvider', plural: 'authproviders', namespaced: true, storage: 'etcd' }
647
+
648
+ // ─── Data-Plane (etcd, org-scoped) ───
649
+ { kind: 'Repository', plural: 'repositories', namespaced: true, storage: 'etcd' }
650
+ { kind: 'SSHKey', plural: 'sshkeys', namespaced: true, storage: 'etcd' }
651
+ { kind: 'RepositoryPermission', plural: 'repositorypermissions', namespaced: true, storage: 'etcd' }
652
+ { kind: 'BranchProtection', plural: 'branchprotections', namespaced: true, storage: 'etcd' }
653
+ { kind: 'RefPolicy', plural: 'refpolicies', namespaced: true, storage: 'etcd' }
654
+
655
+ // ─── Policy (etcd, org-scoped) ───
656
+ { kind: 'PolicyProfile', plural: 'policyprofiles', namespaced: true, storage: 'etcd' }
657
+ { kind: 'PolicyTemplate', plural: 'policytemplates', namespaced: true, storage: 'etcd' }
658
+ { kind: 'PolicyBinding', plural: 'policybindings', namespaced: true, storage: 'etcd' }
659
+ { kind: 'PolicyExceptionRequest', plural: 'policyexceptionrequests', namespaced: true, storage: 'etcd' }
660
+
661
+ // ─── Hooks & CI (etcd/postgres) ───
662
+ { kind: 'WebhookSubscription', plural: 'webhooksubscriptions', namespaced: true, storage: 'etcd' }
663
+ { kind: 'RunnerPool', plural: 'runnerpools', namespaced: true, storage: 'etcd' }
664
+ { kind: 'PullRequest', plural: 'pullrequests', namespaced: true, storage: 'postgres' }
665
+ { kind: 'Issue', plural: 'issues', namespaced: true, storage: 'postgres' }
666
+ { kind: 'Review', plural: 'reviews', namespaced: true, storage: 'postgres' }
667
+ { kind: 'Pipeline', plural: 'pipelines', namespaced: true, storage: 'postgres' }
668
+ { kind: 'Job', plural: 'jobs', namespaced: true, storage: 'postgres' }
669
+ { kind: 'WebhookDelivery', plural: 'webhookdeliveries', namespaced: true, storage: 'postgres' }
670
+
671
+ // ─── KubeVela Delivery (kubevela storage) ───
672
+ { kind: 'KubeVelaApplication', plural: 'applications', group: 'core.oam.dev', namespaced: true, storage: 'kubevela' }
673
+ { kind: 'KubeVelaApplicationRevision', plural: 'applicationrevisions', group: 'core.oam.dev', namespaced: true, storage: 'kubevela' }
674
+ { kind: 'KubeVelaComponentDefinition', plural: 'componentdefinitions', group: 'core.oam.dev', namespaced: true, namespace: 'vela-system', storage: 'kubevela' }
675
+ { kind: 'KubeVelaWorkloadDefinition', plural: 'workloaddefinitions', group: 'core.oam.dev', namespaced: true, namespace: 'vela-system', storage: 'kubevela' }
676
+ { kind: 'KubeVelaTraitDefinition', plural: 'traitdefinitions', group: 'core.oam.dev', namespaced: true, namespace: 'vela-system', storage: 'kubevela' }
677
+ { kind: 'KubeVelaScopeDefinition', plural: 'scopedefinitions', group: 'core.oam.dev', namespaced: true, namespace: 'vela-system', storage: 'kubevela' }
678
+ { kind: 'KubeVelaPolicyDefinition', plural: 'policydefinitions', group: 'core.oam.dev', namespaced: true, namespace: 'vela-system', storage: 'kubevela' }
679
+ { kind: 'KubeVelaPolicy', plural: 'policies', group: 'core.oam.dev', namespaced: true, storage: 'kubevela' }
680
+ { kind: 'KubeVelaWorkflowStepDefinition', plural: 'workflowstepdefinitions', group: 'core.oam.dev', namespaced: true, namespace: 'vela-system', storage: 'kubevela' }
681
+ { kind: 'KubeVelaWorkflow', plural: 'workflows', group: 'core.oam.dev', namespaced: true, storage: 'kubevela' }
682
+ { kind: 'KubeVelaResourceTracker', plural: 'resourcetrackers', group: 'core.oam.dev', namespaced: false, storage: 'kubevela' }
683
+
684
+ // ─── Views & Selectors (etcd) ───
685
+ { kind: 'View', plural: 'views', namespaced: true, storage: 'etcd' }
686
+ { kind: 'Selector', plural: 'selectors', namespaced: true, storage: 'etcd' }
687
+
688
+ // ─── Agent Orchestration CRDs (etcd) ───
689
+ { kind: 'AgentStack', plural: 'agentstacks', namespaced: true, storage: 'etcd' }
690
+ { kind: 'AgentSubagent', plural: 'agentsubagents', namespaced: true, storage: 'etcd' }
691
+ { kind: 'AgentToolProfile', plural: 'agenttoolprofiles', namespaced: true, storage: 'etcd' }
692
+ { kind: 'AgentMcpServer', plural: 'agentmcpservers', namespaced: true, storage: 'etcd' }
693
+ { kind: 'AgentSkill', plural: 'agentskills', namespaced: true, storage: 'etcd' }
694
+ { kind: 'AgentTriggerRule', plural: 'agenttriggerrules', namespaced: true, storage: 'etcd' }
695
+ { kind: 'AgentContextLabel', plural: 'agentcontextlabels', namespaced: true, storage: 'etcd' }
696
+ { kind: 'KradleWorkspacePolicy', plural: 'kradleworkspacepolicies', namespaced: true, storage: 'etcd' }
697
+ { kind: 'AgentServiceAccount', plural: 'agentserviceaccounts', namespaced: true, storage: 'etcd' }
698
+ { kind: 'AgentRoleBinding', plural: 'agentrolebindings', namespaced: true, storage: 'etcd' }
699
+ { kind: 'AgentSecretGrant', plural: 'agentsecretgrants', namespaced: true, storage: 'etcd' }
700
+ { kind: 'AgentConfigGrant', plural: 'agentconfiggrants', namespaced: true, storage: 'etcd' }
701
+ { kind: 'AgentAdapter', plural: 'agentadapters', namespaced: true, storage: 'etcd' }
702
+ { kind: 'AgentTransportBinding', plural: 'agenttransportbindings', namespaced: true, storage: 'etcd' }
703
+ { kind: 'AgentProviderConfig', plural: 'agentproviderconfigs', namespaced: true, storage: 'etcd' }
704
+ { kind: 'KradleProject', plural: 'kradleprojects', namespaced: true, storage: 'etcd' }
705
+ { kind: 'AgentGatewayConfig', plural: 'agentgatewayconfigs', namespaced: true, storage: 'etcd' }
706
+ { kind: 'AgentMemoryRepository', plural: 'agentmemoryrepositories', namespaced: true, storage: 'etcd' }
707
+ { kind: 'AgentMemorySource', plural: 'agentmemorysources', namespaced: true, storage: 'etcd' }
708
+ { kind: 'AgentMemoryOntology', plural: 'agentmemoryontologies', namespaced: true, storage: 'etcd' }
709
+ { kind: 'AgentMemoryAssociation', plural: 'agentmemoryassociations', namespaced: true, storage: 'etcd' }
710
+
711
+ // ─── Agent Aggregated Resources (postgres) ───
712
+ { kind: 'AgentDispatchRun', plural: 'agentdispatchruns', namespaced: true, storage: 'postgres' }
713
+ { kind: 'AgentDispatchAttempt', plural: 'agentdispatchattempts', namespaced: true, storage: 'postgres' }
714
+ { kind: 'AgentSession', plural: 'agentsessions', namespaced: true, storage: 'postgres' }
715
+ { kind: 'AgentContextBundle', plural: 'agentcontextbundles', namespaced: true, storage: 'postgres' }
716
+ { kind: 'KradleArtifact', plural: 'kradleartifacts', namespaced: true, storage: 'postgres' }
717
+ { kind: 'AgentApproval', plural: 'agentapprovals', namespaced: true, storage: 'postgres' }
718
+ { kind: 'KradleWorkspace', plural: 'kradleworkspaces', namespaced: true, storage: 'postgres' }
719
+ { kind: 'AgentTriggerExecution', plural: 'agenttriggerexecutions', namespaced: true, storage: 'postgres' }
720
+ { kind: 'KradleWorkspaceRuntime', plural: 'kradleworkspaceruntimes', namespaced: true, storage: 'postgres' }
721
+ { kind: 'AgentSessionTranscript', plural: 'agentsessiontranscripts', namespaced: true, storage: 'postgres' }
722
+
723
+ // ─── External Backend (etcd) ───
724
+ { kind: 'ExternalBackendProvider', plural: 'externalbackendproviders', namespaced: true, storage: 'etcd' }
725
+ { kind: 'ExternalBackendBinding', plural: 'externalbackendbindings', namespaced: true, storage: 'etcd' }
726
+ { kind: 'ExternalBackendSyncPolicy', plural: 'externalbackendsyncpolicies', namespaced: true, storage: 'etcd' }
727
+
728
+ // ─── Core Kubernetes (excluded from snapshot — on-demand access only) ───
729
+ { kind: 'Secret', plural: 'secrets', group: '', namespaced: true, storage: 'core' }
730
+ { kind: 'ConfigMap', plural: 'configmaps', group: '', namespaced: true, storage: 'core' }
731
+ ```
732
+
733
+ Additionally, `KYVERNO_RESOURCES` (10 entries, discovered separately):
734
+
735
+ ```javascript
736
+ { kind: 'KyvernoPolicy', plural: 'policies', group: 'kyverno.io', namespaced: true, storage: 'kyverno', namespace: KRADLE_KYVERNO_POLICY_NAMESPACE }
737
+ { kind: 'KyvernoClusterPolicy', plural: 'clusterpolicies', group: 'kyverno.io', namespaced: false, storage: 'kyverno' }
738
+ { kind: 'KyvernoValidatingPolicy', plural: 'validatingpolicies', group: 'policies.kyverno.io', namespaced: false, storage: 'kyverno' }
739
+ { kind: 'KyvernoMutatingPolicy', plural: 'mutatingpolicies', group: 'policies.kyverno.io', namespaced: false, storage: 'kyverno' }
740
+ { kind: 'KyvernoGeneratingPolicy', plural: 'generatingpolicies', group: 'policies.kyverno.io', namespaced: false, storage: 'kyverno' }
741
+ { kind: 'KyvernoDeletingPolicy', plural: 'deletingpolicies', group: 'policies.kyverno.io', namespaced: false, storage: 'kyverno' }
742
+ { kind: 'KyvernoImageValidatingPolicy', plural: 'imagevalidatingpolicies', group: 'policies.kyverno.io', namespaced: false, storage: 'kyverno' }
743
+ { kind: 'KyvernoPolicyException', plural: 'policyexceptions', group: 'policies.kyverno.io', namespaced: true, storage: 'kyverno', namespace: KRADLE_KYVERNO_POLICY_NAMESPACE }
744
+ { kind: 'PolicyReport', plural: 'policyreports', group: 'wgpolicyk8s.io', namespaced: true, storage: 'kyverno-reports' }
745
+ { kind: 'ClusterPolicyReport', plural: 'clusterpolicyreports', group: 'wgpolicyk8s.io', namespaced: false, storage: 'kyverno-reports' }
746
+ ```
747
+
748
+ ---
749
+
750
+ ## 6. Agent Dispatch State Machine
751
+
752
+ > Source: `packages/kradle/core/src/agent-dispatch-controller.js`, observed from controller-ui.js active filtering
753
+
754
+ ### 6.1 Phase Transitions (K8s Job-Based)
755
+
756
+ Agents are dispatched as Kubernetes `batch/v1` Jobs. The dispatch run phase
757
+ reflects both the Kradle resource lifecycle and the underlying K8s Job state.
758
+
759
+ ```
760
+ ┌────────────────────────────────────────────────────────────┐
761
+ │ │
762
+ ┌─────────┐ ┌──▼──────────────┐ ┌──────────┐ ┌─────────┐ ┌──────────▼─┐
763
+ │ Pending │──▶│AwaitingApproval │──▶│ Queued │──▶│ Running │──▶│ Completed │
764
+ └─────────┘ └─────────────────┘ └──────────┘ └─────────┘ └────────────┘
765
+ │ │ │ │
766
+ │ │ (denied) │ │
767
+ │ ▼ ▼ │
768
+ │ ┌──────────┐ ┌──────────┐ │
769
+ └───────────▶│ Failed │◀────────────────────│ Failed │◀───────┘
770
+ └──────────┘ └──────────┘
771
+ ```
772
+
773
+ ### 6.2 K8s Job States
774
+
775
+ Each `AgentDispatchRun` in `Running` phase maps to exactly one K8s `batch/v1` Job.
776
+ The Job progresses through its own state machine independently:
777
+
778
+ | K8s Job State | Description | Kradle Run Phase |
779
+ |---------------|-------------|-----------------|
780
+ | `Pending` | Pod not yet scheduled (image pull, resource constraints) | `Running` |
781
+ | `Active` | Pod running, agent executing | `Running` |
782
+ | `Succeeded` | Pod exited 0, callback delivered | `Completed` |
783
+ | `Failed` | Pod exited non-zero or `activeDeadlineSeconds` exceeded | `Failed` |
784
+
785
+ The Kradle dispatch run enters `Completed` or `Failed` only after receiving the
786
+ agent's callback at `POST /api/orgs/{org}/agents/runs/{name}/callback`. If the
787
+ Job exceeds `activeDeadlineSeconds` (budget enforcement), Kubernetes terminates
788
+ the pod and the run transitions to `Failed` via a deadline-exceeded callback
789
+ generated by the dispatch controller's Job watch loop.
790
+
791
+ ### 6.3 Transition Triggers
792
+
793
+ | From | To | Trigger | Conditions |
794
+ |------|----|---------|-----------|
795
+ | (new) | `Pending` | `createDispatchRun()` called | Valid stack reference, org resolved |
796
+ | `Pending` | `AwaitingApproval` | Stack or workspace policy requires approval | `spec.requiresApproval: true` or KradleWorkspacePolicy matches |
797
+ | `Pending` | `Queued` | No approval required; budget check in progress | Direct dispatch allowed by permission review |
798
+ | `AwaitingApproval` | `Queued` | `approveAgentAction()` invoked by authorized user | AgentApproval resource phase → `Approved` |
799
+ | `AwaitingApproval` | `Failed` | `denyAgentAction()` invoked | AgentApproval resource phase → `Denied` |
800
+ | `Queued` | `Running` | `submitAgentJob()` succeeds | K8s Job created; workspace PVC mounted at `/workspace` |
801
+ | `Running` | `Completed` | Callback received with `phase: Succeeded` | `persistSessionEvent()` applies result |
802
+ | `Running` | `Failed` | Callback with `phase: Failed`, or Job deadline exceeded | `activeDeadlineSeconds` enforces budget ceiling |
803
+ | `Pending` | `Failed` | Permission review denies dispatch | Missing role binding, workspace policy violation, or cross-org denial |
804
+
805
+ ### 6.4 Callback Endpoint Spec
806
+
807
+ Agent pods report results to the Kradle API after session completion:
808
+
809
+ ```
810
+ POST /api/orgs/{org}/agents/runs/{name}/callback
811
+ Authorization: Bearer <kradle-run-token>
812
+ Content-Type: application/json
813
+
814
+ Request Body:
815
+ {
816
+ "phase": "Succeeded" | "Failed",
817
+ "exitCode": number, // 0 on success
818
+ "artifacts": [ // optional list of produced artifacts
819
+ { "kind": string, "digest": string, "path": string }
820
+ ],
821
+ "costUsd": number, // actual incurred cost
822
+ "errorMessage": string // present when phase = "Failed"
823
+ }
824
+
825
+ Response:
826
+ 200 { "ok": true } // result persisted
827
+ 400 { "error": "..." } // validation error
828
+ 404 { "error": "run not found" } // unknown run name
829
+ ```
830
+
831
+ ### 6.5 Transport Resolution Algorithm
832
+
833
+ `resolveTransport(stack, resources)` runs before `createAgentJob()`:
834
+
835
+ 1. Resolve `AgentAdapter` from `stack.spec.adapter`
836
+ 2. Find `AgentTransportBinding` where `spec.adapterRef === adapter.metadata.name`
837
+ 3. Extract `binding.spec.protocol` → `AGENT_MUX_TRANSPORT`
838
+ 4. Extract `binding.spec.codec ?? 'json'` → `TRANSPORT_MUX_CODEC`
839
+ 5. If no binding found: use `transport: 'http'`, `codec: 'json'` (safe defaults)
840
+ 6. Inject both values as env vars in the Job's container spec
841
+
842
+ ### 6.6 Budget Check Algorithm
843
+
844
+ `checkBudget({ org, model, estimatedTokens })`:
845
+
846
+ 1. Load `AgentProviderConfig` for the stack's model (from `resources`)
847
+ 2. Look up per-token rate: `config.spec.modelRates[model] ?? DEFAULT_RATES[model]`
848
+ 3. Compute `estimatedCostUsd = estimatedTokens * inputRate + estimatedOutputTokens * outputRate`
849
+ 4. Load org budget ceiling from `org.spec.budgetLimitUsd` (or env default)
850
+ 5. If `estimatedCostUsd > remainingBudget`: abort dispatch with `budget-exceeded`
851
+ 6. Compute `activeDeadlineSeconds = Math.floor(remainingBudget / costPerSecond)`
852
+ 7. Set deadline on Job spec to enforce budget at the infrastructure level
853
+
854
+ `estimateCost(model, tokens)` is a pure helper that applies the rate table
855
+ without side effects. Used both in the budget check and for pre-dispatch estimates.
856
+
857
+ ### 6.7 Data Stored at Each Phase
858
+
859
+ | Phase | Key Status Fields |
860
+ |-------|-------------------|
861
+ | `Pending` | `createdAt`, `stackRef`, `organizationRef`, `triggerRef?`, `requestedBy` |
862
+ | `AwaitingApproval` | + `approvalRef` (name of AgentApproval resource), `awaitingSince` |
863
+ | `Queued` | + `queuedAt`, `budgetCheckResult`, `resolvedTransport` |
864
+ | `Running` | + `startedAt`, `k8sJobName`, `sessionRef`, `workspaceRef`, `attemptNumber` |
865
+ | `Completed` | + `completedAt`, `duration`, `artifacts[]`, `costUsd`, `exitCode: 0` |
866
+ | `Failed` | + `failedAt`, `duration?`, `lastError`, `retryable`, `exitCode?`, `deadlineExceeded?` |
867
+
868
+ ### 6.8 Retry Semantics
869
+
870
+ - **New attempt:** A failed run can be retried by creating a new `AgentDispatchRun` with the same `stackRef` and an incremented `spec.attemptNumber`. The new run starts at `Pending`.
871
+ - **Re-queue:** Not supported. Once a run leaves `Queued`, it cannot return to that phase. The Job controller handles low-level pod restart policy via `backoffLimit: 0`.
872
+ - Each run's `AgentDispatchAttempt` resources track per-attempt history (one per execution cycle), including the K8s Job name for cross-referencing with cluster logs.
873
+
874
+ ### 6.9 Hooks Event Types
875
+
876
+ `createHooksLifecycleEmitter(bus)` wraps the in-process event bus and emits
877
+ structured lifecycle events forwarded to `WebhookSubscription` endpoints:
878
+
879
+ | Event | Trigger | Payload Fields |
880
+ |-------|---------|----------------|
881
+ | `RUN_CREATED` | `createManualDispatch()` called | `runId`, `org`, `stackRef`, `requestedBy` |
882
+ | `RUN_QUEUED` | Run enters Queued phase | `runId`, `queuedAt`, `budgetCheck` |
883
+ | `RUN_STARTED` | Job submitted, pod scheduled | `runId`, `k8sJobName`, `workspaceRef` |
884
+ | `STEP_STARTED` | Agent reports tool/reasoning step | `runId`, `stepKind`, `toolName?` |
885
+ | `STEP_COMPLETED` | Agent reports step done | `runId`, `stepKind`, `durationMs` |
886
+ | `APPROVAL_REQUESTED` | `createApprovalRequest()` called | `runId`, `action`, `requestedBy` |
887
+ | `APPROVAL_GRANTED` | `recordDecision()` Approved | `runId`, `decidedBy`, `approvalRef` |
888
+ | `APPROVAL_DENIED` | `recordDecision()` Denied | `runId`, `decidedBy`, `reason` |
889
+ | `RUN_COMPLETED` | Callback: `phase: Succeeded` | `runId`, `costUsd`, `artifacts[]` |
890
+ | `RUN_FAILED` | Callback: `phase: Failed` or deadline | `runId`, `errorMessage`, `deadlineExceeded?` |
891
+
892
+ ---
893
+
894
+ ## 7. Workspace State Machine
895
+
896
+ > Source: `packages/kradle/core/src/agent-workspace-controller.js`
897
+
898
+ ### 7.1 Workspace Lifecycle Phases
899
+
900
+ ```
901
+ ┌─────────┐ ┌──────────────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌──────────┐ ┌──────────┐
902
+ │ Pending │──▶│ Provisioning │──▶│ Ready │──▶│ InUse │──▶│ Ready │──▶│ Archiving│──▶│ Archived │
903
+ └─────────┘ └──────────────┘ └───────┘ └───────┘ └───────┘ └──────────┘ └──────────┘
904
+ │ ▲
905
+ └───────────────────────┘
906
+ (released by run)
907
+ ```
908
+
909
+ | Phase | Description | Duration |
910
+ |-------|-------------|----------|
911
+ | `Pending` | Workspace resource created, waiting for provisioner | Seconds |
912
+ | `Provisioning` | PVC being created, git clone starting, runtime booting | 10-60s |
913
+ | `Ready` | Workspace available for claiming by a dispatch run | Indefinite (warm pool) |
914
+ | `InUse` | Claimed by an AgentDispatchRun, agent session active | Duration of run |
915
+ | `Ready` (released) | Run completed, workspace returned to pool | Until next claim or TTL |
916
+ | `Archiving` | Artifacts being collected, PVC snapshot taken | Seconds |
917
+ | `Archived` | Terminal state. PVC released, metadata retained | Permanent |
918
+
919
+ ### 7.2 PVC Lifecycle
920
+
921
+ | PVC Phase | Workspace Phase | Action |
922
+ |-----------|-----------------|--------|
923
+ | — | `Pending` | PVC does not exist yet |
924
+ | `Pending` | `Provisioning` | PVC created with `storageClassName` and requested size |
925
+ | `Bound` | `Ready` | PVC bound to a PV, filesystem mounted |
926
+ | `Bound` | `InUse` | Same PVC, now mounted in runner pod |
927
+ | `Bound` | `Archiving` | Snapshot taken if configured |
928
+ | `Released` | `Archived` | PVC deleted or reclaimed by storage class |
929
+
930
+ PVC naming convention: `kradle-ws-${runId}` (generated by runner-controller, see architecture-v2.md §30.5).
931
+
932
+ ### 7.3 Git State (within workspace)
933
+
934
+ | Git Phase | Description |
935
+ |-----------|-------------|
936
+ | `Cloning` | `git clone` in progress during Provisioning |
937
+ | `Ready` | Clean worktree, all branches fetched |
938
+ | `Dirty` | Agent has uncommitted changes (during InUse) |
939
+ | `Synced` | Changes committed and pushed (during InUse or on release) |
940
+
941
+ ### 7.4 Codespace State (optional runtime container)
942
+
943
+ | Codespace Phase | Trigger |
944
+ |-----------------|---------|
945
+ | `Stopped` | Workspace created but runtime not started |
946
+ | `Starting` | Container runtime booting (image pull, env setup) |
947
+ | `Running` | IDE/agent connected, dev server available |
948
+ | `Stopping` | Graceful shutdown initiated (run complete or timeout) |
949
+
950
+ ### 7.5 Key Transitions
951
+
952
+ | From | To | Trigger |
953
+ |------|----|---------|
954
+ | `Pending` → `Provisioning` | PVC creation initiated by workspace controller |
955
+ | `Provisioning` → `Ready` | PVC bound + git clone complete + runtime healthy |
956
+ | `Ready` → `InUse` | `scheduleJob()` claims workspace for a dispatch run |
957
+ | `InUse` → `Ready` | Run completes, workspace released back to pool |
958
+ | `Ready` → `Archiving` | TTL expired or explicit archive request |
959
+ | `InUse` → `Archiving` | Run failed + workspace marked for cleanup |
960
+ | `Archiving` → `Archived` | Artifacts saved, PVC released |
961
+
962
+ ---
963
+
964
+ ## 8. Memory Import State Machine
965
+
966
+ > Source: `packages/kradle/core/src/agent-memory-controller.js`, observed from controller-ui.js memoryImports filtering
967
+
968
+ ### 8.1 Lifecycle Phases
969
+
970
+ ```
971
+ ┌───────────┐ ┌───────────┐ ┌──────────────┐ ┌────────────┐ ┌─────────────────┐ ┌────────────────────────┐ ┌────────┐
972
+ │ Collected │──▶│ Redacting │──▶│ Normalizing │──▶│ Validating │──▶│ AwaitingReview │──▶│ Approved / Rejected │──▶│ Merged │
973
+ └───────────┘ └───────────┘ └──────────────┘ └────────────┘ └─────────────────┘ └────────────────────────┘ └────────┘
974
+ ```
975
+
976
+ ### 8.2 Phase Descriptions
977
+
978
+ | Phase | Description | Owner |
979
+ |-------|-------------|-------|
980
+ | `Collected` | Raw memory data extracted from a babysitter run or agent session transcript. Contains conversation fragments, decisions, tool outputs. | Automated (agent session completion handler) |
981
+ | `Redacting` | PII and secrets are stripped. Credential patterns, email addresses, API keys, file paths with usernames are removed or masked. | Automated (redaction pipeline) |
982
+ | `Normalizing` | Extracted facts are normalized into the ontology schema: entities, relationships, decisions, patterns. Deduplication against existing memory. | Automated (normalization engine) |
983
+ | `Validating` | Schema validation of normalized memory entries. Cross-references checked against existing AgentMemoryAssociation resources. Confidence scores computed. | Automated (validation rules) |
984
+ | `AwaitingReview` | Human review required. Low-confidence entries, novel ontology terms, or entries referencing sensitive resources are queued for approval. | Human reviewer |
985
+ | `Approved` | Reviewer accepted the import. Ready for merge into the memory repository. | Human (via UI or API) |
986
+ | `Rejected` | Reviewer rejected. Reasons recorded. Will not be merged. | Human (via UI or API) |
987
+ | `Merged` | Terminal. Memory entries written to AgentMemoryRepository, associations created, ontology updated if needed. | Automated (merge pipeline) |
988
+
989
+ ### 8.3 Data at Each Phase
990
+
991
+ | Phase | Key Fields |
992
+ |-------|-----------|
993
+ | `Collected` | `sourceRef` (session/run), `rawEntries[]`, `collectedAt`, `sourceType` |
994
+ | `Redacting` | + `redactedFields[]`, `redactionRules` applied |
995
+ | `Normalizing` | + `normalizedEntries[]`, `ontologyTerms[]`, `deduplicationResults` |
996
+ | `Validating` | + `validationErrors[]`, `confidenceScores{}`, `crossRefResults` |
997
+ | `AwaitingReview` | + `reviewRequestedAt`, `reviewerHint`, `flaggedEntries[]` |
998
+ | `Approved` | + `approvedBy`, `approvedAt`, `approvalNotes` |
999
+ | `Rejected` | + `rejectedBy`, `rejectedAt`, `rejectionReason` |
1000
+ | `Merged` | + `mergedAt`, `repositoryRef`, `createdAssociations[]`, `mergedEntryCount` |
1001
+
1002
+ ### 8.4 Transition Rules
1003
+
1004
+ - `Collected → Redacting`: automatic, immediate after collection
1005
+ - `Redacting → Normalizing`: automatic after redaction pass completes
1006
+ - `Normalizing → Validating`: automatic after normalization
1007
+ - `Validating → AwaitingReview`: when any entry has confidence < threshold OR novel ontology term OR references sensitive resource
1008
+ - `Validating → Approved`: when all entries pass validation with high confidence (auto-approve path)
1009
+ - `AwaitingReview → Approved`: human calls approve endpoint
1010
+ - `AwaitingReview → Rejected`: human calls reject endpoint
1011
+ - `Approved → Merged`: automatic, writes to memory repository
1012
+ - `Rejected`: terminal (no further transitions)
1013
+
1014
+ The controller-ui.js filters pending imports as: `memoryImports.filter(i => !i.status?.phase || i.status.phase === 'Pending' || i.status.phase === 'AwaitingReview')`
1015
+
1016
+
1017
+ ---
1018
+
1019
+ ## 9. KServe Inference Resources
1020
+
1021
+ Source: `packages/kradle/core/src/kradle-inference-service-controller.js`
1022
+
1023
+ ### 9.1 KradleInferenceService
1024
+
1025
+ Wraps KServe `InferenceService` CRD (`serving.kserve.io/v1beta1`).
1026
+
1027
+ | Field | Type | Required | Description |
1028
+ |-------|------|----------|-------------|
1029
+ | `spec.predictor.model.modelFormat.name` | string | Yes | Model format: `sklearn`, `xgboost`, `lightgbm`, `tensorflow`, `pytorch`, `onnx`, `triton`, `huggingface`, `custom` |
1030
+ | `spec.predictor.model.storageUri` | string | Yes | URI to model artifacts (e.g., `s3://bucket/model`) |
1031
+ | `spec.predictor.model.runtime` | string | No | Name of a KradleServingRuntime to use |
1032
+ | `spec.predictor.model.protocolVersion` | string | No | `v1` or `v2`. Default: `v2` |
1033
+ | `spec.predictor.resources.limits` | object | No | CPU/memory limits (e.g., `{ cpu: '2', memory: '4Gi' }`) |
1034
+ | `spec.predictor.resources.requests` | object | No | CPU/memory requests |
1035
+ | `spec.features` | object | No | Feature flags for the inference service |
1036
+
1037
+ **Status fields:**
1038
+
1039
+ | Field | Description |
1040
+ |-------|-------------|
1041
+ | `status.phase` | `Pending` => `Ready` => `Failed` |
1042
+ | `status.url` | Resolved inference endpoint URL (populated after readiness) |
1043
+ | `status.conditions` | Array of K8s-style conditions |
1044
+ | `status.message` | Human-readable status message |
1045
+
1046
+ **Inference protocols:**
1047
+ - V1: `POST /v1/models/{name}:predict`
1048
+ - V2: `POST /v2/models/{name}/infer`
1049
+
1050
+ ### 9.2 KradleServingRuntime
1051
+
1052
+ Wraps KServe `ServingRuntime` CRD.
1053
+
1054
+ | Field | Type | Required | Description |
1055
+ |-------|------|----------|-------------|
1056
+ | `spec.supportedModelFormats` | array | Yes | Each: `{ name, version?, autoSelect? }` |
1057
+ | `spec.containers` | array | Yes | K8s container specs: `{ image, args?, env?, resources? }` |
1058
+ | `spec.multiModel` | boolean | No | Whether runtime supports multiple models per pod |
1059
+
1060
+ ---
1061
+
1062
+ ## 10. Artifact Registry Resources
1063
+
1064
+ Source: `packages/kradle/core/src/artifact-registry-controller.js`
1065
+
1066
+ Five resource kinds managed together as an artifact registry system.
1067
+
1068
+ ### 10.1 ArtifactRegistry
1069
+
1070
+ | Field | Type | Required | Description |
1071
+ |-------|------|----------|-------------|
1072
+ | `spec.organizationRef` | string | Yes | Owning organization |
1073
+ | `spec.displayName` | string | Yes | Human-readable name |
1074
+ | `spec.type` | string | Yes | `npm`, `pip`, `docker`, or `generic` |
1075
+ | `spec.storageBackend` | string | Yes | `internal`, `s3`, `azure-blob`, or `gcs` |
1076
+ | `spec.storageConfig.bucket` | string | No | Bucket name (for S3/GCS/Azure) |
1077
+ | `spec.storageConfig.prefix` | string | No | Key prefix |
1078
+ | `spec.storageConfig.connectionSecret` | string | No | Secret ref for credentials |
1079
+ | `spec.externalIntegration.provider` | string | No | External provider name |
1080
+ | `spec.externalIntegration.mode` | string | No | `read-only`, `read-write`, or `mirror` |
1081
+ | `spec.externalIntegration.connectionSecret` | string | No | Secret ref |
1082
+
1083
+ ### 10.2 ArtifactFeed
1084
+
1085
+ | Field | Type | Required | Description |
1086
+ |-------|------|----------|-------------|
1087
+ | `spec.organizationRef` | string | Yes | Owning organization |
1088
+ | `spec.registryRef` | string | Yes | Parent ArtifactRegistry name |
1089
+ | `spec.displayName` | string | Yes | Human-readable name |
1090
+ | `spec.visibility` | string | No | `public` or `private`. Default: `private` |
1091
+ | `spec.retentionPolicy.maxVersions` | number | No | Max versions to retain per package |
1092
+ | `spec.retentionPolicy.maxAgeDays` | number | No | Max age in days |
1093
+ | `spec.accessPolicies` | array | No | Inline access policy entries |
1094
+
1095
+ ### 10.3 ArtifactAccessPolicy
1096
+
1097
+ | Field | Type | Required | Description |
1098
+ |-------|------|----------|-------------|
1099
+ | `spec.organizationRef` | string | Yes | Owning organization |
1100
+ | `spec.feedRef` | string | Yes | Target ArtifactFeed name |
1101
+ | `spec.subject` | string | Yes | User, team, or service account name |
1102
+ | `spec.permission` | string | Yes | `read`, `write`, or `admin` |
1103
+ | `spec.expiresAt` | string | No | ISO 8601 expiry timestamp |
1104
+
1105
+ ### 10.4 ArtifactVersion
1106
+
1107
+ | Field | Type | Required | Description |
1108
+ |-------|------|----------|-------------|
1109
+ | `spec.organizationRef` | string | Yes | Owning organization |
1110
+ | `spec.feedRef` | string | Yes | Parent ArtifactFeed name |
1111
+ | `spec.name` | string | Yes | Package name |
1112
+ | `spec.version` | string | Yes | Semver version string |
1113
+ | `spec.packageType` | string | Yes | Package type (matches feed type) |
1114
+ | `spec.size` | number | No | Size in bytes |
1115
+ | `spec.checksums.sha256` | string | No | SHA-256 hex digest |
1116
+ | `spec.checksums.md5` | string | No | MD5 hex digest |
1117
+ | `spec.metadata.dependencies` | object | No | Dependency map |
1118
+ | `spec.metadata.tags` | array | No | String tags |
1119
+ | `spec.metadata.description` | string | No | Package description |
1120
+ | `spec.publishedBy` | string | Yes | Publisher user name |
1121
+ | `spec.publishedAt` | string | Yes | ISO 8601 publish timestamp |
1122
+
1123
+ ### 10.5 ArtifactDownload
1124
+
1125
+ | Field | Type | Required | Description |
1126
+ |-------|------|----------|-------------|
1127
+ | `spec.organizationRef` | string | Yes | Owning organization |
1128
+ | `spec.feedRef` | string | Yes | Feed name |
1129
+ | `spec.versionRef` | string | Yes | ArtifactVersion name |
1130
+ | `spec.downloadedBy` | string | No | User or client ID |
1131
+ | `spec.downloadedAt` | string | Yes | ISO 8601 timestamp |
1132
+ | `spec.ipAddress` | string | No | Client IP |
1133
+ | `spec.userAgent` | string | No | HTTP User-Agent string |
1134
+ | `spec.clientId` | string | No | Opaque client identifier |
1135
+
1136
+ ---
1137
+
1138
+ ## 11. Assistant Runtime API
1139
+
1140
+ Source: `packages/kradle/core/src/assistant-runtime.js`
1141
+
1142
+ `createAssistantRuntime(config)` returns an object with four methods:
1143
+
1144
+ ### `chat(opts)` -- `AsyncIterable<chunk>`
1145
+
1146
+ Streams assistant response as SSE chunks.
1147
+
1148
+ | Option | Type | Required | Description |
1149
+ |--------|------|----------|-------------|
1150
+ | `org` | string | Yes | Organization slug for session scoping |
1151
+ | `sessionId` | string | Yes | Session identifier |
1152
+ | `messages` | array | Yes | Message history: `[{ role, content }]` |
1153
+ | `system` | string | No | System prompt override |
1154
+ | `tools` | array | No | Tool definitions passed to the model |
1155
+ | `model` | string | No | Model override (default: from config) |
1156
+
1157
+ ### `generate(opts)` -- `Promise<object>`
1158
+
1159
+ Structured generation call, returning JSON.
1160
+
1161
+ | Option | Type | Required | Description |
1162
+ |--------|------|----------|-------------|
1163
+ | `org` | string | Yes | Organization slug |
1164
+ | `prompt` | string | Yes | User prompt |
1165
+ | `schema` | object | No | JSON schema for structured output |
1166
+ | `system` | string | No | System prompt |
1167
+ | `tools` | array | No | Tool definitions |
1168
+ | `model` | string | No | Model override |
1169
+
1170
+ ### `listSessions(org)` -- `Array<session>`
1171
+
1172
+ Returns all active sessions for the given organization.
1173
+
1174
+ ### `clearSession(org, sessionId)` -- `void`
1175
+
1176
+ Removes session from the in-process store (`globalThis.__kradleSessions`). Sessions are ephemeral and do not persist across process restarts.
1177
+
1178
+ ---
1179
+
1180
+ ## 12. New API Routes (v2)
1181
+
1182
+ Routes added in the KServe, artifact registry, and assistant runtime phases.
1183
+
1184
+ ### 12.1 Inference Routes
1185
+
1186
+ | Method | Path | Auth | Description |
1187
+ |--------|------|------|-------------|
1188
+ | GET | `/api/orgs/{org}/inference/services` | none | List KradleInferenceServices |
1189
+ | POST | `/api/orgs/{org}/inference/services` | withAuth | Create KradleInferenceService |
1190
+ | GET | `/api/orgs/{org}/inference/services/{name}` | none | Get service detail and resolved endpoint |
1191
+ | DELETE | `/api/orgs/{org}/inference/services/{name}` | withAuth | Delete service |
1192
+ | POST | `/api/orgs/{org}/inference/services/{name}/infer` | withAuth | Proxy inference request (V1/V2) |
1193
+ | GET | `/api/orgs/{org}/inference/runtimes` | none | List KradleServingRuntimes |
1194
+ | POST | `/api/orgs/{org}/inference/runtimes` | withAuth | Create serving runtime |
1195
+
1196
+ ### 12.2 Artifact Routes
1197
+
1198
+ | Method | Path | Auth | Description |
1199
+ |--------|------|------|-------------|
1200
+ | GET | `/api/orgs/{org}/artifacts/registries` | none | List ArtifactRegistries |
1201
+ | POST | `/api/orgs/{org}/artifacts/registries` | withAuth | Create registry |
1202
+ | GET | `/api/orgs/{org}/artifacts/feeds` | none | List ArtifactFeeds |
1203
+ | POST | `/api/orgs/{org}/artifacts/feeds` | withAuth | Create feed |
1204
+ | GET | `/api/orgs/{org}/artifacts/feeds/{feed}/versions` | none | List versions for a feed |
1205
+ | POST | `/api/orgs/{org}/artifacts/feeds/{feed}/publish` | withAuth | Publish new version |
1206
+
1207
+ ### 12.3 Assistant Routes
1208
+
1209
+ | Method | Path | Auth | Description |
1210
+ |--------|------|------|-------------|
1211
+ | POST | `/api/orgs/{org}/assistant/chat` | withAuth | SSE chat stream |
1212
+ | POST | `/api/orgs/{org}/assistant/generate` | withAuth | Structured generation |
1213
+ | GET | `/api/orgs/{org}/assistant/sessions` | withAuth | List sessions |
1214
+ | DELETE | `/api/orgs/{org}/assistant/sessions/{sessionId}` | withAuth | Clear session |
1215
+ | GET | `/api/orgs/{org}/assistant/artifacts/{id}` | withAuth | Get assistant artifact |
1216
+
1217
+ ---
1218
+
1219
+ ## Summary: Updated Resource Count
1220
+
1221
+ Total resource kinds: **83** (previously 76)
1222
+
1223
+ **New kinds added:**
1224
+
1225
+ | Domain | Kinds Added |
1226
+ |--------|------------|
1227
+ | Inference | KradleInferenceService, KradleServingRuntime |
1228
+ | Artifact Registry | ArtifactRegistry, ArtifactFeed, ArtifactAccessPolicy, ArtifactVersion, ArtifactDownload |
1229
+
1230
+ Total new routes: **19** (7 inference + 6 artifact + 5 assistant + 1 callback webhook).