Чтобы ответить на второй вопрос, вы можете инициализировать Builder из Reader, например:
fooBulider.setBar(someBarReader);
Или для MessageReader / MessageBuilder верхнего уровня:
messageBuilder.setRoot<RootType>(messageReader.getRoot<RootType>());
Для этого требуется копия, но для вашего случая использования эта копия, вероятно, не имеет большого значения. Конфиги обычно не являются мультигигабайтными файлами и не чувствительны к производительности.
Теоретически также возможно создать MessageBuilder, который непосредственно инициализируется из существующих данных сообщения, которые он затем модифицирует на месте. Тем не менее, есть некоторые серьезные оговорки с этим. См:
https://github.com/capnproto/capnproto/blob/3aa2b2aa02edb1c160b154ad74c08c929a02512a/c++/src/capnp/message.h#L168-L187
Что касается двух других ваших вопросов, это действительно ваше дело. Существуют законные аргументы в обоих направлениях, и это действительно зависит от конкретного варианта использования и вашего личного вкуса.