CC is at best weakly a key-value mapping. The presence of the "cache extensions" hole makes the whole design trickier.

So, seeing two ways forward:

One is to leave as is: intended to be used as it is in Response#set_cache_control, but allow for visiting patterns by leaving directives and validation available. It does the job intended as is.

Or some combination of:

* Add #[] and #[]= including name validation on set. Remove access to directives hash. 
* Convert validation logic into a "validation_issues" method, possibly with valid? and validate! on top of it.
* Convert all mutation to attr_accessor-like methods, including a "set_extension(name, value)" or access to the extensions hash...
* Make initialization 0-arg, and have all object configuration happen through mutation
* Have Response#set_cache_control handle the empty-header case.

I can see virtues to all of those - I'd rather not burn a ton of time on a single iteration though. A third opinion would be useful.