Files
so-many-crows/README.md
T
SmokeyandClaude Opus 5.5 a89157803b Add web UI with Smokey's crow as the stand-in mascot
- ui/: Vite + plain TypeScript, builds into ./web for `crows serve`
- CrowView mirrors CrowModel in RIVE_CONTRACT.md (pose, trust,
  reactions) so the .riv can replace the SVG later
- Event handling follows the contract's mapping table; server text
  is only ever inserted as text
- Prank: toast plus a send-button cooldown countdown
- art/crow.svg: source art for Rive import

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UQnSw4RRWp8uqpj3nsnnXF
2026-10-27 11:44:54 -06:00

79 lines
3.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# So Many Crows
A flock of AI agents. Hand it a todo list; a Sentry crow triages each item, crows fly, and trust is earned over time.
Version one: command-line, text-only crows. No web, files, or APIs until each has guardrails.
## Run
```
go build -o crows .
./crows run todo.txt # offline mock brain (no key needed)
ANTHROPIC_API_KEY=... ./crows run todo.txt # real crows (Claude)
./crows trust # trust ledger
./crows log -n 20 # flight log
```
Optional: `CROWS_MODEL` overrides the model. Results land in `todo.crows.md`; state lives in `.crows/`.
## Web server
```
cd ui && npm install && npm run build && cd .. # builds the UI into ./web
./crows serve # localhost:8080; API + Server-Sent Events (SSE); Ctrl-C to stop
```
The server runs the same pipeline as `crows run`, but items fly in parallel and approvals come over HTTP. `EVENTS.md` is the contract for events and the API:
```
curl -XPOST localhost:8080/api/lists -d '{"text":"- [ ] What is a crow","requester":"me"}'
curl -N "localhost:8080/api/events?list_id=<id>" # replays the list's events so far, then streams
curl -XPOST localhost:8080/api/verdicts -d '{"item_id":"<id>-1","target":"triage","approve":true}'
curl localhost:8080/api/trust
```
- Item IDs are `<list_id>-<n>`, numbered from 1 in list order.
- Approvals left unanswered for 10 minutes count as rejected (`verdict: timeout`). `-approval-timeout` changes this for testing.
- A flooding requester gets 429 with `message` and `cooldown_s`; any list of theirs that is still flying also gets `requester.pranked`.
- UI development: run `crows serve`, then `cd ui && npm run dev` (Vite proxies `/api`). The crow art is `art/crow.svg`; the UI's `CrowView` mirrors `RIVE_CONTRACT.md`, so a Rive-backed view replaces the SVG stand-in later.
- POST bodies are capped at 64 KB. Static files are served from `./web` when that folder exists.
## How an item flies
1. **Sentry** classifies it: `solo` (one crow), `split` (2–4 subtasks in parallel), or `murder` (3 crows answer independently).
2. Split and murder results go to the **Elder**, who merges them and flags disagreement.
3. You approve or reject, depending on trust.
## Trust ladder
| Level | Triage | Output |
|----------|-------------------|--------------------------------|
| Stranger | you approve | you approve |
| Regular | you approve | auto-accepted, marked unreviewed |
| Trusted | runs on its own | runs on its own |
- Promotion: 10 clean approvals in a row (the flock as a whole needs 20).
- Demotion: one rejection drops a level.
- A crow's level blends its own record with the flock's record for that task type, so new crows start on the flock's reputation.
- The Sentry earns triage trust separately, per task type.
- The least-trusted crow on a job sets the approval bar.
## Guardrails (`guardrails.go`)
| Guardrail | Default |
|---|---|
| Crows in flight | 5 |
| Murder size | 3 |
| Items per list | 20 |
| Subtasks per split (depth 1, never re-split) | 4 |
| Tokens per item / per list | 20,000 / 100,000 |
| Crow timeout | 60s |
| Requests per minute per requester | 5 |
| Cooldown | 30s, doubling per strike, max 1h |
Fail-safe: any answer other than `y`, including no input, is a no.
## Abuse
Flooding the flock earns a mild prank message and a cooldown. Strikes fade one per clean day. Nothing destructive, nothing public.