Overview
Link to section: OverviewRVI tells an investigator what was visible at the iPhone's remote capture interface. PKTAP adds process, interface, and direction metadata to Mac traffic. Unified Log can provide context about Mac services and connections. The Correlator preserves those distinctions while placing observations on a shared timeline.
Two separate relationship views answer different questions:
| Review | Question | Meaning |
|---|---|---|
| Shared-service candidates | Did both devices communicate with the same remote endpoint near the same time? | A scored investigative lead, with competing processes and limitations. |
| TCP direct-peer review | Do packets on both sides have a defensible matching header fingerprint? | An inferred, unscored packet relationship; not proof of process ownership, causation, or payload identity. |
Capture and decoding have been exercised on a physical iPhone. Correlation remains experimental: scores are a transparent evidence-strength rubric, not calibrated probabilities. Zero qualifying relationships can be a valid result.
Native App Screenshots
Link to section: Native App ScreenshotsThese are screenshots of the packaged native app. Analysis screenshots use its SYNTHETIC DEMO, containing fabricated packet and log records. Example process labels, hostnames, and addresses are illustrative; they are not observations of Apple service behavior or evidence from a private device.
Branded overview and capture readiness
Link to section: Branded overview and capture readiness
This real screenshot of the packaged development preview shows the selected Aligned Evidence identity, separate device/RVI/decoder readiness, import controls, and the labeled synthetic demonstration. It is a setup state, not a running capture or a claim of zero packet loss. The development preview also shows the local session-navigation and optional iPhone-log work; publication of those capabilities is separate from this artwork update.
Candidate explanations, focused evidence review, and the interpretation guide are described in the investigation walkthrough. The preserved screenshots with the previous branding remain under assets/branding-v1/screenshots/.
What It Does
Link to section: What It Does- Starts iPhone RVI, Mac PKTAP, and a targeted Mac Unified Log stream in one bounded session.
- Discovers paired physical devices through CoreDevice; excludes simulators and requires reported USB readiness.
- Decodes growing PCAPNG files with separately installed TShark and refreshes the timeline during capture.
- Imports existing PCAP/PCAPNG captures, including RVI-Sentinel output, and UTF-8 Unified Log JSON Lines.
- Reads both raw PKTAP headers and Apple PCAPNG process/interface/direction options.
- Preserves original timestamps, capture records, source identity, hashes, and clock adjustments.
- Associates captured DNS answers with flows using source, client, CNAME chain, and TTL boundaries.
- Explains shared-service candidates, rejected initiations, competing processes, and missing evidence.
- Reviews possible TCP direct-peer traffic independently of shared-service scoring.
- Links relationship records to a focused timeline and supports returning to the expanded peer group.
- Saves original evidence locally and checks finalized session manifests before reopening.
- Offers optional, explicitly initiated current DNS/PTR lookup, separate from captured evidence and scores.
Architecture
Link to section: ArchitectureiPhone via Apple RVI Mac via PKTAP Mac Unified Log
| | |
Original PCAPNG Original PCAPNG Raw NDJSON
| | |
+---- TShark protocol/metadata decoding ------+
|
Source-scoped normalization and provenance
|
DNS / TLS / QUIC / process / interface / log evidence
|
Normalized timeline
|
+--------------------+---------------------+
| |
Shared-service candidates TCP direct-peer review
Explained evidence strength Inferred, unscored pairs
| |
+---------------- Investigator view --------+
Evidence and uncertaintyThe app uses Foundation, SwiftUI, AppKit, and CryptoKit. It has no third-party Swift package dependencies. Packet dissection runs through the external tshark executable; the app does not bundle Wireshark.
Requirements
Link to section: Requirements| Requirement | Purpose and limits |
|---|---|
| macOS 14+ | Deployment target. Validation has been on an Apple silicon development Mac; this is not a claim that every supported OS/hardware combination was tested. |
| Swift 6 toolchain | Build the Swift package and native app bundle. |
| Xcode with CoreDevice/device support | Live discovery uses xcrun devicectl; Command Line Tools alone may not supply device support or rvictl. |
Apple rvictl | Creates the remote virtual interface. The app searches /Library/Apple/usr/bin/rvictl and supported system locations. |
| TShark from Wireshark | Required for real and synthetic packet import. Searches /Applications/Wireshark.app/Contents/MacOS/tshark, /opt/homebrew/bin/tshark, then /usr/local/bin/tshark. Validation used TShark 4.6.9. |
| Paired, trusted iPhone on USB | Required only for live RVI capture. Connect, unlock, and accept the device's Trust prompt. Network-only discovery does not qualify. |
| macOS administrator authorization | The native authorization prompt launches the bounded capture helper. Do not run the whole GUI as root. |
| Writable Documents folder and sufficient disk space | Original evidence is saved locally. Allow Documents access if macOS requests it. |
Apple's packet-trace documentation describes RVI setup. Installing Command Line Tools is not a guarantee that rvictl has been installed. Use Apple's supported Xcode/device-support installation and verify the app's readiness checks.
Build and Run
Link to section: Build and Rungit clone https://github.com/hideouts-io/RVI-Correlator.git
cd RVI-Correlator
./scripts/build-app.sh
open 'dist/RVI + PKTAP Correlator.app'The script creates a release build, bundles the capture helper and demo resources, and includes the approved 01 · Aligned Evidence icon for the app, Finder, and Dock. The branding inventory includes editable sources, logo treatments, icon sizes, GitHub artwork, and responsive website images. Open the .app to use its bundled icon. The source repository does not distribute a notarized installer or prebuilt binary. The build is native to the selected toolchain/host architecture, not a universal binary.
For development and tests:
swift build
swift test -j 4Use the packaged app for live capture: the helper and app resources must be present beside the GUI executable.
Live Capture and Health
Link to section: Live Capture and Health- Connect and unlock the iPhone, accept Trust if prompted, then choose Refresh devices.
- Select the physical USB-connected device. Resolve the Device, Apple RVI, and Decoder readiness messages.
- Leave offsets at 0 ms and clock verification unchecked unless you already have an independent calibration.
- Choose Start live session and complete native macOS authorization.
- Check that all collectors remain running and evidence counts increase. Monitor warnings and packet/drop reports.
- Choose Stop and finalize, wait for analysis and manifest creation, then reopen the saved session to check integrity.
The helper creates an rviN interface, validates the capture interfaces, and starts macOS tcpdump with full snap length, immediate writes, and Apple PCAPNG output. Mac capture uses pktap. Unified Log collection runs at default level with a targeted predicate. Collector starts are not simultaneous at hardware precision; their launch separation does not calibrate clocks.
| Health signal | Interpretation |
|---|---|
| Collector PID / running status | The collector has started; this alone does not prove packets are arriving. |
| Packet count pending | tcpdump has not yet reported a counter; not equivalent to zero. |
| Kernel drops not yet measured | Drop information is unavailable so far. |
| Nonzero kernel drops | Evidence may be incomplete. Preserve the warning with the session. |
| Zero reported kernel drops | That collector reported no kernel drops; does not prove end-to-end completeness. |
| HEALTH UNKNOWN | Monitoring failed. Inspect saved diagnostics; do not assume healthy capture. |
| In-progress hash | Capture is still changing; final integrity information is not available yet. |
Unified Log is not a packet collector, so packet counters do not apply. Default-level selection, privacy redaction, and stream loss can omit useful events.
A collector exit, lost GUI process, 30-minute capture limit, or 1 GB raw-log limit ends capture with an explicit failure. Original files remain available even if finalization fails. Do not treat a directory containing files as a successfully finalized session.
iPhone interface coverage
Link to section: iPhone interface coverageOnly packet-reported interface names are directly observed. A name establishes visibility for those packets, not complete capture of that interface. The app does not have a comprehensive device-side interface inventory.
Wi-Fi, cellular, Ethernet, tethering, VPN/tunnel, loopback, and other interfaces must be assessed separately. Inner tunnel and loopback traffic may be unavailable even when an outer flow is visible. A missing interface label does not prove the interface was inactive. A separately entitled Network Extension can observe traffic routed through its own tunnel; this application does not implement a device-side all-interface collector.
Import and Saved Sessions
Link to section: Import and Saved Sessions- Import iPhone RVI: choose an existing PCAP or PCAPNG, including output from either RVI-Sentinel edition.
- Import Mac PKTAP: choose a capture preserving raw PKTAP headers or Apple PCAPNG metadata. A normal Ethernet capture without process metadata is insufficient for Mac process attribution.
- Add Unified Log: import UTF-8 JSON Lines with
timestampandeventMessage, plus availableprocessID,processImagePath,subsystem, andcategoryfields. A.logarchivemust first be exported with Apple'slog show --style ndjson. - Open saved session…: choose a finalized folder containing
manifest.json. Recorded file sizes and SHA-256 hashes must match.
For example, export your own bounded Mac log interval, replacing the example dates:
/usr/bin/log show --style ndjson --timezone UTC \
--start '2026-09-29 10:00:00' --end '2026-09-29 10:05:00' \
> mac-log.ndjsonA finalized session can also be opened from Terminal:
open 'dist/RVI + PKTAP Correlator.app' --args --open-session /absolute/path/to/sessionA matching manifest establishes consistency with that manifest. It does not authenticate who created the evidence or establish complete capture coverage.
Investigation Walkthrough
Link to section: Investigation Walkthrough- Learn with the demo. Select Explore a synthetic example. It loads fabricated DNS, TLS, PKTAP, and log records through the real import/correlation path. The app labels the result SYNTHETIC DEMO.
- Collect a bounded session. Establish a quiet baseline, then perform one identifiable action at a time on the iPhone and Mac. Record actions separately as investigator notes. Action times are not clock-calibration references.
- Check coverage before interpretation. Review collector warnings, reported drops, source counts, and interface labels. Preserve partial failures.
- Inspect the timeline. Filter by source or search hostname, process, protocol, or IP. Open a row for original/adjusted time and observed fields.
- Review relationships. Inspect shared-service candidates and TCP peer partitions separately. Read score components, contradictions, alternatives, and missing evidence. Use cited-record links and Return to relationship for peer review.
- Investigate zero results. Review initiation rejection reasons and nearest endpoint evidence. Different endpoints or events outside the search window can legitimately yield no candidates. Do not widen the window just to produce results.
- Preserve a handoff. Finalize the session, verify reopening, and use Export investigation JSON… under Evidence sources. Share evidence only after a separate privacy review.
Protocol Coverage
Link to section: Protocol CoverageDissection depends on the bytes captured and fields supplied by the installed TShark version. Decoding a protocol is not equivalent to decrypting it or proving a relationship.
| Protocol | Retained or analyzed metadata | Principal limit |
|---|---|---|
| Ethernet | Source/destination MAC, EtherType | Not all capture link types contain Ethernet. |
| ARP | Operation and IPv4 protocol addresses | Local-link evidence only. |
| IPv4 / IPv6 | Addresses and protocol/next-header values | Translated or nested endpoints require care; peer review rejects multiple IP layers. |
| ICMP / ICMPv6 | Message type and network endpoints | Not process ownership evidence. |
| TCP | Ports, stream, raw sequence/ACK, flags, payload length | Offload, segmentation, retransmissions, and missing packets can prevent pairing. |
| UDP | Ports and stream metadata | No implemented UDP direct-peer identity matcher. |
| DNS / mDNS / LLMNR | Queries, structured answers, A/AAAA, CNAME, TTL, response flags | Only supported address/alias answer records feed DNS associations; encrypted DNS remains opaque. |
| TLS | Visible ClientHello, SNI, ALPN, version fields, visible certificate metadata | No ECH inner name or encrypted TLS 1.3 certificate recovery. |
| HTTP/1 | Host, request method/URI, response code when visible | HTTPS contents are not automatically decrypted. |
| STUN | Message type and transaction ID | Does not establish which application caused iPhone traffic. |
| QUIC | Versions, source/destination connection IDs, long-header type, packet number/token length where exposed, recoverable Initial ClientHello | Recovery depends on decoder and captured handshake bytes. Connection IDs or timing alone are not peer identity. |
DNS and Hostname Provenance
Link to section: DNS and Hostname ProvenanceThe inspector distinguishes captured DNS, TLS SNI, HTTP Host, recoverable QUIC ClientHello, inferred flow inheritance, and optional current lookup.
DNS associations stay within the capture artifact and client address. CNAME chains use the intersection of record validity intervals; newer observed RRsets supersede older records. Expired records do not silently remain valid, and multiple names sharing an IP remain ambiguous. Mac DNS results are not automatically applied to iPhone flows.
Flow inheritance uses prior evidence within five minutes on the same stream, interface, and process identity. It is an inference about that flow, not proof of the hostname for each subsequent request. ECH, encrypted DNS, caching, missed answers, and captures beginning after connection establishment can explain missing names.
Look up now explicitly queries the Mac's configured resolver for current A/AAAA or PTR information. Lookup time and results remain separate, do not change scores, and cannot establish which hostname was used during an earlier capture. Passive import does not initiate these lookups.
Correlation and Process Attribution
Link to section: Correlation and Process AttributionShared-service candidates
Link to section: Shared-service candidatesCandidate selection requires a matching remote IP, remote port, transport, and configured time window. Direction determines the remote endpoint. Mac rvi frames are excluded because they may mirror iPhone traffic.
The score can incorporate endpoint matches, source-scoped DNS support, flow hostnames/SNI, ALPN, QUIC version, PKTAP labels, and qualifying logs. Time contributes points only with documented alignment and uncertainty compatible with the matching window.
High additionally requires eligible clock alignment with at most 50 ms uncertainty, matching host evidence, a labeled outbound Mac process, no competing process, no conflicting/ambiguous hostnames, and the score threshold. Inbound Mac evidence is capped at Low. Contradictions and alternatives are displayed explicitly. See Correlate.swift for the actual rubric.
Original and effective PKTAP identities remain distinct. Missing/sentinel PIDs are unknown. A packet-time PID/name label does not establish process lifetime or exclude PID reuse. Truncated process names are not merged by resemblance.
TCP direct-peer review
Link to section: TCP direct-peer reviewPairing requires identical wire endpoints, raw sequence/ACK numbers, payload length and flags, opposite known directions, a non-RVI Mac interface, and a unique match within the search window. A partition needs at least two distinct fingerprints including payload or SYN evidence; repeated ACKs alone are insufficient.
These are header fingerprints, not payload hashes. Forwarding, mirroring, retransmissions, and segmentation/offload differences remain limitations. Partitions preserve capture-local stream, interface, and original/effective process labels. They are not counts of unique processes or user actions. UDP/QUIC peer identity and translated-endpoint equivalence are not implemented.
Unified Log Evidence
Link to section: Unified Log EvidenceLive collection combines targeted networking/service coverage with host-observed executable names CoreDeviceService, remoted, usbmuxd, and AMPDeviceDiscoveryAgent. It does not indiscriminately collect every subsystem or enable private/debug logging.
Normalization retains these device-service events as context. Other retained records require a captured Mac PID and a bounded endpoint/hostname token. Retention is not automatically a supporting link. Relationship log support has separate PID, process-name, endpoint, time, and alignment requirements. Original raw records and line references remain available; derived rviCaptureSelection annotations are not OS fields.
Activity navigation requires original, nonempty boot identity and compatible process/image scope with nonzero activity identifiers. A separate capture-context.json records host boot samples, uptime, collection predicate and level. It is never silently substituted into an original log record. Agreeing host samples do not establish per-event identity, process lifetime, causation, or clock alignment.
Clock Alignment
Link to section: Clock AlignmentStart with 0 ms offsets and alignment unverified. The default 250 ms matching window is a search tolerance. The initial 1,000 ms uncertainty is an explicitly labeled placeholder, not a measured accuracy estimate.
offset = reference timestamp - source timestamp
adjusted timestamp = original timestamp + offsetA positive offset moves a stream later. Original timestamps remain unchanged. Container resolution is shown separately from clock origin and accuracy; files alone may not establish either.
The calibration worksheet requires at least two independently identifiable source/Mac reference pairs, the identification method, and measurement uncertainty. It calculates a constant correction, residuals, combined uncertainty, and observed drift. Applying a correction does not automatically mark alignment verified. Timing support is disabled outside a calibration's measured interval or if its offset no longer matches. Drift is reported, not silently corrected.
Do not calibrate from similar traffic, collector launch timing, user-action timing, or by maximizing match counts.
Evidence Files and Privacy
Link to section: Evidence Files and PrivacySessions are stored in ~/Documents/RVI-Correlator/Sessions/<session-id>/.
| Artifact | Purpose |
|---|---|
iphone-rvi.pcapng / mac-pktap.pcapng | Original packet evidence. |
unified-log.raw | Original collected log stream. |
unified-log.ndjson | Derived selected records with original line references. |
capture-context.json | Separately sourced host/session metadata. |
status.json and collector diagnostics | Capture phase, reported counters, errors and helper diagnostics. |
manifest.json | Final file sizes, SHA-256 hashes, capture status, and coverage. |
| Exported investigation JSON | Observations, original/adjusted times, settings, evidence reasons, peer relationships, and separate current lookups/context. |
There is no capture/report upload workflow. Explicit current DNS lookups can disclose the queried name or address to the configured resolver. Captures, logs, exports, hashes, identifiers, hostnames, and paths may be sensitive even when payloads are encrypted.
The repository excludes real captures, recovered sessions, private validation reports, logs, credentials, and build products. The only capture-format files included are explicitly allowlisted, fabricated demo/test fixtures. Their Apple-like names and process labels are examples, not captured Apple behavior. Review exports separately before sharing; .gitignore is not a complete data-loss prevention system.
Use the app only on devices and networks you own or are authorized to investigate.
Validation and Experimental Status
Link to section: Validation and Experimental StatusA preserved 77-second physical-iPhone session on 2026-09-29 UTC completed live decoding, clean stop, schema-2 finalization, hash verification, and reopening. Private originals and detailed audit reports are intentionally not published.
| Evidence in that bounded validation | Result |
|---|---|
| iPhone / Mac packets | 6,780 / 43,444 |
| Raw / normalized log records | 49,939 / 4,244 |
| Total normalized observations | 54,468 |
| Shared-service candidates | 0: 41 eligible initiations lacked matching Mac endpoints; 10 were outside the unchanged window. |
| TCP peer review | 15 partitions; 182 packet pairs; two partitions had both directions. |
| Qualifying peer log support | 0; retained service context did not qualify as supporting evidence. |
| Collector kernel drops | Both reported zero; not proof of complete collection. |
| Clock alignment | 0 ms offsets, unverified. |
| Final evidence integrity | All nine manifest-listed files matched size and SHA-256. |
Packet metadata named pdp_ip0, utun6, and en2. Those are observed labels, not a verified mapping of all device interfaces. TShark identified iPhone TCP, UDP, IPv4/IPv6, Ethernet, DHCP, ICMPv6, mDNS, TLS, and QUIC. Fourteen frames exposed ClientHello SNI, including ten QUIC frames. These counts do not prove protocol coverage across all scenarios.
A preceding failed run exposed an mDNS import defect, which was repaired and replayed successfully. That run also hit an atomic status-write permission error: reporting now surfaces the failure as unknown health, but its underlying permission cause remains unresolved. It did not recur in the short successful retry. Long-duration reliability remains unverified.
All raw log records in the successful run had empty boot UUIDs. The sidecar remains separate, and automatic boot-scoped activity grouping remains unavailable for those records. Requested iPhone browser actions/interface mode were not independently confirmed, so no action-to-packet attribution is claimed.
Verified in bounded tests: raw PKTAP and Apple PCAPNG import, synthetic DNS/TLS evidence behavior, short physical capture/finalization/reopen, preserved replay, and packaged UI review.
Partial or experimental: relationship inference, heuristic confidence, process association beyond the observed Mac label, targeted log support, and interface coverage.
Unverified: complete Wi-Fi/cellular/Ethernet/VPN/tethering/loopback coverage, end-to-end loss measurement, independently measured cross-device clock correction, UDP/QUIC peer identity, and long-running capture reliability. No accuracy benchmark or calibrated causal attribution is claimed.
Troubleshooting
Link to section: Troubleshooting| Symptom | Check or next step |
|---|---|
rvictl missing | Check /Library/Apple/usr/bin/rvictl; complete Apple's Xcode/device-support installation. A PATH check or Command Line Tools installation alone is insufficient. |
| Device unavailable / transport unknown | Reconnect directly by USB, unlock, accept Trust, and refresh. Confirm Xcode/CoreDevice can see the physical device. Do not substitute a simulator. |
| TShark missing or decoder field unavailable | Install Wireshark/TShark at a supported path; inspect the exact missing-field diagnostic. Do not interpret a decode failure as no network activity. |
| Mac packets but no process metadata | Verify raw PKTAP headers or Apple PCAPNG process options were preserved. A filename extension alone does not establish metadata coverage. |
| Live refresh failed | Preserve capture files and diagnostics; distinguish decoder failure from stopped collectors. Do not assume all streams are healthy. |
| HEALTH UNKNOWN / status-write error | Preserve helper.error, status and collector diagnostics. The prior permission failure's cause remains unresolved; do not broadly change directory permissions to mask it. |
| Zero candidates | Review rejection counts, endpoints, directions, hostname visibility, and clock uncertainty. Zero is not automatically a bug. |
| No hostname | Check for encrypted DNS, ECH, missed DNS replies or handshakes, and a late capture start. Current PTR is not historical evidence. |
| Empty log boot UUID | Keep activity grouping unavailable; a host-session sidecar must not become a fabricated per-event identifier. |
| Manifest mismatch | Preserve the original folder. Investigate the named file and expected/actual hash or size; do not regenerate a manifest merely to bypass the check. |
| Generic Dock icon | Open the packaged .app, not the raw executable. Quit and reopen after rebuilding; confirm you are launching the intended copy. |
Import is bounded to 50,000-frame decoder batches, 256 MB JSON and a 120-second deadline per decoder pass. Normalized log input is bounded to 64 MB and scoring to 20,000 candidate pairs. Exceeding a bound is an explicit error, not silent evidence truncation.
Testing
Link to section: Testingswift test -j 4The publication build passes 21 regular tests; two physical-evidence tests are skipped unless explicitly enabled. Tests exercise real TShark import on fabricated packets, DNS expiry/scoping, PKTAP forms, clock handling, peer ambiguity, log normalization and host context. A passing synthetic suite is not fresh physical-device validation.
For your own preserved session, run the opt-in replay with explicit private paths:
RVI_AUDIT_SESSION=/absolute/path/to/session \
RVI_AUDIT_OUTPUT=/absolute/path/to/private-audit.json \
swift test -j 4 --filter physicalSessionAuditThe audit reads existing evidence and writes the requested report; it does not create a live capture. Keep that report private. Do not commit machine-generated test output containing local paths.
Repository Structure
Link to section: Repository StructurePackage.swift SwiftPM library, GUI, helper, and tests
Sources/CorrelatorCore/ Decoding, evidence models, clocks, correlation
Sources/CorrelatorApp/ SwiftUI investigation and live-session workflow
Sources/CorrelatorApp/Samples/ Fabricated, labeled demonstration records
Sources/CaptureHelper/ Bounded authorized macOS collectors
Tests/CorrelatorCoreTests/ Behavior/integration tests and tiny fixtures
scripts/ App packaging
assets/ Approved logo and real app screenshotsRelationship to RVI-Sentinel
Link to section: Relationship to RVI-Sentinel| Project | Focus |
|---|---|
| RVI-Sentinel-Swift | Native macOS iPhone capture, evidence review, and network baselines. |
| RVI-Sentinel | Separate Python capture/analysis project with cross-platform workflows. |
| RVI + PKTAP Correlator | Companion focused on relationships between iPhone packets, Mac process-aware packets, and Mac log evidence. |
The integration boundary is existing PCAP/PCAPNG evidence and the established Apple RVI/tcpdump capture approach. This is a separate app, not an embedded RVI-Sentinel module or a replacement for either edition. It does not inherit every feature of those projects.
Licensing and Dependencies
Link to section: Licensing and DependenciesThe project code, documentation, and approved Correlator logo are available under the MIT License. Copyright (c) 2026 hideouts-io.
Wireshark/TShark is separately installed and licensed under GPL version 2 or later; it is not redistributed here. Apple developer/system tools remain subject to Apple's terms. Package.swift declares no external Swift packages. The approved Aligned Evidence branding includes original PNG, SVG, and ICNS assets. The app uses the icon and sidebar image, the README uses its banner and real packaged preview, and packaging preserves the ICNS payloads unchanged. Previous artwork is retained under assets/branding-v1/. It is not an Apple or Wireshark logo.


