eden/.llms/rules/ACR_api_validation_tightening.md
Severity: HIGH
return Err(...), bail!(), or HTTP 4xx response in an API handler for a condition that was previously acceptedBAD (breaking existing clients — matches S578742):
pub async fn handle_write(req: WriteRequest) -> Result<Response> {
// NEW: reject writes where file content didn't actually change
for file in &req.files {
if file.old_content == file.new_content {
return Err(Error::NoOpChange(file.path.clone()));
}
}
// Clients that relied on no-op writes succeeding now get errors.
// 368 writes failed over 4 hours before this was caught.
do_write(req).await
}
GOOD (gated rollout):
pub async fn handle_write(req: WriteRequest) -> Result<Response> {
let reject_noops = tunables()
.get_bool("reject_noop_file_changes")
.unwrap_or(false);
if reject_noops {
for file in &req.files {
if file.old_content == file.new_content {
return Err(Error::NoOpChange(file.path.clone()));
}
}
}
do_write(req).await
}
// Roll out per-repo: enable for a test repo first, then gradually expand.
// If breakage is detected, flip the knob off instantly.
When adding new validation to an existing API endpoint, always gate it behind JustKnobs or a per-client/per-repo Configerator flag. Before enabling, audit callers to see if any rely on the currently-accepted behavior. Start with logging-only mode (log violations without rejecting) to measure impact, then enable rejection gradually. The pattern is: log first → enable for test repos → canary → full rollout.