Description
Hoje o guia MOP do rv-agent é 100% estático: vem dos flags de alcançabilidade do GATOR (reachable → reaches_target → directly_reaches_target, MethodCoverageData em rv-android-core/domain/coverage.py:62-69), consumidos via rvagent_visitor.py:243. Não há nenhum sinal de runtime — grep RVSEC no rv-agent dá 0. O problema: a alcançabilidade estática super-aproxima (a "maldição dos 30%" — existe um caminho, mas em runtime a ação pode não disparar a operação monitorada). O agente explora às cegas quanto ao que de fato executou.
Este feature introduz um sinal de runtime que fecha o laço estático→dinâmico, reusando a infraestrutura de camada inferior que já existe (sem tocar rv-platform nem rvsec-core):
- Fonte do feed (forma decidida). O agente lê incrementalmente o arquivo de logcat, sem
adb logcat próprio sob a plataforma: o caminho já está no boundary da tool como task.result.logcat_file (TaskResult, escrito pelo LogcatComponent antes da tool rodar). O adaptador rvagent-tool (que já mapeia Task → RVAgentConfig) injeta esse caminho como um campo plano (logcat_feed_path: str | None); o core do rv_agent recebe só um path e permanece ignorante da plataforma. No modo standalone (sem plataforma) o agente sobe seu próprio LogcatManager com clear_buffer=False (evita adb logcat -c que apagaria o buffer compartilhado); ou roda sem feed.
- Parsers reusados (dep nova rv-agent → rv-coverage, sem ciclo).
parse_logcat_line (RVSEC/RVSEC-COV) + DiagnosticEventParser.feed_line (crash/VerifyError/ANR do gh72). Não usa o CoverageTracker completo (thread daemon + RLock + métrica): o agente opera em passos discretos e lê as linhas novas ao fim de cada ação (no learn_node, ~:677), o que também limita a atribuição à janela "desde a minha última ação".
- Uso do sinal. Cruzar cada assinatura RVSEC-COV nova com o flag estático
directly_reaches_target que o agente já carrega → progresso MOP confirmado em runtime (vs. o proxy estático callback_signature do S1/Change A). Linha RVSEC (violação de monitor) = objetivo terminal do projeto (JCA misuse). Eventos de diagnóstico do gh72 (crash = bug + restart que explica salto de hash; VerifyError = instrumentação quebrada; ANR = evitar ação) como sinais de exploração — precondição: plataforma rodar com RV_LOGCAT_DIAGNOSTICS=true (default off; RVSEC/COV estão sempre no arquivo, diagnósticos não).
Semântica (investigada, rvsec-core/logcats reais). RVSEC-COV deduplica 1x por assinatura por processo (CoverageSourceEmitter.java:47-57); RVSEC 1x por (spec,tipo,classe,método,local) por processo (ErrorCollector.java:36-42). Consequência: o feed serve como sinal de novidade por episódio, não como atribuição fina ação→evento nem reward proporcional à frequência (reinícios de processo re-logam tudo; eventos vêm em rajada ligada a lifecycle). Bug de contrato equals/hashCode em ErrorDescription descoberto na investigação — apenas documentado aqui; NÃO será corrigido (não tocar rvsec-core; mudaria métrica histórica).
Restrições de arquitetura (não-negociáveis). NUNCA via tap no stream/objetos da rv-platform (feed plataforma→tool é vetado). NUNCA tocar rvsec-core. Reuso apenas de camada inferior (rv-android-core LogcatManager; rv-coverage parsers).
OPEN DESIGN DECISION (deixar em aberto na change)
Escopo exato do que entra no reward da v1: (a) só cobertura-nova-que-directly-reaches-target? (b) incluir violações RVSEC com peso máximo? (c) incluir eventos de diagnóstico (crash/VerifyError/ANR) já na v1 ou depois? (d) pesos relativos. A change deve registrar isso como decisão aberta a ser resolvida na fase de design/proposta, com os prós/contras já levantados.
Affected Domains
Related FRs/NFRs
rv-agent MOP-guided exploration / reward (ver PRD.md domínio Agent); relaciona-se a gh72 (diagnostic events) e gh77 (rv-agent revival).
SDD Track
Full SDD (dependência nova cross-module rv-agent→rv-coverage + arquitetura de feed + integração com reward).
Priority
medium
Acceptance Criteria
Investigação e decisões: docs/20260713_relatorio_ape_sata_cegar_gator_30curse.md. Change A (identificação de estado) é separada e independente.
Description
Hoje o guia MOP do rv-agent é 100% estático: vem dos flags de alcançabilidade do GATOR (
reachable → reaches_target → directly_reaches_target,MethodCoverageDataemrv-android-core/domain/coverage.py:62-69), consumidos viarvagent_visitor.py:243. Não há nenhum sinal de runtime —grep RVSECnorv-agentdá 0. O problema: a alcançabilidade estática super-aproxima (a "maldição dos 30%" — existe um caminho, mas em runtime a ação pode não disparar a operação monitorada). O agente explora às cegas quanto ao que de fato executou.Este feature introduz um sinal de runtime que fecha o laço estático→dinâmico, reusando a infraestrutura de camada inferior que já existe (sem tocar rv-platform nem rvsec-core):
adb logcatpróprio sob a plataforma: o caminho já está no boundary da tool comotask.result.logcat_file(TaskResult, escrito peloLogcatComponentantes da tool rodar). O adaptadorrvagent-tool(que já mapeiaTask → RVAgentConfig) injeta esse caminho como um campo plano (logcat_feed_path: str | None); o core dorv_agentrecebe só um path e permanece ignorante da plataforma. No modo standalone (sem plataforma) o agente sobe seu próprioLogcatManagercomclear_buffer=False(evitaadb logcat -cque apagaria o buffer compartilhado); ou roda sem feed.parse_logcat_line(RVSEC/RVSEC-COV) +DiagnosticEventParser.feed_line(crash/VerifyError/ANR do gh72). Não usa oCoverageTrackercompleto (thread daemon + RLock + métrica): o agente opera em passos discretos e lê as linhas novas ao fim de cada ação (nolearn_node, ~:677), o que também limita a atribuição à janela "desde a minha última ação".directly_reaches_targetque o agente já carrega → progresso MOP confirmado em runtime (vs. o proxy estáticocallback_signaturedo S1/Change A). Linha RVSEC (violação de monitor) = objetivo terminal do projeto (JCA misuse). Eventos de diagnóstico do gh72 (crash = bug + restart que explica salto de hash; VerifyError = instrumentação quebrada; ANR = evitar ação) como sinais de exploração — precondição: plataforma rodar comRV_LOGCAT_DIAGNOSTICS=true(default off; RVSEC/COV estão sempre no arquivo, diagnósticos não).Semântica (investigada,
rvsec-core/logcats reais). RVSEC-COV deduplica 1x por assinatura por processo (CoverageSourceEmitter.java:47-57); RVSEC 1x por(spec,tipo,classe,método,local)por processo (ErrorCollector.java:36-42). Consequência: o feed serve como sinal de novidade por episódio, não como atribuição fina ação→evento nem reward proporcional à frequência (reinícios de processo re-logam tudo; eventos vêm em rajada ligada a lifecycle). Bug de contratoequals/hashCodeemErrorDescriptiondescoberto na investigação — apenas documentado aqui; NÃO será corrigido (não tocar rvsec-core; mudaria métrica histórica).Restrições de arquitetura (não-negociáveis). NUNCA via tap no stream/objetos da rv-platform (feed plataforma→tool é vetado). NUNCA tocar rvsec-core. Reuso apenas de camada inferior (rv-android-core
LogcatManager; rv-coverage parsers).OPEN DESIGN DECISION (deixar em aberto na change)
Escopo exato do que entra no reward da v1: (a) só cobertura-nova-que-directly-reaches-target? (b) incluir violações RVSEC com peso máximo? (c) incluir eventos de diagnóstico (crash/VerifyError/ANR) já na v1 ou depois? (d) pesos relativos. A change deve registrar isso como decisão aberta a ser resolvida na fase de design/proposta, com os prós/contras já levantados.
Affected Domains
parse_logcat_line/DiagnosticEventParserrvagent-toolinjeta ologcat_feed_pathLogcatManagerreusado (standalone)Related FRs/NFRs
rv-agent MOP-guided exploration / reward (ver PRD.md domínio Agent); relaciona-se a gh72 (diagnostic events) e gh77 (rv-agent revival).
SDD Track
Full SDD (dependência nova cross-module rv-agent→rv-coverage + arquitetura de feed + integração com reward).
Priority
medium
Acceptance Criteria
logcat_feed_pathinjetado pelorvagent-toola partir detask.result.logcat_file; core do rv-agent recebe apenas um path (sem importar tipos da plataforma).learn_nodereusandoparse_logcat_line+DiagnosticEventParser; semadb logcatextra sob a plataforma; sem threadCoverageTracker.LogcatManagerpróprioclear_buffer=False(ou sem feed), com teardown que encerra o processo.directly_reaches_targetproduz o sinal de novidade MOP-confirmado; violação RVSEC reconhecida./rv-verify rv-agentverde; validação E2E com APK instrumentado (feed vivo) — pode exigirRV_LOGCAT_DIAGNOSTICS=true.Investigação e decisões:
docs/20260713_relatorio_ape_sata_cegar_gator_30curse.md. Change A (identificação de estado) é separada e independente.