Install
$ agentstack add skill-djfksjd-sole-search-sole-search ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
sole-search — 소상공인 지원사업 조사
> 스크립트 위치: ${CLAUDE_PLUGIN_ROOT}/skills/sole-search/scripts/ (단독 스킬 설치 시 스킬 디렉토리 자체). 아래 명령의 경로 변수를 환경에 맞게 치환해 실행한다.
이 스킬은 "룰베이스 수집 + LLM 판정" 구조다. 스크립트는 공고를 기계적으로 수집만 하고, 선별·자격 판정·보고서는 에이전트(너)가 한다.
세 가지 원칙 (위반 금지):
- 조용한 누락 금지 — 커버하지 못한 소스·읽지 못한 첨부는 보고서에 명시한다. 모든 보고서에 coverage_manifest가 있어야 한다.
- 추정 금지 — 공고 원문에 없는 것은 '불명'. 첨부를 읽지 못했으면
확인됨판정 금지. - 허위신청 유도 금지 — "변형하면 가능" 식 프레이밍을 쓰지 않는다. 실제 등록업종·영업내용이 뒷받침되는 것만 후보다.
0단계 — 프로필
먼저 현재 작업 폴더에서 sole-profile.md를 찾는다. 있으면 본문 요약을 보여주고 "바뀐 것 있나요?" 한 번만 묻고 1단계로 간다.
없으면 쉬운 말로, 관공서 용어 없이, 한 번에 묻는다 (이미 대화·폴더에서 파악된 항목은 제외):
- 무슨 장사/사업을 하세요? (예: 치킨집, 네일샵, 스마트스토어)
- 개인사업자세요, 법인이세요? 지금 정상 영업 중이세요?
- 가게는 어느 동네예요? (시·군·구까지. 사업자등록상 주소가 다르면 둘 다)
- 사업자 등록은 언제 하셨어요? (년·월)
- 직원은 몇 명이에요? (4대보험 가입 기준과, 가족·알바 포함 인원을 구분해서)
- 혹시 소상공인확인서(중소기업현황정보시스템 발급) 있으세요? 유효기간은?
- (확인서 없으면) 작년 매출이 대략 어느 정도예요? — 3천만 미만 / 3천만~1억 / 1억~5억 / 5억~10억 / 10억~30억 / 30억 이상
- 대표님 나이대와 성별은? (건너뛰어도 됨)
- 지금 제일 필요한 건? (복수) — 안 갚는 돈 / 빌리는 돈 / 가게 시설 / 온라인 판매 / 홍보 / 배우기 / 정리·재기
확정되면 sole-profile.md로 저장한다. YAML 프론트매터는 원자 필드로 쓴다:
---
schema_version: 1
type: sole-search-profile
entity_type: individual | corporation
business_status: active | suspended | closing | closed
closure_date: YYYY-MM # closed일 때만
industry_text:
industry_code_candidates:
- {code: , label: , confidence: high|medium|low}
registration_date: YYYY-MM
regular_employee_count: # 4대보험 기준
headcount: # 가족·알바 포함
employee_count_as_of: YYYY-MM-DD
sbiz_certificate: none | valid | expired
sbiz_certificate_valid_until: YYYY-MM-DD
sales_band: lt_30m | 30m_100m | 100m_500m | 500m_1b | 1b_3b | gte_3b
sales_period:
sales_basis: statutory_average | recent_year_proxy
sales_vs_industry_threshold: below | near | above | unknown
threshold_industry_code:
sales_threshold_as_of: YYYY-MM-DD
province:
district:
hq_district:
owner_age_band: 20s|30s|40s|50s|60s_plus|unspecified
owner_gender: female | male | unspecified
needs: [grant, loan, facility, online_sales, marketing, education, recovery]
last_survey_at: YYYY-MM-DD
last_survey_dir:
survey_sources: [sbiz24, sbiz24_combine, bizinfo, fanfandaero] # 서울이면 + seoulshinbo, API 키 등록 시 + gov24
---
# sole-search 프로필
소상공인 법적 판정 우선순위: ① 유효한 소상공인확인서 → 확정 ② 법령상 기준기간 평균매출액(statutoryaverage) 근거가 있으면 상시근로자 기준(업종별 5인/10인 미만)과 평균매출액 기준을 함께 판정 ③ 최근 1년 근사치(recentyear_proxy)만 있으면 below라도 법적 지위는 '확인 필요' — 이전 연도 매출 때문에 법령상 평균이 기준을 넘을 수 있다.
개인정보 최소화: 세금 체납·대출액·신용점수는 묻지 않는다. 정책자금 후보가 나온 뒤 "이 요건 해당되세요?"로만 확인하고, 답을 프로필에 저장하지 않는다. 출생연월도 저장하지 않는다.
재조사 (diff 모드)
프로필의 last_survey_dir가 있으면 전수 재검토 대신 증분 조사:
- 직전과 같은 소스 구성으로 1단계 크롤링을 그대로 실행 (새 보고서 폴더에)
- 비교:
``bash python3 "${CLAUDE_PLUGIN_ROOT}/skills/sole-search/scripts/diff_surveys.py" \ --out new_items.jsonl \ --old-profile --new-profile sole-profile.md ``
- 검토·상세검증은
new_items.jsonl(NEW+CHANGED+NEEDS_REHASH)만. UNCHANGED는 직전 판정 승계.
단 프로필 fingerprint가 바뀌었다는 WARNING이 나오면 전체 재판정
- NEEDSREHASH = 직전 조사에 contenthash가 있었는데 새 목록엔 아직 없음. 목록 필드만으로
같아 보여도 본문·첨부가 바뀌었을 수 있으니 상세 재수집(detail --merge-into) 후 해시를 채우고 재비교한다 — 그때 같으면 승계, 다르면 변경 처리
- 정책자금(loan) 전체와 직전
확인됨항목은 diff 결과와 무관하게 접수상태를 재확인 - 보고서: 신규 / 변경(마감·조건 — changed_fields 표기) / 소멸된 확인됨 항목(기회 소멸 알림) / 승계 요약.
WARNING(미갱신 소스)은 coverage_manifest에 "미갱신" 명시
1단계 — 수집
mkdir -p survey-$(date +%Y%m%d)/details && cd survey-$(date +%Y%m%d)
# 소상공인24: 소진공 공고 + 통합조회(지자체·유관기관 포함) — 필수
python3 "${CLAUDE_PLUGIN_ROOT}/skills/sole-search/scripts/sbiz_crawl.py" list all -o sbiz24.jsonl
# 기업마당: 모집중 전체 전 페이지 (~96p, 2~3분) — 필수
python3 "${CLAUDE_PLUGIN_ROOT}/skills/sole-search/scripts/sources_crawl.py" list -o bizinfo.jsonl
# 판판대로: 온라인판로 사업목록 + 세부·수시 모집공고 게시판 — 권장
# (--since: 첫 조사는 1년 전, 재조사는 직전 조사일)
python3 "${CLAUDE_PLUGIN_ROOT}/skills/sole-search/scripts/region_crawl.py" list fanfan \
-o fanfandaero.jsonl --since
# 서울신보: 프로필 province가 서울일 때만 — 권장 (서울시 사업 공고 원출처)
python3 "${CLAUDE_PLUGIN_ROOT}/skills/sole-search/scripts/region_crawl.py" list seoulshinbo \
-o seoulshinbo.jsonl --since
# 보조금24: 선택 소스 (API 키 등록 시에만 — 상시 수혜 제도 커버)
python3 "${CLAUDE_PLUGIN_ROOT}/skills/sole-search/scripts/gov24_crawl.py" list \
-o gov24.jsonl --filter-target 소상공인
게시판형 소스(판판대로 공지·서울신보)는 접수기간이 목록에 없어 status가 불명으로 수집된다 — 선별에서 제목·게시일로 1차 거르고, candidate는 상세에서 접수 여부를 확인한다. --since 컷오프를 쓴 조사는 coverage_manifest에 컷오프 날짜를 명시한다 (전수 아님을 표기).
보조금24는 선택 소스: 종료 코드 4(미활성)면 coverage_manifest에 미활성(선택 소스, API 키 미등록)으로 기록하고 보고서 한계에 활성화 방법 (data.go.kr 15113968 활용신청 → DATA_GO_KR_API_KEY 또는 ~/.config/sole-search/api_key)을 한 줄 안내한다. 활성 시 상시 제도는 보고서에 "상시 혜택(보조금24)" 별도 섹션으로 다룬다 — 마감 기준 정렬인 "오늘 신청할 것"과 섞지 않는다. 키를 프로필·보고서 폴더에 저장하지 않는다.
stderr의 TOTAL/COLLECTED/DUPLICATES·PAGES/CRAWLED를 기록한다 — coverage_manifest 재료다. 종료 코드 2는 부분 수집(partial)이다. 소스별 계약·수동확인 절차는 references/sources.md, 지역신보·지자체 포털은 references/region-registry.md 참조.
중복 제거: ① (발행기관, 공고번호) ② 정규화 canonical URL — 특히 sbiz24_combine의 PBLN_* ID는 bizinfo의 pblancId와 같은 공고다 ③ 제목+기관+접수기간 전부 일치. 애매하면 삭제하지 말고 묶어서 "동일 사업 추정 N건"으로 표기.
1.5단계 — 전수 선별 (screening)
100% 수집해도 일부만 읽으면 전수조사가 아니다:
- 수집된 모든 레코드를 배치(예: 100건씩)로 나눠 빠짐없이 읽는다. 제목 키워드로 자동 제외 금지
- 각 레코드에
screening: candidate | excluded | needs_detail+ 제외 사유를 붙여screening.jsonl로 저장 - 프로필의 needs·업종·지역과 명백히 무관해도 "excluded + 사유"로 기록하고 넘어간다 (조용히 버리지 않는다)
- 중단되면 어디까지 검토했는지 기록하고 coverage를 partial로 보고
- 모델 분기(비용 최적화): 선별은 거친 1차 통과라 서브에이전트를 저비용 모델(Claude Code면
model: haiku)로 돌려도 된다 — 실수는 2단계 판정에서 걸러진다. 단 방향이 중요하다: 애매하면 excluded가 아니라 candidate/needs_detail로 (과소 선별은 2단계가 못 되살린다). 2단계 자격 판정은 원문·첨부 해석이 필요하므로 세션 기본 모델을 유지한다
2단계 — 자격 판정
candidate와 needs_detail 레코드는 상세 원문을 확인한다:
# 소상공인24 상세+첨부 (첨부 자동 다운로드 + 목록 jsonl에 content_hash 병합)
python3 ".../scripts/sbiz_crawl.py" detail --download-dir details \
-o details/.json --merge-into sbiz24.jsonl
# 기업마당 상세 (본문 해시·첨부 링크를 목록에 병합)
python3 ".../scripts/sources_crawl.py" detail "" -o details --merge-into bizinfo.jsonl
# 판판대로·서울신보 상세 (canonical_url로 소스 자동 판별, 소스별 jsonl에 병합)
python3 ".../scripts/region_crawl.py" detail "" -o details --merge-into .jsonl
# 첨부 텍스트 추출 (HWP는 실패가 정상 — 그 후보는 '확인 필요')
python3 ".../scripts/attach_extract.py" details/ -o details/.txt
판정 상태 5단계:
| 상태 | 의미 | |---|---| | 확인됨 | 공고 원문(첨부 포함)에서 모든 필수 신청자격 충족 확인 | | 조건부 | 구체 요건 충족 시 가능 (예: 교육 이수 후) — 요건 명시 | | 확인 필요 | 프로필 또는 원문 부족 — 부족한 항목 명시 | | 신청 불가 | 필수요건 불충족 — 근거 문구 인용 | | 사업전환 후보 | 실제 사업전환 전제 — 별도 섹션, 기본 비표시 |
검증 축: 업종 제한(제외 업종), 업력(공고 기준일로 산정), 상시근로자 수, 매출액 기준, 소재지(본점/사업장 구분), 기수혜 제외, 영업상태.
규칙:
- 판정 상태는 위 5개 중 정확히 하나 — '정보성', '조건부/확인 필요' 같은 비표준·복합 상태 금지.
직접 신청 대상이 아닌 통합·메타 공고는 선별 단계에서 excluded(사유: 메타 공고, 세부공고로 신청) 처리
- 접수 마감이 확정된 후보는 상세검증을 생략할 수 있다 — 단 보고서에 건수·대표 목록·
"차기 재조사 우선확인 대상"을 명시한다 (조용한 생략 금지)
- 첨부를 읽지 못한 후보(
attachments_complete: false포함)는확인됨금지 →확인 필요+ "첨부 미확인(사유)" - status가
불명인 레코드는 접수 여부부터 상세에서 확인 — 크롤러는 낙관 추정하지 않는다 - 크롤러 종료 코드 3(MANUAL)은 차단 신호다 — 재시도하지 말고 해당 소스를 manual로 기록
- 각 판정에 근거 출처(문서·문구)를 기록
확인됨= 공고상 신청자격 확인일 뿐, 선정·대출심사 통과 예측이 아님 — 보고서에 명시- 연락처는
contacts: [{kind: phone|email|url, value}], 없으면 "연락처 미기재" - 유형은
primary_type(grant|loan|advisory) + tags. loan에는 한도·금리(기준일)·기간·
거치·상환방식·보증기관을 채우고, 회차 접수상태는 sources.md의 수동확인 절차를 따른다
3단계 — 보고서
survey-YYYYMMDD/report.md. 사장님이 읽는 문서 — 관공서 용어에 괄호 해설. 구조:
- 오늘 신청할 것 — 전 유형 통합
확인됨목록. 정렬: 마감 D-day 오름차순 →
예산소진 시까지("서두르세요") → 상시 → 회차예정(예정일). 각 항목: 제목, 한 줄 요약, 금액/혜택, 마감, 신청 방법·링크, 연락처. 확인됨 목록 뒤에 남은 조건이 1개뿐인 조건부를 별도 하위 목록(🔶 "조건 1개만 채우면 됨")으로 붙일 수 있다 — 확인됨과 섞지 말고, 각 항목 첫 줄에 남은 조건을 명시하며, 정렬 규칙은 동일 적용
- coverage_manifest — 소스별
collection_status와screening_status
(success|partial|failed|manual), collected/screened/candidate/detail_verified 카운트. 카운트는 소스별로 기재 — "(합산)" 뭉개기 금지. 중복 제거 시 어느 소스에 귀속했는지 설명해 수집→선별 합계가 재검산 가능해야 한다. partial·manual·미갱신은 사유 명시. partial인 소스를 "전수 수집 완료"로 표현 금지. 미커버 영역(미등록 지자체 포털 등) 한계 고지
- 유형별 상세 — 💰 받는 돈 / 🏦 빌리는 돈 / 🎓 배우고 돕기 순, 각 유형 안에서 판정 상태순.
🏦에는 "갚아야 하는 돈입니다" 문구 + 한도·금리(기준일)·기간·취급기관 필수
- 사업전환 후보 — 해당 시에만. 그 외 부가 정보(공통 준비물, 마감 후보 목록 등)는
번호 없는 "비고"로 붙인다
보고서 자가 점검 — 작성 직후 아래를 전부 확인하고, 어긋난 항목은 고친 뒤 완료 선언:
- 판정 상태에 5개 enum 외 값·복합 표기 없음 (항목당 정확히 하나)
- "오늘 신청할 것"에서 확인됨/🔶조건부가 구분돼 있고 정렬 규칙(D-day 오름차순 → 예산소진 → 상시 → 회차예정) 준수
- coverage_manifest 카운트가 소스별로 채워져 있고 수집→선별 합계가 재검산됨
- 첨부 미추출 항목 전부가 상세 표에
확인 필요로 존재 (coverage 언급과 상세 표 판정 일치) 확인 필요판정에 "실무상 문제 가능성 낮음" 류의 추정 보완 문구 없음 — 부족한 항목과 확인 방법만 적는다- 사장님용 본문에 내부 식별자(idx, candidate, needs_detail 등) 노출 최소화 — 감사 정보는 산출 파일에 있다
완료 후 프로필의 last_survey_at·last_survey_dir를 갱신한다.
중단선
403·CAPTCHA·로그인 요구를 만나면 우회(TLS 지문 변경, 내부 API 반복 재시도)하지 않는다. 해당 소스를 manual로 전환하고 sources.md의 수동확인 절차를 보고서에 첨부한다.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: djfksjd
- Source: djfksjd/sole-search
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.