* fix: bound the capacity describe reply by instance-type count, not free slots A node answering `DescribeInstanceTypes` with `capacity=true` sent one full copy of an instance type's description per free slot, so the reply grew with how much capacity the host had free. At 1344 bytes per slot the four-node production cluster, holding no guests, produced 874 slots and a reply over the 1 MB NATS maximum payload. Every node's reply was dropped, the gateway collected zero frames, and it returned an empty list as a success. The console reads an empty capacity list as no capacity and refuses every launch, which is how a cluster with hundreds of free vCPU reported "No compute available". The emptier the cluster, the more likely the failure, which is the opposite of what the shape should be. A node now returns each admissible type once with the number of instances of it the node can take, so its reply is bounded by the size of the instance-type catalogue and not by free capacity. On the production catalogue that is 84 KB for 62 types whatever the slot count, against 59 MB for the same reply on a large idle host under the old shape. The gateway sums the per-type counts across nodes and expands them on the last hop, because the client SDK drops response fields it does not model and the console displays the figure to the customer. A capacity fan-out that collected no frames now returns a retryable ServiceUnavailable. Reporting an empty list as a success is what turned a transport failure into a false statement about the cluster. Two tests pin the shape: the node reply for an idle 4096-vCPU host stays under the NATS payload limit, and a capacity fan-out with no responders does not return an empty success. * test: cover the console against a real cluster, and pin the capacity banner The console has never been exercised against a real control plane. `playwright.config.ts` pins `localhost:3101` and `:3102` and intercepts every API call, so the suite cannot be pointed at a cluster and cannot see a defect whose whole content is what the control plane actually sends. That is why an idle production cluster came to tell customers it had no compute: the capacity listing was dropped in transport, the empty result read as no capacity, and nothing in CI could reach the page that says so. `playwright.live.config.ts` runs the same console against a cluster named by `SPX_CONSOLE_URL`, signing in with `SPX_ACCESS_KEY_ID` and `SPX_SECRET_ACCESS_KEY`. It starts no server, mocks nothing, runs one worker because it launches real guests, and is never part of `pnpm e2e`. The suite signs in, asserts a cluster with free capacity offers instance types rather than reporting none, reads the per-type capacity figure, launches an instance and waits for `running`, reads its live metric graphs, terminates it in a `finally` block, and loads the nine listing pages a customer reaches from the sidebar. Three tests in the mocked suite pin the banner's own logic, which is cheap and catches the UI side of the same failure: the form offers what the capacity listing reports, it shows the free slot count for the selected type, and an account with genuinely no capacity is told so and cannot submit. The third passes on the current code and is the one that documents why the banner exists at all. * test: correct three live-console selectors found by running it against prod The first run of the live suite was 11 passed and 2 failed, both in the suite rather than in the console. The dashboard check looked for node status on `/`, where it is not shown. It now loads `/nodes` and asserts the `Resource usage by node` and `Instance type capacity` tables, which is where the daemon reports a node's own capacity. The OS tile's radio is `sr-only` behind the distribution logo, so `check()` failed its actionability test on the `<img>` covering it. The click goes to the enclosing `<label>` instead and the browser forwards it. The terminate dialog holds its confirm disabled until the phrase is typed, so the teardown waited out its timeout on a disabled button and left the instance running. The helper types `terminate` first. With those three corrected the launch, running, live-metrics and terminate path passes against the production console in 34 s.
Live Demo · Services · Deploy · Install · Architecture
Spinifex: the open, AWS-compatible cloud you run yourself
Spinifex, built by Mulga, recreates the AWS services your software already uses on infrastructure you control. Move workloads off the hyperscalers, run AI at a fraction of the cost, or take the cloud to the edge, without rewriting a line.
- Your AWS tooling, unchanged. The AWS CLI, SDKs, and Terraform work as they are.
- Full control of the stack. Your hardware, data, and keys, with no external control plane, running through disconnection.
- Open core under AGPL-3.0. Auditable, yours to keep, with no lock-in.
You change where your software runs, not what it is.
Try It Live
Get a real Spinifex endpoint in under a minute, with no card and no install. The sandbox is yours for 72 hours, with access keys, the web console, and EC2, EBS, S3, VPC, IAM, EKS, and RDS ready to call. Point your existing AWS CLI or Terraform straight at it.
Same Commands, Your Cloud
export AWS_PROFILE=spinifex
aws ec2 describe-images
aws ec2 run-instances --image-id ami-xxxxxxxx --instance-type t3.micro
aws s3 mb s3://my-bucket
For Terraform, start from the example workbooks.
Why Not LocalStack or Floci?
LocalStack and Floci are emulators for local development and CI testing. An emulator returns a plausible response; Spinifex boots the machine. A call launches a real KVM guest, attaches a replicated Viperblock volume, or writes an erasure-coded object into Predastore, so Spinifex can run your production workloads on hardware you own. Test against an emulator, then run in production on Spinifex.
Services
The platform serves 405 AWS API operations across the services below. See exactly which ones in the coverage report.
| Service | What it is | Built on | Status |
|---|---|---|---|
| EC2 | Compute | QEMU/KVM, with spot instances and GPU passthrough | Available |
| EBS | Block storage | Viperblock: replicated, with a WAL on local NVMe | Available |
| S3 | Object storage | Predastore: Reed-Solomon erasure coding | Available |
| VPC | Networking | OVN, with security groups | Available |
| IAM | Identity & auth | SigV4 across every service | Available |
| ALB / NLB | Load balancers | HAProxy (L7), nginx stream (L4), with ACM certificates |
Available |
| EKS | Kubernetes | k3s, with HA control planes and managed node groups | Available |
| ECR | Container registry | Predastore, deduplicated per account | Available |
| ECS | Container service | Spinifex instances | Available |
| RDS | Databases | PostgreSQL and MariaDB, with automated backups | Available |
| Route 53 | DNS | Northstar: authoritative DNS with hosted zones | Available |
| Bedrock | AI deployment | vLLM for text generation and Hugging Face TEI for embeddings and reranking | Q4 2026 |
| Lambda | Serverless functions | Q1 2027 | |
| SQS | Message queues | Q1 2027 |
Roadmap services ship under the same AWS API surface, so code written for AWS today works the moment they land. Track what's shipped in the release notes.
Deploy Anywhere
- Neocloud: lift and shift onto partner GPU capacity (H100 / H200 / B200). Change an endpoint, keep the software.
- On-premise: a multi-node HA cluster in your own data centre, so the stack, the data, and the jurisdiction stay yours.
- Edge: air-gapped sites, vehicles, vessels, factories, and clinics, with compute next to the data.
Install
Spinifex runs on Ubuntu 26.04 or Debian 13. The full guides are at docs.mulgadc.com.
Prerequisite: Spinifex requires a Linux bridge configured on the host for VM networking. See the single-node install guide for setup details.
Bare metal (recommended): download the bootable x86 installer and follow the USB install guide.
curl -fLO https://iso.mulgadc.com/spinifex.iso
Single node:
curl -fsSL https://install.mulgadc.com | bash
sudo /usr/local/share/spinifex/setup-ovn.sh --management
sudo spx admin init --node node1 --nodes 1
sudo systemctl start spinifex.target
export AWS_PROFILE=spinifex
aws ec2 describe-instance-types
From source: see the Source Install guide.
Web Console
Spinifex ships with a built-in web console for your instances, volumes, buckets, networks, and IAM. See Launching the Web UI.
Architecture
Every AWS API call is authenticated at the gateway, published to a NATS subject, and answered by whichever daemon claims it. Daemons are stateless, so you scale horizontally by starting more. Deep dive: docs/DESIGN.md.
How We Build Spinifex
Spinifex is built by infrastructure engineers with deep AWS experience, including former AWS team members, drawing on decades of combined work across AWS, enterprise infrastructure, and edge computing. Engineers architect and implement it, with Claude Code accelerating parts of the work.
| Claude Code assists with | Engineers own |
|---|---|
| Boilerplate AWS API structures and handlers | Architecture and scalability decisions |
| Development guides and API documentation | Authentication, encryption, and threat modelling |
| Test case generation and validation scenarios | Real-world performance tuning and benchmarking |
| Large-scale restructuring and refactoring | Deployment strategy and production operations |
Trademarks
"AWS", "Amazon Web Services", and all related service names (EC2, EBS, S3, VPC, IAM, and others) are trademarks of Amazon.com, Inc. or its affiliates. Mulga Defense Corporation and Spinifex are independent and not affiliated with, endorsed by, or sponsored by Amazon.com, Inc. or Amazon Web Services, Inc. References to AWS services describe interoperability and compatibility only.
License
Spinifex is open source under the GNU Affero General Public License v3.0, with a commercial license available.
