swapit — 가정용 유해물질 인벤토리 + 교체 엔진
이 스킬의 역할
swapit는 막연한 걱정("우리 집에 플라스틱과 BPA가 많을 거야")을 구체적이고 우선순위가 매겨진 추적 가능한 계획으로 바꿔줍니다. 상태 기반(stateful)입니다. 즉, 가정 인벤토리가 디스크에 저장되고 세션 간 유지됩니다. 로컬 우선(local-first)입니다. 즉, 유료 서비스가 전혀 필요 없으며, 명시적으로 (M3) 커먼스에 동의하지 않는 한 어떤 데이터도 기기를 떠나지 않습니다.
한 번 실행으로 다음을 생성합니다:
- 소유한 품목의 인벤토리 — 각 품목은 일반적인 품목 클래스로 태그됨.
- 실제 노출을 반영한 품목별 위험 점수 — 긁힌 코팅 팬을 매일 고온에서 사용하는 것이 차고에 있는 개봉되지 않은 플라스틱 통보다 훨씬 높은 점수를 받음.
- 순위가 매겨진 "먼저 교체할" 목록 — 노출을 가장 많이 줄이는 상위 5%의 변경 사항.
- 교체 추적 — 선택한 대체품, 조달 상태, 체크리스트, 북마크.
- 공유 가능한 HTML 보고서 (그리고 M2에서는
swapit serve로 라이브 대시보드 제공).
세 가지 영역 (그리고 개인정보 보호 불변 규칙)
| 영역 | 내용 | 공유 범위 |
|---|---|---|
| 1 · 지식 | 유해물질 → 품목 클래스 → 대체품 (일반적이고 인용된 사실) | 공유 가능; 캐시됨 + (M3) 커먼스 동기화됨 |
| 2 · 인벤토리 | 사용자의 품목, 방, 수량, 브랜드, 사진, 교체, 북마크 | 비공개 — 절대 기기를 떠나지 않음 |
| 3 · 커먼스(M3) | 공유 지식 그래프를 풍부하게 하는 익명화된 기여 | 선택적, 검토됨, 일반적인 사실만 |
개인정보 보호 불변 규칙(바인딩): 영역-2 인벤토리(품목, 방, 수량, 브랜드, 사진, 구매 정보, 위치)는 절대 동기화 경계를 넘지 않습니다. 오직 영역-1의 일반적인 사실만 공유 가능하며, 명시적 동의 + 검토 가능한
swapit sync --dry-run을 통해서만 가능합니다. 클라이언트의 허용 목록 직렬화기(scripts/anonymize.py)와 커먼스 서버의 백스톱, 그리고 모든 실제 인벤토리 항목이 게이트에서 거부되는지 확인하는 퍼즈 테스트에 의해 적용됩니다. 금지 필드 목록:anonymize.CONTRIBUTION_FORBIDDEN(state.PRIVATE_FIELDS의 인벤토리 구조 하위 집합).
데이터 모델
상태는 ~/.config/swapit/에 저장됩니다 ($SWAPIT_HOME으로 재정의 가능; $XDG_CONFIG_HOME을 존중합니다).
~/.config/swapit/
├── knowledge/ hazards.jsonl · item-classes.jsonl · alternatives.jsonl · products.jsonl · procurement.jsonl
├── inventory/ events.jsonl(추가 전용 감사) · items.json · swaps.json · rooms.json · bookmarks.json
├── contributions/ queue.jsonl (M3)
├── sync/ config.json · sync-log.jsonl (M3)
└── photos/
노드 스키마 (전체 인용 데이터셋은 seed/*.jsonl 참조):
- hazard —
id · name · aliases · class · mechanism · exposure_routes · regulatory · severity(0-3) · evidence_strength · sources - item_class —
id · name · category · description · hazards[]{hazard_id, presence_likelihood, rationale} · detection_hints · sources - alternative —
id · name · replaces[] · material · rationale · tradeoffs · caveats · avoids_hazards · residual_concerns · sources - procurement_option (공개 구매처) —
id · alternative · item_class · retailer · region(ISO-3166-1 a2) · area · url · price_min · price_max · currency · as_of · availability · confidence · corroboration_count - item (비공개) —
id · name · item_class · room · quantity · brand · condition · usage{frequency, food_contact, heat, child_contact} · status · notes · photos - swap (비공개) —
id · item_id · chosen_alternative · procurement{status, cost, vendor} · checklist[] · bookmarks[]
위험 모델
risk = severity × presence_likelihood × evidence × exposure_relevance × frequency × condition
- exposure_relevance는 유해물질의 노출 경로를 품목의 사용 방식에 따라 활성화합니다 (식품 접촉 + 열은 섭취/식품 접촉/열 유해물질을 최대화; 피부 접촉은 개인 관리 용품에 중요; 흡입은 청소/가구에 중요; 어린이 접촉은 증폭).
- 품목 점수 = 유해물질별 위험 합계 → 높음 / 중간 / 낮음 대역.
- 이것이 우선순위 지정 지능입니다 — procurer의 "지배적인 실패 모드"와 유사: 모든 플라스틱에 대한 죄책감 목록이 아니라 노출의 대부분을 유발하는 몇 가지 품목을 먼저 수정합니다.
모드
| 모드 | 기능 |
|---|---|
init | 상태 생성 + 시드 지식 그래프 로드 |
add | 가정 품목 추가 (이름, 클래스, 방, 상태, 사용 방식) → 평가 출력 |
assess | 품목 또는 임시 품목 클래스 평가 → 유해물질 + 위험 + 순위가 매겨진 대체품 |
list | 인벤토리 나열, --room/--band/--status/--class/--hazard로 필터링, 위험순 정렬 |
swap | 교체 계획 생성/업데이트: 대체품 선택, 상태 설정, 체크리스트, 북마크, 비용 |
score | 가정 노출 요약 + 우선 교체 순위 |
report | 독립형 HTML 보고서 생성 (Category-C) |
procure | procurer 핸드오프 브리핑 + 교체 대상에 대한 알려진 구매처 제공 (--region으로 필터링); 발견한 제안 기록 (--retailer/--url/--price-*) → 공개 커먼스에 추가 |
knowledge | 지식 그래프 검색/탐색 (list/search/show) |
rooms | 방 나열/추가 |
selfheal | 지식 엣지 + 인벤토리 참조 + 근거 유효성 검사; 오류 시 0이 아닌 종료 코드 반환 |
serve | 실시간 로컬 대시보드 (http://127.0.0.1:8731) — 칸반 보드, 체크리스트, 북마크, 상태; 모든 클릭이 상태에 다시 기록됨 |
contribute | 익명화된 사실을 큐에 추가 — product / hazard (item-class→hazard) / alternative / procurement (공개 구매처) / item-class (새 분류 노드); 로컬에 적용되고 커먼스용으로 게이트됨 |
sync | 기여 큐 푸시 + 커뮤니티 지식 풀 (선택적); --dry-run은 정확히 무엇이 전송될지 미리보기; --configure는 엔드포인트 설정 |
일반적인 흐름
swapit init
swapit add --name "오래된 테플론 팬" --class nonstick-cookware --room kitchen \
--condition scratched --frequency daily --food-contact --heat
swapit score # 무엇을 먼저 교체할지
swapit swap itm_xxxx --to cast-iron-skillet --status sourcing --add-task "10인치 스킬렛 구매"
swapit procure itm_xxxx # -> `procurer` 스킬에 브리핑 전달
swapit report --open # 공유 가능한 HTML
다른 스킬과의 결합
procurer—swapit procure <item>은 필요 사항 ("폴리카보네이트 병 3개를 유리/스틸로 교체")과 준비된 procurer 프롬프트를 구성합니다. procurer는 인용된 출처와 예산 범위를 반환합니다.bookkeeping(P6) — 새롭고 지속 가능한 유해물질/제품 발견(예: 새로 특성화된 품목 클래스)이 사전 예방적으로research/entities/에 기록되고 나중에 커먼스로 전달될 수 있습니다.health— 개인 노출 컨텍스트.content-creation— 그래프를 기반으로 한 교육용 게시물.
근거 규율
시드 지식은 권위 있는 기관(NIEHS, ATSDR/CDC, US EPA, US FDA, ECHA/EU REACH, CA OEHHA Prop 65, WHO, EWG)만을 인용합니다. 모든 레코드는 ≥1개의 출처를 포함합니다. verified: false는 이들이 참조 등급(새로 가져오지 않음)임을 표시합니다 — 출처 기반 패스(또는 커먼스)를 실행하여 새로 고치십시오. selfheal은 노드가 인용을 잃으면 실패합니다. 이는 공중 보건 과학에 기반한 소비자 안내이며 의학적 또는 법적 조언이 아닙니다.
리소스
scripts/swapit.py— CLI 진입점 + 명령어 핸들러scripts/state.py— 두 영역 상태 레이어 (PRIVATE_FIELDS가 동기화 경계 정의)scripts/ops.py— 단일 상태 변경 쓰기 경로 (CLI + 대시보드 공유)scripts/knowledge.py— 지식 그래프 로드 + 엣지 해석scripts/risk.py— 노출 위험 점수 엔진scripts/report.py— 독립형 HTML 보고서 생성기 (Category-C)scripts/server.py—swapit serve라이브 대시보드 (stdlib http.server, localhost 전용)scripts/anonymize.py— 개인정보 보호 게이트: 허용 목록 사실 빌더 + 금지 필드 스캔scripts/sync.py— 커먼스 동기화 클라이언트 (큐,--dry-run미리보기, 푸시/풀, 병합)scripts/selfheal.py— 무결성 검증기templates/dashboard.html— 라이브 대시보드 (인라인 CSS/JS, Category-C)commons/— 네트워크 커먼스 참조 서버 (FastAPI + SQLite; 게이트 배포)seed/{hazards,item-classes,alternatives}.jsonl— 근거 기반 시작 지식tests/— 위험, 지식, 자가 치유, CLI, 개인정보 보호/익명화, 동기화, 보고서 및 서버 테스트
협업 (커먼스)
기여는 일반적인 사실만 가능합니다 — swapit contribute product|hazard|alternative|procurement|item-class는 익명화된 사실(공개 제품→품목 클래스 매핑, 유해물질 엣지 수정, 대체품, 구매처, 또는 새 분류 노드)을 구축하고 로컬에 적용한 후 큐에 추가합니다. swapit sync --dry-run은 정확히 무엇이 전송될지 보여줍니다. swapit sync는 큐를 푸시하고 커뮤니티 지식을 풀합니다 (선택적, --configure 후). 다른 사용자의 동일한 사실은 중복되지 않고 입증(콘텐츠 주소 지정)됩니다. 커먼스는 두 명의 다른 기여자가 입증한 후(corroboration >= 2)에만 사실을 제공합니다 — 검증은 입증 게이트에 의해 제어되며, 신뢰도 게이트가 아닙니다. 그 이유는 confidence는 호출자가 제공하며 단독 제출자가 스스로 승인할 수 있기 때문입니다. 개인정보 보호 불변 규칙은 양쪽(클라이언트 anonymize 게이트 + 서버 백스톱)에서 적용됩니다. 인벤토리는 절대 경계를 넘지 않습니다.
구매처 (조달) 커먼스
procurement_option 사실은 공개 제안입니다: alternative가 retailer에 의해 region(ISO-3166-1 alpha-2)에서 판매되며, 선택적으로 url, price_min/price_max + currency + as_of, area, availability를 포함합니다. 이는 (alternative, retailer, region) 에 대해 콘텐츠 주소로 지정됩니다 — 동일한 제안은 사용자 간에 입증됩니다. 다른 지역은 다른 사실입니다 (지리적 규모 축). 가격/url/지역은 개선 가능한 시장 데이터입니다: 엄격하게 더 새로운 as_of를 가진 입증은 가격을 앞으로 새로 고치고, 더 새로운 데이터를 절대 되돌리지 않습니다. 개인정보 보호 경계는 명확합니다 — 공개 제안은 retailer + price_*를 사용하고 절대 비공개 vendor/cost (사용자가 구매한 곳과 지불한 금액)를 사용하지 않습니다 (영역 2에 남아 있음). swapit procure <item> --region <CC>는 알려진 제안을 표시하고 사용자가 찾은 새 제안을 기록합니다 — 누구나 사용할 수 있는 개방형의 상세한 지리 범위 데이터셋을 확장합니다.
로드맵
- M1 (출시됨, 0.1.0) — 데이터 모델, 시드 지식, CLI, 위험 엔진, 정적 HTML 보고서, 자가 치유.
- M2 (출시됨, 0.2.0) —
swapit serve: 상태로 읽기/쓰기가 가능한 로컬 라이브 대시보드. - M3 (0.3.0) — 익명화된 협업 + 네트워크 커먼스 (
commons/, FastAPI + SQLite). 개인정보 보호 불변 규칙은 허용 목록 직렬화 + 클라이언트와 서버 모두에서 퍼즈 테스트로 적용됨. - M4 (이번 릴리스, 0.4.0) — 지리적 규모의 조달 커먼스 + 분류 확장:
procurement_option(공개 구매처,(alternative, retailer, region)키 기준, 순방향 가격 새로 고침) 및item_class(입증 게이트 분류 확장) 사실 종류;procure는 제안을 표시하고 기록함; US/CO/DE/GB의 시드 제안; 고정 벡터로 잠긴 교차 언어 해시 패리티. broomva.tech 인프라로의 라이브 배포는 명시적 승인에 달려 있음(자격 증명/DNS); 스킬은 오프라인에서도 완전히 기능함.