# Handling Platform‑Specific Differences (macOS, Linux, Windows) in ADR Sensor

> Learn how the ADR Sensor handles platform-specific differences across macOS Linux and Windows using Python's platform system for OS detection and conditional code execution.

- Repository: [Uber Open Source/ADR](https://github.com/uber/ADR)
- Tags: how-to-guide
- Published: 2026-08-07

---

**The ADR Sensor handles platform-specific differences in macOS, Linux, and Windows by using Python's `platform.system()` for runtime OS detection and conditional execution of OS-specific code paths.**

The ADR Sensor from Uber is a cross-platform Python package that ingests agent activity logs from AI coding tools. To maintain portability across operating systems, the codebase implements targeted branching for features that depend on OS-specific APIs or file locations. This article examines the exact mechanisms used for detecting the host platform and gating functionality accordingly.

## Runtime OS Detection in ADR Sensor

The foundation of all platform-specific logic rests on Python's standard library `platform` module. Two core files implement OS detection:

- [`Sensor/adr_sensor/observer.py`](https://github.com/uber/ADR/blob/main/Sensor/adr_sensor/observer.py) (lines 10–11)
- [`Sensor/adr_sensor/cli.py`](https://github.com/uber/ADR/blob/main/Sensor/adr_sensor/cli.py) (lines 15–16)

Both modules call `platform.system()`, which returns:
- `"Darwin"` for macOS
- `"Linux"` for Linux
- `"Windows"` for Windows

This single function call drives all subsequent conditional logic in the package.

## macOS-Specific: Claude Desktop Agent-Mode Parser

The most significant platform-specific feature in ADR Sensor is the **Claude Desktop Agent-Mode parser**, which only runs on macOS.

In [`Sensor/adr_sensor/observer.py`](https://github.com/uber/ADR/blob/main/Sensor/adr_sensor/observer.py) at lines 43–46, the `AgentObserver.ingest_all` method guards parser instantiation:

```python
import platform

# Inside AgentObserver.ingest_all()

if source_filter in ["all", "claude_desktop_agent"] and platform.system() == "Darwin":
    print("Ingesting Claude Desktop (Agent Mode) logs...")
    try:
        claude_entries = self.claude_desktop_agent_parser.parse_all()
        # ... additional processing

    except Exception as e:
        # error handling

```

**Why macOS only?** The Claude Desktop Agent-Mode parser ([`Sensor/adr_sensor/parsers/claude_desktop_parser.py`](https://github.com/uber/ADR/blob/main/Sensor/adr_sensor/parsers/claude_desktop_parser.py)) contains file-path logic specific to macOS application bundle locations. Rather than implement path abstraction, the codebase simply excludes this parser on non-Darwin systems.

All other parsers—[`claude_parser.py`](https://github.com/uber/ADR/blob/main/claude_parser.py), [`cursor_parser.py`](https://github.com/uber/ADR/blob/main/cursor_parser.py), [`cline_parser.py`](https://github.com/uber/ADR/blob/main/cline_parser.py), [`warp_parser.py`](https://github.com/uber/ADR/blob/main/warp_parser.py), and [`codex_parser.py`](https://github.com/uber/ADR/blob/main/codex_parser.py)—contain no OS-specific code and run unchanged on every platform.

## Windows-Specific: Disabling Resource Usage Capture

On Windows, ADR Sensor disables **Unix resource metrics** that rely on the `resource` module, which is not available on non-POSIX systems.

In [`Sensor/adr_sensor/cli.py`](https://github.com/uber/ADR/blob/main/Sensor/adr_sensor/cli.py), the implementation uses a two-layer guard:

```python

# Lines 15-16: OS detection

import platform
host_os = platform.system()

# Lines 21-23: Conditional resource module import

try:
    import resource  # Unix-only module

    RESOURCE_AVAILABLE = True
except ImportError:
    RESOURCE_AVAILABLE = False

# Lines 88-90: Runtime flag override

capture_resource = args.capture_resource and host_os != "Windows" and RESOURCE_AVAILABLE

```

**The logic hierarchy:**
1. If `resource` import fails (Windows or restricted environment), `RESOURCE_AVAILABLE = False`
2. Even if import succeeds, `host_os == "Windows"` forces `capture_resource = False`
3. Only on non-Windows Unix systems does resource usage capture proceed via `resource.getrusage()`

This defensive pattern prevents runtime exceptions while preserving functionality where supported.

## Linux: Default Path Execution

Linux receives no special branching in ADR Sensor. It follows the **default execution path**: all platform-agnostic parsers run, and resource usage capture works normally via the `resource` module.

The Linux behavior is effectively defined by the absence of `"Darwin"` and `"Windows"` guards—any logic not explicitly gated by `platform.system() == "Darwin"` or `host_os == "Windows"` executes normally on Linux.

## Extending Platform-Specific Patterns

To add new OS-conditional features to ADR Sensor, follow the established patterns from the source code.

### Pattern 1: Parser-Level Gating (macOS-Style)

For features tied to OS-specific file paths or APIs, gate at the observer level:

```python

# In Sensor/adr_sensor/observer.py inside ingest_all()

if source_filter in ["all", "my_linux_parser"] and platform.system() == "Linux":
    print("Ingesting MyLinux-Only logs...")
    try:
        linux_entries = self.my_linux_parser.parse_all()
        linux_filtered = [e for e in linux_entries if e.has_meaningful_content()]
        all_entries.extend(linux_filtered)
        print(f"Found {len(linux_filtered)} entries\n")
    except Exception as e:
        self._emit_error({
            "source": "my_linux_parser",
            "stage": "parse",
            "error_type": e.__class__.__name__,
            "message": str(e),
            "trace": traceback.format_exc(limit=5),
        })

```

### Pattern 2: CLI Flag Validation (Windows-Style)

For command-line features with OS dependencies, validate early and fail fast:

```python

# In Sensor/adr_sensor/cli.py after parsing arguments

if args.enable_windows_feature:
    if host_os != "Windows":
        raise RuntimeError("The --enable-windows-feature flag is only supported on Windows.")
    # Windows-specific code here

```

### Pattern 3: Normalized OS Strings

For consistent external API communication, normalize `platform.system()` output:

```python
def _normalize_host_os() -> str:
    """Return a normalized identifier for the host OS."""
    raw = platform.system()
    return {"Darwin": "macOS", "Windows": "Windows", "Linux": "Linux"}.get(raw, "Unknown")

```

This normalized value populates the `host_os` field in [`system_config_schema.py`](https://github.com/uber/ADR/blob/main/system_config_schema.py) and [`agent_event_schema.py`](https://github.com/uber/ADR/blob/main/agent_event_schema.py).

## Key Files for Platform Handling

| File | Role |
|------|------|
| [`Sensor/adr_sensor/observer.py`](https://github.com/uber/ADR/blob/main/Sensor/adr_sensor/observer.py) | Central orchestrator; contains Darwin-gated Claude Desktop parser selection |
| [`Sensor/adr_sensor/cli.py`](https://github.com/uber/ADR/blob/main/Sensor/adr_sensor/cli.py) | CLI entry point; conditional `resource` import and Windows resource capture disable |
| [`Sensor/adr_sensor/parsers/claude_desktop_parser.py`](https://github.com/uber/ADR/blob/main/Sensor/adr_sensor/parsers/claude_desktop_parser.py) | macOS-only parser implementation |
| `Sensor/adr_sensor/parsers/*` | Platform-agnostic parsers (Claude, Cursor, Cline, Warp, Codex) |
| [`Sensor/adr_sensor/schemas/system_config_schema.py`](https://github.com/uber/ADR/blob/main/Sensor/adr_sensor/schemas/system_config_schema.py) | Schema defining `host_os` field populated via `platform.system()` |

## Summary

- **OS detection**: `platform.system()` drives all branching in [`observer.py`](https://github.com/uber/ADR/blob/main/observer.py) and [`cli.py`](https://github.com/uber/ADR/blob/main/cli.py)
- **macOS specialization**: Claude Desktop Agent-Mode parser gated by `platform.system() == "Darwin"`
- **Windows compatibility**: Resource usage capture disabled via dual guard (`ImportError` + `host_os` check)
- **Linux default**: No special handling required; standard Python execution path
- **Extension pattern**: Mirror existing checks at appropriate entry points (observer for parsers, CLI for flags)

## Frequently Asked Questions

### How does ADR Sensor detect which operating system it's running on?

ADR Sensor uses Python's standard `platform` module, specifically `platform.system()`. This function is called in both [`observer.py`](https://github.com/uber/ADR/blob/main/observer.py) (line 10) and [`cli.py`](https://github.com/uber/ADR/blob/main/cli.py) (line 15) to determine runtime behavior. The string returned—`"Darwin"`, `"Linux"`, or `"Windows"`—controls all subsequent conditional logic.

### Why does the Claude Desktop parser only work on macOS?

The Claude Desktop Agent-Mode parser ([`claude_desktop_parser.py`](https://github.com/uber/ADR/blob/main/claude_desktop_parser.py)) implements file-path logic specific to macOS application bundle structures. Rather than abstract these paths, the codebase located in `uber/ADR` gates parser instantiation with `platform.system() == "Darwin"` in [`observer.py`](https://github.com/uber/ADR/blob/main/observer.py) lines 43–46. This prevents path resolution errors on Linux and Windows.

### What happens to resource usage metrics on Windows?

Resource usage capture is completely disabled on Windows. In [`cli.py`](https://github.com/uber/ADR/blob/main/cli.py), the code first attempts to import the Unix-only `resource` module, which fails on Windows. Even if imported successfully, an explicit `host_os != "Windows"` check at line 89 forces `capture_resource = False`. This prevents any call to `resource.getrusage()` on non-POSIX systems.