-
Notifications
You must be signed in to change notification settings - Fork 0
Placement Engine
Relevant source files
The following files were used as context for generating this wiki page:
- internal/agent/cortex_memory.go
- internal/agent/cortex_memory_test.go
- internal/models/types_test.go
- internal/placement/explain.go
- internal/placement/infer.go
- internal/placement/placement_test.go
- internal/placement/ranker.go
- internal/placement/selector.go
- internal/snapshot/snapshot.go
- internal/snapshot/snapshot_test.go
The Placement Engine is Layer 3 of the AXIS architecture. It is responsible for transforming a high-level task description into a specific, optimal node selection through a deterministic pipeline. This engine ensures that workloads are matched to the hardware best suited for them—whether that is a local workstation with Apple Silicon or a remote Linux server with NVIDIA GPUs.
The engine operates on the Truth Rule: decisions are made based on the most recent ClusterSnapshot internal/snapshot/snapshot.go:16-124, ensuring that placement is always grounded in actual hardware telemetry rather than stale configuration.
Placement follows a strict Filter → Rank → Select sequence to ensure results are both optimal and reproducible.
- Filter: Hard constraints (RAM requirements, tool availability, health status) are applied to exclude ineligible nodes internal/placement/ranker.go:37-45.
- Rank: Eligible nodes are sorted using a 10-level deterministic priority sort internal/placement/ranker.go:68-202.
-
Select: The top-ranked node is chosen, and a
PlacementDecisionis generated, including a detailed reasoning trace for diagnostic transparency internal/placement/selector.go:14-27.
The following diagram illustrates how the placement logic bridges the gap between raw NodeFacts and the final PlacementDecision.
graph TD
subgraph "Natural Language Space"
TaskDesc["Task Description (string)"]
end
subgraph "Placement Plane (internal/placement)"
direction TB
Infer["placement.InferRequirements()"]
Filter["placement.FilterCandidates()"]
Rank["placement.RankCandidates()"]
Select["placement.SelectBestNode()"]
Explain["placement.evaluateCandidate()"]
end
subgraph "Code Entity Space"
Reqs["models.TaskRequirements"]
Snap["models.ClusterSnapshot"]
Facts["models.NodeFacts"]
Decision["models.PlacementDecision"]
end
TaskDesc --> Infer
Infer --> Reqs
Reqs --> Filter
Snap --> Facts
Facts --> Filter
Filter --> Rank
Rank --> Select
Select --> Decision
Explain -.->|Diagnostic Reasoning| Decision
Sources: internal/placement/ranker.go:37-202, internal/placement/selector.go:11-27, internal/placement/infer.go:14-16, internal/placement/explain.go:31-117
The core logic resides in ranker.go and selector.go. Filtering enforces hard blockers like StatusComplete, MinFreeRAMMB, and RequiredTools internal/placement/ranker.go:32-45. Ranking then applies a sophisticated sort that considers:
- Allocatable RAM: Nodes with more headroom rank higher.
- Locality: Preference for resident models and local execution where beneficial.
- Hardware Specialized: GPU scores and Unified Memory suitability internal/placement/ranker.go:142-194.
For details, see Filter, Rank, and Select Pipeline.
Before placement begins, AXIS must understand what the task requires. placement.InferRequirements parses natural language descriptions to detect WorkloadClass (e.g., Inference, Build, Search), RAM floors, and specialized tool requirements like ollama or turboquant internal/placement/infer.go:14-16. This system uses both heuristic string matching and an optional semantic LLM router.
For details, see Workload Inference and Classification.
The Placement Engine is "immune-aware." It consults the state.ClusterState to find FailureRecords internal/placement/explain.go:73-82. If a node has repeatedly failed a specific workload class (e.g., OOM crashes), it is either penalized during ranking or filtered out entirely via isBlockingFailure internal/placement/ranker.go:47-53. It also uses ExecutionObservation data (Peak RAM, Wall Time) to refine future placement decisions based on actual past performance internal/placement/explain.go:119-132.
For details, see Empirical Feedback and Failure Memory.
This diagram maps the code entities involved in a placement decision to their functional roles.
graph LR
subgraph "Input State"
Snapshot["models.ClusterSnapshot"]
History["state.ClusterState (Failures/Obs)"]
end
subgraph "Decision Engine"
Ranker["ranker.go"]
Selector["selector.go"]
Explainer["explain.go"]
end
subgraph "Output"
Decision["models.PlacementDecision"]
Reasoning["Decision.Reasoning (string list)"]
end
Snapshot --> Ranker
History --> Ranker
Ranker --> Selector
Selector --> Decision
Explainer --> Reasoning
Reasoning --> Decision
Sources: internal/placement/ranker.go:68-202, internal/placement/selector.go:11-27, internal/placement/explain.go:174-191
To prevent "thrashing" and ensure consistent behavior, AXIS uses a stable tie-break: if two nodes are identical across all 9 primary ranking criteria, the engine selects based on the NodeFacts.Name in ascending alphabetical order internal/placement/ranker.go:193.
Sources:
- internal/placement/ranker.go:37-202
- internal/placement/selector.go:11-27
- internal/placement/explain.go:31-117
- internal/snapshot/snapshot.go:16-124