Skip to content

feat(mac): run verified model profiles through a private runner - #354

Open
kesslerio wants to merge 9 commits into
MiaAI-Lab:mainfrom
kesslerio:upstream/mac-runtime-profiles
Open

kesslerio wants to merge 9 commits into
MiaAI-Lab:mainfrom
kesslerio:upstream/mac-runtime-profiles

Conversation

@kesslerio

Copy link
Copy Markdown
Contributor

Stacked on #277 — @MiaAI-Lab, this branch is 589606b (#277's head) plus one commit, 8f74993. Review that commit; #277 needs to merge first.

What it adds

The Mac agent could collect telemetry but not switch models. This adds a private current-user runner that owns the single heavy-model slot: it validates binaries and cached paths before stopping the current engine, waits for its processes and listeners to disappear, detaches the selected profile, verifies the exact API model ID, and runs an optional warmup. A failed launch reports its error and cleans its own tree instead of restoring a different model.

Profiles carry their own start argv and optional health check, so a target can serve several models; an ambiguous command is refused rather than guessed. Control actions return HTTP202 and poll a read-only operation snapshot, so a closed dashboard connection never implies the engine stopped, and polling never replays an action. The control token comes from the environment or an owner-only file, never reaches the browser, and status reads execute nothing.

Agent-backed Macs get the Models panel catalog and a bounded-output viewer; SSH hosts keep the script path. Documentation is in agents/macos/README.md.

#277's guarantees are intact: the agent fetch and the /control proxy each resolve once and pin the connection to those checked addresses, and the strict inventory probes and authorized status reads are unchanged.

Verification

  • Targeted Mac/agent/ssh/validate suites: 108 pass; alerts and sparks suites: 325 pass; MacRuntimeControl plus MacAgentCollector: 41 pass.
  • npm run test:server: 1467 pass / 44 fail / 16 skipped, with the same failure names as untouched 589606b (gpuclock systemd/sudo/cron, BSD tail --pid, missing uv).
  • Full frontend: 855 pass. tsc --noEmit clean, i18n check passes.
  • python3 -m unittest discover -s agents/macos/tests: 96 tests, 8 failures in test_privileged_service_lifecycle (launchctl/sudo on this non-macOS host, identical at baseline).
  • python3 tests/test_profile_runner.py: 49 pass.

Risk

Runtime actions are privileged, so this sits in the same sign-off queue as #277. Merging installs nothing: the runner is a current-user process, the agent stays optional, and root collectors remain read-only.

kesslerio and others added 9 commits November 1, 2026 11:14
When powermetrics is unavailable the collectors published usage: 0,
power.draw: 0 and systemDraw: 0 while the poll still counted as successful,
so a non-root Mac dragged fleet watts and Wh/token down as if measured.

Publish null for unread GPU usage/power and CPU usage/draw, keep the
metricAvailability flags, and make fleet energy require available, finite
readings rather than a non-zero vram.total. Keep the agent's own unavailable
list on RAM and unified memory. Validate the Mac agent URL/host/port where it
is saved (not only in the collector constructor), compare the runtime control
token with hmac.compare_digest, and pin the powermetrics sudoers rule to the
exact argv the collector runs.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
The control proxy checked the agent's address policy and then let the
fetch resolve the hostname again, so the authorized target and the
connected socket were two separate DNS answers. Resolve once, hand the
checked addresses to the connection, and read the response body while
that pinned dispatcher is still open.
The rebase kept main's host-only RAM condition while keeping the comment
that promised RAM when a Mac's unified pool is unknown, so an agent
without memory readings showed neither panel. Restore the PR's Mac branch
of that condition.
The agent's nullable cpu/gpu temperature landed after main's kiosk page
was written, and the kiosk still compared those fields as plain numbers,
so an unread reading typed as a number and could be treated as 0. Leave
the figure unknown and cover both the card and the fleet maximum.
The Mac agent could collect telemetry but not switch models safely. Add a
private current-user runner that owns the single heavy-model slot: validate
binaries and cached paths before stopping the current engine, wait for its
processes and listeners to disappear, detach the selected profile, and verify
its exact API model ID, with optional warmup. A failed launch reports an error
and cleans its own tree instead of restoring a different model.

Profile-specific `start` argv and `health` checks let a target serve several
models, and an ambiguous command is refused rather than guessed. Control
actions return HTTP202 and poll a read-only operation snapshot, so closing the
dashboard connection does not imply the engine stopped; output stays bounded
and the token file is served without ever reaching the browser.

Agent-backed Macs get the Models panel catalog and the output viewer; SSH hosts
keep the script path. Tests cover the runner, control serialization, operation
polling, token file safety and the viewer.
@MiaAI-Lab

Copy link
Copy Markdown
Owner

The agent's defaults are careful: loopback bind (DEFAULT_HOST = 127.0.0.1), token from a 0600 non-symlink file, status GETs that never execute, control POSTs token-checked. Because this adds authenticated remote command execution on the Mac (model start/stop via the agent) and a new server→agent trust path, it deserves a maintainer-led security pass rather than a drive-by merge — in particular whether the token comparison is constant-time and whether the server validates the agent URL like its other fetch targets (server/validate.js). The scope (4.2k lines, new agent, launcher UI) also wants staging. Not merging from my side; leaving open with those as the review items.

(Review notes prepared with Claude Code on behalf of the maintainer.)

@kesslerio

Copy link
Copy Markdown
Contributor Author

@MiaAI-Lab autoreview is clean on 8f74993 (scoped-clean, patch correct at 0.94, no P0 findings). Ready to merge when you are.

This is stacked on #277, so merging it lands #277's commits as well; #277 can be closed as superseded once this goes in. I can do the John deployment right after the merge lands.

MiaAI-Lab added a commit that referenced this pull request Nov 4, 2026
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
MiaAI-Lab added a commit that referenced this pull request Nov 4, 2026
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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.

2 participants