Skip to content

perf(acpmux): track only live process slots for idle census (SW-11) - #30712

Merged
teamleaderleo merged 2 commits into
feat-cmux-nextfrom
sw11/active-background-process-ids
Nov 2, 2026
Merged

teamleaderleo merged 2 commits into
feat-cmux-nextfrom
sw11/active-background-process-ids

Conversation

@teamleaderleo

Copy link
Copy Markdown
Collaborator

SW-11: keep an ordered set of live background processes for idle checks and host exit

Root cause

A daemon session's ProcessTable retains completed background-process history for its list/tail contract. The frequent running_processes_read census and any_process_running check still searched every retained entry to find active work; lose_running likewise scanned all entries whenever an agent host ended. At 3,000 historical processes with only 2 live tasks, idle checks did 3,000 status tests per request despite #29277's process-id and tool-call indexes.

Change

  • Add a per-session BTreeSet<usize> of running process slots. Slots refer to the existing append-ordered Vec<Process>; the process vector remains the authoritative record and keeps its original order.
  • Update the set on insert, live→terminal fold, replay/upsert (in either direction) and host exit. A new table reconstructed from its log rebuilds the active set automatically.
  • any_process_running now tests !running.is_empty(), and running_processes_read answers running.len(), both O(1) regardless of completed-history length.
  • lose_running visits only active slots, in original append order, preserving the order and content of emitted process_update notifications. No new background scan, timer, disk state or wire field.

Regression

The added Rust test module processes_active_tests.rs exercises 3,000 completed entries plus three live ones, out-of-order replay updates, live→completed→live transitions, lost-notification order and idempotent repeat host exits. Existing Claude/Codex hub_integration process tests remain the end-to-end contract.

Performance

No perf numbers: count/idle checks become O(1) reads instead of O(N) scans, and loss propagation visits only R live entries (BTreeSet lookup O(log R) when a state changes). The test verifies the 3,000-record scale and preserved identities, but same-host CPU/RSS/wakeup measurements have not run. The live index retains a small extra entry for each currently running process.

Validation and ownership

  • Source base: feat-cmux-next@fd34ef95aa2c8f741aa23da7789e0b564732087a, which already includes perf(acpmux): read background-process output sizes after releasing the session lock (SW-11) #29238 and perf(acpmux): index background process identities for 3,000-entry replay (SW-11) #29277. This PR extends their daemon-owned process table and does not modify any other SW-11 worktree.
  • Two Rust files, no protocol/API/UI change. Draft: unit test and Cargo/Clippy/fmt verification still need CI; no local Cargo available in the connected environment.
  • Run cd cmux-tui && cargo test -p acpmux --lib process_active_tests, cargo test -p acpmux --lib process_index_tests, cargo test -p acpmux --test hub_integration -- process, cargo fmt --check, Clippy and the NEXT fast-tier gate before marking ready. Compare base/head at 1/100/3,000 historical entries with 0/1/30 live processes.
  • Any lost-process ordering or hibernation-status regression blocks landing.

Capture

No capture: daemon-only bookkeeping with identical process-list and status responses.

Changelog: Background-process idle checks use a live set, avoiding full-history scans and ending only currently running processes on host exit.

SW-11: HQ investigation.

@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Nov 1, 2026

Copy link
Copy Markdown
Collaborator Author

SW-11 CI triage: api-compat failed on run 41296652137 with spec/api-compat.surface.json is stale. This daemon-only PR adds internal ProcessTable bookkeeping and a unit test, no public protocol or spec edits. The spec surface blob 30b68e08a37c80bb878684abc44aa3b3079f4bbd is identical at source base fd34ef... and PR head 097dd79.... This appears to be current base API snapshot drift; the required Rust unit/integration and format gates remain pending. Please keep the red visible for the API owner instead of changing generated public spec files in this performance PR.

@github-actions

github-actions Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review cd0e3bb: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr30712 -f ref=sw11/active-background-process-ids -f platform=macos -f backend_mode=local

web and size checks: green

Shipped in:

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Awareness note from an agent lane that does not own this PR; it is not a review or a request to take the PR over.


Taking this ChatGPT draft over for Leo's ask ask-e06a62154f (acpmux / mux-host batch): reviewing against current feat-cmux-next, then carrying it to land on a lane/ branch or closing it.

@teamleaderleo
teamleaderleo force-pushed the sw11/active-background-process-ids branch from 097dd79 to cd0e3bb Compare November 2, 2026 01:31
@blacksmith-sh

blacksmith-sh Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Found 14 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmp1_3tkeic/summary-fail.json (live):/summary-fail.json (live): View Logs
/tmp/tmpc6gblcmc/summary-missing.json (live):/summary-missing.json (live): View Logs
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows/
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows
View Logs
[new_workspaces] the window draws no frames/[new_workspaces] the window draws no frames View Logs
[tabs] debug.tab_switch timed 0 of 40 switches/
[tabs] debug.tab_switch timed 0 of 40 switches
View Logs
[tabs] the window draws no frames/[tabs] the window draws no frames View Logs
main.DeveloperIdAppTests.test_download_prints_the_active_profile_only/
test_download_prints_the_active_profile_only
View Logs
imported web bundle inputs are not routed:/imported web bundle inputs are not routed: View Logs
stubs: /System/Library/Frameworks/Security.framework/Versions/A/Security has no stub/
Security has no stub
View Logs
stubs: CoreFoundation.tbd: install-name /System/Library/Frameworks/
CoreFoundation.framework/Versions/A/CoreFoundation, missing 1: ['_CFRetain']/
CoreFoundation, missing 1: ['_CFRetain']
View Logs

...and 4 more test failures. View all on Blacksmith: run 41372930222, run 41372930013

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

@teamleaderleo
teamleaderleo marked this pull request as ready for review November 2, 2026 01:41
@teamleaderleo
teamleaderleo merged commit 5a0fd07 into feat-cmux-next Nov 2, 2026
128 of 135 checks passed
@teamleaderleo
teamleaderleo deleted the sw11/active-background-process-ids branch November 2, 2026 01:41
@lawrencecchen

Copy link
Copy Markdown
Contributor

For Leo (teamleaderleo): this PR made the Rust panic ratchet red on feat-cmux-next (acpmux clippy::indexing_slicing 687 > 686: processes.rs lose_running self.processes[index]). Fix: #31695 (get_mut; same behavior). Found by agent tip-fix-0200.

@lawrencecchen

Copy link
Copy Markdown
Contributor

Base red from this PR (author: Leo, teamleaderleo). ProcessTable::lose_running in cmux-tui/crates/acpmux/src/hub/processes.rs reads self.processes[index]. clippy::indexing_slicing counts that index, so the acpmux row of the Rust panic ratchet is 687 > baseline 686 on feat-cmux-next (fleet job 8a7a7b9e174ab282a858454d, hq run 41379993459). The broken cmux-tui Cargo.lock from #31462 hid it. #31697 changes it to self.processes.get_mut(index) and skips a slot with no row; the behavior is the same. The open carry #31539 has the same line, so it needs the same change before it lands.

lawrencecchen added a commit that referenced this pull request Nov 2, 2026
…ratchet indexing_slicing 687 > 686, #30712) (#31695)

#30712 (5a0fd07) ends each running process through self.processes[index], one
clippy::indexing_slicing hit over the acpmux baseline (687 > 686), so the Rust panic
ratchet is red on feat-cmux-next. It now reads the slot with get_mut and skips a slot with
no row; a running slot always names a row (ProcessTable::insert), so nothing changes.

Fleet panic step (cmux-tui-rust-check.sh panic): RED at origin/feat-cmux-next 34446e1.

Co-authored-by: cmux-bot[bot] <348531757+cmux-bot[bot]@users.noreply.github.com>
lawrencecchen added a commit that referenced this pull request Nov 2, 2026
…uspicious_open_options, #31462) (#31697)

* base red: cmux-tui Cargo.lock matches #31462's fs4 dependency

#31462 added `fs4.workspace = true` to crates/cmux-tui/Cargo.toml, but its
Cargo.lock change put "fs4" in the dependency list of cmux-server, not
cmux-tui. Every `--locked` cargo step on feat-cmux-next at 765d3c4
fails with "cannot update the lock file cmux-tui/Cargo.lock because
--locked was passed".

The lock here is what `cargo metadata --manifest-path cmux-tui/Cargo.toml`
writes (no hand edit): "fs4" moves from cmux-server to cmux-tui.

Red at d3aaa26: cargo metadata --locked --manifest-path cmux-tui/Cargo.toml
  -> error: cannot update the lock file ... because --locked was passed
Green on this commit: the same command exits 0.

(cherry picked from commit d59b646)

* base red: acpmux lose_running reads its slot without an index (panic ratchet indexing_slicing 687 > 686, #30712)

#30712 (5a0fd07) ends each running process through self.processes[index], one
clippy::indexing_slicing hit over the acpmux baseline (687 > 686), so the Rust panic
ratchet is red on feat-cmux-next. It now reads the slot with get_mut and skips a slot with
no row; a running slot always names a row (ProcessTable::insert), so nothing changes.

Fleet panic step (cmux-tui-rust-check.sh panic): RED at origin/feat-cmux-next 34446e1.

(cherry picked from commit 7bf145e)

* base red: plugin update lock opens without truncation (clippy suspicious_open_options, #31462)

#31462 (765d3c4) opens .plugin-update.lock with create(true) and no truncate
setting. clippy::suspicious_open_options is deny under -D warnings, so the Linux
clippy step of cmux-tui-rust-check.sh fails to compile cmux-tui (exit 101). The
broken Cargo.lock from the same PR hid it: every --locked step stopped before
clippy. The file only carries the advisory lock, so truncate(false) keeps what it
does today and says so.

Fleet clippy step (Linux) at 5fbcfca (lock + panic fix, before this commit):
RED, crates/cmux-tui/src/plugin_manager.rs:233:43 (hq run 41379993466).

* base red: acpmux process pages read rows without an index (panic ratchet indexing_slicing 696 > 686, #30726)

#30726 (fbaa7a5, "byte-bound background-process history with opt-in pages")
added ten clippy::indexing_slicing hits in acpmux hub/processes.rs: the page
window self.processes[start..end] in ProcessTable::page_snapshot and nine
serde_json indexes row["..."] in the too-large row of process_page_values.
With #31695 merged, acpmux is 696 > baseline 686, so the Rust panic ratchet
is red on feat-cmux-next.

The window is now processes.get(start..end): start is an ID's slot + 1 (at most
len) and end = min(start + limit, len), so the range is always in bounds and the
fallback never applies. The row fields use row.get(..), which serializes a
missing field as null, the same as an index on a missing key. The output does
not change. No baseline change and no allow.

Fleet panic step: RED at tip 7da73fe (indexing_slicing 697 > 686, hq run
41384159581) and at 4a94625 with the get_mut fix (696 > 686, hq run
41384159646, hits at processes.rs:327 and 384-388).

* Move the acpmux process pages fix (#30726) to its own PR

The lead asked for it in a separate PR (base-red/acpmux-process-pages-index).
This PR keeps only the truncate(false) Linux clippy fix for #31462.

This reverts commit 9b650d5.

---------

Co-authored-by: cmux-bot[bot] <348531757+cmux-bot[bot]@users.noreply.github.com>

This branch was previously deployed

1 inactive deployment
ci-routing-agent — cd0e3bbf Deployed Nov 2, 2026 by teamleaderleo via cmux-tui tree preflight #98341
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants