AI가 쓴 티가 나는 한국어 글을 자연스러운 사람 글로 고치는 프롬프트 기반 스킬.
blader/humanizer의 구조·방법론(패턴 카탈로그 + draft→audit→final 루프 +
false positive 가이드)을 한국어에 맞게 재구성했다.
- 한국어 특화 33개 패턴: 번역체(직역 조사·무생물 주어·"~들"·"가지다"·이중피동·
명사화), AI 상투어, 3의 법칙, 과장된 의의 부여, 마무리 상투구, 챗봇 잔재,
줄표·가운뎃점·곡선따옴표 등
- Triage(최소 개입) 원칙: 서식만 문제면 산문은 그대로 두어 과교정 방지
- Length control: 목표 글자수 지정 시 ±5% 내로 맞추고 공백 포함/제외 수치 보고,
korean-character-count 스킬과 연동
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(srt): 좌석 조회와 탐색 우선순위 추가
SRT search 결과의 stable train_id로 객차별 좌석을 조회하고, 특정 호차/좌석 확인과 탐색 우선순위 옵션을 제공한다.
Constraint: SRT와 KTX는 별도 upstream 표면이므로 SRT HTML 파서와 테스트를 분리함
Rejected: KTX 좌석 helper 공유 | Korail API와 SRT 웹 좌석선택 HTML 계약이 달라 혼용하면 파서 안정성이 낮아짐
Confidence: medium
Scope-risk: moderate
Directive: SRT 좌석선택 HTML에서 노출되지 않는 속성은 추정하지 말고 명시적으로 처리할 것
Tested: PYTHONPATH=.:scripts python3 -m unittest scripts.test_srt_booking scripts.test_ktx_booking; python3 -m py_compile scripts/srt_booking.py scripts/srt_seats.py scripts/test_srt_booking.py
Not-tested: 실제 예약 API에 우선순위 좌석 선택을 연결하는 흐름
* fix(srt): 좌석 조회 JSON 출력 안정화
SRT 대기열 메시지가 stdout에 섞여 seats JSON을 깨는 실제 표면 문제를 막고, 누락된 좌석 방향/위치 속성을 unknown으로 정규화한다.
Constraint: issue #303 범위는 예약 부작용이 없는 좌석 조회 보조 흐름으로 제한됨
Rejected: 실제 예약 subcommand 추가 | 좌석 선점/예약은 외부 부작용이라 이번 acceptance criteria에 포함되지 않음
Confidence: high
Scope-risk: narrow
Directive: SRTrain upstream 출력이 추가되더라도 helper stdout은 JSON 전용으로 유지할 것
Tested: RED→GREEN in .omo/ulw-loop/evidence/srt-c002-red-green-tests.txt; live SRT tmux QA in .omo/ulw-loop/evidence/srt-c001-live-search-seats.txt; npm run ci in .omo/ulw-loop/evidence/srt-c003-regression-ci.txt
Not-tested: 실제 예약/결제/취소 부작용 흐름
* test(srt): split seat helper regression coverage
---------
Co-authored-by: Jeffrey (Dongkyu) Kim <vkehfdl1@gmail.com>
라이브 불변식 검증(예비 제외·dedup·useDt 범위)이 통과한 뒤,
사용자 대면 출력 함수인 print_text가 테스트 0개였던 갭을 메운다.
- PrintTextTest 2개: 결과 렌더링 / 빈 결과 메시지
- stub_fetch는 fetch_one의 미사용 인자를 **_ 로 흡수해 lint 경고 제거
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
월별예약조회 API가 srchDate 단일 일자 요청에도 5일 윈도우를 반환하고,
"예비"로 표기된 운영자 보유분이 raw 응답에 포함되며, 같은 객실이 다른
goodsId로 중복 표시되는 세 가지 문제를 한꺼번에 fix한다.
수정:
- collect_results 안에 strict useDt gate 추가 (today~last_day 범위 밖 행 차단)
- is_reserve_room() helper로 goodsNm에 "예비" 포함 객실 제외
- (forest_id, use_dt, name) 단위 dedup으로 중복 행 제거
- is_available()는 시그니처/로직 변경 없이 booking-state predicate 유지
추가:
- foresttrip-vacancy/tests/ 18개 단위 테스트 (mock + fixture 기반)
- IsReserveRoomTest, IsAvailableTest, CollectResultsFilterTest,
StrictUseDtGateTest, GroundTruthTest 다섯 클래스
- 거제·구재봉 fixture로 사용자 라이브 검증 결과 회귀 보호
- package.json lint·test 스크립트에 등록
문서:
- SKILL.md: API 5일 윈도우/예비 객실/중복 dedup 자동 처리 명시 + 회복 시나리오 보강
- docs/features/foresttrip-vacancy.md: 기본 흐름 6단계와 주의할 점 보강
사용자 라이브 검증 ground truth (2026-05-12 기준):
- 거제자연휴양림 5/13 ~9개, 5/16 0개, 5/17 19개, 5/23 0개, 5/24 0개
- 구재봉자연휴양림 5/16 1개 (206호 쑥부쟁이방)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Fail closed when Korail reports remaining seats but returns malformed, sentinel-only, or schema-incomplete detail rows, and keep the seat research endpoints inside the same Dynapath/Sid request boundary as other protected mobile calls.\n\nConstraint: PR #298 review required TDD regressions for false empty-seat success and raw external payload failures.\nRejected: Preserve lenient normalization of partial seat rows | it can mislead automation with authoritative empty results.\nConfidence: high\nScope-risk: narrow\nDirective: Keep KTX seat detail parsing fail-closed unless live Korail evidence proves a specific empty or partial shape is valid.\nTested: PYTHONPATH=.:scripts python3 -m unittest scripts.test_ktx_booking; node --test scripts/skill-docs.test.js; npm run typecheck; python3 -m compileall -q scripts/ktx_booking.py scripts/test_ktx_booking.py; ruff check scripts/ktx_booking.py scripts/test_ktx_booking.py; shellcheck scripts/validate-skills.sh; bash scripts/validate-skills.sh; PYENV_VERSION=3.11.9 npm run ci\nNot-tested: live Korail seat-detail network flow with production credentials
Boundary validation now distinguishes unavailable/malformed Korail car and seat-detail payloads from valid zero-seat results, so automation does not consume false successful empty-seat JSON.\n\nConstraint: PR #298 follow-up for issue #293 required TDD, clear errors for malformed details/metadata, and branch feature/#293.\nRejected: Per-car partial error payloads | broader interface change than the existing fail-fast command contract.\nRejected: Missing Korail car counts defaulting to zero | masks unknown external summary data as authoritative no-seat state.\nConfidence: high\nScope-risk: narrow\nDirective: Keep seat-detail and car-summary schema checks at the command boundary before normalizing rows.\nTested: Targeted malformed payload probe; PYTHONPATH=.:scripts python3 -m unittest scripts.test_ktx_booking; node --test scripts/skill-docs.test.js; npm run typecheck; python3 -m compileall -q scripts/ktx_booking.py scripts/test_ktx_booking.py; ruff check scripts/ktx_booking.py scripts/test_ktx_booking.py; shellcheck scripts/validate-skills.sh; bash scripts/validate-skills.sh; PYENV_VERSION=3.11.9 npm run ci.\nNot-tested: Live Korail seat-detail endpoints requiring user credentials.
Constraint: PR #298 review blocker required missing seat_infos.seat_info to fail clearly instead of reporting zero seats.
Rejected: Treating absent seat_info as an empty list | this masks Korail detail endpoint failures as authoritative no-seat results.
Confidence: high
Scope-risk: narrow
Directive: Preserve explicit empty seat_info lists as valid; only absent or malformed detail schema should fail.
Tested: PYTHONPATH=.:scripts python3 -m unittest scripts.test_ktx_booking; node --test scripts/skill-docs.test.js; npm run typecheck; python3 -m compileall -q scripts/ktx_booking.py scripts/test_ktx_booking.py; ruff check scripts/ktx_booking.py scripts/test_ktx_booking.py; shellcheck scripts/validate-skills.sh; bash scripts/validate-skills.sh; PYENV_VERSION=3.11.9 npm run ci
Not-tested: plain npm run ci with local default Python 3.14 remains blocked by pyexpat/libexpat linkage before project tests
Convert malformed Korail seat-detail payloads into the existing CLI failure path so advisory lookup callers get a clear retryable error instead of an AttributeError.
Constraint: PR #295 review watch item identified successful-but-malformed seat_infos payloads as an unhelpful crash surface.
Rejected: Letting raw adapter fallbacks leak AttributeError | CLI users need actionable SystemExit diagnostics at the command boundary.
Confidence: high
Scope-risk: narrow
Directive: Keep detailed seat lookup advisory; validate raw Korail shapes before exposing fields to JSON callers.
Tested: PYTHONPATH=.:scripts python3 -m unittest scripts.test_ktx_booking; node --test scripts/skill-docs.test.js; npm run typecheck; python3 -m compileall -q scripts/ktx_booking.py scripts/test_ktx_booking.py; ruff check scripts/ktx_booking.py scripts/test_ktx_booking.py; shellcheck scripts/validate-skills.sh; bash scripts/validate-skills.sh; PATH=<pyenv 3.11.9 shim> npm run ci
Not-tested: Plain npm run ci with /opt/homebrew Python 3.14 due local pyexpat/libexpat linkage error reproduced before project tests.
Preserve car-level remaining_seats when Korail detail payloads drift, and mark the affected car with an explicit lookup error instead of reporting a false zero-seat result.\n\nConstraint: PR #293 review required malformed detail responses to be visible when car summary still reports remaining seats.\nRejected: silently normalizing malformed seat_infos to [] | it hides upstream schema drift as legitimate zero availability.\nConfidence: high\nScope-risk: narrow\nDirective: Keep seat-detail schema drift observable; do not collapse positive remaining seats and malformed detail payloads into successful empty results.\nTested: PYTHONPATH=.:scripts PYTHONNOUSERSITE=1 python3 -m unittest discover -s scripts -p 'test_ktx_booking.py'\nTested: PYTHONPATH=.:scripts python3 -m unittest scripts.test_ktx_booking\nTested: python3 -m py_compile scripts/ktx_booking.py scripts/test_ktx_booking.py\nTested: node --check scripts/skill-docs.test.js\nTested: node --test scripts/skill-docs.test.js\nNot-tested: live Korail seat-detail endpoint with production credentials
Preserve car-level remaining_seats when Korail detail payloads drift, and mark the affected car with an explicit lookup error instead of reporting a false zero-seat result.\n\nConstraint: PR #293 review required malformed detail responses to be visible when car summary still reports remaining seats.\nRejected: silently normalizing malformed seat_infos to [] | it hides upstream schema drift as legitimate zero availability.\nConfidence: high\nScope-risk: narrow\nDirective: Keep seat-detail schema drift observable; do not collapse positive remaining seats and malformed detail payloads into successful empty results.\nTested: PYTHONPATH=.:scripts PYTHONNOUSERSITE=1 python3 -m unittest discover -s scripts -p 'test_ktx_booking.py'\nTested: PYTHONPATH=.:scripts python3 -m unittest scripts.test_ktx_booking\nTested: python3 -m py_compile scripts/ktx_booking.py scripts/test_ktx_booking.py\nTested: node --check scripts/skill-docs.test.js\nTested: node --test scripts/skill-docs.test.js\nNot-tested: live Korail seat-detail endpoint with production credentials
Constraint: PR #295 review found power-only summaries included non-power seats and empty car-list payloads looked successful.
Rejected: Document available_seats as unfiltered | would preserve a surprising JSON contract for power-only callers.
Rejected: Ignore local hidden directories one by one | hidden runtime/cache directories can keep reappearing outside git.
Confidence: high
Scope-risk: narrow
Directive: Keep seats output summaries aligned with active display filters, while --limit remains a detailed seats display cap.
Tested: PYTHONPATH=.:scripts python3 -m unittest scripts.test_ktx_booking; python3 -m compileall -q scripts/ktx_booking.py scripts/test_ktx_booking.py; git diff --check; node --test scripts/skill-docs.test.js; npm run typecheck; PIP_BREAK_SYSTEM_PACKAGES=1 npm run ci
Not-tested: live Korail production seat endpoint behavior
로컬 개발 환경에서 생성되는 .agents와 .venv를 최상위 스킬로
검사하지 않도록 제외해 skill layout 검증을 실제 스킬 디렉터리에 한정합니다.
Constraint: npm run ci가 validate-skills.sh를 필수로 실행함
Rejected: 로컬 .agents/.venv 삭제 | 사용자 환경 파일을 제거하는 방식은 부적절함
Confidence: high
Scope-risk: narrow
Directive: 새 로컬 런타임 디렉터리가 생기면 skill-docs.test.js 제외 목록과 함께 검토할 것
Tested: npm run ci
KTX 상세 좌석 조회에서 가운데 호차를 먼저 탐색하고,
같은 호차 안에서는 콘센트 좌석과 순방향 좌석을 우선 노출합니다.
#294 요구사항을 우선순위 함수와 command_seats 회귀 테스트로 고정합니다.
Constraint: #294는 기존 seats 공개 인터페이스 유지를 요구함
Rejected: 예약 API에 객차/좌석 번호를 직접 주입 | 현재 helper 예약 경로가 해당 선택 인자를 노출하지 않음
Confidence: high
Scope-risk: narrow
Directive: 좌석 우선순위 변경 시 command_seats 출력 순서 테스트를 함께 갱신할 것
Tested: PYTHONPATH=.:scripts python3 -m unittest scripts.test_ktx_booking
Tested: node --test scripts/skill-docs.test.js
Tested: npm run typecheck
Tested: npm run ci
Add a seats command to inspect residual seats by car, normalize seat metadata, and surface power-outlet hints while preserving the existing search and reserve selector flow. Update skill docs so seat-number and good-seat requests route through the detailed lookup before reservation.
Constraint: Korail reservation remains separate from seat inspection; the new flow must not select, hold, or pay for seats.
Rejected: Reusing train-level has_general_seat flags for good-seat requests | those flags cannot answer car number, seat label, or outlet availability.
Confidence: high
Scope-risk: moderate
Directive: Keep search, seats, and reserve on the same train_type and stable train_id path so stale results fail explicitly.
Tested: PYTHONPATH=.:scripts python3 -m unittest scripts.test_ktx_booking; python3 -m py_compile scripts/ktx_booking.py scripts/test_ktx_booking.py; node --check scripts/skill-docs.test.js
Not-tested: npm run ci is blocked locally because gitignored .agents/ and .venv directories are treated as missing SKILL.md by scripts/validate-skills.sh.
- Add startup-support API routes for Korean government startup programs
- Implement /v1/startup-support/list, /detail, /region, /deadline endpoints
- Integrate with existing k-skill-proxy infrastructure
Closes #startup-support
- Add startup-support skill to search Korean government startup support programs
- Implement Python script with multiple data sources (public data, local governments)
- Add k-skill-proxy routes for API endpoints
- Update documentation (README.md, docs/features/, docs/sources.md, etc.)
- Add comprehensive test suite
Closes #startup-support