vita: generate the project index, and add a web_visible axis
The project index was the last hand-maintained duplicate of CV data, and it had already drifted: a superseded Weenix line count and an end date the CV disagreed with. It now renders from yaml-source/data/projects.yml, which grows from three entries to nine and gains `group` (drives the index's sections, first-appearance order, like now.yaml) and `links`. Pmacs, Levshell, and Epiphany join under "Personal" — self-directed tools rather than coursework or employment — written from the repos rather than from memory. They are web-only: personal infrastructure is not academic output, and the résumé is a full page. LeVCS keeps its essay; project writeups stay essays, since a writeup is an informal presentation of a project and not a record of it. web_visible is a third visibility axis alongside cv_visible and resume_visible, defaulting to cv_visible so nothing changes until it is set. The file already knew how to let the CV and résumé disagree about an entry; generating a third surface from the same data would otherwise have collapsed that, and a document handed to a chosen reader is not a page that gets crawled. This is what makes web-only projects expressible — and what would let the xAI entry sit quietly on the CV while staying off the site, if that is wanted later. It stays off both for now. Two LaTeX conversions added while moving the markdown prose into the YAML: $\rightarrow$ and $\sim$. The latter fixes a bug I introduced doing it — "~10 crates" meant "about ten", but bare ~ is LaTeX's non-breaking space, so it rendered "( 10 crates" and dropped the approximation. Weenix's description now carries the site's fuller tail (the CS 169 origin and the later pipes/preemption work) rather than the CV's terser "Brown CS 169." Single-sourcing means picking one, and this is the better one; the CV grows by a clause and the résumé still fits on one page. 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
af4c9e4ef2
commit
1f1969ab28
|
|
@ -29,7 +29,7 @@ import Compilers (essayCompiler, postCompiler, pageCompiler, poetryCompiler, fi
|
|||
import Catalog (musicCatalogCtx)
|
||||
import Commonplace (commonplaceCtx)
|
||||
import Now (nowCtx)
|
||||
import Vita (vitaCtx)
|
||||
import Vita (vitaCtx, projectsCtx)
|
||||
import Contexts (siteCtx, essayCtx, postCtx, pageCtx, poetryCtx, fictionCtx, compositionCtx,
|
||||
contentKindField, recentFirstByDisplay,
|
||||
tagLinksFieldExcludingTopSegment, isProvedConfidence)
|
||||
|
|
@ -404,7 +404,18 @@ rules = do
|
|||
-- so nginx serves them via index-file resolution and the URLs stay stable
|
||||
-- if the underlying files are later reorganized into co-located directories.
|
||||
-- ---------------------------------------------------------------------------
|
||||
match "content/cv/*.md" $ do
|
||||
-- The project index is generated from yaml-source/data/projects.yml —
|
||||
-- the same file that feeds the CV's and résumé's project sections — so
|
||||
-- it gets projectsCtx and its own template. The markdown keeps only the
|
||||
-- page's framing prose. Individual project writeups stay as essays.
|
||||
match "content/cv/projects.md" $ do
|
||||
route $ constRoute "cv/projects/index.html"
|
||||
compile $ pageCompiler
|
||||
>>= loadAndApplyTemplate "templates/projects.html" projectsCtx
|
||||
>>= loadAndApplyTemplate "templates/default.html" projectsCtx
|
||||
>>= relativizeUrls
|
||||
|
||||
match ("content/cv/*.md" .&&. complement "content/cv/projects.md") $ do
|
||||
route $ customRoute $ \ident ->
|
||||
let fname = takeFileName (toFilePath ident)
|
||||
slug = takeWhile (/= '.') fname
|
||||
|
|
|
|||
133
build/Vita.hs
133
build/Vita.hs
|
|
@ -21,10 +21,12 @@
|
|||
-- for the full supported set and why escaping happens before conversion.
|
||||
module Vita
|
||||
( vitaCtx
|
||||
, projectsCtx
|
||||
) where
|
||||
|
||||
import Data.Aeson (FromJSON (..), Object, Value (..), withObject, (.:), (.:?), (.!=))
|
||||
import Data.Aeson.Types (Parser, typeMismatch)
|
||||
import Data.Char (toLower)
|
||||
import Data.List (isPrefixOf, sortOn)
|
||||
import Data.Maybe (mapMaybe)
|
||||
import Data.Scientific (isInteger, toRealFloat)
|
||||
|
|
@ -62,6 +64,23 @@ reqLoose o k = unLoose <$> o .: K.fromString k
|
|||
optLoose :: Object -> String -> Parser (Maybe String)
|
||||
optLoose o k = fmap unLoose <$> o .:? K.fromString k
|
||||
|
||||
-- | Whether an entry appears on this page.
|
||||
--
|
||||
-- The YAML has carried two visibility axes since it drove two documents:
|
||||
-- @cv_visible@ and @resume_visible@, so the CV and the résumé can disagree
|
||||
-- about an entry without duplicating it. Generating the vita page from the
|
||||
-- same data added a third surface, and folding it into @cv_visible@ would
|
||||
-- have silently collapsed a distinction the file already knew how to make
|
||||
-- — an entry can be worth keeping on a document handed to a reader while
|
||||
-- being wrong for a page that is crawled.
|
||||
--
|
||||
-- @web_visible@ therefore defaults to @cv_visible@: existing entries behave
|
||||
-- exactly as before, and the axis only exists where someone sets it.
|
||||
webVisible :: Object -> Parser Bool
|
||||
webVisible o = do
|
||||
cv <- o .:? "cv_visible" .!= True
|
||||
o .:? "web_visible" .!= cv
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Entry types
|
||||
-- ---------------------------------------------------------------------------
|
||||
|
|
@ -84,7 +103,7 @@ data Edu = Edu
|
|||
, edEnd :: Maybe String
|
||||
, edGpa :: Maybe String
|
||||
, edNotes :: Maybe String
|
||||
, edVisible :: Bool
|
||||
, edWeb :: Bool
|
||||
}
|
||||
|
||||
instance FromJSON Edu where
|
||||
|
|
@ -96,7 +115,7 @@ instance FromJSON Edu where
|
|||
<*> optLoose o "end"
|
||||
<*> optLoose o "gpa"
|
||||
<*> optLoose o "notes_cv"
|
||||
<*> o .:? "cv_visible" .!= True
|
||||
<*> webVisible o
|
||||
|
||||
newtype EduDoc = EduDoc { unEduDoc :: [Edu] }
|
||||
|
||||
|
|
@ -112,7 +131,7 @@ data Pub = Pub
|
|||
, pbTarget :: Maybe String
|
||||
, pbLinks :: [Link]
|
||||
, pbNote :: Maybe String
|
||||
, pbVisible :: Bool
|
||||
, pbWeb :: Bool
|
||||
}
|
||||
|
||||
instance FromJSON Pub where
|
||||
|
|
@ -125,7 +144,7 @@ instance FromJSON Pub where
|
|||
<*> optLoose o "target"
|
||||
<*> o .:? "links" .!= []
|
||||
<*> optLoose o "equal_contrib_note"
|
||||
<*> o .:? "cv_visible" .!= True
|
||||
<*> webVisible o
|
||||
|
||||
newtype PubDoc = PubDoc { unPubDoc :: [Pub] }
|
||||
|
||||
|
|
@ -140,7 +159,7 @@ data Pres = Pres
|
|||
, prYear :: String
|
||||
, prMonth :: Maybe String
|
||||
, prStatus :: Maybe String
|
||||
, prVisible :: Bool
|
||||
, prWeb :: Bool
|
||||
}
|
||||
|
||||
instance FromJSON Pres where
|
||||
|
|
@ -152,7 +171,7 @@ instance FromJSON Pres where
|
|||
<*> reqLoose o "year"
|
||||
<*> optLoose o "month"
|
||||
<*> optLoose o "status"
|
||||
<*> o .:? "cv_visible" .!= True
|
||||
<*> webVisible o
|
||||
|
||||
newtype PresDoc = PresDoc { unPresDoc :: [Pres] }
|
||||
|
||||
|
|
@ -170,7 +189,7 @@ data Exp = Exp
|
|||
, exOrder :: Int
|
||||
, exPreamble :: Maybe String
|
||||
, exBullets :: [String]
|
||||
, exVisible :: Bool
|
||||
, exWeb :: Bool
|
||||
}
|
||||
|
||||
instance FromJSON Exp where
|
||||
|
|
@ -185,27 +204,54 @@ instance FromJSON Exp where
|
|||
<*> o .:? "cv_order" .!= 99
|
||||
<*> optLoose o "cv_preamble"
|
||||
<*> o .:? "bullets" .!= []
|
||||
<*> o .:? "cv_visible" .!= True
|
||||
<*> webVisible o
|
||||
|
||||
newtype ExpDoc = ExpDoc { unExpDoc :: [Exp] }
|
||||
|
||||
instance FromJSON ExpDoc where
|
||||
parseJSON = withObject "ExpDoc" $ \o -> ExpDoc <$> o .: "experience"
|
||||
|
||||
data Proj = Proj
|
||||
{ pjName :: String
|
||||
, pjGroup :: String
|
||||
, pjEssay :: Maybe String
|
||||
, pjStart :: String
|
||||
, pjEnd :: Maybe String
|
||||
, pjDescription :: String
|
||||
, pjLinks :: [Link]
|
||||
, pjWeb :: Bool
|
||||
}
|
||||
|
||||
instance FromJSON Proj where
|
||||
parseJSON = withObject "Proj" $ \o -> Proj
|
||||
<$> reqLoose o "name"
|
||||
<*> o .:? "group" .!= "Projects"
|
||||
<*> optLoose o "essay"
|
||||
<*> reqLoose o "start"
|
||||
<*> optLoose o "end"
|
||||
<*> reqLoose o "description"
|
||||
<*> o .:? "links" .!= []
|
||||
<*> webVisible o
|
||||
|
||||
newtype ProjDoc = ProjDoc { unProjDoc :: [Proj] }
|
||||
|
||||
instance FromJSON ProjDoc where
|
||||
parseJSON = withObject "ProjDoc" $ \o -> ProjDoc <$> o .: "projects"
|
||||
|
||||
-- | @personal.yml@ also carries a @display@ string per link (the value the
|
||||
-- CV prints in full, since paper cannot be clicked). It is deliberately
|
||||
-- not read here — see 'renderContact'.
|
||||
data ProfileLink = ProfileLink
|
||||
{ plLabel :: String
|
||||
, plHref :: String
|
||||
, plVisible :: Bool
|
||||
, plWeb :: Bool
|
||||
}
|
||||
|
||||
instance FromJSON ProfileLink where
|
||||
parseJSON = withObject "ProfileLink" $ \o -> ProfileLink
|
||||
<$> reqLoose o "label"
|
||||
<*> reqLoose o "href"
|
||||
<*> o .:? "cv_visible" .!= True
|
||||
<*> webVisible o
|
||||
|
||||
-- | Contact details from @personal.yml@. The phone number is deliberately
|
||||
-- not parsed: it is printed on the CV PDF, which is a document handed to
|
||||
|
|
@ -246,6 +292,10 @@ latexToHtml =
|
|||
. substAll "--" "–"
|
||||
. substAll "$\\times$" "×"
|
||||
. substAll "$\\delta$" "δ"
|
||||
. substAll "$\\rightarrow$" "→"
|
||||
-- Approximation, not a non-breaking space. Bare `~` is LaTeX's nbsp, so
|
||||
-- "~10 crates" silently renders as "( 10 crates" and loses the "about".
|
||||
. substAll "$\\sim$" "~"
|
||||
. substAll "\\#" "#"
|
||||
. substAll "{,}" ","
|
||||
. substAll "~" " "
|
||||
|
|
@ -371,7 +421,7 @@ renderEducation es
|
|||
, "</ul>"
|
||||
]
|
||||
where
|
||||
visible = filter edVisible es
|
||||
visible = filter edWeb es
|
||||
one e = concat
|
||||
[ "<li class=\"item-card vita-card\">"
|
||||
, "<div class=\"item-card-main\">"
|
||||
|
|
@ -395,7 +445,7 @@ renderPublications ps
|
|||
, footnote
|
||||
]
|
||||
where
|
||||
visible = filter pbVisible ps
|
||||
visible = filter pbWeb ps
|
||||
-- The dagger legend lives on whichever entry declares it, but reads as a
|
||||
-- section-level note, so it is rendered once at the foot of the list.
|
||||
footnote = case mapMaybe pbNote visible of
|
||||
|
|
@ -434,7 +484,7 @@ renderPresentations ps
|
|||
, "</ul>"
|
||||
]
|
||||
where
|
||||
visible = filter prVisible ps
|
||||
visible = filter prWeb ps
|
||||
dateOf p = maybe "" (\m -> tex m ++ " ") (prMonth p) ++ tex (prYear p)
|
||||
one p = concat
|
||||
[ "<li class=\"item-card vita-card\">"
|
||||
|
|
@ -458,7 +508,7 @@ renderPresentations ps
|
|||
renderExperience :: [Exp] -> String
|
||||
renderExperience xs = research ++ industry
|
||||
where
|
||||
visible = sortOn exOrder (filter exVisible xs)
|
||||
visible = sortOn exOrder (filter exWeb xs)
|
||||
isRes e = exSection e == Just "research"
|
||||
research = group "experience-research" "Research Experience" (filter isRes visible)
|
||||
industry = group "experience-industry" "Industry Experience" (filter (not . isRes) visible)
|
||||
|
|
@ -481,13 +531,57 @@ renderExperience xs = research ++ industry
|
|||
, "</li>"
|
||||
]
|
||||
|
||||
-- | The @/cv/projects/@ index. Groups render in first-appearance order, the
|
||||
-- same convention "Now" uses for its sections — reordering the YAML
|
||||
-- reorders the page and no separate ordering key is needed.
|
||||
--
|
||||
-- Entry titles link to the project's essay where one exists. The essays are
|
||||
-- deliberately not generated: a writeup is an informal presentation of a
|
||||
-- project, not a record of it, and belongs in the same voice as the rest of
|
||||
-- the essays.
|
||||
renderProjects :: [Proj] -> String
|
||||
renderProjects ps = concatMap one (groupOrder visible)
|
||||
where
|
||||
visible = filter pjWeb ps
|
||||
groupOrder = foldl (\acc g -> if g `elem` acc then acc else acc ++ [g]) []
|
||||
. map pjGroup
|
||||
-- "Machine Learning & Deployed" → "machine-learning-deployed".
|
||||
slugify s = case foldr step [] s of
|
||||
('-':rest) -> rest
|
||||
cleaned -> cleaned
|
||||
where
|
||||
step c acc
|
||||
| c `elem` (['a'..'z'] ++ ['0'..'9']) = c : acc
|
||||
| c `elem` ['A'..'Z'] = toLower c : acc
|
||||
| null acc || head acc == '-' = acc
|
||||
| otherwise = '-' : acc
|
||||
one g = section ("projects-" ++ slugify g) (escapeHtml g) $ concat
|
||||
[ "<ul class=\"item-card-list vita-list\">"
|
||||
, concatMap entry (filter ((== g) . pjGroup) visible)
|
||||
, "</ul>"
|
||||
]
|
||||
entry p = concat
|
||||
[ "<li class=\"item-card vita-card\">"
|
||||
, "<div class=\"item-card-main\">"
|
||||
, "<h3 class=\"vita-entry-title\">"
|
||||
, case pjEssay p of
|
||||
Just u -> "<a href=\"" ++ escapeHtml u ++ "\">" ++ tex (pjName p) ++ "</a>"
|
||||
Nothing -> tex (pjName p)
|
||||
, "</h3>"
|
||||
, metaLine (dateRange (pjStart p) (pjEnd p)) Nothing Nothing
|
||||
, "<p class=\"vita-note\">", tex (pjDescription p), "</p>"
|
||||
, renderLinks (pjLinks p)
|
||||
, "</div>"
|
||||
, "</li>"
|
||||
]
|
||||
|
||||
renderContact :: Person -> String
|
||||
renderContact p = section "contact" "Contact" $ concat
|
||||
[ "<p class=\"vita-links\">"
|
||||
, "<a class=\"vita-chip\" href=\"mailto:", escapeHtml (pnEmail p), "\">"
|
||||
, escapeHtml (pnEmail p)
|
||||
, "</a>"
|
||||
, concatMap one (filter plVisible (pnLinks p))
|
||||
, concatMap one (filter plWeb (pnLinks p))
|
||||
, "</p>"
|
||||
]
|
||||
where
|
||||
|
|
@ -541,3 +635,12 @@ vitaCtx =
|
|||
<> sectionField "vita-contact-html"
|
||||
(renderContact <$> loadYaml "yaml-source/data/personal.yml")
|
||||
<> siteCtx
|
||||
|
||||
-- | The @/cv/projects/@ index. Reuses the vita flag so it picks up the same
|
||||
-- stylesheets and reads as the same kind of surface.
|
||||
projectsCtx :: Context String
|
||||
projectsCtx =
|
||||
constField "vita" "true"
|
||||
<> sectionField "vita-projects-html"
|
||||
(renderProjects . unProjDoc <$> loadYaml "yaml-source/data/projects.yml")
|
||||
<> siteCtx
|
||||
|
|
|
|||
|
|
@ -4,22 +4,6 @@ tags: meta
|
|||
portal: true
|
||||
---
|
||||
|
||||
Index of engineering artifacts. Systems depth is the primary axis of this page; machine-learning and deployed artifacts follow.
|
||||
Index of engineering artifacts, generated from the same data as the project sections of the [CV](/cv.pdf) and [résumé](/resume.pdf). Systems depth is the primary axis; self-directed tools and deployed machine-learning work follow.
|
||||
|
||||
## Low-Level & Systems
|
||||
|
||||
- **[Weenix](/essays/weenix/)**\
|
||||
Unix-like kernel in 10,000 lines of C. Virtual memory, VFS, system calls, threading, device drivers, interrupt handlers, and file systems; custom linker support for running userspace x86-64 ELF binaries. Originally a project from Brown CS 169 (Operating Systems with Lab), extended with further features like pipes and userspace preemption. January – August 2025.
|
||||
- **[Networking Stack from Scratch](/essays/networking-stack/)**\
|
||||
TCP/IP, RIP, UDP, and DNS in Go, supporting file transmission of up to 1 GB across networks of 8 virtual machines. Extended with a fully RFC-compliant SSH implementation (2,000+ additional lines) supporting sustained sessions of arbitrary length. October 2024 – July 2025.
|
||||
- **[Where Does SIMD Help Post-Quantum Cryptography?](/essays/where-does-simd-help-post-quantum-cryptography/)** · [Artifact](https://git.levineuwirth.org/neuwirth/where-simd-helps)\
|
||||
Hand-written AVX2 assembly for ML-KEM / Kyber. 35×–56× speedup over compiler-optimized C for core NTT arithmetic; 5.4×–7.1× end-to-end KEM speedup. Full statistical-analysis pipeline (Mann-Whitney U, Cliff's δ, bootstrapped CIs) on Brown's OSCAR HPC cluster. Phase 1 report and reproducible artifact public.
|
||||
- **[LeVCS](/essays/levcs/)** · [Artifact](https://git.levineuwirth.org/neuwirth/levcs) · [Instance](https://levcs.levineuwirth.org)\
|
||||
Distributed version control system in Rust (~10 crates, 194 passing tests at v0.1.0). BLAKE3 content addressing, signed Ed25519 authority chains for protocol-level identity and push authorization, federation as the normal operating mode with three storage modes (full / release / metadata), and a cascading per-file merge engine (textual → format-aware → tree-sitter → wasm plugin) that resolves git's common false conflicts. Substrate complete; workflow surface (PR/review, issues, web UI) deferred. First federation instance at [levcs.levineuwirth.org](https://levcs.levineuwirth.org). April 2026 – present.
|
||||
|
||||
## Machine Learning & Deployed
|
||||
|
||||
- **[ICD-10-CM outcome calculator](https://levineuwirth.github.io/icd_embeddings/)** · [Preprint](/essays/beyond-comorbidity-indices/) · [Code](https://github.com/levineuwirth/icd_embeddings)\
|
||||
Public, read-only calculator for the permutation-invariant Deep Sets model underlying the paper currently under review at *JAMIA*. Takes a diagnosis-code set; returns 30-day readmission and postdischarge mortality predictions with Integrated-Gradients attribution.
|
||||
- **[NeuroPose](/essays/neuropose/)**\
|
||||
3D pose-estimation and kinematic-analysis system for neurological-recovery research in Liqi Shu's laboratory at Brown Neurology. Python/TensorFlow inference pipeline, MATLAB-based statistical post-processing, Rust backend with HTML/JS frontends. 20,000+ lines across four externally-funded sub-projects since 2023.
|
||||
Where a project has a writeup, its title links to it. Those are essays rather than records — informal, longer, and written in their own voice.
|
||||
|
|
|
|||
BIN
static/cv.pdf
BIN
static/cv.pdf
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,7 @@
|
|||
<main id="markdownBody" data-pagefind-body>
|
||||
<h1 class="page-title">$title$</h1>
|
||||
|
||||
<div class="vita-intro">$body$</div>
|
||||
|
||||
$vita-projects-html$
|
||||
</main>
|
||||
|
|
@ -1,29 +1,154 @@
|
|||
# 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. One list, three consumers, three visibility axes:
|
||||
#
|
||||
# cv_visible — CV, under "Systems and Engineering Projects"
|
||||
# resume_visible — résumé, under "Projects" (ordered by resume_order)
|
||||
# web_visible — the /cv/projects/ index (defaults to cv_visible)
|
||||
#
|
||||
# The web index was hand-written markdown until August 2026 and had already
|
||||
# drifted from this file (a superseded Weenix line count, dates that ended
|
||||
# where the CV said "Present"). It is now generated from here, so the three
|
||||
# surfaces cannot disagree. Individual project *writeups* stay as essays —
|
||||
# they are informal presentations, not records, and `essay` points at them.
|
||||
#
|
||||
# `group` drives the index's section headings and renders in first-appearance
|
||||
# order, like now.yaml's sections. Descriptions are LaTeX-flavoured because
|
||||
# xelatex is the first consumer; build/Vita.hs converts the same subset for
|
||||
# the web (\textbf, \textit, \texttt, \href, $\times$, --, ~, {,}).
|
||||
|
||||
projects:
|
||||
# ---------------------------------------------------------------------
|
||||
# Systems & Infrastructure
|
||||
# ---------------------------------------------------------------------
|
||||
- name: Post-Quantum Cryptography on x86 AVX2
|
||||
group: Systems & Infrastructure
|
||||
essay: /essays/where-does-simd-help-post-quantum-cryptography/
|
||||
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."
|
||||
links:
|
||||
- label: Report
|
||||
href: /essays/where-does-simd-help-post-quantum-cryptography/
|
||||
- label: Artifact
|
||||
href: https://git.levineuwirth.org/neuwirth/where-simd-helps
|
||||
cv_visible: false # appears under Publications instead on CV
|
||||
resume_visible: true
|
||||
resume_order: 1
|
||||
web_visible: true
|
||||
|
||||
- name: LeVCS
|
||||
group: Systems & Infrastructure
|
||||
essay: /essays/levcs/
|
||||
start: April 2026
|
||||
end: Present
|
||||
description: "Distributed version control system in Rust ($\\sim$10 crates, 194 passing tests at v0.1.0). BLAKE3 content addressing, signed Ed25519 authority chains for protocol-level identity and push authorization, federation as the normal operating mode with three storage modes (full / release / metadata), and a cascading per-file merge engine (textual $\\rightarrow$ format-aware $\\rightarrow$ tree-sitter $\\rightarrow$ wasm plugin) that resolves git's common false conflicts. Substrate complete; workflow surface (PR/review, issues, web UI) deferred."
|
||||
links:
|
||||
- label: Writeup
|
||||
href: /essays/levcs/
|
||||
- label: Artifact
|
||||
href: https://git.levineuwirth.org/neuwirth/levcs
|
||||
- label: Instance
|
||||
href: https://levcs.levineuwirth.org
|
||||
cv_visible: false
|
||||
resume_visible: false
|
||||
web_visible: true
|
||||
|
||||
- name: Weenix
|
||||
group: Systems & Infrastructure
|
||||
essay: /essays/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."
|
||||
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. Originally Brown CS 169 (Operating Systems with Lab), extended afterward with pipes and userspace preemption."
|
||||
links:
|
||||
- label: Writeup
|
||||
href: /essays/weenix/
|
||||
cv_visible: true
|
||||
resume_visible: true
|
||||
resume_order: 2
|
||||
web_visible: true
|
||||
|
||||
- name: Networking Stack from Scratch
|
||||
group: Systems & Infrastructure
|
||||
essay: /essays/networking-stack/
|
||||
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."
|
||||
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. Extended with a fully RFC-compliant SSH implementation (2{,}000+ additional lines) supporting sustained sessions of arbitrary length."
|
||||
links:
|
||||
- label: Writeup
|
||||
href: /essays/networking-stack/
|
||||
cv_visible: true
|
||||
resume_visible: true
|
||||
resume_order: 3
|
||||
web_visible: true
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Personal — self-directed tools, not coursework or employment. Web-only:
|
||||
# they are infrastructure I use rather than academic output, and the
|
||||
# résumé is a full page already.
|
||||
# ---------------------------------------------------------------------
|
||||
- name: Pmacs
|
||||
group: Personal
|
||||
start: "2025"
|
||||
end: Present
|
||||
description: "Parallel Emacs: a Rust-cored, Lua-scripted editor in the Emacs tradition, at v1.1.0 with prebuilt binaries. The hot path (rope, buffers, views, async runtime, process supervision) is Rust; commands, keymaps, hooks, and packages are an embedded Lua VM. Partitioned into a long-lived instance and thin frontends over a typed protocol: a \\texttt{crossterm} TUI attachable over SSH with \\texttt{mosh}-style reconnect, and a GPU frontend (wgpu / winit / glyphon) that renders from a semantic projection of editor state and edits optimistically against a local CRDT replica. Buffers are optionally CRDT-backed, so both frontends can edit the same buffer concurrently."
|
||||
links:
|
||||
- label: Source
|
||||
href: https://github.com/levineuwirth/pmacs
|
||||
cv_visible: false
|
||||
resume_visible: false
|
||||
web_visible: true
|
||||
|
||||
- name: Levshell
|
||||
group: Personal
|
||||
start: "2026"
|
||||
end: Present
|
||||
description: "Wayland-targeted productivity and research shell, in daily use as my main environment. Five Rust crates over a sway/i3-ipc substrate: a capture-and-restore planner for desktop state, an event-logged store with UUIDv7 ids, a daemon whose every action is a persisted job under a global lock with rollback capsules taken before any mutating restore, and a control CLI. Currently growing from a single machine to a fabric of machines that work as one, with project resume as the hero verb."
|
||||
cv_visible: false
|
||||
resume_visible: false
|
||||
web_visible: true
|
||||
|
||||
- name: Epiphany
|
||||
group: Personal
|
||||
start: "2026"
|
||||
end: Present
|
||||
description: "FOSS music-notation platform: a specified, deterministic, CRDT-based score model whose LaTeX specification suite is the source of truth rather than its documentation. Twelve Rust crates across two tracks — the wire format, bundle, operations, and text projection on one; the editing seam, engraving, and layout IR on the other. Work is scoped into ratified contracts with numbered pins, mutation tables, and adversarial review rounds before any code is dispatched."
|
||||
links:
|
||||
- label: Source
|
||||
href: https://github.com/levineuwirth/epiphany
|
||||
cv_visible: false
|
||||
resume_visible: false
|
||||
web_visible: true
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Machine Learning & Deployed
|
||||
# ---------------------------------------------------------------------
|
||||
- name: ICD-10-CM outcome calculator
|
||||
group: Machine Learning & Deployed
|
||||
essay: /essays/beyond-comorbidity-indices/
|
||||
start: "2025"
|
||||
end: Present
|
||||
description: "Public, read-only calculator for the permutation-invariant Deep Sets model underlying the paper under review at \\textit{JAMIA}. Takes a diagnosis-code set; returns 30-day readmission and postdischarge mortality predictions with Integrated-Gradients attribution."
|
||||
links:
|
||||
- label: Calculator
|
||||
href: https://levineuwirth.github.io/icd_embeddings/
|
||||
- label: Preprint
|
||||
href: /essays/beyond-comorbidity-indices/
|
||||
- label: Code
|
||||
href: https://git.levineuwirth.org/neuwirth/beyond_comorbidity_indices
|
||||
cv_visible: false # appears under Publications and the Shu Lab bullet on CV
|
||||
resume_visible: false
|
||||
web_visible: true
|
||||
|
||||
- name: NeuroPose
|
||||
group: Machine Learning & Deployed
|
||||
essay: /essays/neuropose/
|
||||
start: "2023"
|
||||
end: Present
|
||||
description: "3D pose-estimation and kinematic-analysis system for neurological-recovery research in Liqi Shu's laboratory at Brown Neurology. Python/TensorFlow inference pipeline, MATLAB statistical post-processing, Rust backend with HTML/JS frontends. 20{,}000+ lines across four externally-funded sub-projects since 2023."
|
||||
links:
|
||||
- label: Writeup
|
||||
href: /essays/neuropose/
|
||||
- label: Artifact
|
||||
href: https://git.levineuwirth.org/neuwirth/neuropose
|
||||
cv_visible: false # appears via the Shu Lab bullet on CV
|
||||
resume_visible: false
|
||||
web_visible: true
|
||||
|
|
|
|||
Loading…
Reference in New Issue