v1.4.0
ai-job-search-dev/ai-job-searchv1.4.0Aug 7, 2026by MadsLorentzen
Upgrading?
AI Summary
Fixes silent failures in the application workflow and fetch logic. Applications are now tracked, and fetches respect robots.txt.
Key Highlights
- /apply now writes a drafted status so applications aren't lost.
- /rank no longer marks live jobs as expired due to 403s (now respects robots.txt).
- All portal CLIs now use honest User-Agents.
- Danish demo portals are disabled by default.
Breaking Changes
- drafted is now a legal tracker status (consumers must handle it).
- tools/robots_check.py gates retries on robots.txt (sites denied are never overridden).
New Features
- /setup captures a structured Languages table.
- --jobage-minutes flag for LinkedIn.
- .env file is now gitignored.
Full Release Notes
## Why update Two silent failures in the flagship flow are fixed: **Your applications no longer vanish.** `/apply` wrote your CV and cover letter to disk and then recorded nothing - a drafted-and-submitted application was invisible to `/gmail-sync`, `/html-report`, `/notion-sync`, `/interview`, and `/rank`'s dedup, and nothing ever detected the loss (#269, fixed in #291 by @jakob1379). `/apply` now writes a `drafted` row to the tracker, a new `drafted` status flows through every reader honestly (unsent drafts are never counted as "waiting for a reply", never chased with follow-ups, and never reported as submitted), and an employer's acknowledgement email lets `/gmail-sync` promote the row to `applied` with the real date - catching exactly the case where you submitted by hand and forgot to run `/outcome`. **Live postings are no longer declared dead.** `WebFetch` identifies itself as a bot, and many corporate sites answer it with HTTP 403 while serving browsers normally. `/rank` read that as "posting gone" and marked live jobs `expired`; `/apply` silently fell back to search-snippet prose (#277, reported and fixed by @kblackma). The new `09-web-research.md` methodology file defines the trust boundary and a retry escalation - and the retry is **gated on robots.txt** via the new `tools/robots_check.py`: a site whose published policy permits access gets a browser-header retry past its WAF; a site that has said no is never overridden. The gate itself was then adversarially hardened (#286): a soft-200 HTML page no longer reads as permission, and percent-encoded Disallow rules now match. ## Honest self-identification, completed Every shipped portal CLI now sends an identifying `User-Agent` token instead of a browser spoof: jobnet and jobdanmark (#283 by @oscarbol09), jobbank and the jobdanmark detail path, and finally linkedin-search - the last holdout. Live-verified on every portal: identical responses under the honest token. Sites can now see exactly who is asking, which is the posture the robots gate depends on. ## Also in this release - **Danish demo portals ship disabled** (#288, suggested by @a-vysokov) - `/setup` enables them when your market is Denmark; everyone else's `/scrape` stops spending tokens on Danish boards it never needed. - **`--jobage-minutes` on linkedin-search** (#302 by @kgurnoor) - sub-day freshness windows for early-applicant timing; LinkedIn filters at second granularity server-side. - **`.env` can no longer be committed** (#303 by @Haseeb-1698) - ignored and pinned in the security guard, protecting forks whose generated portal skills use an API token. - **Negative and fractional filter flags rejected** in the Danish portal CLIs (#281 by @oscarbol09) - some portals silently ignore invalid filters and return unfiltered results. - **The upstream checker no longer prints a false all-clear** when upstream renames or deletes a tracked file (#282 by @oscarbol09), and it now tracks `09-web-research.md`. - **Spec-pinning tests** for the Language Gate's `/rank` contract (#278 by @GabrielMensi). - **A video walkthrough** in the README's Quick start - The Next New Thing's hands-on tour of the workflow, for newcomers who want to see it before reading. ## Fork reconciliation `python3 tools/check_upstream_updates.py` will flag three methodology files this release: | File | Version | What changed | |---|---|---| | `job-application-assistant/SKILL.md` | 1.1.0 → 1.3.0 | Bash added to allowed-tools (robots-gated retry); new Step 3b records the application | | `03-writing-style.md` | 1.1.0 → 1.2.0 | Rule 5 routes 403s through the web-research escalation | | `09-web-research.md` | new, 1.1.0 | New file - adopt as-is unless you have your own fetch conventions | Two personalized-file landmines to check by hand: - **Danish-market forks:** the four Danish portal `SKILL.md` files now ship `enabled: false`. If you search the Danish market, flip them back to `enabled: true` after updating (or re-run `/setup --section search`). Forks that already curated their portal set are unaffected. - **Tracker vocabulary:** `drafted` is now a legal tracker status. If your fork customized `/outcome`, `/gmail-sync`, `/html-report`, or `/notion-sync`, reconcile the new status handling - unsent drafts must stay out of funnel statistics and follow-up nudges. (A full single-definition cleanup of the status enum is in review as #304's sibling effort, #298/#299 - it will land in a future release.) ## Credits @jakob1379 (the #269 diagnosis and the #291 fix, plus the #298 follow-up analysis), @kblackma (the 403 investigation, `robots_check.py`, and the adversarial hardening in #286), @oscarbol09 (#281, #282, #283), @GabrielMensi (#278), @kgurnoor (#302), @Haseeb-1698 (#303), @a-vysokov (#288).
Related Repositories
public-apis/public-apis★ 491,326
A collective list of free APIs
NousResearch/hermes-agent★ 256,173
The agent that grows with you
yt-dlp/yt-dlp★ 200,390
A feature-rich command-line audio/video downloader
microsoft/markitdown★ 191,631
Python tool for converting files and office documents to Markdown.
Significant-Gravitas/AutoGPT★ 187,711
AutoGPT is the vision of accessible AI for everyone, to use and to build on. Our mission is to provide the tools, so that you can focus on what matters.