Fourteen days. That is the number I put on the whiteboard before anyone talks about seats, token price, or a complimentary server.
Here is the scene I walk in reviews. Monday, 9:40 a.m. Two new hires are flashing laptops. Slack already has a “just use the free path” link. Paid tooling sits in a queue. Self-host is a ticket that aged four days and slipped. You still want a first reviewed PR inside ten business days. Which path goes on the image?
If you pick by sticker price, you will pick wrong. Seats are a procurement unit. They are not an onboarding unit.
Stop scoring the path with a monthly seat
A seat tells you someone can log in. It does not tell you when a diff is small enough for a tired reviewer to approve.
Honestly? Most teams are scoring the wrong object. Can a seat approve a PR? No. A reviewer can.
Would you rather ship a new hire’s first reviewed PR on day 9 with a messy free path, or wait until day 22 for a self-hosted box that nobody pagered? That is the real trade. Not “we should be using AI.”
I use one unit: days to first reviewed PR (TFRP). First commit is vanity. First reviewed PR is the moment the team accepted the work.
Five fields I actually score
This scorecard is a conversation tool. It is not objective truth. If your reviewers disagree with the weights, the disagreement is the decision.
I define the fields before I fill numbers.
- Image lag (days) — calendar days until the path is on the laptop image and a new hire can run it without a hallway ticket.
- TFRP (days) — calendar days from start date to the first PR that receives a human approve. Target is a policy, not a vibe.
- Reviewer tax (hours / hire) — extra reviewer hours in week 1–2 caused by AI-authored noise: drive-by files, missing tests, secret-shaped strings, “helpful” refactors nobody asked for.
- Data class allowed — what the new hire may paste. I use three buckets only: public, internal, secret. If the path cannot name the bucket, it fails.
- Exit hours — hours for the team to leave the path with rules, prompts, and eval fixtures still in git.
Owner, expiry, and kill criteria sit next to the numbers. A score without an owner is a poster.
Hard gates (these are not weights)
- Secrets never leave the building on a free path.
- A named human owns outages and bad diffs during onboarding week.
- The path expires on a written date. I use day 14 for new-hire cohorts.
- Exit hours are estimated before install, not after the tool becomes furniture.
Miss a hard gate and I do not score the rest. Scoring a forbidden path is how shadow tools get a logo.
Free vs paid vs self-host, on the onboarding clock
I compare three shapes. Not three brands.
Free path (hosted free-model access, sometimes a free server):
- Image lag can be hours.
- TFRP can look great in week one.
- Reviewer tax is the silent bill.
- Data class is usually the weak point.
- Exit hours stay low if you kept rules in git. They explode if setup lived in one person’s chat history.
Paid path:
- Image lag is procurement lag. That number, not the list price, kills onboarding cohorts.
- TFRP is fine once the seat exists. It is ugly if legal is still redlining.
- Reviewer tax is often lower if the workflow matches your review norms. Often. Not always.
- Data class depends on the DPA you actually signed, not the homepage.
- Exit hours are the trap. Prompt libraries rot inside a vendor UI.
Self-host:
- Image lag is your platform team’s current WIP, not the README.
- TFRP for this cohort is frequently worse than the six-month TCO slide.
- Reviewer tax depends on model quality you can actually operate at 2 a.m.
- Data class can be the reason you self-host. That is a real reason. It is not an onboarding reason.
- Exit hours are excellent if prompts already live in the repo. They are terrible if the box is a snowflake.
See the pattern? Each path wins a different field. The onboarding clock tells you which field is allowed to win this month.
Worked example (labeled, not telemetry)
I am going to fill numbers for a fictional team I call Northwind Platform. Eight engineers. Two new hires start the same Monday. Three reviewers share eight hours a week for onboarding reviews. Target TFRP is ten business days. Fully loaded reviewer hour is $150 in this arithmetic. That last number is an assumption you should replace.
Do not treat this table as a benchmark. Treat it as a spreadsheet you can argue with.
| Field | Free path | Paid (seat already approved) | Paid (still in procurement) | Self-host (ticket open 4 days) |
|---|---|---|---|---|
| Image lag (days) | 0.5 | 1 | 12 | 8 |
| TFRP (days) | 8 | 9 | 19 | 16 |
| Reviewer tax (hours/hire) | 5 | 2 | 2 | 3 |
| Data class | internal | internal, DPA-dependent | internal, DPA-dependent | internal + secret possible |
| Exit hours | 4 if rules in git, 20 if not | 16 | 16 | 6 |
| Secrets hard-gate | fail if anyone pastes .env
|
depends | depends | pass only with an allowlist |
| Named owner | often missing | vendor + champion | nobody yet | platform team (you) |
Two-hire reviewer tax on the free path: 10 hours. At $150, that is $1,500 of onboarding review you will not get back. The free path still wins TFRP (8 vs 16 vs 19). If your only KPI is “they opened the tool,” free looks like a gift. If your KPI is “reviewed PR by day 10 without burning the reviewers,” you now have a fight.
I score with a simple weighted sum I can run in a repo. Weights are opinions. Change them.
# proposal: TFRP fit card — conversation tool, not a ranking engine
# labeled example only; replace the dicts with your numbers
WEIGHTS = {
"image_lag": -1.0, # days; lower is better
"tfrp": -2.0, # days; this is the onboarding unit
"reviewer_tax": -1.5, # hours per hire
"exit_hours": -0.5,
}
def hard_gates(path):
if path.get("data_class") == "secret" and path.get("shape") == "free":
return "FAIL: secrets on a free path"
if not path.get("owner"):
return "FAIL: no named owner"
if not path.get("expiry"):
return "FAIL: no expiry date"
if path.get("exit_hours") is None:
return "FAIL: no exit invoice"
return "PASS"
def fit(path):
gate = hard_gates(path)
if gate != "PASS":
return gate, None
score = (
WEIGHTS["image_lag"] * path["image_lag"]
+ WEIGHTS["tfrp"] * path["tfrp"]
+ WEIGHTS["reviewer_tax"] * path["reviewer_tax"]
+ WEIGHTS["exit_hours"] * path["exit_hours"]
)
return gate, score
northwind_free = {
"shape": "free",
"image_lag": 0.5,
"tfrp": 8,
"reviewer_tax": 5,
"exit_hours": 4,
"data_class": "internal",
"owner": "A. Rivera, EM",
"expiry": "day-14",
}
print(fit(northwind_free))
Run it after you replace the dict. If you cannot name owner and expiry, the script should refuse to score. That refusal is the product.
# labeled example: portable rules lived in git, or they did not
git ls-files '*rules*' '*prompts*' '*eval*' | head
test -f .ai-onboarding.yml && echo "POLICY_PRESENT" || echo "POLICY_MISSING"
If POLICY_MISSING, I do not let a new hire “just try something.” That is how you get three prompt dialects by Friday.
Sensitivity: which number actually flips the call
I do not ask “would you buy the tool?” I ask which threshold reverses you.
- If paid image lag > 7 days, the free path wins this cohort on TFRP even with an uglier reviewer tax. Procurement is the decision, not the model.
- If free-path reviewer tax > 6 hours per hire, I stop putting it on the image. You are paying reviewers to unscrew onboarding.
- If self-host TFRP > target + 4, self-host is a platform investment for the next cohort. It is not an onboarding plan for Monday.
- If exit hours > 16 on the paid path, I will not put it on the image without an export fixture in git. Lock-in during week one is how tools become accidental policy.
- If data class cannot be named, every other field is decoration.
Flip one row in the table and the winner changes. That is the point of a card. A card that cannot lose is a brochure.
Break-even in one line
Let R be the reviewer-tax difference in hours and C be fully loaded reviewer cost.
If R * C * hires exceeds the paid seat cost covering the same two weeks, “free” was a financing trick. You financed onboarding with reviewer overtime.
Northwind: (5 - 2) * 150 * 2 = 900. If two weeks of paid seats cost less than $900 and image lag is already zero, paid can win on P&L even when the free path wins on pride. If paid seats cost more, free still has to clear the secret gate.
Replace 150. If your reviewer hour is 80, the break-even moves. If it is 250, it moves the other way. The formula stays.
Want a faster check? Plug your own three numbers and stop debating brands.
python3 - <<'PY'
R, C, hires, paid_two_weeks = 3, 150, 2, 800
print("reviewer_tax_dollar", R * C * hires)
print("free_still_cheaper", (R * C * hires) < paid_two_weeks)
PY
Owner, expiry, exit — write them like a policy
I want a file in the repo. Not a wiki paragraph that dies in Q4.
# .ai-onboarding.yml — proposal, not a standard
cohort: northwind-2026-09-10
unit: days_to_first_reviewed_pr
target_tfrp_days: 10
owner: A. Rivera
expiry: 2026-09-24
hard_gates:
- no_secrets_on_free_path
- named_owner
- written_exit_hours
paths:
free:
allowed_data_class: internal
exit_hours: 4
kill_if:
tfrp_miss_days_gt: 4
reviewer_tax_hours_gt: 6
paid:
allowed_data_class: internal
requires: existing_approval
self_host:
allowed_data_class: internal
not_for_this_cohort_if_tfrp_gt: 14
exit:
keep_in_git: [rules, prompts, eval_fixtures]
success: first_reviewed_pr_by_target
fail: revert_laptop_image
Expiry is a date. “We will see how it feels” is how free paths become unowned infrastructure.
Exit criteria I actually write:
- Keep: TFRP hit, reviewer tax under the cap, secrets never appeared in prompts, rules live in git.
- Convert: TFRP hit but data class is about to tighten — move the cohort, keep the fixtures.
- Kill: TFRP miss plus reviewer tax over cap, or any secret paste, or owner goes on PTO with no deputy.
Who owns the file? The EM for the cohort. Not “platform,” not “AI,” not a rotating intern.
Where a free-model path and a free server actually fit
Sometimes the free path is the only way to hit a ten-day TFRP because procurement will not move. That is a constraint. Honor it. Then still run the gates.
Disclosure: This article was prepared as part of MonkeyCode's product outreach.
MonkeyCode is one open-source option I will put into this comparison when a team needs free model access and a free server option to collapse image lag. Availability of those two things can zero out Monday-morning setup. It does not zero out reviewer tax, data class, named owner, or the exit invoice. If those fail, it stays off the laptop image.
I do not treat a free server as a platform. I treat it as a path that must earn day 14.
If you want a concrete free-path input for the same card, run MonkeyCode against the Day-14 gates and keep or kill it on TFRP and reviewer tax — not on the landing page.
Who should not use this card
- Solo hobbyists. You do not have a reviewer tax. Use whatever you want.
- Orgs that already banned cloud prompts. Your hard gate already fired. Stop scoring.
- Teams that cannot name an owner for fourteen days. You are not ready for a path. You are ready for a pause.
- Anyone trying to prove a vendor is “the winner.” This card will not do that, and it should not.
Limitations are boring, so I will be blunt. I have no telemetry for your team. The Northwind numbers are a filled example. Weights are opinions. TFRP ignores product-management wait time, flaky CI, and the new hire who is actually stuck on VPN. If those dominate, fix those first. An AI path will not.
I also will not use this card to greenlight secret-bearing production work on any free path. Onboarding is a smaller blast area. Production is not.
What would reverse you?
Not “do you like the tool.”
Which variable. Which threshold.
If image lag on paid dropped to zero tomorrow, would you still put a free path on the new-hire image? If reviewer tax on free fell to one hour because your repo rules are good, would self-host still be worth slipping TFRP? If exit hours on paid were two, not sixteen, would lock-in still scare you?
Write the number that reverses you next to the expiry date. Then go watch the first reviewed PR, not the first chat transcript.
Top comments (0)