refactor: retire sandbox dual-write; file tools write in-place into workspace

This commit is contained in:
2026-05-31 10:39:58 +04:00
parent 3c90ac4aef
commit 95e79bffb8
3 changed files with 34 additions and 77 deletions
@@ -44,7 +44,6 @@ import com.correx.core.toolintent.rules.ExecInterpreterRule
import com.correx.core.toolintent.rules.NetworkHostRule
import com.correx.core.toolintent.rules.PathContainmentRule
import com.correx.infrastructure.InfrastructureModule
import com.correx.infrastructure.artifactscas.DefaultMaterializingArtifactWriter
import com.correx.infrastructure.inference.DefaultProviderRegistry
import com.correx.infrastructure.inference.FirstAvailableRoutingStrategy
import com.correx.infrastructure.inference.llama.cpp.LlamaCppInferenceProvider
@@ -92,10 +91,13 @@ fun main() {
?: toolsConfig.workingDir.takeIf { it.isNotEmpty() }?.let { Path.of(it) }
?: Path.of("").toAbsolutePath()
val shellAllowedExecutables = toolsConfig.shellAllowedExecutables.toSet()
val workspaceRoot = System.getenv("CORREX_WORKSPACE_ROOT")
?.let { Path.of(it) }
?: toolsConfig.workspaceRoot.takeIf { it.isNotEmpty() }?.let { Path.of(it) }
?: workingDir
val toolRegistry = InfrastructureModule.createToolRegistry(
buildToolConfig(
artifactStore,
sandboxRoot,
workspaceRoot,
workingDir,
shellAllowedExecutables,
toolsConfig,
@@ -110,10 +112,6 @@ fun main() {
logToolInfo(sandboxRoot, workingDir, shellAllowedExecutables, toolRegistry)
val workspaceRoot = System.getenv("CORREX_WORKSPACE_ROOT")
?.let { Path.of(it) }
?: toolsConfig.workspaceRoot.takeIf { it.isNotEmpty() }?.let { Path.of(it) }
?: workingDir
val privilegedLocations = toolsConfig.privilegedLocations.map { Path.of(it) }
val workspacePolicy = WorkspacePolicy(workspaceRoot, privilegedLocations)
val toolCallAssessor = ToolCallAssessor(
@@ -297,36 +295,39 @@ private fun buildRepositories(
approvalRepository = InfrastructureModule.createApprovalRepository(eventStore),
)
// File tools write IN PLACE into the workspace (cwd / allow-listed dirs). The old
// sandboxRoot dual-write is retired; reversibility is event-sourced (FileWrittenEvent +
// CAS pre/post images, captured by SandboxedToolExecutor). sandboxRoot survives only as
// the executor's scratch workDir, never as a write destination.
private fun buildToolConfig(
artifactStore: ArtifactStore,
sandboxRoot: Path,
workspaceRoot: Path,
workingDir: Path,
shellAllowedExecutables: Set<String>,
toolsConfig: com.correx.core.config.ToolsConfig,
): ToolConfig = ToolConfig(
shell = ShellConfig(
enabled = toolsConfig.shellEnabled,
allowedExecutables = shellAllowedExecutables,
workingDir = workingDir,
),
fileRead = FileReadConfig(
enabled = toolsConfig.fileReadEnabled,
allowedPaths = setOf(sandboxRoot, workingDir),
),
fileWrite = FileWriteConfig(
allowedPaths = setOf(sandboxRoot, workingDir),
enabled = toolsConfig.fileWriteEnabled,
artifactStore = artifactStore,
materializingWriter = DefaultMaterializingArtifactWriter(),
sandboxRoot = sandboxRoot,
workingDir = workingDir,
),
fileEdit = FileEditConfig(
enabled = toolsConfig.fileEditEnabled,
allowedPaths = setOf(sandboxRoot, workingDir),
workingDir = workingDir,
),
)
): ToolConfig {
val allowed = setOf(workspaceRoot, workingDir)
return ToolConfig(
shell = ShellConfig(
enabled = toolsConfig.shellEnabled,
allowedExecutables = shellAllowedExecutables,
workingDir = workingDir,
),
fileRead = FileReadConfig(
enabled = toolsConfig.fileReadEnabled,
allowedPaths = allowed,
),
fileWrite = FileWriteConfig(
allowedPaths = allowed,
enabled = toolsConfig.fileWriteEnabled,
workingDir = workingDir,
),
fileEdit = FileEditConfig(
enabled = toolsConfig.fileEditEnabled,
allowedPaths = allowed,
workingDir = workingDir,
),
)
}
private fun DefaultProviderRegistry.asServerRegistry(): ProviderRegistry = object : ProviderRegistry {
override fun listAll() = this@asServerRegistry.listAll()