zeroclaw/CLAUDE.md
Chummy ba287a2ea5 add CLAUDE.md
add CLAUDE.md to better guide users who vibe code with claude code.
2026-02-17 16:19:31 +08:00

18 KiB

CLAUDE.md — ZeroClaw Agent Engineering Protocol

This file defines the default working protocol for claude code in this repository. Scope: entire repository.

1) Project Snapshot (Read First)

ZeroClaw is a Rust-first autonomous agent runtime optimized for:

  • high performance
  • high efficiency
  • high stability
  • high extensibility
  • high sustainability
  • high security

Core architecture is trait-driven and modular. Most extension work should be done by implementing traits and registering in factory modules.

Key extension points:

  • src/providers/traits.rs (Provider)
  • src/channels/traits.rs (Channel)
  • src/tools/traits.rs (Tool)
  • src/memory/traits.rs (Memory)
  • src/observability/traits.rs (Observer)
  • src/runtime/traits.rs (RuntimeAdapter)
  • src/peripherals/traits.rs (Peripheral) — hardware boards (STM32, RPi GPIO)

2) Deep Architecture Observations (Why This Protocol Exists)

These codebase realities should drive every design decision:

  1. Trait + factory architecture is the stability backbone
    • Extension points are intentionally explicit and swappable.
    • Most features should be added via trait implementation + factory registration, not cross-cutting rewrites.
  2. Security-critical surfaces are first-class and internet-adjacent
    • src/gateway/, src/security/, src/tools/, src/runtime/ carry high blast radius.
    • Defaults already lean secure-by-default (pairing, bind safety, limits, secret handling); keep it that way.
  3. Performance and binary size are product goals, not nice-to-have
    • Cargo.toml release profile and dependency choices optimize for size and determinism.
    • Convenience dependencies and broad abstractions can silently regress these goals.
  4. Config and runtime contracts are user-facing API
    • src/config/schema.rs and CLI commands are effectively public interfaces.
    • Backward compatibility and explicit migration matter.
  5. The project now runs in high-concurrency collaboration mode
    • CI + docs governance + label routing are part of the product delivery system.
    • PR throughput is a design constraint; not just a maintainer inconvenience.

3) Engineering Principles (Normative)

These principles are mandatory by default. They are not slogans; they are implementation constraints.

3.1 KISS (Keep It Simple, Stupid)

Why here: Runtime + security behavior must stay auditable under pressure.

Required:

  • Prefer straightforward control flow over clever meta-programming.
  • Prefer explicit match branches and typed structs over hidden dynamic behavior.
  • Keep error paths obvious and localized.

3.2 YAGNI (You Aren't Gonna Need It)

Why here: Premature features increase attack surface and maintenance burden.

Required:

  • Do not add new config keys, trait methods, feature flags, or workflow branches without a concrete accepted use case.
  • Do not introduce speculative “future-proof” abstractions without at least one current caller.
  • Keep unsupported paths explicit (error out) rather than adding partial fake support.

3.3 DRY + Rule of Three

Why here: Naive DRY can create brittle shared abstractions across providers/channels/tools.

Required:

  • Duplicate small, local logic when it preserves clarity.
  • Extract shared utilities only after repeated, stable patterns (rule-of-three).
  • When extracting, preserve module boundaries and avoid hidden coupling.

3.4 SRP + ISP (Single Responsibility + Interface Segregation)

Why here: Trait-driven architecture already encodes subsystem boundaries.

Required:

  • Keep each module focused on one concern.
  • Extend behavior by implementing existing narrow traits whenever possible.
  • Avoid fat interfaces and “god modules” that mix policy + transport + storage.

3.5 Fail Fast + Explicit Errors

Why here: Silent fallback in agent runtimes can create unsafe or costly behavior.

Required:

  • Prefer explicit bail!/errors for unsupported or unsafe states.
  • Never silently broaden permissions/capabilities.
  • Document fallback behavior when fallback is intentional and safe.

3.6 Secure by Default + Least Privilege

Why here: Gateway/tools/runtime can execute actions with real-world side effects.

Required:

  • Deny-by-default for access and exposure boundaries.
  • Never log secrets, raw tokens, or sensitive payloads.
  • Keep network/filesystem/shell scope as narrow as possible unless explicitly justified.

3.7 Determinism + Reproducibility

Why here: Reliable CI and low-latency triage depend on deterministic behavior.

Required:

  • Prefer reproducible commands and locked dependency behavior in CI-sensitive paths.
  • Keep tests deterministic (no flaky timing/network dependence without guardrails).
  • Ensure local validation commands map to CI expectations.

3.8 Reversibility + Rollback-First Thinking

Why here: Fast recovery is mandatory under high PR volume.

Required:

  • Keep changes easy to revert (small scope, clear blast radius).
  • For risky changes, define rollback path before merge.
  • Avoid mixed mega-patches that block safe rollback.

4) Repository Map (High-Level)

  • src/main.rs — CLI entrypoint and command routing
  • src/lib.rs — module exports and shared command enums
  • src/config/ — schema + config loading/merging
  • src/agent/ — orchestration loop
  • src/gateway/ — webhook/gateway server
  • src/security/ — policy, pairing, secret store
  • src/memory/ — markdown/sqlite memory backends + embeddings/vector merge
  • src/providers/ — model providers and resilient wrapper
  • src/channels/ — Telegram/Discord/Slack/etc channels
  • src/tools/ — tool execution surface (shell, file, memory, browser)
  • src/peripherals/ — hardware peripherals (STM32, RPi GPIO); see docs/hardware-peripherals-design.md
  • src/runtime/ — runtime adapters (currently native)
  • docs/ — architecture + process docs
  • .github/ — CI, templates, automation workflows

5) Risk Tiers by Path (Review Depth Contract)

Use these tiers when deciding validation depth and review rigor.

  • Low risk: docs/chore/tests-only changes
  • Medium risk: most src/** behavior changes without boundary/security impact
  • High risk: src/security/**, src/runtime/**, src/gateway/**, src/tools/**, .github/workflows/**, access-control boundaries

When uncertain, classify as higher risk.

6) Agent Workflow (Required)

  1. Read before write
    • Inspect existing module, factory wiring, and adjacent tests before editing.
  2. Define scope boundary
    • One concern per PR; avoid mixed feature+refactor+infra patches.
  3. Implement minimal patch
    • Apply KISS/YAGNI/DRY rule-of-three explicitly.
  4. Validate by risk tier
    • Docs-only: lightweight checks.
    • Code/risky changes: full relevant checks and focused scenarios.
  5. Document impact
    • Update docs/PR notes for behavior, risk, side effects, and rollback.
  6. Respect queue hygiene
    • If stacked PR: declare Depends on #....
    • If replacing old PR: declare Supersedes #....

6.3 Branch / Commit / PR Flow (Required)

All contributors (human or agent) must follow the same collaboration flow:

  • Create and work from a non-main branch.
  • Commit changes to that branch with clear, scoped commit messages.
  • Open a PR to main; do not push directly to main.
  • Wait for required checks and review outcomes before merging.
  • Merge via PR controls (squash/rebase/merge as repository policy allows).
  • Branch deletion after merge is optional; long-lived branches are allowed when intentionally maintained.

6.4 Worktree Workflow (Required for Multi-Track Agent Work)

Use Git worktrees to isolate concurrent agent/human tracks safely and predictably:

  • Use one worktree per active branch/PR stream to avoid cross-task contamination.
  • Keep each worktree on a single branch; do not mix unrelated edits in one worktree.
  • Run validation commands inside the corresponding worktree before commit/PR.
  • Name worktrees clearly by scope (for example: wt/ci-hardening, wt/provider-fix) and remove stale worktrees when no longer needed.
  • PR checkpoint rules from section 6.3 still apply to worktree-based development.

6.1 Code Naming Contract (Required)

Apply these naming rules for all code changes unless a subsystem has a stronger existing pattern.

  • Use Rust standard casing consistently: modules/files snake_case, types/traits/enums PascalCase, functions/variables snake_case, constants/statics SCREAMING_SNAKE_CASE.
  • Name types and modules by domain role, not implementation detail (for example DiscordChannel, SecurityPolicy, MemoryStore over vague names like Manager/Helper).
  • Keep trait implementer naming explicit and predictable: <ProviderName>Provider, <ChannelName>Channel, <ToolName>Tool, <BackendName>Memory.
  • Keep factory registration keys stable, lowercase, and user-facing (for example "openai", "discord", "shell"), and avoid alias sprawl without migration need.
  • Name tests by behavior/outcome (<subject>_<expected_behavior>) and keep fixture identifiers neutral/project-scoped.
  • If identity-like naming is required in tests/examples, use ZeroClaw-native labels only (ZeroClawAgent, zeroclaw_user, zeroclaw_node).

6.2 Architecture Boundary Contract (Required)

Use these rules to keep the trait/factory architecture stable under growth.

  • Extend capabilities by adding trait implementations + factory wiring first; avoid cross-module rewrites for isolated features.
  • Keep dependency direction inward to contracts: concrete integrations depend on trait/config/util layers, not on other concrete integrations.
  • Avoid creating cross-subsystem coupling (for example provider code importing channel internals, tool code mutating gateway policy directly).
  • Keep module responsibilities single-purpose: orchestration in agent/, transport in channels/, model I/O in providers/, policy in security/, execution in tools/.
  • Introduce new shared abstractions only after repeated use (rule-of-three), with at least one real caller in current scope.
  • For config/schema changes, treat keys as public contract: document defaults, compatibility impact, and migration/rollback path.

7) Change Playbooks

7.1 Adding a Provider

  • Implement Provider in src/providers/.
  • Register in src/providers/mod.rs factory.
  • Add focused tests for factory wiring and error paths.
  • Avoid provider-specific behavior leaks into shared orchestration code.

7.2 Adding a Channel

  • Implement Channel in src/channels/.
  • Keep send, listen, health_check, typing semantics consistent.
  • Cover auth/allowlist/health behavior with tests.

7.3 Adding a Tool

  • Implement Tool in src/tools/ with strict parameter schema.
  • Validate and sanitize all inputs.
  • Return structured ToolResult; avoid panics in runtime path.

5.4 Adding a Peripheral

  • Implement Peripheral in src/peripherals/.
  • Peripherals expose tools() — each tool delegates to the hardware (GPIO, sensors, etc.).
  • Register board type in config schema if needed.
  • See docs/hardware-peripherals-design.md for protocol and firmware notes.

5.5 Security / Runtime / Gateway Changes

  • Include threat/risk notes and rollback strategy.
  • Add/update tests or validation evidence for failure modes and boundaries.
  • Keep observability useful but non-sensitive.
  • For .github/workflows/** changes, include Actions allowlist impact in PR notes and update docs/actions-source-policy.md when sources change.

8) Validation Matrix

Default local checks for code changes:

cargo fmt --all -- --check
cargo clippy --all-targets -- -D warnings
cargo test

Preferred local pre-PR validation path (recommended, not required):

./dev/ci.sh all

Notes:

  • Local Docker-based CI is strongly recommended when Docker is available.
  • Contributors are not blocked from opening a PR if local Docker CI is unavailable; in that case run the most relevant native checks and document what was run.

Additional expectations by change type:

  • Docs/template-only: run markdown lint and relevant doc checks.
  • Workflow changes: validate YAML syntax; run workflow lint/sanity checks when available.
  • Security/runtime/gateway/tools: include at least one boundary/failure-mode validation.

If full checks are impractical, run the most relevant subset and document what was skipped and why.

9) Collaboration and PR Discipline

  • Follow .github/pull_request_template.md fully (including side effects / blast radius).
  • Keep PR descriptions concrete: problem, change, non-goals, risk, rollback.
  • Use conventional commit titles.
  • Prefer small PRs (size: XS/S/M) when possible.
  • Agent-assisted PRs are welcome, but contributors remain accountable for understanding what their code will do.

9.1 Privacy/Sensitive Data and Neutral Wording (Required)

Treat privacy and neutrality as merge gates, not best-effort guidelines.

  • Never commit personal or sensitive data in code, docs, tests, fixtures, snapshots, logs, examples, or commit messages.
  • Prohibited data includes (non-exhaustive): real names, personal emails, phone numbers, addresses, access tokens, API keys, credentials, IDs, and private URLs.
  • Use neutral project-scoped placeholders (for example: user_a, test_user, project_bot, example.com) instead of real identity data.
  • Test names/messages/fixtures must be impersonal and system-focused; avoid first-person or identity-specific language.
  • If identity-like context is unavoidable, use ZeroClaw-scoped roles/labels only (for example: ZeroClawAgent, ZeroClawOperator, zeroclaw_user) and avoid real-world personas.
  • Recommended identity-safe naming palette (use when identity-like context is required):
    • actor labels: ZeroClawAgent, ZeroClawOperator, ZeroClawMaintainer, zeroclaw_user
    • service/runtime labels: zeroclaw_bot, zeroclaw_service, zeroclaw_runtime, zeroclaw_node
    • environment labels: zeroclaw_project, zeroclaw_workspace, zeroclaw_channel
  • If reproducing external incidents, redact and anonymize all payloads before committing.
  • Before push, review git diff --cached specifically for accidental sensitive strings and identity leakage.

9.2 Superseded-PR Attribution (Required)

When a PR supersedes another contributor's PR and carries forward substantive code or design decisions, preserve authorship explicitly.

  • In the integrating commit message, add one Co-authored-by: Name <email> trailer per superseded contributor whose work is materially incorporated.
  • Use a GitHub-recognized email (<login@users.noreply.github.com> or the contributor's verified commit email) so attribution is rendered correctly.
  • Keep trailers on their own lines after a blank line at commit-message end; never encode them as escaped \\n text.
  • In the PR body, list superseded PR links and briefly state what was incorporated from each.
  • If no actual code/design was incorporated (only inspiration), do not use Co-authored-by; give credit in PR notes instead.

When superseding multiple PRs, use a consistent title/body structure to reduce reviewer ambiguity.

  • Recommended title format: feat(<scope>): unify and supersede #<pr_a>, #<pr_b> [and #<pr_n>]
  • If this is docs/chore/meta only, keep the same supersede suffix and use the appropriate conventional-commit type.
  • In the PR body, include the following template (fill placeholders, remove non-applicable lines):
## Supersedes
- #<pr_a> by @<author_a>
- #<pr_b> by @<author_b>
- #<pr_n> by @<author_n>

## Integrated Scope
- From #<pr_a>: <what was materially incorporated>
- From #<pr_b>: <what was materially incorporated>
- From #<pr_n>: <what was materially incorporated>

## Attribution
- Co-authored-by trailers added for materially incorporated contributors: Yes/No
- If No, explain why (for example: no direct code/design carry-over)

## Non-goals
- <explicitly list what was not carried over>

## Risk and Rollback
- Risk: <summary>
- Rollback: <revert commit/PR strategy>

When a commit unifies or supersedes prior PR work, use a deterministic commit message layout so attribution is machine-parsed and reviewer-friendly.

  • Keep one blank line between message sections, and exactly one blank line before trailer lines.
  • Keep each trailer on its own line; do not wrap, indent, or encode as escaped \n text.
  • Add one Co-authored-by trailer per materially incorporated contributor, using GitHub-recognized email.
  • If no direct code/design is carried over, omit Co-authored-by and explain attribution in the PR body instead.
feat(<scope>): unify and supersede #<pr_a>, #<pr_b> [and #<pr_n>]

<one-paragraph summary of integrated outcome>

Supersedes:
- #<pr_a> by @<author_a>
- #<pr_b> by @<author_b>
- #<pr_n> by @<author_n>

Integrated scope:
- <subsystem_or_feature_a>: from #<pr_x>
- <subsystem_or_feature_b>: from #<pr_y>

Co-authored-by: <Name A> <login_a@users.noreply.github.com>
Co-authored-by: <Name B> <login_b@users.noreply.github.com>

Reference docs:

  • CONTRIBUTING.md
  • docs/pr-workflow.md
  • docs/reviewer-playbook.md
  • docs/ci-map.md
  • docs/actions-source-policy.md

10) Anti-Patterns (Do Not)

  • Do not add heavy dependencies for minor convenience.
  • Do not silently weaken security policy or access constraints.
  • Do not add speculative config/feature flags “just in case”.
  • Do not mix massive formatting-only changes with functional changes.
  • Do not modify unrelated modules “while here”.
  • Do not bypass failing checks without explicit explanation.
  • Do not hide behavior-changing side effects in refactor commits.
  • Do not include personal identity or sensitive information in test data, examples, docs, or commits.

11) Handoff Template (Agent -> Agent / Maintainer)

When handing off work, include:

  1. What changed
  2. What did not change
  3. Validation run and results
  4. Remaining risks / unknowns
  5. Next recommended action

12) Vibe Coding Guardrails

When working in fast iterative mode:

  • Keep each iteration reversible (small commits, clear rollback).
  • Validate assumptions with code search before implementing.
  • Prefer deterministic behavior over clever shortcuts.
  • Do not “ship and hope” on security-sensitive paths.
  • If uncertain, leave a concrete TODO with verification context, not a hidden guess.