Profile img

악하

@akastoot@hackers.pub · 147 following · 108 followers

설계 능력 없고 코딩 AI보다 못하고 뭔가 이상한 걸 만들고 있고 (, http://referral.akaiaoon.dev) 뭔가 남의 프로젝트에 기여도 하고 (, https://github.com/cosmoslide/cosmoslide) 매일 커피 비슷한 거나 마시는 여전히 직장이 없는 개발자

GitHub
@IAOON
Referral Project
referral.akaiaoon.dev

최근 그냥 코딩 에이전트에게 코딩을 넘어서 삶의 귀찮은 자동화나 일들을 대신 해주는 느낌으로도 쓸 수 있지 않을까 싶어서, 자는 동안 남은 토큰 한도로 epub 파일로 된 소설을 번역시켰더니 꽤 그럴싸한 수준의 번역이 나와서 놀랐다. 그래서 이건 좀 잘 만들어두면 굉장히 편하겠다 싶어서 pdf 파일과 epub 파일을 번역하는걸 Agent Skills로 만들어보았다.

  • PDF or epub 파일 지원
  • 번역 효율과 context window 문제를 피하기 위해 큰 파일은 잘라서 병렬로 하위 Task를 실행하는 형태로 동작
  • PDF의 경우, 텍스트를 추출 과정에서 줄바꿈 등에 대한 후처리
  • epub의 경우, 우종서(중국어나 일본어)나 RTL 방식 언어의 레이아웃에도 대응

Repository

Claude Code에서 pdf translator 스킬을 사용한 화면영어로 된 논문이 잘 번역되어 PDF로도 출력되고 있다.
11

1. 블스에 이주한다고 와놓고 하루만에 트위터로 떠나버리는 행위... 2. 텅 빈 계정만 남기고 트위터로 떠나는 행위... 3. 가지말아요 그대..

RE: https://bsky.app/profile/did:plc:uqjinmyx4cbrk26yjvr4xcms/post/3mawpcrhh6c2w

0
0
0

(번역) [RP 직후 반응글을 모아주는 피드]인 Repost Next Post를 소개합니다. 트위터에도 있었던 RT직후 반응을 보는 것에 영감을 받은 커스텀피드입니다! Repost Next Post : 반응글만 모아둠 RepostNextPost+ : 반응글과 원본 RT글을 나란히 보여줌 사용법은 피드를 열기만 하면 됩니다! 한 번 열어보고 나면 그뒤로 계속 기록되기 시작합니다. 피드를 저장만 해두고 필요할 때 꺼내보는 것도 괜찮고, 자주 보고 싶다면 고정해 탭으로 추가해 두는 것도 좋습니다.

RE: https://bsky.app/profile/did:plc:xt2h3ltab6sagq4lbpbd37m2/post/3mavhbnsx222v

0

SQL 튜닝 공부 기록

인덱스를 이용한 스캔은 조건에 맞는 데이터가 '소량'일 때 유리한 것 같다. 조건에 맞는 데이터가 너무 많은데 인덱스로 접근하게 되면 랜덤액세스가 너무 많아서 오히려 성능이 떨어질 수도 있다. 물론, 이런 경우 옵티마이저가 알아서 풀스캔을 적용하는 경우도 있다.

인덱스를 처음 배울 때에는 '데이터를 빠르게 접근하는 수단'으로만 이해했는데, 뽑아야 하는 데이터가 적을 때 더 유용성이 크다는 건 이제 이해했다.

1

내가 일반 리눅스 쓴 경험으로 이런 이야기도 썼는데! 아! 망각하는 인간에게는 고통이 반복될 뿐이다! 허나 우리 모두는 망각하지 않는가?! 우리는 모두 고통 받는다!

RE: https://bsky.app/profile/did:plc:de27rm6eyuf5ez6gmvjdmilq/post/3mcor36wxxk2x

2
1

악하 shared the below article:

MS Outlook(메일 클라이언트)의 데이터를 ChatGPT로 보내기

고남현 @gnh1201@hackers.pub

주고받는 이메일 데이터에 AI를 활용하는 것에 대한 이야기가 나왔다.

하지만, 이걸 위해 메일 서버를 별도로 구축하거나, 메일 클라이언트와 검색 기능 등을 별도로 코딩하기에는 아무리 AI Code Generation을 쓴다고 해도, 쓸만한 결과물이 나오기까지의 과정이 여간 쉬운 일이 아니다.

결국, 이메일과 관련된 모든 기능이 이미 있는 "MS Office"에 붙어서 바로 코딩할 수 있는 JS 프레임워크를 이용하기로 했다.

MS Outlook의 메일을 AI로 분석하는 실제 예시

// Analyze Microsoft Outlook data with ChatGPT
// Require: WelsonJS framework (https://github.com/gnh1201/welsonjs)
// Workflow: Microsoft Outlook -> OpenAI -> Get Response
var Office = require("lib/msoffice");
var LIE = require("lib/language-inference-engine");

function main(args) {
    var prompt_texts = [];

    var keyword = "example.com";
    var maxCount = 10;
    var previewLen = 160;

    console.log("Searching mails by sender OR recipient contains: '" + keyword + "'.");
    console.log("This test uses Restrict (Sender/To/CC/BCC) + Recipients verification.");
    console.log("Body preview length: " + previewLen);

    var outlook = new Office.Outlook();
    outlook.open();
    outlook.selectFolder(Office.Outlook.Folders.Inbox);

    var results = outlook.searchBySenderOrRecipientContains(keyword);
    console.log("Printing search results. (max " + maxCount + ")");

    results.forEach(function (m, i) {
        var body = String(m.getBody() || "");
        var preview = body.replace(/\r/g, "").replace(/\n+/g, " ").substr(0, previewLen);
        
        var text = "#" + String(i) +
            " | From: " + String(m.getSenderEmailAddress()) +
            " | To: " + String(m.mail.To || "") +
            " | Subject: " + String(m.getSubject()) +
            " | Received: " + String(m.getReceivedTime());

        console.log(text);
        console.log("  Body: " + preview);
        
        // Add an email data to the prompt text context
        prompt_texts.push(text);
        
        // The body to reduce token usage and avoid sending overly large/sensitive content.
        var bodyForPrompt = body;
        var maxBodyLengthForPrompt = 2000; // Keep the body snippet short
        if (bodyForPrompt.length > maxBodyLengthForPrompt) {
            bodyForPrompt = bodyForPrompt.substring(0, maxBodyLengthForPrompt) + "...";
        }
        prompt_texts.push("  Body: " + bodyForPrompt);
    }, maxCount);

    outlook.close();

    // build a AI prompt text
    var instruction_text = "This is an email exchange between the buyer and me, and I would appreciate it if you could help me write the most appropriate reply.";
    prompt_texts.push(instruction_text);

    // complete the prompt text
    var prompt_text_completed = prompt_texts.join("\r\n");

    //console.log(prompt_text_completed);  // print all prompt text

    // get a response from AI
    var response_text = LIE.create().setProvider("openai").inference(prompt_text_completed, 0).join(' ');

    console.log(response_text);
}

exports.main = main;

실행 방법

1. CLI 사용

모든 작성 및 저장을 마친 후, 다음 명령을 통해 실행한다. (outlook_ai.js 파일로 저장했을 때.

cscript app.js outlook_ai

2. GUI 사용

모든 작성 및 저장을 마친 후, WelsonJS Launcher 앱을 통해 실행한다.

실행하면 어떤 결과가 나오는가?

메일 내용에는 개인정보가 포함되어 있으므로 예시는 따로 첨부하지 않았다.

위 코드의 작업이 성공하면 메일 내용이 출력되면서, OpenAI 서버에서 분석을 마친 결과값을 얻어올 수 있다.

Read more →
0

Sometimes when I see programming experts trying to help new learners I imagine what would happen if we were a driving school:

"The gas pedal makes the car go, right?"

"Well, only if the engine is started, and not if you are out of gas, and not if the car is in neutral, and not if the car is parked against a wall, and not if the parking brake is on, and it shouldn't be called a gas pedal in an electric car, and, and, and...."

2
0
0
0
4
1
2

악하 shared the below article:

생성 AI 논의에 대해 두서없이 몇 가지

lark @lark@hackers.pub

오랫동안 머신러닝 딥러닝 AI 모델링을 업으로 삼아 왔지만 정작 LLM이나 이미지 생성 같은 생성쪽은 피해다니다 보니[1] 이쪽 주제에 대해 아는 척 하기도 쉽지 않지만.. 관련 논의들 구경하다 보면 제가 평소 생각하는 중요 지점들이 잘 이야기되지 않는 것 같아 의식의 흐름을 따라 이것저것 남겨봅니다.

우선 모델이 생성한 결과물이 어떤 성격이나 맥락을 가지는지에 따라 저작권 문제가 완전히 달라지는데, 이건 원래 저작권에 대한 전반적인 성격이 그러하기 때문입니다. 기존 저작물을 복사/변형하더라도 그 목적이 원래 저작물과 판이하게 다를수록 저작권 침해가 아니라 fair use로 인정받을 가능성이 높아집니다.

맥락과 의도가 얼마나 중요한지를 보여주는 상징적인 사례가 구글 북스 소송인데, 구글 북스는 저작권이 있는 책을 사용자들에게 그대로 보여주니까 심각한 저작권 침해로 보일 수 있지만, 법정에서는 구글 북스 웹사이트가 원래 책 내용을 그대로 접근하는 목적을 막고 검색이라는 새로운 목적에만 사용가능하도록 했다고 판단했습니다.

이러한 다양한 사례 연구들이 Foundation Models and Fair Use에 나와 있습니다. 이 논문은 AI 연구자들과 법학 연구자가 같이 썼고 여러 legal edge case가 등장해서 생각을 정리하는 데에 도움이 될 수 있습니다.

Fair use의 핵심 요소인 transformative에 대해 AI모델 입장에서 보면, 사용자가 준 입력 텍스트에 있는 정보를 추출하거나 변환하는 task가 이에 해당할 가능성이 높습니다. 가장 유명한 예시가 텍스트 번역일 것 같은데, 사용자가 입력한 텍스트를 다른 언어로 바꾸는 것이 전부고 거기에 새로운 창작성이 드러나지는 않습니다[2]. 제가 이해하기로는 LLM이나 소위 AI가 잘 한다고 알려진 task도 대부분 이러한 것입니다. 번역이라든지, 텍스트 포맷을 바꾼다든지 등등. 제 주변에 LLM 잘 활용하신다는 분들을 보면 아마도 대부분 그렇게 쓰시는 것 같고요.

여기서 UX 관점에서의 불평을 하고 싶은데요, 무조건적인 텍스트 생성이 아니라 주어진 입력을 변환하는 능력이 LLM의 핵심 가치라면 모델이나 서비스 입장에서 그런 기능만 제공하고 지나친 생성을 제한하는 UI나 기술 장치를 도입해야 하지 않을까요? LLM을 긍정적으로 생각하지만 전반적인 생성(특히 입력보다 출력이 더 자유도가 높을 경우)이 사회적으로 위험하다고 생각된다면 그러한 조치를 LLM 서비스 제공자들에게 요구할 수는 없을까요? 저는 이러한 방향의 논의를 거의 본 적이 없는데, 아마 LLM를 접해본 사람들은 긍정적이든 부정적이든 그런 인터페이스가 어쩔 수 없는 일이라고 가정하고 있어서 그런 것 같습니다. (마침 며칠 전부터 ChatGPT나 Gemini에 번역 전용 UI가 생겼다는 소식이 보이고 있습니다. 이 글을 조금 더 빨리 쓸 걸 그랬네요..)

프로그래밍 쪽에서도 비슷하게 코드를 생성하는 사용법보다는 코드를 읽고 정보를 추출해주는 쪽이 저작권이나 윤리 문제가 적고 프로그래머의 능력 향상에 도움이 되지 않을거라고 생각하고요. (제가 상상하는 최적의 코딩 AI agent는 Rubber duck에 가까운데, 모든 질문과 해답이 제 머릿속에서 나와야 한다고 생각합니다. 그 중 문제 해결이나 능력 향상에 명백히 도움 안 될 질문만 잘 쳐내주면 좋겠어요.)

cf: 최근 Moral Codes를 조금씩 읽고 있습니다. 프로그래밍과 UI와 LLM과 윤리에 대한 책입니다. 아직 전부를 차근차근 읽은 건 아니지만, 기존의 LLM 논의가 갖혀있던 프레임에 빠져나오는 데에 큰 도움이 될 수 있다고 보여서 이 주제에 관심이 있는 분들에게 추천합니다. Open access라 무료로 볼 수 있어요.


  1. Generative AI in Servo에서 제시하는 potential exceptions가 제 분야와 정확하게 겹칩니다. ↩︎

  2. 현실적으로는 학습 데이터 오류 등으로 입력에 없던 내용이 튀어나오는 문제가 있습니다. Hallucination이라는 용어가 LLM 논의할때 주로 나오지만 실제로는 번역 task 연구 논문에서 처음 제시된 용어이고 해당 분야에서 이 문제는 오랫동안 중요하게 인지되어 왔습니다. ↩︎

Read more →
4

모두 새해 복 많이 받으시기 바랍니다!

FOSS for All () 에서는 오는 1월 31일에 모두의연구소 강남캠퍼스에서 첫 개최를 준비하고 있습니다. 국내 Fiscal sponsorship 사례 연구, 포용기술 전문가 간담회 후기 등을 주제로 프로그램이 구성 될 예정입니다.

참가 등록이 몇일 안으로 열릴 예정이니, 조금만 기다려 주세요!

1
3
11
3
0
0
0
8
1

악하 shared the below article:

코드를 한 줄도 안 짰는데, 최고의 개발자로 평가받았다

고남현 @gnh1201@hackers.pub

코드를 한 줄도 안 짰는데, 최고의 개발자로 평가받았다

최근(정확하게는 작년 7월쯤) 한 사람이 실리콘밸리 회사를 포함해 많게는 60여 개의 회사에 동시에 취업해 일했다는 이야기가 화제가 되었다. 놀라운 점은 그가 여러 회사를 속였다는 사실이 아니라, 오히려 각 회사에서 “일을 정말 잘한다”는 평가를 받았다는 점이었다. 더 어처구니없는 사실은, 그가 실제로는 코드를 거의, 혹은 전혀 작성하지 않았다는 것이다.

그의 직함은 분명 프로그래머였다. 채용 공고 역시 프로그램을 작성할 사람을 찾고 있었다. 그러나 실무에 투입된 뒤 그가 한 일은 코드 작성이 아니라 방향 제시, 구조 정리, 기술 선택에 대한 조언, 그리고 갈등 중재였다. 말하자면 그는 개발자가 아니라 컨설턴트처럼 일했다. 그런데 결과적으로 팀의 생산성은 올라갔고, 프로젝트는 이전보다 더 잘 굴러갔다.

이 기묘한 상황은 개인의 기지나 편법 때문이 아니라, 현대 소프트웨어 조직이 안고 있는 구조적인 모순을 드러낸다.

회사는 정말로 ‘코드를 짜는 사람’을 원했을까

많은 회사가 개발자를 채용할 때 “무엇을 만들 사람인가”보다 “어떤 직무명을 가진 사람인가”를 먼저 적는다. 백엔드 개발자, 시니어 엔지니어, 풀스택 개발자 같은 익숙한 단어들이 채용 공고를 채운다. 그러나 실제로 현장에 들어가 보면 문제는 코드에 있지 않은 경우가 훨씬 많다.

무엇을 만들어야 할지 내부 합의가 없고, 기술 선택에 대한 책임을 누구도 지고 싶어 하지 않으며, 기존 시스템은 누더기처럼 얽혀 있다. 개발자들은 각자 옳은 말을 하지만, 결정은 나지 않는다. 이때 회사에 진짜로 필요한 사람은 코드를 잘 짜는 사람이 아니라, 결정을 내려주고 방향을 정해주는 사람이다.

그 사례의 주인공은 바로 이 공백을 정확히 채웠다. 그는 코드를 쓰지 않았지만, 쓸 필요 없는 코드를 줄였고, 잘못된 선택을 미리 막았으며, 팀이 앞으로 나아갈 수 있도록 정리해 주었다. 회사 입장에서는 그 어떤 개발자보다 “일을 잘하는 사람”처럼 보일 수밖에 없었다.

가장 가치 있는 코드는 ‘안 써도 된 코드’다

소프트웨어 개발에서 가장 큰 손실은 느린 타이핑이 아니라 잘못된 방향이다. 필요 없는 기능을 만드는 데 들어간 시간, 나중에 갈아엎어야 할 구조를 유지하느라 소모되는 에너지, 아무도 책임지지 않는 설계 결정들이 프로젝트를 망친다.

컨설턴트형 인력은 바로 이 지점을 건드린다. “이 기능은 지금 만들 필요가 없다”, “이 문제는 기술 문제가 아니라 조직 문제다”, “이 구조로 가면 반드시 다시 고치게 된다”는 말을 할 수 있는 사람은 코드 생산량으로는 측정되지 않지만, 결과에는 결정적인 영향을 미친다.

그 사람이 동시에 여러 회사에서 일할 수 있었던 이유도 여기에 있다. 각 회사는 하루 여덟 시간을 모두 가져간 것이 아니라, 결정이 막히는 순간에 필요한 ‘판단력’을 빌린 것이었다.

채용 공고는 문제를 말하지 못한다

만약 회사가 솔직하게 채용 공고를 쓸 수 있다면 이렇게 적혀야 할지도 모른다.

“우리는 무엇을 해야 할지 잘 모르겠습니다. 내부에 의견 충돌이 많고, 누군가 정리해 주길 원합니다.”

하지만 현실에서는 그럴 수 없으니, 프로그래머라는 이름으로 사람을 찾는다. 그 결과 코드 작성자를 뽑았다고 생각했지만, 사실은 컨설턴트가 더 잘 맞는 자리에 개발자를 앉혀두는 일이 반복된다.

이번 사례는 그 불일치가 극단적으로 드러난 사건일 뿐이다.

불편하지만 피할 수 없는 결론

이 이야기가 많은 개발자에게 불편하게 느껴지는 이유는 분명하다. 우리는 오랫동안 “코딩을 잘하면 인정받는다”고 믿어왔기 때문이다. 그러나 현실의 많은 조직에서 가장 희소한 자원은 코딩 능력이 아니라 문제 정의 능력, 판단력, 그리고 책임지고 결정하는 용기다.

이 사건은 사기극이라기보다, 회사들이 스스로 무엇이 필요한지 정확히 알지 못했다는 증거에 가깝다. 그리고 그 틈을 정확히 읽어낸 사람이, 코드를 한 줄도 쓰지 않고도 최고의 개발자로 평가받았다.

어처구니없어 보이지만, 이것이 지금의 소프트웨어 산업이 서 있는 위치다.

Read more →
8
8
0
0

LLM 코딩의 부정적인 영향으로 우려하는 부분이 있는데, 점점 현실이 되어가는거 같다. 사람들이 코드를 안 읽고 너무 많이 짠다.

사실 오랫동안 많은곳에서 쓰이는 좋은 프로그램들은, 그 많은 코드를 짜서 어떻게든 동작시키게 만들었다는 것 이전에, 그냥 '뭘 만들지'에 대한 접근부터 훌륭한 경우가 많다(많은 UNIX 기본 프로그램들을 생각해보라). 옛날에는, 내가 어떤 기능 A가 필요할때, 내가 그 기능 A를 짜는게 힘든 일이니까 그 기능 A를 제공하는 프로그램을 먼저 찾게되고, 그러면 그 프로그램은 나의 근시안적인 접근보다 나은 더 좋은 개념을 갖고 있는 경우가 많았다. 그러면 나는 이제 그 개념을 익히며 내 자신을 업데이트하면 되는 것이다.

근데 자기 자신을 업데이트하는건 피곤한 일이라서, 사람들은 그걸 피할수 있는 기회를 놓치지 않는다. 그래서 현재 자기 수준에 맞는 평범한 프로그램을 만드는 길을(단돈 0.1$) 기꺼이 선택해버린다.

7

안녕하세요, 플래닛 등의 연합우주 SNS를 사용한 적 있는 모든 사람을 대상으로, 동인을 위한 더 나은 SNS 및 서비스 개발을 위한 설문조사를 1월 11일(일)까지 진행 중입니다.

tally.so/r/OD4J6R

혹시 설문조사에 대한 질문이나 개선점 등이 필요하다 생각하시다면 편히 멘션이나 DM으로 이야기해주세요. 감사합니다.

0
0
0

I finally got the data transfer from the AISC110C high-speed camera sensor working!

It's a 5€ chip that outputs 80x120 video at up to 40k fps.

Data is read with a Xilinx Spartan7 and transmitted via USB3 with a Cypress FX3, each on its own little PCB.

The front PCB is exchangeable, making this a neat modular platform. I already have an analog video frontend with the ADV7182 and am working on a Cameralink interface.

Videos are coming tomorrow, I need more light for the high framerates.

A greyscale image of a hand giving thumbs-up. It's a video capture of the highspeed sensor, albeit only recording at 30fps with 8ms exposure time in this case.A stack of three PCBs sitting on a grey 3D-printed base (the back of the camera housing)  lying on top of a hand. The uppermost PCB has the image sensor on top. Between the upper and middle PCB a 80 pin connector is visible. The middle and lower PCB have some components visible on their top sides.The grey 3D-printed casing of the PCB stack is sitting in a bracket on top of a camera mount. On the front a metal CS-mount thread is screwed into the 3D-print. Inside that, a printed adapter is holding a black M12 lens.
0
0
0

오픈소스 활동하면서 고민하게 되는 법적 어려움들

1. 오픈소스가 완전 공개에 무료인 것은 맞으나, 무상이라도 저작권 관리, 기업 납품 등 법적 행위가 정상적으로 성립하려면 절차상 결국 사업자등록 사실이 필요한 경우가 많다.

2. 리눅스 재단과 하버드대 공동 연구에 따르면, 오픈소스 메인테이너들은 본업 외에 주당 20시간 이상을 오픈소스에 쏟으며 사실상 '투잡'을 뛰지만 월급은 한 곳에서만 받는 기형적 구조다.

3. 이런 기형적인 구조에서, 그나마 비영리 활동을 한다고 인정을 받는 방법을 고민하게 되지만 실질적으로는 그 어느 나라도 제도적으로 방법이 없다시피한 경우가 많다.

4. 기존의 영리 사업자 제도에 대부분을 의존해야 해서 협력자가 아닌, 겸업으로 인식되거나 아예 경쟁사를 창업한 것으로 인식되는 등 의도치 않은 여러가지 오해를 불러일으키기도 한다.

5. 이 1에서 4까지의 내용을 이해하고 상담해주는 법률가조차 찾아보기 어렵다.

2
0
0
1
1

악하 shared the below article:

Hackers' Pub 신고(flag) 기능 기획서

洪 民憙 (Hong Minhee) @hongminhee@hackers.pub

개요

목적

신고 기능은 Hackers' Pub 커뮤니티의 행동 강령(code of conduct)을 위반하는 콘텐츠나 사용자를 식별하고, 관리자가 적절한 조치를 취할 수 있도록 돕는 시스템입니다.

핵심 철학

신고 기능의 궁극적인 목적은 계도와 성장입니다. 무균실처럼 완벽한 사용자만을 남기려는 것이 아니라, 신고를 통해 각자의 행동을 돌아보고 더 나은 커뮤니티 구성원으로 성장할 수 있는 기회를 제공하는 데 있습니다.

추방은 최후의 수단이며, 시스템은 다음과 같은 단계적 접근을 권장합니다:

  1. 인지 — 피신고자가 자신의 행동이 문제가 될 수 있음을 알게 됩니다
  2. 성찰 — 왜 그 행동이 문제인지 이해할 기회를 갖습니다
  3. 개선 — 행동을 수정하고 커뮤니티와 조화롭게 참여합니다
  4. 제재 — 개선 의지가 없거나 심각한 위반의 경우에만 적용됩니다

분산형 네트워크 고려

Hackers' Pub은 ActivityPub 프로토콜 기반의 분산형 소셜 네트워크입니다. 따라서 신고 기능도 다음을 고려하여 설계되었습니다:

  • 다른 서버(인스턴스)에 호스팅된 콘텐츠도 신고 가능
  • Mastodon 등 주요 ActivityPub 플랫폼과의 호환성
  • 연합(federation) 환경에서의 조치 전파

설계 원칙

신고자 보호

원칙
신고자의 신원은 철저히 비공개로 유지됩니다.
근거
신고자가 보복을 두려워하면 신고를 주저하게 되고, 이는 커뮤니티 건강성을 해칠 수 있습니다. 익명성이 보장되어야 신고 시스템이 효과적으로 작동합니다.
구현
  • 피신고자에게는 신고 사실과 사유만 전달되며, 신고자 정보는 공개되지 않습니다
  • 관리자만 신고자 정보에 접근할 수 있습니다
  • 데이터베이스 수준에서도 접근 제어가 적용됩니다

피신고자의 알 권리

원칙
피신고자는 자신이 왜 신고되었는지 알 권리가 있습니다.
근거
무엇이 문제인지 알지 못하면 개선할 수 없습니다. 계도라는 목적을 달성하려면 피신고자가 자신의 행동을 돌아볼 수 있는 충분한 정보를 제공해야 합니다.
구현
  • 신고 사유(행동 강령 위반 내용)가 피신고자에게 전달됩니다
  • 어떤 콘텐츠가 문제가 되었는지 명시됩니다
  • 단, 신고자가 누구인지는 알 수 없습니다

행동 강령의 유연한 참조

원칙
행동 강령은 살아있는 문서이며, 시간이 지남에 따라 발전하고 변화할 수 있습니다.
근거
커뮤니티가 성장하고 사회적 맥락이 변화함에 따라 행동 강령도 함께 진화해야 합니다. 신고 시스템은 이러한 변화에 유연하게 대응할 수 있어야 합니다.
구현
  • 신고 사유를 특정 조항 번호에 하드코딩하지 않습니다
  • 신고 시점의 행동 강령 버전을 기록하여 맥락을 보존합니다
  • LLM 매칭 시 현재 행동 강령 전문을 참조하여 동적으로 분석합니다
  • 신고자가 작성한 원본 사유는 항상 보존됩니다

투명한 처리 과정

원칙
신고의 처리 과정과 결과는 관련 당사자에게 투명하게 공유됩니다.
근거
신고자는 자신의 신고가 어떻게 처리되었는지 알 권리가 있으며, 피신고자도 어떤 조치가 취해졌는지 알아야 합니다.
구현
  • 신고자에게 처리 진행 상황과 최종 결과가 통보됩니다
  • 피신고자에게 조치 내용과 사유가 전달됩니다
  • 관리자의 판단 근거가 기록됩니다

단계적 제재

원칙
제재는 위반의 심각성과 빈도에 비례하여 단계적으로 적용됩니다.
근거
경미한 위반에 과도한 제재를 가하면 커뮤니티 참여를 위축시키고, 심각한 위반에 가벼운 제재를 가하면 커뮤니티 안전을 해칩니다.
구현
  • 경고 → 콘텐츠 검열 → 일시 정지 → 영구 정지의 단계적 체계
  • 위반 이력이 누적되어 다음 제재 수준에 반영됩니다
  • 심각한 위반은 단계를 건너뛰고 즉각적인 강력한 조치 가능

용어 정의

용어 정의
신고(flag/report) 행동 강령 위반으로 의심되는 콘텐츠나 사용자를 관리자에게 알리는 행위
신고자(reporter) 신고를 제출하는 사용자
피신고자(reported) 신고의 대상이 되는 사용자
신고 대상(target) 신고된 콘텐츠(게시글, 단문) 또는 사용자
관리자(moderator) 신고를 검토하고 조치를 취할 권한이 있는 사용자
조치(action) 관리자가 신고에 대해 취하는 결정 (기각, 경고, 검열, 정지 등)
이의 제기(appeal) 피신고자가 조치에 대해 재검토를 요청하는 행위
로컬 사용자 Hackers' Pub에 계정이 있는 사용자
원격 사용자 다른 ActivityPub 인스턴스의 사용자

신고 대상

콘텐츠 신고

사용자는 다음 유형의 콘텐츠를 개별적으로 신고할 수 있습니다:

게시글(article) 신고

대상
장문의 블로그 형식 게시글
표시 위치
게시글 하단 또는 더보기 메뉴에 “신고하기” 옵션
신고 시 수집 정보
  • 게시글 ID 및 영구 링크
  • 게시글 작성자 정보
  • 신고 시점의 게시글 내용 스냅샷 (증거 보존)
  • 신고자가 작성한 사유

단문(note) 신고

대상
짧은 마이크로블로그 형식 글
표시 위치
단문의 더보기 메뉴에 “신고하기” 옵션
신고 시 수집 정보
게시글과 동일

사용자 신고

특정 사용자의 전반적인 행동 패턴이 문제가 되는 경우, 개별 콘텐츠가 아닌 사용자 자체를 신고할 수 있습니다.

사용 시나리오
  • 여러 콘텐츠에 걸쳐 지속적으로 문제 행동을 보이는 경우
  • 개별 콘텐츠는 경계선상에 있지만, 전체적인 패턴이 문제인 경우
  • 프로필 자체(이름, 약력, 프로필 사진 등)가 행동 강령을 위반하는 경우
표시 위치
사용자 프로필 페이지의 더보기 메뉴에 “사용자 신고하기” 옵션
신고 시 수집 정보
  • 사용자 ID 및 프로필 링크
  • 신고 시점의 프로필 정보 스냅샷
  • 신고자가 작성한 사유
  • (선택) 관련 콘텐츠 링크 첨부 가능

원격 콘텐츠 및 사용자

다른 ActivityPub 인스턴스의 콘텐츠와 사용자도 동일하게 신고할 수 있습니다.

근거
연합 타임라인에 표시되는 모든 콘텐츠는 Hackers' Pub 사용자에게 영향을 미치므로, 원격 콘텐츠도 신고 대상이 되어야 합니다.
처리 방식
  • Hackers' Pub 내에서의 표시/연합 여부에 대한 조치
  • 원격 인스턴스로 ActivityPub Flag 액티비티 전송 (선택적)

신고 프로세스

신고 흐름도

flag_process start 사용자가 콘텐츠/사용자 신고 클릭 form 신고 양식 표시 start->form reason 사유 작성 (자유 형식) form->reason submit 신고 제출 reason->submit llm LLM이 사유를 분석 submit->llm coc 행동 강령 조항 매칭 llm->coc save 신고 저장 (대기 상태) llm->save notify_mod 관리자에게 알림 발송 save->notify_mod notify_reporter 신고자에게 접수 확인 notify_mod->notify_reporter

신고 양식

신고 양식은 간결하면서도 필요한 정보를 수집할 수 있도록 설계됩니다.

필수 입력 항목

신고 사유 (자유 형식 텍스트)

이 콘텐츠/사용자를 신고하는 이유를 설명해 주세요.
구체적인 행동 강령 조항을 알지 못해도 괜찮습니다.
어떤 점이 불편하거나 문제가 된다고 느꼈는지
자유롭게 작성해 주세요.

[                                        ]
[                                        ]
[                                        ]

최소 10자 이상 작성해 주세요.

근거:

  • 사용자가 행동 강령의 모든 조항을 숙지하고 있다고 가정하지 않습니다
  • 자유 형식으로 작성하면 더 풍부한 맥락을 수집할 수 있습니다
  • LLM이 사유를 분석하여 관련 조항을 자동으로 매칭합니다

선택 입력 항목

추가 콘텐츠 링크 (사용자 신고 시)

관련된 다른 콘텐츠가 있다면 링크를 추가해 주세요. (선택)

[링크 추가 +]

근거: 사용자 신고의 경우, 문제 행동의 패턴을 보여주는 여러 콘텐츠를 함께 제출하면 관리자가 더 정확한 판단을 내릴 수 있습니다.

LLM 기반 행동 강령 매칭

신고가 제출되면 LLM이 신고 사유를 분석하여 관련된 행동 강령 조항을 식별합니다.

매칭 프로세스

  1. 입력 구성

    • 신고자가 작성한 사유 텍스트
    • 현재 버전의 행동 강령 전문
    • 신고된 콘텐츠 내용 (있는 경우)
  2. LLM 분석

    • 신고 사유와 행동 강령 조항 간의 관련성 분석
    • 관련 조항 식별 및 신뢰도 점수 산출
    • 분석 요약 생성
  3. 결과 저장

    • 매칭된 조항 목록 (신뢰도 점수 포함)
    • LLM 분석 요약
    • 신고 시점의 행동 강령 버전 식별자

행동 강령 버전 관리

근거
행동 강령이 변경되면 과거 신고의 맥락이 불명확해질 수 있습니다. 따라서 신고 시점의 행동 강령 버전을 기록하여 맥락을 보존합니다.
구현 방식
  • 행동 강령 파일의 Git 커밋 해시를 버전 식별자로 사용
  • 신고 기록에 버전 식별자 저장
  • 관리자가 신고를 검토할 때 해당 버전의 행동 강령 참조 가능

매칭 결과 활용

관리자 검토
매칭 결과는 관리자의 참고 자료로 활용됩니다
최종 판단
관리자가 매칭 결과를 수정하거나 무시할 수 있습니다
피신고자 통보
최종 확정된 위반 조항이 피신고자에게 전달됩니다

중복 신고 처리

같은 콘텐츠나 사용자에 대해 여러 신고가 접수될 수 있습니다.

처리 방식
  • 동일 대상에 대한 신고는 하나의 “신고 케이스”로 그룹화됩니다
  • 각 신고의 사유는 개별적으로 보존됩니다
  • 관리자에게는 신고 건수와 함께 표시됩니다
  • 신고 건수가 많을수록 우선순위가 높아집니다
근거
  • 여러 사람이 독립적으로 같은 문제를 발견했다면 더 심각한 문제일 가능성이 높습니다
  • 다양한 관점의 신고 사유를 종합하면 더 정확한 판단이 가능합니다

신고 내역 조회

신고자는 자신이 제출한 신고의 상태를 확인할 수 있습니다.

확인 가능한 정보
  • 신고 대상 (콘텐츠/사용자)
  • 신고 일시
  • 자신이 작성한 신고 사유
  • 처리 상태 (대기 중 / 검토 중 / 처리 완료)
  • 처리 결과 (조치됨 / 기각됨)
확인 불가능한 정보
  • 다른 신고자의 존재 여부
  • 구체적인 제재 내용 (프라이버시 보호)
  • 피신고자의 이의 제기 내용

관리자 처리 프로세스

신고 검토 흐름도

moderation_process cluster_review 콘텐츠/사용자 검토 pending 신고 접수 (대기 상태) check 관리자가 신고 확인 pending->check reviewing 검토 시작 (검토 중) check->reviewing review1 신고된 콘텐츠 확인 review2 신고 사유 검토 review3 LLM 매칭 결과 참고 review4 사용자 이력 확인 review5 맥락 파악 decision 판단 결정 review5->decision dismiss 기각 decision->dismiss warn 경고 decision->warn action 제재 decision->action notify 조치 기록 및 알림 - 신고자에게 결과 통보 - 피신고자에게 조치 통보 - (필요시) 원격 서버 통보 dismiss->notify warn->notify action->notify

신고 상태

상태 설명
pending 신고가 접수되어 검토 대기 중
reviewing 관리자가 검토 중
resolved 처리 완료 (조치됨)
dismissed 기각됨 (위반 아님)

검토 시 확인 사항

관리자는 다음 정보를 종합적으로 검토합니다:

신고 정보

  • 신고자가 작성한 사유
  • LLM이 매칭한 행동 강령 조항
  • 신고 건수 (중복 신고의 경우)
  • 각 신고자의 사유 (중복 신고의 경우)

콘텐츠 정보

  • 신고된 콘텐츠 원문
  • 콘텐츠의 맥락 (댓글 스레드 등)
  • 신고 시점의 스냅샷 (수정/삭제된 경우)

사용자 정보

  • 피신고자의 이전 위반 이력
  • 이전 경고/제재 기록
  • 계정 생성일 및 활동 기간
  • 로컬/원격 사용자 여부

조치 옵션

관리자는 다음 조치 중 하나를 선택합니다:

조치 설명 적용 기준
기각 위반이 아니라고 판단 행동 강령 위반 사실이 없는 경우
경고 경고 메시지 발송 경미한 위반, 초범인 경우
콘텐츠 검열 해당 콘텐츠 숨김 처리 콘텐츠 자체가 문제인 경우
일시 정지 일정 기간 계정 정지 반복 위반 또는 중간 수준의 위반
영구 정지 계정 영구 정지 심각한 위반 또는 지속적 악의적 행동

조치 시 필수 입력 사항

관리자가 조치를 취할 때 다음을 기록해야 합니다:

위반 조항 (최종 확정):
[행동 강령 내 관련 조항 선택/입력]

조치 사유:
[관리자의 판단 근거를 상세히 기술]

피신고자에게 전달할 메시지:
[피신고자가 받을 통보 내용]

(일시 정지의 경우) 정지 기간:
[시작일] – [종료일]

근거:

  • 조치의 투명성을 확보합니다
  • 이의 제기 시 검토 자료로 활용됩니다
  • 일관된 판단 기준을 유지하는 데 도움이 됩니다

피신고자 프로세스

신고 통보

피신고자는 자신이 신고되었다는 사실과 사유를 알림으로 받습니다.

통보 시점

즉시 통보하지 않는 경우:

  • 신고 접수 직후에는 피신고자에게 통보하지 않습니다
  • 무분별한 신고로 인한 불필요한 스트레스 방지

통보하는 경우:

  • 관리자가 신고를 검토하고 조치를 결정한 후 통보합니다
  • 기각된 경우에도 교육적 목적으로 통보할 수 있습니다 (관리자 재량)

통보 내용

경고/제재 시:

귀하의 [콘텐츠/계정]에 대해 신고가 접수되어 검토한 결과,
행동 강령 위반으로 판단되어 다음과 같은 조치가 취해졌습니다.

위반 내용:
[행동 강령의 관련 조항]

대상 콘텐츠:
[해당되는 경우 콘텐츠 링크]

조치:
[경고 / 콘텐츠 검열 / N일 정지 / 영구 정지]

관리자 메시지:
[관리자가 작성한 설명]

이 조치에 대해 이의가 있으시면 아래 버튼을 통해
이의 제기를 하실 수 있습니다.

[이의 제기하기]

기각 통보 시 (선택적):

귀하의 [콘텐츠/계정]에 대해 신고가 접수되었으나,
검토 결과 행동 강령 위반에 해당하지 않는다고 판단되었습니다.

다만, 일부 커뮤니티 구성원이 불편함을 느꼈을 수 있으므로
참고해 주시면 감사하겠습니다.

관련 내용:
[간략한 설명]

피신고자가 확인할 수 있는 정보

정보 확인 가능 여부
신고된 사실 가능
위반으로 지적된 행동 강령 조항 가능
대상 콘텐츠 가능
조치 내용 및 기간 가능
관리자의 판단 사유 가능
신고자가 누구인지 불가능
신고자가 작성한 원본 사유 불가능
신고 건수 불가능

근거: 피신고자에게 개선에 필요한 정보는 모두 제공하되, 신고자를 특정할 수 있는 정보는 철저히 보호합니다.

제재 중 제한 사항

콘텐츠 검열

  • 해당 콘텐츠가 타임라인과 검색에서 숨겨집니다
  • 직접 링크(퍼머링크)로는 접근 가능하지만, 검열 안내가 표시됩니다
  • 작성자 본인은 콘텐츠를 볼 수 있습니다

일시 정지

  • 새로운 콘텐츠 작성 불가
  • 댓글 작성 불가
  • 반응 불가
  • 팔로/언팔로 불가
  • 기존 콘텐츠 열람은 가능
  • DM 수신은 가능하나 발신 불가

영구 정지

  • 계정 접근 불가
  • 모든 기능 사용 불가
  • 기존 콘텐츠는 숨김 처리됨

이의 제기 프로세스

이의 제기 자격

  • 조치를 받은 피신고자만 이의 제기 가능
  • 하나의 조치에 대해 1회의 이의 제기 가능
  • 이의 제기 기한: 조치 통보 후 14일 이내

이의 제기 흐름도

appeal_process start 피신고자가 이의 제기 write 이의 내용 작성 start->write submit 이의 제출 write->submit review 관리자 검토 (다른 관리자 권장) submit->review decision 판단 review->decision reject 기각 decision->reject uphold 조치 유지 decision->uphold modify 조치 변경 decision->modify notify 결과 통보 (피신고자, 원신고자) reject->notify uphold->notify modify->notify

이의 제기 양식

이의 제기 사유:
[왜 이 조치가 부당하다고 생각하시는지 설명해 주세요]

추가 맥락 또는 증거:
[조치 결정 시 고려되지 않았다고 생각되는
맥락이나 정보가 있다면 제공해 주세요]

[제출]

이의 제기 검토

검토 원칙
  • 가능하면 원래 조치를 결정한 관리자가 아닌 다른 관리자가 검토합니다
  • 원 신고 내용, 조치 사유, 이의 제기 내용을 종합적으로 검토합니다
  • 새로운 정보나 맥락이 있는지 확인합니다
결정 옵션
  • 이의 기각: 원 조치 유지
  • 조치 완화: 더 가벼운 조치로 변경 (예: 정지 → 경고)
  • 조치 철회: 조치 취소 및 기록 정정
  • 조치 강화: 드문 경우, 이의 제기 과정에서 더 심각한 위반이 발견된 경우

결과 통보

피신고자에게:

귀하의 이의 제기를 검토한 결과를 알려드립니다.

결정: [이의 기각 / 조치 완화 / 조치 철회]

판단 사유:
[관리자의 검토 결과 설명]

(해당 시) 변경된 조치:
[새로운 조치 내용]

원 신고자에게:

귀하가 신고하신 건에 대해 피신고자로부터
이의 제기가 있어 재검토가 진행되었습니다.

재검토 결과: [원 조치 유지 / 조치 변경]

(조치가 변경된 경우)
변경 사유에 대한 간략한 설명:
[설명]

패널티 체계

패널티 종류 및 기준

경고 (warning)

설명
위반 사실을 알리고 재발 방지를 요청하는 가장 가벼운 조치입니다.
적용 기준
  • 경미한 행동 강령 위반
  • 초범이며 악의가 없어 보이는 경우
  • 실수나 무지로 인한 위반으로 판단되는 경우
효과
  • 경고 메시지가 발송됩니다
  • 경고 이력이 기록되어 향후 판단에 참고됩니다
  • 일정 기간(예: 1년) 경과 후 이력에서 제외될 수 있습니다
경고 누적
  • 경고 3회 누적 시 자동으로 더 강한 조치 검토 대상이 됩니다
  • 단, 자동 제재는 없으며 관리자의 판단이 필요합니다

콘텐츠 검열 (content censorship)

설명
특정 콘텐츠를 공개 영역에서 숨기는 조치입니다.
적용 기준
  • 콘텐츠 자체가 행동 강령을 위반하는 경우
  • 사용자의 전반적 행동보다 특정 콘텐츠가 문제인 경우
효과
  • 해당 콘텐츠가 타임라인, 검색, 추천에서 제외됩니다
  • 퍼머링크는 유지되나, 접근 시 검열 안내가 표시됩니다
  • 연합(federation)으로 다른 서버에 Delete 액티비티가 전송될 수 있습니다

검열 콘텐츠 표시

이 콘텐츠는 행동 강령 위반으로 검열되었습니다.
[원문 보기] (클릭 시 경고와 함께 표시)

일시 정지 (temporary suspension)

설명
일정 기간 동안 계정 활동을 제한하는 조치입니다.
적용 기준
  • 경고에도 불구하고 위반이 반복되는 경우
  • 중간 수준의 심각한 위반인 경우
  • 즉각적인 활동 중단이 필요하지만 영구 정지까지는 아닌 경우
정지 기간
  • 최소 1일 – 최대 90일
  • 관리자가 위반 정도에 따라 결정
  • 권장 기준:
    • 경미한 반복 위반: 1–7일
    • 중간 수준 위반: 7–30일
    • 심각한 위반 (초범): 30–90일
효과
  • 새 콘텐츠 작성 불가
  • 상호작용(반응, 댓글 등) 불가
  • 기존 콘텐츠 열람은 가능
  • 정지 해제 시 완전한 기능 복구
원격 사용자의 경우
  • Hackers' Pub 내에서 해당 기간 동안 연합 차단
  • 원격 서버 관리자에게 ActivityPub Flag 액티비티로 통보

영구 정지 (permanent suspension)

설명
계정을 영구적으로 비활성화하는 가장 강력한 조치입니다.
적용 기준
  • 매우 심각한 행동 강령 위반 (혐오 발언, 불법 콘텐츠 등)
  • 일시 정지 후에도 동일한 위반이 반복되는 경우
  • 명백한 악의를 가지고 커뮤니티를 해치려는 의도가 확인된 경우
효과
  • 계정 로그인 불가
  • 모든 기능 사용 불가
  • 공개 콘텐츠 숨김 처리
  • 프로필 페이지에 정지 안내 표시
원격 사용자의 경우
  • Hackers' Pub과의 영구적 연합 차단
  • 원격 서버 관리자에게 ActivityPub Flag 액티비티로 통보
복구
  • 원칙적으로 영구 정지는 복구되지 않습니다
  • 극히 예외적인 경우, 충분한 시간 경과 후 재심 요청 가능

패널티 이력 관리

패널티 이력 보존 기간 비고
경고 1년 1년간 추가 위반 없으면 이력에서 제외
콘텐츠 검열 무기한 콘텐츠 존재하는 한 유지
일시 정지 무기한 기록은 유지, 판단 시 경과 시간 고려
영구 정지 무기한 -

ActivityPub 연합 처리

개요

Hackers' Pub은 ActivityPub 프로토콜을 사용하는 분산형 네트워크의 일부입니다. 신고 기능도 이 환경에서 원활히 작동해야 합니다.

Flag 액티비티

ActivityPub 명세에는 Flag 액티비티가 정의되어 있으며, 이를 통해 신고를 연합 네트워크에 전파할 수 있습니다.

Flag 액티비티 구조:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "type": "Flag",
  "actor": "https://hackerspub.example/users/moderator",
  "object": [
    "https://remote.example/users/reported_user",
    "https://remote.example/posts/problematic_post"
  ],
  "content": "Violation of Code of Conduct: harassment"
}

원격 콘텐츠 신고 처리

신고 접수

  1. 로컬 사용자가 원격 콘텐츠/사용자를 신고합니다
  2. 신고는 Hackers' Pub 데이터베이스에 저장됩니다
  3. 관리자가 일반 신고와 동일하게 검토합니다

조치 적용

  1. Hackers' Pub 내 조치:

    • 해당 콘텐츠의 로컬 캐시 숨김/삭제
    • 해당 사용자와의 연합 차단 (일시/영구)
  2. 원격 서버 통보 (선택적):

    • Flag 액티비티를 원격 서버에 전송
    • 원격 서버의 조치 여부는 해당 서버의 재량

외부에서 받은 Flag 처리

다른 서버에서 Hackers' Pub으로 Flag 액티비티가 전송된 경우:

  1. Flag 액티비티 수신 및 파싱
  2. 신고 대상이 로컬 사용자/콘텐츠인지 확인
  3. 관리자에게 외부 신고로 표시하여 알림
  4. 관리자가 검토 후 자체 판단에 따라 조치

외부 신고 표시:

[외부 신고] remote.example에서 접수됨

대상: @localuser의 콘텐츠
사유: "Violation of our community guidelines"

* 이 신고는 외부 서버에서 접수되었습니다.
  자체 행동 강령에 따라 판단해 주세요.

Mastodon 호환성

Mastodon은 가장 널리 사용되는 ActivityPub 구현체입니다. Mastodon과의 호환성을 위해 다음을 고려합니다:

  • Mastodon의 Flag 액티비티 형식 지원
  • Mastodon 관리자 API와의 연동 고려 (향후)
  • Mastodon에서 보내는 신고 수신 및 처리

알림 체계

알림 유형

알림 유형 수신자 내용
flag_received 관리자 새 신고 접수됨
flag_resolved 신고자 신고 처리 완료됨
action_taken 피신고자 조치가 취해짐
appeal_received 관리자 이의 제기 접수됨
appeal_resolved 피신고자 이의 제기 처리 완료됨
appeal_result 신고자 이의 제기로 인한 변경 알림
suspension_ending 피신고자 정지 해제 임박 알림

알림 채널

인앱 알림
기본 알림 방식
이메일
중요 알림 (조치, 정지 등)
ActivityPub
원격 사용자의 경우 해당 서버로 전송

프라이버시 및 보안

신고자 익명성 보호

원칙
신고자의 신원은 피신고자에게 절대 공개되지 않습니다.
기술적 조치
  • API 응답에서 신고자 정보 필터링
  • 관리자 UI에서만 신고자 정보 표시
  • 로그에서 신고자 정보 마스킹 (필요시)

데이터 접근 제어

역할 접근 가능 정보
일반 사용자 자신의 신고 내역만
피신고자 자신에 대한 조치 및 사유 (신고자 정보 제외)
관리자 모든 신고 정보 (신고자 정보 포함)

콘텐츠 스냅샷

신고 시점의 콘텐츠를 스냅샷으로 저장하는 이유:

  • 피신고자가 콘텐츠를 수정/삭제해도 원본 증거 보존
  • 공정한 판단을 위한 기록 유지
  • 이의 제기 시 참고 자료로 활용
보존 기간
  • 케이스 종료 후 최소 1년간 보존
  • 법적 요구사항이 있는 경우 더 오래 보존

악용 방지

허위 신고 방지
  • 동일 사용자의 동일 대상 반복 신고 제한
  • 허위 신고 시 신고자에 대한 제재 가능
  • 신고 패턴 모니터링
신고 폭주 방지
  • 단시간 다수 신고 시 속도 제한
  • 관리자에게 이상 패턴 경고

관리자 대시보드

대시보드 개요

관리자 대시보드는 신고 관리의 중심 허브입니다.

주요 화면
  1. 대기 중인 신고 목록
  2. 신고 상세 및 처리 화면
  3. 이의 제기 목록
  4. 통계 및 분석
  5. 제재 중인 사용자 목록

신고 목록 화면

┌─────────────────────────────────────────────────────────┐
│  신고 관리                                    [통계 보기] │
├─────────────────────────────────────────────────────────┤
│  필터: [전체 ▼] [대기 중 ▼] [최신순 ▼]      검색: [____]│
├─────────────────────────────────────────────────────────┤
│                                                         │
│  ⚠️ 높은 우선순위 (신고 5건 이상)                        │
│  ┌─────────────────────────────────────────────────┐   │
│  │ 🔴 @user123의 콘텐츠 (신고 7건)                 │   │
│  │    "혐오 발언", "차별적 표현" 외 5건             │   │
│  │    최초 신고: 2시간 전                          │   │
│  └─────────────────────────────────────────────────┘   │
│                                                         │
│  일반 신고                                              │
│  ┌─────────────────────────────────────────────────┐   │
│  │ 🟡 @remote@other.server 사용자 (신고 2건)       │   │
│  │    "스팸 행위"                                  │   │
│  │    최초 신고: 5시간 전                          │   │
│  └─────────────────────────────────────────────────┘   │
│  ┌─────────────────────────────────────────────────┐   │
│  │ 🟢 @newuser의 댓글 (신고 1건)                   │   │
│  │    "부적절한 언어 사용"                         │   │
│  │    신고: 1일 전                                 │   │
│  └─────────────────────────────────────────────────┘   │
│                                                         │
└─────────────────────────────────────────────────────────┘

신고 상세 화면

┌─────────────────────────────────────────────────────────┐
│  신고 상세 - 케이스 #12345                    [← 목록]  │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  📋 기본 정보                                           │
│  ────────────────────────────────────────               │
│  대상: @user123의 콘텐츠                                │
│  유형: 단문 (note)                                      │
│  신고 건수: 7건                                         │
│  상태: 대기 중                                          │
│                                                         │
│  📝 신고된 콘텐츠                                       │
│  ────────────────────────────────────────               │
│  ┌─────────────────────────────────────────────────┐   │
│  │ [콘텐츠 원문 표시]                              │   │
│  │ 작성일: 2024-12-01 14:30                        │   │
│  └─────────────────────────────────────────────────┘   │
│                                                         │
│  🔍 신고 사유 (7건)                                     │
│  ────────────────────────────────────────               │
│  1. "명백한 혐오 발언입니다" - 신고자A, 2시간 전        │
│  2. "특정 집단을 비하하는 표현" - 신고자B, 3시간 전     │
│  3. "불쾌한 차별적 언어" - 신고자C, 4시간 전            │
│  ... (더 보기)                                          │
│                                                         │
│  🤖 LLM 분석 결과                                       │
│  ────────────────────────────────────────               │
│  관련 행동 강령 조항:                                   │
│  - 차별 금지 (신뢰도: 95%)                              │
│  - 존중하는 언어 사용 (신뢰도: 88%)                     │
│                                                         │
│  📊 피신고자 이력                                       │
│  ────────────────────────────────────────               │
│  - 가입일: 2024-06-15                                   │
│  - 이전 경고: 1회 (2024-09-20)                          │
│  - 이전 정지: 없음                                      │
│                                                         │
│  ⚡ 조치                                                │
│  ────────────────────────────────────────               │
│  [기각] [경고] [콘텐츠 검열] [일시 정지] [영구 정지]    │
│                                                         │
└─────────────────────────────────────────────────────────┘

통계 화면

기간 선택 드롭다운으로 조회 범위를 설정합니다 (예: 최근 30일).

요약

항목
총 신고 건수 127건
처리 완료 98건 (77%)
평균 처리 시간 4.2시간

조치 분포

조치 건수 비율
기각 45건 46%
경고 38건 39%
콘텐츠 검열 10건 10%
일시 정지 4건 4%
영구 정지 1건 1%

위반 유형 (상위 5개)

순위 유형 건수
1 스팸/광고 32건
2 혐오 발언 24건
3 괴롭힘 18건
4 부적절한 콘텐츠 12건
5 허위 정보 8건

향후 고려사항

자동화 기능 (향후 도입 검토)

  • 자동 숨김: 특정 임계값 이상의 신고가 접수되면 관리자 검토 전 임시 숨김
  • AI 기반 사전 필터링: 명백한 위반 콘텐츠 자동 감지
  • 스팸 자동 처리: 명백한 스팸에 대한 자동 조치

주의

자동화 기능은 오탐의 위험이 있으므로 신중하게 도입해야 합니다.

커뮤니티 참여

  • 신뢰할 수 있는 신고자: 정확한 신고 이력을 가진 사용자의 신고에 높은 가중치
  • 커뮤니티 중재자: 관리자 부담 분산을 위한 커뮤니티 중재자 제도 검토

다국어 지원

  • 신고 사유 자동 번역 (관리자가 다른 언어 사용 시)
  • 행동 강령 다국어 버전과의 연동
  • 조치 통보 메시지 다국어 템플릿

법적 요구사항 대응

  • 법적 요청에 따른 데이터 보존/제공 절차
  • 저작권 침해 신고 (DMCA 등) 별도 처리 절차
  • 사법기관 협조 절차

부록: 용어 대조표

한국어 영어 설명
신고 flag/report 위반 의심 콘텐츠/사용자를 알림
행동 강령 code of conduct 커뮤니티 규칙
관리자 moderator 신고 처리 권한자
검열 censorship 콘텐츠 숨김 처리
정지 suspension 계정 활동 제한
이의 제기 appeal 조치에 대한 재검토 요청
연합 federation 분산 네트워크 간 연결
콘텐츠 post 게시글과 단문을 통칭
게시글 article 장문의 블로그 형식 글
단문 note 짧은 마이크로블로그 형식 글
타임라인 timeline 콘텐츠 피드
팔로 follow 다른 사용자 구독
팔로워 follower 나를 구독하는 사용자
차단 block 특정 사용자 접근 제한
반응 react 콘텐츠에 이모지로 반응
연합우주 fediverse ActivityPub 기반 분산 소셜 네트워크
인스턴스 instance 연합우주의 개별 서버

이 문서는 Hackers' Pub 커뮤니티의 의견을 수렴하여 지속적으로 개선됩니다.

Read more →
7

Hi ! I'm working on Hackers' Pub, a small -powered social platform for developers and tech folks.

We're currently drafting a content (/) system and would really appreciate any feedback from those who have experience with federated moderation—we're still learning.

Some ideas we're exploring:

  • Protecting reporter anonymity while giving reported users enough context to understand and improve
  • Graduated responses (warning → content removal → suspension) rather than jumping to bans
  • Using LLM to help match reports to code of conduct provisions
  • Supporting ActivityPub Flag activity for cross-instance reports

Our guiding principle is that moderation should be about growth, not punishment. Expulsion is the last resort.

Here's the full draft if you're curious: https://github.com/hackers-pub/hackerspub/issues/192.

If you've dealt with moderation in federated contexts, what challenges did you run into? What worked well? We'd love to hear your thoughts.

5

🔁 환영!! 책을 찾고 있습니다. (0103 수정)

어린이~청소년문학 정도의 책입니다.
소년이 주인공이고, 청바지...(혹은 운동화 같은 초등 고학년 정도 남자애들이 가지고 싶어할 법한 의류/패션잡화)인가를 갖고 싶은데 안된다고 해서 벌어지는 일들이 내용이었던 걸로 기억해요.
미국이나 영국 같은 영어권 국가가 배경이었던 것 같습니다. (확실×, may be)
하늘색~파란색 계통 색상의 표지였고, 주인공 소년의 일러스트(실사체에 가까움)가 그려져 있었어요.
대략 15년 이상 전에 읽었던 책입니다.
단서가 부족하지만 혹시 알 것 같은 분은 도움 주심 감사하겠습니다... 몇년 째 찾고 있는데 이 키워드만으로는 찾기가 어렵네요...

0
0
0
0

서울 올라왔을때 여러가지로 충격을 받았는데 그중 하나가 최저임금을 지키는 알바가 더 많고 최저임금 안지키는게 이상한 취급을 받는것이었음 대구는 어디 시골도 아니고 대도시 한복판에서도 알바하면(특히 편의점 알바는 거의 무조건) 한 열에 여덟정도는 최저임금 절대 안 줌 당연히 야간 등 각종 수당도 절대 안 줌

0
0

악하 shared the below article:

2025 Q4 Review

Jaeyeol Lee @kodingwarrior@hackers.pub

이번 분기는 그렇게 기대는 많이 하지는 않았는데, 이것저것 벌려놓은 일들은 있었어서 이거라도 수습은 해야겠다라는 마음가짐은 했던 것 같다. 벌려놓은 일이 많았던 만큼 역시나 업보를 청산하느라 정신이 없는 나날의 연속이었고, 그러면서도 나름 만족스러운 하루를 보내고 있었다. 그러면서도 여러가지 좋은 소식도 생겼다. 기대했던 것들을 상회하는 좋은 기회를 누리고 있어서 요즘은 매일마다 도파민이 넘치고 있는 삶을 살고 있다. 자세한 얘기는...... 후술하도록 하겠다.

Timeline

이번에도 업보청산하느라 정신없는 나날을 보내고 있었고, 그러면서도 중요한 이벤트도 몇 가지 일어났다.

  • 2025-10-06 (일본 IT 회사와의 첫 캐주얼 면담) : 지난 분기 마지막 쯤에 PyCon JP에서 알게된 좋은 인연을 통해서, 일본 소재의 IT 회사에서 원격으로 캐주얼 면담할 기회를 가질 수 있었다. 듀오링고로 겨우 체득한 어설픈 일본어 구사 실력, 읽고 쓰는 쪽으로는 문제가 없지만 듣고 말하는 쪽으로는 부족한 영어 실력이었기 때문에 여러모로 걱정은 되었는데 한국인 직원 분이 중간에 통역을 해주신 덕분에 나에 대해서 어필할 수도 있고, 일본의 IT 회사는 어떤 분위기인지 알아가는 유익한 시간을 보낼 수 있었다.
    • 이 시점까지만 해도..... 일본으로 꼭 가고 싶은 생각이 들었던 것 같다. 한 6개월 정도는 길게 보고 준비해야겠다는 생각을 했을 정도니까.
  • 2025-10-15 (구직 시작) : OSSCA 프로그램도 슬슬 끝나가고 있었던 시점이어서, 이력서도 완성하고 구직을 시동걸기 시작했다. 이력서는 평소에 했던 것처럼 typst로 깎았는데, 2 column 구조로 어떻게든 공백을 채웠던 것 같다. 이 때 당시까지만 해도, Fedify 프로젝트 기여할 때 NestJS 미들웨어를 개발했던 경험을 살려서 NodeJS 백엔드 개발자 혹은 풀스택 개발자 지원해야겠다는 마음가짐을 가지고 있었던 것 같다. 경력은 사실상 망하긴 했지만 외부활동을 나름? 열심히 했던 덕분인지 생각했던 것보다 채워넣을 수 있는 내용들이 많았다. 한 10명 정도 되는 분들한테 이력서 피드백을 요청했었는데, 전부 긍정적인 평가를 받았다. 이력서는 여기서 볼 수 있다.
  • 2025-10-25 (브라우저 스터디 시작) : Fedify 팀에서의 인연 (그리고, 누군가의 팬클럽 디스코드)으로 알게된 사람들과 밑바닥에서부터 만드는 웹 브라우저 라는 책으로 스터디를 시작했다. 다들 프로그래밍에 어느 정도는 자신있는 사람들이었어서, 매 챕터마다 연습문제를 모두 풀어오는 하드코어한 스터디였다. 풀스택 엔지니어로서의 근무를 희망하는 사람으로서 브라우저의 동작 원리를 제대로 이해하지 않으면 안되겠다는 생각이 들었기 때문에, 구직을 성공하기 전까지는 누구보다 진도를 앞서서 진행하고 매주마다 연습문제를 전부 다 풀고 Hackers Pub에도 풀이글을 꾸준히 게시했던 것 같다. 구직을 성공하기 전까지는.....
    • 어떻게든 16챕터까지 전부 풀어서 이걸로 나만의 스토리를 만들고 싶었던 욕심은 있지만, 2025년 12월 31일 기준, 챕터 5까지만 진도를 끝내고 멈춘 상태인 지금 당장의 나로서는 지금 내가 하고 있는 일에 충실해야겠다는 판단이 들어서 당분간은 미루고 있다.
    • 책 자체는 웹 개발을 공부한다기보다는 브라우저를 진짜로 밑바닥에서부터 만들면서 이해하는 교재이다보니 프론트엔드 개발 비슷한걸 기대한 사람들에게는 약간 당혹감을 느낄 수도 있다. 첫장부터 **"소켓프로그래밍"**으로 직접 HTTP 프로토콜로 요청을 쏘고 HTML 응답을 읽어들여서 화면에 GUI 툴킷으로 어떻게든 뿌리는 **"데스크톱 어플리케이션"**을 만드는 것이기 때문이다. 같이 스터디했던 분의 표현을 빌리자면, 사실상 게임엔진을 만드는 것이랑 유사하다.
    • 코드를 직접 따라치는 것 만으로도 벅차다고 느낄 수도 있긴 한데, 연습문제를 푸는 것도 굉장히 해볼만한 도전과제라고 생각하고 있다. "여기 있는 연습문제를 모두 풀 수 있는 사람이라면 어딜 가도 먹히지 않을까?" 라는 생각도 들곤 하는데, 나 말고도 연습문제를 푸는 스터디를 했던 사람이라면 모두 공감할 것이다.
  • 2025-11-01 (OSSCA 성과 발표회) : 길다면 길었고, 짧다면 짧았던 OSSCA 일정이 끝이 났다. Fedify 팀을 대표해서 OSSCA 기간 동안 어떤 기여를 했는지 발표하는 시간을 가졌다. 여기저기 UbuCon Korea/PyCon Korea/NeovimConf.live 등등에서 발표해본 경험은 있었기 때문에, 내가 발표하는게 맞겠다는 생각이 들어서 자진해서 지원했다. 다만..... OSSCA 성과 발표회에서는 대본만 열심히 준비했고, 대본을 안 보고 발표를 할 수도 있다는 가능성을 생각하지 못해서 만족스러운 수준으로 발표하지는 못했다. OSSCA를 중심으로 오픈소스 기여하는 사람들을 어셈블해서 Hackers Pub을 부흥시키겠다는 원대한 계획이 실현되지는 못해서 아쉬운 감은 없지 않다.
  • 2025-11-04 (미국 스타트업에서의 Work trial 시작) : OSSCA 성과발표회가 있고 얼마 지나지 않아서, 어느날 갑자기 미국의 어떤 스타트업 CTO분한테서 커피챗 관련으로 연락이 왔다. 당장 미국으로 갈 계획까지는 없었지만, 어떻게든 진짜 구직을 해야겠다고 생각하고 있던 입장이었어서 가벼운 마음으로 커피챗을 했던 것 같다. 그리고, 그 다음날 CEO도 같이 껴서 역시 가볍게 커피챗을 진행했는데 커피챗이 끝나자마자? 바로 Work Trial을 시작했다. 매일마다 도파민에 찌든 삶을 살게 된 것은 이때부터가 시작이었다...
  • ⭐️ 2025-11-15 (Work trial 수습 통과) : 2주도 안되는 Work Trial이 진행되는 동안, 정말 많은 일들이 있었던 것 같다. 뭔가 좀 부족하다 싶은 것들을 발견할때마다 PR을 올리긴 했었는데, 진행하게 된 지 거의 3~5일 만에 PR을 많이 올렸다면서 샤라웃을 받기도 했었고, 수습 7일차되는 시점에 외부 시스템을 연동하는 등의 큰 기능을 맡게 되기도 했다. 그리고 12일차에 Work trial 수습 통과했고 정식적인 멤버로 같이 할 수 있게 되었다. 당장은 미국으로 건너갈 조건이 되지 않아서 파트타임으로 일하고 있긴 하지만, 지금까지 받아왔던 대우, 지금까지 근무했던 것보다 훨씬 더 좋은 조건으로 일하고 있어서 너무 만족스럽게 살고 있다. 구직을 본격적으로 시작한지 한 달 만에 자리 잡았다는 것 자체도 사실은 안 믿긴다.
    • 회사에 대해서 자랑을 좀 하자면.......
      1. 최고의 복지는 동료라고 했던가? 누구보다 제품개발에 진심이고 배울 점이 많은 사람들과 함께 하고 있다. 소수 정예로 돌아가는 팀이긴 하지만, 소규모 팀에서만 일한 경험만 남는 것에 대한 불안이 오히려 줄어들었다.
      2. 어떻게 보면 당연하지만, 풀재택이 가능한, 근무조건이 굉장히 자유로운 회사이다. 명목상으로는 근무시간을 11:00 ~ 20:00 정도로 두고 주 40시간 기준으로 계약을 하긴 했지만, 프로젝트 일정에 지장이 생기지만 않는다면 자율적으로 일할 수 있는 회사이다. (물론, 나는 자발적으로 50시간 이상은 채워서 일하고 있다.)
        • 근무조건이 굉장히 자유로워서 두 달 혹은 세 달에 한번 정도는 일본에서 길게 워케이션하는 것도 한번 상상해볼 수 있는 처지가 되었다. 실제로, 11월 21일 ~ 24일에는 Fedify 팀과 같이 후쿠오카 여행을 하다가도 중간에 비는 시간에 회사 업무를 보기도 했었다.
      3. 회사 자체의 비즈니스가 마음에 든다. 교육이라는 분야에 꾸준히 관심은 있었고, 관련 도메인에서 일해본 적이 두-세차례 정도 있었다. 내가 좋아하는 도메인에서, 비전이 있는 사업을 하고 있기 때문에 더욱 몰입해서 일하게 되는 것 같다.
      4. 포괄이라는 개념이 없다. 페이는 시급 단위로 계산하기 때문에, 일을 한 만큼 더 받아갈 수 있다. 그래서, 무리하지 않는 선에서 최대한 땡겼더니 전 직장 대비 60%-75% 까지 더 끌어당겨서 받고 있다.
      5. AI 도구를 굉장히 적극적으로 쓰고 있는 회사이다. 교육 분야를 AI로 개척하는 사업을 하고 있기도 하지만, 그 과정에서 AI를 어떻게 활용할 수 있는지 어깨너머로 배워갈 수 있다. 개발생산성을 높이기 위한 AI 도구 도입도 굉장히 열려있는 편이고, 워크플로우 개선에 대해서도 진지하게 고민을 많이 하고 있는 동료들과 함께하고 있다보니 AI 도구를 더욱 잘 쓰게 되는 것 같다. AI 도구 활용에 있어서 시너지 효과를 낼 수 있는 환경에서 일하고 있다.
      6. 사실 기술 스택에 대해서 별로 호불호 의견이 있는 편도 아니기도 하고 내가 밥벌이 할 수 있으면 그걸로 그만이라는 인식이 없지는 않지만, 내가 원하는 기술 스택으로 일하고 있다. 크게 보면 Python(FastAPI) + React 조합으로 일하고 있는데, 최근에 여러가지 기술적인 도전을 하고 있어서, 필수불가결하게 새로운 스택도 점진적으로 도입하고 있다. 궁금하면? 커피챗으로 문의 😘
    • 어떻게 보면, 나는 운이 좋아서 좋은 조건의 회사에서 일할 수 있게 되었긴 하지만.... 2025년 12월 기준으로 국내에 좋은 일자리가 열려있지 않은 현재 기준으로는, 해외로 눈을 돌리는 것도 나쁘지 않은 선택지인 것 같다.
  • ⭐️ 2025-11-30 (VIMRC 2025 진행) : 2025년 7월 6일부터 시작했던 VIMRC 2025 진행을 무사히 끝냈다. 이번 VIMRC 2025 행사에서 라이트닝토크 발표를 지원해주셨던 오정민님/위성훈님/황정현님/이광효님/이승록님/이효승님께 정말 감사함을 느끼고 있다. 스티커 굿즈를 만들어 주신 어떤 프리랜서 분에게도 감사함을 느끼고 있다. 그리고, 네트워킹 세션을 같이 진행해 주셨던 김대현님한테도 신세를 많이 졌다. 재치있는 굿즈 스티커 디자인을 맡아주신 백송민님도, VIMRC 2025까지 같이 달려주신 다른 vim.kr 모더레이터 분들도 감사...
    • VIMRC 2025 행사는 라이트닝토크도 재밌는 컨텐츠가 많았지만, 네트워킹 시간도 굉장히 알찼다. 일단 내가 있었던 테이블 기준으로는 스플릿 키보드를 직접 커스터마이징해서 시연하는 분이 계셨는데, 현장에 있는 분들이 물개박수를 칠 정도. 김대현님이 있었던 테이블은 Neovim 플러그인 개발자 뿐만이 아니라 Neovim 코어에도 기여했던 분들이 계셨어서 그 쪽도 그 쪽 나름대로 재밌는 컨텐츠가 있었을 것으로 생각된다.
    • VIMRC 2025 공식 일정이 끝나고 난 다음에는 뒷풀이를 2차/3차까지 달렸는데, 9시 30분 카페가 문 닫는 시간까지 서로 인생 살아가는 얘기하다가 Vim 관련 얘기로 컨텐츠가 가득한 알찬 하루를 보낼 수 있었다. 내가 이런 모임을 주최할 수 있었다는 것 자체도 믿기지가 않는다.
    • 한편 아쉬운 부분도 많았다. 단체사진 찍어놓을걸...... 라이트닝토크 발표 현장 녹화도 떠놓을걸..... 행사 현장의 사진을 좀 더 많이 찍어놓을 걸......

크게 보자면 뭔가 좀 적은 것 같긴 한데, 좋은 일들이 가득한 나날이었다. 지금 당장은 회사 쪽 일에 전념하고 싶기도 하고, 향후에 근황 공유를 하더라도 좀 심심할 수 있겠다는 생각은 들고 있다. 한 4년 전 쯤, 리걸테크 분야 회사에서 일했던 것과 비슷한 심정을 느끼고 있는데, 지금 회사에 있는 매 순간순간이 성장하고 있다는 느낌이 들고 있고, 긍정적인 의미로 한계에 도전하게 되는 일들이 많다. 회사의 성장이 곧 나의 성장이라는 확신이 들게 하는 환경이고, 회사 일 자체가 정말 재밌기도 해서 스스로가 워커홀릭이 되어가는게 느껴진다.

참...... 인생 살다가도 모르는 일이다. 3년 내내 어디에다가 말하기도 어려운 힘든 나날을 보내기만 했는데, 문득 좋은 기회가 찾아와서 이렇게 행복하게 살아도 되는건가 싶은 생각을 늘상 하고 있다. 뭐, 지금은 즐겨야지 싶다.

지금 상태를 요약하자면....

  1. 지금까지 받아왔던 대우보다 훨씬 상회하는 조건의 좋은 회사에서 근무할 수 있게 되었다.
  2. 그 이후로 삶이 더더욱 윤택하게 되었고, 매일마다 행복하다는 생각을 요즘 들어서 하게 되었다.
  3. 매사를 조금이나마 긍정적으로 생각할 수 있게 되었다.

그리고, 어쩌다보니 좋은 기회가 생겨서 책을 쓰게 되었는데 조만간 소식을 공유할 수 있으면 좋겠다.

다음엔 뭘 해볼까?

말 그대로 오늘내일하는 삶을 살아왔기 때문에, 회고라는 것도 딱히 생각도 없었고, (있는 그대로 말하면 어지간하면 경악할만한) 열악한 환경에서 살아왔기 때문에 더 나은 미래를 가정한다는 것 자체가 성립이 되지 않았는데, "이제는 진짜 바뀔 수 있다" 라는 확신이 들고 있다. 거의 3-4년을 무기력하고 우울한 삶, 악순환의 고리 속에서 살아왔는데 이제는 좀 달라졌다.

해외 컨퍼런스에 좀 더 적극적으로 참여해보자

올해에 PyCon JP에 참여한 이후로, 해외 컨퍼런스에 좀 더 많이 참여해보고 싶은 생각이 들었다. PyCon JP에서도 좋은 인연들을 알아갈 수 있었고, 좋은 기회를 얻을뻔도 했었다. 심지어, FastAPI 메인테이너인 tiangolo님과도 같이 사진을 찍을 수 있었다. 이런 맛으로 해외 컨퍼런스에 참여하는 것일까? 올해에 참여한 해외 컨퍼런스는 PyCon JP 밖에 없었지만, 내년에는 홍콩에도 가보고 필리핀에도 가보고 PyCon JP는 당연히 참여를 하는거고, 특히 일본에서 열리는 VimConf는 이번에는 반드시 참가하고 말 것이라는 확고한 의지가 있다.

내년에는 그래도, 내가 생각하는 것을 자유롭게 표현할 수 있는 수준으로는 능숙해질 필요는 있어야겠어서 전화영어는 알아보고 있다. 지금 일하고 있는 회사가 현지 직원을 채용하고 있기도 해서, 이제는 영어로 회화하는건 피할 수가 없는 현실이 되었다. 그리고.... 돈 모아서 PyCon US 갈 생각도 이미 하고 있다.

좀 더 좋은 영향력을 행사할 수 있도록 하자

Python 생태계에 언젠가는 기여를 해야겠다고 생각만 해왔던 것 같다. 내가 애정을 가져왔고 지금도 애정을 가지는 언어 생태계에서 밥벌이를 시작한 만큼, 이제는 좀 기여할 수 있는 여지도 명분도 충분히 생겼다. 여러 생태계를 관찰하면서 느낀 점이 있는데, 개발 커뮤니티 생태계가 성숙해지려면 여러가지 요소가 필요하다. 그나마 직관적으로 와닿는 예시를 들자면.. (1) 좋은 일자리, (2) 보고 배울 수 있는 멘토, (3) 질적인 네트워킹, (4) 포용적인 분위기, (5) 상호간 영감을 주면서 시너지를 낼 수 있는 환경 정도 되겠다. 그렇지 않은 환경을 수차례 관찰을 해온 적이 있기 때문에 더욱 실감하고 있는 부분이기도 하다.

커뮤니티를 직접 빌드하는건 이미 벌려놓은게 있으니 지금 하는거라도 잘해야겠다 치더라도, 이미 이렇게 자리를 잡게 된 이상 (내가 하고 있는 일을 더욱 잘해서) Python 생태계의 양질의 일자리를 더 확보하는데 기여를 해야겠고, 어딜 내놔도 부끄러운 사람이 되지 않기 위해 더욱 분발해서 Python 생태계의 보고 배울 수 있는 멘토가 되고 싶고, 필요하다면 여기저기 발표도 해보고 싶다. 2026년 목표는 해외 Python 관련 행사에서 영어로 발표해본다? 정도 될 것 같다.

비즈니스적으로 기여할 수 있는 사람이 되도록 하자

개발자로서 기술만 잘한다고 해서 좋은 결과를 만들 수 있는 건 아니다. 주변 지인분들의 표현을 빌리자면, 개발자도 어떻게 보면 회사의 일원이다. 스스로는 회사의 일원으로서, 특히 어느 정도 연차가 있는 사람으로서, 회사의 비즈니스적인 성장에 기여할 의무는 어느 정도 있다고 생각하는 편이다.

현재 회사에서 일하면서 AI 도구를 활용하거나 워크플로우를 개선하는 과정을 통해, 기술이 어떻게 비즈니스 임팩트를 만드는지 배워가고 있다. 앞으로는 "이 기능이 사용자에게 어떤 가치를 줄까" "이 기술 선택이 비용과 시간 면에서 타당할까"라는 질문을 더 자주 던질 수 있는 엔지니어가 되고 싶다. 좋은 제품은 좋은 코드와 좋은 비즈니스 센스의 조화에서 나온다.

내실을 좀 더 다듬도록 하자

서른이 넘은지 시간이 어느 정도는 지난 지금 생각해보면, 스스로를 돌아볼 기회가 없었다. 그냥 말 그대로 미래라는게 없었다고 생각되었기 때문이다. 좋은 동료와 일하는 경험의 부재, 진지하게 제품 개발에 임할 수 있는 기회의 부재, 대외활동은 적극적으로 해오긴 했지만 결과적으로는 본업의 불만족으로 인한 우울감 때문에 일상을 제대로 유지하기도 어려웠다. 인생이 이따위인데 뭔 회고인가? 라는 꼬인 생각도 했었던 것 같다. 이제는 좀 확실하게 달라졌다.

진심박치기 모드일 때는 다르다고 확신은 하고 있었고, 이젠 진심박치기 모드일 수 있는 기회가 왔다. 해볼 수 있는 것들은 다 해보고 싶고, 본업에 충실한 나로서 제대로 인정받고 싶다. 본업으로 같이 일하고 싶은 동료로서, 사람 대 사람으로서 안심할 수 있는 사람으로서. 내가 인정하는 내가 인정받고 싶은 사람들과 함께 하는 시간이 많아지다보니, 사고의 흐름이 자연스럽게 변하게 된 것 같다.

이번엔 진짜 최선을 다해서 살아볼까싶다.

Read more →
14

X가 프리미엄 구독을 1,000원에 낚시한다.
현재 개발 중인 이어잇 서비스 계정을 프리미엄으로 전환해 뭐가 좋은지 봐야지.
12월 1일 프리미엄 전환!
절대 몇 천조 있는 회사에 놀아나지 않고, 제 때 해지할 것이다.
아이폰 달력에 해지 알림 추가.

1월 1일, "띠링~ stripe가 x 구독료 후루룩 했음"

아......... 당했다. 애플 달력이 왜 알림을 안해줬지. 애플과 X가 손잡고 있을 줄이야...

※ 그런데, 구독 후 바로 해지 예약 해 둘 걸. 왜 안해놨지란 생각이 드네요. 직 후에는 UI가 안보였었나...어쨌든, 딱히 필요성을 못 느꼈는데 몇 천조에 9,000원을 보태줬습니다.

3

악하 shared the below article:

`X-Frame-Options` 의 악몽에서 깨어나세요, 프록시 서버 개발기

소피아 @async3619@hackers.pub

X-Frame-Options 의 악몽에서 깨어나세요, 프록시 서버 개발기

X-Frame-Options? 그게 뭔가요?

우리가 아는 몇몇 대형 웹 서비스들(유튜브 등)은 보통의 경우 다른 웹 사이트에서 iframe 요소를 통해 임베딩 되는 것을 거부하지 않습니다. 다만, 몇몇 웹 서비스는 다른 웹 페이지에서 iframe 요소를 통해 표시되길 거부합니다. 제품 정책 및 보안상의 이유로 표시를 거부하는 목적이 있겠습니다.

이러한 니즈를 충족시킬 수 있는 HTTP 헤더가 X-Frame-Options 입니다. 이 헤더의 값을 SAMEORIGIN 내지는 DENY로 설정하면, 직관적인 값에 따라 알맞게 프레임 내 임베딩 가능 여부를 결정할 수 있습니다.

네이버 웹 사이트의 Response Header 목록, X-Frame-Options가 명시되어 있다.

위 이미지에서 볼 수 있듯, 네이버는 X-Frame-Options 헤더를 명시함으로써 그 어떠한 출처에서도 프레임 내에 임베딩 되는 것을 거부한 상황입니다. #

왜 이걸 우회하나요?

image

웹 페이지 내에 다른 웹 페이지가 임베딩 되어 '미리보기' 처럼 제공되는 경험을 보신 적이 있으신가요? Omakase AI는 자사 프로덕트의 데모를 위와 같이 제공하고 있습니다. 캡쳐하여 실시간으로 전송되는 영상의 화면 위에, 자사 컨텐츠를 올려두어 실제 적용 시에 어떤 네러티브를 제공할지 데모 형식으로 보여줍니다.

문제는 이 모든 경험이 영상을 통해 진행 된다는 점 입니다. 영상 전송은 필연적으로 지연 시간이 존재할 수 밖에 없습니다. 여러분이 스크롤을 내리고, 클릭을 하는 등의 작은 인터렉션 하나가, 큰 지연 시간 뒤에 처리가 된다고 하면 유저는 답답하고 매끄럽지 않음을 느낄 것이고 이는 곧 이탈로 이어질 가능성이 있습니다. (구글은 비슷한 맥락에서 Core Web Vitals로써 INP를 설명하고 있습니다)

따라서 저는 영상을 보내는 나이브한 방법 이외의 유저의 브라우저에서 외부 웹 서비스를 표시할 좋은 방법을 찾아야 했고, 그것이 바로 프레임 내지는 iframe을 사용하는 방법 이었습니다. 이런 맥락에서 X-Frame-Options를 우회할 필요가 생긴 것 입니다.

어떻게 했나요?

중간자의 필요성

image

우리는 정상적인 방법으로는 제 3자 출처의 요청을 가로채어 응답 데이터 및 헤더를 조작할 수 없음을 잘 알고 있습니다. 여기서 필요한게 중간자 (Man in the Middle) 입니다. 누군가를 클라이언트 - 원격지 서버 사이에 두어, 서로에게 오가는 요청과 응답을 수정하는 작업을 수행하도록 하는 것 입니다. 그렇게 하면, 둘은 각자 수신한 요청과 응답이 모두 원본인지, 수정한 것인지 알 수 있는 방법은 거의 없을 것 입니다.[1]

image

이 중간자 역할을 하는 프록시 서버를 중간에 두어 요청을 모두 프록시 서버를 거치도록 하는 방법을 이용하는 것 입니다. 간단하게는 X-Frame-Options 응답 헤더의 제거가 있을 것 입니다. 중간자가 X-Frame-Options 헤더를 제거함으로 응답을 수신하는 클라이언트 브라우저의 iframe 요소는 큰 문제 없이 내용을 표시할 수 있게 됩니다.

여기서 끝이 아니다. URL을 조작하기

처음에는 그저 GET Query Parameter로 프록시 서버에게 어떤 원격 URL을 프록시 할 것인지 명시하도록 구현 했습니다. 예를 들면 다음과 같은 형식이 될 수 있겠습니다:

https://example.com/proxy?target=https://www.naver.com/...

보통의 경우에는 별 문제 없이 동작 했습니다만, 재앙은 그다지 먼 곳에 있지 않았습니다. 만약 다음과 같은 코드가 원격지 웹 서비스 코드에 있다고 해봅시다. 아래 코드는 무신사 웹 페이지의 빌드된 소스코드 입니다:

import {E as k0} from "./vendor/react-error-boundary.js";
import {b as o0, d as Wt} from "./vendor/react-router.js";
import {d as F0} from "./vendor/dayjs.js";
import {L as Qt} from "./vendor/lottie.js";
import "./vendor/scheduler.js";
import "./vendor/prop-types.js";
import "./vendor/react-fast-compare.js";
import "./vendor/invariant.js";
import "./vendor/shallowequal.js";
import "./vendor/@remix-run.js";
import "./vendor/tslib.js";
import "./vendor/@emotion.js";
import "./vendor/stylis.js";
import "./vendor/framer-motion.js";
import "./vendor/motion-utils.js";
import "./vendor/motion-dom.js";

무신사는 내부적으로 ESM을 사용해서, import 구문을 통해 필요한 에셋을 불러오는 코드를 사용중에 있습니다. 문제는 여기서 발생합니다. import 의 대상이 되는 소스코드가 상대 경로를 따르게 되어 아래와 같은 결과를 초래하게 됩니다.

https://example.com/proxy?target=https://www.naver.com/...

위와 같은 URL을 표시하고 있는 `iframe` 요소에서,
`import "./vendor/framer-motion.js"` 구문을 만난다면..

https://example.com/proxy/vendor/framer-motion.js 를 요청하게 됨.

이를 해결하기 위해, 프록시 된 대상 URL에 대한 개념의 도입이 필요 했습니다. 상대 경로 진입에도 안정적으로 작동할 수 있는 새로운 방식의 접근이 필요 했습니다. 저는

  1. 상대 경로 접근에도 안전하며,
  2. 원본 URL의 구조를 그대로 남길 수 있는 구조

를 생각해 냈어야 했고, 그 결과는 이렇습니다. https://section.blog.naver.com/BlogHome.naver?directoryNo=0&currentPage=1&groupId=0 를 예시로 들면, 프록시화 (Proxified) 된 URL은 다음과 같은 것 입니다.

https://example.com/proxy/section/blog/naver/com/_/BlogHome.naver?...

URL hostname. 구분자를 /로 치환하고, 이후의 모든 pathname, search 등은 모두 _ 구분자 뒤로 넘김으로서 URL의 원형을 유지할 수 있게 됩니다. 추가적으로 상대 경로 접근에도 안전한 URL을 만들 수 있습니다.

최종 보스가 남아있다. HTML API 후킹하기

우리는 상대 경로 문제를 해결하기 위해 URL을 프록시화 하는 방법을 사용했고, 이는 제대로 동작하는 듯 해보였습니다. 악몽은 React, Vue 등의 SPA 웹 앱을 프록시하여 표시하는 데에서 시작 되었습니다.

React, Vue 와 같은 프레임워크들은 History API 및 window.location 객체를 기반으로 한 Routing 기능을 제공하고 있습니다.[2] 이 말은, 결국엔 어떤 프레임워크가 되었든 저수준 빌트인 자바스크립트 API를 사용할 수 밖에 없다는 것을 의미 합니다. 그렇다면 직관적으로 생각 해봤을 때,

window (및 globalThis) 객체의 location 속성의 값을 변경해주면 되지 않겠나?

라고 생각할 수 있습니다. 그러나 이는 불가능 합니다.

image

어떠한 이유 때문인지는 알 길이 없었지만, 자바스크립트는 그렇게 만만한 존재가 아니었습니다. 다른 좋은 방법을 찾아야 할 필요가 있었고, 결론에 도달하는 데에는 오랜 시간이 걸리지 않았습니다. 그것은 바로 원격지 웹 페이지에서 실행되는 모든 스크립트의 window.location 객체 접근을 감시하면 어떨지에 대한 아이디어 였습니다.

번들된 소스코드의 경우 대체적으로 다음과 같은 형식을 가지게 됩니다:

const l = window.location;
/* ... */ l.pathname /* ... */

여기서 우리는 변수 lwindow.location의 별칭인지 소스코드만 분석해서는 알기 매우 어렵습니다. 따라서, babel을 사용해서 소스코드를 AST로 분석하고, 모든 프로퍼티 접근을 특정 함수 호출로 변환하면, '특정 함수'에서 모든 것을 처리할 수 있으니 좋을 것 같다는 생각이 있었고, 실행에 옮겼습니다:

const l = window.location;
l.pathname;

// 위 코드는 아래와 같이 변환됨

const l = __internal_get__(window, 'location');
__internal_get__(l, 'pathname');

__internal_get__ 함수 내부에서 첫번째 인자가 window.location 과 동일한 인스턴스를 가지고 있는지 비교하거나, 두번째 인자인 프로퍼티 키를 비교해서 href 등의 값이라면, 원하는 값을 반환하도록 후킹 함수를 만들 수 있겠습니다.

function __internal_get__(owner, propertyKey) {
  if (owner === window.location) {
    return {
      get href() { /* proxified 된 url을 기반으로 Router를 속이는 URL을 반환하는 로직 */ }
    }
  }

  // ...
}

마치며

글에 열거한 내용 이외에도 정말 많은 기술이 사용 되었는데, 아주 재밌는 경험 이었습니다. 혹여나 이러한 비슷한 기능을 하는 기능을 개발할 일이 있으시다면, 도움이 됐으면 좋겠습니다.


  1. 여기서 거의 라는 표현을 사용한 이유는, 제 짧은 식견에서 보자면 비슷한 맥락에서 사용하는 기법으로 integrity 속성이 있을 수 있겠습니다. ↩︎

  2. 예를 들면, location.pathname을 읽어 현재 Route가 어떤 Route인지 감지하는 등의 동작이 있겠음. ↩︎

Read more →
4

사실 저거 작가가 일러레 출신이라는 점은 차치하고, 저 친구가 타과(법대였던 걸로 기억) 대학 다니다가 디버거 알바로 시작해서 독학입문한지 얼마 안 된 상태로 기억합니다.

2

2026년 병오년 새해를 맞아 식탁보 1.16.0 버전을 출시했습니다. 이번 버전에서는 폴더 마운트 기능, 그리고 백그라운드 비동기 다운로드를 구현하여 이전보다 최대 30~40% 이상 빨라진 환경 구축 속도를 달성했습니다.

코딩 AI 어시스턴트의 도움을 받아 계속해서 빠른 출시와 적극적인 기능 반영을 이어 나가도록 하겠습니다. 많은 공유와 후원을 계속 부탁드리겠습니다!

https://github.com/yourtablecloth/TableCloth/releases/tag/v1.16.0

5
2
1