Skip to content
LedgrLive · Vietnam

The AI reads the contract. The rules make the call.

A copilot for the one person doing HR, payroll and tax at a small Vietnamese company.

Ledgr home page on a laptop
Role
Founder · product and build
Company
Personal
Period
Personal project
Stack
Next.js, TypeScript, Supabase, Anthropic Claude SDK

Context

The problem

At a 10–50 person Vietnamese company, one person often runs HR, operations and payroll at once. Vietnam updates minimum wage, social insurance, overtime and tax rules by decree, and most small companies cannot afford a compliance specialist to keep up.

The tempting fix is a chatbot that "knows the law". The trouble is that a can sound certain while being wrong, and in compliance a confident wrong answer is worse than no answer.

Approach

The decision: the AI never makes the call

I split the work in two. The language model reads the document and pulls out facts: wage, probation length, overtime, clauses. A deterministic rule engine, with every limit stored next to the article it comes from, decides pass or fail. Then the model explains the result in plain Vietnamese.

The decision

Ask an AI for the answer, or keep the AI away from the verdict?

Chosen: Extract, then rules decide

The model only reads the document and pulls out facts. A rule engine with every limit stored next to its article decides pass or fail. Then the model explains the result.

Cost I accepted: Coverage grows rule by rule: 27 seeded rules across 6 document types today. The 100+ on the landing page is the roadmap, not the count.

Source: Ledgr repository: src/lib/compliance (extractor.ts, engine.ts, narrator.ts); seed migrations 20260616000002 and 20260618000001.

Who decides what

  1. 01UploadPDF, Word or image
  2. 02AI extracts factsWages, dates, clauses
  3. 03Rule engine decidesEach limit cited to its article
  4. 04AI explains the fixIn Vietnamese, with the citation
The model reads in and writes out. The legal call in the middle is plain code, so the same contract always gets the same answer.Source: Ledgr repository: src/lib/compliance (extractor.ts, engine.ts, narrator.ts)

If a wage sits exactly on the legal floor, the engine doesn't pass it. It asks a human.

Two details carry the trust. A value exactly at a limit is flagged, not passed. And when the engine cannot pin a rule (say, the contract never states its region), the finding is marked as not source-backed instead of guessed.

Cross-check

Where the real errors hide

A contract, a payroll sheet and a tax return can each pass alone and still contradict each other. So Ledgr also reads them together: the contract wage times twelve should match the income on the year-end tax return.

The public site: from the landing page to a free check, no sign-up.

Outcome

What shipped

  • Ledgr home page on a phone, with an example findings card

    Home

  • Ledgr labour-contract check page on a phone

    Labour contract check

  • Ledgr pricing page on a phone

    Pricing

The live site on a phone, in Vietnamese by default

I demoed Ledgr at Build Stuffs #33 (20 June 2026), a builders' showcase in Ho Chi Minh City, and talked it through with around 20 people there. I kept showing it at the next sessions (#34 on 4 July, #36 on 1 August).

Build Stuffs #33, 20 June 2026

Results

rules seeded across 6 document types (100+ is the roadmap)Live, seeded rules
27
people I talked it through with at Build Stuffs #33My account
~20

Source: Ledgr repository: seed migrations 20260616000002 and 20260618000001 (rules added at runtime are not counted); my own account of Build Stuffs #33, 20 June 2026.

Next project