CommunityPesquisa e Análise de Dadosgithub.com

mooracle/cost-attribution

Construção guiada de um sistema personalizado de atribuição de custos (cost allocation) FinOps a partir de exportações de faturamento no formato FOCUS da AWS, Azure ou Google Cloud, moldado para as contas, tags, clusters e fornecedores SaaS de uma organização, na própria pilha do usuário (a pilha de referência é S3, Athena e Lambda).

O que é cost-attribution?

Esta skill orienta um desenvolvedor ou equipe de finanças a construir um sistema de atribuição de custos FinOps sob medida, evitando ferramentas comerciais genéricas. Ela começa analisando a fatura real do usuário para extrair o que os dados já mostram, depois faz perguntas direcionadas apenas sobre o que não pode ser descoberto automaticamente (como taxas compartilhadas ou nomes de times). As respostas são registradas em um perfil validado (`profile.yaml`), e a skill avalia se cada componente do sistema está pronto para ser construído (`READY`), bloqueado por falta de informação (`BLOCKED`) ou simplesmente não se aplica ao cenário (`NOT_A_FIT`). Em seguida, a construção é feita fase por fase, a partir de especificações técnicas e casos de teste dourados, com uma verificação rigorosa após cada fase. A skill é ideal para cenários de chargeback/showback, alocação de custos compartilhados (como Suporte Enterprise) ou divisão por namespaces Kubernetes e fornecedores SaaS. Funciona com exportações FOCUS e suporta as três nuvens principais, além de oferecer um modo de teste com dados sintéticos para quem não quer (ou não pode) dar acesso à fatura real de imediato. A pilha de referência usa S3, Athena e Lambda, mas a skill se adapta a qualquer engine compatível com SQL.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/mooracle/finops-skills/tree/HEAD/skills/cost-attribution

Installed? Explore more Pesquisa e Análise de Dados skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Construa atribuição de custos moldada como a organização

Você está guiando uma pessoa (e, quando a organização tem uma, um parceiro de finanças) por uma construção que é principalmente cola entre um esquema padrão (FOCUS) e um runtime serverless. Os padrões são fixos; a forma é deles. Seu trabalho é encontrar a forma deles nos seus dados, escrevê-la e aplicar os padrões a ela — nunca instalar um produto genérico.

O artigo explica por que cada padrão é correto: https://mooracle.io/blog/build-custom-finops-tool/ (Partes 1–7). Quando o usuário perguntar "por quê", aponte para a parte; mantenha a sessão no "como".

Invariantes

Estes nunca variam por perfil. Verifique o código gerado contra eles antes de mostrá-lo.

  1. Cada divisão mantém seu total. SUM(out) == SUM(in) por coluna de custo. Os divisores movem dinheiro; nunca o criam ou destroem.
  2. Aloque no momento da consulta. As categorias da organização são anexadas em uma view, por meio de uma consulta. Nunca escreva team em uma linha do warehouse.
  3. EffectiveCost para chargeback. BilledCost concilia faturas, ListCost mede economias. Nunca os misture.
  4. Reconstrua o mês inteiro. Cada partição (billing_period, provider) é limpa e reescrita a partir dos dados brutos em cada entrega. Sem deltas, sem merges.
  5. Limite até ontem. Nada datado de hoje ou posterior entra no warehouse.
  6. Cada divisão é uma única expansão. Uma linha que é dividida junta seus pesos dentro do carregamento regular e se torna uma linha por peso; os pesos de uma chave somam 1,0. Divisões fair-share, Kubernetes e de fornecedores funcionam todas assim, por meio de uma única tabela split_weights. Nada é excluído do carregamento e adicionado depois, portanto não há exclusão a ser esquecida, e nada é contado duas vezes.
  7. Toda execução prova seus números. Raw contém exatamente os arquivos que o manifesto do provedor lista, e uma verificação bloqueante de totais compara a fatura com ambas as tabelas base e falha a execução (e limpa o que escreveu) quando discordam. Depois que as views existem, cada execução e cada fechamento também verificam se services_monthly serve exatamente base_monthly (a verificação das views, que falha sem limpar nada).
  8. Nunca perca custos; o roteamento pode falhar. Quando uma divisão não pode ser feita com segurança, o custo permanece inteiro onde foi faturado. Uma divisão ignorada é visível; um custo perdido é silencioso.
  9. Leituras brutas são do mês exato. WHERE billing_period = 'YYYY-MM', com o limite de varredura do mecanismo ativado (um limite de bytes do workgroup no Athena). Leituras de todo o histórico são permitidas apenas sobre base_monthly (megabytes).
  10. Classifique uma coluna compartilhada uma vez, em uma view. x_namespace contém workspaces Kubernetes e SaaS igualmente; split_by diz qual. Nunca infira a partir da forma do valor.

Arquivos que você mantém no repositório do usuário

Crie finops/ na Fase 0, ou onde o usuário quiser. Registre o caminho como o primeiro D-001; abaixo, finops/ significa esse caminho.

  • finops/profile.yaml — a forma da organização. Comece a partir de assets/profile.template.yaml. Cada fase o lê; nada mais contém decisões específicas da organização.

  • finops/DECISIONS.md — log somente de acréscimo. Nunca edite uma entrada; substitua-a.

    ## D-007 Enterprise Support é compartilhado (2026-10-17)
    Fonte: D5 em 2026-09; Q-S1 respondido por <usuário>
    Decisão: dividir pelo gasto próprio do mesmo mês, por pagador
    Substitui: —
    

    Resultados de descoberta, respostas, suposições, aprovações e decisões negativas ("tentei uma tabela de pesos diários; reverti porque a mistura não varia dentro de um mês; não proponha novamente") vão todos aqui. Os campos evidence do perfil apontam para esses ids.

  • finops/STATUS.md — uma linha por fase: estado, resultado do gate com os números, o commit SHA em que o gate passou e os campos do perfil dos quais a fase depende.

    | Fase | Estado | Gate | Em | Depende de |
    | 3 tabelas base | passou | fatura 2026-09 120.000,00 = mensal 120.000,00 | a1b2c3d | providers, dimensions, routing.key, finance, period_charges, shared_costs |
    

Loop de execução

Entrando

  • finops/STATUS.md existe → retomar: leia STATUS, DECISIONS e o perfil. Para cada fase que passou, git diff <seu SHA> -- finops/profile.yaml; se um campo do qual ela depende mudou, reabra essa fase e toda fase posterior que lê sua saída (1 → 2 → 3; 3 → 4, A, B, 5; 4 → 5). Re-execute o último gate que passou com os dados atuais (os dados também mudam). Continue da primeira fase que não passou.
  • O usuário relata uma mudança (reorganização, nova família de contas, novo fornecedor, novo cluster) → atualizar: re-execute as consultas de descoberta correspondentes, compare com o perfil, pergunte novamente apenas o que mudou, verifique novamente, reabra fases dependentes.
  • O usuário quer ver funcionando primeiro, ou não dará acesso à fatura ainda → o teste (references/trial.md): um mês sintético no DuckDB, sem credenciais, verificado contra um gabarito de respostas. Nada disso é transferido para uma construção real.
  • Caso contrário → iniciar abaixo.

1. Descubra antes de perguntar

Leia references/discovery.md e execute suas consultas no último mês fechado, contra a exportação onde ela já está (uma tabela sobre seus arquivos, ou DuckDB sobre uma entrega baixada quando não há mecanismo), antes de qualquer construção existir. Mostre cada resultado. Registre cada um como um D-NNN. A descoberta lê; ela não muda nada na conta, nem mesmo a ativação de uma tag.

Ainda não há exportação → o caminho de bootstrap: ative a exportação (references/focus-export.md), execute as rodadas de admissão sem dados (Organização, Runtime, Categorias, Finanças), construa a pilha contra o layout esperado e execute a descoberta na próxima sessão assim que a primeira entrega chegar. Ofereça o teste (references/trial.md) enquanto espera.

2. Entreviste para preencher as lacunas

Leia references/intake.md. A regra de parada ou suposição:

  • a resposta move dinheiro ou propriedade → deixe null; o componente permanece BLOQUEADO;
  • é um nome, local ou ferramenta → use o padrão, adicione uma entrada assumptions: e um D-NNN, prossiga.

Nunca preencha um fato com um palpite plausível, um valor fixo ou um valor de um exemplo.

3. Verifique e aprove o plano

Escreva o verificador que references/plan.md descreve em finops/ (uma vez, com um teste por regra) e execute-o no perfil. Ele imprime um veredito por componente e o que está pronto para construir (PRONTO em toda a cadeia de dependências). Mostre-o. Para cada linha BLOQUEADA, nomeie quem pode responder e a pergunta exata. Para cada NÃO_APLICÁVEL, diga a alternativa mais simples em voz alta — incluindo "não construa isso" quando a linha organizacional assim o disser. Obtenha aprovação explícita do plano; registre-a como um D-NNN.

4. Construa, fase por fase

Para cada fase no mapa abaixo, em ordem (as trilhas opcionais A e B após a Fase 4, apenas quando PRONTO):

  1. Verificação de entrada. O verificador com --entering <fase> sai com 0, e toda fase da qual ela depende está como passada em STATUS.md.
  2. Leia sua especificação (references/<arquivo>, coluna Especificação do mapa de fases): o contrato, os invariantes e os casos de borda que mordem quando improvisados.
  3. Escreva na pilha deles. Construa os componentes da fase no mecanismo e idioma do usuário (Athena, BigQuery, Snowflake, Databricks, dbt, …) e no estilo do repositório deles, moldado pelo perfil deles: um adaptador por provedor de providers.md, apenas as divisões que o perfil precisa, apenas as colunas que ele roteia. As especificações dizem o que deve ser válido e os casos o que deve sair; o código é seu para escrever. Tome o máximo cuidado onde um erro é silencioso: os pesos, a distribuição ao longo dos dias, as verificações de totais, as proteções de moeda.
  4. Porte os casos dourados (cases/*.yaml; como, em references/testing.md) que se aplicam ao que esta fase construiu e adicione um caso para cada adaptação específica da organização. Uma fase não está construída até que seus casos passem.
  5. Implante e execute o gate contra os dados reais deles. Gates são SQL que retornam zero linhas quando saudáveis. Mostre os números.
  6. Registre o resultado, o SHA e as dependências em STATUS.md.

Relatório do gate, toda vez:

Gate 3 (tabelas base), 2026-09, aws: APROVADO
  fatura 120.000,00 · mensal 120.000,00 · diário 120.000,00 · deriva 0,00
  suporte: 1 linha → 12 contas, pesos soma 1,000000

Um gate com falha interrompe a construção. Depure com a tabela de falhas da especificação (os nomes de problema de cada verificação estão em reconciliation-ops.md, "Modos de falha"), corrija, re-execute.

Mapa de fases

FaseConstróiCampos do perfilEspecificaçãoCasosGate
0descoberta, entrevista, o verificador, planotodosdiscovery.md, intake.md, plan.md—plano aprovado (D-NNN)
1Exportações FOCUSprovidersfocus-export.md—um mês inteiro consultável (D0)
2layout de armazenamento, mecanismo, tabelas e as entregas que preenchem raw (cópia ou poller, staging, etapa de publicação do ETL)runtime, providersstack.md, data-model.md, pipeline.md ("Entrega")—um mês publicado corresponde ao seu manifesto; uma consulta raw de um mês varre uma fração dos arquivos desse mês
3adaptadores, tabelas base com rateio e divisões de custos compartilhados, a reconstrução do ETLproviders, dimensions, routing.key, finance, period_charges, shared_costsproviders.md, data-model.md, splitters.md, pipeline.mdadapters, load, share, checksfatura == mensal == diário por pagador em um mês fechado
4regras, lookup, viewscategories, routingrules-engine.mdrules, viewscategorias aparecem; Não Alocado reportado
ADivisões SaaSsaas.vendorssaas.mdvendoro fornecedor mostra split; totais se mantêm
BNamespaces Kuberneteskuberneteskubernetes.mdk8spesos limpos; cobertura ≥ alvo
5reconciliação, operações, fechamentofinance, org.finance_partnerreconciliation-ops.md, testing.mdchecksonde a organização insere totais de fatura (Q-F5), um mês fechado passa a verificação de fatura para cada provedor, seu resultado armazenado com o mês; uma divisão deliberadamente quebrada falha a execução em uma cópia de desenvolvimento; uma caminhada pelos números com o parceiro de finanças, ou o proprietário quando não houver

references/pipeline.md tem a ordem de processamento que essas peças executam em tempo de execução.

Graus de liberdade

  • Fixo (seja qual for o mecanismo): os invariantes e o que os casos dizem que deve sair (adapters.yaml exceto: mostra as escolhas de um perfil nas formas brutas das exportações): as regras de rateio, a expansão com pesos que somam 1,0, os gates dos produtores (por pagador, gasto positivo, dados de fornecedor do mês inteiro), as verificações e no que elas param, a ordem de execução e limpeza em caso de falha, recusar parâmetros de consulta não preenchidos.
  • Deles (escreva livremente para corresponder ao código deles): o mecanismo e idioma, layout de arquivo, infraestrutura como código, empacotamento, agendamento, dashboards, CI e os nomes de arquivos, funções e infraestrutura (os nomes de tabela, coluna e problema que os casos usam são fixos).

Quando você não tiver certeza de qual lado uma mudança está, é fixo.

Quando o usuário resiste

references/pushback.md tem os usuais ("alocar no ETL", "mapear 100%", "um framework para cada fornecedor", "precisão por pod") com a resposta e onde o artigo argumenta.

Pronto significa

  • Cada mês fechado passa na verificação de totais para cada provedor, através de cada divisão, e, onde a organização insere totais de fatura, na verificação de fatura.
  • Quem reporta custo (o parceiro de finanças, ou o proprietário quando não houver) responde "quanto custou o time X no mês passado?" a partir de uma view, sem novo SQL.
  • Uma mudança de regra é um pull request: CI expande, o revisor vê o que se move, o merge recategoriza todo o histórico sem reconstrução.
  • Não Alocado é alertado como um valor, em sua moeda, e com tendência de queda.
  • O custo de execução é pequeno e medido (na pilha de referência, cerca de $10 por mês para S3, Athena e Lambda juntos para 15 milhões de linhas de fatura por mês; a parte do Athena está nas métricas de varredura do workgroup).
  • STATUS.md mostra toda fase que o plano constrói passou com um SHA; DECISIONS.md explica cada escolha que um recém-chegado questionaria.

Habilidades Relacionadas