{"schema_version":"1","site":"https://decosa.ai","id":"tariff-classification","num":"70","name":"Tariff classification memo","tool_name":"Draft a tariff classification memo","short":"Tariff memo","blurb":"For customs brokers and importers' trade-compliance teams. Describe a product. It searches public CBP rulings on similar products and the HTS text of the candidate headings, and an open model proposes a heading, subheading and statistical number with the General Rules of Interpretation it applied. Code checks that every code is printed in the current HTS release and that every quote from a ruling is found word for word in the text it retrieved. When the description leaves out a fact the code turns on, or the evidence is thin, it says so and sends it to a broker. You get a memo and a signed record naming the ruling set and the index it searched. A research aid: a licensed broker decides.","status":"live","labels":{"industry":["compliance-trust"],"job":["review","draft"],"input":["text"],"deploy":["hosted","selfhost"],"status":"live","output":["record","text"],"data":["confidential"],"hardware":"gpu-96","licence":"permissive"},"industries":["compliance-trust"],"runs_in":["hosted","selfhost"],"part_of":[],"built_from":["evidence-retrieval","signed-record"],"models":"Qwen3.8-27B (the proposal); Qwen3 embedder and reranker (the search over rulings)","where":"Hosted or self-host","hardware":"1x RTX PRO 6000 (96 GB) for Qwen3.8-27B; the embedder and reranker fit in about 10 GB beside it or on a second card; the checks and signing run on CPU","final_artifact":"A classification memo in Markdown for a broker (proposed code or 'needs a broker', GRI reasoning, verified quotes, alternatives) and a signed memo record.","self_host_first":false,"verification":{"receipt_coverage":"full","summary":"Receipt per model call; signed search receipts with the ruling-set index hash; every ruling quote verified word for word with its byte offsets; codes checked against the HTS release; signed hash-chained memo record","manual_qa":{"hosted":{"date":"2026-09-27","result":"pass","p50_ms":32130,"p95_ms":null,"runs":null,"receipts_per_run":1,"cost_per_run_usd":0.0041},"selfhost":{"date":"2026-09-27","result":"pass","method":"fresh clone into a clean directory, the api image built from it, compose up (named volume), rehearsal bundle and the heater sample against the already-running local Qwen3.8-27B (direct route) and decosa-retrieval services","notes":"9/9 rehearsal checks with the bundled 198-ruling sample set; receipts attested. The retrieval container build and the one-hour ruling fetch in the assemble prompt were not re-run in the sandbox (no new GPU loads; the fetch ran on the host)."},"known_limits":["Hosted verification ran on the pre-release server (decosa-api the pre-release branch on our server, gateway route). The production API gets this tool when the branch merges.","The eval asks about products CBP already ruled on, described in CBP's own words; real product sheets are vaguer, so expect more 'needs a broker'.","Older rulings cite statistical numbers that no longer exist; the memo keeps the valid 8- or 6-digit prefix and flags it.","1,992 rulings in 35 headings; a product outside those chapters gets thin evidence and goes to a broker."],"nightly_covers":null},"nightly":"https://api.decosa.ai/verify/status"},"eval_summary":{"metrics":[{"name":"Memo top-1 subheading (6-digit)","value":"145 / 200","unit":null,"n":200,"split":"test","note":"held-out CBP rulings, run once; the index excludes them and their near duplicates"},{"name":"Memo top-1 heading (4-digit)","value":"171 / 200","unit":null,"n":200,"split":"test","note":null},{"name":"Memo top-3 subheading","value":"172 / 200","unit":null,"n":200,"split":"test","note":"proposal plus up to two alternatives"},{"name":"Memo top-3 heading","value":"187 / 200","unit":null,"n":200,"split":"test","note":null},{"name":"Proposed (not sent to a broker)","value":"108 / 200","unit":null,"n":200,"split":"test","note":"subheading right on 81% of these"},{"name":"Same model without retrieval, top-1 subheading","value":"57 / 200","unit":null,"n":200,"split":"test","note":"baseline: description and the GRI only"},{"name":"Rulings' vote, hybrid + rerank, top-1 subheading","value":"118 / 200","unit":null,"n":200,"split":"test","note":"baseline: no model, the codes of the top 5 rulings"},{"name":"Rulings' vote, BM25, top-1 subheading","value":"116 / 200","unit":null,"n":200,"split":"test","note":"baseline: no embedder, no reranker"},{"name":"Ruling quotes verified word for word","value":"415 / 429","unit":null,"n":429,"split":"test","note":"unverified quotes send the memo to a broker"}],"dataset":"CBP CROSS New York classification rulings since 2018 (public domain), 35 headings in 11 chapters: 200 held-out test and 60 dev rulings; the index holds the other rulings minus near duplicates.","held_out":true,"caveats":["Queries are CBP's own product descriptions from the rulings, cut before the classification paragraphs and with codes masked; real product sheets are vaguer.","Gold is the code CBP gave, which can be older than the 2026 HTS release; accuracy is scored at 4 and 6 digits only.","One subset of CROSS (35 headings); rulings on the same product line by the same requester can remain in the index when their descriptions differ.","A broker's judgment on the memos that went to a broker was not measured."],"date":"2026-09-27","doc_url":"https://decosa.ai/metrics/evals/tariff-classification"},"stack":{"summary":"For customs brokers and importers' trade-compliance teams. It searches public CBP New York rulings and the HTS text of the candidate headings, an open model proposes a heading, subheading and statistical number with the General Rules of Interpretation it applied, and code checks every code against the HTS release and every quote against the ruling text it retrieved. When a fact the code turns on is missing, or the evidence is thin, it says so. A research aid: a licensed broker decides.","tagline":"A product description in; CBP rulings on similar products, a proposed HTS code with the GRI and word-for-word quotes, or a clear 'needs a broker', out.","deployment":"hosted-or-self-host","regulatory_note":"Checked 27 Sep 2026. Importers must use reasonable care to classify (19 U.S.C. 1484, https://www.law.cornell.edu/uscode/text/19/1484); binding rulings come only from CBP under 19 CFR Part 177 (https://www.ecfr.gov/current/title-19/chapter-I/part-177), and a ruling binds only the transaction it describes. Customs business, including classification for others, is for licensed customs brokers (19 U.S.C. 1641, https://www.law.cornell.edu/uscode/text/19/1641). The General Rules of Interpretation are quoted from the HTS (USITC, 2026 Revision 19, https://hts.usitc.gov). The memo is not a ruling, not advice, and not a filing; Chapter 99 duties (Section 301, 232, IEEPA) are not applied.","components":[{"id":"llm","role":"One call per memo: reads the rulings found, the HTS text of the candidate headings and the GRI, and proposes a heading, subheading and statistical number with quotes, or declines.","name":"Qwen3.8-27B (NVIDIA NVFP4)","hf_repo":"nvidia/Qwen3.8-27B-NVFP4","license":"Apache-2.0","params":"27.8B","quant":"NVFP4 (MLP) + FP8 (attention/GDN), FP8 KV cache, MTP speculative decoding k=3","vram_gb":57,"memory_gb_estimate":null,"engine":"vLLM 0.29.0","receipt_coverage":"strong","in_hosted_demo":true,"tiers":["lite","standard"],"alternative_to":null},{"id":"embedder","role":"Embeds the ruling set once (cached) and each product description, for the dense half of the hybrid search (BM25 is the other half).","name":"Qwen3-Embedding-0.6B","hf_repo":"Qwen/Qwen3-Embedding-0.6B","license":"Apache-2.0","params":"0.6B","quant":"BF16","vram_gb":null,"memory_gb_estimate":1.2,"engine":"transformers (services/retrieval, the evidence retrieval block)","receipt_coverage":"partial","in_hosted_demo":true,"tiers":["lite","standard"],"alternative_to":null},{"id":"reranker","role":"Scores the 40 best chunks for each description, so the rulings the model reads are the closest products, not the closest words.","name":"Qwen3-Reranker-4B","hf_repo":"Qwen/Qwen3-Reranker-4B","license":"Apache-2.0","params":"4B","quant":"BF16","vram_gb":null,"memory_gb_estimate":8.1,"engine":"transformers (services/retrieval)","receipt_coverage":"partial","in_hosted_demo":true,"tiers":["standard"],"alternative_to":null},{"id":"reranker-small","role":"The smaller reranker for a card with less memory.","name":"Qwen3-Reranker-0.6B","hf_repo":"Qwen/Qwen3-Reranker-0.6B","license":"Apache-2.0","params":"0.6B","quant":"BF16","vram_gb":null,"memory_gb_estimate":1.2,"engine":"transformers (services/retrieval, RETRIEVAL_RERANK=qwen3-rr-0.6b)","receipt_coverage":"partial","in_hosted_demo":false,"tiers":["lite"],"alternative_to":null},{"id":"checks","role":"Codes against the HTS release, codes nest, quotes word for word with byte offsets, a cited ruling at the proposed heading, rulings agree, evidence not thin; the signed record.","name":"Checks and record (decosa-api, Python)","hf_repo":null,"license":"AGPL-3.0-or-later","params":null,"quant":null,"vram_gb":0,"memory_gb_estimate":null,"engine":"CPU","receipt_coverage":"none","in_hosted_demo":true,"tiers":["lite","standard"],"alternative_to":null}],"tiers":[{"id":"lite","label":"Lite · smaller reranker","summary":"Qwen3-Reranker-0.6B instead of the 4B: about 7 GB less GPU memory. Not measured on this tool.","components":["llm","embedder","reranker-small","checks"],"hardware":"1x 80-96 GB card","quality_evidence":[{"metric":"held-out accuracy with the 0.6B reranker","value":"not measured yet","source":null}],"latency_note":"not measured","in_hosted_demo":false,"receipt_coverage":"strong","receipt_note":"Same receipts as standard.","hosting":null},{"id":"standard","label":"Standard · the hosted demo","summary":"Hybrid search with the 4B reranker, one Qwen3.8-27B call, the checks and the signed record.","components":["llm","embedder","reranker","checks"],"hardware":"1x RTX PRO 6000 Blackwell 96 GB (or the LLM and retrieval on two cards)","quality_evidence":[{"metric":"memo top-1 subheading (6-digit), held-out rulings (n=200, run once)","value":"145 / 200","source":"decosa-api docs/evals/tariff-classification.md, 2026-09-27"},{"metric":"memo top-1 heading (4-digit), held-out","value":"171 / 200","source":"decosa-api docs/evals/tariff-classification.md, 2026-09-27"},{"metric":"memo top-3 subheading, held-out","value":"172 / 200","source":"decosa-api docs/evals/tariff-classification.md, 2026-09-27"},{"metric":"memos proposed (not sent to a broker) and their subheading accuracy, held-out","value":"108 / 200 proposed; 81% right","source":"decosa-api docs/evals/tariff-classification.md, 2026-09-27"},{"metric":"same model without retrieval, top-1 subheading, held-out","value":"57 / 200","source":"decosa-api docs/evals/tariff-classification.md, 2026-09-27"},{"metric":"ruling vote alone (hybrid + rerank) / BM25 alone, top-1 subheading, held-out","value":"118 / 200 / 116 / 200","source":"decosa-api docs/evals/tariff-classification.md, 2026-09-27"}],"latency_note":"measured on our server: about half a minute per memo on shared GPUs","in_hosted_demo":true,"receipt_coverage":"strong","receipt_note":"Gateway-signed receipt for the model call; model-call receipts signed by decosa-api for the embedder and reranker; a signed search receipt with the index hash.","hosting":null}],"alternates":[],"services":[{"name":"decosa-api","port":8445,"image":"${DECOSA_REGISTRY}/decosa-api:0.1.0","purpose":"The ruling set and HTS, the checks, the record and the HTTP API (/tariff/*). No GPU."},{"name":"decosa-retrieval","port":8499,"image":null,"purpose":"The evidence retrieval block's embedder and reranker (services/retrieval). Internal only."},{"name":"decosa-llm","port":8000,"image":"${DECOSA_REGISTRY}/decosa-llm:0.1.0","purpose":"vLLM OpenAI endpoint for Qwen3.8-27B. Internal only."}],"tools":[{"name":"CBP CROSS rulings","url":"https://rulings.cbp.gov","license":"US Government work, public domain (17 U.S.C. 105)","purpose":"1,992 New York classification rulings since 2018 in 35 headings of 11 chapters, fetched 27 Sep 2026 (scripts/tariff_fetch.py); addressee and salutation removed."},{"name":"Harmonized Tariff Schedule (USITC REST export)","url":"https://hts.usitc.gov","license":"US Government work, public domain","purpose":"Headings and subheadings of the 11 chapters, and the General Rules of Interpretation, 2026 Revision 19."}],"hardware":[{"tier":"1x RTX PRO 6000 Blackwell 96 GB","fits":true,"notes":"Measured on our server: the LLM on one card, the embedder and reranker (12.4 GB peak) on the other; both fit one card by the numbers (57 + 12.4 GB), not measured together."},{"tier":"Two 48 GB cards","fits":null,"notes":"Not measured: FP8 LLM on one, retrieval on the other."}],"latency":[{"lane":"one memo, hosted (search + one model call), busy shared GPUs","typical_ms":32130,"source":"measured on our server 2026-09-27, pre-release server, gateway route"},{"lane":"index the 1,992 rulings (about 10,000 chunks), once per ruling-set version","typical_ms":141770,"source":"measured on our server 2026-09-27; cached on disk afterwards"}],"benchmark":{"title":"How often is the proposed code right?","intro":"Held-out CBP New York rulings: the product description from each ruling (tariff numbers masked, the classification paragraphs cut) against the code CBP gave. The index never holds the held-out rulings or near duplicates of them. Prompts and checks were set on 60 dev rulings; the 200 test rulings were run once.","rows":[{"label":"Memo, top-1 heading / subheading","value":"86% / 72%","detail":"n = 200; top-3 subheading 86%"},{"label":"Proposed memos only","value":"81% subheading right","detail":"108 of 200 proposed; the rest sent to a broker with the reason"},{"label":"Same model, no retrieval","value":"50% / 28%","detail":"heading / subheading, top-1"},{"label":"Rulings' vote, no model (hybrid + rerank / BM25)","value":"59% / 58%","detail":"subheading, top-1"}],"points":[{"heading":"Retrieval is most of the gain","text":"The same model with no rulings to read gets the subheading right far less often; with them it beats the rulings' own vote because it reads the product against the heading texts."},{"heading":"It declines a lot","text":"Many memos go to a broker, usually because the description lacks a fact the line turns on (fibre shares, gender, essential character) or a quote could not be verified. That is the intended direction of error, and it costs coverage."}],"source":"decosa-api docs/evals/tariff-classification.md, 2026-09-27; docs/evals/tariff-classification/test-score.json"},"notes":[]},"buyer_facts":[{"label":"What it gives you","value":"A memo: the rulings found (with the matching passages), a proposed heading, subheading and statistical number with the GRI applied and verified quotes, up to two alternatives, the facts a broker should confirm, and a signed record naming the ruling set and the index searched."},{"label":"Coverage","value":"It covers CBP New York rulings in 35 headings of 11 chapters. Chapters: 39, 42, 61, 62, 63, 64, 73, 84, 85, 94, 95. Headings: 3923, 3924, 3926, 4202, 6104, 6109, 6110, 6114, 6204, 6211, 6307, 6402, 6403, 6404, 7323, 7326, 8414, 8419, 8471, 8479, 8481, 8504, 8516, 8517, 8518, 8528, 8543, 8544, 9401, 9403, 9405, 9503, 9504, 9505, 9506. A product outside them comes back as \"out of coverage\", naming the heading it would need; a licensed customs broker can classify it. Inside them, a description that lacks a deciding fact comes back as \"needs a broker\"."},{"label":"What it does not do","value":"It does not decide, file or rule: a licensed customs broker or the importer of record decides, and only CBP issues binding rulings. It searches 1,992 New York rulings in 35 headings, not all of CROSS, and not HQ rulings, court cases or the Explanatory Notes. It does not apply Chapter 99 duties or decide origin or value."},{"label":"Data retention","value":"Nothing stored: the description lives in memory for the request. Logs carry counts and timings only."},{"label":"Evidence it keeps","value":"The record commits to the description's hash, the ruling-set hash, the HTS release, the retrieval index hash (a Merkle root over every chunk), the search and model receipts, the proposal and every check."}],"data_handling":{"page":"/data#tariff-classification","self_host":{"level":"confidential","leaves":"identifiers","summary":"Runs on your machine; by default only short identifiers or a digest go to the public services listed in external_calls."},"hosted":{"level":"operator-processed","demo_only":false,"summary":"TLS to Decosa's server, then decrypted and processed by Decosa's API server, with the open models run by NEAR AI through OpenRouter, with Reka AI as the only fallback under Decosa's account.","gpus":"operator-contracted","third_parties":[],"retention":"Nothing stored: the description lives in memory for the request. Logs carry counts and timings only.","used_for_training":false,"encrypted_while_processed":false},"sealed_tier":{"applies":false,"note":"The sealed tier (raw chat only, never use-case pipelines) is paused at launch (/docs/sealed-tier)."},"external_calls":[{"to":"rulings.cbp.gov and hts.usitc.gov","route":"selfhost","sends":"identifiers","what":"Only the one-time download of the public ruling set and the HTS (scripts/tariff_fetch.py): search terms (heading numbers, product words) and ruling numbers, never a product description. The hosted service calls no outside data sources: retrieval and the model run on Decosa's hosted service.","default":"on","off":"Copy rulings.jsonl, manifest.json and hts/ from another machine into DECOSA_TARIFF_DATA and skip the fetch."}]},"console":{"href":"/tools/finance/tariff-classification","input":"tariff","lanes":[{"id":"rulings","title":"Rulings found","kind":"list"},{"id":"proposal","title":"Proposed code","kind":"list"},{"id":"checks","title":"Checks in code","kind":"list"},{"id":"record","title":"Memo record","kind":"json"}],"samples":[{"n":1,"id":"insulated-lunch-bag","title":"Insulated lunch bag","deep_link":"/tools/finance/tariff-classification?sample=1&autorun=0"},{"n":2,"id":"knit-pullover","title":"Knit pullover","deep_link":"/tools/finance/tariff-classification?sample=2&autorun=0"},{"n":3,"id":"wall-heater","title":"Wall heater","deep_link":"/tools/finance/tariff-classification?sample=3&autorun=0"},{"n":4,"id":"storage-bin","title":"Storage bin","deep_link":"/tools/finance/tariff-classification?sample=4&autorun=0"},{"n":5,"id":"vague-bag","title":"Vague bag","deep_link":"/tools/finance/tariff-classification?sample=5&autorun=0"}],"deep_link_params":{"sample":"1-based index into samples, or a sample id","autorun":"1 = start the run once the sample is loaded; 0 (default) = only preselect","reduce-motion":"1 = turn off animations"}},"api":{"base":"https://api.decosa.ai","contract":"/api/contract.json","contract_markdown":"/api/contract.md","reference":"/docs/api","keys":"/account/keys"},"prompts":{"hosted":"/prompts/tariff-classification-hosted.md","selfhost":"/prompts/tariff-classification-selfhost.md","assemble":"/prompts/tariff-classification-assemble.md","mac":null},"rehearsal":{"bundle":"/samples/tariff-classification.zip","bundle_url":"https://decosa.ai/samples/tariff-classification.zip","folder":"/samples/tariff-classification/","expected":"/samples/tariff-classification/expected.json","files":["/samples/tariff-classification/coverage.json","/samples/tariff-classification/expected.json","/samples/tariff-classification/inputs/vague-bag.json","/samples/tariff-classification/inputs/wall-heater.json"],"bytes":2320,"checks":["the heater is proposed","under heading 8516","subheading 8516.29","at least one ruling quote verified word for word","a retrieved ruling was classified by CBP in 8516","the ruling search has a signed search receipt","the memo record verifies","the thin description goes to a broker","every model call has a signed receipt"],"licence":"Synthetic descriptions written for decosa-api (AGPL-3.0-or-later). The rulings searched are CBP CROSS rulings and the HTS text, US Government works in the public domain.","about":"Two synthetic product descriptions. The wall-mounted, hard-wired fan heater must be proposed under heading 8516 (subheading 8516.29) with at least one quote verified word for word in a retrieved CBP ruling; the bag described only as a bag with a strap must go to a broker. The memo record must verify. Run it against your own ruling set: the ruling numbers you see depend on the set fetched.","run":{"containers":"docker compose exec api python scripts/rehearse.py tariff-classification","checkout":"python scripts/rehearse.py tariff-classification --bundle tariff-classification.zip --base-url http://127.0.0.1:8445","mac":".venv/bin/python scripts/rehearse.py tariff-classification"},"guidance":"Set up with a coding agent (we recommend Claude Code with Claude Opus 5.5; any capable coding agent works) on mock data only, run the rehearsal until every check passes, then run your own data locally yourself. Never give the agent real data during setup."},"hardware_fit":{"check":"/self-host/hardware?use=tariff-classification","data":"/api/hardware.json","tiers":[{"id":"lite","gpu_gb":62.4,"basis":"estimate","unknown":[]},{"id":"standard","gpu_gb":70.6,"basis":"estimate","unknown":[]}],"mac":null},"links":{"page":"/tools/finance/tariff-classification","json":"/use-cases/tariff-classification.json","metrics":"/metrics/tariff-classification","console":"/tools/finance/tariff-classification","console_sample":"/tools/finance/tariff-classification?sample=1&autorun=0","stack":"/tools/finance/tariff-classification#stack","try_live":"/tools/finance/tariff-classification","watch":"/tools/finance/tariff-classification","build":"/tools/finance/tariff-classification#build","self_host":"/tools/finance/tariff-classification#self-host","prompts":{"hosted":"/prompts/tariff-classification-hosted.md","selfhost":"/prompts/tariff-classification-selfhost.md","assemble":"/prompts/tariff-classification-assemble.md","mac":null}}}