Nota (PT-BR): este documento é uma referência normativa de engenharia e permanece temporariamente em inglês para preservar precisão técnica. A visão geral em português está em Decision Engine. A tradução completa está no backlog de documentação.
Matriz de fontes de decisioning¶
Status: normativo. Baseline: 2026-08-20. Esta matriz define autoridade, owner, frequência, SLA, dedupe e moeda. O significado dos gates está no contrato de dados.
1. Papéis¶
| Papel | Responsabilidade |
|---|---|
| Integration owner | credenciais, disponibilidade, schema drift, replay e raw |
| Media owner | taxonomia e vínculo dos IDs de account/campaign/ad set/ad |
| Finance owner | saldos, compromissos, FX, reconciliação e policy de reserva |
| Data owner | normalização, fórmulas, qualidade, watermarks e cutover |
| Workspace owner/admin | aprovação humana e concessão de acesso |
| System | coleta e avaliação determinística; nunca aprovação humana |
Owner é responsabilidade operacional, não origem do dado. Uma importação feita
por Finance continua tendo a instituição emissora como source_system e o
arquivo/hash como proveniência.
2. Hierarquia de autoridade¶
Conflitos não são resolvidos por “última escrita vence”:
- Caixa liquidado: extrato/saldo do provedor financeiro é autoridade; ledger interno é reconciliado contra ele.
- Comissão e ajustes ClickBank: evento detalhado INS é a trilha transacional; QuickStats/relatório oficial é o controle agregado. Divergência abre finding, não sobrescreve silenciosamente o evento.
- Gasto e entrega Meta: Insights API da ad account é autoridade. CSV Meta é fallback e controle de cutover, não fonte concorrente permanente.
- Atribuição:
click_idfirst-party devolvido emextclidé autoridade. UTMs e nomes fuzzy são fallback provisional. - FX realizado: comprovante da conversão é autoridade. Cotação de mercado é benchmark e não altera lucro realizado.
- Compromisso: obrigação incorrida na plataforma/provedor prevalece sobre budget; aprovação interna prevalece apenas para reserva ainda não incorrida.
- Marketplace: payout, Gravity, EPC de marketplace e score são sinais de pre-flight, nunca autoridade de lucratividade própria.
3. ClickBank e tracking¶
| ID | Dado / fonte | Autoridade e owner | Frequência / SLA | Dedupe | Moeda | Gate e uso |
|---|---|---|---|---|---|---|
TRK-CLICK |
endpoint first-party de click/visit | Brandvelia; Integration owner | evento em tempo real; soft 1 min, hard 15 min | (workspace_id,event_id) e click_id único; retry devolve o resultado original |
n/a | VALID com landing/campaign IDs, clocks e consent; UTMs sem ID canônico são PROVISIONAL |
TRK-CB-OUT |
LinkBuilder/HopLink extclid |
Brandvelia; Media owner | em cada outbound click; soft imediato, hard 1 min | (workspace_id,outbound_event_id); click_id pode ter mais de um outbound legítimo |
n/a | confirma propagação; não é conversão |
CB-INS |
ClickBank Instant Notification Service | ClickBank; Integration owner | event-driven; soft 5 min, hard 1 h | ID da fonte quando houver; fallback (account,receipt,type,transaction_time,item_no,payload_hash) |
moeda do payload; piloto espera USD, nunca hard-code sem validar | fato transacional PROVISIONAL até atribuição/reconciliação; schema/hash/tenant conflict é INVALID |
CB-QUICK |
QuickStats API | ClickBank; Finance owner | diário + lookback móvel de 30 dias; concluído até 10:00 UTC; soft 30 h, hard 48 h | raw por (account,from,to,response_hash); snapshot por (account,business_date,observed_at) |
moeda informada/contratada pela conta; não presumir USD fora do piloto | controle agregado; período vira VALID se dentro da tolerância SQL e com watermark |
CB-CSV |
relatório oficial exportado pelo operador | ClickBank/documento; Finance owner | sob demanda e no fechamento mensal; soft 2 dias úteis, hard 5 dias úteis | (workspace,file_sha256,row_number) mais business key receipt/type/item |
moeda da linha/arquivo | PROVISIONAL até validar cobertura; VALID como evidência de fechamento reconciliado |
CB-MKT-CAP |
captura autenticada do marketplace | ClickBank UI; Media owner | no máximo diária; soft 36 h, hard 7 dias | (workspace,vendor,snapshot_date,source) e hash do run |
payout na moeda publicada, normalmente USD | sinal de pre-flight no máximo PROVISIONAL; nunca prova de lucro |
CB-MKT-IMPORT |
CSV/JSON de marketplace fornecido pelo operador | documento importado; Media owner | sob demanda; soft 36 h e hard 7 dias desde captured_at |
(workspace,file_sha256,row_number) e upsert vendor/date |
moeda obrigatória por linha | PROVISIONAL; UNKNOWN para campos ausentes; sample/demo é excluído de decisões |
3.1 Campos obrigatórios do raw ClickBank¶
workspace_id nullable até resolução controlada, source_account_id,
received_at, delivery_type, raw_ciphertext/raw_payload protegido,
payload_hash, source_ip protegido, dedupe_key, processing_status,
normalization_version, error_code
Eventos sem workspace não são atribuídos automaticamente à “única workspace”
em uma implantação multi-workspace. Permanecem em inbox isolada UNKNOWN até
uma regra determinística resolver a conta.
3.2 Reconciliação ClickBank¶
- A tolerância inicial é
USD 0.01por tipo e business date, configurada em policy SQL, não em Route Handler. - Sale, rebill, refund e chargeback são comparados separadamente. Somar todos em um total pode esconder sinais opostos e não é válido.
- O run mantém
from,to, accounts, source watermark, contagens, totais, diferença, versão e hash. matchedsem cobertura completa da janela não promove paraVALID.- Ausência de chaves QuickStats produz
UNKNOWN/SOURCE_UNAVAILABLE, não sucesso nem zeros.
4. Meta Ads, piloto oficial read-only¶
Meta Ads é o canal selecionado. O piloto é estritamente de leitura e abrange uma allowlist explícita de ad accounts.
| ID | Dado / endpoint lógico | Autoridade e owner | Frequência / SLA | Dedupe | Moeda | Gate e uso |
|---|---|---|---|---|---|---|
META-OBJECTS |
account, campaign, ad set e ad metadata | Meta Marketing API; Media owner | a cada 6 h; soft 8 h, hard 24 h | (workspace,account_id,object_type,object_id,source_updated_at-or-payload_hash) |
account currency para budgets | IDs/status VALID se credencial e account allowlisted; nomes nunca são join key |
META-INSIGHTS |
insights diários nível ad | Meta Marketing API; Media/Finance owners | horário para D0-D7 e backfill diário D0-D37; soft 3 h/hard 12 h para gasto corrente; dia fechado soft 30 h/hard 72 h | (account,date_start,date_stop,level,object_id,breakdowns,attribution_setting,action_report_time,observed_at,payload_hash) |
account_currency; spend preserva decimal/micros |
autoridade de spend/entrega; revisions são append-only; VALID após complete paging e watermark |
META-CSV |
export oficial Ads Manager | Meta/documento; Finance owner | somente bootstrap, contingência e comparação de cutover; soft 1 dia útil, hard 3 dias úteis | (workspace,file_sha256,row_number) + chave dimensional do export |
moeda declarada no export | PROVISIONAL; pode validar fechamento após reconciliação, mas não coexistir sem source precedence |
4.1 Dimensões e métricas do piloto¶
Granularidade padrão: um registro por
account_id + campaign_id + adset_id + ad_id + account_business_date +
attribution_setting + action_report_time + observed_at.
Campos mínimos:
account_id, campaign_id, adset_id, ad_id,
configured_status, effective_status,
date_start, date_stop, account_timezone, account_currency,
spend, impressions, clicks, outbound_clicks, landing_page_views,
actions[action_type], action_values[action_type],
attribution_setting, action_report_time,
source_updated_at, observed_at, ingested_at, api_version
Regras:
- paginação incompleta torna o run
INVALID; - campos não retornados são
null, não zero; - actions ficam normalizadas por
action_type; não se soma action types com semânticas diferentes; - breakdowns demográficos, PII, audiences e criativos brutos ficam fora do piloto;
- conversão reportada pela Meta não cria receita no ledger;
- não existe fallback por nome entre objetos Meta e campanhas Brandvelia. O vínculo usa mapping aprovado de IDs externos.
4.2 Credencial e saúde¶
O run registra somente credential_ref, nunca token. Antes de coleta, o adapter
valida expiração, ads_read, app/business esperado e allowlist da ad account.
Erro de autenticação é UNKNOWN/SOURCE_UNAVAILABLE; resposta parcial, moeda ou
account divergente é INVALID.
5. Caixa, FX e compromissos¶
| ID | Dado / fonte | Autoridade e owner | Frequência / SLA | Dedupe | Moeda | Gate e uso |
|---|---|---|---|---|---|---|
CASH-CB |
balance/payout statement ClickBank | ClickBank; Finance owner | diário e em payout; soft 30 h, hard 72 h | (account,statement_id-or-as_of,balance_type,payload_hash) |
moeda da conta | accrued/held/payout scheduled nunca entra em S0; received só após conta destino confirmar |
CASH-PAYONEER |
saldo/extrato Payoneer | Payoneer; Finance owner | diário; soft 30 h, hard 72 h | (account,statement_id,entry_id); snapshot (account,as_of,hash) |
por wallet | available pode entrar em S0 apenas se reconciliado e na allocation currency |
CASH-WISE |
saldo/extrato Wise | Wise; Finance owner | diário; soft 30 h, hard 72 h | (profile,account,statement_id,entry_id) |
por balance | mesma regra; transferência não é receita |
CASH-BANK |
extrato de banco brasileiro | banco; Finance owner | diário; soft 1 dia útil, hard 3 dias úteis | (account,statement_id,entry_id) |
BRL | não entra em S0 USD antes de FX liquidado |
FX-ACTUAL |
comprovante/settlement do provedor | banco/Payoneer/Wise; Finance owner | por operação; soft 1 dia útil, hard 3 dias úteis | (provider,external_ref,base_currency,quote_currency) |
par explícito | autoridade de lucro realizado; requer amounts, fee e settled clock |
FX-MARKET |
provedor de benchmark a selecionar | provedor externo; Data owner | em dias úteis; soft 24 h, hard 72 h | (provider,pair,rate_type,observed_at) |
quote por unidade de base | benchmark PROVISIONAL até fonte contratada; nunca substitui actual FX |
COMMIT-INTERNAL |
aprovação/reserva interna | Brandvelia; Finance owner/approver | event-driven; soft imediato, hard 1 h | (workspace,commitment_id,version) |
moeda do compromisso | AUTHORIZED entra em Cp; exige approval evidence |
COMMIT-META |
spend incorrido ainda não liquidado | Meta Insights/billing; Finance owner | horário; soft 3 h, hard 12 h | account/day/object revision; ligação com ledger por settlement | account currency | entra em Cp sem duplicar o débito já refletido no caixa |
COMMIT-OPEX |
invoice/contrato/tax provision | documento/fornecedor; Finance owner | na criação e revisão diária; soft 1 dia útil da emissão, hard antes do vencimento | (workspace,counterparty,external_ref,version) |
moeda documental | AUTHORIZED/INCURRED entra em Cp; draft não entra |
RESERVE-POLICY |
policy de liquidez e risco | Brandvelia; Finance owner + approver | por versão; reavaliada em todo run | (workspace,policy_id,version) |
allocation currency | componentes de L; só versão aprovada e vigente é VALID |
5.1 Controles contra dupla contagem¶
- Saldo snapshot é estoque; ledger é fluxo. Não se soma ambos.
- Payout ClickBank emitido continua fora de
S0até crédito confirmado na conta destino. - Transferência Payoneer -> Wise reduz uma conta e aumenta outra, com o mesmo
transfer_id; não cria lucro. - Spend Meta incorrido e não pago é
Cp. Depois de liquidado, sai deCpe a redução já aparece emS0/ledger. - Reserva para refund fica em
L; refund já incorrido e não liquidado fica emCp. A policy exclui a parcela já materializada para não contar duas vezes.
6. Dados internos de decisão¶
| ID | Dado / fonte | Autoridade e owner | Frequência / SLA | Dedupe | Moeda | Gate e uso |
|---|---|---|---|---|---|---|
BV-CAMPAIGN |
cadastro e mapping da campanha | Brandvelia; Media owner | event-driven; imediato | UUID interno + mapping único (workspace,platform,external_id) |
budget currency explícita | status operacional e fase são independentes; mapping por nome é provisional |
BV-SCENARIO |
LOW/BASE/HIGH e assumptions | operador; scenario owner | por mudança; expiração por input | (scenario_set_id,version); versão aprovada imutável |
moeda por input e moeda comum do cenário | assumption é PROVISIONAL; aprovação não a promove a fato |
BV-POLICY |
regras, limites, janelas e fórmulas | Finance/Data owner + approver | por versão | (policy_id,version) + content hash |
quando aplicável | aprovada/vigente para VALID; código SQL referencia versão |
BV-EVIDENCE |
envelope imutável de evidência | Brandvelia; Data owner | ao materializar fato/snapshot | evidence_id UUID + content hash único no escopo |
herdada do fato | sem PII; cross-workspace é INVALID |
BV-SNAPSHOT |
cutoff determinístico do decisioning | SQL/RPC; System | sob demanda e em schedule diário | (workspace,as_of,input_hash,policy_version) |
uma allocation currency | todos os inputs e watermarks congelados |
BV-RECOMMENDATION |
TEST/VALIDATE/SCALE/HOLD/BLOCK | avaliador SQL; System | após snapshot válido | (snapshot_id,rule_set_version) |
allocation currency | começa OFF, depois SHADOW, só então ADVISORY |
BV-DECISION |
ACCEPT/REJECT/DEFER | humano autorizado | por recomendação | uma decisão vigente por recommendation/version; histórico append-only | n/a | obrigatória antes de ação ou mudança de fase |
7. Watermarks e cobertura¶
Cada integration run publica:
run_id, source_system, source_account_id, requested_from, requested_to,
covered_through, page_count, record_count, response_hash,
started_at, finished_at, status, error_code, credential_ref,
adapter_version, source_schema_version
finished_at não prova cobertura. O gate usa covered_through, paginação e
contagem. Runs skipped por falta de credencial preservam UNKNOWN; não
atualizam o watermark.
Um decision snapshot só seleciona versões com ingested_at <= as_of e registra
o watermark exato de cada fonte. Backfill posterior cria um novo snapshot; não
reescreve a decisão histórica.
8. Matriz de gates por uso¶
| Input | TEST |
VALIDATE |
SCALE |
Caixa S0/Cp/L/Ca |
|---|---|---|---|---|
| tracking | VALID |
VALID |
VALID |
n/a |
| spend Meta | PROVISIONAL permitido com cap explícito |
VALID |
VALID |
gasto incorrido deve refletir Cp |
| ClickBank detalhe | PROVISIONAL |
VALID para conversão |
VALID |
accrued não entra em S0 |
| reconciliação ClickBank | pode estar pendente dentro de cap | necessária para janela de conversão | necessária para conversão e refund | payout recebido precisa confirmar conta destino |
| conversion maturity | opcional/immature | MATURE |
MATURE |
n/a |
| refund maturity | reserva conservadora em L |
pode ser IMMATURE com policy e cap |
MATURE |
exposição imatura aumenta L |
| rebill maturity | rebill excluído | só entra se MATURE |
só entra se MATURE |
expected rebill nunca entra em S0 |
| balance snapshots | VALID |
VALID |
VALID |
obrigatório |
| commitments | VALID |
VALID |
VALID |
obrigatório |
| reserve policy | VALID |
VALID |
VALID |
obrigatório |
| actual FX | exigido só para valor realizado convertido | mesmo | mesmo | outra moeda fica excluída sem settlement |
| scenario LOW/BASE/HIGH | aprovado; assumptions visíveis | aprovado e vigente | aprovado; inputs críticos fact-backed | I vem do cenário aprovado |
Qualquer INVALID obrigatório bloqueia. Qualquer UNKNOWN de caixa bloqueia
alocação. PROVISIONAL só é aceito nos pontos explicitamente marcados acima e
sempre mantém recomendação conservadora.
9. Lacunas atuais e ordem de habilitação¶
| Prioridade | Lacuna atual | Consequência | Gate de saída |
|---|---|---|---|
| P0 | a foundation migration define balance snapshots, commitments e reserve inputs, mas não há ingestores, approvals nem cálculo | S0, Cp, L e Ca continuam UNKNOWN |
três fontes operacionais, aprovadas e reconciliadas |
| P0 | nulls financeiros são coalescidos para zero | falsa completude | reason codes e testes de missingness |
| P0 | webhook ClickBank escreve raw/conversion/ledger em etapas | retry pode deixar estado parcial | RPC transacional/outbox + replay tests |
| P0 | foundation define accounts/mappings/performance, mas o adapter Meta API não existe e o CSV assume USD | spend oficial e moeda são desconhecidos | piloto ads_read, allowlist e shadow reconciliation |
| P0 | não há evidence IDs/snapshots | IA e recomendações não são auditáveis | envelopes imutáveis + allowlist server-side |
| P1 | tracking não possui event_id, consent ou clocks completos |
dedupe e atribuição não atingem VALID |
contrato TRK-CLICK e mapping por ID |
| P1 | QuickStats usa constante de tolerância no TypeScript e single workspace no cron | qualidade não é policy-driven/tenant-safe | reconciliação SQL por account/workspace |
| P1 | FX do formulário não chega à server action e não há comprovante | lucro realizado BRL não é confiável | FX-ACTUAL completo e reconciliado |
| P1 | campanha tem só status draft/active/paused/archived | operação e evidência ficam misturadas | campaign phase independente |
| P1 | raw ClickBank e conversão duplicam email/nome sem purge | retenção LGPD indefinida | job de retenção e pseudonimização |
| P2 | fonte de benchmark FX não foi selecionada | benchmark é UNKNOWN |
provider/termos/SLA aprovados |
Sequência pragmática¶
- Contratos, evidence IDs, reason codes e objetos de qualidade.
- Caixa/compromissos/reserva, porque sem eles não existe
Ca. - Tornar ClickBank transacional e reconciliado por account/workspace.
- Implementar Meta read-only em
SHADOW, comparando com CSV. - Backfill legado como
PROVISIONALe produzir snapshots shadow. - Habilitar
ADVISORYapenas após os gates de cutover definidos em architecture-decisions.md.