← Back to Portfolio
Download

Hyeonjun Kil

Backend Engineer / Platform Part Leader
Flex — Constraint-Explicit Work Planner2026.07 — Present · Sole designer, implementer, and verifier · Personal
Deterministic monthly allocator · per-date constraints · Python/React verification

A local-first work planner that combines recognized load, actual work, leave, and daily/weekly caps into one deterministic allocation contract, exposing infeasible targets as explicit gaps instead of forced over-allocation.

PythonReactTypeScriptFastAPIPlaywrightProperty TestingGitHub Actions
Flex — Constraint-Explicit Work Planner architecture
Expose an infeasible target as a gap
When a synthetic monthly target exceeds remaining daily and weekly capacity, the planner preserves those caps and returns insufficient_slots with the remaining gap.
Performance MetricsBeforeAfter
Infeasible stateRisk of forced allocationinsufficient_slots + gap (hard limits preserved)
Date-change scopeRisk of full-month overwritefixed date + remainder redistribution (preview and redistribution boundary)

Problem Solving

Forced allocation above remaining capacity would hide an infeasible plan
Apply daily/weekly caps and fixed plans first, compute allocatable time, then return the remaining gap as an explicit state
→ Preserves hard limits while displaying insufficient_slots and the remaining gap
A date override could unexpectedly overwrite the whole monthly plan
Lock the selected date first, preview conflicts, then deterministically redistribute only the remainder
→ Shows change scope and conflict boundaries in preview without external writes

Tech Decisions

  • Restored the existing _minimum_activation flow so minimum work remains a selective activation floor rather than a mandatory seed
  • Kept the decision surface reproducible through URL/local state without adding external-system integration

Highlights

  • One allocator contract for fixed-plan priority, selective minimum activation, and hard-limit preservation
  • Infeasibility exposed as a remaining gap and reason
  • Date-override preview and redistribution calculation for remaining dates
  • Synthetic scenarios, public-boundary scan, and Python/Playwright CI

Lessons Learned

  • A planner must model infeasibility before optimizing, or it will distort reality.
  • User overrides remain predictable when the fixed scope is separated from redistribution of the remainder.

A Public Launcher for Isolated, Verified AI CLI Runtimes2026.04 — Present · Sole designer, implementer, and operator · Personal
Public launcher · 3 AI CLIs · contract demo

A public launcher that isolates global Claude Code, Codex, and Kiro state into project-scoped boundaries and blocks invalid workspaces or configuration drift before startup.

A Public Launcher for Isolated, Verified AI CLI Runtimes architecture
Performance MetricsBeforeAfter
Runtime isolationProjects shared global CLI stateRuntime homes per registered project (Sessions, skills, MCP tools, and policy stay boundary-scoped)
Boundary resolutionRisk of profile inference from names or remotesOne owning boundary from the canonical path (Outside, escaped, or ambiguous paths stop before AI CLI startup)
Public verificationEvidence depended on a private environmentPublic launcher + contract demo + CI (Core contracts and failure behavior reproduce without login)

Problem Solving

Sharing one global AI CLI home across projects could mix sessions, tools, and rules across trust boundaries.
Generated Codex and Kiro runtime homes per registered project and routed profile commands and harness-exec through the same execution policy.
→ Runtime state stays project-scoped, with installation, profile, and runtime behavior verified in the public repository suite.
A workspace manager that guessed profiles from names or remotes could start an agent with the wrong tools and permissions.
Made harness-auto canonicalize the current path and select only the single most-specific registered boundary, rejecting outside paths, symlink escapes, and equally specific duplicates.
→ Profile selection is based on path ownership rather than inference, and no AI CLI starts when ownership is unresolved.
A private operating environment alone did not let visitors independently verify profile isolation and source-verification contracts.
Linked the public harness-launcher implementation and tests to a separate public contract demo. The demo checks profile uniqueness, path escape, source SHA-256 drift, and relationship integrity with the standard library.
→ The core boundaries and failure behavior are reproducible from README, source, and CI without login, while private company data and production indexes remain outside public evidence.

Concert Reservation Service2024.10 — 2024.11 · Personal
Configured 3,000 requests/s · 2,400 max VUs · observed reservation error rate 0.64% · Prometheus+Grafana

Concert reservation project that verifies same-seat booking and wallet payment with optimistic and Redisson locks, then reduces cache-stampede p95 from 5.74s to 676ms through cache warming and TTL changes in the public load-test report

JavaSpring BootJPARedisMySQLKafkaDockerK6
Concert Reservation Service architecture
Performance MetricsBeforeAfter
Reservation p955.74s676ms (cache warming + TTL 2m→5m)
Reservation error rate-0.64% (394 failures in the reservation scenario)
Queue p95-62.5ms (0% error rate in the queue scenario)

Problem Solving

Duplicate-reservation risk when 100 threads target the same seat
Exercised the conflict path with ConcertSeat @Version optimistic locking and a 100-thread Spring integration test
→ Assertions confirm one reservation row and the reserved state after the test
Balance integrity corruption under concurrent point charging and payments
Serialized per-user charge and payment paths with a Redisson distributed lock (userWalletLock:{userId})
→ A 100-thread charge test compares the final balance with the expected sum, while the payment test checks a single payment state
Observed a cache stampede and p95 5.74s latency during the reservation load test
Applied cache warming three minutes before reservations and changed TTL from two to five minutes
→ Public report records reservation p95 5.74s → 676ms, within its configured 1s SLO
Payment-event persistence, publication, and failed-event retry states needed separate boundaries
Kafka Transactional Outbox stores a PENDING outbox_event within the payment transaction, then a scheduler publishes it asynchronously
→ Separated PENDING outbox creation from publication-failure state and retry paths in code and tests

Tech Decisions

  • @Version optimistic locking for seats: a 100-thread same-seat integration test asserts one reservation row
  • Per-user Redisson locking for payment and charging: 100-thread tests compare payment state and final balance with expected values
  • Redis Sorted Set queue: scores track entry order and expiry state
  • Create a PENDING outbox record in the payment transaction, then let the scheduler manage publication-failure and retry paths

Highlights

  • One reservation row after a 100-thread same-seat integration test
  • Per-user Redisson serialization for wallet and payment paths
  • Public-report p95 5.74s → 676ms after cache warming and TTL changes
  • PENDING outbox in the payment transaction plus scheduler publication and retry paths
  • Configured 3,000 requests/s and 2,400 max VUs kept separate from observed outcomes

Lessons Learned

  • Separated optimistic locking for same-seat contention from per-user distributed locking for wallet contention
  • Kept configured k6 rate and max VUs distinct from observations reported by the load test

Family Budget — A Shared Household Budget for Daily Entry and Month-End Close2026.08 — Present · Personal product · owned product design, backend, data model, automation, and responsive UX end to end · Personal

A shared household budget that turns daily income and expense entry, joint and individual ownership, purpose accounts, and recurring plans into one month-end decision.

TypeScriptNext.jsReactVitestVercel
Implemented Family Budget month-end dashboard with synthetic data
Implemented canonical UI · synthetic data · Family Budget month-end decision
Operational product architecture where household members and an approval-gated assistant reach the ledger through an authenticated API while the historical spreadsheet and synthetic public demo remain separate
Core system designBeforeAfter
Operational source of truthSpreadsheet-led entry and interpretationApplication-owned writes (Historical sheets remain a read-only import boundary)
Plan ≠ actualExpected rules confused with actual income and spendRule · occurrence · actual separation (Expected, actual, and variance stay independently traceable)
Duplicate and ambiguity controlRisk of creating a new actual despite an existing candidateLink first · confirm · read back (Partial success and reopen remain explicit)

Key problem solving

Treating planned items as actual ledger events would duplicate income and spend and erase explainable monthly variance.
→ The dashboard derives expected, actual, and variance independently while preserving the contract that a plan is not an actual transaction.
Additional Backend Projects
Gamebang — Server-Authoritative Realtime Game Room(Personal)— TypeScript, React, WebSocket, Cloudflare WorkersDetail ↗

A five-game realtime service where mobile clients request actions and a room-scoped Durable Object owns phase, turn, hidden information, and reconnect behavior.

Clinical-Lab Job Decision Dashboard(Personal)— Python, FastAPI, SQLite, ReactDetail ↗

A mobile-first dashboard that normalizes job-platform and hospital-career-page sources, explains deadline/region/employment recommendations, and keeps account-scoped application state.

Daesin Logistics Dispatch Operations Ledger(Personal)— TypeScript, Express, Next.js, ReactDetail ↗

A current-day dispatch ledger for route, vehicle, and statistics views, with singleton collection ownership and a fixed browser data boundary

NyamNyam WeDu — Cafeteria Menu Alert Bot(Personal)— TypeScript, Playwright, Slack Bot API, ExpressDetail ↗

Bot that crawls weekly cafeteria menus from Kakao Channel via Playwright and auto-delivers to Slack — Clean Architecture + TSyringe DI, Slack Bot API slash command, up to 6 retries, DeliveryHistory duplicate prevention

StartupPool(Team)— NestJS, TypeScript, PostgreSQL, JavaScriptDetail ↗

Backend developer in 8-member cross-functional team building a startup vertical network platform — designed and implemented core community APIs on NestJS, integrated 4 OAuth 2.0 social login providers, built independent admin backend across 2-month sprints