AGENTS.md
Guidance for agents (and forgetful humans) working in this repo.
What this is
The GitHub Pages site for xlr8harder.github.io. Jekyll (minima theme), built
automatically by GitHub from the main branch root — pushing to main is
publishing. No build tooling is required to publish; markdown files with a
front-matter block render to HTML at the same path. /mirror/ is generated —
never hand-edit it.
Updating the Substack mirror after a post is published
Background: a newly published post is available immediately at
/p/<slug>, via /api/v1/posts/<slug>, and in the publication’s
sitemap.xml — but Substack’s archive listing (/api/v1/archive) lags
publication substantially (observed 2026-07: 30+ minutes). The importer
therefore discovers posts from the union of the archive listing and the
sitemap, so a plain run works immediately after publishing.
When the request is “I posted, update the mirror,” do this:
./tools/sync.sh
It imports everything (waiting briefly if needed — --poll checks sitemaps
too, so new posts are found within seconds), commits, and pushes. Equivalent
manual form: python3 tools/substack_mirror.py, then commit and push.
For anything that isn’t a brand-new post (edits to old posts, config changes),
plain python3 tools/substack_mirror.py suffices — it refetches everything,
and output is deterministic: no diffs unless upstream actually changed.
Publications live in mirror.yml. Deps: pandoc, python3-yaml.
Importing fragments (from the owner’s private vault)
/archive/fragments/ holds stories and notes imported from private markdown
vaults. Procedure: strip the vault frontmatter and the ## Summary /
## Full Text cataloging headers; keep the text verbatim otherwise (bulleting
line-stacked lists for markdown rendering is OK). Date each piece by the
frontmatter created date, never modified. Scrub before committing:
no source paths, no usernames, personal names reduced to initials — grep the
staged content for identity strings every time. The owner approves each piece
individually; the publishing queue lives in the vault’s _Reading Guide.md.
Testing the build locally
GitHub builds the site on push, but to check before pushing:
PATH="$(ruby -e 'print Gem.user_dir')/bin:$PATH" jekyll build -d /tmp/_site
Or preview with live rebuilds:
jekyll serve
Things that bite: a .md file without a leading ---/--- front-matter
block is served as raw text, not rendered; the header nav is pinned via
header_pages in _config.yml (don’t let new pages auto-populate it);
styling overrides live in assets/main.scss (that exact path — minima
ignores stylesheets elsewhere).
Deploy hiccups
The Pages deploy step occasionally fails with “Deployment failed, try again
later” even when the build succeeds (observed 2026-07: three consecutive
failures over ~10 hours, then success). The site keeps serving the last good
deploy, so nothing user-facing breaks. Retry with an empty commit, or check
gh run list / re-run from the Actions tab.