WikiFred

Sources & Methods

WikiFred

How the wiki is built and maintained.

WikiFred — Presentation Layer

How to turn a processed life-archive into a browsable, threaded website

Owner: Fred Heald Updated: 2026-06-04 Status: Active development. ~561 pages, 10+ threads, live at obtainium.org/wiki/ (early-review period, noindex). Project: projects/private/wikifred/

This is the presentation end of the archive pipeline. The sources-and-methods doc covers raw source → processed text → synthesis. This doc covers the last step: synthesis → a thing people can read and wander through. Output is a public, hyperlinked static site on obtainium.org.

If the sources-and-methods work is the mise en place — a life’s worth of raw material washed, sorted, and laid out in its station — this doc is where it goes on the heat and gets plated. The archive is the stocked pantry; the articles are the dishes; the site is the dining room.

Working name: WikiFred. Generic candidates for the reusable version: WikiArchive, WikiPerson. The method generalizes to anyone with a processed personal/family archive.


The core idea

Everything is articles and threads.

  • An article is one short page — one story, one event, one observation. A page at most; shorter is fine. Quality and quantity.
  • A thread is an ordered set of articles — the only structural primitive. A person is a thread. A place is a thread. A vehicle is a thread. A curated arc is a thread.

Two ways an article joins a thread:

Kind How Example
Curated declared in threads: frontmatter dylan-stories, burning-man
Entity auto-generated from people/pets/places/vehicles: tags every article tagged dora is the Dora thread

Article pipeline

Raw source (journal, Facebook post, blog, Yelp review, photo story)
    ↓  Select       identify good standalone stories
    ↓  Extract      get Fred's actual words from the raw source
    ↓  Scrub        remove private/NSFW content → visibility: public
    ↓  Tag          frontmatter: threads + entity tags + source thread
    ↓  Photos       check photo-reviews.jsonl for matching photos (by people/place/date/topic)
                    — copy matches to src/img/, add to article frontmatter
                    — photo-matches.md has pre-analyzed candidates
                    — record ALL candidates found (selected + not selected) in the source
                      file for the subject (memory-notes, portrait source, or equivalent)
                      NOT in the wiki article itself — wiki articles are output targets
    ↓  Build        eleventy → static HTML; pagefind → search index   (cook)
    ↓  Deploy       rsync _site/ → obtainium.org/wiki/                 (plate & serve)

Critical rule: Always use Fred’s actual words from the raw source. Never paraphrase.


The feedback loop

The pipeline above looks one-way but isn’t. Building a wiki article is also a research pass — and discoveries made during that pass feed back into the source files.

The loop:

  • Finding photos for an article → record ALL candidates (selected + not) in the source/notes file
  • Discovering a new fact while writing → add it to the portrait source or memory-notes
  • Fred adds content during review (new quotes, corrections, stories) → goes back into the source, not just the article
  • Wiki articles are output — they receive content, they don’t store it

Why this matters: if photo candidates or new facts only exist in the wiki article, they’re lost the next time the article is regenerated or the session compacts. The source files are the memory; the wiki is the display.

In practice: any time you find, select, or decide against a photo — note it in the subject’s source file (memory-notes, portrait source, or equivalent). Same for facts Fred adds during conversation. The article is the last stop, not the only stop.


The tagging system

Every article carries two kinds of tags in its frontmatter:

1. Curated thread membership (threads: array) Explicit membership in named threads. An article can belong to multiple:

  • Content threads: stories, burning-man, travel, food, el-centro, tech, vehicles, portraits, fragments, doofs, webb
  • Source threads: src-journal, src-facebook, src-blog, src-yelp, src-autobiography, src-photo-stories, src-journal-summary (needs raw replacement)

2. Entity tags (auto-generate entity threads) Tags in people:, pets:, places:, vehicles: arrays. Every article tagged with a slug automatically joins that entity’s thread — no declaration needed. E.g. every article with people: ["nicholas-corwin"] becomes part of his thread.

Thread kinds (controlled in lib/registry.mjs): curated · person · pet · toy · place · vehicle · source · topic

topic = fallback for unregistered slugs. These work for article nav but are hidden from the browse index. To promote a slug from topic to a proper kind, add it to the registry.

Browse index visibility: Currently suppressed from the index: topic (unregistered overflow), vehicle (covered by curated Vehicles thread), toy (Stick Fluffy only). Hardcoded in src/browse.njk. Future: make a registry hideFromBrowse flag.

Validation: npm run validate checks all articles for malformed frontmatter — trailing slashes in thread slugs, invalid visibility values, missing required fields.


Source threads

Every article is tagged with a src-* thread identifying its provenance. This lets you browse by source at /thread/src-journal/ etc., and tracks what’s been mined.

Thread Label Raw source Selection aid
src-journal Journal self-analysis/source/journal-notes-*.md (Apple Notes exports) The notes files are the raw material
src-facebook Facebook facebook/posts.md, facebook/posts 2.md self-analysis/source/facebook-notes-*.md identify good posts; get actual text from posts.md
src-blog Blog blogs/source/*.md — one file per post Read directly
src-yelp Yelp review yelp/reviews/all-reviews.md Read directly
src-autobiography Autobiography draft autobiography/drafts/*.md Read directly; already in Fred’s voice
src-photo-stories Photo story journals/originals/2026/*/photo-stories.md Read directly
src-quora Quora self-analysis/source/obtainium-notes.md (Quora section) Read directly

Mining status tracked in wikifred/SOURCES.md.


Voice rules

  • Dylan Stories — third-person warm voice (“Dylan was nine years old and it was a mountain creek”)
  • All other articles — Fred’s actual words from raw source. Quote or minimally expand. Never paraphrase into a neutral voice.
  • Editorial notes — a soupçon of italics at the bottom of the article body: only when context is genuinely needed, never enough to taste on its own

Names & deadnames

Display a person’s current/chosen name everywhere it is presented: article titles, headings, the registry display name (which drives thread headings and link labels), and slugs.

In historical article body text, the default is to keep the name as it was actually used at the time — the prose stays true to the lived moment. John and I were the ones who did the thing, even if the title now reads “Jane and Fred Did the Thing.” This default yields to the subject’s own preference: if they want the former name fully replaced in the prose too, do that.

Always keep the original in source-provenance fields (source.file, entry:) — these must match the source filename/heading, not the display name.

Worked example: Nicholas Corwin went by “Kip” for decades. Titles, slugs, and his thread/registry name are all Nicholas Corwin; the old article bodies still say “Kip” where that’s how it happened.


Scrubbing rules (public site)

Omit: romantic/sexual relationships, marriage/separation/divorce, therapy/counseling, substance self-monitoring, gender expression outings, other people’s private medical/financial/relationship info.

Safe: travel, adventure, vehicles, places, food, Burning Man (public aspects), work (general), tech observations, family history (deceased relatives fine), funny incidents, friends in public/fun contexts.

Visibility / access model — an audience axis (who may see it) plus admin-only flags. Single source of truth: lib/visibility.mjs. Three roles: anyone / logged-in / admin (Fred).

visibility Who may see it Deploy build (_site) Admin build (npm run review)
public anyone yes yes
login logged-in users no¹ yes
admin admin (Fred) only no yes
draft admin only — review state no yes

¹ login needs real logins; pre-login it simply isn’t deployed. Legacy aliases: private→login, personal/hidden→admin.

Admin-only flags (force admin-only regardless of visibility; both keep an article out of deploy until resolved):

  • needs_review: true — pending review. Approve-forward: a public article with this flag is held back from deploy until cleared. Also what puts an article on /review/; every draft is initialized with it.
  • nsfw: true — not-safe-for-public. Admin sees it; deploy never does.

Build rule (in code): deploy = public AND not needs_review AND not nsfw; the admin build shows everything. The “logged-in” middle role (public + login) isn’t separately buildable until logins land.

NSFW photo filtering from LR export: When exporting photos from the LR catalog for published stubs, exclude photos tagged with the NSFW keyword subtree (LR keyword id=67335 in this catalog). Descendants include: NSFW, Medical, Private, Dresses, Mushrooms. Do NOT use the broader NoPublish tree (id=1628171) — it includes organizational categories (Collections, Events, Burning Man, etc.) that are safe to publish and would produce hundreds of false exclusions. Use album-scoped queries when checking for NSFW tags — basename-only lookup produces false positives from duplicate filenames across different LR folders.

Editor-comment processing (review-questions.md): apply the note, then set state and clear needs_review. A bare “OK” / “ok to publish” = reviewed & approved → visibility: public. Dispositions Fred uses: “keep private” → login; “hide this” / admin-only → admin; “split into two” → public part + admin/login part.


Travel stubs

Naming convention: YYYY-MM Destination Subject (e.g., 2007-07 Santa Fe Blake and Joley's Wedding). Slug follows: 2007-07-santa-fe-blake-joley-wedding.

trips thread: One entry per trip. The trip-overview article gets trips in threads. Day articles within a multi-day trip (e.g., oregon-trip-2024-day-1) get the trip slug as their thread but not trips — day articles should not clutter the trips timeline. Solo-day trips that have no overview article also get trips.

Slug rename cascade: If the trip slug doubles as a thread name referenced by other articles (e.g., day articles), renaming it requires updating all those articles’ threads lists and the registry entry simultaneously. Script it — don’t do it by hand.

LR collection query types:

  • Direct collection: c.creationId = 'com.adobe.ag.library.collection' — query AgLibraryCollectionImage directly.
  • Collection set (older organization): join parent set → child named 'Project Photos' → AgLibraryCollectionImage. Many pre-2010 albums use this structure.

Craft rules — lessons learned

Hard rules from review passes. Running log of specifics: wikifred/review-feedback.md.

Conventions (2026-06, established across the relative-profile batch; per-rule enforcer “cleanup runs” tracked in wikifred/TODO.md):

  • tag ≠ link. A people:/threads: tag means the article is about that entity (puts it in the entity’s hub) — tag deliberately, only the subject(s). A [[link]] is just a mention — link freely. Profiles link direct family in prose; don’t over-tag. Scrub over-tagged articles.
  • No relative dates in our editorial prose (“a year ago” → “2025”). Fred’s verbatim journal quotes keep their original phrasing.
  • No rimshots — front or back. Cut trite scene-setting openers (“He started a long way from the desert”) as well as theme-stating closers. Lead with the concrete.
  • Sensitive info → a “Personal / do-not-publish” section in the source/data record, never the published article (cause of death, private family matters).
  • Photo curation: young + old + action per person; avoid group shots. Default search = processed photo-reviews.jsonl; the Lightroom catalog is the expensive, face-tag-dependent tier (see sources-and-methods.md § Photo search).
  • Web-search augment for notable ancestors (a line or two + a source link).
  • People pipeline + data-record format: people/people-workflow.md.

Use Fred’s actual words; add nothing. A source link is necessary but not sufficient. For every article:

  1. Read the actual _source/<source>/ entry — never a summary, rehash, or analysis doc.
  2. Record the resolvable source path in frontmatter.
  3. Use Fred’s own words; quote or lightly edit — never paraphrase into a neutral voice.
  4. Add no inference, dates, places, or “what happened” narration that isn’t in the source. (Canonical failure: gila-bend-postcard invented a wrong birthday and a “that’s the thing about photos” closer on top of good source.)

Editorial notes — the keep/cut test. A trailing italic note is allowed only if it adds external verifiable fact the source itself can’t supply: identity (“X was Fred’s grandfather”), aftermath (“X passed away in 2000”), archival significance (“the last journal entry that mentions him alive”). Cut it if it restates the article, infers/embellishes, or lands an aphorism. Keep example: the Gramp-death note on daltons-rash-decisions. Cut example: gila-bend.

No rimshots. Don’t end on a tidy thematic closer that states the theme out loud. Cut unless it’s Fred’s own line.

Avoid chops (journal duplication). A journal entry with several dated sub-entries (YYMMDD.HHMM) must not be split so one article keeps the whole entry (duplicated tail), and adjacent articles must not overlap. Detect by shared timestamps and shared verbatim sentences. (See the journals extraction doc.)

Scrub at the line, not the article. Cut the offending sentence and keep the article when the rest is safe — e.g. gender-expression asides (bra shopping, “wear a dress”) get surgically removed, and a revealing slug gets renamed (sachs-madass-and-bras → sachs-madass). Draft the whole article only when its premise is the private content.

Verify photo captions. Never trust an inherited caption — confirm who/what/when from the image plus sources (the “Amy” who was actually Britt). Check photo-reviews.jsonl / photo-matches.md.

One canonical slug per entity. No alias slugs (kip vs nicholas-corwin); the display label carries the nickname via [[nicholas-corwin|Kip]].


Frontmatter format

---
title: "Title"
date: YYYY-MM-DD
threads: ["content-thread", "src-source-thread"]
people: ["slug"]
places: ["slug"]
vehicles: ["slug"]
pets: ["slug"]
visibility: public          # public | hidden | draft
needs_review: true          # optional; author flag only, no visual effect until Phase 2
photos:
  - src: /img/filename.jpg
    caption: "Caption"
source:
  label: "Journal"        # or: Facebook | Blog | Yelp review | Autobiography draft | Photo story
  url: "https://..."      # optional, for external links
---

Entity registry

All entity slugs and thread metadata live in lib/registry.mjs. Key fields:

  • name — display name
  • kind — curated | person | pet | toy | place | vehicle | source | topic
  • blurb — shown on thread hub page

Unknown slugs auto-titleize from the slug (no registry entry needed for one-offs).


Technology

Concern Choice Why
Generator Eleventy (11ty) Markdown-native, plain JS, static HTML
Search Pagefind Zero-backend full-text; indexes built HTML
Hosting static files on obtainium.org No server, no DB, no login
Linking custom [[wiki-link]] markdown-it plugin First-mention treatment at build time
Client nav tiny JS over /threads.json In-place next/random; degrades gracefully

Build note: npx eleventy hangs on Node v24. Use node node_modules/@11ty/eleventy/cmd.cjs directly. This is wired into package.json scripts.


Dylan Stories: generated vs. hand-authored

Dylan Stories are the only generated thread. scripts/build-content.mjs:

  • Reads source files from ../journals/dylan-stories/ — never modified
  • Injects frontmatter (tags, date, people/places/pets) from a per-file META map
  • Injects [[wiki-links]] on first entity mention
  • Writes derived articles to src/articles/dylan-stories/ — always overwritten

All other articles are hand-authored .md files placed directly in src/articles/<thread>/.


Current threads (2026-06-03)

Content: Dylan Stories, Stories, Burning Man, Travel, Food, El Centro, Tech, Vehicles, Portraits, Fragments

Source: src-journal, src-facebook, src-blog, src-yelp, src-autobiography, src-photo-stories, src-quora

Entity (people): Fred Heald, Becke Shulman, Amy Heald, Phillip Heald, Nicholas Corwin “Kip”, Pamarie, Dylan Heald, and others

Entity (pets/toys): Dora, Pasquale, Sabio, The Puppies, Stick Fluffy, Tikka, Masala

Entity (places): El Centro, Mission Bay, Colorado, Telluride, Ouray, Claremont, San Felipe, and others

Entity (vehicles): Pinzgauer, and individual vehicle articles via the Vehicles thread


Generalizability

This pattern works for any processed personal or family archive: write short articles, tag entities, let entity threads auto-generate, publish static. The reusable version (WikiArchive) is the same code with Fred-specific registry and source-derive script swapped out. Candidate for the Personal Archive Handbook publication.


Chef’s note: the kitchen metaphor running through this doc — mise en place, soupçon, cook, plate — is a deliberate seasoning, not an accident. Keep the pinch light if you add to it.