Todos os projetos publicado/ · quatro coisas que outra pessoa instala

O que eu publico: código que vira dependência de outra pessoa

Período
agosto de 2026 · em andamento
Papel
autor e mantenedor
Distribuição
dois pacotes no npm, dois plugins de Claude Code
Licença
MIT nos quatro

A diferença entre isto e o resto do site

Nos outros casos deste site o erro aparece rápido: alguém abre o sistema de manhã e ele não abriu. Aqui o erro tem outro prazo. Quem instala uma biblioteca fica preso ao desenho que eu escolhi, e o custo de eu ter escolhido errado só aparece quando trocar já ficou caro para essa pessoa.

Por isso os quatro blocos abaixo dizem a mesma coisa na mesma ordem: o problema, a decisão que carrega o valor, o código que a implementa, e o comando que você roda para conferir sem precisar acreditar em mim.

lull: quatro mensagens, uma resposta

Alguém digita "oi", depois "queria perguntar", depois "sobre o apartamento", depois "o do centro". São quatro webhooks, quatro chamadas de modelo e quatro respostas para uma pergunta só. As três últimas foram escritas sem saber o que a pessoa ainda estava digitando.

O núcleo é um reducer puro: entram estado e evento, saem estado novo e uma lista de efeitos. Não tem timer nem rede lá dentro. É por isso que o mesmo arquivo compilado de src/core roda no demo do navegador e no servidor, e é o que deixa testar o comportamento sem subir Redis e sem esperar relógio.

src/core/reduce.ts ver inteiro ↗
/** When the buffered turn is due: quiet silence, capped by maxWaitMs. */
export function deadline(state: ConversationState, policy: Policy): number {
  // Typing counts as activity, so a person still composing holds their turn
  // open. The cap below is what stops that from lasting forever.
  const lastActivity = Math.max(state.lastMessageAt, state.lastTypingAt ?? 0)
  const quiet = lastActivity + policy.quietMs
  const cap = (state.firstBufferedAt ?? state.lastMessageAt) + policy.maxWaitMs
  return Math.min(quiet, cap)
}

Em mil conversas simuladas, digitadas do jeito que gente digita, são 71,3% menos chamadas de modelo: 20.888 mensagens viraram 6.000 turnos. O comando que reproduz esse número é npm run bench, no repositório.

eventlaw: a mesma regra em três lugares

A mesma regra de produção costuma existir três vezes: como asserção num teste, como consulta sobre evento gravado, e como alerta no monitoramento. As três discordam sobre prazo, chave de correlação e o que fazer com trace incompleto. Quando uma falha, o retorno costuma ser um booleano ou um despejo de log, e não a menor sequência que explica a violação.

A lei vira dado serializável em vez de código de teste. Uma definição só falsifica com entrada gerada, verifica trace gravado e monitora evento vivo, porque as três leem a mesma estrutura. E o construtor recusa prazo que não seja número finito e não negativo na hora de montar, não na hora de avaliar: erro de definição aparece onde ele foi escrito.

src/laws.ts ver inteiro ↗
class EventuallyBuilder {
  constructor(
    private readonly trigger: EventPattern,
    private readonly consequent: EventPattern,
  ) {}

  within(withinMs: number): LawPattern {
    if (!Number.isFinite(withinMs) || withinMs < 0) {
      throw new Error('within must be a finite, non-negative number')
    }
    return new LawPattern({
      kind: 'eventually',
      trigger: this.trigger.ast,
      consequent: this.consequent.ast,
      withinMs,
    })
  }
}

Está em beta público, e esta página diz isso em vez de esconder: o núcleo é testado, e a validação independente da API ainda está em andamento. O que é estável e o que não é está declarado em docs/stability.md. Instala com npm install eventlaw@beta.

anti-slop: 49 marcas de trabalho que ninguém terminou

Interface que saiu genérica tem sintoma repetido: a paleta que ninguém escolheu, o tema escuro que ninguém abriu, o texto que ninguém escreveu, o ajuste que ninguém ajustou. Nada disso prova que um modelo escreveu o código. Prova que ninguém voltou nele.

As duas skills são um loop. O auditor engole o falso positivo quando acha prova de que alguém escolheu aquele valor, e o build escreve exatamente nos quatro lugares onde o auditor procura essa prova. Um sinal que dispara em árvore feita pelo build é falha do build, e chega com arquivo e linha. Cada verbete do catálogo é obrigado a trazer quatro campos, um deles o caso em que ele não se aplica, que é a parte que costuma faltar em lista de regra. Quem cobra isso é um script, não a boa vontade de quem escreve.

scripts/validate.py ver inteiro ↗
def check_tells(text, source):
    """Report every tell in the text that is missing one of the four fields.

    Containment is by substring, so the fields are accepted in any order and
    anywhere in the tell's body. This check does not police their sequence.
    """
    tells = collect_tells(text)
    if not tells:
        return ["{}: no tells found".format(source)]
    return [
        "{}: {} is missing {}".format(source, tell_id, field)
        for tell_id, tell in tells.items()
        for field in FIELDS
        if field not in tell["body"]
    ]

São 49 sinais em cinco eixos: doze de superfície, quinze de acabamento fino, três de estado, sete de texto e doze de fechamento. O script acima é o que impede o catálogo de crescer sem eles.

merge-odds: leia as regras antes de tocar no repositório

Mantenedor gasta hora fechando pull request que ninguém pediu, muitos deles escritos por agente que nunca abriu o arquivo onde o projeto explica as próprias regras. Esses arquivos existem: template de pull request, política de IA, guia de contribuição.

Toda afirmação do dataset carrega citação palavra por palavra, com link preso ao commit em que ela foi lida. O texto citado é recorte literal do arquivo, cortado só por tamanho, nunca reindentado nem reescrito. E o valor padrão de um campo significa "nada encontrado nos arquivos lidos", nunca "o projeto permitiu". Ler o padrão como permissão é o erro que faz alguém abrir pull request num projeto que nunca disse que aceita.

src/merge_odds/policy.py ver inteiro ↗
def _block_around(lines: list[str], index: int) -> tuple[int, int]:
    start = index
    while start > 0 and lines[start - 1].strip():
        start -= 1
    end = index
    while end < len(lines) - 1 and lines[end + 1].strip():
        end += 1
    if end - start + 1 > QUOTE_MAX_LINES:
        start, end = index, min(index + QUOTE_MAX_LINES - 1, len(lines) - 1)
    return start, end

São 8 projetos medidos até agora, e duas skills que respondem duas perguntas em ordem: vet-repo diz se o projeto aceita trabalho de fora e sob quais regras, e vet-issue diz se aquela tarefa específica ainda está disponível. Issue aberta, sem responsável e sem pull request apontando para ela pode descrever defeito que já foi corrigido.

E o que eu mando para projeto dos outros

Esta página é o que eu publico. O outro lado, correção minha entrando em projeto que não é meu e passando pela revisão de um mantenedor que não me conhece, tem página própria: open source.