## Lesson — Use delimiters in multi-field cache keys

**Tags:** caching, security, architecture
**Scope:** packages/cli/src/utils.ts

When constructing a cache key from multiple input fields, the architectural concern is **boundary preservation**: adjacent fields must remain distinguishable from each other after concatenation, otherwise different inputs can collide into the same cache key. The class of bug is "ambiguous serialization" — the same flat byte sequence can represent multiple distinct inputs because the field boundaries weren't preserved at the serialization layer.

This is a design-time architectural decision for any function that hashes multi-field inputs, not a syntactic pattern that grep or AST-grep can reliably catch. The right fix is a code-review checklist for cache key constructors, not a compiled rule that flags every adjacent string concatenation. Reviewers should ask: "if I swap two fields' contents, can the resulting key remain identical?" If yes, the constructor needs explicit delimiter discipline (a separator byte that cannot appear in field values, like `\0`, or a length-prefixed encoding).

This is a conceptual/architectural pattern, not a compilable rule.
