# Changelog All notable changes to this project are documented here. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Releases are vetted checkpoints of `master`. If you maintain a personalized fork, prefer updating to a tagged release over pulling raw `master` (see [SETUP.md, section 8](SETUP.md#8-pulling-upstream-updates-into-your-fork)). The `framework_version` markers on methodology files tell you which of your customized files a release touched; `python3 tools/check_upstream_updates.py` lists them with per-file diff commands. ## [Unreleased] ### Added - **Company-research cache for `/apply` and `/interview`** - `/apply` Step 3's reviewer agent and `/interview` Step 2 each independently execute the Company Research Checklist (`04-job-evaluation.md`) for the same company, so applying and later prepping for an interview on the same application researches the company twice from scratch. A new `company_research/.json` cache (30-day TTL, documented in `04-job-evaluation.md` alongside the checklist it mirrors) lets either consumer reuse a recent result instead of repeating the search/fetch work. This does not change how a claim gets verified: cached research is a lead, exactly like reviewer-agent research already is under `03-writing-style.md` rule 5 - only the discovery step is cached, never the final verification before a claim ships in a cover letter or prep pack. `company_research/*.json` added to `.gitignore` and `security_guards.py`'s `REQUIRED_IGNORE_RULES` (a plain rooted pattern, not `**/` -prefixed - the cache is referenced from commands, not a skill, so it resolves against the repo root normally). Pinned by the new `tests/test_company_research_cache.py`. Cache contents are documented as data, never instructions, for a later session reading the file - the same trust-boundary rule `apply.md` Step 0 states for the posting itself, since cache notes are written from the same fetched web content. The verification-still-applies restatement in both `apply.md` and `interview.md`'s cache-check paragraphs is now pinned too. - **CI now compiles the LaTeX examples on Debian bookworm's apt-packaged TeX Live** (the separate-PR follow-up invited in #323's review). The `latex-smoke` job ran only `texlive/texlive:latest` - the environment that never had the #242 bug, so the moderncv-2.3.1 compile fix shipped guarded by nothing: the next edit to `cv/main_example.tex` could reintroduce a `\firstnamestyle` override or a top-level `\usepackage{hyperref}` and CI would stay green. The job is now a two-leg matrix, `texlive-latest` unchanged and `debian-bookworm` installing TeX Live 2022 from apt (moderncv 2.3.1, verified in a real bookworm container: both documents compile clean and the strict stock assertions - 2-page CV, 1-page cover letter, extractable text - pass on both legs unchanged). `--no-install-recommends` keeps the leg lean, which makes two font packages explicit requirements: `texlive-fonts-extra` (moderncv loads fontawesome5) and `texlive-fonts-recommended` (hyperref's xetex driver probes the `pzdr` metrics). **Note for repo admins:** the matrix renames the check from "Compile example CV and cover letter" to two leg-suffixed names, so a branch-protection rule requiring the old name needs updating once. ## [1.6.0] - 2026-08-19 ### Added - **Cross-portal `/scrape` contract pin** (#344) - a repo-level test deriving the Step 2 search-output field list (`title`, `company`, `location`, `date`, `url`) from `job-scraper/SKILL.md`'s own contract sentence and checking every installed portal CLI's search source for it, so a portal that quietly stops emitting a contract field (the failure class jobnet and jobdanmark actually shipped before #339/#340) fails CI with a clean diff instead of degrading every `/scrape` run silently. The pin survived the #347 output-shape changes unmodified - evidence the derived-from-spec design holds. Contributed by @oscarbol09, the invited follow-up from #342's review. - **`freehire-search` gains `--no-description` for cheap discovery passes** - a default search hydrates full description bodies (~73% of the payload, ~20k tokens per query) while `/scrape` is told to pre-filter by title before reading bodies. The new flag drops the bodies (a live 10-result search shrinks from ~58k to ~10k chars) while keeping every other field; hydration stays the default. The API currently returns bodies regardless of `include_description=false`, so the lean guarantee is enforced client-side. Pinned in `tests/commands.test.ts`. - **Fixture coverage for linkedin's date/location and jobindex's `parseSearchPage`** - linkedin's search-card fixture carried no `