cekernel
CLAUDE.md17 starsChanged 8 months agoMITView on GitHub
cekernel is a parallel agent infrastructure for Claude Code. It maps Unix concepts (processes, IPC, schedulers) onto Claude workflows. See README.md for architecture details. When implementing something, always check existing patterns first. Background: When designing the Reviewer, an existing spawn pattern was overlooked and a subagent-based approach was implemented instead, requiring a rework. The skill → agent → agent nesting constraint was true at the time (2026-03) and could have been discovered with prior investigation. Nested subagents were later unlocked…
- Deletes or force-pushes
- Installs packages
In this repository10 other files it gives its agents.
- release-cekernelSkill
- atSkill
- cronSkill
- dispatchSkill
- orchctlSkill
- orchestrateSkill
- postmortemSkill
- probeSkill
- setupSkill
- unix-architectSkill
The file
Show its rules and text
We split this CLAUDE.md into the rules it gives an agent
23 rules. About 0 are common, 14 are distinctive, and 9 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈14
Distinctive · estimate
This author's own choices. Worth a look.
9
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 9
When uncertain about Claude Code specifications or behavior, always consult primary sources (official documentation, GitHub issues) before …
- Distinctive: line 14
When implementing something, always check existing patterns first.
- Distinctive: line 16
Feasibility check before implementation: When adopting an approach different from existing patterns, verify technical constraints first …
- Distinctive: line 18
Document deviations in ADR: When choosing not to use an existing pattern, record the reason in an ADR.
- Distinctive: line 52
Simplicity: No unnecessary complexity.
- Distinctive: line 53
Parsimony: Avoid large programs unless clearly necessary.
- Very specific: line 66
TDD compliance: When TDD is used, verify the Red-Green-Refactor cycle — failing test → minimal fix → refactor.
- Very specific: line 67
No tests for non-executable files: If the change only modifies non-executable files (agent definitions, skill definitions, documentation), …
- Very specific: line 81
Arithmetic safety: Use var=$((var + 1)) instead of ((var++)) (fails under set -e when var=0).
- Distinctive: line 89
All scripts must begin with:
- Very specific: line 150
Use the CEKERNEL_ prefix. Use ${VAR:-default} pattern for default values.
- Very specific: line 152
Use BASH_SOURCE[0]-based path resolution for locating files relative to the script.
- Very specific: line 164
Use a while-case loop (see cleanup-worktree.sh --force):
- Very specific: line 178
Use the ${1:?Usage: ...} pattern:
- Distinctive: line 229
Test only the behavior of executable scripts.
- Distinctive: line 304
Do not add new function-override mocks.
- Very specific: line 354
After changing any uses: line (adding, removing, or bumping an action), regenerate the lockfile and include it in the same commit:
- Distinctive: line 400
Commit message titles in English, body preferably in English
- Distinctive: line 405
Never commit directly to main.
- Distinctive: line 406
Use regular merge (not squash) for PRs unless explicitly told otherwise
- Distinctive: line 408
Commit messages follow conventional commits:
- Very specific: line 451
Never delete the current working directory (CWD) or its parent during a session.
- Distinctive: line 452
When the user has a problem visible in terminal output, proactively diagnose it rather than asking what the problem is
≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
cekernel Development Guide
cekernel is a parallel agent infrastructure for Claude Code. It maps Unix concepts (processes, IPC, schedulers) onto Claude workflows. See README.md for architecture details.
Principles
- When uncertain about Claude Code specifications or behavior, always consult primary sources (official documentation, GitHub issues) before answering. Do not guess.
- Links in CLAUDE.md are not references — they are part of the instructions. You MUST read linked documents and follow them.
Design Decisions
When implementing something, always check existing patterns first.
- Feasibility check before implementation: When adopting an approach different from existing patterns, verify technical constraints first (e.g., tool availability, API limitations, call depth restrictions). Do not start implementation without confirming feasibility.
- Verify feasibility in BOTH local and plugin modes: cekernel runs both as a local checkout (self-hosting) and as a distributed plugin (
--plugin-dir). Local self-hosting systematically hides plugin-mode failures — agent namespacing (reviewervscekernel:reviewer), hook loading (${CLAUDE_PLUGIN_ROOT}), env delivery, and Agent-tool subagent allowlists all differ. Any change touching agent spawn, hooks, env, or subagents MUST be feasibility-checked in a foreign repo via--plugin-dir, not local-only. Dogfood via--plugin-dirin a foreign repo before every release. - Document deviations in ADR: When choosing not to use an existing pattern, record the reason in an ADR. See the ADRs section for how to create one.
Background: When designing the Reviewer, an existing spawn pattern was overlooked and a subagent-based approach was implemented instead, requiring a rework. The
skill → agent → agentnesting constraint was true at the time (2026-03) and could have been discovered with prior investigation. Nested subagents were later unlocked in claude v2.1.172 (2026-06-10), so ADR-0012 Amendment 2 (2026-07) moved the Reviewer back to a subagent — a sound call, but it reused the 2026-03Agent(reviewer)grant unchanged, which broke in plugin mode (#600: the grant did not permit the plugin-namespacedcekernel:reviewer). The durable lesson is not the constraint (now lifted) but the both-modes feasibility check above.
Philosophy
cekernel's design is rooted in UNIX philosophy and TDD.
- UNIX Philosophy — Eric S. Raymond's 17 principles
- TDD — Red-Green-Refactor cycle and testing principles
These documents are symlinked in .claude/rules/ for automatic loading by Claude Code.
This ensures Worker agents read the content without requiring explicit Read calls.
Note:
.claude/rules/relative symlinks resolve correctly inside full worktree checkouts (verified 2026-07-06, claude v2.1.201), but automatic loading of the rules is only guaranteed for the session's project directory. Reviewers operating in worktrees should refer to the Review section below, which extracts the essential review criteria from these documents.
Review
Review criteria for Reviewer agents. This section exists in CLAUDE.md so that
Reviewers get the essential criteria directly, without depending on .claude/rules/
auto-loading inside their worktree.
The criteria below are extracted from unix-philosophy.md, tdd.md, and
claude-code-constraints.md.
Design Principles
Assess whether changes follow these UNIX philosophy principles:
- Modularity: Simple parts connected by clean interfaces. Each component has well-defined boundaries.
- Clarity: Readability over cleverness. Code serves future maintainers.
- Simplicity: No unnecessary complexity. Favor simple solutions over intricate ones.
- Parsimony: Avoid large programs unless clearly necessary.
- Transparency: Design for visibility. Systems should be immediately understandable.
- Robustness: Transparency and simplicity enable correctness verification.
- Least Surprise: Interfaces follow familiar conventions.
- Repair: Fail noisily and as soon as possible. Never silently continue in a broken state.
- Separation: Separate policy from mechanism; interfaces from engines.
- Composition: Programs accept and emit straightforward text streams for easy connection.
Testing Criteria
- Test behavior, not internals: Tests verify externally observable behavior, not internal state.
- Test independence: Tests must not share state or depend on execution order.
- Edge cases: Cover null/empty values, boundary values (0, 1, max), and error paths.
- TDD compliance: When TDD is used, verify the Red-Green-Refactor cycle — failing test → minimal fix → refactor. Check commit suffixes:
(RED),(GREEN),(REFACTOR). - No tests for non-executable files: If the change only modifies non-executable files (agent definitions, skill definitions, documentation), there should be no content-based tests (e.g., grep-testing
*.mdfor specific strings). If such tests exist, request their removal.
Platform Constraints
- claude CLI ownership (ADR-0018):
scripts/shared/claude-bg.shis the sole owner of the claude CLI surface (claude --bginvocation and spawn-line parsing,claude agents --jsonparsing,claude stop). A direct claude CLI parse or invocation outsideclaude-bg.sh, or a new implicit cross-boundary assumption (ADR-0018 boundary ownership table), is grounds for changes-requested. Consumers use the verdict predicates and keep their degradation policy (what to do onquery-failed/unknown-value) explicit at the call site. - zsh compatibility: Scripts
sourced in Claude Code must use${BASH_SOURCE[0]:-${(%):-%x}}fallback. - bash 3.2 compatibility: No
declare -A(associative arrays). Use temp files withgrep -qxFinstead. - Arithmetic safety: Use
var=$((var + 1))instead of((var++))(fails underset -ewhen var=0). - Subagent nesting: Officially supported since Claude Code v2.1.172; the depth limit is governed by
CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH(default 3, verified v2.1.317), not a fixed 5. Subagents fit short-lived, session-bound work (e.g., Reviewer); use independent processes with file-based IPC (state files) where cross-session persistence is required (e.g., Workers). - Context window: Workers must externalize state to files/git — do not rely on conversation history.
Scripts
Basic Rules
All scripts must begin with:
set -euo pipefailSource shared/session-id.sh to establish session scope:
source "${SCRIPT_DIR}/../shared/session-id.sh"Shared Helpers
Each helper in scripts/shared/ has a header comment documenting its API (functions, arguments, return values). Read the script file directly for usage details.
Known Pitfalls
((var++)) returns exit 1 when var=0 (bash treats 0 as falsy in arithmetic expressions).
Under set -e this causes immediate termination. Use var=$((var + 1)) instead:
# BAD: terminates under set -e when FAILED=0
((FAILED++))
# OK
FAILED=$((FAILED + 1))declare -A (associative arrays) requires bash 4+. macOS ships bash 3.2 by default,
so scripts using declare -A fail with exit code 2 on macOS. Use a temp file with
grep -qxF for set-membership lookups instead:
# BAD: fails on bash 3.2
declare -A seen
seen["key"]=1
[[ -n "${seen["key"]:-}" ]]
# OK: bash 3.2 compatible
seen_file=$(mktemp /tmp/cekernel-seen.XXXXXX)
echo "key" >> "$seen_file"
grep -qxF "key" "$seen_file"
rm -f "$seen_file"BASH_SOURCE[0] does not resolve correctly in zsh. Claude Code's Bash tool runs
in zsh, so scripts that are sourced by Orchestrator/Worker subagents need the
zsh fallback ${(%):-%x}. Scripts with a #!/usr/bin/env bash shebang that are
executed directly (not sourced) are unaffected because bash is invoked explicitly:
# BAD: BASH_SOURCE[0] is empty/wrong when sourced in zsh
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# OK: bash/zsh both work — fallback only evaluated in zsh
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-${(%):-%x}}")" && pwd)"Environment Variables
Use the CEKERNEL_ prefix. Use ${VAR:-default} pattern for default values. See envs/README.md for the full variable catalog.
Use BASH_SOURCE[0]-based path resolution for locating files relative to the script.
For scripts that may be sourced in zsh, use the zsh-compatible fallback (see Known Pitfalls):
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# If the script may be sourced in zsh (e.g., shared helpers):
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-${(%):-%x}}")" && pwd)"Flag Parsing
Use a while-case loop (see cleanup-worktree.sh --force):
FORCE=0
while [[ $# -gt 0 ]]; do
case "$1" in
--force) FORCE=1; shift ;;
*) break ;;
esac
donePositional Argument Validation
Use the ${1:?Usage: ...} pattern:
ISSUE_NUMBER="${1:?Usage: spawn-worker.sh <issue-number> [base-branch]}"
BASE_BRANCH="${2:-main}"Agents & Skills
Frontmatter
Agents and skills use different frontmatter key names for tool access:
| Type | File | Key | Example |
| Agent | agents/*.md | tools | tools: Read, Edit, Write, Bash |
| Skill | skills/*/SKILL.md | allowed-tools | allowed-tools: Read, Bash, Task |
Agent frontmatter:
name: <agent-name>
description: <description>
tools: Read, Edit, Write, BashSkill References
Shared logic used by multiple skills is placed in skills/references/ as markdown files. Skills read these via the Read tool and execute the instructions.
skills/references/
├── namespace-detection.md # Plugin vs local detection (ADR-0009)
├── postmortem-patterns.md # Post-mortem detection patterns (ADR-0013)
└── triage.md # Issue triage protocolThis avoids duplicating the same logic across multiple SKILL.md files. When the shared logic changes, only the reference file needs updating.
ADRs
Architecture Decision Records are stored in docs/adr/. Use /unix-architect adr <topic> to create new ADRs.
Numbering: check the latest file with ls docs/adr/*.md | sort -V | tail -1 and increment.
Status lifecycle: Proposed → Accepted (or Rejected). Amendments are added as subsections within the original ADR.
Testing
What to Test
Test only the behavior of executable scripts.
- OK:
session-id.shgenerates and exportsSESSION_ID - OK:
spawn-worker.shreturns exit 2 when the concurrency limit is exceeded - NG: Grep-testing
*.mdcontent to verify specific strings are present
Agent definitions (agents/*.md), skill definitions (skills/*/SKILL.md),
and documentation files are NOT executable scripts — do not write tests for them.
This rule takes precedence over TDD: do not write a RED test for non-executable file changes.
TDD applies only to executable scripts.
There is no exception. Content-based assertions on markdown or
configuration files are not acceptable even as regression guards for
doc-only changes — this was tried in the project's earliest days and
proved meaningless (removed 2026-07-07). Such tests pin prose, not
behavior, and force future edits to contort documents to satisfy greps.
(Note: runtime artifacts named *.md — .cekernel-task.md,
.cekernel-checkpoint.md — are script outputs; asserting on them is
normal behavior testing and is fine.)
Assert behavior, never text (ADR-0017). Tests verify executed effects
and recorded argv — not the text of generated scripts, and not the source
text of scripts either. Grep-testing a generated runner for strings like
claude --bg, or grepping spawn.sh source for resolve_repo_root,
is the same anti-pattern as .md-grep — it breaks on mechanism or wording
changes even when behavior is preserved.
Test Harness (bats-core)
The test suite uses bats-core exclusively.
CI runs bats --recursive tests/.
Local setup: brew install bats-core (macOS). CI pins bats-core v1.13.0
via git checkout in cekernel-tests.yml.
Tests are written as .bats files. Naming: one .bats file per
script under test, named after the script (e.g. tests/shared/session-id.bats
for scripts/shared/session-id.sh).
In .bats files, use load '../helpers/assertions' for the ported
assert_* functions (bats-assert is not vendored).
Test File Naming
tests/
├── helpers/
│ ├── assertions.bash # Assertion functions
│ ├── mock-bin.bash # mock_bin PATH-shim helper
│ ├── mock-claude.bash # Canonical claude shim for v2 spawn tests
│ └── session.bash # Per-test unique CEKERNEL_SESSION_ID
├── ctl/
│ └── {script-name}.bats # Control script tests
├── hooks/
│ └── {script-name}.bats # Hook script tests
├── orchestrator/
│ └── {script-name}.bats # Orchestrator script tests
├── process/
│ └── {script-name}.bats # Process script tests
├── shared/
│ └── {script-name}.bats # Shared helper tests
└── scheduler/
└── {script-name}.bats # Scheduler script testsAssertion Functions
In .bats files, load '../helpers/assertions' provides the assert_*
API (failures return 1 and fail the surrounding @test; bats tracks
pass/fail counts automatically).
Mocking
PATH shims are the only sanctioned mock style (ADR-0017). Shell-function
overrides are banned — they silently fail across exec/subshell boundaries.
Do not add new function-override mocks.
In .bats files, use the canonical helpers:
load '../helpers/mock-bin' # mock_bin <cmd> <script-body>
load '../helpers/mock-claude' # canonical claude shim (--bg / agents --json / stop)mock-claude.bash emulates the ADR-0016 delegated-spawn contract. Any PR
updating the "Background Agent Sessions" section of
docs/claude-code-constraints.md must update the mock in the same PR.
git and git worktree stay real against temp repos (ADR-0017): mocking
them would fake the exact behavior worktree tests exist to verify.
Test Isolation
Isolate commands with side effects (WezTerm, gh, git worktree) from tests, or structure them to be mockable.
In .bats files, use a per-test unique CEKERNEL_SESSION_ID (derived from
BATS_TEST_NAME, safe under parallel bats runs):
load '../helpers/session'
setup() {
set_test_session_id # exports a per-test unique CEKERNEL_SESSION_ID
source "${CEKERNEL_DIR}/scripts/shared/session-id.sh"
rm -rf "$CEKERNEL_IPC_DIR"
mkdir -p "$CEKERNEL_IPC_DIR"
}
teardown() {
rm -rf "$CEKERNEL_IPC_DIR"
}CI
GitHub Actions runs bats --recursive tests/ when changes are detected. PRs that fail tests are not merged.
Workflow Lockfile
External actions are locked in .github/workflows/actions.lock
(generated by gh actions-lock);
verify-lockfile.yml runs gh actions-lock --verify on every PR and main push.
uses:references must be full semver tags (e.g.actions/checkout@v7.0.1), not bare SHAs or force-pushed branch refs — the lockfile records the resolved commit- After changing any
uses:line (adding, removing, or bumping an action), regenerate the lockfile and include it in the same commit:
gh extension install github/gh-actions-lock # once
gh actions-lock # regenerate actions.lock
gh actions-lock --verifyVersioning
/plugin update uses the version string in plugin.json to determine differences.
Version management is automated via the /release-cekernel skill and GitHub Actions.
Semantic Versioning Rules
| Bump | Condition | Example |
| patch | Bug fixes, documentation updates, test additions | fix:, docs:, test:, refactor: |
| minor | New scripts/skills, backward-compatible feature additions | feat: |
| major | Breaking changes: argument changes, deprecated env vars, removed scripts | Changes that break existing callers |
Release Procedure
/release-cekernelThe skill analyzes git log and recommends a bump level. After confirmation:
- CI creates a
release/cekernel-vX.Y.Zbranch with the version bump and opens a PR - Human reviews and merges the PR (follows normal branch protection)
plugin-release-tag.ymlautomatically creates the tag and GitHub Release on merge- Human edits the release notes to add categorized summary
Versioned Artifacts
.claude-plugin/plugin.json— Plugin manifest
Tag Format
cekernel-v{major}.{minor}.{patch} (prefixed for future multi-plugin support)
Conventions
- Branch names:
issue/{number}-{short-description} - Commit message titles in English, body preferably in English
- PR body must include
closes #{issue-number} - GitHub issues, issue comments, and PR descriptions are written in Japanese by default
- Project documentation files (
docs/,skills/,agents/,README.md,RELEASE_NOTES.md,CLAUDE.md, etc.) are written in English - RELEASE_NOTES.md is written in English (What's Changed section uses PR titles as-is; Japanese PR titles are kept verbatim)
- Never commit directly to main. Always create a feature branch and open a PR
- Use regular merge (not squash) for PRs unless explicitly told otherwise
- Worktrees are created under
.worktrees/(already in .gitignore). See Worktree Naming for details - Commit messages follow conventional commits:
feat:New featurefix:Bug fixdocs:Documentation onlytest:Tests onlyrefactor:Refactoringrelease:Version bump (CI auto-generated)
- Skill reference files (
skills/references/*.md) and skill definitions (skills/*/SKILL.md) are executable instructions, not documentation. Usefeat:/fix:accordingly.docs:is reserved for purely informational files (README, architecture docs, ADRs).
Worktree Naming
spawn.sh creates worktrees deterministically from the issue number and title:
.worktrees/issue/{N}-{slug}/{N}— Issue number{slug}— Title converted to lowercase, non-alphanumeric characters replaced with-, truncated to 40 characters
Example: issue #42 "Add widget support" → .worktrees/issue/42-add-widget-support/
Claude Code Project Directory Mapping
Claude Code stores per-project data under ~/.claude/projects/, using the worktree's absolute path with / replaced by -:
Worktree: /Users/alice/git/repo/.worktrees/issue/42-add-widget-support/
Project: ~/.claude/projects/-Users-alice-git-repo--worktrees-issue-42-add-widget-support/transcript-locator.sh uses this mapping to discover transcripts. The glob pattern *-issue-{N}-* matches project directories for a given issue number, regardless of host path or slug content.
Issue Management
- Issues labeled
ideaor exploratory topics should follow: ADR first → then implementation issue(s) - Large or complex issues should be broken down into smaller sub-issues that a Worker can complete independently
- Each issue should be scoped so that a single Worker can implement, test, and merge it without ambiguity
Safety
- Never delete the current working directory (CWD) or its parent during a session. If cleanup is needed,
cdto a safe directory first - When the user has a problem visible in terminal output, proactively diagnose it rather than asking what the problem is
Self-hosting
cekernel's own issues are also resolved using /orchestrate.
This CLAUDE.md also serves as a guide for Workers developing cekernel itself.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

