← 돌아가기

이 카드에 뭐가 왜 실렸는지

점수나 등급을 매기지 않는다. 대신 무엇을 보여줄지 고르는 규칙을 여기 다 적어둔다. 공개되지 않은 선택은 그 자체가 이미 평가다.

열린국회정보 OpenAPI의 22대 국회 데이터만 쓴다. 카드의 모든 줄은 국회 의안정보시스템 원문으로 되돌아갈 수 있다.


1. 국회에서 찬반이 갈린 표결 5개

찬반이 갈린 정도가 큰 순, 같으면 최근 의결순으로 5개.

찬반이 갈린 정도 = min(찬성 수, 반대 수) ÷ 실제 투표한 의원 수

만장일치면 0, 반반이면 0.5다. 값이 클수록 국회 안에서 의견이 갈렸다는 뜻이다. 어느 쪽이 옳은지, 누가 어느 편인지는 계산에 들어가지 않는다. 의원이 아니라 안건을 재는 값이다. 모수는 실제 투표한 의원 수라 불참은 빠진다. 계산식은 schema.sql의 v_bill_contest 뷰에 있다.

관심 주제를 켜면 최근 의결순으로 바뀐다. 상임위 소관 안건은 대체로 여야 합의로 올라와 만장일치에 가깝기 때문이다. 정무위원회에서 제일 갈린 안건도 0.0092, 299명 중 반대가 한둘인 수준이다. 이런 걸 "찬반이 갈린 표결"이라고 내보내면 기준이 이름값을 못 한다. 기준이 성립하는 범위에서만 그 기준을 쓰고, 아니면 날짜 역순이라는 더 단순한 규칙으로 간다. 어느 기준으로 뽑았는지는 화면에 적는다.

의원의 표결

찬성·반대·기권·불참 네 가지를 국회 기록 그대로 쓴다. 재분류하지 않는다. 재임 전이라 기록이 없으면 "기록 없음"이다.

여기에 같은 당 의원들의 표결 분포를 한 줄 덧붙인다.

반대 | 국회법 일부개정법률안(대안)
     전체 찬성 171 · 반대 101 · 2024-11-28
     더불어민주당 찬성 150 · 반대 1(이 의원 포함) · 불참 16

대부분의 안건은 정당별로 표가 갈린다. 이걸 감추면 카드가 실제보다 개인의 선택처럼 보인다. 반대로 같은 당과 다르게 투표한 의원도 드물게 있는데, 위 예시의 '반대 1'이 그렇다. 그 의원에게는 이게 카드에서 제일 중요한 사실인데 정당 숫자가 없으면 보이지 않는다.

이 의원의 표가 들어간 항목에는 이 의원 포함을 붙이고 굵게 둔다. 본인 표와 정당 숫자를 눈으로 대조하는 일을 대신 해줄 뿐이다. 150명 쪽이든 1명 쪽이든 똑같이 붙는다. 소수일 때만 붙이면 그 순간 "이건 특기할 일"이라는 판단이 들어간다. 어느 쪽이 다수인지, 그게 잘한 일인지는 여전히 적지 않는다.


1-2. 같은 당에서 가장 많은 표와 다르게 던진 표

위의 '찬반이 갈린 표결' 은 안건을 재는 값이라 누구 카드에나 거의 같은 5건이 나온다. 실제로 지역구 80곳을 뽑아보면 77곳이 글자 하나까지 같았다. 그건 기준대로 도는 것이지만, 핵심 표결 이라는 이름 아래 놓으면 이 의원의 표결처럼 읽힌다.

그래서 절을 나눴다. 이 절은 의원마다 다르다.

같은 당에서 가장 많은 표 = 그 안건에서 같은 당 의원들이 던진
                          찬성 · 반대 · 기권 중 제일 많은 것

때도 빼고, 이 의원이 불참한 안건도 여기 안 들어간다.

같은 자료에서 매번 다른 답이 나온다.

카드에 다 넣을 수 없다. 전체는 /<선거구>/다르게 에 최근 의결순으로 다 있다.

계산은 schema.sql 의 v_bill_party_major · v_vote_differed 두 뷰에 있다. 안건 페이지의 '같은 당 다수와 다르게 던진 의원' 도 같은 뷰를 쓴다. 기준을 두 군데 적어두면 언젠가 갈라진다.

'당론'이라는 말은 여기서도 쓰지 않는다. 국회는 당론을 공표하지 않으므로 우리가 아는 건 그 안건에서 같은 당 의원들이 실제로 어떻게 던졌는가뿐이다. 따랐다 이탈했다도 판정하지 않는다. 두 값이 다르다는 사실만 적는다.

7,624건 중 90%는 다수가 30명 이상이지만, 2.4%는 다수가 4명 이하다. 그래서 줄마다 정당 분포를 그대로 붙여 몇 명 기준인지 보이게 한다. 문턱을 두어 걸러내지 않는다. 걸러내는 순간 어디까지가 '진짜 다른 표'인지 우리가 정하게 된다.


1-3. 표결 안건 목록의 범위와 순서

/안건 에서 범위와 순서는 따로 고른다. 하나로 묶으면 '최근 3개월 중 갈린 순' 같은 걸 볼 수 없다. 범위로 거른 다음 그 위에 순서를 얹는다.

거르개 셋 — 서로 겹쳐 쓸 수 있다.

거르개기준
기간의결일. 시작일·종료일을 직접 넣거나 전체·1년·6개월·3개월
주제4절의 소관 상임위 라벨. 본회의·특별위원회 안건은 `전체` 에서만 보인다
이름법안 이름에 그 글자가 들어가면 남긴다. 대소문자를 가리지 않고, 부분 일치다. 한 줄 설명은 안 뒤진다

거른 뒤에는 1,777건 중 106건 · 2025-09-02 ~ 2026-09-03 · 보건·복지 처럼 몇 건이 남았고 무슨 조건이 걸려 있는지 적는다. 몇 건이 빠졌는지 안 보이면 거르기 자체가 숨은 선택이 된다. 조건 지우기 로 한 번에 되돌린다.

처음에는 최근 3개월만 싣는다

1,777건을 한 번에 실으면 714KB다. 최근 것만 보려는 사람도 2년치를 통째로 받는다. 그래서 처음에는 최근 3개월(182건)만 싣고, 나머지 1,595건은 범위를 넓히거나 주제·이름으로 찾을 때 받아온다. 첫 화면이 92KB로 줄었다.

받아오기 전까지는 전체 기준인 척하지 않는다. 처음 화면은 182건 · 최근 3개월 (전체 1,777건은 범위를 넓히거나 찾을 때 불러옵니다) 라고 적는다. 182건만 뒤져 놓고 1,777건 중 5건 이라고 적으면 그 숫자가 거짓말이 된다.

주제나 이름으로 찾으면 기간을 전체로 넓힌다. 최근 3개월만 뒤지고 '5건'을 내놓으면 찾은 사람은 그게 전부인 줄 안다.

순서 — 범위 안의 안건에만 적용된다.

고르면정렬
최근 의결순 (처음)의결일 내림차순. 달별로 묶어 보여준다
찬반이 갈린 순`min(찬성, 반대) ÷ 실제 투표한 의원 수` 내림차순

거르기도 정렬도 화면에서만 한다. 자료를 다시 받지 않고 이미 그려진 줄을 옮길 뿐이다. 자바스크립트가 안 돌아도 최근 의결순 전체 목록은 그대로 보인다.

'당론'이라는 말은 쓰지 않고 따랐다 이탈했다도 판정하지 않는다. 그런 말을 쓰는 순간 평가가 된다. 숫자만 나란히 놓는다. 계산은 v_bill_party_vote 뷰. 정당명은 표결 당시 소속이라 나중에 탈당하거나 옮겼어도 그 시점 기준으로 맞다.

숫자의 출처

안건의 찬반 총계는 국회가 공표한 의안별 표결현황(ncocpgfiaoituanbr), 의원 개인의 표결은 국회의원 본회의 표결정보(nojepdqqaweusdfbi)에서 가져온다.

둘을 나눈 건 숫자가 어긋나기 때문이다. 22대 표결 안건 1,656건 중 285건에서 공표 총계보다 개별기록이 적다. 대개 1표, 많으면 14표 차이다. 공표 집계에는 들어가 있는데 그 표를 누가 던졌는지는 국회가 공개하지 않는다. 그래서 총계는 공표값을 그대로 쓰고 개별기록을 더해 새로 만들지 않는다. 차이는 v_vote_mismatch 뷰로 언제든 볼 수 있다.

이 차이로 안건을 빼지는 않는다. 두 기준으로 각각 순위를 매겨도 상위 50건이 그대로 같아서 카드에 실릴 안건이 달라지지 않는다.

안건 페이지

안건 하나에 평균 296명의 표결 기록이 있는데, 카드는 그중 한 사람 것만 보여준다. /안건/<의안번호> 에 안건 쪽에서 보는 화면을 따로 뒀다.

의원 296명을 다 나열하지는 않는다. 그건 국회 의안정보시스템이 이미 하고, 우리가 할 일은 '우리 동네 의원은 어느 쪽이었나' 로 잇는 것이다. 그래서 정당별 집계와 같은 당 다수와 다르게 던진 의원만 적는다.

'다수와 다르게'를 재는 방법은 이렇다. 그 정당에서 찬성·반대·기권 중 가장 많이 나온 쪽을 다수로 보고, 거기서 벗어난 사람을 적는다. 불참은 뜻을 밝힌 것이 아니므로 세지 않는다. '이탈'이라고 부르지 않고 당론을 따랐는지도 판정하지 않는다. 그런 말을 쓰는 순간 평가가 된다. 누가 어느 쪽이었고 같은 당은 몇 명이 어느 쪽이었는지, 숫자만 나란히 놓는다.


2. 본회의 표결 참여율

출석률이 아니다. 국회 OpenAPI는 본회의 출석부를 주지 않는다. 그래서 출석률 대신 아래 값을 그 이름 그대로 쓴다.

본회의 표결 참여율 = (불참이 아닌 표결 수) ÷ (그 의원 이름으로 표결 기록이 남은 안건 수)

분모에는 찬성·반대·기권·불참이 다 들어간다. 기권은 참여로 센다. 표결에 참여해 의사를 밝힌 것이기 때문이다. 재임하지 않은 기간의 안건은 애초에 기록이 없어 자연히 빠지므로, 보궐로 들어온 의원이 불리해지지 않는다. 실제로 299명 중 20명은 표결 기록이 1,656건보다 적고 15명은 아예 없다. 이 15명은 참여율을 계산하지 않고 "본회의 표결 기록 없음"이라고만 적는다. 0%가 아니다.

기록이 아예 없는 15명

이들은 투표를 안 한 게 아니다. 국회가 이들의 표결을 공개하지 않는다.

국회는 표결을 두 갈래로 내놓는다. 안건별 표결현황은 재적 299 · 투표 178 · 찬성 175 처럼 합계만 주고, 본회의 표결정보는 누가 어느 쪽에 던졌는지 이름이 붙은 명단을 준다. 카드의 찬성 | 국회법 일부개정법률안 같은 줄은 전부 뒤쪽에서 온다.

2026년 7월 31일 형사소송법 개정안을 예로 들면 이렇다.

안건별 집계   재적 299 · 투표 178 · 찬성 175 · 반대 2 · 기권 1
의원별 명단   284줄 · 찬성 166 · 반대 2 · 기권 1 · 불참 115

집계는 178명이 투표했다는데 명단에는 169명뿐이다. 9명은 표가 잡혔는데 이름이 없다. 명단에 빠진 284 대 299의 차이가 정확히 이 15명이고, 표결 기록이 0인 의원과 같다.

1,656건 전부에서 투표수 차이가 명부 부족분을 한 번도 넘지 않는다.

명부 부족분안건 수투표수 차이
0명1,0560
1명5390 ~ 1
15명618 ~ 15

명부가 완전한 1,056건은 두 값이 100% 일치한다. 빠진 의원이 그날 투표하면 그만큼 벌어지고 불참하면 0이다. 집계가 부정확한 것이었다면 이렇게 떨어질 수 없다.

빈 자리가 생긴 시점과도 맞는다. 2025년 12월까지는 명부와 재적이 같아 불일치가 0건인데, 2026년 1월 1명으로 시작해 6월에 15명이 된다. 사퇴가 쌓여 5월 재적이 286까지 내려갔다가 6월에 300으로 돌아온다.

그래도 카드에는 "재보궐로 왔다"고 쓰지 않는다. 국회 API에 취임일도 재보궐 여부도 없어서 그건 우리가 밖에서 가져온 얘기다. 국회 데이터로 말할 수 있는 것만 쓴다.

> 이 의원이 어떻게 투표했는지는 국회가 아직 공개하지 않았습니다. > 전체 찬반 집계에는 이 의원의 표가 들어 있습니다.

국회가 명단을 채우면 이 문구는 저절로 사라지고 참여율이 뜬다.

불참한 이유는 국회가 공개하지 않는다. 해외출장이든 질병이든 사임이든 기록에는 똑같이 '불참'으로만 남는다. 이 숫자는 성실함의 지표가 아니고, 카드에도 그렇게 적어둔다. 상임위 회의 출석은 데이터가 없어 아예 다루지 않는다.

계산식은 v_vote_participation 뷰.

숫자 옆에 최저·평균·최고를 함께 놓는다. 83.7% 만 보면 높은 건지 낮은 건지 알 수 없기 때문이다. 순위나 백분위는 매기지 않는다. '상위 30%' 는 등수를 매기는 것이라 1절 원칙을 어긴다. 어디쯤인지 점 하나로 표시할 뿐, 낮으면 빨강 같은 식으로 칠하지도 않는다. 그 순간 색이 곧 평가가 된다.

참여율 분포는 표결 기록이 있는 284명만으로 낸다. 기록이 없는 15명을 0으로 넣으면 분포가 통째로 내려앉는다.


2-2. 임기가 끝난 의원

국회 인적사항 API 는 사퇴하거나 승계로 임기가 끝난 의원을 명단에서 뺀다. 우리는 지우지 않고 표시한다.

지우지 않는 이유가 셋이다.

언제 빠졌는지는 그 사람이 명단에서 마지막으로 보인 날로 적는다. 우리가 알아챈 날이 아니다. 실제로 8월 31일에 빠진 의원을 9월 8일에 알아챈 적이 있다.

사유는 적지 않는다. 국회 API 가 주지 않는다. 뉴스로는 알 수 있지만 규칙 6에서 열린국회정보만 쓰기로 했고, 사유를 적기 시작하면 매번 뉴스를 따라다녀야 한다. 화면에는 이렇게만 적는다.

2026-08-31까지 국회 의원 명단에 있었고 그 뒤로는 없습니다.
아래 기록은 재임 중의 것입니다.

의원 수를 셀 때는 임기가 끝난 사람을 빼고, 목록에서는 정당 묶음 아래에 따로 모은다. 정당 안에 섞으면 '더불어민주당 161명' 이 지금 인원과 안 맞는다. 검색에서는 찾을 수 있게 두되 임기 끝 이라고 함께 적는다.

계산은 collect.py 의 step_members 에 있다. 명단에 다시 들어오면 되돌린다.


3. 대표발의 법안

대표발의만 세고, 이름만 올린 공동발의는 따로 표시해 섞지 않는다. 출처는 국회의원 발의법률안(nzmimeepazxkubdpn)의 RST_MONA_CD와 PUBL_MONA_CD다. 대표발의자가 두 명 이상인 법안은 양쪽 다 대표발의로 센다. 국회 기록이 그렇게 되어 있다.

카드에는 가장 최근 3건만 싣는다. 중요도를 판단할 여지를 없애려고 날짜 역순만 쓴다. 발의 건수가 많다고 일을 잘한다는 뜻은 아니다.


4. 주제 태그

소관 상임위원회를 그대로 쓴다. 법안 내용을 읽고 분류하지 않는다. 상임위 이름이 낯설어서 라벨만 1:1로 바꿨고, 대응표 전체가 아래다.

소관 상임위원회표시 라벨
국회운영위원회국회 운영
법제사법위원회법·사법
정무위원회금융·공정거래
재정경제기획위원회세금·경제
교육위원회교육
과학기술정보방송통신위원회과학·통신·방송
외교통일위원회외교·통일
국방위원회국방
행정안전위원회행정·안전
문화체육관광위원회문화·체육·관광
농림축산식품해양수산위원회농림·해양수산
산업통상자원중소벤처기업위원회산업·에너지·중소기업
보건복지위원회보건·복지
기후에너지환경노동위원회환경·노동
국토교통위원회부동산·교통
정보위원회정보
성평등가족위원회성평등·가족

22대 후반기에 이름이 바뀐 위원회는 옛 이름도 같은 라벨로 묶는다. 기획재정 → 재정경제기획, 환경노동 → 기후에너지환경노동, 여성가족 → 성평등가족. 안건에는 처리 당시의 이름이 남으므로 없어진 이름도 표에 함께 담아 둔다. 대응표 원문은 collect.py의 TOPIC_LABELS.

본회의와 특별위원회 안건에는 주제가 없다. 소관 상임위가 없기 때문이다. 표결 안건 1,777건 중 136건(본회의 55건, 예산결산·기후위기 등 특별위원회 81건)이 여기 해당한다. 없는 주제를 지어 붙이지 않고 주제별 보기에서 빼 둔다.

관심 주제는 브라우저(localStorage)에만 저장된다. 서버로 보내지 않으니 누가 무슨 주제를 골랐는지 우리도 모른다.


5. 법안 한 줄 설명

의안 원문의 '제안이유'를 잘라 쓴다. 새로 쓰지 않는다.

있으면 "주요내용" 앞까지가 제안이유 구간이다. 합본이 절반을 넘어서, 구분하지 않으면 본문이 통째로 날아간다.

마지막 것. 앞에 붙은 이에 따라서 같은 접속어는 뗀다.

3번이 있는 이유는 이렇다. 제안이유는 대개 세 토막이다.

현행법은 ~하고 있음.        배경
그런데 ~문제가 있음.         문제
이에 ~하려는 것임.           목적

첫 문장만 쓰면 배경만 보여주게 되어 이 법안이 뭘 바꾸는지가 안 나온다.

첫 문장   최근 선불전자지급수단의 이용이 확대되면서 선불충전금 규모가 지속적으로
          증가하고 있으나, 소멸시효가 완성된 휴면선불충전금은 현행법상…

목적 문장  휴면선불충전금을 휴면예금등의 범위에 포함하고 휴면예금등을 일정 기간
          내에 출연하도록 의무화하여 서민금융 재원을 안정적으로 확보하려는 것임.

둘 다 국회 원문이고, 어느 문장을 고르느냐만 다르다. 목적 문장이 있는 것은 2,917건 중 2,733건(93%)이고 나머지는 첫 문장을 그대로 쓴다.

목적 문장은 것임 과 마침표 사이에 조문 번호가 끼는 일이 아주 흔하다.

… 본회의에 부의할 수 있도록 하려는 것임(안 제85조의3제2항).

이 괄호를 허용하지 않으면 1,071건밖에 못 잡는다. 괄호는 읽는 사람에게 군더더기라 문장에서 뗀다.

잘린 설명

200자 안에 문장이 안 끝나 … 로 자른 것은 540건이다. 눌러서 전문을 볼 수 있고, 전문은 /api/reason/<의안ID>.json 에 따로 있다. 카드마다 원문을 심으면 13MB 가 붙지만 따로 두면 2MB 남짓이고, 누른 사람만 받아간다.

목록에서는 설명을 서버에서 자르지 않는다. 국회가 준 제안이유를 그대로 싣고 두 줄까지만 보인 다음, 두 줄에 안 들어가면 더 보기 를 단다. 예전에는 목록마다 60~90자로 잘라 보내서, 잘린 자리를 펼 방법이 아예 없었다.

안건 상세에서는 아무것도 자르지 않는다. 제안이유 원문 전부를 싣고 여섯 줄에서 접는다. '제안이유 및 주요내용' 같은 머리글만 떼고 내용은 손대지 않는다.

카드에서는 설명을 링크 밖에 둔다. 링크 안에 있으면 설명을 짚었을 때 법안 이름에 밑줄이 그어져 무엇이 눌리는지 헷갈린다. 목록은 줄 전체가 링크라 설명도 그 안에 있고, 설명을 누르면 링크로 넘어가는 대신 그 자리에서 펴진다.

구현은 collect.py의 _reason_head(), 출처 API는 BPMBILLSUMMARY다. 이 규칙으로 문장이 안 나오는 법안은 설명을 비우고 원문 링크만 건다.

AI로 요약을 만든 경우에는 그 줄에 자동생성 라벨을 반드시 붙인다. 라벨이 없으면 국회 원문에서 잘라낸 것이다. 지금 이 라벨이 붙은 줄은 하나도 없다.

제안이유가 없는 안건

국회는 법률안의 제안이유만 준다. 예산안·결의안·동의안·규칙안 따위는 어느 API에도 없다. ALLBILL과 BILLINFODETAIL은 제안자와 날짜만 주고, 의안정보시스템 상세 페이지에도 정적 HTML로는 안 나온다. 표결 안건 1,760건 중 206건이 이렇다.

없는 요약을 지어내는 대신, 그 안건이 어떤 종류인지만 적는다. 개별 안건을 설명하는 게 아니라 용어 풀이다. 문장을 '회기결정의 건'은 …으로 시작해 특정 안건의 요약이 아님이 드러나게 했고, 화면에서도 기울임으로 국회 원문과 구분한다.

이름에 아래 말이 들어가면 그 설명을 쓴다. 위에서부터 먼저 걸리는 것 하나만 쓴다.

이름에 들어간 말붙는 설명
회기결정의 건이번 국회를 며칠 동안 열지 정하는 안건
의사일정 변경동의그날 본회의 안건 순서를 바꾸는 안건
특별위원회 구성의 건특정 사안을 다룰 위원회를 새로 만드는 안건
활동기간 연장의 건특별위원회가 더 활동하도록 기한을 늘리는 안건
국정조사계획서국정조사의 범위와 기한을 담은 계획을 승인하는 안건
비준동의안정부가 맺은 조약을 국회가 최종 확정하는 안건
파견연장 동의안국군 부대의 해외 파견 기간을 늘리는 데 동의하는 안건
임명동의안대통령이 지명한 사람의 임명에 동의하는 안건
예비비지출정부가 예비비로 이미 쓴 돈을 사후에 확인하는 안건
대안같은 주제의 여러 법안을 상임위가 하나로 합친 안건

이름에 안 걸리면 안건 종류로 떨어진다. 예산안·결산·결의안·동의안·중요동의·승인안· 규칙안 일곱 가지다. 법률안은 넣지 않았다. 제목에 이미 '…법률안'이 있어 아무것도 더해주지 않는다.

이렇게 206건 중 199건에 설명이 붙는다. 남은 7건은 대안이 아닌 법률안인데 국회가 제안이유를 주지 않은 경우라, 제목과 원문 링크만 둔다. 대응표 원문은 card.py의 KIND_BY_NAME과 KIND_BY_TYPE이다.

원문에 ?가 섞여 나오는 법안도 있다. 회장?부회장?이사, ?출입국관리법? 같은 식이다. 국회 API가 내려주는 원문 자체가 그렇다. 같은 응답 안에 ㆍ와 「 」는 멀쩡히 들어 있는 걸 보면 특정 글자만 국회 쪽에서 깨진 건데, 원래 무슨 글자였는지 알 방법이 없다. 추측해서 바꾸지 않고 그대로 둔다. 한 줄 설명 2,504건 중 36건이 그렇다.


5-2. 의원 사진

국회가 공개한 의원 사진(ALLNAMEMBER 의 NAAS_PIC)을 쓴다. 우리가 고르거나 보정하지 않는다. 300명 전원 있다.

국회 주소를 그대로 걸지 않고 받아서 우리 쪽에 둔다. 두 가지 이유다.

우리를 거치지 않고 밖으로 나간다. 8절에서 하지 않기로 한 일이다.

원본은 형식이 섞여 있다(7KB JPEG 와 1MB PNG). 그대로 실으면 100MB 가까이 되므로 긴 변 220px JPEG 로 맞춘다. 300장 모두 합쳐 3MB다. 얼굴 위치가 대체로 위쪽이라 가운데보다 조금 위를 기준으로 잘라 원형으로 놓는다.

사진이 없는 의원은 자리를 비워 둔다. 깨진 그림틀을 두거나 아무 그림이나 넣지 않는다.


6. 심사중 법안과 입법예고

'심사중'은 국회가 계류의안(nwbqublzajtcqpdae)으로 분류한 법안이다. 우리가 판단하지 않는다. 입법예고는 게시종료일(NOTI_ED_DT)에서 오늘을 빼 남은 날짜를 센다. 종료일 당일이 D-0이다.

의견은 국회 입법예고 사이트에서 낸다. 우리는 링크만 걸고 의견을 받거나 모으거나 저장하지 않는다.


6-2. 국민동의청원

국민동의청원은 30일 안에 5만 명이 동의하면 소관 위원회에 회부된다. 지금 동의를 받고 있는 것만 싣는다. 마감이 가까운 순이고, 같은 날 마감이면 동의가 많은 순이다.

동의는 국회 전자청원 사이트에서 한다. 제목을 누르면 그리로 넘어간다. 이 사이트는 동의를 받지도, 세지도, 저장하지도 않는다. 입법예고와 같다(6절).

분야는 국회가 붙인 값 그대로다. 우리가 고르거나 순위를 매기지 않는다.

카드에는 넣지 않는다

동의를 받는 동안에는 소관 위원회가 안 정해진다. 회부돼야 붙는다. 그래서 '우리 동네 의원' 과 이을 방법이 없다. 억지로 이으면 카드가 국회 종합 정보가 된다. 첫 화면과 청원 목록에만 둔다.

출처가 다르다

이것만 열린국회정보 OpenAPI 가 아니다. 국회전자청원(petitions.assembly.go.kr)이 별도 시스템이라 거기서 받는다. 인증키 없이 열리는 공개 API 다.

6절에서 '열린국회정보만 쓴다' 고 한 것은 출처를 뒤섞지 않겠다는 뜻이므로, 다른 곳을 쓰는 자리는 이렇게 밝혀 둔다. 둘 다 국회가 내놓는 자료다.


7. 광고와 후원

서버비와 도메인 값은 나온다. 후원을 받고, 광고를 붙일 수도 있다. 다만 돈이 카드 내용에 닿지 않게 선을 그어둔다.

무엇을 보여줄지는 이 문서의 규칙이 정한다. 후원했다고 뭐가 더 실리거나 빠지는 일은 없고, 그 규칙을 바꾸려면 이 문서부터 고쳐야 한다.

정당과 국회의원, 후보자, 선거 캠프에서는 후원을 받지 않는다. 광고도 정치 관련은 받지 않는다. 특정 인물이나 정당을 홍보해주는 대가로 돈을 받는 일도 없다. 정치 정보를 다루는 곳에서 정치권 돈을 받으면 나머지 규칙을 아무리 잘 지켜도 의심을 못 벗는다.

광고는 카드 바깥 두 자리에만 둔다. 표결이나 발의 기록 사이에 끼워넣지 않고, 광고에는 '광고'라고 적어 기록과 구분한다.

후원 안내도 같은 원칙이다. 모든 페이지 맨 아래, 꼬리말 링크 줄 위에 같은 모양으로 한 번 둔다. 카드 안이나 기록 사이에는 두지 않는다. 후원 페이지 자신에는 따로 두지 않는다.

광고는 구글 애드센스로 싣는다. 구글은 광고를 보여주고 성과를 재려고 이용자 기기에 쿠키를 심고 광고 식별자와 IP를 수집한다. 우리가 그 내용을 넘겨받지는 않지만, 우리 사이트에서 벌어지는 일이니 숨기지 않는다. 무엇을 수집하고 어떻게 끄는지는 개인정보처리방침에 적었고, 처음 방문했을 때 화면 아래에 한 번 알린다.

결제는 외부 서비스(그로블)로 넘긴다. 카드번호나 계좌 정보가 우리 쪽을 지나가지 않는다.

후원해도 보이는 내용은 달라지지 않는다. 별도의 상품도 이용권도 추가 기능도 없다. 후원하지 않는 사람과 똑같은 화면을 본다.

후원 화면에는 설문이 붙어 있다. 알게 된 경로와 마음에 든 점은 선택지에서 고르고, 아쉬웠던 점과 남기고 싶은 말은 직접 적는다. 여기에 적은 글은 운영자에게 전달된다. 9절에서 "자유롭게 쓰는 칸은 두지 않는다"고 한 것과 어긋나 보일 수 있어 밝혀둔다. 그 조항은 카드마다 붙는 공개 제보 창구를 두고 쓴 것이고, 이쪽은 후원한 사람만 지나는 자리이며 건너뛸 수 있다. 서비스를 고치는 데만 쓰고 공개하지 않는다.


8. 조회 통계

어느 지역구 카드가 몇 번 열렸는지는 센다. 어디를 고쳐야 할지 알려면 그 정도는 봐야 한다. 서버에 남는 건 이런 줄이다.

2026-08-17 | card  | 서울 중구성동구갑 | 1,204
2026-08-17 | topic | 부동산·교통       |   318

방문 하나를 한 줄로 남기지 않는다. 요청이 들어오면 카운터를 1 올리고 그대로 버린다. 줄이 없으니 나중에 시간 순서로 이어 붙일 것도 없다. 시각은 저장하지 않고 날짜까지만 남긴다.

IP도 User-Agent도 리퍼러도 저장하지 않는다. 우리 쪽에서는 쿠키를 굽지 않으므로 같은 사람이 다시 왔는지 모른다. 다만 광고 사업자는 별개다. 아래 7절과 개인정보처리방침에 적어뒀다.

방문 통계 도구

위 카운터는 카드가 몇 번 열렸는지만 센다. 어디를 통해 들어왔는지, 어느 페이지에서 읽다 나갔는지는 모른다. 그걸 보려고 Cloudflare Web Analytics 를 붙였다.

이 사이트는 Cloudflare 를 거쳐 전달되므로 서버 쪽에서 집계한다. 방문자 브라우저에는 추적 스크립트가 들어가지 않는다. 쿠키도 브라우저 저장소도 쓰지 않고, 이 사이트 밖에서의 활동을 따라가지 않는다. 지금 방문자 브라우저가 우리 것 말고 내려받는 스크립트는 광고 하나뿐이다.

Cloudflare 가 보는 것은 열린 페이지 주소, 유입 경로, 기기·브라우저 종류, 접속 국가, 로딩 속도다. 개인을 알아볼 수 있는 형태로 우리에게 오지 않는다.

성별이나 연령대는 볼 수 없다. 그건 광고 사업자가 평소에 그 사람을 따라다니며 만든 프로필에서 나오는 값이라, 이 사이트가 하지 않겠다고 적어둔 바로 그 추적이다. 정확히 알 수 없는 편을 택했다.

항목과 보관 기간은 개인정보처리방침 2절에 적었다.

검색창에 친 말은 받지 않는다. 읍면동 이름은 사는 곳을 꽤 좁히기 때문이다. 이미 해석이 끝난 선거구만 센다. 선거구 하나에 20만 명쯤 산다.

셀 수 있는 이름은 선거구 254개와 주제 17개로 미리 정해져 있다. 목록에 없는 값은 받지 않으므로 이 표에 자유 문자열이 들어올 수 없다.

DNT나 Global Privacy Control을 켠 브라우저에서는 아무것도 보내지 않는다. 같은 카드를 여러 번 봐도 한 탭에서는 한 번만 센다.

센 숫자는 조회 통계에 그대로 올린다. 기준을 공개한다면서 트래픽만 따로 쥐고 있으면 앞뒤가 안 맞는다.

구현은 stats.sql, stats.py, stats_worker.js 세 파일이고 다 합쳐 270줄이다.


9. 잘못된 걸 봤을 때

카드마다 아래에 "이 카드에 잘못된 게 있나요?" 링크를 둔다. 누르면 다섯 가지 중에서 고른다. 의원 정보가 틀림, 표결 기록이 이상함, 우리 동네가 아닌 것 같음, 링크가 안 열림, 법안 설명이 깨져 보임.

자유롭게 쓰는 칸은 두지 않는다. 글을 받으면 이름이나 전화번호가 섞여 들어오고, 의원에 대한 의견을 적는 사람도 생긴다. 그 순간 이 서비스는 개인정보를 모으는 곳이 되고 댓글창이 된다. 고르는 방식이면 둘 다 애초에 불가능하다.

제보도 조회 수와 같은 카운터에 쌓인다. 남는 건 `2026-08-17 | report | 서울 강남구갑

district3` 같은 줄이고, 누가 눌렀는지는 남지 않는다.

집계는 조회 통계에 올리되 유형별 합계만 낸다. 어느 선거구에서 몇 건이 들어왔는지까지 내걸면, 확인도 안 된 제보가 "이 의원 카드는 틀렸다"로 읽힌다. 선거구별 내역은 고치는 데만 쓴다.

다섯 가지에 안 맞는 얘기는 메일로 받는다. 주소는 화면 아래에 적어둔다. 메일은 우리 서버를 거치지 않는다. 다만 답장은 못 드린다.


10. 우리가 하지 않는 것

의원에게 점수·등급·순위를 매기지 않는다. 진보나 보수 같은 성향을 추정하지 않는다. 표결을 옳은 표결과 틀린 표결로 나누지 않는다.

회원가입도 로그인도 댓글도 커뮤니티도 없다. 계정이 없으니 계정에 쌓이는 기록도 없다. 개인을 알아볼 수 있는 데이터를 서버에 저장하지 않는다. 위 8절의 카운터가 서버에 남는 전부다.


11. 데이터 갱신과 한계

22대 국회(2024~) 기준이고 그 이전 국회는 다루지 않는다. 국회가 올린 다음에 우리가 받아오므로 본회의 직후 며칠은 반영이 늦을 수 있다. 마지막 수집 시각은 화면 아래에 항상 적어둔다.

받아올 때마다 무엇이 늘었는지도 바뀐 것 아래쪽에 적는다. 수집 시각만 있으면 그게 어제 것인지 3주 전 것인지 알 수 없다. 아무것도 안 늘은 날은 그렇게 적는다. 국회가 새로 올린 게 없었다는 뜻이지 갱신이 멈춘 게 아니다.

이름으로 찾기

의원 299명의 이름도 검색된다. 이름이 같은 의원이 있어(박지원 2명) 결과에 정당과 선거구를 함께 보여준다. 비례대표는 지역구가 없어 이름으로 만든 주소로 간다.

이름을 눌렀을 때 새 페이지를 만들지 않고 그 의원의 지역구 카드로 보낸다. 같은 내용을 주소만 바꿔 두 번 두면 검색엔진이 중복으로 본다.

동네 이름을 선거구로 잇는 방법

열린국회정보 OpenAPI에는 주소와 선거구를 잇는 데이터가 없다. 국회가 주는 건 서울 중구성동구을 같은 선거구 이름뿐이다. 그래서 공직선거법 별표1 국회의원지역선거구구역표를 국가법령정보 공동활용 API로 받아 그대로 옮겼다. 읍면동 하나가 어느 선거구인지는 전부 이 법에 적힌 대로다. 받아온 판본은 공포일자까지 district_area.source에 남는다.

선거구는 254개인데 의원은 253명이다. 강원 강릉시가 공석이라 그 지역은 카드 대신 "현재 공석"이라고 뜬다.

광주는 시도 목록에 없다. 국회 표기가 전남광주통합특별시라 광주와 전남이 한 덩어리다. "광주"로 검색해도 찾아지도록 별칭만 둔다.

입력한 말국회 표기
광주 · 광주광역시 · 전남 · 전라남도전남광주통합특별시
세종세종특별자치시
강원도 · 강원특별자치도강원
전라북도 · 전북특별자치도전북
(그 외) 서울특별시, 경기도 …서울, 경기 …

같은 이름의 의원도 있다. 22대에 박지원 의원이 두 명이다. 전북 군산시김제시부안군을, 전남광주통합특별시 해남군완도군진도군. 사람 구분은 이름이 아니라 국회의원코드로 하고 카드에는 지역구를 늘 같이 적는다.

광고 및 후원

직필은 개인이 운영하는 서비스입니다. (직필을 만든 이유)

지속가능한 좋은 품질의 서비스 제공을 위해 운영자금을 모으고자 광고를 붙이고 후원을 받고 있습니다.

후원 금액은 운영 자금으로 사용하고, 후원 금액의 일부는 재난 구호 기금 또는 교육 지원 기금으로 기부합니다.

후원하기
← 처음으로 · 의원 전체 · 지역구 전체 · 표결 안건 · 입법예고 · 소개 · 선정 기준 · 바뀐 것 · 조회 통계 · 개인정보처리방침 · 후원하기