<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>younghoon — backend engineer</title>
  <subtitle>Notes from a backend engineer who designs complex systems with clarity. TypeScript, Go, and the Backend Service Playbook.</subtitle>
  <link href="https://kyhsa93.github.io/atom.xml" rel="self" />
  <link href="https://kyhsa93.github.io/" />
  <id>https://kyhsa93.github.io/</id>
  <updated>2026-08-08T00:00:00Z</updated>
  <author>
    <name>younghoon</name>
  </author>
  <entry>
    <title>The List That Broke Five Harnesses</title>
    <link href="https://kyhsa93.github.io/posts/the-list-that-broke-five-harnesses/" />
    <id>https://kyhsa93.github.io/posts/the-list-that-broke-five-harnesses/</id>
    <updated>2026-08-08T00:00:00Z</updated>
    <published>2026-08-08T00:00:00Z</published>
    <summary>Every Kubernetes anti-pattern checker in a five-check harness assumed `---`-separated documents. Naming more than one resource in a single `kubectl get -o yaml` call wraps the result in `kind: List` instead — and every checker silently found zero resources to flag, which looked identical to a clean pass.</summary>
    <category term="Kubernetes" />
    <category term="Tooling" />
  </entry>
  <entry>
    <title>Two Tools, the Same Missing Root</title>
    <link href="https://kyhsa93.github.io/posts/two-tools-the-same-missing-root/" />
    <id>https://kyhsa93.github.io/posts/two-tools-the-same-missing-root/</id>
    <updated>2026-08-08T00:00:00Z</updated>
    <published>2026-08-08T00:00:00Z</published>
    <summary>Argo CD&apos;s App-of-Apps proof lives entirely on the parent; Flux&apos;s dependsOn proof is declared by the child and unverifiable alone. Audit either tree without including its root, and both fail the same way — for what turns out to be the same underlying reason.</summary>
    <category term="Kubernetes" />
    <category term="GitOps" />
  </entry>
  <entry>
    <title>A Benchmark That Can Never Hit 100</title>
    <link href="https://kyhsa93.github.io/posts/a-benchmark-that-can-never-hit-100/" />
    <id>https://kyhsa93.github.io/posts/a-benchmark-that-can-never-hit-100/</id>
    <updated>2026-08-08T00:00:00Z</updated>
    <published>2026-08-08T00:00:00Z</published>
    <summary>A scoring harness covers nineteen categories of Kubernetes deployment mistake. One of them — drift — can only exist after a manifest has already been applied, which an authoring benchmark structurally cannot produce or avoid. The honest fix was a permanent, documented ceiling, not a future version.</summary>
    <category term="Kubernetes" />
    <category term="Benchmark" />
  </entry>
  <entry>
    <title>A Tied Score, Two Different Kinds of Wrong</title>
    <link href="https://kyhsa93.github.io/posts/a-tied-score-two-different-kinds-of-wrong/" />
    <id>https://kyhsa93.github.io/posts/a-tied-score-two-different-kinds-of-wrong/</id>
    <updated>2026-08-08T00:00:00Z</updated>
    <published>2026-08-08T00:00:00Z</published>
    <summary>Two models scored an identical 9/9 on a Kubernetes manifest-authoring task, independently reproduced. Reading what each one actually wrote found a self-defeating NetworkPolicy in one and a promotion pipeline referencing a resource that doesn&apos;t exist in the other — two unrelated defects invisible to a tied harness score.</summary>
    <category term="Kubernetes" />
    <category term="AI Agents" />
  </entry>
  <entry>
    <title>The Defaults Nobody Declared</title>
    <link href="https://kyhsa93.github.io/posts/the-defaults-nobody-declared/" />
    <id>https://kyhsa93.github.io/posts/the-defaults-nobody-declared/</id>
    <updated>2026-08-08T00:00:00Z</updated>
    <published>2026-08-08T00:00:00Z</published>
    <summary>A drift checker pointed at a cluster that had just been applied cleanly reported drift everywhere. The cluster wasn&apos;t lying — the API server&apos;s own admission defaulting had filled in fields Git never mentioned, and a naive full-object comparison had no way to tell the difference.</summary>
    <category term="Kubernetes" />
    <category term="Reliability" />
  </entry>
  <entry>
    <title>The Factory Knows Where to Put It</title>
    <link href="https://kyhsa93.github.io/posts/the-factory-knows-where-to-put-it/" />
    <id>https://kyhsa93.github.io/posts/the-factory-knows-where-to-put-it/</id>
    <updated>2026-08-08T00:00:00Z</updated>
    <published>2026-08-08T00:00:00Z</published>
    <summary>Two codebases generate an Aggregate&apos;s ID in two different places — one in the constructor, one via a Factory asking Infrastructure for it. Eric Evans&apos; own book has a specific, citable answer for which pattern it actually describes, and it isn&apos;t the one either codebase&apos;s convention assumes.</summary>
    <category term="DDD" />
    <category term="Comparative" />
  </entry>
  <entry>
    <title>A Rule Evans Never Wrote</title>
    <link href="https://kyhsa93.github.io/posts/a-rule-evans-never-wrote/" />
    <id>https://kyhsa93.github.io/posts/a-rule-evans-never-wrote/</id>
    <updated>2026-08-08T00:00:00Z</updated>
    <published>2026-08-08T00:00:00Z</published>
    <summary>Nearly every DDD codebase forbids referencing another Aggregate by direct object reference — ID only. Eric Evans&apos; 2003 book explicitly permits it. The person who actually wrote the ID-only rule, Vaughn Vernon, says so himself, in the same paper that argues for the stricter rule anyway.</summary>
    <category term="DDD" />
    <category term="Comparative" />
  </entry>
  <entry>
    <title>The Same Instant, Two Different Timestamps</title>
    <link href="https://kyhsa93.github.io/posts/the-same-instant-two-different-timestamps/" />
    <id>https://kyhsa93.github.io/posts/the-same-instant-two-different-timestamps/</id>
    <updated>2026-08-05T00:00:00Z</updated>
    <published>2026-08-05T00:00:00Z</published>
    <summary>The same moment, serialized by the same driver, produces a different string depending on the process&apos;s timezone. Four languages had this bug at the call site and one had it at the process boundary — and the fix belonged in a genuinely different place in each, verified by literally running the tests nine time zones apart.</summary>
    <category term="Backend" />
    <category term="Reliability" />
  </entry>
  <entry>
    <title>The Automation That Was Waiting on Itself</title>
    <link href="https://kyhsa93.github.io/posts/the-automation-that-was-waiting-on-itself/" />
    <id>https://kyhsa93.github.io/posts/the-automation-that-was-waiting-on-itself/</id>
    <updated>2026-08-04T00:00:00Z</updated>
    <published>2026-08-04T00:00:00Z</published>
    <summary>Every PR a Dependabot auto-merge workflow had ever merged did so by winning a race against its own six-hour deadlock — one of its steps was waiting for a check run that could only finish after that step did. Fixing it surfaced a second bug waiting right behind the first, and a class of half-merge left behind by plain GitHub 502s.</summary>
    <category term="Tooling" />
    <category term="Automation" />
  </entry>
  <entry>
    <title>The Image Nothing Noticed Couldn&apos;t Build</title>
    <link href="https://kyhsa93.github.io/posts/the-image-nothing-noticed-couldnt-build/" />
    <id>https://kyhsa93.github.io/posts/the-image-nothing-noticed-couldnt-build/</id>
    <updated>2026-08-04T00:00:00Z</updated>
    <published>2026-08-04T00:00:00Z</published>
    <summary>A Spring Boot 4 migration that checked git history instead of a stale doc, found a workaround for a library a search index insisted did not exist, and ended a day later with the deployable image unable to build — because nothing in CI was watching the file whose meaning had just changed.</summary>
    <category term="Architecture" />
    <category term="Tooling" />
  </entry>
  <entry>
    <title>Zero Findings, Eighty Bugs</title>
    <link href="https://kyhsa93.github.io/posts/zero-findings-eighty-bugs/" />
    <id>https://kyhsa93.github.io/posts/zero-findings-eighty-bugs/</id>
    <updated>2026-08-04T00:00:00Z</updated>
    <published>2026-08-04T00:00:00Z</published>
    <summary>A path-existence checker reported zero findings before and after a three-language audit round that fixed roughly eighty real issues — stale code quotes, an evaluator that grades itself a perfect score for scanning nothing, and a generator still emitting a bug already fixed in the code it was modeled on.</summary>
    <category term="Tooling" />
    <category term="Architecture" />
  </entry>
  <entry>
    <title>An End-to-End Test That Wasn&apos;t</title>
    <link href="https://kyhsa93.github.io/posts/an-end-to-end-test-that-wasnt/" />
    <id>https://kyhsa93.github.io/posts/an-end-to-end-test-that-wasnt/</id>
    <updated>2026-08-04T00:00:00Z</updated>
    <published>2026-08-04T00:00:00Z</published>
    <summary>NestJS&apos;s e2e suite assembled its own approximation of the app instead of booting the real one, and every language&apos;s LLM features had only ever run through their own fallback path. Fixing both surfaced a stranger bug: nock and testcontainers fighting over the same patched module.</summary>
    <category term="Testing" />
    <category term="Reliability" />
  </entry>
  <entry>
    <title>A Perfect Score, A Broken Feature</title>
    <link href="https://kyhsa93.github.io/posts/a-perfect-score-a-broken-feature/" />
    <id>https://kyhsa93.github.io/posts/a-perfect-score-a-broken-feature/</id>
    <updated>2026-07-28T00:00:00Z</updated>
    <published>2026-07-28T00:00:00Z</published>
    <summary>Same doc, same task, two models, run at the same time in separate worktrees. Both self-reported a perfect harness score. Only one of them, independently reproduced against real Postgres and LocalStack, actually worked.</summary>
    <category term="AI Agents" />
    <category term="Benchmark" />
  </entry>
  <entry>
    <title>The Bug Came Back, Wearing Five Different Masks</title>
    <link href="https://kyhsa93.github.io/posts/the-bug-came-back-wearing-five-different-masks/" />
    <id>https://kyhsa93.github.io/posts/the-bug-came-back-wearing-five-different-masks/</id>
    <updated>2026-07-28T00:00:00Z</updated>
    <published>2026-07-28T00:00:00Z</published>
    <summary>A week after a benchmark task exposed two languages that could not support a second event subscriber, four real features made every language need one. This time all five broke — from a loud boot-time crash to a silent single-handler drop nothing ever logged.</summary>
    <category term="Event-driven" />
    <category term="Reliability" />
  </entry>
  <entry>
    <title>Not Every Report Needs a Server</title>
    <link href="https://kyhsa93.github.io/posts/not-every-report-needs-a-server/" />
    <id>https://kyhsa93.github.io/posts/not-every-report-needs-a-server/</id>
    <updated>2026-07-27T00:00:00Z</updated>
    <published>2026-07-27T00:00:00Z</published>
    <summary>A monthly statement and a GDPR-style data export both died to the same question: couldn&apos;t the client just build this itself? The spending-analysis ETL that survived it, and the rule it revealed.</summary>
    <category term="ETL" />
    <category term="Architecture" />
  </entry>
  <entry>
    <title>The Fraud Signal That Trusted the Fraudster</title>
    <link href="https://kyhsa93.github.io/posts/the-fraud-signal-that-trusted-the-fraudster/" />
    <id>https://kyhsa93.github.io/posts/the-fraud-signal-that-trusted-the-fraudster/</id>
    <updated>2026-07-26T00:00:00Z</updated>
    <published>2026-07-26T00:00:00Z</published>
    <summary>RefundReasonClassifier&apos;s fraud-risk score was computed entirely from text the refund requester controlled. Removing it, the sibling ML scorer that went with it, and the one rule the removal left behind.</summary>
    <category term="Security" />
    <category term="LLM" />
  </entry>
  <entry>
    <title>Narrow What, Never Who</title>
    <link href="https://kyhsa93.github.io/posts/narrow-what-never-who/" />
    <id>https://kyhsa93.github.io/posts/narrow-what-never-who/</id>
    <updated>2026-07-26T00:00:00Z</updated>
    <published>2026-07-26T00:00:00Z</published>
    <summary>A structured-data RAG feature over an account&apos;s own transaction history, the guardrail that lets an LLM touch it safely, and how the same invariant survived five different languages&apos; own conventions.</summary>
    <category term="LLM" />
    <category term="Comparative" />
  </entry>
  <entry>
    <title>The Bugs Unit Tests Can&apos;t See</title>
    <link href="https://kyhsa93.github.io/posts/bugs-only-e2e-tests-catch/" />
    <id>https://kyhsa93.github.io/posts/bugs-only-e2e-tests-catch/</id>
    <updated>2026-07-24T00:00:00Z</updated>
    <published>2026-07-24T00:00:00Z</published>
    <summary>A missing @Transactional, a JDK HTTP client retry quirk, a VARCHAR(36) overflow, an SQS FIFO dedup collision — four real bugs that needed real infrastructure to even exist.</summary>
    <category term="Testing" />
    <category term="Reliability" />
  </entry>
  <entry>
    <title>Wiring an LLM Into a Domain Service</title>
    <link href="https://kyhsa93.github.io/posts/llm-technical-service/" />
    <id>https://kyhsa93.github.io/posts/llm-technical-service/</id>
    <updated>2026-07-23T00:00:00Z</updated>
    <published>2026-07-23T00:00:00Z</published>
    <summary>RefundReasonClassifier reads a refund reason and hands back a signal — the Domain Service that actually decides never calls it, and swapping the LLM backend from Claude to self-hosted Ollama touched almost no test.</summary>
    <category term="LLM" />
    <category term="Architecture" />
  </entry>
  <entry>
    <title>A Second Fraud Signal: Scoring History, Not Reading It</title>
    <link href="https://kyhsa93.github.io/posts/refund-fraud-risk-scorer/" />
    <id>https://kyhsa93.github.io/posts/refund-fraud-risk-scorer/</id>
    <updated>2026-07-23T00:00:00Z</updated>
    <published>2026-07-23T00:00:00Z</published>
    <summary>RefundFraudRiskScorer is a hand-rolled logistic regression trained on refund history, swappable between a native and an HTTP implementation, feeding the same Domain Service a second independent threshold.</summary>
    <category term="Machine Learning" />
    <category term="Architecture" />
  </entry>
  <entry>
    <title>Designing Aggregates: Transaction Boundaries and Invariants</title>
    <link href="https://kyhsa93.github.io/posts/aggregate-design/" />
    <id>https://kyhsa93.github.io/posts/aggregate-design/</id>
    <updated>2026-07-22T00:00:00Z</updated>
    <published>2026-07-22T00:00:00Z</published>
    <summary>What actually decides an Aggregate boundary, and how the Domain layer generates its own ID.</summary>
    <category term="DDD" />
    <category term="Tactical Design" />
  </entry>
  <entry>
    <title>Request-Scoped Context: Why req.user Is an Anti-Pattern</title>
    <link href="https://kyhsa93.github.io/posts/request-scoped-user-context/" />
    <id>https://kyhsa93.github.io/posts/request-scoped-user-context/</id>
    <updated>2026-07-22T00:00:00Z</updated>
    <published>2026-07-22T00:00:00Z</published>
    <summary>An AsyncLocalStorage-based UserContextStore, and the Guard/Interceptor split it took to get there.</summary>
    <category term="Cross-cutting Concerns" />
    <category term="Backend" />
  </entry>
  <entry>
    <title>Observability Is a Design Decision, Not an Afterthought</title>
    <link href="https://kyhsa93.github.io/posts/observability-by-design/" />
    <id>https://kyhsa93.github.io/posts/observability-by-design/</id>
    <updated>2026-07-22T00:00:00Z</updated>
    <published>2026-07-22T00:00:00Z</published>
    <summary>Log-level policy, structured logging, and propagating a Correlation ID through AsyncLocalStorage.</summary>
    <category term="Observability" />
    <category term="Operations" />
  </entry>
  <entry>
    <title>Compliance as Code: Building a Harness That Enforces Architecture</title>
    <link href="https://kyhsa93.github.io/posts/compliance-as-code/" />
    <id>https://kyhsa93.github.io/posts/compliance-as-code/</id>
    <updated>2026-07-22T00:00:00Z</updated>
    <published>2026-07-22T00:00:00Z</published>
    <summary>What a harness rule is and is not allowed to assume, and the failure modes even careful audits miss.</summary>
    <category term="Tooling" />
    <category term="Architecture" />
  </entry>
  <entry>
    <title>Five Bugs Nobody Was Looking For</title>
    <link href="https://kyhsa93.github.io/posts/five-bugs-nobody-was-looking-for/" />
    <id>https://kyhsa93.github.io/posts/five-bugs-nobody-was-looking-for/</id>
    <updated>2026-07-22T00:00:00Z</updated>
    <published>2026-07-22T00:00:00Z</published>
    <summary>Completing incomplete Swagger docs across five languages, verified by actually booting each app instead of trusting the annotations compiled. What it found had nothing to do with documentation — including a Spring Boot 4 dependency split that left production migrations silently never running.</summary>
    <category term="API Design" />
    <category term="Testing" />
  </entry>
  <entry>
    <title>The Naming Rule That Caught Real Bugs</title>
    <link href="https://kyhsa93.github.io/posts/repository-naming-convention/" />
    <id>https://kyhsa93.github.io/posts/repository-naming-convention/</id>
    <updated>2026-07-21T00:00:00Z</updated>
    <published>2026-07-21T00:00:00Z</published>
    <summary>How a boring find/save/delete naming convention, once automated, immediately found violations nobody had noticed across four different codebases.</summary>
    <category term="Repository Pattern" />
    <category term="Conventions" />
  </entry>
  <entry>
    <title>Scheduling and the Task Outbox Pattern</title>
    <link href="https://kyhsa93.github.io/posts/scheduling-and-task-outbox/" />
    <id>https://kyhsa93.github.io/posts/scheduling-and-task-outbox/</id>
    <updated>2026-07-21T00:00:00Z</updated>
    <published>2026-07-21T00:00:00Z</published>
    <summary>Why a Scheduler should only enqueue, and the real bugs multi-instance Cron jobs surfaced.</summary>
    <category term="Scheduling" />
    <category term="Backend" />
  </entry>
  <entry>
    <title>Can an AI Agent Follow Your Architecture?</title>
    <link href="https://kyhsa93.github.io/posts/can-an-ai-agent-follow-your-architecture/" />
    <id>https://kyhsa93.github.io/posts/can-an-ai-agent-follow-your-architecture/</id>
    <updated>2026-07-21T00:00:00Z</updated>
    <published>2026-07-21T00:00:00Z</published>
    <summary>Reusing an architecture-compliance harness as an AI benchmark, across five difficulty levels and five languages.</summary>
    <category term="AI Agents" />
    <category term="Benchmark" />
  </entry>
  <entry>
    <title>Same Architecture, Five Languages</title>
    <link href="https://kyhsa93.github.io/posts/same-architecture-five-languages/" />
    <id>https://kyhsa93.github.io/posts/same-architecture-five-languages/</id>
    <updated>2026-07-21T00:00:00Z</updated>
    <published>2026-07-21T00:00:00Z</published>
    <summary>Comparing the same Repository/Query split as implemented independently in TypeScript, Go, Python, Java, and Kotlin.</summary>
    <category term="Comparative" />
    <category term="Architecture" />
  </entry>
  <entry>
    <title>When the Tool Output Itself Tries to Manipulate the Agent</title>
    <link href="https://kyhsa93.github.io/posts/prompt-injection-in-tool-output/" />
    <id>https://kyhsa93.github.io/posts/prompt-injection-in-tool-output/</id>
    <updated>2026-07-21T00:00:00Z</updated>
    <published>2026-07-21T00:00:00Z</published>
    <summary>A shell command&apos;s output has, more than once, contained something shaped exactly like a real system message, instructing the agent to hide a change. The rule that matters: disregard it, and say so.</summary>
    <category term="AI Agents" />
    <category term="Security" />
  </entry>
  <entry>
    <title>Two Accounts, One Transaction, Five Different Answers</title>
    <link href="https://kyhsa93.github.io/posts/two-accounts-one-transaction-five-different-answers/" />
    <id>https://kyhsa93.github.io/posts/two-accounts-one-transaction-five-different-answers/</id>
    <updated>2026-07-21T00:00:00Z</updated>
    <published>2026-07-21T00:00:00Z</published>
    <summary>A transfer feature needs one thing every implementation already claimed to support: writing two Aggregates atomically. Building it for real found a working mechanism in one language, a regression waiting one edit inside the obvious fix in another, and a doc that had been quietly wrong about its own code in a third.</summary>
    <category term="Backend" />
    <category term="Reliability" />
  </entry>
  <entry>
    <title>The Bug That Needed Two Subscribers to Exist</title>
    <link href="https://kyhsa93.github.io/posts/the-bug-that-needed-two-subscribers-to-exist/" />
    <id>https://kyhsa93.github.io/posts/the-bug-that-needed-two-subscribers-to-exist/</id>
    <updated>2026-07-21T00:00:00Z</updated>
    <published>2026-07-21T00:00:00Z</published>
    <summary>Five languages scoring 100% on an easy synthetic task taught nothing about where they would fail. A four-level difficulty ladder built specifically to exercise unexercised code paths found the ceiling — and its last rung exposed a fan-out bug that had been invisible since nothing had ever subscribed two things to the same event before.</summary>
    <category term="AI Agents" />
    <category term="Benchmark" />
  </entry>
  <entry>
    <title>The Doc Said &quot;Done.&quot; Half of It Wasn&apos;t.</title>
    <link href="https://kyhsa93.github.io/posts/the-doc-said-done-half-of-it-wasnt/" />
    <id>https://kyhsa93.github.io/posts/the-doc-said-done-half-of-it-wasnt/</id>
    <updated>2026-07-20T00:00:00Z</updated>
    <published>2026-07-20T00:00:00Z</published>
    <summary>A repository-naming fix that only reached the write-side interface, four rounds of turning that gap into permanent harness rules, and a yield curve — three or four real bugs per round, then two, then zero — that was itself the most useful result.</summary>
    <category term="Conventions" />
    <category term="Tooling" />
  </entry>
  <entry>
    <title>How to Find Domain Boundaries</title>
    <link href="https://kyhsa93.github.io/posts/finding-domain-boundaries/" />
    <id>https://kyhsa93.github.io/posts/finding-domain-boundaries/</id>
    <updated>2026-07-19T00:00:00Z</updated>
    <published>2026-07-19T00:00:00Z</published>
    <summary>A record of the thought process for organizing complex requirements into Aggregates and Bounded Contexts.</summary>
    <category term="DDD" />
    <category term="Architecture" />
  </entry>
  <entry>
    <title>Reliability in Event-Driven Systems</title>
    <link href="https://kyhsa93.github.io/posts/reliable-event-driven-systems/" />
    <id>https://kyhsa93.github.io/posts/reliable-event-driven-systems/</id>
    <updated>2026-07-19T00:00:00Z</updated>
    <published>2026-07-19T00:00:00Z</published>
    <summary>Practical patterns for handling message delivery failures and duplicate processing.</summary>
    <category term="Event-driven" />
    <category term="Backend" />
  </entry>
  <entry>
    <title>Developer Experience in Containerized Environments</title>
    <link href="https://kyhsa93.github.io/posts/containerized-development-experience/" />
    <id>https://kyhsa93.github.io/posts/containerized-development-experience/</id>
    <updated>2026-07-19T00:00:00Z</updated>
    <published>2026-07-19T00:00:00Z</published>
    <summary>How teams can build a reproducible environment from local development through deployment.</summary>
    <category term="Docker" />
    <category term="Developer experience" />
  </entry>
  <entry>
    <title>Domain Services: When a Rule Doesn&apos;t Belong to One Aggregate</title>
    <link href="https://kyhsa93.github.io/posts/domain-services-across-aggregates/" />
    <id>https://kyhsa93.github.io/posts/domain-services-across-aggregates/</id>
    <updated>2026-07-18T00:00:00Z</updated>
    <published>2026-07-18T00:00:00Z</published>
    <summary>A real RefundEligibilityService example for logic that has to read two Aggregates at once.</summary>
    <category term="DDD" />
    <category term="Tactical Design" />
  </entry>
  <entry>
    <title>A Path-Existence Checker Found a Real Bug on Day One</title>
    <link href="https://kyhsa93.github.io/posts/a-path-existence-checker-found-a-real-bug-on-day-one/" />
    <id>https://kyhsa93.github.io/posts/a-path-existence-checker-found-a-real-bug-on-day-one/</id>
    <updated>2026-07-18T00:00:00Z</updated>
    <published>2026-07-18T00:00:00Z</published>
    <summary>No parsing, no understanding of what a code snippet does — just comparing backtick-quoted paths against the real file tree. The exclusion rules that kept it from crying wolf mattered more than the two-pattern check itself, and it still caught a real bug in four docs on its first run.</summary>
    <category term="Tooling" />
    <category term="Documentation" />
  </entry>
  <entry>
    <title>From Docs to Runnable Code in One Command</title>
    <link href="https://kyhsa93.github.io/posts/from-docs-to-runnable-code/" />
    <id>https://kyhsa93.github.io/posts/from-docs-to-runnable-code/</id>
    <updated>2026-07-17T00:00:00Z</updated>
    <published>2026-07-17T00:00:00Z</published>
    <summary>Turning a written reference template into a scaffolding generator, and the bugs found by actually running it.</summary>
    <category term="Tooling" />
    <category term="Developer Experience" />
  </entry>
  <entry>
    <title>The Harness Had Never Met a Second Domain</title>
    <link href="https://kyhsa93.github.io/posts/the-harness-had-never-met-a-second-domain/" />
    <id>https://kyhsa93.github.io/posts/the-harness-had-never-met-a-second-domain/</id>
    <updated>2026-07-17T00:00:00Z</updated>
    <published>2026-07-17T00:00:00Z</published>
    <summary>Two harness rules had checked out clean for months — because every domain that ever fed them was Account or Card. Building a genuinely unrelated third domain surfaced two false positives, and confirmed the rule meant to catch a real mistake still did.</summary>
    <category term="Tooling" />
    <category term="Testing" />
  </entry>
  <entry>
    <title>Signing In Without a Password</title>
    <link href="https://kyhsa93.github.io/posts/auth-bypass-vulnerability/" />
    <id>https://kyhsa93.github.io/posts/auth-bypass-vulnerability/</id>
    <updated>2026-07-16T00:00:00Z</updated>
    <published>2026-07-16T00:00:00Z</published>
    <summary>A security audit found /auth/sign-in accepted a userId and nothing else — how the same bug showed up in five languages, and the JDK retry bug a new 401 test uncovered along the way.</summary>
    <category term="Security" />
    <category term="Backend" />
  </entry>
  <entry>
    <title>CQRS in Practice: Why a Query Can&apos;t Use a Repository</title>
    <link href="https://kyhsa93.github.io/posts/cqrs-in-practice/" />
    <id>https://kyhsa93.github.io/posts/cqrs-in-practice/</id>
    <updated>2026-07-12T00:00:00Z</updated>
    <published>2026-07-12T00:00:00Z</published>
    <summary>A real cross-language bug where a Query Handler used a write-capable Repository — and the docs agreed it was fine.</summary>
    <category term="CQRS" />
    <category term="Architecture" />
  </entry>
  <entry>
    <title>When the Docs and the Code Agree to Be Wrong</title>
    <link href="https://kyhsa93.github.io/posts/when-the-docs-and-the-code-agree-to-be-wrong/" />
    <id>https://kyhsa93.github.io/posts/when-the-docs-and-the-code-agree-to-be-wrong/</id>
    <updated>2026-07-12T00:00:00Z</updated>
    <published>2026-07-12T00:00:00Z</published>
    <summary>Three violations across five languages — a Query reading a write Repository, a domain class carrying JPA, a notification module in the wrong layer. Only one was actually a bug, and the other two reveal why dozens of prior audits never caught any of it.</summary>
    <category term="DDD" />
    <category term="Architecture" />
  </entry>
  <entry>
    <title>Talking Across Bounded Contexts</title>
    <link href="https://kyhsa93.github.io/posts/talking-across-bounded-contexts/" />
    <id>https://kyhsa93.github.io/posts/talking-across-bounded-contexts/</id>
    <updated>2026-07-11T00:00:00Z</updated>
    <published>2026-07-11T00:00:00Z</published>
    <summary>Choosing between a synchronous Adapter and an asynchronous Integration Event, with a real compensating-transaction example.</summary>
    <category term="DDD" />
    <category term="Integration" />
  </entry>
  <entry>
    <title>Graceful Shutdown: The Reliability Feature Nobody Tests</title>
    <link href="https://kyhsa93.github.io/posts/graceful-shutdown/" />
    <id>https://kyhsa93.github.io/posts/graceful-shutdown/</id>
    <updated>2026-07-11T00:00:00Z</updated>
    <published>2026-07-11T00:00:00Z</published>
    <summary>Getting the order right between readiness, in-flight requests, and resource cleanup during SIGTERM.</summary>
    <category term="Reliability" />
    <category term="Operations" />
  </entry>
  <entry>
    <title>Typed Errors and a Consistent Response Schema</title>
    <link href="https://kyhsa93.github.io/posts/typed-errors-and-response-schemas/" />
    <id>https://kyhsa93.github.io/posts/typed-errors-and-response-schemas/</id>
    <updated>2026-07-11T00:00:00Z</updated>
    <published>2026-07-11T00:00:00Z</published>
    <summary>Why an error-message enum key has to equal its value, and the four-field error response shape.</summary>
    <category term="API Design" />
    <category term="Conventions" />
  </entry>
</feed>
