Mini-LSM with Coding Agents
This is a three-day guided track for students who intend to use a coding agent. The agent will write much of the code, but it must not silently design the system for you. You will reason about concrete examples, the agent will turn a few accepted decisions into a small code change, and tests will challenge your shared model.
All three guided days are available.
The goal is not to finish with the fewest prompts. It is to finish able to explain, test, and change the system the agent helped you build.
| Guided day | Original course material | Outcome |
|---|---|---|
| Day 1 | Mini-LSM | A working storage engine with memtables, SSTs, reads, writes, and flushes. |
| Day 2 | Compaction and persistence | Background compaction, restart recovery, and checksummed disk formats. |
| Day 3 | MVCC and transactions | Stable snapshots, atomic commits, safe version reclamation, and point-key serializable validation. |
The original chapters remain a reference library. This track changes the pacing and the student’s role; it does not remove the need to understand ordering, representation, concurrency, and failure modes.
Prepare the Repository and the Agent
Do all repository-wide preparation before beginning Day 1, then start the agent from the starter directory—not from the repository root.
1. Install the Toolchain and Course Tools
Install Rust with rustup if it is not already available. Then clone the repository and install the tools used by the course:
git clone https://github.com/skyzh/mini-lsm
cd mini-lsm
cargo x install-tools
The repository pins its Rust toolchain in rust-toolchain.toml, so Cargo will select it automatically when Rust is managed by rustup.
If you already have the repository and tools, update your checkout as appropriate and begin from the repository root.
2. Start the Agent from mini-lsm-starter
Change into the starter directory before launching your coding agent:
cd mini-lsm-starter
pwd
# Start your coding agent here using the command for your tool.
The final component of pwd should be mini-lsm-starter. This matters because repository-aware agents discover the AGENTS.md in this directory and begin with the starter as their working scope.
Starting there is not a security sandbox: an agent can still traverse to a parent directory if instructed. The local AGENTS.md therefore prohibits reading, searching, diffing, or copying ../mini-lsm and ../mini-lsm-mvcc, including attempts to reconstruct a solution through Git history or an online copy. The only Week 3 exceptions are the exact course commands that copy the provided key module and tests into the starter; the agent may read the destinations afterward, never the sources.
Do not open the whole repository as the agent’s workspace if your tool lets you choose a directory. The agent may consult starter interfaces, Rust documentation, and course chapters under ../mini-lsm-book/src/. It may consult a copied test only after finishing an independent first-pass implementation of that test’s checkpoint.
3. Verify the Instructions Before Coding
Do not assume the tool discovered AGENTS.md. Make the first prompt a handshake that performs no implementation:
Before editing anything, confirm that your working directory is
mini-lsm-starterand read./AGENTS.md. Summarize its reference-solution boundaries, narrow Week 3 copy exceptions, test protections, and student-owned design protocol. Explain which choices require a stop and which mechanical coding choices do not. Tell me which local sources you may use, then stop without changing files.
If the response omits the reference-solution boundary, test protection, or one-decision-at-a-time stop, correct the agent before continuing. If the tool cannot load repository instructions automatically, paste AGENTS.md into its persistent project instructions.
The Design-and-Test Loop
Begin a checkpoint with an ordinary capability request:
Implement block format.
That prompt authorizes the learning process, not a one-shot patch. The agent should inspect allowed context and ask its first design question. It should not return a complete design, edit code, or run ahead to a passing suite.
Repeat this loop:
- Agent gives one short stop. It starts with a concrete example, labels the question Course rule or Your choice, and asks you to choose or predict in plain English.
- Student reasons. State a choice and why. A prediction is useful even when you are uncertain.
- Agent checks the reasoning. It connects the answer to interfaces, prose, or already-revealed tests. If the answer violates a constraint, it shows the evidence and asks again instead of silently overriding you.
- Agent records the choice. The accepted answer enters a short decision ledger.
- Agent implements one slice independently. Once enough decisions specify a coherent slice, it previews the files, behavior, and later validation target and waits for your authorization. It completes a compiling first pass without copying or inspecting the supplied tests.
- Reveal tests after the checkpoint. Once the checkpoint’s first pass is complete, copy its test module and run the focused check. The implementation comes from the specification and accepted decisions; the test is new evidence rather than a design source.
- Student diagnoses product failures. The agent explains the test’s setup, expected result, observed result, and implicated invariant, then asks you to identify the likely bad execution path. It does not investigate the implementation or propose a fix before your attempt. Test-harness and environmental failures remain the agent’s responsibility.
- Student reviews. Inspect the diff and test output before authorizing a diagnosed fix or the next slice.
The agent must stop on topics that affect behavior or understanding: representation, ordering, ownership, size and boundary accounting, seek behavior, errors, synchronization, and where an optimization belongs. Some answers are course rules to derive; others are genuine choices. It need not interrupt you over a local variable name, import order, formatting, or an obvious compiler-directed repair.
The distinction keeps the conversation educational without turning every keystroke into ceremony.
At any stop, you can answer with one of these commands:
simpler— ask the same question with shorter sentences and less terminology;example— show the smallest concrete example that exposes the behavior;hint— reveal one useful fact, then let you try again; orchoose for me— let the agent decide this one, explain why, and record it as delegated.
Here is the intended shape of a stop:
Course rule — Which value should be visible?
We write
cat = old, freeze that memory table, then writecat = new.What should
get("cat")return, and why?You can reply
simpler,example,hint, orchoose for me.
After you answer, the agent can name the general rule—here, newest-value precedence—and connect it to the implementation. A question should teach the terminology, not require you to decode it before you can begin.
Keep a Decision Ledger
Ask the agent to maintain this table during each checkpoint:
| Decision or constraint | Student’s conclusion | Invariant or evidence | Consequence |
|---|---|---|---|
| Example: exact-size block | Accept it | The limit is inclusive | Reject only when projected size is greater than the target. |
The ledger makes hidden assumptions reviewable. It also prevents a required course constraint from being presented as a free preference, and lets you distinguish a coding bug from code that faithfully implements a bad decision.
You can delegate a decision when it is not where you want to spend learning time:
Choose this one for me, explain the tradeoff, and record it as delegated. Continue asking me about the remaining decisions.
Delegating one choice is not permission for the agent to decide the rest.
Review a Code Slice
Before each edit, the agent should state:
- which accepted decisions determine the slice;
- which files and observable behavior will change; and
- which supplied test module will be revealed after the independent first pass.
Non-test compiler and formatter feedback may be used during implementation. Do not run, copy, or inspect the supplied behavioral tests until the checkpoint is implemented end to end. This prevents the agent from reconstructing the implementation one assertion at a time while still making the tests available as independent evidence.
When a newly revealed product-behavior test fails, the agent may read the test and report what it does. It should not trace the implementation, identify the faulty line, propose a patch, or silently repair the failure. First ask the student to connect the failure to the decision ledger and propose a diagnosis. After the student reaches or accepts a diagnosis, the agent may implement an authorized fix and rerun the test. The agent should handle broken test commands, missing tools, dependency problems, and other harness failures directly.
After the edit, require the exact command and result, then ask:
Treat this slice as untrusted. Connect the changed behavior to the decision ledger and supplied tests. Identify one plausible bug that could still pass, propose the smallest adversarial check, and ask me to predict its outcome before adding it.
The agent should also point to one important changed line and ask: “What is this line trying to do, and what behavior might break if it changed?” The purpose is to connect a decision to code, not to quiz you on arbitrary syntax.
Do not let “all tests pass” end the review. Conversely, once the contract and adversarial checks are satisfied, continue to the next unresolved decision instead of inventing unrelated refactors.
When the workspace is prepared and the instruction handshake succeeds, continue to Day 1 - Mini-LSM.
Your feedback is greatly appreciated. Welcome to join our Discord Community.
Found an issue? Create an issue / pull request on github.com/skyzh/mini-lsm.
mini-lsm-book © 2022-2026 by Alex Chi Z is licensed under CC BY-NC-SA 4.0.