@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,62 @@
1
+ # Product Requirements
2
+
3
+ ## Product summary
4
+
5
+ Kradle is a Kubernetes-native forge for platform engineering teams. It extends the Kubernetes API with repository, pull request, issue, pipeline, runner, hook, and policy resources so Git workflows compose directly with RBAC, admission webhooks, Argo, Crossplane, ARC, Kyverno, and Gatekeeper.
6
+
7
+ ## Problem
8
+
9
+ Existing Kubernetes-hosted forges are usually monoliths packaged in Helm. They still bring a separate identity model, permission model, webhook system, CI security surface, and integration layer. The naive Kubernetes-native design also fails if every issue/comment is stored in etcd, every repository gets its own PVC, or push traffic is cold-started.
10
+
11
+ ## Goals
12
+
13
+ - Provide a forge where repos, PRs, CI, hooks, and policy share one Kubernetes identity and RBAC model.
14
+ - Make forge resources queryable and automatable with `kubectl`.
15
+ - Support admission-webhook policy for PRs, issues, and CI without custom integration glue.
16
+ - Keep high-cardinality social data out of etcd while preserving Kubernetes API semantics.
17
+ - Make GitOps transparency a first-class UX pattern for every mutation.
18
+ - Ship an MVP that proves policy, Git push, PR review, and CI identity end to end.
19
+
20
+ ## Non-goals for MVP
21
+
22
+ - Scaled Gitea-backed production data plane beyond the single-backend MVP.
23
+ - Full native runner abstraction if ARC integration is sufficient for the first demo.
24
+ - Built-in code search beyond design-ready interfaces.
25
+ - Multi-cluster federation.
26
+ - Replacing Kyverno or Gatekeeper with a bespoke policy language.
27
+
28
+ ## Personas
29
+
30
+ ### Developer
31
+
32
+ Developers review PRs, browse code, debug failing runs, and need fast keyboard-first workflows. They should not need to understand cluster internals to use the forge, but should always be able to reveal the underlying resource and command.
33
+
34
+ ### Platform engineer
35
+
36
+ Platform engineers own runner pools, policy, identity, storage, hooks, tenancy, install, upgrade, and cost. They need auditability, safe rollout modes, and GitOps-managed configuration.
37
+
38
+ ### Repo admin
39
+
40
+ Repo admins configure repository settings, branch protection, webhooks, runner permissions, and policy overrides. They use the same IA as developers with additional settings access.
41
+
42
+ ## Product principles
43
+
44
+ - Kubernetes is the backend. Kradle should not recreate permission, policy, audit, and identity systems already present in Kubernetes.
45
+ - CRDs are contracts, not a database. High-cardinality records must live behind the aggregated API server.
46
+ - Push paths must stay warm. Reads can scale elastically; writes cannot impose cold-start latency on `git push`.
47
+ - UI state can be declarative. Saved views and selectors should be resources that teams can commit, share, and apply.
48
+ - Policy rollout must be observable. Audit mode and violation preview are required for PR policy authoring.
49
+
50
+ ## Success metrics
51
+
52
+ - Time from `helm install kradle` to first repository push is under 15 minutes in a documented environment.
53
+ - A Kyverno policy can block or audit PR creation without custom Kradle code.
54
+ - A developer can open, review, and merge a PR with CI status from the UI.
55
+ - A platform engineer can configure a runner pool and export/save its YAML.
56
+ - Webhook failures are inspectable and replayable from both UI and `kubectl`.
57
+
58
+ ## Organization-scoped tenancy
59
+
60
+ Kradle is organization-first. Every repository, deployment, runner pool, agent stack, trigger, company brain memory repository, session, workspace, secret grant, and config grant belongs to an org. Each org maps to its own Kubernetes namespace so Kubernetes RBAC, ServiceAccounts, Secrets, ConfigMaps, admission, and audit remain the isolation boundary.
61
+
62
+ The UI should feel like GitHub organization navigation: select an org, then browse repositories, deployments, agents, memory, settings, runners, and audit for that org. Cross-org sharing is explicit policy, not an accidental reference.
@@ -0,0 +1,235 @@
1
+ # Kradle Requirements Specification v2
2
+
3
+ > Exhaustive requirements derived from implemented functionality.
4
+ > Every requirement corresponds to verified source code behavior.
5
+
6
+ ---
7
+
8
+ ## 1. Functional Requirements — Identity and Access
9
+
10
+ | ID | Priority | Description | Acceptance Criteria | Implementation | Test Coverage | Status |
11
+ |----|----------|-------------|--------------------:|----------------|---------------|--------|
12
+ | REQ-FUNC-IAM-001 | MUST | Multi-tenant organizations with display name and namespace binding | Organization resource created with displayName and namespaceName; OrgNamespaceBinding created; tenant namespace created in K8s | `kubernetes-controller.js:createOrganization()` | `tests/kubernetes-controller.test.js` | Implemented |
13
+ | REQ-FUNC-IAM-002 | MUST | User accounts with email, display name, admin flag | User resource created with required spec fields; admin derived from group membership | `auth.js:mapLoginProfileToKradleIdentity()` | `tests/auth.test.js` | Implemented |
14
+ | REQ-FUNC-IAM-003 | MUST | Teams with membership, maintainers, and permission grants | Team resource with members[], maintainers[], repositoryGrants[]; memberCount in status | `auth.js:createTeamResource()` | `tests/auth.test.js` | Implemented |
15
+ | REQ-FUNC-IAM-004 | MUST | Pending invitations with email, role, team, and expiry | Invite resource with expiresAt computed from expiresInDays; phase=Pending | `auth.js:createInviteResource()` | `tests/auth.test.js` | Implemented |
16
+ | REQ-FUNC-IAM-005 | MUST | Identity mapping between Kradle users and external subjects | IdentityMapping with workspaceIdentity and repositoryIdentity sub-objects | `auth.js:mapLoginProfileToKradleIdentity()` | `tests/auth.test.js` | Implemented |
17
+ | REQ-FUNC-IAM-006 | MUST | Configurable auth providers (GitHub OAuth, OIDC/SSO, Delegated) | AuthProvider resource per provider; environment-driven configuration | `auth.js:createAuthProviderConfig()` | `tests/auth.test.js` | Implemented |
18
+ | REQ-FUNC-IAM-007 | MUST | Agent service accounts for K8s identity binding | AgentServiceAccount with namespace and serviceAccountName fields | `resource-model.js` | `tests/resource-model.test.js` | Implemented |
19
+ | REQ-FUNC-IAM-008 | MUST | Managed RBAC projection for agent identity | AgentRoleBinding with subject, roleRef, scope fields | `agent-permission-review.js` | `tests/agent-permission-review.test.js` | Implemented |
20
+ | REQ-FUNC-IAM-009 | MUST | Explicit secret access grants with purpose scope | AgentSecretGrant with subject, secretRef, purpose; validated by permission reviewer | `agent-secret-config-grant-controller.js` | `tests/agent-secret-config-grant.test.js` | Implemented |
21
+ | REQ-FUNC-IAM-010 | MUST | Explicit ConfigMap access grants with purpose scope | AgentConfigGrant with subject, configMapRef, purpose; validated by permission reviewer | `agent-secret-config-grant-controller.js` | `tests/agent-secret-config-grant.test.js` | Implemented |
22
+ | REQ-FUNC-IAM-011 | MUST | Admin detection from group membership | Groups `kradle:platform-engineers` or `kradle:repo-admins` set admin=true | `auth.js:normalizeProviderProfile()` line 124 | `tests/auth.test.js` | Implemented |
23
+ | REQ-FUNC-IAM-012 | MUST | Bootstrap admin via KRADLE_ADMIN_USERNAME | Username match against profile sets isBootstrapAdmin | `auth.js:registerLoginProfile()` line 143 | `tests/auth.test.js` | Implemented |
24
+
25
+ ---
26
+
27
+ ## 2. Functional Requirements — Authentication
28
+
29
+ | ID | Priority | Description | Acceptance Criteria | Implementation | Test Coverage | Status |
30
+ |----|----------|-------------|--------------------:|----------------|---------------|--------|
31
+ | REQ-FUNC-AUTH-001 | MUST | GitHub OAuth sign-in flow | Authorization URL built with client_id, redirect_uri, scope, state; code exchanged for access_token; profile fetched from /user | `auth.js:buildAuthorizationRedirect(), exchangeOAuthCodeForProfile()` | `tests/auth.test.js` | Implemented |
32
+ | REQ-FUNC-AUTH-002 | MUST | OIDC/SSO sign-in flow | Same OAuth flow with configurable issuer/token/userinfo endpoints; scopes include groups | `auth.js:exchangeOAuthCodeForProfile()` | `tests/auth.test.js` | Implemented |
33
+ | REQ-FUNC-AUTH-003 | MUST | Delegated identity via proxy headers | x-forwarded-user, x-forwarded-groups, x-forwarded-email parsed; local dev fallback | `auth.js:profileFromDelegatedHeaders()` | `tests/auth.test.js` | Implemented |
34
+ | REQ-FUNC-AUTH-004 | MUST | HMAC-SHA256 signed session cookies | Payload base64url encoded; signature = HMAC-SHA256(payload, secret).base64url | `auth.js:createSessionCookie()` | `tests/auth.test.js` | Implemented |
35
+ | REQ-FUNC-AUTH-005 | MUST | Timing-safe signature verification | `timingSafeEqual(expected, received)` from node:crypto | `auth.js:parseSessionCookie()` line 189 | `tests/auth.test.js` | Implemented |
36
+ | REQ-FUNC-AUTH-006 | MUST | Reject unsigned cookies when secret configured | If dotIndex === -1 and secret is set: return null | `auth.js:parseSessionCookie()` line 178 | `tests/auth.test.js` | Implemented |
37
+ | REQ-FUNC-AUTH-007 | MUST | Reject signed cookies when no secret | If dotIndex !== -1 and no secret: return null | `auth.js:parseSessionCookie()` line 172 | `tests/auth.test.js` | Implemented |
38
+ | REQ-FUNC-AUTH-008 | MUST | HttpOnly and SameSite=Lax cookie attributes | Cookie string ends with `; Path=/; HttpOnly; SameSite=Lax` | `auth.js:createSessionCookie()` line 162 | `tests/auth.test.js` | Implemented |
39
+ | REQ-FUNC-AUTH-009 | SHOULD | Local development auto-login | Active when NODE_ENV !== 'production'; configurable user/groups | `auth.js:localDelegatedDevelopmentProfile()` | `tests/auth.test.js` | Implemented |
40
+ | REQ-FUNC-AUTH-010 | MUST | User+IdentityMapping registration on first login | registerLoginProfile creates/updates User and IdentityMapping resources via applyResource | `auth.js:registerLoginProfile()` | `tests/auth.test.js` | Implemented |
41
+
42
+ ---
43
+
44
+ ## 3. Functional Requirements — Repository Management
45
+
46
+ | ID | Priority | Description | Acceptance Criteria | Implementation | Test Coverage | Status |
47
+ |----|----------|-------------|--------------------:|----------------|---------------|--------|
48
+ | REQ-FUNC-REPO-001 | MUST | Repository CRUD with visibility | Repository created with organizationRef, visibility (private/internal/public); delete removes CRD | `api-controller.js:createRepository()` | `tests/api-controller.test.js` | Implemented |
49
+ | REQ-FUNC-REPO-002 | MUST | SSH key management (user, deploy, automation scopes) | SSHKey with scope field; fingerprint computed via sha256 hash | `kubernetes-controller.js:identityAccessReconciliationPlan()` | `tests/kubernetes-controller.test.js` | Implemented |
50
+ | REQ-FUNC-REPO-003 | MUST | Repository permission management | RepositoryPermission with subject, permission (read/write/admin), revoked flag | `kubernetes-controller.js:identityAccessReconciliationPlan()` | `tests/kubernetes-controller.test.js` | Implemented |
51
+ | REQ-FUNC-REPO-004 | MUST | Branch protection rules | BranchProtection with refs pattern; PR requirement enforcement | `resource-model.js` | `tests/resource-model.test.js` | Implemented |
52
+ | REQ-FUNC-REPO-005 | MUST | Reference deny rules and force-push policy | RefPolicy resource with organizationRef | `resource-model.js` | `tests/resource-model.test.js` | Implemented |
53
+ | REQ-FUNC-REPO-006 | MUST | Git object recording | POST /api/orgs/:org/repositories/:repo/objects stores object reference | `http-server.js` line 60-63 | `tests/http-server.test.js` | Implemented |
54
+ | REQ-FUNC-REPO-007 | MUST | Search index enqueuing | POST returns 202 Accepted; search indexing queued asynchronously | `http-server.js` line 66-70 | `tests/http-server.test.js` | Implemented |
55
+
56
+ ---
57
+
58
+ ## 4. Functional Requirements — Agent Orchestration
59
+
60
+ | ID | Priority | Description | Acceptance Criteria | Implementation | Test Coverage | Status |
61
+ |----|----------|-------------|--------------------:|----------------|---------------|--------|
62
+ | REQ-FUNC-AGENT-001 | MUST | Reusable agent stacks with full config | AgentStack with baseAgent, adapter, runtimeIdentity, toolPolicy, mcpServerRefs, skillRefs, subagentRefs, contextLabelRefs, approvalMode | `agent-stack-controller.js` | `tests/agent-stack-controller.test.js` | Implemented |
63
+ | REQ-FUNC-AGENT-002 | MUST | Stack readiness reconciliation with 10 conditions | reconcileStack() resolves all refs, runs permission review, computes Ready condition | `agent-stack-controller.js:reconcileStack()` | `tests/agent-stack-controller.test.js` | Implemented |
64
+ | REQ-FUNC-AGENT-003 | MUST | MCP health check with 3s timeout | HTTP GET to endpoint with AbortController timeout; returns healthy/unhealthy + latencyMs | `agent-stack-controller.js:checkMcpHealth()` | `tests/agent-stack-controller.test.js` | Implemented |
65
+ | REQ-FUNC-AGENT-004 | MUST | Manual dispatch with permission gating | createManualDispatch: find stack → permission review → memory snapshot → workspace → context → launch | `agent-dispatch-controller.js` | `tests/agent-dispatch-controller.test.js` | Implemented |
66
+ | REQ-FUNC-AGENT-005 | MUST | Permission review with cross-org denial | Cross-org check: agent org vs repository org; denied if mismatch | `agent-permission-review.js` line 44-52 | `tests/agent-permission-review.test.js` | Implemented |
67
+ | REQ-FUNC-AGENT-006 | MUST | Untrusted fork detection | Refs matching `/^refs\/pull\/\d+\//` flagged as fork; privileged grants restricted | `agent-permission-review.js` line 64 | `tests/agent-permission-review.test.js` | Implemented |
68
+ | REQ-FUNC-AGENT-007 | MUST | Approval mode enforcement (yolo/prompt/deny) | deny: immediate block; prompt: requires-approval; yolo: allowed | `agent-permission-review.js` lines 34-40 | `tests/agent-permission-review.test.js` | Implemented |
69
+ | REQ-FUNC-AGENT-008 | MUST | Workspace provisioning with PVC | createWorkspace generates KradleWorkspace + PVC manifest with storage class, capacity, access modes | `agent-workspace-controller.js:createWorkspace()` | `tests/agent-workspace-controller.test.js` | Implemented |
70
+ | REQ-FUNC-AGENT-009 | MUST | Workspace reuse by repo+branch+phase | findReusableWorkspace matches org+repo+branch+Ready phase | `agent-workspace-controller.js:findReusableWorkspace()` | `tests/agent-workspace-controller.test.js` | Implemented |
71
+ | REQ-FUNC-AGENT-010 | MUST | Codespace lifecycle (launch/stop/status) | Pod spec with code-server image, PVC mount, Service with ClusterIP | `agent-workspace-controller.js:launchCodespace()` | `tests/agent-workspace-controller.test.js` | Implemented |
72
+ | REQ-FUNC-AGENT-011 | MUST | Event-to-stack routing via trigger rules | evaluateEvent matches event type against rule sources; dedup check; dispatch creation | `agent-trigger-controller.js:processEvent()` | `tests/agent-trigger-controller.test.js` | Implemented |
73
+ | REQ-FUNC-AGENT-012 | MUST | Cron expression validation (5-field) | validateCronExpression checks 5 fields, valid chars [0-9*/,-] | `agent-trigger-controller.js:validateCronExpression()` | `tests/agent-trigger-controller.test.js` | Implemented |
74
+ | REQ-FUNC-AGENT-013 | MUST | Next cron run calculation | calculateNextRun iterates minute-by-minute up to 527,040 iterations (1 year) | `agent-trigger-controller.js:calculateNextRun()` | `tests/agent-trigger-controller.test.js` | Implemented |
75
+ | REQ-FUNC-AGENT-014 | MUST | Human approval gates for agent actions | createApprovalRequest with 5 valid actions; recordDecision approve/deny; dedup check | `agent-approval-controller.js` | `tests/agent-approval-controller.test.js` | Implemented |
76
+ | REQ-FUNC-AGENT-015 | MUST | Approval enforcement gate | enforceApproval returns allowed/denied/pending based on phase | `agent-approval-controller.js:enforceApproval()` | `tests/agent-approval-controller.test.js` | Implemented |
77
+ | REQ-FUNC-AGENT-016 | MUST | Work item linking (issues/PRs to sessions/workspaces) | WorkItemSessionLink and WorkItemWorkspaceLink resources created | `agent-workspace-controller.js:linkWorkItem(), linkWorkItemToSession()` | `tests/agent-workspace-controller.test.js` | Implemented |
78
+ | REQ-FUNC-AGENT-017 | MUST | Workspace associations | addAssociation/removeAssociation with valid kinds: AgentDispatchRun, User, AgentSession | `agent-workspace-controller.js:addAssociation()` | `tests/agent-workspace-controller.test.js` | Implemented |
79
+ | REQ-FUNC-AGENT-018 | MUST | Workspace run history | getWorkspaceRuns partitions into active (Running/Queued/Pending/Dispatched) and history | `agent-workspace-controller.js:getWorkspaceRuns()` | `tests/agent-workspace-controller.test.js` | Implemented |
80
+
81
+ ---
82
+
83
+ ## 5. Functional Requirements — Memory System
84
+
85
+ | ID | Priority | Description | Acceptance Criteria | Implementation | Test Coverage | Status |
86
+ |----|----------|-------------|--------------------:|----------------|---------------|--------|
87
+ | REQ-FUNC-MEM-001 | MUST | Graph query with nodeKind filtering and depth | queryGraph: records filtered by kinds[], scored by id/attribute match, edges followed to depth | `agent-memory-query.js:queryGraph()` | `tests/agent-memory-query.test.js` | Implemented |
88
+ | REQ-FUNC-MEM-002 | MUST | Full-text grep with context extraction | queryGrep: line-by-line case-insensitive search; context lines above/below; highlighted output | `agent-memory-query.js:queryGrep()` | `tests/agent-memory-query.test.js` | Implemented |
89
+ | REQ-FUNC-MEM-003 | MUST | Combined graph+grep query | queryMemory: mode selects graph-only, grep-only, or both; merged stats | `agent-memory-query.js:queryMemory()` | `tests/agent-memory-query.test.js` | Implemented |
90
+ | REQ-FUNC-MEM-004 | MUST | Query validation (non-empty string required) | Throws Error if query is null, undefined, or empty string | `agent-memory-query.js` lines 42-45 | `tests/agent-memory-query.test.js` | Implemented |
91
+ | REQ-FUNC-MEM-005 | MUST | Mode validation | Throws Error if mode not in ['graph-only', 'grep-only', 'graph-and-grep'] | `agent-memory-query.js` line 168 | `tests/agent-memory-query.test.js` | Implemented |
92
+ | REQ-FUNC-MEM-006 | MUST | Grep path filtering with glob patterns | Glob match: * matches any sequence; documents filtered before search | `agent-memory-query.js:globMatch()` | `tests/agent-memory-query.test.js` | Implemented |
93
+ | REQ-FUNC-MEM-007 | MUST | Grep max matches limit | Default 25; stops searching once limit reached | `agent-memory-query.js:queryGrep()` line 106 | `tests/agent-memory-query.test.js` | Implemented |
94
+ | REQ-FUNC-MEM-008 | MUST | Graph adjacency from both record edges and flat edges | buildAdjacency merges per-record edges[] with flat edges parameter | `agent-memory-query.js:buildAdjacency()` | `tests/agent-memory-query.test.js` | Implemented |
95
+ | REQ-FUNC-MEM-009 | MUST | BFS edge traversal with cycle prevention | visited Set prevents infinite loops; frontier-based BFS up to maxDepth | `agent-memory-query.js:followEdges()` | `tests/agent-memory-query.test.js` | Implemented |
96
+ | REQ-FUNC-MEM-010 | MUST | Memory import from babysitter runs | parseJournalForImport extracts importable data; validateMemoryImport checks structure | `agent-memory-import.js` | `tests/agent-memory-import.test.js` | Implemented |
97
+
98
+ ---
99
+
100
+ ## 6. Functional Requirements — External Backend Integration
101
+
102
+ | ID | Priority | Description | Acceptance Criteria | Implementation | Test Coverage | Status |
103
+ |----|----------|-------------|--------------------:|----------------|---------------|--------|
104
+ | REQ-FUNC-EXT-001 | MUST | HMAC-SHA256 webhook signature verification | sha256= prefix; createHmac + timingSafeEqual; reject on mismatch | `external/webhook-controller.js:verifyHmacSignature()` | `tests/external/webhook-controller.test.js` | Implemented |
105
+ | REQ-FUNC-EXT-002 | MUST | Delivery deduplication by ID | isDuplicate(deliveryId) checks Map; processDelivery returns duplicate=true if exists | `external/webhook-controller.js:isDuplicate()` | `tests/external/webhook-controller.test.js` | Implemented |
106
+ | REQ-FUNC-EXT-003 | MUST | Event normalization from raw provider format | normalizeEvent produces canonical { eventType, action, nativeId, providerRef, resourceKind, data, timestamps } | `external/sync-controller.js:normalizeEvent()` | `tests/external/sync-controller.test.js` | Implemented |
107
+ | REQ-FUNC-EXT-004 | MUST | Resource upsert with external envelope | upsertResource stores nativeId, url, etag, providerRef, firstSyncedAt, lastSyncedAt | `external/sync-controller.js:upsertResource()` | `tests/external/sync-controller.test.js` | Implemented |
108
+ | REQ-FUNC-EXT-005 | MUST | High-watermark tracking per binding | updateWatermark only advances forward; getWatermark returns current | `external/sync-controller.js:updateWatermark()` | `tests/external/sync-controller.test.js` | Implemented |
109
+ | REQ-FUNC-EXT-006 | MUST | Ownership mode enforcement | bidirectional=allow all; external-owned=block kradle writes; kradle-owned=block external writes | `external/sync-controller.js:applyOwnershipMode()` | `tests/external/sync-controller.test.js` | Implemented |
110
+ | REQ-FUNC-EXT-007 | MUST | Tombstone creation for deleted externals | createTombstone stores nativeId, providerRef, localRef, deletedAt, tombstoned=true | `external/sync-controller.js:createTombstone()` | `tests/external/sync-controller.test.js` | Implemented |
111
+ | REQ-FUNC-EXT-008 | MUST | Field-level conflict detection | detectConflict compares localValue vs externalValue; creates ExternalSyncConflict if different | `external/conflict-controller.js:detectConflict()` | `tests/external/conflict-controller.test.js` | Implemented |
112
+ | REQ-FUNC-EXT-009 | MUST | Conflict resolution with 4 strategies | prefer-external, prefer-kradle, manual, ignore; resolveConflict sets phase=Resolved | `external/conflict-controller.js:resolveConflict()` | `tests/external/conflict-controller.test.js` | Implemented |
113
+ | REQ-FUNC-EXT-010 | MUST | Write intent lifecycle with approval | createWriteIntent → PendingApproval → ReadyToSend → Sending → Succeeded/Failed | `external/write-controller.js` | `tests/external/write-controller.test.js` | Implemented |
114
+ | REQ-FUNC-EXT-011 | MUST | Write intent idempotency key | Deterministic djb2 hash of (interfaceKey, operation, resourceRef, payload) | `external/write-controller.js:getIdempotencyKey()` | `tests/external/write-controller.test.js` | Implemented |
115
+ | REQ-FUNC-EXT-012 | MUST | GitHub adapter (auth, git-forge, issues, CI) | Separate modules: auth.js, git-forge.js, issue-tracking.js, cicd.js, index.js | `external/github/` | `tests/external/github/` | Implemented |
116
+
117
+ ---
118
+
119
+ ## 7. Non-Functional Requirements — Performance
120
+
121
+ | ID | Priority | Description | Acceptance Criteria | Implementation | Status |
122
+ |----|----------|-------------|--------------------:|----------------|--------|
123
+ | NFR-PERF-001 | MUST | Stale-while-revalidate cache with 30s TTL | Return stale data immediately; background refresh; configurable via KRADLE_SNAPSHOT_CACHE_TTL_MS | `snapshot-cache.js:staleWhileRevalidate()` | Implemented |
124
+ | NFR-PERF-002 | MUST | Per-org independent cache entries | Map-based; each org revalidates independently | `snapshot-cache.js:orgCacheMap` | Implemented |
125
+ | NFR-PERF-003 | MUST | Event batching with configurable flush | maxBatchSize=50, flushIntervalMs=1000; fire-and-forget on size limit | `async-controller.js:createEventBatcher()` | Implemented |
126
+ | NFR-PERF-004 | MUST | Exponential backoff retry with jitter | baseDelay * 2^attempt, capped at maxDelay; full-jitter option | `async-controller.js:createRetryPolicy()` | Implemented |
127
+ | NFR-PERF-005 | MUST | Concurrent delivery queue | configurable concurrency (default 5); ordered processing | `async-controller.js:createDeliveryQueue()` | Implemented |
128
+ | NFR-PERF-006 | MUST | SSE heartbeat every 30 seconds | setInterval(30000) writes heartbeat JSON | `http-server.js` line 302 | Implemented |
129
+ | NFR-PERF-007 | MUST | kubectl timeout protection | spawnSync with configurable timeout (default 3s) | `kubernetes-controller.js:runKubectl()` | Implemented |
130
+ | NFR-PERF-008 | MUST | 32MB kubectl output buffer | maxBuffer: KRADLE_KUBECTL_MAX_BUFFER_BYTES | `kubernetes-controller.js:runKubectl()` | Implemented |
131
+
132
+ ---
133
+
134
+ ## 8. Non-Functional Requirements — Security
135
+
136
+ | ID | Priority | Description | Acceptance Criteria | Implementation | Status |
137
+ |----|----------|-------------|--------------------:|----------------|--------|
138
+ | NFR-SEC-001 | MUST | HMAC-SHA256 session cookie signing | createHmac('sha256', secret).update(payload).digest('base64url') | `auth.js:createSessionCookie()` | Implemented |
139
+ | NFR-SEC-002 | MUST | Timing-safe signature comparison | `timingSafeEqual` from node:crypto; length check before compare | `auth.js:parseSessionCookie()` line 189 | Implemented |
140
+ | NFR-SEC-003 | MUST | Auth on all mutating API routes | POST/DELETE routes check session; read routes generally unprotected | `http-server.js` | Implemented |
141
+ | NFR-SEC-004 | MUST | Cross-org namespace isolation | applyResource/deleteResourceForOrg verify namespace matches org | `api-controller.js` lines 85-100 | Implemented |
142
+ | NFR-SEC-005 | MUST | HMAC-SHA256 webhook signature verification | External webhook controller uses timing-safe comparison | `external/webhook-controller.js` | Implemented |
143
+ | NFR-SEC-006 | MUST | Delivery deduplication prevents replay | Map-based check before processing; duplicate returns early | `external/webhook-controller.js:isDuplicate()` | Implemented |
144
+ | NFR-SEC-007 | MUST | No secrets in permission review output | permissionReviewer mustNotOwn: 'secret values' | `agent-permission-review.js` boundary | Implemented |
145
+ | NFR-SEC-008 | MUST | Fork-restricted privileged grants | Untrusted fork detection blocks AgentServiceAccount/AgentSecretGrant auto-approval | `agent-permission-review.js` line 66-73 | Implemented |
146
+
147
+ ---
148
+
149
+ ## 9. Non-Functional Requirements — Reliability
150
+
151
+ | ID | Priority | Description | Acceptance Criteria | Implementation | Status |
152
+ |----|----------|-------------|--------------------:|----------------|--------|
153
+ | NFR-REL-001 | MUST | Audit failures must not crash operations | try/catch around emitAuditEvent; swallowed silently | `api-controller.js:emitAuditEvent()` | Implemented |
154
+ | NFR-REL-002 | MUST | Background revalidation errors reset flag | catch block clears revalidating=false for retry | `snapshot-cache.js:staleWhileRevalidate()` | Implemented |
155
+ | NFR-REL-003 | MUST | Fire-and-forget persistence in external controllers | `Promise.resolve(persistFn(resource)).catch(() => {})` | All external controllers | Implemented |
156
+ | NFR-REL-004 | MUST | Delivery queue error isolation | processItem catches; retries per policy; swallows after max | `async-controller.js:createDeliveryQueue()` | Implemented |
157
+ | NFR-REL-005 | MUST | Graceful degraded snapshot on kubectl failure | Returns partial snapshot with errors[] array; resources empty | `kubernetes-controller.js:getControllerSnapshot()` | Implemented |
158
+
159
+ ---
160
+
161
+ ## 10. Integration Requirements
162
+
163
+ | ID | Priority | Description | Acceptance Criteria | Implementation | Status |
164
+ |----|----------|-------------|--------------------:|----------------|--------|
165
+ | INT-K8S-001 | MUST | Store CONFIG resources as CRDs | kubectl apply/get/delete with kradle.a5c.ai group | `kubernetes-controller.js` | Implemented |
166
+ | INT-K8S-002 | MUST | Use kubectl for all K8s operations | spawnSync/spawn with configurable binary path | `kubernetes-controller.js:runKubectl()` | Implemented |
167
+ | INT-K8S-003 | MUST | In-cluster authentication support | Auto-detect SA token + CA cert; inject --server/--token/--certificate-authority | `kubernetes-controller.js:inClusterKubectlConfig()` | Implemented |
168
+ | INT-K8S-004 | MUST | Namespace auto-creation | ensureNamespace before apply; kubectl create namespace if not exists | `kubernetes-controller.js:ensureNamespace()` | Implemented |
169
+ | INT-K8S-005 | MUST | SubjectAccessReview for permission discovery | `kubectl auth can-i <verb> <resource>` for each CRD | `kubernetes-controller.js:canI()` | Implemented |
170
+ | INT-GITEA-001 | MUST | Repository hosting via Gitea | createGiteaService with baseUrl and token | `gitea-service.js` | Implemented |
171
+ | INT-ATLAS-001 | SHOULD | Atlas graph search for stack builder | fetchAtlasRecordsByKinds queries /api/v1/kinds/{kind}; searchAtlasGraph queries /api/v1/search | `sdk/src/atlas-graph-client.js` | Implemented |
172
+ | INT-GH-001 | MUST | GitHub webhook normalization | normalizeWebhookEvent handles workflow_run, PR, comment, label, push | `http-server.js:normalizeWebhookEvent()` | Implemented |
173
+ | INT-KYVERNO-001 | SHOULD | Kyverno policy engine integration | CRD discovery; controller health check; policy report aggregation | `kubernetes-controller.js:discoverKyverno()` | Implemented |
174
+ | INT-KUBEVELA-001 | SHOULD | KubeVela application delivery | Application, Revision, Component, Trait, Scope discovery | `kubernetes-controller.js:KRADLE_RESOURCES` | Implemented |
175
+
176
+ ---
177
+
178
+ ## 11. Testing Requirements
179
+
180
+ | ID | Description | Framework | Count | Source |
181
+ |----|-------------|-----------|-------|--------|
182
+ | TEST-CORE-001 | Core package unit+integration tests | node:test | 1259 | `packages/kradle/core/package.json` |
183
+ | TEST-SDK-001 | SDK export and integration tests | node:test | 73 | `packages/kradle/sdk/tests/` |
184
+ | TEST-CLI-001 | CLI command and MCP protocol tests | node:test | 51 | `packages/kradle/cli/tests/` |
185
+ | TEST-E2E-001 | End-to-end package validation | npm run e2e | 3 | `packages/kradle/core/package.json` |
186
+ | TEST-SMOKE-001 | MVP smoke assertions | npm run smoke | 21 | `packages/kradle/core/package.json` |
187
+ | TEST-WEB-001 | Web console build validation | npm run build | 1 | `packages/kradle/web/package.json` |
188
+
189
+
190
+ ---
191
+
192
+ ## Inference Management Requirements
193
+
194
+ | ID | Title | Priority | Description |
195
+ |----|-------|----------|-------------|
196
+ | REQ-FUNC-INFERENCE-001 | KradleInferenceService CRUD | Must | Create, read, update, delete KradleInferenceService resources via Kradle API |
197
+ | REQ-FUNC-INFERENCE-002 | KServe manifest generation | Must | Translate KradleInferenceService spec to valid KServe InferenceService CRD manifest and apply it |
198
+ | REQ-FUNC-INFERENCE-003 | Serving runtime management | Must | Create and manage KradleServingRuntime resources referencing KServe ServingRuntime CRDs |
199
+ | REQ-FUNC-INFERENCE-004 | Endpoint discovery | Must | Resolve inference endpoint URL from KServe status.url after service readiness |
200
+ | REQ-FUNC-INFERENCE-005 | Inference proxy | Should | Proxy V1/V2 inference requests through the API to the resolved service endpoint |
201
+ | REQ-FUNC-INFERENCE-006 | Provider bridge | Must | Convert KradleInferenceService to AgentProviderConfig with type kserve for agent stack integration |
202
+ | REQ-FUNC-INFERENCE-007 | Model format validation | Must | Validate model format against SUPPORTED_MODEL_FORMATS before applying KServe manifest |
203
+ | REQ-FUNC-INFERENCE-008 | Web console inference pages | Should | Service list, detail, test panel, runtime manager pages in the web console |
204
+
205
+ ---
206
+
207
+ ## Artifact Registry Requirements
208
+
209
+ | ID | Title | Priority | Description |
210
+ |----|-------|----------|-------------|
211
+ | REQ-FUNC-ARTIFACT-001 | Registry CRUD | Must | Create, read, update, delete ArtifactRegistry resources |
212
+ | REQ-FUNC-ARTIFACT-002 | Feed management | Must | Create and manage ArtifactFeed resources within a registry |
213
+ | REQ-FUNC-ARTIFACT-003 | Version publishing | Must | Publish ArtifactVersion records with checksums (sha256, md5) and metadata |
214
+ | REQ-FUNC-ARTIFACT-004 | Access policy enforcement | Must | Enforce ArtifactAccessPolicy (read/write/admin) per feed and subject |
215
+ | REQ-FUNC-ARTIFACT-005 | Download tracking | Should | Record ArtifactDownload for each package download with IP, userAgent, clientId |
216
+ | REQ-FUNC-ARTIFACT-006 | Storage backend support | Must | Support internal (etcd), S3, Azure Blob, and GCS storage backends |
217
+ | REQ-FUNC-ARTIFACT-007 | External integration | Should | Sync/mirror feeds with external providers (GitHub Packages, etc.) |
218
+ | REQ-FUNC-ARTIFACT-008 | Install command generation | Should | Generate protocol-specific install commands per feed type (npm, pip, docker) |
219
+ | REQ-FUNC-ARTIFACT-009 | Retention policy | Should | Prune old versions based on maxVersions or maxAgeDays retention policy on publish |
220
+ | REQ-FUNC-ARTIFACT-010 | Web console artifact pages | Should | Registry list, feed browser, version table, access policy pages |
221
+
222
+ ---
223
+
224
+ ## Assistant Agent Requirements
225
+
226
+ | ID | Title | Priority | Description |
227
+ |----|-------|----------|-------------|
228
+ | REQ-FUNC-ASSISTANT-001 | In-process chat runtime | Must | Provide assistant chat via in-process Anthropic API calls, not K8s Job dispatch |
229
+ | REQ-FUNC-ASSISTANT-002 | Session persistence | Must | Maintain message history per org:sessionId in process memory (globalThis) across requests |
230
+ | REQ-FUNC-ASSISTANT-003 | SSE streaming | Must | Stream chat responses as Server-Sent Events with real-time chunk delivery |
231
+ | REQ-FUNC-ASSISTANT-004 | Structured generation | Should | Support structured JSON output via generate endpoint with optional JSON schema |
232
+ | REQ-FUNC-ASSISTANT-005 | Session management | Must | List and clear sessions per org; sessions expire with process restart |
233
+ | REQ-FUNC-ASSISTANT-006 | AgentStack selector | Should | Allow using different AgentStack CRDs for different conversation contexts |
234
+ | REQ-FUNC-ASSISTANT-007 | Tool definitions | Should | Pass tool definitions through to Anthropic API model calls |
235
+ | REQ-FUNC-ASSISTANT-008 | Web console assistant pages | Should | Chat interface, generation form, session sidebar |
@@ -0,0 +1,87 @@
1
+ # MVP Roadmap
2
+
3
+ ## MVP promise
4
+
5
+ A user can install Kradle, create a repository resource, push Git content, create/review a PR, run CI through ARC with Workload Identity, and apply a Kyverno policy that blocks a PR while the same policy appears in the UI.
6
+
7
+ ## Six-week plan
8
+
9
+ ### Weeks 1-2: Aggregated API server
10
+
11
+ Deliverables:
12
+
13
+ - `Repository` and `PullRequest` resources with Kubernetes discovery.
14
+ - Postgres-backed storage for aggregated resources.
15
+ - Working `kubectl get/create` flows.
16
+ - Initial RBAC and admission compatibility.
17
+
18
+ Exit criteria:
19
+
20
+ - PR creation and listing work through `kubectl`.
21
+ - PR data is not stored as large etcd objects.
22
+
23
+ ### Week 3: Gitea-backed data plane
24
+
25
+ Deliverables:
26
+
27
+ - Gitea-backed smart-HTTP and SSH pathing.
28
+ - Single Gitea backend with persistent repository storage.
29
+ - `git-upload-pack` and `git-receive-pack` support.
30
+ - Repository operator creates Gitea repository integration plans.
31
+
32
+ Exit criteria:
33
+
34
+ - `kubectl create -f repo.yaml` followed by `git push` works.
35
+
36
+ ### Week 4: Next.js skeleton
37
+
38
+ Deliverables:
39
+
40
+ - OIDC login skeleton.
41
+ - Repo list and file view.
42
+ - PR list.
43
+ - Watch API to SSE route.
44
+ - GitOps-transparent mutation panel pattern.
45
+
46
+ Exit criteria:
47
+
48
+ - Repo and PR pages update from watch streams.
49
+
50
+ ### Week 5: PR creation and review
51
+
52
+ Deliverables:
53
+
54
+ - PR creation flow.
55
+ - Inline diff view.
56
+ - Comment threads.
57
+ - Pipeline status in PR rail.
58
+
59
+ Exit criteria:
60
+
61
+ - Developer can create and review a PR in the UI.
62
+
63
+ ### Week 6: CI identity and demo
64
+
65
+ Deliverables:
66
+
67
+ - ARC-backed workflow execution.
68
+ - Workload Identity for CI jobs.
69
+ - Demo Kyverno PR policy.
70
+ - Outbound webhook and delivery log.
71
+ - Helm chart packaging.
72
+
73
+ Exit criteria:
74
+
75
+ - Public demo path: `helm install kradle`; create repo; push; create PR; run CI; policy blocks a PR; UI shows policy and delivery state.
76
+
77
+ ## Post-MVP roadmap
78
+
79
+ - v0.2: Live run view refinements, `RefPolicy` with WASM hooks, scaled Gitea data plane, and richer saved `View`/`Selector` templates.
80
+ - v0.3: Zoekt code search, multi-cluster federation, richer insights and cost attribution.
81
+
82
+ ## Open decisions
83
+
84
+ - Commit to aggregated API server over pure CRDs for high-cardinality resources.
85
+ - Choose ARC-only MVP or executor-pluggable runner abstraction from day one.
86
+ - Decide whether to bundle Kyverno or support BYO only.
87
+ - Decide final product name before public README and chart publication.