← All changelog entries
August 8, 2026 · Infrastructure

Markdown wins the stack argument: the DB scripts run again, seven identities reconciled, and the July 29 cohort lands on the roster

Adding one tool to the registry surfaced that every stack-sync script had been dead since the Astro 7 upgrade — and that Turso had been a stale photocopy of markdown since May 21. Fixed the tooling, declared markdown the source of truth, and caught a roster sync that was about to publish seven duplicate profiles including one called `mail`.

Authors
Michael Staton
Augmented with
Claude Code on Opus 5
Tags
#Tooling#Data-Integrity#Participants#Tool-Registry

Markdown wins the stack argument

Why Care?

The task was one line: add MCP Market to the tool registry and to an aspirational stack. Doing it honestly meant asking whether the markdown edit would actually stick — and the answer was no. Stack rows live in Turso, markdown is a materialized view, and the script that materializes it had been dead for weeks.

Pulling that thread found a second, worse problem: the roster sync was one WRITE=true away from publishing seven duplicate profiles for people already on the site.

The Astro 7 tail

The August 2 entry closed with a note that sync-session.ts still needed the default-export shim treatment. It turns out five more scripts were in the same state, and nobody had noticed because they fail by printing the astro --help screen and exiting 0.

Converted to the export default async function () shape the db-execute.mjs shim requires, with package.json entries rerouted through it:

  • add-to-stack.ts, sync-stacks.ts, migrate-stacks-to-turso.ts, sync-people-from-db.ts, rename-user-handle.ts

(sync-session.ts remains the last one standing — same two-line fix, still tracked.)

Markdown is the source of truth

With the tooling alive, the direction question became answerable on evidence rather than intuition. Every Stack row for mpstaton — including the two that looked like the DB knew something markdown didn’t — carried created_at 2026-05-21T22:30:37.719Z, the one-time backfill. In the eleven weeks since, exactly two rows in the entire database came from a human using the app.

So Turso wasn’t a competing record. It was a May 21 photocopy, and the “conflicts” were just markdown having moved on. Declared accordingly:

  • pnpm push:stacks:remote (md → DB) — the routine publish, renamed from migrate:stacks since it stopped being a migration. Skips handles whose markdown stack is empty rather than blanking them.
  • pnpm sync:stacks:remote (DB → md) — now the capture step, for pulling an app-entered edit back to disk. Always with an explicit HANDLE=; bare ALL-mode would have rewritten mpstaton from stale rows and silently dropped eight tools.
  • pnpm audit:stacks — new read-only drift report, run before either.

Order matters and isn’t obvious: capture before publish, never after.

Seven identities, one near-miss

sync-people-from-db derives handles from github_handle, else the email local-part with dots stripped. That never matched our hand-authored slugs, so 7 of the 20 unlisted accounts would have been minted as second profiles for people already on the rosterraeedzz next to raeedzainuddin, jpardo next to jimena-pardo, and, because his email local-part is literally mail, a public profile called mail.md for Aravind Bharadwaj.

Huiting Koh only surfaced on a second pass: her file reads name: "Hui Koh" while the account says “Huiting Koh,” so exact-name matching missed her.

Renamed all seven DB handles to match the existing slugs. Knock-on effects, both good:

  • Stub creation dropped 20 → 13, all genuinely new.
  • Stack-push coverage went 19 → 26 participants; the 8 still skipped are people who genuinely never registered.

Six of the seven had github_handle: NULL — they signed in via Google or LinkedIn. That column is the canonical handle everywhere in the codebase despite its name, which is a wart worth renaming someday.

Also included

  • MCP Market added to the tool registry — the 42,000-server MCP/Agent-Skills directory plus Hub, its version-control and toolkit-sync layer. Banner and favicon self-hosted per the August 2 convention; the site 403s plain curl, so the banner is a headless capture.
  • Francesco Corea is the first of the July 29 cohort published. Filled from his Kauffman Fellows directory entry (KF 31, Independent, UK) with a local headshot. Handle moved coreafrfrancesco-corea for a legible URL — which requires the DB rename too, since owner-edit compares User.github_handle against the frontmatter handle.
  • 13 participant stubs written, 12 still publish: false pending a per-person call.
  • hstanford and punit24-lab had their app-entered tools captured into their new stubs — the only two people who ever used StackBuilder.

What’s Next?

  • sync-session.ts — the last un-shimmed script.
  • Francesco’s linkedin is blank (no verifiable URL found), and his Turso User.name still reads CoreaFr with an empty firm column; rename-user-handle.ts only touches the handle.
  • /people/[handle] is SSR, so no individual profile is in sitemap-0.xml — they’re crawlable only via the index. If profiles matter for search, that needs customPages or a prerender split.
  • The remaining 12 stubs are thin next to hand-authored profiles. crawl-fetch-ingest is the tool for filling them before publishing.