Skip to content

feat(platform): cut over macOS listener inspection - #303

Merged
munezaclovis merged 12 commits into
mainfrom
agent/macos-14-listener-cutover
Jul 29, 2026
Merged

feat(platform): cut over macOS listener inspection#303
munezaclovis merged 12 commits into
mainfrom
agent/macos-14-listener-cutover

Conversation

@munezaclovis

@munezaclovis munezaclovis commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

  • raise the supported PV v1 floor to macOS 14 while retaining best-effort binary compatibility for macOS 13
  • run the full Rust quality and test job across macOS 14 arm64, macOS 15 Intel, and macOS 26 arm64
  • make the PV-owned kernel PCB inspector the sole production source for macOS TCP listener inspection
  • remove netstat-esr, the /usr/sbin/netstat production command path, legacy text parsing, errors, and snapshots
  • run the live listener comparison against Apple netstat as a normal, non-ignored platform test in every Rust matrix lane
  • harden loopback test fixtures for the hosted macOS matrix by avoiding FQDN resolution, making fixture platforms deterministic, and normalizing accepted Unix streams to blocking mode

Why

PR #301 added the kernel inspector but deliberately left it acceptance-only, so the application continued unioning netstat-esr with /usr/sbin/netstat. The remaining cutover gate included macOS 13, for which the repository has no current hosted runner. PV now supports macOS 14 and newer; macOS 13 may remain compatible but is untested and unsupported. GitHub provides hosted runners for the resulting representative matrix.

Impact

PV now answers loopback TCP listener questions directly from net.inet.tcp.pcblist_n on macOS. Inspection failures remain fail-safe and surface through the typed PlatformError::ListenerInspection variant. Managed Resource deployment targets remain at macOS 13, so this policy change does not trigger artifact rebuilds or intentionally break compatible installations.

The only remaining /usr/sbin/netstat execution is test-only and acts as the acceptance oracle; it is not shipped runtime behavior.

The existing Rust job now runs formatting, Clippy, unused-dependency checks, ShellCheck, and the complete workspace test suite on every representative macOS host. There is no separate listener-only CI job.

Validation

  • local macOS 26.5.2 arm64 production-path comparison: 10/10 detections for IPv4 loopback, IPv4 wildcard, IPv6 loopback, and IPv6 wildcard
  • focused local update fixture tests: 2/2 passed
  • local cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
  • local cargo fmt --all -- --check
  • full CI matrix:
    • macOS 14 arm64: 1060/1060 tests passed, including the live listener acceptance test
    • macOS 15 Intel: 1060/1060 tests passed, including the live listener acceptance test
    • macOS 26 arm64: 1060/1060 tests passed, including the live listener acceptance test
    • Linux and Windows runtime jobs passed
    • formatting, Clippy, unused-dependency checks, and artifact recipe checks passed in every macOS Rust lane
  • CodSpeed passed

Summary by CodeRabbit

  • New Features

    • Enhanced macOS TCP listener detection using a more reliable system-level approach.
    • Expanded macOS CI coverage with multiple macOS versions and both Intel/Apple Silicon architectures.
  • Bug Fixes

    • Improved diagnostics when TCP listener inspection fails.
    • Strengthened safeguards to prevent activation of unsupported macOS 13 binaries.
  • Documentation

    • Updated macOS support policy for PV v1 and clarified compatibility/update requirements.
    • Clarified managed resource recipe deployment-target expectations for macOS.

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

macOS listener inspection now uses kernel-table logic instead of the netstat-based implementation. Error handling, dependencies, acceptance coverage, CI validation, privileged evidence collection, macOS support documentation, and test failure diagnostics were updated.

Changes

macOS Listener Inspection Migration

Layer / File(s) Summary
Kernel-table listener implementation
Cargo.toml, crates/platform/Cargo.toml, crates/platform/src/{error.rs,ca.rs,listener.rs}, crates/platform/src/listener/macos*
macOS listener detection delegates to kernel-table inspection, netstat-specific errors and parser tests are removed, and failures use PlatformError::ListenerInspection.
Cross-source listener acceptance validation
.github/workflows/ci.yml, crates/platform/src/listener/macos/kernel_table.rs, scripts/ci/privileged-macos-rc.sh
Acceptance tests compare kernel-table and netstat detections across sampled ports, CI runs the macOS matrix, and listener evidence uses direct lsof output.
macOS support and deployment policy
DESIGN.md, docs/superpowers/specs/...
Documentation defines macOS 14+ support, macOS 13 compatibility limits, representative acceptance coverage, and explicit deployment-target rules.

Test Environment and Fixture Diagnostics

Layer / File(s) Summary
Platform defaults and Mailpit fixture errors
crates/cli/tests/php.rs, crates/daemon/src/managed_resources/tests.rs
CLI test environments default to Darwin arm64, while Mailpit reconciliation failures include fixture log contents or log-read errors.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

  • prvious/pv#253: Establishes the platform boundary and initial listener error shape used by this migration.
  • prvious/pv#272: Introduces the Mailpit managed-resource test suite extended with fixture diagnostics here.
  • prvious/pv#301: Introduces the listener inspector structure aligned with this kernel-table implementation.

Poem

A rabbit watched the listeners hop,
From netstat’s path to kernel’s shop.
Across Mac versions, tests now gleam,
While fixture logs reveal the dream.
“Hop, hop!” says Bun—the checks all pass!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: switching platform macOS listener inspection to the new implementation.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/macos-14-listener-cutover

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codspeed-hq

codspeed-hq Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 7 untouched benchmarks


Comparing agent/macos-14-listener-cutover (67bfd78) with main (b025350)

Open in CodSpeed

@munezaclovis
munezaclovis marked this pull request as ready for review July 29, 2026 00:16

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — this PR makes the PV-owned XNU PCB inspector the sole macOS listener source after establishing a supported-version and architecture acceptance matrix.

  • Cut over production listener inspection — macOS listener discovery now delegates exclusively to the bounds-checked kernel_table implementation and wraps failures as PlatformError::ListenerInspection.
  • Remove legacy inspection paths — the netstat-esr dependency, production /usr/sbin/netstat execution, text parser, legacy error variants, and parser snapshots are removed.
  • Add private-interface acceptance coverage — required CI compares controlled IPv4 and IPv6 loopback and wildcard listeners with Apple netstat on macOS 14 arm64, macOS 15 Intel, and macOS 26 arm64.
  • Raise the documented support floorDESIGN.md now supports macOS 14 and newer while retaining macOS 13 deployment targets for otherwise compatible Managed Resource artifacts.
  • Update diagnostic collection — the privileged macOS RC script records gateway listener evidence through lsof without invoking netstat.

Pullfrog  | View workflow run | Using GPT Sol𝕏

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
.github/workflows/ci.yml (1)

62-65: 🩺 Stability & Availability | 🔵 Trivial

macos-14 runner image is being deprecated.

GitHub Actions began deprecating the macos-14 (Sonoma) runner image on July 6, 2026, with scheduled brownout failures now and full removal by November 2, 2026. Since the matrix entry pins the macOS 14 floor to this label, it will start failing intermittently now and permanently within a few months, right when this PR's whole purpose is asserting macOS 14 support.

Source

Deprecation will begin on July 6th, 2026 and the images will be fully unsupported by November 2nd, 2026 for GitHub Actions and Azure DevOps. To raise awareness of the upcoming removal, we will temporarily fail jobs using macOS 14 and macOS 14 arm64. Builds that are scheduled to run during the brownout periods will fail.

Consider tracking this so the matrix is updated once GitHub retires the macos-14 image (there is no currently announced macos-14-equivalent successor other than moving the floor check to a self-hosted or pinned VM image).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 62 - 65, Update the macOS 14 arm64
matrix entry associated with runner label macos-14 to avoid relying on the
deprecated GitHub-hosted image, using the project’s supported self-hosted or
pinned VM strategy when available. Preserve the macOS 14 floor metadata and
arm64 coverage, and ensure the matrix remains valid after macos-14 retirement.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 62-65: Update the macOS 14 arm64 matrix entry associated with
runner label macos-14 to avoid relying on the deprecated GitHub-hosted image,
using the project’s supported self-hosted or pinned VM strategy when available.
Preserve the macOS 14 floor metadata and arm64 coverage, and ensure the matrix
remains valid after macos-14 retirement.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ddd61f22-24fa-4f64-a788-0bc06f42e4d9

📥 Commits

Reviewing files that changed from the base of the PR and between b025350 and 9358d51.

⛔ Files ignored due to path filters (3)
  • Cargo.lock is excluded by !**/*.lock
  • crates/platform/src/listener/macos/snapshots/platform__listener__implementation__kernel_table__tests__live_kernel_table_repeatedly_detects_all_controlled_listener_classes.snap is excluded by !**/*.snap
  • crates/platform/src/snapshots/platform__tests__netstat_tcp_listener_port_parser_covers_loopback_and_wildcard_addresses.snap is excluded by !**/*.snap
📒 Files selected for processing (12)
  • .github/workflows/ci.yml
  • Cargo.toml
  • DESIGN.md
  • crates/platform/Cargo.toml
  • crates/platform/src/ca.rs
  • crates/platform/src/error.rs
  • crates/platform/src/lib.rs
  • crates/platform/src/listener.rs
  • crates/platform/src/listener/macos.rs
  • crates/platform/src/listener/macos/kernel_table.rs
  • docs/superpowers/specs/2026-07-19-portable-platform-architecture-design.md
  • scripts/ci/privileged-macos-rc.sh
💤 Files with no reviewable changes (4)
  • crates/platform/src/listener.rs
  • crates/platform/src/lib.rs
  • Cargo.toml
  • crates/platform/Cargo.toml

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — the new commits fold listener acceptance into the complete supported macOS CI matrix instead of maintaining a separate ignored-test lane.

  • Expanded the Rust CI matrix — the full formatting, lint, dependency, script, and workspace test suite now runs on macOS 14 arm64, macOS 15 Intel, and macOS 26 arm64 after verifying each host.
  • Promoted listener acceptance into the normal suite — the live test now requires both the production kernel inspector and Apple netstat to detect every controlled IPv4 and IPv6 listener across ten samples in each matrix lane.
  • Aligned platform documentationDESIGN.md and the architecture specification now describe private-interface acceptance as part of the full representative CI matrix.

Pullfrog  | View workflow run | Using GPT Sol𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — the latest commit makes PHP integration fixtures independent of the CI runner architecture while preserving explicit platform overrides and failure injection.

  • Pinned the PHP fixture platformTestEnvironment now defaults to TargetPlatform::DarwinArm64, matching its artifact fixtures on every macOS matrix lane.
  • Preserved targeted platform coverage — the injected DarwinAmd64 case and unsupported-platform resolution cases continue to override the fixture default explicitly.

Pullfrog  | View workflow run | Using GPT Sol𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

The new failure diagnostics violate denied workspace Clippy policy and will block the macOS Rust matrix.

Reviewed changes — the latest commit adds Mailpit fixture process logs to three reconciliation test failures so hosted-runner timeouts expose their underlying process output.

  • Added Mailpit failure diagnosticsprint_mailpit_fixture_log_on_error now reads the fake Mailpit runtime log and emits it alongside reconciliation errors in three fixture tests.

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using GPT Sol𝕏

Comment thread crates/daemon/src/managed_resources/tests.rs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/ci.yml (1)

77-78: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Do not make a known-red macOS 26 lane required.

The PR context reports three unrelated Mailpit fixture-readiness timeouts on macOS 26, but this command runs the entire workspace in every matrix lane. The new diagnostics improve failure reporting but do not make those tests pass. Land the fixture fix first, or add a tracked temporary filter for only the affected tests.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 77 - 78, Update the macOS 26 CI matrix
configuration around the “Run tests” step so the known Mailpit fixture-readiness
timeout tests are temporarily excluded, or make that lane non-required. Keep
full workspace coverage for unaffected lanes and document the temporary scope
using the existing tracked CI configuration.
🧹 Nitpick comments (1)
.github/workflows/ci.yml (1)

18-20: 🩺 Stability & Availability | 🔵 Trivial

Plan for the macOS 14 runner retirement.

GitHub’s runner-image project says macOS 14 images began deprecation on July 6, 2026, and will be fully unsupported by November 2, 2026. This macos-14 lane will therefore lose hosted coverage of the macOS 14 support floor after November 2, 2026; move it to a supported or self-hosted runner, or document the replacement. (github.com)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 18 - 20, Update the “macOS 14 arm64”
workflow matrix entry to use a supported or self-hosted runner instead of
macos-14, and adjust macos_major to match the replacement; if retaining macOS 14
coverage is required, document the chosen replacement or support strategy in the
workflow.

Source: MCP tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In @.github/workflows/ci.yml:
- Around line 77-78: Update the macOS 26 CI matrix configuration around the “Run
tests” step so the known Mailpit fixture-readiness timeout tests are temporarily
excluded, or make that lane non-required. Keep full workspace coverage for
unaffected lanes and document the temporary scope using the existing tracked CI
configuration.

---

Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 18-20: Update the “macOS 14 arm64” workflow matrix entry to use a
supported or self-hosted runner instead of macos-14, and adjust macos_major to
match the replacement; if retaining macOS 14 coverage is required, document the
chosen replacement or support strategy in the workflow.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c9e7b3da-1db9-4a85-80ad-40a210c1f3c5

📥 Commits

Reviewing files that changed from the base of the PR and between 9358d51 and eb752a8.

📒 Files selected for processing (6)
  • .github/workflows/ci.yml
  • DESIGN.md
  • crates/cli/tests/php.rs
  • crates/daemon/src/managed_resources/tests.rs
  • crates/platform/src/listener/macos/kernel_table.rs
  • docs/superpowers/specs/2026-07-19-portable-platform-architecture-design.md
💤 Files with no reviewable changes (1)
  • crates/platform/src/listener/macos/kernel_table.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/superpowers/specs/2026-07-19-portable-platform-architecture-design.md

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — the two commits since the prior Pullfrog review make Mailpit fixture failures CI-compliant and remove threaded HTTP handling from the affected fixtures.

  • Returned Mailpit diagnostics through test errors — the three affected reconciliation tests now attach fixture logs to propagated anyhow::Error values instead of using denied direct stderr macros.
  • Serialized Mailpit HTTP fixture handlingmailpit.py and mailpit-fast-exit.py now use HTTPServer, while the full fixture preserves its separate SMTP serving and signal-shutdown threads.

Pullfrog  | View workflow run | Using GPT Sol𝕏

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f9040de2ca

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/ci.yml
Comment on lines +26 to +29
- name: macOS 26 arm64
runner: macos-26
macos_major: "26"
architecture: arm64

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Stabilize the macOS 26 lane before requiring it

When the newly added macOS 26 lane runs cargo nextest run --workspace --all-features --locked, this commit's own validation reports three Mailpit HTTP-readiness timeouts on that host. The fixture changes in this diff only add stderr diagnostics and error context—and still use ThreadingHTTPServer—so they do not resolve the reported failures; enabling this required lane therefore leaves PR and push CI red whenever those timeouts reproduce. Stabilize the affected tests before requiring this lane, or temporarily isolate the failing coverage.

Useful? React with 👍 / 👎.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — the latest commit restores concurrent Mailpit fixture handling while adding captured lifecycle evidence for the macOS 26 readiness investigation.

  • Restored threaded HTTP fixturesmailpit.py and mailpit-fast-exit.py again use ThreadingHTTPServer, whose daemon request threads preserve safe fixture shutdown while allowing readiness requests to complete independently.
  • Added fixture lifecycle tracing — both fixtures now record server construction, request receipt, and serve-loop entry in their captured process logs so hosted-runner failures identify where startup stalled.

Pullfrog  | View workflow run | Using GPT Sol𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — the latest commit removes reverse hostname lookups from loopback Python fixtures while preserving their server and shutdown contracts.

  • Bypassed fixture FQDN resolution — gateway, Mailpit, and RustFS HTTP fixtures now bind through TCPServer directly and initialize the HTTPServer address fields without calling socket.getfqdn.
  • Added a lookup-failure contract — the multi-server fixture test injects a failing socket.getfqdn while retaining readiness and signal-exit validation for Mailpit and RustFS fixtures.
  • Removed temporary lifecycle tracing — Mailpit fixtures drop the diagnostic request and startup prints added during the preceding hosted-runner investigation while preserving threaded request handling and response flushing.

Pullfrog  | View workflow run | Using GPT Sol𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — the latest commit extends the fixture FQDN lookup fix to the RustFS server embedded in release smoke tests without changing its runtime contract.

  • Extended the RustFS fixture bind fixpv-release smoke tests now bind their embedded HTTP server through TCPServer directly while preserving HTTPServer address fields, readiness, console binding, and shutdown behavior.

Pullfrog  | View workflow run | Using GPT Sol𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — the latest commit makes the bounded fake daemon’s accepted connections safe for newline-framed protocol I/O on platforms where they inherit the listener’s nonblocking mode.

  • Restored blocking accepted streamsFakeDaemon::start_until_idle now keeps nonblocking mode limited to accept polling and switches each accepted UnixStream back to blocking mode before reading requests and writing responses.

Pullfrog  | View workflow run | Using GPT Sol𝕏

@munezaclovis
munezaclovis merged commit d5e4532 into main Jul 29, 2026
8 checks passed
@munezaclovis
munezaclovis deleted the agent/macos-14-listener-cutover branch July 29, 2026 03:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant