Repository navigation
Releases
Releases · Samuelfmedeiros/ai-test-loop
v1.2.1 — config null não aprova mais tudo
Corrigido
Chave de configuração com valor null aprovava tudo no runner JS.
setdefault("threshold", 85) (Python) e if (cfg.threshold === undefined) (JS) só cobrem chave ausente — não chave presente com valor nulo. Medido por exploit:
- Python:
float(None)→TypeErrorcom traceback, exit 1, sem dizer qual chave. - JS:
Number(null) === 0, entãoscore >= 0era sempre verdadeiro e o gate aprovava qualquer pontuação, inclusive zero. Silencioso.
threshold e max_rounds nulos normalizam para o default nos dois runners.
Adicionado
tests/test_config_null.py— 3 contratos × 2 runners = 6 testes: sem estouro, check falhando reprova,max_roundsnulo usa default.CHANGELOG.mdcom o histórico das versões.
Verificação
152 passed
npm test → TUDO OK
CI: critic ✓ mutation ✓
v1.2.0 — o gate que bloqueia de verdade
Adicionado
O gate deixou de ser relatório e passou a ser portão.
severity: "block"por check — check bloqueante que falha →GATE=blockede exit 3, distinto defailed(exit 1).required: truesemseverityé recusado na carga da config.config_fingerprint()— SHA-256 dethreshold,max_roundse dos campos de cada check. Drift entre rodadas →GATE=blocked;--approve <id> --approve-by <nome>re-baseia com snapshot.runner_fingerprint()+roger-runner-pin.py— detecta runner alterado entre rodadas.- Orçamento de rodadas monotônico —
round_no = max(prev+1, args.round);--round 1repetido não estende mais o limite. - Anti-cheat —
strict_tests,allow_skipped,min_passed,junit_xmlautoritativo,blocking_gaps. Skip/xfail não conta como aprovado. Parser com fallback por caractere de progresso para quandopytest -qnão imprime sumário. - Mutation testing do gate e meta-gate com defeito semeado.
Esta tag foi movida para o commit que inclui o fix de null da 1.2.1, para que quem instalar v1.2.0 não receba o bug do Number(null) === 0.
v1.0.0 — the loop that scores before you ship
Deterministic critic, stdlib only. Prova no proprio repo:
python3 scripts/loop_runner.py --config examples/demo/loop.demo.json-> SCORE=100, GATE=passed, rc=0python3 scripts/loop_runner.py --config examples/demo/loop.demo-fail.json-> SCORE=55, GATE=failed, rc=1
No caso quebrado o self-test FALSO passa (nao afirma nada) e quem pega e o check de comportamento — e por isso que o gate existe.