@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,255 @@
1
+ // Agent Memory Repository & Source Controller — Slice 2.3a
2
+ //
3
+ // AgentMemoryRepository: org-level memory storage pointer, git repo ref validation.
4
+ // AgentMemorySource: read policies for memory paths, access control.
5
+
6
+ // ---------------------------------------------------------------------------
7
+ // Boundaries
8
+ // ---------------------------------------------------------------------------
9
+
10
+ export const AGENT_MEMORY_REPOSITORY_CONTROLLER_BOUNDARY = {
11
+ role: 'agent-memory-repository-controller',
12
+ scope: 'AgentMemoryRepository lifecycle: validation, repo URL resolution, retention policy defaults',
13
+ owns: ['memory repository validation', 'repo URL', 'retention policy defaults'],
14
+ delegatesTo: ['resource-model'],
15
+ mustNotOwn: ['git operations', 'secret values', 'Agent Mux sessions', 'memory search']
16
+ };
17
+
18
+ export const AGENT_MEMORY_SOURCE_CONTROLLER_BOUNDARY = {
19
+ role: 'agent-memory-source-controller',
20
+ scope: 'AgentMemorySource lifecycle: validation, read policy, included/excluded paths, access control',
21
+ owns: ['memory source validation', 'read policy defaults', 'included paths', 'excluded paths'],
22
+ delegatesTo: ['resource-model'],
23
+ mustNotOwn: ['git operations', 'secret values', 'Agent Mux sessions', 'memory search']
24
+ };
25
+
26
+ // ---------------------------------------------------------------------------
27
+ // Constants — defaults
28
+ // ---------------------------------------------------------------------------
29
+
30
+ const DEFAULT_RETENTION_POLICY = Object.freeze({
31
+ maxAgeDays: 90,
32
+ maxSizeMb: 500,
33
+ });
34
+
35
+ const DEFAULT_READ_POLICY = Object.freeze({
36
+ mode: 'allow-all',
37
+ maxDepth: 5,
38
+ });
39
+
40
+ // Valid git/http/ssh URL schemes
41
+ // Accepted forms:
42
+ // https://... http://... ssh://... git://... git@host:path (SCP-style)
43
+ const VALID_REPO_URL_PATTERNS = [
44
+ /^https?:\/\//,
45
+ /^ssh:\/\//,
46
+ /^git:\/\//,
47
+ /^git@[^:]+:.+/,
48
+ ];
49
+
50
+ // ---------------------------------------------------------------------------
51
+ // Standalone validateMemoryRepository
52
+ // ---------------------------------------------------------------------------
53
+
54
+ /**
55
+ * Validate an AgentMemoryRepository resource. Returns { valid, errors }.
56
+ * @param {object} resource
57
+ * @returns {{ valid: boolean, errors: string[] }}
58
+ */
59
+ export function validateMemoryRepository(resource) {
60
+ const errors = [];
61
+
62
+ // Guard against null/undefined
63
+ if (resource == null) {
64
+ errors.push('resource must not be null or undefined');
65
+ return { valid: false, errors };
66
+ }
67
+
68
+ // Validate metadata.name
69
+ if (!resource.metadata?.name) {
70
+ errors.push('metadata.name is required');
71
+ }
72
+
73
+ const spec = resource.spec || {};
74
+
75
+ // Validate organizationRef
76
+ if (!spec.organizationRef) {
77
+ errors.push('spec.organizationRef is required');
78
+ }
79
+
80
+ // Validate repoUrl — presence
81
+ if (!spec.repoUrl) {
82
+ errors.push('spec.repoUrl is required; provide a git/http/ssh repository URL');
83
+ } else {
84
+ // Validate repoUrl — format (git/http/ssh/scp-style)
85
+ const isValid = VALID_REPO_URL_PATTERNS.some((re) => re.test(spec.repoUrl));
86
+ if (!isValid) {
87
+ errors.push(
88
+ 'spec.repoUrl must be a valid git repository URL (https://, http://, ssh://, git://, or git@host:path format)'
89
+ );
90
+ }
91
+ }
92
+
93
+ return { valid: errors.length === 0, errors };
94
+ }
95
+
96
+ // ---------------------------------------------------------------------------
97
+ // AgentMemoryRepository controller factory
98
+ // ---------------------------------------------------------------------------
99
+
100
+ /**
101
+ * Factory that returns an AgentMemoryRepository controller instance.
102
+ */
103
+ export function createAgentMemoryRepositoryController() {
104
+ return {
105
+ role: 'agent-memory-repository-controller',
106
+
107
+ /**
108
+ * Validate an AgentMemoryRepository resource.
109
+ * @param {object} resource
110
+ * @returns {{ valid: boolean, errors: string[] }}
111
+ */
112
+ validateMemoryRepository(resource) {
113
+ return validateMemoryRepository(resource);
114
+ },
115
+
116
+ /**
117
+ * Return the repository URL configured in spec.repoUrl.
118
+ * @param {object} resource
119
+ * @returns {string}
120
+ */
121
+ getRepositoryUrl(resource) {
122
+ if (resource == null) {
123
+ throw new Error('resource must not be null or undefined');
124
+ }
125
+ return resource.spec?.repoUrl ?? null;
126
+ },
127
+
128
+ /**
129
+ * Return the effective retention policy for the memory repository.
130
+ * Merges spec.retentionPolicy with defaults; spec values take precedence.
131
+ * Defaults: maxAgeDays = 90, maxSizeMb = 500.
132
+ * @param {object} resource
133
+ * @returns {{ maxAgeDays: number, maxSizeMb: number }}
134
+ */
135
+ getRetentionPolicy(resource) {
136
+ if (resource == null) {
137
+ throw new Error('resource must not be null or undefined');
138
+ }
139
+ const specPolicy = resource.spec?.retentionPolicy ?? {};
140
+ return {
141
+ maxAgeDays: specPolicy.maxAgeDays ?? DEFAULT_RETENTION_POLICY.maxAgeDays,
142
+ maxSizeMb: specPolicy.maxSizeMb ?? DEFAULT_RETENTION_POLICY.maxSizeMb,
143
+ };
144
+ },
145
+ };
146
+ }
147
+
148
+ // ---------------------------------------------------------------------------
149
+ // Standalone validateMemorySource
150
+ // ---------------------------------------------------------------------------
151
+
152
+ /**
153
+ * Validate an AgentMemorySource resource. Returns { valid, errors }.
154
+ * @param {object} resource
155
+ * @returns {{ valid: boolean, errors: string[] }}
156
+ */
157
+ export function validateMemorySource(resource) {
158
+ const errors = [];
159
+
160
+ // Guard against null/undefined
161
+ if (resource == null) {
162
+ errors.push('resource must not be null or undefined');
163
+ return { valid: false, errors };
164
+ }
165
+
166
+ // Validate metadata.name
167
+ if (!resource.metadata?.name) {
168
+ errors.push('metadata.name is required');
169
+ }
170
+
171
+ const spec = resource.spec || {};
172
+
173
+ // Validate organizationRef
174
+ if (!spec.organizationRef) {
175
+ errors.push('spec.organizationRef is required');
176
+ }
177
+
178
+ // Validate repositoryRef
179
+ if (!spec.repositoryRef) {
180
+ errors.push('spec.repositoryRef is required; provide a reference to the AgentMemoryRepository');
181
+ }
182
+
183
+ // Validate paths — must be present and non-empty
184
+ const paths = spec.paths;
185
+ if (!Array.isArray(paths) || paths.length === 0) {
186
+ errors.push('spec.paths must be a non-empty array of memory path patterns');
187
+ }
188
+
189
+ return { valid: errors.length === 0, errors };
190
+ }
191
+
192
+ // ---------------------------------------------------------------------------
193
+ // AgentMemorySource controller factory
194
+ // ---------------------------------------------------------------------------
195
+
196
+ /**
197
+ * Factory that returns an AgentMemorySource controller instance.
198
+ */
199
+ export function createAgentMemorySourceController() {
200
+ return {
201
+ role: 'agent-memory-source-controller',
202
+
203
+ /**
204
+ * Validate an AgentMemorySource resource.
205
+ * @param {object} resource
206
+ * @returns {{ valid: boolean, errors: string[] }}
207
+ */
208
+ validateMemorySource(resource) {
209
+ return validateMemorySource(resource);
210
+ },
211
+
212
+ /**
213
+ * Return the effective read policy for the memory source.
214
+ * Merges spec.readPolicy with defaults; spec values take precedence.
215
+ * Defaults: mode = 'allow-all', maxDepth = 5.
216
+ * @param {object} resource
217
+ * @returns {{ mode: string, maxDepth: number }}
218
+ */
219
+ getReadPolicy(resource) {
220
+ if (resource == null) {
221
+ throw new Error('resource must not be null or undefined');
222
+ }
223
+ const specPolicy = resource.spec?.readPolicy ?? {};
224
+ return {
225
+ mode: specPolicy.mode ?? DEFAULT_READ_POLICY.mode,
226
+ maxDepth: specPolicy.maxDepth ?? DEFAULT_READ_POLICY.maxDepth,
227
+ };
228
+ },
229
+
230
+ /**
231
+ * Return the included memory path patterns from spec.paths.
232
+ * @param {object} resource
233
+ * @returns {string[]}
234
+ */
235
+ getIncludedPaths(resource) {
236
+ if (resource == null) {
237
+ throw new Error('resource must not be null or undefined');
238
+ }
239
+ return Array.isArray(resource.spec?.paths) ? [...resource.spec.paths] : [];
240
+ },
241
+
242
+ /**
243
+ * Return the excluded memory path patterns from spec.excludedPaths.
244
+ * Returns an empty array when not set.
245
+ * @param {object} resource
246
+ * @returns {string[]}
247
+ */
248
+ getExcludedPaths(resource) {
249
+ if (resource == null) {
250
+ throw new Error('resource must not be null or undefined');
251
+ }
252
+ return Array.isArray(resource.spec?.excludedPaths) ? [...resource.spec.excludedPaths] : [];
253
+ },
254
+ };
255
+ }