Esta página foi escrita para pessoas que ajudam a triar issues no rastreador de issues do Github.
Preamble
- Qualquer projeto tem recursos limitados; a diferença entre os projetos estará no limiar.
- Qualquer projeto deve ter metas claras. Para o Ansel, é gerenciar, editar e exportar coleções de imagens RAW em um computador desktop, por um usuário final que não é usuário de CLI mas que coloca a qualidade visual da imagem acima de tudo.
- Qualquer projeto tem sobrecarga, isto é, ações requisitadas para atingir as metas, embora não sejam diretamente a meta e portanto devam permanecer mínimas. Para o Ansel, é a manutenção do site, da documentação, dos servidores, dos pacotes de compilação noturna, limpezas de código, depuração, testes de regressão, suporte a múltiplos sistemas operacionais, triagem de issues, etc.
- Metas e sobrecarga devem ser expressas em termos de tarefas a executar a fim de resolver problemas (issues). Se não há problema a resolver, então não há trabalho a fazer: o status quo também é ótimo, não crie trabalho só por criar.
- por causa da limitação de recursos, as tarefas precisam ser ordenadas conforme sua prioridade.
O documento a seguir tem por objetivo definir essa prioridade.
O Ansel foi bifurcado do Darktable porque o Darktable não tem meta clara, nem gerenciamento de prioridades, e a sobrecarga aumenta a cada ano, o que é a marca registrada das fábricas de burn-out e é insustentável a médio prazo.
Definindo boas issues
O gerenciamento de projetos funciona melhor com tarefas SMART. S.M.A.R.T. significa:
- Específica (Specific) (ex: encontrar a URI das fotos que o Ansel exportou no sistema de arquivos e abri-las)
- Mensurável (Measurable) (ex: número de cliques/passos requeridos, tempo de CPU para executar a tarefa em alguma plataforma-alvo)
- Acionável/Alcançável (Actionnable/Achievable) (ex: pode ser integrada à base de código atual com apenas pequenas reescritas, precisa de apenas algumas centenas de linhas de código)
- Relevante/Razoável (Relevant/Reasonable) (ex: faz parte de um fluxo de trabalho fotográfico razoavelmente geral, seria usada por uma parcela significativa dos usuários)
- Delimitada no tempo (Time-bound) (ex: requer no máximo 70 homens-hora).
Uma boa issue é aquela que leva a uma tarefa SMART. Para o Ansel, isso significa issues focadas em um problema claramente definido que afeta uma etapa claramente definida do fluxo de trabalho de edição de fotos (“Tenho problemas para fazer X por causa de Y e eu gostaria de Z”).
Perguntas e discussões gerais devem acontecer em https://community.ansel.photos.
Issues ruins são:
- amplas demais (“automatizar o fluxo de trabalho”, “melhorar a UX”),
- focadas nos meios (“usar rede neural”, “estender a curva de tons”) em vez da meta (“mascarar o céu”, “controlar a saturação seletivamente”),
- fora do escopo (“portar para Android”, “mudar para Qt”, “mudar para Vulkan”)
- que afetam bibliotecas/projetos de terceiros (Rawspeed, Libraw, Exiv2, Lensfun, GPhoto2, Gtk, etc.),
- subjetivas demais (“por favor, faça as coisas como aquele outro software que eu usei no passado e que gosto muito”). O que o usuário A gosta será desgostado pelo usuário B, não temos como trabalhar com isso.
Nota lateral: algumas issues podem soar como coisas que precisam de mais código, quando na verdade precisam de melhor documentação dos recursos atuais, ou de pequenos retoques na GUI (renomear rótulos, reorganizar widgets), então isso é algo a ter em mente antes de sair atirando.
Definindo prioridades
Em um mundo ideal, as tarefas (ou seja, as boas issues) seriam adicionadas à lista de afazeres de forma linear, à medida que os marcos são alcançados, e seu produto de código seria testado por algumas semanas enquanto o código estaria congelado no restante, até que ficasse comprovado que tudo se sustenta, caso em que descongelaríamos o código e passaríamos para a próxima tarefa da lista de afazeres.
O problema é que isso implica todos a postos para a fase de testes, para que não congele o código por tempo demais. Como isso não acontece (as pessoas tiram férias, têm filhos, se mudam, trocam de emprego, têm uma vida…), precisamos paralelizar os testes do produto das tarefas anteriores enquanto trabalhamos na próxima, para sermos eficientes.
Isso quer dizer que a lista de afazeres não é linear e algumas coisas importantes podem ser adicionadas ou removidas dinamicamente, dependendo do que acontece. O problema, então, é determinar o que constitui algo importante o suficiente para perturbar o cronograma.
Não há regra definitiva aqui, então você terá que usar seu melhor julgamento, mas há algumas regras práticas:
- algo recentemente quebrado (uma regressão) é mais fácil de localizar e corrigir mais cedo do que mais tarde, então, no cômputo geral, pode dar menos trabalho no total fazê-lo mais cedo,
- algo que impede o software de funcionar por completo (travamento, arquivos de saída corrompidos, perda de dados) é crítico o suficiente para ter precedência sobre melhorias e correções mais cosméticas,
- algo que impacta um grande número de usuários e para o qual não se encontra nenhuma solução alternativa também terá precedência.
Pelo contrário, qualquer coisa que impacte um pequeno número de usuários, ou recursos de nicho/secundários, ou pequenos incômodos que têm soluções alternativas, não são críticos o suficiente para justificar perturbar o cronograma. Esses serão adicionados à fila de forma primeiro a entrar/primeiro a sair.
O Ansel tem 4 níveis de prioridade, definidos como tags de issue:
priority: critical: Afeta funcionalidades básicas e centrais do software de um modo que o impede de funcionar por completo,priority: high: Afeta funcionalidades básicas e centrais do software de um modo que degrada severamente a usabilidade,priority: medium: Afeta funcionalidades básicas e centrais do software de um modo que degrada levemente a usabilidade (soluções alternativas disponíveis),priority: low: Afeta funcionalidades opcionais e de nicho
Definindo marcos
Os parâmetros dos módulos são salvos como blobs binários. Lidamos com eles gerenciando seu tamanho em bits. Quando um novo parâmetro é adicionado, precisamos escrever código para lidar com a conversão, ou seja, o tamanho em bits diferente do blob de parâmetros, e incrementamos a versão interna dos parâmetros dos módulos. Nenhum código é escrito para compatibilidade retroativa, então fotos editadas com módulos mais novos não podem ser abertas em módulos mais antigos. Os parâmetros dos módulos são usados em estilos, em predefinições e também em arquivos XMP.
Por essas razões, qualquer issue que levasse a adicionar parâmetros em módulos (seja os módulos de processamento de imagem na sala escura, seja os módulos da mesa de luz que lidam com exportação e metadados) quebraria a compatibilidade retroativa e precisa ser planejada para a próxima versão maior do software (1.0, 2.0, 3.0, etc.). Isso significa que apenas mudanças de GUI e de comportamento são permitidas dentro da mesma versão maior, e podem ser planejadas para a próxima versão menor (0.1, 0.2, 0.3, depois 1.1, 1.2, 1.3, etc.).
O Ansel tem apenas 2 marcos em todos os momentos: a próxima versão menor e a próxima versão maior.
Definindo a dificuldade
A dificuldade está diretamente relacionada à quantidade de trabalho requerida por uma tarefa, isto é:
- o número de linhas de código a escrever,
- o número de arquivos a alterar,
- a probabilidade de quebrar recursos existentes, levando a trabalho extra de testes,
- a existência de recursos similares ou de teoria escrita para realizar a tarefa,
- a sobrecarga de fazer as mudanças e os recursos funcionarem de forma confiável em diferentes sistemas operacionais.
Estimar a dificuldade de forma precisa é algo que apenas um desenvolvedor experiente consegue fazer.
Definindo a natureza
A natureza das issues é gerenciada com rótulos. Temos:
- regressões (coisas que costumavam funcionar mas foram quebradas por mudanças relativamente recentes),
- bugs (coisas que nunca funcionaram nos últimos anos),
- melhorias (coisas que precisam ser aprimoradas ou adicionadas),
- wontfix (não é um bug, mas um recurso ou escolha de design ou necessidade imposta por dependências de terceiros),
- pergunta (não deveria estar no Github, mas em https://community.ansel.photos),
- duplicada (issue já reportada),
- imprecisa (a issue não pode ser compreendida),
- inválida (a issue é “ruim” de acordo com a definição de boa issue acima).
As prioridades são relativas
Veja https://www.youtube.com/watch?v=8fnfeuoh4s8 . Ter que consertar o carro para poder trocar a lâmpada é uma ótima metáfora para trabalhar no código de um software de 12 anos de idade com centenas de milhares de linhas de código escritas por pessoas que não falavam entre si e não documentavam suas mudanças. Consertar o carro não é a prioridade máxima até que se torne o pré-requisito para consertar a lâmpada de alta prioridade.
Seu trabalho de triador
Em última instância, apenas um desenvolvedor experiente será capaz de triar issues com precisão. Mas a razão exige que um desenvolvedor experiente seja empregado para fazer coisas que apenas um desenvolvedor experiente consegue fazer: escrever código simples para resolver eficientemente problemas técnicos que requerem certa quantidade de teoria e design.
O meio-termo é ter triadores ajudando a priorizar as issues óbvias, para que os desenvolvedores só tenham que lidar com as issues menos óbvias e se concentrem em programar.
- rotule apenas as issues que você entende e com as quais se sente à vontade para fazer a triagem. Você não precisa fazer todas, tudo bem se você não souber.
- para as issues que você entende:
- atribua um rótulo de prioridade se puder,
- atribua um rótulo de natureza se puder,
- atribua um marco se puder,
- feche imediatamente a issue se ela for inválida ou duplicada.
- para as issues que você não entende:
- tente fazer mais perguntas ao autor,
- garanta que os autores preencham todas as informações relevantes (SO, hardware, passos para reproduzir bugs),
- é melhor não fazer nada do que fazer errado: issues sem rótulos são mais fáceis de localizar do que issues com rótulos errados.
- não hesite em convocar reuniões por vídeo: melhor sentar-se juntos por 30 min para ter uma conversa produtiva e ajustar decisões do que trocar threads intermináveis de mensagens inúteis.
Obrigado !
Translated from English by : Claude. In case of conflict, inconsistency or error, the English version shall prevail.