@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.
@@ -1,352 +1,923 @@
1
1
  # Krate System Specification v2
2
2
 
3
- > Derived from implementation. Source: `packages/krate/core/src/`
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
- ### CONFIG Kinds (etcd storage — 44 kinds)
10
-
11
- | Kind | Context | Plural | Purpose | RequiredSpec |
12
- |------|---------|--------|---------|--------------|
13
- | Organization | identity | organizations | Krate organization identity in the platform namespace | displayName, namespaceName |
14
- | OrgNamespaceBinding | identity | orgnamespacebindings | Binding from org to tenant namespace | organizationRef, namespace |
15
- | User | identity | users | Human account profile, sign-in state, admin flag | organizationRef, displayName, email |
16
- | Team | identity | teams | Team membership, maintainers, permission grants | organizationRef, displayName |
17
- | Invite | identity | invites | Pending user invitation with expiry | organizationRef, email, role |
18
- | IdentityMapping | identity | identitymappings | Mapping between Krate users and external subjects | organizationRef, user, provider, subject |
19
- | AuthProvider | identity | authproviders | Sign-in provider configuration | organizationRef, type |
20
- | Repository | data-plane | repositories | Repository identity, visibility, hosting integration | organizationRef, visibility |
21
- | SSHKey | data-plane | sshkeys | User/deploy/automation SSH keys | organizationRef, scope, key |
22
- | RepositoryPermission | data-plane | repositorypermissions | Repository collaborators and teams | organizationRef, repository, subject, permission |
23
- | WebhookSubscription | hooks-events | webhooksubscriptions | Endpoint, event filters, signing, delivery mode | organizationRef, url, events |
24
- | RefPolicy | data-plane | refpolicies | Reference deny rules, force-push policy | organizationRef |
25
- | BranchProtection | control-plane | branchprotections | Protected ref rules | organizationRef, refs |
26
- | PolicyProfile | policy | policyprofiles | Org policy posture, default templates | organizationRef, displayName, mode |
27
- | PolicyTemplate | policy | policytemplates | Kyverno policy template metadata | displayName, targetKinds, kyverno |
28
- | PolicyBinding | policy | policybindings | Template binding with audit/enforce state | organizationRef, templateRef, mode |
29
- | PolicyExceptionRequest | policy | policyexceptionrequests | Temporary PolicyException request | organizationRef, policyRef, justification, expiresAt |
30
- | View | web-ui | views | Saved triage/dashboard view | organizationRef, selector |
31
- | Selector | web-ui | selectors | Reusable label/query selector | organizationRef |
32
- | RunnerPool | runners-ci | runnerpools | Runner capacity, warm/max replicas, cache | organizationRef, warmReplicas, maxReplicas |
33
- | AgentStack | agents | agentstacks | Reusable agent definition with full config | organizationRef, baseAgent, adapter, runtimeIdentity |
34
- | AgentSubagent | agents | agentsubagents | Named child-agent definition | organizationRef, rolePrompt, taskKinds |
35
- | AgentToolProfile | agents | agenttoolprofiles | Native tool policy for filesystem/network/shell | organizationRef, filesystemPolicy, approvalPolicyByTool |
36
- | AgentMcpServer | agents | agentmcpservers | Managed MCP endpoint with transport/health | organizationRef, transport, scope |
37
- | AgentSkill | agents | agentskills | Reusable runbook/procedure bundle | organizationRef, format, sourceRef |
38
- | AgentTriggerRule | agents | agenttriggerrules | Event-to-stack routing | organizationRef, sources, agentStack, taskKind |
39
- | AgentContextLabel | agents | agentcontextlabels | Reviewed prompt fragment | organizationRef, promptFragment, allowedSources |
40
- | KrateWorkspacePolicy | agents | krateworkspacepolicies | Workspace provisioning/cleanup policies | organizationRef, mode, retentionPolicy |
41
- | AgentServiceAccount | identity | agentserviceaccounts | K8s ServiceAccount wrapper for agent identity | organizationRef, namespace, serviceAccountName |
42
- | AgentRoleBinding | identity | agentrolebindings | Managed RBAC projection for agent identity | organizationRef, subject, roleRef, scope |
43
- | AgentSecretGrant | identity | agentsecretgrants | Permission to access Secret keys | organizationRef, subject, secretRef, purpose |
44
- | AgentConfigGrant | identity | agentconfiggrants | Permission to access ConfigMap keys | organizationRef, subject, configMapRef, purpose |
45
- | AgentAdapter | agents | agentadapters | Agent adapter with transport/capabilities | organizationRef, adapterType, transport |
46
- | AgentTransportBinding | agents | agenttransportbindings | Adapter connection configuration | organizationRef, adapterRef, endpoint, protocol |
47
- | AgentProviderConfig | agents | agentproviderconfigs | Model provider configuration | organizationRef, provider, authType |
48
- | KrateProject | agents | krateprojects | Org project grouping issues/repos | organizationRef, displayName |
49
- | AgentGatewayConfig | agents | agentgatewayconfigs | Agent Mux gateway connection settings | organizationRef, gatewayUrl |
50
- | AgentMemoryRepository | agents | agentmemoryrepositories | Git repo pointer for shared agent memory | organizationRef, repositoryRef, defaultBranch, layoutProfile |
51
- | AgentMemorySource | agents | agentmemorysources | Read policy for memory paths/kinds | organizationRef, repositoryRef, appliesTo, include |
52
- | AgentMemoryOntology | agents | agentmemoryontologies | Ontology policy with fields/edges/vocabulary | organizationRef, memoryRepository, ontologyPath |
53
- | AgentMemoryAssociation | agents | agentmemoryassociations | Bridge linking memory to Krate resources | organizationRef, memoryRef, targetRef, relationship |
54
- | KrateWorkspace | workspaces | krateworkspaces | Volume-backed git workspace with PVC lifecycle | organizationRef, repository, volumeSpec |
55
- | ExternalBackendProvider | external-backends | externalbackendproviders | External provider registration | organizationRef, providerType, endpoint |
56
- | ExternalBackendBinding | external-backends | externalbackendbindings | Provider binding to org | organizationRef, providerRef, credentialRef |
57
- | ExternalBackendSyncPolicy | external-backends | externalbackendsyncpolicies | Sync interval, conflict resolution | organizationRef, providerRef, syncInterval |
58
- | ExternalProviderCapabilityManifest | external-backends | externalprovidercapabilitymanifests | Discovered provider capabilities | organizationRef, providerRef, capabilities |
59
-
60
- ### AGGREGATED Kinds (postgres storage 32 kinds)
61
-
62
- | Kind | Context | Plural | Purpose | RequiredSpec |
63
- |------|---------|--------|---------|--------------|
64
- | PullRequest | control-plane | pullrequests | Review unit with source/target refs | organizationRef, repository, title |
65
- | Issue | control-plane | issues | Project-scoped work item | organizationRef, title |
66
- | Review | control-plane | reviews | Approval/comment for a PR | organizationRef, pullRequest |
67
- | Pipeline | runners-ci | pipelines | CI pipeline run state | organizationRef, repository, ref |
68
- | Job | runners-ci | jobs | Executable CI step | organizationRef, pipeline, step |
69
- | WebhookDelivery | hooks-events | webhookdeliveries | Outbound webhook delivery attempt | organizationRef, subscription, eventType, signature |
70
- | AgentDispatchRun | agents | agentdispatchruns | Logical agent run with queue/status/cost | organizationRef, repository, sourceRefs, agentStack, taskKind |
71
- | AgentDispatchAttempt | agents | agentdispatchattempts | Concrete execution attempt | organizationRef, agentDispatchRun, attemptReason, agentStackSnapshot |
72
- | AgentSession | agents | agentsessions | Agent Mux session projection | organizationRef, agentMuxSessionId, dispatchRun |
73
- | AgentContextBundle | agents | agentcontextbundles | Immutable prompt/context snapshot | organizationRef, dispatchRun, digest, sources |
74
- | KrateArtifact | agents | krateartifacts | Durable agent output | organizationRef, dispatchRun, kind, digest |
75
- | AgentApproval | agents | agentapprovals | Human gate for actions | organizationRef, dispatchRun, action, requestedBy |
76
- | AgentTriggerExecution | agents | agenttriggerexecutions | Trigger evaluation record | organizationRef, triggerRule, sourceEvent, decision |
77
- | AgentCapabilityRequirement | agents | agentcapabilityrequirements | Computed dependency record | organizationRef, ownerRef, requiredRoles |
78
- | WorkItemSessionLink | agents | workitemsessionlinks | Issue/PR to session association | organizationRef, workItemRef, agentSession |
79
- | WorkItemWorkspaceLink | agents | workitemworkspacelinks | Issue/PR to workspace association | organizationRef, workItemRef, workspace |
80
- | AgentSessionTranscript | agents | agentsessiontranscripts | Chat transcript with cost | organizationRef, sessionRef, messages |
81
- | AgentSessionAttachment | agents | agentsessionattachments | File attached to session | organizationRef, sessionRef, sourceType, digest |
82
- | KrateWorkspaceRuntime | agents | krateworkspaceruntimes | Workspace runtime state | organizationRef, workspaceRef, status |
83
- | AgentMemorySnapshot | agents | agentmemorysnapshots | Dispatch-time memory pin | organizationRef, memoryRepository, requestedRef, resolvedCommit |
84
- | AgentMemoryQuery | agents | agentmemoryqueries | Retrieval record with results | organizationRef, snapshotRef, requester, query |
85
- | AgentMemoryUpdate | agents | agentmemoryupdates | Proposed memory mutation | organizationRef, memoryRepository, sourceRun, changes |
86
- | AgentRunMemoryImport | agents | agentrunmemoryimports | Import run metadata into memory | organizationRef, memoryRepository, source, include |
87
- | ExternalWebhookDelivery | external-backends | externalwebhookdeliveries | Inbound webhook from external | organizationRef, providerRef, eventType, payload |
88
- | ExternalSyncEvent | external-backends | externalsyncevents | Sync event record | organizationRef, providerRef, eventKind, resourceRef |
89
- | ExternalSyncState | external-backends | externalsyncstates | Current sync phase/status | organizationRef, providerRef, resourceRef, phase |
90
- | ExternalWriteIntent | external-backends | externalwriteintents | Queued write-back intent | organizationRef, providerRef, resourceRef, operation |
91
- | ExternalSyncConflict | external-backends | externalsyncconflicts | Detected conflict with diff | organizationRef, providerRef, resourceRef, conflictKind |
92
- | ExternalObjectLink | external-backends | externalobjectlinks | Mapping between local and external | organizationRef, providerRef, externalId, localRef |
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
- All HTTP routes from `packages/krate/core/src/http-server.js`:
99
-
100
- | Method | Path | Auth | Description |
101
- |--------|------|------|-------------|
102
- | GET | `/healthz` | No | Health check |
103
- | GET | `/api/controller` | No | Full controller UI model (optional `?org=`) |
104
- | GET | `/api/orgs` | No | List organizations |
105
- | POST | `/api/orgs` | Yes | Create organization |
106
- | GET | `/api/orgs/:org/resources` | No | List resources by kind (`?kind=`) |
107
- | POST | `/api/orgs/:org/resources` | Yes | Apply (create/update) resource |
108
- | GET | `/api/orgs/:org/resources/:kind/:name` | No | Get single resource |
109
- | DELETE | `/api/orgs/:org/resources/:kind/:name` | Yes | Delete resource |
110
- | GET | `/api/orgs/:org/repositories` | No | List repositories |
111
- | POST | `/api/orgs/:org/repositories` | Yes | Create repository |
112
- | GET | `/api/orgs/:org/repositories/:name` | No | Get repository |
113
- | DELETE | `/api/orgs/:org/repositories/:name` | Yes | Delete repository |
114
- | GET | `/api/orgs/:org/snapshot` | No | Org runtime snapshot |
115
- | POST | `/api/orgs/:org/snapshot` | Yes | Import snapshot |
116
- | GET | `/api/orgs/:org/runtime-resources/:kind` | No | List runtime resources by kind |
117
- | POST | `/api/orgs/:org/repositories/:repo/objects` | Yes | Record git object |
118
- | POST | `/api/orgs/:org/repositories/:repo/search-index` | Yes | Enqueue search index |
119
- | POST | `/api/orgs/:org/pullrequests` | Yes | Create pull request |
120
- | POST | `/api/orgs/:org/pullrequests/:pr/reviews` | Yes | Add review |
121
- | POST | `/api/orgs/:org/pullrequests/:pr/checks/complete` | Yes | Complete pipeline check |
122
- | POST | `/api/orgs/:org/pullrequests/:pr/merge` | Yes | Merge pull request |
123
- | POST | `/api/orgs/:org/agents/approvals/:name/decide` | Yes | Approve/deny agent action |
124
- | POST | `/api/orgs/:org/agents/webhooks/ingest` | Yes | Ingest webhook event |
125
- | POST | `/api/orgs/:org/agents/events/pipeline-failure` | Yes | Pipeline failure event |
126
- | POST | `/api/orgs/:org/agents/events/comment` | Yes | Comment event |
127
- | POST | `/api/orgs/:org/agents/events/label` | Yes | Label event |
128
- | POST | `/api/orgs/:org/agents/triggers/process` | Yes | Process trigger |
129
- | POST | `/api/orgs/:org/agents/memory/query` | Yes | Query agent memory |
130
- | GET | `/api/orgs/:org/secrets` | No | List secrets |
131
- | POST | `/api/orgs/:org/secrets` | Yes | Create secret |
132
- | DELETE | `/api/orgs/:org/secrets/:name` | Yes | Delete secret |
133
- | GET | `/api/orgs/:org/secret-grants` | No | List secret grants |
134
- | POST | `/api/orgs/:org/secret-grants` | Yes | Create secret grant |
135
- | POST | `/api/orgs/:org/external/sync` | Yes | Trigger external sync |
136
- | POST | `/api/orgs/:org/external/conflicts/:name/resolve` | Yes | Resolve sync conflict |
137
- | POST | `/api/orgs/:org/external/write-intents/:name/approve` | Yes | Approve write intent |
138
- | POST | `/api/orgs/:org/external/write-intents/:name/cancel` | Yes | Cancel write intent |
139
- | GET | `/api/orgs/:org/agents/events/stream` | No | SSE event stream |
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
- Each controller declares an explicit boundary object. Source: respective controller files.
146
-
147
- | Controller | File | Role | Owns | Delegates To | Must Not Own |
148
- |-----------|------|------|------|--------------|--------------|
149
- | KubernetesResourceClient | `kubernetes-controller.js` | Workspace API, access checks | command execution, API discovery, access checks, watch streams | — | HTTP routes, Next.js pages, forge DTO, business workflows |
150
- | KrateKubernetesReconciler | `kubernetes-controller.js` | Resource reconciliation | Repository status, identity projection, hosting intent, policy sync, degraded conditions | kubernetes-resource-gateway, git-data-plane | HTTP routes, web pages, API DTO, browser behavior |
151
- | AgentStackController | `agent-stack-controller.js` | Stack readiness reconciliation | capability resolution, conditions, readiness, MCP health | agent-permission-review, resource-model | secret values, dispatch execution, Agent Mux sessions |
152
- | AgentDispatchController | `agent-dispatch-controller.js` | Manual dispatch orchestration | dispatch creation, attempt lifecycle, session binding, workspace provisioning | agent-permission-review, agent-stack, agent-context-bundles, agent-mux-client, agent-memory, agent-approval, agent-workspace | secret values, UI rendering |
153
- | AgentWorkspaceController | `agent-workspace-controller.js` | Volume-backed workspace provisioning | workspace creation, PVC generation, git specs, mount specs, reuse, codespace, associations, run history | resource-model | git execution, K8s API, secrets |
154
- | AgentMemoryQuery | `agent-memory-query.js` | In-memory graph/grep query | graph traversal, nodeKind filtering, edge following, scoring, grep, context extraction | (none) | persistence, HTTP, K8s, secrets |
155
- | WebhookController | `external/webhook-controller.js` | Inbound webhook delivery | HMAC validation, delivery records, dedup, event queue | sync-controller | resource persistence, ownership |
156
- | SyncController | `external/sync-controller.js` | External sync orchestration | sync events, state transitions, watermarks | conflict-controller | webhook ingestion, write execution |
157
- | ConflictController | `external/conflict-controller.js` | Conflict detection/resolution | conflict records, resolution strategies, diff computation | — | sync execution, write-back |
158
- | WriteController | `external/write-controller.js` | Write intent management | intent creation, approval, execution queue | — | sync, conflict detection |
159
- | AuditController | `audit-controller.js` | Audit event recording | event capture, query, time-range filtering | — | business logic, auth |
160
- | RunnerController | `runner-controller.js` | Runner pool management | pool sizing, pod spec, capacity tracking | | job execution |
161
- | NotificationController | `notification-controller.js` | Notification delivery | notification creation, delivery, read status | — | business decisions |
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
- ## 4. Event System
376
+ ## 6. CLI Commands
166
377
 
167
- Source: `packages/krate/core/src/event-bus.js`, `notification-controller.js`, `audit-controller.js`
378
+ Source: `packages/krate/cli/src/index.js`
168
379
 
169
- ### 4.1 Event Bus
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(listener); // Register listener
174
- bus.emit(event); // Broadcast to all
175
- bus.emitResourceChange(kind, name, operation); // Convenience
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
- Global singleton: `globalEventBus`
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
- ### 4.2 SSE Streaming
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
- Route: `GET /api/orgs/:org/agents/events/stream`
425
+ ---
426
+
427
+ ## 8. Trigger Rule System
428
+
429
+ ### 8.1 Source Types
183
430
 
184
- - Content-Type: `text/event-stream`
185
- - Initial connection message: `{"type":"connected"}`
186
- - Heartbeat every 30 seconds: `{"type":"heartbeat"}`
187
- - Resource change events forwarded from globalEventBus
188
- - Connection cleanup on client disconnect
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
- ### 4.3 Notification Controller
439
+ ### 8.2 Rule Matching Algorithm
191
440
 
192
- Manages notification lifecycle:
193
- - Create notifications with type, title, body, target
194
- - Mark as read/unread
195
- - List with filtering by read status
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
- ### 4.4 Audit Controller
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
- Records audit events with:
201
- - Action (create, update, delete, login, dispatch)
202
- - Actor (user, system, agent)
203
- - Resource reference
204
- - Timestamp
205
- - Query by org, action, time range, with pagination
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
- ## 5. Workspace Lifecycle
468
+ ## 9. Approval System
210
469
 
211
- Source: `packages/krate/core/src/agent-workspace-controller.js`
470
+ ### 9.1 Valid Actions
212
471
 
213
- ### 5.1 Provisioning Flow
472
+ ```javascript
473
+ const VALID_ACTIONS = new Set(['tool-use', 'secret-access', 'write-back', 'release', 'escalation']);
474
+ ```
214
475
 
215
- 1. **Create workspace** — Generate `KrateWorkspace` resource with PVC spec
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
- ### 5.2 Workspace Reuse
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
- Workspaces can be reused across dispatch runs:
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
- ### 5.3 Codespace Management
498
+ Source: `agent-stack-controller.js` `reconcileStack()`
229
499
 
230
- - Live workspace runtime state (`KrateWorkspaceRuntime`)
231
- - Process status, environment variables, preview URLs
232
- - Session shell access via web console
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
- ## 6. Runner System
516
+ ## 11. External Conflict Resolution
237
517
 
238
- Source: `packages/krate/core/src/runner-controller.js`, `runners-ci.js`
518
+ ### 11.1 Valid Strategies
239
519
 
240
- ### 6.1 Pool Management
520
+ ```javascript
521
+ const VALID_STRATEGIES = ['prefer-external', 'prefer-krate', 'manual', 'ignore'];
522
+ ```
241
523
 
242
- `RunnerPool` defines:
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
- ### 6.2 Pod Spec Generation
526
+ ```
527
+ (detected) → Open → Resolved (with strategy + resolvedValue)
528
+ → Superseded (newer conflict replaces)
529
+ ```
249
530
 
250
- Runner pods include:
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
- ### 6.3 Job Scheduling
533
+ ```javascript
534
+ const VALID_PHASES = ['PendingApproval', 'ReadyToSend', 'Sending', 'Retrying', 'Succeeded', 'Failed', 'Rejected'];
535
+ ```
257
536
 
258
- `Pipeline` → `Job` hierarchy:
259
- - Pipeline tracks overall state, steps, and resume point
260
- - Job represents a single executable step
261
- - Trust tier determines isolation level
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
- ## 7. External Sync Pipeline
547
+ ## 12. Runner System
548
+
549
+ ### 12.1 Pool Validation Rules
266
550
 
267
- Source: `packages/krate/core/src/external/`
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
- ### 7.1 Full Pipeline Flow
556
+ ### 12.2 Runner Statuses
270
557
 
558
+ ```javascript
559
+ const RUNNER_STATUSES = new Set(['Idle', 'Running', 'Terminating']);
271
560
  ```
272
- Webhook Ingest → HMAC Verify → Dedup → Normalize → Sync Event → State Update → Conflict Check → Write Intent
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
- ### 7.2 Step Details
595
+ ### 13.2 Query Parameters
276
596
 
277
- | Step | Controller | Action |
278
- |------|-----------|--------|
279
- | 1. Ingest | WebhookController | Receive POST, extract signature header |
280
- | 2. HMAC Verify | WebhookController | `sha256=` prefix comparison, timing-safe |
281
- | 3. Dedup | WebhookController | Check deliveryId against store |
282
- | 4. Normalize | WebhookController | Create `ExternalWebhookDelivery` record |
283
- | 5. Sync Event | SyncController | Create `ExternalSyncEvent`, update watermark |
284
- | 6. State Update | SyncController | Update `ExternalSyncState` phase |
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
- ### 7.3 Conflict Resolution Strategies
606
+ ---
289
607
 
290
- - `local-wins` Keep local version
291
- - `remote-wins` — Accept external version
292
- - `manual` — Create conflict record for human resolution
293
- - `merge` — Attempt field-level merge
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
- ## 8. MCP Protocol
630
+ ## 5. Complete KRATE_RESOURCES Array
298
631
 
299
- Source: `packages/krate/cli/src/mcp-server.js`
632
+ > Source: `packages/krate/core/src/kubernetes-controller.js` — lines 31–111
300
633
 
301
- ### 8.1 Tools (14)
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
- | Prompt | Description |
323
- |--------|-------------|
324
- | `krate_workspace_setup` | Guide for setting up a new krate workspace |
325
- | `krate_stack_config` | Help configuring an agent stack |
326
- | `krate_troubleshoot` | Diagnose common krate issues |
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
- ### 8.3 Resources (2)
733
+ Additionally, `KYVERNO_RESOURCES` (10 entries, discovered separately):
329
734
 
330
- | URI | Name | MIME Type |
331
- |-----|------|-----------|
332
- | `krate://snapshot` | Workspace Snapshot | application/json |
333
- | `krate://stacks` | Agent Stacks | application/json |
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
- ## 9. CLI Commands
750
+ ## 6. Agent Dispatch State Machine
338
751
 
339
- Source: `packages/krate/cli/src/index.js`, `packages/krate/core/CLAUDE.md`
752
+ > Source: `packages/krate/core/src/agent-dispatch-controller.js`, observed from controller-ui.js active filtering
340
753
 
341
- | Command | Description | Key Options |
342
- |---------|-------------|-------------|
343
- | `krate serve` | Start HTTP API server | `--port 3080` |
344
- | `krate mcp` | Start MCP server over stdio | — |
345
- | `krate status` | Show workspace status | `--org`, `--json` |
346
- | `krate stacks` | List agent stacks | `--org`, `--json` |
347
- | `krate dispatch` | Dispatch an agent run | `--stack`, `--repo`, `--ref` |
348
- | `krate apply` | Apply resource from file | `--file`, `--org` |
349
- | `krate get` | Get resource by kind/name | `kind`, `name`, `--org` |
350
- | `krate list` | List resources by kind | `kind`, `--org`, `--json` |
351
- | `krate delete` | Delete resource | `kind`, `name`, `--org` |
352
- | `krate version` | Show CLI version | — |
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')`