1. O ciclo de vida de um problema
- Nasce privado dentro de uma ORG (o prefixo do id:
apc#fibonacci). Ninguém de fora da org o vê — nem que ele existe. Prova em elaboração não vaza, por construção. - Validar é o portão de qualidade: seções obrigatórias no enunciado, testes pareados, soluções good aceitas. Não publica nada — é exatamente o modo p/ provas.
- Calibrar: o juiz roda as SUAS soluções good em cada máquina e mede o time limit por máquina E por linguagem. Você nunca mais chuta TL.
- Publicar o coloca no treino livre (a org precisa permitir público — trava que protege provas). Em contests de turma você usa problemas ainda privados.
O Painel acompanha cada fase — e avisa, com os commits exatos, quando um problema mudou e precisa recalibrar.
2. A CLI em 60 segundos
curl -fsSL https://moj.naquadah.com.br/moj -o ~/.local/bin/moj && chmod +x ~/.local/bin/moj moj login # o MESMO login desta página — sem git, sem chave SSH
Requisitos: bash, curl e jq. A CLI é um arquivo só, com a biblioteca comum embutida. Se você gere contests ou o parque de juízes, baixe /moj-contest e /moj-judges no mesmo endereço.
moj update atualiza a própria CLI. O comando moj version compara o seu build com o do servidor. Quando algo parecer errado, rode moj doctor. Ele confere a atualização, o jq e o curl, o checkout do mojtools, o bubblewrap e a sessão, e diz o que consertar. A CLI também avisa sozinha quando está desatualizada.Há dois jeitos de trabalhar. Misture os dois como quiser. O comando moj edit abre um menu interativo com todos os campos: enunciado, exemplos, soluções, conf e publicar. No jeito de arquivos locais, o pacote é um diretório: edite com as suas ferramentas e envie com moj push.
.moj-id. Exemplo: moj check, moj publish e moj log não precisam do id ali. Um nome sem a org também funciona: moj publish fibonacci usa a org da pasta. Exceção: moj rm e moj mv sempre pedem o id completo.moj test --run (julgamento local; também exige Linux com bubblewrap real), moj checker, moj interactive e moj fn (instalam os drivers de correção especial). Para esses comandos:
git clone https://github.com/cd-moj/mojtools ~/mojtools export MOJTOOLS_DIR=~/mojtools # no seu .bashrcTodos os outros comandos precisam só de bash, curl e jq.
3. Passo a passo: do zero ao publicado
Passo 1 — o esqueleto
moj new minha-org fibonacci # scaffold completo em ./fibonacci (nome = slug minúsculo [a-z0-9._-]) cd fibonacci && ls # docs/enunciado.md tests/input/ tests/output/ sols/good/ conf author tags
O primeiro argumento é a ORG (o id vira minha-org#fibonacci). Sua org pessoal (seu login) sempre existe e é sempre privada — perfeita p/ rascunhos.
moj mv fibonacci apc2026 — muda o id, nada mais. Na web: “+ Novo problema” na gestão.Passo 2 — o enunciado (docs/enunciado.md)
Markdown com matemática ($O(n \log n)$ vira MathML). Duas regras que o validador cobra e uma que ele não tem como cobrar:
- As seções
## Entradae## Saídasão obrigatórias (## Input/## Outputtambém valem). - O título é um campo (definido no
moj new/editou no formulário web) —% Títulona primeira linha é legado e é removido. - Declare as restrições EXPLICITAMENTE (
1 ≤ N ≤ 10⁵, cabe em 64 bits…). O aluno resolve as restrições, não a estória.
moj preview renderiza EXATAMENTE o HTML que o aluno verá (mesmo renderizador do site). Deixe aberto enquanto escreve.Formatação e fórmulas, com exemplos para copiar (frações, somatórios, casos, matrizes, o que evitar e como cada uma sai no PDF da prova): Escrevendo o enunciado.
Enunciado em mais de um idioma (opcional)
O português é o texto principal e é obrigatório. Para oferecer o problema em inglês ou espanhol, escreva a tradução ao lado, com o código do idioma no nome do arquivo:
docs/enunciado.md # português (obrigatório) docs/enunciado.en.md # inglês — mesmas seções: ## Input / ## Output docs/enunciado.es.md # espanhol — ## Entrada / ## Salida docs/notes/sample1.en.md # explicação do exemplo 1 em inglês (sem ela: a PT) docs/solucao.en.md # editorial em inglês (entra no documento de editorial em EN) moj title . --lang en "Sum of Two" # o título da tradução (fica no .moj-id, campo titles)
- Os exemplos vêm dos testes e aparecem em todos os idiomas, com os rótulos do idioma (Exemplos / Entrada / Saída / Explicação; Examples / Input / Output / Explanation).
- Exemplo sem explicação traduzida mostra a explicação em português. O validador avisa (
nota-sem-traducao) e não bloqueia. - O validador confere cada tradução como o português: ela tem de renderizar e tem de ter as seções de entrada e de saída.
- No editor web: os chips PT · EN · ES acima do enunciado. Cada idioma tem título, editor e campos de explicação próprios. O botão Pré-visualizar renderiza o idioma ativo. O botão ✂ Separar em seções funciona em todo idioma: os cabeçalhos saem no idioma (## Input / ## Output, ## Entrada / ## Salida). A aba Resolução tem os mesmos chips, com + EN e + ES: dá para escrever o editorial em outro idioma sem traduzir o enunciado. Ela tem um botão Pré-visualizar próprio.
moj preview --lang enrenderiza a tradução.moj cloneemoj pushlevam todos os idiomas. Remover odocs/enunciado.en.mde darpushremove a tradução no servidor.- No treino livre a página do problema mostra um chip por idioma. Em um contest, o admin ou o juiz-chefe escolhe os idiomas que a sanfona oferece.
Imagens no enunciado (leia este bloco inteiro uma vez)
Primeiro, o que acontece por baixo: o aluno NUNCA recebe um arquivo de imagem separado. O renderizador (pandoc --embed-resources) converte toda imagem para base64 DENTRO do HTML — o enunciado que o aluno abre é uma página auto-contida. Seu único trabalho é fazer a imagem chegar ao renderizador. Há DOIS jeitos:
Jeito 1 — colar no editor web. Ctrl-V ou arraste a imagem no editor de enunciado: ela vira um data:URI DENTRO do texto (uma linha gigante ). Não existe arquivo separado — a imagem viaja colada no markdown, por qualquer via. Ótimo p/ um print rápido; feio de manter (o texto fica enorme).
Jeito 2 — arquivo em docs/ (o jeito da CLI). A figura vive como arquivo de verdade ao lado do enunciado.md e o texto referencia pelo nome:
cp ~/screenshots/grafo.png docs/ # no enunciado.md: 
moj pusha carrega (campodocs_files— mesma família de round-trip doscripts/);moj clonea traz de volta;moj upload(tar inteiro) sempre carregou tudo.- O Pré-visualizar (botão web e
moj preview) MOSTRA a imagem: a CLI manda as figuras locais junto, e o editor web pede ao servidor as do pacote. - Regras de nome: nomes simples (letras/dígitos/
._-), extensão png/jpg/jpeg/gif/svg/webp, até 2MB cada (figura de enunciado não precisa de mais; reduza screenshots).
docs/, AO LADO do enunciado.md; (2) o nome no  bate EXATAMENTE (maiúsculas incluídas); (3) você rodou moj push (ou upload) depois de adicionar o arquivo; (4) seu moj está atual — moj doctor diz (builds antigos não mandavam imagem no push/preview)..vimrc) e emacs (init.el):" vim — :MojImg ~/screenshots/grafo.png (copia p/ o dir do arquivo atual e insere a linha)
command! -nargs=1 -complete=file MojImg
\ execute '!cp' shellescape(<q-args>) shellescape(expand('%:p:h')) |
\ execute 'normal! o . ')'
;; emacs — M-x moj-img (idem: copia p/ o dir do buffer e insere )
(defun moj-img (file)
(interactive "fImagem: ")
(let ((dest (expand-file-name (file-name-nondirectory file) default-directory)))
(copy-file file dest t)
(insert (format "" (file-name-nondirectory file)))))
Passo 3 — exemplos visíveis (samples)
printf '5\n1 2 3 4 5\n' > tests/input/sample1 # a saída de CADA teste você vai gerar com a sua solução no passo 5
Cada tests/input/sampleX casa com tests/output/sampleX e aparece no enunciado, em ordem. Tudo que NÃO se chama sample* é teste oculto.
Problema sem exemplo: SAMPLE=no
Em alguns problemas, entrada e saída de exemplo não fazem sentido para o aluno: submissão de função (a entrada é o formato interno do driver), problema interativo (a entrada é o cenário secreto do árbitro), linguagem própria e outros. Nesses problemas:
- Não crie
tests/input/sample*. - Ponha a linha
SAMPLE=nonoconf. No editor web, é a opção “este problema não tem exemplos” da aba Limites. Na CLI:moj edit→ 8 (conf) → 6. Omoj interactivejá grava a linha. - Explique o exemplo no texto do enunciado, numa seção
## Exemplo: uma figura, uma chamada da função e o que ela devolve, a transcrição da conversa com o árbitro.
Com SAMPLE=no, o enunciado não mostra a caixa de exemplos e nenhum exemplo pode ser baixado, nem de arquivos sample* que existam (eles continuam corrigindo, como qualquer teste). A validação exige uma das duas coisas: pelo menos um sample*, ou SAMPLE=no. Teste oculto nunca aparece como exemplo. A linha SAMPLE não pede recalibração.
Explicando cada exemplo: docs/notes/<sample>.md
Sample bom merece um PORQUÊ. Escreva um arquivo Markdown por exemplo, com o nome do sample que ele explica — markdown normal, quebras de linha de verdade, listas, imagens (mesmas regras do enunciado). Você nunca encosta em JSON; a contabilidade é da plataforma.
mkdir -p docs/notes cat > docs/notes/sample1.md <<'EOF' Neste exemplo temos 4 grupos: - dois grupos de 2 pessoas - dois grupos de 3 pessoas  EOF
A nota renderiza logo abaixo do exemplo dela, no enunciado. No editor web é o campo “explicação” de cada exemplo; no moj edit, a opção [n]ota. O legado sample-notes.json ainda é lido em pacotes antigos, mas nunca mais é escrito — qualquer salvamento converte.
Passo 4 — testes ocultos
É aqui que a nota se decide. Cubra: o menor caso válido, o MAIOR caso (limites das restrições — é ele que derruba o O(n²)), valores que estouram int, empates/duplicatas e formatos degenerados. Um gerador vale mais que arquivos à mão:
for i in $(seq 1 8); do python3 gen.py $i > tests/input/t$i; done
tests/output/* COM a sua solução good (passo 5) — nunca à mão. Uma saída digitada com espaço sobrando reprova a turma inteira.Validador de entrada: prove que os testes seguem o enunciado
Um teste fora dos limites do enunciado é um bug silencioso: a saída esperada pode ser lixo (caso real: n=1296 num problema de N ≤ 1000, e a solução de referência tinha um vetor de 1001). Escreva scripts/validator.cpp com a testlib (o padrão do Polygon) e rode na sua máquina:
moj validator . validator.cpp # instala em scripts/ e roda sobre tests/input/* moj validator # (na pasta do problema) roda de novo depois de mexer nos testes
Cada entrada ganha ✓ ou a mensagem da testlib (qual linha, qual valor, qual intervalo). A calibração completa roda o mesmo validador no juiz: o resultado aparece como Entradas no editor, no Painel e no moj check, e entrada inválida deixa o problema não pronto. O editor web tem o template “Validador de entrada (testlib)”. Mexer no validador não pede recalibração. Guia: mojtools/docs/validador-testlib.md.
Nota parcial estilo OBI: tests/score passo a passo
- Nomeie os testes ocultos POR GRUPO — é o glob que os amarra:
tests/input/g1_pequeno1 g1_pequeno2 # casos N ≤ 100 tests/input/g2_medio1 g2_medio2 # N ≤ 10^4 tests/input/g3_grande1 g3_grande2 # N ≤ 10^6
- Uma linha por grupo no
tests/score: globs, depois-, depois o peso. O separador ENTRE globs é vírgula+espaço (", ") — o parser exige, dos dois lados (API e juiz):sample* - 0 pontos g1_* - 20 pontos g2_* - 30 pontos g3_* - 50 pontos
- Regras: grupo é tudo-ou-nada (um teste falhou = grupo vale 0); o valor do problema é a SOMA dos pesos (não precisa dar 100); os samples entram com peso 0 p/ aparecerem no relatório sem valer nota; linha começando com
#é comentário; TODO teste tem de cair num grupo (a validação do upload confere). - O que o aluno vê embaixo do veredicto:
✓ Grupo 2 (30/30) · ✗ Grupo 3 (0/50)— feedback explícito por grupo; em contest modo OBI o placar também vira pontos.
moj test mostra a distribuição por grupo e acusa ali mesmo teste órfão (ZERARIA a submissão), linha inválida e grupo de peso>0 sem teste — conserte local, depois moj push.Passo 5 — soluções de referência (sols/)
A extensão define a linguagem (sol.c, sol.cpp, sol.py, Main.java…). Cada subdiretório tem um PAPEL na conferência:
good/— obrigatório (≥1): as corretas. Geram as saídas esperadas, o juiz as cronometra p/ calibrar o TL, e cada uma tem de ser aceita em todos os testes dentro do tempo-limite que o juiz cobra (com oTLOVERRIDE).wrong/— erradas de propósito: têm de ser REPROVADAS, de preferência por WA. Provam que seus testes PEGAM o erro clássico.slow/— lentas de propósito (o O(n²) que você quer reprovar): têm de tomar TLE em pelo menos 1 teste e ser aceitas nos outros. Provam que o TL de fato as derruba.pass/— devem passar raspando: aceitas em todos os testes dentro do TL. Provam que o TL não ficou apertado demais.upcoming/— rascunhos; não rodam.
A calibração (botão Calibrar, moj calibrate, publicar) roda todas as soluções num juiz e confere cada uma contra a categoria dela. O editor, o Painel, o moj calib e o moj check mostram o resultado por solução: ✓ conforme; ≈ conforme, outro motivo (uma wrong reprovada só por TLE, sem WA — confira se era esse o erro que você queria pegar; uma slow que também deu WA); ✗ divergente (good ou pass reprovada ou mais lenta que o TL, slow sem TLE, wrong aceita); ✗ não rodou (erro de compilação, erro do juiz, linguagem indisponível).
# gere as saídas com a good (exemplo em C): gcc -O2 sols/good/sol.c -o /tmp/sol for f in tests/input/*; do /tmp/sol < "$f" > "tests/output/$(basename "$f")"; done
Passo 6 — conf: limites e opções
MEMLIMITMB— limite de memória (a JVM/-Xmx se dimensiona por ele também).calibrafactor— a folga do aluno sobre o tempo medido da sua good. Mais generoso = mais justo com abordagens alternativas.languages— restringe as linguagens de submissão (vazio = todas as padrão):moj languages ./dir c,cpp,pye depoispush(ouupload— viaja dos dois jeitos).CPUNEEDED— problema PARALELO (OpenMP/MPI/threads): CPUs que CADA teste precisa (1..64). O juiz junta esse nº de CPUs por teste, mede o tempo-limite assim (um teste por vez) e entrega o número à jaula comoMOJ_TEST_CPUS/OMP_NUM_THREADS— umrun.shde MPI fazmpirun -np "$MOJ_TEST_CPUS", nunca um-npfixo.SAMENUMA=ypede o mesmo nó NUMA. Web: aba Limites › Problemas paralelos; CLI:moj edit→ 8 → 7/8. Templatesparalelo-openmp/paralelo-mpi. Guia:problema-paralelo.mdnas docs do mojtools. Não confundir comALLOWPARALLELTEST/MAXPARALLELTESTS(vários TESTES ao mesmo tempo, otimização do juiz que nunca muda o tempo-limite).
MEMLIMITMB e a folga — ou forneça uma good em Python e deixe a calibração por linguagem fazer a justiça por você.Opcional — correção especial (checker próprio / interativo)
Quando o diff puro não basta: várias respostas válidas (qualquer ordem topológica, qualquer caminho máximo), tolerância numérica, ou problemas interativos. Os caminhos abaixo COMPÕEM (preenchem SLOTS independentes do scripts/): função + checker especial é combinação normal — moj fn dir && moj checker dir checker.cpp. O único que não mistura é o interativo (dono da execução por linguagem). No editor web, o “+ Adicionar template” também é ADITIVO.
A) testlib (recomendado) — escreva um checker.cpp testlib padrão e instale o driver normalizado:
moj checker ./fibonacci checker.cpp # instala scripts/ (stub canônico + seu checker) moj interactive ./meu-jogo arbitro.cpp # idem p/ problema INTERATIVO (árbitro via FIFOs)
B) na mão — um scripts/compare.sh com este CONTRATO:
#!/bin/bash
# $1 = saída do ALUNO $2 = saída ESPERADA $3 = ENTRADA do teste
# exit 4 = Accepted · 5 = Accepted (Presentation Error) · 6 = Wrong Answer
awk -v a="$1" -v b="$2" 'BEGIN{ ... }' && exit 4 || exit 6
C) submissão de FUNÇÃO (o aluno envia SÓ a função) — o driver do autor (o seu main) vive em scripts/<lang>/compile.sh; instale os templates das 5 linguagens (com a SENTINELA anti-IO embutida — pega função que lê a entrada escondido) e edite as zonas EDIT-ME:
moj fn ./meu-problema --langs c,py # ou o template "Submissão de função" no editor web moj languages ./meu-problema c,py # OBRIGATÓRIO: sem whitelist, trocar de linguagem burla o driver # depois: EDIT-ME nos drivers · sols/good = SÓ a função · todo tests/input termina com 424242
O moj fn também grava a linha FUNCTION_LANGS=c,py no conf. Essa linha diz ao editor do aluno (treino e contest com o módulo de esqueleto de código) que nessas linguagens ele escreve SÓ a função: o editor abre vazio, sem o main do esqueleto. Se você tirar o driver de uma linguagem, tire a linguagem da linha também. Pela CLI: moj edit → 8 (conf) → 10. No editor web: aba Limites, campo Submissão de função. A validação reprova linguagem listada sem scripts/<lang>/compile.sh.
Guia completo (anatomia por linguagem, boas práticas anti-IO, erros comuns): submissao-de-funcao.md nas docs do mojtools.
chmod +x é OBRIGATÓRIO em todo scripts/*.sh (a jaula os executa direto — sem o bit, TUDO vira Compilation Error). E mexer em scripts/ muda o tl-checksum: o Painel vai pedir recalibração — está certo, aceite.Guias: checker-testlib.md, correcao-especial.md, problema-interativo.md e submissao-de-funcao.md nas docs do mojtools (banimento de função incluso).
Passo 7 — teste local, depois envie
moj preview # o HTML do aluno no navegador moj test # pré-voo: estrutura, pareamento, seções moj test --run # JULGA de verdade na sua máquina (Linux + bwrap) moj push # envia — cria/atualiza no servidor (round-trip completo)
Todo push/salvar é um commit git no servidor: a aba histórico do editor (e moj log/moj restore) permite inspecionar e voltar qualquer versão.
Alguém mudou o problema na web? moj pull
cd fibonacci moj pull # traz para a pasta o que mudou no servidor desde o seu último clone/pull/push moj pull --force # a pasta tem mudanças suas: guarda a pasta em fibonacci.local-AAAAMMDD-HHMMSS e traz a versão
moj pulltroca só os arquivos do pacote. Os outros arquivos da pasta ficam (por exemplo, umgerador.py). Um arquivo que o servidor removeu some da pasta também.- Se a pasta tem mudanças que você não enviou, o
moj pullrecusa e lista os arquivos. Envie commoj push, ou usemoj pull --force. - O
moj pull --forcecopia a pasta inteira antes de trocar os arquivos. Compare a cópia comdiff -re aplique as suas mudanças de novo.
moj push recusa quando o problema mudou no servidor depois do seu último clone, pull ou push. O editor web ou outro autor salvou o problema. Nada é enviado. A mensagem diz quem mudou e quando. Rode moj pull para trazer a versão nova, ou rode moj push --overwrite para enviar a sua versão por cima. O editor web tem a mesma trava: ele mostra quem mudou o problema, com os botões Recarregar e Salvar por cima. O moj upload tem a mesma trava e o mesmo --overwrite.Uma pasta clonada antes de o moj pull existir não tem linha de base. O primeiro moj pull compara a pasta com o servidor. Se forem iguais, ele grava a linha de base. Se forem diferentes, ele recusa e sugere --force.
Passo 8 — validar, calibrar, publicar
moj validate minha-org#fibonacci # confere o PACOTE + (RE)ENFILEIRA calibração — CONTINUA PRIVADO moj check minha-org#fibonacci # QA read-only: pacote, TL por juiz, soluções, entradas, PRONTO? moj publish minha-org#fibonacci # público no treino (a ORG precisa permitir)
validate é o modo prova: exposição zero. Ele confere o PACOTE (estático: enunciado, exemplos, testes emparelhados; não roda solução) e RE-ENFILEIRA a calibração, que roda as soluções no juiz. P/ só OLHAR use check/status (read-only). check mostra o pacote, os TLs calibrados, cada solução contra a categoria dela, o validador de entrada e a linha final: “pronto: SIM” ou a lista do que falta. publish exige a trava de público da org aberta (aba Orgs) — a org pessoal implícita nunca publica. Se o problema ainda não está pronto, o publish mostra as pendências e pede confirmação (--yes mostra e segue).
validate, o resumo mostra “⏳ calibrado: aguardando (calibração na fila)” — isso é normal, não é falha. Rode moj check de novo em ~30 s e vira “calibrado: sim” com os TLs por linguagem. Só fora dessa janela é que “⚠ solução good SEM TL — falhou em TODAS as máquinas de juiz” indica problema de verdade.4. Receitas de professor
Uma lista/prova do zero, em lote
moj mkdir apc2026 # org da disciplina (privada por padrão) for p in soma-vetores busca-bin pilha-min; do moj new apc2026 $p # três esqueletos done # ... edite cada um (moj edit ./$p ou seus arquivos) ... for p in soma-vetores busca-bin pilha-min; do (cd $p && moj push) && moj validate "apc2026#$p" done moj board # a saúde de tudo num tiro só
Os problemas ficam privados até você decidir o contrário; o contest da turma pode usá-los ainda privados. No dia da prova, nada nunca esteve exposto.
Reusar entre semestres
moj clone apc2026#fibonacci fib-2027 # o pacote inteiro, scripts incluídos # ajuste os testes / a estória / os limites ... (cd fib-2027 && moj push) # o histórico git guarda cada versão moj log apc2026#fibonacci -n 5 # e se algo der errado: moj restore apc2026#fibonacci <sha> # volta como um commit NOVO (nada se perde)
Delegar a monitores; organizar o acervo
moj share apc2026 monitor-joao # membro da org: edita TUDO da org moj collection create "APC 2026.1" # coleção = TAG de agrupamento (m:n, cross-org) moj collection add apc2026#fibonacci "APC 2026.1"
Duas pessoas no mesmo problema: cada uma roda moj pull antes de editar e moj push depois. Se a outra pessoa enviou antes, o seu push recusa e diz quem foi. Rode moj pull e envie de novo.
ORG = acesso (uma por problema, o prefixo do id). COLEÇÃO = rótulo de navegação/curadoria, várias por problema. O aluno filtra o treino por coleção.
Revisar em equipe: issues
moj issues new apc2026#fibonacci "Teste 7 fora do limite" -m "n=1296, o enunciado diz N <= 1000" moj issues apc2026#fibonacci # as abertas (--all inclui as fechadas) moj issues comment apc2026#fibonacci 1 -m "conferi: é o gerador" moj issues close apc2026#fibonacci 1 -m "t7 regerado" # dentro da pasta, o id é opcional
Issue é uma nota de que o problema precisa de conserto: um teste suspeito, uma solução que diverge, uma frase ambígua. Todos os membros da org veem, comentam e fecham — na CLI ou na aba 🐞 Issues do editor web. Enquanto houver issue aberta, o problema não está pronto (o moj check e o Painel dizem isso). Issues não fazem parte do pacote: não viajam no moj push/clone. Texto longo: -F arquivo.txt (-F - lê a entrada padrão).
De olho em tudo
moj board # seus problemas: pacote? calibrado? soluções? PRONTO? moj check apc2026#fibonacci # o porquê de cada estado, juiz por juiz moj calibrate --all-stale # recalibra TUDO que o painel marcou (lote seguro)
Inspecionar a calibração; testar no juiz REAL
moj calib apc2026#fibonacci # a calibração POR EXTENSO: cada juiz, cada solução,
# cada teste {nome, código, tempo, tl}
moj --json calib apc2026#fibonacci # o mesmo, em JSON — p/ os seus scripts
moj calib-report apc2026#fibonacci # lista os report.html disponíveis (e baixa com --host/--sol)
moj calibrate apc2026#fibonacci --all-judges # calibra em TODOS os juízes online (como na web;
# --hosts j1,j2 escolhe, --per-cpu pega 1 por modelo,
# moj calibrate --judges lista o parque)
moj testrun apc2026#fibonacci sol.c # roda UMA solução avulsa NO JUIZ (jaula e TL reais),
# fora do histórico — devolve o vetor por teste
moj testrun ... --report out.html # e ainda baixa o report.html do julgamento
testrun exige permissão de EDIÇÃO no problema (roda contra os testes ocultos). Se o conf do pacote tem TLOVERRIDE, o TL exibido/julgado é o do override — a calibração continua rodando como referência.
No editor web, é a sub-aba 🧪 testar no juiz de Soluções & Correção. Escolha um arquivo ou cole o código; a linguagem vem da extensão do arquivo. O botão 🧪 de cada solução testa a versão que está no editor, sem salvar. As execuções ficam na lista com o veredicto, os testes e o report.html.
5. ⚡ Comandos rápidos
| Comando | O que faz |
|---|---|
| moj login · whoami | sessão (mostra se você pode criar problemas) |
| [<id>] | opcional dentro da pasta do problema (o id vem do .moj-id) |
| moj new <org> <prob> | scaffold completo do pacote em ./prob |
| moj clone <id> [dir] | baixa o pacote INTEIRO (testes, soluções, scripts) |
| moj edit [<id|dir>] | menu interativo com todos os campos |
| moj preview [dir] | o HTML exato do aluno, no navegador |
| moj test [dir] [--run] | pré-voo local, incl. grupos do tests/score; --run julga de verdade (bwrap) |
| moj push [dir] [--overwrite] | envia (cria/atualiza; round-trip completo). Recusa se o servidor mudou depois do seu último clone/pull/push; --overwrite envia por cima |
| moj pull [dir] [--force] | traz para a pasta as mudanças do servidor (web, outro autor); --force guarda a sua pasta numa cópia |
| moj upload/download [<id>] | pacote inteiro via tarball (download --sha = versão antiga) |
| moj validate [<id>] | portão + calibração — CONTINUA privado (modo prova) |
| moj check [<id>] | QA: pacote, TLs por juiz, soluções, entradas, pronto ou o que falta, o porquê da recalibração |
| moj issues [<id>] · new · comment · close · reopen | as issues do problema (revisão da banca); issue aberta = não está pronto |
| moj calib [<id>] | a calibração POR EXTENSO: por juiz/solução/teste, cada solução com esperado × obtido (--json p/ scripts) |
| moj calib-report [<id>] | report.html de uma solução calibrada (sem args = lista) |
| moj testrun [<id|dir>] <sol> | roda UMA solução avulsa no juiz REAL, fora do histórico (permissão de edição). Na web: Soluções & Correção › 🧪 testar no juiz |
| moj publish [<id>] · public [<id>] on|off | público no treino (org precisa permitir) / alternar |
| moj ls · board · info [<id>] | listas · painel de saúde · tudo de um problema |
| moj log [<id>] · restore [<id>] <sha> | histórico git · volta como commit NOVO |
| moj mv <id> <org> | move rascunho p/ outra org (muda o id) |
| moj mkdir <org> · share <org> <login> | cria org · adiciona membro (quem edita) |
| moj collection … | cria/marca/navega coleções (tags de agrupamento) |
| moj calibrate [<id>] | --all-stale | enfileira calibração / recalibra tudo que precisa |
| moj validator [<dir>] [validator.cpp] | instala e roda o validador de entrada testlib sobre tests/input/* |
| moj checker · interactive | instala checker testlib / problema interativo (correção especial) |
| moj doctor · version · update | diagnóstico do ambiente · build local×servidor · auto-atualiza a CLI |
6. 💡 Dicas & armadilhas (aprendidas na prática)
- Exemplos vivem em arquivos, nunca no texto do enunciado — o renderizador os injeta e mantém tudo consistente.
- Saídas esperadas são SEMPRE geradas por uma good. Edição à mão é WA futuro p/ a turma inteira.
- Mudou testes, soluções good, conf ou scripts de correção? O TL ficou velho — o Painel marca (com os commits causadores) e
moj calibrateresolve. Mudança SÓ de enunciado não recalibra. - Justiça por linguagem vem de good por linguagem. Se você permite Python, entregue uma good em Python.
- A privacidade é estrutural: problema privado não aparece em lugar nenhum (nem p/ admin global de fora da org). A trava de público é da ORG — fechá-la despublica tudo em cascata.
- Precisa de checker próprio (várias respostas válidas) ou problema interativo? Os dois são cidadãos de primeira classe:
moj checker/moj interactiveinstalam os drivers normalizados. moj test --runexige Linux com bubblewrap real; sem ele, a validação simplesmente adia a execução p/ o juiz — não é bug.- CLI esquisita (comando que “não faz nada”, recurso que falta)? Rode
moj doctorprimeiro — nove em dez vezes émojdesatualizado;moj updateresolve numa linha.
7. Referências
Formato do pacote (fonte única) · Escrevendo o enunciado (Markdown e fórmulas) · Documentação completa · API · ← voltar à Gestão de Problemas