Boundaries Carry the Risk

A slice can pass its focused tests and still fail when it crosses an interface, handles a retry, or accepts data written by someone else. In addyosmani/agent-skills, this chapter examines the boundary-first reasoning used to control those failures. Readers will learn to see an interface as an observable commitment, place validation and authorization at the edge where trust changes, and reason about retries and agent tools without assuming that “exactly once” happens automatically.

The boundary is where one part of a system stops knowing what another part intends. A caller sees a response shape, an error, a timing behavior, or an ordering rule. A service receives a request it did not create. A browser reports data from a page the agent does not control. An agent receives model output that may look like a command. Local correctness is still necessary, but it is no longer enough: the behavior is now visible to another actor that can depend on it, misuse it, or repeat it under uncertainty.

An interface is an observable commitment

The repository uses Hyrum’s Law to make this risk concrete: with enough users, every observable behavior of an interface will be depended on by someone, whether or not the behavior was promised. A public contract is therefore larger than its type signature. Error text, ordering, timing, default values, and quirks can become dependencies once consumers build around them.

This does not mean that every accidental behavior must be preserved forever. It means that changing an observable behavior is a migration decision, not merely a local cleanup. The interface skill therefore starts contract-first. It defines typed inputs and outputs, consistent error semantics, validation at the system edge, predictable names, and additive evolution before implementation details spread.

Consistent errors are part of that contract. If one endpoint throws, another returns null, and a third returns a structured error object, callers cannot predict how to handle failure. A consistent machine-readable code and human-readable message give consumers a stable way to branch without exposing internal details. The status code or equivalent boundary signal then becomes part of the behavior the service owns.

Validation belongs where untrusted data enters. An API route, form handler, environment loader, or external-service parser should establish the shape and constraints of its input before handing it to internal code. Once the boundary has validated a value against the shared contract, internal functions do not need to re-litigate every property on every call. Scattering validation throughout trusted internals makes ownership unclear and leaves gaps at the actual edge.

The additive-evolution rule follows from the same reasoning. Adding an optional field can extend a contract without forcing every consumer to change at once. Removing a field or changing its type breaks consumers that may not be visible in the current repository.