Skip to content
liter8.sh
~/liter8/Makefile

The roadmap

Where to start, and why.

Seventeen gyms is a menu, not a path. This is the path. A Makefile is the oldest dependency graph in software: a target, what it needs first, and the recipe. Every gym below is listed after the ones it needs, with the reason on the edge.

Complete beginner? Run make all and start at the top. Know what you want? Pick a goal and the list shrinks to what that goal actually needs. Mark what you already have as up to date; make skips those.

Goal
make

The whole path, every target in dependency order. Start here if you do not know what you would fail.

17 targets for ‘all

Dependency graph

the graph · left needs nothing, right needs everything · click a target to jump to its rule

1. The floor

# What you type into. Every other gym is driven from a prompt; the shell, the object model under your commits, and the patterns in your greps are the substrate.

  1. [1/17]shell.liter8.shstart here

    ShellThe last interface that does not guess what you meant

    # Needs nothing. Everything else is typed into this: the filesystem, the process, the quote you forgot.

    needs
    — nothing. This is where the path starts.
    unlocks
    GitRegexVimNetLinux
    skip if
    you can say why `rm -rf "$DIR"/` and `rm -rf $DIR/` differ when DIR is unset
    Open shell.liter8.sh24 lessons · 7 tracksengine: a real shell with a virtual filesystem
  2. [2/17]git.liter8.sh

    GitPractise on a real object model

    # A diff is the unit of review, and a diff is a difference between two commits. Learn what a commit points to before you read what changed between them.

    needs
    • Shellgit is a command-line tool; the prompt, paths and pipes are assumed
    unlocks
    ReviewInfra
    skip if
    you can explain what `git reset --hard` does to the index, the worktree and the reflog
    Open git.liter8.sh22 lessons · 26 drillsengine: a real Git object model
  3. [3/17]regex.liter8.shelective

    RegexSay what it matches before you run it

    # The first thing you will read that looks like line noise. Predict what a pattern matches before you trust a grep, a validator, or a generated route.

    needs
    • Shellpatterns show up first in `grep` and `sed` at the prompt
    unlocks
    — a leaf.
    skip if
    you can say what `a*?` matches, and what makes `(a+)+$` hang
    Open regex.liter8.sh18 lessons · 36 drills · 23 tasksengine: a backtracking VM that exposes every step
  4. [4/17]vim.liter8.shelective

    VimPractice until it becomes instinct

    # Optional and orthogonal. Speed, not understanding. Do it whenever; it only asks that you already live in a terminal.

    needs
    • Shellthe editor lives in the terminal
    unlocks
    — a leaf.
    skip if
    you already have an editor you do not think about
    Open vim.liter8.sh51 lessons · 120 drillsengine: a deterministic Vim editing engine

2. Reading

# The thesis of the site. The model writes the code; you read it. Everything after this is a specialised way of reading.

  1. [5/17]review.liter8.sh

    ReviewRead the diff like it's lying to you

    # The thesis. Read a diff the model wrote, find the one defect, prove it with an input. Never skip this.

    needs
    • Gita diff is a difference between commits; you need the object model to know what a diff is
    unlocks
    TestSecure
    skip if
    don't. This is the thesis.
    Open review.liter8.sh56 exercisesengine: a verifier that checks your witness input
  2. [6/17]test.liter8.sh

    TestA green suite is a claim

    # A green suite is a claim about the code. You have to be able to read the code before you can judge the claim; then watch an engine break the code under your tests.

    needs
    • Reviewmutation testing is code review run backwards: you judge whether the test would catch the defect you learned to spot
    unlocks
    Concurrency
    skip if
    you know what a mutant is and have killed one
    Open test.liter8.sh10 lessons · 8 tracksengine: a mutation-testing engine

3. Data

# The first place the cost is not in the source. A query is a program a planner runs; a migration is a lock you did not see.

  1. [7/17]sql.liter8.sh

    SQLRead the plan, not the query

    # A query is a program that a planner runs. Read the plan the way you read the diff: the cost is in the pages, not the SELECT.

    needs
    — nothing. This is where the path starts.
    unlocks
    SchemaSystem DesignSecure
    skip if
    you can read EXPLAIN and say why a sequential scan happened
    Open sql.liter8.sh25 lessons · 7 tracksengine: a relational engine with a cost-based planner
  2. [8/17]schema.liter8.sh

    SchemaMigrations that don't lock the table

    # A migration is a lock you did not see. You need tables, indexes and transactions in hand before you watch a lock queue form behind an ALTER.

    needs
    • SQLlocks are taken on tables you must already know how to query and index
    unlocks
    Deploy
    skip if
    you know which ALTER TABLE takes ACCESS EXCLUSIVE and for how long
    Open schema.liter8.sh9 lessons · 10 tasks · 5 auditsengine: a lock manager conformed against real PostgreSQL 16

4. The wire and the machine

# Requests cross a network and land on a kernel. What a handshake costs, what a file descriptor is, and why two threads disagree.

  1. [9/17]net.liter8.sh

    NetRead the handshake, not the docs

    # Every request crosses DNS, TCP, TLS and HTTP before your handler sees it. Reading a capture is reading a trace; the latency budget is arithmetic.

    needs
    • Shellcaptures and curl are read from the prompt; the shell gym is where you learned to read command output at all
    unlocks
    DeploySystem DesignSecureDebug
    skip if
    you can read a TCP handshake in a capture and say where the third round-trip went
    Open net.liter8.sh9 lessons · 7 tasksengine: a discrete-event packet simulator
  2. [10/17]linux.liter8.sh

    LinuxRead the strace, not the man page

    # The shell is what you type; the kernel is what happens. A pipe at the prompt is two file descriptors here.

    needs
    • Shellthe shell gym leaves you knowing what a pipe does; this one shows what it is
    unlocks
    ContainerDebug
    skip if
    you can say what a file descriptor is without saying "a file"
    Open linux.liter8.sh12 lessons · 5 tasks · 4 auditsengine: a syscall-level kernel model with /proc and strace
  3. [11/17]concurrency.liter8.sh

    ConcurrencyThe bug that only happens on the fourteenth Tuesday

    # A concurrent bug is an assertion that holds under one interleaving and fails under another. You need to be able to write the assertion first.

    needs
    • Testthe engine searches for the schedule that breaks your assertion; you learned to write assertions that mean something in test
    unlocks
    — a leaf.
    skip if
    you can name the interleaving that breaks a check-then-act
    Open concurrency.liter8.sh21 lessonsengine: a deterministic scheduler and model checker

5. Shipping

# How code gets to the machine: a filesystem diff, a plan you should read before applying, and a loop that fights you.

  1. [12/17]container.liter8.sh

    ContainerAn image is a filesystem diff, not a zip

    # An image is a filesystem diff; a container is namespaces plus cgroups. Both are kernel objects, so the kernel comes first.

    needs
    • Linuxnamespaces, cgroups and SIGTERM delivery are the linux gym's model, copied
    unlocks
    Deploy
    skip if
    you can predict which layers rebuild when one Dockerfile line changes
    Open container.liter8.sh9 lessons · 9 tasks · 5 drillsengine: a layer store, a build cache and an OCI runtime
  2. [13/17]infra.liter8.sh

    InfraRead the plan before you apply

    # A plan is a diff between declared state and recorded state. Read it before you apply it, the way you read a diff before you merge it.

    needs
    • Gita plan is read like a diff: what is added, what is destroyed, what is quietly replaced
    unlocks
    — a leaf.
    skip if
    you can read a plan and spot a destroy-and-recreate
    Open infra.liter8.sh9 lessons · 8 tasks · 6 drills · 4 auditsengine: a dependency graph with a real plan differ
  3. [14/17]deploy.liter8.sh

    DeployDeclare the state, then watch the loop fight you

    # A rollout is old and new code running side by side against one database, in containers a scheduler placed, behind probes that speak HTTP. Three gyms, all at once.

    needs
    • Containerpods are containers; SIGTERM and the entrypoint are the same story
    • Netreadiness probes, timeouts and the retry loop are network behaviour
    • Schemaold and new application code against one live table is the schema gym's central exercise
    unlocks
    — a leaf.
    skip if
    you know what a failing readiness probe does to a rollout
    Open deploy.liter8.sh10 lessons · 6 tasks · 2 incidentsengine: a reconciliation loop with a scheduler and live traffic

6. Operating

# The capstones. Build a system and break it, prove the exploit, and get paged. Everything above is what you need to read the trace.

  1. [15/17]system-design.liter8.sh

    System DesignLearn by operating systems

    # Build an architecture, generate traffic, break it. Every box is a database or a network hop; you need both before the diagram means anything.

    needs
    • SQLa cache, a replica and a queue are all answers to what a query costs
    • Netlatency, loss and retries are what the traffic simulator is made of
    unlocks
    Debug
    skip if
    you can say what a cache does to p99 under a thundering herd
    Open system-design.liter8.sh37 lessons · 4 labs · 4 missionsengine: a traffic simulator with real failure modes
  2. [16/17]secure.liter8.sh

    SecureProve the exploit

    # Read a generated handler, prove the exploit with a request, ship the fix. Review gave you the reading, net gave you the request, sql gave you the injection.

    needs
    • Reviewthe same loop: find the defect, prove it with a witness
    • Netthe attacker console speaks HTTP; you need to know what a request is
    • SQLinjection is the canonical class; you need to know what the query would have done
    unlocks
    — a leaf.
    skip if
    you can turn a handler into an exploit request
    Open secure.liter8.sh21 lessons · 41 exercisesengine: a sandboxed app, an attacker console, and a witness verifier
  3. [17/17]debug.liter8.sh

    DebugFind the fault before the clock does

    # The capstone. Get paged, read traces, logs and metrics, prove the diagnosis. Every trace is a request through a system on a machine.

    needs
    • System Designthe incident is in an architecture you must be able to picture
    • Netthe trace is a request; the timeout is a handshake
    • Linuxthe metric is a process; the log line came from a file descriptor
    unlocks
    — a leaf.
    skip if
    don't. This is where all of it gets tested.
    Open debug.liter8.sh9 incidentsengine: a simulated production system with traces, logs and metrics

Already know where you are? Pick whichever you'd fail today.