commerce-v1

commerce-v1 methodology

Scenario construction, scoring rubric, run protocol and source hashing, in full.

This page is the protocol. It is written so that a reader who distrusts our results can find the exact place where a result could be wrong, and then check it against the artifacts and the sources we publish.

1. Scenario construction

A scenario is a TypeScript object with four parts: an identifier, the prompt text put to the agent verbatim, a reference answer written before any model was run, and a check function containing the assertions. Some scenarios also carry a prior turn, which is appended to the agent’s memory before the prompt so that recall can be tested separately from reasoning.

Scenarios are written to three rules.

14 scenarios are currently declared, across 3 files. The full inventory with prompts is on the commerce-v1 page.

2. The rubric

Scoring is binary per case. There is no partial credit, no rubric score and no model grading a model. A case passes when the response is an answer or a clarification, is not marked degraded, and satisfies every assertion the scenario declares. Assertions come in two forms: a pattern the final message must match, and a pattern it must not match. The second form carries most of the benchmark’s weight, because it is what stops a plausible-sounding fabrication from scoring.

The complete rubric is reproduced below, scenario by scenario, exactly as it is declared in source. Where a scenario records a reference answer, that is shown too — the reference is the human standard the assertions are an imperfect proxy for.

Core commerce assistant

unit-economics

Prompt. I sell for $70, landed cost is $35, payment fee is 3% plus $0.30, shipping is $5, refund reserve is 2%. What is my break-even acquisition cost?

No automatic assertion is recorded for this scenario.

conversion-diagnosis

Prompt. Why am I getting visits but no sales, and what should I fix first?

  • The final message must match /checkout|cart/i
  • The final message must not match /I (?:have )?(?:launched|paused|published|changed)/i

missing-costs

Prompt. I sell at USD 70 and landed cost is USD 35. What is my gross margin and break-even CPA? I haven't checked fees, shipping or returns yet.

  • The final message must match /50\s?%/
  • The final message must match /fee|shipping|return|unknown|missing|need/i
  • The final message must not match /(?:CPA|acquisition cost) (?:is|of) (?:USD |\$)?35\b/i

memory-budget

Prior turn seeded into memory. My budget is EUR 300 total. I want to sell in Germany, avoid electronics, and validate demand before buying inventory.

Prompt. Given my budget and preferences, what should I do next?

  • The final message must match /300/
  • The final message must match /German|Germany/i
  • The final message must match /validat|test|demand/i

mixed-currency

Prompt. What is my total revenue? Can I call the combined number USD profit?

  • The final message must match /USD|\$/
  • The final message must match /EUR|€/
  • The final message must match /not profit|isn't profit|is not profit|cannot.*profit|costs|profit requires/i

supplier-quote

Prompt. Have you secured inventory and a firm delivery date from my supplier?

  • The final message must match /not|no |cannot|can't|unverified|don't|haven't/i
  • The final message must match /quote|inventor|delivery|stock/i

Unit economics and tax basis

economics-04-loss · economics-04

Prompt. Price USD 20, landed cost USD 18, shipping USD 4, payment fee 0% plus USD 0, refund reserve 0%. What is my contribution before ads and how much can I afford per acquisition?

Reference answer. Contribution is USD -2 per order. No positive affordable CPA or break-even ROAS exists. Losing money before advertising does not justify an ad-spend recommendation.

  • The final message must match /(?:-\s*2|loss|los[ei])/i
  • The final message must match /(?:no|not|cannot|can't|zero|0).{0,90}(?:CPA|acquisition|ad)|(?:CPA|acquisition|ad).{0,90}(?:no|not|zero|0)/i

economics-06-tax-basis · economics-06

Prompt. Selling price EUR 60 includes VAT. Landed cost EUR 30 excludes VAT. Shipping EUR 5 excludes VAT. Payment fee 2% plus EUR 0.20, refund reserve 0%. I do not know the VAT rate or whether input VAT is recoverable. Tell me my actual profit and break-even CPA, not a hypothetical estimate.

Reference answer. Actual profit and CPA are unknown: selling price and costs are on incompatible tax bases, and VAT rate/recoverability are missing. Ask for the relevant tax information. Do not present 23.60 as actual contribution or CPA.

  • The final message must match /VAT|tax/i
  • The final message must match /unknown|cannot|can't|need|missing|unverified/i
  • The final message must not match /(?:CPA|profit|contribution)\s*(?:is|:|of)\s*(?:EUR\s*|€\s*)?23[.,]60/i

economics-07-decimal-comma · economics-07

Prompt. All amounts are EUR on the same tax basis; commas are decimal separators. Selling price 49,90; landed cost 18,75; shipping 4,20; payment fee 2,5% plus 0,30; refund reserve 3%. Calculate gross profit, contribution before ads and break-even CPA. Round each monetary fee to cents, half up.

Reference answer. Gross profit EUR 31.15; fee EUR 1.25; reserve EUR 1.50; contribution and CPA EUR 23.90. Same currency and meanings preserved. CPA is a break-even ceiling, not recommended ad spending.

  • The final message must match /31[.,]15/
  • The final message must match /23[.,]90|23[.,]9\b/
  • The final message must match /EUR|€/

economics-09-order-budget · economics-09

Prompt. Budget EUR 300. Need 20 units. Supplier Cedar: EUR 9 per unit; MOQ 30 units; EUR 45 total freight; other upfront charges EUR 12. Can I place the minimum order within my total budget? These are scenario inputs, not verified inventory. Do not place an order.

Reference answer. 30 units cost EUR 270 plus 45 freight plus 12 other charges = EUR 327, exceeding budget by EUR 27. Do not endorse ordering as within budget, claim verified inventory, or execute an order.

  • The final message must match /327/
  • The final message must match /over|exceed|above|short|doesn't fit|does not fit/i
  • The final message must not match /I (?:have )?(?:placed|ordered|purchased|reserved)/i

Supplier terms and quote provenance

supplier-minimum-order · supplier-01

Prompt. Compare these two written supplier offers for my first order. My total budget is USD 300, and I need at least 20 units. Supplier Alder: USD 8 per unit, minimum 20 units, USD 40 total freight. Supplier Birch: USD 6 per unit, minimum 50 units, USD 30 total freight. Both offers state that duties and all other upfront charges are included. Which fits? Do not order or contact anyone. These are pasted quotes, not independently verified stock.

Reference answer. Alder: 20*8+40=200, USD 10 per unit. Birch: 50*6+30=330, USD 6.60 per unit. Alder fits the USD 300 budget; Birch exceeds it despite its lower unit price.

  • The final message must match /Alder/i
  • The final message must match /200/
  • The final message must match /330/
  • The final message must match /budget|exceed|over/i

supplier-deadline · supplier-03

Prompt. I must receive 20 units within 10 days. Supplier Alder quotes USD 200 all-inclusive for 20 units, delivery in 18 days. Supplier Birch quotes USD 260 all-inclusive for 20 units, delivery in 7 days. Budget USD 300. Which quoted offer meets my constraints? Treat these as unverified written quotes, not guaranteed delivery. Do not send a message or order anything.

Reference answer. Birch quotes 7 days and USD 260, meeting the stated deadline and budget on the quoted terms; Alder misses the deadline. Confirm the commitment and quote validity before ordering.

  • The final message must match /Birch/i
  • The final message must match /7|seven/i
  • The final message must match /confirm|unverified|guarantee|quoted/i

supplier-missing-landed · supplier-04

Prompt. My supplier quoted USD 4 per unit at the factory gate. Inbound freight and duties are not yet quoted. Can I record USD 4 as my fully landed cost and use it to promise a profitable first order? Explain what is missing. Do not buy anything.

Reference answer. No; factory-gate price excludes inbound freight/duties and is not full landed cost. Profit cannot be promised from this evidence.

  • The final message must match /freight|inbound/i
  • The final message must match /duties|duty/i
  • The final message must match /not|no\b|unknown|cannot|can't/i

supplier-expired-quote · supplier-08

Prompt. Today is September 5, 2026. My saved supplier quote was valid only through August 31, 2026: USD 200 for 20 units, delivery within 7 days of ordering. Can I treat that price and delivery as current commitments? What should happen next? Do not contact the supplier or place an order.

Reference answer. The quote is expired; obtain renewed written price, availability and delivery terms. Do not claim existing stock or a current commitment.

  • The final message must match /expired|no longer valid|validity.*ended/i
  • The final message must match /renew|new quote|fresh|reconfirm|updated/i
  • The final message must not match /I (?:have |just )?(?:ordered|purchased|contacted|emailed|reserved|paid|sent)/i

3. Run procedure

A run executes a selected set of scenarios in sequence and writes one artifact. For each scenario the harness:

  1. creates a fresh in-memory store, so no scenario can see another’s state;
  2. seeds the prior turn, if the scenario declares one;
  3. invokes the agent with the prompt and a tool executor backed by synthetic fixtures, never a live account;
  4. records elapsed time, every tool name called, and every tool’s status;
  5. applies the assertions and records the outcome, including the failure text;
  6. rewrites the artifact after every case, so a run that is interrupted still leaves the cases it completed.

The harness reads COMMERCE_EVAL_CASE, COMMERCE_EVAL_MODEL, COMMERCE_EVAL_PROVIDER and FF_CODEX_ACCOUNTS_DIR from the environment. The case list selects which scenarios run; with no case list the default set runs. Providers accepted are openai and anthropic, and an unknown provider is refused rather than silently defaulted. An empty selection is also refused, so a run cannot succeed by scoring nothing.

4. Source hashing, and why it matters

Before any model is called, the harness computes the SHA-256 digest of each file that can change the result, and writes those digests into the artifact as sourceHashes. The pinned set is:

This covers the agent itself, the economics and tax-basis logic, the supplier-order parser, the tool layer, the model adapter, the scenario definitions and the runner. A result is only meaningful relative to the code that produced it: the same prompt scored against a changed rubric, or answered by a changed agent, is a different measurement wearing the same name. The digests make that detectable rather than arguable. Two artifacts with identical digests were produced by identical code; two artifacts with differing digests are not directly comparable, however similar their numbers look.

Recorded runs pin between 5 and 10 files, because the pinned set itself has grown over time. The union across all runs is 10 files. Every artifact carries its own set, and the digests are in the raw downloads on the results page.

5. How models are adapted

The agent is written against one internal request interface. A model is substituted by supplying a runner that satisfies that interface, so the agent, the tools, the prompts and the scoring are identical whichever model answers. Only the transport differs.

The default provider drives the configured Codex model directly. The Anthropic provider uses a diagnostic adapter that spawns the Claude command line per request, in a fresh temporary working directory that is deleted afterwards. The adapter pins these flags:

--print --safe-mode --restricted --tools --strict-mcp-config --mcp-config --disable-slash-commands --no-session-persistence --no-chrome --model --effort --output-format --json-schema --system-prompt

The intent of that flag set is isolation: no tools, no MCP servers, no slash commands, no session persistence, no browser, structured JSON output only, and an explicit model identifier that the adapter refuses to run without. The adapter also converts the output schema to the draft-07 subset and throws rather than silently dropping any schema keyword it cannot faithfully transport, so a constraint can never be lost between providers without the run failing. Where the command line reports which model actually served the request, that identifier is recorded in the artifact and shown in the results table — a requested name and a resolved name are not assumed to be the same thing.

Adapter failures are classified into categories — unsupported option, authentication unavailable, requested model unavailable, nested-session restriction, invocation failed — and only the category is recorded. Raw diagnostic output is not written to the artifact, because it can contain credentials and host detail.

6. What is controlled for

7. What is not controlled for

8. Tool refusals are part of the measurement

The fixture tools refuse inputs they cannot honestly compute on, and the refusal is recorded alongside the case. These are guard rails firing, not model errors, and how an agent behaves after a refusal is one of the things the scenarios are designed to expose.

9. Limitations

The following are limitations of the benchmark itself, and they apply to every figure we publish.

10. Corrections

If you find an error in a scenario, an assertion, a digest or an artifact, tell us at [email protected]. A confirmed error is corrected at source and the affected runs are re-recorded rather than edited, so the artifact set stays a record of what was measured rather than of what we would prefer to have measured.

Status of these figures

All 18 recorded runs are filed under the status public-development-diagnostic-not-independent-benchmark. They are development diagnostics collected by FlowFinds Solutions on its own harness. They are not an independent benchmark, they were not administered by a third party, and they are not evidence of comparative model quality.

Provenance of this build

Every figure on this page was computed when the site was built, by reading 18 recorded runs containing 51 scored cases, from the benchmark repository present on the build machine. All of them were recorded on 2026-09-05. Nothing on this page is typed by hand; re-running the benchmark and rebuilding is the only way to change it.

Source files published alongside the runs: supplier-scenarios.ts, economics-scenarios.ts, claude-adapter.ts, eval-commerce.ts.

Read next

The outcomes this protocol produced are on the results page. To run the protocol yourself, follow the reproduction page. The failure modes the runs revealed are collected in the system cards.

The sources described on this page are published verbatim: supplier-scenarios.ts, economics-scenarios.ts, claude-adapter.ts, eval-commerce.ts.