chore: track CV/résumé pipeline source
yaml-source/ was fully gitignored, so the YAML that drives both the CV and the résumé had no version history and no backup — it existed only on one machine. Track the pipeline *source* (data/, templates/, build.py, Makefile) and keep only the artifacts (build/, output/, editor backups) local, matching the existing intent that rendered PDFs ship via static/. This is also a prerequisite for the site build: the vita page currently hand-copies education, publications, presentations, and experience out of these files, and has drifted from them in ~15 places. Generating it needs the data present in the repo. Includes the .claude/settings.local.json ignore rule already staged in the working tree. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SUGesXiMmACsLBTGG1xuEU
This commit is contained in:
parent
3a089c3f76
commit
76a6587815
|
|
@ -97,9 +97,13 @@ content/drafts/
|
|||
checklist.md
|
||||
|
||||
# CV/résumé build pipeline (YAML → Jinja → xelatex). The canonical PDFs
|
||||
# live under static/ and ship with the site; the pipeline itself is
|
||||
# kept locally for regeneration but not version-controlled here.
|
||||
yaml-source/
|
||||
# live under static/ and ship with the site. The pipeline *source* is
|
||||
# tracked: data/ is the single source of truth for both documents (and is
|
||||
# read by the site build to render the vita page), and templates/ +
|
||||
# build.py are what regenerate them. Only artifacts stay local.
|
||||
yaml-source/build/
|
||||
yaml-source/output/
|
||||
yaml-source/data/*~
|
||||
# Handover bundle (archived locally for reference; not part of the site).
|
||||
levineuwirth_handover.zip
|
||||
|
||||
|
|
@ -147,4 +151,7 @@ content/photography/**/*.raf
|
|||
content/photography/**/*.orf
|
||||
content/photography/**/*.tif
|
||||
content/photography/**/*.tiff
|
||||
content/photography/**/*.psd
|
||||
content/photography/**/*.psd
|
||||
# Claude Code local settings — machine-specific, and this repo mirrors
|
||||
# to a public GitHub remote.
|
||||
.claude/settings.local.json
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
.PHONY: all all_all cv resume resume_ats ats clean install
|
||||
|
||||
# Default: build the two website-facing PDFs (cv + 1-page résumé).
|
||||
# Use `make all_all` to also build the ATS-optimized résumé variant.
|
||||
all:
|
||||
@python3 build.py all
|
||||
|
||||
all_all:
|
||||
@python3 build.py all_all
|
||||
|
||||
cv:
|
||||
@python3 build.py cv
|
||||
|
||||
resume:
|
||||
@python3 build.py resume
|
||||
|
||||
# ATS-optimized résumé variant. See templates/resume_ats.tex.j2.
|
||||
resume_ats ats:
|
||||
@python3 build.py resume_ats
|
||||
|
||||
clean:
|
||||
@rm -rf build output
|
||||
@echo "cleaned."
|
||||
|
||||
install:
|
||||
@pip install --user pyyaml jinja2
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
# Levi Neuwirth — CV and Résumé
|
||||
|
||||
Single-source pipeline producing two PDFs from a shared YAML content store:
|
||||
|
||||
- `output/cv.pdf` — multi-page academic CV.
|
||||
- `output/resume.pdf` — one-page industry résumé.
|
||||
|
||||
## How it works
|
||||
|
||||
Content lives in `data/*.yml`, one file per logical section. Each entry has
|
||||
`cv_visible` and `resume_visible` flags that control whether it appears in
|
||||
the CV, the résumé, or both. The two Jinja2 templates in `templates/` render
|
||||
into LaTeX, which `xelatex` compiles.
|
||||
|
||||
## Building
|
||||
|
||||
```bash
|
||||
make all # build both PDFs
|
||||
make cv # build CV only
|
||||
make resume # build résumé only
|
||||
make clean # remove build/ and output/
|
||||
make install # pip install pyyaml + jinja2 (user install)
|
||||
```
|
||||
|
||||
Requires: Python 3.9+, `xelatex` (TeX Live, MacTeX, or equivalent), Source
|
||||
Serif Pro and Source Sans Pro fonts. On most Linux distributions these fonts
|
||||
are in the `texlive-fonts-extra` or equivalent package; on macOS they're
|
||||
available through Homebrew (`brew install --cask font-source-serif-pro
|
||||
font-source-sans-pro`) or directly from Adobe.
|
||||
|
||||
## Maintenance patterns
|
||||
|
||||
**Add a new publication:** edit `data/publications.yml`, append an entry,
|
||||
set `cv_visible` and `resume_visible` as appropriate. Rebuild.
|
||||
|
||||
**Update a role:** edit `data/experience.yml`. The `cv_order` and
|
||||
`resume_order` fields let you reorder per document.
|
||||
|
||||
**Change the ordering on the résumé without changing the CV:** adjust
|
||||
`resume_order` in `experience.yml`. The CV uses `cv_order` independently.
|
||||
|
||||
**Move a project from "in progress" to "published":** move its entry from
|
||||
`projects.yml` into `publications.yml`.
|
||||
|
||||
**Hide something temporarily:** flip its visibility flag to `false`. The
|
||||
entry stays in source, preserving history.
|
||||
|
||||
## Page-count notes
|
||||
|
||||
- **Résumé is a clean 1 page.** It holds five Experience entries (MARS V,
|
||||
Shu Lab, NeuroAI, xAI, contracting), 3 projects, education, and header.
|
||||
The fit depends on two deliberate choices: xAI is held to a single line
|
||||
(scope line dropped, metrics bullets removed — see below), and the
|
||||
résumé-only spacing in `resume.tex.j2` (`\titlespacing`, `itemize`
|
||||
spacing, `\parskip`) is tuned so the last education note lands on page 1.
|
||||
Adding a multi-line Experience or Projects entry will spill onto a second
|
||||
page; when that happens, either trim content or nudge `\parskip` down
|
||||
(0.1em is the current value; page 1 still reads with air at that level).
|
||||
- **xAI is intentionally de-emphasized.** It sits fourth in Experience and
|
||||
is one line that keeps only the `grok-code-fast-1` credential. The old
|
||||
scope line and the two metrics bullets (tool-execution / API-usage
|
||||
percentages, hallucination-rate reduction) were removed on purpose to
|
||||
keep both documents' centre of gravity on research; do not re-add them
|
||||
without a reason.
|
||||
- **CV at 4 pages is normal** for this level of output. Page 4 is sparse
|
||||
(Languages, Skills, Research Interests); tightening `\titlespacing` and
|
||||
`\parskip` in `preamble.tex` can collapse to 3 pages but tends to
|
||||
reappear at 4 as soon as new content is added.
|
||||
|
||||
## Design notes
|
||||
|
||||
- Body: Source Serif Pro. Headers: Source Sans Pro. Fully black and white.
|
||||
- Templates use LaTeX-safe Jinja delimiters: `%% ... %%` for blocks,
|
||||
`(( ... ))` for variables, `%# ... #%` for comments. This avoids
|
||||
collisions with LaTeX's own `%` and `{}`.
|
||||
- `\entryheader` in `templates/shared/commands.tex` is the unified
|
||||
organization/role/date/location block used by both templates.
|
||||
- The MARS V and Shu Lab entries have `cv_section: research` set in
|
||||
`experience.yml`, which routes them into the CV's "Research Experience"
|
||||
section while they still sit under plain "Experience" on the résumé.
|
||||
Other routing flags can be added similarly.
|
||||
- **Ordering is per-axis.** The résumé sorts Experience by `resume_order`
|
||||
(research-first: MARS V, Shu Lab, NeuroAI, then xAI and contracting).
|
||||
The CV templates render in **file order** within each section — the
|
||||
`cv_order` field is documentation of intent, not a sort key, so keep the
|
||||
YAML file order and `cv_order` consistent when reordering.
|
||||
|
||||
## File layout
|
||||
|
||||
```
|
||||
cv/
|
||||
├── data/ # YAML content (source of truth)
|
||||
│ ├── affiliations.yml
|
||||
│ ├── education.yml
|
||||
│ ├── experience.yml
|
||||
│ ├── grants.yml
|
||||
│ ├── personal.yml
|
||||
│ ├── presentations.yml
|
||||
│ ├── projects.yml
|
||||
│ ├── publications.yml
|
||||
│ └── skills.yml
|
||||
├── templates/
|
||||
│ ├── cv.tex.j2
|
||||
│ ├── resume.tex.j2
|
||||
│ └── shared/
|
||||
│ ├── commands.tex
|
||||
│ └── preamble.tex
|
||||
├── build.py # renders + compiles
|
||||
├── Makefile
|
||||
├── build/ # intermediate (.aux, .log, rendered .tex)
|
||||
└── output/
|
||||
├── cv.pdf
|
||||
└── resume.pdf
|
||||
```
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Build script for CV and résumé.
|
||||
|
||||
Loads YAML data files, renders Jinja2 LaTeX templates with a LaTeX-safe
|
||||
delimiter configuration, and compiles both documents via xelatex.
|
||||
|
||||
Usage:
|
||||
python build.py cv # build CV only
|
||||
python build.py resume # build website résumé only
|
||||
python build.py resume_ats # build ATS-optimized résumé only
|
||||
python build.py all # build cv + resume (default; not ats)
|
||||
python build.py all_all # build cv + resume + resume_ats
|
||||
"""
|
||||
|
||||
import sys
|
||||
import subprocess
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
from datetime import date
|
||||
|
||||
import yaml
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
|
||||
|
||||
ROOT = Path(__file__).parent
|
||||
DATA_DIR = ROOT / "data"
|
||||
TEMPLATE_DIR = ROOT / "templates"
|
||||
OUTPUT_DIR = ROOT / "output"
|
||||
BUILD_DIR = ROOT / "build"
|
||||
|
||||
|
||||
def load_all_data():
|
||||
"""Load every .yml file in data/ and merge into a single dict."""
|
||||
data = {}
|
||||
for yml_file in sorted(DATA_DIR.glob("*.yml")):
|
||||
with open(yml_file) as f:
|
||||
loaded = yaml.safe_load(f)
|
||||
if not loaded:
|
||||
continue
|
||||
stem = yml_file.stem
|
||||
if stem == "personal":
|
||||
# personal.yml's contents become the `personal` key
|
||||
data["personal"] = loaded
|
||||
elif stem == "skills":
|
||||
# skills.yml has multiple top-level keys — merge all directly
|
||||
data.update(loaded)
|
||||
else:
|
||||
# everything else merges directly (education.yml has key
|
||||
# 'education', experience.yml has key 'experience', etc.)
|
||||
data.update(loaded)
|
||||
data["build_date"] = date.today().strftime("%B %Y")
|
||||
return data
|
||||
|
||||
|
||||
def make_env():
|
||||
"""Jinja2 environment configured for LaTeX-safe delimiters."""
|
||||
return Environment(
|
||||
loader=FileSystemLoader(str(TEMPLATE_DIR)),
|
||||
block_start_string="((*",
|
||||
block_end_string="*))",
|
||||
variable_start_string="(((",
|
||||
variable_end_string=")))",
|
||||
comment_start_string="((#",
|
||||
comment_end_string="#))",
|
||||
trim_blocks=True,
|
||||
lstrip_blocks=True,
|
||||
autoescape=False,
|
||||
)
|
||||
|
||||
|
||||
def render(template_name, data):
|
||||
env = make_env()
|
||||
template = env.get_template(template_name)
|
||||
return template.render(**data)
|
||||
|
||||
|
||||
def compile_tex(tex_path, output_name):
|
||||
"""Run xelatex twice (for cross-references) and move the PDF to output/."""
|
||||
BUILD_DIR.mkdir(exist_ok=True)
|
||||
OUTPUT_DIR.mkdir(exist_ok=True)
|
||||
|
||||
# Copy shared templates into build dir so \input paths resolve cleanly
|
||||
build_template_dir = BUILD_DIR / "templates"
|
||||
if build_template_dir.exists():
|
||||
shutil.rmtree(build_template_dir)
|
||||
shutil.copytree(TEMPLATE_DIR, build_template_dir)
|
||||
|
||||
# Write .tex into build dir
|
||||
tex_in_build = BUILD_DIR / f"{output_name}.tex"
|
||||
tex_in_build.write_text(tex_path.read_text())
|
||||
|
||||
# Compile (twice, as is tradition)
|
||||
for _ in range(2):
|
||||
result = subprocess.run(
|
||||
["xelatex", "-interaction=nonstopmode", "-halt-on-error",
|
||||
f"-output-directory={BUILD_DIR}", str(tex_in_build)],
|
||||
cwd=ROOT,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
if result.returncode != 0:
|
||||
print(f"ERROR compiling {output_name}.tex:")
|
||||
print(result.stdout[-2000:])
|
||||
sys.exit(1)
|
||||
|
||||
# Move PDF to output/
|
||||
pdf_src = BUILD_DIR / f"{output_name}.pdf"
|
||||
pdf_dst = OUTPUT_DIR / f"{output_name}.pdf"
|
||||
shutil.copy(pdf_src, pdf_dst)
|
||||
print(f" → {pdf_dst}")
|
||||
|
||||
|
||||
def build_one(name):
|
||||
"""Build a single document by name ('cv' or 'resume')."""
|
||||
print(f"Building {name}...")
|
||||
data = load_all_data()
|
||||
tex_source = render(f"{name}.tex.j2", data)
|
||||
|
||||
# Write rendered .tex into build dir
|
||||
BUILD_DIR.mkdir(exist_ok=True)
|
||||
tex_path = BUILD_DIR / f"{name}.tex"
|
||||
tex_path.write_text(tex_source)
|
||||
|
||||
compile_tex(tex_path, name)
|
||||
|
||||
|
||||
def main():
|
||||
target = sys.argv[1] if len(sys.argv) > 1 else "all"
|
||||
if target in ("cv", "resume", "resume_ats"):
|
||||
build_one(target)
|
||||
elif target == "all":
|
||||
build_one("cv")
|
||||
build_one("resume")
|
||||
elif target == "all_all":
|
||||
build_one("cv")
|
||||
build_one("resume")
|
||||
build_one("resume_ats")
|
||||
else:
|
||||
print(f"Unknown target: {target}")
|
||||
print("Usage: python build.py [cv|resume|resume_ats|all|all_all]")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
affiliations:
|
||||
- name: "NSF Award \\#2148451"
|
||||
full_title: "A Learning Ecosystem for Teaching High School Students Machine Learning Concepts and Data Science Skills in Healthcare and Medicine"
|
||||
role: "Undergraduate mentor / research affiliate"
|
||||
start: October 2023
|
||||
end: May 2025
|
||||
# The award title and role line above already state what the project is
|
||||
# and what the role was; this line carries only the two non-obvious
|
||||
# qualifications a reader can't infer from them.
|
||||
description: "Not an author on the study's research outputs; independent of the Shu laboratory research."
|
||||
cv_visible: true
|
||||
resume_visible: false
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
# Education entries, most recent first.
|
||||
education:
|
||||
- institution: Technical University of Denmark (DTU)
|
||||
location: Kongens Lyngby, Denmark
|
||||
degree: MSc in Computer Science and Engineering
|
||||
start: September 2026
|
||||
end: expected 2028
|
||||
notes_cv: "Intended path toward PhD upon completion."
|
||||
notes_resume: null
|
||||
cv_visible: true
|
||||
resume_visible: true
|
||||
|
||||
- institution: Brown University
|
||||
location: Providence, RI
|
||||
degree: "Sc.B., Mathematics and Computer Science"
|
||||
start: August 2022
|
||||
end: May 2026
|
||||
gpa: "3.8/4.0"
|
||||
notes_cv: "Primary undergraduate advisor: D. Ellis Hershkowitz (Computer Science). Primary research supervisor: Liqi Shu, MD (Neurology, Warren Alpert Medical School)."
|
||||
# Résumé keeps the UTRA credential only; DIS lives on the CV as its own entry.
|
||||
notes_resume: "Brown Undergraduate Teaching and Research Award (UTRA), individual recipient, Summer 2024."
|
||||
cv_visible: true
|
||||
resume_visible: true
|
||||
|
||||
- institution: DIS Copenhagen / Københavns Universitet
|
||||
location: Copenhagen, Denmark
|
||||
degree: Semester abroad
|
||||
start: Fall 2024
|
||||
end: null
|
||||
notes_cv: null
|
||||
notes_resume: null
|
||||
cv_visible: true
|
||||
resume_visible: false # folded into Brown entry on résumé
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
# Experience entries. `resume_order` drives the résumé's Experience sort
|
||||
# (research-first: MARS V, the two Shu Lab stints, contracting, then NeuroAI).
|
||||
# `cv_order` documents intent; the CV template renders in file order within
|
||||
# each section, so keep file order and cv_order consistent. The two axes let
|
||||
# us order independently per audience without duplicating content.
|
||||
|
||||
experience:
|
||||
# MARS V heads both documents. On the CV it is routed into "Research
|
||||
# Experience" via cv_section and sits first because it appears first among
|
||||
# research entries in this file (the CV template preserves file order).
|
||||
- organization: Cambridge AI Safety Hub
|
||||
role: MARS V Fellow
|
||||
location: Cambridge, United Kingdom
|
||||
start: July 2026
|
||||
end: October 2026
|
||||
cv_section: research
|
||||
cv_order: 1
|
||||
resume_order: 1
|
||||
cv_visible: true
|
||||
resume_visible: true
|
||||
bullets:
|
||||
- "Selected for MARS V, a competitive part-time AI-safety research fellowship, working under James Petrie (Future of Life Institute)."
|
||||
- "Research on zero-knowledge proofs for large language models, toward cryptographic verification of claims about model training, inference, and deployment."
|
||||
|
||||
# TOGGLED OFF on both documents as of August 2026 — retained, not deleted.
|
||||
# The entry is accurate and stays in the file so it can be switched back on
|
||||
# by flipping the two visibility flags; the orders below are kept live so it
|
||||
# lands back in the right slot (last among industry entries) if it is.
|
||||
# Held to one line when shown: the grok-code-fast-1 scope is the dated,
|
||||
# externally verifiable part, and the metrics bullets are omitted to keep
|
||||
# both documents' centre of gravity on research.
|
||||
- organization: xAI
|
||||
location: Remote
|
||||
start: May 2025
|
||||
end: August 2025
|
||||
cv_order: 5
|
||||
resume_order: 5
|
||||
cv_visible: false
|
||||
resume_visible: false
|
||||
scope: null
|
||||
bullets:
|
||||
- "Contributed to the training of \\texttt{grok-code-fast-1}, xAI's agentic coding model. Built LLM integrations into autonomous agent frameworks and resolved 50+ agentic tool-execution failures."
|
||||
cv_summary: null
|
||||
|
||||
# Contract work renders inside Industry Experience rather than its own
|
||||
# section, and sits above NeuroAI because it is the more active of the two.
|
||||
# `contract_work: false` keeps it out of the (now conditional) Selected
|
||||
# Contract Work section while leaving that machinery available.
|
||||
- organization: "Independent Research Contractor"
|
||||
role: "Frontier AI labs"
|
||||
contract_work: false
|
||||
location: null
|
||||
start: "2025"
|
||||
end: "Present"
|
||||
cv_order: 6
|
||||
resume_order: 4
|
||||
cv_visible: true
|
||||
resume_visible: true
|
||||
bullets:
|
||||
- "Code and mathematics contributions across agentic workflow design, task and capability evaluation, reasoning assessment, model safety, and red-teaming."
|
||||
|
||||
# Held to one line: the role is stated plainly without framing the venture's
|
||||
# scope or direction.
|
||||
- organization: NeuroAI LLC
|
||||
role:
|
||||
location: neuroai.health
|
||||
location_url: https://neuroai.health
|
||||
start: March 2026
|
||||
end: Present
|
||||
cv_order: 7
|
||||
resume_order: 5
|
||||
cv_visible: true
|
||||
resume_visible: true
|
||||
bullets:
|
||||
- "Early-stage clinical-AI venture. Leading model development and deployment infrastructure."
|
||||
|
||||
# The Shu Lab is the anchor research block, split at the degree boundary:
|
||||
# the undergraduate stint carries the body of work, and the affiliate stint
|
||||
# below carries only what is still open. Splitting rather than retitling
|
||||
# keeps "Undergraduate Researcher" accurate to the years it was true.
|
||||
# Both live under "Research Experience" on the CV (a separate section from
|
||||
# Industry Experience) and under "Experience" on the résumé. The template
|
||||
# handles the section-header difference.
|
||||
- organization: Shu Laboratory, Brown University Department of Neurology
|
||||
role: Undergraduate Researcher and Technical Lead
|
||||
location: Providence, RI
|
||||
start: October 2023
|
||||
end: May 2026
|
||||
cv_section: research # forces this into "Research Experience" on CV
|
||||
cv_order: 2
|
||||
resume_order: 2
|
||||
cv_visible: true
|
||||
resume_visible: true
|
||||
# Preamble paragraph only rendered on CV; résumé jumps straight to bullets.
|
||||
cv_preamble: "Research with Dr.~Liqi Shu spanning clinical machine learning, movement-disorder kinematic analysis, and claims-based outcome prediction. Two distinct research threads:"
|
||||
bullets:
|
||||
- "Technical lead on \\textbf{NeuroPose}, a 3D pose-estimation and kinematic-analysis system for neurological-recovery research. Built end-to-end pipeline: Python/TensorFlow deep-learning inference, MATLAB statistical post-processing, Rust backend with HTML/JS frontends. System supports four externally-funded sub-projects; clinical-implications manuscript in preparation."
|
||||
- "Co-lead developer on an \\textbf{order-invariant ICD-10-CM embedding model} for 30-day readmission (AUC 0.75 vs 0.66 CCI baseline) and postdischarge mortality prediction (AUC 0.86 vs 0.78), Deep Sets architecture trained on 113M+ adult hospitalizations from the HCUP Nationwide Readmissions Database. Preprint under review at \\textit{JAMIA}; public calculator deployed at \\href{https://levineuwirth.github.io/icd_embeddings/}{levineuwirth.github.io}."
|
||||
|
||||
# Post-graduation continuation, deliberately bulletless: the work is fully
|
||||
# described in the block above, so this entry's only job is to show the
|
||||
# collaboration did not stop at the degree. Winding down through 2026.
|
||||
# (The templates skip the itemize when `bullets` is absent.)
|
||||
- organization: Shu Laboratory, Brown University Department of Neurology
|
||||
role: Research Affiliate
|
||||
location: Providence, RI
|
||||
start: May 2026
|
||||
end: Present
|
||||
cv_section: research
|
||||
cv_order: 3
|
||||
resume_order: 3
|
||||
cv_visible: true
|
||||
resume_visible: true
|
||||
|
||||
# CCV / PQC block — research experience on CV only. Not on résumé because
|
||||
# the PQC work appears there under Projects instead.
|
||||
- organization: Brown University Center for Computation and Visualization (CCV)
|
||||
role: Independent Researcher
|
||||
location: Providence, RI
|
||||
start: March 2025
|
||||
end: July 2026
|
||||
cv_section: research
|
||||
cv_order: 4
|
||||
cv_visible: true
|
||||
resume_visible: false
|
||||
bullets:
|
||||
- "Micro-architectural study of SIMD contributions to lattice-based post-quantum cryptography (ML-KEM / Kyber) on x86-64 AVX2, conducted on Brown's OSCAR HPC cluster with staff support. Phase 1 released as a technical report (see Publications)."
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
grants:
|
||||
- name: MARS V Fellowship, Cambridge AI Safety Hub
|
||||
kind: competitive selection
|
||||
year: 2026
|
||||
# Fellowship description, dates, and mentor live on the MARS V experience
|
||||
# entry; this note carries only the funding terms.
|
||||
note: "Compute, travel, and accommodation provided."
|
||||
cv_visible: true
|
||||
resume_visible: false
|
||||
|
||||
- name: Brown Undergraduate Teaching and Research Award (UTRA)
|
||||
kind: individual recipient
|
||||
year: Summer 2024
|
||||
note: "First funding awarded for NeuroPose; the work has since attracted three additional project-wide grants through the Shu laboratory."
|
||||
cv_visible: true
|
||||
resume_visible: false # folded into Brown education entry on résumé
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
# Personal contact info and header links
|
||||
name: Levi Neuwirth
|
||||
email: ln@levineuwirth.org
|
||||
phone: "+1 (845) 332-0898"
|
||||
website: levineuwirth.org
|
||||
website_url: https://levineuwirth.org
|
||||
|
||||
# Links shown in header, in order. Set 'resume_visible' / 'cv_visible' to control appearance.
|
||||
links:
|
||||
- label: ORCID
|
||||
href: https://orcid.org/0009-0002-0162-3587
|
||||
display: "0009-0002-0162-3587"
|
||||
cv_visible: true
|
||||
resume_visible: false
|
||||
- label: Forgejo
|
||||
href: https://git.levineuwirth.org/neuwirth
|
||||
display: git.levineuwirth.org/neuwirth
|
||||
cv_visible: true
|
||||
resume_visible: true
|
||||
- label: GitHub
|
||||
href: https://github.com/levineuwirth
|
||||
display: github.com/levineuwirth
|
||||
cv_visible: true
|
||||
resume_visible: true
|
||||
- label: LinkedIn
|
||||
href: https://linkedin.com/in/levineuwirth
|
||||
display: linkedin.com/in/levineuwirth
|
||||
cv_visible: false
|
||||
resume_visible: true
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
presentations:
|
||||
- authors: "Shu L, Neuwirth L†, Wang X†, Zheng H†"
|
||||
title: "Order-Invariant ICD-10-CM Embedding for Readmission and Mortality Prediction: Toward Multimodal Generative Patient Models"
|
||||
venue: "IEEE/ACM Conference on Connected Health: Applications, Systems and Engineering Technologies (CHASE)"
|
||||
year: 2026
|
||||
month: August
|
||||
status: "Presented"
|
||||
cv_visible: true
|
||||
resume_visible: false
|
||||
|
||||
- authors: "Ma J, Arms S, Kaneira L, Lall M, Chen K, Cabral W, Man D, Neuwirth L, Shu L"
|
||||
title: "Early Detection of Neurological Disorders through Video-Captured Kinematic Analysis"
|
||||
venue: "Summer UTRA Symposium, Brown University / Rhode Island Hospital Neurology Department"
|
||||
kind: "Poster presentation"
|
||||
year: 2025
|
||||
month: August
|
||||
cv_visible: true
|
||||
resume_visible: false
|
||||
|
||||
- authors: "Neuwirth L, Dasher AS"
|
||||
title: "Proving What a Datacenter Did: Verified Inference Between Adversaries"
|
||||
venue: "MARS V, Cambridge AI Safety Hub"
|
||||
year: 2026
|
||||
month: July
|
||||
status: "Accepted"
|
||||
cv_visible: true
|
||||
resume_visible: false
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
# Projects shown on CV under "Systems and Engineering Projects" and on
|
||||
# résumé under "Projects". The PQC entry is research-grade and also
|
||||
# appears in Publications on the CV; on the résumé it's the strongest
|
||||
# project and leads the list.
|
||||
|
||||
projects:
|
||||
- name: Post-Quantum Cryptography on x86 AVX2
|
||||
start: March 2025
|
||||
end: Present
|
||||
description: "Micro-architectural study of SIMD contributions to ML-KEM / Kyber on Intel AVX2, conducted on Brown's OSCAR HPC cluster. Hand-written AVX2 assembly achieves 35--56$\\times$ speedup over compiler-optimized C for core NTT arithmetic; 5.4--7.1$\\times$ end-to-end KEM speedup. Full statistical analysis (Mann-Whitney U, Cliff's $\\delta$, bootstrapped CIs). Technical report and reproducible artifact public."
|
||||
cv_visible: false # appears under Publications instead on CV
|
||||
resume_visible: true
|
||||
resume_order: 1
|
||||
|
||||
- name: Weenix
|
||||
start: January 2025
|
||||
end: August 2025
|
||||
description: "Full Unix-like kernel in 10{,}000 lines of C: virtual memory, VFS, system calls, threading, device drivers and interrupt handlers, and file systems with custom linker support for running userspace x86-64 ELF binaries. Brown CS 169."
|
||||
cv_visible: true
|
||||
resume_visible: true
|
||||
resume_order: 2
|
||||
|
||||
- name: Networking Stack from Scratch
|
||||
start: October 2024
|
||||
end: July 2025
|
||||
description: "TCP/IP, RIP, UDP, and DNS implementations in Go, supporting file transmission of up to 1~GB across networks of up to 8 virtual machines."
|
||||
cv_visible: true
|
||||
resume_visible: true
|
||||
resume_order: 3
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
# Publications and preprints. Equal-contribution undergrad authors marked
|
||||
# with equal_contrib: true; the template renders the appropriate footnote.
|
||||
|
||||
publications:
|
||||
- authors: "Shu L, Neuwirth L†, Wang X†, Zheng H†"
|
||||
title: "Beyond Comorbidity Indices: An Order-Invariant ICD-10-CM Embedding for Readmission and Mortality Prediction"
|
||||
venue: "Under review at \\textit{Journal of the American Medical Informatics Association} (JAMIA)"
|
||||
year: 2026
|
||||
links:
|
||||
- label: Preprint
|
||||
href: https://levineuwirth.org/essays/beyond-comorbidity-indices/
|
||||
- label: Code
|
||||
href: https://git.levineuwirth.org/neuwirth/beyond_comorbidity_indices
|
||||
- label: Calculator
|
||||
href: https://levineuwirth.github.io/icd_embeddings/
|
||||
equal_contrib_note: "†~Equal contribution among undergraduate authors."
|
||||
cv_visible: true
|
||||
resume_visible: false # surfaced instead via the Shu Lab bullet on résumé
|
||||
|
||||
- authors: "Neuwirth L"
|
||||
title: "Branch-Tube Persistence and Static Coverage in Tree-Ball Geometry"
|
||||
venue: "Preprint"
|
||||
year: 2026
|
||||
month: July
|
||||
links:
|
||||
- label: Preprint
|
||||
href: https://levineuwirth.org/essays/branch-based-local-capture-in-tree-balls/
|
||||
cv_visible: true
|
||||
resume_visible: false # math preprint; engineering résumé surfaces other work
|
||||
|
||||
- authors: "Neuwirth L"
|
||||
title: "The Annealed Critical Window for Growing-Radius Domination in Random Regular Graphs"
|
||||
venue: "Preprint"
|
||||
year: 2026
|
||||
month: July
|
||||
links:
|
||||
- label: Preprint
|
||||
href: https://levineuwirth.org/essays/near-critical-growing-radius-domination.html
|
||||
cv_visible: true
|
||||
resume_visible: false # math preprint; engineering résumé surfaces other work
|
||||
|
||||
- authors: "Neuwirth L"
|
||||
title: "Where Does SIMD Help Post-Quantum Cryptography? A Micro-Architectural Study of ML-KEM on x86 AVX2"
|
||||
venue: "Technical report, Brown University Department of Computer Science"
|
||||
year: 2026
|
||||
month: April
|
||||
links:
|
||||
- label: Report
|
||||
href: https://levineuwirth.org/essays/where-does-simd-help-post-quantum-cryptography/
|
||||
- label: Artifact
|
||||
href: https://git.levineuwirth.org/neuwirth/where-simd-helps
|
||||
cv_visible: true
|
||||
resume_visible: false # surfaced instead via the PQC project on résumé
|
||||
|
||||
- authors: "NeuroPose clinical-implications manuscript"
|
||||
title: null
|
||||
venue: "In preparation. Shu laboratory, Brown University Department of Neurology."
|
||||
year: "2026--2027"
|
||||
links:
|
||||
- label: Artifact
|
||||
href: https://git.levineuwirth.org/neuwirth/neuropose
|
||||
target: "Target venue TBD"
|
||||
cv_visible: true
|
||||
resume_visible: false # "in prep" doesn't belong on a résumé
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
skills:
|
||||
programming:
|
||||
label: Programming
|
||||
items:
|
||||
- "Assembly (x86-64, inline SIMD)"
|
||||
- C
|
||||
- C++
|
||||
- "C\\#"
|
||||
- Go
|
||||
- Haskell
|
||||
- Java
|
||||
- JavaScript
|
||||
- Python
|
||||
- Rust
|
||||
cv_visible: true
|
||||
resume_visible: true
|
||||
|
||||
ml_ai:
|
||||
label: ML and AI
|
||||
items:
|
||||
- PyTorch
|
||||
- TensorFlow
|
||||
- NumPy
|
||||
- Pandas
|
||||
- OpenCV
|
||||
cv_visible: true
|
||||
resume_visible: true
|
||||
|
||||
tools:
|
||||
label: Tools and platforms
|
||||
items:
|
||||
- Git
|
||||
- LaTeX
|
||||
- Linux (Arch, Debian, Gentoo)
|
||||
- make
|
||||
- SLURM
|
||||
- perf
|
||||
- Docker
|
||||
cv_visible: true
|
||||
resume_visible: true
|
||||
|
||||
# Human languages — separate section on CV, folded into Skills on résumé.
|
||||
languages:
|
||||
- name: English
|
||||
level: native
|
||||
- name: Spanish
|
||||
level: C1
|
||||
- name: German
|
||||
level: B1
|
||||
- name: Danish
|
||||
level: A2
|
||||
- name: French
|
||||
level: A1
|
||||
|
||||
# Research interests line — CV only; absent from résumé.
|
||||
research_interests: "AI safety; graph theory, number theory, and theoretical computer science; computer systems and high-performance computing; artificial intelligence and machine learning; reinforcement learning; deep learning; cryptography; computer vision; computer architecture; security; clinical and biomedical ML"
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
\documentclass[11pt]{article}
|
||||
|
||||
\input{templates/shared/preamble.tex}
|
||||
|
||||
\geometry{
|
||||
letterpaper,
|
||||
top=0.9in,
|
||||
bottom=0.9in,
|
||||
left=1.0in,
|
||||
right=1.0in
|
||||
}
|
||||
|
||||
\input{templates/shared/commands.tex}
|
||||
|
||||
\begin{document}
|
||||
|
||||
% HEADER
|
||||
\begin{center}
|
||||
{\headerfont\LARGE\bfseries (((personal.name)))}\\[0.3em]
|
||||
{\headerfont\small\color{metagray}CURRICULUM VITAE \textperiodcentered\ Last updated (((build_date)))}\\[0.8em]
|
||||
{\small
|
||||
\href{mailto:(((personal.email)))}{(((personal.email)))}
|
||||
\ \textperiodcentered\
|
||||
(((personal.phone)))
|
||||
\ \textperiodcentered\
|
||||
\href{(((personal.website_url)))}{(((personal.website)))}
|
||||
((* for link in personal.links if link.cv_visible *))
|
||||
\ \textperiodcentered\
|
||||
\href{(((link.href)))}{(((link.label))): (((link.display)))}
|
||||
((* endfor *))
|
||||
}
|
||||
\end{center}
|
||||
|
||||
\vspace{0.4em}
|
||||
|
||||
% EDUCATION
|
||||
\section*{Education}
|
||||
|
||||
((* for edu in education if edu.cv_visible *))
|
||||
\entryheader{(((edu.institution)))}{}{(((edu.start)))((* if edu.end *)) -- (((edu.end)))((* endif *))}{(((edu.location)))}
|
||||
\textit{(((edu.degree)))}((* if edu.gpa *)). GPA (((edu.gpa))).((* else *)).((* endif *))
|
||||
((* if edu.notes_cv *))
|
||||
\\[0.2em] {\small (((edu.notes_cv)))}
|
||||
((* endif *))
|
||||
\par\vspace{0.5em}
|
||||
((* endfor *))
|
||||
|
||||
% RESEARCH EXPERIENCE
|
||||
\section*{Research Experience}
|
||||
|
||||
((* for exp in experience if exp.cv_visible and exp.cv_section == 'research' *))
|
||||
\entryheader{(((exp.organization)))}{(((exp.role or '')))}{(((exp.start)))((* if exp.end *)) -- (((exp.end)))((* endif *))}{(((exp.location or '')))}
|
||||
((* if exp.cv_preamble *))
|
||||
(((exp.cv_preamble)))
|
||||
\par\vspace{0.3em}
|
||||
((* endif *))
|
||||
((* if exp.bullets *))
|
||||
\begin{itemize}
|
||||
((* for bullet in exp.bullets *))
|
||||
\item (((bullet)))
|
||||
((* endfor *))
|
||||
\end{itemize}
|
||||
((* endif *))
|
||||
\vspace{0.3em}
|
||||
((* endfor *))
|
||||
|
||||
% PUBLICATIONS AND PREPRINTS
|
||||
\section*{Publications and Preprints}
|
||||
|
||||
{\small Equal-contribution undergraduate authors are marked with \textdagger.}\par\vspace{0.4em}
|
||||
|
||||
((* for pub in publications if pub.cv_visible *))
|
||||
\noindent
|
||||
((* if pub.title *))
|
||||
\textbf{(((pub.authors))).} \textit{(((pub.title))).} (((pub.venue))).%
|
||||
((* if pub.links *))
|
||||
((* for link in pub.links *))
|
||||
\ \href{(((link.href)))}{[(((link.label)))]}%
|
||||
((* endfor *))
|
||||
((* endif *))
|
||||
\ (((pub.year)))((* if pub.month *)), (((pub.month)))((* endif *)).
|
||||
((* else *))
|
||||
\textbf{(((pub.authors))).} (((pub.venue)))((* if pub.target *)) (((pub.target)))((* endif *)), (((pub.year))).
|
||||
((* endif *))
|
||||
\par\vspace{0.5em}
|
||||
((* endfor *))
|
||||
|
||||
% PRESENTATIONS
|
||||
\section*{Presentations}
|
||||
|
||||
((* for pres in presentations if pres.cv_visible *))
|
||||
\noindent
|
||||
\textbf{(((pres.authors))).} \textit{(((pres.title))).}
|
||||
((* if pres.kind *)) (((pres.kind))),((* endif *))
|
||||
\ (((pres.venue))),((* if pres.month *)) (((pres.month))) (((pres.year))).((* else *)) (((pres.year))).((* endif *))
|
||||
((* if pres.status *)) (((pres.status))).((* endif *))
|
||||
\par\vspace{0.5em}
|
||||
((* endfor *))
|
||||
|
||||
% GRANTS AND AWARDS
|
||||
\section*{Grants and Awards}
|
||||
|
||||
((* for grant in grants if grant.cv_visible *))
|
||||
\noindent
|
||||
\textbf{(((grant.name)))}((* if grant.kind *)), (((grant.kind)))((* endif *)).((* if grant.year *)) (((grant.year))).((* endif *))
|
||||
((* if grant.note *))
|
||||
\\[0.15em] {\small (((grant.note)))}
|
||||
((* endif *))
|
||||
\par\vspace{0.4em}
|
||||
((* endfor *))
|
||||
|
||||
% RESEARCH AFFILIATIONS
|
||||
\section*{Research Affiliations}
|
||||
|
||||
((* for aff in affiliations if aff.cv_visible *))
|
||||
\entryheader{(((aff.name))) --- (((aff.full_title)))}{(((aff.role)))}{(((aff.start)))((* if aff.end *)) -- (((aff.end)))((* endif *))}{}
|
||||
{\small (((aff.description)))}
|
||||
\par\vspace{0.4em}
|
||||
((* endfor *))
|
||||
|
||||
% SYSTEMS AND ENGINEERING PROJECTS
|
||||
\section*{Systems and Engineering Projects}
|
||||
|
||||
((* for proj in projects if proj.cv_visible *))
|
||||
\noindent
|
||||
\textbf{(((proj.name)))} {\small\color{metagray}\textit{(((proj.start)))((* if proj.end *)) -- (((proj.end)))((* endif *))}}. (((proj.description)))
|
||||
\par\vspace{0.4em}
|
||||
((* endfor *))
|
||||
|
||||
% INDUSTRY EXPERIENCE
|
||||
\section*{Industry Experience}
|
||||
|
||||
((* for exp in experience if exp.cv_visible and exp.cv_section != 'research' and not exp.contract_work *))
|
||||
\entryheader{(((exp.organization)))}{(((exp.role or '')))}{(((exp.start)))((* if exp.end *)) -- (((exp.end)))((* endif *))}{(((exp.location or '')))}
|
||||
((* if exp.scope *))
|
||||
(((exp.scope)))
|
||||
\par\vspace{0.2em}
|
||||
((* endif *))
|
||||
((* if not exp.bullets *))
|
||||
((* elif exp.bullets|length == 1 *))
|
||||
(((exp.bullets[0])))
|
||||
\par
|
||||
((* else *))
|
||||
\begin{itemize}
|
||||
((* for bullet in exp.bullets *))
|
||||
\item (((bullet)))
|
||||
((* endfor *))
|
||||
\end{itemize}
|
||||
((* endif *))
|
||||
\vspace{0.3em}
|
||||
((* endfor *))
|
||||
|
||||
% SELECTED CONTRACT WORK
|
||||
% Conditional: contract entries normally render inside Industry Experience.
|
||||
% This section appears only if an entry opts in with `contract_work: true`,
|
||||
% so the heading never renders empty.
|
||||
((* set contract_entries = experience | selectattr('cv_visible') | selectattr('contract_work', 'defined') | selectattr('contract_work') | list *))
|
||||
((* if contract_entries *))
|
||||
\section*{Selected Contract Work}
|
||||
|
||||
((* for exp in contract_entries *))
|
||||
\noindent
|
||||
\textbf{(((exp.organization))) --- (((exp.role)))}. {\small\color{metagray}(((exp.start)))((* if exp.end *)) -- (((exp.end)))((* endif *))}.
|
||||
\par\vspace{0.2em}
|
||||
((* for bullet in exp.bullets *))
|
||||
(((bullet)))
|
||||
((* endfor *))
|
||||
((* if exp.cv_disclaimer *))
|
||||
\par\vspace{0.2em}
|
||||
{\small\textit{(((exp.cv_disclaimer)))}}
|
||||
((* endif *))
|
||||
((* endfor *))
|
||||
((* endif *))
|
||||
|
||||
% LANGUAGES
|
||||
\section*{Languages}
|
||||
|
||||
((* for lang in languages *))
|
||||
(((lang.name))) (((lang.level)))((* if not loop.last *)) \textperiodcentered\ ((* else *)).((* endif *))
|
||||
((* endfor *))
|
||||
|
||||
% TECHNICAL SKILLS
|
||||
\section*{Technical Skills}
|
||||
|
||||
((* for key, group in skills.items() if group.cv_visible *))
|
||||
\noindent\textbf{(((group.label))):} (((group['items'] | join(', ')))).\par\vspace{0.2em}
|
||||
((* endfor *))
|
||||
|
||||
% RESEARCH INTERESTS
|
||||
\section*{Research Interests}
|
||||
|
||||
(((research_interests)))
|
||||
|
||||
\end{document}
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
\documentclass[10pt]{extarticle}
|
||||
|
||||
\input{templates/shared/preamble.tex}
|
||||
|
||||
% 10.5pt body via extarticle + renewcommand approach.
|
||||
% extarticle supports 8pt-20pt in 0.5pt increments; we set via class option
|
||||
% above to 10pt then bump with \fontsize locally. Cleaner: just use 11pt
|
||||
% class option with compensating \linespread. Simplest approach below:
|
||||
\renewcommand{\normalsize}{\fontsize{10.5}{12.5}\selectfont}
|
||||
\normalsize
|
||||
|
||||
\geometry{
|
||||
letterpaper,
|
||||
top=0.5in,
|
||||
bottom=0.5in,
|
||||
left=0.7in,
|
||||
right=0.7in
|
||||
}
|
||||
|
||||
\input{templates/shared/commands.tex}
|
||||
|
||||
% Ragged-right to prevent awkward word-spacing from full justification.
|
||||
\RaggedRight
|
||||
|
||||
% Résumé spacing: tightened for one-page fit.
|
||||
\titlespacing*{\section}{0pt}{0.4em}{0.15em}
|
||||
\setlist[itemize]{
|
||||
leftmargin=1.2em,
|
||||
topsep=0.1em,
|
||||
itemsep=0.08em,
|
||||
parsep=0pt,
|
||||
label={\small\textbullet}
|
||||
}
|
||||
\setlength{\parskip}{0.1em}
|
||||
|
||||
% Looser entryheader: date/location on its own line below the org/role line.
|
||||
% This prevents awkward wrap for long org names like Shu Laboratory.
|
||||
\renewcommand{\entryheader}[4]{%
|
||||
\noindent
|
||||
\textbf{#1}\ifx&\else~---~\textit{#2}\fi%
|
||||
\par
|
||||
\vspace{-0.15em}%
|
||||
{\small\color{metagray}#3\ifx&\else~\textperiodcentered~#4\fi}%
|
||||
\par\vspace{0.15em}%
|
||||
}
|
||||
|
||||
\begin{document}
|
||||
|
||||
% HEADER
|
||||
\begin{center}
|
||||
{\headerfont\Large\bfseries (((personal.name)))}\\[0.25em]
|
||||
{\small
|
||||
\href{mailto:(((personal.email)))}{(((personal.email)))}
|
||||
\ \textperiodcentered\
|
||||
(((personal.phone)))
|
||||
\ \textperiodcentered\
|
||||
\href{(((personal.website_url)))}{(((personal.website)))}
|
||||
((* for link in personal.links if link.resume_visible *))
|
||||
\ \textperiodcentered\
|
||||
\href{(((link.href)))}{(((link.label)))}
|
||||
((* endfor *))
|
||||
}
|
||||
\end{center}
|
||||
|
||||
\vspace{0.1em}
|
||||
|
||||
% EXPERIENCE (ordered by resume_order)
|
||||
\section*{Experience}
|
||||
|
||||
((* for exp in (experience | selectattr('resume_visible') | sort(attribute='resume_order') | list) *))
|
||||
\entryheader{(((exp.organization)))}{(((exp.role or '')))}{(((exp.start)))((* if exp.end *)) -- (((exp.end)))((* endif *))}{(((exp.location or '')))}
|
||||
((* if exp.scope *))
|
||||
(((exp.scope)))
|
||||
\par\vspace{0.1em}
|
||||
((* endif *))
|
||||
((* if not exp.bullets *))
|
||||
((* elif exp.bullets|length == 1 *))
|
||||
(((exp.bullets[0])))
|
||||
\par
|
||||
((* else *))
|
||||
\begin{itemize}
|
||||
((* for bullet in exp.bullets *))
|
||||
\item (((bullet)))
|
||||
((* endfor *))
|
||||
\end{itemize}
|
||||
((* endif *))
|
||||
\vspace{0.1em}
|
||||
((* endfor *))
|
||||
|
||||
% PROJECTS
|
||||
\section*{Projects}
|
||||
|
||||
((* for proj in (projects | selectattr('resume_visible') | sort(attribute='resume_order') | list) *))
|
||||
\noindent\textbf{(((proj.name)))} {\small\color{metagray}\textit{(((proj.start)))((* if proj.end *)) -- (((proj.end)))((* endif *))}}. (((proj.description)))
|
||||
\par\vspace{0.1em}
|
||||
((* endfor *))
|
||||
|
||||
% EDUCATION
|
||||
\section*{Education}
|
||||
|
||||
((* for edu in education if edu.resume_visible *))
|
||||
\entryheader{(((edu.institution)))}{(((edu.degree)))}{(((edu.start)))((* if edu.end *)) -- (((edu.end)))((* endif *))}{(((edu.location)))}
|
||||
((* if edu.gpa or edu.notes_resume *))
|
||||
{\small ((* if edu.gpa *))GPA (((edu.gpa))).((* endif *))((* if edu.notes_resume *)) (((edu.notes_resume)))((* endif *))}
|
||||
((* endif *))
|
||||
\vspace{0.1em}
|
||||
((* endfor *))
|
||||
|
||||
% Skills are intentionally omitted from this résumé — the projects and
|
||||
% experience entries above prove the stack more credibly than a list can.
|
||||
% A keyword-dense ATS variant can be rendered from the same YAMLs via a
|
||||
% separate template when needed.
|
||||
|
||||
\end{document}
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
%% ATS-optimized résumé variant.
|
||||
%%
|
||||
%% Design priorities, in order:
|
||||
%% 1. Parses cleanly through ATS pipelines — single column, conventional
|
||||
%% section headings ("Work Experience", "Technical Skills", etc.),
|
||||
%% no images or boxes, no fancy typography hacks.
|
||||
%% 2. Keyword density — restores the Technical Skills section and opens
|
||||
%% with a professional summary so keyword matchers have plenty to
|
||||
%% grep over.
|
||||
%% 3. Readable for a human recruiter skimming the output of whatever
|
||||
%% ATS the company uses.
|
||||
%%
|
||||
%% Page budget is unconstrained; ATS pipelines do not penalize 2 pages.
|
||||
%% The website-facing résumé (resume.tex.j2) is the 1-page artifact.
|
||||
|
||||
\documentclass[11pt]{article}
|
||||
|
||||
\input{templates/shared/preamble.tex}
|
||||
|
||||
\geometry{
|
||||
letterpaper,
|
||||
top=1in,
|
||||
bottom=1in,
|
||||
left=1in,
|
||||
right=1in
|
||||
}
|
||||
|
||||
\input{templates/shared/commands.tex}
|
||||
|
||||
% Ragged-right reads more naturally than full justification in short lines.
|
||||
\RaggedRight
|
||||
|
||||
% Conventional section spacing — not tight, not loose. ATS parsers are
|
||||
% sensitive to unusual vertical rhythm; stick close to article defaults.
|
||||
\titlespacing*{\section}{0pt}{0.8em}{0.3em}
|
||||
\setlist[itemize]{
|
||||
leftmargin=1.2em,
|
||||
topsep=0.25em,
|
||||
itemsep=0.2em,
|
||||
parsep=0pt,
|
||||
label={\small\textbullet}
|
||||
}
|
||||
\setlength{\parskip}{0.3em}
|
||||
|
||||
% Entryheader for ATS: organization/role on one line, date/location on
|
||||
% the next. Plain black text (no metagray) because some ATS grayscale
|
||||
% conversions mangle low-contrast text.
|
||||
\renewcommand{\entryheader}[4]{%
|
||||
\noindent
|
||||
\textbf{#1}\ifx&\else~---~\textit{#2}\fi%
|
||||
\par
|
||||
\vspace{-0.15em}%
|
||||
{\small #3\ifx&\else~\textperiodcentered~#4\fi}%
|
||||
\par\vspace{0.2em}%
|
||||
}
|
||||
|
||||
\begin{document}
|
||||
|
||||
%% HEADER
|
||||
\begin{center}
|
||||
{\headerfont\Large\bfseries (((personal.name)))}\\[0.25em]
|
||||
{\small
|
||||
\href{mailto:(((personal.email)))}{(((personal.email)))}
|
||||
\ \textperiodcentered\
|
||||
(((personal.phone)))
|
||||
\ \textperiodcentered\
|
||||
\href{(((personal.website_url)))}{(((personal.website)))}
|
||||
((* for link in personal.links if link.resume_visible *))
|
||||
\ \textperiodcentered\
|
||||
\href{(((link.href)))}{(((link.label)))}
|
||||
((* endfor *))
|
||||
}
|
||||
\end{center}
|
||||
|
||||
\vspace{0.3em}
|
||||
|
||||
%% SUMMARY
|
||||
\section*{Summary}
|
||||
|
||||
Computer science and mathematics researcher and engineer building autonomous AI agents, clinical machine-learning systems, and low-level cryptographic software. Summer 2025 intern at xAI contributing to training of \texttt{grok-code-fast-1}. Co-founder of NeuroAI LLC (clinical AI tooling). Undergraduate research at Brown University Department of Neurology; preprint under review at \textit{JAMA Network Open}. Independent research in post-quantum cryptography and SIMD micro-architecture, supported by Brown's HPC staff. Proficient in Python, Rust, Go, C, Assembly (x86-64 AVX2), and modern ML frameworks (PyTorch, TensorFlow).
|
||||
|
||||
%% WORK EXPERIENCE
|
||||
\section*{Work Experience}
|
||||
|
||||
((* for exp in (experience | selectattr('resume_visible') | sort(attribute='resume_order') | list) *))
|
||||
\entryheader{(((exp.organization)))}{(((exp.role)))}{(((exp.start)))((* if exp.end *)) -- (((exp.end)))((* endif *))}{(((exp.location or '')))}
|
||||
((* if exp.scope *))
|
||||
(((exp.scope)))
|
||||
\par\vspace{0.1em}
|
||||
((* endif *))
|
||||
((* if exp.bullets|length == 1 *))
|
||||
(((exp.bullets[0])))
|
||||
\par
|
||||
((* else *))
|
||||
\begin{itemize}
|
||||
((* for bullet in exp.bullets *))
|
||||
\item (((bullet)))
|
||||
((* endfor *))
|
||||
\end{itemize}
|
||||
((* endif *))
|
||||
\vspace{0.3em}
|
||||
((* endfor *))
|
||||
|
||||
%% PROJECTS
|
||||
\section*{Projects}
|
||||
|
||||
((* for proj in (projects | selectattr('resume_visible') | sort(attribute='resume_order') | list) *))
|
||||
\noindent\textbf{(((proj.name)))} \textit{(((proj.start)))((* if proj.end *)) -- (((proj.end)))((* endif *))}. (((proj.description)))
|
||||
\par\vspace{0.3em}
|
||||
((* endfor *))
|
||||
|
||||
%% EDUCATION
|
||||
\section*{Education}
|
||||
|
||||
((* for edu in education if edu.resume_visible *))
|
||||
\entryheader{(((edu.institution)))}{(((edu.degree)))}{(((edu.start)))((* if edu.end *)) -- (((edu.end)))((* endif *))}{(((edu.location)))}
|
||||
((* if edu.gpa or edu.notes_resume *))
|
||||
{\small ((* if edu.gpa *))GPA (((edu.gpa))).((* endif *))((* if edu.notes_resume *)) (((edu.notes_resume)))((* endif *))}
|
||||
((* endif *))
|
||||
\vspace{0.2em}
|
||||
((* endfor *))
|
||||
|
||||
%% TECHNICAL SKILLS — restored for ATS keyword matching.
|
||||
\section*{Technical Skills}
|
||||
|
||||
((* for key, group in skills.items() if group.resume_visible *))
|
||||
\noindent\textbf{(((group.label))):} (((group['items'] | join(', ')))).\par\vspace{0.15em}
|
||||
((* endfor *))
|
||||
\noindent\textbf{Human Languages:}
|
||||
((* for lang in languages *))
|
||||
(((lang.name))) (((lang.level)))((* if not loop.last *)), ((* else *)).((* endif *))
|
||||
((* endfor *))
|
||||
|
||||
\end{document}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
% Custom macros and section formatting.
|
||||
|
||||
% \sectionheader — unified section header style, sans-serif, uppercase tracking,
|
||||
% thin rule beneath. Used by both templates for consistency.
|
||||
\titleformat{\section}
|
||||
{\headerfont\large\bfseries\MakeUppercase}
|
||||
{}{0pt}
|
||||
{}
|
||||
[\vspace{-0.4em}\rule{\linewidth}{0.4pt}]
|
||||
|
||||
\titlespacing*{\section}{0pt}{1.2em}{0.6em}
|
||||
|
||||
% \subsectionheader — for sub-entries (e.g., NeuroPose within Shu Lab).
|
||||
\titleformat{\subsection}
|
||||
{\headerfont\normalsize\bfseries}
|
||||
{}{0pt}
|
||||
{}
|
||||
|
||||
\titlespacing*{\subsection}{0pt}{0.6em}{0.2em}
|
||||
|
||||
% \entryheader — a standard role/institution block. Two lines:
|
||||
% Line 1: \textbf{Organization} — \textit{Role}
|
||||
% Line 2: \small dates · location
|
||||
\newcommand{\entryheader}[4]{%
|
||||
\noindent\textbf{#1}%
|
||||
\ifx&\else~---~\textit{#2}\fi\\[0.1em]
|
||||
{\small\color{metagray}#3\ifx&\else~\textperiodcentered~#4\fi}%
|
||||
\par\vspace{0.2em}%
|
||||
}
|
||||
|
||||
% \pubentry — a publication/presentation line.
|
||||
\newcommand{\pubentry}[3]{%
|
||||
\noindent #1. \textit{#2}. {\small\color{metagray}#3}%
|
||||
\par\vspace{0.35em}%
|
||||
}
|
||||
|
||||
% \headerblock — document-top name and contact. Rendered differently by the
|
||||
% two templates, so the actual layout is defined there; this is just a
|
||||
% placeholder hook if we want to factor it out later.
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
% Shared preamble: packages, fonts, page geometry.
|
||||
% Kept intentionally minimal — every package here is mainstream and stable.
|
||||
|
||||
\usepackage{fontspec}
|
||||
\usepackage{geometry}
|
||||
\usepackage{titlesec}
|
||||
\usepackage{enumitem}
|
||||
\usepackage{hyperref}
|
||||
\usepackage{xcolor}
|
||||
\usepackage{ragged2e}
|
||||
\usepackage{fancyhdr}
|
||||
|
||||
% Fonts: Source Serif/Sans if available, fall back to TeX Gyre (Termes/Heros).
|
||||
% TeX Gyre ships with every TeX Live install, so this compiles anywhere.
|
||||
% To force Source fonts on your own machine, just ensure they're installed
|
||||
% system-wide or via TeX Live's fontspec search path.
|
||||
\IfFontExistsTF{Source Serif Pro}{
|
||||
\setmainfont[Ligatures=TeX, Numbers={Lining,Proportional}]{Source Serif Pro}
|
||||
}{
|
||||
\setmainfont[Ligatures=TeX, Numbers={Lining,Proportional}]{TeX Gyre Termes}
|
||||
}
|
||||
|
||||
\IfFontExistsTF{Source Sans Pro}{
|
||||
\newfontfamily\headerfont[Ligatures=TeX, Numbers={Lining,Proportional}]{Source Sans Pro}
|
||||
}{
|
||||
\newfontfamily\headerfont[Ligatures=TeX, Numbers={Lining,Proportional}]{TeX Gyre Heros}
|
||||
}
|
||||
|
||||
% Black-and-white color palette. `linkcolor` stays black for print-conservative
|
||||
% output; the URL is still clickable in PDF readers.
|
||||
\definecolor{headerblack}{gray}{0.0}
|
||||
\definecolor{rulegray}{gray}{0.15}
|
||||
\definecolor{metagray}{gray}{0.35}
|
||||
|
||||
\hypersetup{
|
||||
colorlinks=true,
|
||||
linkcolor=black,
|
||||
urlcolor=black,
|
||||
citecolor=black,
|
||||
pdfborder={0 0 0}
|
||||
}
|
||||
|
||||
% No paragraph indent, small inter-paragraph space.
|
||||
\setlength{\parindent}{0pt}
|
||||
\setlength{\parskip}{0.35em}
|
||||
|
||||
% Tight list defaults — itemize blocks should feel controlled, not sprawling.
|
||||
\setlist[itemize]{
|
||||
leftmargin=1.2em,
|
||||
topsep=0.2em,
|
||||
itemsep=0.25em,
|
||||
parsep=0pt,
|
||||
label={\small\textbullet}
|
||||
}
|
||||
Loading…
Reference in New Issue