Daeseon Yoo

Active · May 25, 2026

daeseon.ai

This site. Bilingual blog + private admin dashboard for drafts and distribution.

Role
Solo
Stack
Next.js 15 · TypeScript · Tailwind · MDX · Vercel

The blog you're on. Built from scratch so the constraints (writing tone, admin features, distribution) are mine, not a template's.

What it does

Why

I've been writing in private docs for years and not shipping any of it. This site exists to break that loop.

What's still missing

Project log

Chronological record of troubleshooting, retros, and updates while building this.

filter
  1. MDX broke on `$\mathbb{R}^d$` with `R is not defined`

    Troubleshoot

    May 25, 2026 · 1 min

    Curly braces in math notation are JSX expressions to MDX. The build crashed on a sample embeddings post.

  2. Stack and storage: Next.js 15 + GitHub commit-as-database

    Tech retro

    May 25, 2026 · 1 min

    Why I picked Next.js 15 + Vercel + GitHub Contents API for storage instead of a database.

  3. Why I split content into post / note / knowledge / log

    Tech retro

    May 26, 2026 · 2 min

    One bucket for everything fails three different audiences. Four content types with different visibility defaults each.

  4. EROFS on every Vercel publish — production fs is read-only

    Troubleshoot

    May 26, 2026 · 2 min

    Admin publish crashed with EROFS. Cause: I wrote to disk first, then committed to GitHub. Production fs is read-only.

  5. Why publish-to-live used to take 60s, and how I got it to 3-5s

    Tech retro

    May 26, 2026 · 2 min

    Production fs is a frozen build snapshot. Reading content through fs.readFile meant 60s of staleness per publish. Moved reads to GitHub Raw.

  6. Hobby photos on a dev portfolio: when they help and when they don't

    UX retro

    May 26, 2026 · 1 min

    I considered a 추억-style photo gallery on /about. Decided against. Kept a small slot for conference/maker/workspace shots only.

  7. Vercel refused to build with next-mdx-remote@5.x (CVE)

    Troubleshoot

    May 26, 2026 · 1 min

    First production build was blocked by Vercel's security scanner. Solved with a one-line dep bump.

  8. Sidebar width: 16rem felt empty, 13rem felt cramped, 14rem stuck

    UX retro

    May 26, 2026 · 2 min

    The hub layout (left sticky profile / right content) needed two rounds of width tuning before it stopped looking off.

  9. Live site returned 401 to everyone (Vercel Authentication on by default)

    Troubleshoot

    May 26, 2026 · 1 min

    Production URL was unreachable until I disabled Vercel's default deployment protection. No code change.

  10. Client component pulled node:fs into the browser bundle

    Troubleshoot

    May 27, 2026 · 1 min

    Vercel build failed with `You may need an additional plugin to handle node: URIs`. LogTimeline.tsx (client) imported lib/logs.ts (server), pulling node:fs into webpack's client bundle.

  11. Cross-repo log aggregation: each repo keeps its own, the portfolio pulls

    Tech retro

    May 27, 2026 · 3 min

    Added `logSourceRepo` to project frontmatter so each project's log timeline can be fetched from its own separate repo. Pull-on-demand with 30s ISR cache, no polling.

  12. Domain typo: daseon.ai vs daeseon.ai

    Troubleshoot

    May 27, 2026 · 1 min

    Project was bootstrapped with daseon.ai (one letter short). The real registered domain is daeseon.ai. Found at Vercel domain connection time.

  13. Image upload UX: from a tiny button to a real dropzone

    UX retro

    May 27, 2026 · 1 min

    Admin image upload worked the whole time, but I couldn't reliably find it. Fixed the discoverability instead of the mechanism.

  14. Designing the project-log system (this thing you're reading)

    Tech retro

    May 27, 2026 · 3 min

    Why I added a fourth content type for project logs, dual-wrote to a machine-facing reference and a human-facing timeline, and built explicit anti-hallucination rules.

  15. Stop hook: from reminder to enforcement (blocking + self-terminating sentinel)

    Tech retro

    May 27, 2026 · 3 min

    The original Stop hook nudged with a systemMessage, which Claude could ignore. Upgraded to decision:block + reason with a commit-hash sentinel that terminates the loop once a log entry exists.