I avoid to make HashRef attributes writable (and even making them readable can have surprising effects).
In your case, you seem to want to overwrite individual elements of limit by passing a hashref containing only the values you want to change. While the auto-generated attribute accessors of Moo* are very convenient for simple cases, I don't use them for complex attributes. I'd rather write a separate method like that:
sub new_limit {
my $self = shift;
my ($aggregation, $dimension, $val) = @_; # e.g. 'min', 'x', '-42'
$self->limit->{$aggregation}{$dimension} = $val;
}
That would, for example, allow to change the interna from aggregation-first to dimension-first without changing the external API.
Even if you want to allow many values to be changed in one go, I recommend not to use the auto-generated Moo* accessor, but to write a separate method which contains pretty much the same code which you used in your before modifier.