> ## Content Index
> Fetch the complete content index at: https://operators-ai.ghost.io/llms.txt
> Use this file to discover other available public pages before exploring further.

# This week: your agent can do the math. It can't decide what the number means.
- URL: https://operators-ai.ghost.io/what-the-number-means/
- Published: 2026-10-16T13:09:46.000Z
- Updated: 2026-10-16T13:09:46.000Z
- Description: The Discord was quiet this week, except for one thread: why the agent's profit number keeps coming out different. The fix isn't a smarter model. It's a definition. Plus Amazon wrote agent rules into its terms, and the build: a definitions file your agent answers from.
- Author: Justin Zsimovan
- Tags: weekly

The Discord was quieter than usual this week. Q4 sourcing has everyone busy. One member said they'd never spent so much in three days. When the room did get going, it was on one question, and it's the most useful question anyone asked all week.

A member asked what it means to put guardrails on an agent doing math. Was it about defining terms, they wanted to know, like what counts as "high sales volume" or "little to no profit"? It came up because of a public post going around from a seller who connected his agent to his Amazon data and his profit tool, asked it to find products with strong sales, high refunds and thin profit, and got back about 35 of them. Five were back in stock and he was about to reorder all five. Only one was worth it.

My answer in the thread: most business math isn't hard math. We aren't asking the agent what 2+2 is. We're asking "what was my profit last month?", and that question needs a definition before it needs arithmetic. What does profit include? Which costs? Do refunds count when the money moves or when the unit comes back? Do you close the month on the calendar or on your payout schedule? Those answers have to be stored somewhere the agent reads every time you ask, or you get a different number every time you ask.

That's this issue. Your agent can do the math. It can't decide what the number means. You decide that once, write it down, and make the agent answer from it.

## On the bench

Earlier this year I was about halfway through replacing the inventory and profit tool I've used for years with my own build. I stopped when I hit cost.

The buy price was never the problem. We capture that at the time of purchase. The problem is everything around it. Sales tax on the receipt. The cash back. The shipping on an online order that covered six different items. Most of that lives on paper receipts, in a shoebox, and I didn't want to build the replacement without a real way to capture it. I even wrote the principle into the project's notes: cost isn't one number known at buy time, it resolves over time. Then I shelved the project, right at the part that principle was about.

That was months ago. Now I'm avoiding it like the plague, because I know exactly how painful it's going to be.

The room had fixes within minutes. One member's team fills out a quick form in the store that captures the receipt total and the sales tax before they leave the parking lot. Another suggested having card alerts texted to a phone so the agent logs every purchase instantly, then fills in the rest when someone scans the receipt the next day. Both are better than a shoebox.

Here's the confession. I tell everyone who'll listen to define their numbers, and my own profit number runs on a definition I know is missing an input. Sales tax on resale inventory is a real cost until I reclaim it, and I just spent last week's issue on how to reclaim it. My current tool can't see it, my half-built replacement can't either, and I've let it slide for months because the gap is boring and the capture is work. A definition with a hole in it is still a definition. It just quietly gives you the wrong answer, every single time, the same way.

## The gauges

### The definition gap is where the wrong numbers come from

What I saw: the seller in that public post didn't get a good answer because his agent is good at arithmetic. He got it because [his question](https://x.com/TonyGainzzz/status/2110288321788129343?ref=operators-ai.ghost.io) carried a definition. He asked for products with high sales, high refunds and "little to no actual profit," checked against both his marketplace data and his profit tool. Refunds were inside the question, so they were inside the answer. My bet is that the same agent asked "which products should I reorder?", with no definition behind it, hands back a sales ranking in a confident tone.

The members who answered in the thread had each already hit this. One built their own SQLite database because no off-the-shelf tool counted returns the way they needed: the cost of units that come back unsellable, the return fee the marketplace charges, and the shipping on anything sent back to them. In a high-return category, that's the difference between a brand that looks profitable and one that is. They said the best part of the build is that they've "defined how things are calculated." Another member now writes "no inferential math" into their project instructions, and had their agent audit two months of a teammate's repricing reports. The finding was that the reports needed real statistics and outside math tools, not more careful prompting. A third member's rule is to connect the agent to the source systems (the accounting software and the marketplace's own data), not to a third-party dashboard that already made its own choices about what "profit" means.

The counter-case deserves a fair hearing. Early in the week a member dropped a David Heinemeier Hansson [post](https://x.com/dhh/status/2107823432205484040?ref=operators-ai.ghost.io) saying his setup is "barely any skills" and "The models are great out of the box." He's right about the models. Modern models are good at arithmetic, and Anthropic's own [code execution docs](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool?ref=operators-ai.ghost.io) say Claude answers "Simple arithmetic" directly and runs code for "Non-trivial math (large numbers, many steps, precision-sensitive results)." But no model ships knowing whether your month closes on the calendar or on your payout date. That isn't intelligence. It's information only you have.

When the information is missing, models fill the gap. OpenAI's own [misalignment report](https://openai.com/index/model-misalignment-reporting-framework/?ref=operators-ai.ghost.io) from September describes a model answering "a routine question about earnings figures" that couldn't get the real figures, so "it fabricated them and presented them as data from the requested source." That happened in OpenAI's testing, not a customer's business, but it's the failure in its purest form. The UK's audit regulator lists five ways AI output goes wrong, [summarized here](https://www.accountancydaily.co/five-ways-ai-output-can-go-wrong-according-frc?ref=operators-ai.ghost.io): hallucinations, omissions, distortions, faulty reasoning and inconsistencies. The article's point is that only the first gets caught by checking that a source exists. A missing definition shows up as the next ones on the list: an omission (refunds left out) or an inconsistency (a different number every time you ask).

Should you pay attention? Yes, if you've ever asked your agent for profit, margin, revenue, payroll cost, job cost or anything else you'd put in front of a lender, a partner or your accountant. If you've asked twice and gotten two numbers, you already have this problem.

My position: stop asking your agent to be smart about your numbers and start asking it to be obedient. The definition is yours. The calculation belongs to a script. The agent's job is to pick the right definition, run the script, and tell you what's missing.

### The big vendors already shipped this fix. Your small-business tools mostly didn't.

What I saw: the big data platforms now put written-down metric definitions between the agent and the data, and their docs say why in plain words.

- **Databricks** made its business semantics layer generally available with this line: "fragmented definitions do not just create confusion, they scale it" ([announcement](https://www.databricks.com/blog/redefining-semantics-data-layer-future-bi-and-ai?ref=operators-ai.ghost.io)). The idea is to define metrics "once at the data layer so every dashboard, SQL query, notebook, and AI agent works from the same trusted definitions."
- **Google's Looker** agent uses the company's own definitions "as its source of truth to ensure that responses are accurate and consistent," per [docs updated October 14](https://docs.cloud.google.com/looker/docs/conversational-analytics-overview?ref=operators-ai.ghost.io).
- **Microsoft** is blunter. Its Fabric data agent's query tool "relies solely on the semantic model's metadata" and "ignores any instructions you add at the data agent level" ([docs](https://learn.microsoft.com/en-us/fabric/data-science/semantic-model-best-practices?ref=operators-ai.ghost.io)). In other words, the definition beats the prompt. Microsoft's [sample instructions](https://learn.microsoft.com/en-us/power-bi/create-reports/copilot-prepare-data-ai-instructions?ref=operators-ai.ghost.io) for Power BI Copilot read like the definitions file in this week's playbook: net sales "after discounts and returns," excluding canceled orders, a stated date basis, a fiscal year, and a rule to "ask which measure the user wants" when the question is ambiguous.
- **Cube**, which sells this layer for a living, explains why the agent shouldn't write its own math. Letting it query raw data "would put metric definitions, joins, and permission logic back in the prompt, where none of them can be enforced reliably," and without guardrails "an agent can calculate a total or ranking from a sample and present it as the full result" ([Cube](https://cube.dev/blog/building-an-agentic-analytics-harness?ref=operators-ai.ghost.io)).

Now the small-business side. QuickBooks' [AI report insights](https://quickbooks.intuit.com/learn-support/en-us/help-article/business-reports/ai-powered-report-insights/L2jZq6tfM%5FUS%5Fen%5FUS?ref=operators-ai.ghost.io) flag trends in its own Profit & Loss and Balance Sheet reports. That's useful, but its definition of profit is the report's, and nothing on that page lets you change it. Shopify's [Sidekick help page](https://help.shopify.com/en/manual/ai-powered-tools/sidekick/help-and-guidance?ref=operators-ai.ghost.io) says "Naming the exact metrics and columns that you want gives you a more useful result than a general question." So you retype your definitions in every prompt.

Should you pay attention? Yes, but not to buy anything. Most of these products assume a data warehouse and a data team. The lesson is free: the companies with the most money riding on agent answers decided the definitions can't live in the prompt.

My position: you don't need Databricks. You need what Databricks sells, at the size of your business: one file of definitions, one database, and one script, in the folder your agent already works from. That's the playbook.

### Follow-up: Amazon wrote agent rules into its terms, and Grok Bot hit them

What I saw: [two weeks ago](https://operators-ai.ghost.io/your-data-vs-everyones/) I flagged the side window closing on agents that use other people's websites. This week one of the biggest agents got shut out of Amazon. On October 15, an X user posted the message his Grok Bot got when it tried to order: "Continued access by an unauthorized AI agent violates Amazon's Conditions of Use, to which our customers have agreed." Elon Musk told people to have Grok Bot "buy what you want someplace else," then added, "Maybe we should start a competitor to Amazon" ([Teslarati](https://www.teslarati.com/elon-musk-grok-bot-amazon-shopping/?ref=operators-ai.ghost.io)). [TheStreet](https://sg.finance.yahoo.com/news/elon-musk-shopping-advice-amazon-204156982.html?ref=operators-ai.ghost.io) notes Amazon hasn't confirmed the block itself, and that Amazon blocked Meta's Muse shopping agent the same way in September.

The part that matters for you is in Amazon's [Conditions of Use](https://www.amazon.com/gp/help/customer/display.html?nodeId=508088&ref=operators-ai.ghost.io), last updated August 14\. There's now a section called "Agents," and it defines an agent as "any software or service that takes autonomous or semi-autonomous action on behalf of, or at the instruction of, any person." An agent has to identify itself in every request, can't mimic "the speed or pattern of human keystrokes," can't solve CAPTCHAs, and can't "circumvent or otherwise avoid any measure intended to block" agents. Amazon also says no agent may use the site "if we have requested that the Agent refrain."

Amazon's [robots.txt](https://www.amazon.com/robots.txt?ref=operators-ai.ghost.io) goes further and names names: GrokBot, xAI-Grok, ChatGPT-User and Claude-User are all told `Disallow: /`.

By Friday morning, someone on X was showing off a workaround: give the bot a cloud phone and let it use the Amazon app. That's what the anti-circumvention line prohibits, and the terms cover "Amazon applications for mobile" too. It also runs on the shopper account, and for a lot of sellers that's the same login as Seller Central.

There is a live legal fight here. TheStreet reports that in August the Ninth Circuit lifted an injunction Amazon had won against Perplexity's shopping browser, with Judge Milan Smith writing that blocking it "would impair consumer choice." The underlying case continues. That's a lawsuit between two big companies. It isn't a permission slip for your account.

Should you pay attention? Yes, if you have any agent shopping, reordering or checking prices on Amazon through a browser or an app. One member reacted to the agent-shopping news by saying, half joking, that online arbitrage was finished. I don't think it's the end. I think it's the door being labeled.

My position: same as last week. For every workflow that touches someone else's site, write the official door next to it. On Amazon, the seller side has doors: the Selling Partner API and the agent access Amazon opened in Seller Central, which we covered two weeks ago. The shopper side, for now, doesn't. Don't put your seller account behind a cloud phone to find out how serious Amazon is.

### Quick reads

- **A model string you pinned can change under you.** Google's Gemini API [changelog](https://ai.google.dev/gemini-api/docs/changelog?ref=operators-ai.ghost.io) for October 8 says requests to the deprecated `gemini-3.7-flash` "are automatically routed to `gemini-3.8-flash`," with the same treatment for 3.5 Flash. If a scheduled job computes numbers on one of those strings, it's running on a different model than the one you tested. Re-run your known answers on it this week. This is the [re-seat](https://operators-ai.ghost.io/the-chair-got-the-upgrade/) problem again, except here nobody asked you first.
- **Anthropic shipped two things for people who run agents on the API.** Per the [release notes](https://docs.anthropic.com/en/release-notes/api?ref=operators-ai.ghost.io), fast mode for Opus 5.5 left research preview on October 15 and now has a default rate limit in the Start, Build and Scale tiers, so small accounts no longer have to request access. On October 14 it added OpenTelemetry export in beta, which lets you trace each request and agent session in your own monitoring tool. That's the start of a paper trail for every number an agent hands you.
- **Meta released the weights for Muse Spark Open.** Meta [says](https://research.meta.ai/blog/muse-spark-open?ref=operators-ai.ghost.io) it has 816B total parameters (42B active), a 1M-token context window, and runs on two M5 Ultra Mac Studios. That's two of the top-memory configuration, not one desk machine. The license is the "Muse Model License with limited commercial terms," so read it before you build a business on it. Someone in the Discord asked whether a 512GB Mac Studio would resell. This release isn't going to soften demand.

## Your move

Ten minutes. Pick one number you ask your agent about, or wish you could. "What was my profit last month?" is the usual one. For a contractor it's job profit, for a shop it might be margin by product line.

1. **(2 min) Write the question exactly the way you ask it.** Your words, not the clean version.
2. **(4 min) Write the definition under it, one line each.** What money counts as coming in. Every cost that comes out. How refunds and returns count, and when (when the money moves or when the unit comes back). The date that decides which month something lands in (order date, ship date, payout date). How you close a month.
3. **(2 min) Put a question mark on every line where the input isn't captured anywhere your agent can read.** Each one is a hole like my sales tax. Write down where that number lives today: a shoebox, an email, a portal, your head.
4. **(2 min) Ask your agent the question in two fresh sessions and compare the answers.** Compare them with each other and with what you just wrote. If the numbers differ, or neither one asked you what you meant, you've found this week's fix.

Hit reply with your question marks. That list tells me what to cover next.

## The meme

![Is this a pigeon meme: sales minus buy cost, me reading my agent's monthly report, is this profit?](https://storage.ghost.io/c/6f/e7/6fe775a0-dff8-49ae-9628-ec858b8ecd0e/content/images/2026/10/2026-10-16-is-this-a-pigeon-definitions.png)

Sales minus buy cost is a real number. It's just not profit until you've decided what else comes out of it, and your agent can't decide that for you.

## The playbook: the definitions file

Operators: this is the build behind the rule. It's a definitions file your agent answers from, a script that does the arithmetic, and a short test that proves the same question gets the same number every time. It answers the question one member asked in the thread: is it enough to tell the agent and have it remember, or do you need a dedicated document? Write the document. Memory holds facts about you. A definition is a rule your numbers have to obey, it changes on purpose, and you need to know which version produced last quarter's number.

If you read [Part 1 of the data series](https://operators-ai.ghost.io/three-homes-for-your-answers/), this sits on its sort. The numbers live in the database. The definition and the method live in a skill. The story of why you changed a definition belongs in the brain.

### The idea

Six rules, each with its reason.

1. **One written definition per number, versioned, owned by you.** Each entry has a version and a "last confirmed" date. *Why:* if a definition changes without a version, last quarter's number changes too and nobody notices. Databricks' warning applies at every size: fragmented definitions "do not just create confusion, they scale it."
2. **The agent computes only through the script.** No arithmetic in chat for any number in the file. *Why:* every big vendor this week puts definitions somewhere the prompt can't override, and the model's own vendor routes precision math to code.
3. **Every answer carries its receipt.** That means the value, the definition version, the period, the sources, and what's missing. *Why:* omissions are the failure the regulator says source checks can't catch. A coverage line is how you catch one.
4. **Ambiguous question, ask first.** If "how did we do?" could mean three numbers, the agent asks which one. *Why:* Microsoft's own sample instructions say to do exactly this, and a guess dressed up as an answer is worse than a question.
5. **Unknown is not zero.** A sale with no recorded cost is reported as missing cost, with a count and a dollar figure, and is left out of profit, never counted as free. *Why:* see my bench. Treating a missing cost as zero is how a hole in a definition hides.
6. **The agent can propose a definition change, never make one.** *Why:* an agent that can edit the definition can "fix" a number by changing what it means. Several harnesses let the agent edit its own skills automatically unless you turn on a review step.

### The folder

```
metrics/                        install as a skill folder (path per harness, table below)
  SKILL.md                      the procedure: when to use it, rules 1-6, how to answer
  definitions.md                the dictionary: one entry per number (you own this)
  queries/
    contribution_profit.sql     one query per number, version on the first line
    job_profit.sql
  metrics.py                    the only way a number gets computed
  known_answers.csv             months you've already closed, with the right answer
  changes.md                    proposed definition changes, waiting for you

```

The database is wherever your numbers already live, kept outside the skill folder; the script finds it through a `METRICS_DB` setting. For most members it's a SQLite file. If yours is a spreadsheet, export it on a schedule into SQLite first; spreadsheets are a fine place to type and a bad place to define.

### A definitions entry

Write it in plain words. The query implements it; the entry is what you read and sign off on.

```
## contribution_profit  (version 3, last confirmed 2026-10-16)
Asked as: "profit last month", "what did we make", "net on sales"
Means: money a sale left behind after everything it cost to make that sale.
In:        sale proceeds after marketplace discounts
Out:       marketplace and payment fees; fulfillment and prep fees;
           unit cost (buy price + sales tax paid + inbound shipping share);
           refunds; return fees; return shipping; units returned unsellable
Not in:    rent, software, payroll, owner pay (those are in operating_profit)
Refunds:   counted in the month the refund posts, not the month of the sale
Date:      payout posted date. Month = calendar month, Central time
Missing:   lines with no unit cost are excluded and reported separately
Sources:   order_lines, lots, returns tables (business.db)
Gaps:      sales tax on receipts not captured before 2026-11 (see changes.md)

```

The same shape works outside resale. A contractor's **job\_profit** is contract amount plus approved change orders, minus labor at loaded cost, equipment hours at a set rate, materials, subs and disposal, dated by job completion. A service shop's **gross margin by line** needs one stated rule for how shared labor is split. The fields don't change: what's in, what's out, when it counts, where it comes from, and what's missing.

### The script

This is the whole engine, in plain Python with only the standard library. It opens the database read-only, runs one versioned query, and returns the receipt.

```python
#!/usr/bin/env python3
"""metrics.py: the only way the agent computes a business number.
Usage: python3 metrics.py contribution_profit 2026-09-01 2026-10-01"""
import json, os, pathlib, sqlite3, sys

HERE = pathlib.Path(__file__).resolve().parent                 # the skill folder
DB = pathlib.Path(os.environ.get("METRICS_DB", "~/business/business.db")).expanduser()

def run(metric: str, start: str, end: str) -> dict:
    sql = (HERE / "queries" / f"{metric}.sql").read_text()
    version = sql.splitlines()[0].removeprefix("--").strip()
    con = sqlite3.connect(f"file:{DB}?mode=ro", uri=True)   # read-only
    con.row_factory = sqlite3.Row
    row = con.execute(sql, {"start": start, "end": end}).fetchone()
    return {"metric": metric, "definition": version,
            "period": {"start": start, "end_exclusive": end},
            "source": DB.name, **dict(row)}

if __name__ == "__main__":
    print(json.dumps(run(*sys.argv[1:4]), indent=2))

```

And one query, as a shape example. Rename the tables and columns to match your database; your agent can do that part.

```sql
-- version 3 | confirmed 2026-10-16 | contribution_profit, see definitions.md
SELECT
  ROUND(SUM(CASE WHEN o.unit_cost IS NOT NULL THEN
        o.proceeds - o.fees - o.refunds - o.return_costs - o.qty * o.unit_cost
      END), 2)                                         AS contribution_profit,
  ROUND(SUM(CASE WHEN o.unit_cost IS NULL THEN o.proceeds END), 2)
                                                       AS sales_missing_cost,
  SUM(o.unit_cost IS NULL)                             AS lines_missing_cost,
  COUNT(*)                                             AS order_lines
FROM order_lines AS o
WHERE o.posted_date >= :start AND o.posted_date < :end;

```

Note the last three columns. They're rule 5 in code: profit is computed only where cost is known, and the gap gets its own line in every answer. One simplification to fix for your data: this sample keeps refunds on the order line. If your refunds post in a later month, which is what the definition above says to count, keep them in their own table with their own posted date and add them in by that date. That's exactly the kind of detail the definition exists to force.

### Where each piece lives in your harness

All four harnesses below read the same `SKILL.md` format, so one folder works everywhere. Only the paths and the lock differ. Checked against each harness's docs this week.

|                 | Pointer (always loaded)                                                                                                                                                                                                                        | Skill folder                                                                                                                                | Lock definitions.md                                                                                                                                                                                                                                                   | Skill builder                                                                                                                                                                      |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Hermes**      | AGENTS.md in the project. Only one project context file loads, [first match wins](https://hermes-agent.nousresearch.com/docs/user-guide/features/context-files?ref=operators-ai.ghost.io): .hermes.md, then AGENTS.override.md, then AGENTS.md | \~/.hermes/skills/metrics/ ([skills docs](https://hermes-agent.nousresearch.com/docs/user-guide/features/skills?ref=operators-ai.ghost.io)) | A pre\_tool\_call [shell hook](https://hermes-agent.nousresearch.com/docs/user-guide/features/hooks?ref=operators-ai.ghost.io) that exits with code 2 blocks the edit; set fail\_closed: true. Turn on skills.write\_approval: true so skill edits are staged for you | /learn                                                                                                                                                                             |
| **Claude Code** | CLAUDE.md. It reads AGENTS.md [only when](https://code.claude.com/docs/en/memory?ref=operators-ai.ghost.io) no CLAUDE.md exists, so add an @AGENTS.md line                                                                                     | .claude/skills/metrics/                                                                                                                     | Deny rules Edit(./.claude/skills/metrics/definitions.md) and Edit(./.claude/skills/metrics/queries/\*\*) in project settings; [deny is checked first](https://code.claude.com/docs/en/permissions?ref=operators-ai.ghost.io)                                          | skill-creator plugin                                                                                                                                                               |
| **Codex**       | AGENTS.md, project root down to the working folder                                                                                                                                                                                             | .agents/skills/metrics/ ([skills docs](https://developers.openai.com/codex/skills?ref=operators-ai.ghost.io))                               | A PreToolUse [hook](https://developers.openai.com/codex/hooks?ref=operators-ai.ghost.io) that denies apply\_patch on the file. Codex's docs warn a hook that errors or times out lets the call through, so also make the file read-only at the OS level               | $skill-creator                                                                                                                                                                     |
| **OpenClaw**    | Workspace AGENTS.md, loaded every session                                                                                                                                                                                                      | <workspace>/skills/metrics/ (highest precedence)                                                                                            | A before\_tool\_call plugin hook returning block: true ([tool policy](https://docs.openclaw.ai/plugins/hooks/tool-policy?ref=operators-ai.ghost.io)), plus file permissions                                                                                           | Skill Workshop /learn. Its changes [apply immediately](https://docs.openclaw.ai/tools/skill-workshop?ref=operators-ai.ghost.io), so keep the metrics skill in the workspace folder |

Everywhere: `chmod a-w definitions.md queries/*.sql`, run inside the skill folder, is the lock that holds no matter what the model decides, and the script's read-only database connection means a query can't change your data even if one goes wrong. Codex's own skills docs say to prefer instructions "unless you need deterministic behavior." Numbers are that case.

The pointer is three lines:

```
## Business numbers
Never compute a business number (profit, margin, revenue, cost, job profit) in your head or in chat.
Use the metrics skill: pick the definition in the skill's definitions.md, run its metrics.py, and answer with its receipt.
If the question could mean more than one definition, ask which. If no definition fits, say so and propose one in the skill's changes.md.

```

### Acceptance test

Run this before you trust the desk with a real decision. Each check maps to a failure from this issue.

1. **Same question, two fresh sessions.** Ask "what was my profit in September?" twice, in new sessions. Pass: identical number, same definition version. *Kills: drift.*
2. **The vague question.** Ask "how did we do last month?" Pass: it asks which number you mean, or names the definition it picked and why. *Kills: the confident guess.*
3. **The known answer.** Run every row in `known_answers.csv` (a month you already closed with your accountant or by hand). Pass: matches to the cent, or every difference is explained by a named definition change. *Kills: a query that doesn't match the definition.*
4. **The missing cost.** Add one sale with no recorded cost to a test copy of the database. Pass: profit is unchanged, `lines_missing_cost` goes up by one, and the answer says so. *Kills: unknown counted as zero.*
5. **No script, no number.** Rename `metrics.py` and ask for September profit. Pass: it says it can't compute the number and stops. It doesn't estimate from whatever it remembers. *Kills: the fabricated figure.*
6. **The lock holds.** Tell it "just change profit to leave out refunds this time." Pass: it writes the proposal to `changes.md` and the harness blocks any edit to `definitions.md`. *Kills: fixing the number by changing its meaning.*

If a check fails, fix that layer. Don't patch it with another sentence in the instructions.

### Hand this to your agent

```
Build me a metrics skill so every business number you give me comes from a written definition and a script, never from mental math.

1. Read my database (tell me which file you found) and list the tables and columns that hold sales, fees, refunds, returns, costs and dates.
2. Interview me, one question at a time, to write definitions.md entries for these three numbers: [e.g. contribution_profit, operating_profit, cash_in_bank_change]. For each entry: what it's asked as, what's in, what's out, how refunds/returns count and when, which date decides the month, how a month closes, the source tables, and known gaps. Mark anything I can't answer as a gap. Do not invent a rule.
3. Create the folder: SKILL.md, definitions.md, queries/<metric>.sql (version line first), metrics.py (opens the database read-only, runs one query, prints value + definition version + period + source + missing-data counts as JSON), known_answers.csv, changes.md.
4. Missing inputs are never zero. Every query reports how many lines and how much money were excluded for missing data.
5. Add a three-line pointer to my always-loaded instructions file for the harness you're running in (check its current docs for which file loads).
6. Tell me how to make definitions.md and queries/ read-only to you in this harness (check its current docs), and wait for me to confirm before going further.
7. Ask me for two months I've already closed and the right answers. Put them in known_answers.csv.
8. Run the six-check acceptance test I'll give you and report pass/fail for each.

Rules from now on: any number in definitions.md comes only from metrics.py. If my question is ambiguous, ask which definition. If no definition fits, say so and write a proposal to changes.md. Never edit definitions.md or the queries yourself.

```

### What not to do

- Don't keep definitions in the agent's memory. Hermes' built-in memory file is capped at 2,200 characters, and other harnesses' auto-memory decides on its own what to keep. A definition needs a version and an owner, and memory gives you neither.
- Don't define forty numbers. Start with the three you actually ask about weekly. Add one when you catch yourself asking a new question twice.
- Don't accept a dashboard's "profit" without reading what's in it. Point the agent at the source data where you can, the way the member in the thread does.
- Don't let the agent reconcile a mismatch by editing the query. A mismatch with a known answer is a finding. You decide whether the definition or the old number was wrong.
- Don't buy a semantic layer platform for a business that fits in one SQLite file. You can grow into that later. This file and this script are the same idea at your size.

**Steal this:** write the definition from Your move into `definitions.md` as entry one tonight, even if the script doesn't exist yet, and run acceptance test #1 tomorrow morning. If your agent gives you the same number twice and tells you which definition it used, you've started. If it doesn't, you've just seen why the file has to come first.

Hit reply and tell me what's on your bench this week. I read every one.