PageSourceSearch

https://joeywang.github.io/about/

html joeywang.github.io collected 2026-10-03 09:24:20 UTC 20,360 bytes, 1 lines download raw bytes

1<!doctype html><html lang=""><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta name="theme-color" media="(prefers-color-scheme: light)" content="#f7f7f7"><meta name="theme-color" media="(prefers-color-scheme: dark)" content="#1b1b1e"><meta name="viewport" content="width=device-width, user-scalable=no initial-scale=1, shrink-to-fit=no, viewport-fit=cover" ><meta name="generator" content="Jekyll v4.4.1" /><meta property="og:title" content="About" /><meta property="og:locale" content="en_US" /><meta name="description" content="Joey Wang writes about Ruby on Rails, learning platforms, reliability, practical AI workflows, and the engineering work that keeps established software dependable." /><meta name="twitter:description" property="og:description" content="Joey Wang writes about Ruby on Rails, learning platforms, reliability, practical AI workflows, and the engineering work that keeps established software dependable." /><link rel="canonical" href="https://joeywang.github.io/about/" /><meta property="og:url" content="https://joeywang.github.io/about/" /><meta property="og:site_name" content="Joey" /><meta property="og:type" content="website" /><meta name="twitter:card" content="summary" /><meta name="twitter:title" content="About" /><meta name="twitter:site" content="@alazycoder2" /> 
1<script type="application/ld+json"> {"@context":"https://schema.org","@type":"WebSite","description":"Joey Wang writes about Ruby on Rails, learning platforms, reliability, practical AI workflows, and the engineering work that keeps established software dependable.","headline":"About","name":"Joey","url":"https://joeywang.github.io/about/"}</script>
1<title>About | Joey</title><link rel="icon" type="image/png" href="/assets/img/favicons/favicon-96x96.png" sizes="96x96"><link rel="icon" type="image/svg+xml" href="/assets/img/favicons/favicon.svg"><link rel="shortcut icon" href="/assets/img/favicons/favicon.ico"><link rel="apple-touch-icon" sizes="180x180" href="/assets/img/favicons/apple-touch-icon.png"><link rel="preconnect" href="https://fonts.googleapis.com" ><link rel="dns-prefetch" href="https://fonts.googleapis.com" ><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link rel="dns-prefetch" href="https://fonts.gstatic.com" ><link rel="preconnect" href="https://cdn.jsdelivr.net" ><link rel="dns-prefetch" href="https://cdn.jsdelivr.net" ><link rel="stylesheet" href="/assets/css/jekyll-theme-chirpy.css"><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Lato:wght@300;400&family=Source+Sans+Pro:wght@400;600;700;900&display=swap"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@7/css/all.min.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/loading-attribute-polyfill@2/dist/loading-attribute-polyfill.min.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/glightbox@3/dist/css/glightbox.min.css"> 
1<script src="/assets/js/dist/theme.min.js"></script>
1 
1<script defer src="https://cdn.jsdelivr.net/combine/npm/simple-jekyll-search@1/dest/simple-jekyll-search.min.js,npm/loading-attribute-polyfill@2/dist/loading-attribute-polyfill.umd.min.js,npm/glightbox@3/dist/js/glightbox.min.js,npm/clipboard@2/dist/clipboard.min.js"></script>
1 
1<script defer src="/assets/js/dist/page.min.js"></script>
vendor: 64 bytes, line 1
1 <script defer src="https://www.googletagmanager.com/gtag/js?id=
1G-E31NLRCXN6
vendor: 12 bytes, line 1
1"></script> 
1<script> document.addEventListener('DOMContentLoaded', () => { 
vendor: 130 bytes, line 1
1window.dataLayer = window.dataLayer || []; function gtag() { dataLayer.push(arguments); } gtag('js', new Date()); gtag('config', '
1G-E31NLRCXN6
vendor: 4 bytes, line 1
1'); 
1const isPost = !!document.querySelector('article'); const pageTitle = document.querySelector('meta[property="og:title"]')?.getAttribute('content') || document.title; const pageCategory = document.querySelector('meta[property="article:section"]')?.getAttribute('content') || ''; const pageTags = [...document.querySelectorAll('meta[property="article:tag"]')].map(m => m.getAttribute('content')); /* 1. Enhanced post view */ if (isPost) { const text = document.querySelector('article')?.textContent || ''; const wordCount = text.match(/\b\w+\b/g)?.length || 0; gtag('event', 'post_view', { post_title: pageTitle, post_category: pageCategory, post_tags: pageTags.join(', '), word_count: wordCount }); } /* 2. Scroll depth (posts only) */ if (isPost) { const docHeight = Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight ) - (window.innerHeight || document.documentElement.clientHeight); if (docHeight <= 0) { /* no scroll tracking needed */ } else { const firedDepths = new Set(); let ticking = false; const trackScroll = () => { const scrollTop = window.pageYOffset || document.documentElement.scrollTop || 0; const pct = Math.round((scrollTop / docHeight) * 100); [25, 50, 75, 100].forEach(d => { if (pct >= d && !firedDepths.has(d)) { firedDepths.add(d); gtag('event', 'scroll_depth', { scroll_depth: d }); } }); }; window.addEventListener('scroll', () => { if (!ticking) { window.requestAnimationFrame(() => { trackScroll(); ticking = false; }); ticking = true; } }, { passive: true }); } } /* 3. Outbound link clicks */ document.addEventListener('click', e => { const link = e.target.closest('a'); if (!link) return; const url = link.href; if (!url || !url.startsWith('http')) return; try { if (new URL(url).hostname === location.hostname) return; } catch { return; } gtag('event', 'outbound_click', { link_url: url, link_text: (link.textContent || '').trim().slice(0, 100) }); }); /* 4. Copy code */ document.addEventListener('copy', () => { const sel = window.getSelection(); if (!sel || !sel.toString()) return; let node = sel.anchorNode; while (node && node !== document.body) { if (node.nodeName === 'CODE' || node.nodeName === 'PRE') { gtag('event', 'copy_code', { code_length: sel.toString().length }); break; } node = node.parentNode; } }); /* 5. Search queries */ const searchInput = document.getElementById('search-input'); if (searchInput) { searchInput.addEventListener('search', e => { if (e.target.value) { gtag('event', 'search', { search_term: e.target.value }); } }); } /* 6. Share button clicks */ document.querySelectorAll('.share-icons a').forEach(link => { link.addEventListener('click', () => { gtag('event', 'share', { platform: link.getAttribute('aria-label') || link.href }); }); }); const copyLink = document.getElementById('copy-link'); if (copyLink) { copyLink.addEventListener('click', () => { gtag('event', 'share', { platform: 'copy_link' }); }); } }); </script>
1<body><aside aria-label="Sidebar" id="sidebar" class="d-flex flex-column align-items-end"><header class="profile-wrapper"> <a href="/" id="avatar" class="rounded-circle"><img src="https://pbs.twimg.com/profile_images/1642888448422866945/fAbKo0Q3_400x400.jpg" width="112" height="112" alt="avatar" onerror="this.style.display='none'"></a> <a class="site-title d-block" href="/">Joey</a><p class="site-subtitle fst-italic mb-0">A developer's world</p></header><nav class="flex-column flex-grow-1 w-100 ps-0"><ul class="nav"><li class="nav-item"> <a href="/" class="nav-link"> <i class="fa-fw fas fa-home"></i> <span>HOME</span> </a><li class="nav-item active"> <a href="/about/" class="nav-link"> <i class="fa-fw fas fa-user"></i> <span>ABOUT</span> </a><li class="nav-item"> <a href="/consulting/" class="nav-link"> <i class="fa-fw fas fa-handshake"></i> <span>CONSULTING</span> </a><li class="nav-item"> <a href="/blog/" class="nav-link"> <i class="fa-fw fas fa-pen-nib"></i> <span>BLOG</span> </a><li class="nav-item"> <a href="/ai-agents/" class="nav-link"> <i class="fa-fw fas fa-robot"></i> <span>AI & AGENTS</span> </a><li class="nav-item"> <a href="/projects/" class="nav-link"> <i class="fa-fw fas fa-laptop-code"></i> <span>PROJECTS</span> </a><li class="nav-item"> <a href="/categories/" class="nav-link"> <i class="fa-fw fas fa-stream"></i> <span>CATEGORIES</span> </a><li class="nav-item"> <a href="/tags/" class="nav-link"> <i class="fa-fw fas fa-tags"></i> <span>TAGS</span> </a><li class="nav-item"> <a href="/todo/" class="nav-link"> <i class="fa-fw fas fa-tasks"></i> <span>TODO</span> </a><li class="nav-item"> <a href="/tools/" class="nav-link"> <i class="fa-fw fas fa-wrench"></i> <span>TOOLS</span> </a></ul></nav><div class="sidebar-bottom d-flex flex-wrap align-items-center w-100"><div class="btn-group dropup"> <button type="button" class="btn btn-link nav-link" aria-label="Switch Mode" id="mode-toggle" data-bs-toggle="dropdown" ><i class="fa-regular fa-sun" data-theme-mode="light"></i><i class="fa-regular fa-moon" data-theme-mode="dark"></i><i class="fa-solid fa-display" data-theme-mode="system"></i></button><ul class="dropdown-menu rounded-3 mb-1 p-1"><li> <button class="dropdown-item d-flex align-items-center" type="button" data-theme-mode="light"><i class="fa-regular fa-sun" data-theme-mode="light"></i>Light</button><li> <button class="dropdown-item d-flex align-items-center" type="button" data-theme-mode="dark"><i class="fa-regular fa-moon" data-theme-mode="dark"></i>Dark</button><li> <button class="dropdown-item d-flex align-items-center" type="button" data-theme-mode="system"><i class="fa-solid fa-display" data-theme-mode="system"></i>System</button></ul></div><span class="icon-border"></span> <a href="https://www.youtube.com/@alazycoder101" aria-label="youtube" target="_blank" rel="noopener noreferrer" > <i class="fa-brands fa-youtube"></i> </a> <a href="https://github.com/joeywang" aria-label="github" target="_blank" rel="noopener noreferrer" > <i class="fa-brands fa-github"></i> </a> <a href="javascript:void(location.href = 'mailto:' + ['joeyw','reallyenglish.com'].join('@'))" aria-label="email" > <i class="fas fa-envelope"></i> </a> <a href="/feed.xml" aria-label="rss" > <i class="fas fa-rss"></i> </a></div></aside><div id="main-wrapper" class="d-flex justify-content-center"><div class="container d-flex flex-column px-xxl-5"><header id="topbar-wrapper" class="flex-shrink-0" aria-label="Top Bar"><div id="topbar" class="d-flex align-items-center justify-content-between px-lg-3 h-100" ><nav id="breadcrumb" aria-label="Breadcrumb"> <span> <a href="/">Home</a> </span> <span>About</span></nav><button type="button" id="sidebar-trigger" class="btn btn-link" aria-label="Sidebar"> <i class="fas fa-bars fa-fw"></i> </button><div id="topbar-title"> About</div><button type="button" id="search-trigger" class="btn btn-link" aria-label="Search"> <i class="fas fa-search fa-fw"></i> </button> <search id="search" class="align-items-center ms-3 ms-lg-0"> <i class="fas fa-search fa-fw"></i> <input class="form-control" id="search-input" type="search" aria-label="search" autocomplete="off" placeholder="Search..." > </search> <button type="button" class="btn btn-link text-decoration-none" id="search-cancel">Cancel</button></div></header><div class="row flex-grow-1">
1<main aria-label="Main Content" class="col-12 col-lg-11 col-xl-9 px-md-4"><article class="px-1"><h1 class="dynamic-title"> About</h1><div class="content"><p><a href="/assets/pdf/JoeyW-dev.pdf" class="btn btn-link btn-lg" style="float: right;">📄 Download Resume (PDF)</a></p><h2 id="i-build-software-that-can-be-operated-with-confidence"><span class="me-2">I build software that can be operated with confidence</span><a href="#i-build-software-that-can-be-operated-with-confidence" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h2><p>I’m Joey Wang, a software engineer and consultant focused on Ruby on Rails, learning platforms, and the work that keeps established products dependable as they evolve.</p><p>My background is rooted in long-lived web systems. I’ve designed and maintained learning platforms, worked on product teams, modernized application and deployment infrastructure, and supported systems where reliability matters to the people using them every day.</p><p>The interesting work is rarely just choosing a framework. It is understanding the existing system, finding the constraint that is actually limiting it, making a change that can be explained, and leaving the next person with a safer path forward.</p><h2 id="what-i-work-on"><span class="me-2">What I work on</span><a href="#what-i-work-on" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h2><ul><li><strong>Rails and LMS modernization</strong> — improving established applications without pretending that a rewrite is always the answer.<li><strong>Reliability and performance</strong> — tracing slow paths, reducing avoidable complexity, and making failures easier to diagnose.<li><strong>Cloud and delivery systems</strong> — improving deployment, infrastructure, testing, and operational feedback loops.<li><strong>Practical AI workflows</strong> — using AI to support engineering judgment and repeatable work, with explicit boundaries around verification, privacy, and human approval.</ul><h2 id="how-i-work"><span class="me-2">How I work</span><a href="#how-i-work" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h2><p>I start with evidence: the code, the data, the deployment path, the logs, and the experience of the people using the system. I prefer a small, reversible improvement over a broad redesign justified by fashion.</p><p>A typical engagement may involve:</p><ol><li>understanding the current architecture and the problem behind the request;<li>identifying risks, dependencies, and a practical first slice;<li>implementing and testing the smallest coherent change;<li>documenting what was learned and how to operate or roll it back.</ol><p>That approach is useful when a team has a Rails application that has grown over time, an LMS that is difficult to change safely, or a delivery process that no longer gives enough confidence.</p><h2 id="selected-work"><span class="me-2">Selected work</span><a href="#selected-work" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h2><ul><li><a href="/consulting/">Consulting</a> — a practical starting point for Rails, LMS, reliability, and modernization conversations.<li><a href="/posts/rails-lms-reliability-modernization/">When a Rails or LMS Platform Becomes Hard to Change</a> — an evidence-led way to diagnose platform friction.<li><a href="/posts/ai-impact-software-development-lifecycle/">AI’s Impact on the Software Development Lifecycle</a> — thinking about useful AI without confusing assistance with judgment.<li><a href="/posts/durable-codebase-context-hermes-gitnexus-lsp/">Durable Codebase Context</a> — notes on making engineering context easier to inspect and reuse.</ul><h2 id="a-note-on-this-site"><span class="me-2">A note on this site</span><a href="#a-note-on-this-site" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h2><p>This site is a working record rather than a catalogue of buzzwords. Some posts describe completed engineering work; others are experiments or developing ideas. I try to make that distinction clear, show the reasoning behind decisions, and avoid presenting an interesting possibility as a shipped result.</p><p>If you are dealing with a difficult-to-change Rails or learning platform, <a href="/consulting/">get in touch through the Consulting page</a>.</p></div></article></main><aside aria-label="Panel" id="panel-wrapper" class="col-xl-3 ps-2 text-muted"><div class="access"><section id="access-lastmod"><h2 class="panel-heading">Recently Updated</h2><ul class="content list-unstyled ps-0 pb-1 ms-1 mt-2"><li class="text-truncate lh-lg"> <a href="/posts/ci-gates-test-caches-code-graphs/">CI Gates, Test Result Caches, and the Code Graph That Might Tell Us What to Test</a><li class="text-truncate lh-lg"> <a href="/posts/when-a-green-deployment-still-serves-a-500/">When a Green Deployment Still Serves a 500</a><li class="text-truncate lh-lg"> <a href="/posts/wordpress-security-incident-rebuild/">Recovering a hacked WordPress site: why I rebuilt instead of patching</a><li class="text-truncate lh-lg"> <a href="/posts/ai-native-one-person-company-operating-system/">
1The One-Person Company Is a Coordination Problem</a><li class="text-truncate lh-lg"> <a href="/posts/when-productivity-turns-against-its-purpose/">When Productivity Turns Against Its Purpose</a></ul></section><section><h2 class="panel-heading">Trending Tags</h2><div class="d-flex flex-wrap mt-3 mb-1 me-3"> <a class="post-tag btn btn-outline-primary" href="/tags/debugging/">debugging</a> <a class="post-tag btn btn-outline-primary" href="/tags/devops/">devops</a> <a class="post-tag btn btn-outline-primary" href="/tags/rails/">rails</a> <a class="post-tag btn btn-outline-primary" href="/tags/ai/">ai</a> <a class="post-tag btn btn-outline-primary" href="/tags/database/">database</a> <a class="post-tag btn btn-outline-primary" href="/tags/ruby/">ruby</a> <a class="post-tag btn btn-outline-primary" href="/tags/performance/">performance</a> <a class="post-tag btn btn-outline-primary" href="/tags/security/">security</a> <a class="post-tag btn btn-outline-primary" href="/tags/agents/">agents</a> <a class="post-tag btn btn-outline-primary" href="/tags/kubernetes/">kubernetes</a></div></section></div></aside></div><div class="row"><div id="tail-wrapper" class="col-12 col-lg-11 col-xl-9 px-md-4"><footer aria-label="Site Info" class=" d-flex flex-column justify-content-center text-muted flex-lg-row justify-content-lg-between align-items-lg-center pb-lg-3 " ><p>© <time>2026</time> <em class="fst-normal">Joey</em>. <span data-bs-toggle="tooltip" data-bs-placement="top" title="Except where otherwise noted, the blog posts on this site are licensed under the Creative Commons Attribution 4.0 International (CC BY 4.0) License by the author." >Some rights reserved.</span></p><p>Using the <a data-bs-toggle="tooltip" data-bs-placement="top" title="v7.6.0" href="https://github.com/cotes2020/jekyll-theme-chirpy" target="_blank" rel="noopener" >Chirpy</a> theme for <a href="https://jekyllrb.com" target="_blank" rel="noopener">Jekyll</a>.</p></footer></div></div><div id="search-result-wrapper" class="d-flex justify-content-center d-none"><div class="col-11 content"><div id="search-hints"><section><h2 class="panel-heading">Trending Tags</h2><div class="d-flex flex-wrap mt-3 mb-1 me-3"> <a class="post-tag btn btn-outline-primary" href="/tags/debugging/">debugging</a> <a class="post-tag btn btn-outline-primary" href="/tags/devops/">devops</a> <a class="post-tag btn btn-outline-primary" href="/tags/rails/">rails</a> <a class="post-tag btn btn-outline-primary" href="/tags/ai/">ai</a> <a class="post-tag btn btn-outline-primary" href="/tags/database/">database</a> <a class="post-tag btn btn-outline-primary" href="/tags/ruby/">ruby</a> <a class="post-tag btn btn-outline-primary" href="/tags/performance/">performance</a> <a class="post-tag btn btn-outline-primary" href="/tags/security/">security</a> <a class="post-tag btn btn-outline-primary" href="/tags/agents/">agents</a> <a class="post-tag btn btn-outline-primary" href="/tags/kubernetes/">kubernetes</a></div></section></div><div id="search-results" class="d-flex flex-wrap justify-content-center text-muted mt-3"></div></div></div></div><aside aria-label="Scroll to Top"> <button id="back-to-top" type="button" class="btn btn-lg btn-box-shadow"> <i class="fas fa-angle-up"></i> </button></aside></div><div id="mask" class="d-none position-fixed w-100 h-100 z-1"></div>
1<script> document.addEventListener('DOMContentLoaded', () => { SimpleJekyllSearch({ searchInput: document.getElementById('search-input'), resultsContainer: document.getElementById('search-results'), json: '/assets/js/data/search.json', searchResultTemplate: '<article class="px-1 px-sm-2 px-lg-4 px-xl-0"><header><h2><a href="{url}">{title}</a></h2><div class="post-meta d-flex flex-column flex-sm-row text-muted mt-1 mb-1"> {categories} {tags}</div></header><p>{content}</p></article>', noResultsText: '<p class="mt-5">Oops! No results found.</p>', templateMiddleware: function(prop, value, template) { if (prop === 'categories') { if (value === '') { return `${value}`; } else { return `<div class="me-sm-4"><i class="far fa-folder fa-fw"></i>${value}</div>`; } } if (prop === 'tags') { if (value === '') { return `${value}`; } else { return `<div><i class="fa fa-tag fa-fw"></i>${value}</div>`; } } } }); }); </script>
vendor: 1 bytes, line 1
1

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.