Architectural Fitness
Rubrica normativa das dimensões pelas quais se avalia se uma arquitetura é boa de longo prazo. É a checklist concreta que o Princípio #2 (Quality > Speed) manda aplicar quando o `/k-go` ou qualquer IA desempata entre opções/abordagens. Escala (hyperscale) é UMA das dimensões, não o todo. Consolida o que estava espalhado (k-evolve §2, multi-tenant, reuse/sdk-first, security) num único lugar normativo e fecha 3 gaps: evolvabilidade, consistência de dados, reversibilidade.
Vocabulário. Architectural Fitness (pt-BR: Solidez Arquitetural) é o nome do guarda-chuva — quão bem uma arquitetura satisfaz suas dimensões de qualidade ao longo do tempo (termo de *Building Evolutionary Architectures*; as dimensões são as "-ilities" / quality attributes da ISO/IEC 25010). Arquivo permanece
architecture-quality.kmdpor compat de referências. As 12 dimensões abaixo são candidatas naturais a fitness functions quando o audit (/k-audit policies) deixar de ser advisory.
"Melhor arquitetura de longo prazo" ≠ "mais escalável". Escala é uma dimensão entre onze. Este arquivo define o conjunto. É a checklist que o Princípio #2 (Quality > Speed) manda aplicar no desempate — quando duas opções são igualmente conformes à Stack, vence a que melhor satisfaz estas dimensões pensando nos próximos anos.
Como usar
- No desempate (
/k-goRegra 13, ou qualquer decisão de design),percorrer as dimensões abaixo e escolher a opção que maximiza o conjunto no horizonte de longo prazo, não no esforço imediato.
- Cada dimensão tem
pergunta-chave+anti-padrões+ `onde a Stackjá enforça` (pra não duplicar).
- Dimensões com
→ policydelegam o detalhe normativo àquela policy —esta rubrica só as enumera como dimensão; o detalhe vive lá (reuse-first per
divide-and-conquer). - Não é checklist de bloqueio mecânico — é lente de julgamento
(
stack-principles= guidelines, não regras). Audit é advisory.
As 12 dimensões
D1 — Contratos & abstração correta
Pergunta: as fronteiras têm contrato explícito (interface, tipo, protobuf, OpenAPI) e a abstração modela o domínio certo? Anti-padrões: abstração vazada, contrato implícito "por convenção", tipo any/map[string]any onde cabe um tipo nomeado, abstração que existe mas é a errada (pior que nenhuma). Enforça: k-evolve §2.3.
D2 — Acoplamento & fronteiras
Pergunta: as camadas são independentes? Trocar a implementação de uma exige tocar nas outras? Anti-padrões: escalar A exige reescrever B; estado global mutável como ponto de acoplamento; dependência circular entre módulos. Enforça: k-evolve §2.3, hyperscale-first §1.
D3 — Evolvabilidade & extensibilidade (gap fechado)
Pergunta: adicionar a próxima feature/variante cabe sem reescrever o núcleo? O design é aberto pra extensão, fechado pra modificação? Anti-padrões: switch gigante que cresce a cada caso novo; assumir um único tenantlocalesurface; constantes onde deveria haver config; decisão que só funciona pro caso de hoje. Enforça: implícito em k-evolve §2.3 — nomeado aqui.
D4 — Escala & eficiência
Pergunta: funciona em 100× volume? Menor overhead de I/O, cache, índice, streaming? Anti-padrões: ver tríade completa em hyperscale-first.kmd. Enforça: → policies/hyperscale-first.kmd (não duplicar).
D5 — Isolamento multi-tenant
Pergunta: isola corretamente entre N koder_user_id e N workspace_id? Eixo ortogonal à escala — escalar bem e vazar cross-tenant é falha equivalente a não escalar. Anti-padrões: ver multi-tenant-by-default.kmd. Enforça: → policies/multi-tenant-by-default.kmd (não duplicar).
D6 — Consistência & integridade de dados (gap fechado)
Pergunta: o modelo de consistência foi escolhido de propósito (forte × eventual)? Operações são transacionais/idempotentes onde precisam ser? Há caminho pra perda ou corrupção silenciosa de dados? Anti-padrões: write sem transação onde há invariante cross-row; retry não-idempotente; "eventual" escolhido por acidente, não por decisão; ausência de constraint/migração que garanta invariante. Enforça: tangencia rfcs/stack-RFC-001 — nomeado aqui como dimensão de primeira classe.
D7 — Segurança & privacidade
Pergunta: authz aplicada onde deve, inputs validados nos boundaries, segredos fora de log, dado de identidade com retenção correta? Anti-padrões: ver security.kmd + identity-data-retention.kmd. Enforça: → policies/security.kmd, k-evolve §2.5 (não duplicar).
D8 — Observabilidade & operação
Pergunta: dá pra ver o que acontece em produção (traces, métricas, logs estruturados, health checks) e operar com segurança (graceful shutdown, retry com backoff)? Anti-padrões: ver observability-first.kmd (sinais) + always-on.kmd (resiliência/operação). Enforça: → policies/observability-first.kmd (sinais: logsmétricas tracesSLOalerting) + always-on.kmd (operação) (não duplicar).
D9 — Reversibilidade & custo de migração (gap fechado)
Pergunta: é uma porta de mão dupla ou de mão única? Dá pra migrar pra fora depois sem reescrever os consumidores? Há plano de migração? Anti-padrões: wire format/schema sem versão; acoplar consumidores ao detalhe interno de um substrato; escolha irreversível sem RFC; migração sem checkpoint/rollback. Enforça: parcialmente stack-principles §8 (spec-before-code: "migration plan") + always-on.kmd — nomeado aqui como dimensão.
D10 — Conformância à Stack & reuso
Pergunta: reusa o que já existe (SDK, spec irmã, binário, padrão) em vez de reinventar? Segue naming, specs e RFCs ratificadas? Anti-padrões: código que duplica padrão do SDK; reinventar contrato que já tem spec; naming fora do registry; ignorar RFC ratificada. Enforça: → policies/reuse-first.kmd, policies/sdk-first.kmd, specs/naming/forms.kmd, k-evolve §2.6 (não duplicar).
D11 — Debuggability / analisabilidade (composição)
Pergunta: dado um defeito, quão rápido se diagnostica a causa e se reproduz? Há repro determinístico, stacktrace simbolicado, e correlação do sintoma até a causa? Anti-padrões: stacktrace com offsets crus (sem símbolos); bug não-reproduzível por falta de seed/determinismo ("funciona às vezes"); panic sem contexto nem trace_id; ausência de repro-as-test; precisar adicionar instrumentação nova só pra diagnosticar. Enforça (composição — não policy própria): → observability-first.kmd (diagnóstico em prod: trace_id correlaciona os 3 sinais + symbolication §1.5) + headless-first.kmd R5 (repro determinístico de UI) + `specs/errors