Skip to content

Read the port scan's process table from the kernel instead of ps - #15353

Merged
teamleaderleo merged 23 commits into
mainfrom
port-scan-no-ps
Sep 30, 2026
Merged

teamleaderleo merged 23 commits into
mainfrom
port-scan-no-ps

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Sep 28, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

The local port scanner still spawned /bin/ps: ps -t <ttys> for each panel scan (twice per scan) and ps -ax up to twice per agent scan. Agent scans repeat every 2 s while an agent runs and panel scans burst six times over 10 s after every shell command, so cmux forked ps dozens of times a minute, and endpoint security tools log every one of those execs. After this change the scanner spawns no subprocess at all. Together with #10277 (which replaced lsof), an idle agent goes from about 3 execs every 2 s to none.

KernelPortProcessTable answers both questions in process with the existing DarwinProcessEnumerator (the same proc_listallpids + proc_pidinfo/sysctl reader the Task Manager uses), so there is no new enumerator:

  • Terminal processes: stat each requested /dev/<tty> and match proc_bsdinfo.e_tdev. A terminal that no longer exists is authoritative emptiness (this replaces the ps vanished-TTY retry loop); one that exists but can't be inspected makes the answer incomplete.
  • Parents: pbi_ppid for every process, for agent process-tree expansion.

Completeness follows the PID list: DarwinProcessListing gains isTruncated, so a PID that exited between listing and reading (which can hold no port and parent nothing) no longer counts as missing evidence, while a truncated or unreadable list still does. PortScanner takes the reader through a PortProcessTableReading seam instead of CommandRunning.

This re-lands the ps half of #3801 by @TrevorBurnham on the current layout, reusing the codebase's process enumerator instead of adding a new sysctl(KERN_PROC_ALL) copy. Commits carry his Co-authored-by.

Stacked on #10277; until that merges this diff also shows its commits.

Testing

  • python3 scripts/verify-local.py passes (Swift syntax, pbxproj, test wiring, package groups). Nothing was compiled locally; CI compiles and runs the tests.
  • New KernelPortProcessTableTests cover the seams: a vanished TTY does not discard surviving panels, every TTY vanished is complete emptiness, an unreadable device is incomplete, /dev/ttysNNN names map back to the canonical name, truncated or empty listings are incomplete, a PID missing between list and read stays complete, NODEV processes are ignored, plus live checks against this test process and /dev/null.
  • New CmuxFoundation test that truncation is reported separately from missing processes.
  • The PortScanner fixtures that stubbed ps output now return process mappings directly; the ps output-parsing tests (malformed rows, stderr diagnostics, retry budget, timeout) are removed with the code they tested.
  • Dogfood (spawn counts with an agent running, sidebar port 8123 appearing and retiring) requested on a fleet build.

Changelog

Changed: The sidebar port scan no longer spawns ps or lsof; it reads processes and listening ports directly from the kernel

Checklist

  • Behavior changes have added or updated tests, or Testing says why not
  • Reviewed with a subagent before merge (cmux-review), and all bot and human review comments resolved

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Summary by cubic

Replaces the port scanner's ps and lsof calls with direct kernel reads, so a scan spawns no subprocesses. Panel scans previously forked ps -t twice each, agent scans forked ps -ax up to twice every two seconds, and the listening-port lookup forked lsof; endpoint security tools log every exec. An idle agent goes from several forks every two seconds to none.

KernelPortProcessTable answers process questions through the existing DarwinProcessEnumerator: terminal processes by matching proc_bsdinfo.e_tdev against a stat of each requested /dev/<tty>, parents from pbi_ppid. A vanished terminal is authoritative emptiness (replacing the old ps retry loop); one that exists but can't be inspected makes the scan incomplete. ListeningPortLookup reads each PID's listening TCP sockets from the kernel through libproc, cutting a scan from ~200ms to under 7ms.

  • PortScanner now takes both readers through seams instead of CommandRunning.
  • DarwinProcessListing gains isTruncated, so a PID that exits between listing and reading no longer counts as missing evidence; only a truncated or unreadable PID list does.
  • Local scans now stop when the ports detail is hidden, matching the remote rule from issue Remote SSH port polling causes Broken pipe on cmux socket across stable and nightly #6123; hiding it clears published ports and fences off in-flight and queued scans. Showing it again rescans every registered panel once.
  • None required; the scanner's public behavior is unchanged.

Written for commit 65f437c. Summary will update on new commits.

Review in cubic

hyzyla and others added 6 commits August 17, 2026 19:26
The batched port scan ran `lsof -nP -a -p <pids> -iTCP -sTCP:LISTEN -Fpn`
every two seconds. Before lsof answers it calls close() on every descriptor
number up to `kern.maxfilesperproc`, which is 138,240 on current macOS, and
it forks a child that repeats the sweep. That is far more work than the
lookup itself, and it repeats for the life of the app.

`ListeningPortLookup` asks the kernel directly through libproc
(PROC_PIDLISTFDS + PROC_PIDFDSOCKETINFO) and keeps only TCP sockets in
TSI_S_LISTEN. Measured against lsof over 483 PIDs the results are identical,
and one scan drops from 200ms to under 7ms.

Completeness semantics are unchanged: a PID we may not read is a miss only
when its identity is also unreadable while it is still present, so a panel
behind the root `login` process can still retire its ports.
Remote port scanning already follows `sidebar.showPorts` (issue #6123), but
the local scanner kept running its two-second sweep no matter what. Nothing
displays or reports the result while the detail is hidden, so the work is
pure cost.

`SidebarWorkspaceDetailDefaults.portScanningEnabled` now holds the one rule
both paths read, and `TabManager` pushes changes to the local scanner
alongside the remote sessions it already updates.

Note this also blanks `listeningPorts` for local workspaces in the control
socket and CLI summaries while ports are hidden, which is the same trade
remote workspaces already make.
Resolves conflicts with the cancellable burst lifecycle (#11109) and the
lsof PID chunking that came with it: the kernel lookup has no argv, so the
chunking and its test go away, and PortLsofScanResult keeps its new name
PortListenerScanResult at the call sites main added. The end-to-end
retirement tests keep main's compressed burst schedule and its late-burst
stop, now triggered from the fifth listener lookup instead of the fifth
lsof call.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Hiding the ports detail now also invalidates a burst that is already
running, the same way unregistering the last panel does, so its remaining
timers never scan. Showing it again rescans every registered panel once,
since ports that opened or closed while hidden were never seen and an idle
panel would otherwise keep a stale list until its next command.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Hiding the ports detail now publishes no ports for every tracked panel
  and agent workspace, so the socket, CLI, custom sidebars and the command
  palette (which read published ports without the sidebar's visibility
  gate) don't keep a list frozen at the moment scanning stopped. A fresh
  agent request ID fences off any scan still in flight.
- A queued follow-up panel or agent scan no longer runs after scanning is
  turned off; a dropped agent request clears its in-flight mark.
- PortScannerPublicationTests fed ports through a fake lsof, which the
  scanner no longer calls. Both runners now supply ports through
  listeningPortsProvider, and the churn test counts per-PID lookups instead
  of lsof argv lists.
- Test for the cleared list; normalize the pbxproj; drop stale lsof
  wording from two doc comments.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Fixes the CI compile error in the previous commit: remove(keys:) takes a
Set, not an Array.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@teamleaderleo teamleaderleo added the full-ci EXPENSIVE: full macOS tests/builds; overrides selective PR routing. Not needed for normal checks. label Sep 28, 2026
@github-actions

github-actions Bot commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@coderabbitai

coderabbitai Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 5 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 10 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Repository: manaflow-ai/cmux/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 8f8adbd9-f392-40d3-9d9d-be98604eb6a6

📥 Commits

Reviewing files that changed from the base of the PR and between 8b011ad and 65f437c.

📒 Files selected for processing (14)
  • Packages/macOS/CmuxFoundation/Sources/CmuxFoundation/Process/DarwinProcessEnumerator.swift
  • Packages/macOS/CmuxFoundation/Sources/CmuxFoundation/Process/DarwinProcessListing.swift
  • Packages/macOS/CmuxFoundation/Tests/CmuxFoundationTests/DarwinResourceSamplingTests.swift
  • Sources/KernelPortProcessTable.swift
  • Sources/PortProcessTableReading.swift
  • Sources/PortScanner+Process.swift
  • Sources/PortScanner.swift
  • Sources/PortTerminalDeviceLookup.swift
  • cmux.xcodeproj/project.pbxproj
  • cmuxTests/KernelPortProcessTableTests.swift
  • cmuxTests/PortScannerIdentityContinuityTests.swift
  • cmuxTests/PortScannerPublicationTests.swift
  • cmuxTests/PortScannerTests.swift
  • scripts/localization-allowed-omissions.json
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


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.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Cross-model review (Codex gpt-5.6-sol)

  • Sources/ListeningPortLookup.swift:29-53 — a second PROC_PIDLISTFDS read that fills the supplied buffer is silently treated as complete. Darwin truncates at buffer capacity and returns exactly that byte count; if a process grows by more than the combined sizing/+32 headroom between calls, a live listening FD can be omitted. PortScanner+Process.swift:457-484 then marks the PID authoritative, and three such misses retire the still-live port. Retry with a larger buffer whenever written >= buffer.count under a bounded growth policy; if the bound is exhausted, propagate an explicit incomplete PID instead of negative evidence. Add an injected two-call growth test covering truncation beyond the combined margin.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review: correctness pass by a review subagent on a0090bc (this PR's own commit; the #10277 commits underneath were reviewed there).

No correctness or compile blockers found. Checked: stat/S_IFCHR/st_rdev usage matches existing call sites, e_tdev is UInt32 with NODEV filtered, bare and /dev/ names both canonicalize, an absent TTY is complete emptiness and an unreadable one is incomplete, and a PID missing between listing and reading is safe to treat as gone (the reader falls back to public sysctl for any live process). Existing DarwinProcessListing callers compile unchanged and CmuxTop only reads isComplete. The fixture conversions keep each test's intent, and no references to the removed ps helpers remain.

Fixed (491e0ab):

  • isTruncated was a public var; it is now a let set through an internal initializer that defaults it, so hand-built listings still compile and consumers can't flip it.
  • The doc comment claimed scans never overlap. A panel scan makes up to four enumerations and can overlap an agent scan; the comment now says so. Still far cheaper than forking ps.

Left:

  • The full-path TTY end-to-end test's fixture canonicalizes names itself, so the real reader's /dev/ mapping is covered by KernelPortProcessTableTests instead. Fine.
  • Optional later: answer terminal queries with proc_listpids(PROC_TTY_ONLY, dev) to skip the per-PID reads. Not needed now.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review: The follow-up review checked process-list truncation semantics and scan concurrency documentation. Fixed: DarwinProcessListing.isTruncated is read-only and initialized explicitly, and the KernelPortProcessTable concurrency note now accurately describes up to four panel enumerations and overlap with an agent scan. Left: No known review issues.

teamleaderleo and others added 3 commits September 30, 2026 01:00
PortScanner still spawned /bin/ps for every panel scan (ps -t) and up to
twice per agent scan (ps -ax), which repeats every two seconds while an
agent runs. Each of those execs is a fork that endpoint security tools
log. The scanner now asks the kernel directly and spawns no subprocess.

KernelPortProcessTable answers both questions with one
DarwinProcessEnumerator capture per call: terminal processes by matching
e_tdev against a stat of each requested /dev entry, and parents from
pbi_ppid. A terminal that no longer exists is dropped as authoritative
emptiness, replacing the ps vanished-TTY retry loop; one that exists but
cannot be inspected makes the answer incomplete. PortScanner takes the
reader through a PortProcessTableReading seam instead of CommandRunning.

DarwinProcessListing gains isTruncated so callers can tell a truncated
PID list from a listed PID that exited before it was read. Only the
first leaves a port scan incomplete.

The ps output parsing tests are replaced by KernelPortProcessTable tests
through its seams, and the PortScanner fixtures return process mappings
directly.

Co-authored-by: Trevor Burnham <trevorburnham@gmail.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
DarwinProcessListing.isTruncated is now a let set through an explicit
internal initializer that defaults it, so hand-built listings still compile
and consumers can't flip it. The KernelPortProcessTable doc comment now
says a panel scan makes up to four enumerations and can overlap an agent
scan, instead of claiming scans never overlap.

Co-authored-by: Trevor Burnham <trevorburnham@gmail.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Catch-up merge by scripts/ci/catch_up_pr.py (RFC #14631).

Merged by scripts/merge-main.sh: origin/main at 02dac3c.

Catch-up-previous-head: be248820ebea4b0e1375218e722dc27d3920531d5

Catch-up-base: 02dac3c

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
teamleaderleo and others added 3 commits September 30, 2026 01:37
Catch-up merge by scripts/ci/catch_up_pr.py (RFC #14631).

Merged by scripts/merge-main.sh: origin/main at 7f27bfc.

Catch-up-previous-head: d55a345

Catch-up-base: 7f27bfc1fe5f8f84f3d0f3d59180d4d0ec1f00a8

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Catch-up merge by scripts/ci/catch_up_pr.py (RFC #14631).

Merged by scripts/merge-main.sh: origin/main at 0fc35d6.

Catch-up-previous-head: 55bd64c

Catch-up-base: 0fc35d6

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Catch-up merge by scripts/ci/catch_up_pr.py (RFC #14631).

Merged by scripts/merge-main.sh: origin/main at 8b75678.

Catch-up-previous-head: 0b8e70c

Catch-up-base: 8b75678

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

/catch-up

Catch-up merge by scripts/ci/catch_up_pr.py (RFC #14631).
Requested by teamleaderleo on pull request #15353.

Resolved conflicts:
- cmux.xcodeproj/project.pbxproj: union of added entries, then normalize-pbxproj.py

Catch-up-previous-head: 89b3db8
Catch-up-base: 572beb6
@github-actions

Copy link
Copy Markdown
Contributor

Caught port-scan-no-ps up with main (572beb691901) in f5a7d5c0a86e.

Resolved:

  • cmux.xcodeproj/project.pbxproj: union of added entries, then normalize-pbxproj.py

This push used the Actions token, so CI will not start on its own. Push any commit (or close and reopen) to get checks on the new head.

Catch-up run · RFC #14631

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Heads up, I ran /catch-up here because the PR was conflicting and the merge train could not move it. Two consequences worth knowing.

The head is now f5a7d5c0a86 and the PR is MERGEABLE again, so any SHA-pinned CI wait on the previous head is now waiting on a superseded commit and will sit there until it times out. If you have a glaeda-gh wait ... --sha <old> running, restart it on f5a7d5c0a86.

Second, do not read the current green as a verified head. The rollup says SUCCESS but there are only 7 contexts on f5a7d5c0a86, against roughly 45 on the previous head. The catch-up merge commit is authored and committed by github-actions[bot], which is the usual reason a caught-up head ends up with little or no pull_request CI. Nothing is failing, but almost nothing has run either, and an absent signal renders the same as a passing one. This needs a real run before it merges.

Catch-up resolved cmux.xcodeproj/project.pbxproj among others, so it is worth confirming the project file is still sorted (python3 scripts/normalize-pbxproj.py) before you push anything on top, since worktrees skip the pre-commit hook.

Not taking this PR over, it is clearly yours and moving. I only unblocked the conflict.

— Raindrop g2 🫧 / Run: run_worker_20260930_3fc64ba6

The automated catch-up merge did not emit the normal pull-request check suite.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

CI failure attribution

CI stopped on 36e0a540cf (run 36762985316 attempt 1): 1 unknown.

Job Verdict Why
guards / workflow-guard-tests / ci unknown no known signature; failed step: Run canonical CMUX CI guard profile

Not re-run automatically: guards / workflow-guard-tests / ci is not a machine failure.

Written by scripts/ci/classify_failures.py (ci-failure-attribution.yml); signatures are its SIGNATURES table. A machine verdict is the runner's fault, not this PR's.

@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Dogfood tours of 7aa11a7c

sidebar-and-chrome-tour at 7aa11a7c: not run

skipped: CI built this head on a runner pool whose products the UI test Macs cannot load, and media never compiles one; gh workflow run pr-media.yml -f pr=&lt;n&gt; -f allow_compile=true does

Tours are picked by the paths globs in dogfood/scenarios/*.json; a Dogfood-tours: a, b line in the description picks them instead (none turns this off). Look at every frame before merging: a green tour only means no step failed.

Catch-up merge by scripts/ci/catch_up_pr.py (RFC #14631).

Merged by scripts/merge-main.sh: origin/main at 6d7ad14.

Catch-up-previous-head: c522541

Catch-up-base: 6d7ad14

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review: independent correctness pass on port-scan-no-ps @ 7aa11a7c48c8

Engineering verdict is favourable. The one blocking item is merge order, not code.

Blocking: land #10277 first. This PR is not merely related to #10277, it contains it. 0635186cde3d (10277's head) is an ancestor of 7aa11a7c48c8, and two files plus one hunk are byte-identical to hyzyla's work:

  • Sources/ListeningPortLookup.swift (all 76 lines)
  • Sources/PortListenerScanResult.swift
  • the portScanningEnabled addition in Sources/CmuxSettingsJSONPathSupport.swift

The repo is squash-only (allow_rebase_merge: false). Squashing this PR collapses hyzyla's f6adb62410d and c26a551cff7 into one commit authored by this PR's author, so his name survives as body text but not as commit authorship and never shows in git log --author. At the same moment #10277 becomes fully duplicated by main and can only be closed unmerged: an outside contributor's PR closed with his code shipped under someone else's name.

Safe sequence: merge #10277, then merge main into this branch keeping main's copy of those three identical files, then land this. The body does say "Stacked on #10277", so the author knows. The risk is whoever presses the button not knowing.

The ps equivalence claim holds, and better than the body claims. I checked against Apple's adv_cmds/ps/ps.c rather than the man page. ps.c:720 compares kp_eproc.e_tdev against a ttylist built by stat()ing /dev/<elem> and taking st_rdev for char devices, which is exactly what KernelPortProcessTable.resolveTerminalDevice does against proc_bsdinfo.e_tdev. Same field, same comparison. The three divergences I expected to find are all refuted:

  • uid filtering: -t sets nselectors++, skipping the default-uid block at ps.c:533-540. ps -t never filtered by uid. Neither does the kernel read.
  • zombies and no-tty processes: -t sets xkeep_implied = 1, skipping the xkeep == 0 filter at ps.c:681-690. Both sides keep zombies that still carry the tty.
  • pid 0: excluded both sides (ps.c:~653, and KernelPortProcessTable.swift:86,97).

Process names are irrelevant here: the old invocation was -o pid=,tty= and reads no names.

Error handling is the strongest part. coversEveryProcess treating an empty listing as failure rather than "no matches" is the right call, since the reader is always in its own PID list, so empty is impossible in a live process. No path turns a kernel failure into a confident empty answer, and there is no silent fallback to ps.

Worth fixing before merge

M1, two lines of test away. KernelPortProcessTable.swift:118-119 can be changed from return .unreadable to return .absent in the default: arm and nothing fails. No test drives resolveTerminalDevice to a non-ENOENT/ENOTDIR errno: the live tests use /dev/null (readable char device) and /dev/fd (directory, so ENOTDIR), and every .unreadable case arrives through the injected terminalDevice seam, which bypasses resolveTerminalDevice entirely. A terminal the user cannot stat would then report .complete on a scan that saw none of its processes.

Worth knowing, not blocking

The process table is no longer an atomic snapshot, and the equivalence framing does not mention it. ps -ax was one sysctl(KERN_PROC_ALL); this is proc_listallpids plus up to 2N per-PID calls. A process reaped mid-walk is dropped by DarwinProcessInfoReader.processHasExited without setting isTruncated, so parentsByPID() can name a parent PID the map does not contain while still reporting .complete. With PortScanner+Process.swift:65 mapping .complete straight to .complete evidence, a mid-tree reap can break an agent subtree and retire a live port for one cycle. Self-healing next scan, and the old ps+lsof pipeline had its own races, so not blocking. It is the one behavioural regression.

ListeningPortLookup has no direct unit tests, and it is the riskiest code in the stack: two-pass PROC_PIDLISTFDS sizing with a 32-entry headroom, a guard read == expected check, raw socket_fdinfo decoding. It is reached only through PortScanner's injected provider seam, so always faked, while KernelPortProcessTable got 11 tests including two live-kernel ones. hyzyla's file, so the gap predates this PR, but this is what ships it.

Smaller: PortScanner.swift:62 initialises scanningEnabled from UserDefaults.standard in a property initialiser with no init parameter, unlike processTable and listeningPortsProvider which both got one. And runTrackedAgentScan() at :770 is the only one of the four scan sites missing the scanningEnabled guard its siblings at :749 and :794 have. Harmless today (the timer is cancelled and publication is fenced by the request-ID bump), just asymmetric.

Verification honesty

None of the above was executed. This host is Linux with Swift 6.1.3 and no xcodebuild, and app builds are off the table, so every mutant is a static finding: "no test appears to cover this", not "proven to survive". What did run: scripts/verify-local.py in a detached worktree at 7aa11a7c48c8 (6/6 selected checks passed, with its own caveat that native compilation and app tests were not checked), the pbxproj membership checks confirming all four new files are wired, and an em-dash sweep that came back clean across all seven changed files.

Prose and platform guards are clean. CmuxFoundation declares platforms: [.macOS(.v14)] and the new files are macOS-only by target membership, so the unguarded proc_pidinfo/stat/SOCKINFO_TCP use is fine.

— Raindrop g2 🫧 / Run: run_worker_20260930_3fc64ba6

teamleaderleo and others added 2 commits September 30, 2026 12:02
Resolve the port scanner and project conflicts while retaining the kernel process-table implementation.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Reconcile cmuxTests target membership introduced by the main catch-up merge.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

CI fast guards failed on 36e0a540cf (https://github.com/manaflow-ai/cmux/actions/runs/36762984766). It does not block the merge; a red guard merged into main breaks it for every open PR.

Run canonical CMUX CI guard profile (red on main too, not this PR)

Main has failed this step since #16150 by @teamleaderleo (self-merged) (#16162). Merge main again once the fix lands there.

Agents: python3 scripts/ci/guard_attribution.py fix applies the mechanical fixes locally. This comment is updated in place on each push.

Keep main project entries while restoring the kernel port scanner sources and tests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@teamleaderleo
teamleaderleo marked this pull request as ready for review September 30, 2026 19:20
@cursor

cursor Bot commented Sep 30, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

teamleaderleo and others added 5 commits September 30, 2026 12:22
Catch up the ready PR to the current main tip without changing the kernel scanner implementation.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Merge-main commit by scripts/merge-main.sh.
Merged by scripts/merge-main.sh: origin/main at ef0d444.

Merge-main-previous-head: 8852ced
Merge-main-base: ef0d444
Merge-main commit by scripts/merge-main.sh.
Merged by scripts/merge-main.sh: origin/main at 8b011ad.

Resolved conflicts:
- cmux.xcodeproj/project.pbxproj: union of added entries, then normalize-pbxproj.py

Merge-main-previous-head: 4921d72
Merge-main-base: 8b011ad
@cursor

cursor Bot commented Sep 30, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@teamleaderleo
teamleaderleo enabled auto-merge (squash) September 30, 2026 20:06
@teamleaderleo
teamleaderleo merged commit 89c936c into main Sep 30, 2026
24 checks passed
@teamleaderleo
teamleaderleo deleted the port-scan-no-ps branch September 30, 2026 20:08
@github-actions

Copy link
Copy Markdown
Contributor

Merge receipt for 65f437c4d8, merged 2026-09-30 20:08:29 UTC

  • Not verified at merge: ci-status (not reported), CI fast guards (in progress), Fast static checks (in progress)
  • Verified: detect-ios-changes, ios-tests, package-conventions-lint, runner, Testbox broker trust boundary, Web complexity, web-validation
  • Skipped by policy: ios-simulator, ios-simulator-build, mobile-core-package, web-build, web-database-tests, web-tests
  • Full suite: runs on main after merge.

Labeled merged-unverified: if main breaks near this merge, look here first.

@github-actions github-actions Bot added the merged-unverified A judging check was not green at merge; see the merge receipt comment label Sep 30, 2026
austinywang added a commit that referenced this pull request Sep 30, 2026
#15353 rewrote the late-burst test's fixture again, now reading the
process table from the kernel too, and kept the fifth-lookup trigger and
so its race. cmuxTests/PortScannerTests.swift resolves to main's version
with this branch's change ported onto it: the per-lookup hook
perform(atListenerLookup:stopsListening:_:), a kick from inside the
second port lookup, and the lookup count in the failure message.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

full-ci EXPENSIVE: full macOS tests/builds; overrides selective PR routing. Not needed for normal checks. merged-unverified A judging check was not green at merge; see the merge receipt comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants