Design (canon)
O design é concluído quando uma sessão posterior pode ler o porquê (uma decisão, canon/decisions/D-n.md) e o que deve valer (regras, canon/rules/<dominio>/BR-n.md) sem perguntar a ninguém. Um design que vive apenas nesta conversa está perdido.
1. Escolha o modo
| Modo | Leia | Foco |
|---|---|---|
architecture | references/mode-architecture.md, references/architecture-patterns.md | camadas, limites, C4, migração |
api | references/mode-api.md, references/api-design.md | endpoints / comandos, erros, autenticação, paginação |
database | references/mode-database.md, references/database-design.md | esquema, índices, migrações, padrões de acesso |
system | references/mode-system.md, references/system-design.md | SLAs, modos de falha, capacidade |
module | references/mode-module.md | responsabilidade, profundidade (teste de deleção), costuras, categorias de dependência |
Leia apenas os arquivos do modo que você precisa. Referências transversais (references/cross-cutting/: autorização, tratamento de erros, idempotência, identidade de sessão) quando o design as tocar.
2. Antes de projetar
canon context <caminho|dominio|C-n>: todo o domínio atual, suas regras, as decisões aceitas e mudanças abertas. O design não deve contradizer uma regra ativa ou uma decisão aceita; se for preciso, diga e altere-as na mesma mudança.canon search <topico>: decisões e anotações anteriores sobre a mesma questão. Estenda ou substitua (--supersedes D-n), nunca refaça silenciosamente.- Veja como 1–3 produtos ou bibliotecas maduros resolvem o mesmo problema antes de inventar um.
- Leia o código existente que você está alterando (símbolos, chamadores) antes de propor estrutura.
3. Projetar
- Enquadre o problema antes de listar opções: que perguntas este design deve responder, quais cenários deve atender? Ao avaliar um design existente, uma lista de seus defeitos é entrada, não o enquadramento: um plano construído apenas a partir da lista de defeitos é um remendo, não um design.
- Dê pelo menos duas opções reais com seus trade-offs e uma recomendação. Real significa designs diferentes, não um design feito mais ou menos ("consertar 3 coisas" vs. "consertar 10 coisas" é uma opção). Três ou mais opções ou várias dimensões → escreva o raciocínio dimensão por dimensão em vez de uma lista de prós/contras da memória.
- Antes de dar a recomendação, faça com que ela seja desafiada uma vez por um subagente que veja o problema e as opções, mas não a sua recomendação. Pergunte a ele: a própria pergunta está mal formulada, falta um design genuinamente diferente, em qual cenário cada opção falha? Aborde o que ele levantar, então recomende. Pule isso apenas para um design pequeno dentro de um módulo que não mude interface alguma, e diga que pulou e por quê.
- Verifique a documentação oficial atual antes de propor qualquer biblioteca, versão ou API.
- Uma pergunta que é respondida mais rápido por um protótipo descartável do que por argumentação (este modelo de estado ou dados se sustenta no uso, qual de alguns layouts de tela funciona) é resolvida primeiro com a skill canon-prototype; o design então cita o que o protótipo mostrou.
- Quantifique objetivos vagos primeiro ("rápido" → p99 abaixo de X ms a Y rps).
- Cada cenário que o design atende nomeia pelo menos uma falha de nível de negócio que deve tratar (limite atingido, pagamento recusado, permissão revogada no meio do fluxo, interrupção upstream) e como falha alto e de forma recuperável; "nenhum modo de falha se aplica" precisa ser argumentado, não assumido.
- Pese a complexidade de cada opção contra o que custa quando o cenário acontece, e faça uma pergunta para cada cenário: as operações normais levam a ele? Para o canon, várias sessões trabalhando e finalizando ao mesmo tempo é uso normal; como um teste poderia reproduzi-lo não decide. Uma situação que precisa de uma configuração ou ação anormal (um wrapper de usuário em torno de um comando do sistema, um backend não padrão que ninguém usa, matar um processo específico no meio do passo, entrada hostil que não cruza fronteira de segurança) torna-se um limite conhecido (uma linha nas consequências ou na regra), não um novo mecanismo; perda de dados, segurança e quebrar uma das promessas do projeto (para canon, P1 a P7 em canon/product.md) são as exceções.
- Revise o rascunho contra as lentes do modo você mesmo. Subagentes de revisão paralela (um por lente, veja o arquivo do modo) são opcionais: cada um parte do zero de contexto e custa dezenas de milhares de tokens, então use-os apenas quando o raio de explosão for grande (cross-module, API pública, migração de dados, segurança).
Gates de qualidade (todos devem passar, ou diga qual não passa e por quê)
| Modo | Gates |
|---|---|
architecture | todo requisito não funcional tem uma resposta arquitetural mensurável; toda tensão tem uma decisão com fundamentação; riscos altos têm mitigações; fases de migração com rollback |
api | toda operação tem seus erros; toda operação tem seu requisito de autenticação; questões de segurança resolvidas ou aceitas com fundamentação; paginação e limites de taxa declarados |
database | todas as chaves estrangeiras indexadas; toda tabela justificada por um padrão de acesso; migração com zero downtime para toda mudança de esquema; sem float para dinheiro, fusos horários em timestamps |
system | metas de SLA (throughput, p99, disponibilidade); nenhum ponto único de falha não mitigado; todo componente tem um modo de falha e degradação; capacidade em 1×/10×/100× |
module | nenhum ciclo de dependência; uma responsabilidade clara por módulo; todo módulo passa no teste de deleção; nenhuma costura com um único adaptador; superfície pública suficiente para testar como caixa preta; dependências injetáveis |
Transversal (avalie toda vez; pule apenas com uma razão declarada)
| Preocupação | Quando | Faça |
|---|---|---|
| Segurança | entrada do usuário, autenticação, armazenamento, chamadas externas | rastreie o fluxo de dados, liste ameaças e mitigações |
| Concorrência | estado compartilhado, várias sessões ou processos | nomeie o entrelaçamento que poderia quebrá-lo em uso normal e o que o torna atômico; os mais raros são limites conhecidos, a menos que percam dados |
| Performance | caminhos sensíveis à latência, dados grandes | defina um orçamento e mostre que o design o atende |
| Observabilidade | novo componente | o que é registrado ou gravado, e como uma falha é percebida |
| Privacidade de dados | PII ou outros dados do usuário | classifique sua sensibilidade; criptografia em repouso e em trânsito; período de retenção e exclusão; trilha de auditoria de quem lê ou altera |
4. Registre o design
- Decisão para cada escolha real:
canon decision new --title "..."→ preencha 背景 (fatos, dados), 方案 (cada opção marcada 采用 ou 否决 com porquê, pelo menos uma de cada), 决定, 后果. Escreva em chinês (documentos do canon são em chinês). Sob as opções, cite de onde vêm os fatos, uma linha cada:- 来源:<URL ou caminho do repositório> "<citação exata, 8+ caracteres>"— pesquise a prática externa primeiro, depois cite-a; uma nova decisão precisa de pelo menos uma fonte, e o landing busca cada nova e a recusa a menos que a citação esteja realmente lá. Não adicione pontuações autoavaliadas ou níveis de confiança: ninguém pode verificá-los. - Regras para cada comportamento que o design compromete o produto:
canon rule new --domain <d> --title "...". Uma regra = um gatilho e um resultado; preencha 规则 e 例子 com entradas concretas de ambos os lados do limite. Um comportamento que esta mudança não constrói (seu código vem em um passo posterior do plano) recebestatus: plannedno front matter da regra: precisa de 规则 e 例子, mas sem teste, e a mudança que o constrói o lista sobrules:e o torna ativo. Nos 例子 de uma regra planejada, fixe apenas os limites que o design estabelece; os casos de borda que a implementação encontrar são adicionados pelo passo que a constrói. - Arquivo de mudança (
canon/changes/C-n.md): 为什么 / 要改什么 referenciando a decisão e as regras. - Se o design alterar um contêiner (uma parte de runtime, onde seus dados vivem) ou um fluxo principal, atualize
canon/architecture.mdna mesma mudança: ele descreve o sistema como ele é agora, cada parte terminando com seus números de decisão. Verifique seus números de decisão contra o que você acabou de decidir: uma decisão substituída ou alterada significa uma linha a reescrever. - Finalize como de costume (
canon work land). A revisão de regras lê a decisão e as regras contra todo o domínio, e a visão geral; corrija o que ela bloquear.
Nenhum documento separado por design: interfaces que valem a pena fixar antes da implementação (tipos, assinaturas de comando, esquema) vão para o arquivo de mudança ou para o próprio código.