Clearline · Live product · Procurement

Kill the quote
spreadsheet.

Every procurement team on earth retypes vendor quotes into a comparison sheet, and everyone has quietly accepted it as the cost of doing business. Clearline is the system that drafts an RFx, reads whatever vendors send back, and lets a buyer interrogate the result in plain language — built, deployed and running.

Role

Product and build · end to end

Stack

LLM extraction, agentic analysis, libSQL, deployed web app

State

Live, with an eval harness

01The two weeks worth deleting

01

Day 1

The RFx is written by hand

A category buyer needs thirty line items of corrugated packaging quoted. Scope, line items, quality questionnaire and terms all get typed from scratch, every cycle.

02

Day 2–9

Vendors reply however they like

A spreadsheet that ignores the template. A PDF on letterhead with the discount buried in a footnote. A Word doc with commercials in a paragraph. A phone photo of a printed rate card, taken at an angle. And one email that just says “₹42/kg for the 5-ply, ₹38 for the 3-ply, rest same as last year, freight extra.”

03

Day 10–12

The buyer retypes all of it

Three days of copy-paste into a comparison sheet, converting units and currencies by hand — the exact work where an awarding error costs real money.

04

Day 13

One question resets the sheet

“What if we split it, cheapest per line, but only among vendors who cleared the quality questionnaire?” There goes the fourth day.

02The five formats, and the edge each one carries
VendorFormatWhat makes it hardRead
PackRite IndustriesxlsxOwn codes, own column order, lines reordered30 / 30
Global Corrugates FZEpdfUSD pricing; 4% settlement discount in a footnote30 / 30
Shakti PackagingdocxCommercials in prose; sheet pads priced per 10027 / 30
Metro Board & PackjpgAngled phone photo of a printed rate card18 / 30
Nova PacktxtTwo-line email; “rest same as last year, freight extra”4 / 30

Nova Pack is the important one. Twenty-six lines are unknown, not zero. The system quotes four and refuses the rest, because “same as last year” is not a price and this system has no last year.

03The three AI loops

01

Drafting co-pilot

Plain-language brief → structured RFx. Strict tool schema; every dimension is canonicalised to millimetres at authoring time. The model must declare, in assumptions, anything it invented that the buyer never said.

02

Extraction

One document → one filled schema. Null when a value is absent, never a guess. Every field carries a mandatory verbatim source reference. Off-schema output is rejected, not repaired. There is no field for a rank, score or recommendation.

03

Analyst Q&A

Question → query → answer. The model picks one of nine queries. The application computes every number. The model narrates. It does no arithmetic.

Both providers sit behind one module, and the loops never learn which vendor answered. The PRD claimed swapping models would touch one file; porting from Claude to Gemini mid-build was the test, and it held. The figures below were produced on gemini-3.6-flash, which reads the letterhead PDF and the angled photograph as bytes rather than as pre-converted text.

04One flow, end to end
  1. 01

    Draft the RFx by talking

    A buyer builds the request with an AI co-pilot — scope, line items, quality questionnaire, commercial terms — instead of starting from a blank template.

  2. 02

    Send it out, no format rules

    The RFx goes to vendors over a chosen channel. Nobody is forced into a template, because in practice that rule is what vendors ignore.

  3. 03

    Read whatever comes back

    Spreadsheets, letterhead PDFs, Word docs, photographed rate cards and freeform email are all extracted into structured line items, units and currencies.

  4. 04

    One normalised comparison

    Same lines, same units, same currency, side by side — with questionnaire answers and attached documents sitting next to the numbers, not in a separate folder.

  5. 05

    Interrogate it in plain language

    The buyer stops clicking and starts asking. Answers come back as text, tables and charts over the extracted data, exportable, all the way to a defensible award.

05Normalisation — three separate problems

Currency

An explicit FX table with rate, source and as-of date. A converted value always displays next to its original: ₹24.30 (from USD 0.291 @ 83.5). A quote with no stated currency is never assumed to be rupees.

Unit of measure

A declared factor table. per 100 pieces → per piece converts and shows the arithmetic. per box, where the box size is never stated, does not convert — it goes to the review queue.

Line matching

Three tiers, visually distinguished: exact when the vendor cited our line code; fuzzy via deterministic attribute scoring with no model involved; and semantic as a model proposal, never counted until a human confirms it.

06The eval harness — extraction you can measure

Why it exists

The assignment came with no sample data, so I authored a synthetic set: a 30-line RFQ and five vendor replies, each awkward in a different way, plus a sixth carrying a prompt-injection payload. The expected answers were written out separately — from the documents, not from the running system — and npm run eval scores a real extraction against them.

Graded checkExpectedProduced
Split award — cheapest per line, qualified vendors only₹4,47,16,859exact
Per-line winner and price, every line30 / 3030 / 30
Single-vendor total — PackRite₹4,63,47,510exact
Single-vendor total — Global Corrugates₹4,56,06,857exact
Coverage — PackRite / Global / Shakti / MetroBoard / NovaPack30 · 30 · 27 · 18 · 4exact
Line 1 across all five vendors, incl. the FX-converted oneexactexact
Sheet pads, per 100 pieces → per piece6.10 · 4.72exact
Apex injection document appears in the rankingnevernever

34 of 34 checks pass, alongside 28/28 pipeline integration tests and deterministic line matching at 97.1% coverage with 100% precision.

What this proves, and what it does not. I wrote both the test data and the answer key, so this is a regression harness rather than independent validation: it shows the pipeline does what I specified on the cases I chose, not that it generalises to real vendor documents. The substantive work was designing the cases. Each targets a specific way these systems fail quietly — silent FX assumptions, zero-filling unquoted lines, applying a footnote discount to unit rates, treating a missing questionnaire answer as a pass. Scoring a new document set is a single command, which is exactly what I would want next.

07Trust and security

Prompt injection

The adversarial document is a permanent regression fixture, not a claim. The structural defence is that the extraction schema has no field for a ranking or a recommendation, so there is nothing for injected text to populate. Document content is delimited, and forged boundary markers are stripped.

Provenance

Every number in the comparison carries its document and the verbatim words it came from. Click any price to see them.

Exports

Every CSV routes through one sanitiser that neutralises formula injection. There is no code path that writes a CSV without it.

Files and access

Byte-level MIME sniffing rather than trusting the extension; short-TTL HMAC-signed document links; a password gate on every route; an append-only audit log.

One case where the rule worked against me

My answer key expected Metro Board to be excluded for on-time delivery of 89.5%. That figure appears nowhere in the rate-card photograph — the card states ISO 9001, the in-house lab, lead time, payment terms and MOQ, and no delivery percentage. The system therefore excludes them as unassessable on that question rather than as failing it. Same outcome, reached from the only evidence in the file. When my expected answer and the actual document disagreed, I corrected the answer key rather than teaching the system to invent the number.

08Decisions I made, and why

Refusal over coverage

Where a value is ambiguous the line is held out of the comparison rather than shown as a number nobody has checked. The grid says when it is incomplete, and why.

The application computes; the model narrates

No total, ranking or award figure is ever produced by a language model. The model picks the query; the code runs the arithmetic.

Show provenance, not just answers

Every normalised number traces back to the vendor document it came from. A buyer with crores on the line acts on evidence, not on a confident sentence.

SQLite via libSQL

An identical code path on a laptop with zero provisioning and on a host with one environment variable. Postgres buys nothing at this scale and costs setup time.

The RFx is parsed from the buyer's own workbook

The dataset arrived after the system was built, and nothing about it is hardcoded. Seeding a new RFx is a single command.

09Out of scope, on purpose
  • —Multi-round negotiation, counter-offers and re-bids.
  • —Supplier onboarding, master data management and contract lifecycle.
  • —ERP or P2P integration; real e-signature on the award.
  • —Multi-tenant accounts and per-user roles — one shared password gates the demo.
  • —Live FX rates. The table is explicit and dated, because a silently drifting rate is worse than a stale one you can see.
10Known limitations

Free-tier hosting sleeps

After roughly 15 minutes idle, the first request takes up to a minute while the instance wakes.

Free-tier Gemini allows 20 requests per day, per model

Extracting all five documents costs five. The deploy ships a committed snapshot of a genuine extraction run so the comparison is populated on arrival; re-running live may hit the daily cap.

No persistent disk on the free plan

Work done through the hosted app is lost on the next cold start. Pointing LIBSQL_URL at a Turso database makes it durable with no code change.

Vision extraction is the weakest link

18 of 30 lines from the photograph. The remainder are reported as not-quoted rather than guessed.

Matching is tuned to this category

The attribute scorer understands ply, GSM and millimetre dimensions. A different category needs a different scorer.

11How to use it — five minutes
  1. 01

    Open the link and enter the password. The first load may take a minute while the instance wakes.

  2. 02

    RFx & responses. The buyer's requirement, parsed from their own workbook, and the five vendor documents. Each shows how many of the 30 lines were read.

  3. 03

    Comparison. Same lines, same units, same currency. The cheapest quote on each line is marked. Click any price for the source document and the exact words behind it. Toggle only vendors that cleared the questionnaire to see the gate applied.

  4. 04

    Review queue. What the system refused to decide, and why. Resolving an item releases the lines held behind it.

  5. 05

    Ask. Plain language — “cheapest split across qualified vendors”. The answer arrives with the query that produced it and the caveats attached.

  6. 06

    Award & audit. Two defensible options, what each one excludes, and the record of the decision.

A buyer should spend their week choosing the right vendor — not retyping what the vendors said.