# Build Plan & Task Breakdown — Invoice Match (Agent 1)

The PRD broken into workstreams, with what landed in this first foundation commit
and what remains. The foundation is deliberately a complete, runnable skeleton:
the deterministic matching core (the heart, and the shared Pi-track core) is real
and tested; the integrations (Odoo, live model streaming) are wired and need
credentials + a confirmation pass to light up against production.

Legend: ✅ done in this commit · 🟡 scaffolded, needs creds/live verification · ⬜ follow-up

## 1. Foundation & contract
- ✅ Single-source-of-truth contract (`docs/CONTRACT.md`): schema, HTTP API, SSE events, matching spec, config.
- ✅ Docker Compose project: `web` (nginx), `app` (CI4), `service` (FastAPI), `mysql` — private network, single published port, shared `uploads` volume.
- ✅ `.env.example`, `.gitignore`, nginx config.

## 2. Database & migrations (MySQL, CI4-owned)
- ✅ Migrations for every table in CONTRACT §2: `runs`, `planned_lines`, `invoices`, `results`, `name_map`, `memory_rules`, `traces`, `connections`.
- ✅ Shield auth tables via the Shield package migrations.
- ✅ Seeder: initial admin, a few `name_map` rows, secret-reference `connections` rows.

## 3. Deterministic matching core (`service/app/matching/`) — the heart
- ✅ `sheet_parser.py`: parses the `projects` tab, rows 1–138, name=B, value=F, month located by header date; skips subtotal/label/blank/zero rows.
- ✅ `candidates.py` (`get_candidates`) + `variance.py` (`variance`): read-only, deterministic tools.
- ✅ `classifier.py`: three-tier decision (deterministic green/red → agent amber residue → reverse billed-unplanned), memory-rule aware, VAT-exclusive.
- ✅ Pure (openpyxl + stdlib only) → offline unit tests + offline runner.
- 🟡 Tune the exact tolerance/rounding once Jaco confirms (open question 4).

## 4. Agent runtime (`service/app/agent/`) — Strands
- ✅ Provider selection (bedrock/anthropic/openai), temperature pinned to 0.
- ✅ Orchestrator + parallel worker adjudicators over the residue; read-only tools only, no writer tool.
- 🟡 Live model adjudication needs provider credentials to run end-to-end; deterministic path runs today without a model.

## 5. Odoo integration (`service/app/odoo/`)
- ✅ Read-only client interface; native JSON-RPC implementation against `account.move` (posted + sent, invoice_date in month, Software-filtered), amount_untaxed as the matched figure.
- 🟡 Needs a read-only Odoo account + confirmation of the Software-invoice rule (open question 1) and REST flavour (open question 2).

## 6. PHP UI (`app/`) — CodeIgniter 4 + Shield
- ✅ Shield login; WhatsApp-style left rail of past runs + conversation pane.
- ✅ Composer (upload Excel, pick provider, Run) with auto-start-on-upload and auto-play of the Strands flow via SSE (EventSource).
- ✅ Live agent-activity roster; result view with green/amber/red summary + variance table.
- ✅ Report Excel download (PhpSpreadsheet), colour-coded.
- ✅ Memory screen + inline confirm/correct feeding `name_map` / `memory_rules`.

## 7. Observability (`service/app/telemetry/`)
- ✅ OpenTelemetry span emission for the agent loop; spans persisted to `traces` and streamed as `flow.span` SSE events; no-op when disabled.
- ⬜ Bake-off comparison dataset view (cost/latency/tokens, run-to-run stability) — reads `traces`, a reporting follow-up.

## 8. Testing
- ✅ Self-contained pytest suite for the matching core.
- ✅ Offline end-to-end runner (`python -m app.runner --offline …`) over the sample workbook, exercising green/amber/red/billed-unplanned.
- ⬜ PHP feature tests (CI4) + a browser smoke test once a provider/Odoo sandbox is available.

## Follow-up workstreams (post-foundation)
1. Wire a read-only Odoo sandbox account; confirm the Software-invoice rule and REST flavour; verify invoice pull end-to-end.
2. Provider credentials (Anthropic / OpenAI / Bedrock); run the agent tier live and capture the first bake-off traces.
3. Two-month parallel trial against the manual recon; measure the ≥95% match rate and the zero-false-green bar; feed corrections into memory.
4. Bake-off comparison dashboard over `traces` (cost/latency/tokens) and the Pi-track run of the shared core.
5. Harden: CI pipeline, PHP feature/browser tests, backup/retention policy on the uploads volume.

## Open questions (defaults chosen, see CONTRACT §7)
1. Exact Odoo "Software invoice" rule (journal / category / analytic). Default: journal "Software".
2. Odoo REST flavour: native JSON-RPC vs OCA REST. Default: JSON-RPC.
3. Unresolved client fallback: stay amber vs fuzzy-suggest. Default: stay amber (never a silent guess).
4. Green/amber amount delta + rounding. Default: max(R1.00, 0.5%), 2 decimals.
