Self-Development Orchestration Patterns
September 5, 2026 · View on GitHub
This directory contains real-world orchestration patterns used by the Kelos project itself for autonomous development.
The nested agora/ directory applies the same orchestration
pattern to the sibling kelos-dev/agora
repository while keeping the configuration in this repo.
The nested kanon/ directory does the same for the sibling
kelos-dev/kanon repository.
The nested open-actions/ directory does the same
for the sibling
kelos-dev/open-actions
repository.
cs creates persistent interactive Codex environments for developing
Kelos with the same Workspace, credentials, model, effort, and Git identity as
the kelos-workers SessionSpawner.
How It Works
Every self-development Task, TaskSpawner, Session, and SessionSpawner in this
directory and its nested Agora, Kanon, and Open Actions directories references
base-agent.yaml, which copies
gjkim42/kanon-repo's instructions/AGENTS.md
and installs all skills from that repository through spec.skills.
Tasks and TaskSpawners add a second role-specific AgentConfig when they need
local identity, conventions, or workflow instructions. The issue and PR
pick-up SessionSpawners for Kelos, Agora, Kanon, and Open Actions, plus
Sessions created with cs, use only base-agent.
Apply the shared AgentConfig before deploying any self-development resource:
kubectl apply -f self-development/base-agent.yaml
All other AgentConfigs provide only role- or repository-specific instructions; they do not duplicate the shared skills.
Autonomous discovery agents that publish GitHub issues maintain at most one
open generated-by-kelos issue slot per TaskSpawner. Its title starts with the
TaskSpawner name in brackets, and its body includes both a
kelos-taskspawner=<name> marker and one replaceable Latest verdict section.
Each run checks whether an unassigned slot is still valid against the current
repository before retaining, replacing, or closing it. Assigned issues and PRs
are treated as ongoing human or agent work and are not updated by autonomous
discovery jobs.
Spawners
| Spawner | Trigger | Agent | Description |
|---|---|---|---|
| kelos-workers | Webhook: issue comment /kelos pick-up | Codex | Creates a durable Session with the open issue URL and a dedicated issue branch |
| kelos-planner | Webhook: issue comment /kelos plan | Codex | Investigates an issue and posts a structured implementation plan — advisory only, no code changes |
| kelos-reviewer | Webhook: PR comment /kelos review | Codex | Reviews PRs on demand — analyzes code, checks conventions, and updates a sticky review comment |
| kelos-claude-reviewer | Webhook: PR comment /kelos claude-review | Claude Fable | Runs an additional code review path with Claude Code and updates a Claude-specific sticky review comment |
| kelos-api-reviewer | Webhook: issue/PR comment /kelos api-review | Codex | Reviews Kubernetes API design on issues or PRs — naming, compatibility, CRD validation |
| kelos-claude-api-reviewer | Webhook: issue/PR comment /kelos claude-api-review | Claude Fable | Runs an additional Kubernetes API design review path with Claude Code and updates Claude-specific sticky PR comments |
| kelos-pr-responder | Webhook: PR comment/review /kelos pick-up | Codex | Creates a durable Session with the open PR URL on its existing branch |
| kelos-triage | Webhook: issue opened/labeled/reopened (needs-actor) | Codex | Classifies issues by kind/priority, detects duplicates, and recommends an actor |
| kelos-fake-user | Cron (daily 09:00 UTC) | Codex | Tests DX as a new user and maintains one unassigned issue slot for the highest-impact problem found |
| kelos-fake-strategist | Cron (every 12 hours) | Codex | Explores new use cases, integrations, and API ideas while maintaining one unassigned strategic issue slot |
| kelos-config-update | Cron (daily 18:00 UTC) | Codex | Reviews recent PR feedback and creates or updates unassigned configuration PRs accordingly |
| kelos-self-update | Cron (daily 06:00 UTC) | Codex | Reviews prompts, configs, and workflow files while maintaining one unassigned improvement issue slot |
| kelos-image-update | Cron (daily 03:00 UTC) | Codex | Checks for newer agent image versions and creates or updates unassigned PRs for them |
| kelos-squash-commits | Webhook: PR comment /kelos squash-commits | Codex | Rebases and squashes PR branch commits into a single clean commit |
kelos-workers.yaml
Creates a durable Session when the maintainer posts /kelos pick-up on an open
issue. The initial prompt supplies the issue URL and asks the agent to find the
best way to address it. Follow-ups continue through the Session's web or
terminal clients after the initial turn.
| Trigger | GitHub issue_comment webhook with an exact /kelos pick-up command from gjkim42 on an open issue |
| Agent | Codex |
| Storage | 10 GiB persistent volume per created Session |
Key features:
- Lets the agent choose how to address the linked issue
- Uses
kelos-task-<number>for the issue branch - Requires
/kelos pick-upfrom the maintainer before starting work - Excludes comments from
kelos-bot[bot]to prevent self-trigger loops - Keeps the Session available for later web or terminal follow-ups
Deploy:
kubectl apply -f self-development/base-agent.yaml
kubectl apply -f self-development/kelos-workers.yaml
kelos-planner.yaml
Reacts to /kelos plan comments on open issues. Investigates the issue, inspects the codebase, and posts a structured implementation plan — advisory only, no code changes.
| Trigger | GitHub issue_comment webhook with /kelos plan |
| Agent | Codex |
| Concurrency | 2 |
Key features:
- Reads the issue body, all comments, linked issues/PRs, and relevant source code
- Posts a single planning comment with: plan assessment, implementation steps, acceptance criteria, and open questions/risks
- If the issue already contains a solid plan, normalizes it into a canonical step list instead of inventing a new one
- A later
/kelos plancomment retriggers planning after more discussion or scope changes
Handoff flow:
/kelos plan— requests or refreshes an implementation plan/kelos pick-up— maintainer hands off to workers when ready
Deploy:
kubectl apply -f self-development/kelos-planner.yaml
kelos-reviewer.yaml
Reviews open pull requests on demand when a maintainer or kelos-bot[bot]
posts /kelos review.
| Trigger | GitHub PR comment webhook with /kelos review from a maintainer or kelos-bot[bot] |
| Agent | Codex |
| Concurrency | 3 |
Key features:
- Uses the
review-allskill to reconcile two independent reviews of the same diff - Reads the full diff and surrounding context to understand changes
- Checks correctness, tests, project conventions, security, and code quality
- Reviews test adequacy without rerunning local validation
- Creates or updates a single sticky PR comment with the structured review result
- Summarizes specific file/line findings in the sticky comment without inline review comments
- Read-only agent — does not push code or modify files
Handoff flow:
/kelos review— a maintainer orkelos-bot[bot]requests a code review/kelos review— a maintainer can retrigger review after changes are pushed
Deploy:
kubectl apply -f self-development/kelos-reviewer.yaml
kelos-claude-reviewer.yaml
Runs a Claude Fable review when a maintainer posts /kelos claude-review,
using the Claude Code runner. It uses a separate trigger from the Codex
reviewer.
| Trigger | GitHub PR comment webhook with /kelos claude-review from a maintainer or kelos-bot[bot] |
| Agent | Claude Fable via Claude Code |
| Concurrency | 3 |
Key features:
- Uses the same code review checklist and structured sticky comment output as
kelos-reviewer - Creates or updates a single Claude-specific sticky PR comment with the structured review result
- Provides an independent model-family review without replacing the Codex reviewer
- Read-only agent — does not push code or modify files
Deploy:
kubectl apply -f self-development/kelos-claude-reviewer.yaml
kelos-api-reviewer.yaml
Reviews issues and pull requests for Kubernetes API design conventions,
compatibility, and best practices when a maintainer or kelos-bot[bot] posts
/kelos api-review.
| Trigger | GitHub issue/PR comment webhook with /kelos api-review from a maintainer or kelos-bot[bot] |
| Agent | Codex |
| Concurrency | 3 |
Key features:
- Uses the
api-reviewskill for API design analysis and verdicts - Works on both issues (API design proposals) and pull requests (API implementation review)
- Focused on Kubernetes API design concerns (field naming, primitive types, compatibility, CRD validation, naming/docs, defaulting/conversion)
- References upstream Kubernetes API conventions and API review process documentation
- Checks for correct use of
resource.Quantity,metav1.Time,metav1.Duration - Verifies additive-only changes and forwards compatibility
- For PRs: creates or updates a single sticky PR comment with structured API review feedback
- For issues: posts a structured comment with API design guidance
- Read-only agent — does not push code or modify files
Handoff flow:
/kelos api-review— a maintainer orkelos-bot[bot]requests an API design review/kelos api-review— a maintainer can retrigger review after changes or further discussion
Deploy:
kubectl apply -f self-development/kelos-api-reviewer.yaml
kelos-claude-api-reviewer.yaml
Runs a Claude Fable API design review when a maintainer posts
/kelos claude-api-review, using the Claude Code runner. It uses a separate
trigger from the Codex API reviewer.
| Trigger | GitHub issue/PR comment webhook with /kelos claude-api-review from a maintainer or kelos-bot[bot] |
| Agent | Claude Fable via Claude Code |
| Concurrency | 3 |
Key features:
- Uses the
api-reviewskill for API design analysis and verdicts - Uses the same Kubernetes API design checklist and structured output as
kelos-api-reviewer - Works on both issues and pull requests
- Creates or updates a Claude-specific sticky PR comment for pull requests
- Posts a structured API design comment for issues
- Provides an independent model-family review without replacing the Codex API reviewer
- Read-only agent — does not push code or modify files
Deploy:
kubectl apply -f self-development/kelos-claude-api-reviewer.yaml
kelos-pr-responder.yaml
Creates a durable Session when the maintainer posts an exact /kelos pick-up
PR comment or review on an open pull request. The initial prompt supplies the
PR URL and asks the agent to find the best way to address it.
| Trigger | GitHub PR comment or review webhook with an exact /kelos pick-up command from gjkim42 on an open PR; review events also exclude drafts |
| Agent | Codex |
| Storage | 10 GiB persistent volume per created Session |
Key features:
- Starts the Session on the existing PR branch
- Lets the agent choose how to address the linked PR
- Keeps the Session available for later web or terminal follow-ups
- Requires
/kelos pick-upPR comment or review body to be picked up
Deploy:
kubectl apply -f self-development/base-agent.yaml
kubectl apply -f self-development/kelos-pr-responder.yaml
kelos-triage.yaml
Picks up open GitHub issues labeled needs-actor and performs automated triage.
| Trigger | GitHub issue opened/labeled/reopened webhooks with needs-actor |
| Agent | Codex |
| Concurrency | 8 |
For each issue, the agent:
- Classifies with exactly one
kind/*label (kind/bug,kind/feature,kind/api,kind/docs).kind/apicovers any change that introduces or modifies a user-facing API surface — CRD fields, CLI commands or flags, webhooks, etc. - Checks if the issue has already been fixed by a merged PR or recent commit
- Checks if the issue references outdated APIs, flags, or features
- Detects duplicate issues
- Assesses priority (
priority/important-soon,priority/important-longterm,priority/backlog) - Recommends an actor — assigns
actor/kelosif the issue has clear scope and verifiable criteria, otherwise assignsactor/human.kind/apiissues always getactor/humanand are not markedtriage-accepted, because new user-facing APIs must be reviewed and discussed with a maintainer before any PR is opened.
Posts a single triage comment with its findings and adds the kelos/needs-input label to prevent re-triage.
Deploy:
kubectl apply -f self-development/kelos-triage.yaml
kelos-fake-user.yaml
Runs daily to test the developer experience as if you were a new user.
| Trigger | Cron 0 9 * * * (daily at 09:00 UTC) |
| Agent | Codex |
| Concurrency | 1 |
Each run picks one focus area:
- Documentation & Onboarding — follow getting-started instructions, test CLI help text
- Developer Experience — review error messages, test common workflows
- Examples & Use Cases — verify manifests, identify missing examples
Creates or updates the single unassigned kelos-fake-user issue slot for the
highest-impact problem found. If that issue is assigned, the run treats it as
ongoing and exits without editing it or creating another issue.
Deploy:
kubectl apply -f self-development/kelos-fake-user.yaml
kelos-fake-strategist.yaml
Runs every 12 hours to strategically explore new ways to use and improve Kelos.
| Trigger | Cron 0 */12 * * * (every 12 hours) |
| Agent | Codex |
| Concurrency | 1 |
Each run picks one focus area:
- New Use Cases — explore what types of projects/teams could benefit from Kelos
- Integration Opportunities — identify tools/platforms Kelos could integrate with
- New CRDs & API Extensions — propose new CRDs or extensions to existing ones
Creates or updates the single unassigned kelos-fake-strategist issue slot for
the highest-impact actionable insight. If that issue is assigned, the run treats
it as ongoing and exits without editing it or creating another issue.
Deploy:
kubectl apply -f self-development/kelos-fake-strategist.yaml
kelos-config-update.yaml
Runs daily to update agent configuration based on patterns found in PR reviews.
| Trigger | Cron 0 18 * * * (daily at 18:00 UTC) |
| Agent | Codex |
| Concurrency | 1 |
Reviews recent PRs and their review comments to identify recurring feedback patterns, then updates agent configuration accordingly:
- Project-level changes — updates
AGENTS.mdor the applicable role-specific AgentConfig - Task-specific changes — updates TaskSpawner prompts in
self-development/*.yamlor creates/updates AgentConfig for specific agents
Creates PRs with changes for maintainer review. Skips uncertain or contradictory feedback, and skips an existing configuration PR when it has assignees.
Deploy:
kubectl apply -f self-development/kelos-config-update.yaml
kelos-self-update.yaml
Runs daily to review and update the self-development workflow files themselves.
| Trigger | Cron 0 6 * * * (daily at 06:00 UTC) |
| Agent | Codex |
| Concurrency | 1 |
Each run picks one focus area:
- Prompt Tuning — review and improve prompts based on actual agent output quality
- Configuration Alignment — ensure resource settings, labels, and AgentConfig stay consistent
- Workflow Completeness — check that agent prompts reflect current project conventions and Makefile targets
- Task Template Maintenance — keep one-off task definitions in sync with their TaskSpawner counterparts
Creates or updates the single unassigned kelos-self-update issue slot for the
highest-impact actionable improvement. If that issue is assigned, the run treats
it as ongoing and exits without editing it or creating another issue.
Deploy:
kubectl apply -f self-development/kelos-self-update.yaml
kelos-image-update.yaml
Runs daily to check for newer versions of coding agent images and creates PRs to update them.
| Trigger | Cron 0 3 * * * (daily at 03:00 UTC) |
| Agent | Codex |
| Concurrency | 1 |
Checks the following coding agents for updates:
- claude-code —
@anthropic-ai/claude-codenpm package - codex —
@openai/codexnpm package - gemini —
@google/gemini-clinpm package - opencode —
opencode-ainpm package - cursor — binary download, version discovered from
https://cursor.com/install
Creates at most one PR per agent. Skips agents that are already up to date or already have an assigned open update PR.
Deploy:
kubectl apply -f self-development/kelos-image-update.yaml
kelos-squash-commits.yaml
Rebases and squashes PR branch commits into a single clean commit when a maintainer posts /kelos squash-commits.
| Trigger | GitHub PR comment webhook with /kelos squash-commits |
| Agent | Codex |
| Concurrency | 1 |
Key features:
- Rebases the PR branch on
origin/mainand squashes all commits after the merge base into one - Amends the squashed commit message based on the linked issue and PR description when needed
- Force-pushes with
--force-with-lease - Updates the PR description to match the squashed change, preserving the
Closes #Nreference - Adds
kelos/needs-inputto the linked issue to signal the PR is ready for re-review - Does not start new development work or modify source code
Deploy:
kubectl apply -f self-development/kelos-squash-commits.yaml
Interactive Development Session
cs NAME creates a persistent Codex Session with the same Workspace,
credentials, model, effort, Git identity, and base-agent AgentConfig as
kelos-workers. It does not use the worker's resource requests and limits,
allowing namespace resource defaults to apply.
The Session requires the base-agent AgentConfig, kelos-session-agent
Workspace, personal-github-token Secret, and kelos-credentials Secret
described below. Its 10Gi workspace persists across Pod replacement and is
deleted with the Session.
Add this directory to your PATH and run the script from any directory:
export PATH="$PWD/self-development:$PATH"
cs my-session
cs embeds the Session manifest and uses the current kubectl context and
namespace. It fails if that name already exists and prints the kelos session connect command after creation.
Prerequisites
Before deploying these examples, you need to create the following resources:
1. Workspace Resources
workspaces.yaml defines the kelos-agent, agora-agent,
kanon-agent, and open-actions-agent Workspaces used by Tasks and
TaskSpawners. They reference the kelos-agent-credentials Secret described
below so GitHub operations use the Kelos bot identity.
Sessions use dedicated Workspaces so they can authenticate with a personal
token without changing Task credentials. The checked-in manifest includes
Session Workspaces for Kelos, Agora, Kanon, and kelos-dev/open-actions.
Apply both manifests after creating their Secrets below:
kubectl apply -f self-development/workspaces.yaml
kubectl apply -f self-development/session-workspaces.yaml
The Kelos Session Workspace is equivalent to:
apiVersion: kelos.dev/v1alpha2
kind: Workspace
metadata:
name: kelos-session-agent
spec:
repo: https://github.com/kelos-dev/kelos.git
ref: main
secretRef:
name: personal-github-token
2. Project GitHub App Secret
Create the GitHub App Secret referenced by workspaces.yaml:
kubectl create secret generic kelos-agent-credentials \
--from-literal=appID=<your-github-app-id> \
--from-literal=installationID=<your-github-app-installation-id> \
--from-file=privateKey=<path-to-private-key.pem>
The GitHub App installation must have access to the repositories used by the project Workspaces.
3. Session GitHub Token Secret
Create the personal token Secret referenced only by the Session Workspaces:
kubectl create secret generic personal-github-token \
--from-literal=GITHUB_TOKEN="$(gh auth token)" \
--dry-run=client -o yaml | kubectl apply -f -
The token needs these permissions:
repo(full control of private repositories)workflow(if your repo uses GitHub Actions)
4. WebhookGateway, Secret, and Delivery
The issue and pull request TaskSpawners in this directory are webhook-driven and
routed through a WebhookGateway (webhookgateway.yaml) that each spawner
references via githubWebhook.gatewayRef. The gateway authenticates inbound
deliveries against its own secret and resolves outbound GitHub API credentials
per gateway.
Create the github-webhook-secret Secret (in the same namespace as the
TaskSpawners) and apply the gateway. The gateway reads two things from it: the
inbound HMAC secret under a webhook-secret key, and outbound GitHub API
credentials for PR-file enrichment and status reporting — a GITHUB_TOKEN PAT
or GitHub App keys; the credential needs repo and checks:write.
kubectl create secret generic github-webhook-secret \
--from-literal=webhook-secret=<your-github-webhook-secret> \
--from-literal=GITHUB_TOKEN=<token-with-repo-and-checks:write>
# Or use GitHub App credentials instead of GITHUB_TOKEN:
# --from-literal=appID=... --from-literal=installationID=... \
# --from-file=privateKey=app.private-key.pem
kubectl apply -f webhookgateway.yaml
Then:
- Enable the gateway webhook server in your Kelos deployment —
webhookServer.gatewayServer.enabled: trueplus Gateway-API or Ingress routing (seeexamples/webhook-gateway-values.yaml). - Find the gateway's inbound path:
kubectl get webhookgateway kelos -o jsonpath='{.status.path}'(it is/webhook/<namespace>/kelos). - Expose
https://<your-domain>/webhook/<namespace>/kelosover HTTPS and configure the repository webhook to POST there using the same secret. - Subscribe the repository webhook to
issues,issue_comment, andpull_request_review.
Spawners with a
gatewayRefare served only by the gateway server. The gateway server and referencedWebhookGatewaymust both be available for their webhook deliveries to be processed.
Webhook spawners only react to new events after deployment. If an issue or PR was already in a matching state before the webhook server went live, retrigger it with a fresh comment or relabel after deployment.
5. Agent Credentials Secret
Create a secret with your agent credentials. Most checked-in spawners use Codex OAuth, and the Claude reviewer spawners use Claude Code with OAuth from the same Secret:
kubectl create secret generic kelos-credentials \
--from-file=CODEX_AUTH_JSON=$HOME/.codex/auth.json \
--from-literal=CLAUDE_CODE_OAUTH_TOKEN=<your-claude-code-oauth-token>
kubectl label secret kelos-credentials kelos.dev/codex-oauth-refresh=true
Labeling the OAuth Secret opts it into controller-managed Codex OAuth refresh.
Kelos creates one CronJob per labeled Secret with a non-empty CODEX_AUTH_JSON
key, skips unlabeled Secrets and API-key credentials, and preserves other keys
such as CLAUDE_CODE_OAUTH_TOKEN.
For API-key auth, change the task template credential type to api-key and
create the secret without the OAuth refresh label:
kubectl create secret generic kelos-credentials \
--from-literal=CODEX_API_KEY=<your-openai-api-key>
Customizing for Your Repository
To adapt these examples for your own repository:
-
Update the Workspace reference:
- Change
spec.taskTemplate.worker.workspaceRef.nameto match your Workspace resource - Or update the Workspace to point to your repository
- Change
-
Update the webhook repository and filters:
spec: when: githubWebhook: repository: your-org/your-repo excludeAuthors: - your-bot[bot] # avoid self-trigger loops events: [issue_comment] filters: - event: issue_comment action: created bodyPattern: '(?m)^/kelos pick-up[ \t]*\r?$' commentOn: Issue # or PullRequest, depending on spawner author: your-maintainer # maintainer-approval gate labels: [your-label] state: openWebhook filter fields the shipped self-development spawners rely on. The same
githubWebhookfields are available underTaskSpawner.spec.whenandSessionSpawner.spec.when:Field Where it lives Purpose excludeAuthorsTaskSpawner.spec.when.githubWebhook(top-level)Drop events sent by listed usernames before filter evaluation; use this to exclude your own bot account and prevent self-trigger loops. bodyPatternTaskSpawner.spec.when.githubWebhook.filters[]Go re2 regex match against the comment/review body — the modern replacement for substring-only matching. excludeBodyPatternsTaskSpawner.spec.when.githubWebhook.filters[]Companion to bodyPattern: a list of regexes that, if any match, drop the event. Use to carve out bot-echo replies that would otherwise matchbodyPattern.commentOnTaskSpawner.spec.when.githubWebhook.filters[]Scopes issue_commentevents toIssueorPullRequest. GitHub firesissue_commentfor both, so set this to keep issue-only spawners off PRs (and vice versa).authorTaskSpawner.spec.when.githubWebhook.filters[]Restrict matches to a single sender's username. Omit it to accept every sender not listed in top-level excludeAuthors;kelos-workerssets it to the maintainer as an approval gate.draftTaskSpawner.spec.when.githubWebhook.filters[]Match by PR draft status. Set falseto skip drafts; omit to match both.See docs/reference.md for the full
TaskSpawner.spec.when.githubWebhookfield reference. -
Customize the prompt:
- Edit
spec.taskTemplate.promptTemplatefor a TaskSpawner orspec.sessionTemplate.initialPromptfor a SessionSpawner - Available template variables (Go
text/templatesyntax):
Variable Description GitHub Webhook Cron {{.ID}}Unique identifier for the work item Issue/PR number as string (e.g., "42")Date-time string (e.g., "20260207-0900"){{.Number}}Issue or PR number Issue/PR number (e.g., 42)0{{.Title}}Title of the work item Issue/PR title Trigger time (RFC3339) {{.Body}}Body text of the work item Issue/PR body Empty {{.URL}}URL to the source item GitHub HTML URL Empty {{.Event}}GitHub webhook event type issue_comment,issues,pull_request_review, etc.Empty {{.Action}}GitHub webhook action created,labeled,submitted, etc.Empty {{.Sender}}GitHub username that triggered the webhook GitHub login Empty {{.Branch}}Branch name when present in the webhook payload PR head branch or pushed branch; empty for issue events Empty {{.CommentBody}}Triggering comment or review body Available for comment and review events Empty {{.CommentURL}}Triggering comment or review URL Available for comment and review events Empty {{.Kind}}Type of work item "webhook""Issue"{{.Time}}Trigger time (RFC3339) Empty Cron tick time (e.g., "2026-02-07T09:00:00Z"){{.Schedule}}Cron schedule expression Empty Schedule string (e.g., "0 * * * *")The webhook-based self-development agents re-read the latest issue or PR state with
ghbefore acting, so they do not depend on aggregated{{.Comments}},{{.ReviewComments}}, or{{.ReviewState}}variables. - Edit
-
Remember the trigger is event-driven:
- Webhook spawners do not poll or backfill old work items
- Retrigger an existing issue or PR with a fresh comment or relabel after deployment
- Duplicate a filter if you need to allow multiple specific GitHub usernames
-
Adjust the Codex model and effort:
spec: taskTemplate: worker: model: gpt-6-astra effort: xhighThe checked-in spawners use
gpt-6-astrafor high-capability tasks andgpt-5.4-minifor lower-cost routine tasks. They seteffortby role:xhighfor complex planning, coding, strategy, review, PR update, and configuration update workflows;highfor triage; andmediumfor routine image, fake-user, and squash workflows.
Feedback Loop Pattern
The key pattern in these examples is webhook-triggered handoff with durable, agent-directed Sessions:
- GitHub delivers an
issue_comment,issues, orpull_request_reviewwebhook - The matching TaskSpawner creates a Task, while the issue and PR pick-up spawners for Kelos, Agora, Kanon, and Open Actions create Sessions
- A pick-up Session receives the issue or PR URL and asks the agent to choose the best way to address it
- Issue Sessions start on a dedicated issue branch, while PR Sessions start on the existing PR branch
- An exact
/kelos pick-upcommand creates a Session for an open issue or PR; explicit commands or relabel events retrigger the other matching automation
Each matching webhook delivery creates a discrete Task or Session. A created Session remains available for interactive follow-ups through Session clients. Bot status and review replies should not include trigger commands accidentally. Explicit bot comments can trigger reviewer spawners when those spawners include a matching bot-author filter.
Troubleshooting
TaskSpawner not creating tasks:
- Check the TaskSpawner status:
kubectl get taskspawner <name> -o yaml - Verify the Workspace exists:
kubectl get workspace - Ensure credentials are correctly configured:
kubectl get secret kelos-credentials - Ensure the gateway webhook server is enabled (
webhookServer.gatewayServer.enabled), theWebhookGatewayisAuthenticated(kubectl get webhookgateway kelos), and thegithub-webhook-secretexists with awebhook-secretkey - Check webhook server logs:
kubectl logs -l app.kubernetes.io/component=webhook-gateway-server - Review the repository webhook's recent deliveries in GitHub
- If the issue or PR matched before you deployed the webhook server, retrigger it with a new comment or relabel
SessionSpawner not creating a Session:
- Check the SessionSpawner status:
kubectl get sessionspawner <name> -o yaml - Check created Sessions:
SPAWNER_UID=$(kubectl get sessionspawner <name> -o jsonpath='{.metadata.uid}'); kubectl get sessions -l kelos.dev/sessionspawner="$SPAWNER_UID" - Check the same Workspace, credentials, webhook server, and recent-delivery details listed above
Tasks failing immediately:
- Verify the agent credentials are valid
- Check if the Workspace repository is accessible
- Review task logs:
kubectl logs -l job-name=<job-name>
Agent not creating PRs:
- For Sessions, ensure
personal-github-tokenexists and the corresponding*-session-agentWorkspace references it - For Tasks, check the credentials referenced by the regular project Workspace
- Verify the token has
repopermissions - Check if the SessionSpawner configures the Git identity in
worker.podOverrides.env
Next Steps
- Read the main README for more details on Tasks and Workspaces
- Review the agent image interface to create custom agents
- Check existing TaskSpawners:
kubectl get taskspawners - Monitor task execution:
kelos get tasksorkubectl get tasks