@a5c-ai/krate 5.0.1-staging.69cb593ea → 5.0.1-staging.6be34ee2a
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.
- package/bin/krate-demo.mjs +0 -0
- package/bin/krate-server.mjs +0 -0
- package/dist/krate-controller-ui.json +5 -5
- package/dist/krate-lifecycle.json +1 -1
- package/dist/krate-runtime-snapshot.json +48 -48
- package/dist/krate-summary.json +3 -3
- package/docs/architecture-v2.md +2389 -285
- package/docs/crd-behaviors-and-relationships.md +3732 -0
- package/docs/integration-and-design-decisions.md +1444 -0
- package/docs/requirements-v2.md +163 -214
- package/docs/sdk-api-reference.md +434 -437
- package/docs/system-spec-v2.md +846 -275
- package/docs/web-console-spec.md +332 -368
- package/package.json +1 -1
package/docs/system-spec-v2.md
CHANGED
|
@@ -1,352 +1,923 @@
|
|
|
1
1
|
# Krate System Specification v2
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Exhaustive system specification derived from implementation source code.
|
|
4
|
+
> Source: `packages/krate/core/src/resource-model.js`, `http-server.js`, controller files.
|
|
5
|
+
|
|
6
|
+
---
|
|
4
7
|
|
|
5
8
|
## 1. Resource Taxonomy
|
|
6
9
|
|
|
7
|
-
All 76 resource kinds from `RESOURCE_DEFINITIONS` in `packages/krate/core/src/resource-model.js
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
|
30
|
-
|
|
31
|
-
|
|
|
32
|
-
|
|
|
33
|
-
|
|
|
34
|
-
|
|
|
35
|
-
|
|
|
36
|
-
|
|
|
37
|
-
|
|
|
38
|
-
|
|
|
39
|
-
|
|
|
40
|
-
|
|
|
41
|
-
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
|
46
|
-
|
|
47
|
-
|
|
|
48
|
-
|
|
|
49
|
-
|
|
|
50
|
-
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
|
55
|
-
|
|
56
|
-
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
|
63
|
-
|
|
64
|
-
|
|
|
65
|
-
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
|
70
|
-
|
|
71
|
-
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
|
76
|
-
|
|
77
|
-
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
|
82
|
-
|
|
83
|
-
|
|
|
84
|
-
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
|
89
|
-
|
|
90
|
-
|
|
|
91
|
-
|
|
|
92
|
-
|
|
|
10
|
+
All 76 resource kinds from `RESOURCE_DEFINITIONS` in `packages/krate/core/src/resource-model.js`.
|
|
11
|
+
Every resource follows the Kubernetes object model:
|
|
12
|
+
|
|
13
|
+
```javascript
|
|
14
|
+
{
|
|
15
|
+
apiVersion: 'krate.a5c.ai/v1alpha1',
|
|
16
|
+
kind: '<ResourceKind>',
|
|
17
|
+
metadata: {
|
|
18
|
+
name: '<unique-name>', // Required: validated by validateResource()
|
|
19
|
+
namespace: '<krate-org-slug>', // Defaults to 'default' if not provided
|
|
20
|
+
labels: { 'krate.a5c.ai/org': '<org>' },
|
|
21
|
+
annotations: {}
|
|
22
|
+
},
|
|
23
|
+
spec: { /* kind-specific; requiredSpec fields validated */ },
|
|
24
|
+
status: { /* storage, phase, conditions */ }
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### 1.1 CONFIG Kinds (etcd storage — 44 kinds)
|
|
29
|
+
|
|
30
|
+
#### Identity Context (11 kinds)
|
|
31
|
+
|
|
32
|
+
| # | Kind | Plural | Required Spec Fields | Purpose |
|
|
33
|
+
|---|------|--------|---------------------|---------|
|
|
34
|
+
| 1 | Organization | organizations | `displayName`, `namespaceName` | Krate organization identity in the platform namespace with a bound tenant namespace |
|
|
35
|
+
| 2 | OrgNamespaceBinding | orgnamespacebindings | `organizationRef`, `namespace` | Binding from one organization to exactly one tenant namespace for resources and side effects |
|
|
36
|
+
| 3 | User | users | `organizationRef`, `displayName`, `email` | Human account profile, sign-in state, admin flag, and linked identities |
|
|
37
|
+
| 4 | Team | teams | `organizationRef`, `displayName` | Team membership, maintainers, and repository permission grants |
|
|
38
|
+
| 5 | Invite | invites | `organizationRef`, `email`, `role` | Pending user invitation with requested teams and expiry |
|
|
39
|
+
| 6 | IdentityMapping | identitymappings | `organizationRef`, `user`, `provider`, `subject` | Mapping between Krate users, sign-in subjects, workspace identities, and repository accounts |
|
|
40
|
+
| 7 | AuthProvider | authproviders | `organizationRef`, `type` | Installation sign-in provider visibility and delegated identity settings |
|
|
41
|
+
| 8 | AgentServiceAccount | agentserviceaccounts | `organizationRef`, `namespace`, `serviceAccountName` | Kubernetes ServiceAccount wrapper for agent/runner identity binding |
|
|
42
|
+
| 9 | AgentRoleBinding | agentrolebindings | `organizationRef`, `subject`, `roleRef`, `scope` | Managed projection to native Kubernetes RBAC for agent identity |
|
|
43
|
+
| 10 | AgentSecretGrant | agentsecretgrants | `organizationRef`, `subject`, `secretRef`, `purpose` | Explicit permission for subject to access Secret keys with purpose scope |
|
|
44
|
+
| 11 | AgentConfigGrant | agentconfiggrants | `organizationRef`, `subject`, `configMapRef`, `purpose` | Explicit permission for subject to access ConfigMap keys with purpose scope |
|
|
45
|
+
|
|
46
|
+
#### Data-Plane Context (4 kinds)
|
|
47
|
+
|
|
48
|
+
| # | Kind | Plural | Required Spec Fields | Purpose |
|
|
49
|
+
|---|------|--------|---------------------|---------|
|
|
50
|
+
| 12 | Repository | repositories | `organizationRef`, `visibility` | Repository identity, visibility, repository hosting integration, object storage, and search settings |
|
|
51
|
+
| 13 | SSHKey | sshkeys | `organizationRef`, `scope`, `key` | User, deploy, and automation SSH keys reconciled into repository key APIs |
|
|
52
|
+
| 14 | RepositoryPermission | repositorypermissions | `organizationRef`, `repository`, `subject`, `permission` | Repository collaborators and teams synced with repository permissions |
|
|
53
|
+
| 15 | RefPolicy | refpolicies | `organizationRef` | Reference deny rules, force-push policy, signing policy, and future custom hook gates |
|
|
54
|
+
|
|
55
|
+
#### Control-Plane Context (1 kind)
|
|
56
|
+
|
|
57
|
+
| # | Kind | Plural | Required Spec Fields | Purpose |
|
|
58
|
+
|---|------|--------|---------------------|---------|
|
|
59
|
+
| 16 | BranchProtection | branchprotections | `organizationRef`, `refs` | Protected ref rules such as pull-request requirements |
|
|
60
|
+
|
|
61
|
+
#### Policy Context (4 kinds)
|
|
62
|
+
|
|
63
|
+
| # | Kind | Plural | Required Spec Fields | Purpose |
|
|
64
|
+
|---|------|--------|---------------------|---------|
|
|
65
|
+
| 17 | PolicyProfile | policyprofiles | `organizationRef`, `displayName`, `mode` | Organization policy posture, default templates, rollout mode, and exception approval rules |
|
|
66
|
+
| 18 | PolicyTemplate | policytemplates | `displayName`, `targetKinds`, `kyverno` | Curated Kyverno policy template metadata, parameters, rollout defaults, and remediation guidance |
|
|
67
|
+
| 19 | PolicyBinding | policybindings | `organizationRef`, `templateRef`, `mode` | Binding from a policy template to org/repo/env with audit/enforce rollout state |
|
|
68
|
+
| 20 | PolicyExceptionRequest | policyexceptionrequests | `organizationRef`, `policyRef`, `justification`, `expiresAt` | Auditable request and approval workflow for temporary Kyverno PolicyException resources |
|
|
69
|
+
|
|
70
|
+
#### Hooks-Events Context (1 kind)
|
|
71
|
+
|
|
72
|
+
| # | Kind | Plural | Required Spec Fields | Purpose |
|
|
73
|
+
|---|------|--------|---------------------|---------|
|
|
74
|
+
| 21 | WebhookSubscription | webhooksubscriptions | `organizationRef`, `url`, `events` | Endpoint, event filters, signing reference, delivery mode, and retry policy |
|
|
75
|
+
|
|
76
|
+
#### Runners-CI Context (1 kind)
|
|
77
|
+
|
|
78
|
+
| # | Kind | Plural | Required Spec Fields | Purpose |
|
|
79
|
+
|---|------|--------|---------------------|---------|
|
|
80
|
+
| 22 | RunnerPool | runnerpools | `organizationRef`, `warmReplicas`, `maxReplicas` | Runner capacity, warm/max replicas, cache policy, and trust boundary |
|
|
81
|
+
|
|
82
|
+
#### Web-UI Context (2 kinds)
|
|
83
|
+
|
|
84
|
+
| # | Kind | Plural | Required Spec Fields | Purpose |
|
|
85
|
+
|---|------|--------|---------------------|---------|
|
|
86
|
+
| 23 | View | views | `organizationRef`, `selector` | Saved triage and dashboard view backed by resource selectors |
|
|
87
|
+
| 24 | Selector | selectors | `organizationRef` | Reusable label/query selector for workflows and views |
|
|
88
|
+
|
|
89
|
+
#### Agents Context (18 kinds)
|
|
90
|
+
|
|
91
|
+
| # | Kind | Plural | Required Spec Fields | Purpose |
|
|
92
|
+
|---|------|--------|---------------------|---------|
|
|
93
|
+
| 25 | AgentStack | agentstacks | `organizationRef`, `baseAgent`, `adapter`, `runtimeIdentity` | Reusable agent definition with model, prompt, tools, MCP servers, skills, subagents, approval mode, and runner policy |
|
|
94
|
+
| 26 | AgentSubagent | agentsubagents | `organizationRef`, `rolePrompt`, `taskKinds` | Named child-agent definition with role, task kinds, tool subset, and workspace scope |
|
|
95
|
+
| 27 | AgentToolProfile | agenttoolprofiles | `organizationRef`, `filesystemPolicy`, `approvalPolicyByTool` | Native tool policy for filesystem, network, shell, and approval gates |
|
|
96
|
+
| 28 | AgentMcpServer | agentmcpservers | `organizationRef`, `transport`, `scope` | Managed MCP endpoint with transport, discovery, health, and secret/config refs |
|
|
97
|
+
| 29 | AgentSkill | agentskills | `organizationRef`, `format`, `sourceRef` | Reusable runbook/procedure bundle with prompt fragments, tool deps, and output contracts |
|
|
98
|
+
| 30 | AgentTriggerRule | agenttriggerrules | `organizationRef`, `sources`, `agentStack`, `taskKind` | Event-to-stack routing for CI failures, webhooks, comments, labels, schedules, and manual dispatch |
|
|
99
|
+
| 31 | AgentContextLabel | agentcontextlabels | `organizationRef`, `promptFragment`, `allowedSources` | Reviewed prompt fragment with provenance and allowlisted sources |
|
|
100
|
+
| 32 | KrateWorkspacePolicy | krateworkspacepolicies | `organizationRef`, `mode`, `retentionPolicy` | Git worktree provisioning, cleanup, retention, and trust tier policies |
|
|
101
|
+
| 33 | AgentAdapter | agentadapters | `organizationRef`, `adapterType`, `transport` | Agent adapter definition with transport type, capabilities matrix, auth requirements, and installation method |
|
|
102
|
+
| 34 | AgentTransportBinding | agenttransportbindings | `organizationRef`, `adapterRef`, `endpoint`, `protocol` | Connection configuration for an adapter instance with endpoint, protocol, auth, health check, and reconnect policy |
|
|
103
|
+
| 35 | AgentProviderConfig | agentproviderconfigs | `organizationRef`, `provider`, `authType` | Model provider configuration with API base, auth type, default model, model translations, and rate limits |
|
|
104
|
+
| 36 | KrateProject | krateprojects | `organizationRef`, `displayName` | Org project grouping issues, linked repositories, kanban board config, default workflow, and backend sync refs |
|
|
105
|
+
| 37 | AgentGatewayConfig | agentgatewayconfigs | `organizationRef`, `gatewayUrl` | Runtime Agent Mux gateway connection settings with URL, auth, reconnect policy, and feature flags |
|
|
106
|
+
| 38 | AgentMemoryRepository | agentmemoryrepositories | `organizationRef`, `repositoryRef`, `defaultBranch`, `layoutProfile` | Org-level Git repository pointer for shared agent memory with layout profile and index policy |
|
|
107
|
+
| 39 | AgentMemorySource | agentmemorysources | `organizationRef`, `repositoryRef`, `appliesTo`, `include` | Read policy for memory paths and kinds per repository, team, stack, or trigger |
|
|
108
|
+
| 40 | AgentMemoryOntology | agentmemoryontologies | `organizationRef`, `memoryRepository`, `ontologyPath` | Ontology policy pointer with required fields, edge kinds, and controlled vocabulary |
|
|
109
|
+
| 41 | AgentMemoryAssociation | agentmemoryassociations | `organizationRef`, `memoryRef`, `targetRef`, `relationship` | Bridge record linking memory content to Krate resources by relationship type |
|
|
110
|
+
|
|
111
|
+
#### Workspaces Context (1 kind)
|
|
112
|
+
|
|
113
|
+
| # | Kind | Plural | Required Spec Fields | Purpose |
|
|
114
|
+
|---|------|--------|---------------------|---------|
|
|
115
|
+
| 42 | KrateWorkspace | krateworkspaces | `organizationRef`, `repository`, `volumeSpec` | Volume-backed git workspace with PVC lifecycle, repo binding, and runner mount spec |
|
|
116
|
+
|
|
117
|
+
#### External-Backends Context (4 kinds)
|
|
118
|
+
|
|
119
|
+
| # | Kind | Plural | Required Spec Fields | Purpose |
|
|
120
|
+
|---|------|--------|---------------------|---------|
|
|
121
|
+
| 43 | ExternalBackendProvider | externalbackendproviders | `organizationRef`, `providerType`, `endpoint` | External backend provider registration with type, endpoint, auth configuration, and capability discovery settings |
|
|
122
|
+
| 44 | ExternalBackendBinding | externalbackendbindings | `organizationRef`, `providerRef`, `credentialRef` | Binding of an external backend provider to an organization with credential reference and sync scope |
|
|
123
|
+
| 45 | ExternalBackendSyncPolicy | externalbackendsyncpolicies | `organizationRef`, `providerRef`, `syncInterval` | Sync interval, conflict resolution mode, field mapping overrides, and retry policy for an external backend provider |
|
|
124
|
+
| 46 | ExternalProviderCapabilityManifest | externalprovidercapabilitymanifests | `organizationRef`, `providerRef`, `capabilities` | Discovered capability surface of an external backend provider including supported resource kinds and API features |
|
|
125
|
+
|
|
126
|
+
### 1.2 AGGREGATED Kinds (postgres storage — 32 kinds)
|
|
127
|
+
|
|
128
|
+
#### Control-Plane Context (3 kinds)
|
|
129
|
+
|
|
130
|
+
| # | Kind | Plural | Required Spec Fields | Purpose |
|
|
131
|
+
|---|------|--------|---------------------|---------|
|
|
132
|
+
| 47 | PullRequest | pullrequests | `organizationRef`, `repository`, `title` | Review unit with source/target refs, title, checks, and merge lifecycle |
|
|
133
|
+
| 48 | Issue | issues | `organizationRef`, `title` | Project-scoped work item with labels, comments, backend sync metadata, and zero-or-more repository associations |
|
|
134
|
+
| 49 | Review | reviews | `organizationRef`, `pullRequest` | Approval, comment, or change-request record for a pull request |
|
|
135
|
+
|
|
136
|
+
#### Runners-CI Context (2 kinds)
|
|
137
|
+
|
|
138
|
+
| # | Kind | Plural | Required Spec Fields | Purpose |
|
|
139
|
+
|---|------|--------|---------------------|---------|
|
|
140
|
+
| 50 | Pipeline | pipelines | `organizationRef`, `repository`, `ref` | CI pipeline run state, trust tier, steps, and resume point |
|
|
141
|
+
| 51 | Job | jobs | `organizationRef`, `pipeline`, `step` | Executable CI step with service-account scope and isolation metadata |
|
|
142
|
+
|
|
143
|
+
#### Hooks-Events Context (1 kind)
|
|
144
|
+
|
|
145
|
+
| # | Kind | Plural | Required Spec Fields | Purpose |
|
|
146
|
+
|---|------|--------|---------------------|---------|
|
|
147
|
+
| 52 | WebhookDelivery | webhookdeliveries | `organizationRef`, `subscription`, `eventType`, `signature` | Durable outbound webhook delivery attempt with signature, phase, response, and replay metadata |
|
|
148
|
+
|
|
149
|
+
#### Agents Context (17 kinds)
|
|
150
|
+
|
|
151
|
+
| # | Kind | Plural | Required Spec Fields | Purpose |
|
|
152
|
+
|---|------|--------|---------------------|---------|
|
|
153
|
+
| 53 | AgentDispatchRun | agentdispatchruns | `organizationRef`, `repository`, `sourceRefs`, `agentStack`, `taskKind` | Logical CI-like run visible beside Pipeline/Job records with queue, status, workspace, and cost |
|
|
154
|
+
| 54 | AgentDispatchAttempt | agentdispatchattempts | `organizationRef`, `agentDispatchRun`, `attemptReason`, `agentStackSnapshot` | Concrete execution attempt with reason, stack snapshot, and runtime state |
|
|
155
|
+
| 55 | AgentSession | agentsessions | `organizationRef`, `agentMuxSessionId`, `dispatchRun` | Krate projection of Agent Mux chat/session with lifecycle state |
|
|
156
|
+
| 56 | AgentContextBundle | agentcontextbundles | `organizationRef`, `dispatchRun`, `digest`, `sources` | Immutable prompt/context snapshot with digest, provenance, and redaction manifest |
|
|
157
|
+
| 57 | KrateArtifact | krateartifacts | `organizationRef`, `dispatchRun`, `kind`, `digest` | Durable agent output with kind, digest, and retention policy |
|
|
158
|
+
| 58 | AgentApproval | agentapprovals | `organizationRef`, `dispatchRun`, `action`, `requestedBy` | Human gate for tools, secrets, write-back, and release actions |
|
|
159
|
+
| 59 | AgentTriggerExecution | agenttriggerexecutions | `organizationRef`, `triggerRule`, `sourceEvent`, `decision` | Durable trigger evaluation record with dedupe, coalescing, and rejection reason |
|
|
160
|
+
| 60 | AgentCapabilityRequirement | agentcapabilityrequirements | `organizationRef`, `ownerRef`, `requiredRoles` | Computed dependency record from tools, MCP, skills, models, and subagents |
|
|
161
|
+
| 61 | WorkItemSessionLink | workitemsessionlinks | `organizationRef`, `workItemRef`, `agentSession` | Association between issues/PRs and agent sessions |
|
|
162
|
+
| 62 | WorkItemWorkspaceLink | workitemworkspacelinks | `organizationRef`, `workItemRef`, `workspace` | Association between issues/PRs and agent workspaces |
|
|
163
|
+
| 63 | AgentSessionTranscript | agentsessiontranscripts | `organizationRef`, `sessionRef`, `messages` | Durable chat transcript with message nodes, pagination support, and cost per turn |
|
|
164
|
+
| 64 | AgentSessionAttachment | agentsessionattachments | `organizationRef`, `sessionRef`, `sourceType`, `digest` | File attached to a session message with source type, MIME type, digest, and redaction status |
|
|
165
|
+
| 65 | KrateWorkspaceRuntime | krateworkspaceruntimes | `organizationRef`, `workspaceRef`, `status` | Workspace runtime surface state with cwd, environment variables, process status, and preview URL |
|
|
166
|
+
| 66 | AgentMemorySnapshot | agentmemorysnapshots | `organizationRef`, `memoryRepository`, `requestedRef`, `resolvedCommit` | Immutable dispatch-time memory pin with resolved commit, query manifest digest, and selected records digest |
|
|
167
|
+
| 67 | AgentMemoryQuery | agentmemoryqueries | `organizationRef`, `snapshotRef`, `requester`, `query` | Graph and grep retrieval record with query parameters, result digests, and ranking metadata |
|
|
168
|
+
| 68 | AgentMemoryUpdate | agentmemoryupdates | `organizationRef`, `memoryRepository`, `sourceRun`, `changes` | Reviewable proposed memory mutation with branch, changes, and validation status |
|
|
169
|
+
| 69 | AgentRunMemoryImport | agentrunmemoryimports | `organizationRef`, `memoryRepository`, `source`, `include` | Import curated babysitter run metadata into org company brain with redaction and review |
|
|
170
|
+
|
|
171
|
+
#### External-Backends Context (6 kinds)
|
|
172
|
+
|
|
173
|
+
| # | Kind | Plural | Required Spec Fields | Purpose |
|
|
174
|
+
|---|------|--------|---------------------|---------|
|
|
175
|
+
| 70 | ExternalWebhookDelivery | externalwebhookdeliveries | `organizationRef`, `providerRef`, `eventType`, `payload` | Inbound webhook delivery from an external backend provider with event type, payload, and processing state |
|
|
176
|
+
| 71 | ExternalSyncEvent | externalsyncevents | `organizationRef`, `providerRef`, `eventKind`, `resourceRef` | Discrete sync event record from an external backend for a specific resource kind with dedupe and ordering metadata |
|
|
177
|
+
| 72 | ExternalSyncState | externalsyncstates | `organizationRef`, `providerRef`, `resourceRef`, `phase` | Current sync phase, last successful sync timestamp, and error details for an external resource binding |
|
|
178
|
+
| 73 | ExternalWriteIntent | externalwriteintents | `organizationRef`, `providerRef`, `resourceRef`, `operation` | Queued write-back intent to an external backend with operation, payload snapshot, and approval state |
|
|
179
|
+
| 74 | ExternalSyncConflict | externalsyncconflicts | `organizationRef`, `providerRef`, `resourceRef`, `conflictKind` | Detected conflict between local and external state with conflict kind, diff, and resolution outcome |
|
|
180
|
+
| 75 | ExternalObjectLink | externalobjectlinks | `organizationRef`, `providerRef`, `externalId`, `localRef` | Stable mapping between a Krate local resource and its external backend counterpart by external ID |
|
|
93
181
|
|
|
94
182
|
---
|
|
95
183
|
|
|
96
184
|
## 2. API Surface
|
|
97
185
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
|
103
|
-
|
|
104
|
-
| GET | `/
|
|
105
|
-
|
|
|
106
|
-
| GET | `/api/orgs
|
|
107
|
-
| POST | `/api/orgs
|
|
108
|
-
| GET | `/api/orgs/:org/resources
|
|
109
|
-
|
|
|
110
|
-
| GET | `/api/orgs/:org/
|
|
111
|
-
|
|
|
112
|
-
| GET | `/api/orgs/:org/repositories
|
|
113
|
-
|
|
|
114
|
-
| GET | `/api/orgs/:org/
|
|
115
|
-
|
|
|
116
|
-
| GET | `/api/orgs/:org/
|
|
117
|
-
| POST | `/api/orgs/:org/
|
|
118
|
-
|
|
|
119
|
-
| POST | `/api/orgs/:org/
|
|
120
|
-
| POST | `/api/orgs/:org/
|
|
121
|
-
| POST | `/api/orgs/:org/pullrequests
|
|
122
|
-
| POST | `/api/orgs/:org/pullrequests/:pr/
|
|
123
|
-
| POST | `/api/orgs/:org/
|
|
124
|
-
| POST | `/api/orgs/:org/
|
|
125
|
-
| POST | `/api/orgs/:org/agents/
|
|
126
|
-
| POST | `/api/orgs/:org/agents/
|
|
127
|
-
| POST | `/api/orgs/:org/agents/events/
|
|
128
|
-
| POST | `/api/orgs/:org/agents/
|
|
129
|
-
| POST | `/api/orgs/:org/agents/
|
|
130
|
-
|
|
|
131
|
-
| POST | `/api/orgs/:org/
|
|
132
|
-
|
|
|
133
|
-
|
|
|
134
|
-
|
|
|
135
|
-
|
|
|
136
|
-
| POST | `/api/orgs/:org/
|
|
137
|
-
| POST | `/api/orgs/:org/external/
|
|
138
|
-
| POST | `/api/orgs/:org/external/
|
|
139
|
-
|
|
|
186
|
+
Source: `packages/krate/core/src/http-server.js`
|
|
187
|
+
|
|
188
|
+
### 2.1 All HTTP Routes (40 routes)
|
|
189
|
+
|
|
190
|
+
| # | Method | Path | Auth | Request Body | Success | Error | Purpose |
|
|
191
|
+
|---|--------|------|------|-------------|---------|-------|---------|
|
|
192
|
+
| 1 | GET | `/healthz` | No | — | 200 `{ ok: true }` | — | Health check |
|
|
193
|
+
| 2 | GET | `/api/controller` | No | Query: `?org=` | 200 UI model | 400 | Full controller UI model |
|
|
194
|
+
| 3 | GET | `/api/orgs` | No | — | 200 `{ organizations }` | 400 | List organizations |
|
|
195
|
+
| 4 | POST | `/api/orgs` | Yes | `{ slug, displayName }` | 201 `{ organization, namespace, binding }` | 400 | Create organization |
|
|
196
|
+
| 5 | GET | `/api/orgs/:org/resources` | No | Query: `?kind=` | 200 `{ items }` | 400 | List resources by kind |
|
|
197
|
+
| 6 | POST | `/api/orgs/:org/resources` | Yes | Resource object | 201 `{ operation, resource }` | 400 | Apply resource |
|
|
198
|
+
| 7 | GET | `/api/orgs/:org/resources/:kind/:name` | No | — | 200 resource | 400 | Get single resource |
|
|
199
|
+
| 8 | DELETE | `/api/orgs/:org/resources/:kind/:name` | Yes | — | 200 result | 400 | Delete resource |
|
|
200
|
+
| 9 | GET | `/api/orgs/:org/repositories` | No | — | 200 `{ items }` | 400 | List repositories |
|
|
201
|
+
| 10 | POST | `/api/orgs/:org/repositories` | Yes | `{ name, visibility }` | 201 `{ repository }` | 400 | Create repository |
|
|
202
|
+
| 11 | GET | `/api/orgs/:org/repositories/:name` | No | — | 200 resource | 400 | Get repository |
|
|
203
|
+
| 12 | DELETE | `/api/orgs/:org/repositories/:name` | Yes | — | 200 result | 400 | Delete repository |
|
|
204
|
+
| 13 | GET | `/api/orgs/:org/snapshot` | No | — | 200 snapshot | 400 | Org runtime snapshot |
|
|
205
|
+
| 14 | POST | `/api/orgs/:org/snapshot` | Yes | Snapshot object | 200 result | 400 | Import snapshot |
|
|
206
|
+
| 15 | GET | `/api/orgs/:org/runtime-resources/:kind` | No | — | 200 items | 400 | List runtime resources |
|
|
207
|
+
| 16 | POST | `/api/orgs/:org/repositories/:repo/objects` | Yes | Object data | 201 result | 400 | Record git object |
|
|
208
|
+
| 17 | POST | `/api/orgs/:org/repositories/:repo/search-index` | Yes | Index request | 202 result | 400 | Enqueue search index |
|
|
209
|
+
| 18 | POST | `/api/orgs/:org/pullrequests` | Yes | PR data | 201 PR | 400 | Create pull request |
|
|
210
|
+
| 19 | POST | `/api/orgs/:org/pullrequests/:pr/reviews` | Yes | Review data | 201 review | 400 | Add review |
|
|
211
|
+
| 20 | POST | `/api/orgs/:org/pullrequests/:pr/checks/complete` | Yes | Pipeline data | 200 result | 400 | Complete pipeline check |
|
|
212
|
+
| 21 | POST | `/api/orgs/:org/pullrequests/:pr/merge` | Yes | Merge options | 200 result | 400 | Merge pull request |
|
|
213
|
+
| 22 | POST | `/api/orgs/:org/agents/approvals/:name/decide` | Yes | `{ decision, decidedBy, reason }` | 200 result | 400 | Approve/deny agent action |
|
|
214
|
+
| 23 | POST | `/api/orgs/:org/agents/webhooks/ingest` | Yes | Webhook payload | 200 result | 400 | Ingest webhook event |
|
|
215
|
+
| 24 | POST | `/api/orgs/:org/agents/events/pipeline-failure` | Yes | `{ name, repository, ref }` | 200 result | 400 | Pipeline failure event |
|
|
216
|
+
| 25 | POST | `/api/orgs/:org/agents/events/comment` | Yes | `{ kind, name, body }` | 200 result | 400 | Comment event |
|
|
217
|
+
| 26 | POST | `/api/orgs/:org/agents/events/label` | Yes | `{ kind, name, label }` | 200 result | 400 | Label event |
|
|
218
|
+
| 27 | POST | `/api/orgs/:org/agents/triggers/process` | Yes | Event + options | 200 result | 400 | Process trigger |
|
|
219
|
+
| 28 | POST | `/api/orgs/:org/agents/memory/query` | Yes | `{ query, mode, kinds }` | 200 results | 400 | Query agent memory |
|
|
220
|
+
| 29 | GET | `/api/orgs/:org/secrets` | No | — | 200 `{ secrets }` | 400 | List secrets |
|
|
221
|
+
| 30 | POST | `/api/orgs/:org/secrets` | Yes | `{ name, data }` | 201 result | 400 | Create secret |
|
|
222
|
+
| 31 | DELETE | `/api/orgs/:org/secrets/:name` | Yes | — | 200 result | 400 | Delete secret |
|
|
223
|
+
| 32 | GET | `/api/orgs/:org/secret-grants` | No | — | 200 grants | 400 | List secret grants |
|
|
224
|
+
| 33 | POST | `/api/orgs/:org/secret-grants` | Yes | Grant data | 201 grant | 400 | Create secret grant |
|
|
225
|
+
| 34 | POST | `/api/orgs/:org/external/sync` | Yes | `{ bindingName, kind, localName, spec, externalEnvelope }` | 200 result | 400 | Trigger external sync |
|
|
226
|
+
| 35 | POST | `/api/orgs/:org/external/conflicts/:name/resolve` | Yes | `{ strategy, resolvedValue }` | 200 result | 400 | Resolve sync conflict |
|
|
227
|
+
| 36 | POST | `/api/orgs/:org/external/write-intents/:name/approve` | Yes | `{ approvedBy }` | 200 result | 400 | Approve write intent |
|
|
228
|
+
| 37 | POST | `/api/orgs/:org/external/write-intents/:name/cancel` | Yes | `{ cancelledBy }` | 200 result | 400 | Cancel write intent |
|
|
229
|
+
| 38 | GET | `/api/orgs/:org/agents/events/stream` | No | — | 200 SSE | — | SSE event stream |
|
|
230
|
+
|
|
231
|
+
### 2.2 Route Pattern Matching
|
|
232
|
+
|
|
233
|
+
All routes use regex matching on `url.pathname`:
|
|
234
|
+
```javascript
|
|
235
|
+
url.pathname.match(/^\/api\/orgs\/([^/]+)\/resources$/)
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Priority: routes are checked in order of declaration in `createKrateHttpHandler()`.
|
|
239
|
+
|
|
240
|
+
### 2.3 SSE Protocol
|
|
241
|
+
|
|
242
|
+
```
|
|
243
|
+
GET /api/orgs/:org/agents/events/stream HTTP/1.1
|
|
244
|
+
|
|
245
|
+
HTTP/1.1 200 OK
|
|
246
|
+
Content-Type: text/event-stream
|
|
247
|
+
Cache-Control: no-cache
|
|
248
|
+
Connection: keep-alive
|
|
249
|
+
X-Accel-Buffering: no
|
|
250
|
+
|
|
251
|
+
data: {"type":"connected"}
|
|
252
|
+
|
|
253
|
+
data: {"type":"heartbeat"}
|
|
254
|
+
|
|
255
|
+
data: {"type":"resource-change","kind":"Repository","name":"my-repo","operation":"apply","timestamp":"2025-01-01T00:00:00.000Z"}
|
|
256
|
+
```
|
|
140
257
|
|
|
141
258
|
---
|
|
142
259
|
|
|
143
260
|
## 3. Controller Boundaries
|
|
144
261
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
|
148
|
-
|
|
149
|
-
| KubernetesResourceClient | `kubernetes-controller.js` |
|
|
150
|
-
| KrateKubernetesReconciler | `kubernetes-controller.js` |
|
|
151
|
-
|
|
|
152
|
-
|
|
|
153
|
-
|
|
|
154
|
-
|
|
|
155
|
-
|
|
|
156
|
-
|
|
|
157
|
-
|
|
|
158
|
-
|
|
|
159
|
-
|
|
|
160
|
-
|
|
|
161
|
-
|
|
|
262
|
+
### 3.1 Complete Controller Inventory
|
|
263
|
+
|
|
264
|
+
| # | Controller | Source File | Lines | Methods |
|
|
265
|
+
|---|-----------|-------------|-------|---------|
|
|
266
|
+
| 1 | KubernetesResourceClient | `kubernetes-controller.js` | 883 | snapshot, listResource, getResource, applyResource, deleteResource, createRepository, createOrganization, watchResource |
|
|
267
|
+
| 2 | KrateKubernetesReconciler | `kubernetes-controller.js` | (shared) | describeReconciliationScope, reconcileRepository, reconcileIdentityAccess, reconcileIdentityAccessResources |
|
|
268
|
+
| 3 | KubernetesResourceGateway | `kubernetes-resource-gateway.js` | 48 | snapshot, list, get, apply, delete, createRepository, createOrganization, watch |
|
|
269
|
+
| 4 | KrateApiController | `api-controller.js` | 541 | snapshot, listResource, getResource, applyResource, deleteResource, createRepository, createOrganization, dispatchAgent, processWebhookEvent, queryAgentMemory, syncExternalBinding, resolveExternalConflict, + 10 more |
|
|
270
|
+
| 5 | AgentStackController | `agent-stack-controller.js` | 347 | reconcileStack, listStackCapabilities, checkMcpHealth |
|
|
271
|
+
| 6 | AgentDispatchController | `agent-dispatch-controller.js` | 209 | createManualDispatch |
|
|
272
|
+
| 7 | AgentWorkspaceController | `agent-workspace-controller.js` | 702 | createWorkspace, deleteWorkspace, getWorkspaceStatus, initializeWorkspace, checkoutBranch, syncWorkspace, getMountSpec, findReusableWorkspace, claimWorkspace, releaseWorkspace, provisionWorkspace, archiveWorkspace, recoverWorkspace, bindSession, linkWorkItem, linkWorkItemToSession, listWorkspacesForRepo, listWorkspacesForRun, launchCodespace, stopCodespace, getCodespaceStatus, addAssociation, removeAssociation, listAssociations, getWorkspaceRuns |
|
|
273
|
+
| 8 | AgentTriggerController | `agent-trigger-controller.js` | 381 | matchRule, evaluateEvent, createTriggerExecution, evaluateWebhookEvent, processEvent |
|
|
274
|
+
| 9 | AgentApprovalController | `agent-approval-controller.js` | 170 | createApprovalRequest, recordDecision, isActionApproved, listPendingApprovals, listApprovalsForRun, persistApproval, enforceApproval |
|
|
275
|
+
| 10 | AgentMemoryQuery | `agent-memory-query.js` | 293 | queryGraph, queryGrep, queryMemory |
|
|
276
|
+
| 11 | WebhookController | `external/webhook-controller.js` | 144 | verifyHmacSignature, createDeliveryRecord, recordDelivery, isDuplicate, onEvent, processDelivery |
|
|
277
|
+
| 12 | SyncController | `external/sync-controller.js` | 235 | normalizeEvent, upsertResource, updateWatermark, getWatermark, applyOwnershipMode, createTombstone, getTombstone |
|
|
278
|
+
| 13 | ConflictController | `external/conflict-controller.js` | 225 | detectConflict, resolveConflict, listOpenConflicts, supersede |
|
|
279
|
+
| 14 | WriteController | `external/write-controller.js` | 283 | createWriteIntent, approveWriteIntent, rejectWriteIntent, markSending, confirmSuccess, confirmFailure, listIntents |
|
|
280
|
+
| 15 | AuditController | `audit-controller.js` | ~180 | log, query, getStream, getMetrics |
|
|
281
|
+
| 16 | RunnerController | `runner-controller.js` | ~300 | validateRunnerPool, getPoolStatus, getCapacity, createRunner, assignJob, releaseRunner, generatePodSpec |
|
|
282
|
+
| 17 | NotificationController | `notification-controller.js` | 178 | createNotification, listNotifications, markAsRead, markAllAsRead, getUnreadCount, getPreferences, updatePreferences |
|
|
283
|
+
| 18 | PermissionReviewer | `agent-permission-review.js` | 250 | reviewPermissions, createPermissionSnapshot |
|
|
284
|
+
|
|
285
|
+
### 3.2 Boundary Pattern
|
|
286
|
+
|
|
287
|
+
Every controller exports:
|
|
288
|
+
```javascript
|
|
289
|
+
export const <NAME>_BOUNDARY = {
|
|
290
|
+
role: 'controller-name',
|
|
291
|
+
scope: 'What it does in one sentence',
|
|
292
|
+
owns: ['capability-1', 'capability-2'],
|
|
293
|
+
delegatesTo: ['other-controller-1'],
|
|
294
|
+
mustNotOwn: ['thing-it-must-not-do']
|
|
295
|
+
};
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## 4. Resource Validation Rules
|
|
301
|
+
|
|
302
|
+
Source: `packages/krate/core/src/resource-model.js` — `validateResource()`
|
|
303
|
+
|
|
304
|
+
### 4.1 Universal Validation
|
|
305
|
+
|
|
306
|
+
1. `resource` must be a non-null object
|
|
307
|
+
2. `resource.kind` must match a key in `RESOURCE_DEFINITIONS`
|
|
308
|
+
3. `resource.metadata.name` is required (non-empty string)
|
|
309
|
+
4. `resource.spec` and `resource.status` default to `{}` if missing
|
|
310
|
+
5. `resource.metadata.namespace` defaults to `'default'`
|
|
311
|
+
6. `resource.metadata.labels` and `annotations` default to `{}`
|
|
312
|
+
7. Every field listed in `requiredSpec` must be non-null, non-undefined, non-empty-string
|
|
313
|
+
|
|
314
|
+
### 4.2 Name Normalization
|
|
315
|
+
|
|
316
|
+
`normalizeName(value)`:
|
|
317
|
+
```javascript
|
|
318
|
+
String(value).toLowerCase()
|
|
319
|
+
.replace(/[^a-z0-9-]+/g, '-')
|
|
320
|
+
.replace(/^-+|-+$/g, '')
|
|
321
|
+
.slice(0, 63) || 'user'
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### 4.3 Org Slug Normalization
|
|
325
|
+
|
|
326
|
+
`normalizeOrgSlug(value)`:
|
|
327
|
+
```javascript
|
|
328
|
+
String(value).trim().toLowerCase()
|
|
329
|
+
.replace(/[^a-z0-9-]+/g, '-')
|
|
330
|
+
.replace(/^-+|-+$/g, '')
|
|
331
|
+
.slice(0, 63)
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## 5. MCP Server Protocol
|
|
337
|
+
|
|
338
|
+
Source: `packages/krate/cli/src/mcp-server.js`
|
|
339
|
+
|
|
340
|
+
### 5.1 Tools (14)
|
|
341
|
+
|
|
342
|
+
| # | Tool | Inputs | Output |
|
|
343
|
+
|---|------|--------|--------|
|
|
344
|
+
| 1 | `krate_list_resources` | `{ kind: string }` | Resource list |
|
|
345
|
+
| 2 | `krate_get_resource` | `{ kind: string, name: string }` | Single resource |
|
|
346
|
+
| 3 | `krate_apply_resource` | `{ resource: object }` | Apply result |
|
|
347
|
+
| 4 | `krate_delete_resource` | `{ kind: string, name: string }` | Delete result |
|
|
348
|
+
| 5 | `krate_snapshot` | `{}` | Full org snapshot |
|
|
349
|
+
| 6 | `krate_search` | `{ query: string }` | Search results |
|
|
350
|
+
| 7 | `krate_list_stacks` | `{}` | Agent stacks |
|
|
351
|
+
| 8 | `krate_create_stack` | `{ name: string, org: string }` | Created stack |
|
|
352
|
+
| 9 | `krate_dispatch_agent` | `{ stackRef: string }` | Dispatch result |
|
|
353
|
+
| 10 | `krate_list_secrets` | `{ org?: string }` | Secret grants |
|
|
354
|
+
| 11 | `krate_create_secret` | `{ name, org, agentRef, secretRef }` | Created grant |
|
|
355
|
+
| 12 | `krate_sync_external` | `{ bindingName, kind, localName }` | Sync result |
|
|
356
|
+
| 13 | `krate_resolve_conflict` | `{ conflictName, strategy }` | Resolution |
|
|
357
|
+
| 14 | `krate_audit_query` | `{ org?, action?, since?, until?, limit?, offset? }` | Audit events |
|
|
358
|
+
|
|
359
|
+
### 5.2 Prompts (3)
|
|
360
|
+
|
|
361
|
+
| Prompt | Description |
|
|
362
|
+
|--------|-------------|
|
|
363
|
+
| `krate_workspace_setup` | Guide for setting up a new krate workspace |
|
|
364
|
+
| `krate_stack_config` | Help configuring an agent stack |
|
|
365
|
+
| `krate_troubleshoot` | Diagnose common krate issues |
|
|
366
|
+
|
|
367
|
+
### 5.3 Resources (2)
|
|
368
|
+
|
|
369
|
+
| URI | MIME Type |
|
|
370
|
+
|-----|-----------|
|
|
371
|
+
| `krate://snapshot` | application/json |
|
|
372
|
+
| `krate://stacks` | application/json |
|
|
162
373
|
|
|
163
374
|
---
|
|
164
375
|
|
|
165
|
-
##
|
|
376
|
+
## 6. CLI Commands
|
|
166
377
|
|
|
167
|
-
Source: `packages/krate/
|
|
378
|
+
Source: `packages/krate/cli/src/index.js`
|
|
168
379
|
|
|
169
|
-
|
|
380
|
+
| Command | Description | Key Options |
|
|
381
|
+
|---------|-------------|-------------|
|
|
382
|
+
| `krate serve` | Start HTTP API server | `--port 3080` |
|
|
383
|
+
| `krate mcp` | Start MCP server over stdio | — |
|
|
384
|
+
| `krate status` | Show workspace status | `--org`, `--json` |
|
|
385
|
+
| `krate stacks` | List agent stacks | `--org`, `--json` |
|
|
386
|
+
| `krate dispatch` | Dispatch an agent run | `--stack`, `--repo`, `--ref` |
|
|
387
|
+
| `krate apply` | Apply resource from file | `--file`, `--org` |
|
|
388
|
+
| `krate get` | Get resource by kind/name | `kind`, `name`, `--org` |
|
|
389
|
+
| `krate list` | List resources by kind | `kind`, `--org`, `--json` |
|
|
390
|
+
| `krate delete` | Delete resource | `kind`, `name`, `--org` |
|
|
391
|
+
| `krate version` | Show CLI version | — |
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
395
|
+
## 7. Event System
|
|
396
|
+
|
|
397
|
+
### 7.1 Event Bus API
|
|
170
398
|
|
|
171
399
|
```javascript
|
|
172
400
|
const bus = createEventBus();
|
|
173
|
-
bus.subscribe(
|
|
174
|
-
bus.
|
|
175
|
-
bus.
|
|
401
|
+
bus.subscribe(fn); // Add listener
|
|
402
|
+
bus.unsubscribe(fn); // Remove listener
|
|
403
|
+
bus.emit(event); // Broadcast
|
|
404
|
+
bus.emitResourceChange(kind, name, op); // Convenience
|
|
176
405
|
```
|
|
177
406
|
|
|
178
|
-
|
|
407
|
+
### 7.2 Event Types
|
|
408
|
+
|
|
409
|
+
| Type | Origin | Payload |
|
|
410
|
+
|------|--------|---------|
|
|
411
|
+
| `connected` | SSE endpoint | `{}` |
|
|
412
|
+
| `heartbeat` | SSE interval (30s) | `{}` |
|
|
413
|
+
| `resource-change` | applyResource/deleteResource | `{ kind, name, operation, timestamp }` |
|
|
414
|
+
|
|
415
|
+
### 7.3 Notification Types
|
|
179
416
|
|
|
180
|
-
|
|
417
|
+
| Type | Trigger | Severity |
|
|
418
|
+
|------|---------|----------|
|
|
419
|
+
| `run-complete` | AgentDispatchRun phase change | info/error |
|
|
420
|
+
| `approval-needed` | AgentApproval created (pending) | warning |
|
|
421
|
+
| `conflict-detected` | ExternalSyncConflict created | warning |
|
|
422
|
+
| `workspace-ready` | KrateWorkspace claimed | info |
|
|
423
|
+
| `system` | Default/fallback | info |
|
|
181
424
|
|
|
182
|
-
|
|
425
|
+
---
|
|
426
|
+
|
|
427
|
+
## 8. Trigger Rule System
|
|
428
|
+
|
|
429
|
+
### 8.1 Source Types
|
|
183
430
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
431
|
+
| Source Type | Detection Logic | Validation Function |
|
|
432
|
+
|-------------|----------------|-------------------|
|
|
433
|
+
| `cron` | `spec.cronExpression !== undefined` | `validateCronExpression(expr)` |
|
|
434
|
+
| `webhook` | `spec.webhookTrigger !== undefined` | `validateWebhookTrigger(config)` |
|
|
435
|
+
| `comment` | `spec.commentTrigger !== undefined` | `validateCommentTrigger(config)` |
|
|
436
|
+
| `label` | `spec.labelTrigger !== undefined` | `validateLabelTrigger(config)` |
|
|
437
|
+
| `event` | `spec.sources !== undefined` | Array.isArray + non-empty |
|
|
189
438
|
|
|
190
|
-
###
|
|
439
|
+
### 8.2 Rule Matching Algorithm
|
|
191
440
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
- Auto-expiry based on age
|
|
441
|
+
For event-based rules (`matchRule()`):
|
|
442
|
+
1. Event type must be in `rule.spec.sources[]`
|
|
443
|
+
2. If `rule.spec.repository` set: must match `event.repository`
|
|
444
|
+
3. If `rule.spec.allowedActors[]` non-empty: `event.actor` must be included
|
|
197
445
|
|
|
198
|
-
|
|
446
|
+
For webhook-based rules (`evaluateWebhookEvent()`):
|
|
447
|
+
1. `rule.spec.enabled !== false`
|
|
448
|
+
2. `rule.spec.webhookTrigger` must exist
|
|
449
|
+
3. `webhookTrigger.events` includes event type (or `['*']` or absent)
|
|
450
|
+
4. `webhookTrigger.repository` matches (if set)
|
|
451
|
+
5. `webhookTrigger.action` matches (if set)
|
|
199
452
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
453
|
+
### 8.3 Deduplication
|
|
454
|
+
|
|
455
|
+
Before dispatching, checks `AgentTriggerExecution` resources:
|
|
456
|
+
```javascript
|
|
457
|
+
executions.some(ex =>
|
|
458
|
+
ex.spec?.triggerRule === rule.metadata?.name &&
|
|
459
|
+
ex.spec?.sourceEvent === eventUid &&
|
|
460
|
+
ex.status?.phase !== 'Failed'
|
|
461
|
+
)
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
Event UID format: `${event.type}:${event.source.kind}:${event.source.name}`
|
|
206
465
|
|
|
207
466
|
---
|
|
208
467
|
|
|
209
|
-
##
|
|
468
|
+
## 9. Approval System
|
|
210
469
|
|
|
211
|
-
|
|
470
|
+
### 9.1 Valid Actions
|
|
212
471
|
|
|
213
|
-
|
|
472
|
+
```javascript
|
|
473
|
+
const VALID_ACTIONS = new Set(['tool-use', 'secret-access', 'write-back', 'release', 'escalation']);
|
|
474
|
+
```
|
|
214
475
|
|
|
215
|
-
|
|
216
|
-
2. **PVC manifest** — StorageClass, capacity (default 10Gi), access modes (ReadWriteOnce)
|
|
217
|
-
3. **Git clone spec** — Commands to clone repository into workspace volume
|
|
218
|
-
4. **Checkout spec** — Branch/ref checkout commands
|
|
219
|
-
5. **Runner mount spec** — Volume mount configuration for runner pods
|
|
476
|
+
### 9.2 Approval Phases
|
|
220
477
|
|
|
221
|
-
|
|
478
|
+
```
|
|
479
|
+
(none) → Pending → Approved
|
|
480
|
+
→ Denied
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
### 9.3 Duplicate Detection
|
|
484
|
+
|
|
485
|
+
Before creating a new approval, checks for existing:
|
|
486
|
+
```javascript
|
|
487
|
+
resources.AgentApproval.find(a =>
|
|
488
|
+
a.spec?.dispatchRun === dispatchRun &&
|
|
489
|
+
a.spec?.action === action &&
|
|
490
|
+
(!a.status?.phase || a.status.phase === 'Pending')
|
|
491
|
+
)
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
---
|
|
222
495
|
|
|
223
|
-
|
|
224
|
-
- Match by repository + branch
|
|
225
|
-
- Update workspace status to reflect new session binding
|
|
226
|
-
- Track run history per workspace
|
|
496
|
+
## 10. Stack Readiness Conditions
|
|
227
497
|
|
|
228
|
-
|
|
498
|
+
Source: `agent-stack-controller.js` — `reconcileStack()`
|
|
229
499
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
500
|
+
| Condition Type | True When | False When |
|
|
501
|
+
|---------------|-----------|------------|
|
|
502
|
+
| `CapabilitiesResolved` | All referenced resources exist | Any missing ref |
|
|
503
|
+
| `ToolsAdmitted` | AgentToolProfile found (or no ref) | Referenced profile missing |
|
|
504
|
+
| `McpHealthy` | All AgentMcpServer resources exist | Any missing MCP server |
|
|
505
|
+
| `SkillsValidated` | All skills exist with valid format+sourceRef | Missing or invalid skills |
|
|
506
|
+
| `SubagentsValid` | All subagents exist with non-empty taskKinds | Missing or invalid subagents |
|
|
507
|
+
| `ContextLabelsValid` | All context labels exist | Any missing label |
|
|
508
|
+
| `RuntimeIdentityReady` | AgentServiceAccount found | SA not found |
|
|
509
|
+
| `RolesAdmitted` | No role binding errors in permission review | Missing AgentRoleBinding |
|
|
510
|
+
| `SecretsAdmitted` | No secret grant errors | Missing AgentSecretGrant |
|
|
511
|
+
| `ConfigAdmitted` | No config grant errors | Missing AgentConfigGrant |
|
|
512
|
+
| `Ready` | ALL above conditions are True | ANY condition is False |
|
|
233
513
|
|
|
234
514
|
---
|
|
235
515
|
|
|
236
|
-
##
|
|
516
|
+
## 11. External Conflict Resolution
|
|
237
517
|
|
|
238
|
-
|
|
518
|
+
### 11.1 Valid Strategies
|
|
239
519
|
|
|
240
|
-
|
|
520
|
+
```javascript
|
|
521
|
+
const VALID_STRATEGIES = ['prefer-external', 'prefer-krate', 'manual', 'ignore'];
|
|
522
|
+
```
|
|
241
523
|
|
|
242
|
-
|
|
243
|
-
- `warmReplicas` — Pre-provisioned ready runners
|
|
244
|
-
- `maxReplicas` — Maximum capacity
|
|
245
|
-
- Cache policy for workspace data
|
|
246
|
-
- Trust boundary for execution isolation
|
|
524
|
+
### 11.2 Conflict Lifecycle
|
|
247
525
|
|
|
248
|
-
|
|
526
|
+
```
|
|
527
|
+
(detected) → Open → Resolved (with strategy + resolvedValue)
|
|
528
|
+
→ Superseded (newer conflict replaces)
|
|
529
|
+
```
|
|
249
530
|
|
|
250
|
-
|
|
251
|
-
- Workspace PVC volume mount
|
|
252
|
-
- Service account binding (`AgentServiceAccount`)
|
|
253
|
-
- Resource limits and requests
|
|
254
|
-
- Network policy annotations
|
|
531
|
+
### 11.3 Write Intent Phases
|
|
255
532
|
|
|
256
|
-
|
|
533
|
+
```javascript
|
|
534
|
+
const VALID_PHASES = ['PendingApproval', 'ReadyToSend', 'Sending', 'Retrying', 'Succeeded', 'Failed', 'Rejected'];
|
|
535
|
+
```
|
|
257
536
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
537
|
+
Lifecycle:
|
|
538
|
+
```
|
|
539
|
+
PendingApproval → ReadyToSend (approved) → Sending → Succeeded
|
|
540
|
+
→ Retrying → Sending (retry)
|
|
541
|
+
→ Failed
|
|
542
|
+
→ Rejected (cancelled)
|
|
543
|
+
```
|
|
262
544
|
|
|
263
545
|
---
|
|
264
546
|
|
|
265
|
-
##
|
|
547
|
+
## 12. Runner System
|
|
548
|
+
|
|
549
|
+
### 12.1 Pool Validation Rules
|
|
266
550
|
|
|
267
|
-
|
|
551
|
+
- `spec.organizationRef`: required, non-empty string
|
|
552
|
+
- `spec.warmReplicas`: non-negative integer
|
|
553
|
+
- `spec.maxReplicas`: positive integer (>= 1)
|
|
554
|
+
- `warmReplicas <= maxReplicas`
|
|
268
555
|
|
|
269
|
-
###
|
|
556
|
+
### 12.2 Runner Statuses
|
|
270
557
|
|
|
558
|
+
```javascript
|
|
559
|
+
const RUNNER_STATUSES = new Set(['Idle', 'Running', 'Terminating']);
|
|
271
560
|
```
|
|
272
|
-
|
|
561
|
+
|
|
562
|
+
### 12.3 Pool Phases
|
|
563
|
+
|
|
564
|
+
| Phase | Condition |
|
|
565
|
+
|-------|-----------|
|
|
566
|
+
| `Empty` | No runners registered |
|
|
567
|
+
| `Active` | At least one runner is Running |
|
|
568
|
+
| `Idle` | All runners are Idle |
|
|
569
|
+
|
|
570
|
+
### 12.4 Scaling States
|
|
571
|
+
|
|
572
|
+
| State | Condition |
|
|
573
|
+
|-------|-----------|
|
|
574
|
+
| `ScalingUp` | total < warmReplicas |
|
|
575
|
+
| `ScalingDown` | total > maxReplicas |
|
|
576
|
+
| `Stable` | warmReplicas <= total <= maxReplicas |
|
|
577
|
+
|
|
578
|
+
---
|
|
579
|
+
|
|
580
|
+
## 13. Audit System
|
|
581
|
+
|
|
582
|
+
### 13.1 Event Structure
|
|
583
|
+
|
|
584
|
+
```javascript
|
|
585
|
+
{
|
|
586
|
+
id: number, // Auto-incrementing sequence
|
|
587
|
+
org: string, // Required
|
|
588
|
+
actor: string, // Default: 'system'
|
|
589
|
+
action: string, // Required (e.g., 'apply', 'delete', 'dispatch')
|
|
590
|
+
resource: object, // Optional resource reference
|
|
591
|
+
timestamp: string // ISO 8601
|
|
592
|
+
}
|
|
273
593
|
```
|
|
274
594
|
|
|
275
|
-
###
|
|
595
|
+
### 13.2 Query Parameters
|
|
276
596
|
|
|
277
|
-
|
|
|
278
|
-
|
|
279
|
-
|
|
|
280
|
-
|
|
|
281
|
-
|
|
|
282
|
-
|
|
|
283
|
-
|
|
|
284
|
-
|
|
|
285
|
-
| 7. Conflict Check | ConflictController | Compare local vs external, create `ExternalSyncConflict` if diverged |
|
|
286
|
-
| 8. Write Intent | WriteController | Queue `ExternalWriteIntent` if write-back needed |
|
|
597
|
+
| Parameter | Type | Description |
|
|
598
|
+
|-----------|------|-------------|
|
|
599
|
+
| `org` | string | Filter by organization |
|
|
600
|
+
| `action` | string | Filter by action type |
|
|
601
|
+
| `since` | string (ISO) | Events after this time |
|
|
602
|
+
| `until` | string (ISO) | Events before this time |
|
|
603
|
+
| `limit` | number | Max results to return |
|
|
604
|
+
| `offset` | number | Skip first N results |
|
|
287
605
|
|
|
288
|
-
|
|
606
|
+
---
|
|
289
607
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
608
|
+
## 14. Resource Model Utility Functions
|
|
609
|
+
|
|
610
|
+
Source: `packages/krate/core/src/resource-model.js`
|
|
611
|
+
|
|
612
|
+
| Function | Signature | Purpose |
|
|
613
|
+
|----------|-----------|---------|
|
|
614
|
+
| `listResourceDefinitions()` | `() → Array<{kind, storage, context, plural, purpose, requiredSpec}>` | List all 76 definitions |
|
|
615
|
+
| `resourceDefinitionForKind(kind)` | `(string) → definition` | Lookup by kind name |
|
|
616
|
+
| `resourceSchemaForKind(kind)` | `(string) → schema object` | Get schema with required fields |
|
|
617
|
+
| `storageClassForKind(kind)` | `(string) → 'etcd' | 'postgres'` | Get storage backend |
|
|
618
|
+
| `resourceKey(resource)` | `(object) → 'Kind/namespace/name'` | Unique resource key |
|
|
619
|
+
| `clone(value)` | `(any) → deep copy` | `JSON.parse(JSON.stringify(value))` |
|
|
620
|
+
| `createResource(kind, metadata, spec, status)` | `(string, object, object, object) → resource` | Create well-formed resource |
|
|
621
|
+
| `validateResource(resource)` | `(object) → resource (mutated)` | Validate and normalize |
|
|
622
|
+
| `toKubernetesList(kind, items)` | `(string, Array) → { apiVersion, kind, items }` | Wrap as K8s list |
|
|
623
|
+
| `matchLabels(resource, selector)` | `(object, object) → boolean` | Label selector match |
|
|
624
|
+
| `createSelector(spec)` | `(object) → Selector resource` | Create Selector |
|
|
625
|
+
| `createView(spec)` | `(object) → View resource` | Create View |
|
|
626
|
+
| `resourceToYaml(resource)` | `(object) → string` | Serialize to YAML |
|
|
294
627
|
|
|
295
628
|
---
|
|
296
629
|
|
|
297
|
-
##
|
|
630
|
+
## 5. Complete KRATE_RESOURCES Array
|
|
298
631
|
|
|
299
|
-
Source: `packages/krate/
|
|
632
|
+
> Source: `packages/krate/core/src/kubernetes-controller.js` — lines 31–111
|
|
300
633
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
| Tool | Description | Required Inputs |
|
|
304
|
-
|------|-------------|-----------------|
|
|
305
|
-
| `krate_list_resources` | List resources of a given kind | `kind` |
|
|
306
|
-
| `krate_get_resource` | Get single resource | `kind`, `name` |
|
|
307
|
-
| `krate_apply_resource` | Create or update resource | `resource` (object) |
|
|
308
|
-
| `krate_delete_resource` | Delete a resource | `kind`, `name` |
|
|
309
|
-
| `krate_snapshot` | Full org runtime snapshot | (none) |
|
|
310
|
-
| `krate_search` | Search resources by query | `query` |
|
|
311
|
-
| `krate_list_stacks` | List agent stacks | (none) |
|
|
312
|
-
| `krate_create_stack` | Create AgentStack | `name`, `org` |
|
|
313
|
-
| `krate_dispatch_agent` | Dispatch an agent run | `stackRef` |
|
|
314
|
-
| `krate_list_secrets` | List AgentSecretGrant resources | `org` (optional) |
|
|
315
|
-
| `krate_create_secret` | Create AgentSecretGrant | `name`, `org`, `agentRef`, `secretRef` |
|
|
316
|
-
| `krate_sync_external` | Trigger external sync | `bindingName`, `kind`, `localName` |
|
|
317
|
-
| `krate_resolve_conflict` | Resolve sync conflict | `conflictName`, `strategy` |
|
|
318
|
-
| `krate_audit_query` | Query audit events | (all optional: org, action, since, until, limit, offset) |
|
|
319
|
-
|
|
320
|
-
### 8.2 Prompts (3)
|
|
634
|
+
Every entry in `KRATE_RESOURCES` with all fields:
|
|
321
635
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
636
|
+
```javascript
|
|
637
|
+
// ─── Platform-Scoped (listed from krate-system only) ───
|
|
638
|
+
{ kind: 'Organization', plural: 'organizations', namespaced: true, namespace: KRATE_PLATFORM_NAMESPACE, storage: 'etcd', platformScoped: true }
|
|
639
|
+
{ kind: 'OrgNamespaceBinding', plural: 'orgnamespacebindings', namespaced: true, namespace: KRATE_PLATFORM_NAMESPACE, storage: 'etcd', platformScoped: true }
|
|
640
|
+
|
|
641
|
+
// ─── Identity & Access (etcd, org-scoped) ───
|
|
642
|
+
{ kind: 'User', plural: 'users', namespaced: true, storage: 'etcd' }
|
|
643
|
+
{ kind: 'Team', plural: 'teams', namespaced: true, storage: 'etcd' }
|
|
644
|
+
{ kind: 'Invite', plural: 'invites', namespaced: true, storage: 'etcd' }
|
|
645
|
+
{ kind: 'IdentityMapping', plural: 'identitymappings', namespaced: true, storage: 'etcd' }
|
|
646
|
+
{ kind: 'AuthProvider', plural: 'authproviders', namespaced: true, storage: 'etcd' }
|
|
647
|
+
|
|
648
|
+
// ─── Data-Plane (etcd, org-scoped) ───
|
|
649
|
+
{ kind: 'Repository', plural: 'repositories', namespaced: true, storage: 'etcd' }
|
|
650
|
+
{ kind: 'SSHKey', plural: 'sshkeys', namespaced: true, storage: 'etcd' }
|
|
651
|
+
{ kind: 'RepositoryPermission', plural: 'repositorypermissions', namespaced: true, storage: 'etcd' }
|
|
652
|
+
{ kind: 'BranchProtection', plural: 'branchprotections', namespaced: true, storage: 'etcd' }
|
|
653
|
+
{ kind: 'RefPolicy', plural: 'refpolicies', namespaced: true, storage: 'etcd' }
|
|
654
|
+
|
|
655
|
+
// ─── Policy (etcd, org-scoped) ───
|
|
656
|
+
{ kind: 'PolicyProfile', plural: 'policyprofiles', namespaced: true, storage: 'etcd' }
|
|
657
|
+
{ kind: 'PolicyTemplate', plural: 'policytemplates', namespaced: true, storage: 'etcd' }
|
|
658
|
+
{ kind: 'PolicyBinding', plural: 'policybindings', namespaced: true, storage: 'etcd' }
|
|
659
|
+
{ kind: 'PolicyExceptionRequest', plural: 'policyexceptionrequests', namespaced: true, storage: 'etcd' }
|
|
660
|
+
|
|
661
|
+
// ─── Hooks & CI (etcd/postgres) ───
|
|
662
|
+
{ kind: 'WebhookSubscription', plural: 'webhooksubscriptions', namespaced: true, storage: 'etcd' }
|
|
663
|
+
{ kind: 'RunnerPool', plural: 'runnerpools', namespaced: true, storage: 'etcd' }
|
|
664
|
+
{ kind: 'PullRequest', plural: 'pullrequests', namespaced: true, storage: 'postgres' }
|
|
665
|
+
{ kind: 'Issue', plural: 'issues', namespaced: true, storage: 'postgres' }
|
|
666
|
+
{ kind: 'Review', plural: 'reviews', namespaced: true, storage: 'postgres' }
|
|
667
|
+
{ kind: 'Pipeline', plural: 'pipelines', namespaced: true, storage: 'postgres' }
|
|
668
|
+
{ kind: 'Job', plural: 'jobs', namespaced: true, storage: 'postgres' }
|
|
669
|
+
{ kind: 'WebhookDelivery', plural: 'webhookdeliveries', namespaced: true, storage: 'postgres' }
|
|
670
|
+
|
|
671
|
+
// ─── KubeVela Delivery (kubevela storage) ───
|
|
672
|
+
{ kind: 'KubeVelaApplication', plural: 'applications', group: 'core.oam.dev', namespaced: true, storage: 'kubevela' }
|
|
673
|
+
{ kind: 'KubeVelaApplicationRevision', plural: 'applicationrevisions', group: 'core.oam.dev', namespaced: true, storage: 'kubevela' }
|
|
674
|
+
{ kind: 'KubeVelaComponentDefinition', plural: 'componentdefinitions', group: 'core.oam.dev', namespaced: true, namespace: 'vela-system', storage: 'kubevela' }
|
|
675
|
+
{ kind: 'KubeVelaWorkloadDefinition', plural: 'workloaddefinitions', group: 'core.oam.dev', namespaced: true, namespace: 'vela-system', storage: 'kubevela' }
|
|
676
|
+
{ kind: 'KubeVelaTraitDefinition', plural: 'traitdefinitions', group: 'core.oam.dev', namespaced: true, namespace: 'vela-system', storage: 'kubevela' }
|
|
677
|
+
{ kind: 'KubeVelaScopeDefinition', plural: 'scopedefinitions', group: 'core.oam.dev', namespaced: true, namespace: 'vela-system', storage: 'kubevela' }
|
|
678
|
+
{ kind: 'KubeVelaPolicyDefinition', plural: 'policydefinitions', group: 'core.oam.dev', namespaced: true, namespace: 'vela-system', storage: 'kubevela' }
|
|
679
|
+
{ kind: 'KubeVelaPolicy', plural: 'policies', group: 'core.oam.dev', namespaced: true, storage: 'kubevela' }
|
|
680
|
+
{ kind: 'KubeVelaWorkflowStepDefinition', plural: 'workflowstepdefinitions', group: 'core.oam.dev', namespaced: true, namespace: 'vela-system', storage: 'kubevela' }
|
|
681
|
+
{ kind: 'KubeVelaWorkflow', plural: 'workflows', group: 'core.oam.dev', namespaced: true, storage: 'kubevela' }
|
|
682
|
+
{ kind: 'KubeVelaResourceTracker', plural: 'resourcetrackers', group: 'core.oam.dev', namespaced: false, storage: 'kubevela' }
|
|
683
|
+
|
|
684
|
+
// ─── Views & Selectors (etcd) ───
|
|
685
|
+
{ kind: 'View', plural: 'views', namespaced: true, storage: 'etcd' }
|
|
686
|
+
{ kind: 'Selector', plural: 'selectors', namespaced: true, storage: 'etcd' }
|
|
687
|
+
|
|
688
|
+
// ─── Agent Orchestration CRDs (etcd) ───
|
|
689
|
+
{ kind: 'AgentStack', plural: 'agentstacks', namespaced: true, storage: 'etcd' }
|
|
690
|
+
{ kind: 'AgentSubagent', plural: 'agentsubagents', namespaced: true, storage: 'etcd' }
|
|
691
|
+
{ kind: 'AgentToolProfile', plural: 'agenttoolprofiles', namespaced: true, storage: 'etcd' }
|
|
692
|
+
{ kind: 'AgentMcpServer', plural: 'agentmcpservers', namespaced: true, storage: 'etcd' }
|
|
693
|
+
{ kind: 'AgentSkill', plural: 'agentskills', namespaced: true, storage: 'etcd' }
|
|
694
|
+
{ kind: 'AgentTriggerRule', plural: 'agenttriggerrules', namespaced: true, storage: 'etcd' }
|
|
695
|
+
{ kind: 'AgentContextLabel', plural: 'agentcontextlabels', namespaced: true, storage: 'etcd' }
|
|
696
|
+
{ kind: 'KrateWorkspacePolicy', plural: 'krateworkspacepolicies', namespaced: true, storage: 'etcd' }
|
|
697
|
+
{ kind: 'AgentServiceAccount', plural: 'agentserviceaccounts', namespaced: true, storage: 'etcd' }
|
|
698
|
+
{ kind: 'AgentRoleBinding', plural: 'agentrolebindings', namespaced: true, storage: 'etcd' }
|
|
699
|
+
{ kind: 'AgentSecretGrant', plural: 'agentsecretgrants', namespaced: true, storage: 'etcd' }
|
|
700
|
+
{ kind: 'AgentConfigGrant', plural: 'agentconfiggrants', namespaced: true, storage: 'etcd' }
|
|
701
|
+
{ kind: 'AgentAdapter', plural: 'agentadapters', namespaced: true, storage: 'etcd' }
|
|
702
|
+
{ kind: 'AgentTransportBinding', plural: 'agenttransportbindings', namespaced: true, storage: 'etcd' }
|
|
703
|
+
{ kind: 'AgentProviderConfig', plural: 'agentproviderconfigs', namespaced: true, storage: 'etcd' }
|
|
704
|
+
{ kind: 'KrateProject', plural: 'krateprojects', namespaced: true, storage: 'etcd' }
|
|
705
|
+
{ kind: 'AgentGatewayConfig', plural: 'agentgatewayconfigs', namespaced: true, storage: 'etcd' }
|
|
706
|
+
{ kind: 'AgentMemoryRepository', plural: 'agentmemoryrepositories', namespaced: true, storage: 'etcd' }
|
|
707
|
+
{ kind: 'AgentMemorySource', plural: 'agentmemorysources', namespaced: true, storage: 'etcd' }
|
|
708
|
+
{ kind: 'AgentMemoryOntology', plural: 'agentmemoryontologies', namespaced: true, storage: 'etcd' }
|
|
709
|
+
{ kind: 'AgentMemoryAssociation', plural: 'agentmemoryassociations', namespaced: true, storage: 'etcd' }
|
|
710
|
+
|
|
711
|
+
// ─── Agent Aggregated Resources (postgres) ───
|
|
712
|
+
{ kind: 'AgentDispatchRun', plural: 'agentdispatchruns', namespaced: true, storage: 'postgres' }
|
|
713
|
+
{ kind: 'AgentDispatchAttempt', plural: 'agentdispatchattempts', namespaced: true, storage: 'postgres' }
|
|
714
|
+
{ kind: 'AgentSession', plural: 'agentsessions', namespaced: true, storage: 'postgres' }
|
|
715
|
+
{ kind: 'AgentContextBundle', plural: 'agentcontextbundles', namespaced: true, storage: 'postgres' }
|
|
716
|
+
{ kind: 'KrateArtifact', plural: 'krateartifacts', namespaced: true, storage: 'postgres' }
|
|
717
|
+
{ kind: 'AgentApproval', plural: 'agentapprovals', namespaced: true, storage: 'postgres' }
|
|
718
|
+
{ kind: 'KrateWorkspace', plural: 'krateworkspaces', namespaced: true, storage: 'postgres' }
|
|
719
|
+
{ kind: 'AgentTriggerExecution', plural: 'agenttriggerexecutions', namespaced: true, storage: 'postgres' }
|
|
720
|
+
{ kind: 'KrateWorkspaceRuntime', plural: 'krateworkspaceruntimes', namespaced: true, storage: 'postgres' }
|
|
721
|
+
{ kind: 'AgentSessionTranscript', plural: 'agentsessiontranscripts', namespaced: true, storage: 'postgres' }
|
|
722
|
+
|
|
723
|
+
// ─── External Backend (etcd) ───
|
|
724
|
+
{ kind: 'ExternalBackendProvider', plural: 'externalbackendproviders', namespaced: true, storage: 'etcd' }
|
|
725
|
+
{ kind: 'ExternalBackendBinding', plural: 'externalbackendbindings', namespaced: true, storage: 'etcd' }
|
|
726
|
+
{ kind: 'ExternalBackendSyncPolicy', plural: 'externalbackendsyncpolicies', namespaced: true, storage: 'etcd' }
|
|
727
|
+
|
|
728
|
+
// ─── Core Kubernetes (excluded from snapshot — on-demand access only) ───
|
|
729
|
+
{ kind: 'Secret', plural: 'secrets', group: '', namespaced: true, storage: 'core' }
|
|
730
|
+
{ kind: 'ConfigMap', plural: 'configmaps', group: '', namespaced: true, storage: 'core' }
|
|
731
|
+
```
|
|
327
732
|
|
|
328
|
-
|
|
733
|
+
Additionally, `KYVERNO_RESOURCES` (10 entries, discovered separately):
|
|
329
734
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
735
|
+
```javascript
|
|
736
|
+
{ kind: 'KyvernoPolicy', plural: 'policies', group: 'kyverno.io', namespaced: true, storage: 'kyverno', namespace: KRATE_KYVERNO_POLICY_NAMESPACE }
|
|
737
|
+
{ kind: 'KyvernoClusterPolicy', plural: 'clusterpolicies', group: 'kyverno.io', namespaced: false, storage: 'kyverno' }
|
|
738
|
+
{ kind: 'KyvernoValidatingPolicy', plural: 'validatingpolicies', group: 'policies.kyverno.io', namespaced: false, storage: 'kyverno' }
|
|
739
|
+
{ kind: 'KyvernoMutatingPolicy', plural: 'mutatingpolicies', group: 'policies.kyverno.io', namespaced: false, storage: 'kyverno' }
|
|
740
|
+
{ kind: 'KyvernoGeneratingPolicy', plural: 'generatingpolicies', group: 'policies.kyverno.io', namespaced: false, storage: 'kyverno' }
|
|
741
|
+
{ kind: 'KyvernoDeletingPolicy', plural: 'deletingpolicies', group: 'policies.kyverno.io', namespaced: false, storage: 'kyverno' }
|
|
742
|
+
{ kind: 'KyvernoImageValidatingPolicy', plural: 'imagevalidatingpolicies', group: 'policies.kyverno.io', namespaced: false, storage: 'kyverno' }
|
|
743
|
+
{ kind: 'KyvernoPolicyException', plural: 'policyexceptions', group: 'policies.kyverno.io', namespaced: true, storage: 'kyverno', namespace: KRATE_KYVERNO_POLICY_NAMESPACE }
|
|
744
|
+
{ kind: 'PolicyReport', plural: 'policyreports', group: 'wgpolicyk8s.io', namespaced: true, storage: 'kyverno-reports' }
|
|
745
|
+
{ kind: 'ClusterPolicyReport', plural: 'clusterpolicyreports', group: 'wgpolicyk8s.io', namespaced: false, storage: 'kyverno-reports' }
|
|
746
|
+
```
|
|
334
747
|
|
|
335
748
|
---
|
|
336
749
|
|
|
337
|
-
##
|
|
750
|
+
## 6. Agent Dispatch State Machine
|
|
338
751
|
|
|
339
|
-
Source: `packages/krate/
|
|
752
|
+
> Source: `packages/krate/core/src/agent-dispatch-controller.js`, observed from controller-ui.js active filtering
|
|
340
753
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
754
|
+
### 6.1 Phase Transitions
|
|
755
|
+
|
|
756
|
+
```
|
|
757
|
+
┌────────────────────────────────────────────────────────────┐
|
|
758
|
+
│ │
|
|
759
|
+
┌─────────┐ ┌──▼──────────────┐ ┌──────────┐ ┌─────────┐ ┌──────────▼─┐
|
|
760
|
+
│ Pending │──▶│AwaitingApproval │──▶│ Queued │──▶│ Running │──▶│ Completed │
|
|
761
|
+
└─────────┘ └─────────────────┘ └──────────┘ └─────────┘ └────────────┘
|
|
762
|
+
│ │ │ │
|
|
763
|
+
│ │ (denied) │ │
|
|
764
|
+
│ ▼ ▼ │
|
|
765
|
+
│ ┌──────────┐ ┌──────────┐ │
|
|
766
|
+
└───────────▶│ Failed │◀────────────────────│ Failed │◀───────┘
|
|
767
|
+
└──────────┘ └──────────┘
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
### 6.2 Transition Triggers
|
|
771
|
+
|
|
772
|
+
| From | To | Trigger | Conditions |
|
|
773
|
+
|------|----|---------|-----------|
|
|
774
|
+
| (new) | `Pending` | `createDispatchRun()` called | Valid stack reference, org resolved |
|
|
775
|
+
| `Pending` | `AwaitingApproval` | Stack or workspace policy requires approval | `spec.requiresApproval: true` or KrateWorkspacePolicy matches |
|
|
776
|
+
| `Pending` | `Queued` | No approval required | Direct dispatch allowed by permission review |
|
|
777
|
+
| `AwaitingApproval` | `Queued` | `approveAgentAction()` invoked by authorized user | AgentApproval resource phase → `Approved` |
|
|
778
|
+
| `AwaitingApproval` | `Failed` | `denyAgentAction()` invoked | AgentApproval resource phase → `Denied` |
|
|
779
|
+
| `Queued` | `Running` | Runner pool assigns a runner | Runner created/reused via `scheduleJob()` (see §30 in architecture-v2.md) |
|
|
780
|
+
| `Running` | `Completed` | Agent session reports success | Session status phase → `Completed` |
|
|
781
|
+
| `Running` | `Failed` | Agent session reports failure or timeout | Session status phase → `Failed` or runner terminated |
|
|
782
|
+
| `Pending` | `Failed` | Permission review denies dispatch | Missing role binding, workspace policy violation, or cross-org denial |
|
|
783
|
+
|
|
784
|
+
### 6.3 Data Stored at Each Phase
|
|
785
|
+
|
|
786
|
+
| Phase | Key Status Fields |
|
|
787
|
+
|-------|-------------------|
|
|
788
|
+
| `Pending` | `createdAt`, `stackRef`, `organizationRef`, `triggerRef?`, `requestedBy` |
|
|
789
|
+
| `AwaitingApproval` | + `approvalRef` (name of AgentApproval resource), `awaitingSince` |
|
|
790
|
+
| `Queued` | + `queuedAt`, `priority`, `runnerPoolRef` |
|
|
791
|
+
| `Running` | + `startedAt`, `runnerId`, `sessionRef`, `workspaceRef`, `attemptNumber` |
|
|
792
|
+
| `Completed` | + `completedAt`, `duration`, `artifacts[]`, `exitCode: 0` |
|
|
793
|
+
| `Failed` | + `failedAt`, `duration?`, `lastError`, `retryable`, `exitCode?` |
|
|
794
|
+
|
|
795
|
+
### 6.4 Retry Semantics
|
|
796
|
+
|
|
797
|
+
- **New attempt:** A failed run can be retried by creating a new `AgentDispatchRun` with the same `stackRef` and an incremented `spec.attemptNumber`. The new run starts at `Pending`.
|
|
798
|
+
- **Re-queue:** Not supported. Once a run leaves `Queued`, it cannot return to that phase. The runner controller handles low-level scheduling retries internally.
|
|
799
|
+
- Each run's `AgentDispatchAttempt` resources track per-attempt history (one per execution cycle).
|
|
800
|
+
|
|
801
|
+
---
|
|
802
|
+
|
|
803
|
+
## 7. Workspace State Machine
|
|
804
|
+
|
|
805
|
+
> Source: `packages/krate/core/src/agent-workspace-controller.js`
|
|
806
|
+
|
|
807
|
+
### 7.1 Workspace Lifecycle Phases
|
|
808
|
+
|
|
809
|
+
```
|
|
810
|
+
┌─────────┐ ┌──────────────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌──────────┐ ┌──────────┐
|
|
811
|
+
│ Pending │──▶│ Provisioning │──▶│ Ready │──▶│ InUse │──▶│ Ready │──▶│ Archiving│──▶│ Archived │
|
|
812
|
+
└─────────┘ └──────────────┘ └───────┘ └───────┘ └───────┘ └──────────┘ └──────────┘
|
|
813
|
+
│ ▲
|
|
814
|
+
└───────────────────────┘
|
|
815
|
+
(released by run)
|
|
816
|
+
```
|
|
817
|
+
|
|
818
|
+
| Phase | Description | Duration |
|
|
819
|
+
|-------|-------------|----------|
|
|
820
|
+
| `Pending` | Workspace resource created, waiting for provisioner | Seconds |
|
|
821
|
+
| `Provisioning` | PVC being created, git clone starting, runtime booting | 10-60s |
|
|
822
|
+
| `Ready` | Workspace available for claiming by a dispatch run | Indefinite (warm pool) |
|
|
823
|
+
| `InUse` | Claimed by an AgentDispatchRun, agent session active | Duration of run |
|
|
824
|
+
| `Ready` (released) | Run completed, workspace returned to pool | Until next claim or TTL |
|
|
825
|
+
| `Archiving` | Artifacts being collected, PVC snapshot taken | Seconds |
|
|
826
|
+
| `Archived` | Terminal state. PVC released, metadata retained | Permanent |
|
|
827
|
+
|
|
828
|
+
### 7.2 PVC Lifecycle
|
|
829
|
+
|
|
830
|
+
| PVC Phase | Workspace Phase | Action |
|
|
831
|
+
|-----------|-----------------|--------|
|
|
832
|
+
| — | `Pending` | PVC does not exist yet |
|
|
833
|
+
| `Pending` | `Provisioning` | PVC created with `storageClassName` and requested size |
|
|
834
|
+
| `Bound` | `Ready` | PVC bound to a PV, filesystem mounted |
|
|
835
|
+
| `Bound` | `InUse` | Same PVC, now mounted in runner pod |
|
|
836
|
+
| `Bound` | `Archiving` | Snapshot taken if configured |
|
|
837
|
+
| `Released` | `Archived` | PVC deleted or reclaimed by storage class |
|
|
838
|
+
|
|
839
|
+
PVC naming convention: `krate-ws-${runId}` (generated by runner-controller, see architecture-v2.md §30.5).
|
|
840
|
+
|
|
841
|
+
### 7.3 Git State (within workspace)
|
|
842
|
+
|
|
843
|
+
| Git Phase | Description |
|
|
844
|
+
|-----------|-------------|
|
|
845
|
+
| `Cloning` | `git clone` in progress during Provisioning |
|
|
846
|
+
| `Ready` | Clean worktree, all branches fetched |
|
|
847
|
+
| `Dirty` | Agent has uncommitted changes (during InUse) |
|
|
848
|
+
| `Synced` | Changes committed and pushed (during InUse or on release) |
|
|
849
|
+
|
|
850
|
+
### 7.4 Codespace State (optional runtime container)
|
|
851
|
+
|
|
852
|
+
| Codespace Phase | Trigger |
|
|
853
|
+
|-----------------|---------|
|
|
854
|
+
| `Stopped` | Workspace created but runtime not started |
|
|
855
|
+
| `Starting` | Container runtime booting (image pull, env setup) |
|
|
856
|
+
| `Running` | IDE/agent connected, dev server available |
|
|
857
|
+
| `Stopping` | Graceful shutdown initiated (run complete or timeout) |
|
|
858
|
+
|
|
859
|
+
### 7.5 Key Transitions
|
|
860
|
+
|
|
861
|
+
| From | To | Trigger |
|
|
862
|
+
|------|----|---------|
|
|
863
|
+
| `Pending` → `Provisioning` | PVC creation initiated by workspace controller |
|
|
864
|
+
| `Provisioning` → `Ready` | PVC bound + git clone complete + runtime healthy |
|
|
865
|
+
| `Ready` → `InUse` | `scheduleJob()` claims workspace for a dispatch run |
|
|
866
|
+
| `InUse` → `Ready` | Run completes, workspace released back to pool |
|
|
867
|
+
| `Ready` → `Archiving` | TTL expired or explicit archive request |
|
|
868
|
+
| `InUse` → `Archiving` | Run failed + workspace marked for cleanup |
|
|
869
|
+
| `Archiving` → `Archived` | Artifacts saved, PVC released |
|
|
870
|
+
|
|
871
|
+
---
|
|
872
|
+
|
|
873
|
+
## 8. Memory Import State Machine
|
|
874
|
+
|
|
875
|
+
> Source: `packages/krate/core/src/agent-memory-controller.js`, observed from controller-ui.js memoryImports filtering
|
|
876
|
+
|
|
877
|
+
### 8.1 Lifecycle Phases
|
|
878
|
+
|
|
879
|
+
```
|
|
880
|
+
┌───────────┐ ┌───────────┐ ┌──────────────┐ ┌────────────┐ ┌─────────────────┐ ┌────────────────────────┐ ┌────────┐
|
|
881
|
+
│ Collected │──▶│ Redacting │──▶│ Normalizing │──▶│ Validating │──▶│ AwaitingReview │──▶│ Approved / Rejected │──▶│ Merged │
|
|
882
|
+
└───────────┘ └───────────┘ └──────────────┘ └────────────┘ └─────────────────┘ └────────────────────────┘ └────────┘
|
|
883
|
+
```
|
|
884
|
+
|
|
885
|
+
### 8.2 Phase Descriptions
|
|
886
|
+
|
|
887
|
+
| Phase | Description | Owner |
|
|
888
|
+
|-------|-------------|-------|
|
|
889
|
+
| `Collected` | Raw memory data extracted from a babysitter run or agent session transcript. Contains conversation fragments, decisions, tool outputs. | Automated (agent session completion handler) |
|
|
890
|
+
| `Redacting` | PII and secrets are stripped. Credential patterns, email addresses, API keys, file paths with usernames are removed or masked. | Automated (redaction pipeline) |
|
|
891
|
+
| `Normalizing` | Extracted facts are normalized into the ontology schema: entities, relationships, decisions, patterns. Deduplication against existing memory. | Automated (normalization engine) |
|
|
892
|
+
| `Validating` | Schema validation of normalized memory entries. Cross-references checked against existing AgentMemoryAssociation resources. Confidence scores computed. | Automated (validation rules) |
|
|
893
|
+
| `AwaitingReview` | Human review required. Low-confidence entries, novel ontology terms, or entries referencing sensitive resources are queued for approval. | Human reviewer |
|
|
894
|
+
| `Approved` | Reviewer accepted the import. Ready for merge into the memory repository. | Human (via UI or API) |
|
|
895
|
+
| `Rejected` | Reviewer rejected. Reasons recorded. Will not be merged. | Human (via UI or API) |
|
|
896
|
+
| `Merged` | Terminal. Memory entries written to AgentMemoryRepository, associations created, ontology updated if needed. | Automated (merge pipeline) |
|
|
897
|
+
|
|
898
|
+
### 8.3 Data at Each Phase
|
|
899
|
+
|
|
900
|
+
| Phase | Key Fields |
|
|
901
|
+
|-------|-----------|
|
|
902
|
+
| `Collected` | `sourceRef` (session/run), `rawEntries[]`, `collectedAt`, `sourceType` |
|
|
903
|
+
| `Redacting` | + `redactedFields[]`, `redactionRules` applied |
|
|
904
|
+
| `Normalizing` | + `normalizedEntries[]`, `ontologyTerms[]`, `deduplicationResults` |
|
|
905
|
+
| `Validating` | + `validationErrors[]`, `confidenceScores{}`, `crossRefResults` |
|
|
906
|
+
| `AwaitingReview` | + `reviewRequestedAt`, `reviewerHint`, `flaggedEntries[]` |
|
|
907
|
+
| `Approved` | + `approvedBy`, `approvedAt`, `approvalNotes` |
|
|
908
|
+
| `Rejected` | + `rejectedBy`, `rejectedAt`, `rejectionReason` |
|
|
909
|
+
| `Merged` | + `mergedAt`, `repositoryRef`, `createdAssociations[]`, `mergedEntryCount` |
|
|
910
|
+
|
|
911
|
+
### 8.4 Transition Rules
|
|
912
|
+
|
|
913
|
+
- `Collected → Redacting`: automatic, immediate after collection
|
|
914
|
+
- `Redacting → Normalizing`: automatic after redaction pass completes
|
|
915
|
+
- `Normalizing → Validating`: automatic after normalization
|
|
916
|
+
- `Validating → AwaitingReview`: when any entry has confidence < threshold OR novel ontology term OR references sensitive resource
|
|
917
|
+
- `Validating → Approved`: when all entries pass validation with high confidence (auto-approve path)
|
|
918
|
+
- `AwaitingReview → Approved`: human calls approve endpoint
|
|
919
|
+
- `AwaitingReview → Rejected`: human calls reject endpoint
|
|
920
|
+
- `Approved → Merged`: automatic, writes to memory repository
|
|
921
|
+
- `Rejected`: terminal (no further transitions)
|
|
922
|
+
|
|
923
|
+
The controller-ui.js filters pending imports as: `memoryImports.filter(i => !i.status?.phase || i.status.phase === 'Pending' || i.status.phase === 'AwaitingReview')`
|