refactor(apple-runner): encapsulate XCTest-channel penalty state
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 35/100
- issue の種類
- リファクタリング
- 明瞭さ
- おおむね明確
- 活発さ
- 活発
- 技術スタック
- swift
- 領域
- mobile-dev, testing-qa
調査の方向性
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.
索引モデルが issue の本文から書いたものです。
説明
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.
- 主要言語
- TypeScript
- スター
- 4.7k
- フォーク
- 304
- 平均マージ
- 11時間 6分
- マージ済み PR(30日)
- 521
環境構築
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
callstack/agent-device のほかの issue
-
ready-for-agent
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
callstack/agent-device#2995 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
callstack/agent-device#1869 ·
メンテナーはふだん 1 日以内に返信
-
難易度 3/5 1〜2日 初心者へのやさしさ 75/100
callstack/agent-device#3047 ·
メンテナーはふだん 1 日以内に返信
-
難易度 5/5 1週間以上 初心者へのやさしさ 45/100
callstack/agent-device#3021 ·
メンテナーはふだん 1 日以内に返信
-
ready-for-agent
難易度 3/5 1〜2日 初心者へのやさしさ 68/100
callstack/agent-device#3004 ·
メンテナーはふだん 1 日以内に返信
callstack/agent-device の issue をすべて見る
似ている issue
-
難易度 1/5 1〜3時間 初心者へのやさしさ 88/100
supabase/agent-skills#611 ·
-
難易度 1/5 1時間未満 初心者へのやさしさ 68/100
polka-codes/test#345 ·
メンテナーはふだん 1 日以内に返信
-
難易度 1/5 1〜3時間 初心者へのやさしさ 92/100
GoogleChromeLabs/project-sesame#217 ·
メンテナーはふだん 12 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
solana-foundation/solana-com#2202 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100