Engineering handbook

Take your cloud Mac from provisioning to repeatable runs

Start with the essentials, not the theory. Verify your order and node details, then configure access credentials, Xcode, CI, and MLX inference. Each guide lays out the checks, success criteria, and diagnostic details to keep.

Service type
Dedicated physical Mac, not a VM
Setup time
About 4 minutes
Availability
Runs 365 days a year
Node checklist First-run checklist
4 checks
01
Order & node Model, region, term, and add-ons match
Verify
02
Access credentials Update right after first connection; store securely
Update
03
Development toolchain Check macOS, Xcode, and CLI tool versions
Verify
04
Network & workspace Check connectivity, free space, and task directory permissions
Ready
Success criteria Connect, build, and reproduce
First-time setup

Four-minute setup checklist

Start the timer after confirming your order. Availability is based on the live status shown in the console. If any step is missing information, don’t move on to the next one.

  1. 01
    Verify your order About 45 seconds

    Check that the model, node region, rental term, and add-ons match your plan. The base configuration is M4, 16GB, 256GB; the high-memory configuration is M4 Pro, 64GB, 2TB. If anything doesn’t match, stop and submit a support ticket before proceeding.

    • Note the order number and node region.
    • Confirm whether you need SSD expansion or Thunderbolt 5 daisy-chaining.
  2. 02
    Get your node details About 2 minutes

    Wait for automatic assignment and system checks to finish, then find the node address and connection details in the console. Don’t share connection details in public channels or store plaintext credentials in a code repository.

    • Check that the address matches the region on your order.
    • Store the initial details in a credential manager approved by your team.
  3. 03
    Update access credentials About 1 minute

    Update your credentials as soon as you connect for the first time, and set up a separate key for automation. Keep interactive and CI runner accounts separate so scripts don’t get unnecessary system privileges.

    • Change the initial password and verify the new credentials work.
    • Set up a key for command-line access and verify the host fingerprint.
  4. 04
    Verify system & network About 15 seconds

    Record the macOS and Xcode versions. Check the default route, DNS resolution, available disk space, and write access to the workspace. Then run a small build or inference request to confirm the environment returns a verifiable result.

Development environment

Set a baseline for Xcode and code signing

Repeatable builds need consistent versions, an accessible Keychain, and the right command-line tools. Don’t treat opening a project in the GUI as a substitute for command-line checks.

Setup sequence

  1. 01
    Check your Xcode version

    Record the full version and build number. Check that the required SDKs, simulator runtimes, and minimum OS version are available.

  2. 02
    Import certificates & provisioning profiles

    Import only what the current project needs. Include the project and purpose in each name so others can identify its origin when handing it off.

  3. 03
    Check Keychain permissions

    Verify that the private key is readable by the target runner account. Test non-interactive signing before automating builds to keep jobs from getting stuck at a permission prompt.

  4. 04
    Select command-line tools

    Make sure the selected tools point to the intended Xcode, and record the selection in the project environment notes. After switching versions, rerun dependency and signing checks.

  5. 05
    Validate your first build

    Clean up old artifacts, then run tests, archive, and verify signing. Keep the command, exit code, log path, and checksum of the final artifact.

Continuous integration

Treat your runner as a dedicated resource, not a temporary workspace

A dedicated physical Mac gives you consistent hardware, but jobs can still fail because of cache contamination, excessive concurrency, or missing logs. Define workspace and cleanup responsibilities before connecting it.

01

Install a self-hosted runner

Create a dedicated system account and service directory for the runner, with only the permissions needed to build. After registration, run a small unsigned job to check the queue, network, and exit status.

Success: automatically resumes accepting jobs after a restart
02

Plan your workspace

Keep source checkouts, dependency caches, temporary builds, archives, and long-term logs separate. Clean up only temporary directories when a job ends; don’t remove shared caches needed by the next job.

Success: directory ownership and cleanup rules are clear
03

Set concurrency limits

Establish memory, disk, and runtime baselines with one job, then increase concurrency gradually. When Xcode builds and MLX inference run together, monitor peak memory and disk writes separately.

Success: no swapping or running out of disk space at peak load
04

Keep evidence of failures

For each failed job, keep its job ID, commit, runner version, start time, exit code, key logs, and artifact path. Remove tokens and signing materials before uploading logs.

Success: another team member can reproduce the issue independently
Cache cleanup boundaries

Use cache keys based on project, branch, and tool version where possible. Don’t rely on scheduled full-disk deletion to manage capacity; first make sure no builds or archives are running.

AI & MLX

Make inference services testable, observable, and recoverable

Get a single request working before increasing context length or concurrency. Keep model files, runtime environments, and service logs separate so dependency updates don’t disrupt models.

MLX service checklist Start with a single-request baseline
Apple Silicon
Isolated environment
Give each service its own Python environment, pin dependency versions, and save the installation manifest.
Model directory
Keep model files separate from source. Record the model name, quantization format, checksum, and disk usage.
Listening interfaces
Listen only on the interfaces and addresses the task requires. Don’t expose debug endpoints to unrelated networks.
Concurrency testing
Test 1, 2, then 4 concurrent requests. Record time to first token, total duration, failure rate, and peak memory.
Memory monitoring
Track model residency, context growth, and request caches separately. Stop increasing load before reaching the stable memory limit.
Restart strategy
Add the startup command, working directory, environment variables, and log path to the service configuration. Verify recovery after an unexpected exit.
Storage & daisy-chaining

Choose storage based on your working set, not your project name

Estimate peak usage across source, dependencies, models, build artifacts, logs, and temporary files, then leave room for cleanup and rollback. Base SSD capacity depends on the model you choose.

ArmMesh M4

256GB base SSD

A good fit for code checkouts, typical dependency caches, single-project builds, and short release cycles. Check peak usage first if you need large models, multiple Xcode runtimes, or lots of video assets.

ArmMesh M4 Pro

2TB base SSD

A good fit for larger model repositories, long-lived build caches, parallel projects, and audio/video exports. Fixed capacity doesn’t replace cleanup policies; set retention periods for logs and artifacts.

Storage and Thunderbolt 5 add-on prices, billed in USD
Add-on Daily Weekly Monthly Quarterly When to use
+1TB SSD $2.4 $6.4 $11.9 $32.4 For dependency caches, build archives, or mid-sized models that exceed base capacity.
+2TB SSD $4.8 $12.8 $23.8 $64.8 For large models, long-term artifact retention, or audio/video workflows with larger working sets.
Thunderbolt 5 daisy-chaining, per device $1.2 $3.2 $5.9 $16 Before linking devices, plan how to split tasks, sync data, recover from failures, and consolidate results.

Five checks before linking devices

  • Can the work be split into independent, retryable units?
  • Is there a single source of truth for input data, and could multiple devices write to it at once?
  • Can you keep model, dependency, and tool versions consistent?
  • Can work from a failed node be safely reassigned without generating duplicate results?
  • Do output artifacts have a consistent naming scheme, checksum, and collection location?
Troubleshooting

Narrow down the cause before changing settings

Change one thing at a time and record the results before and after. Reinstalling repeatedly, clearing all caches, or changing network and toolchain settings together makes it harder to identify the cause.

Can’t connect

Check from your local network to node status

  1. Make sure your local network is working and that no proxy or firewall is blocking the connection.
  2. Recheck the node address, port, and host fingerprint.
  3. Check that your credentials are up to date and that no spaces were added when copying them.
  4. Check the node status in the console, then record your client version and the exact error.
Unexpectedly slow

Separate latency, bandwidth, and node load

  1. Repeat the test on a stable network to rule out Wi-Fi fluctuations.
  2. Compare interactive latency with file transfer speed; they measure different things.
  3. Check whether builds, syncs, or inference jobs are using resources.
  4. Record your access location, node region, time of day, and results from repeated tests.
Build failed

Determine whether it’s a code or environment issue

  1. Pin the commit and rerun the same build command.
  2. Record Xcode, SDK, dependency, and command-line tool versions.
  3. Check signing materials, Keychain permissions, and workspace permissions.
  4. Clean temporary artifacts for the current project and retry; don’t delete everything.
Low disk space

Find what’s growing before expanding storage

  1. Check usage for models, dependency caches, archives, logs, and temporary directories separately.
  2. Look for duplicate models, old archives, or leftovers from unfinished jobs.
  3. Clean up regenerable files according to your retention rules, then record peak usage again.
  4. If peak usage still leaves too little headroom, choose a +1TB or +2TB SSD.
Inference process exited

Compare request size with peak memory

  1. Identify whether the exit happened during startup, model loading, or request processing.
  2. Check whether the model format, context length, or concurrency changed.
  3. Review memory, disk, and service logs from before the exit.
  4. Reestablish a baseline with one request, then increase the load step by step.
Credentials rejected

Stop retrying and check what changed

  1. Check whether you’re using an interactive or automation account.
  2. Check for recent password, key, or access-member changes.
  3. Remove old credentials from scripts and caches, then test the new ones.
  4. If you can’t identify what changed, submit a ticket in the console.
Support

Include the details needed to investigate your ticket

For technical issues, submit a ticket through the console so it can be linked to your order and node. If you can’t sign in to the console, email us at support@armmesh.com.

Six things to include

01 Order number

Include the order number affected. If multiple nodes are involved, list each one rather than just the team name.

02 Node region

State the region in use and whether the issue affects one node or several.

03 macOS version

Include the full version and build number. For build issues, include Xcode and command-line tool versions too.

04 Timestamp

Include the time zone, first and most recent occurrence, and whether you can reproduce the issue consistently.

05 Reproduction steps

Starting from a working state, list each action, input, expected result, and actual result.

06 Redacted logs

Keep timestamps, error codes, and context. Remove passwords, keys, tokens, signing materials, and project secrets.

Next steps

Choose a physical node, then run through the checklist

Both models are dedicated physical Macs, not VMs, available by the day, week, month, or quarter. Live availability is shown in the console.