황준혁 포트폴리오 — AI Native Problem Solver

HWANG JUNHYEOK · PORTFOLIO 2026

PORTFOLIO

사용자가 겪는 문제를 실제 제품에서 작동하는 기능으로 풀고, AI 실행과 검증 조건을 설계합니다.

CONTACT

justn.hyeok@gmail.comjustn.hyeok@gmail.com

WEB

justn.mejustn.me

GITHUB

justn-hyeokjustn-hyeok

LINKEDIN

justn-hyeokjustn-hyeok

황준혁 사진

안녕하세요

황준혁입니다.

HWANG JUNHYEOK · JUSTN

AI Native Problem Solver

학력

2024.03 - 2027.01

부산소프트웨어마이스터고 소프트웨어개발과 졸업 예정

자격

2025.07 정보처리산업기사

2026.03 SQL 개발자 (SQLD)

2026.04 리눅스마스터 2급

다루는 영역

AI-native 제품 개발

사용자 문제를 화면·API·AI 기능으로 구현하고 실패와 검증 조건까지 제품에 연결합니다. 개발 과정에서도 agent가 반환한 코드와 실행 결과를 다시 확인합니다.

기반 역량 · Frontend

TypeScript·React·Next.js로 사용자 흐름을 구현합니다. 입력과 제출, 편집 상태와 복원이 일치하도록 조건을 정합니다.

2/21

목차

입력과 복구에서 AI 실행·검증까지 확장합니다.

01

제품 구현의 기반

Maru의 입력 · 제출과 자갈치의 저장 · 복원

02

AI 기능의 실행과 결과 검증

brgr의 워커 결과 승인과 적용

03

개인 제품

라피 · Watchdog · justn.me의 확인된 취소 · 안전한 개입 · 즉시 반영

04

협업과 의사결정

자갈치의 리뷰 기준 정리

05

조직 운영

제품 팀과 공개 프로젝트 조직의 서로 다른 책임

06

오픈소스 기여

React Flow · Gajae Code의 문제 재현과 공개 반영

3/21
Maru 로고

부산소프트웨어마이스터고 입학 전형 서비스

Maru

입학전형 지원서에서 늦게 온 임시저장 응답이 사진 값을 덮어쓰던 race와 검정고시 원서 제출 400을 수정했습니다. 화면에 보이는 값과 전송 데이터가 어긋나는 두 문제입니다.

Maru 원서 작성 화면

#입학 전형 서비스 #Frontend · DX

기간

2025.04 – 2026.03

GitHub

저장소 보기저장소 보기

기여

01 사진 값 덮어쓰기 race 수정

02 검정고시 원서 제출 400 해결

기술

Next.js · React · TypeScript · Recoil · TanStack Query

4/21

Maru · 입학전형 지원서

사진을 올렸는데 다음 단계가 열리지 않았습니다

상황

증명사진을 올려 화면에 보이는데도 '다음' 단계 검증이 실패할 수 있었습니다.

원인

사진 값이 반영된 뒤 늦게 도착한 임시저장 응답이 사진 값을 빈 값으로 덮어썼습니다.

해결

다음 단계 버튼을 누른 시점의 이미지와 업로드 주소를 함께 읽어 진입 조건을 판단하도록 바꿨습니다.

결과

늦은 응답 순서에서 '다음' 막힘 100% → 0%.

근거 · PR #268 · 사진 값 덮어쓰기 race ↗근거 · PR #268 · 사진 값 덮어쓰기 race ↗

다음 단계 검증 기준

2개 상태

보이는 이미지와 업로드 주소를 같은 시점에 확인합니다.

이미지 미리보기

READY

AND

업로드 URL

READY

두 값이 모두 준비되면

다음 단계 진입 조건 충족

구현 조건

image && (downloadUrl || uploadUrl)

5/21

Maru · 전형별 입력

검정고시 지원자의 원서 제출이 400으로 거절됐습니다

상황

검정고시를 선택하면 학교 입력 항목이 사라지는데, 제출하면 서버가 거절했습니다.

원인

숨긴 학교 칸이 빈 값이나 이전에 입력한 값 그대로 전송됐고 빈 schoolCode는 서버의 7자 검사에 걸렸습니다.

해결

제출 직전에 graduationType을 확인하고 학교 관련 7개 필드를 null로 만들었습니다.

결과

검정고시 지원서도 정상 제출되고 숨긴 학교 7개 필드는 값 대신 null로 전송됩니다.

근거 · PR #287 · 학교 정보 7개 제거 ↗근거 · PR #287 · 학교 정보 7개 제거 ↗

직접 해 보기 →직접 해 보기 →

BEFORE · 화면만 변경

학교 정보는 숨겨졌지만

제출값에는 빈 값이 남았습니다.

서버는 빈 schoolCode를 400으로 거절했습니다.

AFTER · 제출값도 변경

지원 유형을 다시 확인하고

학교 관련 7개 값을 비웠습니다.

검정고시 전형에서는 학교 관련 값을 비웁니다.

결과

보이는 조건과 보내는 조건을 하나의 기준으로 맞췄습니다.

6/21
자갈치 로고

개발자 학습 경로를 만드는 노드 편집기

자갈치

노드와 선으로 학습 경로를 만들고 공유하는 6인 팀 프로젝트입니다. 학습 경로 편집기의 상태·저장·복구 구현을 맡았습니다.

자갈치 로드맵 편집기 화면

#FE Lead · PM

기간

2025.12 – 2026.05

GitHub

저장소 보기저장소 보기

기여

01 변경 빈도와 역할에 따른 상태 분리

02 노드·선의 통합 실행 취소와 복원

03 실행 취소 깨짐 59.9% → 0%

04 손상 항목만 제외하는 부분 복구

05 복사한 노드의 ID와 연결 관계 갱신

기술

Next.js · React · TypeScript · Jotai · React Flow

7/21

자갈치 · 노드 편집기

실행 취소가 노드와 선을 서로 다른 시점으로 돌렸습니다

상황

노드와 선을 함께 바꾸고 실행 취소도 그래프 전체를 한 시점으로 복원해야 했습니다.

원인

노드와 선의 기록을 따로 관리해, 한 번의 실행 취소에서 서로 다른 시점이 선택됐습니다.

해결

독립적으로 바뀌는 상태는 나누고 실행 취소에서 함께 돌아가야 하는 노드와 선은 하나의 편집 이력으로 묶었습니다.

결과

실행 취소·다시 실행 시 노드와 연결선이 같은 편집 시점으로 복원됩니다. 무작위 편집 1,000회 기준 깨짐 59.9% → 0%.

근거 · PR #120 · 통합 편집 이력 ↗근거 · PR #120 · 통합 편집 이력 ↗

이전 구조

노드

선

t-1

t-2

서로 다른 시점

통합 후

실행 취소

EditorState

{ nodes, edges } snapshot

결과

한 번의 실행 취소가 하나의 그래프를 복원합니다.

8/21

자갈치 · 로드맵 저장

자동 저장 한 번에 다른 로드맵이 지워졌습니다

상황

텍스트 상자나 섹션이 든 로드맵이 하나라도 있으면, 자동 저장할 때 저장돼 있던 다른 로드맵이 사라졌습니다.

원인

저장할 때마다 목록 전체를 한 번에 검사했고 이름 칸이 없는 게 정상인 텍스트 상자·섹션이 규칙 위반으로 걸렸습니다. 검사에 실패하면 목록을 빈 것으로 보고 덮어썼습니다.

해결

로드맵을 하나씩 검사해 깨진 것만 건너뛰고 텍스트 상자·섹션은 label 없이도 통과하게 규칙을 바로잡았습니다.

결과

저장할 때 다른 로드맵이 사라지는 비율 100% → 0% (무작위 저장 1,000회).

근거 · PR #172 · 항목별 검증 ↗근거 · PR #172 · 항목별 검증 ↗

직접 해 보기 →직접 해 보기 →

BEFORE · 목록 전체 검사

하나라도 검사에 걸리면

목록 전체를 버렸습니다.

지금 로드맵 하나만 남기고 덮어썼습니다.

AFTER · 로드맵마다 검사

깨진 항목만 건너뛰고

나머지는 그대로 남깁니다.

텍스트 상자·섹션은 이름 없이도 통과합니다.

결과

다른 로드맵 손실 100% → 0% (1,000회)

9/21

brgr

코딩 에이전트 오케스트레이터

brgr

Codex나 Claude Code가 다른 코딩 에이전트에게 일을 넘기고, 각 워커가 옆 Herdr 패인에서 프롬프트를 누가 눌러 주지 않아도 끝까지 돌게 합니다.

Claude Code 옆에 brgr가 띄운 워커 3개가 쌓여 있는 Herdr 화면

#코딩 에이전트 오케스트레이터 #공개 저장소

기간

2026.09 – 지금

GitHub

저장소 보기저장소 보기

기여

01 워커마다 Herdr 패인 하나

02 신뢰·계속 프롬프트 자동 응답

03 모르는 화면은 3분 뒤 실패

04 결과 봉인 후 승인해야 적용

05 실패는 확인할 때까지 알림

06 owner·워커 간 질문과 답장

기술

Rust · SQLite · git worktree · Herdr

10/21

brgr · 결과 승인과 적용

승인한 변경인데 새 파일이 빠진 채 적용됐습니다

상황

brgr는 워커 결과를 봉인해 두고 owner가 승인해야만 저장소에 적용합니다. 그런데 승인한 결과를 적용했더니 워커가 새로 만든 파일이 오류 없이 빠져 있었습니다.

원인

결과를 git diff로 봉인했는데, git diff는 git이 이미 추적하는 파일만 담습니다. 워커가 새로 만든 파일은 아직 추적 전이라 통째로 빠졌습니다.

해결

봉인할 때 index를 임시로 복사해 새 파일을 담을 대상으로 표시한 뒤 diff를 만듭니다. 워커의 실제 index는 건드리지 않습니다.

결과

새 파일 10개를 만든 결과에서 봉인에 담긴 새 파일 0/10 → 10/10. 워커 index 변경 0개, 관련 테스트 2개 통과 (2026-10-08 재현).

근거 · brgr · git_diff.rs ↗근거 · brgr · git_diff.rs ↗

BEFORE · git diff로 봉인

승인한 결과를 적용해도

새 파일은 빠져 있었습니다.

추적 전 파일은 diff에 안 들어갑니다.

AFTER · 임시 index에 새 파일 표시

새 파일까지 diff에 담고

승인한 그대로 적용합니다.

워커의 실제 index는 그대로.

봉인에 담긴 새 파일 (10개 중)

0개 → 10개

11/21

라피

개인 에이전트

라피

여기저기 흩어진 소식을 모아 Discord와 이메일(SMTP)로 브리핑하고 제가 승인한 일만 대신 하는 개인 에이전트입니다.

라피가 공개 블로그에 올린 데일리 브리핑

#개인 에이전트 #v0.1.2 배포

기간

2026.09 – 지금

GitHub

저장소 보기저장소 보기

기여

01 RSS · GitHub · 웹훅 수집

02 Discord · 이메일(SMTP) 브리핑

03 공개 분석만 올리는 블로그

04 USER · ADMIN · SUPERADMIN 권한

05 승인한 작업만 실행

06 취소하면 프로세스 종료

기술

TypeScript · Node.js · PostgreSQL · Zod · MDX · Discord

12/21

라피 · 운영과 복구

혼자 운영하는 서비스라 되돌리는 길부터 만들었습니다

상황

라피는 VM 한 대에서 수집·발송·실행 서비스 8개가 함께 돕니다. 혼자 운영하다 보니 배포가 잘못되거나 서버가 멈춰도 바로 붙어 있지 못할 때가 많습니다.

원인

배포와 복구를 손으로 하면 장애를 늦게 알거나, 되돌리는 도중에 데이터를 잃을 수 있었습니다. 재시작 중 잠깐의 오류를 복구로 착각해 알림을 끄는 것도 위험했습니다.

해결

CI를 통과한 커밋은 5분 안에 자동 배포하고, 전환이 실패하면 직전 릴리스로 되돌립니다. 외부 감시는 재시작 중에는 장애 상태를 유지하고, 실제 응답이 돌아와야 복구로 알립니다.

결과

운영 DB 덤프를 별도 PostgreSQL에 복원해 테이블 31개·migration 12개·제약 105개 일치 (2026-09-28). 장애 알림 1번, 재시작 중 잘못된 복구 알림 0번, 복구 확인 뒤 알림 1번.

근거 · 라피 운영 기록 2026-09-28 ↗근거 · 라피 운영 기록 2026-09-28 ↗

배포와 복구

31 · 12 · 105

복원 점검: 테이블 · migration · 제약

배포

CI 통과 후 5분 안에 자동

전환 실패

직전 릴리스로 롤백

외부 감시

복구 확인 후에만 알림

운영 데이터

덮어쓰지 않고 별도 DB에 복원

13/21

라피 · 개인 에이전트 · v0.1.0 배포

취소했다고 답한 뒤에도 에이전트가 계속 돌고 있었습니다

상황

디스코드에서 /취소를 보내면 라피는 "작업을 취소했습니다"라고 답했지만, 그사이 Codex가 제 저장소를 계속 고칠 수 있었습니다.

원인

취소는 DB 상태만 바꿨고 실행기에는 Codex를 멈출 방법이 없었습니다. 시간 초과 때도 직접 띄운 프로세스에만 SIGTERM을 보내서, 신호를 무시하거나 그 아래에서 뜬 프로세스는 살아남았습니다.

해결

Codex를 프로세스 그룹으로 띄우고 그룹 전체에 SIGTERM, 1초 뒤 SIGKILL을 보냅니다. 종료를 확인한 뒤에만 취소로 기록하고, 확인이 안 되면 "미확정"이라고 답합니다.

결과

취소 후 살아남은 실행 20회 중 20회 → 0회 (2026-10-07 재현). 운영에서도 실제 Codex 프로세스의 PID가 사라지고 DB와 일치했습니다.

근거 · 라피 v0.1.0 · process.ts ↗근거 · 라피 v0.1.0 · process.ts ↗

직접 해 보기 →직접 해 보기 →

BEFORE · DB만 취소

"작업을 취소했습니다"라고 답해도

Codex 프로세스는 남아 있었습니다.

신호를 무시하는 자식·손자 2개가 그대로.

AFTER · 종료 확인 후 기록

프로세스 그룹에 SIGTERM → SIGKILL

끝난 걸 확인해야 취소로 기록합니다.

확인이 안 되면 "미확정"으로 답합니다.

취소 후 살아남은 실행 (20회)

20회 → 0회

14/21

Watchdog · macOS 메뉴바 앱 · 2026.08–2026.09 · v0.2.1 공개

멈추려던 PID가 다른 프로세스일 수 있었습니다

상황

폭주하거나 고아가 된 프로세스를 찾아 메뉴바에서 멈추게 합니다. 감지한 순간과 멈추기를 누르는 순간 사이에 원래 프로세스가 끝날 수 있습니다.

원인

끝난 프로세스의 PID는 다른 프로세스에 다시 배정될 수 있고 macOS에는 신원 확인과 신호 보내기를 한 번에 하는 방법이 없습니다.

해결

신호를 보내기 직전에 PID·UID·시작 시각을 다시 읽어 감지 당시와 같을 때만 보냅니다. 멈춤은 되돌릴 수 있는 일시정지부터 씁니다.

결과

신호 직전 재확인에서 신원이 바뀌었으면 processChanged로 중단합니다.

근거 · Watchdog v0.2.1 · ProcessController ↗근거 · Watchdog v0.2.1 · ProcessController ↗

직접 해 보기 →직접 해 보기 →

BEFORE · PID만 기억

감지한 PID로 바로 보내면

다른 프로세스가 멈출 수 있습니다.

그사이 PID가 재사용될 수 있었습니다.

AFTER · 직전 재확인

PID·UID·시작 시각을 다시 읽고

같을 때만 일시정지합니다.

바뀌었으면 processChanged로 멈춥니다.

결과

신원이 바뀐 PID는 processChanged로 중단합니다.

15/21

justn.me · 이력서·포트폴리오 편집기

고치는 즉시 보이는 문서를 CDN 캐시에 올렸습니다

상황

PDF 모양 그대로 웹에서 고치는 이력서·포트폴리오입니다. 공개 화면이 요청마다 GitHub에서 문서를 읽어 서버 첫 응답에 640ms가 걸렸습니다.

원인

같은 문서를 편집기에서 수시로 고치고 자소서는 로그인해야 보여서, 화면을 그대로 캐시하면 저장한 내용이 늦게 보이거나 비공개 문서가 캐시에 남을 수 있었습니다.

해결

공개 문서만 미리 그려 CDN에 두고 저장하면 그 주소만 다시 그리게 했습니다. 자소서·회사별 문서는 매번 로그인을 확인하는 주소로 넘기고, git으로 직접 고친 내용은 5분 안에 다시 그립니다.

결과

서버 첫 응답 640ms → 17ms (2026-10-06, Lighthouse 모바일). 프로덕션 빌드에서 저장 직후 반영, 로그인 전 자소서 404를 확인했습니다.

justn.me ↗justn.me ↗

문서마다 다르게 그리기

640ms → 17ms

공개 화면 서버 첫 응답

공개 문서

CDN에 미리 그려 둠

편집기 저장

그 주소만 바로 다시 그림

자소서·회사별

매번 로그인 확인

git으로 직접 고친 내용

5분 안에 다시 그립니다

16/21

자갈치 · 6인 팀 FE Lead · 코드 리뷰

팀원 PR을 바로 머지하지 않고 기준부터 먼저 고쳤습니다

상황

2026-01-12 팀원이 올린 커뮤니티 화면 PR(#41)에 테스트가 없었고, 기존 코드의 꼬인 테스트 구조를 그대로 따르고 있었습니다.

원인

기존 코드베이스의 테스트 구조와 이름·export 규칙이 정리돼 있지 않아, 새 코드가 따를 기준이 없었습니다.

해결

PR에는 수정을 요청하고, 같은 날 직접 이슈(#44)를 열어 기존 코드의 구조와 컨벤션부터 통일했습니다(#45, 파일 52개).

결과

정리된 기준에 맞춰 고친 PR을 다음 날 승인했습니다. 확립한 규칙은 팀 문서(CLAUDE.md)에 남겼습니다.

근거 · PR #41 리뷰 · #45 ↗근거 · PR #41 리뷰 · #45 ↗

2026-01-12 ~ 01-14

요청 → 정리 → 승인

팀원 PR을 막기 전에 따를 기준을 먼저 만들었습니다.

PR #41 (팀원)

변경 요청 → 승인

PR #45 (기준 정리)

파일 52개 · 머지

순서

기준을 먼저 고치고 머지

17/21

조직 체계 · BSSM-OSS 관리자

외부에서 찾고 기여할 수 있게 공개 기준을 정리했습니다

외부 사람이 프로젝트를 이해하고 실행·기여할 수 있도록 공개 기준을 정리했습니다.

대표 목록

대표 프로젝트를 첫 화면에서 바로 찾을 수 있게 정리했습니다.

README

조직 소개 README를 영/한으로 분리하고 분야별 카탈로그로 재구성했습니다.

기여 경로

조직 공통 Issue 양식 4종과 PR 양식을 만들었습니다.

유지 기준

운영 중인 저장소만 대표 목록에 올렸습니다.

조직 전체 공개 저장소 98개 · 2026.09.08

근거 · BSSM-OSS Organization ↗근거 · BSSM-OSS Organization ↗

BSSM-OSS 대표 프로젝트 목록
18/21

주요 작업 · 오픈소스 · React Flow

연결선 양 끝에서 둥근 모서리가 사라지는 문제를 재현했습니다

중복 좌표 때문에 두 점 사이 거리와 모서리를 둥글게 만드는 값이 0이 되는 조건을 찾았습니다.

React Flow 연결선 수정 전후 비교

PR #5730 제안

근거 · PR #5730 · @xyflow/system 0.0.76 ↗근거 · PR #5730 · @xyflow/system 0.0.76 ↗

PR #5730

문제 재현

꺾임 위치 0·1에서 각진 모서리를 재현했습니다.

계산 원인 분석

중복 좌표 → 두 점 사이 거리 0 → 곡률 값 0

메인테이너 병합

원인을 찾아 PR을 제출했고 병합됐습니다(@xyflow/system 0.0.76).

19/21

주요 작업 · 오픈소스 · Gajae Code

에이전트의 완료 이벤트와 모델 연결 경로를 원 프로젝트에 구현했습니다

오픈소스 코딩 에이전트 Gajae Code에 완료 알림 연결과, 모델 제공자 Command Code의 GOAT 요금제 인증·요청 경로를 각각 PR로 제출했습니다.

Gajae Code PR #1272

PR #1272PR #1272

작업 완료 알림

작업이 끝나면 완료 정보를 외부 명령으로 전달하는 연결 기능을 추가했습니다.

Gajae Code PR #5050

PR #5050PR #5050

Command Code GOAT Plan 인증

API key 로그인과 해당 모델 제공자로 요청을 보내는 경로를 구현했습니다.

두 변경 모두 원 저장소에 병합됐습니다.

근거 · PR #1272PR #1272 · PR #5050PR #5050 ↗

20/21

황준혁

제품을 만들고 진행 상태를 정직하게 남깁니다

justn.hyeok@gmail.comjustn.hyeok@gmail.com

PDF 다운로드