
r/LLMDevs

Ramp Launches Router.com to Cut Companies Rising AI Bills
prnewswire.comOpenSourcing TrueForge Agent harness : Expect feedback from community on the agent loop
Hey folks 👋
We just open sourced TrueForge, our vendor-neutral agent harness for building general-purpose agents.
It handles the runtime pieces that get painful quickly : context management, tool/MCP execution, subagents, sandboxing, approvals, persistent state, and more.
We also benchmarked the harness itself. With the same Opus 4.8 model, TrueForge delivered a similar solve rate at ~30% lower cost than Claude Managed Agents. Switching to an open model pushed that to ~75% lower cost on the same benchmark.
Would love feedback from people building agents.
⭐ Star the repo: https://github.com/truefoundry/trueforge
📖 Read the launch article: https://x.com/truefoundry/status/2090081376330715176
TokenMizer - a local proxy for session checkpoint/resume and graph memory across Claude, GPT, and Ollama
I've been building TokenMizer, a local proxy that sits between your editor/CLI and whatever model you're using (Claude, GPT, Ollama) and handles two things I kept re-solving by hand: session checkpoint/resume, and a graph-based memory instead of a flat transcript.
The problem: once a long agent session hits the context limit, the usual fix is summarization, and summaries lose the reasoning behind a decision, not just the decision itself. I'd see a summary saying "switched to Argon2" with no trace of why bcrypt was rejected, so the agent would re-litigate the same tradeoff two sessions later. Flat transcripts have the opposite problem: everything is kept, but nothing is prioritized, so retrieval is just recency-biased keyword luck.
What TokenMizer does differently: instead of one growing text blob, decisions, constraints, and open questions are stored as nodes with edges (this decision depends on that constraint, this question was resolved by that decision). Checkpointing snapshots that graph plus a resumable session state, so you can kill a session and pick it back up without replaying the whole history through the model again.
Where it's rough: there's no eval harness yet comparing retrieval quality against a naive flat-transcript baseline, so right now my evidence is anecdotal (my own sessions), not benchmarked. I also learned the hard way that benchmarking your own memory system by asking it questions only it can answer is circular, so I'm holding off on publishing numbers until I have an honest comparison.
Repo: github.com/Shweta-Mishra-ai/tokenmizer (I'm the author). It's a Python project, MIT licensed. If you've hit the same summarization-loses-reasoning problem, I'd be interested in how you're handling it, and PRs/issues on the eval-harness gap would genuinely help.
pagedMark: invisible SynthID-class watermark removal for AI images (ChatGPT, gpt-image, DALL·E, Sora, Gemini, Nano Banana), running on Metal
pagedMark removes AI provenance from content you generated yourself. Two different things, and it is worth separating them. The first is metadata: C2PA Content Credentials, EXIF, XMP, IPTC, the generator parameters. That part is easy and verifiable, and a screenshot does it too. The second is the invisible pixel watermark that a screenshot does not touch, the SynthID class of marks, which has to be disrupted by regenerating the image itself.
Coverage on the image side is ChatGPT, gpt-image, DALL·E, Sora, Gemini and Nano Banana for the invisible marks, plus a registry of visible vendor labels (Doubao, Jimeng, Qwen, Kling, Yuanbao, Baidu, LibLibAI, Samsung Galaxy AI). On the video side it handles the visible marks from Sora, Veo, Seedance, Dola, Hailuo and Kling, and the metadata that travels with them.
The reason this is worth a post rather than a link is that it is built for Apple Silicon instead of ported to it. I spent several days getting the pipeline to run correctly on an M5 with 16 GB, meaning predictable and measured rather than merely launching. Most of what I assumed turned out to be wrong, so the measurements are below.
The four-step distillation LoRA invents texture, and more steps make it worse
A low strength edit runs the tail of a long schedule: strength 0.15 executes the last four steps of twenty seven. A LoRA distilled for four timesteps spanning the entire noise range is off its distribution there. Wherever nothing conditions the model, and flat dark fabric gives a Canny ControlNet no edges at all, it fills the gap from its prior. On a night photograph that arrives as coloured camouflage across black clothing.
| Global stage, 1448x1080, strength 0.15, seed 0 | Invented texture | PSNR | Wall |
|---|---|---|---|
| Lightning, 4 steps | 1.73x source | 28.54 dB | 41 s |
| Lightning, 8 steps | 1.80x | 28.19 dB | 29 s |
| Lightning, 16 steps | 1.84x | 27.85 dB | 62 s |
| Undistilled base, 16 steps | 1.19x | 29.25 dB | 71 s |
| Undistilled base, 24 steps | 1.20x | 29.17 dB | 132 s |
Asking the distilled model for more steps made the artifact worse, which is what identified the distillation rather than the step count as the cause. Dropping the LoRA costs roughly three times the wall time and buys back both fidelity and correctness.
Three wrong theories I paid for first, in case they save someone else the time. Not the fp16 VAE: a bare encode and decode round trip of the same crop is clean in fp16 and in fp32, tiled or whole, at 34.6 dB. Not Metal's fp16 in general: bf16 measured marginally worse. Not Canny picking up sensor noise: the Canny map of that region is completely empty, which was the actual clue.
Metal pages instead of failing, so memory has to be measured
torch.mps.recommended_max_memory() reports 11.84 GiB on a 16 GB machine. Exceed it and nothing raises an error. The process starts swapping, and a run that should take 23 seconds takes an hour instead.
With VAE tiling disabled, a 1.57 MP frame peaks at 18.74 GiB and takes 59 seconds. With tiling it peaks at 10.92 GiB and takes 23 seconds. So tiling carries real weight on a small machine, but its boundaries leave a faint texture, which is why it is now decided per frame from the device budget rather than switched on globally.
Diffusion untiled at 2.5 MP went into swap and did not finish within twelve minutes. Tiled at 1024 px, a 5.07 MP frame holds 10.93 GiB, finishes in 88 seconds, and keeps its native geometry.
Sequential CPU offload works on MPS, and it is what makes 8 GB usable
The stack is 7.7 GiB of weights. An 8 GB Mac reports a working set of roughly 5.3 GiB, so it does not fit however the activations are handled. Streaming the weights one module at a time:
| Same frame, same seed | Peak device memory | Wall |
|---|---|---|
| Weights resident | 7.70 GiB | 7.1 s |
enable_sequential_cpu_offload(device="mps") |
0.28 GiB | 24.1 s |
Twenty seven times less peak memory for 3.4 times the wall time. The plan is chosen from the measured budget and then printed, because a run three times slower than the fast path looks broken unless it says why.
Two Metal gaps worth knowing if you are porting anything
torch.float8_e4m3fn does not exist on MPS at all. The error is RuntimeError: Undefined type Float8_e4m3fn. Any pipeline that streams float8 weights, which several VRAM managed stacks do, cannot be loaded there under any configuration.
SAM's processor emits its box and point prompts as float64, which Metal also has no type for, so moving the batch to the device raises rather than degrading. A single cast fixes it, but nothing tells you that is the problem.
The expensive one: fp16 sampling on MPS returns zeros silently
I added a memory optimisation that encodes the two fixed prompts once and drops the text encoders, saving a measured 1.52 GiB of the 8.79 GiB the loaded stack holds. Two of four face crops then came back as all zero black rectangles. Deterministically, at the same seed, with nothing raised anywhere.
The embeddings were innocent. CPU fp16, MPS fp16 and fp32 encodings of that prompt agree to 0.0009 on tensors with a standard deviation of 3.06, and the same crop generated in isolation is correct either way. Freeing unrelated memory changed the allocation pattern the crops met after the global pass, and that alone was enough. I withdrew the optimisation and added a guard that drops any empty crop instead of compositing it.
If you run fp16 diffusion on Metal, check your output for degeneracy. It will not tell you.
What it does not claim
Regeneration is not payload deletion. The image changes: faces, text and fine detail move, and the numbers above are the measured size of that change rather than a reassurance.
No public local decoder exists for SynthID class marks, so identify reports unknown and never clean. Verification is the provider's verifier or nothing. The 0.15 operating point comes from the upstream project's record against openai.com/verify on CUDA. I have not re-run that check on Metal, and Metal is not bit identical to CUDA, so I am claiming the same operating point and not the same verdict.
It is for content you generated or own. The visible mark registry accepts AI generation labels only. Stock agency previews, marketplace and classifieds watermarks are deliberately out of scope, and that boundary is in the repository rather than only in this comment.
Because "how much did that cost my picture" is the whole question
pagedmark measure before.png after.png
PSNR over the frame, PSNR per detected face, and how much mid band structure appeared where the source was flat and dark. The third metric is the one that caught the camouflage, and it took two attempts. Per pixel chroma statistics rank the artifact below the source, because the source's own sensor grain carries more per pixel variance than the invented blotches do. A plain band ratio fails too, since any linear filter reports doubled grain and doubled blotches identically. Normalising mid band energy by fine detail energy, against the same ratio in the source, measures the shape of the spectrum instead of its size.
uv tool install "pagedmark[diffusion]"
pagedmark invisible photo.png -o clean.png
pagedmark invisible photo.png --preview # 46.6 s instead of 112.6 s
Code: https://github.com/doofzoff/pagedMark
PyPI: https://pypi.org/project/pagedmark/
Happy to answer anything about the Metal specifics. That is the part I would have wanted written down before I started.
How would you structure an AI-assisted React Native rewrite workflow?
Disclaimer: This question is written with the help of AI, but that doesn't mean it's slop. It's a genuine problem I'm facing at work. Please don't be quick to judge or dismiss this as AI Slop.
I’m rewriting an entire React Native application from scratch, using the existing app as the baseline and AI (primarily Claude Code) heavily in the process.
I’m trying to design a migration workflow that gives me high reliability without burning an insane number of tokens.
My priorities are:
- Complete parity with the baseline — nothing important should get missed.
- Strict adherence to a predefined code architecture — folder structure, design patterns, separation of concerns, naming conventions, etc.
- Do not port over existing smells, hacks, or bad practices — the baseline should be treated as a behavioural reference, not a code reference.
- Keep token usage low without compromising quality — avoid repeatedly feeding huge amounts of context to the model or having agents redo work unnecessarily.
I’m particularly interested in hearing from anyone who has done something similar.
If you’ve used AI for a large-scale rewrite/migration, how did you structure the workflow? Did you use specific agents, skills, validation steps, checkpoints, etc.?
Even if you haven’t done an AI-assisted rewrite, I’d also love to hear about workflows you’ve used for large-scale migrations/refactors that consistently produced good results.
I’m mainly looking for practical approaches that scale beyond simply “migrate one feature at a time.”
Made a video of a llm web browser I am building. Wanted to get your thoughts about the product?
How would you use LLMs to extract structured register mappings from unseen industrial manuals?
I’m working on a system that converts industrial communication manuals into a structured catalog that can later support deterministic lookup and RAG/chat.
The manuals may describe Modbus, Siemens-style DB/DW/bit addressing, OPC UA, proprietary protocols, or memory ranges. Although they often contain similar information, table layouts, column names and addressing conventions vary significantly between manufacturers.
For example, an unseen manual might contain:
| Absolute Address | Parameter | Number of Items | Format |
|---|---|---|---|
| 30101 | Phase Current | 2 | Float |
The desired canonical result would be something like:
{
"name": "Phase Current",
"data_type": "Float",
"protocol": "modbus",
"register_type": "input_register",
"address": 30101,
"register_count": 2
}
My current experimental pipeline is:
PDF
→ document/table extraction
→ protocol and table-type detection
→ schema matching
→ canonical catalog
→ validation
→ deterministic address/name lookup
→ optional LLM-generated natural-language answer
For known manual families, deterministic extractors work well. The main difficulty is generalizing to unseen layouts: identifying which tables contain actual variables, mapping unfamiliar headers to canonical fields, interpreting address conventions, and avoiding protocol examples or configuration tables being mistaken for register maps.
I experimented with a local LLM as a constrained schema planner. Instead of generating register values, it only proposes mappings such as:
Absolute Address → address
Parameter → variable_name
Number of Items → register_count
Format → data_type
The source values are then read and validated deterministically. This prevents many hallucinations, but results have been mixed: it helped significantly on one unseen manual, added nothing where deterministic extraction already worked, and sometimes proposed incorrect column roles. Sending many tables to the model also adds several minutes of latency.
I’m therefore still open to the overall architecture and to a different role for the LLM. Possible options include:
- deterministic extraction with an LLM fallback;
- LLM-based table classification or schema matching;
- constrained structured extraction followed by validation;
- retrieval of similar previously solved table schemas;
- a multi-stage planner/verifier setup;
- fine-tuning a smaller model on labeled tables;
- using the LLM only for ambiguous cases and human review.
How would you design this system to generalize across unseen industrial manuals while keeping every extracted value traceable to the source? Where would an LLM provide genuine value, and which parts should remain deterministic? I’m especially interested in approaches that improve recall without silently inventing addresses, data types, scaling factors, or protocol bindings.
9 concurrent users @ 128K context on 1x A100 (up from 6) per-user needle checks passing in vLLM
I’ve been testing how far I can push long-context serving on a single A100 before the KV cache becomes the thing that kills concurrency.
Here’s the latest result:
9 concurrent users
~128K context per user
1× A100 80GB
Needle checks run independently for every user
FP8 holds the first 5 users
One technical detail I also want to correct from some of the earlier shorthand:
The V tail is tiered 4/3/2-bit bit-plane. It is not plain INT4.
Some of the recipe labels are stale. The actual pool sizes line up with the tiered 4/3/2-bit representation, so calling the tail “INT4” would describe the old label rather than what is actually being stored.
Method
I don’t keep the entire KV cache at one fixed precision.
The cache is divided into regions. Newer or more sensitive KV stays at higher precision, while older regions progressively move into cheaper representations.
As the context grows, the cache footprint can keep falling without forcing the same quantization level across the entire cache.
The 9-user run is currently the capacity end of the curve.
I’m also rerunning the 2-user and 4-user points using the same V2 tiered recipe. The July numbers came from the earlier V1 recipe family, and I want the next throughput curve to be completely apples-to-apples.
So far, a single A100 is keeping 9 users at ~128K context resident, with the per-user retrieval checks still passing.
There are a lot of knobs here: concurrency, context length, per-user throughput, precision, and memory.
I want to make those knobs much more flexible so long-context serving isn’t immediately dictated by the KV-memory wall. At scale, that can have a very real impact on how much useful inference you can get out of the same hardware.
Happy to share more of the pool math, the 4/3/2-bit layout, or the vLLM implementation if anyone wants to dig into it.
One MCP tool schema was ~54k tokens in context. We cut it to ~1.3k by never letting the model see the catalog.
The default MCP pattern has a quiet cost: the model reads the full schema of every tool on every connected server, every turn, before it even knows which tool it needs.
We stress-tested it with a deliberately oversized tool: 217,316 bytes of schema, roughly 54k tokens at four characters per token, sitting in context just to make one tool callable.
You pay for that three times. It's input tokens on every call (caching softens the bill, not the rest). It's latency, more context to process before the first useful token. And it's context pressure, schema you never use crowding out the task.
The fix was to stop showing the model the catalog at all. It gets exactly two operations: search and execute. It searches with plain-language intent ("create a support ticket"), gets back a few compact cards capped at 1,800 bytes each, and executes one by its action ID. The full schema never enters context. The bridge rebinds it after selection and validates the call server-side against the real thing.
Result on the stress fixture: 217,316 bytes became a 5,062 byte card. 97.7% less, ~54k tokens down to ~1.3k, and execution stayed exact. The model still called the right tool with the right arguments. It just stopped reading the encyclopedia first.
What this does not solve, honestly:
- Discovery adds a step. The model searches before it executes.
- Large tool results still cost context. This compresses schemas, not outputs.
- It's one oversized fixture, not a promise that every catalog saves the same. What it demonstrates is the shape: two fixed operations and a few small cards, no matter how many servers you connect.
You can check your own overhead in two API calls: send the same one-line prompt with your MCP servers connected and with none, and diff the input tokens in the usage fields. That difference is your schema tax.
*We build Orca, an agent runtime, and this bridge is part of it. Happy to go deeper on any of this in the comments, including the tradeoffs.*
Switching between Claude Code, Codex, and Cursor kept costing me so much time, built a tool for it.
I've always gotten frustrated and wasted time explaining the same thing to an AI every time I start a new chat from an existing one or when I start another convo with a whole new AI model. That's why I built a tool that fixes that, it condenses everything in a chat into one simple .md file you can carry across different AI tools.
PS: Please contribute or give your feedback so that we can grow and make this community tool better.
Which model if i have unlimited tokens?
I have access to unlimited Luna, Terra, Sonnet 5 and Deepseek v4 flash. What is the best model i can safely have on 99% of the time when coding(C++, C). Working with open source code bases and mostly custom solutions, in the HIL simulation area. I have found terra high/xhigh/max to be good, Luna max also. Havent done much with Sonnet. What would you guys use mostly?
introducing KAISEN AI system - autonomous loops with deterministic testing
hello everybody,
since November 2025 i've been working on an genetic algorithm that uses local LLMs as a mutation factor to continuously iterate over a single C program in order to improve its performance.
this system proved extremely effective at reaching my performance goals by bruteforcing thousands of generations then measuring the results passing the generated programs through a test suite that the LLM has no access to (so it cannot cheat, but it's gonna try!). Every new found best becomes the basis for the next generations and guardrails are in place so that most dangerous code doesn't get tested.
since this system served me well and gave me results with gpt oss 20b that i couldn't get with frontier models in full reasoning mode (and with a lot of interaction by me), i opened an AI lab and started working on a generic version that is able to work with any program (22 languages and counting) and to build the test pipeline autonomously. for the nerds: part of the reason small models punch above their weight here are a deterministic autofix ladder, compiler-hint fixes, linter fixes, then one LLM repair pass fed the real compiler error, and every candidate is re-verified for real before it gets counted as valid. you can use it as humans with a gui that helps you step by step or you can point your agent at the KAISEN folder and tell it to use the kai protocol to start tests on its own (works very well with llms using the omp and deepseek harness)
right now you can check out the alpha version of KAISEN here: https://github.com/RAZZULLIX/KAISEN
tldr
KAISEN lets you use local LLMs to improve software performance by iterating thousands of little changes and keeping the new best as basis for the next generations. it has a GUI, your harness can spawn it as a sidecar, and it speaks a small-model-friendly protocol (KAI) so an LLM agent itself can drive it over stdio or http. every program it generates runs guarded by default. read the manual to know everything it can do, or ask here.
P.S.
i expect A LOT of bugs and problems, most of the tests i did were done through deepseek v4 using OMP and deepseek harness calling KAISEN through the kai protocol (KAISEN was hooked to 6 instances of gpt oss 20b) and it actually worked quite nice. please let me know everything you find by opening an issue or asking here, this is my job now so i'll do my best to fix everything you need fixed and make sure KAISEN becomes a useful tool in every LLM user toolbox.
Semantic LLM caching: how do you evaluate a verifier that rewrites instead of rejects, when there's no ground truth for the rewrite?
ok so quick context if you haven't seen the other posts: I've been messing around with CacheVerifier, basically testing whether bolting a verifier onto semantic caching actually helps. right now it's dumb and binary, candidate answer either gets a thumbs up or thumbs down, no in-between.
there's this other paper, TweakLLM (arXiv:2507.23674), that does something I think is genuinely smarter: instead of rejecting a bad candidate and eating the full regen cost, it has a cheap LLM just... rewrite the candidate so it fits the new query. patch it instead of throwing it out. I want to add that as a comparison to my own setup and I've been stuck on it for a while, so figured I'd just ask here, since this sub has already bailed me out twice on this project (the axis-problem theory and the bucketing design both came from comment threads here, not from me).
here's where I'm stuck. everything I currently measure is trace-based against public benchmarks , "was this correct" comes entirely from the dataset's own labels, no actual LLM judge anywhere in the loop. works great when the answer is binary. falls apart completely once you're rewriting text, because now you've got a brand new string that isn't in any label anywhere. nothing to check it against.
things I've considered and don't love:
just throw an LLM judge at grading the rewrites. but now I'm introducing a whole new cost/noise source that literally nothing else in this project needed, and "let an LLM grade another LLM's output" is its own whole mess
when there happen to be multiple reference answers for the same query cluster, score the rewrite against one of them by similarity. except that's literally the "similarity ≠ correctness" problem this entire project exists to complain about. using it as my metric here feels like cheating on my own thesis
just skip fine scoring, measure something crude like "did rewriting recover some recall vs just rejecting," and not even try to put it on the same hit-rate/error-rate curve as everything else. doable but honestly a weaker result than I want
if anyone's had to evaluate a generate-a-rewrite step where there's no clean ground truth for the output, not classification, not ranking, an actual freeform string you have to judge somehow , genuinely curious how you dealt with it. or if you think I'm overcomplicating this and should just pick one of the above and move on.
repo's here if you want the full context on what's been tested so far: https://github.com/imxinchengyou/CacheVerifier
I deliberately sabotaged five of my own QLoRA runs to see if a training linter could catch them. Four got caught. One fooled it completely. Body:
I went to bed with a fine-tune running. Woke up eight hours later to a loss that had been NaN since step 300 — the whole night of GPU time gone, and nothing had told me. If you fine-tune, you've lived some version of this: the run that trained at learning-rate-zero the entire time, or quietly ate a dataset with 40 broken rows, and you only find out at the end.
So I built a deterministic linter for training runs — trainproof (pip install trainproof, MIT) — and then I spent days trying to prove it wrong.
One Qwen2.5-3B QLoRA, run five times: once clean, four times with exactly one thing sabotaged. Four it caught instantly. One fooled it completely — and that one taught me the most.
It wasn't the NaN run. It wasn't the fp16 overflow. It wasn't the learning rate cranked 100× too high (that spiked the gradient norm to 2650× the median — caught in seconds).
It was shuffled labels. Pure garbage — a dataset that literally cannot be learned.
That run reduced its loss by 62%. On the curve it looked like textbook-healthy training. It was learning absolutely nothing — just memorizing the statistics of noise, which any network will happily do. From its own loss curve it is indistinguishable from a real run. No single-run, loss-only rule can catch it. So instead of pretending my tool is magic, I wrote that limitation straight into the README — and added a compare mode, because the failure is visible the moment you put it next to a known-good run.
That's the whole philosophy: no ML judging ML, no "87%-confidence" scores. Every check is a deterministic rule that either fires or doesn't, and every finding cites the exact numbers behind it. When it can't be sure, it says so instead of guessing.
Across a run's life:
- Before a single GPU-second — lints the dataset + tokenizer (malformed JSONL with the line number, empty rows, duplicates, missing eos_token, pad==eos, over-length samples). Exits non-zero → straight into CI.
- During training — one-line HuggingFace callback. Warns by default; flip on
stop_on_failand it aborts a doomed run itself. In testing it killed a diverging run at step 20 of 300 — 93% of the scheduled steps never ran. - After — reads the log: diverged / flatlined / NaN'd / spiked.
- vs a baseline — the ratio rules that catch the shuffled-labels case.
All five sabotaged runs' real logs ship in the repo (examples/gallery/) with a 15-run / 3-seed evidence matrix — reproduce every verdict yourself. Reads plain logs (HF trainer_state.json, Coqui, JSONL/CSV), doesn't import torch.
Repo: https://github.com/Mormolykos/trainproof · pip install trainproof
Honest question: what's burned your GPU hours? If a deterministic check would've saved you, tell me — it goes in, with credit.
SALT: Salience-aware lexical trie for long-context compression.
SALT shrinks a long document down to a fixed size before it is sent to a language model, keeping the sentences that carry the most information. It works with any model, produces a shorter plain-text prompt, and cuts the compute, memory, and wait time that long inputs cost. saltChat keeps the theme trie in DRAM across turns, so a document is indexed once and reused for the whole conversation instead of being re-read every message.
Which AI router is everyone using and how well has it been working?
Hi everyone, I'm pretty new to AI routers but I've been diving deep in the rabbit hole the past few weeks. Made a post last week asking how the model selection logic works, as I thought it was worth a try to make one myself. Going to put that on hold for now and look for already existing routers. Currently looking at LiteLLM or Ramp Router, which seems to be promising for token cost cutting which is the main thing I want this for.
Just wanna ask if you guys would recommend any of those or alternatives, and how effective it's been for you. Thanks everyone!
59 public runs on Terminal-Bench 3.0's task, zero passes. Then one passed, using the method from the preprint I posted here.
Ten days ago I posted a theory preprint here and got told, correctly, that it had no evidence behind it. So I built a method out of it and ran it on Terminal-Bench 3.0.
On a binary patching task where the public record shows 59 runs from 11 different model and agent setups and zero passes, one run using the method scored 19 of 19 on the official verifier, inside the original 90 minute limit.
Two ways to poke at this, and I'd genuinely like both.
The easy one: just run that task with whatever setup you already use. It's called ico-path-patch, it's public, 90 minute limit, 19 checks, all or nothing. 59 public runs from 11 different configurations, none passed. If your stack gets through it with none of my stuff involved, that's a much more interesting data point than anything I posted, and it kills my claim. Fine by me.
The harder one: take the method and go after the leaderboard with it. The idea is one line — before solving the task, have the agent build itself a small service for that task, then solve the task through the service. The method is the set of rules for what that service has to pin down. Everything else is your own agent, your own model, your own runs. If it works for you, the score is yours.
My runs took forty to ninety minutes each and cost a few dollars. Nothing in the setup is mine except the method text. Everything I ran is on the repo, including what failed and what I changed in between.
The task: https://hub.harborframework.com/tasks/terminal-bench/ico-path-patch/latest
The 60 trial rows behind that zero-pass baseline, with the query: https://github.com/amingclawdev/charting-loop/blob/main/public/results/ico-path-patch/job-009/PUBLIC-TRIALS.json
How to try the method:
https://github.com/amingclawdev/charting-loop/blob/main/docs/REPLICATION-INVITATION.md
The original preprint post : https://www.reddit.com/r/ResearchML/comments/1vjeznd/the_charting_loop_a_probabilistic_theory_of/
I stopped letting the LLM pick sets, reps and rest. A 240 line pure function does it now.
We build an AI fitness coach. For a long time the workout generator was what most of them still are: a big prompt, a JSON schema, and a hope that the model had read enough training literature.
It produced valid JSON every time. It also produced 3 sets of 5 on a leg press for a beginner who had told us she had a knee problem, and 31 weekly sets of chest for someone whose goal was general fitness. Schema valid. Structurally fine. Bad programming.
The fix was to stop asking the model for numbers at all.
### What the model is allowed to decide now
Before any prompt is rendered, a pure function computes a `TrainingPrescription` from the user's goal, experience level, weekly frequency and health screening. The model receives that prescription as a constraint and picks exercises inside it. It never picks the numbers.
The prescription is not a vibe. It is this:
```
rep ranges compound and accessory, per training intent
RIR target beginner 3-4, intermediate 2-3, advanced 1-3
rest strength 150-300s, hypertrophy compound 90-180s,
isolation 60-120s, metabolic 45-90s
weekly sets beginner 10-12, intermediate 12-16, advanced 14-20 per muscle
progression linear / double progression / autoregulation by level
deload every 6 weeks, every 4 in medically flagged mode
```
Frequency nudges the envelope rather than replacing it. Training 5 or more days a week raises the weekly set ceiling by 2, capped at 22. Training 2 days or fewer lowers it by 2. The floor never drops below 6 sets per muscle no matter what else is applied, because below that you are not training the muscle, you are visiting it.
Goal maps to a training intent, and intent is what actually drives the numbers:
```
strength_power -> STRENGTH, and reps scale with experience:
beginner 5-8, intermediate 3-6, advanced 2-5
toning -> HYPERTROPHY_ISOLATION, 10-15 compound, 12-20 accessory
lose_weight -> METABOLIC, 10-15 reps, 45-90s rest
build_muscle -> HYPERTROPHY_COMPOUND, 6-10 compound, 8-15 accessory
```
"Toning" mapping to isolation hypertrophy is a product decision, not a physiological claim. Users ask for toning and mean something real, and the honest translation of it is higher rep isolation work on top of the same compounds everyone else gets.
### Two adjustments that are code, not prompt
**Low readiness.** When someone reports being sick or under recovered, weekly volume is multiplied by 0.7 and the RIR floor is raised to at least 2-3. That is a 30% volume cut computed in code. A model asked politely to "reduce volume a bit" reduces it a bit differently every time.
**Health screening.** If the PAR-Q flags anything and the user acknowledges the medical disclaimer, generation continues in safe mode: progression is forced to linear, volume is scaled to 80%, deload cadence drops from 6 weeks to 4, and RIR is raised to at least 2-3. A cardiac flag additionally raises RIR to 3-4 and downgrades a strength intent to hypertrophy with a rep floor of 8-12. A joint flag raises RIR to 3-4 and tags the plan so exercise selection avoids heavy axial loading and impact.
If the PAR-Q is flagged and the user has **not** acknowledged the disclaimer, generation is blocked entirely. Not degraded. Blocked.
### The part I would tell my past self
The thing that made this work was not a better prompt. It was accepting that the LLM is good at one job here, choosing sensible exercises for a given slot given a catalog and a set of constraints, and bad at another, holding a numeric policy consistent across seven days and fourteen muscle groups.
So we gave it the first job and took away the second. Everything numeric is a pure, unit tested function with no framework dependencies, which means the entire training policy can be tested without a database, a network call or a model.
Whatever you are building, the question worth asking is: which decisions in my pipeline have a correct answer that I could write down? Those should not be in the prompt.
---
*I build Vires, an AI training app. iOS is live, Android is in the pipeline. Happy to go deeper on any part of this in the comments, including the parts that still do not work.*
I built an MCP server that lets your coding agent read its own past runs and light up a graph as it answers (free, MIT, local)
Disclosure up front: I built this. It's free, MIT, and shipped (npm: rungraph).
Claude Code and Codex CLI write full session transcripts to disk, and rungraph reconstructs them into interactive run graphs. The MCP server is the part this sub might find interesting: npx rungraph mcp --install gives your agent tools over its own history. list_runs, get_graph, find_nodes, get_detail, focus_nodes, get_current_view, open_visualization.
The design problem was context size. A real 176-node run is about 20k tokens as a full graph, 13.5k in the compact projection, and 1.1k through find_nodes. Narrowing beats projecting, so the tool descriptions steer agents to find_nodes first, then get_detail for one node's actual error text.
The fun tool is focus_nodes. You ask Claude in your own terminal "why did the Edit on token.js keep failing", it answers there, and the dashboard you have open lights up the exact nodes the answer is about, then returns a deep link that restores the same highlight against that dashboard (or a bundle the recipient has open). Honest limitation: with no dashboard watching, the call still succeeds and just reports that the highlight was skipped. The read tools parse straight from disk, so they work with no server running at all.
Implementation note for the protocol nerds: the JSON-RPC transport is hand-rolled over stdio because the package has zero runtime dependencies, which keeps the npx install tiny. If more than one dashboard is live (yours, plus a bundle someone sent you), list_runs merges them and every other tool routes by run id.
Live Demo: https://fayzan123.github.io/rungraph/
Repo: https://github.com/fayzan123/rungraph
If you wire it into a client other than Claude Code, I'd like to hear whether the tool descriptions hold up