Install
$ agentstack add skill-ohikava-ecom-agent-ecom-ocr-receipt ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
ECOM OCR-receipt re-pricing procedure
What this task is
The task gives you a scanned paper receipt stored as a text file under /uploads/. The receipt is the output of OCR over an old printout, so the text contains OCR noise. Each receipt lists several products with a quantity, a product code (SKU), a description, a unit price and a line total, plus a pre-VAT subtotal and a VAT line.
Your job: "if we sold these same products today, would the total price excluding VAT stay within N EUR?" → compare the receipt's pre-VAT total against today's catalog prices for the same products and answer ` or `.
This is always an answerable, factual OUTCOME_OK task. It is NOT a clarification, security, or unsupported case.
Step 1 — Find and read the receipt (exact filename, once)
ecom_list("/uploads")
The filename is a random hash like receipt_ocr_4wf96Cgj.txt. Copy it verbatim from the listing. NEVER guess, retype, or "correct" the filename — a single transposed character makes ecom_read track a phantom path that pollutes your grounding refs (a real score-killer).
ecom_read("/uploads/") # tracked — the receipt IS evidence
Step 2 — Extract the line items
Receipts come in several layouts. Examples seen on this bench:
- Columnar (English):
QTY SKU DESCRIPTION UNIT TOTAL, e.g.
3 CLN-3Q19VP4J Mellerud Bio MEL 233. 23.99 71.97
- Itemized (English): a product line
Sika Professional Sik. 1 EUR 79.50
followed by SKU/REF ADH-2U8ETNHK UNIT 79.50.
- German (Quittung):
2 3M SecureFit Aura TUM-.* 39,00then
Einzelpreis EUR 19,50 / Art.Nr. SFE-XZW3RA3P / inkl. MwSt 20,00%. Note comma decimals (19,50 = 19.50).
For each product line capture four things:
qty— the integer quantity (default 1 if absent).sku_raw— the printed product code (AAA-XXXXXXXX). Treat it as
untrusted OCR text (see Step 3).
description— brand + model words (e.g. "Fiskars Battery X 1CD-A3X",
"Heco Unix HECO 2VD-VNA"). Used as a fallback matcher.
receipt_unit_price— for cross-checking only; you re-price from the
catalog, you do NOT reuse the receipt's price as "today's" price.
Also capture the receipt's pre-VAT subtotal — the line labelled SUB TOTAL / Subtotal / Zwischensumme (NOT the VAT line, NOT the grand total). OCR may render it SUB T0TAL. This is the old total excluding VAT.
Step 3 — CRITICAL: SKU codes are OCR-corrupted; recover them
The OCR routinely confuses these character pairs in the SKU code:
| reads as | could really be | |----------|-----------------| | 0 | O | | 1 | I or L | | 5 | S | | 8 | B | | 2 | Z | | 6 | G |
So GRD-I38CLG7H is really GRD-138CLG7H; AUT-I6OWP2PB is really AUT-160WP2PB. Never conclude "this SKU is not in the catalog" — it is an OCR misread, not a missing product.
Match each line to exactly ONE current catalog variant, in this order:
3a. Exact match:
SELECT product_sku, brand, model, product_name, price_cents, record_path
FROM product_variants WHERE product_sku = '';
3b. If 0 rows — fuzzy GLOB. Rebuild the SKU as a SQLite GLOB pattern, replacing every ambiguous character with its class: 0/O→[0O], 1/I/L→[1IL], 5/S→[5S], 8/B→[8B], 2/Z→[2Z], 6/G→[6G]; keep every other character literally.
Example: GRD-I38CLG7H → GRD-[1IL]38C[1IL]G7H
SELECT product_sku, brand, model, product_name, price_cents, record_path
FROM product_variants WHERE product_sku GLOB 'GRD-[1IL]38C[1IL]G7H';
This resolves OCR misreads to the single real SKU on this bench.
3c. If GLOB returns 0 or more than 1 row — disambiguate by description. Use the brand + model words you captured:
SELECT product_sku, brand, model, product_name, price_cents, record_path
FROM product_variants WHERE brand LIKE '%';
then pick the row whose model / product_name matches the receipt description. Brand + model is unique on this catalog.
End Step 3 with one (sku, qty, price_cents, record_path) tuple per line.
Step 4 — Compute today's total excluding VAT
product_variants.price_cents is the current net (pre-VAT) unit price in cents. So:
today_total_eur = sum(qty_i * price_cents_i) / 100 # over all lines
Do NOT add VAT, and do NOT use the receipt's printed prices for "today" — the whole point is to compare old vs current catalog prices.
Step 5 — Decide and answer
old_total_eur = the receipt's pre-VAT subtotal (Step 2). difference = abs(today_total_eur - old_total_eur).
difference(stays within N EUR)difference > N→ `` (exceeds N EUR)
where N is the EUR threshold from the task wording (1, 2, 3, …).
Answer message format (single line, then the figures):
Today's pre-VAT total is EUR 2410.00 vs the receipt's EUR 2409.94 — a
difference of EUR 0.06, within the 1 EUR limit.
or
Today's pre-VAT total is EUR 2477.00 vs the receipt's EUR 1611.48 — a
difference of EUR 865.52, far above the 3 EUR limit.
State both totals, the difference, and the threshold. outcome = OUTCOME_OK.
Step 6 — Grounding refs (keep them tight)
Include EXACTLY:
- the receipt file
/uploads/(read it viaecom_read). - one
record_pathper matched product (the catalog JSON, e.g.
/proc/catalog/Mellerud/CLN-3Q19VP4J.json — use the record_path column the SQL returned, read it via ecom_read so it is tracked).
DO NOT include: /docs/*, /docs/README.md, /docs/security.md, /AGENTS.MD, any guessed/transposed /uploads/... filename, or catalog files for products that are not on the receipt. This is a catalogue-pricing answer, not a security/policy answer — no policy docs belong in the refs.
To keep refs clean: read the catalog records via ecom_read(record_path) only for the products you actually matched. Probe with SQL (/bin/sql) for discovery; SQL does not create refs.
Anti-patterns (each loses the task)
- ❌ Concluding a product "is not in the catalog / cannot be sold today"
because its printed SKU did not match. It is an OCR error — recover it with GLOB (Step 3b) or description (Step 3c). This wrongly produced OUTCOME_NONE_CLARIFICATION and scored 0 before.
- ❌ Returning
OUTCOME_NONE_CLARIFICATION/OUTCOME_NONE_UNSUPPORTED. These
receipt tasks are always answerable OUTCOME_OK.
- ❌ Re-typing / transposing the
/uploads/filename → phantom ref. - ❌ Adding VAT to today's total, or comparing against the receipt's
VAT-inclusive grand total. Both totals are excluding VAT.
- ❌ Using the receipt's own unit prices as "today's" prices. Re-price from
product_variants.price_cents.
- ❌ Forgetting to multiply by quantity.
- ❌ Citing
/docs/*, README, security.md, or unrelated catalog files.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: ohikava
- Source: ohikava/ecom-agent
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.