Regression after: #176
Related: #120, #123, wesleysimplicio/simplicio-runtime#2989 e #3005
Problema medido
O mapper publicado ainda pode ficar preso indefinidamente por um .simplicio/index.lock órfão.
Reprodução em 2026-07-11, Windows, após o preflight atualizar para simplicio-mapper 0.19.0:
simplicio-mapper scan . --json foi executado em simplicio-agent e simplicio-runtime.
- O comando retornou deep-pass PIDs
13204 e 15764.
simplicio-mapper status . --await --timeout 120 --json permaneceu:
phase=deep_running
terminal=false
lock=true
- Os dois PIDs já não existiam.
- Ambos os
background-index.log continham repetidamente:
index skipped: lock already exists at .../.simplicio/index.lock.
- No Agent,
artifacts_present=false; no Runtime, apenas artefatos anteriores/stale estavam presentes.
Resultado: o survey obrigatório não converge, inspect/handoff não pode produzir prova fresca e o usuário precisa remover lock manualmente, contrariando o contrato de #176.
Objetivo
Tornar aquisição, recuperação e liberação do lock de indexação crash-safe, cross-platform e observável, sem roubar lock de processo vivo.
Contrato proposto
Registro versionado no lock, por exemplo:
simplicio.mapper-index-lock/v1 com pid, process_start_identity, host, created_at, heartbeat_at, owner_token, root_fingerprint, mapper_version e operation.
Reason codes mínimos:
lock_acquired
lock_live_owner
lock_dead_owner_reclaimed
lock_expired_reclaimed
lock_malformed_reclaimed
lock_legacy_reclaimed
lock_owner_mismatch
worker_died_before_terminal.
Critérios de aceite
Evidência exigida
- fixtures de lock por caso;
- testes unit/integration cross-platform;
- transcript do kill/recovery;
- JSON status antes/depois;
- prova de dois scanners concorrentes;
- smoke com pacote publicado/instalado;
- changelog/release note da regressão.
Não objetivos
- Permitir deep passes concorrentes no mesmo root;
- apagar locks indiscriminadamente por idade;
- depender de remoção manual;
- usar apenas
kill(pid, 0) POSIX como prova cross-platform;
- mascarar falha retornando artefato stale como fresco.
Regression after: #176
Related: #120, #123, wesleysimplicio/simplicio-runtime#2989 e #3005
Problema medido
O mapper publicado ainda pode ficar preso indefinidamente por um
.simplicio/index.lockórfão.Reprodução em 2026-07-11, Windows, após o preflight atualizar para
simplicio-mapper 0.19.0:simplicio-mapper scan . --jsonfoi executado emsimplicio-agentesimplicio-runtime.13204e15764.simplicio-mapper status . --await --timeout 120 --jsonpermaneceu:phase=deep_runningterminal=falselock=truebackground-index.logcontinham repetidamente:index skipped: lock already exists at .../.simplicio/index.lock.artifacts_present=false; no Runtime, apenas artefatos anteriores/stale estavam presentes.Resultado: o survey obrigatório não converge,
inspect/handoffnão pode produzir prova fresca e o usuário precisa remover lock manualmente, contrariando o contrato de #176.Objetivo
Tornar aquisição, recuperação e liberação do lock de indexação crash-safe, cross-platform e observável, sem roubar lock de processo vivo.
Contrato proposto
Registro versionado no lock, por exemplo:
simplicio.mapper-index-lock/v1compid,process_start_identity,host,created_at,heartbeat_at,owner_token,root_fingerprint,mapper_versioneoperation.Reason codes mínimos:
lock_acquiredlock_live_ownerlock_dead_owner_reclaimedlock_expired_reclaimedlock_malformed_reclaimedlock_legacy_reclaimedlock_owner_mismatchworker_died_before_terminal.Critérios de aceite
scan/indexdetecta PID morto e recupera o lock automaticamente.owner_tokencorrespondente e não apaga lock alheio.status --awaittermina comofailedou recupera/reinicia conforme policy, nunca ficadeep_runningcom PID morto.--timeoutretorna estado terminal/timeout honesto e exit code documentado.scanapós crash converge semRemove-Item index.lockmanual.scan -> status --await -> inspect -> handoffpassa em repositório temporário.Evidência exigida
Não objetivos
kill(pid, 0)POSIX como prova cross-platform;