Skip to content

[Feature] rv-agent: sinal de novidade MOP/cobertura/diagnóstico em runtime via tail do logcat #79

Description

@phtcosta

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

  • Agent (rv-agent, rv-llm)
  • Analysis (rv-static-analysis, rv-coverage, rv-screen-parser) — reuso de parse_logcat_line/DiagnosticEventParser
  • Tools (rv-tools, rv-uiautomator) — rvagent-tool injeta o logcat_feed_path
  • Core (rv-android-core) — LogcatManager reusado (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_path injetado pelo rvagent-tool a partir de task.result.logcat_file; core do rv-agent recebe apenas um path (sem importar tipos da plataforma).
  • Leitura incremental por passo no learn_node reusando parse_logcat_line + DiagnosticEventParser; sem adb logcat extra sob a plataforma; sem thread CoverageTracker.
  • Standalone: fallback com LogcatManager próprio clear_buffer=False (ou sem feed), com teardown que encerra o processo.
  • Cruzamento RVSEC-COV × directly_reaches_target produz o sinal de novidade MOP-confirmado; violação RVSEC reconhecida.
  • Decisão de escopo do reward registrada como OPEN na proposal/design e resolvida antes da implementação.
  • Zero referência/dependência a rv-platform em runtime do feed; zero alteração em rvsec-core (bug equals/hashCode apenas documentado).
  • /rv-verify rv-agent verde; validação E2E com APK instrumentado (feed vivo) — pode exigir RV_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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions