Build of people/ per-person pages for the private roots-timeline site, per dispatch spec.
What was built
build-people.mjs— generator (Node, no deps). Runnode build-people.mjsfrom this dir.people/style.css— shared stylesheet;:root+ dark-mode palette copied verbatim from index.html; Georgia serif h1/h2, system body, chip/ring/badge tokens, responsive, noindex on every page.people/index.html— all 93 people grouped by the six family lines, birth-order within line. Search-free.people/<slug>.html× 93 — name, dates, confidence badge (dashed = probable), region-swatch trail line, full story, Immediate family (linked), Sources & further reading, back-links to../index.htmland the people index.people/slugs.js—window.PEOPLE_SLUGS(194 keys) for the tooltip wiring.
Extraction approach (decision)
The ANC / GROUPS / REGIONS blocks in index.html are JS object literals (typographic quotes, unquoted integer keys), so regex→JSON would be fragile. The generator does a balanced-delimiter scan (string-aware) to slice each const X=… block, then evaluates it with new Function — JS evaluating JS is the faithful parser. Chose .mjs over .py for exactly this reason.
Identity, dedupe, slugs
- Person identity = (normalized name, birth year). Alias map merges GROUPS/ANC spelling variants:
Wm N. LeQuire→William N. LeQuire,Rowena Rowland→Rowena E. Rowland,Mattie Hayes→Mattie Hayes Mashburn. ★ stripped before compare. - Slug = kebab name; non-ASCII (incl. Ⅲ/Ⅳ) dropped, so the three William Olneys and two John Herman Wilsons collide → birth year appended:
william-olney-1756/-1694/-1663,john-herman-wilson-1861/-1956. All other slugs stay clean. - When ANC and GROUPS stories differ, the longer story wins (e.g. Monroe's GROUPS story carries the postmaster detail).
Inclusion decisions
- 91 ANC persons + Danny Wilson (GROUPS-only) + Anita B. Lambert (new small page, per spec) = 93 pages.
Next generation(living child) — no page, and no slugs.js entry (tooltip shows no link).- Ben / John (1956) / Brenda — minimal living pages: name, b-year, one line, family links only. No story/sources.
- Unknown-placeholder ANC entries (30/31 Eva Brown's parents, 42/43 Josephine's parents) get no pages; they render on the child's page as "not yet found — research frontier" + the ANC hunt hint. For notable absent-key parents (Edgar Rogers, Richard Wilson brick wall, Rachel Strain, John M. Hayes, Thomas Olney, Catharine Sayles, Ashtons, Jacob Sharp, Lumpkin Foster) a manual
FRONTIER_HINTSmap supplies the hint.
Relationships
- Parents/spouse/children derived from ahnentafel arithmetic (father 2n, mother 2n+1, child ⌊n/2⌋, couple = (2k,2k+1)). Manual overrides: Danny under Monroe+Eleanor; Anita under John James+Josephine. Living non-page children noted as text ("Also two daughters — living, no pages"), matching the main site's footer precedent.
- Marriage years shown where documented (hand-curated
MARRIAGEmap keyed by even ahn). - Spouse notes for absent partner keys (e.g. Richard Burt's wife "Airies" POSSIBLE-tier note).
Sources
- Hand-curated per-slug
SOURCESmap compiled from2026-07-21-lineage-research-partA/B.md+2026-07-20-wilson-tree-v0.md. Research docs cite Find A Grave/WikiTree by ID; URLs constructed asfindagrave.com/memorial/<id>/wikitree.com/wiki/<id>. Labeled by relation (own memorial vs relative's). Capped at 8 per page. - Own-memorial entries drive the "📷 photos at Find A Grave" header link — no images hotlinked or downloaded (contributor-owned), no placeholders.
- People with no citable URL (e.g. Franklin C. Foster — census-only) get an honest fallback line pointing at the research files.
- GA Archives pension link points at the Virtual Vault root with the record id in the label (deep-link format unverified — deliberate).
Special content (per spec)
- Monroe + Eleanor: "In the New York Times" block (Oct 19 1945 headline + TimesMachine link + subscription note).
- Monroe: USPS postmaster record block (Acting 04/14/1961, PM 09/15/1961, to early 1983) + Navy/WWII + NARA-request-pending block.
- Eleanor: memoirs block — My Journey to Appalachia (2004, ISBN 0914875310), My Life in Brasstown (2009, ISBN 0914875574).
index.html wiring
<script src="people/slugs.js">added before the main script;pageLink(name,b)helper appendsfull page →into the tooltip on all three views. Lookup triesname|birthyearfirst (disambiguates the two John Herman Wilsons), then bare name; wrapped in try/catch and null-guarded → degrades gracefully if slugs.js is missing (verified by deleting the map live).- "People index →" link added to the tab bar (small CSS rule added;
#tip .conf astyled).
Bug found & fixed during verification
- People with open death dates (Marie Ashton b.1605, William Olney Ⅲ b.1663) rendered as "living". Fixed with the main site's own heuristic: no death date + born after 1900 = living, else
?. Applied to page dates, family links, and the people index.
Verification (local server :8743, Playwright, cache-busted ?v= on every load)
- 0 console errors on: index.html, monroe-wilson, eleanor-lambert-wilson, jacob-sharp, people/index.
- Tooltips verified on all three tabs; link resolves correctly for both same-name JHWs; unknown wedges/stubs get no link; end-to-end click-through fan→tooltip→page navigated.
- Screenshots read (index+tooltip, Monroe, Eleanor, Jacob Sharp, people index).
- curl: 12 internal paths → 200. 15 external source URLs: all 200 except Find A Grave (403 = curl bot-block; URL format standard), WikiTree (202 challenge), FetchYourNews Danny obit (500 — known-flaky per tree doc, kept as canonical URL).
- Internal-link integrity script: 0 dangling hrefs across all 94 files.
- Server killed after verification.
Not done / open
- No deploy (per instructions).
publish-sitewiring untouched. - Non-ancestor children beyond Danny/Anita (e.g. the other eight Wilson siblings) intentionally not paged — out of scope.
- Dark mode not interactively tested; palette is a verbatim copy of the proven index.html block.