Two AI coding paths. One invoice. Same two reviewers.
I keep walking into planning rooms where an engineering manager has already split the stack: a free path for spikes, a paid or self-hosted path for the product monorepo. Nobody mapped repos to paths. Three weeks later the paid path looks unused, the free path is touching customer-adjacent services, and review time has quietly doubled. Finance still thinks the experiment is cheap. The calendar knows otherwise.
Would you keep both paths after that meeting? I would not. Not without a written split, a leak number, and a date when the exception dies.
The constraint that actually reverses the decision
Token price will not save you here. Seat price will not either. The scarce resource is review hours colliding with data class.
Free paths win on onboarding speed. Paid and self-hosted paths win on boundary control. Run both without rules and you do not get both benefits. You get the incentives of the easy path plus the blast radius of the hard one. Sound familiar?
This article is a fit score for that split. It is a conversation tool, not objective truth. If one field flips, the recommendation should flip with it.
Define the seven fields before you argue tools
Write the variables down. If a field has no owner, it is not a field. It is a vibe.
- data_class — Highest sensitivity allowed on the free path. Public and disposable sandbox scores high. Restricted customer data scores zero.
- autonomy — What the agent may do. Suggest-only or pull request with required review scores high. Direct writes to the default branch score zero.
- review_hours — Slack in the review budget, in hours per week, after the current queue. No slack means the free path is a tax, not a gift.
- onboarding_days — Calendar days for a new hire to land a useful diff on the paid or self-hosted path. If that path is a maze, people will leak back to the free one.
- leak_pct — Share of product-repo pull requests in the last 14 days that used the free path or a personal key. This is the field most teams refuse to measure.
- switch_days — Engineering days to enforce the split with policy plus CI, not a Slack announcement.
- owner_expiry — Named human plus a date no more than 60 days out. No owner, no expiry, score zero.
Score each field 0–3. I treat 0 as a hard stop on that dimension, not as a soft minus.
The fit table, not a winner's podium
| Track | Where it belongs | What it is for | Kill it when |
|---|---|---|---|
| A: free hosted models and free server | Public, throwaway, or clearly internal sandbox repos | Speed to first diff, architecture spikes, onboarding drills | Restricted data appears, or product-repo leak_pct leaves 0% |
| B: paid private tenant or self-hosted | Product services, customer data, default-branch risk | Bounded context, audit trail, stable policy | Reviewers cannot finish the queue even after the split |
| C: stop | No named owner, no review slack, no data-class map | You do not have an AI coding path. You have unreviewed text | Any team that wants a third unofficial tool |
Track A is not "the cheap stack." Track B is not "the serious stack." They are different products serving different repos. If you cannot say which repo is on which track in one sentence, you are already on Track C and pretending otherwise.
Worked example: a 12-person team, labeled as an example
This is a filled example for a conversation, not a customer report. Do not copy the numbers into a board deck as evidence.
- 12 engineers, 3 staff reviewers
- Review budget: 15 hours / week after meetings
- 4 sandbox repos that should be Track A
- 2 product services with customer records that must be Track B
- Last 14 days: 18 extra sandbox diffs, about 20 minutes of review each → 6 hours
- Product-repo leak_pct: 12% still used the sandbox path
- Paid path onboarding_days: 9 (SSO plus repo allowlist plus a stale runbook)
- switch_days to add a classifier and CODEOWNERS: 4
- Owner: platform lead. Expiry: 45 days
Scores I would put on the whiteboard:
- data_class: 1 (product leak means the free path is not actually sandbox-only)
- autonomy: 2 (pull requests, but one bot can still open stacks of them)
- review_hours: 1 (6 extra hours against a 15-hour budget is not fatal, but it is not slack)
- onboarding_days: 1 (nine days is long enough for people to keep personal keys)
- leak_pct: 0 (12% on a product repo is a gate fail, not a yellow flag)
- switch_days: 2 (four days is doable)
- owner_expiry: 3 (named owner, date inside 60 days)
Total: 10, with two zeros. Recommendation: do not keep dual path this week. Close Track A on anything that can see product data. Rebuild the sandbox allowlist. Measure leak_pct again in 14 days. Only then reopen Track A.
If leak_pct had been 0% and data_class had been 3, the same team could keep both tracks. That is the point. One field reversed the split. The invoice did not.
Sensitivity: which threshold kills dual path?
Hold every field constant and move one. That is the only sensitivity analysis this score needs.
- leak_pct 0% → 10%: dual path dies. You are laundering product work through the easy path.
- review_hours 3 → 0: dual path dies even with perfect data class. You are buying diffs you cannot read.
- onboarding_days 3 → 0: dual path dies later, not today. People will keep personal tools until Track B is day-one usable.
- switch_days 3 → 0: do not announce a split you cannot enforce. Announcements without CI become folklore.
- data_class 3 → 0: no debate. Restricted data on a free remote path is an exit, not a meeting.
Break-even in review hours, still as an example: if Track A adds 6 review hours a week, and a fully loaded reviewer hour is an internal $150 planning number, that is $900 a week of attention. Compare that to whatever you actually pay for Track B. If Track B is more expensive in cash but cheaper in review contention and it passes data_class, cash is not the scarce resource. Stop pretending it is.
A scorer you can run this afternoon
Label this as a checklist with arithmetic. It will not bless a vendor. It will stop a vague argument.
# dual_path_fit.py
# Conversation tool. Not a procurement oracle.
from dataclasses import dataclass
@dataclass
class Scores:
data_class: int
autonomy: int
review_hours: int
onboarding_days: int
leak_pct: int
switch_days: int
owner_expiry: int
def as_dict(self):
return self.__dict__.copy()
HARD_STOPS = ("data_class", "leak_pct", "autonomy")
def recommend(s: Scores) -> str:
d = s.as_dict()
if any(v < 0 or v > 3 for v in d.values()):
raise ValueError("each field must be 0..3")
if any(d[k] == 0 for k in HARD_STOPS):
return (
"B_ONLY_OR_STOP: data_class, leak_pct, or autonomy is a hard stop. "
"Do not keep a free path on product repos."
)
total = sum(d.values())
if total >= 15 and d["review_hours"] >= 2 and d["owner_expiry"] >= 2:
return (
"DUAL_PATH: Track A for public/sandbox only; "
"Track B for product. Recompute leak_pct in 14 days."
)
if total >= 10:
return "SINGLE_TRACK_B: paid or self-hosted only until onboarding and review slack recover."
return "STOP: no named owner, no slack, or no map. Do not scale a third tool."
if __name__ == "__main__":
example = Scores(
data_class=1,
autonomy=2,
review_hours=1,
onboarding_days=1,
leak_pct=0,
switch_days=2,
owner_expiry=3,
)
print(sum(example.as_dict().values()), recommend(example))
Run it:
python3 dual_path_fit.py
You should see a hard stop, not a pep talk. If your real scores print DUAL_PATH while product repos still accept the free endpoint, the script is not wrong. Your inputs are.
Enforce the split in the repo, not in Slack
A policy file is cheaper than another all-hands. Keep it boring.
# ai-path-policy.yml
owner: platform-lead
expires_on: 2026-10-20
tracks:
A_free:
repos: ["sandbox-*", "spikes/*"]
data_class: [public, internal-sandbox]
autonomy: pull_request_required
B_paid_or_self_hosted:
repos: ["billing-service", "customer-api"]
data_class: [restricted]
autonomy: pull_request_required
hard_gates:
- no_default_branch_writes
- product_repo_leak_pct_max: 0
- recompute_every_days: 14
Then fail the build when a product repo still points at the free endpoint. This is a classifier, not a security novel.
# ci/check-ai-path.sh
set -euo pipefail
REPO="${GITHUB_REPOSITORY##*/}"
ENDPOINT="${AI_ENDPOINT:-}"
if grep -qx "$REPO" <<'REPOS'
billing-service
customer-api
REPOS
then
case "$ENDPOINT" in
*free*|*sandbox*)
echo "Track B repo cannot use the free path endpoint"
exit 1
;;
esac
fi
Is this elegant? No. Does it beat a wiki page that nobody reads? Yes.
Hard gates, owner, expiry, exit
These are not scoring dimensions. They are stops.
- Hard gate: restricted data never rides a free remote path.
- Hard gate: no agent writes to the default branch on either track.
- Hard gate: if product-repo leak_pct is above 0% for two windows, freeze Track A.
- Owner: the platform lead, named in the YAML, not "the AI working group."
- Expiry: 60 days or less. Dual path is an exception with a date, not a architecture.
- Exit: delete the free endpoint from product CI, revoke personal keys that touched Track B repos, and recompute onboarding_days before you reopen anything.
If you cannot name the person who will kill Track A, you do not have a dual path. You have drift with a slide title.
Where a free hosted path still belongs
Track A is real. It belongs on public sandboxes, throwaway spikes, and onboarding drills where the worst case is wasted review time, not a data-class incident.
Disclosure: This article was prepared as part of MonkeyCode's product outreach. MonkeyCode is an open-source project with free model access and a free server option. That pair is one way to stand up Track A without pretending Track A is also Track B. I would still fill the seven fields before anyone points a product repo at it. I would not use a free remote path as a stealth tenant for customer data, and I would not treat "it booted" as an adoption win.
If you want a sandbox to run this split against, use a free path only on repos that already pass data_class. Score leak_pct two weeks later. Keep the product work on paid or self-hosted iron.
Who should not use this
Skip this score if you already banned remote inference. You do not need a dual-path model. You need a self-hosted decision and a review budget.
Skip it if there is no platform owner. A 7-field table in a team without an owner becomes fan fiction.
Skip it if you are trying to bake off model quality. This artifact does not measure completion quality, latency, or token economics. Those are different papers, and they will lie to you if data_class is already a zero.
Skip it in regulated workflows that need a vendor DPA, residency proof, or an audit trail you can hand to counsel. A fit score is not that packet.
And skip a third unofficial tool while you argue this. Dual path is already one path too many when leak_pct is unknown.
The question that matters
Which field would reverse your split this month?
If leak_pct flipped from 3 to 0, would you still defend Track A? If review_hours hit 0, would you still call the free path a developer-experience win? If onboarding_days on Track B stayed at nine, would you be honest that people will keep personal keys no matter what the wiki says?
Write the seven numbers. Put an expiry on the YAML. Then ask the room to name the field that kills the split. If nobody can name it, you are not choosing a stack. You are hoping the reviewers stay quiet.
Top comments (0)