Treat API-like boundaries (HTTP headers, REST/GraphQL payloads, event envelopes, and even cross-layer client calls) as contracts: field names and field meaning must remain consistent end-to-end, and gating/serialization rules should follow the spec.
Apply this:
Example (rename or add header to keep meaning unambiguous):
// Before (contract ambiguous):
// headers: { "X-Task-ID": ulid }
// After (contract explicit):
headers: {
"X-Task-ID": taskId, // if backend expects a task id here
"X-Task-ULID": ulid, // if backend also needs ulid
}
// Or (if backend only wants ulid):
// headers: { "X-Task-ULID": ulid }
Example (avoid boolean meaning drift):
// Instead of:
// load(true, true)
// Prefer:
load({ refresh: true, background: true });
This prevents “it works but semantics changed” bugs that typically surface as missing/incorrect fields, spec violations, wrong attribution/rate limits, or silent capability downgrade.