# LLD Dojo

Java low-level-design and machine-coding trainer. Local only. No accounts, no cloud, no git.

## Run

- **Windows:** `.\run.ps1`
- **macOS:** `./run.sh`

First run downloads a portable Temurin JDK 21 (~180 MB) and the JUnit standalone jar (~2.5 MB) into
`.toolchain/`. Every run after that is instant and fully offline. Then open
<http://127.0.0.1:7777>.

**Requires:** Node 22 or newer (for built-in `node:sqlite`).

The server binds `127.0.0.1` only — it is never reachable from another machine on the network.

## The ladder

Eight phases per problem, from a 90-second vocabulary rep to a full timed round:

| Phase | What it drills | Graded by |
|---|---|---|
| 0 | Vocabulary — enums with behaviour, records, seams | structural checks |
| 1 | Requirement extraction from an ambiguous prompt | LLM + deterministic fallback |
| 2 | 12-minute skeleton sprint — types and seams, must compile | deterministic |
| 3 | Core build — the base JUnit suite green, `main` mandatory | deterministic |
| 4 | Extension under fire — a curveball requirement, diff measured | deterministic |
| 5 | Written defence — why this seam, what breaks under concurrency | LLM + self-marked fallback |
| 6 | Concurrency stress — repeated runs against a real thread pool | deterministic |
| 7 | Full company-mode round on a sealed problem | rubric (STANDARD v1.0) |

`GET /api/standard` returns the exact anchored rubric a submission is judged against — an
auditable judge is a trustable judge.

## Grading tiers

Detected at startup and shown in the header.

| Tier | Meaning |
|---|---|
| T1 | `claude` CLI found — full-quality grading, drawn from your Claude Code plan |
| T2 | `ollama` found — local model, lower confidence |
| T3 | Neither — deterministic checks and keyword overlap only |

Deterministic checks (compilation, the base suite, the diff budget) run in every tier and are
**never** overridden by a model. A submission that does not compile is always reported as
`INVALID` — a mechanical problem, never a judgement about ability — and nothing is recorded
against you for it.

## Layout

| Path | Contents |
|---|---|
| `corpus/` | Problems — **the irreplaceable part** |
| `lessons/` | Worked / faded / independent micro-lessons, routed to from failure tags |
| `harness/` | Shared concurrency-drill test primitives |
| `snapshots/` | Timestamped `.tar.gz` backups of the project. Stands in for git |
| `workspace/` | Your Java, one directory per attempt |
| `data/dojo.db` | Progress |

## Development

```bash
node --test                  # run the suite (bare invocation only — see docs/plans)
node tools/fetch-fonts.mjs    # one-time: pull the bundled woff2 faces
node tools/build-ui.mjs       # rebuild the frontend
node tools/validate-corpus.mjs   # check every problem directory and syllabus coverage
node tools/validate-lessons.mjs  # check every lesson directory
node tools/snapshot.mjs msg   # snapshot before risky changes — there is no git here
node tools/package.mjs        # produce lld-trainer.zip for distribution
```

`node tools/package.mjs` ships `server/`, the prebuilt `ui/`, `corpus/`, `lessons/`, `harness/`,
`tools/`, `docs/`, the launchers and this file. It never ships `.toolchain/` (platform-specific,
re-fetched on first run), `data/`, `workspace/` or `snapshots/` (personal progress and backups),
or `node_modules/`.

Set your OS to reduce animations to check the reduced-motion path; every drill must stay fully
usable with all motion removed.
