no_slotsLição 02
Sem print, não há conclusão.
O estado terminal descreve o que a tela provou — nunca o que a automação esperava encontrar.
Árvore de decisão
Contrato de evidência
final-options.png + result.jsonblocked_browser_initCrashed após a única recuperação permitidablocked_*slot_selectedreservedconfirmation.png + localizadorBootstrap confiável do Computer Use
O plugin deve ser carregado pelo wrapper computer-use-client.mjs, chamando setupComputerUseRuntime({globals: globalThis}). Depois, a API correta é globalThis.sky: primeiro sky.list_apps(), depois sky.get_app_state({app: "com.brave.Browser"}). Importar @oai/sky diretamente ou chamar sky.sky contorna o runtime confiável e produz um bloqueio antes da interface.
O prompt da rodada agendada mantém a associação explícita com plugin://computer-use@openai-bundled?app=com.brave.Browser. Uma mensagem delegada não substitui essa associação persistida.
Escudo contra índice obsoleto
Um element_index só vale para a árvore acessível que acabou de ser lida. Depois de seleção, clique, mudança de foco ou navegação, o índice é descartado. Para Continuar, a execução foca o botão com Tab, confirma o foco, aciona Return uma vez, espera dois segundos e faz três leituras sem novos cliques. A mesma disciplina vale para SOLO SEPE e Presencial.
Essa espera é decisiva: uma leitura imediata pode mostrar a árvore antiga enquanto a página já está mudando. Repetir o mesmo número nesse intervalo pode clicar numa aba em vez do botão original.
Integridade do PNG
final-options.png precisa vir da captura real devolvida por get_app_state. Antes de anexar, a rodada valida PNG real, largura mínima de 300 px, altura mínima de 200 px e mais de 10 KB. Um arquivo 1x1, placeholder, imagem sintética ou cópia de outra rodada é evidência inválida. Quando a interface não chegou a ser capturada, o registro correto é screenshots=[] e final_options_available=false.
Janela-alvo antes da escolha
target_window_start recebe o instante real da rodada em Europe/Madrid; target_window_end fica exatamente 48 horas corridas depois. O intervalo é inclusivo: no limite entra; um segundo depois, não.
Primeiro filtra, depois ordena pela data/hora. A primeira linha é só uma candidata, nunca um atalho. A automação escolhe a opção elegível cronologicamente mais próxima; se existir somente uma elegível, escolhe essa. Se todas forem posteriores, não clica: registra no_slots_within_target_window e mantém ACTIVE.
Experimente: classifique a tela
Cenário: a tela diz “não podemos oferecer citas” e mostra apenas “Justificante” e “Volver”.
Fechar a aba também exige prova
Depois do print, do result.json e do read-back do ntfy, um estado terminal fecha somente a aba nova desta execução. Antes de super+w, uma árvore fresca comprova que a aba SEPE está selecionada e que há exatamente uma aba a mais que o baseline. Depois de dois segundos, list_apps deve mostrar que o Brave continua ativo; só então get_app_state comprova que a contagem caiu uma unidade e voltou ao baseline. Nenhum conteúdo da aba anterior é salvo.
needs_booking_confirmation não é terminal: a tela permanece aberta. Já reserved com confirmação explícita e localizador cumpre o objetivo definitivo: o Scheduler muda de ACTIVE para PAUSED, valida o TOML reaberto, fecha a aba de execução e não agenda novas rodadas.
Tentativa encerrada
no_slots ou bloqueio: fecha a aba; o Scheduler continua ACTIVE.
Objetivo cumprido
reserved + localizador: pausa o Scheduler e fecha a aba.
ntfy não reclassifica o SEPE
O resumo e o anexo podem aparecer no feed com pequeno atraso. Por isso a rodada faz até três read-backs frescos. A publicação fica em ntfy_status e um eventual erro em notification_blocker; o status primário — por exemplo no_slots ou blocked_site_error — não é substituído por uma falha de notificação.
Fonte e próximo passo
Os nomes e requisitos vêm do escopo e do prompt persistido. Continue em Confirmações e iPhone →.