# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Principles

`PRINCIPLES.md` at the repo root carries the four Corviduo engineering
principles (Excellence over uniqueness · Explicit over implicit ·
Elegance is a byproduct · Action-relevance over thoroughness). These
are *what to optimize for* across all work — distinct from this file's
behavioral guidelines (*how to operate session-to-session*) and the
workflow mechanics below (*project-level mechanics*). The principles
also live at `~/.claude/CLAUDE.md` § Core principles; this repo copy
is the load-bearing version when human contributors or non-Claude-Code
AI tooling read the codebase.

## Canonical Corviduo specifications

This project depends on cross-cutting Corviduo specifications that
live canonically at `~/development/corviduo-project-template/` (the
spec-stewardship repository, Brokkr-managed as of 2026-05-15). When
this file is read inside the template repository itself, the
canonicals live here directly; when seeded into a derivative project,
pinned copies of the canonicals live in the derivative.

### What lives canonically in the template

| Spec | Canonical path | Covers |
|---|---|---|
| `CONTRACT-FORMAT.md` | `docs/contracts/CONTRACT-FORMAT.md` | Format spec for `.contract.md` files (v2.x). |
| `contract_parser.py` | `docs/contracts/contract_parser.py` | Validator/extractor for `.contract.md`. Python ≥3.11, stdlib only. |
| `contract_drift_check.py` | `scripts/contract_drift_check.py` | Verifies issue-scoped contracts' `prd:` block hashes match live tracker state. |
| `PRINCIPLES.md` | `PRINCIPLES.md` | Four engineering principles. |
| `methodology.md` | `docs/methodology.md` | The Corviduo preferred development pipeline ((optional) Vor → (required) Contract → branch (direct or AFK TDD) → verify → merge/commit). |
| `PRACTICES.md` | (to migrate from `galdrabok/conventions/`) | Engineering practices (contract-first, TDD, no-backwards-compat, atomic commits). |
| `CONTEXT-FORMAT.md` | (to migrate from `galdrabok/conventions/`) | Format spec for `CONTEXT.md` glossary files. |
| `ADR-FORMAT.md` | (to migrate from `galdrabok/conventions/`) | Format spec for Architecture Decision Records. |

### What to seed into a new project, by stack

When you seed a new Corviduo project from this template, copy the
canonical files that apply to your target stack. The drift-check
mechanism (below) keeps consumer copies in sync as canonicals evolve.

**Every project (cross-language baseline):**

- `CONTRACT-FORMAT.md`, `PRINCIPLES.md`, `PRACTICES.md` — applies
  regardless of implementation language.
- `contract_parser.py`, `contract_drift_check.py` — Python
  meta-tooling. Invoke via `uv run python scripts/...` in non-Python
  projects.

**Python projects** (Worldtree, Sleipnir, Brokkr-Smithy, Skaldsong,
Vor backend):

- All baseline files.
- `env.sh.template` (Python-shape: `PYTHONPATH`, uv-managed venv
  expectations).
- `.gitignore` (Python-shape: `__pycache__/`, `.venv/`, ruff /
  mypy / pytest / uv caches).
- **Preferred tooling**: `uv` exclusively (`uv venv`, `uv pip
  install`, `uv run`, `uv tool install`). Ruff for lint. Mypy for
  types. Pytest for tests. No `pip` / `pipx` / `poetry` unless
  the project clearly already uses something else.

**TypeScript / Bun projects** (Mead Hall, Vor UI, future client
apps):

- All baseline files. `CONTRACT-FORMAT.md` applies cross-language —
  `.contract.md` files describe code regardless of implementation
  language.
- `env.sh.template` (TS/Bun-shape: project-name-uppercase root,
  per-app env vars, no Python venv references).
- `.gitignore` (TS/Bun-shape: `node_modules/`, `dist/`,
  `bun.lockb` is committed; no Python caches).
- **Preferred tooling**: Bun exclusively (no npm / yarn / pnpm).
  Bun's native bundler. Bun's native test runner (`bun test`).
  TypeScript strict mode. React + Vite for UI projects where
  applicable.

**Mixed-stack projects** (Python backend + TypeScript frontend in
one repo): take both stacks' files; document which directory is
which in `docs/architecture.md`.

### Keeping canonicals in sync

Two tools at `scripts/` handle drift detection and sync for
cross-cutting Corviduo canonicals. Both Python ≥3.11 stdlib-only;
invoke via `uv run python scripts/...` in non-Python projects.

- **`scripts/canonical_sync.py`** — operator-triggered. Fetches each
  pinned canonical from `~/development/<canonical_source>/<canonical_path>`,
  writes the consumer copy, bumps the pin's `pinned_sha256_16` +
  `pinned_at` in the manifest. Reports per-pin: `OK` / `SYNCED` /
  `WOULD` (dry-run) / `ERROR`. Run after the architect broadcasts a
  canonical update on althing.
- **`scripts/canonical_drift.py`** — read-only verifier suitable for
  CI gating. Detects drift between pinned canonicals and their
  sources, and consumer-copy divergence from the pinned hash. Exits
  non-zero on staleness, divergence, or missing canonical.

Each consumer carries a `.corviduo-canonicals.toml` manifest at the
repo root pinning each canonical:

```toml
[[pins]]
id = "contract-format-v2"
canonical_source = "corviduo-project-template"
canonical_path = "docs/contracts/CONTRACT-FORMAT.md"
consumer_path = "docs/contracts/CONTRACT-FORMAT.md"
pinned_sha256_16 = "..."
pinned_at = "2026-05-15T..."
```

The pattern generalises beyond template-only canonicals. Same shape
handles Worldtree's `conversation-api-client-spec-v2.md`, Bifrost's
protocol spec, and any future cross-cutting canonical — set
`canonical_source` to whichever `~/development/<repo>/` directory
hosts the truth.

Optional per-pin `tolerate_drift = true` makes `canonical_drift.py`
warn-only for that pin when `--allow-warn` is set (useful for pins
the consumer deliberately allows to lag).

## Persistent memory

`persistent-memory.md` at the repo root captures durable intent and
supporting evidence (goals, decisions, foot-gun warnings, in-flight
state) across context resets. Read it at session start; treat it as
one input alongside this CLAUDE.md and the auto-memory system, not
as the single source of truth. When durable state shifts enough to
warrant capture, run `/snapshot` and commit alongside the next commit.

## Architecture map

`docs/architecture.md` is the top-level module map (dependency graph,
session-load boundaries, execution order). Each core module gets its own
`CLAUDE.md` at `core/{module}/CLAUDE.md` once it grows past trivial.
When a development session focuses on one module, load that module's
`CLAUDE.md` plus the stable-infrastructure dependencies listed there.

## BEHAVIORAL GUIDELINES

**Tradeoff:** These guidelines bias toward caution over speed. For trivial tasks, use judgment.

### 1. Think Before Coding

**Don't assume. Don't hide confusion. Surface tradeoffs.**

Before implementing:
- State your assumptions explicitly. If uncertain, ask.
- If multiple interpretations exist, present them — don't pick silently.
- If a simpler approach exists, say so. Push back when warranted.
- If something is unclear, stop. Name what's confusing. Ask.

### 2. Simplicity First

**Minimum code that solves the problem. Nothing speculative.**

- No features beyond what was asked.
- No abstractions for single-use code.
- No "flexibility" or "configurability" that wasn't requested.
- No error handling for impossible scenarios.
- If you write 200 lines and it could be 50, rewrite it.

Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify.

### 3. Surgical Changes

**Touch only what you must. Clean up only your own mess.**

When editing existing code:
- Don't "improve" adjacent code, comments, or formatting.
- Don't refactor things that aren't broken.
- Match existing style, even if you'd do it differently.
- If you notice unrelated dead code, mention it — don't delete it.

When your changes create orphans:
- Remove imports/variables/functions that YOUR changes made unused.
- Don't remove pre-existing dead code unless asked.

The test: Every changed line should trace directly to the user's request.

### 4. Goal-Driven Execution

**Define success criteria. Loop until verified.**

Transform tasks into verifiable goals:
- "Add validation" → "Write tests for invalid inputs, then make them pass"
- "Fix the bug" → "Write a test that reproduces it, then make it pass"
- "Refactor X" → "Ensure tests pass before and after"

For multi-step tasks, state a brief plan:
```
1. [Step] → verify: [check]
2. [Step] → verify: [check]
3. [Step] → verify: [check]
```

Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification.

---

## Project conventions

### Naming hierarchy

```
Corviduo.ai          (company)
└─ ratatoskr  (project / repo — this codebase)
   └─ ...            (modules, agents, components — fill in as the project grows)
```

Sibling Corviduo projects: `Worldtree` (multi-agent framework), `Skaldsong` (story-generation engine), `vastai-app` (Vast Blue SEA — multi-agent web app), `sleipnir` (AFK orchestrator), `Vor` (pre-contract design partner UI), `Galdrabok` (Sleipnir-preflight skill author), `task-board` (per-session web UI), `althing`.

Norse / Germanic naming convention is the house style for Corviduo projects. Module and agent names follow the same vein.

### No backwards compatibility until v1.x

This project is pre-release. When something is redesigned, everything gets updated and everything old gets ripped out. **No shims, no compat layers, no deprecation periods.** If a new approach replaces an old one, the old code is deleted and all references are updated in the same commit. This keeps the codebase clean and avoids accumulating dead paths.

### Contract-first workflow

Contracts at `docs/contracts/` are machine-parseable architectural pseudocode specs. They serve as unambiguous work specifications: a planning pass writes the contract, then the implementation pass translates it to code, then an audit pass verifies compliance.

**Workflow: contracts come before code.** When implementing a new module or making non-trivial changes to an existing one, write or update the `.contract.md` file first. The contract captures function signatures, preconditions, postconditions, error handling, steps, and invariants — settling design questions before writing code. Contracts are not documentation of existing code; they are the source of truth that code is written to satisfy.

- Format spec: [`docs/contracts/CONTRACT-FORMAT.md`](docs/contracts/CONTRACT-FORMAT.md) (v2.1 is current; v2.0 and v1 contracts remain accepted)
- Parser: [`docs/contracts/contract_parser.py`](docs/contracts/contract_parser.py) — `--validate` checks required fields; `--list` shows function signatures; `--dir` batch processes
- Drift checker: [`scripts/contract_drift_check.py`](scripts/contract_drift_check.py) — verifies issue-scoped contracts' `prd:` block hashes match the live tracker state
- File convention: `docs/contracts/{module_name}.contract.md` for module contracts; `docs/contracts/issues/{N}.contract.md` for issue-scoped contracts

When to write a contract:
- **New module** — always write a contract before implementation
- **Complex changes** — new function blocks, new error handling, new state transitions
- **Cross-module interfaces** — when the change affects `depends_on` / `used_by` relationships

When a contract is not needed:
- Bug fixes that don't change function signatures or behavior
- Trivial helpers, one-liners, config changes
- Documentation-only changes

### Issue → AFK dispatch hygiene (Sleipnir)

Before marking any issue `ready-for-agent` (the label that gates AFK
dispatch via Sleipnir), it MUST have an issue-numbered contract at
`docs/contracts/issues/<N>.contract.md` AND that contract MUST carry
a `prd:` block in its YAML frontmatter pinning it to:

- the issue body (SHA-256, first 16 hex chars)
- the lock-in comment id + content SHA (or `null` if the issue body
  alone is the spec)
- a `pinned_at` timestamp

This is hard policy, not a suggestion. Without the contract Sleipnir's
gate refuses dispatch with `blocked-needs-contract`. Without the `prd:`
block PRD-↔-ship drift becomes invisible — the audit infrastructure
that detects it is a no-op.

Verify before applying the label:

- contract file exists at the expected path
- frontmatter has a populated `prd:` block
- `python scripts/contract_drift_check.py --contract <path>` returns clean

The full convention — frontmatter shape, required fields, reasoning
behind the four drift entry points — lives in
[`docs/contracts/CONTRACT-FORMAT.md`](docs/contracts/CONTRACT-FORMAT.md).

### TDD development cycle

Contract → failing test → minimal code to pass → run test. Tests written
before/alongside code, never deferred. Vertical slices (tracer bullet first,
then incremental loop), not horizontal slices (don't write all tests then all
code — that produces tests of *imagined* behavior).

### Persistent-memory + housekeeping commit-along rule

When committing changes, also commit `persistent-memory.md` if it's dirty.
Same applies to housekeeping files (`HANDOFF-SUMMARY.md`, `NEXT-STEPS.md`,
`README.md`, `State-Of-Development.md`) where they exist. The repo state
should always be coherent across these files at every commit.

---

## Tooling conventions

### Issues

For Worldtree-and-friends Gitea-tracked issues, prefer `python -m core.issues`
(the project's own CLI wrapping the Gitea API) over `gh` or `tea`. Until
this project grows its own `core/issues/` adapter, fall back to `tea`
(local Gitea CLI at `/usr/local/bin/tea`, v0.14.0) for simple operations.

### Tea CLI

`tea` is the local Gitea CLI. Use for PRs, releases, branch/repo ops. For
issues prefer `python -m core.issues` when it exists. **Note:**
`tea issues edit <N> --add-labels <label>` is the bucket-2 ergonomic
(client-side add-semantics, doesn't clobber other labels) — Gitea's HTTP
label endpoint is replace-semantics. For comment-edits, use direct HTTP
against the Gitea API (`tea` v0.14.0 has no comment-edit subcommand).

### Sleipnir AFK orchestration

If this project uses Sleipnir for AFK dispatch:
- `~/.config/sleipnir/config.yaml` carries user-global config
- `.sleipnir/config.yaml` (this repo) carries per-project overrides; gitignored per-checkout
- Default convention: `dispatch.dependency_aware: true` for INV-029 dependency-aware dispatch
- Skills: `/sleipnir-scaffold <N>` to bootstrap a contract; `/sleipnir-preflight <N>` to apply `ready-for-agent`

### Task-board status reporting

If the user runs the task-board plugin, the session card on the web UI shows
at-a-glance status. The plugin's auto-hook fires `task_update` on
UserPromptSubmit and `task_wait` on Stop. You should also call `task_start`
and `task_update` proactively to set what the session is working on:

- **`task_start`** — at the start of a distinct piece of work (new feature,
  investigation, phase, bug hunt). Sets the card's activity subheader.
- **`task_update`** — at mid-task inflection points (issue filed/closed,
  branch merged, QA verdict, blocker hit, milestone). One per inflection.
- **`task_set_shells`** — when starting a `Bash run_in_background: true`,
  pass an array of one short description per *currently active* background
  shell. Update when shells finish; clear with `[]` when the last completes.

**SID derivation** (post-v0.1.5):

```bash
SID="$(cat "${XDG_CACHE_HOME:-$HOME/.cache}/claude-task-board/$(basename "$PWD").sid" 2>/dev/null)"
LABEL="${TASK_BOARD_SESSION:-$(basename "$PWD")}"
```

If `$SID` is empty (no hook has fired yet this Claude Code restart),
**skip the explicit task-board call for this turn**. Subsequent turns
can call freely. Re-derive at the start of every turn — do NOT cache.
Do NOT fall back to JSONL-mtime guess (that was the source of duplicate-
card bugs).

---

## Project Overview

_Author this section once the project's purpose, modules, and conventions
solidify. Mirror the shape of `Worldtree/CLAUDE.md` § Project Overview when
the project grows enough surface to need module-level documentation._

### What this project does

_TODO — one paragraph._

### Module structure

_TODO — once modules exist, list them here with one-line descriptions._

### Development setup

_TODO — typical pattern: `source .venv/bin/activate && source env.sh` before
running anything. Mirror Worldtree's pattern when relevant._

---

## Development Notes

- **No backward compatibility until v1.x** (see above).
- **Contracts before code** for non-trivial work (see above).
- **Persistent-memory + housekeeping commit-along** (see above).
- The `.gitignore` is configured for Python projects using tools like
  ruff, pytest, mypy, and uv/poetry/pdm. Adjust if this is not a Python
  project.
- Build, lint, and test commands will be documented here as the project
  grows.
