// Robb Doering's resume, typeset by RenderCV 2.8. Compile it with `typst compile <this file>`.
// Needs Typst 0.14 or newer. The first compile fetches @preview/rendercv:0.3.0 and its
// fontawesome dependency from Typst Universe, so it wants a network connection once.
// Set in Newsreader Text, Newsreader Display, and MonaspiceNe NF (Nerd Font), which it does not
// embed: without them Typst falls back to its default font and the page count can change.
// Import the rendercv function and all the refactored components
#import "@preview/rendercv:0.3.0": *

// doering.ai v5 "academic" palette: slate ink, one mineral-cyan accent, amber as a rare mark.
#let ink = rgb("#16202c")
#let ink-2 = rgb("#4c5a6a")
#let rule-1 = rgb("#dce2e9")
#let rule-2 = rgb("#c4cdd7")
#let paper = rgb("#f5f7f9")
#let accent-2 = rgb("#074b59")
#let amber-mark = rgb("#e8a01e")
#let mono = "MonaspiceNe NF"

// Small tracked mono label, as on the site's figures.
#let mono-label(body) = text(font: mono, size: 6.6pt, tracking: 0.08em, fill: accent-2, upper(body))

// Dates and locations: mono metadata in secondary ink.
#let meta-column(body) = {
  set text(font: mono, size: 7.4pt, fill: ink-2, tracking: 0.01em)
  body
}

// Skills as plates: one tinted cell per area, items set as a run separated by thin dots.
#let skills-plates(columns: 3, ..areas) = {
  set par(leading: 0.48em, spacing: 0pt, justify: false)
  grid(
    columns: (1fr,) * columns,
    column-gutter: 5pt,
    row-gutter: 5pt,
    fill: paper,
    stroke: 0.6pt + rule-2,
    inset: (x: 7pt, top: 6pt, bottom: 7pt),
    ..areas.pos().map(((label, items)) => {
      block(below: 5pt, text(font: mono, fill: amber-mark, size: 5.6pt, baseline: -0.5pt)[■] + h(0.45em) + mono-label(label))
      text(size: 0.93em, items.map(box).join([~#text(fill: ink-2, weight: 600)[·] ]))
    }),
  )
}

// Skills as a ledger: hairline rows, mono label at left, items at right.
#let skills-ledger(columns: 3, ..areas) = {
  set par(leading: 0.5em, spacing: 0pt, justify: false)
  let rows = areas.pos()
  grid(
    columns: (3.4cm, 1fr),
    column-gutter: 8pt,
    inset: (y: 4.2pt),
    stroke: (x, y) => (
      top: 0.5pt + rule-1,
      bottom: if y == rows.len() - 1 { 0.5pt + rule-1 },
    ),
    ..rows.map(((label, items)) => (pad(top: 1.2pt, mono-label(label)), items.join([, ]))).flatten(),
  )
}

#set strong(delta: 200)
#show raw: set text(font: mono, size: 0.92em)

// Apply the rendercv template with custom configuration
#show: rendercv.with(
  name: "Robb Doering",
  title: "Robb Doering - CV",
  footer: context { [#emph[Robb Doering -- #str(here().page())\/#str(counter(page).final().first())]] },
  top-note: [ #emph[Last updated in Oct 2026] ],
  locale-catalog-language: "en",
  text-direction: ltr,
  page-size: "us-letter",
  page-top-margin: 1.2cm,
  page-bottom-margin: 1.2cm,
  page-left-margin: 1.5cm,
  page-right-margin: 1.5cm,
  page-show-footer: true,
  page-show-top-note: false,
  colors-body: rgb(22, 32, 44),
  colors-name: rgb(22, 32, 44),
  colors-headline: rgb(76, 90, 106),
  colors-connections: rgb(76, 90, 106),
  colors-section-titles: rgb(196, 205, 215),
  colors-links: rgb(10, 108, 128),
  colors-footer: rgb(76, 90, 106),
  colors-top-note: rgb(76, 90, 106),
  typography-line-spacing: 0.6em,
  typography-alignment: "left",
  typography-date-and-location-column-alignment: right,
  typography-font-family-body: "Newsreader Text",
  typography-font-family-name: "Newsreader Display",
  typography-font-family-headline: "Newsreader Text",
  typography-font-family-connections: "MonaspiceNe NF",
  typography-font-family-section-titles: "Newsreader Text",
  typography-font-size-body: 10pt,
  typography-font-size-name: 28pt,
  typography-font-size-headline: 11.5pt,
  typography-font-size-connections: 7.4pt,
  typography-font-size-section-titles: 12pt,
  typography-small-caps-name: false,
  typography-small-caps-headline: false,
  typography-small-caps-connections: false,
  typography-small-caps-section-titles: false,
  typography-bold-name: false,
  typography-bold-headline: false,
  typography-bold-connections: false,
  typography-bold-section-titles: false,
  links-underline: false,
  links-show-external-link-icon: false,
  header-alignment: left,
  header-photo-width: 3.5cm,
  header-space-below-name: 0.24cm,
  header-space-below-headline: 0.3cm,
  header-space-below-connections: 0.3cm,
  header-connections-hyperlink: true,
  header-connections-show-icons: false,
  header-connections-display-urls-instead-of-usernames: true,
  header-connections-separator: "",
  header-connections-space-between-connections: 0.25cm,
  section-titles-type: "with_partial_line",
  section-titles-line-thickness: 0.5pt,
  section-titles-space-above: 0.5cm,
  section-titles-space-below: 0.24cm,
  sections-allow-page-break: true,
  sections-space-between-text-based-entries: 0.3em,
  sections-space-between-regular-entries: 0.9em,
  entries-date-and-location-width: 3.6cm,
  entries-side-space: 0cm,
  entries-space-between-columns: 0.1cm,
  entries-allow-page-break: false,
  entries-short-second-row: false,
  entries-degree-width: 1cm,
  entries-summary-space-left: 0cm,
  entries-summary-space-above: 0cm,
  entries-highlights-bullet: text(fill: rule-2.darken(18%), [•]),
  entries-highlights-nested-bullet: text(fill: rule-2.darken(18%), [•]),
  entries-highlights-space-left: 0.3cm,
  entries-highlights-space-above: 0.1cm,
  entries-highlights-space-between-items: 0.12cm,
  entries-highlights-space-between-bullet-and-text: 0.5em,
  date: datetime(
    year: 2026,
    month: 10,
    day: 13,
  ),
)

#grid(
  columns: (1fr, auto),
  column-gutter: 14pt,
  align: (left + bottom, left + bottom),
  [
    #block(below: 0.24cm, text(
      font: "Newsreader Display",
      size: 28pt,
      weight: 600,
      fill: ink,
    )[Robb Doering])
    #text(
      font: "Newsreader Text",
      size: 11.5pt,
      style: "italic",
      fill: ink-2,
    )[Senior Full Stack Engineer · Agentic Engineering]
  ],
  [
    #set text(font: mono, size: 7.4pt, fill: ink-2)
    #grid(
      columns: 2,
      column-gutter: 13pt,
      row-gutter: 4.6pt,
      [#link("mailto:robb@doering.ai", icon: false, if-underline: false, if-color: false)[robb\@doering.ai]],
      [#link("tel:+1-415-713-1766", icon: false, if-underline: false, if-color: false)[(415) 713-1766]],
      [#link("https://doering.ai/", icon: false, if-underline: false, if-color: false)[doering.ai]],
      [#link("https://linkedin.com/in/robbd", icon: false, if-underline: false, if-color: false)[linkedin.com\/in\/robbd]],
      [#link("https://gitlab.com/robbd", icon: false, if-underline: false, if-color: false)[gitlab.com\/robbd]],
      [#link("https://github.com/robbwdoering", icon: false, if-underline: false, if-color: false)[github.com\/robbwdoering]],
    )
  ],
)
#v(0.3cm)
#line(length: 100%, stroke: 0.5pt + rule-2)
#v(0.3cm)

== #text(fill: ink, weight: 600)[Skills]

#strong[Languages:] Python, TypeScript\/JavaScript, C++, Java, SQL, Bash


#strong[Frontend:] React, Redux, Next.js, Astro, HTML\/CSS, Tailwind CSS, Bun


#strong[Backend and data:] REST APIs, WebSockets, Node.js, Flask, PostgreSQL, embeddings, RAG


#strong[Agentic engineering:] Claude Code, Codex CLI, Gemini CLI, MCP servers, skills, hooks, Git worktrees


== #text(fill: ink, weight: 600)[Experience]

#regular-entry(
  [
    #strong[Doering Thinking Machines] · #emph[Software Engineer (self-employed)]

  ],
  [
    #show: meta-column
    Aug 2023 – Sept 2026

  ],
  main-column-second-row: [
    #summary[AI prototyping and agent tooling in Python and TypeScript, published as \~30 open-source repositories.]

    - #strong[Agent orchestration.] Directed coding agents (Claude Code, Codex CLI, Gemini CLI) through scoped tasks in isolated Git worktrees, with automated code review as the gate to main: nearly 2,400 agent branches merged across 45 repositories in Q3 2026.

    - #strong[MCP integrations.] Built four FastMCP servers that replace fragile shell calls with structured tools: #link("https://gitlab.com/doering-ai/libs/tact")[inTact] (on PyPI) heals stale agent edits through seven increasingly permissive matches and refuses ambiguous ones; the others handle Git with commit-time secret scanning, Plane task tracking, and task routing.

  ],
)

#regular-entry(
  [
    #strong[Google] · #emph[Software Engineer, AdSense]

  ],
  [
    #show: meta-column
    Feb 2022 – June 2023

  ],
  main-column-second-row: [
    #summary[Modernized the JavaScript ad tag of AdSense, a multi-billion-dollar-a-year product, and implemented new ad formats across browser (TypeScript) and backend (C++) code.]

    - Set up, monitored, and analyzed A\/B experiments on billions of ad queries to verify the impact of my changes, using Python notebooks and internal tools.

  ],
)

#regular-entry(
  [
    #strong[Space Ground System Solutions] · #emph[Software Engineer]

  ],
  [
    #show: meta-column
    June 2019 – July 2021

  ],
  main-column-second-row: [
    #summary[Helped bring a command-and-control system for government satellites to the web, building features in React\/Redux, Java, and C++ on data-intensive APIs from NASA, DoD, and commercial partners.]

    - Delivered \~12 full stack features end to end, some from design documents and others where I led requirements gathering and UX design.

    - Chosen as acting project lead for six engineers during the lead's three-month leave; ran Agile ceremonies, met with stakeholders, and cleared blockers.

  ],
)

== #text(fill: ink, weight: 600)[Projects]

#regular-entry(
  [
    #strong[#link("https://epstein-index.org")[The Epstein Index]] · #emph[Public Document Explorer]

  ],
  [
    #show: meta-column
    Astro · React · OCR

  ],
  main-column-second-row: [
    - A public explorer for over 45,000 DOJ case-file documents, fed by an eight-stage Python pipeline (download, OCR, clean), with an interactive React timeline, maps, and a network graph.

  ],
)

#regular-entry(
  [
    #strong[#link("https://gitlab.com/doering-ai/apps/wiki-parse")[Wikiparse]] · #emph[Wikitext Translation Pipeline]

  ],
  [
    #show: meta-column
    Python data pipeline

  ],
  main-column-second-row: [
    - Extracted 45M citations from a full English Wikipedia dump on home hardware and published a #link("https://huggingface.co/datasets/robbd/wikiparse-2606")[Hugging Face dataset] of 5.1M articles; converts wikitext to Markdown with composed regular expressions.

  ],
)

#regular-entry(
  [
    #strong[#link("https://doering.ai")[doering.ai]] · #emph[Professional Portfolio Site]

  ],
  [
    #show: meta-column
    Astro · TypeScript

  ],
  main-column-second-row: [
    - An Astro and TypeScript site on Bun and Tailwind CSS, with accessibility and reproducibility checks.

  ],
)

== #text(fill: ink, weight: 600)[Education]

#education-entry(
  [
    #strong[Vanderbilt University] · #emph[Computer Science]

  ],
  [
    #show: meta-column
    Aug 2015 – May 2019

  ],
  degree-column: [
    #strong[B.S.]
  ],
  main-column-second-row: [
    #summary[Minors in Philosophy and Spanish.]

  ],
)

#education-entry(
  [
    #strong[Georgia Institute of Technology] · #emph[Computer Science, Interactive Intelligence]

  ],
  [
    #show: meta-column
    Sept 2020 – June 2022

  ],
  degree-column: [

  ],
  main-column-second-row: [
    #summary[Completed 8 of 10 courses toward an M.S.; degree not completed.]

  ],
)
