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 |
|
Refresh + toolchain |
“I came back and shipped in 30 days.” |
GitHub + LinkedIn post |
|
2 |
M3 |
|
Modern C++ core |
RAII, move semantics, benchmark honesty |
GitHub + r/cpp “show your work” |
|
3 |
M4 |
|
Modern C++ core |
Templates, ranges, error handling |
GitHub + short blog |
|
4 |
M5 |
|
DSA fluency |
Raw C++ DSA, GHA compiles all 150 |
GitHub + r/cpp / r/csMajors |
|
5 |
M7 |
|
Systems + concurrency |
SPSC ring buffer + thread pool, TSan-clean, within 2× Boost |
GitHub + r/cpp + Bluesky/X |
|
6 |
M9 |
|
C++ for ML |
Applied ML C++, MNIST ≥95%, matches PyTorch ≤1%, wheel on Test PyPI |
GitHub + r/cpp + r/MachineLearning + HN |
🟧 #1 |
7 |
M11 |
|
Production ML |
gRPC + ONNX + dynamic batching + Prom + OTel + Docker + live URL |
GitHub + HN Show HN + blog + LinkedIn |
🟧 #2 |
8 |
M13 |
|
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
wcclone, a JSON-line pretty-printer, atail -fclone) plus a Google Benchmark harness and CI. C++23 withstd::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 astd::map-based baseline andstd::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::expectedchanges 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::expectedand 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
.onnxon 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 againstfaisson 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.