Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ body:
attributes:
label: What happened?
description: A clear description of the bug, including any error messages or unexpected output.
placeholder: e.g. provider crashed with X after running `eigeninference-provider serve` on a fresh M2 Air
placeholder: e.g. provider crashed with X after running `darkbloom-provider serve` on a fresh M2 Air
validations:
required: true

Expand All @@ -52,7 +52,7 @@ body:
description: Minimal steps that reliably trigger the bug.
placeholder: |
1. Install v0.3.5 via the install.sh one-liner
2. Run `eigeninference-provider serve --model llama-3.1-8b-instruct`
2. Run `darkbloom-provider serve --model llama-3.1-8b-instruct`
3. Send a chat completion from the console UI
4. Observe the failure
validations:
Expand All @@ -63,7 +63,7 @@ body:
attributes:
label: Environment
description: |
Anything relevant to reproducing this — provider version (`eigeninference-provider --version`), macOS version, Mac model + RAM, browser (for console UI bugs), etc.
Anything relevant to reproducing this — provider version (`darkbloom-provider --version`), macOS version, Mac model + RAM, browser (for console UI bugs), etc.
placeholder: |
- provider: v0.3.5
- macOS: 15.4 (Sequoia)
Expand All @@ -75,7 +75,7 @@ body:
id: logs
attributes:
label: Logs
description: Relevant log output. For provider crashes, include the last ~50 lines of `~/Library/Logs/eigeninference-provider/*.log`. Use code fences and redact anything sensitive.
description: Relevant log output. For provider crashes, include the last ~50 lines of `~/Library/Logs/darkbloom-provider/*.log`. Use code fences and redact anything sensitive.
render: shell

- type: checkboxes
Expand Down
128 changes: 64 additions & 64 deletions .github/workflows/release.yml

Large diffs are not rendered by default.

30 changes: 15 additions & 15 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# EigenInference - Decentralized Private Inference
# Darkbloom - Decentralized Private Inference

EigenInference is a decentralized/private inference stack for Apple Silicon Macs. Consumers use OpenAI-compatible APIs, the coordinator handles routing/auth/billing/attestation, and providers run local text, transcription, and image workloads on macOS hardware.
Darkbloom is a decentralized/private inference stack for Apple Silicon Macs. Consumers use OpenAI-compatible APIs, the coordinator handles routing/auth/billing/attestation, and providers run local text, transcription, and image workloads on macOS hardware.

## Project Structure

```text
coordinator/ Go control plane
├── cmd/coordinator/ main service entrypoint
├── cmd/verify-attestation/
│ └── main.go verifies attestation blobs from /tmp/eigeninference_attestation.json
│ └── main.go verifies attestation blobs from /tmp/darkbloom_attestation.json
└── internal/
├── api/ HTTP + WebSocket handlers
│ ├── consumer.go OpenAI-compatible chat/completions/messages/transcriptions/images
Expand Down Expand Up @@ -53,7 +53,7 @@ provider/ Rust provider agent for Apple Silicon Macs
└── Cargo.toml default `python` feature enables in-process PyO3 inference

image-bridge/ Python FastAPI image generation bridge
├── eigeninference_image_bridge/
├── darkbloom_image_bridge/
│ ├── __main__.py
│ ├── server.py OpenAI-compatible `/v1/images/generations`
│ ├── drawthings_backend.py Draw Things gRPC backend adapter
Expand All @@ -62,9 +62,9 @@ image-bridge/ Python FastAPI image generation bridge
├── requirements.txt
└── tests/ pytest coverage for server/backend/integration

app/EigenInference/ SwiftUI macOS menu bar app
├── Sources/EigenInference/
│ ├── EigenInferenceApp.swift
app/Darkbloom/ SwiftUI macOS menu bar app
├── Sources/Darkbloom/
│ ├── DarkbloomApp.swift
│ ├── StatusViewModel.swift
│ ├── ProviderManager.swift
│ ├── CLIRunner.swift
Expand All @@ -79,13 +79,13 @@ app/EigenInference/ SwiftUI macOS menu bar app
│ ├── MenuBarView.swift / SetupWizardView.swift
│ ├── DoctorView.swift / LogViewerView.swift / ModelCatalogView.swift
│ └── Resources/
└── Tests/EigenInferenceTests/
└── Tests/DarkbloomTests/

enclave/ Swift Secure Enclave helper + bridge binary
├── Sources/EigenInferenceEnclave/ enclave key + attestation library + FFI bridge
├── Sources/EigenInferenceEnclaveCLI/ `eigeninference-enclave` CLI (attest, sign, info)
├── Tests/EigenInferenceEnclaveTests/
└── include/eigeninference_enclave.h
├── Sources/DarkbloomEnclave/ enclave key + attestation library + FFI bridge
├── Sources/DarkbloomEnclaveCLI/ `darkbloom-enclave` CLI (attest, sign, info)
├── Tests/DarkbloomEnclaveTests/
└── include/darkbloom_enclave.h

console-ui/ Next.js 16 / React 19 frontend
├── src/app/ chat, billing, images, models, stats, providers, settings, link, api-console, earn
Expand All @@ -100,7 +100,7 @@ console-ui/ Next.js 16 / React 19 frontend

scripts/ build, signing, install, and deploy helpers
├── build-bundle.sh provider/enclave/python/ffmpeg bundle builder (+ optional upload)
├── bundle-app.sh build EigenInference.app + DMG
├── bundle-app.sh build Darkbloom.app + DMG
├── install.sh end-user installer served from coordinator (hash + codesign verification)
├── sign-hardened.sh hardened runtime signing helper
├── admin.sh admin CLI (Privy auth, release mgmt, API calls)
Expand Down Expand Up @@ -130,7 +130,7 @@ go build ./cmd/coordinator
go build ./cmd/verify-attestation

# Linux deployment build
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o eigeninference-coordinator-linux ./cmd/coordinator
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o darkbloom-coordinator-linux ./cmd/coordinator
```

### Provider (Rust)
Expand All @@ -156,7 +156,7 @@ PYTHONPATH=. pytest

### macOS App (Swift)
```bash
cd app/EigenInference
cd app/Darkbloom
swift build -c release
swift test
```
Expand Down
28 changes: 14 additions & 14 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# EigenInference - Decentralized GPU Inference
# Darkbloom - Decentralized GPU Inference

Decentralized inference network for Apple Silicon Macs. Providers offer GPU compute, consumers send OpenAI-compatible requests, the coordinator matches them.

Expand Down Expand Up @@ -41,18 +41,18 @@ provider/ Rust — runs on Apple Silicon Macs
├── stt_server.py Local speech-to-text server script

image-bridge/ Python FastAPI image generation bridge
├── eigeninference_image_bridge/
├── darkbloom_image_bridge/
│ ├── server.py OpenAI-compatible /v1/images/generations
│ └── drawthings_backend.py Draw Things gRPC backend adapter
├── requirements.txt
└── tests/

app/EigenInference/ Swift — macOS menu bar app (SwiftUI)
├── Sources/EigenInference/
│ ├── EigenInferenceApp.swift App entry, menu bar setup
app/Darkbloom/ Swift — macOS menu bar app (SwiftUI)
├── Sources/Darkbloom/
│ ├── DarkbloomApp.swift App entry, menu bar setup
│ ├── StatusViewModel.swift Core state management
│ ├── ProviderManager.swift Provider subprocess lifecycle
│ ├── CLIRunner.swift Launches eigeninference-provider
│ ├── CLIRunner.swift Launches darkbloom-provider
│ ├── ConfigManager.swift TOML config read/write
│ ├── SecurityManager.swift Trust level checks (SIP, SE, MDM, Secure Boot)
│ ├── ModelManager.swift HuggingFace model scanning
Expand All @@ -71,14 +71,14 @@ app/EigenInference/ Swift — macOS menu bar app (SwiftUI)
│ ├── ModelCatalogView.swift Model browser with RAM fit indicators
│ ├── GuideAvatar.swift Animated mascot (mood-based PNGs)
│ └── Illustrations.swift Procedural Mac illustration
├── Tests/EigenInferenceTests/
├── Tests/DarkbloomTests/

enclave/ Swift — Secure Enclave attestation CLI helper
├── Sources/
│ ├── EigenInferenceEnclave/ Library (P-256 key gen, attestation blob, FFI bridge for Rust)
│ └── EigenInferenceEnclaveCLI/ CLI tool (attest, sign, info, wallet-address)
├── Tests/EigenInferenceEnclaveTests/
└── include/eigeninference_enclave.h
│ ├── DarkbloomEnclave/ Library (P-256 key gen, attestation blob, FFI bridge for Rust)
│ └── DarkbloomEnclaveCLI/ CLI tool (attest, sign, info, wallet-address)
├── Tests/DarkbloomEnclaveTests/
└── include/darkbloom_enclave.h

console-ui/ Next.js 16 / React 19 frontend (chat, billing, models, images)
├── src/app/ Pages: chat (/), billing, images, models, stats, providers, settings, link, api-console, earn
Expand Down Expand Up @@ -117,7 +117,7 @@ The `.external/` directory contains our fork of [vllm-mlx](https://github.com/Ga
cd coordinator
go test ./...
# Cross-compile for the EigenCloud container (Linux amd64):
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o eigeninference-coordinator-linux ./cmd/coordinator
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o darkbloom-coordinator-linux ./cmd/coordinator
```

### Provider (Rust)
Expand All @@ -135,7 +135,7 @@ cargo build --release --no-default-features

### macOS App (Swift)
```bash
cd app/EigenInference
cd app/Darkbloom
swift build -c release
swift test
```
Expand Down Expand Up @@ -275,7 +275,7 @@ Always think from first principles. When fixing a bug or designing a feature:
- Attestation tests need `AuthenticatedRootEnabled: true` in test blobs or the ARV check fails and overwrites earlier error messages (the checks run sequentially, last failure wins).
- The `python` feature flag in the provider Cargo.toml links PyO3. Use `--no-default-features` when building for distribution to avoid Python linking issues.
- The coordinator uses in-memory store by default. Provider state is lost on restart. Postgres store exists but is not used in production yet.
- Binary files like `coordinator/eigeninference-coordinator` and `coordinator/eigeninference-coordinator-linux` should NOT be committed to git (15MB+ each).
- Binary files like `coordinator/darkbloom-coordinator` and `coordinator/darkbloom-coordinator-linux` should NOT be committed to git (15MB+ each).
- CI release workflow must compute binary SHA-256 hashes AFTER code signing, not before. Providers verify hashes of the signed binary.
- Provider bundle semantics span multiple files: `scripts/build-bundle.sh`, `scripts/install.sh`, the Swift app launcher, and `LatestProviderVersion` in `coordinator/internal/api/server.go`. Keep them in sync.
- Image generation changes span three places: coordinator consumer/provider handlers, provider proxying, and `image-bridge/`.
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ See [CLAUDE.md](CLAUDE.md) for the full layout and architectural decisions. The
| `coordinator/` | Go | Central matchmaking server (runs on EigenCloud / GCP) |
| `provider/` | Rust | Hardened daemon on Apple Silicon Macs |
| `console-ui/` | Next.js 16 / React 19 | Web app (chat, billing, models) |
| `app/EigenInference/` | Swift / SwiftUI | macOS menu bar app for providers |
| `app/Darkbloom/` | Swift / SwiftUI | macOS menu bar app for providers |
| `enclave/` | Swift | Secure Enclave attestation helper |
| `image-bridge/` | Python / FastAPI | Image generation backend adapter |

Expand Down Expand Up @@ -60,7 +60,7 @@ cd provider && PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 cargo test
cd console-ui && npm install && npm test && npx eslint src/

# macOS app
cd app/EigenInference && swift test
cd app/Darkbloom && swift test

# Enclave helper
cd enclave && swift test
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ from openai import OpenAI

client = OpenAI(
base_url="https://api.darkbloom.dev/v1",
api_key="eigeninference-..."
api_key="darkbloom-..."
)

# Chat completion
Expand Down Expand Up @@ -104,7 +104,7 @@ A native SwiftUI app is also available:

### Scheduling

Providers can configure time-based availability windows. Outside scheduled hours, the provider disconnects and shuts down the backend to free GPU memory. Configured in the app's Settings or directly in `~/.config/eigeninference/provider.toml`:
Providers can configure time-based availability windows. Outside scheduled hours, the provider disconnects and shuts down the backend to free GPU memory. Configured in the app's Settings or directly in `~/.config/darkbloom/provider.toml`:

```toml
[schedule]
Expand Down Expand Up @@ -158,7 +158,7 @@ Attestation data is publicly verifiable at `GET /v1/providers/attestation`.
| Coordinator (`coordinator/`) | Go | Control plane: routing, attestation, billing, API |
| Provider (`provider/`) | Rust | Inference agent: security, attestation, WebSocket client |
| Console (`console-ui/`) | Next.js 16 | Web dashboard: chat, billing, provider verification |
| macOS App (`app/EigenInference/`) | Swift | Menu bar app: status, scheduling, earnings |
| macOS App (`app/Darkbloom/`) | Swift | Menu bar app: status, scheduling, earnings |
| Secure Enclave (`enclave/`) | Swift | Hardware-bound P-256 identity |
| Landing (`landing/`) | HTML | Static landing page |

Expand All @@ -172,7 +172,7 @@ cd coordinator && go test ./...
cd provider && cargo test

# macOS App
cd app/EigenInference && swift build -c release
cd app/Darkbloom && swift build -c release

# Console UI
cd console-ui && npm install && npm run dev
Expand Down
2 changes: 1 addition & 1 deletion analytics/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Analytics

Standalone read-only analytics service for Darkbloom / EigenInference.
Standalone read-only analytics service for Darkbloom / Darkbloom.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update


This service is meant to sit beside the coordinator, not inside it.
It serves public read models like:
Expand Down
8 changes: 4 additions & 4 deletions analytics/cmd/analytics/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import (
"syscall"
"time"

"github.com/eigeninference/analytics/internal/config"
"github.com/eigeninference/analytics/internal/httpapi"
"github.com/eigeninference/analytics/internal/leaderboard"
"github.com/eigeninference/analytics/internal/pseudonym"
"github.com/darkbloom/analytics/internal/config"
"github.com/darkbloom/analytics/internal/httpapi"
"github.com/darkbloom/analytics/internal/leaderboard"
"github.com/darkbloom/analytics/internal/pseudonym"
)

func main() {
Expand Down
2 changes: 1 addition & 1 deletion analytics/go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/eigeninference/analytics
module github.com/darkbloom/analytics

go 1.25.0

Expand Down
2 changes: 1 addition & 1 deletion analytics/internal/httpapi/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"strings"
"time"

"github.com/eigeninference/analytics/internal/leaderboard"
"github.com/darkbloom/analytics/internal/leaderboard"
)

type Service interface {
Expand Down
4 changes: 2 additions & 2 deletions analytics/internal/httpapi/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (
"testing"
"time"

"github.com/eigeninference/analytics/internal/leaderboard"
"github.com/eigeninference/analytics/internal/pseudonym"
"github.com/darkbloom/analytics/internal/leaderboard"
"github.com/darkbloom/analytics/internal/pseudonym"
)

func TestHealthz(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion analytics/internal/leaderboard/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"testing"
"time"

"github.com/eigeninference/analytics/internal/pseudonym"
"github.com/darkbloom/analytics/internal/pseudonym"
)

func fixedNow() time.Time {
Expand Down
12 changes: 6 additions & 6 deletions app/EigenInference/Package.swift → app/Darkbloom/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@
import PackageDescription

let package = Package(
name: "EigenInference",
name: "Darkbloom",
platforms: [.macOS(.v14)],
dependencies: [],
targets: [
.executableTarget(
name: "EigenInference",
path: "Sources/EigenInference",
name: "Darkbloom",
path: "Sources/Darkbloom",
resources: [
.process("Resources"),
]
),
.testTarget(
name: "EigenInferenceTests",
dependencies: ["EigenInference"],
path: "Tests/EigenInferenceTests"
name: "DarkbloomTests",
dependencies: ["Darkbloom"],
path: "Tests/DarkbloomTests"
),
]
)
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
///
/// TOML structure:
/// [provider]
/// name = "eigeninference-mac16-1"
/// name = "darkbloom-mac16-1"
/// memory_reserve_gb = 4
///
/// [backend]
Expand Down Expand Up @@ -53,7 +53,7 @@ enum ConfigManager {
).first!

let newPath = appSupport.appendingPathComponent("darkbloom").appendingPathComponent("provider.toml")
let legacyPath = appSupport.appendingPathComponent("eigeninference").appendingPathComponent("provider.toml")
let legacyPath = appSupport.appendingPathComponent("darkbloom").appendingPathComponent("provider.toml")
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rm


if FileManager.default.fileExists(atPath: newPath.path) {
return newPath
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ final class SecurityManager: ObservableObject {
let profiles = await CLIRunner.shell("profiles list 2>&1")
let combined = (profiles.stdout + profiles.stderr).lowercased()
if combined.contains("micromdm") || combined.contains("darkbloom") ||
combined.contains("eigeninference") ||
combined.contains("darkbloom") ||
combined.contains("com.github.micromdm") {
return true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -442,8 +442,8 @@ final class StatusViewModel: ObservableObject {
/// Parse tracing-formatted output from the provider binary.
///
/// The Rust binary uses `tracing` which outputs lines like:
/// 2026-03-24T10:00:00.123Z INFO eigeninference_provider: Connected to coordinator
/// 2026-03-24T10:00:01.234Z INFO eigeninference_provider: Received inference request: req-abc
/// 2026-03-24T10:00:00.123Z INFO darkbloom_provider: Connected to coordinator
/// 2026-03-24T10:00:01.234Z INFO darkbloom_provider: Received inference request: req-abc
private func parseProviderOutput(_ line: String) {
guard !line.isEmpty else { return }
let lower = line.lowercased()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import Testing
import Foundation
@testable import EigenInference
@testable import Darkbloom

@Suite("CLIRunner - Binary Resolution")
struct CLIRunnerBinaryTests {
Expand Down
Loading
Loading