Skip to content

brfid/brfid.github.io

Repository files navigation

brfid.github.io

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.

Hugo

Content lives in hugo/content/. The site builds with Hugo extended ≥ 0.156.0 (ARM64 binary available from Hugo releases).

Local preview

hugo server --source hugo

Open http://localhost:1313/.

Build to site/

hugo --source hugo --destination ../site

Note: --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.

Vintage pipeline (publish path)

Generates four Hugo input artifacts and drops them into place before the Hugo build:

  • hugo/static/brad.man.txt — resume rendered by nroff -man on PDP-11 (2.11BSD)
  • hugo/static/brad.bio.txt — plain-text bio block emitted by bradman.c -mode bio on VAX
  • hugo/static/build.log.html — machine-boundary build log with VAX and PDP-11 console sections
  • hugo/data/bio.yaml — parsed from brad.bio.txt; label, principal_headline, impact_highlights, and summary are vintage-pipeline generated; about is read from resume.yaml top-level field on each build. (principal_headline rendered on landing page; impact_highlights generated 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 -man to render brad.1brad.man.txt (scripts/pdp11_pexpect.py)
  • Stage B: VAX (4.3BSD) compiles and runs bradman.c to generate brad.1 from resume.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.

Setup

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).

Quality checks

.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 -sn

Publish path

The site is currently in redirect mode. The SITE-REDIRECT file makes deploy.yml skip 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; see SITE-REDIRECT for 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.txt

That 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.

Testing the pipeline without publishing

.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=b0de44a6a115c5039f99b47492840b7d4dcb75a30b3aa5c59b10fcebb4be1af1

Two things make a naive hash comparison useless, and both inputs above exist to neutralize them:

  • brad.man.txt is a render of resume.yaml, so comparing against an old baseline only isolates the host if the input is pinned to whatever produced it (resume_ref).
  • bradman stamps date.today() into every nroff page footer, so the raw hash changes daily no matter what. expected_sha256 is 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.

Vintage pipeline prerequisites

  • docker, git, python3 on the host. Nothing else — no AWS, no secrets.
  • Pre-built images pulled from ghcr.io/brfid/{vax,pdp11}-pexpect:latest, with a local docker build fallback. Both are amd64-only, so they run natively on ubuntu-latest but require emulation (or a multi-arch rebuild) on an arm64 Mac.
  • scripts/edcloud_lifecycle.py is retained for reference but manages an account that no longer exists.

Source of truth

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

Cold start order

  1. This file
  2. CHANGELOG.md ([Unreleased] first, then latest dated entries)
  3. hugo/ (Hugo site root — theme, content, config)

Then apply AGENTS.md constraints.

About

Technical writing portfolio built with Hugo and a VAX-to-PDP-11 publishing pipeline.

Resources

Stars

Watchers

Forks

Used by

Contributors

Languages