🤖 Kelos Strategist Agent @gjkim42
Summary
The current API allows a Task or TaskTemplate to reference exactly one AgentConfig via agentConfigRef. In practice, multi-spawner deployments duplicate large blocks of shared instructions (environment, standards, project conventions) across every AgentConfig, with only role-specific sections differing. This proposal adds an agentConfigRefs (plural) field that references an ordered list of AgentConfig resources, merged at task creation time.
Problem
Duplicated instructions across AgentConfigs
The self-development workflow demonstrates this clearly. Every AgentConfig repeats the same boilerplate:
| AgentConfig |
Environment |
Standards |
Project Conventions |
Role-specific |
kelos-dev-agent |
✅ duplicated |
✅ duplicated |
✅ duplicated |
1 line |
kelos-workers-agent |
✅ duplicated |
✅ duplicated |
✅ duplicated |
~5 lines |
kelos-self-update-agent |
✅ duplicated |
✅ duplicated |
✅ duplicated |
0 lines |
kelos-planner-agent |
✅ duplicated |
✅ duplicated |
✅ duplicated |
1 line |
The ## Environment, ## Standards, and ## Project Conventions sections are nearly identical across all four configs (see self-development/agentconfig.yaml, kelos-workers.yaml, kelos-self-update.yaml, kelos-planner.yaml). Only the ## Identity agent name and role-specific additions differ.
Maintenance burden
When shared instructions change (e.g., a new Makefile target, a new logging convention, or a project convention update), every AgentConfig must be updated independently. The kelos-config-update spawner attempts to keep these in sync, but drift is inevitable — issue #601 documents exactly this problem ("AgentConfig co-location incomplete... agentsMD still drifted").
No composition model
Kubernetes itself solves this pattern with layered abstractions (PodDefaults, LimitRanges, admission webhooks that inject common config). Kelos's AgentConfig has no equivalent. You cannot say "use the base project config plus worker-specific additions."
Proposed API Change
New field: agentConfigRefs
Add an ordered list field alongside the existing singular agentConfigRef:
// TaskSpec (and TaskTemplate) changes:
// AgentConfigRef references a single AgentConfig resource.
// Deprecated: Use AgentConfigRefs for composable configuration.
// +optional
AgentConfigRef *AgentConfigReference `json:"agentConfigRef,omitempty"`
// AgentConfigRefs references an ordered list of AgentConfig resources.
// Configs are merged in order: agentsMD is concatenated (separated by
// newlines), plugins/skills/mcpServers lists are appended. Later entries
// can extend but not remove content from earlier entries.
// Mutually exclusive with AgentConfigRef.
// +optional
AgentConfigRefs []AgentConfigReference `json:"agentConfigRefs,omitempty"`
Merge semantics
When multiple AgentConfigs are referenced, they are merged in order (index 0 is the base):
| Field |
Merge strategy |
agentsMD |
Concatenate with \n\n separator |
plugins |
Append (later plugins added after earlier ones) |
skills |
Append |
mcpServers |
Append; if two entries share the same name, the later one wins |
This follows the principle of additive composition — each layer can only add to or override (by name) the configuration, never subtract from it.
Validation
agentConfigRef and agentConfigRefs are mutually exclusive (CEL validation rule)
agentConfigRefs must have at least 1 entry when set
- All referenced AgentConfigs must exist in the same namespace
Example: Self-development refactored
Before (current — duplicated instructions):
# 4 separate AgentConfigs, each ~30 lines, with ~25 lines identical
apiVersion: kelos.dev/v1alpha1
kind: AgentConfig
metadata:
name: kelos-workers-agent
spec:
agentsMD: |
# Kelos Worker Agent
## Environment
You are running in an ephemeral container environment... # DUPLICATED
## Identity
- When commenting... "🤖 **Kelos Worker Agent** @gjkim42\n\n"
## Standards
- Do not create duplicate issues... # DUPLICATED
- Keep changes minimal and focused # DUPLICATED
## Project Conventions
- Use Makefile targets... # DUPLICATED
- Always try to add or improve tests... # DUPLICATED
- Logging conventions... # DUPLICATED
- Commit messages... # DUPLICATED
After (with composition):
# Shared base config — defined once
apiVersion: kelos.dev/v1alpha1
kind: AgentConfig
metadata:
name: kelos-base
spec:
agentsMD: |
## Environment
You are running in an ephemeral container environment. Your file system
changes disappear after the task completes. Persist work by creating PRs,
issues, or comments.
## Standards
- Do not create duplicate issues — check existing issues first with `gh issue list`
- Keep changes minimal and focused
## Project Conventions
- Use Makefile targets instead of discovering build/test commands yourself:
- `make verify` — run all verification checks (lint, fmt, vet, etc.)
- `make update` — update all generated files
- `make test` — run all unit tests
- `make test-integration` — run integration tests
- `make build` — build binary
- Always try to add or improve tests when modifying code
- Logging conventions: start log messages with capital letters and do not end with punctuation
- Commit messages: do not include PR links in commit messages
---
# Worker-specific config — only the delta
apiVersion: kelos.dev/v1alpha1
kind: AgentConfig
metadata:
name: kelos-worker-role
spec:
agentsMD: |
## Identity
- When commenting on issues or PRs, always start with "🤖 **Kelos Worker Agent** @gjkim42\n\n"
---
# TaskSpawner references both
apiVersion: kelos.dev/v1alpha1
kind: TaskSpawner
metadata:
name: kelos-workers
spec:
taskTemplate:
agentConfigRefs:
- name: kelos-base # shared project config
- name: kelos-worker-role # role-specific additions
# ... rest of template
The resulting merged agentsMD injected into the agent would be:
## Environment
You are running in an ephemeral container environment...
## Standards
- Do not create duplicate issues...
...
## Identity
- When commenting... "🤖 **Kelos Worker Agent** @gjkim42\n\n"
Implementation approach
Controller changes (internal/controller/task_controller.go)
The current code at line 247 fetches a single AgentConfig:
if task.Spec.AgentConfigRef != nil {
var ac kelosv1alpha1.AgentConfig
// ... fetch and use
}
This would become:
refs := task.Spec.AgentConfigRefs
if task.Spec.AgentConfigRef != nil {
// Backward compat: treat singular as single-element list
refs = []AgentConfigReference{*task.Spec.AgentConfigRef}
}
if len(refs) > 0 {
merged := mergeAgentConfigs(configs...)
agentConfig = &merged
}
Spawner changes (cmd/kelos-spawner/main.go)
Line 342 forwards the singular ref — extend to forward the list.
CLI changes (internal/cli/run.go)
Support --agent-config accepting comma-separated names or repeated flags.
Scope
- New files: None (merging logic is ~50 lines in task_controller.go)
- Modified files:
api/v1alpha1/task_types.go, api/v1alpha1/taskspawner_types.go, internal/controller/task_controller.go, cmd/kelos-spawner/main.go, internal/cli/run.go, internal/cli/printer.go
- Generated files:
zz_generated.deepcopy.go, CRD manifests (via make update)
Backward compatibility
agentConfigRef (singular) continues to work unchanged
agentConfigRefs is purely additive
- CEL validation prevents using both simultaneously, with a clear error message
- Existing TaskSpawners and Tasks require zero changes
Related issues
| Issue |
Relationship |
| #601 |
AgentConfig drift problem — composition eliminates the root cause by centralizing shared config |
| #537 |
Conditional per-item overrides — complementary (overrides modify the template, composition builds the base config) |
| #335 |
Extract shared instructions from prompts — closed, but the underlying need for shared config persists |
/kind feature
🤖 Kelos Strategist Agent @gjkim42
Summary
The current API allows a Task or TaskTemplate to reference exactly one AgentConfig via
agentConfigRef. In practice, multi-spawner deployments duplicate large blocks of shared instructions (environment, standards, project conventions) across every AgentConfig, with only role-specific sections differing. This proposal adds anagentConfigRefs(plural) field that references an ordered list of AgentConfig resources, merged at task creation time.Problem
Duplicated instructions across AgentConfigs
The self-development workflow demonstrates this clearly. Every AgentConfig repeats the same boilerplate:
kelos-dev-agentkelos-workers-agentkelos-self-update-agentkelos-planner-agentThe
## Environment,## Standards, and## Project Conventionssections are nearly identical across all four configs (seeself-development/agentconfig.yaml,kelos-workers.yaml,kelos-self-update.yaml,kelos-planner.yaml). Only the## Identityagent name and role-specific additions differ.Maintenance burden
When shared instructions change (e.g., a new Makefile target, a new logging convention, or a project convention update), every AgentConfig must be updated independently. The
kelos-config-updatespawner attempts to keep these in sync, but drift is inevitable — issue #601 documents exactly this problem ("AgentConfig co-location incomplete... agentsMD still drifted").No composition model
Kubernetes itself solves this pattern with layered abstractions (PodDefaults, LimitRanges, admission webhooks that inject common config). Kelos's AgentConfig has no equivalent. You cannot say "use the base project config plus worker-specific additions."
Proposed API Change
New field:
agentConfigRefsAdd an ordered list field alongside the existing singular
agentConfigRef:Merge semantics
When multiple AgentConfigs are referenced, they are merged in order (index 0 is the base):
agentsMD\n\nseparatorpluginsskillsmcpServersname, the later one winsThis follows the principle of additive composition — each layer can only add to or override (by name) the configuration, never subtract from it.
Validation
agentConfigRefandagentConfigRefsare mutually exclusive (CEL validation rule)agentConfigRefsmust have at least 1 entry when setExample: Self-development refactored
Before (current — duplicated instructions):
After (with composition):
The resulting merged
agentsMDinjected into the agent would be:Implementation approach
Controller changes (
internal/controller/task_controller.go)The current code at line 247 fetches a single AgentConfig:
This would become:
Spawner changes (
cmd/kelos-spawner/main.go)Line 342 forwards the singular ref — extend to forward the list.
CLI changes (
internal/cli/run.go)Support
--agent-configaccepting comma-separated names or repeated flags.Scope
api/v1alpha1/task_types.go,api/v1alpha1/taskspawner_types.go,internal/controller/task_controller.go,cmd/kelos-spawner/main.go,internal/cli/run.go,internal/cli/printer.gozz_generated.deepcopy.go, CRD manifests (viamake update)Backward compatibility
agentConfigRef(singular) continues to work unchangedagentConfigRefsis purely additiveRelated issues
/kind feature