Changelog
What we shipped — generated from our commit history, curated weekly.
Week of May 25, 2026
27 new33 fixes
- featfounderweave first-person conviction into D8 essay Frame (Graham passed)
- featfounderD8 reasoning-first essay SSR page (STAGED noindex)
- feattgclassify TG vacancies at insert (primary_role + consistent direction)
- fixworkerfall back to legacy direction for primary_roles with no taxonomy page
- fixworkerderive vacancy direction from primary_role at web-ingestion
- featsecurityweekly SCA via VPS cron — pip-audit + npm audit (A5/S28.3/D61)
- fixbackupB2 off-site push failed silently under cron (PATH) — A4/S28.2/D60
- featprivacyhonest analytics §7 + /privacy/cookies page + webvisor off (A3/S28.1/D59)
- fixclassifierrescue scores stack-only, not description prose
- featclassifierstack-signal rescue for min_core-gated "Other" rows
- fixpublicstrip t.me/domain links from public vacancy text (A+ catch-all)
- fixclassifybackfill vacancy direction from role-classifier when classify_direction is None
- fixworkertask_auto_match matches recent entities (30-min fresh matches)
- featmatches«Свежие матчи» preset for the sales work queue
- featuiS20.1 CardSkeleton on Analytics + DealKanban (D53, HB#4 Step 4)
- featdemodemo_viewer PII-masked role + central default-deny guard (D38, HB#4 Step 3)
- fixchangelogdrop superseded legal identity from public changelog
- featchangelogpublic /changelog SSR page auto-from-git (D55, HB#4 Step 1)
- featanalyticsTalent Source radar from CV work-history (S14.1)
- featscriptsbackfill_prior_employments — enrich existing candidates (S14.1)
- fixstorageaccept RTF content under application/msword (.doc uploads)
- featparserwork-history extraction (S14.1) — candidates.prior_employments
- fixscraperNULLIF guard so grade-enrichment never writes empty string
- fixparsernormalize resume grade to lowercase canonical form
- fixparserad-CTA junk filter no longer drops vacancies with «Пишите @recruiter»
- feati18nLatin display alias «1с»→«1C» for EN tech lists
- fixpublicrate-limiter bucketed on docker peer IP → site-wide empty-state
- fixparser_first_content_line skips narrative greetings + caps at 80 chars
- featd41standalone /anti-war page + EN mirror — Sprint 24 D41 ship
- featseodefault per-page hreflang annotations in computeHead
- fixseofilter malformed long vacancy titles from /research/<dir> recent
- fixseoapply role-name blacklist to /research/<dir> top_stacks + pairs
- fixseoseo_health_check expects /en/ after Phase 5 cutover (was /ru/)
- fixseoblacklist space-variant of «бизнес аналитик» (DB has both forms)
- fixseofilter role-name pseudo-techs from /research/stacks (EN audit cleanup)
- featseostatic-page lastmod in sitemap for Phase 8 reindexing signal
- fixthemedark-mode overrides leaking into public pages after Phase 6 prefix
- fixparserlinkedin URL vs label disambiguation + 5 new experience_years patterns
- fixlegal/privacy §5 — remove false "EU data centre" claim (Sprint 23 pre-outbound)
- featseodatePublished/dateModified on AboutPage + HowItWorks LDs (Phase 8 #4)
- featseomax-snippet robots meta for AI Overviews citation (Phase 8 #3)
- featseoBreadcrumbList JSON-LD for /about + /research hub (Phase 8 AI-search #2)
- featseoSSR-time FAQPage Schema for /en/faq + /ru/faq (Phase 8 AI-search #1)
- fixlegalEN polish pass on Privacy + Terms (Phase 8 — compliance precision)
- fixseoJSON-LD inLanguage + SearchAction urlTemplate /en/jobs (Phase 8 polish)
- fixuiproper 404 page для /en/<unknown> + /ru/<unknown> (Phase 8 EN polish)
- fixi18nSitemapPage hardcoded RU → lang-aware (S20/Phase8 EN audit fix)
- featuiapply EmptyState to public /jobs + /jobs/role/:slug (S20.1 Phase 4)
- fixseoHEAD handlers for /llms.txt, /healthz, SPA-served static files
- featuiempty-state library + skeleton-screens unified pattern (S20.1)
- fixi18nsubniche country labels lang-aware — close last RU leak
- feati18nPhase 7 — backend research narrative i18n for /en/research/<dir>
- fixi18nEN cleanup pass — wrap remaining hardcoded RU on /en/* pages
- fixi18n/en/privacy + /en/terms now render EN (not RU) — Phase 6 legal pages
- fixseoadd HEAD handler for /robots.txt — Yandex crawler HEAD-prechecks
- fixi18nrobots.txt sitemap pointer + add absolute_resource_url helper
- feati18nPhase 6 — symmetric /en/ URL prefix (parallel /ru/)
- fixi18nextract PUBLIC_LANGS/DEFAULT_PUBLIC_LANG to leaf constants.ts — break SSR TDZ cycle
- feati18nPhase 5.3 — URL generation as single source of truth
- feati18nPhase 3.3w pair 117/117 — gamedev/web3-game EN + devops/general slug fix — PHASE 3.3w COMPLETE 117/117 ✅ (+59 related commits)
Week of May 18, 2026
79 new45 fixes
- feati18nPhase 3.3w pair 57/117 — architect/integration EN — ARCHITECT 6/6 CLOSED (+56 related commits)
- feati18nPhase 3.3w step 0 — sub-niche overrides EN dispatch infra
- feati18nPhase 4.5 — JSON-LD page-canonical URLs go locale-aware
- feati18nPhase 4.3 — self-canonical per locale URL
- fixi18nPhase 4 — flip _LANG_ROOT to "en" (feat/multilang is post-cutover-ready)
- feati18nPhase 4.1/4.2/4.4 — sitemap-index + per-lang sitemaps + hreflang
- fixseoadd HEAD handler for /sitemap.xml — Yandex crawler HEAD-prechecks
- feati18nPhase 3.3v — Blockchain / Web3 direction translated to EN
- feati18nPhase 3.3u — DevRel direction translated to EN
- feati18nPhase 3.3t — Marketing direction translated to EN
- feati18nPhase 3.3s — GameDev direction translated to EN
- feati18nPhase 3.3r — Security direction translated to EN
- feati18nPhase 3.3q — Design / UX direction translated to EN
- feati18nPhase 3.3p — PM / PO direction translated to EN
- feati18nPhase 3.3o — Support / SysAdmin direction translated to EN
- feati18nPhase 3.3n — Embedded / IoT direction translated to EN
- feati18nPhase 3.3m — HR direction translated to EN
- feati18nPhase 3.3l — Mobile direction translated to EN
- feati18nPhase 3.3k — QA / Testing direction translated to EN
- feati18nPhase 3.3j — Sales direction translated to EN
- feati18nPhase 3.3i — Product Manager direction translated to EN
- feati18nPhase 3.3h — ML / AI / Data Science translated to EN
- feati18nPhase 3.3g — DevOps / SRE direction translated to EN
- feati18nPhase 3.3f — Data Engineer direction translated to EN
- feati18nPhase 3.3e — Architect direction translated to EN
- feati18nPhase 3.3d — Analyst direction translated to EN
- feati18nPhase 3.3c — Fullstack direction translated to EN
- feati18nPhase 3.3b — Frontend direction translated to EN
- feati18nPhase 3.3a — pSEO EN infra + Backend direction translated
- feati18nPhase 3.4b.5 — /about, /how-it-works, /faq, /apply EN translation
- feati18nPhase 3.4b.4 — /jobs, /jobs/:id, /jobs/role/:slug EN translation
- feati18nPhase 3.4b.3 — /research/* analytics pages EN translation
- feati18nPhase 3.4b.2 — /vs/{huntflow,potok,greenhouse} EN translation
- feati18nPhase 3.4b.6 — DirectionPage template chrome to English
- feati18nPhase 3.4b.1 — shell chrome (Header / Footer / CookieBanner)
- feati18nPhase 3.4d — apex index.html defaults switched to English
- feati18nPhase 3.4c — research route-layer EN strings + parent_name_en
- feati18nPhase 3.4a — branch SEO heads on lang in publicHeads.ts
- feati18nPhase 3.2 — niche-role landings EN fields + lang-aware API
- feati18nPhase 2.7 — dynamic html lang + og:locale per locale
- feati18nPhase 2.6 — merge Privacy/Terms EN+RU into unified i18n pages
- feati18nPhase 2.5 — locale-aware internal links across public surface
- feati18nPhase 2.4 — language switcher in PublicHeader
- feati18nPhase 2.3 — language prefix on public routes
- feati18nPhase 2.2 — URL ↔ locale parser (parsePublicLocale + localizePath)
- feati18nPhase 2.1 — public i18n catalogues + pure t() helper
- fixnginxproxy_pass uses container_name (tdcrm-web-v2 / tdcrm-ssr)
- featssrPhase 1.5.8 / 1.6 — drop legacy hand-rolled SSR
- featssrPhase 1.5.7 — cutover index.html → entry-client.tsx (JSON data island, no CSP change)
- featssrPhase 1.5.5 — Dockerfile.ssr + docker-compose ssr service
- featssrPhase 1.5.4 — Redis cache layer in ssr.mjs
- fixssrswitch render() to renderToReadableStream — wait for Suspense
- featssrPhase 1.5.2 — Node SSR HTTP server (no Redis yet)
- featssrPhase 1.5.1 — entry-client.tsx (isolated, not yet wired)
- featssrPhase 1.7 — fix useIsMobile SSR safety
- featssrLD-debt close — DirectionPage 4 LD via extraJsonLd
- featssrLD-debt close — FaqPage faq-ld via extraJsonLd (client-only)
- featssrLD-debt close — HowItWorksPage article-ld via extraJsonLd
- featssrLD-debt close — AboutPage about-ld via extraJsonLd
- featssrhead migration — NicheRolePage (data-driven + niche-role-ld) (+17 related commits)
- featssrAllDirectionsPage enrichment + DirectionPage defensive shape
- featssrextraJsonLd infra for arbitrary per-page JSON-LD
- featssrhead migration batch — privacy/terms (5 legal pages)
- featssrhead migration infra + SalariesPage PoC
- featssrPhase 1.3 cont. — /sitemap prefetch (last public route) (+10 related commits)
- featssrPhase 1.4 — split publicMeta into computeHead + applyHeadToDOM
- featssrPhase 1.3 final — shared publicJobs query builder for byte-parity
- featssrPhase 1.3 — /jobs prefetch wired in entry-server
- featssrPhase 1.3 skeleton — prefetch + dehydrate pipeline in entry-server
- featssrPhase 1.2 scaffolding — entry-server, queryClient, Vite SSR build
- fixlintdoc_drift_check accepts gitignored build-output paths
- fixparsersre-enable indeed / seek / glassdoor web parsers
- featcandidatessub-niche drill-down filter, mirroring vacancies
- fixtg-pipelinevacancy role = first meaningful line, not raw line 1
- featmonitoringcron-task liveness watchdog (audit follow-up)
- fixreliabilityP2b — input hardening, silent failures, FK/config drift
- fixsecurityP2a — role gates, public exposure, GDPR erasure
- fixdrversion-control the backup scripts (P1 #6)
- fixsecuritybulk_convert_candidates — role-gate + soft-delete (P1 #5)
- fixsecurityclose 4 P1 audit findings — auth gaps + exposure + flood
- featoutreachTG-lead drill-down — comparison table + click-through to profile
- featnav/companies (outreach lists) was a nav-orphan — add it to menu
- fixvacanciesconvert-to-candidate no longer destroys real vacancies
- featoutreachTG-lead drill-down — candidates behind the match count
- fixtg-pipelinestop spam leaking into the candidates table
- featoutreachTG-recruiter lead list for Алина
- fixseolast research anchor still rendered a raw URL
- featseojob detail links to its /research direction page
- featseowire /vs/* and /jobs/role/* into the internal-link cluster
- featseo/research lists all 22 directions in a grid
- featseodescriptive anchor text for research cross-links
- fixpublicno self-links — current page rendered as plain text
- fixsitemapsingle-column layout — drop the grid that scattered rows
- featpublic/sitemap — human HTML sitemap page
- fixresearch articles3 audit bugs — FAQ gaps + invalid devops/devops slug
- feattalent-poolsalary column (normalised salary_usd)
- fixsalarytask_update_currency_rates recomputes candidates.salary_usd too
- fixsalarytask_update_currency_rates recomputes existing salary_usd
- fixsalaryRUB_K — Latin «k» is currency-ambiguous, not always RUB
- fixsalarylanguage-aware currency default + sub-niche median min-sample gate
- fixresearchunify remote_pct — hero tile matched body text
- fixmatcherOption A — ignore phantom tech stack on non-IT vacancies
- fixclassifierRule N — match engineering token in title only, not body
- fixuse 'slug' (route param) not 'direction_slug' in sub_niches override check
- fixmetrikamove noscript pixel to body (HTML5 parse error in head)
- fixdrop description ILIKE from search — count-subquery seq-scan killer
- fixsearch query optimization — drop cast-stack-ILIKE + smarter JCUKEN-flip
- fixbump db pool 10+5 → 30+20 (search QueuePool exhaustion under load)
- fixpdfinit line='' in Description block — UnboundLocalError when vacancy has no stack
- fixphase2 hotfixmatch parent payload shape on sub-niche page
- fixresume parser — handle internal-channel «Шаблон.txt» field format
- fix409 detail as string (frontend apiFetch expects string, not object)
- fixcreate-candidate — handle telegram duplicate as 409 not 500
- fixcandidate create — accept null country/salary_currency, coerce to defaults
- fixskip dark theme on public routes - real root cause for broken styles
- fixcolor-scheme light (only) to actually disable Chrome force-dark
- fixdeclare color-scheme to prevent Chrome force-dark inversion
- fixleadsfallback to TD_ALERT_CHAT_ID for TG notify (already set on prod)
- fixhero SQL adds 3-month filter — was missed in prior commit
- fix/research/:slug dynamic route — DirectionPage works for all 22 dirs
- fixdirection endpoint clients table column is company_name not name
- fixcurrencyraise _ANNUAL_THRESHOLDS to stop mis-classifying monthly as annual
- fixTStooltip handles null y values in TimeSeriesChart
- featdrop fontsource imports to eliminate FOUT-induced CLS