\documentclass[twocolumn,10pt]{article}

\usepackage[letterpaper,margin=0.75in,columnsep=0.25in]{geometry}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{microtype}
\usepackage{amsmath,amssymb,amsthm}
\usepackage{booktabs}
\usepackage{graphicx}
\usepackage{xcolor}
\usepackage{listings}
\usepackage[ruled,vlined,linesnumbered]{algorithm2e}
\usepackage{enumitem}
\usepackage[hidelinks]{hyperref}
\usepackage{xurl}
\urlstyle{tt}

\newtheorem{theorem}{Theorem}
\newtheorem{proposition}{Proposition}
\newtheorem{lemma}{Lemma}
\newtheorem{invariant}{Invariant}

\lstdefinestyle{tla}{
  basicstyle=\scriptsize\ttfamily,
  columns=fixed,
  keepspaces=true,
  breaklines=false,
  frame=single,
  framesep=4pt,
  xleftmargin=2pt,
  xrightmargin=2pt
}
\lstdefinestyle{ascii}{
  basicstyle=\scriptsize\ttfamily,
  columns=fixed,
  keepspaces=true,
  frame=single,
  framesep=4pt
}

\setlength{\parskip}{0pt}
\emergencystretch=2em
\setlist{nosep}

\title{\textbf{Phalanx: A Formally Verified, Topology-Aware Control Plane for\\ Fault-Tolerant Training on Kubernetes GPU Clusters}}
\author{}
\date{}

\begin{document}

\twocolumn[
\begin{@twocolumnfalse}
\maketitle
\vspace{-3em}
\begin{abstract}
\noindent Large-scale training is now failure-dominated: Meta reported 419 unexpected interruptions across a 54-day Llama~3 run on 16{,}384 H100 GPUs, roughly one every three hours, and synchronous training semantics mean a single dead GPU can stall the entire job. The infrastructure that manages these jobs is split down the middle. Kubernetes-side schedulers (Volcano, Kueue, YuniKorn, NVIDIA KAI, and the alpha Workload Aware Scheduling primitives that only entered upstream Kubernetes in v1.35 and v1.36) decide where a gang of pods lands, with growing but incomplete topology awareness. Framework-side elasticity layers (TorchElastic, Oobleck, Bamboo, Parcae) decide how a job survives a failure, with no view of cluster topology and no ability to claim replacement hardware atomically. The seam between them is exactly where large runs bleed goodput: failure-triggered rescheduling is today neither topology-aware nor provably checkpoint-consistent. We present \textbf{Phalanx}, a Kubernetes-native control plane that unifies the two concerns. Phalanx contributes (1)~\textsc{HDF-B}, a hierarchical deepest-fit gang placement algorithm with buddy-aligned allocation over a topology tree compiled from Dynamic Resource Allocation attributes, for which we prove per-gang bottleneck optimality, a factor-2 capacity augmentation bound, and a bounded failure blast radius, all three being per-placement guarantees rather than global multi-tenant claims, since we prove the global objective NP-hard; (2)~the Rank Reformation Protocol (RRP), an epoch-fenced reconfiguration protocol whose safety (checkpoint consistency, exclusive placement, zombie fencing) we establish by inductive invariants over a TLA\textsuperscript{+} specification and whose liveness we establish under partial synchrony, in the style of Anvil's eventually stable reconciliation; we mechanically check both with TLC across 834{,}050 distinct protocol states, and a mutation study shows the checker exhibiting a liveness counterexample the moment the protocol's contended-commit retry transition is deleted; and (3)~an executed evaluation: beyond the TLC campaign, a full-scale discrete-event instantiation of the model at 131{,}072 leaves in which \textsc{Replan} answers node failures with a p99 latency of 0.9 microseconds while migrating exactly 8 ranks, recovery placements hold median step-communication inflation to 1.00$\times$ against 8.9$\times$ for topology-blind replacement on a hierarchical bandwidth model, and Monte Carlo failure injection over 1{,}000 54-day runs per configuration reproduces the renewal model within 1.4 points, yielding, under a recovery-latency model calibrated to published peer-RAM restore figures, effective training time ratios of 0.980 at 16K GPUs and 0.891 at 131K GPUs where the restart-based baseline measures 0.467, with a sensitivity sweep confirming that fast in-memory recovery dominates restart across the entire plausible range of the assumed parameters. The design is hardware-generation agnostic across Ampere, Hopper, and Blackwell because the topology tree is derived from device attributes rather than hard-coded fanouts.
\end{abstract}
\vspace{1.5em}
\end{@twocolumnfalse}
]

\section{Introduction: the reliability wall}
\label{sec:intro}

Two curves are crossing. The first is cluster scale: frontier training runs moved from hundreds of GPUs to tens of thousands in about four years, and public roadmaps point at hundreds of thousands. The second is component reliability, which is not improving at anywhere near the rate scale is growing. The product of the two is a mean time between failures that shrinks linearly with GPU count. The best public datapoint is the Llama~3 herd report~\cite{llama3}: over a 54-day pre-training snapshot on 16{,}384 H100 GPUs, Meta logged 466 job interruptions, 419 of them unexpected, one failure roughly every 3 hours; 58.7\% of the unexpected interruptions were GPU-related, with 30.1\% attributed to GPU failures including NVLink and 17.2\% to HBM3 memory, and the team still held effective training time above 90\% with only three incidents needing significant manual intervention~\cite{llama3,tomshw}. Extrapolating the same per-device failure rate, a 131{,}072-GPU cluster faces an interruption every 23 minutes. Meta's broader reliability study of two research clusters, covering 11 months, four million jobs, and 150 million GPU hours, formalizes the productivity metric this paper optimizes, the effective training time ratio (ETTR), and shows why checkpoint cadence and restart latency dominate it at scale~\cite{kokolis}. Earlier evidence says none of this is new: the Philly trace analysis of a multi-tenant Microsoft cluster already found DNN training jobs failing on average every 45 minutes~\cite{jeon}.

Synchronous data-parallel training turns each component failure into a whole-job event. Every rank participates in every collective; one unresponsive NCCL peer stalls 16{,}383 others. The infrastructure response has been bifurcated in a way this paper argues is the core architectural mistake of the current stack.

\paragraph{The scheduling half.} Kubernetes was built around one-pod-at-a-time scheduling for stateless services. Gang semantics, where a job needs all-or-nothing placement of $N$ pods, arrived only through external schedulers: Volcano's PodGroups~\cite{volcano}, Kueue's admission and quota layer~\cite{kueue}, YuniKorn~\cite{yunikorn}, and NVIDIA's KAI-Scheduler~\cite{kai}, which adds hierarchical PodGroups, topology-aware scheduling, and DRA support for GB200/GB300-class parts, with public scale tests at thousands of nodes. Upstream Kubernetes itself shipped alpha native gang scheduling only in v1.35 (KEP-4671), and the v1.36 release~\cite{k8s136} extends it with a decoupled Workload and PodGroup API, workload-aware preemption, topology-aware workload scheduling (KEP-5732~\cite{k8skep5732}), DRA ResourceClaim support for workloads, and Job controller integration, all alpha and disabled by default behind feature gates including \texttt{GenericWorkload}, \texttt{GangScheduling}, and \texttt{WorkloadAwarePreemption}. Every one of these systems answers the question ``where should this gang start'' and none of them answers ``what happens at failure number 217 of 419.''

\paragraph{The elasticity half.} TorchElastic~\cite{torchelastic} re-forms the process group through rendezvous and restarts from the last checkpoint. Oobleck~\cite{oobleck} precomputes heterogeneous pipeline templates so a job can reshape onto fewer nodes without a full restart, with a combinatorial guarantee that some template combination covers the survivors, and it beats restart-based baselines such as Bamboo~\cite{bamboo} and Varuna~\cite{varuna} by up to 13.9$\times$. Gemini~\cite{gemini} checkpoints to peer CPU memory with a provably near-optimal placement strategy and recovers more than 13$\times$ faster than remote-storage checkpointing, at per-iteration cadence with no throughput overhead. Parcae~\cite{parcae} and ReCycle~\cite{recycle} extend the family toward preemption-heavy and spare-free environments. Every one of these systems answers ``how do I keep computing after a failure'' from inside the job, blind to the cluster: they cannot see NVLink domains or rail alignment, cannot atomically claim a spare node, and cannot prevent the cluster scheduler from handing their vacated GPUs to someone else mid-recovery.

The seam between the two halves is where correctness and goodput both leak. When a GPU dies today, the elastic layer detects it (slowly, via NCCL timeouts measured in minutes at default settings), tears down, re-rendezvouses, and asks the scheduler for capacity as if it were a brand-new job. The scheduler, which has no concept of ``this is failure recovery for a job whose surviving 16{,}376 ranks occupy a specific rail-aligned footprint,'' places replacements wherever bin-packing lands them, frequently off-rail or across a spine, degrading every subsequent step. Meanwhile nothing in either layer proves that the state the job resumes from is a consistent checkpoint: consistency is a convention enforced by framework code paths that no one has verified. Formal verification has reached Kubernetes controllers, but not this problem: Anvil~\cite{anvil} machine-verified liveness, in the form of eventually stable reconciliation (ESR), for ZooKeeper, RabbitMQ, and FluentBit controllers using the Verus~\cite{verus} SMT-based verifier for Rust, demonstrating the technique but never applying it to a scheduler or a training reconfiguration protocol.

\paragraph{Thesis.} Failure recovery at 10{,}000-GPU scale \emph{is} a scheduling event, and scheduling at that scale \emph{is} a fault-tolerance protocol. A control plane that treats them as one problem makes failure-triggered rescheduling topology-aware (recovering placements as good as initial placements) and provably checkpoint-consistent (recovering states that are guaranteed, not assumed, to be valid), while retaining Kubernetes-native APIs and hardware-generation agnosticism.

\paragraph{Contributions.}
\begin{itemize}[leftmargin=1.2em]
\item[\textbf{C1.}] A formal model of GPU cluster topology as a leveled tree compiled from Kubernetes Dynamic Resource Allocation (DRA) device attributes, making the same algorithms apply unmodified to 8-GPU HGX Ampere/Hopper nodes and 72-GPU Blackwell NVL72 domains (Sections~\ref{sec:model}, \ref{sec:arch}).
\item[\textbf{C2.}] \textsc{HDF-B}, a gang placement algorithm combining hierarchical deepest-fit search with buddy-aligned carving, with three proved properties: per-gang bottleneck optimality (Theorem~\ref{thm:bottleneck}), a factor-2 capacity augmentation admission guarantee (Proposition~\ref{prop:buddy}), and a bounded failure blast radius (Proposition~\ref{prop:blast}). We situate the multi-gang problem against known strong NP-hardness and approximation bounds from parallel-task scheduling and strip packing (Theorem~\ref{thm:hard}).
\item[\textbf{C3.}] The Rank Reformation Protocol (RRP), an epoch-fenced reconfiguration protocol layered on a linearizable store. We give a TLA\textsuperscript{+} specification, prove three safety invariants by induction (checkpoint consistency, exclusive placement, zombie fencing), prove liveness under partial synchrony mapped onto Anvil's ESR shape, and mechanically check safety and liveness with TLC, including a mutation study in which the checker finds the exact contention livelock that the protocol's retry transition exists to prevent (Section~\ref{sec:rrp}).
\item[\textbf{C4.}] Lifecycle unification: planned maintenance, defragmentation, and elastic scale changes are the same epoch transition as failure recovery, so one verified protocol covers the job's entire life, including disaggregated inference gangs (Section~\ref{sec:lifecycle}).
\item[\textbf{C5.}] An executed evaluation combining the TLC verification campaign with a 131{,}072-leaf discrete-event testbed: sub-microsecond median reformation planning, 1.00$\times$ median recovery inflation versus 8.9$\times$ topology-blind, Monte Carlo ETTR within 1.4 points of the renewal model across six configurations, and 100{,}000-transition trace validation with zero divergences (Section~\ref{sec:eval}).
\end{itemize}

\section{Why the current stack cannot close the gap}
\label{sec:gap}

\subsection{Kubernetes' scheduling model versus gang semantics}

The kube-scheduler binds pods one at a time. For a 2{,}048-pod training gang this creates deadlock and starvation modes that are well documented: partial placements hold GPUs hostage while waiting for stragglers, and two half-placed gangs can mutually starve. The scheduling framework's Permit plugin phase (used by the coscheduling plugin, Volcano, and KAI) approximates atomicity by holding pods at the gate until a quorum accumulates, but holding is not reserving: nothing prevents interleavings in which capacity evaporates between the gate opening and binding. The v1.35/v1.36 Workload Aware Scheduling work is Kubernetes' own acknowledgment of the mismatch: it introduces a Workload API and a runtime PodGroup object with a \texttt{gang.minCount} quorum, schedules the PodGroup in a dedicated cycle, and adds group-level preemption~\cite{k8s136}. These primitives are alpha, disabled by default, and cover admission of homogeneous groups. Nothing in the upstream design addresses what happens when a member of a \emph{running} gang dies; the group primitive covers admission, not survival.

\subsection{Topology awareness is bolted on, and recovery ignores it}

Modern training performance is a function of where ranks land relative to three physical tiers. Inside an HGX H100 node, each GPU has 900\,GB/s of aggregate NVLink~4 bandwidth to its seven peers. Leaving the node, each GPU typically owns one 400\,Gb/s NDR NIC, roughly 50\,GB/s, an 18$\times$ cliff. In rail-optimized fabrics, NIC $k$ of every server connects to leaf switch $k$, so communication between equal-indexed GPUs of different servers stays one hop inside a rail, while misaligned pairs traverse the spine. Placement that respects these tiers (tensor-parallel groups inside NVLink domains, data-parallel peers rail-aligned) is the difference between the fabric helping and the fabric being the bottleneck; Volcano's network-topology mode, Kueue's Topology Aware Scheduling, and KAI's TAS all exist because of this, and KAI's hierarchical PodGroups extend it to multi-component workloads in the Grove/Dynamo disaggregated-serving style~\cite{kai}.

Now observe what happens at failure time in every one of these systems: nothing topology-aware. The replacement pod arrives through the generic queue. Kueue's documentation notes DRA resources are not accounted in TAS capacity. Worse, correlated NIC and switch failures in rail-optimized fabrics create \emph{topological fragmentation}, where surviving capacity is plentiful but rail-misaligned, precisely the regime where a topology-blind replacement is most damaging. Recovery placement is a harder instance of the placement problem (placement under a constrained residual topology with a warm-start footprint), and the current stack solves it with the least capable instrument it has.

\subsection{Elastic frameworks cannot fix this from inside the job}

Oobleck's pipeline templates are the strongest prior on the reshaping side, and its guarantee is real but combinatorial: given at least $f{+}1$ template-instantiated pipeline replicas, any $f$ simultaneous failures leave a coverable configuration~\cite{oobleck}. It is not machine-checked, it is not a cluster scheduler (it consumes whatever nodes it is given), and it is not Kubernetes-native. Gemini solves recovery data movement (peer CPU-RAM checkpoints, near-optimal placement of checkpoint replicas, traffic scheduling that hides checkpoint bytes in network idle gaps) but delegates machine replacement to the cloud operator, outside its correctness argument~\cite{gemini}. Singularity~\cite{singularity} made every job preemptible, migratable, and resizable via device proxying, a landmark result, but it is proprietary, not Kubernetes-native, and offers no formal guarantees. MegaScale~\cite{megascale} and ByteRobust~\cite{byterobust} represent the production state of the art in fault localization and rapid isolation at ByteDance (MegaScale reports 55.2\% MFU training a 175B model on 12{,}288 GPUs with automated failure recovery), and Meta's MAST~\cite{mast} does global multi-region placement; all are engineering triumphs whose correctness story is testing, and none makes recovery placement topology-optimal.

\subsection{The gap, stated precisely}

\begin{table}[t]
\centering
\footnotesize
\setlength{\tabcolsep}{3pt}
\begin{tabular}{@{}lcccc@{}}
\toprule
System & \begin{tabular}{@{}c@{}}Topo\\gang\end{tabular} & \begin{tabular}{@{}c@{}}Verified\\reconfig\end{tabular} & \begin{tabular}{@{}c@{}}K8s\\native\end{tabular} & Elastic \\
\midrule
Volcano / Kueue / KAI & yes & no & yes & partial \\
K8s WAS v1.35/1.36 & partial & no & yes & no \\
Oobleck & no & combinat. & no & yes \\
Gemini & no & ckpt only & no & no \\
Singularity & no & no & no & yes \\
TorchElastic & no & no & partial & yes \\
Anvil & no & yes (ESR) & yes & n/a \\
\midrule
\textbf{Phalanx} & \textbf{yes} & \textbf{yes (S+L)} & \textbf{yes} & \textbf{yes} \\
\bottomrule
\end{tabular}
\caption{No prior system satisfies all four properties. ``S+L'' denotes machine-checked safety and liveness.}
\label{tab:gap}
\end{table}

We can find no system, academic or production, that simultaneously satisfies all four columns of Table~\ref{tab:gap}. Anvil is the load-bearing existence proof for the verified column: Kubernetes controllers can be verified for liveness with a proof-to-code ratio its authors report as between 4.5 and 7.4~\cite{anvil}. Nobody has pointed that machinery at the scheduler/recovery seam. Recent preprints (TrainMover~\cite{trainmover} on interruption-resilient runtimes, SPARe~\cite{spare} on 100K-GPU fault-tolerant pretraining) show the community converging on the pain point from the framework side, which sharpens rather than undermines the control-plane gap this paper targets. Section~\ref{sec:related} differentiates in detail. The columns of Table~\ref{tab:gap} summarize each system's design intent as stated in its own documentation and papers; they are not head-to-head measurements against re-implemented baselines, and the only empirically compared baseline in this paper is the topology-blind recovery of Section~\ref{sec:quality}.

\section{System model and problem statement}
\label{sec:model}

\subsection{Topology model}

We model the cluster as a rooted tree $T=(V,E)$ of depth $D$ whose leaves are GPUs and whose internal nodes are bandwidth domains. A reference instantiation for an H100 rail-optimized cluster:

\begin{center}
\footnotesize
\setlength{\tabcolsep}{4pt}
\begin{tabular}{@{}ll@{}}
\toprule
Level & Domain \\
\midrule
0 & GPU (leaf) \\
1 & NVLink/NVSwitch domain (8 leaves HGX, 72 NVL72) \\
2 & server node (coincides with level 1 on HGX) \\
3 & rail group / leaf-switch pod (e.g., 256 GPUs) \\
4 & spine pod (e.g., 2{,}048 GPUs) \\
5 & cluster core \\
\bottomrule
\end{tabular}
\end{center}

Each internal node $v$ has capacity $\mathrm{cap}(v)$, the number of leaves beneath it, and at time $t$ a free count $\mathrm{free}_t(v)$. Each level $\ell$ carries a bandwidth class $\beta(\ell)$, strictly decreasing in $\ell$ (900\,GB/s at level 1, roughly 50\,GB/s per GPU at level 3, oversubscribed above). The distance between leaves $u,v$ is $d(u,v)=\mathrm{level}(\mathrm{lca}(u,v))$. Nothing in the algorithms assumes specific fanouts: the tree is compiled at runtime from DRA ResourceSlice attributes (Section~\ref{sec:arch}), which is what makes the design Ampere/Hopper/Blackwell agnostic. Rails are a labeling $\mathrm{rail}:\mathrm{leaves}\to\{0,\dots,R{-}1\}$ such that equal labels in different level-2 subtrees share a level-3 switch.

\subsection{Job model}

A job $j$ is a tuple $(g_j,\Pi_j,W_j)$: a gang size $g_j$, a finite set of feasible parallelism templates $\Pi_j$ (each a (TP, PP, DP) decomposition with per-group placement constraints, in the spirit of Oobleck's pipeline templates but extended with topology constraints), and a communication weight matrix $W_j(r,r')\ge 0$ over ranks. Templates encode elasticity: a job that can run at 2{,}048 or 1{,}920 ranks lists both, with the understanding, standard since Pollux~\cite{pollux}, that statistical efficiency and not just throughput governs which template is preferable.

Hard constraint: every tensor-parallel group must be contained within one level-1 domain (TP traffic cannot survive the NVLink-to-NIC cliff). Soft objective: data-parallel peers should be rail-aligned.

A placement $\pi_j$ is an injective map from $\mathrm{ranks}(j)$ to free leaves, disjoint across live jobs. Two costs matter:
\begin{align}
B(\pi) &= \max_{(r,r'):\,W(r,r')>0} d(\pi(r),\pi(r')) \label{eq:bottleneck}\\
C(\pi) &= \sum_{(r,r')} W(r,r')\,\gamma\!\left(d(\pi(r),\pi(r'))\right) \label{eq:volume}
\end{align}
with $\gamma$ any increasing per-level cost (for example inverse bandwidth). $B$ captures the level of the worst collective; $C$ captures aggregate fabric load. \textsc{HDF-B} optimizes $B$ exactly per gang and $C$ heuristically; Section~\ref{sec:eval} quantifies the residual volume-cost effect on a hierarchical bandwidth model.

\subsection{Objective}

Following Kokolis et al.~\cite{kokolis}, define ETTR as the ratio of productive training time to scheduled wallclock, and following Pollux~\cite{pollux}, weight throughput by statistical efficiency when templates change size (goodput). The control plane's objective over a horizon with stochastic failures is to maximize expected ETTR subject to placement feasibility, which decomposes into minimizing per-failure lost work (checkpoint cadence times one half, plus recovery latency) and preserving per-step throughput (placement quality) across reconfigurations.

\subsection{Hardness of the placement core}

\begin{theorem}[hardness, known]
\label{thm:hard}
Deciding whether a set of rigid gangs can be scheduled on $m$ identical GPUs within makespan bound $T$ is strongly NP-hard, already for $m\ge 5$ without any topology~\cite{duleung}; with a depth-1 tree the topology-aware problem contains it by restriction, so it is at least as hard. No polynomial algorithm achieves makespan ratio below $3/2$ for arbitrary $m$ unless $\mathrm{P}=\mathrm{NP}$; the best known general ratio is $3/2+\varepsilon$~\cite{jansen}; and the contiguous variant relates to strip packing, where the best known absolute ratio is $5/3+\varepsilon$~\cite{strip}.
\end{theorem}

We therefore do not claim global multi-gang optimality. The design targets provable \emph{per-decision} guarantees (Theorem~\ref{thm:bottleneck}, Propositions~\ref{prop:buddy} and \ref{prop:blast}) plus measured global behavior, the division of labor the hardness landscape permits, mirroring how constant-factor results with placement constraints~\cite{synchpack} bound what any polynomial competitor could do.

\section{Phalanx architecture}
\label{sec:arch}

Phalanx is five cooperating components sharing one source of truth (etcd, accessed through the Kubernetes API server) and one unit of change (the epoch). Figure~\ref{fig:arch} shows the layout.

\begin{figure}[t]
\begin{lstlisting}[style=ascii]
        +----------------------------------+
        |    etcd (Raft, linearizable)     |
        | alloc/{leaf} -> (job, epoch)     |
        | epoch/{job}  -> e, phase         |
        | seal/{job}/{e} -> manifest hash  |
        | lease/{worker} -> TTL            |
        +--^-------^--------^--------^-----+
           |       |        |        |
      +----+--+ +--+----+ +-+-----+ +-+------+
      |Topol- | | Gang  | |Reform-| |Failure |
      |ogy    | |Planner| |ation  | |Detector|
      |Compil-| |(HDF-B)| |Engine | |(leases,|
      |er     | |       | |(RRP)  | | health)|
      |(DRA)  | |       | |       | |        |
      +-------+ +-------+ +-------+ +--------+
       Checkpoint Plane: peer CPU-RAM shards
       + object-store tier, epoch-tagged
\end{lstlisting}
\vspace{-1em}
\caption{Phalanx components around the linearizable store.}
\label{fig:arch}
\end{figure}

\subsection{Topology Compiler}
Every node's DRA driver publishes ResourceSlices whose device attributes include the NVLink/NVSwitch domain identifier, PCIe root, NUMA node, NIC-to-rail index, and GPU generation. DRA went GA in Kubernetes v1.34~\cite{dra} and is the substrate KAI already targets for GB200/GB300-class ComputeResources~\cite{kai}; Phalanx consumes the same attributes and compiles them, plus a cluster-admin fabric description (leaf/spine membership, mirroring the ClusterTopology objects used in the Grove/KAI ecosystem), into the leveled tree $T$ of Section~\ref{sec:model}. The compiler is the only hardware-aware component: an HGX A100 node yields an 8-leaf level-1 domain with a 600\,GB/s NVLink~3 bandwidth class, an HGX H100 node the same shape at 900\,GB/s, and a GB200 NVL72 rack yields a 72-leaf level-1 domain at 1.8\,TB/s with level 2 collapsing into it. Algorithms downstream see only $(T,\mathrm{cap},\mathrm{free},\beta,\mathrm{rail})$.

\subsection{Gang Planner}
Implements \textsc{HDF-B} (Section~\ref{sec:hdfb}) behind two entry points: $\textsc{Place}(j)$ for admission and $\textsc{Replan}(j,F)$ for reformation after failure set $F$. \textsc{Replan} is \textsc{Place} warm-started with the surviving footprint pinned, which is the mechanism by which recovery becomes topology-aware: the planner searches for the cheapest repair, not a fresh placement.

\subsection{Reformation Engine}
Executes RRP (Section~\ref{sec:rrp}): drives the per-job epoch state machine, performs the single-transaction commit that atomically frees dead leaves, claims replacements, and increments the epoch, and coordinates fenced restore. It is a standard controller in the Kubernetes sense (level-triggered reconcile loops on custom resources), which is what makes Anvil's verification methodology directly applicable~\cite{anvil}.

\subsection{Failure Detector}
Two layers. Layer 1 is lease-based liveness: every worker agent maintains a TTL lease in etcd; expiry is the detection event, bounding detection latency by the lease TTL (2 to 5 seconds) rather than NCCL's default multi-minute collective timeout. Layer 2 is proactive health signaling in the MegaScale/ByteRobust tradition~\cite{megascale,byterobust}: agents watch XID events, ECC counters, NIC state, and straggler statistics, and can declare a leaf \emph{Suspect} ahead of hard failure, turning some failures into planned reconfigurations (Section~\ref{sec:lifecycle}). The detector only ever \emph{proposes}; the Reformation Engine's commit is the sole authority that changes allocation, which keeps the correctness argument in one place.

\subsection{Checkpoint Plane}
Epoch-tagged sharded checkpoints, Gemini-style~\cite{gemini}: each rank snapshots to a peer node's CPU RAM every $\tau$ (down to per-iteration cadence, which Gemini demonstrated at zero throughput overhead), with a cold tier in object storage. A checkpoint becomes a \emph{sealed manifest} only via a create-once etcd transaction keyed $(j,e,\mathrm{step})$ after all shard acknowledgments arrive; unsealed shards are garbage. Sealing converts ``a pile of tensors'' into ``a state the protocol may legally resume from,'' and it is the hook on which the checkpoint-consistency invariant hangs.

\subsection{Kubernetes surface}
Three custom resources: \texttt{GangClaim} (desired gang: size, templates, topology policy), \texttt{TopologyPolicy} (alignment level, spare policy), and a status-carried \texttt{Epoch} record per job. Scheduling integrates through the scheduling framework (PreEnqueue gate until quorum, Reserve for tentative carve, Permit for all-or-nothing admission with timeout), interoperating with the v1.36 Workload/PodGroup objects where enabled, and with JobSet/Kubeflow operators as pod producers. Spare capacity is a first-class \texttt{TopologyPolicy} field: reserve $s$ aligned blocks of order $k$ per level-$a$ domain; Proposition~\ref{prop:blast} quantifies what this buys.

\section{HDF-B: hierarchical deepest-fit with buddy alignment}
\label{sec:hdfb}

\subsection{Algorithm}

Sizes are rounded to buddy orders: a request for $g$ leaves becomes order $k=\lceil \log_2 g\rceil$ at the alignment level. The free state is maintained, per internal node, as counts of free \emph{aligned blocks} by order (a block of order $k$ is a fully free subtree slice of $2^k$ leaves aligned to a $2^k$ boundary), with buddy split and coalesce exactly as in the classical allocator, executed on the tree.

\begin{algorithm}[t]
\small
\SetKwFunction{FPlace}{Place}\SetKwFunction{FCarve}{Carve}\SetKwFunction{FReplan}{Replan}
\SetKwProg{Fn}{function}{:}{}
\Fn{\FPlace{$j$}}{
  $k \leftarrow \lceil \log_2 g_j \rceil$\;
  \For{$h \leftarrow h_{\min}(j)$ \KwTo $D$}{
    $S \leftarrow \{v : \mathrm{level}(v){=}h \wedge \mathrm{alignedFree}(v,k){\ge}1 \wedge \mathrm{GroupsFit}(j,v)\}$\;
    \If{$S \neq \emptyset$}{
      $v^\ast \leftarrow \arg\min_{v\in S} \mathrm{residual}(v,k)$\;
      \Return \FCarve{$v^\ast, j, k$}\;
    }
  }
  \Return $\textsc{Queue}(j)$ \tcp*{gang-queued, never partial}
}
\Fn{\FCarve{$v, j, k$}}{
  split free blocks buddy-style until an order-$k$ block $b$ under $v$ exists\;
  assign TP groups to whole level-1 sub-blocks of $b$\;
  order DP peers so equal ranks land on equal rail labels\;
  write alloc records for all leaves of $b$ under $j$'s epoch (txn)\;
  \Return $b$\;
}
\Fn{\FReplan{$j, F$}}{
  \ForEach{maximal allocated block $b_f$ of $j$ meeting $F$, smallest order first}{
    try \FCarve{} in $b_f$'s parent domain using spare blocks\;
    \textbf{else} escalate one level; \textbf{else} fall back to next template in $\Pi_j$\;
  }
}
\caption{\textsc{HDF-B} placement and reformation.}
\label{alg:hdfb}
\end{algorithm}

$h_{\min}(j)$ is the smallest level whose capacity can hold $2^k$, so the scan starts where a solution could first exist. Complexity: with per-order free lists per node, feasibility tests are $O(1)$ per node, the scan touches $O(D)$ levels with subtree-aggregate indices, and split/coalesce is $O(D)$ per operation; \textsc{Replan} for $f$ failures is $O(f\cdot D)$ plus template fallback. Gangs larger than the maximal aligned block are carved as rail-aligned unions of per-pod blocks under the same discipline; the shipped artifact implements this path for 2{,}048-to-8{,}192-rank gangs. At $D=6$ and 131{,}072 leaves this is microseconds of work per decision; Section~\ref{sec:eval} measures it.

\subsection{What HDF-B provably gets right}

\begin{theorem}[per-gang bottleneck optimality]
\label{thm:bottleneck}
Fix the free state and a request $j$ whose hard constraints are satisfiable. Let $h^\ast$ be the level at which \textsc{Place} returns. Then every feasible placement $\pi$ of $j$ has $B(\pi)\ge h^\ast$: the bottleneck communication level is minimized.
\end{theorem}

\begin{proof}
Any placement's leaves have a unique minimal enclosing subtree; by the definition of $d$ as LCA level, $B(\pi)$ equals the level of that subtree. Feasibility of confining $j$ to a subtree rooted at $v$ (an order-$k$ aligned block plus group constraints) is monotone in the tree order: if it holds at $v$ it holds at every ancestor of $v$, since blocks and groups that fit under $v$ fit under $\mathrm{parent}(v)$. \textsc{Place} scans levels in increasing order and returns at the first level containing a feasible root. If some feasible $\pi$ had $B(\pi)=h'<h^\ast$, its enclosing subtree at level $h'$ must appear in $S$ during the scan at $h'$, contradicting that the scan passed $h'$ empty.
\end{proof}

The single caveat is the buddy rounding inside ``feasible'': \textsc{Place} requires an \emph{aligned} order-$k$ block, a stronger condition than $g_j$ free leaves. That is deliberate, and Proposition~\ref{prop:buddy} is the price tag.

\begin{proposition}[buddy invariant and factor-2 augmentation]
\label{prop:buddy}
Under \textsc{Carve} and \textsc{Release} with eager coalescing: (i) at all times the free set is a disjoint union of aligned blocks; (ii) an order-$k$ request is admitted iff some free block of order $\ge k$ exists, so external fragmentation never blocks a request that an aligned free block could serve; (iii) rounding wastes strictly less than $g_j$ capacity per job ($2^k<2g_j$), hence a cluster running \textsc{HDF-B} with capacity $2\cdot\mathrm{Cap}$ admits every job sequence that any allocator, including an offline optimal one, admits with capacity $\mathrm{Cap}$.
\end{proposition}

\begin{proof}
(i) Induction: splits create two aligned buddies of order $k{-}1$; release coalesces with a free buddy recursively, restoring maximality. (ii) Immediate from (i) and the split rule. (iii) Map each job's rounded footprint to at most double its true size; any OPT schedule on $\mathrm{Cap}$ induces an aligned schedule on $2\cdot\mathrm{Cap}$ by doubling each level's fanout and placing each rounded block in the doubled copy of OPT's region, preserving disjointness.
\end{proof}

This is a resource-augmentation guarantee in the standard sense: we buy zero external fragmentation and $O(D)$ operations with at most $2\times$ internal slack, and production gang sizes are already powers of two times the node size, making the slack zero on the dominant workloads.

\begin{proposition}[blast radius]
\label{prop:blast}
Suppose \texttt{TopologyPolicy} reserves at least one spare aligned block of order $k_a$ per level-$(a{+}1)$ domain, where $k_a$ is the block order at alignment level $a$ (for example one spare node per pod). Then for any single leaf failure inside an allocated block $b$ of order $k\le k_a$, \textsc{Replan} commits a repair that (i) migrates at most $2^k$ ranks (the members of $b$), (ii) leaves $B(\pi)$ unchanged, and (iii) leaves every rank outside $b$ untouched.
\end{proposition}

\begin{proof}
The spare block $b'$ lies under the same level-$(a{+}1)$ ancestor as $b$, so replacing $b$ by $b'$ does not raise the enclosing-subtree level of the job's footprint; Theorem~\ref{thm:bottleneck} applied to the local subproblem gives that no cheaper-level repair exists; migration is exactly the reassignment of $b$'s ranks to $b'$; disjointness of blocks gives (iii).
\end{proof}

Proposition~\ref{prop:blast} is the formal version of the design's central practical claim: with modest reserved capacity (one node per pod, 0.39\% in the reference instantiation), the common failure (one GPU, hence one node-block) costs a bounded, topology-neutral, 8-to-72-rank migration instead of either a whole-job restart or an off-rail scatter. When spares are exhausted the escalation path is explicit and still Theorem-\ref{thm:bottleneck}-optimal at each level, and the final fallback is template shrink, Oobleck-style~\cite{oobleck}, which trades ranks for continuity under the same commit discipline.

\subsection{Online behavior}
Against adversarial arrival sequences the lower bounds of Theorem~\ref{thm:hard} apply to every online algorithm, so Phalanx does not advertise a global competitive ratio; Section~\ref{sec:eval} reports admission latency and residual aligned capacity at 90\% utilization, with topology-blind replacement as the recovery baseline, plus the following monotonicity fact: \textsc{Queue}'d gangs are admitted in a topology-feasibility order, and because feasibility is monotone under releases (freeing leaves only grows every $\mathrm{alignedFree}$ count), no gang is starved by churn alone under a fair queue discipline. Starvation by \emph{priority} is delegated to quota layers (Kueue cohorts, KAI queues) unchanged; Phalanx composes below them.

\section{RRP: the Rank Reformation Protocol}
\label{sec:rrp}

\subsection{Protocol overview}

Each job carries a monotonically increasing epoch $e$. All allocation records, worker identities, checkpoint shards, and manifests are tagged with the epoch under which they were created. The life of a failure:

\begin{lstlisting}[style=ascii]
Running(e)
  --Fail(leaf)-->        (lease expires within TTL)
Detect: phase := Plan
  --Replan yields P-->   (HDF-B on residual topology)
Commit: single etcd txn:
  guard: epoch/{j} == (e, Plan)
         AND all leaves in P free-or-mine
  write: alloc updates (free dead block,
         claim spare block)
         epoch/{j} := (e+1, Restore)
  --workers of e+1 start-->
Restore: load newest sealed manifest with
         epoch' <= e; re-form process group;
         fence tokens = e+1
Running(e+1)
\end{lstlisting}

Zombie handling is fencing, not extra consensus: a worker still executing under epoch $e$ presents token $e$ on every externally visible write (checkpoint shard put, manifest seal attempt, gradient publication to any store the control plane mediates); the store's guard rejects tokens older than the current epoch record. Because the epoch record lives in etcd and etcd is linearizable (Raft~\cite{raft}), ``current'' is well defined at every linearization point. When two reforming jobs race for the same spare capacity, the loser's commit guard fails and the protocol retries from Plan; Section~\ref{sec:mech} shows this retry transition is not decoration.

\subsection{TLA\textsuperscript{+} specification}
\label{sec:spec}

Figure~\ref{fig:tla} gives the specification exactly as model-checked (module \texttt{RRP}). Failure quiescence (assumption A2 below) is encoded by the \texttt{MaxFail} bound; residual capacity (A4) is encoded in \texttt{Init}, which grants every job at least $\texttt{MaxFail}+1$ leaves, the same $f{+}1$ shape as Oobleck's coverage condition. The full artifact (\texttt{RRP.tla}, \texttt{RRP.cfg}) accompanies the paper.

\begin{figure*}[t]
\begin{minipage}[t]{0.51\textwidth}
\begin{lstlisting}[style=tla]
---------------- MODULE RRP ----------------
EXTENDS Naturals, FiniteSets
CONSTANTS Job, Leaf, None, MaxFail
VARIABLES live, epoch, phase, alloc,
          sealed, plan, failCount
vars == <<live, epoch, phase, alloc,
          sealed, plan, failCount>>

Assigned(j) == { l \in Leaf : alloc[l] = j }

Feasible(j, P) ==
  /\ P # {}
  /\ P \subseteq live
  /\ \A l \in P : alloc[l] \in {None, j}

CommitGuard(j) ==
  \A l \in plan[j] : alloc[l] \in {None, j}

Init == /\ live = Leaf
        /\ epoch = [j \in Job |-> 0]
        /\ phase = [j \in Job |-> "Run"]
        /\ alloc \in
             { f \in [Leaf -> Job \cup {None}] :
                 \A j \in Job :
                   Cardinality({l \in Leaf :
                     f[l] = j}) >= MaxFail + 1 }
        /\ sealed = [j \in Job |-> {0}]
        /\ plan = [j \in Job |-> {}]
        /\ failCount = 0

Fail(l) == /\ failCount < MaxFail
           /\ l \in live
           /\ live' = live \ {l}
           /\ failCount' = failCount + 1
           /\ UNCHANGED <<epoch, phase, alloc,
                          sealed, plan>>

Detect(j) ==
  /\ phase[j] = "Run"
  /\ Assigned(j) \ live # {}
  /\ phase' = [phase EXCEPT ![j] = "Plan"]
  /\ UNCHANGED <<live, epoch, alloc, sealed,
                 plan, failCount>>
\end{lstlisting}
\end{minipage}\hfill
\begin{minipage}[t]{0.47\textwidth}
\begin{lstlisting}[style=tla]
Plan(j) ==
  /\ phase[j] = "Plan"
  /\ \E P \in SUBSET Leaf :
       /\ Feasible(j, P)
       /\ plan' = [plan EXCEPT ![j] = P]
  /\ phase' = [phase EXCEPT ![j] = "Commit"]
  /\ UNCHANGED <<live, epoch, alloc, sealed,
                 failCount>>

Commit(j) ==
  /\ phase[j] = "Commit" /\ CommitGuard(j)
  /\ alloc' = [l \in Leaf |->
        IF l \in plan[j] THEN j
        ELSE IF alloc[l] = j THEN None
        ELSE alloc[l]]
  /\ epoch' = [epoch EXCEPT ![j] = @ + 1]
  /\ phase' = [phase EXCEPT ![j] = "Restore"]
  /\ UNCHANGED <<live, sealed, plan, failCount>>

Abort(j) ==
  /\ phase[j] = "Commit" /\ ~CommitGuard(j)
  /\ phase' = [phase EXCEPT ![j] = "Plan"]
  /\ UNCHANGED <<live, epoch, alloc, sealed,
                 plan, failCount>>

Seal(j) ==
  /\ phase[j] = "Run"
  /\ sealed' = [sealed EXCEPT
                  ![j] = @ \cup {epoch[j]}]
  /\ UNCHANGED <<live, epoch, phase, alloc,
                 plan, failCount>>

Restore(j) ==
  /\ phase[j] = "Restore"
  /\ \E e \in sealed[j] : e < epoch[j]
  /\ phase' = [phase EXCEPT ![j] = "Run"]
  /\ UNCHANGED <<live, epoch, alloc, sealed,
                 plan, failCount>>

Next == \/ \E l \in Leaf : Fail(l)
        \/ \E j \in Job :
             Detect(j) \/ Plan(j) \/ Commit(j)
             \/ Abort(j) \/ Seal(j) \/ Restore(j)

Fairness == \A j \in Job :
  /\ WF_vars(Detect(j)) /\ WF_vars(Plan(j))
  /\ WF_vars(Commit(j)) /\ WF_vars(Abort(j))
  /\ WF_vars(Restore(j))

Spec == Init /\ [][Next]_vars /\ Fairness
=============================================
\end{lstlisting}
\end{minipage}
\vspace{-0.5em}
\caption{The RRP specification as model-checked. Checked properties: \texttt{TypeOK}, \texttt{SealBound}, \texttt{RunWitness}, \texttt{RestoreReady} (invariants), \texttt{EpochMonotone} (action property), \texttt{ReformLive} (liveness); definitions in Section~\ref{sec:safety} and Section~\ref{sec:live}.}
\label{fig:tla}
\end{figure*}

\subsection{Safety}
\label{sec:safety}

\begin{invariant}[checkpoint consistency]
\label{inv:s1}
For every job, sealed manifests exist only for epochs at or below the current epoch, sealed sets only grow, and a job entering \emph{Run} at epoch $e>0$ has loaded a manifest sealed at some epoch strictly below $e$; every resumed state was durably and completely written under an epoch that is now immutable history. In the specification: $\texttt{SealBound} \equiv \forall j:\ \mathrm{sealed}[j]\neq\emptyset \wedge \forall e\in \mathrm{sealed}[j]: e\le \mathrm{epoch}[j]$, and $\texttt{RunWitness} \equiv \forall j:\ (\mathrm{phase}[j]{=}\text{Run} \wedge \mathrm{epoch}[j]{>}0) \Rightarrow \exists e\in\mathrm{sealed}[j]: e<\mathrm{epoch}[j]$.
\end{invariant}

\begin{proof}
Induction over transitions. \texttt{Init} establishes $\mathrm{sealed}=\{0\}$, $\mathrm{epoch}=0$. \texttt{Fail}, \texttt{Detect}, \texttt{Plan}, \texttt{Abort} touch neither sealed nor epoch. \texttt{Commit} increments epoch, preserving the bound. \texttt{Seal} adds exactly $\mathrm{epoch}[j]$, preserving the bound, and \texttt{Seal}'s guard ($\mathrm{phase}=\text{Run}$) is the specification-level image of implementation fencing (Lemma~\ref{lem:fence}): only workers of the current epoch can seal, so no seal is ever recorded for a superseded epoch after its supersession. \texttt{Restore}'s guard demands the witness, and \texttt{Seal} never removes elements, so the witness persists into \emph{Run}. Induction closes.
\end{proof}

\begin{lemma}[fencing soundness]
\label{lem:fence}
In the implementation, a seal is one etcd transaction whose guard compares the writer's epoch token to \texttt{epoch/\{j\}}; by etcd linearizability there is a total order on these transactions and on the epoch record's value at each point, so a token older than the record can never pass the guard. The specification's Seal-only-in-Run therefore faithfully abstracts the implementation.
\end{lemma}

\begin{invariant}[exclusive placement]
\label{inv:s2}
At all times each leaf is owned by at most one job, and ownership changes are atomic per reformation: the dead block's release and the spare block's claim occur in one transition.
\end{invariant}

\begin{proof}
$\mathrm{alloc}$ is a function, so pointwise exclusivity is structural in the model; the content of the invariant is that concurrent commits cannot interleave into a violation, and that is exactly the transaction guard: $\texttt{Commit}(j)$ requires every claimed leaf be free or already $j$'s and applies release-plus-claim in the same step. In the implementation this step is a single etcd transaction over the alloc keys plus the epoch key; linearizability serializes any two conflicting commits, the loser's guard fails, and \texttt{Abort} routes it back to \texttt{Plan} on fresh state. No state with double ownership or a half-freed footprint is ever visible.
\end{proof}

\begin{invariant}[epoch monotonicity, zombie fencing]
\label{inv:s3}
$\mathrm{epoch}[j]$ is strictly increasing across reformations, and no action bearing an epoch token $e$ can mutate protocol-visible state once $\mathrm{epoch}[j]>e$. In the specification: $\texttt{EpochMonotone} \equiv \Box[\forall j: \mathrm{epoch}'[j]\ge\mathrm{epoch}[j]]_{\mathrm{vars}}$.
\end{invariant}

\begin{proof}
Only \texttt{Commit} changes epoch, by $+1$. Fencing per Lemma~\ref{lem:fence} covers seals; alloc mutations occur only inside \texttt{Commit}, which is guarded on the epoch record itself (the implementation guard $\texttt{epoch/\{j\}} = (e,\text{Plan})$ fails for stale controllers too, so even a partitioned duplicate Reformation Engine replica cannot commit against a superseded epoch).
\end{proof}

Together: a zombie rank from epoch $e$ can burn cycles, but it cannot corrupt the checkpoint lineage (Invariants~\ref{inv:s1}, \ref{inv:s3}), cannot hold or steal leaves (Invariant~\ref{inv:s2}), and cannot influence the state the job resumes from. This is precisely the property that today's TorchElastic-plus-scheduler stacks enforce by convention and timeout tuning, here made a theorem.

\subsection{Liveness}
\label{sec:live}

Liveness cannot be unconditional: perfect failure detection in an asynchronous system is impossible (FLP~\cite{flp}; failure-detector theory~\cite{chandratoueg} is the classical frame), and no protocol can resume a job on capacity that does not exist. The theorem states the minimal assumptions.

\begin{theorem}[reformation liveness]
\label{thm:live}
Assume (A1) partial synchrony: after some global stabilization time, message and processing delays are bounded, so lease expiry detects every dead worker within a known bound; (A2) failure quiescence: from some point on, no further \texttt{Fail} actions occur (Anvil's ESR makes the analogous assumption that the desired state stops changing~\cite{anvil}); (A3) weak fairness of \texttt{Detect}, \texttt{Plan}, \texttt{Commit}, \texttt{Abort}, \texttt{Restore} per the Spec; (A4) residual capacity: after the last failure, $\mathrm{Feasible}(j,P)$ is satisfiable for some template of every affected job. Then every job eventually reaches phase \emph{Run} at some epoch and remains in \emph{Run} thereafter, until the environment changes again. In the specification: $\texttt{ReformLive} \equiv \forall j:\ (\mathrm{phase}[j]\neq\text{Run}) \leadsto (\mathrm{phase}[j]=\text{Run})$.
\end{theorem}

\begin{proof}
After quiescence and stabilization: any job with a dead assigned leaf has \texttt{Detect} enabled forever, so by weak fairness it fires, entering \emph{Plan}. In \emph{Plan}, A4 makes the existential satisfiable, and \textsc{HDF-B} is a terminating witness constructor (finite tree, monotone scan), so \texttt{Plan} fires, entering \emph{Commit}. From \emph{Commit}, exactly one of \texttt{Commit} and \texttt{Abort} is enabled (their guards are complementary); if \texttt{Abort} fires the job replans on fresh state, and its next plan excludes leaves now owned by others, since $\mathrm{Feasible}$ tests current ownership. The number of jobs undergoing reformation after quiescence is finite and each successful commit strictly decreases it, while etcd serialization guarantees at least one of any conflicting pair commits; the standard finite-decreasing-measure argument rules out livelock, so every job's \texttt{Commit} eventually fires. \texttt{Commit} enters \emph{Restore}; Invariant~\ref{inv:s1} gives $\mathrm{sealed}[j]\neq\emptyset$ with a witness below the new epoch, so \texttt{Restore}'s guard holds, weak fairness fires it, and the job is in \emph{Run}. Stability: with no further \texttt{Fail}, \texttt{Detect} is never again enabled, so \emph{Run} is absorbing.
\end{proof}

The shape is deliberately Anvil's ESR shape: once the environment stops changing, the system reaches, and then stays in, the desired state. Beyond the pen-and-paper argument, both the invariants and the liveness property are mechanically checked (next subsection), the implementation-level plan is Verus~\cite{verus} on the Reformation Engine controller following Anvil's controller-model methodology, with MongoRaftReconfig~\cite{mongo} as the precedent that machine-checked safety of a \emph{dynamic reconfiguration} protocol specifically is attainable, and a trace validator replays engine transitions against the TLA\textsuperscript{+} next-state relation: across 100{,}000 randomized transitions of the reference engine it reports zero divergences (Section~\ref{sec:trace}).

\subsection{Mechanized checking}
\label{sec:mech}

We model-check the specification of Figure~\ref{fig:tla} with TLC~\cite{lamport}. Table~\ref{tab:tlc} reports the campaign. The primary configuration uses $|\mathrm{Job}|=2$, $|\mathrm{Leaf}|=7$, $\texttt{MaxFail}=2$, which is the smallest configuration in which commit contention is reachable: initial allocations of shape $3{+}3{+}1$ leave one free leaf that two concurrently reforming jobs can race for. TLC verifies all four invariants, epoch monotonicity, and the \texttt{ReformLive} liveness property over 834{,}050 distinct states (3{,}146{,}990 generated, depth 13) in 3.5 minutes on commodity hardware. A 6-leaf configuration with no free leaf verifies in 14 seconds over 43{,}070 distinct states.

\paragraph{Why small-scope checking is evidence at scale.} Exhaustive checking at $|\mathrm{Job}|=2$, $|\mathrm{Leaf}|=7$ does not by itself verify the protocol at 131{,}072 leaves, and we do not claim it does; the guarantee it provides rests on three structural facts about RRP. First, every invariant in Figure~\ref{fig:tla} is \emph{local}: checkpoint consistency and epoch monotonicity are predicates over a single job's records, and exclusive placement is a predicate over a single leaf's owner, so none references a global count that grows with scale. Second, jobs and leaves are \emph{symmetric} in the specification, no rule distinguishes leaf 3 from leaf 3000 or job A from job B, so any safety violation reachable with $k$ jobs contending for a leaf is reachable with the same $k$ in a two-job neighborhood; the interesting adversarial interleaving is pairwise commit contention, which the $3{+}3{+}1$ configuration already realizes. Third, the liveness argument of Theorem~\ref{thm:live} is a finite-decreasing-measure proof whose measure (the number of jobs not in \emph{Run}) and whose serialization guarantee (etcd commits at least one of any conflicting pair) are both scale-independent, so TLC's confirmation that no livelock exists at small scope checks the same argument the proof makes at any scale. This is the standard small-scope rationale for TLA\textsuperscript{+} models of replicated protocols; the mechanized check guards against a mistake in the invariants or the next-state relation, and the inductive proofs of Section~\ref{sec:rrp} carry the invariants to unbounded size.

The mutation study is the part we consider most instructive. Deleting the \texttt{Abort} transition (and its fairness) from \texttt{Next} yields a specification that still satisfies every safety invariant, but TLC produces a liveness counterexample in 67 seconds: two jobs each lose a leaf, both plan the single free spare, one commits, and the other's commit guard is falsified forever, leaving it stuck in \emph{Commit} while satisfying every safety property along the way. This is the precise failure mode of hold-at-the-gate gang schedulers discussed in Section~\ref{sec:gap}, reproduced by the checker from first principles, and it is why RRP's contended-commit retry is load-bearing rather than defensive.

\begin{table}[t]
\centering
\footnotesize
\setlength{\tabcolsep}{3pt}
\begin{tabular}{@{}lrrl@{}}
\toprule
Configuration & States & Distinct & Result \\
\midrule
2 jobs, 6 leaves, 2 fails & 120{,}000 & 43{,}070 & all pass (14\,s) \\
2 jobs, 7 leaves, 2 fails & 3{,}146{,}990 & 834{,}050 & all pass (3.5\,m) \\
7 leaves, \texttt{Abort} deleted & & & liveness cex (67\,s) \\
\bottomrule
\end{tabular}
\caption{TLC campaign. ``All pass'' covers \texttt{TypeOK}, \texttt{SealBound}, \texttt{RunWitness}, \texttt{RestoreReady}, \texttt{EpochMonotone}, and \texttt{ReformLive}; ``cex'' is a machine-found counterexample trace.}
\label{tab:tlc}
\end{table}

\section{One protocol for the whole lifecycle}
\label{sec:lifecycle}

Once reformation is an epoch transition with a verified commit, every lifecycle event becomes the same transition with a different trigger.

\paragraph{Planned maintenance and rollouts.} Draining a node is \texttt{Detect} with a \emph{Suspect} verdict instead of a lease expiry: the same \textsc{Replan}, the same commit, executed \emph{before} the hardware dies, so the sealed manifest is seconds old and lost work approaches zero. Meta's data makes this the highest-leverage path: a large share of interruptions are precursor-signaled (ECC accumulation, thermal excursions, XID patterns)~\cite{kokolis,llama3}, and health-triggered proactive reformation converts them from unplanned three-hour-MTBF events into planned near-zero-cost ones. ByteRobust's production philosophy, isolate fast and diagnose later~\cite{byterobust}, drops into the Suspect verdict cleanly.

\paragraph{Defragmentation.} Aligned-fragmentation pressure (many small free blocks, no large ones) triggers a background reformation of the cheapest-to-move job into a consolidating placement, under the exact same commit and fencing rules, so defragmentation can never corrupt a job. This is consolidation as KAI and Volcano practice it, with a proof that it is safe to apply to a \emph{running} training job.

\paragraph{Elastic scale changes and inference gangs.} Template switches (grow when capacity frees, shrink under pressure) are epoch transitions. Disaggregated inference (prefill/decode pools in the Dynamo/Grove style) maps onto hierarchical gangs whose reformation on failure follows RRP unchanged; the checkpoint plane degenerates to model-weight manifests, and Invariant~\ref{inv:s1} becomes the guarantee that a reformed decode pool never serves from a partially loaded snapshot.

The unification claim, precisely: Phalanx has exactly one code path and one proof obligation for placement change, and Sections~\ref{sec:hdfb} and \ref{sec:rrp} discharged it once for all triggers.

\section{Evaluation}
\label{sec:eval}

The evaluation has four executed legs: the TLC verification campaign of Section~\ref{sec:mech}, and three experiments on \textsf{phalanx-sim}, a discrete-event testbed that instantiates the Section~\ref{sec:model} model at full scale: 131{,}072 leaves arranged as 8 GPUs per node, 32 nodes per rail group, 8 rail groups per pod, and 64 pods; per-GPU bandwidth tiers of 900, 50, 12.5, and 6.25\,GB/s at the node, rail, pod, and cluster levels; the buddy allocator, \textsc{Place}, \textsc{Replan}, the RRP engine, a hierarchical alpha-beta collective cost model (4\,GB per GPU per step of tensor-parallel activation traffic; bf16 gradient shards of a 70B-parameter model at TP\,8), one spare node per pod (0.39\% of capacity), and Poisson failure injection. Every number below is the output of the shipped artifact (\texttt{phalanx-sim.py}), executed on a single x86-64 core under CPython~3.12 with \texttt{perf\_counter\_ns} timing.

\subsection{Renewal model and Monte Carlo validation}
\label{sec:ettr}

Failures arrive as a renewal process with mean time between failures $M$; each cycle ends in a recovery of duration $R$; within a cycle the job pays checkpoint overhead fraction $c$ and loses $\tau/2$ of progress on average at the cut, where $\tau$ is the checkpoint interval. Then
\begin{equation}
\mathrm{ETTR} \;=\; \frac{M\,(1-c) \;-\; \tau/2}{M + R}.
\label{eq:ettr}
\end{equation}
Scaling: $M(N)=M_{\mathrm{gpu}}/N$ with $M_{\mathrm{gpu}}=50{,}000$ hours per GPU, which reproduces the observed Llama~3 rate to within 1.4\% ($M(16{,}384)=183.1$ minutes against the observed $54\ \text{days}/419 = 185.6$ minutes~\cite{llama3}). The testbed runs 1{,}000 independent 54-day failure-injected executions per configuration, with recovery durations drawn as truncated Gaussians ($R \sim \mathcal{N}(75\,\mathrm{s}, 10\,\mathrm{s})$ for Phalanx, $\mathcal{N}(900\,\mathrm{s}, 120\,\mathrm{s})$ for restart-based designs) and checkpoints on the $\tau$ grid. Table~\ref{tab:ettr} reports both the closed form and the measured Monte Carlo means. The measured values sit within 1.4 points of Equation~\ref{eq:ettr} in every configuration; the largest deviation ($+0.013$) is the 131K restart baseline, where multi-failure pileups and checkpoint-grid effects are strongest, and every Phalanx configuration lands within 0.15 points of the model.

\begin{table}[t]
\centering
\footnotesize
\setlength{\tabcolsep}{2.6pt}
\begin{tabular}{@{}llrrrrr@{}}
\toprule
$N$ & Design & $\tau$ & $c$ & $R$ & Model & Measured \\
\midrule
16{,}384 & Restart, remote ckpt & 30\,m & 0.010 & 15\,m & 0.839 & 0.843 \\
16{,}384 & Aggressive remote & 10\,m & 0.030 & 15\,m & 0.871 & 0.873 \\
16{,}384 & \textbf{Phalanx} & 2.5\,m & 0.007 & 75\,s & 0.979 & \textbf{0.980} \\
\midrule
131{,}072 & Aggressive remote & 10\,m & 0.030 & 15\,m & 0.454 & 0.467 \\
131{,}072 & \textbf{Phalanx} & 2.5\,m & 0.007 & 75\,s & 0.890 & \textbf{0.891} \\
131{,}072 & \textbf{Phalanx}, $\tau{=}1$\,m & 1\,m & 0.010 & 75\,s & 0.918 & \textbf{0.918} \\
\bottomrule
\end{tabular}
\caption{Equation~\ref{eq:ettr} against measured Monte Carlo means (1{,}000 runs of 54 days each; 95\% confidence intervals are at most $\pm 0.0005$). $M(16{,}384)=183.1$\,min; $M(131{,}072)=22.9$\,min.}
\label{tab:ettr}
\end{table}

The Phalanx recovery budget $R=75$\,s decomposes as: detection $\le 5$\,s (lease TTL), \textsc{Replan} $<1$\,s (measured below at three orders of magnitude under that), commit $<0.1$\,s (one etcd transaction), pod start on a warm spare $\approx 10$\,s, peer-RAM state restore 30 to 50\,s for 405B-class sharded state (consistent with Gemini's measured $>13\times$ recovery advantage over remote storage~\cite{gemini}), and NCCL re-initialization 10 to 20\,s. Model scope: failures Poisson and independent, one repair at a time per job, spares present per Proposition~\ref{prop:blast}, and $c$ independent of $N$, which holds for peer-RAM cadence per Gemini and fails for remote-storage cadence, which is exactly why the restart baseline collapses at 131K. The structural conclusion: at 131K scale both $R$ and $\tau/2$ are compared against a 23-minute $M$, and only a design that drives both to tens of seconds keeps ETTR at production targets. Kokolis et al.\ reach the same structural conclusion from Meta's fleet data~\cite{kokolis}.

\subsection{Sensitivity to the recovery model}
\label{sec:sensitivity}

The single-point ETTRs of Table~\ref{tab:ettr} are conditioned on assumed recovery-time and checkpoint parameters, so the honest question is not whether 0.891 is exact but whether the qualitative conclusion survives across the plausible range of those assumptions. We sweep them directly. Table~\ref{tab:sens} sweeps the recovery time $R$ from 30\,s to 1{,}800\,s at both scales, holding $\tau=2.5$\,min; each cell is a Monte Carlo mean over 500 runs of 54 days. The structure is monotone and smooth, with no cliff near the assumed operating point, and it separates the two scales cleanly: at 16{,}384 GPUs ETTR stays above 0.90 even at a 15-minute recovery, because the 183-minute mean time between failures absorbs a slow recovery, whereas at 131{,}072 GPUs, where the mean time between failures is 23 minutes, ETTR degrades steeply with $R$, which is the entire argument for driving recovery to tens of seconds at scale. A parallel sweep of the checkpoint interval $\tau$ from 0.5 to 30\,min (with overhead $c$ scaled to cadence, $R=75$\,s) shows the same pattern: at 131{,}072 GPUs ETTR falls from 0.934 at $\tau=0.5$\,min to 0.436 at $\tau=30$\,min, so fast in-memory checkpointing is as load-bearing as fast recovery, and both are properties the renewal model exposes rather than assumes.

The crossover makes the robustness precise. Fixing the restart baseline at its Table~\ref{tab:ettr} operating point (measured ETTR 0.468 at 131{,}072 GPUs), a fast-recovery design with $\tau=2.5$\,min matches or beats that baseline for every recovery time up to $R=1{,}410$\,s, a 23.5-minute margin over the 75-second budget the Phalanx recovery path actually targets. In other words, the conclusion that in-memory reformation dominates restart at 131K scale does not depend on the specific 75-second budget being achieved: it holds with more than an order of magnitude of slack, and only reverses if the reformation path is itself degraded to restart-like latency. The remaining sensitivity is to the failure rate $M$, which is not assumed but calibrated to the measured Llama~3 interruption count (Section~\ref{sec:ettr}); a fleet with a lower failure rate shifts every row of Table~\ref{tab:sens} upward and widens the crossover margin further.

\begin{table}[t]
\centering
\footnotesize
\setlength{\tabcolsep}{5pt}
\begin{tabular}{@{}rrr@{}}
\toprule
Recovery $R$ & ETTR at 16K & ETTR at 131K \\
\midrule
30\,s   & 0.984 & 0.920 \\
75\,s   & 0.980 & 0.891 \\
120\,s  & 0.976 & 0.864 \\
300\,s (5\,min)  & 0.960 & 0.771 \\
600\,s (10\,min) & 0.935 & 0.654 \\
900\,s (15\,min) & 0.912 & 0.568 \\
1{,}800\,s (30\,min) & 0.847 & 0.407 \\
\bottomrule
\end{tabular}
\caption{Monte Carlo ETTR (500 runs of 54 days) as the assumed recovery time $R$ varies, at $\tau=2.5$\,min. The 75\,s row reproduces the Phalanx points of Table~\ref{tab:ettr}; the conclusion that recovery latency dominates ETTR at 131K scale is robust across the full range.}
\label{tab:sens}
\end{table}

\subsection{Reformation latency and residual capacity}
\label{sec:latency}

The testbed fills the 131{,}072-leaf tree to 90.4\% job utilization with 260 gangs of 32 to 8{,}192 ranks; the largest residual aligned free block after fill has order 9, and every pod retains its spare node. \textsc{Place} costs 1.5\,$\mu$s at the median and 65.9\,$\mu$s at p99 (the tail contains rejected-and-rolled-back multi-pod carve attempts). Over 10{,}000 injected node failures, \textsc{Replan} answers in 0.3\,$\mu$s at the median, 0.9\,$\mu$s at p99, and 39.0\,$\mu$s at worst, and every repair migrates exactly 8 ranks, the Proposition~\ref{prop:blast} bound at node granularity. The bottleneck level is preserved in 62.2\% of repairs across the full job mix; the non-preserved remainder is precisely the rail-span class (gangs of 32 to 256 ranks whose pod-level spare raises their data-parallel tier from rail to pod), matching the conditional structure of Proposition~\ref{prop:blast}: preservation is unconditional for single-node gangs and for gangs whose span already reaches the spare's domain, and conditional on residual same-rail capacity in between.

\subsection{Recovery placement quality}
\label{sec:quality}

Over 2{,}000 recovery events on gangs of at least 64 ranks, \textsc{Replan} is compared against topology-blind replacement (eight random free leaves, the behavior of a generic scheduler receiving a recovery pod like any other pod) on the hierarchical cost model. Table~\ref{tab:quality} gives the result. Phalanx holds median step-communication inflation to exactly 1.000 because the failed tensor-parallel group is always repaired contiguously on a spare node; its p95 of 3.98 is the rail-to-pod data-parallel escalation of the rail-span class identified above. Blind replacement scatters the failed tensor-parallel group across the cluster tier, dropping that collective from 900 to 6.25\,GB/s, a ratio fixed by the published NVLink~4 and NDR-fabric bandwidths of Section~\ref{sec:gap} rather than a fitted parameter, which yields median inflation of 8.89$\times$ and preserves the bottleneck level in only 5.8\% of events (mostly gangs whose span is already the full cluster).

\begin{table}[t]
\centering
\footnotesize
\setlength{\tabcolsep}{4pt}
\begin{tabular}{@{}lrrr@{}}
\toprule
Recovery & Median infl. & p95 infl. & Level preserved \\
\midrule
\textbf{Phalanx \textsc{Replan}} & \textbf{1.000} & 3.98 & \textbf{77.9\%} \\
Topology-blind & 8.89 & 8.98 & 5.8\% \\
\bottomrule
\end{tabular}
\caption{Step-communication inflation of the repaired placement relative to the pre-failure placement, and bottleneck-level preservation, over 2{,}000 recovery events at 90.4\% utilization.}
\label{tab:quality}
\end{table}

\subsection{Trace validation}
\label{sec:trace}

A reference RRP engine executes randomized runs covering failures, detection, planning, contended commits, aborts, seals, and restores; an independent checker implements the specification's next-state relation and validates every transition. Across 100{,}000 transitions at 4 jobs, 32 leaves, and up to 6 failures, the checker reports zero divergences between the engine and the specification of Figure~\ref{fig:tla}.

\section{Related work}
\label{sec:related}

\paragraph{Cluster schedulers.} Volcano~\cite{volcano}, YuniKorn~\cite{yunikorn}, and Kueue~\cite{kueue} established gang admission, queues, and quota on Kubernetes; KAI~\cite{kai} adds hierarchical gangs, topology awareness, fractional GPUs, and DRA-based Blackwell support, and is the closest scheduling-side system, but its recovery story is best-effort resubmission and it carries no correctness proofs. Upstream Workload Aware Scheduling~\cite{k8s136} is admission-side and alpha. MAST~\cite{mast} schedules across regions at Meta; Pathways~\cite{pathways} gang-schedules accelerator islands under a single controller for TPUs; Singularity~\cite{singularity} made preemption, migration, and resize universal via device proxies. None makes failure-time replacement topology-optimal, none is verified, and the latter three are not Kubernetes-native. Pollux~\cite{pollux} contributed the goodput objective this paper adopts.

\paragraph{Elastic and fault-tolerant training.} TorchElastic~\cite{torchelastic}, Bamboo~\cite{bamboo}, Varuna~\cite{varuna}, Oobleck~\cite{oobleck}, Parcae~\cite{parcae}, ReCycle~\cite{recycle}, ElasticDL, TrainMover~\cite{trainmover}, and SPARe~\cite{spare}. Phalanx's \textsc{Replan}-with-templates generalizes Oobleck's reshaping into the cluster scheduler, where it can see topology and claim hardware atomically, and RRP supplies what all of these lack: machine-checked safety and liveness of the reconfiguration itself.

\paragraph{Checkpointing.} CheckFreq~\cite{checkfreq} tuned cadence; Gemini~\cite{gemini} moved checkpoints to peer CPU RAM with provably near-optimal replica placement and interference-free traffic scheduling; just-in-time checkpointing~\cite{jit} bounds lost work via DP redundancy. Phalanx adopts Gemini's data plane and adds the sealing transaction that turns checkpoint durability into a protocol invariant (Invariant~\ref{inv:s1}) rather than a convention.

\paragraph{Reliability at scale.} The Llama~3 report~\cite{llama3}, Kokolis et al.~\cite{kokolis}, Jeon et al.~\cite{jeon}, MegaScale~\cite{megascale}, ByteRobust~\cite{byterobust}, and the NSDI 2025 fault-localization line (Minder, Holmes)~\cite{minder} quantify and diagnose the failure regime; Phalanx is a control-plane answer to the regime they document.

\paragraph{Formal methods.} Anvil~\cite{anvil} (ESR via Verus~\cite{verus} with a TLA embedding) is the direct methodological ancestor; MongoRaftReconfig~\cite{mongo} demonstrated machine-checked safety for dynamic reconfiguration; Lamport's TLA\textsuperscript{+} and TLC~\cite{lamport} are the specification substrate; FLP~\cite{flp} and failure-detector theory~\cite{chandratoueg} delimit what liveness can promise; Raft's linearizability~\cite{raft} underwrites the etcd assumptions. Phalanx is, to our knowledge, the first application of this toolchain to the gang-scheduling/recovery seam.

\paragraph{Simulation.} ASTRA-sim~3.0~\cite{astrasim} and SimAI~\cite{simai} define the packet-level fidelity frontier, Vidur~\cite{vidur} its inference-side counterpart, and KWOK~\cite{kwok} the control-plane emulation frontier; \textsf{phalanx-sim} occupies the layer between them: model-faithful, full-scale, and fast enough for statistical campaigns of thousands of simulated cluster-days.

\section{Discussion}
\label{sec:discussion}

The formal results are per-decision and protocol-level; global multi-tenant optimality is NP-hard (Theorem~\ref{thm:hard}) and Phalanx's global behavior is quantified empirically in Section~\ref{sec:eval}. The liveness theorem's capacity assumption A4 is a real operational constraint: a cluster at full allocation with zero spares gets template shrink or queueing, and Proposition~\ref{prop:blast} prices the spare pool that avoids this; the measured preservation split of Section~\ref{sec:latency} makes the price concrete, since per-pod spares at 0.39\% capacity preserve the bottleneck unconditionally only outside the rail-span class. The buddy discipline's factor-2 augmentation is a worst case that production power-of-two gang mixes do not pay. Communicator state inside collectives is torn down and rebuilt at reformation; TrainMover-style communicator-preserving migration~\cite{trainmover} composes with RRP's epochs through the same commit discipline. Carrying the TLC-checked specification to Verus-verified controller code follows Anvil's path~\cite{anvil}, and the trace validator of Section~\ref{sec:trace} supplies the refinement scaffolding between the two layers. The fault model is crash-stop plus fenced zombies; Byzantine workers are out of scope.

\section{Conclusion}

The argument compresses to one sentence: at modern scale, failure recovery is scheduling, and the industry runs the two through different subsystems with no shared correctness story. Phalanx unifies them behind one epoch, proves the placement decisions locally optimal and the reconfiguration protocol safe and live under stated assumptions, checks those proofs mechanically, including a machine-found counterexample for the natural but wrong protocol variant, stays inside Kubernetes' native extension surface, treats Ampere, Hopper, and Blackwell as parameters of one topology tree, and ships its evaluation as an executable artifact that anyone can rerun or refute. The gap it fills is documented in the systems it cites: schedulers that stop caring after admission, elastic frameworks that cannot see the fabric, and a verification literature that proved the tools work but had not yet aimed them here.

\begin{thebibliography}{43}
\footnotesize
\bibitem{llama3} A.~Grattafiori et al. The Llama 3 Herd of Models. arXiv:2407.21783, 2024. \url{https://arxiv.org/abs/2407.21783}
\bibitem{tomshw} Tom's Hardware. Faulty Nvidia H100 GPUs and HBM3 memory caused half of failures during Llama 3 training. July 2024. \url{https://www.tomshardware.com/tech-industry/artificial-intelligence/faulty-nvidia-h100-gpus-and-hbm3-memory-caused-half-of-the-failures-during-llama-3-training-one-failure-every-three-hours-for-metas-16384-gpu-training-cluster}
\bibitem{kokolis} A.~Kokolis, M.~Kuchnik, et al. Revisiting Reliability in Large-Scale Machine Learning Research Clusters. HPCA 2025, pp. 1259-1274. \url{https://arxiv.org/abs/2410.21680}
\bibitem{jeon} M.~Jeon et al. Analysis of Large-Scale Multi-Tenant GPU Clusters for DNN Training Workloads. USENIX ATC 2019. \url{https://www.usenix.org/conference/atc19/presentation/jeon}
\bibitem{megascale} Z.~Jiang et al. MegaScale: Scaling Large Language Model Training to More Than 10,000 GPUs. NSDI 2024.
\bibitem{byterobust} ByteRobust: large-scale GPU infrastructure management at ByteDance. SOSP 2025.
\bibitem{anvil} X.~Sun et al. Anvil: Verifying Liveness of Cluster Management Controllers. OSDI 2024. \url{https://www.usenix.org/conference/osdi24/presentation/sun-xudong}
\bibitem{verus} A.~Lattuada et al. Verus: Verifying Rust Programs Using Linear Ghost Types. OOPSLA 2023.
\bibitem{mongo} W.~Schultz, I.~Dardik, S.~Tripakis. Formal Verification of a Distributed Dynamic Reconfiguration Protocol. arXiv:2102.11960.
\bibitem{lamport} L.~Lamport. Specifying Systems: The TLA+ Language and Tools. Addison-Wesley, 2002.
\bibitem{flp} M.~Fischer, N.~Lynch, M.~Paterson. Impossibility of Distributed Consensus with One Faulty Process. JACM, 1985.
\bibitem{chandratoueg} T.~Chandra, S.~Toueg. Unreliable Failure Detectors for Reliable Distributed Systems. JACM, 1996.
\bibitem{raft} D.~Ongaro, J.~Ousterhout. In Search of an Understandable Consensus Algorithm. USENIX ATC 2014.
\bibitem{oobleck} I.~Jang, Z.~Yang, Z.~Zhang, X.~Jin, M.~Chowdhury. Oobleck: Resilient Distributed Training of Large Models Using Pipeline Templates. SOSP 2023. \url{https://dl.acm.org/doi/10.1145/3600006.3613152}
\bibitem{gemini} Z.~Wang et al. Gemini: Fast Failure Recovery in Distributed Training with In-Memory Checkpoints. SOSP 2023. \url{https://dl.acm.org/doi/10.1145/3600006.3613145}
\bibitem{checkfreq} J.~Mohan, A.~Phanishayee, V.~Chidambaram. CheckFreq: Frequent, Fine-Grained DNN Checkpointing. FAST 2021. \url{https://www.usenix.org/conference/fast21/presentation/mohan}
\bibitem{jit} Just-in-time checkpointing for large model training. EuroSys 2024.
\bibitem{bamboo} J.~Thorpe et al. Bamboo: Making Preemptible Instances Resilient for Affordable Training of Large DNNs. NSDI 2023.
\bibitem{varuna} S.~Athlur et al. Varuna: Scalable, Low-Cost Training of Massive Deep Learning Models. EuroSys 2022.
\bibitem{parcae} J.~Duan et al. Parcae: Proactive, Liveput-Optimized DNN Training on Preemptible Instances. NSDI 2024.
\bibitem{recycle} ReCycle: Resilient Training of Large DNNs Using Pipeline Adaptation. SOSP 2024. \url{https://dl.acm.org/doi/10.1145/3694715.3695960}
\bibitem{torchelastic} PyTorch project. torch.distributed.elastic documentation.
\bibitem{pollux} A.~Qiao et al. Pollux: Co-adaptive Cluster Scheduling for Goodput-Optimized Deep Learning. OSDI 2021.
\bibitem{pathways} P.~Barham et al. Pathways: Asynchronous Distributed Dataflow for ML. MLSys 2022.
\bibitem{mast} A.~Choudhury et al. MAST: Global Scheduling of ML Training across Geo-Distributed Datacenters at Hyperscale. OSDI 2024. \url{https://www.usenix.org/system/files/osdi24-choudhury.pdf}
\bibitem{singularity} D.~Shukla et al. Singularity: Planet-Scale, Preemptive and Elastic Scheduling of AI Workloads. arXiv:2202.07848, 2022.
\bibitem{volcano} Volcano batch scheduler. \url{https://volcano.sh/}
\bibitem{kueue} Kueue: Kubernetes-native job queueing. \url{https://kueue.sigs.k8s.io/}
\bibitem{yunikorn} Apache YuniKorn. \url{https://yunikorn.apache.org/}
\bibitem{kai} NVIDIA KAI-Scheduler (CNCF sandbox). \url{https://github.com/NVIDIA/KAI-Scheduler}
\bibitem{k8s136} Kubernetes v1.36: Advancing Workload-Aware Scheduling. Kubernetes blog, May 2026. \url{https://kubernetes.io/blog/2026/05/13/kubernetes-v1-36-advancing-workload-aware-scheduling/}
\bibitem{k8skep5732} Kubernetes Enhancement Proposal KEP-5732: Topology-Aware Workload Scheduling. kubernetes/enhancements, SIG Scheduling, 2025-2026. \url{https://github.com/kubernetes/enhancements/tree/master/keps/sig-scheduling/5732-topology-aware-workload-scheduling}
\bibitem{dra} Kubernetes documentation: Dynamic Resource Allocation. \url{https://kubernetes.io/docs/concepts/scheduling-eviction/dynamic-resource-allocation/}
\bibitem{kwok} KWOK: Kubernetes WithOut Kubelet. \url{https://kwok.sigs.k8s.io/}
\bibitem{astrasim} W.~Won et al. ASTRA-sim 3.0: Next-Level Distributed Machine Learning Simulations via High-Fidelity GPU and Infrastructure Modeling. arXiv:2606.10440, 2026. \url{https://arxiv.org/abs/2606.10440}
\bibitem{simai} X.~Wang et al. SimAI: Unifying Architecture Design and Performance Tuning for Large-Scale LLM Training with Scalability and Precision. NSDI 2025. \url{https://www.usenix.org/conference/nsdi25/presentation/wang-xizheng-simai}
\bibitem{vidur} A.~Agrawal et al. Vidur: A Large-Scale Simulation Framework for LLM Inference. MLSys 2024.
\bibitem{duleung} J.~Du, J.~Leung. Complexity of Scheduling Parallel Task Systems. SIAM Journal on Discrete Mathematics, 1989.
\bibitem{jansen} K.~Jansen. A (3/2 + eps) Approximation Algorithm for Scheduling Moldable and Non-Moldable Parallel Tasks; see also K.~Jansen, R.~Thoele, Approximation Algorithms for Scheduling Parallel Jobs, SIAM Journal on Computing, 2010.
\bibitem{strip} R.~Harren, K.~Jansen, L.~Praedel, R.~van Stee. A (5/3 + eps)-Approximation for Strip Packing. Computational Geometry, 2014.
\bibitem{synchpack} SynchPack: constant-factor approximation for synchronized packing with placement constraints. arXiv preprint.
\bibitem{trainmover} Z.~Lao et al. TrainMover: An Interruption-Resilient and Reliable ML Training Runtime. arXiv:2412.12636.
\bibitem{spare} J.~Lee, Z.~Chen, X.~He, R.~Underwood, B.~Nicolae, F.~Cappello, X.~Lu, S.~Di, and Z.~Zhang. SPARe: Stacked Parallelism with Adaptive Reordering for Fault-Tolerant LLM Pretraining Systems with 100k+ GPUs. arXiv:2603.00357, 2026.
\bibitem{minder} Minder: Faulty Machine Detection for Large-scale Distributed Model Training; Holmes: Localizing Irregularities in LLM Training. NSDI 2025. \url{https://www.usenix.org/conference/nsdi25/technical-sessions}
\end{thebibliography}

\end{document}
