A local-first cluster substrate that discovers hardware across your machines via SSH, builds deterministic snapshots, and makes reservation-aware placement decisions — with native distributed model lifecycle, optional gossip mesh discovery, AI agent surfaces, and guarded execution.
Truth Boundary: No generated output may present itself as cluster truth unless it is backed by a real snapshot or live probe.
AXIS is built as a 5-layer stack. Each layer is subordinate to the one below it — advisory surfaces never override observed state.
┌─────────────────────────────────────────────────────────────────┐
│ Layer 5: ADVISORY │
│ Chat · Agent · MCP Server │
│ Experimental helpers — never authoritative │
├─────────────────────────────────────────────────────────────────┤
│ Layer 4: EXECUTION & LIFECYCLE │
│ Guarded Exec · Model Lifecycle · Safety Gates · Reservations │
│ Structured NDJSON streaming · Resource accounting │
├─────────────────────────────────────────────────────────────────┤
│ Layer 3: PLACEMENT │
│ Filter → Rank → Select · Model Evaluation · FitScore 0-100 │
│ GPU/VRAM matching · Locality · Empirical observations │
├─────────────────────────────────────────────────────────────────┤
│ Layer 2: SNAPSHOT │
│ ClusterSnapshot assembly · Daemon cache · 7 refresh triggers │
│ Content-aware config watches · Staleness detection │
├─────────────────────────────────────────────────────────────────┤
│ Layer 1: FACT PLANE │
│ SSH hardware probes · UDP beacons · Mesh gossip │
│ (axis mesh status/peers; also started from axis serve) │
│ Local + remote collectors · HMAC-authenticated beacons │
└─────────────────────────────────────────────────────────────────┘
# Install (Recommended)
curl -fsSL https://raw.githubusercontent.com/toasterbook88/axis/main/install.sh | bash
# Or install via Go (Requires Go 1.26+)
go install github.com/toasterbook88/axis/cmd/axis@latest
# Configure your cluster (Interactive Wizard)
axis init
# Inspect the local machine
axis node facts
# Inspect the full cluster
axis cluster status
# Ask where to run a task
axis task place "run ollama inference on a 7b model"
# Explain a placement decision
axis placement explain "run ollama inference on a 7b model"
# Resident model lifecycle (plan, start, await, query, stop, list)
axis model plan qwen3.8-27b
axis model list
axis model query qwen3.8-27b "Why is the sky blue?"
# Health diagnostics
axis doctor| Command | Purpose |
|---|---|
axis version |
Print build version, commit, and Go version |
axis init |
Interactive cluster configuration wizard |
axis node facts |
Local hardware/tool snapshot (--format json|yaml); axis facts still works |
axis cluster status |
Live cluster snapshot (--cached, --cached-only); axis status still works |
axis cluster summary |
Cluster summary view |
axis model |
Resident model lifecycle: plan, start, await, query, stop, list |
axis task place |
Advisory placement with reasoning (--cached) |
axis placement explain |
Detailed per-node placement breakdown |
axis profile match |
Workload class inference (no snapshot needed) |
axis task context |
Compact context block (--format json, --cached) |
axis task run |
Guarded task execution with safety gates |
axis reservations |
Reservation inspection |
axis doctor |
Comprehensive health diagnostics |
axis daemon start |
Background snapshot refresh daemon |
axis daemon status |
Daemon health in one versioned JSON envelope |
axis daemon refresh |
Trigger immediate cache refresh |
axis daemon invalidate |
Invalidate cached snapshot |
axis daemon restart |
Restart the local cache daemon |
axis daemon service install |
Install/start a native launchd or systemd user service |
axis daemon service status |
Inspect native service-manager state |
axis daemon service uninstall |
Stop/remove only an AXIS-managed user service |
axis serve |
Local HTTP API + daemon cache |
axis ai |
Inference backends, roles, and dry-run routing |
axis cortex |
Distributed vector memory / event bus |
axis update |
Self-update via GitHub Releases |
axis context show|clear |
Inspect or clear placement memory |
axis scripts list |
Built-in script catalog |
axis skills |
Learned execution skills |
axis completion |
Shell completions (bash/zsh/fish/powershell) |
axis mesh |
Gossip mesh peer diagnostics (axis mesh status|peers) |
axis observations |
Execution observations tracked by the cluster |
axis tui |
Interactive full-screen cluster dashboard with source-badged snapshots and advisory placement preview |
These commands are shipped but advisory or experimental. They do not override observed cluster state.
| Command | Purpose |
|---|---|
axis mcp serve |
Read-only MCP server over stdio |
axis chat |
Removed; use axis agent |
axis agent |
Tool-calling agent loop |
The placement engine uses a deterministic Filter → Rank → Select pipeline:
- Node status:
complete - Allocatable RAM ≥ requirement (after system reserve)
- GPU VRAM/vendor/backend match
- Required tools present
- Empirical PeakRAMMB filter
- No thermal throttling
- Battery ≥ 20%
- No active tombstones
- Storage class check (HDD penalty)
- Highest allocatable RAM
- Best empirical observation (fresh only)
- Resident model locality
- Preferred backend rank
- GPU score (+25 pts)
- Highest effective headroom
- Unified-memory / TurboQuant suitability
- Lowest RAM pressure
- Lowest reservation ratio
- Node name ascending (stable tiebreak)
- GPU match: +25 pts
- Local node: +10 pts
- Unified memory bonus for matching workloads
- Reservation ratio factor
AXIS manages resident inference models across cluster nodes through a deterministic 5-phase lifecycle pipeline with structured, typed receipts (axis.model-operation/v1):
┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
│ PLAN │ ───> │ START │ ───> │ AWAIT │ ───> │ QUERY │ ───> │ STOP │
└────────┘ └────────┘ └────────┘ └────────┘ └────────┘
axis model plan <spec|weights>: Dry-run evaluation of cluster nodes against available RAM, VRAM, and port availability. Outputs scored placement candidates (axis.model-spec/v1) without mutating services.axis model start <spec|weights>: Starts a model instance (e.g.,llama-server) on a target or auto-placed node with port negotiation, process invocation, and typed lifecycle receipts.axis model await <instance-id>: Readiness poller that probes/health(handling transient 503 loading states) and/v1/modelsagainst local or remote nodes until serving.axis model query <instance-id|model> "<prompt>": Standardized OpenAI-compatible inference (POST /v1/chat/completions) with latency, token counts (prompt_tokens,completion_tokens,total_tokens), and provenance telemetry.axis model stop <instance-id>: Clean process termination, port release, and lifecycle receipt recording.axis model list: Inspects resident model instances across all cluster nodes using the daemon cache with--livefallback.
| Route | Auth | Purpose |
|---|---|---|
GET /health |
No | Daemon health |
GET /snapshot |
Yes | Full ClusterSnapshot |
GET /snapshot/meta |
Yes | Cache metadata |
POST /run |
Yes | Guarded execution (NDJSON stream) |
POST /refresh |
Yes | Trigger cache refresh |
POST /invalidate |
Yes | Invalidate cache |
GET /tools |
Yes | MCP tool definitions |
GET /knowledge |
Yes | Cluster knowledge + skills |
A small set of /v2/* read routes (/v2/cluster, /v2/nodes, /v2/nodes/:name,
/v2/metrics, /v2/doctor) are active. Several endpoints return 501 as
explicit placeholders for unimplemented surfaces. These are not the primary
operator API.
# ~/.axis/nodes.yaml
nodes:
- name: macbook-pro
hostname: 192.168.1.100
ssh_port: 22
ssh_user: admin
role: workstation
timeout: 10s
- name: linux-server
hostname: 192.168.1.200
ssh_user: deploy
role: servermake build # CGO_ENABLED=0 go build -trimpath with LDFLAGS
make install # Build + copy to $GOPATH/bin
make test # go test ./... -count=1 -timeout 180s
make test-race # go test ./... -count=1 -timeout 180s -race
make lint # gofmt + go vet
make coverage # Coverage gates via hack/coverage-check.shReleases are automated via GitHub Actions:
# 1. Prepare version.go, CHANGELOG, goldens, and current-state facts in a PR.
# 2. After merge, cross-build the exact main commit without publishing.
gh workflow run Release --repo toasterbook88/Axis --ref main -f dry_run=true
# 3. After the dry run succeeds, tag the verified merge commit explicitly.
git tag -a v0.X.Y <merge-sha> -m "v0.X.Y"
git push origin v0.X.Y
# 4. release.yml validates the tag and main ancestry, then publishes.Binaries are built for darwin/linux × amd64/arm64 with:
- Reproducible builds (
-trimpath,CGO_ENABLED=0) - Embedded version, commit hash, build date
- SHA-256 checksums
- Per-archive SPDX SBOMs
- GitHub build-provenance attestations
- Conventional Commits changelog
GoReleaser owns the GitHub Release. Do not run gh release create manually,
and do not move a pushed release tag; cut the next patch version after a failed
publication unless the operator explicitly authorizes rewriting the tag.
axis/
├── cmd/axis/ Cobra CLI entry point
├── internal/ Private packages (46 packages)
│ ├── facts/ SSH hardware/tool collection
│ ├── snapshot/ ClusterSnapshot assembly
│ ├── placement/ Deterministic Filter→Rank→Select
│ ├── modellife/ Model start, await, query, and stop lifecycle
│ ├── modelplan/ Dry-run model placement evaluation
│ ├── modelinventory/ Resident model instance discovery
│ ├── execution/ Guarded task execution
│ ├── daemon/ Background cache + 7 refresh triggers
│ ├── api/ HTTP API (v1 + v2 read routes)
│ ├── mesh/ Gossip peer discovery (`axis mesh`, daemon WatchMesh)
│ ├── reservation/ Resource accounting ledger (`axis reservations`)
│ ├── safety/ Structured command safety evaluation and gates
│ ├── discovery/ SSH + UDP node discovery
│ ├── mcp/ MCP server (stdio)
│ ├── agent/ Tool-calling agent loop
│ └── ... 30+ additional packages
├── docs/ Design docs + CI-validated state
├── hack/ Developer scripts
└── .github/ CI + release workflows
- Air-gapped option: On-device inference via llama-server and Ollama, no cloud dependency
- HMAC-SHA256: Beacon and mesh-gossip authentication are shipped; mesh messages do not yet enforce replay protection
- Zero-trust execution: Existing safety gates are shipped; parsed command analysis scaffolding is not wired into the operator path
- Constant-time auth: Bearer token comparison via
crypto/subtle - No data exfiltration: All state persisted locally in
~/.axis/ - govulncheck: Automated vulnerability scanning in release pipeline
- SBOM generation: Supply chain transparency via GoReleaser
See SECURITY.md for our vulnerability disclosure policy.
See CONTRIBUTING.md for development guidelines.
For AI agents working in this repo, see AGENTS.md.
MIT — Smith Software Solutions
axismcp.app · axismcp.tech · smithsolutionssc.com · @AXISBRIDGEMACOS