k-skill/docs/features/local-election-candidate-search.md
Jeffrey (Dongkyu) Kim 68abad3de0
Feature/#256 (#266)
* Enable public local-election candidate lookups

Add an NEC integrated-search skill and helper package so agents can answer 지방선거 후보자 lookup requests without credentials or proxy routes.

Constraint: Issue #256 requested TDD, Ralph completion, branch feature/#256, and PR targeting dev.

Rejected: k-skill-proxy route | NEC integrated candidate search is public and requires no API key.

Confidence: high

Scope-risk: moderate

Directive: Keep the helper read-only and do not automate NEC login, CAPTCHA, filing, or privileged election workflows.

Tested: git diff --check; node --test packages/local-election-candidate-search/test/index.test.js; npm run lint --workspace local-election-candidate-search; npm run test --workspace local-election-candidate-search; npm pack --workspace local-election-candidate-search --dry-run; node packages/local-election-candidate-search/src/cli.js 오세훈 --election 시도지사 --region 서울 --limit 1; PATH=/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin:/Users/jeffrey/.codex/tmp/arg0/codex-arg0a6JueA:/opt/homebrew/lib/node_modules/@openai/codex/node_modules/@openai/codex-darwin-arm64/vendor/aarch64-apple-darwin/path:/Users/jeffrey/.cmuxterm/omo-bin:/opt/homebrew/share/android-commandlinetools/platform-tools:/opt/homebrew/share/android-commandlinetools/emulator:/opt/homebrew/share/android-commandlinetools/cmdline-tools/latest/bin:/Users/jeffrey/.local/bin:/Users/jeffrey/.bun/bin:/opt/homebrew/opt/node@22/bin:/opt/homebrew/opt/openjdk@21/bin:/opt/homebrew/opt/postgresql@18/bin:/Users/jeffrey/.jenv/shims:/Users/jeffrey/.jenv/bin:/opt/homebrew/opt/imagemagick/bin:/opt/homebrew/Cellar/pyenv-virtualenv/1.4.0/shims:/Users/jeffrey/.pyenv/shims:/opt/homebrew/opt/openssl@3/bin:/Users/jeffrey/.rbenv/shims:/Users/jeffrey/.rbenv/bin:/Users/jeffrey/google-cloud-sdk/bin:/Applications/cmux.app/Contents/Resources/bin:/Users/jeffrey/Library/pnpm:/Users/jeffrey/.nvm/versions/node/v24.13.0/bin:/Users/jeffrey/.cops/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/opt/pmk/env/global/bin:/Library/Apple/usr/bin:/Library/TeX/texbin:/Users/jeffrey/.cargo/bin:/Users/jeffrey/Library/Application Support/JetBrains/Toolbox/scripts:/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home/bin:/Users/jeffrey/xcode-projects/marshroom/cli npm run ci

Not-tested: Exhaustive NEC markup variants for every historical election type.

Co-authored-by: OmX <omx@oh-my-codex.dev>

* Enforce fail-closed candidate identity parsing

Constraint: PR #266 review required exact candidate-name matching and CLI help regression coverage.\nRejected: fallback-to-query-name on missing upstream markup | it can mislabel unrelated candidates as exact matches.\nConfidence: high\nScope-risk: narrow\nDirective: Keep NEC parser changes fail-closed when candidate identity cannot be parsed.\nTested: git diff --check; node --test packages/local-election-candidate-search/test/index.test.js; npm run lint --workspace local-election-candidate-search; npm run test --workspace local-election-candidate-search; npm pack --workspace local-election-candidate-search --dry-run; live CLI smoke for 오세훈; CLI --help smoke.\nNot-tested: repo-wide npm run ci remains blocked by pre-existing missing SKILL.md: ohou-today-deal.

* Preserve unique candidate lookup results

Deduplicate parsed NEC candidate/election rows before applying user limits, and make expected CLI validation failures concise by default while keeping an explicit debug stack escape hatch.

Constraint: PR #266 round-2 follow-up requested TDD fixes for duplicate NEC rows and CLI validation UX.\nRejected: Deduplicating after limit | would still allow duplicates to crowd out unique rows.\nRejected: Always printing stack traces | exposes local paths for normal user-input failures.\nConfidence: high\nScope-risk: narrow\nDirective: Keep dedupe keys stable enough to avoid collapsing legitimately distinct historical election rows.\nTested: git diff --check; node --test packages/local-election-candidate-search/test/index.test.js; npm run lint --workspace local-election-candidate-search; npm run test --workspace local-election-candidate-search; npm pack --workspace local-election-candidate-search --dry-run; live 오세훈 smoke; live 김동연 duplicate repro; CLI no-args/help.\nNot-tested: Full npm run ci remains blocked by pre-existing missing SKILL.md: ohou-today-deal.

* Prevent filtered NEC lookup false negatives

Fix the candidate parser so documented education-superintendent and filtered local-election lookups return bounded, evidence-backed results instead of silently dropping valid rows.

Constraint: PR #266 round-3 review required TDD, Ralph verification, and branch update for issue #256.

Rejected: Full NEC pagination in this follow-up | broader than the approved change; bounded 100-row fetch now avoids user-limit false negatives and warns when capped.

Confidence: high

Scope-risk: narrow

Directive: Preserve exact-name fail-closed parsing and count raw parsed upstream rows before cap-warning decisions.

Tested: git diff --check; node --test packages/local-election-candidate-search/test/index.test.js; npm run lint --workspace local-election-candidate-search; npm run test --workspace local-election-candidate-search; npm pack --workspace local-election-candidate-search --dry-run; live CLI smokes for 오세훈, 조희연, 김동연; CLI help/no-args checks; architect verification CLEAR.

Not-tested: Full npm run ci remains blocked by pre-existing repo-wide missing SKILL.md: ohou-today-deal.

---------

Co-authored-by: OmX <omx@oh-my-codex.dev>
2026-05-18 23:11:23 +09:00

2.7 KiB

지방선거 후보자 조회 가이드

local-election-candidate-search는 중앙선거관리위원회 선거통계시스템(info.nec.go.kr)의 공개 통합검색 HTML 표면을 직접 조회하는 read-only 스킬이다. upstream이 인증/키 없이 열려 있는 공개 표면이므로 k-skill-proxy를 사용하지 않는다.

공개 접근 경로

  • 진입점: https://info.nec.go.kr/search/searchCandidate.xhtml
  • 방식: POST searchKeyword=<정확한 후보자 성명>
  • 기본 정책: 지방선거 관련 선거코드만 반환
    • 3 시·도지사선거
    • 4 구·시·군의 장선거
    • 5 시·도의회의원선거
    • 6 구·시·군의회의원선거
    • 8 광역의원비례대표선거
    • 9 기초의원비례대표선거
    • 11 교육감선거

이 경로는 NEC 화면에 공개된 후보자 성명 기반 통합검색이며, 선거별 메뉴에서 모든 시도/구시군/선거구 조합을 먼저 선택하는 방식보다 조회 진입점이 좁고 안정적이다.

CLI 사용

node packages/local-election-candidate-search/src/cli.js 오세훈 --election 시도지사 --region 서울 --limit 5
node packages/local-election-candidate-search/src/cli.js 김동연 --date 2014 --election 기초의원 --region 동작
node packages/local-election-candidate-search/src/cli.js 이재명 --all --limit 20

패키지 설치 후에는 bin 이름을 사용할 수 있다.

local-election-candidate-search 오세훈 --election 시도지사 --region 서울

Node API

const { searchCandidates } = require("local-election-candidate-search")

const result = await searchCandidates({
  name: "오세훈",
  election: "시도지사",
  region: "서울",
  limit: 5
})

출력 필드

반환 JSON의 items[]에는 upstream HTML에 있는 범위에서 다음 필드가 포함된다.

  • name, hanja, birth_date, gender
  • election_date, election_name, election_code, election_type
  • party, district, votes, vote_share, elected
  • job, education, career[]
  • city_code, sgg_city_code, town_code

실패 모드와 주의사항

  • NEC 통합검색은 정확한 후보자명을 기준으로 동작하므로 동명이인이 나올 수 있다. 결과를 보여줄 때는 선거일·선거종류·지역을 함께 표시한다.
  • 사용자가 범위를 좁히면 --election, --date, --region 필터를 적용한다.
  • --all을 주지 않으면 지방선거 관련 선거코드만 반환한다.
  • 빈 결과, NetFunnel 대기열, 점검/로그인/차단 페이지, upstream HTML 변경은 warnings[]에 명시한다.
  • 로그인, CAPTCHA, 후보 등록/신고, 파일 다운로드, 정치 자금/선거 사무 자동화는 하지 않는다.