-
Notifications
You must be signed in to change notification settings - Fork 0
NodeFacts Data Model
Relevant source files
The following files were used as context for generating this wiki page:
- internal/facts/local.go
- internal/facts/parsers_test.go
- internal/facts/remote.go
- internal/models/locality.go
- internal/models/locality_test.go
- internal/models/memory.go
- internal/models/memory_test.go
- internal/models/types.go
- internal/reservation/ledger.go
- internal/reservation/ledger_test.go
- internal/snapshotview/overlay.go
- internal/transport/local.go
The NodeFacts data model is the primary schema for describing the state, capabilities, and health of individual nodes within an AXIS cluster. It serves as the fundamental unit of information in the Fact Plane (Layer 1) and is the building block for the ClusterSnapshot (Layer 2) used by the placement engine.
The NodeFacts struct captures a comprehensive point-in-time view of a node. This includes static hardware identifiers, dynamic resource utilization, software tool availability, and resident AI models.
| Field | Type | Description |
|---|---|---|
Name |
string |
The logical name of the node from nodes.yaml. |
Hostname |
string |
The actual hostname reported by the OS. |
Status |
NodeStatus |
Collection status: complete, partial, unreachable, or error. |
Resources |
*Resources |
Hardware telemetry (CPU, RAM, GPU, Disk). |
ResidentModels |
[]ResidentModel |
Models currently loaded in memory (Ollama, llama.cpp, MLX). |
Tools |
[]ToolInfo |
Discovered binaries and AI runtimes. |
Identity |
*NodeIdentity |
Stable hardware UUIDs (e.g., /etc/machine-id or IOPlatformUUID). |
Sources: internal/models/types.go:151-240, internal/facts/local.go:52-60
The Resources struct provides detailed metrics used for scheduling decisions. AXIS differentiates between total physical RAM and "Allocatable" RAM.
-
Memory Topology: Classified as
standardorunified(e.g., Apple Silicon) internal/models/types.go:47-52. - Memory Classes: Integer rankings for memory speed/bandwidth (e.g., Class 4 for M3 Max) internal/facts/parsers_test.go:212-228.
-
Pressure Signals: AXIS monitors RAM pressure (
none,low,medium,high) and Linux PSI (Pressure Stall Information) to avoid placing tasks on thrashing nodes internal/models/types.go:104-106, internal/facts/remote.go:198-204.
Sources: internal/models/types.go:78-107, internal/facts/remote.go:141-243
AXIS uses a multi-layered approach to determine how much RAM is actually available for a task. This prevents system instability by enforcing a SystemReserveMB floor.
This diagram maps the natural language concepts of "Available Memory" to the specific functions and fields in the AXIS codebase.
"Natural Language to Code Entity Mapping: Memory"
graph TD
subgraph "Natural Language Space"
A["Total Physical RAM"]
B["Protected System Headroom"]
C["Currently Free RAM"]
D["AXIS Task Reservations"]
E["Usable for New Tasks"]
end
subgraph "Code Entity Space (internal/models/memory.go)"
A --- A1["Resources.RAMTotalMB"]
B --- B1["SystemReserveMBWithConfig()"]
C --- C1["Resources.RAMFreeMB"]
D --- D1["NodeFacts.RAMReservedMB"]
E --- E1["AllocatableRAMMBWithConfig()"]
end
A1 --> B1
A1 & C1 & B1 --> F["ReservableRAMMBWithConfig()"]
F --> G["Subtract ReservedMB"]
G --> E1
Sources: internal/models/memory.go:1-98, internal/models/types.go:136-150
-
System Reserve: Defaults to 1024MB or a per-node override in
nodes.yamlinternal/models/memory.go:54-66. -
Reservable RAM: The minimum of (
Total-Reserve) andFreeRAM internal/models/memory.go:69-85. -
Allocatable RAM:
Reservableminus the active commitments in thereservation.Ledgerinternal/models/memory.go:88-98.
AXIS tracks how it knows what it knows about a node through the NodeStatus and CollectedAt fields.
This diagram shows how LocalCollector and RemoteCollector populate the NodeFacts model.
"Discovery Data Flow: Collectors to NodeFacts"
graph LR
subgraph "Collectors (internal/facts/)"
LC["LocalCollector.Collect()"]
RC["RemoteCollector.Collect()"]
end
subgraph "Discovery Probes"
P1["uname/sw_vers"]
P2["/proc/meminfo"]
P3["nvidia-smi/ioreg"]
P4["Ollama API"]
end
subgraph "Data Model"
NF["models.NodeFacts"]
end
LC & RC --> P1 & P2 & P3 & P4
P1 -->|"OS/Arch"| NF
P2 -->|"Resources"| NF
P3 -->|"GPUs"| NF
P4 -->|"ResidentModels"| NF
Sources: internal/facts/local.go:52-143, internal/facts/remote.go:36-139
AXIS tracks "Resident Models" to optimize for "warm" starts. If a node already has llama3:70b loaded in its ResidentModels list, the ranker will prioritize it to avoid loading latency internal/facts/local.go:105-124.
While NodeFacts represents the observed state, the reservation.Ledger tracks intent. This is a double-entry accounting system that prevents race conditions where multiple tasks are scheduled on the same RAM before the OS reports it as "used."
| Field | Description |
|---|---|
ID |
Unique execution ID. |
RAMMB |
Committed memory. |
OwnerExecID |
The task ID responsible for the reservation. |
LastHeartbeat |
Used to reclaim memory if a process crashes without releasing. |
ExpiresAt |
Hard TTL for the reservation. |
Sources: internal/reservation/ledger.go:22-35
The snapshotview.ApplyReservationView function takes a raw ClusterSnapshot and overlays the ledger's active entries. This produces the RAMAllocatableMB field seen by the placement engine, ensuring that "in-flight" tasks are accounted for even if they haven't started consuming physical RSS yet.
Sources: internal/snapshotview/overlay.go:65-114
NodeFacts includes failure metadata to implement the cluster's "immune system."
- SSHHandshakeLatencyMs: Tracked to detect degraded network paths internal/facts/remote.go:56-59.
-
NodeStatus: If a node is
StatusPartial, it indicates that while the node is reachable, specific probes (like GPU telemetry) failed, which may disqualify it from certain workloads internal/models/types.go:12-24.
Sources: internal/models/types.go:12-33, internal/facts/remote.go:33-53