refactor(apple-runner): encapsulate XCTest-channel penalty state
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 35/100
- Tipo de issue
- Refactorización
- Claridad
- Bastante claro
- Estado de actividad
- Activo
- Stack tecnológico
- swift
- Área
- mobile-dev, testing-qa
Línea de trabajo
First read the deletion gate and inspect RunnerTests+SnapshotCapturePlan.swift:133–162, RunnerTests.swift:118–122, and SnapshotTiming.swift:119–154 under apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/. Confirm a concrete deletion or correctness case before starting, since the issue is currently deferred. If resumed, use the owner-matched tests and consuming suites named in the issue; done means penalty behavior and effective-plan outputs remain unchanged and the required focused checks pass.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Encapsulate the runner's XCTest-channel penalty state with its existing operations
Deletion-first acceptance
This is part of #2803's simplify-and-shrink initiative. Before production simplification, name the production mechanism, duplicated decision, state, fallback, forwarding layer, or public/internal interface this change removes. Compare deletion and inlining against extraction. Moving the same state into another file is not a deletion case.
Every PR reports baseline/final SHAs; added, deleted and net production lines; test/fixture/documentation changes separately; and the exact mechanisms removed. Use a rename-aware diff (git diff --numstat -M BASE...HEAD) and account for all affected production paths, including destination packages. Moving tests out of production files, generated output, formatting churn, and moving code elsewhere are not production-code deletion. Preserve readable code; no compressed formatting to hit a number.
Default for simplification work: net production reduction. A required behavior-preserving size split may be line-neutral. Growth needs an explicit, quantified explanation of the correctness or type guarantee it buys, why deletion/inlining cannot achieve it, and what old mechanism is removed; it is not automatically acceptable because ownership looks cleaner. If the only benefit is relocating fields or adding a wrapper, defer the change. Required regression tests and a minimal correctness fix are allowed to grow without inventing unrelated deletion to offset them.
Priority and scope gate
Readiness: deferred; remove ready-for-agent. Existing operations are already collocated and no penalty-state defect has been demonstrated. Resume only for a named deletion of duplicate state/coordination or a concrete correctness need. A new class with the same fields plus forwarding methods does not meet this initiative's goal. Preserve the distinct penalty, warmup and depth lifetimes. Run shared Swift work one issue at a time.
Parent: #2803. Readiness: deferred pending a concrete deletion or correctness case. Evidence baseline: 5712a3552e209c9c853bc1f42cb3e007f1213139; recheck current main. If resumed after its deletion/correctness gate, coordinate edits with target-transition characterization and ownership work; the current penalty operations are already explicit. #2911 has merged and #2882 owns additional actor source guards.
Problem and evidence
RunnerTests+SnapshotCapturePlan.swift:133–162 already colocates arm, clear and lookup functions. The missing piece is concrete ownership: their lock, bundle identity, deadline and duration remain writable on the entire XCTest case (RunnerTests.swift:118–122). This extraction should close that seam, not claim to discover a missing state machine or rewrite capture-plan policy.
The current penalty is a single retained record, not a per-app map. SnapshotTiming.swift:119–154 decides whether an XCTest-backed attempt deserves it from acquisition timing, typed timeout and deadline exhaustion. Main-thread abandonment can also arm it. Lifecycle explicitly clears it for process replacement/external relaunch; ordinary invalidation does not mean the same thing.
Small interface and ownership
Create one concrete SnapshotXCTestChannelPenalty module owning its private lock, optional bundle and expiration. Expose arm, clear and isActive(for:). Preserve the 120-second duration, existing log markers, and strict now < expiresAt lookup. Accept the current instant as an explicit operation input, or reuse an existing production clock seam, so expiry tests advance time without production-length sleeps. Do not add test-only setters or a scheduler framework.
Place the instance on RunnerTests, replace direct accesses, and delete superseded fields/functions. The existing acquisition classifier, capture-plan reordering and presentation-quality decisions retain their owners. The new module must not know backend capabilities, app activation or snapshot node shapes.
Keep SnapshotXCTestPenaltyWarmupExemption separate: it already has lock-protected ownership and a different contract (one pending exemption consumed by an actual plan). Keep private-AX accepted-depth memory separate: its positive-PID matching and non-renewing successful reuse are not this penalty's semantics. Shared duration values today do not justify a combined cache or lifetime abstraction.
Required preservation and completion checks
- Arming replaces the single previous penalty; it does not accumulate one entry per app. A nil-bundle penalty applies to any requested bundle; a named penalty only matches that bundle.
- Re-arming retains current deadline renewal behavior. Expiry itself need not mutate storage. Clearing emits its existing marker only when the old penalty was still active.
- An independently recovered capture must still avoid occupied XCTest work; physical-device plans retain bounded XCTest probes while eligible simulator plans can defer to independent acquisition.
- Slow presentation alone never arms the penalty; acquisition timeout or an exhausted XCTest tier can arm it without crossing the slow-duration threshold. Preserve warmup suppression at its current decision point.
- Before: lock/state exposed across all runner extensions. After: only the owner accesses penalty state, with exactly the same effective-plan and quality outputs for the same observations.
Validation and exclusions
Move penalty-specific cases into the owner-matched test file; retain the consuming assertions in SnapshotCapturePlanTests, SnapshotTimingTests, LifecycleCacheTests, SnapshotCaptureTargetTests and SnapshotCapturePlanOccupancyTests. Cover nil/named bundle, replacement, exact expiry, clear, renewal and concurrent arm/read through the public interface. Plant a nil-bundle mismatch and a presentation-only penalty mutation to prove the nearest negative cases fail.
Run pnpm check:xctest-selection, unit-enabled iOS/macOS builds and selected XCTest cases, pnpm check:packaged-runner-swift, and pnpm check:affected --run. Preserve source-guard lane ownership. No claim of hostile-screen recovery improvement follows from extraction alone; report live evidence separately. No new retry strategy, clock-domain migration, penalty duration change, actor rewrite or host-side bridge-cache change belongs here.
Source paths in this issue are rooted at apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/; extension names abbreviate the RunnerTests+ prefix where stated. Tests live in its UnitTests/ directory. For a fresh worktree, run pnpm install --frozen-lockfile && pnpm build before the focused checks. Read docs/agents/testing.md and docs/agents/device-verification.md for native lane selection and build freshness.
- Lenguaje dominante
- TypeScript
- Estrellas
- 4.7k
- Forks
- 304
- Merge medio
- 11 h 31 min
- PR fusionados (30 d)
- 513
Preparar el entorno
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de callstack/agent-device
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
callstack/agent-device#2998 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
callstack/agent-device#2995 ·
Los mantenedores suelen responder en 1 día
-
Proxy lease refuses every iOS install/open: connection platform 'ios' compared with internal 'apple'Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
callstack/agent-device#2962 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
callstack/agent-device#1869 ·
Los mantenedores suelen responder en 1 día
-
Maestro `eraseText` fails on real Android devices: `test` and `replay` cannot opt in to the test IMEAbierto
Dificultad 3/5 1-2 días Aptitud para principiantes 74/100
callstack/agent-device#2997 ·
Los mantenedores suelen responder en 1 día
Todos los issues de callstack/agent-device
Issues similares
-
bug
Dificultad 1/5 Menos de una hora Aptitud para principiantes 88/100
StabilityNexus/Fate-EVM-Frontend#153 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
code-yeongyu/oh-my-openagent#9039 ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
Tencent/teamai-cli#862 ·
Los mantenedores suelen responder en 1 día
-
bug good first issue hacktoberfest redis
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
libredb/libredb-studio#1164 ·
Los mantenedores suelen responder en 1 día
-
flake
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
coder/xum#4920 · 2 comentarios ·
Los mantenedores suelen responder en 1 día