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.
- Every number in the prompt is stated in the prompt. No scenario requires outside knowledge, market data or a lookup. The arithmetic is checkable by hand, which is what makes the reference answer authoritative.
- The prompt forbids action. Scenarios that mention suppliers instruct the agent not to order or contact anyone, so that a claim of having done so is unambiguously a failure rather than an instruction followed.
- Under-specification is deliberate. Several scenarios omit a cost, mix two tax bases, or present an expired quote. The correct answer to those is that the figure cannot be determined, and the assertions are written so that producing a confident number fails.
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:
- creates a fresh in-memory store, so no scenario can see another’s state;
- seeds the prior turn, if the scenario declares one;
- invokes the agent with the prompt and a tool executor backed by synthetic fixtures, never a live account;
- records elapsed time, every tool name called, and every tool’s status;
- applies the assertions and records the outcome, including the failure text;
- 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:
lib/commerce/agent.tslib/commerce/economics.tslib/commerce/economics-provenance.tslib/intent/codex-cli.tsscripts/eval-commerce.tsbenchmarks/commerce-v1/claude-adapter.tsbenchmarks/commerce-v1/supplier-scenarios.tsbenchmarks/commerce-v1/economics-scenarios.tslib/commerce/supplier-order.tslib/commerce/tools.ts
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
- Prompt. Identical text for every model; the prompt is data in a source file, not a template rendered per provider.
- Agent, tools and scoring. Shared code, pinned by digest in every artifact.
- Tool data. Fixed synthetic fixtures. The same call returns the same data in every run.
- State. A fresh memory per scenario; no carry-over, no shared session, no account state.
- Authority. No scenario can place an order, send a message or spend money. The tool layer has no such capability at all.
7. What is not controlled for
- Sampling. Each case is attempted once per run. Model outputs are not deterministic, and no scenario is repeated enough times to separate variance from capability.
- Scenario subset. Runs vary in which cases they include — recorded runs hold between 1 and 6 cases — so two models’ aggregate pass rates may be computed over different scenarios.
- Harness revision. Runs were recorded against several revisions of the pinned sources. Compare the digests before comparing the numbers.
- Reasoning effort and configuration. Effort level, service tier and provider-side routing are set outside the harness and are only partly recorded.
- Provider attribution. 3 early runs predate the provider field and are shown as unrecorded rather than assigned to a provider by inference.
- Cost and latency. Recorded where the adapter reports them, absent otherwise, and measured on a developer machine rather than a controlled environment.
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.
economics— 2 refusals.- Error: The supplied amounts mix tax-inclusive and tax-exclusive bases. Ask for amounts on one consistent tax basis; do not calculate profit or CPA from these values.
- Error: landed_cost was not supplied in the quoted inputs; use null for an unknown cost.
supplier_order— 1 refusal.- Error: Supply one complete, verbatim founder message containing the supplier terms.
9. Limitations
The following are limitations of the benchmark itself, and they apply to every figure we publish.
- The scoring is shallow by construction. Regular expressions over a final message cannot assess reasoning. They can catch a missing entity, a missing qualification or a forbidden claim. A well-reasoned answer can fail on phrasing, and a poorly reasoned answer can pass by containing the right tokens. The scenario sources describe their own checks as smoke alarms rather than semantic graders, and instruct the reader to inspect the transcript.
- It is first-party. We wrote the scenarios, the assertions and the harness, and we run it on our own machine. The artifacts and sources are published so that this can be audited, not so that it can be waved away.
- The sample is small and unbalanced. With 51 scored cases spread over 4 pairings, most differences between models are within the range that resampling could reverse. No confidence interval is offered because none would be honest at this size.
- The fixtures are synthetic. Real supplier messages are messier than these prompts, real accounting is messier than these fixtures, and performance here does not transfer automatically to production.
- The scenarios cover a narrow slice. They test quantitative and provenance discipline. They do not test product selection, creative work, long-horizon planning, multi-turn negotiation, or anything that requires acting in the world.
- Degraded responses are counted as failures. 12 cases produced no valid final answer. That is the right accounting for a product decision — an answer that never arrives is not a pass — but it conflates model behaviour with transport and adapter reliability.
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.