<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Damien's Developer Diary]]></title><description><![CDATA[Damien's Developer Diary]]></description><link>https://blog.alleyne.dev</link><generator>RSS for Node</generator><lastBuildDate>Wed, 15 Apr 2026 07:45:24 GMT</lastBuildDate><atom:link href="https://blog.alleyne.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[The Job Isn't Writing Code. It's Knowing When the AI Is Wrong.]]></title><description><![CDATA[I use an AI coding agent for almost everything on my job board GlobalRemote. It writes my scrapers, builds my CI pipelines, architects my database schemas. It's written the vast majority of the codeba]]></description><link>https://blog.alleyne.dev/the-job-isn-t-writing-code-it-s-knowing-when-the-ai-is-wrong</link><guid isPermaLink="true">https://blog.alleyne.dev/the-job-isn-t-writing-code-it-s-knowing-when-the-ai-is-wrong</guid><category><![CDATA[AI]]></category><category><![CDATA[llm]]></category><category><![CDATA[GitHub Actions]]></category><dc:creator><![CDATA[Damien Alleyne]]></dc:creator><pubDate>Thu, 19 Feb 2026 13:06:31 GMT</pubDate><content:encoded><![CDATA[<p>I use an AI coding agent for almost everything on my job board <a href="https://jobs.alleyne.dev/">GlobalRemote</a>. It writes my scrapers, builds my CI pipelines, architects my database schemas. It's written the vast majority of the codebase.</p>
<p>After a few months of building this way, I've noticed a pattern: the most valuable thing I do isn't writing code. It's catching where the AI gets it wrong — specifically the cases where the output looks correct but doesn't hold up once you think about it.</p>
<p>Here are three recent examples.</p>
<hr />
<h2>1. The Wrong Tool for the Job</h2>
<p>My pipeline extracts tech stack requirements from job postings using regex. A role showed up on the board with no tech stack listed. The AI investigated, found the regex wasn't matching that posting's format, and proposed expanding the regex pattern.</p>
<p>Fair enough. But we already had LLMs classifying and extracting other fields from these same job descriptions. Why maintain a brittle regex when we could use the LLM we're already paying for?</p>
<p>The agent agreed and built the LLM-based extraction instead. More resilient, handles edge cases the regex never would have caught.</p>
<p>The AI optimized within the current approach. I questioned whether the approach itself was right. That's a pattern I keep seeing — AI agents are excellent at solving the problem you give them, but they don't question whether you're solving the right problem. That's still on you.</p>
<hr />
<h2>2. Technically Correct, Actually Misleading</h2>
<p>My pipeline extracted geographic data from a GitLab job posting — a role open in the US, Canada, France, Germany, Ireland, Netherlands, Spain, and the UK — and tagged it as <code>multi-region</code> with regions <code>Americas</code> and <code>Europe</code>. I asked the agent to verify. It confirmed the data was accurate — the posting listed countries across both regions.</p>
<p>The problem: if a user from Brazil sees "Americas", they'll assume they can apply. Someone in Hungary sees "Europe", same thing. But this job is only open in 8 specific countries.</p>
<p>The agent hadn't considered this. It checked my existing data, found I already had a <code>select-countries</code> badge for this situation, updated the job, and then updated the LLM extraction prompt so the system would get this distinction right on future runs.</p>
<p>I caught this because I've been the person in a non-obvious country getting excluded from roles that say "Americas" or "Global Remote." I've had Zapier, Outliant, and others reject me on location after their postings implied I was eligible.</p>
<hr />
<h2>3. The Silent Failure</h2>
<p>My pipeline ran on schedule. Scraped 39 jobs. Processed them. Reported: "No new entries to add." No errors, clean exit.</p>
<p>Zero new jobs from 39 listings didn't seem right. I pulled the raw data and asked the agent to audit its own pipeline's decisions.</p>
<p>It found two bugs. One was a dedup rule incorrectly matching a new job against a discontinued listing with a similar title — different posting, different job ID, valid salary data, silently dropped. The other was a salary field that the pipeline never parsed, so jobs with visible salary data were being dropped for "no salary transparency."</p>
<p>The pipeline didn't error or warn. It reported success while quietly dropping valid jobs.</p>
<p>I didn't catch this by reading code. I caught it because the output didn't pass a gut check.</p>
<hr />
<h2>Why This Matters</h2>
<p>Ben Shoemaker wrote a <a href="https://www.benshoemaker.us/writing/in-defense-of-not-reading-the-code/">piece recently</a> arguing that engineers should stop reading code line-by-line and invest in the "harness" — specs, tests, verification layers, trust boundaries. OpenAI calls this <a href="https://openai.com/index/harness-engineering/">Harness Engineering</a>.</p>
<p>Looking at these three examples through that lens, that's what I've been doing without realizing it. The AI handles production. I handle specification, trust boundaries, and the "does this actually make sense for my users?" layer.</p>
<p>If you're an engineer building with AI tools right now, I'd suggest paying attention to the moments where you override the AI's suggestions. Those moments aren't interruptions to your workflow — they're the most valuable part of it. That's the skill set the market is shifting toward, and it's worth documenting for yourself even if you never publish it.</p>
<hr />
<p><em>I'm a Senior Software Engineer with over a decade of experience, including building internationalization systems serving 50M+ users. I write about building with AI at</em> <a href="http://blog.alleyne.dev"><em>blog.alleyne.dev</em></a><em>.</em></p>
]]></content:encoded></item><item><title><![CDATA[I Benchmarked 6 LLMs to Automate My Job Board for $0.35/Month]]></title><description><![CDATA[Update (April 11, 2026): I re-ran benchmarks with March 2026 models. GPT-5.4 Nano (\(0.20/\)1.25 per M tokens) matched GPT-5 Mini on classification (96% F1) and beat Claude Haiku on extraction (100% s]]></description><link>https://blog.alleyne.dev/i-benchmarked-6-llms-to-automate-my-job-board-for-035month</link><guid isPermaLink="true">https://blog.alleyne.dev/i-benchmarked-6-llms-to-automate-my-job-board-for-035month</guid><category><![CDATA[llm]]></category><category><![CDATA[AI]]></category><category><![CDATA[github-actions]]></category><category><![CDATA[web scraping]]></category><dc:creator><![CDATA[Damien Alleyne]]></dc:creator><pubDate>Tue, 10 Feb 2026 13:32:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1770729820474/a0576dce-5409-442f-8716-8ed2e7479dde.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Update (April 11, 2026):</strong> I re-ran benchmarks with March 2026 models. <strong>GPT-5.4 Nano</strong> (\(0.20/\)1.25 per M tokens) matched GPT-5 Mini on classification (96% F1) and beat Claude Haiku on extraction (100% salary, 92.3% geo) — at 664ms avg latency and \(0.001/run. We've consolidated from two models down to one. Monthly cost dropped from ~\)0.35 to ~$0.01.</p>
<p>GPT-5 Nano remains unusable (20% F1). The 5.4 generation is a different beast entirely. Gemini Flash still can't produce reliable JSON.</p>
<h2>Background</h2>
<p>I run a curated remote job board (<a href="https://jobs.alleyne.dev">GlobalRemote</a>) focused on established remote-first companies with transparent salaries that hire globally — companies like GitLab, Automattic, Buffer, and Zapier. I <a href="https://blog.alleyne.dev/from-interview-surprise-to-mvp-testing-developer-job-transparency">started it last September</a> to scratch my own itch, manually curating every listing — researching interview processes, verifying geographic restrictions, and cross-referencing salary data. That worked for a small board, but didn't scale.</p>
<p>So I <a href="https://blog.alleyne.dev/i-built-2-job-scrapers-in-one-weekend-to-avoid-paying-for-data">built custom Apify scrapers</a> with department-level filtering to pull only engineering, product, design, and data roles from Greenhouse and Ashby boards. That cut the noise by 80%, but I still needed to automatically:</p>
<ol>
<li><p><strong>Classify</strong> whether a scraped job is a relevant tech role (engineer, designer, data scientist, PM) — department filtering catches the obvious non-tech roles, but borderline titles like "Integrations Consultant" or "Senior Sales Engineer" still slip through</p>
</li>
<li><p><strong>Extract</strong> details that aren't in the job board's structured fields — geographic eligibility, regional variants, and salary data when it's buried in the description text</p>
</li>
</ol>
<p>Previously, this pipeline ran locally using Ollama with qwen3:8b. I wanted to move it entirely to the cloud (GitHub Actions) using cheap API models, so it runs automatically twice a week without my local machine.</p>
<h2>The Question</h2>
<p>Which cloud LLM models give the best accuracy for classification and extraction, at the lowest cost? Should we use the same model for both tasks, or different models for each?</p>
<h2>Methodology</h2>
<h3>Ground Truth Dataset</h3>
<p>I built a test set from my own production data:</p>
<ul>
<li><p><strong>Classification (50 tests):</strong> 25 jobs that ARE on my board (known relevant, with expected categories) + 25 jobs that are NOT relevant (sales, marketing, HR, finance, legal titles from the same companies)</p>
</li>
<li><p><strong>Extraction (5 tests):</strong> Jobs with known geographic badges and salary ranges, covering <code>open-globally</code>, <code>multi-region</code>, <code>us-canada-only</code>, <code>americas-only</code>, and <code>null</code> salary cases</p>
</li>
</ul>
<h3>Models Tested</h3>
<table>
<thead>
<tr>
<th>Model</th>
<th>Provider</th>
<th>Type</th>
<th>Pricing (input/output per 1M tokens)</th>
</tr>
</thead>
<tbody><tr>
<td>Claude Haiku 4.5</td>
<td>Anthropic</td>
<td>Fast inference</td>
<td>\(0.80 / \)4.00</td>
</tr>
<tr>
<td>GPT-5 Mini</td>
<td>OpenAI</td>
<td>Reasoning</td>
<td>~\(0.15 / ~\)0.60</td>
</tr>
<tr>
<td>GPT-5 Nano</td>
<td>OpenAI</td>
<td>Reasoning (smallest)</td>
<td>~\(0.05 / ~\)0.20</td>
</tr>
<tr>
<td>Gemini 2.5 Flash</td>
<td>Google</td>
<td>Fast inference</td>
<td>\(0.15 / \)0.60</td>
</tr>
<tr>
<td>Gemini 3 Flash (preview)</td>
<td>Google</td>
<td>Fast inference (preview)</td>
<td>~\(0.15 / ~\)0.60</td>
</tr>
<tr>
<td>Qwen3 8B</td>
<td>Alibaba (via Ollama)</td>
<td>Open-source</td>
<td>Free</td>
</tr>
</tbody></table>
<p><strong>Note:</strong> GPT-4o-mini and Gemini 2.0 Flash were also tested initially but replaced with their successors (GPT-5 Mini, Gemini 2.5 Flash) for the final benchmarks.</p>
<h3>Prompts</h3>
<p>Same prompts used across all models — the exact prompts from my production pipeline:</p>
<p><strong>Classification prompt:</strong></p>
<pre><code class="language-plaintext">Classify this job title for a tech job board. Respond with JSON only.

Title: {title}
Company: {company}

{"isRelevant": true/false, "category": "engineering|product|design|data|other", "reason": "1-3 words"}

Rules:
- engineering: Software Engineer, Platform Engineer, SRE, DevOps, QA, Solutions Engineer, Design Engineer, Developer Advocate, Security Engineer
- product: Product Manager ONLY (not Growth Manager, not Renewals Manager)
- design: Product Designer, UX Designer, Visual Designer, Brand Designer
- data: Data Scientist, Data Engineer, ML Engineer, AI Engineer, Research Scientist
- ALL other roles (sales, marketing, HR, support, finance, legal) → isRelevant: false, category: "other"
</code></pre>
<p><strong>Extraction prompt:</strong></p>
<pre><code class="language-plaintext">Extract job details from this posting. Respond with JSON only.

Title: {title}
Company: {company}
Text: {description}

{
  "geoBadge": "open-globally|americas-only|emea-only|...|multi-region|...",
  "regionalVariants": ["Americas", "EMEA", "APAC"] or null,
  "salaryMin": number or null,
  "salaryMax": number or null,
  "salaryCurrency": "USD" or "EUR" or "GBP" or "CAD" or null,
  "reasoning": "brief explanation"
}
</code></pre>
<h2>Results</h2>
<h3>Full Comparison Table</h3>
<table>
<thead>
<tr>
<th>Model</th>
<th>F1 (overall score)</th>
<th>Precision (% flagged that were correct)</th>
<th>Recall (% of relevant jobs caught)</th>
<th>Category</th>
<th>Geography</th>
<th>Salary</th>
<th>Cost/run</th>
</tr>
</thead>
<tbody><tr>
<td><strong>GPT-5 Mini</strong></td>
<td><strong>94.1%</strong></td>
<td>92.3%</td>
<td><strong>96.0%</strong></td>
<td><strong>96.0%</strong></td>
<td>80.0%</td>
<td><strong>100%</strong></td>
<td>$0.008</td>
</tr>
<tr>
<td><strong>Claude Haiku 4.5</strong></td>
<td>91.7%</td>
<td><strong>95.7%</strong></td>
<td>88.0%</td>
<td>88.0%</td>
<td><strong>100%</strong></td>
<td><strong>100%</strong></td>
<td>$0.019</td>
</tr>
<tr>
<td>Gemini 2.5 Flash</td>
<td>89.8%</td>
<td>91.7%</td>
<td>88.0%</td>
<td>88.0%</td>
<td>80.0%</td>
<td>80.0%</td>
<td>$0.003</td>
</tr>
<tr>
<td>Gemini 3 Flash (preview)</td>
<td>89.4%</td>
<td>95.5%</td>
<td>84.0%</td>
<td>84.0%</td>
<td>40.0%</td>
<td>40.0%</td>
<td>$0.003</td>
</tr>
<tr>
<td>Qwen3 8B</td>
<td>85.7%</td>
<td>77.4%</td>
<td>96.0%</td>
<td>92.0%</td>
<td>60.0%</td>
<td>100%</td>
<td>free</td>
</tr>
<tr>
<td>GPT-5 Nano</td>
<td>23.3%</td>
<td>27.8%</td>
<td>20.0%</td>
<td>20.0%</td>
<td>0.0%</td>
<td>0.0%</td>
<td>$0.006</td>
</tr>
</tbody></table>
<h3>Key Findings</h3>
<h4>1. GPT-5 Mini is the best classifier</h4>
<ul>
<li><p><strong>F1: 94.1%</strong> with 96% recall — it catches nearly every relevant job</p>
</li>
<li><p>Only 1 false negative: "Senior Marketing Data Analyst" (ambiguous title)</p>
</li>
<li><p>2 false positives: "Integrations Consultant" and "Senior Sales Engineer" (borderline roles)</p>
</li>
<li><p>96% category accuracy — correctly distinguishes engineering vs. design vs. data</p>
</li>
</ul>
<h4>2. Claude Haiku 4.5 is the best extractor</h4>
<ul>
<li><p><strong>100% geography badge accuracy</strong> — correctly identifies open-globally, multi-region, us-canada-only, americas-only</p>
</li>
<li><p><strong>100% salary accuracy</strong> — extracts exact numbers and currency, handles null correctly</p>
</li>
<li><p>Classification is good (91.7% F1) but misses some edge cases like "Growth Designer"</p>
</li>
</ul>
<h4>3. GPT-5 Nano is unusable</h4>
<ul>
<li><p>23.3% F1, 0% extraction accuracy — massive JSON parse errors</p>
</li>
<li><p>Classified most jobs as irrelevant, couldn't extract structured data</p>
</li>
<li><p>Despite being cheapest, it costs MORE than Gemini 2.5 Flash while being terrible</p>
</li>
<li><p><strong>Verdict: Do not use GPT-5 Nano for structured extraction tasks</strong></p>
</li>
</ul>
<h4>4. Gemini 3 Flash (preview) has JSON reliability issues</h4>
<ul>
<li><p>Classification is decent (89.4% F1) but extraction fails 60% of the time with parse errors</p>
</li>
<li><p>The preview model wraps JSON in markdown code blocks or adds commentary</p>
</li>
<li><p><strong>Not production-ready yet</strong> — wait for GA</p>
</li>
</ul>
<h4>5. Gemini 2.5 Flash is the budget option</h4>
<ul>
<li><p>Cheapest cloud model at $0.003/run</p>
</li>
<li><p>Decent classification (89.8% F1) but weaker extraction (80% geography, 80% salary)</p>
</li>
<li><p>One parse error on a EUR salary extraction test</p>
</li>
</ul>
<h4>6. Qwen3 8B is surprisingly capable</h4>
<ul>
<li><p>Free and runs locally</p>
</li>
<li><p>85.7% F1 classification — decent but too many false positives (7)</p>
</li>
<li><p>100% salary extraction but only 60% geography badge accuracy</p>
</li>
<li><p>Misclassifies "multi-region" as "open-globally" consistently</p>
</li>
</ul>
<h3>Error Pattern Analysis</h3>
<p><strong>Common false negatives across models:</strong></p>
<ul>
<li><p>"Senior Marketing Data Analyst" — every model flagged this as marketing, not data. Ambiguous title.</p>
</li>
<li><p>"Data Analyst, Customer Intelligence" — "Customer" in title triggers exclusion</p>
</li>
<li><p>"Senior Growth Designer" — "Growth" confuses classification</p>
</li>
</ul>
<p><strong>Common false positives:</strong></p>
<ul>
<li><p>"Integrations Consultant - Americas" — every model said "engineering" (borderline role)</p>
</li>
<li><p>"Senior Sales Engineer" — GPT-5 Mini incorrectly treated as engineering</p>
</li>
</ul>
<p><strong>Extraction patterns:</strong></p>
<ul>
<li><p>"Americas" region consistently extracted correctly by Claude Haiku</p>
</li>
<li><p>"US and Europe" → "multi-region" was the hardest badge to get right</p>
</li>
<li><p>EUR salary with different format than USD tripped up Gemini models</p>
</li>
</ul>
<h2>Decision: Hybrid Model Strategy</h2>
<p>Based on benchmarks, I implemented <strong>task-based model routing</strong>:</p>
<table>
<thead>
<tr>
<th>Task</th>
<th>Primary Model</th>
<th>Fallback</th>
<th>Why</th>
</tr>
</thead>
<tbody><tr>
<td>Classification</td>
<td>GPT-5 Mini</td>
<td>Claude Haiku → Ollama</td>
<td>Best F1 (94.1%), best recall (96%), best category accuracy (96%)</td>
</tr>
<tr>
<td>Extraction</td>
<td>Claude Haiku</td>
<td>GPT-5 Mini → Ollama</td>
<td>Perfect geography + salary (100%)</td>
</tr>
</tbody></table>
<h3>Cost Estimate</h3>
<p>Per twice-weekly ingestion run (~50-100 jobs to classify, ~10-20 to extract):</p>
<table>
<thead>
<tr>
<th>Task</th>
<th>Model</th>
<th>Estimated tokens</th>
<th>Cost</th>
</tr>
</thead>
<tbody><tr>
<td>Classification</td>
<td>GPT-5 Mini</td>
<td>~30K input, ~5K output</td>
<td>~$0.008</td>
</tr>
<tr>
<td>Extraction</td>
<td>Claude Haiku</td>
<td>~20K input, ~5K output</td>
<td>~$0.036</td>
</tr>
<tr>
<td><strong>Total per run</strong></td>
<td></td>
<td></td>
<td><strong>~$0.044</strong></td>
</tr>
<tr>
<td><strong>Monthly (8 runs)</strong></td>
<td></td>
<td></td>
<td><strong>~$0.35</strong></td>
</tr>
</tbody></table>
<h3>Implementation</h3>
<p>The routing is handled in a small LLM abstraction layer:</p>
<pre><code class="language-javascript">const TASK_ROUTING = {
  classify: ['openai', 'claude', 'ollama'],   // GPT-5 Mini first
  extract:  ['claude', 'openai', 'ollama'],   // Claude Haiku first
  default:  ['claude', 'openai', 'ollama'],
};

// Pipeline calls specify the task:
await batchGenerateJSON(classificationPrompts, { task: 'classify' });
await batchGenerateJSON(extractionPrompts, { task: 'extract' });
</code></pre>
<p>Each task resolves to the best available model in priority order. If OpenAI is down, classification falls back to Claude Haiku. If Anthropic is down, extraction falls back to GPT-5 Mini. Ollama is available as a fallback for local development, but isn't used in the cloud pipeline.</p>
<h2>GPT-5 API Gotchas</h2>
<p>If you're migrating from GPT-4o-mini to GPT-5 models, watch out for:</p>
<ol>
<li><p><strong>No</strong> <code>temperature</code> parameter — GPT-5 models are reasoning models (like o1/o3). They don't accept <code>temperature</code>. Remove it entirely.</p>
</li>
<li><p><code>max_completion_tokens</code> not <code>max_tokens</code> — The parameter name changed for reasoning models.</p>
</li>
<li><p><code>response_format: { type: 'json_object' }</code> still works — JSON mode is supported via Chat Completions.</p>
</li>
<li><p><strong>Chat Completions API still works</strong> — Despite OpenAI promoting the new Responses API, Chat Completions hasn't been deprecated. For simple single-turn JSON extraction, Chat Completions is fine.</p>
</li>
</ol>
<h2>Timeline</h2>
<p>I ran a local pipeline with Ollama for a while, which worked but required my Mac to be on. Moving everything to the cloud was another weekend:</p>
<ol>
<li><p>Benchmarked 6 cloud models to find the best fit for classification and extraction</p>
</li>
<li><p>Built the cloud pipeline on GitHub Actions with hybrid model routing</p>
</li>
<li><p>Hardened data quality — HTML-based requirements extraction, fuzzy title dedup, paid-trial badge detection</p>
</li>
<li><p><strong>Result:</strong> Fully automated, runs twice a week, creates PRs for review, costs ~$0.35/month</p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[I Built 2 Job Scrapers in One Weekend to Avoid Paying for Data]]></title><description><![CDATA[I run GlobalRemote, a curated job board that shows interview processes and hiring transparency upfront. To keep it relevant, I needed to update it 2x per week with fresh jobs from Greenhouse and Ashby boards.
The problem? The scraper I was using fetc...]]></description><link>https://blog.alleyne.dev/i-built-2-job-scrapers-in-one-weekend-to-avoid-paying-for-data</link><guid isPermaLink="true">https://blog.alleyne.dev/i-built-2-job-scrapers-in-one-weekend-to-avoid-paying-for-data</guid><category><![CDATA[AI]]></category><category><![CDATA[apify]]></category><category><![CDATA[web scraping]]></category><category><![CDATA[Open Source]]></category><dc:creator><![CDATA[Damien Alleyne]]></dc:creator><pubDate>Mon, 02 Feb 2026 17:09:40 GMT</pubDate><content:encoded><![CDATA[<p>I run <a target="_blank" href="https://jobs.alleyne.dev">GlobalRemote</a>, a curated job board that shows interview processes and hiring transparency upfront. To keep it relevant, I needed to update it <strong>2x per week</strong> with fresh jobs from Greenhouse and Ashby boards.</p>
<p>The problem? The scraper I was using fetched <em>every</em> job from each company — Sales, HR, Support, everything — and stored it all in my Apify dataset. With 6-8 companies, that's 300-400 jobs per scrape, but only 5-10 were actually relevant.</p>
<p><strong>I was burning through my Apify free tier ($5/month, ~2000 dataset operations) on irrelevant data.</strong> Two scrapes per week would blow past my quota. I wasn't ready to pay for a higher tier just to subsidize wasteful scraping.</p>
<p>So my options were:</p>
<ol>
<li><p>Update infrequently (once every 2-3 weeks) and let the board go stale</p>
</li>
<li><p>Pay for a higher Apify tier to subsidize wasteful scraping</p>
</li>
<li><p>Build my own scrapers with department filtering</p>
</li>
</ol>
<p>I chose #3.</p>
<p>The scrapers are now <a target="_blank" href="https://apify.com/dalleyne">live on Apify Store</a>, open-source, and I'm dogfooding them on GlobalRemote right now.</p>
<h2 id="heading-the-problem-i-couldnt-update-frequently-enough">The Problem: I Couldn't Update Frequently Enough</h2>
<p>The scraper I was using worked like this:</p>
<ol>
<li><p>Fetch all jobs from a company's job board</p>
</li>
<li><p>Store everything in an Apify dataset</p>
</li>
<li><p>I filter locally for the jobs I actually want</p>
</li>
</ol>
<p>This makes sense if you want <em>all</em> the jobs. But for a curated board like GlobalRemote, I only wanted:</p>
<ul>
<li><p>Engineering roles (not Sales, Marketing, HR)</p>
</li>
<li><p>From specific departments (e.g., "Code Wrangling" at Automattic, "Engineering" at GitLab)</p>
</li>
<li><p>Recent postings (not 6-month-old listings)</p>
</li>
</ul>
<p>With 300-400 jobs stored per scrape and only 5-10 relevant, I was wasting my dataset quota. <strong>Two scrapes per week would exceed my free tier limit.</strong> The choice was: pay for a higher tier or update less frequently. Neither was ideal.</p>
<h2 id="heading-the-solution-per-url-department-filtering">The Solution: Per-URL Department Filtering</h2>
<p>I built two Apify actors:</p>
<ul>
<li><p><a target="_blank" href="https://apify.com/dalleyne/greenhouse-job-scraper"><strong>Greenhouse Job Scraper</strong></a> (Automattic, GitLab, Speechify, etc.)</p>
</li>
<li><p><a target="_blank" href="https://apify.com/dalleyne/ashby-job-scraper"><strong>Ashby Job Scraper</strong></a> (Buffer, Zapier, RevenueCat, etc.)</p>
</li>
</ul>
<p>Both support <strong>per-URL configuration</strong>, meaning each company can have different filters:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"urls"</span>: [
    {
      <span class="hljs-attr">"url"</span>: <span class="hljs-string">"https://job-boards.greenhouse.io/automatticcareers"</span>,
      <span class="hljs-attr">"departments"</span>: [<span class="hljs-number">307170</span>],
      <span class="hljs-attr">"maxJobs"</span>: <span class="hljs-number">50</span>,
      <span class="hljs-attr">"daysBack"</span>: <span class="hljs-number">7</span>
    },
    {
      <span class="hljs-attr">"url"</span>: <span class="hljs-string">"https://job-boards.greenhouse.io/gitlab"</span>,
      <span class="hljs-attr">"departments"</span>: [<span class="hljs-number">4011044002</span>],
      <span class="hljs-attr">"maxJobs"</span>: <span class="hljs-number">20</span>
    }
  ]
}
</code></pre>
<p>The scraper:</p>
<ol>
<li><p>Fetches department metadata</p>
</li>
<li><p>Filters jobs by department ID <em>before</em> storing them</p>
</li>
<li><p>Only stores jobs that match your criteria</p>
</li>
<li><p>You only pay for the jobs you actually get (not the ones filtered out)</p>
</li>
</ol>
<p><strong>Result:</strong> I went from storing 300-400 jobs per scrape to 30-50 jobs — an 80% reduction in dataset usage.</p>
<h2 id="heading-how-i-built-it">How I Built It</h2>
<h3 id="heading-tech-stack">Tech Stack</h3>
<ul>
<li><p><strong>Apify platform</strong> — handles hosting, scheduling, dataset storage</p>
</li>
<li><p><strong>Greenhouse + Ashby APIs</strong> — public APIs for job boards</p>
</li>
<li><p><strong>AI (Claude)</strong> — for rapid development</p>
</li>
</ul>
<h3 id="heading-how-the-apis-work">How the APIs Work</h3>
<p>Both platforms expose public APIs for their job boards. This meant I could:</p>
<ul>
<li><p>Fetch departments/teams programmatically</p>
</li>
<li><p>Filter by department/team ID before fetching job details</p>
</li>
<li><p>Only pull full job data for matches</p>
</li>
<li><p>No browser automation or HTML scraping needed</p>
</li>
</ul>
<p>This is key: I'm filtering <em>before</em> fetching details, not after. Most scrapers fetch everything, then you filter locally. Mine filters first, then only fetches what you need.</p>
<h3 id="heading-development-process">Development Process</h3>
<p>I built both scrapers over one weekend using AI (Claude).</p>
<p><strong>Saturday (Jan 31):</strong> Greenhouse scraper</p>
<ul>
<li><p>Prompt: "Build an Apify actor that scrapes Greenhouse job boards with department filtering"</p>
</li>
<li><p>AI figured out the API structure</p>
</li>
<li><p>I tested on Automattic and GitLab job boards</p>
</li>
</ul>
<p><strong>Sunday (Feb 1):</strong> Ashby scraper</p>
<ul>
<li><p>Prompt: "Build an Apify actor for Ashby job boards with department filtering (similar structure to the existing Greenhouse scraper)"</p>
</li>
<li><p>AI figured out Ashby's API</p>
</li>
<li><p>Tested on Buffer, Zapier, RevenueCat</p>
</li>
</ul>
<p><strong>What AI handled:</strong></p>
<ul>
<li><p>Reading API documentation (Greenhouse, Ashby, Apify actor structure)</p>
</li>
<li><p>Writing the scraper logic and Apify boilerplate</p>
</li>
<li><p>Handling edge cases (null departments, missing dates)</p>
</li>
<li><p>Generating input/output schemas</p>
</li>
</ul>
<p><strong>What I did:</strong></p>
<ul>
<li><p>Product decisions (per-URL config vs global config)</p>
</li>
<li><p>Testing on real job boards</p>
</li>
<li><p>Iterating when things didn't work</p>
</li>
<li><p>Catching issues (e.g., updated Node 20 → 22 in Dockerfile)</p>
</li>
</ul>
<p><strong>I never opened:</strong></p>
<ul>
<li><p><a target="_blank" href="https://developers.greenhouse.io/job-board.html">Greenhouse API documentation</a></p>
</li>
<li><p><a target="_blank" href="https://developers.ashbyhq.com/docs/public-job-posting-api">Ashby API documentation</a></p>
</li>
<li><p><a target="_blank" href="https://docs.apify.com/platform/actors">Apify's actor documentation</a></p>
</li>
</ul>
<p><strong>Total development time: One weekend.</strong></p>
<p>AI is a co-pilot, not autopilot - but it handled all the research and boilerplate so I could focus on testing and product decisions.</p>
<h2 id="heading-dogfooding-on-globalremote">Dogfooding on GlobalRemote</h2>
<p>I'm using both scrapers to populate <a target="_blank" href="https://jobs.alleyne.dev">GlobalRemote</a> right now.</p>
<p>When I need fresh data, I trigger both scrapers. They return 30-50 relevant jobs instead of 300-400, keeping me well within my Apify free tier.</p>
<p><strong>What I've learned from dogfooding:</strong></p>
<ul>
<li><p>Department filtering reduced dataset usage by ~80%</p>
</li>
<li><p>I can now update regularly without exceeding my quota</p>
</li>
</ul>
<p>If the scrapers break, GlobalRemote breaks. That's a strong incentive to keep them working.</p>
<h2 id="heading-what-i-learned">What I Learned</h2>
<h3 id="heading-1-filter-before-storing-not-after">1. Filter before storing, not after</h3>
<p>For curated job boards, filtering <em>before</em> storage is way more cost-effective. The scraper I was using didn't do this.</p>
<h3 id="heading-2-per-url-config-beats-global-config">2. Per-URL config beats global config</h3>
<p>My first version had global department filters (same filter for all companies). That was a mistake. Different companies organize departments differently. Per-URL config gives users way more flexibility.</p>
<h3 id="heading-3-real-examples-gt-fake-examples">3. Real examples &gt; Fake examples</h3>
<p>In my README, I used <em>real</em> companies (Automattic, GitLab) and <em>real</em> department IDs (307170 = "Code Wrangling" at Automattic). Fake examples would've been useless for someone trying to replicate this.</p>
<h3 id="heading-4-ai-accelerates-weekend-projects-into-production-tools">4. AI accelerates weekend projects into production tools</h3>
<p>I shipped two working scrapers in one weekend without reading a single API doc. AI handled research and implementation; I handled product decisions and testing. That's the real power of AI in 2026.</p>
<h3 id="heading-5-open-sourcing-on-apify-was-easy">5. Open-sourcing on Apify was easy</h3>
<p>Publishing to Apify Store took ~10 minutes:</p>
<ul>
<li><p>Add README</p>
</li>
<li><p>Set pricing</p>
</li>
<li><p>Add input/output schemas</p>
</li>
<li><p>Add Banking information (they prefer PayPal)</p>
</li>
<li><p>Click "Publish"</p>
</li>
</ul>
<h2 id="heading-whats-next">What's Next</h2>
<p>Both scrapers are live and stable. I will be using them on GlobalRemote twice a week, well within my free tier.</p>
<p><strong>Potential improvements:</strong></p>
<ul>
<li><p>Add automated tests (right now it's just manual verification)</p>
</li>
<li><p>Add salary parsing to Ashby scraper (Greenhouse already extracts salary ranges)</p>
</li>
<li><p>Build a Lever scraper (if there's demand)</p>
</li>
</ul>
<p><strong>But honestly?</strong> I built these to solve my own problem. If other people find them useful, great. If not, I'm still updating GlobalRemote 2x/week without blowing my budget.</p>
<hr />
<h2 id="heading-links">Links</h2>
<ul>
<li><p><strong>Greenhouse scraper:</strong> <a target="_blank" href="http://apify.com/dalleyne/greenhouse-job-scraper">apify.com/dalleyne/greenhouse-job-scraper</a></p>
</li>
<li><p><strong>Ashby scraper:</strong> <a target="_blank" href="http://apify.com/dalleyne/ashby-job-scraper">apify.com/dalleyne/ashby-job-scraper</a></p>
</li>
<li><p><strong>GlobalRemote:</strong> <a target="_blank" href="http://jobs.alleyne.dev">jobs.alleyne.dev</a></p>
</li>
<li><p><strong>GitHub:</strong> Both scrapers are MIT licensed - <a target="_blank" href="https://github.com/d-alleyne/greenhouse-job-scraper">Greenhouse</a> | <a target="_blank" href="https://github.com/d-alleyne/ashby-job-scraper">Ashby</a></p>
</li>
</ul>
<p>If you're building a job board or need ATS data, feel free to use them. And if you have feedback or find bugs, I'm on <a target="_blank" href="https://linkedin.com/in/damienalleyne">LinkedIn</a> or reachable via Apify.</p>
]]></content:encoded></item><item><title><![CDATA[What If We Could Fix Barbados Traffic With Data?]]></title><description><![CDATA[Every morning during my commute, I deal with the same roundabout problem. A car is coming around, and I need to figure out: are they exiting, or staying in?
No indicator light. So I watch their trajectory, their speed, try to read their intentions. I...]]></description><link>https://blog.alleyne.dev/what-if-we-could-fix-barbados-traffic-with-data</link><guid isPermaLink="true">https://blog.alleyne.dev/what-if-we-could-fix-barbados-traffic-with-data</guid><category><![CDATA[Machine Learning]]></category><category><![CDATA[Data Science]]></category><category><![CDATA[transportation ]]></category><category><![CDATA[Tech community]]></category><category><![CDATA[#social good]]></category><dc:creator><![CDATA[Damien Alleyne]]></dc:creator><pubDate>Sun, 23 Nov 2025 21:13:02 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/PmH8eyFjP_w/upload/a53cc4483dad60124893cf0f802be11f.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Every morning during my commute, I deal with the same roundabout problem. A car is coming around, and I need to figure out: are they exiting, or staying in?</p>
<p>No indicator light. So I watch their trajectory, their speed, try to read their intentions. If I guess right and they exit, I can enter and save a few seconds. If I guess wrong, it's dangerous, so most times, I just wait.</p>
<p>I'd always figured this was just how roundabouts work in Barbados. Poor signaling, unpredictable flow, daily frustration. That's just the reality here.</p>
<p>Then I went to a meetup at <a target="_blank" href="https://luma.com/p67mhuz8">Pelican Village</a> on Saturday, November 22nd, 2025.</p>
<h2 id="heading-the-challenge"><strong>The Challenge</strong></h2>
<p>The turnout was smaller than usual — as persons had the option to attend via Zoom. We were there to learn about the <a target="_blank" href="https://zindi.africa/competitions/barbados-traffic-analysis-challenge">Barbados Traffic Analysis Challenge</a>, a machine learning competition organized by <a target="_blank" href="https://govtech.bb/">GovTech</a> and Keleya Labs and hosted on <a target="_blank" href="https://zindi.africa/">Zindi</a> to help the <a target="_blank" href="https://mtw.gov.bb/">Ministry of Transport and Works</a> (MTW).</p>
<p>The presentation covered the technical side: using Machine Learning (ML) to analyze video footage, extracting features from data, different classification models. A lot of it was new territory for me.</p>
<p>During the networking session afterward, <a target="_blank" href="https://www.linkedin.com/in/conrad-brits-30565823/">Conrad Brits</a>, founder of Keleya Labs, explained how the competition came together. He's been working on various projects in Barbados since moving here during COVID. He said that our highway infrastructure is great, but for some reason the speed of traffic at our roundabouts is slow when compared to other places with similar highway infrastructure. When new cameras were installed at the Norman Niles roundabout, he felt that this data can be used to predict traffic conditions with machine learning.</p>
<p>Then he shared his theory about what he thinks is actually causing delays.</p>
<h2 id="heading-the-signaling-problem"><strong>The Signaling Problem</strong></h2>
<p>Conrad shared his hypothesis: people don't signal when exiting roundabouts, and he thinks that's measurably slowing down how quickly cars can enter.</p>
<p>Hearing him say it out loud made me realize — I've experienced this. I've seen the rare driver who <em>does</em> signal their exit, and I've tried it myself a few times. When someone signals, the person waiting to enter the roundabout gets those crucial milliseconds of certainty. They can go instead of hesitating.</p>
<p>But it's uncommon here. And without signals, every driver faces the same choice: wait to be sure, or guess and risk it.</p>
<p>Conrad's idea is to use machine learning to verify this with actual data. If the analysis shows that signaling improves entry rates, he can take that evidence to the MTW. Not assumptions — data. And maybe they'd update driver education to emphasize signaling at exits.</p>
<p>It reminded me of how <strong>jambusting</strong> became accepted practice. What started as an unofficial technique —minivans using the outside lane to go straight through roundabouts in the early 2000s — eventually became allowed at ABC Highway roundabouts as a way to ease traffic flow. Sometimes the practices that work in reality get officially recognized. Maybe signaling could be similar.</p>
<h2 id="heading-the-competition-details"><strong>The Competition Details</strong></h2>
<p>The challenge itself: analyze 15 minutes of traffic video, then predict traffic conditions 5 minutes into the future. You work with four video streams from the Norman Niles roundabout, each with congestion ratings. The goal is identifying what's actually causing the delays.</p>
<p>There are cash prizes and exposure to international companies that recruit from these competitions. Deadline is January 26th, 2026 — two months away.</p>
<p>Conrad emphasized the social good that could come from this. Less time in traffic has ripple effects — people getting home to their families sooner, reduced stress, lower fuel costs, better quality of life. The improvements might seem small on an individual level, but multiply that across thousands of daily commutes and it becomes significant.</p>
<h2 id="heading-why-this-matters"><strong>Why This Matters</strong></h2>
<p>There's something compelling about this challenge. The daily frustrations we accept as unchangeable might not be. Data could turn assumptions into evidence. A small group at Pelican Village on a Saturday might improve commutes for everyone on the island.</p>
<p>If you have any interest in data science, ML, or solving civic problems with code, check out the <a target="_blank" href="https://zindi.africa/competitions/barbados-traffic-analysis-challenge">Barbados Traffic Analysis Challenge</a>. It closes January 26th, 2026.</p>
<p>Maybe someone will prove that a simple indicator light could save thousands of Barbadians time every day.</p>
]]></content:encoded></item><item><title><![CDATA[I Built a Job Board for Transparency. But Is Applying Even the Right Strategy?]]></title><description><![CDATA[Five weeks ago, I launched GlobalRemote — a curated job board focused on interview transparency for remote developers. The feedback was encouraging: developers loved knowing what to expect before applying. I expanded from 7 manually verified jobs to ...]]></description><link>https://blog.alleyne.dev/i-built-a-job-board-for-transparency-but-is-applying-even-the-right-strategy</link><guid isPermaLink="true">https://blog.alleyne.dev/i-built-a-job-board-for-transparency-but-is-applying-even-the-right-strategy</guid><category><![CDATA[remote work]]></category><category><![CDATA[career advice]]></category><category><![CDATA[job search]]></category><dc:creator><![CDATA[Damien Alleyne]]></dc:creator><pubDate>Fri, 10 Oct 2025 10:00:52 GMT</pubDate><content:encoded><![CDATA[<p>Five weeks ago, I launched <a target="_blank" href="https://jobs.alleyne.dev/">GlobalRemote</a> — a curated job board focused on interview transparency for remote developers. The feedback was encouraging: developers loved knowing what to expect before applying. I expanded from 7 manually verified jobs to 26 across 11 companies. People engaged with the concept.</p>
<p>Then I <a target="_blank" href="https://newsletter.pragmaticengineer.com/p/state-of-the-tech-market-in-2025-hiring-managers">read research</a> from 30+ hiring managers that made me question everything I'd built.</p>
<blockquote>
<p><strong>TL;DR:</strong> I built a job board for interview transparency. Then research showed that applications don't work — companies hire 90% of engineers through referrals and direct outreach, not inbound applications. I'm rethinking whether job boards should help people apply, or help them research companies for targeted outreach instead.</p>
</blockquote>
<h2 id="heading-the-problem-i-thought-i-was-solving">The Problem I Thought I Was Solving</h2>
<p>After experiencing surprise interview formats — expecting a conversation about my experience but getting handed a whiteboard problem instead — I realized most job boards tell you the company’s tech stack … <em>may</em> tell you the salary, but rarely the interview process. I built GlobalRemote to fix that: <strong>show developers what to expect before they invest time applying</strong>.</p>
<p>The early validation seemed strong. Developers in my network immediately understood the value. "I would absolutely use this," several told me. The geographic restriction transparency resonated even more —people were tired of discovering location restrictions deep in the job description or application process.</p>
<p>I thought I was solving a real problem. And I was. Just not in the way I expected.</p>
<p>The interview transparency still matters — developers still need to know what they're walking into. But maybe it matters for a different reason than I originally thought.</p>
<h2 id="heading-why-job-applications-dont-work-in-2025">Why Job Applications Don't Work in 2025</h2>
<p>The Pragmatic Engineer recently published findings from conversations with 30+ tech hiring managers and recruiters. The numbers are stark: companies regularly receive <strong>1,000+ applications for a single role</strong>, yet only about 10% of applicants are even minimally qualified.</p>
<p>One startup founder reported 23,000 applications in 30 days for 8 roles. A Spotify engineering manager saw 1,700 applicants in 15 hours. A Swiss startup stopped accepting applications at 600 in just 2 days.</p>
<p>But here's what shook me: despite this flood of applications, most companies hire <strong>fewer than 10% of their engineers through inbound applications</strong>. The majority come from direct outreach, referrals, and recruiter sourcing.</p>
<p>A now-deleted Reddit post (removed as potential advertising, though the pattern is very real) illustrated this perfectly: a senior backend engineer sent <strong>1,147 applications</strong> over five months, which generated 47 phone screenings. Meanwhile, <strong>400 targeted emails</strong> to hiring managers and recruiters resulted in 62 responses and 16 technical interviews. He eventually received 3 offers.</p>
<p>The math is brutal. Traditional job applications have become a numbers game where even qualified candidates get lost in the noise.</p>
<h2 id="heading-ai-is-making-it-worse">AI Is Making It Worse</h2>
<p>Hiring managers consistently reported the same frustration: <strong>application quality has never been lower</strong>. Many applicants don't meet basic job requirements — frontend roles flooded with backend engineers, location requirements completely ignored, resumes clearly tailored by AI to mirror job descriptions when the person lacks the claimed experience.</p>
<p>I'll even admit: I've used AI to tailor my resume to job descriptions. I feed AI the job posting along with my real experience, and it generates a resume that caters to the job posting’s requirements. The problem? It often lists experiences that I've never had — just because they appeared in the job description. Every time, I have to manually edit out the hallucinated experience.</p>
<p>If I'm doing this — and I know enough to catch the fabrications — imagine how many desperate job seekers are submitting AI-generated resumes without reviewing them carefully.</p>
<p>One hiring manager described LinkedIn as "<strong>an irrecoverable hellscape for inbound applications</strong>." Multiple companies have stopped posting jobs on LinkedIn entirely, turning to smaller job boards or relying exclusively on outbound recruiting.</p>
<p>The Atlantic recently ran a headline: "<a target="_blank" href="https://www.theatlantic.com/ideas/archive/2025/09/job-market-hell/684133/">The Job Market Is Hell</a>—Young people are using ChatGPT to write their applications; HR is using AI to read them; no one is getting hired."</p>
<p>The system is broken on both sides. Applicants are desperate, so they use AI to spam applications. Companies are overwhelmed, so they use AI to filter them out. Everyone loses.</p>
<h2 id="heading-what-actually-works-direct-outreach">What Actually Works: Direct Outreach</h2>
<p>The hiring managers' data revealed a clear pattern: <strong>the best hires come from people they already know or people who reach out directly</strong>.</p>
<p>When a recruiter sources a candidate — proactively reaching out on LinkedIn — those candidates pass interviews at significantly higher rates than inbound applicants. When an engineer refers someone they've worked with, the quality is exponentially better. When a candidate identifies a company worth targeting and emails the hiring manager directly, they bypass automated filtering and ensure their application actually gets reviewed.</p>
<p>One hiring manager admitted: "The only way I've gotten truly amazing people to apply is through reaching out to my network."</p>
<p>This isn’t because good engineers don’t apply to jobs. It’s because in a market with 1,000+ applications per role, even strong candidates get filtered out by volume. The signal-to-noise ratio has collapsed.</p>
<p><strong>I experienced this firsthand.</strong> When I applied to Automattic in late 2021, my first application went nowhere. Then I attended a <a target="_blank" href="https://www.youtube.com/live/ktckNt1R0Kw">YouTube livestream</a> where they were partnering with Tech Beach Retreat, a Caribbean tech ecosystem that connects regional talent with global companies. In the chat, I was told to reapply because they were swamped with applications.</p>
<p>My second application - same resume, same qualifications - got reviewed. I still went through their full interview process, including the paid trial.</p>
<p>But something changed between attempt one and attempt two. Maybe someone noticed I’d engaged with their Caribbean recruitment initiative. Maybe they were being more deliberate about reviewing applications from that region. I don’t know exactly what happened.</p>
<p><strong>What I do know:</strong> the same application that was ignored the first time succeeded the second time, not because my credentials improved, but because of context that existed outside the application itself.​​​​​​​​​​​​​​​​</p>
<h2 id="heading-the-realization-i-built-for-the-wrong-workflow">The Realization: I Built for the Wrong Workflow</h2>
<p>Here's what hit me while reading this research: <strong>I built a platform to help developers apply better. But what if applying isn't the strategy anymore</strong>?</p>
<p>Interview transparency still matters. Geographic restrictions still matter. Salary ranges still matter. But maybe they matter for a different reason than I thought.</p>
<p>Instead of: "Here's a job you should apply to, and here's what the interview will be like."</p>
<p>It should be: "Here's a company worth targeting, and here's the research you need to reach out directly."</p>
<p>Let me show you what I mean. Take Automattic's <a target="_blank" href="https://jobs.alleyne.dev/job/experienced-engineer-automattic">Experienced Software Engineer role on GlobalRemote</a>. Right now, it shows:</p>
<ul>
<li><p>Salary: $70K-$170K USD (transparent range based on location and experience)</p>
</li>
<li><p>Location: Fully remote</p>
</li>
<li><p>Interview: Take-home test, paid trial project with actual team (6-8 weeks total)</p>
</li>
</ul>
<p>That's useful for applications. But for direct outreach, you'd want to know:</p>
<ul>
<li><p>Automattic is fully async with 1400+ employees distributed globally</p>
</li>
<li><p>They publish company culture and processes openly</p>
</li>
<li><p>They contribute actively to <a target="_blank" href="http://WordPress.org">WordPress.org</a> open source</p>
</li>
<li><p>Their paid trial process proves they value your time and judge real work</p>
</li>
<li><p>Hiring managers are identifiable on LinkedIn</p>
</li>
</ul>
<p>That's not application information. That's research ammunition for a targeted outreach campaign.</p>
<h2 id="heading-what-job-seekers-actually-need">What Job Seekers Actually Need</h2>
<p>The developer who sent 1,147 applications eventually figured this out. His successful strategy combined:</p>
<ul>
<li><p>Researching companies worth targeting (not just any open role)</p>
</li>
<li><p>Finding recruiter and hiring manager contacts</p>
</li>
<li><p>Sending personalized outreach emails</p>
</li>
<li><p>Negotiating with competing offers</p>
</li>
</ul>
<p>Applications alone weren't enough — 1,147 applications got him 47 phone screenings. But direct outreach changed his results: 400 emails generated 16 interviews from just 62 responses.</p>
<h2 id="heading-rethinking-globalremote">Rethinking GlobalRemote</h2>
<p>This research has me questioning some fundamental assumptions about what I'm building.</p>
<p>What if the value isn't helping people apply better, but helping them research companies worth targeting? The interview transparency wouldn't just be nice-to-have information — it could be proof that a company respects candidates enough to be transparent. That's a signal worth targeting.</p>
<p>The geographic restrictions wouldn't just be filters—they could be indicators of company culture. A truly distributed company that hires globally is fundamentally different from one that requires US timezone overlap. That distinction might matter when you're choosing where to invest your networking energy.</p>
<p>I don't know yet if this reframing makes sense. I've only been at this for five weeks.</p>
<h2 id="heading-the-bigger-question">The Bigger Question</h2>
<p>This research raises uncomfortable questions about what I'm building. If applications don't work, why optimize application experiences? If most hires come from referrals and outreach, what role should a job board play?</p>
<p>I don't have answers yet. I'm five weeks into this journey, with 26 jobs across 11 companies and minimal traffic. The validation from developers suggests the problem I identified is real. But maybe I'm solving it from the wrong angle.</p>
<p>Maybe the future isn't better job boards. Maybe it's better research tools. Or maybe there's a way to do both — help people find opportunities while acknowledging that "apply" might not be the best next step.</p>
<h2 id="heading-what-this-means-for-developers-job-hunting-right-now">What This Means for Developers Job Hunting Right Now</h2>
<p>If you're sending hundreds of applications and hearing nothing back, you're not alone. The system is genuinely broken. But here's what seems to be working:</p>
<p><strong>Stop spraying applications.</strong> Pick 10-20 companies that genuinely interest you and research them deeply. Understand their culture, read their blogs, identify their pain points.</p>
<p><strong>Find the humans.</strong> Bypass automated filters. Find engineering managers, recruiters, or senior engineers at these companies on LinkedIn. Send personalized messages that show you understand what they're building.</p>
<p><strong>Use every tool available.</strong> This isn't cheating — it's survival. If applications worked, you'd use them. Since they don't, use LinkedIn, use email, use your network, use whatever gets you in front of actual humans.</p>
<p><strong>Think like a researcher, not an applicant.</strong> Your goal isn't to apply to more jobs. It's to identify companies worth targeting and figure out how to reach them directly.</p>
<p><strong>Key Takeaways for Job Seekers:</strong></p>
<ul>
<li><p>Companies receive 1,000+ applications per role but only 10% are qualified</p>
</li>
<li><p>Most hires come from direct outreach and referrals, not applications</p>
</li>
<li><p>Research 10-20 target companies deeply instead of mass-applying</p>
</li>
<li><p>Reach out directly to hiring managers on LinkedIn</p>
</li>
<li><p>Interview transparency matters — but for researching companies, not just applying</p>
</li>
</ul>
<h2 id="heading-where-i-go-from-here">Where I Go From Here</h2>
<p>I'm sitting with this tension. The 26 jobs I've curated show companies that are transparent about interviews, clear about geographic policies, and honest about compensation. That information has value — I'm just not sure yet if it's most valuable as "here's where to apply" or "here's what to research for direct outreach."</p>
<p>Maybe it's both. Maybe some developers still want to apply, and transparency helps them choose wisely. Maybe others want to skip applications entirely, and the same information helps them identify targets for outreach.</p>
<p>I'm going to keep curating companies and watching how people actually use GlobalRemote. The data from hiring managers is clear, but I need to see how job seekers respond before making any dramatic changes.</p>
<p>If you're job hunting right now, I'd encourage you to think about your job search differently. Don't just ask "How many applications should I send?" Also ask "Which 10 companies are worth my focused attention, and how do I reach the people who make hiring decisions there?"</p>
<p>The application black hole is real. Whether the solution is better applications, direct outreach, or some combination of both — I'm still figuring that out.</p>
<hr />
<p><em>I'm working through these questions in real-time. If you've had success with direct outreach, or if you have thoughts on what job seekers actually need right now, I'd genuinely love to hear about it. You can check out GlobalRemote at</em> <a target="_blank" href="https://jobs.alleyne.dev"><em>jobs.alleyne.dev</em></a> <em>to see what I've built so far, or reach out to me on</em> <a target="_blank" href="https://linkedin.com/in/damienalleyne"><em>LinkedIn</em></a><em>.</em></p>
]]></content:encoded></item><item><title><![CDATA[From Interview Surprise to MVP: Testing Developer Job Transparency]]></title><description><![CDATA[A few weeks ago, I applied for a Backend Engineering role, expecting a technical interview similar to what I had experienced before—like the collaborative pair programming session I had when joining Automattic, where a developer and I worked together...]]></description><link>https://blog.alleyne.dev/from-interview-surprise-to-mvp-testing-developer-job-transparency</link><guid isPermaLink="true">https://blog.alleyne.dev/from-interview-surprise-to-mvp-testing-developer-job-transparency</guid><category><![CDATA[remote work]]></category><category><![CDATA[job search]]></category><category><![CDATA[developer experience]]></category><category><![CDATA[Build In Public]]></category><dc:creator><![CDATA[Damien Alleyne]]></dc:creator><pubDate>Mon, 15 Sep 2025 11:23:43 GMT</pubDate><content:encoded><![CDATA[<p>A few weeks ago, I applied for a Backend Engineering role, expecting a technical interview similar to what I had experienced before—like the collaborative pair programming session I had when joining Automattic, where a developer and I worked together to add features to a WordPress plugin. Instead, I received a 90-minute coding assessment with a mix of LeetCode-style and domain-specific questions, scheduled within a 5-day window. A few days later, another interview surprised me again—I showed up expecting a discussion about my experience but was handed a piece of paper and asked to design an API response.</p>
<p>This made me wonder: <strong>Why are developers going into interview processes without knowing what to expect?</strong></p>
<h2 id="heading-the-problem-i-experienced">The Problem I Experienced</h2>
<p>Most job boards tell you the salary, tech stack, and basic requirements. Company culture information is usually found on their career pages or sites like Glassdoor. But they rarely mention what the interview process actually looks like. Will there be <a target="_blank" href="https://they.whiteboarded.me/">whiteboarding</a>? Take-home projects? Multiple rounds? System design sessions?</p>
<p>As a senior developer with options, knowing the interview format helps me:</p>
<ul>
<li><p>Allocate preparation time effectively</p>
</li>
<li><p>Choose opportunities that align with my strengths</p>
</li>
<li><p>Avoid processes that feel misaligned with my experience</p>
</li>
</ul>
<p>But this information is typically discovered during the interview process itself — too late to make informed decisions about time investment. Some companies do provide excellent transparency (detailed assessment instructions, preparation resources, and clear reapplication timelines), but they're the exception. Most companies leave you guessing about format, expectations, and preparation requirements until you're already committed to their process.</p>
<h2 id="heading-building-an-mvp-to-test-the-idea">Building an MVP to Test the Idea</h2>
<p>I decided to build something to test whether other developers want this transparency. Enter <a target="_blank" href="https://jobs.alleyne.dev">GlobalRemote</a> — a job board that shows interview processes upfront.</p>
<p>The initial concept was simple: curate remote jobs that include detailed interview process information alongside the usual job details.</p>
<h3 id="heading-what-i-built">What I Built</h3>
<p>Rather than scraping existing job boards, I chose manual curation to ensure data quality:</p>
<p><strong>Data Sources:</strong></p>
<ul>
<li><p>Company career pages and hiring documentation</p>
</li>
<li><p>Direct outreach to recruiters for process clarification</p>
</li>
<li><p>Cross-referencing with resources like the <a target="_blank" href="https://github.com/poteto/hiring-without-whiteboards">hiring-without-whiteboards GitHub repo</a></p>
</li>
<li><p>Employee posts on platforms discussing company interview experiences</p>
</li>
</ul>
<p><strong>Information Collected:</strong></p>
<ul>
<li><p>Number of interview rounds and types (technical, behavioral, system design)</p>
</li>
<li><p>Time commitment expectations for assessments</p>
</li>
<li><p>Specific technologies or frameworks tested</p>
</li>
<li><p>Any unique aspects of their process</p>
</li>
</ul>
<p><strong>Current Status:</strong> 7 manually verified listings with complete interview transparency</p>
<h3 id="heading-problems-i-discovered-while-building">Problems I Discovered While Building</h3>
<p>As I started sharing the concept with other developers, two additional pain points kept coming up:</p>
<p><strong>Geographic Restrictions:</strong> Multiple people mentioned getting excited about "remote" jobs only to discover hidden location requirements during the application process. Some jobs require specific timezone overlap, others have legal restrictions, and some companies prefer certain regions for operational reasons.</p>
<p><strong>Regional Salary Context:</strong> A developer friend in New Zealand pointed out that my original $120k+ USD threshold excluded competitive senior roles in his market. A $90k USD role in Auckland might be excellent locally, even if it wouldn't meet US market expectations.</p>
<p>These insights taught me that the problem space was broader than just interview transparency.</p>
<h2 id="heading-early-feedback-and-response">Early Feedback and Response</h2>
<p>I've been testing this concept in developer communities to see if it resonates:</p>
<p><strong>Developer Community (WhatsApp):</strong></p>
<ul>
<li><p>11 positive reactions</p>
</li>
<li><p>Discussion focused primarily on geographic restriction frustrations</p>
</li>
<li><p>One business-oriented suggestion about data reporting potential</p>
</li>
<li><p>Strong engagement suggesting the concept resonates</p>
</li>
</ul>
<p><strong>Tech Alumni Network (Slack):</strong></p>
<ul>
<li><p>8 positive reactions</p>
</li>
<li><p>One person confirmed experiencing the geographic restriction problem and mentioned facing similar challenges during their recent job search</p>
</li>
<li><p>Another mentioned that LeetCode-style processes feel "lazy" from companies</p>
</li>
<li><p>Generally positive response to the transparency concept</p>
</li>
</ul>
<h2 id="heading-technical-challenges-im-learning-from">Technical Challenges I'm Learning From</h2>
<p>Building this MVP has revealed several interesting technical challenges:</p>
<p><strong>Data Verification Complexity:</strong> Interview processes are described inconsistently across companies. "Technical interview" could mean live coding, whiteboarding, take-home projects, or system design discussions. This required careful manual interpretation to understand what each company actually does.</p>
<p><strong>Geographic Restriction Nuance:</strong> "Remote work" has many different meanings depending on company policy. Some companies require timezone overlap (e.g., "must work EST hours"), others have legal restrictions (e.g., "US/Canada only"), and some have operational preferences. Parsing and categorizing these restrictions requires understanding both company policies and legal frameworks.</p>
<p><strong>Quality vs. Scale Trade-offs:</strong> I could scrape thousands of job listings quickly, but most would lack the interview process details that make the platform valuable. Manual curation ensures quality but limits scale — at least initially.</p>
<h2 id="heading-what-im-learning-about-developer-pain-points">What I'm Learning About Developer Pain Points</h2>
<p><strong>Developers immediately understand the value proposition.</strong> The feedback suggests this is a real pain point, not just my personal frustration.</p>
<p><strong>Geographic restrictions are more frustrating than I initially thought.</strong> The distinction between timezone requirements, legal restrictions, and operational preferences matters to job seekers.</p>
<p><strong>Interview format transparency could change application behavior.</strong> Some developers mentioned they would self-select out of processes that don't align with their strengths or preferences.</p>
<h2 id="heading-is-this-problem-worth-solving">Is This Problem Worth Solving?</h2>
<p>The early feedback suggests there's genuine demand for this transparency, but I need more data points to be confident. The real test is whether developers would actually change their job search behavior based on this information being available upfront.</p>
<p>If interview transparency and geographic clarity would genuinely help you make better decisions about where to spend your time applying and preparing, then this is worth building. If it's just "nice to have" information that wouldn't actually change your behavior, then it's probably not worth the effort.</p>
<h2 id="heading-what-i-need-from-you">What I Need from You</h2>
<p>I'm at the point where I need broader feedback from developers to decide whether to continue developing this or pivot to other opportunities.</p>
<p><strong>If you're a developer who's job hunting or has recently job hunted:</strong></p>
<ul>
<li><p>Have you experienced similar interview process surprises?</p>
</li>
<li><p>Would knowing the interview format upfront change how you apply to jobs?</p>
</li>
<li><p>What other information would be valuable to know before applying?</p>
</li>
<li><p>Does the geographic restriction transparency resonate with your experience?</p>
</li>
</ul>
<p>The engagement so far suggests there's something here, but I want to validate this with more developers before investing significant time in scaling the platform.</p>
<p><strong>Check out the current MVP:</strong> <a target="_blank" href="https://jobs.alleyne.dev">jobs.alleyne.dev</a></p>
<p>Right now, I'm genuinely uncertain whether this problem is significant enough to warrant a dedicated solution, or if it's better solved through incremental improvements to existing platforms. Your feedback as developers who experience this problem firsthand will help me make that decision.</p>
<hr />
<p><em>What's been your experience with interview process transparency during job searches? I'd love to hear your stories and thoughts in the comments.</em></p>
]]></content:encoded></item><item><title><![CDATA[Essential Course Notes on Cloud Native Application Architecture]]></title><description><![CDATA[A few months ago, I signed up for a course to help me understand the responsibilities of a Software Architect, and the projects mentioned in the syllabus were exactly what I was looking for. Refactoring a Monolith is the most difficult Udacity projec...]]></description><link>https://blog.alleyne.dev/essential-course-notes-on-cloud-native-application-architecture</link><guid isPermaLink="true">https://blog.alleyne.dev/essential-course-notes-on-cloud-native-application-architecture</guid><category><![CDATA[Kubernetes]]></category><category><![CDATA[vagrant]]></category><category><![CDATA[Cloud Computing]]></category><dc:creator><![CDATA[Damien Alleyne]]></dc:creator><pubDate>Mon, 25 Oct 2021 06:27:55 GMT</pubDate><content:encoded><![CDATA[<p>A few months ago, I signed up for a <a target="_blank" href="https://www.udacity.com/course/cloud-native-application-architecture-nanodegree--nd064">course</a> to help me understand the responsibilities of a Software Architect, and the projects mentioned in the <a target="_blank" href="https://d20vrrgs8k4bvw.cloudfront.net/documents/en-US/Cloud+Native+Application+Architecture+Nanodegree+Program+Syllabus.pdf">syllabus</a> were exactly what I was looking for. <a target="_blank" href="https://github.com/udacity/nd064-c2-message-passing-projects-starter/">Refactoring a Monolith</a> is the most difficult Udacity project that I've completed, so I'm making a record for myself and future students.</p>
<h3 id="heading-setting-up-the-developer-environment">Setting up the developer environment</h3>
<h4 id="heading-kubernetes">Kubernetes</h4>
<p>The project's setup instructions calls for using vagrant to create a virtual machine which automatically installs <code>k3s</code> and forwards the necessary ports for access this cluster. If you already have a local kubernetes instance installed, this process can be skipped. I already had Docker Desktop installed, which includes kubernetes, it simply needed to be <a target="_blank" href="https://docs.docker.com/desktop/kubernetes/#enable-kubernetes">enabled</a>. Once enabled, the project's deployment folder can be applied to the local cluster with ease.</p>
<blockquote>
<p>kubectl apply -f deployment/</p>
</blockquote>
<p>Using an existing cluster avoids having to <a target="_blank" href="https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/">managing access to multiple clusters</a>. Once the project <strong>works</strong>, you can use vagrant to create your VM and debug with confidence knowing that your installation was sound. Issues typically encountered involved incompatibilities between <code>k3s</code> and virtualbox OS images.</p>
<h4 id="heading-skaffold">Skaffold</h4>
<p>Any project that involves local kubernetes development should use <a target="_blank" href="https://skaffold.dev/">skaffold</a>. From the documentation:</p>
<blockquote>
<p>Skaffold is a command line tool that facilitates continuous development for Kubernetes-native applications. Skaffold handles the workflow for building, pushing, and deploying your application, and provides building blocks for creating CI/CD pipelines.</p>
</blockquote>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/8_Ozfa7JLEs">https://youtu.be/8_Ozfa7JLEs</a></div>
<p>Near the end of your development, you can then use skaffold to push the latest images to your docker hub account. One issue I encountered was that the images pushed to docker hub had tags <em>other than</em> <code>latest</code>. I had to include the following in my <code>skaffold.yaml</code> build section. </p>
<pre><code class="lang-yaml">  <span class="hljs-attr">tagPolicy:</span>
    <span class="hljs-attr">sha256:</span> {}
</code></pre>
<p>An example of how it looks can be seen <a target="_blank" href="https://skaffold.dev/docs/pipeline-stages/taggers/#example-5">here</a>. </p>
<p><strong>Very important</strong>: set the <strong>imagePullPolicy</strong> in your deployment files to <a target="_blank" href="https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy">IfNotPresent</a>. This allows your local cluster to use the images directly built by skaffold, rather than pulling them from Docker Hub.</p>
]]></content:encoded></item></channel></rss>