Route snapshot capture sources through one platform-neutral router
Maintainer antworten meist innerhalb von 1 Tag
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 5/5
- Geschätzter Aufwand
- Über eine Woche
- Anfängerfreundlichkeit
- 5/100
- Issue-Typ
- Refactoring
- Klarheit
- Größtenteils klar
- Aktivitätsstatus
- Aktiv
- Tech-Stack
- android, ios, macos, typescript
Rechercherichtung
Start with the iOS route core in packages/platform-apple/src/snapshot-route.ts and its failure policy in snapshot-route-failure-policy.ts, then the constant ports in packages/platform-apple/src/runner-runtime.ts. The ADR decision on Android's system-UI annotation and SurfaceProof must land before any code moves, and the work is blocked by #4182 on unmerged runner layers. Done means one router in packages/capture-kit serves all channels, with no constant-filled ports and the existing route tests passing unchanged.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
Purpose
Snapshot capture source selection must be one product rule for every platform and provider. Today the rule exists only for iOS, in packages/platform-apple/src/snapshot-route.ts, and each channel fills the route's ports with placeholders. Android, macOS, web, WebDriver and Revyl each have one hard-wired source with no shared fallback, refusal or proof vocabulary. Producer facts live in about six owners.
Current state (evidence)
- The iOS route core:
packages/platform-apple/src/snapshot-route.ts(probes, target resolution, acquisition, one fallback, identity stamping, warnings) andsnapshot-route-failure-policy.ts(refusal scope). - The runner channel (#4182) fills the route's ports with constants:
isDiscoveryPending: () => false,targetFreshness: 'cached',systemSurfacePresent: async () => 'unknown'(packages/platform-apple/src/runner-runtime.ts). The route reads them atsnapshot-route.ts(discovery wait, cached-target refresh, presence probe). - Eligibility is split:
isEligiblein the route, the observe-only bypass inrunner-runtime.tsbindBridgeSnapshot, and thepreferredBackendverdict pin inpackages/capture-kit/src/snapshot-quality-verdict.ts→stable-capture.ts. - Producer facts:
packages/contracts/src/ios-snapshot.ts, three producer-keyed tables inpackages/capture-kit/src/ios-snapshot-acquisition.ts,packages/kernel/src/snapshot.ts(SnapshotProvenance),packages/command-runtime/.../stable-capture.ts, producer switches inpackages/command-runtime/src/commands/capture/runtime/snapshot.ts. Revyl's Android tree is labeledappium-source, the same name WebDriver uses for iOS. - Single-source platforms: Android
packages/platform-android/src/snapshot-capture.ts, macOSpackages/platform-apple/src/os/macos/surface-snapshot.ts, Revylpackages/provider-revyl/src/snapshot.ts, WebDriverpackages/provider-webdriver/src/webdriver-ios-snapshot.ts. validateTargetis duplicated insnapshot-source/adapter.tsandrunner-snapshot-bridge.ts. Three fallback settlers exist:runFallback,runSurfaceFallback,captureOffRoute.- ADR 0004 is about 60 KB.
docs/adr/FORMAT.mdasks for about 8 KB.
Required behavior
-
A new ADR, "Snapshot capture source routing", states the rule for all platforms. ADR 0004 keeps only the iOS facts (bridge, runner plan, system-surface hosts) and drops its amendment history.
-
One platform-neutral router in
packages/capture-kitowns: the source plan (plan(input)returns the source and the reason), one fallback per capture, the per-target generation circuit, the refusal table (capture scope vs generation scope), occlusion proof, identity stamping, and warnings. It imports no platform package. -
Each platform or provider declares its channels. A channel declares only what it has. A channel never fills a port with a constant.
type SurfaceProof = (device, signal) => Promise<'clear' | Readonly<{ occluded: string }> | 'unproven'>; type SourceChannel<T> = Readonly<{ producer: SnapshotProducer; acquire(req: { target: T; hint; signal }): Promise<SourceOutcome>; resolveTarget(device, app, signal): Promise<T>; refreshTarget?(device, app, signal): Promise<T>; // replaces targetFreshness awaitDiscovery?(device, signal): Promise<void>; // replaces isDiscoveryPending proof: 'none' | SurfaceProof; // replaces the presence/foreground pair supports: { customActions: boolean; observeOnly: boolean; pinnedBackend: boolean }; }>; -
iOS local, iOS provider (Limrun runner channel), Android, macOS and web route through the router. A single-source platform is the one-channel case.
-
One producer registry in
packages/contracts, declared withsatisfies Record<SnapshotProducer, ProducerFacts>(channel, truncation, residue, quiet time, ref-namespace owner). The producer union is platform-neutral. Every other producer table derives from the registry. -
The refusal fixture
contracts/fixtures/ios-snapshot-bridge-refusals.json(#4182) becomes the router's refusal table input for every channel that emits typed refusals.
Completion conditions
git grepfinds no route port filled by a constant (() => false,async () => 'unknown') and notargetFreshness.- A layering rule fails when the router module imports a platform or provider package.
- A repo guard fails when a producer in the registry has no production emitter.
- A repo guard fails when an ADR cites a file path or test name that does not exist.
- Existing route behavior tests pass unchanged against the router, for the guest and runner channels.
- Live check: local iOS Simulator, Limrun iOS, local Android emulator. Each capture names the same producer and fallback warnings as before the change.
- The new ADR is accepted, and ADR 0004 is under about 15 KB.
Dependencies
Blocked by: #4182 (runner-served bridge and refusal fixture), which is stacked on the unmerged Limrun runner layers (stack/limrun-native-runner).
Open question: whether Android's system-UI annotation fits the SurfaceProof port. Decide this in the ADR before code moves.
- Vorherrschende Sprache
- TypeScript
- Sterne
- 5.3k
- Forks
- 377
- Ø Merge
- 14 Std. 6 Min.
- Gemergte PRs (30 T.)
- 650
Entwicklungsumgebung
- Kein Dockerfile und keine Docker-Compose-Datei
- Keine Pull-Request-Vorlage
- Beitragsleitfaden lesen
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus callstack/agent-device
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 79/100
callstack/agent-device#4249 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
bug ready-for-agent
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 90/100
callstack/agent-device#4212 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
iOS alert wait: the last poll can get ~30 ms and turns "no alert" into a failed readEvtl. vergeben @pcbeingused333 hat das vor 6 Tagen übernommen. Offenbug ready-for-agent
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 77/100
callstack/agent-device#4018 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 68/100
callstack/agent-device#1869 ·
Maintainer antworten meist innerhalb von 1 Tag
-
bug ready-for-agent
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 55/100
callstack/agent-device#4247 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
Alle Issues in callstack/agent-device
Ähnliche Issues
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 65/100
Maintainer antworten meist innerhalb von 1 Tag
-
"Claude Code request is missing its initial user message" when the prompt starts with an image pathOffen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 84/100
earendil-works/pi-claude-code#31 ·
Maintainer antworten meist innerhalb von 8 Tagen
-
bug pending triage
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 92/100
privatenumber/cleye#48 ·
-
Google text documents are base64-encoded twiceEvtl. vergeben @feiiiiii5 hat das heute übernommen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 84/100
Maintainer antworten meist innerhalb von 1 Tag
-
bug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
Maintainer antworten meist innerhalb von 1 Tag