# GitHub Copilot Instructions — AO

AO (Agent Ops Issues) is a high-performance append-only JSONL issue/event store with a CLI, REST API, and Kanban web UI. Python 3.12+, built with `uv`.

## Build & Test

**Always use `uv run`** — never call `python`, `pytest`, or `ao` directly.

```bash
uv run python scripts/build.py       # Full pipeline: format → lint → types → tests
uv run python scripts/build.py --fix # Auto-fix lint/format issues
uv run pytest tests/ -v              # Run tests only
uv run ao --version                 # Verify CLI works
```

Build passes when: ruff format ✅, ruff check ✅, mypy ✅, pytest ✅, coverage ≥ 75%.

## Code Standards

- **Type annotations** on ALL functions (enforced by mypy strict)
- **Google-style docstrings** on all public APIs
- `pathlib.Path` for all file operations — no `os.path`
- `msgspec.Struct` for data structures — no dataclasses or pydantic
- Max **15 lines** per function, max **3 levels** of nesting
- Line length: **100**
- `rich.console.Console` for user output — never `print()`
- Work with `bytes` throughout hot paths — no string-based JSON

## Forbidden Patterns

```python
# ❌ Wrong import path
from src.ao import X

# ✅ Correct
from ao import X
```

- No business logic in `cli.py` — thin CLI layer only
- No bare `except:` blocks
- No `print()` for output

## Architecture

```
src/ao/
├── api.py              # AOIClient — public Python API
├── models.py           # Issue, Event, etc. msgspec Structs
├── cli.py              # Typer app — thin CLI wiring only
├── _internal/          # Implementation details (not public API)
│   ├── apply.py        # Event → Issue state reducer
│   ├── commands/       # One module per CLI command group
│   ├── context.py      # AppContext (paths, settings)
│   ├── filters.py      # Query-string parser
│   ├── graph.py        # Dependency graph + cycle detection
│   ├── io.py           # JSONL read/write
│   └── output.py       # Output envelope formatting
├── store/              # Low-level JSONL store primitives
└── web/                # FastAPI Kanban UI
    ├── api/            # REST API endpoints
    ├── templates/      # Jinja2 HTML (index.html = full UI)
    └── static/         # JS/CSS assets
```

**Data model:**
- `events.jsonl` — append-only event log (source of truth, never mutated)
- `active.jsonl` — deterministic snapshot rebuilt via `ao rebuild`
- `.counter` — monotonic issue number counter

## CLI Quick Reference

Global flags go **before** the subcommand:

```bash
uv run ao --yes --format json <subcommand>   # ✅ correct
uv run ao <subcommand> --yes                  # ❌ wrong
```

Key commands:

```bash
uv run ao ls                          # List active issues (table)
uv run ao --format json ls            # JSON output
uv run ao --yes add "Title" --type feat --priority medium
uv run ao --yes set FEAT-0042@abc123 --status in_progress
uv run ao --yes close FEAT-0042@abc123 --log "Done"
uv run ao --yes log add FEAT-0042@abc123 "message"
uv run ao rebuild                     # Rebuild active.jsonl (no flags)
uv run ao issue show FEAT-0042@abc123
uv run ao link add FEAT-0042@abc123 --depends-on FEAT-0001@aaa111
uv run ao next                        # Top ready-to-work issues
uv run ao web                         # Start Kanban UI (localhost:8000)
```

Issue IDs are always the full form `TYPE-NNNN@HHHHHH` (short hash from `active.jsonl`).

## Issue Tracking

Issues are stored as JSONL events, not markdown files. The `.agent/ops/issues/` directory contains:

- `events.jsonl` — append-only log of all issue operations
- `active.jsonl` — current snapshot (rebuilt with `ao rebuild`)
- `.counter` — next issue number

**Always use the `ao` CLI** to create/update issues — never edit JSONL files directly.

## Testing Conventions

- All tests use `pytest` with `tmp_path` fixture for isolation
- **Tests must never touch the project directory** — use `tmp_path` exclusively
- Test classes: `Test<Feature>`, test functions: `test_<scenario>`
- Integration tests in `tests/integration/`
- Web tests in `tests/test_web.py` using `httpx.AsyncClient`
- Playwright E2E in `tests/integration/test_web_playwright.py`

## AO Workflow

This repo uses the AO agent protocol. Prompts are in `.github/prompts/`, agents in `.github/agents/`, skills in `.ao/skills/`. Key ops files:

- `.agent/ops/constitution.md` — project authority and constraints
- `.agent/ops/focus.json` — current iteration / next up
- `.agent/ops/memory.md` — durable learnings

Use `/ao-task` to create issues, `/ao-worker` to implement them.
