Skip to content

devlog/flow-recipes/reasoning-models-draft-an-upgrade-plan-in-your-terminal-1080.md

Reasoning Models Draft an Upgrade Plan in Your Terminal

Dependency Plans Drafted From a Manifest Alone

Reasoning models are good at turning a messy dependency question into an ordered plan, and that is exactly why the failure mode is easy to miss. The answer arrives as a numbered list with versions, ordering, and rollback notes, and it reads like work you can merge. Underneath, the model may be filling gaps with averages from training data rather than from your project.

The fix costs almost nothing. Give the model your manifest, the lockfile summary, the runtime version, the package manager, and the last green CI run, then ask it to label every claim as verified or assumed. A plan that admits uncertainty is worth more than one that never hesitates, because you can route the uncertain items into a separate investigation pass before anything is installed.

  • Asking for a plan from the manifest alone invites invented version numbers and confident nonsense.
  • Pasting only the manifest hides the exact resolutions your lockfile already committed to.
  • Leaving out the runtime and toolchain versions lets the model propose releases that cannot install.
  • Accepting a plan that never separates verified facts from assumptions leaves guesswork inside your build.

That separation also makes the plan reviewable by someone who was not in the session. When every item carries its evidence, a teammate can argue with the data instead of with the tone. In practice I ask for three things per item: the change, the proof behind it, and the failure signal I should watch in the first hour after deploy.

Semver Claims That Ignore How You Use the Package

Semver is a contract between a package author and its users, not a guarantee about your application. A reasoning model will cheerfully call a minor bump safe because the exported surface is unchanged, while your code leans on behavior the changelog never documented. Bundler plugins, type stubs, codemods, and lint presets are the usual offenders in my own repositories.

Ask for a risk note per package that cites the changelog entry and the exact import paths your repository touches. Then ask for the smallest safe version instead of the newest one, and require the plan to name the files where a rollback would be applied first. That one request usually cuts a scary upgrade into a set of reversible moves.

  • Treating every minor bump as safe ignores undocumented behavior that your tests already depend on.
  • Skipping the changelog because the model summarized it means you inherit the model's blind spots.
  • Upgrading type stubs alongside runtime packages can mask breakage that only appears at build time.
  • Chasing the newest version instead of the smallest safe one widens the rollback surface unnecessarily.

The same discipline applies to peer dependency warnings, which reasoning models tend to smooth over with reassuring language. Ask the model to translate each warning into a concrete symptom: which command fails, which import breaks, which generated file drifts. Warnings you can describe are warnings you can schedule around.

Transitive Upgrades the Generated Plan Never Mentions

The most expensive upgrades are the ones that do not appear in your manifest. A plan that only walks direct dependencies will miss the hoisted versions your bundler actually resolves, so the suite passes locally while CI installs a different tree. Lockfile format changes and package manager defaults make this worse across a team.

Have the model read the resolved output from your package manager's why or list command, then identify every transitive package whose version moves as a side effect. Ask specifically about duplicated versions, because two copies of the same utility library usually means two copies of its bug fixes and two copies of its bytes in your bundle.

  • Planning against direct dependencies alone leaves hoisted transitive versions completely unexamined.
  • Ignoring duplicate entries in the resolved tree lets bundle size and identity checks drift apart.
  • Skipping native and platform specific packages produces plans that only fail on one developer's machine.
  • Regenerating the lockfile with a different package manager silently rewrites versions the plan assumed.

Once you have the transitive diff, sort it by blast radius rather than by version number. Packages that generate code, compile types, or run at install time deserve their own commit and their own observation window. Everything else can travel in one batch, as long as that batch is a single commit you can revert together.

Sequencing Upgrades Across Commits Without a Red Build

A plan is only as good as its order. Reasoning models tend to produce a dependency ordering instead of an operational ordering, and the difference shows up halfway through when the framework needs a plugin version that has not been touched yet. Ask for the sequence in terms of build gates, test gates, and runtime gates rather than package names.

Give each step its own command, its own expected output, and its own stop condition. I ask for a verification block after every step with the exact test target, the smoke check, and the two or three log lines that prove nothing leaked. When a step fails, the plan should tell you which earlier step to return to, not simply to stop.

  • Ordering upgrades by package name hides the toolchain dependencies that actually enforce ordering.
  • Batching a framework bump together with its ecosystem plugins makes failures impossible to attribute.
  • Writing steps without an expected command output turns verification into a matter of mood.
  • Omitting a stop condition per step encourages pushing forward through a half understood failure.

This is also where a cheap model earns its keep. For the mechanical rewrite of import paths and config keys, a fast model handles the volume, while a longer reasoning pass reviews the resulting diff. If you want to try a workflow like this, create a Fluxo account and point your editor or terminal at the same base URL.

Reasoning Token Spend While the Plan Recalculates

Long upgrade sessions are token hungry in a specific way: every new stack trace makes the model re-read the same dependency tree. Cache reads and cache writes are part of that bill, and pricing that hides them makes an afternoon of planning look cheaper on paper than it is in reality. I budget for re-reading, not for one clean prompt.

That is one reason I run these sessions through Fluxo. One key and one base URL, https://api.fluxorelay.com, covers Claude, GPT, Gemini, DeepSeek, Kimi, GLM, Qwen, Grok and more, with billing per real token including cache reads and writes and no monthly fee. It works with Claude Code, Codex, Gemini CLI and any OpenAI SDK, so the terminal habits you already have stay put. On a recent upgrade I drafted the sweep with DeepSeek V4 Pro and reviewed the risky sections with Gemini 3.8 Flash, using the same key and the same base URL the whole way.

  • Sending the full dependency tree with every follow up question multiplies cache writes and inflates the bill.
  • Asking the model to regenerate an entire plan instead of patching one section wastes every earlier token.
  • Switching providers mid session without a shared base URL forces you to rebuild context from scratch.

Keep a short context pack instead: the manifest diff, the resolved tree excerpt, the failing output, and the last decision you made. Cache friendly prompt shapes pay for themselves when the model re-reads that pack dozens of times before lunch. The referral share is a small extra for teams whose colleagues end up on the same workflow, and if anything in your setup does not line up with the docs, leave a note on the contact page after signing in.

Next in the buffer