hubd

O rastreador de projetos para equipes de humanos e agentes de IA — em arquivos simples. Servidor MCP + CLI, zero dependências.

Documentação

hubd

O rastreador de projetos para equipes de humanos e agentes de IA — em arquivos simples.

Uma ferramenta para agentes raramente falha por travar. Ela falha ao responder — com confiança, e errado. Uma lista que terminou cedo sem avisar. Uma contagem que acaba sendo, em sua maioria, duplicatas. Um fechamento de tarefa que cai no id de outra pessoa. Uma pessoa pararia em "espera, mil e quinhentas tarefas? Eu não criei mil e quinhentas tarefas." Um agente não tem esse tipo de conhecimento prévio: ele pega o número e constrói em cima dele, e cada visualização a jusante herda o erro, ainda soando seguro.

hubd é construído contra esse modo de falha, e isso aparece nas partes chatas. Os logs são somente-acréscimo e atribuídos, então uma visualização errada permanece recuperável a partir de dados que sempre estiveram corretos. Cada truncamento se anuncia. Qualquer coisa que o hub não possa observar é relatada como não observada, em vez de estimada. Grande parte deste código-fonte não são recursos — são recusas a soar certeiro.

Você executa duas, três, cinco sessões de agentes — ferramentas diferentes, fornecedores diferentes — em seus projetos. Cada uma é brilhante, e cada uma não faz ideia de que as outras existem. Você é a camada de coordenação: copiando e colando contexto, re-explicando o estado, descobrindo na segunda-feira o que um agente fez na sexta-feira.

hubd substitui você nessa função pela tecnologia mais chata disponível: arquivos simples. Uma sede compartilhada para toda a sua equipe — agentes e humanos: um diário do que todos fizeram, filas de tarefas nas quais todo agente pode esperar, tarefas entre projetos, e um kanban somente-leitura para observar tudo. Tudo em markdown e JSONL, em uma pasta que é sua.

the hubd kanban: agents pick up, finish and file work while the activity log fills in

hub serve — o quadro é somente-leitura e tem exatamente um botão (⚙ Regras, ele abre AGENTS.md). Os cartões se movem porque os agentes os movem; a página apenas relê os arquivos.

Não é um executor. Orquestradores iniciam seus agentes de codificação e transmitem sua saída — isso é tornar a codificação mais rápida. hubd gerencia o trabalho: quais projetos, o que vem a seguir, quem faz e quando, o que já aconteceu. Um orquestrador pode executar seus agentes; hubd executa seus projetos. Eles se compõem.

O par Unix

  • hubd — o daemon: um servidor MCP (stdio, JSON-RPC 2.0) com o qual os agentes falam.
  • hub — a CLI: os mesmos dados para humanos, sem necessidade de LLM.

Como sshd e ssh. O daemon atende agentes; a CLI atende você.

Início rápido

Opção A — comece uma empresa (copie a pasta). Um comando coloca hubd-company/ em uma pasta sua:

npx degit bzdOS/hubd/hubd-company my-company   # then: cd my-company && git init

Ou clone este repositório e copie a pasta — ela não precisa ser a raiz do seu repositório. Você obtém uma estrutura de organização pronta: constituição (AGENTS.md), integrações de funções, cartões de projeto, um cartão de operador, filas, receitas, e um chronicle/ semanal escrito por agente (a camada narrativa). Contratar um agente = uma nova sessão lê um arquivo de função. Este modelo NÃO está incluído no pacote npm; ele vem do repositório.

Opção B — adicione os binários ao que você já tem:

npm i -g @bzdos/hubd   # installs both binaries: hubd (MCP server) + hub (CLI)
hub init             # scaffold a team folder: AGENTS.md, INBOX.md, queues/
hub version          # which hubd, and which copy of it is answering
hub doctor           # hub base, team root, locks, queues, ghost queues, writer versions
hub status           # every project at a glance (⚠ marks a card behind its journal)
hub brief            # morning brief: tasks, journal, locks
hub queue gc         # list queues nobody ever consumed (--apply archives them)
hub gc               # everything that piled up, by class; touches nothing without --apply --by
                     # doctor also flags: work dispatched to a role with nobody
                     # home, and queues trimmed outside hubd (which used to
                     # re-deliver everything that survived the trim)
hub now              # the ONE task to do next, and why it won
hub agenda           # the day split by who can act: agent work vs owner buttons
hub recall "<q>"     # ranked memory, every hit dated and flagged if stale
hub usage --days 7   # what the work cost: supplied vs measured, never mixed
hub audit            # what the cards declare vs what happened (--apply files incidents)
hub lint             # which of your rules are checks, not just prose
hub serve            # read-only kanban on localhost
# one-off, without install: npx -p @bzdos/hubd hub status

O pacote npm inclui: hub/ (binários + lib), prompts/, docs/, README.md, LICENSE e HARVEST.md. Ele NÃO inclui hubd-company/.

Novo aqui? Dois guias: o início rápido percorre todo o caminho — instalação → pasta da equipe → primeiro agente → filas — e receitas fornece cenários completos (um trabalhador permanente, uma frota de orquestradores, botões de proprietário, colhendo um chat, topologia de infraestrutura).

Conecte seu agente (qualquer cliente MCP):

claude mcp add --scope user hubd --env HUBD_AGENT=dev-<yourproject> -- npx -y @bzdos/hubd

HUBD_AGENT vale a pena configurar no primeiro dia. Cada escrita nomeia seu autor — entradas de diário, tarefas, mensagens de fila — e o campo é obrigatório: um log somente-acréscimo com uma escrita não atribuída permanece não atribuível para sempre. HUBD_AGENT é o mínimo: quando um chamador não diz quem é, a escrita é atribuída a esse nome mais um sufixo curto por sessão, em vez de falhar. Nomeie a função, não o modelo — dev-hubd, reviewer-bsdos — porque qual modelo você é já está na transcrição do seu próprio cliente, enquanto muitas sessões a compartilham. Nomes de modelo e cliente (claude, gpt, cursor) e espaços reservados (unknown, cli, root) são recusados por esse motivo. Um chamador que conhece sua própria função sempre pode ser mais específico do que o mínimo.

Sem MCP? Sem problema — todo modelo que pode ler e escrever arquivos pode participar: cole o bloco correspondente de prompts/ (Claude Code, Cursor, Codex/AGENTS.md, ou um chat MCP) — ele conecta o hubd e aponta para HUBD.md, o protocolo sempre atual.

Executando para uma equipe? hubd também fala MCP sobre HTTP — um hub compartilhado para o qual todos os seus agentes apontam, protegido por token e multi-inquilino. Veja self-hosting.

Atualizando, e onde seus dados vivem

hubd é uma ferramenta, como git ou node: você instala o código, e seus dados são uma pasta que é sua. São duas coisas separadas — e esse é exatamente o ponto.

  • Código — o pacote npm. Atualize como qualquer CLI global: npm i -g @bzdos/hubd@latest (ou execute uma vez com npx -y @bzdos/hubd). Uma nova versão entrega o mecanismo (changelog); ela nunca toca nos seus dados.
  • Dados — HUBD_DIR (padrão ~/.hubd): markdown simples + JSONL, seus para manter. HUBD_TEAM_DIR definido sozinho significa o mesmo diretório único para tudo; defina ambos apenas quando as filas realmente moram em outro lugar. hub doctor diz qual venceu.
  • Quem escreveu — HUBD_AGENT: o autor padrão para chamadas que omitem um, por configuração do servidor. Defina-o em cada cliente e em cada host; um campo obrigatório sem piso transforma um argumento esquecido em uma chamada falha.
  • A malha está realmente sincronizando? hub doctor conta quantos commits este hub está atrás de origin, porque um loop de sincronização que continua tentando parece exatamente com um que funciona: um nó aqui foi 228 commits sem receber o trabalho de ninguém enquanto cada relatório chamava o hub de saudável. Ele também nomeia caminhos rastreados que diferem apenas por maiúsculas/minúsculas — no macOS ou Windows esses são um arquivo para duas entradas de índice, o que nenhum commit pode limpar, e eles param um merge permanentemente. Desde 0.9.6 o hubd não criará tal par em primeiro lugar, e o doctor sinaliza qualquer cartão que ainda contenha marcadores de conflito, já que um leitor os serve como conteúdo em vez de como um erro.
  • Uma fila que responde "nada novo" mas não está vazia. A entrega avança um cursor por arquivo, então um cursor que este usuário não pode escrever interrompe a entrega completamente — e costumava parecer exatamente como uma fila ociosa, em ambos os lados: a espera dizia nada novo, o envio dizia enviado. Quatro funções ativas seguraram um dia de pedidos dessa forma. Agora a espera falha com o arquivo e a correção, hub doctor lista tais cursores, e um envio relata a profundidade agora em espera para que um backlog crescente seja visível ao remetente.
  • Um cartão que virou um log. O resumo é anunciado como algumas linhas do estado atual, e nada o mantinha lá: um hub alcançou três cartões além de 72 KB, e ler o maior foi recusado pelo orçamento de contexto do chamador. O hubd agora recusa um resumo longo demais e um appendLine datado (isso é um evento — hub report o aceita), e move as entradas mais antigas de uma seção longa demais para projects/history/<slug>.md. Movido, nunca descartado: fatos escritos por hub_report vivem apenas no cartão. hub cards compact atualiza um hub que cresceu primeiro.
  • Um par que ficou quieto. Um nó cujo pull continua abortando sabe disso, e ninguém executa o hub doctor de outra máquina — então ele escreve localmente, não alcança ninguém, e parece bem de todos os lados. hub doctor agora nomeia os nós que pararam de aparecer na própria história da malha.
  • Antes de reescrever a pasta do hub — hub freeze "<why>" --by <you> interrompe a sincronização de malha deste nó, seja qual for o agendamento, hub unfreeze a libera, e hub doctor não deixará você esquecer que está ativado.
  • Quando uma fila conflita — somente anexação por contrato, mas sem merge de união, dois lados que ambos anexaram colidem. hub queue resolve mantém o nosso no lugar e anexa o deles no final, o que deixa cada cursor de byte no hub válido.
  • Quando um cartão conflita — o único arquivo compartilhado que pode, sendo o único mutável — hub card resolve une os trechos de lista com marcadores (dois nós anexando fatos não discordaram) e deixa trechos de prosa para você, nomeados por seção. Ele sai com código não zero enquanto algo permanecer.
  • Várias máquinas? Torne HUBD_DIR um repositório git e sincronize-o como quiser — um remoto privado via SSH funciona, sem necessidade de GitHub. Cada máquina instala o código do npm; seus dados viajam no seu próprio git. Duas trilhas separadas: código do pacote, dados na sua pasta. Atualizar o código nunca migra ou exclui seus dados — os logs de eventos são somente anexação e mais ricos que o esquema de qualquer versão única.
  • Um hub que foi escrito isoladamente — uma variável de ambiente mal roteada, um ~/.hubd privado, um laptop que nunca se juntou — é incorporado com hub absorb <dir> --as <label>: seus logs tornam-se os arquivos por nó desse rótulo aqui, seus ids de tarefa são renomeados <label>-<n> em cada campo e cada texto para que parem de colidir com os seus, seu histórico de fila é mantido de lado e nunca reentregue, e o plano (mapa de ids, blocos não lidos, cartões mantidos para um humano) é impresso antes que qualquer coisa seja escrita. Nada já no seu hub é reescrito.
  • Qual versão está realmente rodando — hub version imprime o número e o caminho da cópia que o imprimiu, porque em uma máquina real essas são uma pergunta: uma instalação global desatualizada e um checkout de código-fonte ativo são ambos chamados hub. Desde 0.9.4 cada linha de diário também carrega a versão que a anexou, então hub doctor relata toda a malha — qual nó está atrasado, se esta cópia é a desatualizada, e se dois hubds estão escrevendo em um nó ao mesmo tempo, nomeando os agentes em cada versão. Esse último detalhe é o 0.9.12 pagando por um palpite errado de si mesmo: o aviso costumava dizer "duas instalações em um nó", e neste hub havia uma instalação — um servidor MCP residente continuava escrevendo a versão que havia importado enquanto um CLI novo escrevia a atual a partir do mesmo arquivo. Atualizar um pacote no disco não alcança um processo que já o importou. Este bloco inteiro existe porque a máquina que desenvolve o hubd rodou um CLI nove versões antigo por semanas e nada em lugar algum poderia ter dito isso.
  • Retomando após uma compactação de contexto — uma compactação entrega a um agente um resumo do que aconteceu; o trabalho retoma do que existe. hub whereami (shell) e hub_context (MCP) respondem a partir do estado: o projeto, seu resumo com idade e um veredito digestStale, tarefas abertas, quem mais está com heartbeat neste checkout, o final do diário — além, no shell, do inventário git (assuntos de commit, estatística de diff, arquivos não rastreados com sua primeira linha, arquivos alterados na última meia hora). hub_whatsnew({since:"session"}) retorna o que a própria sessão escreveu, o que o checkpoint padrão "desde minha última chamada" não pode. Hooks de editor que executam hub whereami no início da sessão e após uma compactação: prompts/client-hooks.md.
  • Reivindicações que avisam antes da edição — o area de uma reivindicação é um glob de caminho relativo à raiz do projeto (src/**/*.ts, docs/{a,b}.md, um diretório). hub claim check <path> / hub_claim_check diz de quem é a zona de um arquivo antes de você escrevê-lo, e hub_context relata claimsTouched quando um arquivo recém-alterado está na zona de alguém. O bloqueio permanece suave: ele informa, nunca proíbe. Áreas de prosa ainda são aceitas, sinalizadas matchable:false.
  • Corrigindo um resumo — hub card <slug> --replace "<old>" --with "<new>" (ou hub_card_set({replace:[{from,to}], appendLine})) corrige uma linha desatualizada sem reescrever o enquadramento do dono; um from que não está lá é um erro, nunca um no-op silencioso. hub_report informa a idade do resumo em cada resposta e dá um toque quando ele fica atrás do diário que você acabou de mover.
  • O que uma atualização exige de você — às vezes uma nova versão quer algo fora do código: uma variável na configuração de um cliente, uma função declarada no hub, uma seção de protocolo que vale reler. O hubd resolve isso e informa os próprios agentes: hub_whatsnew retorna uma lista environment, cada item dizendo o que está errado, o que corrige, e quem pode — o agente, o agente mais um reinício do cliente, ou você. Uma mudança de protocolo nomeia as seções que realmente se moveram, para que ninguém releia o manual inteiro. hub doctor mostra a mesma lista a um humano. Nada bloqueia uma chamada, nada precisa de confirmação: um item desaparece quando a condição desaparece. Estado por nó em .env-state.json, nunca sincronizado na malha — três máquinas têm três ambientes.

Como funciona

  • Diário & relatórios estruturados — registro de equipe somente em anexo (INBOX.md) que você lê com seus olhos. Ao final da sessão, um agente arquiva um hub report de linhas com prefixo de tags (DECIDE: … | why, FACT:, COMM:, NEXT:, DONE: ids) que se distribuem nas seções do cartão do projeto — estrutura em campos, não em um bloco de prosa. "O que mudou" é lido do git, não redigitado. Os títulos das seções do cartão (em qualquer idioma) vêm de um único arquivo, HUB/sections.json, que alimenta tanto o esqueleto do cartão quanto o roteador de relatórios — para que nunca divergirem. Uma escrita alcança a seção que um cartão já possui sob qualquer um de seus títulos, então re-localizar um hub nunca gera uma segunda cópia; hub cards merge-sections mescla duplicatas antigas.
  • Filas — filas de mensagens por função. Envie trabalho; um agente bloqueia em wait até algo chegar, depois volta a esperar. Sem consultas suas, sem cutucadas neles. Uma fila tem um consumidor ativo por padrão — execute uma única sessão em espera por função. Funções listadas em <team>/subscriber-roles.json se distribuem em vez disso: cada sessão em espera recebe seu próprio cursor e vê cada mensagem, identificada por um nome que sobrevive a uma reinicialização (HUBD_SUBSCRIBER / HUBD_SESSION / HUBD_AGENT), então um leitor reiniciado retoma de onde parou. Atravessar máquinas é uma preocupação separada e substituível: scripts/mesh-sync.sh move a pasta via git+ssh, e mrgd pode carregar as mesmas filas como tráfego de sala Matrix — simultaneamente, no mesmo diretório. Veja docs/interop.md → Transport, incluindo como verificar qual dos dois está realmente habilitado em um nó específico. No modo de trabalho (hub queue wait <role> --tasks), a fila é o conjunto de tarefas abertas e prontas da própria função: ler não consome nada, iniciar é uma reivindicação com TTL, e cancelar é fechar a tarefa — um pedido lido por uma rodada que não fez nada nunca é perdido, e um pedido para uma tarefa cancelada nunca é executado.
  • Projetos & tarefas — um cartão por projeto; tarefas entre projetos com responsáveis (agente ou humano) e reivindicações como bloqueios suaves, para que dois agentes não se atropelem.
  • Funções, trilhas, supervisão — uma função é um cartão de recurso do tipo role (rank head / worker / fleet, um link head, seu repositório). Um projeto com um head é uma trilha. hub board coloca cada trilha em uma tela para o responsável — o estado de cada função, o que foi feito esta semana e por que foi aceito, o que vem a seguir, o que espera por você. hub sense <head> mede os workers e branches do head sem um modelo e acorda o head apenas em um evento; sem padrões privados declarados, ele não passa nenhum branch. Um loop relata seu estado como campos de heartbeat (--state, --turn, --empty ...), então nada interpreta sua redação.
  • Recursos & relacionamentos — infraestrutura também é um cartão: hosts, vms, serviços, endpoints, provedores sob resources/, com frontmatter estruturado (tipo, endereço, os, provedor, status) e arestas [[wikilink]] tipadas (runs_on, depends_on, deploys_to, exposes, part_of, ...). O mesmo mecanismo de arestas lê cartões de projeto, então hub graph renderiza uma topologia entre projetos ↔ recursos; uma tarefa se conecta ao que toca com --resource. Fatos vão em campos, não em prosa.
  • Quadro (somente leitura) — hub serve: Trilhas, um kanban ao vivo e um Histórico do diário para reproduzir. Cartões se movem porque agentes os movem. O único botão é ⚙ Regras, e ele abre AGENTS.md. Você não gerencia os agentes — você gerencia as regras.
  • Colheita — um prompt transforma qualquer diálogo de trabalho em resumos de projeto, tarefas e decisões registradas. Servido como um prompt MCP (harvest) e hub harvest, então você o invoca diretamente do seu cliente — sem buscar o arquivo. Veja HARVEST.md.
  • MCP + arquivos, dois níveis de compatibilidade — clientes inteligentes se conectam via MCP; todo o resto usa os arquivos diretamente. Se hubd estiver fora do ar, seus dados ainda são apenas markdown.
  • Instruções que permanecem atuais — suas regras de equipe vivem em AGENTS.md (suas para escrever); a mecânica do próprio hubd vive em HUBD.md, regenerada por nó a partir da versão instalada (ignorada pelo git, nunca sincronizada). Atualize o código → o próximo comando hub que escreve (ou hub upgrade) atualiza HUBD.md, então até agentes que apenas leem os arquivos nunca seguem instruções desatualizadas. Um comando que apenas lê não escreve nada no hub.

Princípios (violar estes = não é este produto)

Arquivos primeiro. Servidor burro, agentes inteligentes — sem IA dentro: hubd armazena e serve, a inteligência vem dos seus agentes. Nunca soe mais certo do que os dados: uma ferramenta que engana seu leitor está quebrada mesmo quando nada errou, então uma resposta truncada diz que foi truncada e um número que o hub não pode observar nunca é estimado. Tudo legível por humanos. Zero dependências. Somente leitura para o humano; acesso de escrita flui através das regras. Degradação graciosa: sem MCP → arquivos; sem hubd → arquivos ainda legíveis como estão — em qualquer editor, grep, ou um aplicativo Markdown como Obsidian. Veja Lendo seu hub com qualquer ferramenta.

Sobre essa gravação

O quadro no topo é a coisa real em dados inventados: node scripts/capture-kanban.mjs --gif monta um hub descartável em um diretório temporário, o serve e depois o edita durante a captura — atribui um cartão, fecha um, arquiva uma tarefa, registra uma decisão — e deixa a página perceber por conta própria. Nada é encenado e o hub real de ninguém é filmado. Seis atualizações no quadro, e apenas uma delas é um cartão deslizando para a direita: agentes também adicionam trabalho, e a maior parte do que chega em um registro de coordenação não move cartão algum.

O que hubd não é

Não é um orquestrador (não lança agentes nem transmite saída). Não é memória vetorial (o diário armazena fatos que você pode ler, não embeddings). Não é um Jira para humanos (o humano aqui é um espectador e um legislador, não um designado). Não é outro chat (fale com hubd através do seu agente; mãos — CLI; olhos — kanban).

Construído pela equipe que coordena

O desenvolvimento do próprio hubd passa pelo hubd: um humano e alguns agentes em modelos de diferentes fornecedores, coordenando através de nada além dos arquivos acima. É nosso dogfood diário — e a ilustração mais honesta que podemos oferecer do protocolo em uso real, incluindo a noite em que uma falha de ferramenta forçou tudo de volta para arquivos simples e o trabalho simplesmente continuou. A história de uma equipe, levemente anonimizada e autorrelatada, não um benchmark: doze semanas disso em notas de campo — cada mecanismo que quebrou, e o bug que fez cada painel concordar confiantemente em um número que era 72% inventado — e uma noite hora a hora em o estudo de caso.

O principal trabalho do humano era editar as regras.

Preços

O núcleo é MIT, para sempre. Uso pessoal é gratuito, para sempre. Se um plano de equipe hospedado existir, a linha é simples: agentes são gratuitos, humanos são cobrados.

Roteiro

Enviado: sincronização multi-máquina (logs somente em anexo por host, sem conflitos); acesso remoto via HTTP (com token, multi-tenant, veja auto-hospedagem); um grafo de relacionamentos tipado ([[wikilink]] arestas entre projetos e recursos, hub graph); recursos como cartões de primeira classe (hosts / serviços / endpoints); relatórios estruturados que se distribuem nas seções do cartão; i18n de seções em um arquivo (sections.json); um protocolo HUBD.md por nó que se regenera para corresponder à versão instalada; colheita como um prompt MCP; auto-bootstrap cwd → projeto (hub_context: arquivo marcador / caminho de sincronização gravado / palpite de nome de pasta, sem hub_get manual necessário); um registro de presença (hub_heartbeat/hub_presence, frescor TTL como reivindicações) para que agentes MCP/headless apareçam ao lado dos raspados de tela, com profundidade de fila exibida em hub_brief — e, a partir de 0.9.13, uma visão de frota que admite seus pontos cegos: presence/ é local ao nó, então cada nó publica um pequeno presence.<node>.json e hub_presence relata qual nó observou cada linha, além de uma lista coverage nomeando qualquer membro que não está reportando nada. Uma função que ninguém reporta é invisível, não morta — distinguir esses dois vale 92 horas, que é o que confundi-los custou uma vez; e botões — itens de fila de decisão do proprietário resumidos em hub_brief como "N botões esperando (mais antigo X dias)" (HUB/owner-roles.json nomeia as funções humanas).

Próximo: tipos de tarefa com seus próprios ciclos de vida (uma tarefa comunicativa sabe que está esperando uma resposta); um modo remoto de ponta a ponta (o servidor nunca lê seu trabalho); um gateway que faz proxy de seus servidores MCP pessoais; e a camada narrativa promovida ao servidor — hub_chronicle / hub_probe mais tipos de diário de humor/check-in, uma vez que a versão arquivo-primeiro se prove (design, modelos em hubd-company/). O formato de arquivo é o contrato estável; todo o resto é negociável.

Onde isso foi usado e o que realmente preveniu

O caso contra o qual hubd foi construído, e o único que vale descrever porque é a forma estranha que o trabalho real tem:

Levantando um hipervisor EL2 do zero em um Banana Pi M64 — um hipervisor tipo-1 bare-metal rodando FreeBSD 15.1 arm64 como convidado, além de um driver de GPU Mali-400 portado para FreeBSD no caminho. Três repositórios separados saíram disso: bzdk (o hipervisor), lima-freebsd (o driver de GPU, extraído para ser útil sem o resto), e bsdos (o sistema operacional para o qual tudo isso é).

A máquina de build e o quadro nunca foram a mesma máquina. O cross-compilador, as árvores de fonte do FreeBSD e do drm-kmod e o build do Mesa viviam em um host. O quadro chegou em outro, em uma rede diferente, com o console serial e a Ethernet de depuração fisicamente conectados lá. Então o trabalho foi dividido: compilar em um lugar, gravar e observar em outro. Vários agentes trabalharam em paralelo — um em clocks, um perseguindo coerência de DMA, um escrevendo testes.

O que isso custa sem um diário compartilhado é específico, não abstrato:

  • Dois agentes dirigindo um quadro. A porta serial aceita um leitor; dois fazem um canal saudável parecer morto. "Quem tem o quadro" tem que ser um fato que alguém anotou, não uma suposição.
  • Redescobrindo o mesmo achado. Um bug de hardware diagnosticado na terça é re-diagnosticado na quinta por alguém que nunca viu a primeira conclusão. Vários dos dez patches upstream que saíram deste projeto levaram um dia inteiro para encontrar; encontrar um duas vezes é um dia jogado fora.
  • Reivindicações sem número por trás. "A correção funciona" não é portável entre máquinas. "512 MiB de leituras, zero erros, antes morria após 27 MiB" é. Os relatórios do hubd são onde esses números foram, por isso as notas de versão puderam ser escritas a partir de registros em vez de memória.
  • Conclusões desatualizadas sobrevivendo à sua evidência. Meio dia deste projeto foi gasto encontrando documentos que afirmavam confiantemente coisas que o código desde então refutou. Um diário somente em anexo não impede isso, mas permite que você veja quando uma afirmação foi feita e o que era verdade na época.

Nada disso precisa de um servidor, e nada disso saiu das máquinas envolvidas: os dados são markdown e JSONL em uma pasta, sincronizados através de um remoto git privado via SSH. Essa é toda a razão pela qual foi construído assim.

Licença

MIT.