Some good comments. The rationale is that ScopeBuffer is designed to favor speed over about everything else:

1. in using ScopeBuffer in real code, the power of 2 worked great at minimizing the alloc/copy cases, so yes, it is deliberately eager
2. put() is designed to be inlined. The more code that's in it, the more it will negatively influence the code it is inlined into, i.e. the more registers it uses the fewer registers the caller can use. Adding clamping code would probably cost at least one more register. The `j*2+16` can be done in one instruction.
3. All the realloc's are there for failover should the initial stack buffer be overflowed, i.e. the initial stack buffer should be sized to accommodate the most common cases. If the design is potentially allocating anywhere near 2 Gigabyte arrays on the stack, I'd suggest that is misusing ScopeBuffer, and some other scheme would be a better fit.