← The Machine Room · Case file 002: KorCRM In daily use at my agency · Sheet 1 of 9
Case file: KorCRM, from a new brief to a sent proposal Drawing no. AH-CS-002

Proposals arrive as three scored drafts, and a person approves the best before it is sent.

A system for agencies that win work with written proposals. It reads each brief, writes three drafts and has an AI from another company score them on eight criteria, so no model grades its own writing.

New brief → fit grade → three drafts → scored by a second AI → weak part rewritten → approved and sent by a person
8criteria every draft is scored on, each at 4 of 5 or better to pass Verified: mechanism
3 drafts
For every brief that fits your agency, each scored on eight criteria by an AI from a different company. The best one reaches a person, ready to approve and send Verified
Drawn byAbu Huraira Mukhtar
RoleSole architect and engineer
AI boundaryDrafts and scores; a person sends
Writer and judgeFrom two different AI companies
How longUnder six weeks to production
Built forMy own agency
StatusIn daily use at my agency
SourceSource code and decision records
Sheet 2 of 9: In briefThe case in four parts

01 · The short version

The problem
Every proposal started from a blank page, written by whoever had time, often late in the evening. There was no written standard to meet and no record of why a proposal won, so each one started from scratch, and its bid credits were spent either way.
What I built
A system that grades each new job for fit, writes three drafts from one plan and has an AI from a different company score every draft on eight criteria, with a rule check for stock AI phrases. If the best draft misses the bar, its weak part is rewritten, and it reaches a person with its scores.
How it went
It reached production in April 2026, under six weeks after the first commit, and has been in daily use at my agency. Each draft reaches a person already scored, and nothing goes out until that person sends it.
What you’d get
The same system on your own briefs, with your best past proposals written down as the standard every draft is scored against. AI writes and checks the drafts, and your team approves and sends every proposal.
Sheet 3 of 9: Field notesThe before-state

02 · Every proposal started from a blank page

A new job landed in the feed while the team was busy with client work. By the time someone sat down to answer it, it was evening, and the proposal started from a blank page.

Whoever wrote it read the brief once, guessed at what the client really needed and wrote one draft. Nobody checked it against a standard, because none was written down: the quality depended on who wrote it and how tired they were. Every bid also cost credits, spent whether or not the client opened it.

When a proposal won, nobody recorded why. The bid credits sat in one spreadsheet tab and the payments in another, and the lesson of last month’s win lived in someone’s memory.

So the hundredth proposal was written the same way as the first.

General notes
1. Work came from a freelance marketplace, where each bid costs credits
2. Proposals were written by the owner and the agency’s freelancers
3. Bids, credits and payments were kept in spreadsheets
4. Before-state as observed in my own agency Claimed
Fig. 1: The proposal loop, before the systemEach evening, the same four steps
Sheet 4 of 9: Before and afterOne proposal, step by step

03 · A written standard for every draft

The system puts one standard between a new job and the client: the same eight criteria and the same phrase check for every draft, and a person who approves every proposal before it is sent.

StepBeforeWith the system
Find the workSomeone scrolled the feed when they had time and chose what to bid onJob-alert emails and a browser extension bring each new job in. It is graded for fit against the agency’s profiles, and a good fit is drafted without anyone asking
Read the briefRead once, at the end of the dayRead for the client’s real problem, red flags and how serious the job is, before a word is written
WriteOne draft from a blank pageThree drafts from one plan, each opening a different way
CheckThe writer decided it was good enoughAn AI from a different company scores every draft on eight criteria, and a rule check bars 64 stock AI phrases. If the best draft misses the bar, its weak part is rewritten and scored again
SendPasted and sent, often without a second readerA person reads the best draft with its scores, approves it and sends it. The system sends nothing
LearnNothing recorded why a proposal wonEach outcome is filed against the proposal and its scores, and a win comes with a written note on why it won
Keep the booksBid credits in one tab, payments in anotherBid credits, refunds and payments post by themselves, and every change keeps an audit trail
What the reviewer sawScreens redrawn in outline, with a fictional brief and drafts
Three drafts, scoredFacsimile

Brief: Tallis & Rowe Interiors want their quotes out faster

AOpens on their problemKept4.40
BOpens on a past job4.05
COpens with a question3.60
1. Three drafts. One plan, three openings, each scored out of 5 by a judge from a different AI company. The best weighted score is kept, and the other two stay on file.
Draft A, criterion by criterionFacsimile
Stands out from the rest10%4
Names the real problem20%5
Specific to this brief15%4
Shows proof15%4
About the client10%5
Sounds like a person10%4
Strong opening15%5
Clear next step5%3 → 4
Overall 4.40 → 4.45Rule checks: 5 of 5 pass
2. The scores. Every criterion must reach 4 of 5. The ending scored 3 for a clear next step, so it was rewritten and the whole draft scored again.
Ready for reviewFacsimile

Draft A passed every check: 4.45 of 5

Two days per quote is slow, and a quote sent with last month’s prices costs you margin. Both come from the same place. … If you send me one recent quote, I will show you on a short call where each of its prices would come from.

ApproveReject
3. The review. The draft waits with its scores and checks; the rewritten ending is underlined. A person approves or rejects it, then sends it.
Sheet 5 of 9: Approval plateWhat the case rests on

04 · Scored to one standard, sent by a person

3 → 1Drafts written for each proposal, from one plan. The draft with the best weighted score goes to a personVerified
8 criteriaScored on every draft, from naming the client’s real problem to a clear next step. Each must reach 4 of 5 to passVerified: mechanism
0 stock phrasesA passing draft contains none of the 64 phrases that make a proposal read as AI-written, checked in code before any model callVerified
A person sendsThe system drafts and scores. A person approves every proposal and sends itVerified

How I’d start in your agency

I’d start with your last ten proposals: the ones that won and the ones that did not.

Together they show what a winning proposal of yours looks like, and that becomes the written standard every draft is scored against. The first version drafts into the tools your team already uses, and your team approves and sends every proposal.

Discuss a system like this
Sheet 6 of 9: General arrangementDrawing 002-A

05 · One codebase, with borders a linter enforces

KorCRM is one web app and a set of workers over one Postgres database. Jobs come in from email and a browser extension, workers on a queue grade and draft them, and the web app holds the review queue, the clients and the books.

The web app is Next.js 16, with six views named for the work: Today, Hunt, Craft, Deliver, Money and Learn. The workers run on BullMQ and Redis, and every model call goes through one LiteLLM proxy, so each stage’s model is a setting in its pipeline configuration.

Every change to a record writes an append-only audit row with who made it, when, and the values before and after.

As built
Next.js 16, React 19, strict TypeScript, Postgres through Prisma
Node workers on BullMQ and Redis; a WXT browser extension with three page extractors
22 packages: 12 platform, 9 domain, 1 orchestration Verified
Fig. 2: The system’s general arrangementFunction and package names are the source code’s
Detail A, see fig. 2, the codebase

A monolith with customs borders

One database and one deploy, split into 22 packages. The nine domain packages never import each other: reads cross a border through ports, and writes go through named flows such as submitProposal.

Chose a modular monolith with lint-enforced borders, because with one developer, a border a linter checks is a border that holds. Cost: about thirty steps of rework in May and June 2026 to put the borders in. Gained: a change to proposals cannot quietly reach into finance. Verified
Detail B, see fig. 2, the record

Money moves in one transaction

When a proposal goes out, its bid credits are debited; when credits are refunded, they come back; when a client pays, the payment becomes a transaction and updates the work log. Eleven automation rules like these fire on the changes they watch.

Chose to run each rule inside the database transaction of the change that triggers it, with an audit row, because a proposal and its credits must never disagree. Cost: every write goes through a named flow. Gained: the books and the proposals always agree, and every change shows who made it and what it was before. Verified
Sheet 7 of 9: Section A-A, one briefDrawing 002-B: cut through one run

06 · No model grades its own writing

Follow the fictional brief from sheet 4 through the drafting stages, from the job alert to the person who sends the proposal. The left edge of the drawing shows who does each step.

Fig. 3: Section A-A, one brief through the drafting stagesFictional brief; the stages, thresholds and weights are the code’s
Beat 1: a job arrives

1Arrive and grade

Job-alert emails come in through the Gmail API, and the browser extension reads the job feed, job pages and sent proposals with three extractors. Workers on a queue merge both streams into one job record. A job with no title, or a description under 40 characters, is flagged for a person and never graded. The rest are graded for fit against the agency’s profiles, and a grade at the threshold, 0.60 by default, starts the drafting by itself.

Beat 2: think before writing

2Read, then plan

The brief is read for the client’s real problem, red flags and a job-quality score. A planning stage on Claude then chooses the opening, the framing, the proof point and the structure. Planning is its own stage, so all three drafts argue from the same plan.

Beat 3: one plan, three drafts

3Write three

Claude writes three drafts in parallel from the same plan, each phrased differently at temperature 0.8. The budget tier writes one draft to save cost.

Beat 4: the judge works for another company

4Score each

A GPT judge scores every draft from 1 to 5 on eight weighted criteria, and code runs five rule checks at no cost: 64 stock phrases, sentence-length variety, “you” against “I”, length and the opening word. The writer and the judge come from different AI companies, so no draft is scored by the model that wrote it. The best weighted score is kept.

Draft A leads at 4.40, but its ending scores 3 for a clear next step.

Beat 5: the bar is arithmetic

5Fix the weak part

A draft passes when all eight criteria reach 4, no stock phrase appears and the weighted score reaches 3.5. A draft that misses is rewritten on its weak criteria and scored again from scratch, up to two times. Here one rewrite lifts the ending to 4 and the draft to 4.45.

Beat 6: a person, then the record

6Approve and send

The draft lands in the review queue with its scores and checks, marked if it still missed after two rewrites. A person approves or rejects it and sends it on the marketplace. Each outcome, from opened to hired or lost, is filed against the proposal, and each evaluation keeps the weights it was scored with, so old scores never change. A win triggers a written note on why it won. Nothing is sent until a person sends it.

Detail C, see sheet 7, step 4

A judge from another company

Claude plans and writes; a GPT model judges. Both sit behind one LiteLLM proxy, so moving a stage to another model is a configuration change.

Chose a judge from a different AI company than the writer, because a model grading its own writing tends to favour it. Cost: two providers to pay and to hold keys for. Gained: no draft is scored by the model that wrote it.
Detail D, see sheet 7, steps 1 and 4

Rules before models

Anything a rule can decide is decided in code: the five checks on every draft, and the data gate that keeps a job with no description away from the grading model.

Chose code for every check a rule can make, because a rule gives the same answer every time, at no cost. Cost: the list of stock phrases is kept by hand. Gained: the hard rules never wait on a model’s judgment, and an empty job costs nothing to reject.
Sheet 8 of 9: Revision historyTraced to commits and decisions

07 · Each finding settled at its cause

Each row is a finding from building and running the system, settled where it started.

Most became standing rules, checked by the linter or by the code on every run. Each row traces to a commit, a decision record or the changelog.

Rev.
Part, date
What we found
What changed
Trace
A
Platform
2026-03
The prototypeThe first build ran on Google Sheets and Apps Script. Five weeks in, a spreadsheet could not hold the automation and reporting the agency needed.
Rebuilt earlyReplaced by a Postgres and Next.js web app, released on 30 March 2026 and in production that April.
Changelog 2.0.0
B
Intake
2026-05
Filtered mailA Gmail filter that moves job alerts out of the inbox hid them from intake: the watch, the history read and the fallback search all looked at the inbox.
Read the whole mailboxAll three became label-agnostic, so job alerts are picked by sender and shape wherever a filter files them.
Commit b842215
C
Architecture
2026-05 to 06
BordersAs the codebase grew, imports tangled, and service tests that mocked the database could pass while production differed.
Packages and real data22 packages, with the boundary lint raised from warning to error; every mocked service test replaced by tests on a real Postgres; one facade replaced by named flows.
ADR-185 to ADR-193
D
Grading
2026-06
Empty jobsJobs that arrived without a description were still sent to the grading model, which spent tokens scoring almost no text.
A data gateA job is graded when it has a title and a description of 40 characters or more. Anything less is flagged for a person, at no model cost.
Commit 99d077e
E
Model output
2026-06
A model’s answer as a keyThe grading model names the agency profile that fits a job best, and that name went straight into a database key.
Checked before storingThe answer is stored when it names one of the agency’s own profiles; any other answer is stored as empty.
Commit 6fc5707
Engineering recordChecked in the source code
22Packages in one codebase: nine business domains that never import each other, twelve platform packages and one orchestration packageVerified
11Automation rules on the money side, each inside the database transaction of the change that triggers it, each writing an audit rowVerified
64Stock AI phrases on the rule list, from “delve” to “I’d love to”, checked in code before any model callVerified
Sheet 9 of 9: Close-outFor your agency

08 · What a version for your agency adds

Every draft the system writes is scored against one written standard, and a person approves every proposal before it is sent.

A version for your agency starts from the same method, with three drafts scored by a judge from another AI company and a person on every send, and adds what your team needs.

Scope
Built for: my own agency
Work: bids on a freelance marketplace
Drafts: three per proposal on the standard tier
Sending: a person, every time
Row
Part
As built
Your version adds
A
Intake
Job alertsJob-alert emails and a browser extension on one freelance marketplace
Your channelsBriefs from your inbox, your website form or your CRM, read the same way
B
Standard
Eight criteriaOne agency’s standard: eight weighted criteria, each at 4 of 5 to pass
Your standardCriteria and weights written from your own winning proposals
C
Voice
64 stock phrases barredA list of phrases no passing draft may contain
Your house styleYour own banned words, and the terms your clients expect to see
D
Review
A person on every sendThe best draft reaches a person with its scores; the person approves it and sends it
Your sign-offThe right approver for each client or deal size, with every decision logged
E
Learning
Outcomes on fileEach outcome filed against the proposal and the scores that sent it; each win gets a note on why it won
Monthly re-weightingThe criteria re-weighted each month from your wins, each new version approved by you
F
Documents
ProposalsProposals for marketplace bids
Your other documentsPitch decks, statements of work and follow-ups drafted to the same standard
Discuss a system like this
Drawn & built by
Abu Huraira Mukhtar, sole developer, 2026
A. H. M.
Sheet 9 of 9
End of case file 002
The Drawing Office: after hours

Give your team its evenings back, and keep the final say on every proposal.

If your proposals still start from a blank page, the fix starts with your last ten, the ones that won and the ones that did not. Bring them.

Contact me Back to the Machine Room
Next case file: 003 EHR Behavioral Sheet 1 of 9