Hi, sorry for late reply - busy days 
Yes, I do believe custom materializations is the way to go, as the actual loading pattern is given, and with a minimum of configuration (business keys, columns selected for hash_diff for satellites, etc), together with the dependency tracking built-in to dbt, I think we have a winner.
- By the end of the day, materializations are j"just" a set of macros too when you think about it.
I got side-tracked this last week with building a package for the metrics mart (dv-metrics, close to version 1.0, I think another week and it should be ready at least for the raw vault - still need to work a bit on how to handle bridges. pit tables are easy though), but once that is done I’ll continue on my materialization package.
when you say PK, are we talking physical/actual PK’s, or do you pass the column(s) as part of the config?
the way I see it is kind of like this:
you have a landing zone/extract table like this (pseudo example):
create table stage_.customer_list
(
customer_number varchar(128),
country_code varchar(128),
city varchar(128),
load_dts,
load_src
)
from this we build base models (base__customer_list), materialized as views:
select
customer_number,
country_code,
city,
load_dts,
load_src
from stage_.customer_list
on top of this we can now build:
-hubs:
h_customer.sql
{{ config(materialized=‘hub’, business_key=‘customer_number’) }}
ref {{ref(‘base_customer_list’)}}
h_country.sql
{{ config(materialized=‘hub’, business_key=‘country_code’) }}
select
ref {{ref(‘base_customer_list’)}}
Links:
l_customer_country.sql
{{ config(materialized=‘link’, historization=‘true’, hubs=[‘h_customer’, ‘h_country’]) }}
select X
from ref {{ref(‘base_customer_list’)}}
s_customer.sql
{{ config(materialized=‘satellite’, historization=‘true’, parent=‘h_customer’) }}
select
{{ business_key_hash }},
city,
{{ vault_meta_columns }}
from ref {{ref(‘base_customer_list’)}}
having dived through existing materializations and tracing what dbt does, there is no question in my mind that it is the way to go. The difficult part is two-fold: figuring out a sane level of config/convention/customization, as well as ensuring cross platform (I focus on postgres for now).
Again, I’d love to see what you’ve done so far, if you’re able to share the code somewhere I’d be happy to look at it, test it out, and give you some feedback.
once my dv-metrics is done, I’ll let you know, and I’d very much like to get your feedback as well 
Regards,
Fridthjof-G