Source for brfid.github.io — a Hugo-based personal site and technical writing portfolio deployed to GitHub Pages.
The live site is built and deployed via a Hugo + vintage computing pipeline (VAX/PDP-11 via SIMH). The vintage pipeline generates rendered artifacts that Hugo includes in the final build.
Content lives in hugo/content/. The site builds with Hugo extended ≥ 0.156.0 (ARM64 binary available from Hugo releases).
hugo server --source hugoOpen http://localhost:1313/.
hugo --source hugo --destination ../siteNote: --destination is relative to the source directory, so ../site writes to site/ at the repo root.
Publish: push to main → GitHub Actions runs the vintage pipeline and deploys to GitHub Pages automatically. To skip a deploy, include [nopublish] anywhere in the commit message. workflow_dispatch is available for manual re-runs without a new commit.
Generates four Hugo input artifacts and drops them into place before the Hugo build:
hugo/static/brad.man.txt— resume rendered bynroff -manon PDP-11 (2.11BSD)hugo/static/brad.bio.txt— plain-text bio block emitted bybradman.c -mode bioon VAXhugo/static/build.log.html— machine-boundary build log with VAX and PDP-11 console sectionshugo/data/bio.yaml— parsed frombrad.bio.txt;label,principal_headline,impact_highlights, andsummaryare vintage-pipeline generated;aboutis read fromresume.yamltop-level field on each build. (principal_headlinerendered on landing page;impact_highlightsgenerated but reserved for resume page)
The pipeline uses pexpect to drive SIMH emulators via stdin/stdout (no telnet ports, no sleep-based timing):
- Stage A: PDP-11 (2.11BSD) runs
nroff -manto renderbrad.1→brad.man.txt(scripts/pdp11_pexpect.py) - Stage B: VAX (4.3BSD) compiles and runs
bradman.cto generatebrad.1fromresume.vintage.yaml(scripts/vax_pexpect.py) - Stage A+B: VAX generates, host couriers the file, PDP-11 renders
Both stages are implemented and validated on main. See CHANGELOG.md for validation details.
See docs/integration/INDEX.md for design details.
python3 -m venv .venv
.venv/bin/python -m pip install -e '.[dev]'Run make help to list common commands (Makefile wraps the raw commands
documented in this file: tests, Hugo build, resume PDF, edcloud lifecycle).
.venv/bin/python -m pytest -q
.venv/bin/python -m mypy resume_generator tests
.venv/bin/python -m ruff check resume_generator
.venv/bin/python -m pylint resume_generator -snThe site is currently in redirect mode. The
SITE-REDIRECTfile makesdeploy.ymlskip the Hugo build and the vintage pipeline entirely and publish a two-file site redirecting every URL to LinkedIn. Remove it to publish the real site; seeSITE-REDIRECTfor the procedure. Everything below describes normal mode.
deploy.yml runs the whole publish path on the ubuntu-latest runner itself:
the vintage pipeline, the Hugo build, and the Pages deploy. There is no execution
host to start or stop and no cloud account involved.
bash scripts/edcloud-vintage-runner.sh "build-$(date -u +%Y%m%d-%H%M%S)" > /tmp/stdout.txtThat single line is the whole pipeline invocation. The runner does exec 3>&1
before redirecting its own stdout to a log file, so redirecting it to a file puts
the base64 artifact markers on the parent's stdout while the verbose pipeline log
stays in $LOG_DIR — which is how CI extracts artifacts with awk.
Single orchestration entrypoint: scripts/edcloud-vintage-runner.sh (the edcloud
in the name is vestigial; it has no cloud coupling).
Set KEEP_IMAGES=1 to preserve Docker images between runs (avoids rebuild on retry).
Historically (until 2026-07-25): CI authenticated to AWS, started an EC2 instance
("edcloud"), ran the same script there over SSM, and extracted the artifacts from the
SSM output. That account was decommissioned; the brfid/edcloud repo is retained but
no longer provisions anything for this site:
brfid/edcloud.
.github/workflows/vintage-validate.yml (workflow_dispatch only) runs the pipeline
on a hosted runner, publishes nothing, and compares the rendered brad.man.txt against
a known-good hash. SIMH emulates the guest CPU deterministically, so an unchanged render
is evidence that a host or toolchain change was inert.
# Record the current hashes, comparing against nothing
gh workflow run vintage-validate.yml --ref main
# Reproduce the 2026-07-25 baseline (rendered on the retired edcloud host)
gh workflow run vintage-validate.yml --ref main \
-f resume_ref=366387e \
-f expected_sha256=b0de44a6a115c5039f99b47492840b7d4dcb75a30b3aa5c59b10fcebb4be1af1Two things make a naive hash comparison useless, and both inputs above exist to neutralize them:
brad.man.txtis a render ofresume.yaml, so comparing against an old baseline only isolates the host if the input is pinned to whatever produced it (resume_ref).bradmanstampsdate.today()into every nroff page footer, so the raw hash changes daily no matter what.expected_sha256is therefore compared against a copy with ISO dates masked; every other byte still has to match. Both hashes are reported.
Artifacts and the full pipeline log are uploaded on success and failure alike.
docker,git,python3on the host. Nothing else — no AWS, no secrets.- Pre-built images pulled from
ghcr.io/brfid/{vax,pdp11}-pexpect:latest, with a localdocker buildfallback. Both are amd64-only, so they run natively onubuntu-latestbut require emulation (or a multi-arch rebuild) on an arm64 Mac. scripts/edcloud_lifecycle.pyis retained for reference but manages an account that no longer exists.
| Doc | Role |
|---|---|
CHANGELOG.md ([Unreleased]) |
Current project state, active priorities, blockers, decisions |
CHANGELOG.md (dated entries) |
Chronological change history and milestone evidence |
docs/integration/INDEX.md |
Vintage pipeline design, stages, artifacts, constraints |
- This file
CHANGELOG.md([Unreleased]first, then latest dated entries)hugo/(Hugo site root — theme, content, config)
Then apply AGENTS.md constraints.