<!-- FOR AI AGENTS - Human readability is a side effect, not a goal -->
<!-- Managed by agent: keep sections and order; edit content, not structure -->
<!-- Last updated: 2026-05-06 | Last verified: 2026-05-06 -->

# AGENTS.md

**TipSharks** — Racing ratings and predictions platform. Three services in one monorepo.

**Precedence:** the **closest `AGENTS.md`** to the files you're changing wins. Root holds global defaults only.

## Project Overview

| Service | Directory | Stack | Purpose |
|---------|-----------|-------|---------|
| tab-api-ingest | `tab-api-ingest/` | TypeScript, Express, Prisma, BullMQ, Redis | Near-realtime horse racing data ingestion from TAB/HRNZ APIs |
| tipsharks-elo-api | `tipsharks-elo-api/` | Python 3.12+, FastAPI, SQLAlchemy, PostgreSQL | Elo-style multi-entity ratings engine + REST API + Web UI |
| tipsharks-client | `tipsharks-client/` | React Native (Expo), TypeScript, FastAPI, MongoDB | Mobile racing tips app (thoroughbred, harness, greyhound) |

All services consume racing data and feed into the TipSharks ratings platform.

## Index of scoped AGENTS.md
<!-- AGENTS-GENERATED:START scope-index -->
| Directory | AGENTS.md | Stack |
|-----------|-----------|-------|
| `tab-api-ingest/` | [tab-api-ingest/AGENTS.md](tab-api-ingest/AGENTS.md) | TypeScript/Node.js |
| `tipsharks-elo-api/` | [tipsharks-elo-api/AGENTS.md](tipsharks-elo-api/AGENTS.md) | Python/FastAPI |
| `tipsharks-client/` | [tipsharks-client/AGENTS.md](tipsharks-client/AGENTS.md) | React Native/Expo + Python/FastAPI |
<!-- AGENTS-GENERATED:END scope-index -->

> **Agents**: When you read or edit files in a listed directory, you **must** load its AGENTS.md first. It contains directory-specific conventions that override this root file.

## Response Style
- Answer first, elaborate only if needed. No sycophantic openers.
- For yes/no or status questions, lead with the answer.
- Skip preamble. Match response length to task complexity.

## Workflow
1. **Before coding**: Read nearest `AGENTS.md` + check Golden Samples for the area you're touching
2. **After each change**: Run the smallest relevant check (lint → typecheck → single test)
3. **Before committing**: Run full test suite if changes affect >2 files or touch shared code
4. **Before claiming done**: Run verification and **show output as evidence**

## Boundaries

### Always Do
- Run pre-commit checks before committing
- Add tests for new code paths
- Use conventional commit format: `type(scope): subject`
- Use **atomic commits** (one logical change per commit)
- **Show test output as evidence before claiming work is complete**
- Before any edit, verify `pwd` resolves inside the intended repo worktree
- Force-push only with `--force-with-lease`

### Ask First
- Adding new dependencies
- Modifying CI/CD configuration
- Changing public API signatures
- Running full e2e test suites
- Repo-wide refactoring or rewrites

### Never Do
- Commit secrets, credentials, or sensitive data
- Modify `node_modules/` or generated files
- Push directly to main/master branch — open a PR
- Delete migration files or schema changes
- Use `secrets: inherit` in reusable GitHub Actions workflows

## File Map
<!-- AGENTS-GENERATED:START filemap -->
```
tipsharks/
├── tab-api-ingest/          # TypeScript data ingestion service
│   ├── src/                 # Source code
│   ├── prisma/              # Database schema + migrations
│   ├── scripts/             # Utility scripts
│   ├── docs/                # Documentation
│   ├── grafana/             # Monitoring dashboards
│   └── package.json         # npm scripts + dependencies
├── tipsharks-elo-api/       # Python ratings engine + API
│   ├── apps/                # Application entry points (api, web, worker)
│   ├── packages/            # Shared libraries (common, tab_client, ratings, storage, hrnz_scraper)
│   ├── tests/               # Test suite
│   ├── scripts/             # Standalone utilities (evaluate.py)
│   ├── docs/                # Documentation (architecture, data model, rating math, ops)
│   ├── infrastructure/      # Deployment configs
│   └── pyproject.toml       # Python project config
├── tipsharks-client/        # React Native mobile app + backend
│   ├── frontend/            # Expo/React Native app
│   │   ├── app/             # Expo Router screens
│   │   ├── src/             # Components, services, store, types
│   │   └── package.json     # npm/yarn scripts + dependencies
│   ├── backend/             # FastAPI + MongoDB backend
│   │   └── server.py        # API endpoints + mock data
│   └── tests/               # Test suite
└── AGENTS.md                # This file
```
<!-- AGENTS-GENERATED:END filemap -->

## Terminology
| Term | Means |
|------|-------|
| TAB | Totalisator Agency Board — Australian/NZ betting operator providing racing data API |
| HRNZ | Harness Racing New Zealand — source for additional racing data |
| Elo | Rating system adapted for multi-runner horse racing |
| Ingestion | Process of fetching and storing racing data from external APIs |
| Recompute | Batch recalculation of all ratings from historical data |
| Starter | A horse/driver/trainer combination entered in a race |

## When instructions conflict
The nearest `AGENTS.md` wins. Explicit user prompts override files.
