Czytałem ogłoszenie o pracę. Sensowna rola, przyzwoity język, nic nie rzucało się w oczy. Potem zauważyłem nazwę firmy finansującej projekt i wyszukałem ją. Okazało się, że jest powiązana z Danielem Ekiem, CEO Spotify — człowiekiem, którego związki z przemysłem obronnym są dobrze udokumentowane i którego zaangażowanie w biznesy, które uważam za głęboko nieetyczne, znałem już wcześniej.
Zamknąłem to ogłoszenie, ale ten moment we mnie pozostał — czytałem to ogłoszenie przez kilka minut z rosnącym zainteresowaniem, i wtedy, niemal przypadkowo, złapałem jedno nazwisko i zrobiłem jedno wyszukiwanie, które zmieniło wszystko.
Pomyślałem: gdyby istniało coś, co robiłoby to systemowo — narzędzie, które wyłapałoby to, co o mało nie umknęło, zanim zdążę się zaangażować. Nic takiego nie znalazłem. Żadnego systemu. Wtedy miałem szczęście rozpoznać nazwisko, które akurat znałem.
Ogłoszenia o pracę to dokumenty marketingowe, pisane po to, żeby przyciągać kandydatów — rzadko kiedy po to, żeby rzetelnie opisać rolę, firmę czy warunki zatrudnienia. Efekt jest taki, że kandydat spędza 20 minut na czytaniu, przeszukiwaniu i podejmowaniu decyzji. A przez większość tego czasu przetwarza korporacyjny język zaprojektowany po to, żeby zaciemniać, a nie ujawniać.
Standardowe narzędzia optymalizują pod wolumen. Więcej aplikacji, szybciej. Założenie wbudowane w każdy portal z ofertami, każdy ATS, każdy workflow rekrutera brzmi: filtrowanie leży po stronie pracodawcy. Czas kandydata jest drugorzędny, jeśli w ogóle się liczy.
Portale z ofertami zarabiają na ogłoszeniach, kliknięciach, liczbie aplikacji. Rekruterzy zarabiają na zatrudnieniach. Nikt w tym systemie nie ma finansowego interesu w tym, żeby kandydat aplikował do mniejszej liczby ofert. Struktura zachęt jest produktem.
Job Screener powstał z założenia, że ta struktura zachęt jest problemem i że narzędzie zaprojektowane do szybszego odrzucania, a nie szybszego aplikowania, jest strukturalnie niekompatybilne z rynkiem rekrutacyjnym takim, jakim jest.
To jest główna teza, która mi przyświecała.
Sześć warstw analizy — Triage, Product, Business, Reputation, Values, Fit — tworzy ustrukturyzowany proces wyłapywania sygnałów ostrzegawczych zanim użytkownik zainwestuje czas. Narzędzie domyślnie nie jest optymistyczne. Zero List jest najczystszym wyrazem tej logiki: zestaw kryteriów definiowanych przez użytkownika, które uruchamiają automatyczne odrzucenie zanim analiza w ogóle się zacznie. Bez połowicznych ocen, bez zawahania w rodzaju „ale rola brzmi ciekawie". Jeśli ogłoszenie trafia na listę — odpada.
To jest celowo anty-rynkowa decyzja projektowa. W momencie, w którym ułatwiasz automatyczne odrzucanie — i to szybkie — działasz przeciwko fundamentalnemu założeniu całej branży rekrutacyjnej, które mówi, że ekspozycja na jakiekolwiek ogłoszenie jest dla kogoś coś warta.
Pierwsze warstwy wyrosły z prostego pytania: co naprawdę muszę wiedzieć, zanim zdecyduję, czy aplikować? Zero List wyrosło z innego pytania. Po tym, co stało się z Danielem Ekiem, chciałem narzędzia, które wyłapie nie tylko niedopasowanie roli czy złe sygnały wynagrodzeniowe, ale etyczne niedopasowanie — firmy powiązane z branżami, w których nie chcę pracować, struktury własnościowe, które uważam za szkodliwe, źródła finansowania sprzeczne z rodzajem pracy, którą chcę robić. Rynek nie ma warstwy na to, więc zbudowałem ją sam.
Od pomysłu do działającego prototypu: jeden, dwa dni. Od prototypu do czegoś, z czego zacząłem korzystać codziennie: trzy, cztery tygodnie iteracji. Od pomysłu do obecnego stanu w wersji v0.21: nieco ponad miesiąc.
Jestem projektantem produktu i strategiem, z backgroundem w UX i UI, trochę doświadczenia inżynierskiego, nie jestem zaś programistą z wykształcenia.
Założenie na starcie było takie, jakie ma teraz każdy: AI sprawia, że budowanie jest proste. Jeden dobry prompt, działający produkt.
To, co znalazłem, było bardzo inne. Złożoność nie znika, tylko jest przesuwana w inne obszary projektu.
Pierwszą rzeczą, która obaliła założenie o jednym prompcie, był sam system prompt.
Sześciowarstwowa metodologia analizy, reguła dowodowa, rozróżnienie między odrzuceniem przez AI a odrzuceniem potwierdzonym przez użytkownika — nic z tego nie było w pierwszej wersji. Każda iteracja ujawniała nowy przypadek brzegowy. Prompt jest tutaj produktem, ma wersje, ma regresję, ma momenty, w których naprawienie jednego problemu psuje trzy inne.
Bezpieczeństwo również nie mogło czekać. Dwie pełne rundy wzmacniania zabezpieczeń na tyle, na ile pozwala mi moja wiedza i dociskanie Claude Code: ochrona CSRF, rate limiting, blokada konta, blokowanie SSRF, porównania w stałym czasie, hartowanie sesji. Narzędzie przechowujące dane CV i historię ofert prawdziwych użytkowników nie może traktować bezpieczeństwa jako dodatku. Wiedziałem to w teorii, a potrzebowałem nauczyć się tego w praktyce.
Infrastruktura ma też swoje znaczenie. Przetwarzanie zadań w tle pojawiło się w v0.11, bo wcześniej wysłanie ogłoszenia oznaczało wpatrywanie się przez minutę w ekran ładowania. Po v0.11 wysyłam zapytanie i mogę działać dalej. Ta jedna zmiana zmieniła rytm korzystania bardziej niż jakakolwiek funkcja, którą dodałem.
Schemat bazy danych koduje decyzje produktowe.
verdict_confirmed rozróżnia odrzucenia AI
od odrzuceń potwierdzonych przez użytkownika.
zero_list_hit jest przechowywane oddzielnie
od verdict, natomiast
source_hash obsługuje deduplikację. Każde z
tych pól zostało dodane w odpowiedzi na konkretny
problem, który pojawił się w realnym użyciu.
v0.1 do v0.2: lokalne narzędzie stało się dostępne dla wielu użytkowników z tokenami zaproszenia. To był moment, w którym stało się produktem, a nie skryptem.
v0.5 wprowadziło regułę dowodową. Model musi teraz cytować ogłoszenie dla każdej flagi, którą chce postawić. Brak bezpośredniego dowodu oznacza degradację flagi do ostrzeżenia. To sprawiło, że analiza stała się podważalna — możesz przeczytać flagę, przeczytać cytat, na którym jest oparta, i się nie zgodzić. To właściwa relacja między człowiekiem a AI podejmującym konsekwentne rekomendacje.
Nic nie jest zostawione automatowi, decyzję zawsze podejmuje na końcu człowiek.
101 ogłoszeń przeanalizowanych między 1 kwietnia a 17 maja 2026.
| Werdykt | Liczba | % |
|---|---|---|
| Odrzucone | 57 | 56% |
| Warte rozważenia | 23 | 23% |
| Wymaga przeglądu | 10 | 10% |
| Zero List (automatycznie odrzucone) | 14 | 14% |
Ponad połowa wszystkich ogłoszeń została odrzucona. 14 nigdy nie dotarło do etapu analizy.
| Etap | Liczba |
|---|---|
| Przeanalizowane | 101 |
| Warte rozważenia | 23 |
| Wysłane aplikacje | 23 |
| Odrzucone przez firmę | 6 |
Liczba, która ma znaczenie, to dystans między 101 a 23. To 78 ogłoszeń, na które nie zostały wysłane zgłoszenia — większość z nich w ciągu pierwszych kilku minut przeglądania wyników analizy.
| Warstwa | Flagi | Ostrzeżenia |
|---|---|---|
| Triage | 27 | 36 |
| Fit | 34 | 22 |
| Reputation | 12 | 39 |
| Business | 14 | 18 |
| Values | 11 | 29 |
| Product | 10 | 17 |
Fit i Triage generują najwięcej twardych flag — tych, które dyskwalifikują. Reputation generuje najwięcej ostrzeżeń — sygnałów, które nie dyskwalifikują, ale przez LLM zostały uznane za warte obserwacji.
Jedno ogłoszenie pochodziło od firmy, która dobrze się prezentowała. Spójny opis roli, przemyślany język, obszar produktowy, który naprawdę mnie interesuje. Przed uruchomieniem analizy byłem już ku niemu pozytywnie nastawiony i chętny do wysłania zgłoszenia.
Analiza oznaczyła strukturalne niedopasowanie w warstwie Fit: rola wymagała dostarczania kodu produkcyjnego w wielu stackach, doświadczenia inżynierskiego w co najmniej dwóch językach, umiejętności wejścia w obcy kod i produktywności w ciągu tygodnia. Komentarz z analizy był bardzo konkretny: „Ta rola wymaga przede wszystkim pisania kodu produkcyjnego — w CV kandydata nie ma żadnych sygnałów świadczących o tej umiejętności." Żadna ilość dobrej pracy discovery nie zmienia niedopasowania na tym poziomie.
To, co dało mi narzędzie, to jasność co do tej luki — zanim spędziłem popołudnie na pisaniu listu motywacyjnego.
Narzędzie zostało zbudowane, żeby przetestować konkretne założenie: uruchomienie ustrukturyzowanej analizy ogłoszenia po przeczytaniu go wyciągnie rzeczy, które przeoczyłem.
Pierwszy prawdziwy moment był celowy: znalazłem ogłoszenie, o którym wiedziałem, że jest dla mnie złe i dodałem je do analizy mimo to. Chciałem zobaczyć, jak model wyartykułuje to, co już wiedziałem.
Przy kolejnym ogłoszeniu podjąłem świadomą decyzję: uruchamiam najpierw analizę, zanim porządnie je sam przeczytam.
Ogłoszenia, ku którym czułem przyciąganie, zaczęły wracać z ostrzeżeniami, które przeoczyłem w pierwszym pobieżnym przejrzeniu. Rzeczy, które narzędzie wyciągało w pierwszej analizie, a które sam zauważyłbym pewnie dopiero po zainwestowaniu czasu w research całej firmy.
Po kilku takich momentach nawyk się utrwalił. Samo ogłoszenie stało się niemal drugorzędne wobec wyniku analizy. Pytanie zmieniło się z czy to brzmi dobrze? na co mówi analiza i czy się z nią zgadzam? Kognitywny ciężar pierwszego przesiewu przesunął się ze mnie na system. Stałem się recenzentem, nie pierwszym czytelnikiem.
Reguła dowodowa to najważniejsza decyzja projektowa. Każda flaga wymaga bezpośredniego cytatu z ogłoszenia. Brak dowodu oznacza degradację flagi do ostrzeżenia. Jeśli model nie może wskazać czegoś, co ogłoszenie faktycznie mówi, flaga zostaje usunięta.
Warstwa Reputation jest celowo asymetryczna. Korzysta z wiedzy spoza tekstu ogłoszenia — oceny na Glassdoor, znane incydenty, wzorce zachowań na poziomie C-suite, historia regulacyjna. Dowód oznacza tu konkretne fakty: liczby, nazwiska, daty. Ogłoszenie nie ujawni negatywnych sygnałów reputacyjnych o firmie.
Dwa stany odrzucenia istnieją w bazie
danych: AI rejected i
user rejected. Narzędzie rozróżnia między
„model uważa, że to powinno być odrzucone" a
„użytkownik potwierdził to odrzucenie". AI
rekomenduje, ale to JA potwierdzam.
Reality Check to sekcja neutralna wobec werdyktu, która dekoduje język ogłoszenia. Istnieje, bo korporacyjny język koduje założenia wpływające na to, czym rola naprawdę jest — warto je wyciągać osobno od pytania, czy w ogóle aplikować.
Od lat myślę, piszę i mówię o etycznym projektowaniu produktów — co to znaczy budować rzeczy, które służą ludziom, zamiast ich eksploatować, pytać dlaczego przed jak, pracować nad problemami, które rynek ignoruje, bo ich rozwiązanie zaszkodziłoby dominującym graczom.
Job Screener nie ma naturalnego sponsora. Żaden portal z ofertami, żaden rekruter, żadna platforma HR nie skorzysta na tym, że kandydaci będą aplikowali do mniejszej liczby ofert. Produkt jest strukturalnie niesprzedawalny komukolwiek, kto ma finansowy interes w rynku rekrutacyjnym.
Rynek pracy w 2026 roku jest naprawdę trudny i ta trudność sprawia, że o wiele bardziej kuszące jest rzucanie szerokiej sieci, optymalizowanie pod wolumen kosztem rozeznania. Narzędzie działa w kontrze do tej pokusy — nie mówi, co i jak mam ocenić, ale pomaga mi stosować własne wartości systematycznie, zanim zacznę czytać, szukać informacji i pisać.
To samo pytanie, które zadaję przy każdym produkcie, nad którym pracuję — ale po co to właściwie jest i komu faktycznie służy — jest pytaniem, któremu to narzędzie pomaga odpowiadać, ogłoszenie po ogłoszeniu.
Niesprzedawalny i nierentowny to dwie różne rzeczy. Ciągle sobie o tym przypominam.
System prompt wymagał tyle samo iteracji co wszystko inne w produkcie. Szedłem w to z myślą, że to będzie łatwa część. Okazało się, że każdy przypadek brzegowy w realnym użyciu był problemem promptu. Reguła dowodowa wyrosła z problemu promptu. Dwa stany odrzucenia wyrosły z problemu promptu. Asymetryczna warstwa Reputation wyrosła z problemu promptu. Prompt nie jest częścią konfiguracji, tylko jest Produktem.
Bezpieczeństwo jest decyzją produktową. To, co przechowuję, kto ma dostęp, co się stanie jeśli wycieknie — to należy do specyfikacji, a nie do rozmowy dwa miesiące po tym, jak narzędzie jest już w użyciu.
Budowanie czegoś prostego jest najtrudniejszym problemem. Prostota, którą chciałem osiągnąć — jedno wejście, ustrukturyzowane wyjście, jasny werdykt — wymagała więcej iteracji niż jakakolwiek złożona funkcja. Za każdym razem, gdy myślałem, że ją znalazłem, coś wciągało złożoność z powrotem.
Budowanie czegoś, z czego korzystam codziennie, daje mi feedback, którego żadna sesja badawcza nie może zastąpić. Nie planowałem połowy funkcji, które dodałem. Odkryłem, że ich potrzebuję, używając narzędzia i to dystans między tym, czego się spodziewałem, a tym, co znalazłem, był miejscem, gdzie działo się większość prawdziwego myślenia produktowego.
Metodologię można generalizować. Sześciowarstwowa struktura ma zastosowanie do więcej niż ogłoszeń o pracę — klientów, współpracowników, projektów, decyzji inwestycyjnych. Pomaga wyciągać informacje, które mają znaczenie, zanim zainwestuję czas i wymaga dowodu dla każdej decyzji.
Czy istnieje społeczność, dla której anty-rynkowa logika tego narzędzia jest konkretnym powodem, żeby z niego korzystać? To pytanie, z którym wciąż siedzę. Instynkt mówi mi, że tak, dowodów jednak mam mało i są anegdotyczne.
Pytanie, które przewija się przez wszystko, jest takim samym pytaniem jak na początku — gdy zamknąłem tamto pierwsze ogłoszenie i poczułem, jak blisko byłem, żeby je przeoczyć.
Ale po co to właściwie jest?
Backend: Python / Flask AI: Anthropic Claude API z extended thinking Baza danych: SQLite Deployment: Hetzner VPS + Caddy + systemd Frontend: Jinja2 + vanilla JS, zero frameworków Autoryzacja: system dla wielu użytkowników z tokenami zaproszenia, SHA-256, CSRF, rate limiting, blokada konta Zbudowane z: Zed, uv, Claude Code
Budżet złożoności został wydany na metodologię analizy i bezpieczeństwo, a nie na frontend stack.
I was reading a job listing. Reasonable role, good language, nothing obviously wrong. Then I noticed the name of the company financing the project and searched for it. Turned out it's connected to Daniel Ek, Spotify's CEO, whose ties to the defense industry are well documented and whose involvement in companies I find deeply unethical was something I already knew about.
I closed the tab. But that moment sat with me — I'd been reading for a couple of minutes with a growing sense of interest, and then, almost by accident, caught a name and did a single search that changed everything.
I thought: if there was something that would do this systematically — a tool that would catch what I'd almost missed before I'd invested the time to care. I found nothing. There was no system for that. Just luck, and a name I happened to recognize.
Job listings are marketing documents. They are written to attract candidates, very rarely to accurately describe a role, a company, or the conditions of employment. The result is a candidate spending 20 minutes reading, researching, and deciding — most of that time processing corporate language engineered to obscure rather than reveal.
The standard tooling optimizes for volume. More applications, faster. The assumption baked into every job board, every ATS, every recruiter workflow is that filtering happens on the employer's side. The candidate's time is not accounted for.
Job boards earn from listings, from clicks, from application volume. Recruiters earn from placements. No one in this system has a financial incentive to help a candidate apply to fewer jobs. The incentive structure is the product.
Job Screener was built on the premise that this incentive structure is the problem — and that a tool designed to reject faster, rather than apply faster, is structurally incompatible with the recruitment market as it exists.
This the thesis I had in my head.
The six analysis layers — Triage, Product, Business, Reputation, Values, Fit — form a structured process for surfacing red flags before you invest time. The tool is not optimistic by default. The Zero List is the clearest expression of this logic: a user-defined set of criteria that triggers automatic rejection before analysis even begins. No partial credit, no „but the role sounds interesting". If it hits the list, it's gone.
This is a deliberately anti-market design decision. The moment you make it easy to reject automatically — and fast — you're working against the core assumption of the entire recruitment industry, which is that exposure to any listing is worth something to someone.
The initial layers came from a straightforward question: what do I actually need to know before deciding to apply? The Zero List came from a different question. After the Daniel Ek moment, I wanted a system that would catch not just poor role fit or bad compensation signals, but ethical misalignment — companies connected to industries I won't work for, ownership structures I find corrosive, funding sources that contradict the kind of work I want to do. The market doesn't have a layer for that, so I built one.
Idea to working prototype: one to two days. Prototype to something used daily: three to four weeks. Idea to current state at v0.21: slightly over one month.
I'm a product designer and strategist — UX and UI background, some engineering experience, not a software engineer by training.
The assumption going in was the one everyone has right now: AI makes building simple. One good prompt, working product.
What I found was very different. The complexity doesn't disappear, it simply shifts to other parts of the project.
The first thing that collapsed the one-prompt assumption was the system prompt itself.
The six-layer analysis methodology, the evidence rule, the distinction between AI-rejected and user-confirmed rejection: none of this worked on the first version. Each iteration revealed a new edge case. The prompt is a product — it has versions, it has regression, it has moments where fixing one problem breaks three others.
Security wasn't deferrable. Two full rounds of hardening backed by my limited knowledge of this aspect and pushing Claude Code: CSRF protection, rate limiting, account lockout, SSRF blocking, constant-time comparisons, session hardening. A tool storing CV data and job history for real users cannot treat security as an afterthought. I knew this in principle. I learned it differently in practice.
Infrastructure has opinions. Background job processing arrived in v0.11 because before it, submitting a listing meant staring at a loading screen for 30 to 60 seconds. After v0.11, you submit and navigate away. That single change altered the rhythm of use more than any feature I added.
The database schema encodes product decisions.
verdict_confirmed distinguishes AI
rejections from user-confirmed rejections.
zero_list_hit is stored separately from
verdict. source_hash handles
deduplication. Every one of these fields was added in
response to a specific problem that appeared in real
use.
v0.1 to v0.2: local tool became multi-user with invite tokens. The moment it became a product, not a script.
v0.5 introduced the evidence rule. The model is now required to cite the listing for every flag it raises. No direct evidence means the flag is downgraded to a warning. This made the analysis arguable — you can read the flag, read the quote it's based on, and disagree. That's the right relationship between a person and an AI making consequential recommendations.
101 job listings analyzed between April 1 and May 17, 2026.
| Verdict | Count | % |
|---|---|---|
| Rejected | 57 | 56% |
| Worth considering | 23 | 23% |
| Needs review | 10 | 10% |
| Zero List (auto-rejected) | 14 | 14% |
More than half of all listings were rejected. 14 never made it past the Zero List.
| Stage | Count |
|---|---|
| Analysed | 101 |
| Worth considering | 23 |
| Applied | 23 |
| Rejected by company | 6 |
The number that matters is the gap between 101 and 23. That's 78 listings that didn't get an application — most of them within the first few minutes of analysis.
| Layer | Flags | Warnings |
|---|---|---|
| Triage | 27 | 36 |
| Fit | 34 | 22 |
| Reputation | 12 | 39 |
| Business | 14 | 18 |
| Values | 11 | 29 |
| Product | 10 | 17 |
Fit and Triage generate the most hard flags. Reputation generates the most warnings — signals that aren't disqualifying on their own, but were deemed worth watching by the LLM.
One listing came from a company that presented well. Coherent role description, thoughtful language, product area I find genuinely interesting. I was inclined toward it before the analysis ran.
The analysis flagged a structural mismatch at the Fit layer: the role required shipping production code across multiple stacks, engineering experience in at least two languages, the ability to drop into legacy codebases and be productive within a week. The output was specific: "This role requires writing production code first and foremost — there's no indication of that skill in candidate's CV." No amount of strong discovery work changes a mismatch at that level.
What the tool gave me was clarity about the gap, before I spent an afternoon writing a cover letter.
The tool was built to test a specific assumption — that running a listing through structured analysis after reading it would surface things I'd missed.
The first real moment was deliberate: I found a listing I knew was wrong for me and ran it through anyway, out of curiosity. I wanted to see how the model would articulate what I already knew.
The very next listing, I made a conscious decision: run this first, before reading it properly.
The listings I'd felt pulled toward started coming back with flags I'd missed in the initial scan. Things the tool surfaced in the first pass that I'd have caught eventually — after investing time in researching the company.
After a handful of those moments, the habit settled. The listing became almost secondary to the analysis output. The question changed from does this sound good? to what does the analysis say, and do I agree with it? The cognitive load of initial screening moved from me to the system. I became the reviewer, not the first reader.
The evidence rule is the most consequential design decision. Every flag requires a direct quote from the listing. No evidence means the flag is downgraded to a warning. If the model can't point to something the listing actually says, the flag doesn't stand.
The Reputation layer is deliberately asymmetric. It uses knowledge outside the listing text — Glassdoor ratings, known incidents, C-level patterns, regulatory history. Evidence here means specific facts: numbers, names, dates. A listing can't be expected to reveal its own negative reputation signals.
Two rejection states exist:
AI rejected and User rejected.
The tool distinguishes between „the model thinks this should be rejected" and „you have confirmed this rejection". The
AI recommends, but only I can confirm.
The Reality Check is a verdict-neutral section that decodes the listing's language. It exists because corporate language encodes assumptions that affect what a role actually is — worth surfacing separately from the question of whether you should apply.
I've spent years thinking, writing, and talking about ethical product design — what it means to build things that serve people rather than extract from them, to ask why before how, to work on problems the market ignores because solving them would harm dominant players.
Job Screener has no natural sponsor. No job board, recruiter, or HR platform benefits from candidates applying to fewer jobs. The product is structurally unmarketable to anyone with a financial stake in the recruitment market.
The job market in 2026 is genuinely difficult, and that difficulty makes it tempting to cast a wide net, to optimise for volume at the cost of discernment. The tool runs against that temptation — not by telling you what to value, but by helping you apply your own values systematically, before the reading and the researching and the writing begins.
The same question I ask of every product I work on — but what is this actually for, and who does it actually serve — is the question this tool is built to help answer, listing by listing.
Unmarketable and unprofitable are different things. I keep needing to remind myself of that.
The system prompt required as much iteration as anything else in the product. I went in thinking it was the easy part. What I found was that every edge case in real use was a prompt problem. The evidence rule came from a prompt problem. The two rejection states came from a prompt problem. The asymmetric Reputation layer came from a prompt problem. The prompt is not configuration — it is The Product.
Security is a product decision. What data you're storing, who has access, what happens if it leaks — that belongs in the spec, not two months after the tool is in use.
Building something simple is the hardest problem. The simplicity I wanted — one input, structured output, clear verdict — took more iteration than any complex feature. Every time I thought I'd found it, something pulled the complexity back.
Building something you use every day gives you feedback no research session can replicate. I didn't plan half the features that ended up here. I discovered I needed them by using the tool, and the gap between what I expected and what I found was where most of the real product thinking happened.
The methodology generalizes. The six-layer structure applies to more than job listings — clients, collaborators, projects, investment decisions. Surface the information that matters before you invest time, and require evidence for every flag.
Whether there's a community for whom this tool's anti-market logic is the specific reason to use it is a question I'm still sitting with. My instinct says yes. My evidence is thin.
The question that runs through all of it is the same one it was at the beginning, when I closed that listing and felt how close I'd come to missing it.
But what is this actually for?
Backend: Python / Flask AI: Anthropic Claude API with extended thinking Database: SQLite Deployment: Hetzner VPS + Caddy + systemd Frontend: Jinja2 + vanilla JS, zero frameworks Auth: invite-token multi-user, SHA-256, CSRF, rate limiting, account lockout Built with: uv, Claude Code
The complexity budget was spent on the analysis methodology and security, not the frontend stack.