Background
engine.custom.kwargs exposes user-defined values to templates as \${kwargs.<key>}. There is currently no validation that prevents a user from declaring a kwarg key that shadows a built-in template variable.
Example (today silently accepted):
```yaml
engine:
custom:
kwargs:
case_id: "my-override" # shadows the built-in ${case_id}
model: "custom-name" # shadows ${model}
```
Whether the user-supplied value or the built-in wins depends on the order of completeTemplateVars overlays in internal/agent/custom.go. Either outcome is confusing.
Proposal
In internal/config/validator.go::validateCustomEngine, after the kwargs map is parsed, reject keys that collide with the built-in template variable set already enumerated by IsBuiltinTemplateVar. Emit a clear error pointing at the offending key.
Why this is a follow-up, not a blocker
No bug has been observed yet, and the override-precedence in completeTemplateVars is consistent — but the surface area for confusion grows once HTTP transport lands and ${kwargs} aggregates start being passed through HTTP bodies.
Origin
Raised during the self code-review of feat/custom-engine-local (architecture finding #5).
Background
engine.custom.kwargsexposes user-defined values to templates as\${kwargs.<key>}. There is currently no validation that prevents a user from declaring a kwarg key that shadows a built-in template variable.Example (today silently accepted):
```yaml
engine:
custom:
kwargs:
case_id: "my-override" # shadows the built-in ${case_id}
model: "custom-name" # shadows ${model}
```
Whether the user-supplied value or the built-in wins depends on the order of
completeTemplateVarsoverlays ininternal/agent/custom.go. Either outcome is confusing.Proposal
In
internal/config/validator.go::validateCustomEngine, after the kwargs map is parsed, reject keys that collide with the built-in template variable set already enumerated byIsBuiltinTemplateVar. Emit a clear error pointing at the offending key.Why this is a follow-up, not a blocker
No bug has been observed yet, and the override-precedence in
completeTemplateVarsis consistent — but the surface area for confusion grows once HTTP transport lands and${kwargs}aggregates start being passed through HTTP bodies.Origin
Raised during the self code-review of
feat/custom-engine-local(architecture finding #5).