Stacks

Plan a Multi-File Change Before Editing in Scala With Atlas (2026)

Updated 8 min read

To plan a multi-file change before editing in Scala with Atlas, switch to the plan agent, whose description is literally "Plan mode. Disallows all edit tools." Its permission set denies edit for "*" and allows it only under .atlas/plans/*.md, so research across your build.sbt modules, traits, and implicits cannot accidentally turn into an edit. You investigate with codebase_search, grep, read, and the lsp tool, write the design into the plan markdown, then call plan_exit to hand off to the build agent. Only after that handoff do sbt, ScalaTest via sbt test, and scalafmt come into play.

How do I design a multi-file Scala change without letting the agent edit code?

Switch to Atlas's plan agent. Its description is literally "Plan mode. Disallows all edit tools." The plan agent's permission set denies edit for "*" and allows it only under .atlas/plans/*.md, so a research pass across 6 sbt subprojects cannot put a single character into src/main/scala.

Scala changes are exactly the kind that want a plan first. Adding a type class instance, threading a new implicit through a service trait, or splitting a module in build.sbt touches files that the compiler will only complain about after you have already edited them all. The plan agent removes the temptation to start editing while you are still learning the shape of the change. Every Atlas tool call is permission-gated against allow, ask, and deny rules before it runs, so the deny on edit is enforced by the permission layer, not by asking the model nicely. Atlas drafts a plan in a read-only plan agent and asks before switching to a build agent, which is the whole safety property this workflow is built on.

Which Atlas tools stay available in Scala plan mode?

In Atlas plan mode, 4 research tools stay allowed: codebase_search, grep, read, and the lsp tool. For a Scala change that means you can trace a trait's implementations, grep .scala sources for an implicit conversion, read build.sbt, and run findReferences on a method, all without any edit tool being reachable.

codebase_search finds the concept by meaning, using hybrid semantic and keyword retrieval fused by reciprocal rank fusion, so a query like "where do we serialize the order aggregate" surfaces the relevant Scala declarations even when no file is named Serializer. grep catches what the type system does not see, which in Scala is a large set: string literals, resource paths, and the module names in build.sbt itself. The lsp tool's findReferences operation is the one that matters most before a multi-file Scala refactor, because a trait method has callers the compiler knows about and you do not. Atlas indexes code by AST declarations using tree-sitter, so a hit is a whole def, trait, or case class rather than a slice through a for-comprehension.

Where does Atlas write the Scala plan, and what does plan_exit do?

Atlas writes the Scala plan into .atlas/plans/*.md, the only path plan mode may edit while every other path stays denied. plan_exit then asks whether the plan is complete and whether to switch to the build agent, and it accepts exactly 2 answers: Yes hands off to the build agent, No raises Question.RejectedError and keeps you refining.

Answering Yes hands off to the build agent, which is where the edit tools become reachable and where the Scala work actually begins. Answering No raises Question.RejectedError and keeps you in plan mode refining the design, which is the right outcome when the plan says "add an implicit Encoder" and you realize on reading it that the change belongs in a different sbt subproject. The plan document is the artifact you review. For a Scala refactor it should name the files by path (for example modules/core/src/main/scala/orders/OrderRepo.scala), the traits and implicits involved, and the ScalaTest suites that must stay green. Atlas's question tool is what makes plan_exit an actual gate rather than a formality.

How does the handoff to the build agent work in a Scala project?

Answering Yes to plan_exit hands the Scala plan to Atlas's build agent, and only then do edit tools become available. The build agent implements the plan across the sbt modules, runs ScalaTest via sbt test, and formats with scalafmt. Answering No instead raises Question.RejectedError, which is how a 2026 Scala team keeps refining a design before any file changes.

The build agent implements the plan one file at a time, and each edit arrives as a diff you approve. In a Scala project, run sbt test after each meaningful hunk rather than once at the end, because Scala's compile step is slow enough that batching failures wastes more time than it saves. Run scalafmt on the touched files so that a refactor of a trait does not also produce 200 lines of formatting noise. Atlas snapshots file changes as git patches so edits can be diffed and rolled back, which means a plan step that turns out to be wrong is revertible without unwinding the steps that were right. Atlas also reads git branches, status, and diffs, and can stage and create commits on your behalf.

Why plan first instead of just letting the agent edit the Scala code?

The risk in a multi-file Scala change is that the compiler only tells you the design was wrong after 12 files have already been edited. Atlas's plan agent moves that discovery earlier by denying edit for "*" while you research, so the design is reviewed as a markdown document rather than as a broken working tree.

A Scala change tends to have one load-bearing decision (which trait owns the abstraction, where the implicit is summoned, which sbt module the new code belongs to) and a long tail of mechanical consequences. Getting the decision wrong is cheap in a plan and expensive in a diff. Reviewing .atlas/plans/*.md before any edit lands means the argument happens over the design, not over a pile of half-migrated .scala files. Atlas's design makes this the default path rather than a discipline you have to remember: plan mode denies the edit tools, plan_exit asks explicitly before switching, and No raises Question.RejectedError and returns you to refining the plan.

Step by step

  1. 01Run atlas in a project with a build.sbt and let Atlas read your traits, implicits, and sbt modules.
  2. 02Switch to the plan agent; its permissions deny edit for "*" and allow it only under .atlas/plans/*.md, so no .scala file can be modified while you research.
  3. 03Research the change with codebase_search, grep, read, and the lsp tool, all of which stay allowed in plan mode: use findReferences on the trait method you intend to change to enumerate every caller across your sbt subprojects.
  4. 04Grep the .scala sources and build.sbt for the things the Scala type system does not see, such as string literals, resource paths, and module names.
  5. 05Write the plan into the allowed plan markdown path under .atlas/plans/, naming the exact files (for example modules/core/src/main/scala/orders/OrderRepo.scala) and the ScalaTest suites that must stay green.
  6. 06Call plan_exit; Atlas asks "Plan at <path> is complete. Would you like to switch to the build agent and start implementing?"
  7. 07Answer Yes to hand off to the build agent, or answer No to raise Question.RejectedError and keep refining the plan if the change belongs in a different sbt module.
  8. 08In the build agent, implement the plan one approved diff at a time, running ScalaTest via sbt test after each hunk and scalafmt on the touched files.

Frequently asked questions

how to plan a large scala refactor before writing code
Use Atlas's plan agent. Its permission set denies edit for "*" and allows writes only under .atlas/plans/*.md, so you can research across your build.sbt modules with codebase_search, grep, read, and the lsp tool without any risk of editing a .scala file.
what is atlas plan mode and how do i exit it
Atlas plan mode is a read-only agent described as "Plan mode. Disallows all edit tools." You exit with the plan_exit tool, which asks "Plan at <path> is complete. Would you like to switch to the build agent and start implementing?" Yes hands off, No keeps you planning.
can i say no when atlas asks to switch to the build agent
Yes. Answering No to plan_exit raises Question.RejectedError and keeps you in plan mode refining the plan. That is the correct answer when reading the plan reveals the change belongs in a different sbt subproject than you assumed.
how do i find every caller of a scala trait method before refactoring
Run the lsp tool's findReferences operation in Atlas plan mode. The language server returns the authoritative callsite list across your sbt subprojects, which is what you need before a multi-file Scala change where the compiler only complains after all the edits land.
does atlas run sbt test and scalafmt after a refactor
After plan_exit hands off to the build agent, Atlas runs ScalaTest via sbt test and scalafmt through its bash tool. Run sbt test after each meaningful hunk rather than once at the end, since Scala compile times make batched failures expensive to untangle.
where does atlas store the plan file
Atlas writes the plan into the allowed plan markdown path under .atlas/plans/, which is the only location plan mode is permitted to write. Everything else is denied, so the plan document is the sole output of a planning session.
can i undo a scala change atlas made after leaving plan mode
Yes. Atlas snapshots file changes as git patches, so edits can be diffed and rolled back. A plan step that turns out to be wrong is revertible without unwinding the steps that were right, and Atlas reads git status and diffs to show you where you stand.

Try Atlas in your terminal

The terminal-native AI coding agent. Free core, single binary.

Install Atlas

Related guides

Plan a Multi-File Change Before Editing with Atlas in 2026

How to plan a multi-file change with Atlas in 2026: the plan agent denies all edit tools, you research with codebase_search and lsp, then plan_exit hands off.

Atlas for Scala in 2026

Atlas is a terminal-native AI coding agent for Scala in 2026. Run it in a project with a build.sbt, let it read your traits and implicits, and approve every diff.

Write Unit Tests for Untested Code in Scala with Atlas (2026)

How to add ScalaTest coverage to an untested Scala module with Atlas in 2026: enumerate symbols with lsp documentSymbol, copy repo conventions, then run sbt test.

Migrate a deprecated API across every callsite in Scala with Atlas in 2026

Effortlessly migrate deprecated Scala APIs across your entire codebase using Atlas. Discover every callsite, apply context-aware patches, and verify with `sbt test` for a complete, safe transition in 2026.

Debug a Single Failing Test in Scala with Atlas (2026)

How Atlas debugs one failing Scala test in 2026: run it isolated with sbt, walk the call path with the lsp tool, and fix the code, not the assertion.

Diagnose a hanging or long-running command in Scala with Atlas (2026)

Is your sbt build slow or blocked on stdin? Atlas races every command against a timeout and tells you which. A 2026 guide for Scala teams using sbt and scalafmt.

Audit a Scala Repo with Parallel Subagents in Atlas, 2026

In 2026, Scala developers use Atlas to sweep entire repositories for code problems without context window limits. Launch parallel subagents for efficient, read-only audits of Scala projects.

Automate GitHub issue and pull request triage in Scala with Atlas in 2026

Automate GitHub issue and pull request triage for Scala projects in 2026 using Atlas. Learn how Scala developers can integrate Atlas with sbt and scalafmt for safe, AI-driven workflow automation.

Browse this resource hub