Commit graph

625 commits

Author SHA1 Message Date
Jeffrey (Dongkyu) Kim
08533bd9eb
Merge pull request #325 from NomaDamas/dev
Merge dev into main
2026-06-21 17:39:44 +09:00
Jeffrey (Dongkyu) Kim
eacdfb882a
Merge pull request #323 from jwb0501/feature/talent-search-skills
잡코리아·사람인 인재검색 스킬 추가
2026-06-19 14:38:47 +09:00
Jeffrey (Dongkyu) Kim
b14f65361f Wire JobKorea talent helper into CI 2026-06-18 10:37:08 +09:00
wbjung
caa1f0fd0d Fix JobKorea fallback row parsing 2026-06-18 00:04:07 +09:00
wbjung
c619d3b7c7 Add recruiting talent search skills 2026-06-17 23:14:54 +09:00
Jeffrey (Dongkyu) Kim
e735abe8a4
Merge PR #322: replace KakaoTalk skill with katok
Feature/#320
2026-06-17 16:52:39 +09:00
Jeffrey (Dongkyu) Kim
c3f44eef14 feat(kakaotalk-mac): replace kakaocli workflow with katok
Closes #320

Plan: .omo/plans/issue-320-katok-skill.md
2026-06-16 13:44:56 +09:00
Jeffrey (Dongkyu) Kim
1f186af480
Merge pull request #319 from NomaDamas/dev
Release dev to main
2026-06-15 13:12:02 +09:00
Jeffrey (Dongkyu) Kim
5fd58facf4
Merge pull request #318 from NomaDamas/changeset-release/main
chore: version packages
2026-06-15 13:11:49 +09:00
Jeffrey (Dongkyu) Kim
e0d842435b Merge main into dev for PR 319 2026-06-14 18:11:45 +09:00
Jeffrey (Dongkyu) Kim
ece355b807 fix(korean-humanizer): quote frontmatter description
Quote the long Korean description so the `예:` segment is parsed as a scalar
instead of an invalid YAML mapping key. Also ignore local `.gjc/` runtime state.

Verified with scripts/validate-skills.sh and downstream benchmark eligibility
classification.
2026-06-13 00:21:13 +09:00
Jeffrey (Dongkyu) Kim
a633b001be
feat: add business due-diligence skills
Reviewed, resolved conflicts with latest dev, applied follow-up fixes, and verified with npm run ci.
2026-06-12 19:35:14 +09:00
Jeffrey (Dongkyu) Kim
c8bb7f9f35 Merge dev and address PR review fixes 2026-06-12 19:34:20 +09:00
github-actions[bot]
7586c0dea8 chore: version packages 2026-06-12 10:07:08 +00:00
Jeffrey (Dongkyu) Kim
66f12cb43d
dev → main: srt-booking 좌석 탐색, korean-humanizer 신규 스킬, toss-securities 공식 OpenAPI 클라이언트, korean-law k-skill-proxy 편입 (#314)
* feat(srt-booking): SRT 좌석 확인과 탐색 우선순위 개선 (#305)

* 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>

* feat: add korean-humanizer skill

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(korean-humanizer): rebuild v2 on im-not-ai framework

Build on happy-nut's PR #311 korean-humanizer skill (cherry-picked,
authorship preserved) by re-centering it on the epoko77-ai/im-not-ai
(Humanize KR, MIT) methodology:

- 4대 철칙 (의미 불변 · 근거 기반 · 장르 유지 · 과윤문 금지 30%/50% 가드)
- S1/S2/S3 severity tiers and A~D quality grades
- A~J taxonomy with Korean-specific patterns (A-16 그/그녀 강박,
  A-18 관계절 좌향 수식, A-19 이중 조사, C-11 연결어미 뒤 쉼표, E-7 경어법)
- detect -> rewrite -> audit -> grade loop with self-check checklist
- references/ai-tell-taxonomy.md full A~J table
- docs/features/korean-humanizer.md crediting im-not-ai and happy-nut
- README row + link, regenerated plugin.json, docs regression test

Co-authored-by: happy-nut <happynut.dev@gmail.com>

* docs(korean-law-search): document official precedent API evidence (#313)

Enhance the existing korean-law-search skill and feature doc with the
official 법제처 Open API precedent endpoints and detail retrieval, without
adding a new skill, package, workspace, or changeset.

- Document 판례 목록 조회 (lawSearch.do?target=prec) and 판례 본문 조회
  (lawService.do?target=prec&ID=...) as official evidence behind the
  korean-law-mcp search_precedents/get_precedent_text path.
- Add supported precedent filters (query, court, case number, source
  name, date, sort) and precedent-specific failure modes (missing LAW_OC,
  upstream unavailable/rate-limit/timeout, empty results, body
  unavailable for some sources) plus the legal-advice boundary.
- Keep korean-law-mcp first and Beopmang as the only post-failure
  fallback; lawService.do?target=prec is official detail retrieval, not a
  Beopmang-style fallback.
- Extend the skill-docs regression test with stable endpoint/tool
  literals and concept-level filter/failure-mode/legal-boundary checks.

Closes #308

* feat(toss-securities): add official read-only OpenAPI client (#312)

Add an official Toss Securities Open API client alongside the existing
unofficial tossctl wrapper. The package ships read-only helpers backed by
the official REST API (https://openapi.tossinvest.com): OAuth2
client_credentials token issuance with an in-memory token cache, bearer +
X-Tossinvest-Account header handling, TossApiError/TossCredentialsError
with secret/token redaction, and 429 Retry-After/backoff retry.

Credentials are read from TOSSINVEST_CLIENT_ID/TOSSINVEST_CLIENT_SECRET
(optional TOSSINVEST_ACCOUNT/TOSSINVEST_API_BASE_URL) and sent directly to
Toss, never through a shared proxy. Order mutation remains out of scope;
the tossctl path is retained as a documented fallback.

Closes #306

* Revert "docs(korean-law-search): document official precedent API evidence (#313)"

This reverts commit 5faec8bb2a.

* feat(k-skill-proxy): fold Korean law lookups into k-skill-proxy, drop Beopmang (#315)

Add hosted korean-law proxy routes and make the korean-law-search skill
proxy-first, removing the unstable Beopmang fallback from the support list.

- proxy: new src/korean-law.js wrapping official 법제처 DRF lawSearch.do /
  lawService.do, injecting LAW_OC + browser User-Agent/Referer (the real
  cause of "사용자 정보 검증 실패") and retrying empty/HTML responses.
- proxy: /v1/korean-law/search and /v1/korean-law/detail routes + lawOc
  config + koreanLawConfigured health flag; 17 module + 6 route tests.
- skill/docs: korean-law-search becomes proxy-first (no per-user LAW_OC,
  no local CLI). Drop Beopmang everywhere; credit chrisryugj/korean-law-mcp
  as design reference and 법제처 open.law.go.kr as official source.
- ops: LAW_OC added to deploy doc KEYS, secret accessor loop, and the
  Cloud Run deploy workflow set-secrets.
- changeset: k-skill-proxy minor.

---------

Co-authored-by: iamiks <rmstjr1030@naver.com>
Co-authored-by: happy-nut <happynut.dev@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 19:06:18 +09:00
Jeffrey (Dongkyu) Kim
f485591ac2
feat(k-skill-proxy): fold Korean law lookups into k-skill-proxy, drop Beopmang (#315)
Add hosted korean-law proxy routes and make the korean-law-search skill
proxy-first, removing the unstable Beopmang fallback from the support list.

- proxy: new src/korean-law.js wrapping official 법제처 DRF lawSearch.do /
  lawService.do, injecting LAW_OC + browser User-Agent/Referer (the real
  cause of "사용자 정보 검증 실패") and retrying empty/HTML responses.
- proxy: /v1/korean-law/search and /v1/korean-law/detail routes + lawOc
  config + koreanLawConfigured health flag; 17 module + 6 route tests.
- skill/docs: korean-law-search becomes proxy-first (no per-user LAW_OC,
  no local CLI). Drop Beopmang everywhere; credit chrisryugj/korean-law-mcp
  as design reference and 법제처 open.law.go.kr as official source.
- ops: LAW_OC added to deploy doc KEYS, secret accessor loop, and the
  Cloud Run deploy workflow set-secrets.
- changeset: k-skill-proxy minor.
2026-06-12 18:07:03 +09:00
John
440cd697a7 feat: 사업자 실사 스킬군 — 단품 5종 + 복합 1종, proxy route 3개 추가 (#316)
사업자등록번호로 "이 사업자 실제 문제 없나"를 무료 공공 데이터로 교차 조회하는
스킬군을 기여한다. 점수·등급·"위험" 라벨 없이 사실+출처+조회시각만 병렬한다.

단품 스킬:
- national-pension-workplace  국민연금 가입 사업장 (proxy, 3046071)
- nts-tax-delinquency         국세 체납 명단공개 (무인증 직접)
- fsc-corporate-info          금융위 기업기본정보 (proxy, 15043184)
- g2b-sanctioned-supplier     조달청 부정당제재 (proxy, 15129466)
- localdata-business-status   지방행정 인허가 영업상태 208업종 (무인증 직접)

복합 스킬:
- biz-health-check  위 5종 + 기존 nts-business-registration을 한 번에 호출

proxy(packages/k-skill-proxy):
- keyed route 3개 추가 — 키는 서버의 DATA_GO_KR_API_KEY로만 주입(사용자 시크릿 없음)
- 연금 route는 basic+detail+monthly 3콜 오케스트레이션 + 월별중복 dedup
- server.test.js에 route 테스트 10건 추가 (정상/503 미설정/400/403 forbidden)

무인증 스킬은 stdlib(urllib)만 사용해 의존성 없이 직접 호출한다.
문서: docs/features ×6, README 표·링크, docs/sources.md 갱신, plugin.json 재생성.

활용신청(프록시 운영 서버 등록 필요): 3046071·15043184·15129466
(15081808 국세청 상태조회는 nts-business-registration용으로 이미 등록, 키 공유).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 16:46:30 +09:00
Jeffrey (Dongkyu) Kim
b6200892e3 Revert "docs(korean-law-search): document official precedent API evidence (#313)"
This reverts commit 5faec8bb2a.
2026-06-11 11:45:04 +09:00
Jeffrey (Dongkyu) Kim
79f6038328
feat(toss-securities): add official read-only OpenAPI client (#312)
Add an official Toss Securities Open API client alongside the existing
unofficial tossctl wrapper. The package ships read-only helpers backed by
the official REST API (https://openapi.tossinvest.com): OAuth2
client_credentials token issuance with an in-memory token cache, bearer +
X-Tossinvest-Account header handling, TossApiError/TossCredentialsError
with secret/token redaction, and 429 Retry-After/backoff retry.

Credentials are read from TOSSINVEST_CLIENT_ID/TOSSINVEST_CLIENT_SECRET
(optional TOSSINVEST_ACCOUNT/TOSSINVEST_API_BASE_URL) and sent directly to
Toss, never through a shared proxy. Order mutation remains out of scope;
the tossctl path is retained as a documented fallback.

Closes #306
2026-06-10 22:50:47 +09:00
Jeffrey (Dongkyu) Kim
5faec8bb2a
docs(korean-law-search): document official precedent API evidence (#313)
Enhance the existing korean-law-search skill and feature doc with the
official 법제처 Open API precedent endpoints and detail retrieval, without
adding a new skill, package, workspace, or changeset.

- Document 판례 목록 조회 (lawSearch.do?target=prec) and 판례 본문 조회
  (lawService.do?target=prec&ID=...) as official evidence behind the
  korean-law-mcp search_precedents/get_precedent_text path.
- Add supported precedent filters (query, court, case number, source
  name, date, sort) and precedent-specific failure modes (missing LAW_OC,
  upstream unavailable/rate-limit/timeout, empty results, body
  unavailable for some sources) plus the legal-advice boundary.
- Keep korean-law-mcp first and Beopmang as the only post-failure
  fallback; lawService.do?target=prec is official detail retrieval, not a
  Beopmang-style fallback.
- Extend the skill-docs regression test with stable endpoint/tool
  literals and concept-level filter/failure-mode/legal-boundary checks.

Closes #308
2026-06-10 22:50:34 +09:00
Jeffrey (Dongkyu) Kim
e25f8dd9ab feat(korean-humanizer): rebuild v2 on im-not-ai framework
Build on happy-nut's PR #311 korean-humanizer skill (cherry-picked,
authorship preserved) by re-centering it on the epoko77-ai/im-not-ai
(Humanize KR, MIT) methodology:

- 4대 철칙 (의미 불변 · 근거 기반 · 장르 유지 · 과윤문 금지 30%/50% 가드)
- S1/S2/S3 severity tiers and A~D quality grades
- A~J taxonomy with Korean-specific patterns (A-16 그/그녀 강박,
  A-18 관계절 좌향 수식, A-19 이중 조사, C-11 연결어미 뒤 쉼표, E-7 경어법)
- detect -> rewrite -> audit -> grade loop with self-check checklist
- references/ai-tell-taxonomy.md full A~J table
- docs/features/korean-humanizer.md crediting im-not-ai and happy-nut
- README row + link, regenerated plugin.json, docs regression test

Co-authored-by: happy-nut <happynut.dev@gmail.com>
2026-06-10 14:32:44 +09:00
happy-nut
a8a71eed11 feat: add korean-humanizer skill
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>
2026-06-10 14:22:54 +09:00
iamiks
52dbfee064
feat(srt-booking): SRT 좌석 확인과 탐색 우선순위 개선 (#305)
* 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>
2026-06-09 10:57:54 +09:00
Jeffrey (Dongkyu) Kim
f5d37ddbee
Merge pull request #309 from NomaDamas/changeset-release/main
chore: version packages
2026-06-09 10:55:22 +09:00
github-actions[bot]
819be4897a chore: version packages 2026-06-06 03:08:25 +00:00
Jeffrey (Dongkyu) Kim
1efef285ba
Merge pull request #302 from NomaDamas/dev
Release: dev → main
2026-06-06 12:07:27 +09:00
Jeffrey (Dongkyu) Kim
acc66861ea Merge remote-tracking branch 'origin/main' into dev
# Conflicts:
#	.changeset/issue-268-naver-map-route.md
2026-06-05 22:49:47 +09:00
Jeffrey (Dongkyu) Kim
bbba283151 Archive unsupported map skills 2026-06-05 22:24:15 +09:00
Jeffrey (Dongkyu) Kim
46f44ed724 chore: remove startup-support skill 2026-06-05 17:21:58 +09:00
Jeffrey (Dongkyu) Kim
cc64d66d56 test: isolate python test dependencies 2026-06-05 17:03:27 +09:00
Jeffrey (Dongkyu) Kim
7c1a4530cf test: remove runtime pip install from root ci 2026-06-05 17:00:02 +09:00
Jeffrey (Dongkyu) Kim
346ce7f516 fix(startup-support): use K-Startup proxy surface 2026-06-05 13:03:28 +09:00
Jeffrey (Dongkyu) Kim
e336f7898c chore: resolve integration diagnostics 2026-05-31 17:28:59 +09:00
Jeffrey (Dongkyu) Kim
352876f915 chore(plugin): include startup-support in manifest 2026-05-31 17:26:08 +09:00
Jeffrey (Dongkyu) Kim
581b0344ce Merge commit 'c27a3e9' into ulw-merge-seven-prs
# Conflicts:
#	package.json
2026-05-31 17:25:22 +09:00
Jeffrey (Dongkyu) Kim
cc768f4031 Merge commit 'cff6b29' into ulw-merge-seven-prs 2026-05-31 17:24:25 +09:00
Jeffrey (Dongkyu) Kim
51388a539e Merge commit 'b6b0c70' into ulw-merge-seven-prs
# Conflicts:
#	scripts/validate-skills.sh
2026-05-31 17:24:25 +09:00
Jeffrey (Dongkyu) Kim
fe08b8e068 Merge remote-tracking branch 'origin/pr/293' into ulw-merge-seven-prs 2026-05-31 17:24:05 +09:00
Jeffrey (Dongkyu) Kim
e76c125014 Merge remote-tracking branch 'origin/pr/295' into ulw-merge-seven-prs 2026-05-31 17:24:04 +09:00
Jeffrey (Dongkyu) Kim
a490fcb0c0 Merge remote-tracking branch 'origin/pr/296' into ulw-merge-seven-prs 2026-05-31 17:24:04 +09:00
Jeffrey (Dongkyu) Kim
9dc3577742 Merge remote-tracking branch 'origin/pr/298' into ulw-merge-seven-prs 2026-05-31 17:24:04 +09:00
Jeffrey (Dongkyu) Kim
c27a3e9151 fix(foresttrip-vacancy): preserve category-specific vacancy rows 2026-05-31 17:23:57 +09:00
Jeffrey (Dongkyu) Kim
cff6b29ff9 fix(startup-support): remove fabricated detail data 2026-05-31 17:23:57 +09:00
Jeffrey (Dongkyu) Kim
b6b0c70091 fix(plugin): satisfy Claude marketplace manifest schema 2026-05-31 17:23:57 +09:00
Donghun Seol
edb2892dda test(foresttrip-vacancy): harden availability output coverage 2026-05-29 21:05:31 +09:00
Donghun Seol
b2404e99be test(foresttrip-vacancy): add print_text regression coverage
라이브 불변식 검증(예비 제외·dedup·useDt 범위)이 통과한 뒤,
사용자 대면 출력 함수인 print_text가 테스트 0개였던 갭을 메운다.

- PrintTextTest 2개: 결과 렌더링 / 빈 결과 메시지
- stub_fetch는 fetch_one의 미사용 인자를 **_ 로 흡수해 lint 경고 제거

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 20:57:25 +09:00
Donghun Seol
00a6d9feae fix(foresttrip-vacancy): exclude 예비 rooms, gate useDt strictly, dedup duplicate rooms
월별예약조회 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>
2026-05-29 20:57:25 +09:00
Jeffrey (Dongkyu) Kim
3d8008f2f2 Harden KTX seat detail trust boundaries
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
2026-05-29 01:55:52 +09:00
Jeffrey (Dongkyu) Kim
f8401ef405 Fail clearly at KTX seat payload boundaries
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.
2026-05-29 01:41:33 +09:00
Jeffrey (Dongkyu) Kim
1d4b2eb723 Keep KTX seat lookup typing from obscuring review signals
The seat inspection follow-up already fixed the runtime schema issues, but review still had changed-area pyright noise around the dynamic Korail boundaries. Route those calls through explicit narrow dynamic seams so the remaining pyright output stays confined to the existing baseline.\n\nConstraint: PR #296 follow-up must preserve the existing korail2 dynamic runtime behavior while cleaning the reviewed changed area.\nRejected: Broad pyright baseline cleanup | outside issue #292 scope and higher risk for this follow-up.\nConfidence: high\nScope-risk: narrow\nDirective: Keep future Korail mobile endpoint additions behind explicit typed/dynamic boundaries so changed-area diagnostics remain actionable.\nTested: PYTHONPATH=.:scripts PYTHONNOUSERSITE=1 python3 -m unittest discover -s scripts -p 'test_ktx_booking.py'; 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; node --test scripts/skill-docs.test.js; git diff --check origin/dev...HEAD; ruff check scripts/ktx_booking.py scripts/test_ktx_booking.py; PYTHONPATH=.:scripts python3 scripts/ktx_booking.py seats --help; pyright changed-area grep against search/seat lines\nNot-tested: live authenticated Korail seat lookup; full pyright remains on existing dynamic Korail/test-helper baseline
2026-05-29 01:30:33 +09:00