@a5c-ai/krate 5.0.1-staging.f672fe79b

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 (174) hide show
  1. package/Dockerfile +29 -0
  2. package/README.md +183 -0
  3. package/bin/krate-demo.mjs +23 -0
  4. package/bin/krate-server.mjs +14 -0
  5. package/dist/krate-controller-ui.json +2407 -0
  6. package/dist/krate-lifecycle.json +201 -0
  7. package/dist/krate-runtime-snapshot.json +2955 -0
  8. package/dist/krate-summary.json +687 -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/glossary.md +66 -0
  27. package/docs/agents/implementation-blueprint.md +324 -0
  28. package/docs/agents/implementation-rollout-slices.md +251 -0
  29. package/docs/agents/memory-context-integration-spec.md +194 -0
  30. package/docs/agents/memory-ontology-schema-spec.md +253 -0
  31. package/docs/agents/memory-operations-runbook.md +121 -0
  32. package/docs/agents/mvp-vertical-slice-spec.md +146 -0
  33. package/docs/agents/observability-audit-spec.md +265 -0
  34. package/docs/agents/operator-runbook.md +174 -0
  35. package/docs/agents/org-memory-api-payload-examples.md +333 -0
  36. package/docs/agents/org-memory-controller-sequence-spec.md +181 -0
  37. package/docs/agents/org-memory-e2e-fixture-plan.md +161 -0
  38. package/docs/agents/org-memory-ui-implementation-map.md +114 -0
  39. package/docs/agents/org-memory-vertical-slice-spec.md +168 -0
  40. package/docs/agents/org-resource-model-delta-spec.md +111 -0
  41. package/docs/agents/org-route-resource-model-spec.md +183 -0
  42. package/docs/agents/org-scoping-namespace-spec.md +114 -0
  43. package/docs/agents/rbac-secrets-management-spec.md +406 -0
  44. package/docs/agents/repository-page-integration-spec.md +255 -0
  45. package/docs/agents/resource-contract-examples.md +808 -0
  46. package/docs/agents/resource-relationship-map.md +190 -0
  47. package/docs/agents/security-threat-model.md +188 -0
  48. package/docs/agents/shared-memory-company-brain-spec.md +358 -0
  49. package/docs/agents/storage-migration-spec.md +168 -0
  50. package/docs/agents/subagent-orchestration-spec.md +152 -0
  51. package/docs/agents/system-overview.md +88 -0
  52. package/docs/agents/tools-mcp-skills-spec.md +189 -0
  53. package/docs/agents/traceability-matrix.md +79 -0
  54. package/docs/agents/ui-flow-spec.md +211 -0
  55. package/docs/agents/ui-ux-system-spec.md +426 -0
  56. package/docs/agents/workspace-lifecycle-spec.md +166 -0
  57. package/docs/architecture-spec.md +78 -0
  58. package/docs/components/control-plane.md +78 -0
  59. package/docs/components/data-plane.md +69 -0
  60. package/docs/components/hooks-events.md +67 -0
  61. package/docs/components/identity-rbac-policy.md +73 -0
  62. package/docs/components/kubevela-oam.md +70 -0
  63. package/docs/components/operations-publishing.md +81 -0
  64. package/docs/components/runners-ci.md +66 -0
  65. package/docs/components/web-ui.md +94 -0
  66. package/docs/external/README.md +47 -0
  67. package/docs/external/bidirectional-sync-design.md +134 -0
  68. package/docs/external/cicd-interface.md +64 -0
  69. package/docs/external/external-backend-controllers.md +170 -0
  70. package/docs/external/external-backend-crds.md +234 -0
  71. package/docs/external/external-backend-ui-spec.md +151 -0
  72. package/docs/external/external-backend-ux-flows.md +115 -0
  73. package/docs/external/external-object-mapping.md +125 -0
  74. package/docs/external/git-forge-interface.md +68 -0
  75. package/docs/external/github-integration-design.md +151 -0
  76. package/docs/external/issue-tracking-interface.md +66 -0
  77. package/docs/external/provider-capability-manifests.md +204 -0
  78. package/docs/external/provider-catalog.md +139 -0
  79. package/docs/external/provider-rollout-testing.md +78 -0
  80. package/docs/external/research-results.md +48 -0
  81. package/docs/external/security-auth-permissions.md +81 -0
  82. package/docs/external/sync-state-machines.md +108 -0
  83. package/docs/external/unified-external-backend-model.md +107 -0
  84. package/docs/external/user-facing-changes.md +67 -0
  85. package/docs/gaps.md +161 -0
  86. package/docs/install.md +94 -0
  87. package/docs/krate-design.md +334 -0
  88. package/docs/local-minikube.md +55 -0
  89. package/docs/ontology/README.md +32 -0
  90. package/docs/ontology/bounded-contexts.md +29 -0
  91. package/docs/ontology/events-and-hooks.md +32 -0
  92. package/docs/ontology/oam-kubevela.md +32 -0
  93. package/docs/ontology/operations-and-release.md +25 -0
  94. package/docs/ontology/personas-and-actors.md +32 -0
  95. package/docs/ontology/policies-and-invariants.md +33 -0
  96. package/docs/ontology/problem-space.md +30 -0
  97. package/docs/ontology/resource-contracts.md +40 -0
  98. package/docs/ontology/resource-taxonomy.md +42 -0
  99. package/docs/ontology/runners-and-ci.md +29 -0
  100. package/docs/ontology/solution-space.md +24 -0
  101. package/docs/ontology/storage-and-data-boundaries.md +29 -0
  102. package/docs/ontology/validation-matrix.md +24 -0
  103. package/docs/ontology/web-ui-excellent-flows.md +32 -0
  104. package/docs/ontology/workflows.md +39 -0
  105. package/docs/ontology/world.md +35 -0
  106. package/docs/product-requirements.md +62 -0
  107. package/docs/roadmap-mvp.md +87 -0
  108. package/docs/system-requirements.md +90 -0
  109. package/docs/tests/README.md +53 -0
  110. package/docs/tests/agent-qa-plan.md +63 -0
  111. package/docs/tests/browser-ui-tests.md +62 -0
  112. package/docs/tests/ci-quality-gates.md +48 -0
  113. package/docs/tests/coverage-model.md +64 -0
  114. package/docs/tests/e2e-scenario-tests.md +53 -0
  115. package/docs/tests/fixtures-test-data.md +63 -0
  116. package/docs/tests/observability-reliability-tests.md +54 -0
  117. package/docs/tests/product-test-matrix.md +145 -0
  118. package/docs/tests/qa-adoption-roadmap.md +130 -0
  119. package/docs/tests/qa-automation-plan.md +101 -0
  120. package/docs/tests/security-compliance-tests.md +57 -0
  121. package/docs/tests/test-framework-tools.md +88 -0
  122. package/docs/tests/test-suite-layout.md +121 -0
  123. package/docs/tests/unit-integration-tests.md +48 -0
  124. package/docs/todo-kyverno +714 -0
  125. package/docs/user-stories.md +78 -0
  126. package/examples/minikube-demo.yaml +190 -0
  127. package/examples/oam-application.yaml +23 -0
  128. package/examples/policy-kyverno-pr-title.yaml +18 -0
  129. package/package.json +63 -0
  130. package/scripts/build.mjs +29 -0
  131. package/scripts/setup-minikube.mjs +65 -0
  132. package/scripts/smoke.mjs +37 -0
  133. package/scripts/validate-doc-coverage.mjs +152 -0
  134. package/scripts/validate-package.mjs +93 -0
  135. package/scripts/validate-ui.mjs +207 -0
  136. package/src/agent-approval-controller.js +123 -0
  137. package/src/agent-context-bundles.js +242 -0
  138. package/src/agent-dispatch-controller.js +86 -0
  139. package/src/agent-mux-client.js +280 -0
  140. package/src/agent-permission-review.js +162 -0
  141. package/src/agent-stack-controller.js +296 -0
  142. package/src/agent-trigger-controller.js +108 -0
  143. package/src/api-controller.js +206 -0
  144. package/src/argocd-gitops.js +43 -0
  145. package/src/auth.js +265 -0
  146. package/src/component-catalog.js +41 -0
  147. package/src/control-plane.js +136 -0
  148. package/src/controller-client.js +38 -0
  149. package/src/controller-ui.js +538 -0
  150. package/src/data-plane.js +178 -0
  151. package/src/gitea-backend.js +95 -0
  152. package/src/handoff.js +98 -0
  153. package/src/hooks-events.js +63 -0
  154. package/src/http-server.js +151 -0
  155. package/src/identity-policy.js +86 -0
  156. package/src/index.js +30 -0
  157. package/src/kubernetes-controller.js +812 -0
  158. package/src/kubernetes-resource-gateway.js +48 -0
  159. package/src/operations.js +112 -0
  160. package/src/resource-model.js +203 -0
  161. package/src/runners-ci.js +48 -0
  162. package/src/runtime.js +196 -0
  163. package/src/web-ui.js +40 -0
  164. package/tests/agent-approval-controller.test.js +173 -0
  165. package/tests/agent-context-bundles.test.js +278 -0
  166. package/tests/agent-dispatch-controller.test.js +176 -0
  167. package/tests/agent-mux-client.test.js +204 -0
  168. package/tests/agent-permission-review.test.js +209 -0
  169. package/tests/agent-resources.test.js +212 -0
  170. package/tests/agent-stack-controller.test.js +221 -0
  171. package/tests/agent-trigger-controller.test.js +211 -0
  172. package/tests/deployment.test.js +395 -0
  173. package/tests/e2e/lifecycle.test.js +117 -0
  174. package/tests/krate.test.js +727 -0
@@ -0,0 +1,136 @@
1
+ import { clone, matchLabels, resourceKey, storageClassForKind, toKubernetesList, validateResource } from './resource-model.js';
2
+ import { defaultAuthorizer, evaluateAdmission } from './identity-policy.js';
3
+
4
+ export const STORAGE_BOUNDARY_DESCRIPTIONS = { etcd: 'Kubernetes etcd CRD config', postgres: 'Aggregated API Postgres records' };
5
+
6
+ export class ControlPlane {
7
+ constructor({ authorizer = defaultAuthorizer(), admissionPolicies = [] } = {}) {
8
+ this.authorizer = authorizer;
9
+ this.admissionPolicies = admissionPolicies;
10
+ this.stores = { etcd: new Map(), postgres: new Map() };
11
+ this.auditLog = [];
12
+ this.events = [];
13
+ this.watchers = new Map();
14
+ }
15
+
16
+ addAdmissionPolicy(policy) { this.admissionPolicies.push(policy); }
17
+ create(resource, user) { return this.#mutate('create', resource, user); }
18
+ update(resource, user) { return this.#mutate('update', resource, user); }
19
+
20
+ patchStatus(kind, namespace, name, statusPatch, user) {
21
+ const existing = this.get(kind, namespace, name);
22
+ if (!existing) throw new Error(`${kind}/${namespace}/${name} not found`);
23
+ const next = clone(existing);
24
+ next.status = { ...next.status, ...clone(statusPatch) };
25
+ return this.#mutate('update', next, user, { statusOnly: true });
26
+ }
27
+
28
+ get(kind, namespace = 'default', name) {
29
+ const storage = storageClassForKind(kind);
30
+ return clone(this.stores[storage].get(`${kind}/${namespace}/${name}`));
31
+ }
32
+
33
+ list(kind, { namespace, labels } = {}) {
34
+ const storage = storageClassForKind(kind);
35
+ const items = [...this.stores[storage].values()]
36
+ .filter((resource) => resource.kind === kind)
37
+ .filter((resource) => !namespace || resource.metadata.namespace === namespace)
38
+ .filter((resource) => !labels || matchLabels(resource, labels))
39
+ .map(clone);
40
+ return toKubernetesList(kind, items);
41
+ }
42
+
43
+ watch(kind, handler) {
44
+ if (!this.watchers.has(kind)) this.watchers.set(kind, new Set());
45
+ this.watchers.get(kind).add(handler);
46
+ return () => this.watchers.get(kind)?.delete(handler);
47
+ }
48
+
49
+ storageReport() {
50
+ return {
51
+ etcd: [...this.stores.etcd.values()].map((resource) => resource.kind),
52
+ postgres: [...this.stores.postgres.values()].map((resource) => resource.kind)
53
+ };
54
+ }
55
+
56
+ exportSnapshot() {
57
+ return {
58
+ apiVersion: 'krate.a5c.ai/v1alpha1',
59
+ kind: 'ControlPlaneSnapshot',
60
+ stores: {
61
+ etcd: [...this.stores.etcd.values()].map(clone),
62
+ postgres: [...this.stores.postgres.values()].map(clone)
63
+ },
64
+ auditLog: clone(this.auditLog),
65
+ events: clone(this.events)
66
+ };
67
+ }
68
+
69
+ importSnapshot(snapshot) {
70
+ if (!snapshot || typeof snapshot !== 'object') throw new Error('snapshot must be an object');
71
+ const stores = snapshot.stores || {};
72
+ const nextStores = { etcd: new Map(), postgres: new Map() };
73
+ for (const storage of ['etcd', 'postgres']) {
74
+ for (const resource of stores[storage] || []) {
75
+ const valid = validateResource(clone(resource));
76
+ const expectedStorage = storageClassForKind(valid.kind);
77
+ if (expectedStorage !== storage) throw new Error(`${valid.kind} belongs in ${expectedStorage}, not ${storage}`);
78
+ valid.status.storage = storage;
79
+ nextStores[storage].set(`${valid.kind}/${valid.metadata.namespace}/${valid.metadata.name}`, clone(valid));
80
+ }
81
+ }
82
+ this.stores = nextStores;
83
+ this.auditLog = clone(snapshot.auditLog || []);
84
+ this.events = clone(snapshot.events || []);
85
+ this.#emit({ type: 'snapshot.imported', storage: 'control-plane', resource: createSnapshotResource(this.exportSnapshot()), audit: null });
86
+ return this.exportSnapshot();
87
+ }
88
+
89
+ #mutate(operation, resource, user, options = {}) {
90
+ const candidate = validateResource(clone(resource));
91
+ const namespace = candidate.metadata.namespace;
92
+ const verb = options.statusOnly ? 'update' : operation;
93
+ if (!this.authorizer.can(user, verb, candidate.kind, namespace)) {
94
+ throw new Error(`RBAC denied ${user?.name || 'anonymous'} ${verb} ${candidate.kind}`);
95
+ }
96
+ const admission = evaluateAdmission(this.admissionPolicies, { operation, resource: candidate, user, options });
97
+ const auditEntry = {
98
+ at: new Date().toISOString(),
99
+ operation,
100
+ user: user?.name || 'anonymous',
101
+ groups: user?.groups || [],
102
+ resource: resourceKey(candidate),
103
+ warnings: admission.warnings,
104
+ allowed: admission.allowed
105
+ };
106
+ this.auditLog.push(auditEntry);
107
+ if (!admission.allowed) {
108
+ const messages = admission.violations.map((violation) => violation.message).join('; ');
109
+ throw new Error(`Admission denied ${candidate.kind}: ${messages}`);
110
+ }
111
+ const storage = storageClassForKind(candidate.kind);
112
+ const key = `${candidate.kind}/${namespace}/${candidate.metadata.name}`;
113
+ candidate.metadata.resourceVersion = String((Number(this.stores[storage].get(key)?.metadata?.resourceVersion || 0) || 0) + 1);
114
+ candidate.status.storage = storage;
115
+ this.stores[storage].set(key, clone(candidate));
116
+ this.#emit({ type: operation, storage, resource: candidate, audit: auditEntry });
117
+ return clone(candidate);
118
+ }
119
+
120
+ #emit(event) {
121
+ const publicEvent = { ...event, resource: clone(event.resource) };
122
+ this.events.push(publicEvent);
123
+ for (const handler of this.watchers.get(event.resource.kind) || []) handler(publicEvent);
124
+ for (const handler of this.watchers.get('*') || []) handler(publicEvent);
125
+ }
126
+ }
127
+
128
+ function createSnapshotResource(snapshot) {
129
+ return {
130
+ apiVersion: 'krate.a5c.ai/v1alpha1',
131
+ kind: 'ControlPlaneSnapshot',
132
+ metadata: { namespace: 'default', name: 'latest', labels: {}, annotations: {}, resourceVersion: '1' },
133
+ spec: { resourceCounts: Object.fromEntries(Object.entries(snapshot.stores).map(([storage, resources]) => [storage, resources.length])) },
134
+ status: { storage: 'control-plane', phase: 'Imported' }
135
+ };
136
+ }
@@ -0,0 +1,38 @@
1
+ import { createControllerUiModel } from './controller-ui.js';
2
+ import { createKrateApiController } from './api-controller.js';
3
+ import { createKubernetesResourceGateway } from './kubernetes-resource-gateway.js';
4
+
5
+ export async function fetchControllerUiModel({ controllerUrl = process.env.KRATE_CONTROLLER_URL, fetchImpl = globalThis.fetch, controller = createKrateApiController({ resourceGateway: createKubernetesResourceGateway() }), organization = process.env.KRATE_ORG || null } = {}) {
6
+ if (controllerUrl) {
7
+ try {
8
+ const target = new URL('/api/controller', controllerUrl);
9
+ if (organization) target.searchParams.set('org', organization);
10
+ const response = await fetchImpl(target, { cache: 'no-store' });
11
+ if (!response.ok) throw new Error(`controller API ${response.status}`);
12
+ return response.json();
13
+ } catch (error) {
14
+ return fallbackControllerModel(controller, error, organization);
15
+ }
16
+ }
17
+ return fallbackControllerModel(controller, null, organization);
18
+ }
19
+
20
+ async function fallbackControllerModel(controller, connectionError = null, organization = null) {
21
+ try {
22
+ const model = createControllerUiModel(await controller.snapshot(), { organization });
23
+ if (connectionError) model.controller.connection.errors = [connectionError.message, ...(model.controller.connection.errors || [])];
24
+ return model;
25
+ } catch (error) {
26
+ return createControllerUiModel({
27
+ source: 'kubernetes',
28
+ namespace: process.env.KRATE_NAMESPACE || 'krate-system',
29
+ kubectl: { available: false, context: null, errors: [connectionError?.message, error.message].filter(Boolean) },
30
+ resources: {},
31
+ crds: [],
32
+ events: [],
33
+ permissions: [],
34
+ storage: {},
35
+ commands: []
36
+ }, { organization });
37
+ }
38
+ }