Kanon-Development Orchestration Patterns
August 11, 2026 · View on GitHub
This directory contains the orchestration patterns that drive autonomous
development of kelos-dev/kanon — a Go
CLI that manages coding-agent settings (instructions, skills, MCP servers,
hooks, permissions) across multiple machines.
It mirrors self-development/, which does the same for
this repository (kelos-dev/kelos). The configs live here, in the kelos
repository, but the webhook filters and Workspaces target kelos-dev/kanon, so
the agents they spawn operate on the Kanon repository.
How It Works
Every spawner references the root base-agent for shared
instructions and skills. The issue and PR pick-up SessionSpawners reference
only base-agent. The remaining TaskSpawners add repository- or role-specific
instructions where needed: triage and squash-commits share agentconfig.yaml
(kanon-dev-agent), while planner, the two reviewers, fake-user, and fake-strategist
define their own AgentConfig inline.
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.
The two SessionSpawners operate on the Kanon repository through the
kanon-session-agent Workspace, which uses the personal Session token. Six
Seven TaskSpawners use the kanon-agent Workspace. The two meta-maintenance spawners
(kanon-config-update, kanon-self-update) are different: the files they
maintain (self-development/kanon/*) live in this repository, so they use the
kelos-agent Workspace and the kelos-dev-agent role AgentConfig from
self-development/, and they read Kanon's activity cross-repo with
gh ... --repo kelos-dev/kanon.
Spawners
| Spawner | Trigger | Agent | Description |
|---|---|---|---|
| kanon-workers | Webhook: issue comment /kelos pick-up | Codex | Creates a durable Session with the open issue URL and a dedicated issue branch |
| kanon-planner | Webhook: issue comment /kelos plan | Codex | Investigates an issue and posts a structured implementation plan — advisory only, no code changes |
| kanon-reviewer | Webhook: PR comment /kelos review | Codex | Reviews PRs on demand — analyzes code, checks conventions, and updates a sticky review comment |
| kanon-claude-reviewer | Webhook: PR comment /kelos claude-review | Claude Fable | Runs an independent review path through Claude Code and updates a Claude-specific sticky review comment |
| kanon-pr-responder | Webhook: PR review/comment with /kelos pick-up | Codex | Creates a durable Session with the open PR URL on its existing branch |
| kanon-triage | Webhook: issue opened/reopened (untriaged) | Codex | Classifies issues by kind/priority, detects duplicates, and recommends an actor |
| kanon-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 |
| kanon-fake-strategist | Cron (every 12 hours) | Codex | Explores new use cases, integrations, and managed-settings types while maintaining one unassigned strategic issue slot |
| kanon-config-update | Cron (daily 18:00 UTC) | Codex | Reviews recent Kanon PR feedback and creates or updates unassigned configuration PRs accordingly |
| kanon-self-update | Cron (daily 06:00 UTC) | Codex | Reviews and tunes the self-development/kanon/ prompts, configs, and README while maintaining one unassigned improvement issue slot |
| kanon-squash-commits | Webhook: PR comment /kelos squash-commits | Codex | Rebases and squashes PR branch commits into a single clean commit |
Not ported from
self-development/: the Kelos API reviewers (Kanon has no Kubernetes CRDs/API surface to review) andkelos-image-update(Kanon has no coding-agent Dockerfiles to bump).
Apply the shared Workspaces and root base-agent first, then the whole
directory. The directory includes agentconfig.yaml, which defines the
kanon-dev-agent role instructions referenced by the triage and
squash-commits spawners:
kubectl apply -f self-development/workspaces.yaml
kubectl apply -f self-development/session-workspaces.yaml
kubectl apply -f self-development/base-agent.yaml
kubectl apply -f self-development/kanon/
The per-spawner kubectl apply commands below are for deploying or updating an
individual spawner after base-agent is installed.
kanon-workers.yaml
Picks up open GitHub issues when a maintainer posts /kelos pick-up and
creates a durable Session. The initial prompt supplies the issue URL and asks
the agent to find the best way to address it.
| Trigger | GitHub issue_comment webhook with /kelos pick-up |
| Agent | Codex |
| Storage | 10 Gi PVC |
Key features:
- Lets the agent choose how to address the linked issue
- Uses
kanon-task-<number>for the issue branch - Requires a
/kelos pick-upcomment to pick up an issue (maintainer approval gate) - Keeps the workspace across Session follow-ups and pod restarts
- Supports routine follow-ups through the Session's web or terminal clients
Deploy:
kubectl apply -f self-development/kanon/kanon-workers.yaml
kanon-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. For issues that touch a CLI command/flag or the kanon.yaml schema, the plan must resolve naming, shape, and backward compatibility up front.
| Trigger | GitHub issue_comment webhook with /kelos plan |
| Agent | Codex |
| Concurrency | 2 |
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/kanon/kanon-planner.yaml
kanon-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
- Pays special attention to CLI/config-surface changes (naming, shape, backward compatibility)
- 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, modify files, or run local validation
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/kanon/kanon-reviewer.yaml
kanon-claude-reviewer.yaml
Runs a Claude Fable review when a maintainer or kelos-bot[bot] posts
/kelos claude-review.
| Trigger | GitHub PR comment or review 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 repository-specific checklist and sticky comment format as
kanon-reviewer - Pays special attention to CLI and configuration compatibility
- Creates or updates a Claude-specific sticky PR comment
- Read-only agent — does not push code, modify files, or run local validation
Deploy:
kubectl apply -f self-development/kanon/kanon-claude-reviewer.yaml
kanon-pr-responder.yaml
Picks up open GitHub pull requests when a reviewer requests changes with
/kelos pick-up. The initial prompt supplies the PR URL and asks the agent to
find the best way to address it.
| Trigger | GitHub PR comment with /kelos pick-up, or a PR review whose body contains /kelos pick-up |
| Agent | Codex |
| Storage | 10 Gi PVC |
Key features:
- Starts the Session on the existing PR branch
- Lets the agent choose how to address the linked PR
- Lets the maintainer stay on the PR page for the common review-feedback loop
- Requires a
/kelos pick-upPR comment or review body to be picked up - Keeps the workspace across Session follow-ups and pod restarts
- Supports routine follow-ups through the Session's web or terminal clients
Deploy:
kubectl apply -f self-development/kanon/kanon-pr-responder.yaml
kanon-triage.yaml
Triages newly opened (and certain reopened) GitHub issues.
| Trigger | GitHub issue opened (no triage-accepted), or reopened 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 to a user-facing surface — a CLI command or flag, or thekanon.yamlconfiguration schema. - Checks if the issue has already been fixed by a merged PR or recent commit
- Checks if the issue references outdated commands, flags, or config fields
- 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, otherwiseactor/human.kind/apiissues always getactor/humanand are not markedtriage-accepted, because new user-facing surface must be reviewed with a maintainer first.
Posts a single triage comment and adds triage-accepted to prevent re-triage.
Deploy:
kubectl apply -f self-development/kanon/kanon-triage.yaml
kanon-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 the quick-start, test CLI help text
- Developer Experience — build, exercise init/validate/diff/apply/import, review error messages
- Examples & Use Cases — verify example config, identify missing examples
Creates or updates the single unassigned kanon-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/kanon/kanon-fake-user.yaml
kanon-fake-strategist.yaml
Runs every 12 hours to strategically explore new ways to use and improve Kanon.
| Trigger | Cron 0 */12 * * * (every 12 hours) |
| Agent | Codex |
| Concurrency | 1 |
Each run picks one focus area:
- New Use Cases — explore teams/fleets/workflows that could benefit from managed agent settings
- Integration Opportunities — identify agents, tools, and toolchains Kanon could integrate with
- New Managed-Settings Types & CLI Extensions — propose new render targets, settings types, or
kanon.yamlschema extensions
Creates or updates the single unassigned kanon-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/kanon/kanon-fake-strategist.yaml
kanon-config-update.yaml
Runs daily to update the Kanon agent configuration based on patterns found in Kanon's PR reviews.
| Trigger | Cron 0 18 * * * (daily at 18:00 UTC) |
| Agent | Codex |
| Workspace | kelos-agent (edits self-development/kanon/ in this repo) |
| Concurrency | 1 |
Reviews recent kelos-dev/kanon PRs and their review comments to identify recurring feedback patterns, then updates the configuration under self-development/kanon/ (the shared Kanon role instructions in agentconfig.yaml or a specific TaskSpawner prompt). Opens a PR against this repository using /kind cleanup and release-note: NONE, since it only touches self-development/kanon/.
Skips uncertain or contradictory feedback, and skips an existing configuration
PR when it has assignees.
Deploy:
kubectl apply -f self-development/kanon/kanon-config-update.yaml
kanon-self-update.yaml
Runs daily to review and improve the self-development/kanon/ workflow files themselves.
| Trigger | Cron 0 6 * * * (daily at 06:00 UTC) |
| Agent | Codex |
| Workspace | kelos-agent (reasons about self-development/kanon/ in this repo) |
| Concurrency | 1 |
Each run picks one focus area: Prompt Tuning, Configuration Alignment, or Workflow Completeness.
Creates or updates the single unassigned kanon-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/kanon/kanon-self-update.yaml
kanon-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 - 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/kanon/kanon-squash-commits.yaml
Prerequisites
These spawners are applied to the same cluster that runs self-development/.
Before deploying them, set up the following.
1. Workspaces
Three Workspaces are referenced:
-
kanon-session-agent— points at the Kanon repository and is used only bykanon-workersandkanon-pr-responder. It is defined insession-workspaces.yamland references thepersonal-github-tokenSecret. -
kanon-agent— points at the Kanon repository and is used by the seven TaskSpawners that operate directly on Kanon. It is defined inworkspaces.yamland references thekelos-agent-credentialsSecret. -
kelos-agent— points at this repository (kelos-dev/kelos). Used bykanon-config-updateandkanon-self-update, which edit theself-development/kanon/files that live here. It is also defined inworkspaces.yamland references thekelos-agent-credentialsSecret.
2. Repository labels
The Kanon repository starts with only the default GitHub labels. Create the
labels these spawners rely on (run once, against kelos-dev/kanon):
REPO=kelos-dev/kanon
gh label create generated-by-kelos --repo "$REPO" --color 1d76db --force
for l in kind/bug kind/feature kind/api kind/docs; do
gh label create "$l" --repo "$REPO" --color 0e8a16 --force
done
for l in priority/important-soon priority/important-longterm priority/backlog; do
gh label create "$l" --repo "$REPO" --color fbca04 --force
done
for l in actor/kelos actor/human; do
gh label create "$l" --repo "$REPO" --color 5319e7 --force
done
for l in triage-accepted needs-actor needs-kind needs-priority needs-triage kelos/needs-input; do
gh label create "$l" --repo "$REPO" --color c5def5 --force
done
generated-by-kelosmarks bot-created PRs and issues;gh pr/issue create --labelfails without it.- The
kind/*,priority/*,actor/*, and lifecycle labels are applied bykanon-triage. kelos/needs-inputis applied bykanon-squash-commits.
Unlike this repository, Kanon's CI runs on every PR, so there is no
ok-to-test gate and the spawners do not apply that label.
3. Session GitHub Token Secret
Create the personal token Secret used by the Session-only Workspace. Task
credentials remain configured through kanon-agent and kelos-agent:
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 write access to kelos-dev/kanon and repo plus workflow
when using a classic personal access token.
4. GitHub Webhook Secret and Delivery
The issue and PR pick-up SessionSpawners and the remaining webhook
TaskSpawners are event-driven. Reuse the github-webhook-secret from your
existing deployment, then configure a repository webhook on kelos-dev/kanon:
- Point it at the same
https://<your-domain>/webhook/githubendpoint - Use the same shared secret
- Subscribe to
issues,issue_comment, andpull_request_review
Webhook spawners only react to new events after deployment. Retrigger an existing issue or PR with a fresh matching event if needed.
5. Agent Credentials Secret
The spawners reuse the kelos-credentials secret (the AI agent credentials are
the same regardless of repository). The Codex spawners use Codex OAuth, and
the Claude reviewer uses Claude Code OAuth:
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>
For Codex API-key auth, change the worker credential type to api-key and use
--from-literal=CODEX_API_KEY=<your-openai-api-key>.
Customizing
The spec.when.githubWebhook filters and template variables work the same for
TaskSpawner and SessionSpawner resources. See
self-development/README.md
for the webhook filter field reference and the full
template variable table, and
docs/reference.md for the authoritative field
references.
Troubleshooting
Webhook spawner not creating work:
- For pick-up, check the SessionSpawner status:
kubectl get sessionspawner <name> -o yaml - For other automation, check the TaskSpawner status:
kubectl get taskspawner <name> -o yaml - Verify the Workspaces exist:
kubectl get workspace kanon-session-agent kanon-agent kelos-agent - Ensure credentials are configured:
kubectl get secret kelos-credentials - Ensure the GitHub webhook server is enabled and the
github-webhook-secretexists - Review the
kelos-dev/kanonrepository webhook's recent deliveries in GitHub
Sessions or tasks failing immediately:
- Verify the agent credentials are valid
- Check the Workspace repository is accessible and the token has push access to it
- Review the corresponding Session or Task status and pod logs
Triage or PR/issue creation failing on labels:
- Confirm the labels from Repository labels exist on
kelos-dev/kanon—gherrors when adding or creating with a label that does not exist
Next Steps
- Read the main README for more details on Tasks and Workspaces
- See
self-development/for the equivalent setup that develops this repository - Monitor task execution:
kelos get tasksorkubectl get tasks