$npx -y skills add AgamiAI/agami-core --skill agami-reconcileReconciles known (label, expected_value) numbers from an existing dashboard against agami's answers. Input can be a SCREENSHOT of a Metabase / Power BI / Tableau / Looker dashboard (Claude's vision extracts the pairs), a CSV, or numbers pasted inline — the user doesn't need to kn
| 1 | # agami reconcile |
| 2 | |
| 3 | You are running the reconciliation harness. Goal: take labeled numbers from an existing dashboard (Tableau / Looker / Mode / Metabase / Power BI / spreadsheet) — most often a **screenshot**, sometimes a CSV or pasted list — and prove agami can reproduce each number. When numbers match, that's evidence the semantic model is right. When they don't, the receipt drill-down explains why — typically a definitional disagreement (gross vs net, refunds in vs out, FX rate at booking vs reporting date) — which is exactly the trust signal that makes a DE relax. |
| 4 | |
| 5 | This skill orchestrates: |
| 6 | |
| 7 | 1. **Extract** the `(label, expected_value)` pairs from the input — a dashboard screenshot (via vision, confirmed with the user), a CSV, or a pasted list. Number parsing is always deterministic (`reconcile.py`). |
| 8 | 2. **Generate a matching NL question** for each label. |
| 9 | 3. **Run** each question through the same NL→SQL→execute pipeline as agami-query. |
| 10 | 4. **Diff** actual vs expected with a tolerance. |
| 11 | 5. **Present** a markdown table with per-row status; for mismatches, render the full receipt as a drill-down so the user can find the definitional disagreement. |
| 12 | |
| 13 | Spec for the deterministic helpers: [`scripts/reconcile.py`](../../scripts/reconcile.py) (CSV parser + number normalization + diff with tolerance). |
| 14 | |
| 15 | ## Conversation style |
| 16 | |
| 17 | - **Tight loops.** This skill is a tool, not a tutorial. One question per turn, max two sentences of prose between phases. |
| 18 | - **Surface mismatches loud.** A reconcile run with 9/12 matches and 3 mismatches is a SUCCESSFUL run — the mismatches are the value. Lead with what didn't match. |
| 19 | - **Don't paste raw SQL in chat.** The receipt has it. Same hard rule as agami-query. |
| 20 | |
| 21 | --- |
| 22 | |
| 23 | ## Phase 0: Preflight |
| 24 | |
| 25 | Same checks as agami-query / agami-connect: |
| 26 | |
| 27 | 1. **Plan-mode check** per [`shared/plan-mode-check.md`](../../shared/plan-mode-check.md). This skill needs Bash + Read + Write — refuse if locked in plan mode. **DO NOT write a plan file. DO NOT call `ExitPlanMode`.** Refusal text: *"I can't reconcile in plan mode — each row runs a live query and writes a receipt. Switch to **Auto** or **Edit Automatically** mode (Shift+Tab to cycle) and re-invoke me with the CSV path."* |
| 28 | 2. **Credentials present** — read `<artifacts_dir>/local/credentials` for the active profile. If missing, invoke `/agami-connect` to set up first; this skill needs a working DB connection. |
| 29 | 3. **Model present** — `<artifacts_dir>/<profile>/org.yaml` must exist. If not, invoke `/agami-connect`. This skill needs an introspected model to generate questions against. |
| 30 | 4. **Input — accept any of three shapes; the user needn't know which.** Detect what they gave: |
| 31 | - **A screenshot / image** of a dashboard (Metabase, Power BI, Tableau, Looker, a spreadsheet) — the common case. Go to Phase 1's **vision branch**. |
| 32 | - **A CSV** — a path in `$ARGUMENTS`, or pasted inline (write inline CSV to `/tmp/agami-reconcile-<ts>.csv`). Go to Phase 1's **CSV branch**. |
| 33 | - **Numbers pasted inline** as a list/table — treat as inline CSV. |
| 34 | If they gave nothing (or just asked "can you check my dashboard?"), ask once, welcoming all three: *"Show me the numbers you want to check against — easiest is a **screenshot of your dashboard** (Metabase, Power BI, Tableau, a spreadsheet — whatever you have), but a CSV or a pasted list of `label: value` works too."* Don't make them figure out an export format. |
| 35 | 5. **If they gave a file path, validate it exists.** If not, surface the error and stop. |
| 36 | |
| 37 | --- |
| 38 | |
| 39 | ## Phase 1: Extract the (label, value) pairs |
| 40 | |
| 41 | Whatever the input shape, the goal is the same normalized rows JSON. * |