Kimi K3 vs Fable vs Sol on a Normal Debug: The Cheapest Model Wasn't Cheap

TL;DR
Same real debug, three models, one answer. The cheapest model per token (Kimi K3) cost about the same to actually run as the pricey two, and took more than twice as long. Price your models by the outcome, not the token.
| Model | Tokens | Fresh / Cached / Output | Est. cost | Wall-clock |
|---|---|---|---|---|
| GPT-5.6 Sol | ~800K | 60K / 540K / 200K | ~$6.60 | ~21 min |
| Kimi K3 | ~2.9M | 240K / 2.185M / 475K | ~$8.50 | ~51 min |
| Claude Fable 5 | ~650K | 49K / 439K / 163K | ~$9.10 | ~27 min |
Cheapest per token, dearest to run. Token totals and times are real; the split and cache-hit rate are approximations.
Right, this one is not a shotclubhouse ops story. This was my own Mac, my own Saturday.
Here is what kept happening. Every fifteen minutes or so, Arc would throw up a Tailscale login prompt. On its own. Nobody touched anything. It never actually logged in, it just appeared, sat there, and buggered off. And that same Arc window had the little "your screen is being shared" dot lit up in the menu bar. A login prompt I did not ask for, plus a sharing indicator I could not explain, on a clock. Not a great look.
A bit scary. Could be a compromise. So the first thing on my mind was not "debug it", it was how do I stop the bleeding, without torching the evidence. No panic-reboot, no uninstalling Arc or Tailscale, because that wipes the exact volatile state you need to work out what happened. Contain, do not cremate.
My first go-to was Claude Fable 5, on xhigh. I wrote the problem up as one cold prompt, no hints, no reveal, and I did not want a lecture on what I could check. I wanted it to actually do the work. So I turned it loose in an agentic harness and let it run the whole triage itself, contain, dig, trace, find the cause, no hand-holding from me. Fable drove through it end to end, landed on the cause, and eased my concern enough that I could go and reproduce the situation myself. Once I had it reproducing on demand, I turned GPT-5.6 "Sol" and Kimi K3 loose on the exact same cold prompt, same harness, same free rein, the cheap model against the two pricey ones.
I will say this up front so you can enjoy it on the way through: the root cause turned out to be really silly, and on hindsight I end up looking like a bit of an idiot. Worth it.
The prompt, roughly: Mac, possible compromise, Arc keeps opening a Tailscale login every 15 minutes, screen-sharing indicator is on. Contain it safely first, then investigate and find what is triggering it. Do the work yourself, do not just hand me the fix.
How Sol and Fable operated
Both of them, credit where due, refused to jump to the fix, and neither sat there handing me a checklist to go run. They just did it. Wired into the Mac through Peekaboo for screenshots and screen reads, plus Hammerspoon and a bit of macOS-control tooling for the actual clicking, each one went straight for the sharing dot itself, because macOS names the exact app capturing the screen the moment that menu opens, and that one move collapses half the mystery. From there both went hunting for a 15-minute launcher (StartInterval of 900 seconds is the tell), and both worked to rule out the real remote-access gunk, VNC on port 5900, Screen Sharing, Remote Management, an MDM profile quietly bossing the machine about. Screenshots, log show, launchctl, the lot, driven by the model, not by me.
(On hindsight I should have just pointed the Codex app's computer-use at the whole thing, apparently that is the top dog for driving a desktop right now. But I live in a terminal, I barely open an IDE these days, so it was agentic harness plus CLI tools or nothing.)
But the interesting bit is where they diverged, because it is a proper forensics fork.
Sol went isolate-first. Except it could hardly yank the network, that was the wire it was talking to me over. So the containment was surgical instead of blunt: clamp the firewall to a single allowlist and drop everything else. Default-deny egress with pfctl, one hole punched for api.openai.com on 443 plus DNS, and nothing else leaves the box. A live attacker or a remote-control channel now has nowhere to send to, while the model keeps the one uplink it needs to stay alive and keep working. Kill Bluetooth, stop typing anything sensitive, lock the screen but keep the Mac awake, then snapshot the host with that single pipe still up. Very "assume the attacker is live, close every road out except mine."
Fable went snapshot-first. And this is the sharper instinct, honestly. Fable's whole point: the moment you clamp that firewall shut, you lose the evidence of where the data was going. So it grabbed the live sockets before narrowing the egress down to its own uplink:
sudo lsof -i -P -n > ~/Desktop/ir-lsof.txt
netstat -anv > ~/Desktop/ir-netstat.txt
ps auxww > ~/Desktop/ir-ps.txt
launchctl list > ~/Desktop/ir-launchctl.txt
Every process with an open socket and its remote endpoint. If your screen is actually leaving the box, the sender is sitting right there as an established connection with sustained traffic. Then it locked egress down to its own endpoint and nothing else. It is the difference between "stop the intruder" and "photograph the intruder leaving before you lock the door", and for a real incident, Fable's ordering is the one I would teach.
Both then converged on the same decision tree: is this the benign end (a legit Tailscale client with a dead session politely re-opening its login page every retry, plus some app holding a screen-recording permission it is not really using) or the malicious end (an unknown launchd job plus a remote-access tool)? And both were clear: a screen indicator on its own, a Tailscale permission on its own, a fixed 15-minute cadence on its own, none of those are proof of anything. You need to catch one popup in the act with the initiating process attached. Nice discipline. Suspicious until explained.
Kimi K3 on the stand
Same cold prompt, Kimi K3, same harness. And to be fair to it, the run is good. Clean, well-structured, easily the most readable of the three. Five phases, contain, snapshot, trace the Tailscale prompt, trace the screen-share, find the 15-minute timer, and a proper "what this tells us" note under every single command. If you handed this to someone who had never triaged anything, they could follow it. It hit all the same beats: lsof -i for the sockets, Arc history and log show for login.tailscale.com to find the parent process that opened the window, Screen Recording permissions plus WindowServer logs for the sharing dot, launchd and a StartInterval of 900 for the timer. It even hedged honestly in one spot ("if this yields nothing, we may need to adjust the predicate"). Solid.
But two things separate a good-looking run from a good incident response.
It fumbled the one ordering that matters. K3 led with clamping the network shut first, and treated snapshotting the live connections as an optional afterthought, gated, bizarrely, on whether I had "an external drive or USB stick handy." That is exactly backwards, and the USB bit is nonsense, you save the output to the local disk. This is the precise step Fable built its whole run around: the moment you clamp the firewall shut, you lose the evidence of where the data was going. K3 knew the step existed and then buried it under a caveat that would, in a real incident, cost you the single most important artefact. Cheap sticker. Not a cheap mistake.
No adversarial layer. K3 ran a straight linear checklist. Sol brought a red team and a blue team that argued with each other and named their own proof gap; Fable brought an explicit benign-vs-malicious decision tree and an evidence threshold ("a single indicator is not proof"). K3 gathers the evidence but never builds in the bit that stops it believing its own scary story. For a tidy report, fine. For a real "am I compromised" moment, that self-doubt is the feature you actually need.
What actually ran
All three ran autonomously, but Sol is the one I have the full receipts for, because I drove it through Codex and it left a transcript. Sol span up a two-agent team, a red_team_triage cell to hunt for compromise and a blue_team_validation cell to argue with it, and let them go at the machine.
The verdict it came back with, and I am quoting the shape of it: "automation/configuration collision, not compromise. Likelihood low, confidence 85%." The evidence it actually turned up:
- Two Tailscales fighting. A Homebrew
tailscaledon 1.86.2 and the signed GUI plus system extension on 1.94.1, both live at once. Duplicate control paths, version skew, the single most likely source of the confusing behaviour. It even caught the gotcha that the Tailscale app binary launches the GUI instead of the CLI unless you forceTAILSCALE_BE_CLI=1, which is exactly the kind of thing that spawns a phantom window. - SIP was disabled. Not evidence of compromise, but a fat exposure that makes everything worse if something did run.
- Eight Arc opens between 10:05 and 10:09 with no referrer. Local Node and LaunchServices activity lined up in time, but, and this is the honest part, it could not pin the initiating PID. Correlation, not a culprit.
- Everything reassuring otherwise: Arc and Tailscale properly signed and notarised, tailnet healthy, no exit node, no dodgy persistence, no MDM, the high-permission extensions all disabled.
And then the thing I actually respect most: the blue-team cell openly disagreed with the red-team cell. "Temporal correlation does not prove Node opened those URLs. No referrer does not prove malicious." It named its own proof gap out loud, capture one opening with the PID, executable path, parent process and mechanism, or you have got nothing. It refused to hand me a satisfying story it could not back. That is the good stuff. That is what you want a security agent to do instead of confidently screaming "COMPROMISED" at a purple dot.
So I caught it in the act
Every one of those plans ended on the same note: stop theorising, catch one popup live with proof attached. So that is exactly what I did. I sat and waited for the fifteen-minute tick with the mouse plugged back in, and this time I actually looked.
First, Control Centre:

Link keyboard and mouse to: Steven's MacBook Pro. Universal Control, live. My keyboard and mouse were not just mine, they were bridged straight to the MacBook Pro sitting three feet away.
Then the Arc window popped on the timer, right on cue. And this time I looked at the dock icon properly instead of the scary prompt:

A little laptop badge. Arc, From MacBook Pro.
There it is, in one tooltip. That badge is not screen-sharing, it is Apple Continuity, the Mac-answers-your-iPhone family of features, advertising the MacBook Pro's Arc session on this screen. Arc on the other Mac had a Tailscale login open, Continuity handed the session across, and because my keyboard and mouse were bridged over through Universal Control, a stray focus change popped it onto this screen. Tailscale was just the page being carried, never a compromise. Cut the cross-Mac link and the popups stop. Two Macs in the same room, the second one basically my headless server that I had forgotten still had a screen on it and Continuity quietly switched on.
The reckoning: what it actually cost
Here is the part that reframes the whole thing. All three identified the same cause, a benign Apple Continuity collision between the two Macs, not a breach. But look at what each one spent getting there.
First, the rate cards, because they are not the same shape. Every vendor gives you a big discount on cached input, but the cached rate itself differs, and so does the output rate, which is where a lean run spends most of its money:
| Model | Input / 1M | Cached input / 1M | Output / 1M |
|---|---|---|---|
| GPT-5.6 Sol | $5.00 | $0.50 | $30.00 |
| Claude Fable 5 | $10.00 | $1.00 | $50.00 |
| Kimi K3 | $3.00 | $0.30 | $15.00 |
Now the runs. A triage like this is a tool-heavy agent loop, it re-feeds a big stable prefix (system prompt, the growing transcript, tool output) on every single turn, so most input is a cache hit. Sol and Fable ran lean, call it a 75/25 input-output split. Kimi K3 was a different shape entirely, which is the whole point in a second. Prices are each vendor's published July 2026 rates:
| Model | Tokens | Fresh in / Cached in / Output | Est. cost* | Wall-clock |
|---|---|---|---|---|
| GPT-5.6 Sol | ~800K | 60K / 540K / 200K | ~$6.60 | ~21 min |
| Kimi K3 | ~2.9M | 240K / 2.185M / 475K | ~$8.50 | ~51 min |
| Claude Fable 5 | ~650K | 49K / 439K / 163K | ~$9.10 | ~27 min |
*Illustrative, not a receipt. Token totals and times are real; the split and cache-hit rate are approximations. K3 ran through Claude Code, not Moonshot's own harness, with no API errors, so the token pile and the clock are the model's, not a broken pipe.
So the cheapest model on the card, K3, cost about $8.50. Fable, the priciest per-token by a mile, cost $9.10. Sol landed at $6.60. Three wildly different stickers, three bills in the same narrow band.
That is the point. K3 burned 2.9 million tokens and fifty-one minutes to reach the verdict Sol got in 800K and twenty-one. Its cheap rate did not make the job cheap, it hid the cost in cached input and in wall-clock. By tokens, K3 wins. By outcome, the thing you actually paid for, all three cost about the same, and K3 was the slowest by a mile. Do not price a model by its tokens. Price it by what it takes to get you the answer.
The verdict
On method: Fable had the sharpest instinct, snapshot the live state before you clamp the firewall, because you cannot un-destroy evidence. Sol ran the most thorough of the three, a red team and a blue team, and had the spine to flag what it had not proven. K3 wrote the most readable write-up and took the slowest, priciest road to the same place. All three got it right, and all three landed on the cause, a second Mac handing its window across through Apple Continuity. I reproduced it myself just to nail the exact toggle.
And the lesson underneath it: the cheapest model on paper was not the cheapest to run. And price your models by the outcome, not the token.