North Star Artifacts — The 8 Portfolio Rungs

Eight public artifacts. Each ships between M1 and M13. Each is measurable, reviewable, and defensible. Two are hard gates.

Every rung on this ladder answers a single question a stranger might ask on a recruiter call: “Can you show me something you built that proves it?” If the answer is “here is the repo, here is the benchmark, here is the blog post explaining why I lost to Boost on 4KB messages but won on 8B ones,” the rung is doing its job.

Full acceptance criteria for each rung: 12_portfolio/. This file is the map from ladder → calendar → signal.


The Ladder At A Glance

#

Month

Repo

Domain

Signal

Publish targets

Hard gate

1

M1

cpp-refresh-2026

Refresh + toolchain

“I came back and shipped in 30 days.”

GitHub + LinkedIn post

2

M3

lru-cache-cpp

Modern C++ core

RAII, move semantics, benchmark honesty

GitHub + r/cpp “show your work”

3

M4

mini-json-cpp

Modern C++ core

Templates, ranges, error handling

GitHub + short blog

4

M5

neetcode-150-cpp

DSA fluency

Raw C++ DSA, GHA compiles all 150

GitHub + r/cpp / r/csMajors

5

M7

cpp-concurrency-kit

Systems + concurrency

SPSC ring buffer + thread pool, TSan-clean, within 2× Boost

GitHub + r/cpp + Bluesky/X

6

M9

mynn-cpp

C++ for ML

Applied ML C++, MNIST ≥95%, matches PyTorch ≤1%, wheel on Test PyPI

GitHub + r/cpp + r/MachineLearning + HN

🟧 #1

7

M11

mini-inference-cpp

Production ML

gRPC + ONNX + dynamic batching + Prom + OTel + Docker + live URL

GitHub + HN Show HN + blog + LinkedIn

🟧 #2

8

M13

miniserve + pyfast_ann

Capstones

The M13 pitch, made evidence

GitHub + HN + PyPI + demo videos


Rung 1 · cpp-refresh-2026 · M1

  • What it is: A single repo with three tiny CLI tools (a wc clone, a JSON-line pretty-printer, a tail -f clone) plus a Google Benchmark harness and CI. C++23 with std::print, std::format, std::span.

  • Signal: “I came back to C++ after two years, and in 30 days I have three shipping binaries, tests, a benchmark harness, and CI.”

  • Where to publish: GitHub (public). Post to your LinkedIn with a 2-paragraph note about the return-to-C++ arc.

  • File link: 12_portfolio/01_rung1_m1_toolchain_trio.md.

  • Specificity gradient: low. This rung’s job is to prove you can install, compile, and ship; not to impress anyone.

  • Signal to employer: disposable in isolation, load-bearing in aggregate. Recruiters will glance and move on. The rungs above validate it retroactively.


Rung 2 · lru-cache-cpp · M3

  • What it is: An LRUCache<K,V> template with intrusive-list + hashmap, RAII lifetime, move-only semantics, iterator invalidation contract, and an honest benchmark table against a std::map-based baseline and std::unordered_map + doubly-linked-list.

  • Signal: “I understand ownership, RAII, and move semantics, and I can benchmark honestly — including the workload where I lose.”

  • Where to publish: GitHub. Optional: r/cpp “show your work” weekly thread; feedback is often high quality here.

  • File link: 12_portfolio/02_rung2_m3_lru_cache.md.

  • Specificity gradient: medium. Any C++ dev has written one. What makes yours differentiated: the honest benchmark table (see 13_discipline/03_benchmark_hygiene.md).

  • Signal to employer: “Comfortable with C++ core semantics. Not a coding-bootcamp survivor.”


Rung 3 · mini-json-cpp · M4

  • What it is: A minimal JSON parser + serializer, hand-written recursive descent, no dependencies. Supports subset of RFC 8259. Concept-constrained templated visitor API. std::expected<Value, ParseError> return type.

  • Signal: “I can write a small parser, use templates + concepts idiomatically, and handle errors without exceptions.”

  • Where to publish: GitHub + a short (500-word) blog post: “How C++23 std::expected changes the shape of parser error handling.”

  • File link: 12_portfolio/03_rung3_m4_json_parser.md.

  • Specificity gradient: medium-high. Everyone has written a JSON parser; few have used std::expected and concepts to structure it in 2026 idioms.

  • Signal to employer: “Reads modern C++, writes modern C++, doesn’t pretend it’s still 2014.”


Rung 4 · neetcode-150-cpp · M5

  • What it is: All 150 NeetCode problems solved in raw C++ (STL only). GitHub Actions CI compiles every solution on push. Each solution has a header comment: time complexity, space complexity, pattern name, one-line “trick.” A README index of problems by pattern.

  • Signal: “I can pattern-match algorithm problems and implement them in C++ without touching Python.”

  • Where to publish: GitHub. Optional: r/cpp for the CI setup, r/csMajors for the study log.

  • File link: 12_portfolio/04_rung4_m5_neetcode_150_repo.md.

  • Specificity gradient: medium. NeetCode 150 in Python is generic; NeetCode 150 in C++ with CI is above the median.

  • Signal to employer: “Comfortable in the study environment. Won’t fumble a coding round.”


Rung 5 · cpp-concurrency-kit · M7

  • What it is: Two production-shaped primitives in one repo: an SPSC ring buffer (single producer / single consumer, cache-line-padded, benchmark within 2× of boost::lockfree::spsc_queue) and a thread pool (std::jthread-based, work-stealing optional, 100K empty tasks < 500ms on M-series). TSan + ASan + UBSan all clean. Google Benchmark reports in README.

  • Signal: “I can build lock-free primitives, reason about memory ordering, and benchmark rigorously.”

  • Where to publish: GitHub + r/cpp (concurrency posts do well) + Bluesky/X with a screenshot of the benchmark table.

  • File link: 12_portfolio/05_rung5_m7_concurrency_duo.md.

  • Specificity gradient: high. Real concurrency work with sanitizer-clean guarantees is a small population.

  • Signal to employer: “Understands the C++ memory model, not just C++ syntax. Would trust with a queue.”


Rung 6 · mynn-cpp · M9 🟧 HARD GATE #1

  • What it is: A tiny neural-network library in C++ using Eigen for linear algebra, hand-rolled forward/backward, cross-entropy loss, SGD/Adam optimizers. pybind11 Python bindings. Trained on MNIST, ≥95% test accuracy. Matches PyTorch within 1% on the same seed. Wheel published to Test PyPI: pip install --index-url https://test.pypi.org/simple/ mynn-cpp. Blog post.

  • Signal: “I can implement ML from scratch in C++ and bridge to Python. I am not a Python-only ML person.”

  • Where to publish: GitHub (public) + Test PyPI + r/cpp + r/MachineLearning + Hacker News. Blog title: “I rebuilt a PyTorch MLP in C++ with 380 lines of Eigen — here’s what surprised me.”

  • File link: 12_portfolio/06_rung6_m9_HARDGATE_eigen_mlp_pybind.md.

  • Specificity gradient: very high. This is the rung that most Python-only ML engineers cannot ship. Small population.

  • Signal to employer: “Bridges Python ML and native C++. Rare skill. Cheap to hire vs specialists in either.”

  • Hard-gate consequences: miss by >14 days (2027-04-14) → 14-day pause, 99_pre_mortem/05_the_hard_gate_M9_miss.md, honest rescope, continue.


Rung 7 · mini-inference-cpp · M11 🟧 HARD GATE #2

  • What it is: A production-shaped model-inference server. C++ core. ONNX Runtime backend. gRPC + REST APIs. Dynamic batching (Triton-lite: coalesce requests within a 10ms window up to batch size 32). Prometheus metrics (throughput, latency histogram, error rate). OpenTelemetry traces. Docker image <200MB (multi-stage build). Deployed to a $5/month VM (Hetzner CX11 €4.51/mo or DigitalOcean droplet) with a public URL and 30-day uptime commitment. k6/ghz load tests at concurrency 1/8/32/128 documented. 3 Grafana dashboards. Blog post.

  • Signal: “I can stand up a production ML inference service end-to-end, from .onnx on disk to a load-tested public URL with dashboards.”

  • Where to publish: GitHub + Show HN + Bluesky/X + LinkedIn + blog post. This is the rung that gets shared.

  • File link: 12_portfolio/07_rung7_m11_HARDGATE_grpc_inference_service.md.

  • Specificity gradient: extreme. This maps directly to inference-engineering job descriptions at ByteDance, F5, GM, NVIDIA, Anthropic, and every India inference role at NVIDIA/Databricks/Adobe/Qualcomm.

  • Signal to employer: “Ships production ML infrastructure. Can be dropped into an inference team on Day 1.”

  • Hard-gate consequences: miss by >14 days (2027-06-14) → 14-day pause, reset protocol, honest rescope, continue.


Rung 8 · miniserve + pyfast_ann · M13

  • What it is: Two capstones.

    • Capstone Alpha miniserve: production-grade ML inference server. Superset of Rung 7. Multi-model serving, hot-reload without restart, config-driven, admin API, model versioning. Deployed with real dashboards.

    • Capstone Beta pyfast_ann: Python-native library with a C++ core. HNSW-lite ANN index. nanobind bindings (not pybind11 — this rung showcases the modern binding stack). Benchmark against faiss on 1M vectors: honest table.

  • Signal: “I own the full stack: from the pybind11/nanobind boundary to the deployed inference service. The M13 pitch, made evidence.”

  • Where to publish: GitHub (both public) + PyPI (pyfast_ann) + Show HN + 5–10 min screencast demos + blog posts + LinkedIn.

  • File link: 12_portfolio/08_rung8_m13_capstones_alpha_beta.md.

  • Specificity gradient: maximum. The population of engineers who can point at two shipped, deployed, load-tested, Python-installable artifacts in this domain is genuinely small.

  • Signal to employer: “You want this person on your inference team. Skip the coding round.”


The Specificity Gradient (Why Rung Order Matters)

Rungs 1–4 (M1–M5) prove you can write C++. Rungs 5–8 (M7–M13) prove you can write C++ for the specific market you want to enter. The specificity gradient is intentional: early rungs are generic-good-C++ (any dev), later rungs are inference-engineering-specific (a small, well-paid population).

Do not skip forward. A candidate who ships Rung 7 without Rungs 1–6 raises a red flag: too much AI-copy-paste, too little foundation. A candidate who ships all 8 in order tells a story recruiters can follow — which is the whole point of a portfolio.


What Most People Get Wrong About Portfolio Ladders

They pick one big project and never finish it. Every “portfolio that got me hired” case study I have read has ≥5 distinct public repos with ≥5 distinct signals. One giant unfinished project sends the opposite signal: the person cannot ship. Eight small, done, and blogged is worth ten times one giant, unfinished, and README-only.

They think GitHub stars are the metric. They are not. Stars are noise. The metric is: does the repo compile in a fresh clone, does the README explain the trade-off honestly, and does the benchmark table include a workload where you lose? A repo that answers yes to all three converts recruiter conversations even at 4 stars.

They ship the repo but not the blog. A repo without a written explanation is 30% of the signal. A repo + a 500-word blog post that explains why you built it and what surprised you is 100%. The blog is the interpretation layer. Do not skip it.


Return to: README.md · Next: 04_weekly_rhythm.md — the canonical week given full-time-job constraints.