- BCCARD_EATPL_API_BASE_URL is now required on both the proxy and the Lightsail relay; missing config fails closed with 503 upstream_not_configured / relay_not_configured instead of hitting the unreachable dev endpoint
- proxy responses no longer embed the relay/upstream URL in upstream.url; provider and status_code remain
- relay answers 413 payload_too_large for bodies over 16KB instead of silently destroying the request
pin 된 업스트림의 한글 이용약관 템플릿이 0바이트라 한국어 경로에서
약관 생성이 조용히 불가능한 문제(#660)에 대해, 이슈 제안 2·3안을 구현한다.
- install.sh: pin 검증 직후 *.tmpl 0바이트 파일을 찾아 경고로 표면화
(다른 경로는 정상 생성되므로 설치는 계속)
- instruction.md Failure modes 에 한글 약관 템플릿 누락과 해소 조건
(upstream pin bump) 명시
- docs/features/korean-privacy-terms.md 에 알려진 한계 절 추가
- skill-docs 테스트 2건 추가 (TDD: 실패 확인 후 구현)
- CLI 번들 동기화 + 스냅샷 갱신 + changeset(patch)
검증: 신규 테스트 2건 통과, lint·typecheck·validate-skills 통과,
워크스페이스 테스트 96건 통과, 루트 node 테스트 205/206
(1건은 Python 3.11+ 요구 store_longevity_mirror의 환경성 기존 실패,
clean dev 에서도 동일 재현).
Require Authorization Bearer on the Lightsail relay and fail closed in
k-skill-proxy when the relay URL is set without BCCARD_EATPL_RELAY_TOKEN.
Skill output must show nationwide/local sales percentiles, expected hours,
and merUrl on every row.
Ultraworked with [omo](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
m.map.kakao.com 모바일 웹 스크래핑(비공식, 구조 변경 시 파손 리스크)을
k-skill-proxy의 공식 Kakao Local keyword 검색으로 교체한다.
- anchor 해석과 시설 검색 모두 /v1/kakao-map/search/keyword 사용
- sort=distance + 공식 distance 필드 → haversine 직접 계산 제거
- category_name의 "종교" 노드 필터 유지 (써브웨이 명동성당점류 오탐 차단)
- --type 전체는 "종교시설" 단일 키워드가 교회·사찰을 놓쳐
교회/성당/사찰 3쿼리 병합 + id dedupe, 토큰별 빈 결과는 격리
- --limit 상한 15 → 45 (15건/페이지 × 최대 3페이지)
- --radius 상한 20000 검증 추가 (Kakao Local API 상한)
- homepage는 Local API 미제공으로 null, place_url로 안내
- profiles에 proxy 추가, instruction/docs/sources 갱신
- 테스트를 mock 프록시 응답 기준 24개로 재작성
검증: unittest 24/24, npm run ci exit 0,
강남역/명동 성당/경주 절/온누리교회/성수동 전체 라이브 조회 확인
hostname -s on the production box is marker-multi-gpu-server-01, and
cron does not set KSKILL_PROXY_DEPLOY_HOST, so the watchdog and
trust-proxy default were no-ops. Accept that hostname, keep the cron
env contract, export the user-bus vars cron needs for systemctl, and
persist the proxy unit as Restart=always.
Ultraworked with [omo](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
The 2026-08-29 gpu01 reboot left the public proxy (530) and dashboard
(502) dead for ~10 days. Only the Fastify proxy recovered, because the
deploy cron `restart`s it every run; the tunnel and Loki/Grafana/
Promtail stack used Restart=on-failure, which does not revive a clean
SIGTERM, and nothing else ever started them.
- dashboard systemd units: Restart=on-failure -> always,
StartLimitIntervalSec=0
- commit the previously host-only cloudflared tunnel unit, hardened
with Restart=always, StartLimitIntervalSec=0, and RequiresMountsFor=
on the gpu02:/data NFS paths
- deploy cron: ensure_production_services() starts any watched service
that is installed but inactive, on every run including SHA-noop runs
- document the watchdog and canonical unit locations
Closes#658
동네·역명·랜드마크를 기준으로 주변 교회·성당·사찰을 거리순 조회하는
Python 스크립트 유형 스킬. 카카오 무인증 공개 표면 2단계를 사용하므로
사용자 API 키와 k-skill-proxy 경유가 모두 불필요하다.
- searchView HTML의 data-cid → place panel3 JSON으로 좌표·주소·연락처 확보
- category.name2 == "종교" 필터로 동명 카페·서점 오탐 제거
- 거리는 upstream 값 대신 기준점 좌표와 haversine으로 직접 계산
- 조회 결과는 필터 통과 수와 표시 수를 구분해 보고
- 예배·미사·법회 시간, 교단 소속, 좌표 입력은 미지원으로 명시
- --limit은 upstream 상한 15를 넘으면 명시적으로 거부
- 종교·교단의 우열 평가와 이단 판별을 하지 않음을 instruction에 고정
README에 종교 카테고리를 신설하고, 스킬 개수를 검증하는 카운터
4곳(README 총계, skill-docs.test.js, cli.test.js assetSkills,
runtime-action-audit 서두·lookup 집계)과 audit 카탈로그를 함께 갱신했다.
helper는 Python 표준 라이브러리만 사용하며 새 의존성이 없다.
Drop dead --vessel-code/--route-code/--port-code flags that the official
MTIS allowlist does not accept, return 400 instead of silently caching
distinct queries together, expose komsaConfigured on /health, pin the
health rate limit, and correct the README skill count to 123.
Ultraworked with [omo](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
The KOMSA route accidentally replaced kamisApiKey in buildConfig and
dropped normalizeMofaTravelAlarmQuery from module.exports. Keep both
alongside the new KOMSA symbols, and add the missing komsa changeset.
Ultraworked with [omo](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
* docs: categorize README skill catalog by Korean life domains
- Split the single 123-row skill table into 20 domain tables
(transit/travel, real estate, legal, business, government support,
finance, health, shopping, food, sports, culture, education, news,
Korean writing, weather, daily-life, dev/docs, fortune, meta)
- Drop the duplicated '포함된 기능' link list; the tables are the catalog
- Keep every row text and doc link verbatim; adjust the rhwp-edit
README assertions to the guide-link form that remains in the tables
* docs: merge doc links into the first catalog column and drop the category listing
- Remove the one-line category summary at the top of the catalog
- Promote category headings from h4 to h3 for prominence
- Drop the separate '문서' column in every table; each '할 수 있는 일'
cell now links directly to its feature guide
- Update README pins in scripts/skill-docs.test.js to the merged
link-first row shape (row text and doc targets unchanged)
* docs: drop the 사용자 로그인 column from the skill catalog
- Tables shrink to 3 columns (할 수 있는 일 | 스킬 이름 | 설명);
login requirements stay in each feature guide
- Remove the obsolete login-column explanation paragraph
- Update README pins that asserted 불필요 values and the table
header shape