-
Notifications
You must be signed in to change notification settings - Fork 2
Global config defaults ignored when agent has built-in values #56
Description
Bug
Global defaults in ~/.config/broodbox/config.yaml are silently ignored for tmp_size, cpus, and memory because all built-in agents hardcode non-zero values for these fields.
Reproduction
Set a global default in ~/.config/broodbox/config.yaml:
defaults:
tmp_size: "2g"Run any built-in agent (e.g. bbox claude-code). The VM gets 512 MiB /tmp instead of 2 GiB.
Root cause
There are four priority levels for resource settings:
- CLI flag (
--tmp-size) — highest - Per-agent config override (
agents.claude-code.tmp_sizein config) - Global config default (
defaults.tmp_size) - Agent built-in (e.g. 512 MiB hardcoded in registry) — lowest
Levels 1 and 2 are merged into a single override parameter before config.Merge() is called (pkg/sandbox/sandbox.go:240-255), so they correctly take top priority.
The bug is in how Merge() handles levels 3 vs 4. In pkg/domain/config/config.go:
// TmpSize: override > agent default > global default
if override.TmpSize > 0 {
result.DefaultTmpSize = override.TmpSize.MiB()
}
if result.DefaultTmpSize == 0 && defaults.TmpSize > 0 {
result.DefaultTmpSize = defaults.TmpSize.MiB()
}The global default is only applied when result.DefaultTmpSize == 0, but all built-in agents in internal/infra/agent/registry.go hardcode DefaultTmpSize: 512. So the agent built-in always shadows the global config default.
The same issue affects CPUs (built-in: 2) and Memory (built-in: 4096).
Suggested fix
Change Merge() so global defaults beat agent built-ins when no per-agent override is set. Per-agent overrides already flow through the override parameter (not the agent), so this is safe:
// TmpSize: override > global default > agent built-in
if override.TmpSize > 0 {
result.DefaultTmpSize = override.TmpSize.MiB()
} else if defaults.TmpSize > 0 {
result.DefaultTmpSize = defaults.TmpSize.MiB()
}Apply the same pattern for CPUs and Memory:
if override.CPUs > 0 {
result.DefaultCPUs = override.CPUs
} else if defaults.CPUs > 0 {
result.DefaultCPUs = defaults.CPUs
}
if override.Memory > 0 {
result.DefaultMemory = override.Memory
} else if defaults.Memory > 0 {
result.DefaultMemory = defaults.Memory
}Why this is safe for per-agent overrides: Per-agent config overrides (e.g. agents.claude-code.tmp_size: 1g) are loaded into cfg.AgentOverrides and merged into the override parameter at sandbox.go:241-244 before Merge() is called. They hit the override.TmpSize > 0 branch and take precedence over global defaults. Only when no override exists does the else if apply the global default over the agent built-in.