plresearch-org · open-prs-integration-audit

Open PRs integration audit (#1, #4, #6)

@daviddao

Pulled main, opened all three pending PRs on a fresh integration branch, and pushed the combined build through tsc --noEmit + next build + a live browser smoke. Two of three integrate cleanly. The third ships from a stale base and silently regresses recent work on main.

Date: 2026-05-13 · partial · Base: main@d6daeb9 · Branch: integration/open-prs-audit


Headline result

2
PRs integrated
1
PRs blocked
2
Findings in merged set
0
Build / type errors

Headline. PR #4 and PR #6 were merged onto a fresh branch off main; one expected text conflict in src/app/about/page.tsx + src/app/areas/economies-governance/page.tsx was resolved by combining both intents (use FOCUS_AREA_DESCRIPTIONS as the fallback content piped through the new <MarkdownContent> component) and adding the missing heroSection binding PR #6 had assumed. The combined branch builds clean (npx tsc --noEmit = 0 errors, next build = OK) and renders correctly in the live server. PR #1 (Aileron font) cannot be integrated as-is — see the §Findings.

What was tested

Repodaviddao/plresearch.org Pulled commitd6daeb9 (Merge PR #5 — Neurotech advisory board) PRs covered #1 Font debug + Aileron testing · #4 Sync focus area descriptions · #6 Render edited page markdown Integration branchintegration/open-prs-audit Verificationnpx tsc --noEmit + npm run build + npm start on port 3013

Per-PR result

#TitleRebase on mainBuildStatusNotes
4 Sync focus area descriptions clean (1 commit fast-forwarded) green merge Centralises the four canonical focus-area summaries in src/lib/focus-area-descriptions.ts and threads them through every consumer. One typo, one stale-record interaction — see findings F-1 and F-2.
6 Render edited page markdown clean (1 commit fast-forwarded) green merge Adds a small homemade markdown renderer (src/lib/markdown.ts) and a <MarkdownContent> component used by 9 page files. Replaces the bespoke regex in MarkdownEditor.tsx and PageEditor.tsx. Together with #4: needed a 3-line conflict resolution.
1 Font debug + Aileron testing conflicts + silent regressions n/a (not merged) blocked Rebase fails on commit 333e9c6. A 3-way merge succeeds but the result regresses the hex-mosaic CSS and the Tailwind v4 theme token names — see finding F-3.

Walkthrough — combined build of PR #4 + PR #6

01Landing page hero on the integration branch. Hex-mosaic clouds and brand fonts unchanged.
01bFocus-area cards on the landing page now use the canonical summaries from PR #4. The four-card hex-mosaic layout from main is preserved.
04/about/ focus-area grid. Three of four read fine; the Digital Human Rights cell exposes finding F-1 (missing for).
03/areas/digital-human-rights/. New summary visible — but the missing word is now the hero subtitle of the entire focus area page.
02/areas/economies-governance/. The page shows the old "nation-states" subtitle even though PR #4 updated both the hardcoded fallback and the ATProto seed JSON — see finding F-2.
05Neurotech page picks up the canonical PR #4 summary cleanly. PR #6's <MarkdownContent> is also rendering this subtitle.
06AI & Robotics page, also clean.

Findings

F-1 · Missing word in the new Digital Human Rights description (PR #4)

The new canonical summary reads:

Building open, verifiable, censorship-resistant infrastructure human freedom & agency in the digital age.

Almost certainly meant to be infrastructure for human freedom & agency. The current text reads as a noun phrase joining two unrelated objects and is grammatically broken.

The same string is duplicated in six places, all written by PR #4 — fix all together:

content/areas/digital-human-rights/_index.md            (frontmatter summary)
src/lib/focus-area-descriptions.ts                      (canonical constant)
src/data/generated/areas.json                           (build output — regenerate via build-content.mjs)
public/search-index.json                                (build output — regenerate via build-content.mjs)
data/atproto/pages/landing.json                         (ATProto seed)
data/atproto/pages/area-digital-human-rights.json       (ATProto seed)
data/atproto/pages/about.json                           (ATProto seed)

Fix the constant + the content markdown + the three ATProto seeds, then run node scripts/build-content.mjs to regenerate the two JSONs under src/data/generated/ and public/.

F-2 · Indexer record for area-economies-governance isn't updated, so the new copy never appears on the live FA2 page

PR #4 updates both the hardcoded TypeScript fallback (FOCUS_AREA_DESCRIPTIONS['economies-governance']) and the ATProto seed (data/atproto/pages/area-economies-governance.json) to the new copy:

Building programmable infrastructure for more efficient, equitable
coordination at global scale.

But src/app/areas/economies-governance/page.tsx renders heroSection?.subtitle first and falls back to the canonical only when the indexer is empty. The Railway-hosted indexer still has the previous string baked into the live org.plresearch.page record, so the page on the integration branch still shows the old text (screenshot 02). PR #4's seed-file change is dead code until somebody pushes a corresponding PUT /api/pages/area-economies-governance (which requires admin auth + the ATPROTO_HANDLE/ATPROTO_PASSWORD envs).

Suggest one of:

F-3 · PR #1 cannot be integrated as-is — three blocking issues

PR #1 was authored against a much older main. A git rebase main fails on commit 333e9c6 "debugs font code" with a content conflict in src/app/page.tsx; a git merge --no-ff pr-1-aileron succeeds but the resulting tree has three problems that would ship regressions to production:

(a) Renames Tailwind v4 theme tokens. PR #1 rewrites src/app/globals.css from

--font-body:  var(--font-inter), sans-serif;
--font-serif: var(--font-serif), Georgia, "Times New Roman", serif;

to

--font-family-body:  'Aileron', sans-serif;
--font-family-serif: 'Newsreader', Georgia, "Times New Roman", serif;

Tailwind v4's CSS-first config matches the --font-name namespace, not --font-family-name, so the font-serif utility class stops resolving. There are six call sites today (src/app/edit/page.tsx, src/app/page.tsx, src/components/FundingPipeline.tsx ×4) — they all lose their serif font silently after the merge.

(b) Deletes the hex-mosaic hover animation CSS. The PR's globals.css is missing the entire ~75-line block from .hex-cloud-svg through .hex-cloud-hex that landed on main in earlier commits. The landing-page focus-area cards lose their hover-pulse animation outright. Diff snippet:

$ diff <(git show main:src/app/globals.css) <(git show pr-1-aileron:src/app/globals.css) | head
> @font-face { font-family: 'Aileron'; src: url('/fonts/Aileron-Regular.woff2') format('woff2'); ... }
< --font-body:  var(--font-inter), sans-serif;
< --font-serif: var(--font-serif), Georgia, "Times New Roman", serif;
> --font-family-body:  'Aileron', sans-serif;
> --font-family-serif: 'Newsreader', Georgia, "Times New Roman", serif;
< font-family: var(--font-serif);
> font-family: var(--font-newsreader);
< .hex-cloud-svg { filter: saturate(0.55); ... }   ← deleted by PR #1
< .hex-cloud-card:hover .hex-cloud-svg { ... }      ← deleted by PR #1
< .hex-cloud-hex { ... }                            ← deleted by PR #1

(c) Reverts unrelated work-in-progress. The PR's tip touches files that have changed substantially on main since the PR was opened — notably the Adam Marblestone avatar refresh (public/images/authors/adam-marblestone/avatar.png reverts from 370 KB → 48 KB) and the recent FA2 hero image work (deletes public/images/banners/about-banner.webp and four public/images/fa2/mosaics/*.svg files). These look incidental but they're real diffs the merge tool would apply.

Recommended path: close PR #1 and re-open it as a smaller, focused PR that (1) only adds the Aileron font files + @font-face declarations, (2) sets --font-body: var(--font-aileron), sans-serif in the existing @theme block (preserving the --font-name token naming), (3) does not touch --font-serif, and (4) is rebased on a fresh main. The 5-commit "debugs font code" history should be squashed.

F-4 · PR #6's markdown rendering is working end-to-end

Confirmed by curl on the running server: every editable page section now wraps subtitle/body text in <div class="markdown-content">…</div> with paragraph breaks (\n\n) emitted as <p> blocks rather than literal newlines. Six markdown-content blocks observed on /about/ alone:

$ curl -s http://127.0.0.1:3013/about/ | grep -oc 'class="markdown-content'
6
$ curl -s http://127.0.0.1:3013/about/ | python3 -c '…extract…' | head
Found 6 markdown-content blocks
--- block 3 ---
<p>Co-fund a program: …</p><p>Build with us: …

The implementation in src/lib/markdown.ts is a ~60-line homemade renderer (no new npm deps) supporting bold, italic, links, inline code, headings (h1–h3), and fenced code blocks, with explicit HTML escaping and an isSafeHref allowlist (https?:, mailto:, /, #). XSS-shaped attributes are escaped. No regression observed on any of the 8 page templates that switched from raw {text} to <MarkdownContent>.

Combined-merge mechanics

For posterity — the one conflict that arose merging PR #4 + PR #6 together (each merges fine on its own):

Filessrc/app/about/page.tsx, src/app/areas/economies-governance/page.tsx CauseBoth PRs touch the same hero subtitle render. PR #4 wants the canonical fallback constant; PR #6 wants the <MarkdownContent> wrapper. ResolutionUse both: <MarkdownContent content={section?.subtitle || FOCUS_AREA_DESCRIPTIONS[…]}>. PR #6's logic also assumed a heroSection binding in economies-governance/page.tsx that main doesn't define — added const heroSection = getSection(page, "hero") next to the existing bodySection. Verifiednpx tsc --noEmit → 0 errors. npm run build → green. Live curl → markdown-content blocks present, EG hero rendering through the new component.

Reproducing

cd ~/Projects/plresearch.org
git checkout main && git pull --ff-only

# PR #4 — clean
gh pr checkout 4 -b pr-4-focus-area-descs && git rebase main
npx tsc --noEmit && npm run build

# PR #6 — clean
git checkout main && gh pr checkout 6 -b pr-6-render-markdown && git rebase main
npx tsc --noEmit && npm run build

# PR #1 — fails to rebase, conflicts in src/app/{layout,page}.tsx; merge regresses
git checkout main && gh pr checkout 1 -b pr-1-aileron && git rebase main
# → CONFLICT (content): Merge conflict in src/app/page.tsx

# Combined integration branch
git checkout -B integration/open-prs-audit main
git merge --no-ff pr-4-focus-area-descs -m "Integrate PR #4"
git merge --no-ff pr-6-render-markdown   -m "Integrate PR #6"
# → 2 file conflicts, resolved by combining both intents
npx tsc --noEmit && npm run build && PORT=3013 npm start &
curl -s http://127.0.0.1:3013/about/ | grep -c 'class="markdown-content'
# 6

Recommendation

Land #4 + #6 now (in either order) after fixing the F-1 typo across all seven files and pushing a one-time indexer sync for the EG record to clear F-2. The combined branch is sitting on integration/open-prs-audit with green TS + build; the conflict resolution is one 5-line edit. Send #1 back with the three F-3 items called out — the rename of the Tailwind tokens and the dropped hex-mosaic CSS are the load-bearing problems.