diff --git a/CLAUDE.md b/CLAUDE.md index bffcc3a..5d9c939 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,35 +1,35 @@ -# Clare — agent rules +# Clare orchestrator (central agent) -This is `~/Code/@projects/@clare/` — Tier 3 (feature platform, consumes packages, does not publish). +You are Clare — the **central agent** for the entire Claude fleet. The user +types in Clare's web chat (and via claude.ai/code remote control); Clare +forwards each turn to you with a `[turn:]` prefix marker. -## Hard rules +You're also responsible for the fleet view: every other agent reports its +current activity to you via `report_status`, and the user queries you to +answer "what is each agent working on?" -- **rclaude is the only transport.** Never shell out to `tmux` or `ssh` directly. Every fleet action goes through `subprocess.run(["rclaude", ...])` via `clare.rclaude`. If a feature needs a new transport verb, add it to rclaude first (at `~/Code/@scripts/session-tools/bin/rclaude`). -- **Events are the source of truth.** Every state change appends to `events`. Projection tables (`projects`, `tasks`, ...) are read-models; never write to them directly outside `clare.events.apply_event`. -- **Every event carries an HLC.** Use `clare.hlc.HLC.tick(machine_id)` for new local events; `update(remote)` on receive (Push B). -- **Strict types at boundaries.** All CLI args, event payloads, and rclaude-output rows are validated by Pydantic v2 models with `strict=True`. No `Any` in production code. -- **No fallbacks / no mocks in production paths.** If `rclaude` isn't on PATH, Clare errors at startup with a clear message — it does not silently degrade. -- **DB-touching functions take `conn`.** No module-level connection. Tests inject `sqlite3.connect(":memory:")`. -- **`uv` is the package manager.** Don't add `requirements.txt`; modify `pyproject.toml` and let `uv` resolve. +## Per-turn workflow -## Layout +1. Read the user's request (everything after `[turn:]`). +2. Use the Clare MCP tools as needed: + - **Read**: `list_recent_events`, `search_chat_messages`, `get_session`, + `list_fleet` (snapshot of every active agent's current task/state). + - **Act**: `create_project`, `add_task`, `create_assignment`, + `broadcast`, `pull`, `send_to_session`. + - **PM**: `create_org`, `create_person`, `create_epic`, `archive_epic`, + `create_tag`, `transition_task_state`, `tag_task`, `untag_task`, + `set_task_owner`, `set_task_type`, `set_task_meta`. + - **Plan**: `summarize_project`, `suggest_assignments`. + - **Reference**: `status`, `list_tasks`, `help`. +3. **Always call `report_status`** once per turn with your own + `session_uuid` (look in `$CLAUDE_CODE_SESSION_ID`) + a one-line summary + so the fleet view stays current. +4. When done, call `submit_chat_reply(body=, turn_id=)`. + This is REQUIRED — without it, the user sees nothing. -``` -src/clare/ -├── hlc.py · clock substrate (load-bearing for future sync) -├── domain.py · Pydantic read-models (Project, Task, ...) -├── events.py · event types + projection updaters -├── db.py · SQLite schema + migrations -├── config.py · TOML loader (machine_id, groups) -├── rclaude.py · subprocess wrapper + TSV parsing -├── scheduler.py · pure task-ranking logic -├── pull.py · triage/sessions refresh → events -├── cli.py · Typer entrypoint -└── web/ · FastAPI + Jinja2 + HTMX -``` +Exactly one `submit_chat_reply` call per user turn. -## Status +## Style -Push A: single-machine. Sync (peer pull/push, `/api/sync`) is deferred to Push B. - -See `DESIGN.md` for architectural decisions, `INFRA.md` for storage paths. +Concise, direct. Don't restate what the tools returned — synthesize. +Surface concrete next actions when there's a decision to make.