# Sole Search

> 운영 중인 소상공인(가게·점포·자영업자)을 위한 지원사업 조사 스킬. 소상공인24·기업마당 공고를 전수 수집하고 가게 프로필(업종·지역·업력·직원수·매출)로 자격을 판정해 "오늘 신청할 것"부터 보고한다. 보조금·바우처, 정책자금(대출·보증), 교육·컨설팅 전 범위. 사용자가 "우리 가게 지원사업", "소상공인 지원금", "정책자금 알아봐줘", "가게 시설개선 지원", "사장님 지원 뭐 있어", "소상공인24 조사", "폐업/재기 지원" 등을 요청하면 이 스킬을 사용한다. 재조사("새로 나온 거 있나", "지난번 이후 뭐 올라왔나")는 diff 모드로 사용. 반대로 "우리 아이템", "창업지원", "예비창업", "K-Startup", "TIPS", "R&D 과제", "입주공간", "액셀러레이팅" 등 아이템…

- **Type:** Skill
- **Install:** `agentstack add skill-djfksjd-sole-search-sole-search`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [djfksjd](https://agentstack.voostack.com/s/djfksjd)
- **Installs:** 0
- **Category:** [Search](https://agentstack.voostack.com/c/search)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [djfksjd](https://github.com/djfksjd)
- **Source:** https://github.com/djfksjd/sole-search/tree/main/skills/sole-search

## Install

```sh
agentstack add skill-djfksjd-sole-search-sole-search
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# sole-search — 소상공인 지원사업 조사

> **스크립트 위치**: `${CLAUDE_PLUGIN_ROOT}/skills/sole-search/scripts/` (단독 스킬 설치 시 스킬 디렉토리 자체). 아래 명령의 경로 변수를 환경에 맞게 치환해 실행한다.

이 스킬은 "룰베이스 수집 + LLM 판정" 구조다. 스크립트는 공고를 기계적으로 수집만 하고,
선별·자격 판정·보고서는 에이전트(너)가 한다.

세 가지 원칙 (위반 금지):

1. **조용한 누락 금지** — 커버하지 못한 소스·읽지 못한 첨부는 보고서에 명시한다. 모든 보고서에 coverage_manifest가 있어야 한다.
2. **추정 금지** — 공고 원문에 없는 것은 '불명'. 첨부를 읽지 못했으면 `확인됨` 판정 금지.
3. **허위신청 유도 금지** — "변형하면 가능" 식 프레이밍을 쓰지 않는다. 실제 등록업종·영업내용이 뒷받침되는 것만 후보다.

## 0단계 — 프로필

**먼저 현재 작업 폴더에서 `sole-profile.md`를 찾는다.** 있으면 본문 요약을 보여주고
"바뀐 것 있나요?" **한 번만** 묻고 1단계로 간다.

없으면 쉬운 말로, 관공서 용어 없이, **한 번에** 묻는다 (이미 대화·폴더에서 파악된 항목은 제외):

1. 무슨 장사/사업을 하세요? (예: 치킨집, 네일샵, 스마트스토어)
2. 개인사업자세요, 법인이세요? 지금 정상 영업 중이세요?
3. 가게는 어느 동네예요? (시·군·구까지. 사업자등록상 주소가 다르면 둘 다)
4. 사업자 등록은 언제 하셨어요? (년·월)
5. 직원은 몇 명이에요? (4대보험 가입 기준과, 가족·알바 포함 인원을 구분해서)
6. 혹시 소상공인확인서(중소기업현황정보시스템 발급) 있으세요? 유효기간은?
7. (확인서 없으면) 작년 매출이 대략 어느 정도예요? — 3천만 미만 / 3천만~1억 / 1억~5억 / 5억~10억 / 10억~30억 / 30억 이상
8. 대표님 나이대와 성별은? (건너뛰어도 됨)
9. 지금 제일 필요한 건? (복수) — 안 갚는 돈 / 빌리는 돈 / 가게 시설 / 온라인 판매 / 홍보 / 배우기 / 정리·재기

확정되면 `sole-profile.md`로 저장한다. **YAML 프론트매터는 원자 필드**로 쓴다:

```markdown
---
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 프로필

```

**소상공인 법적 판정 우선순위**: ① 유효한 소상공인확인서 → 확정 ② 법령상 기준기간
평균매출액(statutory_average) 근거가 있으면 상시근로자 기준(업종별 5인/10인 미만)과
평균매출액 기준을 함께 판정 ③ **최근 1년 근사치(recent_year_proxy)만 있으면 below라도
법적 지위는 '확인 필요'** — 이전 연도 매출 때문에 법령상 평균이 기준을 넘을 수 있다.

**개인정보 최소화**: 세금 체납·대출액·신용점수는 묻지 않는다. 정책자금 후보가 나온 뒤
"이 요건 해당되세요?"로만 확인하고, 답을 프로필에 저장하지 않는다. 출생연월도 저장하지 않는다.

## 재조사 (diff 모드)

프로필의 `last_survey_dir`가 있으면 전수 재검토 대신 증분 조사:

1. **직전과 같은 소스 구성으로** 1단계 크롤링을 그대로 실행 (새 보고서 폴더에)
2. 비교:
   ```bash
   python3 "${CLAUDE_PLUGIN_ROOT}/skills/sole-search/scripts/diff_surveys.py" \
         --out new_items.jsonl \
       --old-profile  --new-profile sole-profile.md
   ```
3. 검토·상세검증은 `new_items.jsonl`(NEW+CHANGED+NEEDS_REHASH)만. UNCHANGED는 직전 판정 승계.
   단 **프로필 fingerprint가 바뀌었다는 WARNING이 나오면 전체 재판정**
4. **NEEDS_REHASH** = 직전 조사에 content_hash가 있었는데 새 목록엔 아직 없음. 목록 필드만으로
   같아 보여도 본문·첨부가 바뀌었을 수 있으니 **상세 재수집(`detail --merge-into`) 후 해시를
   채우고 재비교**한다 — 그때 같으면 승계, 다르면 변경 처리
5. **정책자금(loan) 전체와 직전 `확인됨` 항목은 diff 결과와 무관하게 접수상태를 재확인**
6. 보고서: 신규 / 변경(마감·조건 — changed_fields 표기) / 소멸된 확인됨 항목(기회 소멸 알림) / 승계 요약.
   WARNING(미갱신 소스)은 coverage_manifest에 "미갱신" 명시

## 1단계 — 수집

```bash
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 레코드는 상세 원문을 확인한다:

```bash
# 소상공인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`. 사장님이 읽는 문서 — 관공서 용어에 괄호 해설. 구조:

1. **오늘 신청할 것** — 전 유형 통합 `확인됨` 목록. 정렬: 마감 D-day 오름차순 →
   예산소진 시까지("서두르세요") → 상시 → 회차예정(예정일). 각 항목: 제목, 한 줄 요약,
   금액/혜택, 마감, 신청 방법·링크, 연락처. `확인됨` 목록 **뒤에** 남은 조건이 1개뿐인
   `조건부`를 별도 하위 목록(🔶 "조건 1개만 채우면 됨")으로 붙일 수 있다 — 확인됨과
   섞지 말고, 각 항목 첫 줄에 남은 조건을 명시하며, 정렬 규칙은 동일 적용
2. **coverage_manifest** — 소스별 `collection_status`와 `screening_status`
   (`success|partial|failed|manual`), collected/screened/candidate/detail_verified 카운트.
   **카운트는 소스별로 기재 — "(합산)" 뭉개기 금지**. 중복 제거 시 어느 소스에 귀속했는지
   설명해 수집→선별 합계가 재검산 가능해야 한다. partial·manual·미갱신은 사유 명시.
   **partial인 소스를 "전수 수집 완료"로 표현 금지**. 미커버 영역(미등록 지자체 포털 등) 한계 고지
3. **유형별 상세** — 💰 받는 돈 / 🏦 빌리는 돈 / 🎓 배우고 돕기 순, 각 유형 안에서 판정 상태순.
   🏦에는 "갚아야 하는 돈입니다" 문구 + 한도·금리(기준일)·기간·취급기관 필수
4. **사업전환 후보** — 해당 시에만. 그 외 부가 정보(공통 준비물, 마감 후보 목록 등)는
   번호 없는 "비고"로 붙인다

**보고서 자가 점검** — 작성 직후 아래를 전부 확인하고, 어긋난 항목은 고친 뒤 완료 선언:

- 판정 상태에 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](https://github.com/djfksjd)
- **Source:** [djfksjd/sole-search](https://github.com/djfksjd/sole-search)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-djfksjd-sole-search-sole-search
- Seller: https://agentstack.voostack.com/s/djfksjd
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
