Audit of the Fifteen

You specified the project list. I designed to it and never asked whether it was the right list — which is a question upstream of every other decision in the track.

This page is that audit: what the fifteen cover, what they redundantly cover, what they do not cover, and which of the gaps actually matter for the stated goal.

Conclusion first: the list is good, with one real redundancy and three real gaps, of which only one is worth acting on now.


Table of Contents


The Coverage Map

Thirteen fundamental mechanisms in systems work, against the projects that build them. = built by hand. = touched but not built.

MechanismP01P02P03P04P05P06P07P08P09P10P11P12P13P14P15
Cache / memory hierarchy
Durability & crash recovery
Concurrency & synchronisation
Partial failure / consensus
Scheduling
Approximation with a bound
Dispatch & interpretation
Memory management / GC
Compilation / IR
Data movement & locality
Statistical inference
Measurement & experiment design
Protocol / wire format

Every row has at least one ●. Measurement is universal, which is the design intent — it is the one skill the whole track exists to build, and it is trained fifteen times.

Best-covered: data movement (7 projects), durability (4), approximation (6). Those are the right three to over-cover for someone building retrieval and storage systems.

Thinnest: protocol/wire format (1 solid), scheduling (2), compilation (2).


What Is Covered Twice

Redundancy is not automatically waste — repetition in different contexts is how a lesson generalises. But two cases are worth naming.

P06 and P07 share more than they should

Both build: a coordinator, a worker pool, task/operator scheduling, a partitioned shuffle or network partitioner, failure detection and retry, and checkpoint/recovery. P07's page even says the scheduler "generalises" from P06.

P06P07Genuinely distinct?
Coordinator + workersNo
Partitioning / shuffleMostly no
Fault tolerance via re-execution
Fault tolerance via checkpointingYes
Bounded vs unbounded inputYes — the real difference
Event time, watermarks, windowingYes, and it is P07's whole point
Stragglers / speculative executionYes, and it is P06's

The honest reading: ~40% of the two projects overlaps, and the distinct 60% is where each project's value lives. 176 hours for 60% novelty is the weakest hours-per-lesson ratio in the portfolio.

The existing scope cut — build P07 as an extension of P06's runtime, saving 2 weeks — addresses this partially. The stronger version is to make it the default rather than a fallback: build one distributed execution runtime, then run it in two modes. You would save ~4 weeks and lose nothing but the experience of building a second coordinator, which you will have just built.

P03 and P04 both build persistence

P03 builds a naive append-only store; P04 builds a proper LSM. This is deliberate redundancy and it is correct — it is the roadmap's most explicit application of "naive design first", and it costs about six hours of rework on purpose. P03's measured recovery time is what makes P04 feel necessary rather than academic.

Not a defect. Leave it.


What Is Not Covered At All

Nine mechanisms a systems engineer might reasonably be expected to have built, absent from the list.

AbsentWhat it would teachVerdict
Networking below RPC — TCP state machine, congestion control, a userspace stackFlow control, retransmission, the actual behaviour under loss that P05 only simulatesReal gap. See below
Code generation — SSA, register allocation, native emissionThe other half of compilation. P11 stops at a bytecode VM by designReal gap, deliberately deferred
Concurrency primitives from scratch — lock-free queue, MCS lock, epoch reclamationMemory ordering as something you implement rather than useReal gap. Smallest and cheapest to close
Query processing — parsing, planning, optimisation, executionThe layer above P03/P04's storageCorrectly excluded. A whole second journey
Transactions / MVCC — isolation levels, conflict detectionWhy serializable is expensivePartly covered (P03 snapshots, P05 linearizability). Acceptable
Compression — entropy coding, dictionary methodsA real column in the RUM trade-offMentioned in P04, not built. Minor
Security & isolation — capabilities, sandboxing, side channelsA different threat model to P12's basic isolationOut of scope for the stated goal
Observability — tracing, sampling, cardinalityOnly appears as P15 instrumentationYou do this professionally. Low marginal value
Distributed training — data/tensor/pipeline parallelismWhere ML meets distributed systemsNeeds P13 and P05. A strong post-journey project

The Three Gaps That Matter

Ranked by how much they weaken the stated goal.

1. Concurrency primitives from scratch — the cheapest to close

What is missing. You use atomics and mutexes across P05–P07 and P12, and measure them in numbers §4. You never build one. Memory ordering, ABA, and safe reclamation stay theoretical.

Why it matters here. P12 is single-core by design, so the one project that would naturally force this is scoped to avoid it. That is a defensible scoping decision that leaves a hole.

Cost to close: 2–3 weeks. A Small project: a lock-free MPSC queue, a ticket lock and an MCS lock, benchmarked under contention from 1 to N threads, with the crossover found.

Where it fits. As P12's extension, which already names "synchronisation shoot-out" — promote it from optional to standard. Or as a standalone Small project between P12 and P14.

My recommendation: take P12's extension as standard. It is the highest ratio of lesson to weeks on this page.

2. Networking below RPC

What is missing. P05 assumes a network that drops, delays, duplicates and reorders — correctly, and that is the right abstraction for consensus. But you never build the layer that produces those behaviours: no congestion control, no retransmission, no flow control, no head-of-line blocking.

Why it matters. A large fraction of real distributed-systems debugging is network-layer behaviour leaking through the abstraction — Nagle interacting with delayed ACK, TCP incast collapse, a connection pool exhausting under retry storms. Simulating faults at the message level teaches you what to handle; it does not teach you why they occur.

Cost to close: 4–6 weeks for a minimal reliable protocol over UDP with sliding window, retransmission and one congestion-control algorithm.

Verdict: a real gap, and I would not add it. Six weeks against 130 for a mechanism that is one layer below where your stated goals live. Note it as a limitation and consider it post-journey. If you want a cheap partial: in P05, add a fault-injection mode that models bandwidth and queueing rather than only drop and delay — that surfaces congestion-shaped failures for about two days of work.

3. Code generation

What is missing. P11 goes lexer → parser → AST → bytecode → VM → GC, and stops. SSA, register allocation, instruction selection and native emission are absent, so "how does a compiler produce fast machine code" remains a black box — which is a notable hole next to a journey that measures machine code constantly.

Why it is deliberate. A JIT is a project in itself, P11 is already Large at 132 hours, and the dispatch lesson (bytecode's advantage is cheaper operations, not fewer) is fully delivered without codegen.

Cost to close: 6–10 weeks.

Verdict: correctly deferred. It is the single best post-journey project on this page, and it composes: P11 gives the front end, P14 gives the machine model, and a tracing JIT for your own language is a genuinely impressive artifact.


Against the Stated Goal

You named MapReduce, Spanner, TensorFlow, TPUs, programming languages, OS kernels, databases, distributed systems, vector search, recommenders, and Transformers.

Named systemCovered byFidelity
MapReduceP06High — same architecture, same failure model
SpannerP05Partial — consensus and replication yes; TrueTime and distributed transactions read-only
TensorFlowP13High for the autodiff and graph-execution core; no distribution
TPUsP14Good for the reasoning — you derive the TOPS figure and simulate the array; no silicon
Programming languagesP11High to bytecode+GC; no codegen
OS kernelsP12Good — boot, VM, scheduling, syscalls; single-core, no drivers
DatabasesP03+P04Storage engine only. No query layer, no transactions
Distributed systemsP05–P07High
Vector searchP02+P03High — arguably the deepest coverage in the list
RecommendersP08–P10High, including the evaluation problem most treatments skip
TransformersP01+P13High for the mechanism; no scale

Ten of eleven are covered at high or good fidelity. The weakest is Spanner, and the missing pieces there (bounded clocks, distributed transactions) are precisely the parts that need infrastructure you cannot have.

The list is well matched to the goal. That is worth saying plainly, because the rest of this page is criticism and the headline finding is that the portfolio is sound.


What I Would Change

Three changes, in order of confidence.

1. Merge P06 and P07 into one runtime, two modes. Saves ~4 weeks, loses ~nothing. Build one coordinator, worker pool and partitioner; run it in batch mode (with speculative execution and the straggler study) and in streaming mode (with watermarks, windowing and checkpointing). The distinct 60% of each project is fully preserved and you stop building the same scheduler twice. Confidence: high.

2. Promote P12's synchronisation shoot-out from extension to standard. Costs ~2 weeks, closes the cheapest real gap, and produces directly transferable knowledge — every concurrent system you tune afterwards benefits. Confidence: high.

3. Add bandwidth and queueing to P05's fault injector. Two days. Surfaces congestion-shaped failures without a six-week networking project. Confidence: medium.

Net: −2 weeks and one gap closed. Both of the first two are consistent with the existing scope-cut machinery rather than requiring a replan.


What I Would Not Change

  • The fifteen-project scope. It is ambitious and it is coherent. Cutting further would produce breadth without the depth you asked for.
  • P03's deliberate redundancy with P04. The rework is the lesson.
  • P12's single-core scoping. SMP multiplies the difficulty of every subsequent bug; the extension in change 2 gets the concurrency lesson without it.
  • The absence of a query layer. Storage engines and query processing are two journeys. Yours is the storage one.
  • P09 and P10 as separate projects, despite the existing cut that merges them. The A/B platform's statistical content is genuinely distinct from the simulator's modelling content, and it is the part most directly useful in your job next month.

References

  • Brooks, F. P. No Silver Bullet — Essence and Accident in Software Engineering. IEEE Computer 20(4), 1987. The essence/accident distinction underlying the coverage map: the mechanisms are the essence; the fifteen projects are one accidental arrangement of them.
  • Lampson, B. W. Hints for Computer System Design. SOSP 1983. "Do one thing well" — the argument for merging P06 and P07 rather than building two partial runtimes.
  • Ousterhout, J. A Philosophy of Software Design, 2nd ed. Yaknyam Press, 2018. On deep modules, and on the cost of building the same abstraction twice.
  • Mellor-Crummey, J. M., Scott, M. L. Algorithms for Scalable Synchronization on Shared-Memory Multiprocessors. ACM TOCS 9(1), 1991. MCS locks — the reference for gap 1.
  • Herlihy, M., Shavit, N. The Art of Multiprocessor Programming, 2nd ed. Morgan Kaufmann, 2020. The text for the synchronisation shoot-out.
  • Alizadeh, M. et al. Data Center TCP (DCTCP). SIGCOMM 2010. What gap 2 would teach, and why incast is the canonical example.
  • Aycock, J. A Brief History of Just-In-Time. ACM Computing Surveys 35(2), 2003. The entry point for gap 3 as a post-journey project.