Skip to content

Contributing

Language: English | 日本語 Last updated: 2026-05-13 Update history:

  • 2026-05-13: Add design-notes lifecycle section (proposals/, safety-net, evergreen notes) (#118)
  • 2026-04-30: Update Agents-Reference split threshold to 6 pages + New flow checklist (#54)
  • 2026-04-30: README ↔ Wiki responsibility split documented (#76)
  • 2026-04-29: clarify wiki/design-notes/README language policy (#75) Audience: Agent developers

This page covers how to contribute to Aphelion: adding or modifying agents, updating rules, and maintaining the wiki. Read this before opening a pull request.


TypeChanges required
New agent.claude/agents/{name}.md + the matching Agents-{domain}.md page (en+ja)
Modify agent.claude/agents/{name}.md + matching Agents-{domain}.md entry (en+ja)
New rule.claude/rules/{name}.md + Rules-Reference (en+ja)
Modify rule.claude/rules/{name}.md + Rules-Reference entry (en+ja)
Orchestrator rules change.claude/orchestrator-rules.md + Architecture-Operational-Rules.md / Triage-System.md (en+ja)
New flow (orchestrator).claude/agents/{flow}.md + .claude/commands/{flow}.md + Architecture-Domain-Model.md (figures + text) + Architecture-Operational-Rules.md (Phase Execution Loop) + Triage-System.md (new section) + Agents-Orchestrators.md (new orchestrator) + Agents-{Domain}.md (new domain page if applicable; e.g. Agents-Doc.md for Doc domain) + Home.md (personas + glossary + page count) + index.mdx (card)
Wiki page updatewiki/en/{page}.md + wiki/ja/{page}.md (same PR)

  1. Create the agent definition file at .claude/agents/{name}.md.

    Follow the standard frontmatter format used by existing agents:

    ---
    name: {agent-name}
    description: |
    {one-line description for orchestrator discovery}
    tools: Read, Write, Edit, Bash, Glob, Grep
    ---

    Include sections: Mission, Inputs, Workflow, Outputs, AGENT_RESULT (with all fields), NEXT conditions.

  2. Update the matching Agents-{Domain} page in both wiki/en/ and wiki/ja/: Agents-Discovery.md, Agents-Delivery.md, Agents-Operations.md, Agents-Maintenance.md, or Agents-Orchestrators.md for cross-cutting agents (flow orchestrators, sandbox-runner, analyst, codebase-analyzer). Add a new entry following the standard schema (Canonical, Domain, Responsibility, Inputs, Outputs, AGENT_RESULT fields, NEXT conditions).

  3. If the agent is invokable as a standalone slash command, add a corresponding command file in .claude/commands/{name}.md.

  4. If the agent is a new flow orchestrator, update .claude/orchestrator-rules.md to include the new agent in the triage or phase sequence.

  5. Agents-Reference split threshold: The Agents-Reference was split into 6 domain pages (#42 for the initial 5, #54 added Agents-Doc.md as the 6th). If any single domain page exceeds ~250 lines, or the total agent count exceeds 50, consider further splitting into per-agent files (wiki/en/agents/{name}.md). This is a future decision — open an issue to discuss first.


  1. Edit the canonical file at .claude/agents/{name}.md.

  2. Update the corresponding entry in the matching Agents-{Domain}.md page (en+ja) to reflect the change.

    Keeping the Agents-{Domain} pages synchronized with .claude/agents/ is mandatory. If you update an agent definition without updating the matching wiki entry, reviewers will request a correction.


  1. Edit the canonical file at src/.claude/rules/{name}.md (see “Editing Aphelion’s own rules” below for the layout rationale).

  2. Update the corresponding Rules-Reference entry in both wiki/en/Rules-Reference.md and wiki/ja/Rules-Reference.md.

  3. If the rule change affects orchestrator behavior, also update the relevant Architecture sub-page (wiki/{en,ja}/Architecture-Operational-Rules.md for runtime behaviors, Architecture-Domain-Model.md for conceptual changes, Architecture-Protocols.md for AGENT_RESULT / handoff schema changes).

  4. If the rule affects triage, also update wiki/en/Triage-System.md and wiki/ja/Triage-System.md.

The canonical source for rules/*.md lives at src/.claude/rules/, not at .claude/rules/. This is intentional.

Claude Code auto-loads rules/*.md from both ~/.claude/rules/ (user-global) and <project>/.claude/rules/ (project-local) in additive fashion. For Aphelion’s own maintainers, that previously meant every session opened inside the repo loaded two copies of every rule — and during the rule-edit window, two materially different versions. Relocating the source out of the repo-root .claude/rules/ slot eliminates the structural dual-load. See docs/design-notes/archived/claude-rules-isolation.md (#44) for the full analysis.

Practical consequence: when you edit a rule under src/.claude/rules/, your in-progress edit does not automatically take effect in your current Claude Code session. Your session is governed by your user-global mirror at ~/.claude/rules/, which is the deployed snapshot. To pick up your edit:

  1. Bump package.json version per the policy below.
  2. Run node bin/aphelion-agents.mjs update --user (or after merge, npx github:kirin0198/aphelion-agents#main update --user).
  3. Start a new Claude Code session.

This edit-vs-effect decoupling is deliberate: editing a rule while being simultaneously governed by it is a chicken-and-egg problem. Decoupling avoids it.

Do not symlink src/.claude/rules/ to <repo>/.claude/rules/. That re-introduces the dual-load this layout was designed to remove.


  • Always edit the English page (wiki/en/) first — it is the canonical source.
  • Update > Last updated: at the top of the English page.
  • Update the corresponding Japanese page in the same PR. Update > EN canonical: to the current date.
  1. Create wiki/en/{slug}.md with the standard frontmatter.
  2. Create wiki/ja/{slug}.md with EN canonical: {date} of wiki/en/{slug}.md.
  3. Add both pages to the ## Pages section in wiki/en/Home.md and wiki/ja/Home.md.
  4. Add Related Pages links in pages that are topically related.

If you add a new English page but cannot provide a Japanese translation in the same PR, place a stub in wiki/ja/{slug}.md:

> 本ページは英語版が先行しています。[English version](../en/{slug}.md) を参照してください。

Translate within 30 days and link the stub issue to the follow-up PR.

Roles

  • README (README.md / README.ja.md) — landing page. Snapshots a small, hand-curated subset of facts from the Wiki: tagline + agent count, Quick Start command, Features (5 bullet points), and a Learn-more link section. The README is not a canonical source for any of these; it mirrors the Wiki.
  • Wiki (docs/wiki/{en,ja}/) — canonical reference. Agent schemas, rule explanations, triage logic, command reference, troubleshooting all live here. The Wiki is the source of truth for everything the README mentions.

Boundary rule

Items that may stay in README:

  • 1-line tagline + agent count (landing snapshot target)
  • 3-domain mermaid diagram (project overview at a glance)
  • Quick Start 3 commands (npx … init / cd && claude / /aphelion-init)
  • Features bullet list (5 items max, 1 line each)
  • Links to the 5 major Wiki pages

Items that must go to Wiki (do not put these in README):

  • Exhaustive slash command table (README defers to /aphelion-help)
  • Alternative install details (--user / git clone etc.)
  • Cache caveats and troubleshooting
  • Triage plan selection logic
  • Per-agent input/output / NEXT conditions
  • Any persona-based entry points

Decision rule: “3+ lines of explanation”, “branching logic”, or “exhaustive reference” → Wiki side.

Co-update set

The following facts are intentionally duplicated between README and Wiki. Updating one without the others is a defect; reviewers will block the PR.

FactREADME sitesWiki sitesOther sites
Agent count (31, 32, …)README.md, README.ja.mddocs/wiki/en/Home.md (×2), docs/wiki/ja/Home.md (×2)
Slash command names(none — README defers to /aphelion-help)docs/wiki/{en,ja}/Getting-Started.md §Command Reference.claude/commands/aphelion-help.md
Quick Start command (npx … init)README.md, README.ja.md (Quick Start section)docs/wiki/{en,ja}/Getting-Started.md §Quick Start
3-domain mermaid figureREADME.md, README.ja.md(Wiki uses prose + Architecture diagrams instead)
Features bullets (5 items)README.md, README.ja.md(Wiki Home Persona-Based Entry Points covers same ground in prose)
Plan tier names (Minimal/Light/Standard/Full)(none currently)docs/wiki/{en,ja}/Triage-System.md, Home.md glossary.claude/rules/aphelion-overview.md

README en ↔ ja parity

README.md and README.ja.md are bilingual at the repository root with English canonical. The sync convention is governed by language-rules.md → “Hand-authored canonical narrative” and the repo-root README sync convention — not by this Wiki Bilingual Sync Policy. See language-rules.md for the authoritative rule. (#75)


Planning documents in docs/design-notes/ record analyst-phase decisions for features, bug investigations, and refactoring. Each directory level has a distinct purpose.

DirectoryContentsArchive automation
docs/design-notes/*.mdActive planning docs (issue open)Yes — moved automatically when issue closes
docs/design-notes/archived/*.mdClosed planning docs (read-only)Destination only
docs/design-notes/proposals/*.mdPre-issue ideas (no issue yet)Excluded from automation

Active planning docs (docs/design-notes/<slug>.md) must start with:

> Last updated: <YYYY-MM-DD>
> GitHub Issue: [#N](<URL>)
> Analyzed by: analyst (<YYYY-MM-DD>)
> Next: <architect | developer | TBD>

The > GitHub Issue: [#N](...) line is required so that the archive automation can match the file to its issue.

Proposals (docs/design-notes/proposals/<slug>.md) use a different header — no > GitHub Issue: line:

> Status: proposal
> Author: <name or handle>
> Created: <YYYY-MM-DD>
> Last updated: <YYYY-MM-DD>
docs/design-notes/proposals/<slug>.md (idea, no issue)
│ analyst promotes the idea, creates a GitHub issue
docs/design-notes/<slug>.md (active planning doc)
│ PR merges with `Closes #N` body (reactive path)
│ .github/workflows/archive-closed-plans.yml
│ moves file inside the merging PR
│ ─── OR ───
│ weekly cron finds the linked issue is CLOSED
│ .github/workflows/archive-orphan-plans.yml
│ opens a separate "chore: archive orphaned" PR
docs/design-notes/archived/<slug>.md (historical record)
  1. Reactive (default)archive-closed-plans.yml fires on pull_request: opened / edited / synchronize. It parses Closes #N / Fixes #N / Resolves #N in the PR body, finds matching planning docs by their > GitHub Issue: [#N] header, and git mv’s them into archived/ in the same PR.

  2. Weekly safety netarchive-orphan-plans.yml runs every Monday at 03:00 UTC (and on-demand via workflow_dispatch --dry_run). It catches planning docs whose linked issue was already closed but were missed by the reactive workflow (e.g. the PR body lacked Closes #N, or the issue was closed without a PR). It opens a single chore: archive orphaned planning docs PR for human review.

  3. Manual fallback — if neither automated path applied:

    Terminal window
    git mv docs/design-notes/<slug>.md docs/design-notes/archived/
    git commit -m "chore: archive <slug> manually"

Files without a > GitHub Issue: header in docs/design-notes/ are treated as evergreen reference notes (standing guidelines, glossaries, long-lived architectural overviews). Archive automation skips them. Do not move them unless the content has become stale.

  1. Draft — write proposals/<slug>.md with any level of detail. No PR template, no review gate.
  2. Promote — when ready to act on, the analyst agent:
    • opens a GitHub issue,
    • moves (or rewrites) the file to docs/design-notes/<slug>.md,
    • replaces the > Status: proposal header with the standard > GitHub Issue: [#N](...) header.
  3. Reject / pending — leave in place. proposals/ has no automated cleanup; periodic manual review is expected.

proposals/ files are excluded from agent reads (doc-reviewer, handover-author) — they are human scratch space, not part of the formal design-decision history.

See docs/design-notes/README.md for the authoritative active-side guide.


The wiki is bilingual with English as canonical. The following rules are enforced in PR review:

Source of truth. The broader language policy covering hand-authored canonical narrative (wiki, design notes, README) is declared in language-rules.md → “Hand-authored canonical narrative”. This section enforces only the wiki-bilingual subset. For docs/design-notes/ single-file conventions or README sync, consult language-rules.md directly.

Mandatory:

  • Every PR that modifies wiki/en/{page}.md must also update wiki/ja/{page}.md in the same PR.
  • English-only merges are prohibited (except for minor fixes — see below).
  • The > EN canonical: {date} line in every wiki/ja/ page must be updated to match the current date when the English page changes.

Minor fix exception:

  • Typo fixes and broken link corrections in English-only may be merged without same-PR Japanese sync.
  • A follow-up issue must be opened and assigned for the Japanese update within 7 days.

Reviewer responsibility:

  • Reviewers check that wiki/en/ and wiki/ja/ structural parity is maintained (same sections, same headings, matching TOC).

Before opening a PR, verify:

  • Canonical source (.claude/agents/ or .claude/rules/) updated
  • wiki/en/ page updated (if the change affects wiki content)
  • wiki/ja/ page updated in the same PR (bilingual sync)
  • > Last updated: line updated in modified wiki pages
  • > EN canonical: line updated in corresponding wiki/ja/ pages
  • Matching Agents-{Domain}.md or Rules-Reference.md entry updated (if agent/rule changed)
  • If a new flow / orchestrator is added, update all integration points: Architecture-Domain-Model.md figures, Architecture-Operational-Rules.md (Phase Execution Loop), Triage-System.md sections, Agents-Orchestrators.md (cross-cutting agent entry), and Home.md persona entries
  • If a new file is added under .claude/commands/, also append a row to .claude/commands/aphelion-help.md so the static command listing stays in sync with the directory (#39)
  • package.json version bumped if any file under .claude/agents/, .claude/rules/, .claude/commands/, or .claude/orchestrator-rules.md was modified (see “Version bumping policy” below)
  • If the change touches anything in the README ↔ Wiki co-update set (see “README ↔ Wiki responsibility split”), all duplicated sites are updated in this PR. Run: bash scripts/check-readme-wiki-sync.sh and confirm no diffs are reported.
  • bash scripts/smoke-update.sh exits 0 (release-time gate; run before tagging)

Any PR that modifies the canonical source under .claude/agents/, .claude/rules/, .claude/commands/, or .claude/orchestrator-rules.md MUST bump package.json version. This is the only thing that invalidates downstream npx caches — without a bump, users running npx ... update will keep receiving the previous snapshot even after git push to main.

  • Default: bump the patch component (0.2.00.2.1).
  • Bump the minor component when adding a new agent, a new flow, or a breaking rule.
  • Document the change in CHANGELOG.md under the ## [Unreleased] section.

<project>/.claude/settings.local.json ships with a deny-list shape: allow: ["*"] and explicit deny entries for destructive operations. Categories: destructive_fs, destructive_git, privilege_escalation, secret_access, prod_db, external_publish. The list mirrors the categories in .claude/rules/sandbox-policy.md §1.

Customising: deny entries can be removed locally if your workflow needs a banned command (git push --force-with-lease against your own fork, for example). Removed entries are not propagated back when running npx aphelion-agents update — the filter at copy time preserves your local settings.local.json.

See .claude/rules/denial-categories.md for the full protocol. Quick reference:

  • Sandbox / policy denialAskUserQuestion to confirm intent. If still blocked after approval, paste !cmd into the chat input (manual fallback). Claude Code does not currently honor in-conversation approval as a one-shot allowlist.
  • POSIX Permission denied → run ls -la {path}; if owned by root, run sudo chown -R $USER {path} and retry. This is not a sandbox-policy issue; the approval flow will not help.
  • Claude Code auto-mode refusal (sub-agent boundary, branch-protection heuristic, “External System Write”, etc.) — not configurable from settings.local.json. Either approve per-invocation, run the command from the parent session, or split the workflow so the heuristic does not fire.

Planning documents in docs/design-notes/ are written by the analyst phase before implementation. Once the corresponding GitHub issue is closed (its work has shipped), the file moves to docs/design-notes/archived/ so that the active directory only lists work in flight.

The move is automated and lands in the same PR as the work (no separate follow-up PR). The archive-closed-plans workflow fires on pull_request: opened / edited / synchronize, parses the PR body for Closes #N / Fixes #N / Resolves #N keywords, finds matching planning docs by their GitHub Issue: [#N] header reference, git mv’s them into docs/design-notes/archived/, and pushes the resulting commit back to the PR branch. The reviewer then sees one diff containing both the work and the archive move.

The workflow is idempotent — if the planning doc is already archived (or no match exists), it is a no-op. Loop safety against the bot’s own pushes is provided by an actor filter (github.actor != 'github-actions[bot]') plus the idempotency check.

Edge case. The workflow archives at PR-open time, trusting the Closes #N keyword as a commitment that merging will close the issue (which GitHub does automatically on merge). If the PR is ultimately closed without merging, the moves must be reverted manually (git mv docs/design-notes/archived/<slug>.md docs/design-notes/<slug>.md and open a small chore PR). The trade-off is intentional: trigger-on-merge would split every change into two PRs, and PR proliferation was the larger ergonomic problem.

Manual fallback: git mv docs/design-notes/<slug>.md docs/design-notes/archived/. Use this if the workflow could not detect the issue reference (e.g. the planning doc tracks something without a GitHub issue, or the PR body did not use a keyword).

Treat archived planning docs as read-only. Cross-references inside an archived doc to other archived docs stay as the original (relative) paths; do not retroactively rewrite them. Live documents that need to link into the archive should use the explicit docs/design-notes/archived/<slug>.md path.